test: concurrent big uploads
Massimo Melina committed
Jan 24, 2025 at 17:05 UTC
593d2b9dcaf18586efb5b35cb557c75b3737166e
2 files changed
+16
-4
src/upload.ts
+1
-1
@@ -258,7 +258,7 @@ export function uploadWriter(base: VfsNode, baseUri: string, path: string, ctx:
258
}
259
260
function fail(status?: number, msg?: string) {
261
- console.debug('upload failed', status, msg)
261
+ console.debug('upload failed', status||'', msg||'')
262
releaseFile()
263
if (status)
264
ctx.status = status
tests/test.ts
+15
-3
@@ -27,6 +27,15 @@ const BIG_CONTENT = _.repeat(randomId(10), 200_000) // 2MB, big enough to satura
27
const throttle = BIG_CONTENT.length /1000 /0.5 // KB, finish in 0.5s, quick but still overlapping downloads
28
let defaultBaseUrl = BASE_URL
29
30
+class StringRepeaterStream extends Readable {
31
+ constructor(private str: string, private n: number, readonly length=n*str.length) {
32
+ super()
33
+ }
34
+ _read() {
35
+ this.push(this.n-- > 0 ? this.str : null)
36
+ }
37
+}
38
+
39
describe('basics', () => {
40
//before(async () => appStarted)
41
it('frontend', req('/', /<body>/, { headers: { accept: '*/*' } })) // workaround: 'accept' is necessary when running server-for-test-dev, still don't know why
@@ -156,6 +165,10 @@ describe('after-login', () => {
165
await reqUpload(UPLOAD_DEST, 409)() // should conflict
166
await first
167
})
168
+ it('upload.concurrent', () => Promise.all([
169
+ reqUpload(UPLOAD_DEST, 200, new StringRepeaterStream(BIG_CONTENT, 150))(), // 300MB
170
+ ..._.range(3).map(i => reqUpload(UPLOAD_DEST + i, 200, new StringRepeaterStream(BIG_CONTENT, 50))()) // 3 x 100MB
171
+ ])).timeout(5000)
172
const renameTo = 'z'
173
it('rename.ok', reqApi('rename', { uri: UPLOAD_DEST, dest: renameTo }, 200))
174
it('delete.miss renamed', reqApi('delete', { uri: UPLOAD_DEST }, 404))
@@ -183,8 +196,7 @@ describe('after-login', () => {
196
await reqUpload(uri, 200, BIG_CONTENT)()
197
await testMaxDl(uri, 2, 1)
198
})
186
- after(() =>
187
- rm(join(__dirname, 'temp'), { recursive: true}).catch(() => 0))
199
+ after(() => rm(join(__dirname, 'temp'), { recursive: true }).catch(() => 0))
200
})
201
202
function login(usr: string, pwd=password) {
@@ -265,7 +277,7 @@ function req(url: string, test:Tester, { baseUrl, throttle, ...requestOptions }:
277
})
278
|| test.empty && data && 'expected empty body'
279
|| length !== undefined && gotLength !== String(length) && "expected content-length " + length + " got " + gotLength
268
- || test.cb?.(data, res) === false && 'error'
280
+ || test.cb?.(obj ?? data, res) === false && 'error'
281
|| ''
282
if (err)
283
throw Error(err)