tus / tus-js-client

A pure JavaScript client for the tus resumable upload protocol
https://tus.io/
MIT License
2.12k stars 316 forks source link

Idea: Build a load-testing tool for tus server #466

Open Acconut opened 2 years ago

Acconut commented 2 years ago

The idea is to build a tool for load-testing tus servers using tus-js-client.

Examples:

neo502721 commented 7 months ago

Hi @Acconut , I did some exploring on this. k6 doc: k6 is not NodeJS, nor is it a browser. Packages that rely on APIs provided by NodeJS, for instance the os and fs modules, will not work in k6. The same goes for browser-specific APIs like the window object. But tus-js-client only support instance of File, Blob, or Reader. Here is my code:

import { Upload } from './dist/tus.js';

const testFile = open('./test.txt', 'r')

export default async function () {
    // Get the selected file from the input element

    // Create a new tus upload
    var upload = new Upload(testFile, {
        endpoint: 'http://localhost:8080/files/',
        retryDelays: [0, 3000, 5000, 10000, 20000],
        metadata: {
            filename: testFile.name,
            filetype: testFile.type,
        },
        onError: function (error) {
            // Display an error message
            console.log('Failed because: ' + error)
        },
        onShouldRetry: function (err, retryAttempt, options) {
            var status = err.originalResponse ? err.originalResponse.getStatus() : 0
            // If the status is a 403, we do not want to retry.
            if (status === 403) {
                return false
            }

            // For any other status code, tus-js-client should retry.
            return true
        },
    })

    // Check if there are any previous uploads to continue.
    upload.findPreviousUploads().then(function (previousUploads) {
        // Found previous uploads so we select the first one.
        if (previousUploads.length) {
            upload.resumeFromPreviousUpload(previousUploads[0])
        }

        // Start the upload
        upload.start()
    })

}

k6 run test.js output:

k6 run test.js 

          /\      |‾‾| /‾‾/   /‾‾/   
     /\  /  \     |  |/  /   /  /    
    /  \/    \    |     (   /   ‾‾\  
   /          \   |  |\  \ |  (‾)  | 
  / __________ \  |__| \__\ \_____/ .io

     execution: local
        script: test.js
        output: -

     scenarios: (100.00%) 1 scenario, 1 max VUs, 10m30s max duration (incl. graceful stop):
              * default: 1 iterations for each of 1 VUs (maxDuration: 10m0s, gracefulStop: 30s)

INFO[0000] Failed because: Error: source object may only be an instance of File, Blob, or Reader in this environment  source=console

     data_received........: 0 B 0 B/s
     data_sent............: 0 B 0 B/s
     iteration_duration...: avg=413.33µs min=413.33µs med=413.33µs max=413.33µs p(90)=413.33µs p(95)=413.33µs
     iterations...........: 1   1223.990208/s

running (00m00.0s), 0/1 VUs, 1 complete and 0 interrupted iterations
default ✓ [======================================] 1 VUs  00m00.0s/10m0s  1/1 iters, 1 per VU
Acconut commented 7 months ago

We experimented with K6 as well, but didn't use tus-js-client and instead used their HTTP API directly. In the end, the logic of uploads for load testing is simple, so we don't necessarily need tus-js-client. You can find a first, experimental version at https://github.com/tus/load-tester although it uses a slightly different protocol.

Regarding your error, you could try to read the file as binary into an ArrayBuffer using the b mode:

const testFile = open('./test.txt', 'rb')

I don't know out of my head whether tus-js-client accepts ArrayBuffers, but if not we should add support for them/Uint8Arrays to tus-js-client as they are quite useful.

neo502721 commented 7 months ago

We experimented with K6 as well, but didn't use tus-js-client and instead used their HTTP API directly. In the end, the logic of uploads for load testing is simple, so we don't necessarily need tus-js-client. You can find a first, experimental version at https://github.com/tus/load-tester although it uses a slightly different protocol.

Regarding your error, you could try to read the file as binary into an ArrayBuffer using the b mode:

const testFile = open('./test.txt', 'rb')

I don't know out of my head whether tus-js-client accepts ArrayBuffers, but if not we should add support for them/Uint8Arrays to tus-js-client as they are quite useful.

Thanks for for your guidance. I'm new to javascript. I tried using rb mode. But tus-js-client give the same error. I will try your load-tester. Thank you very much.