How should I deal with k6/experimental/fs?

I’m trying to replace default open() with fs.open() to use with http.file().

But I’m stacked on how to provide []byte or ArrayBuffer object to http.file().

My simplified scripts is

import http from 'k6/http';
import { check, fail } from 'k6';
import { FormData } from 'https://jslib.k6.io/formdata/0.0.2/index.js';
import exec from 'k6/execution';
import { open } from 'k6/experimental/fs';

let EXCEL_FILE_BIN
let FILE
(async function () {
    FILE = await open('./test.xlsm');
  })();

async function readAll(file) {
const fileInfo = await file.stat();
const buffer = new Uint8Array(fileInfo.size);

const bytesRead = await file.read(buffer);
if (bytesRead !== fileInfo.size) {
    throw new Error(
    'unexpected number of bytes read; expected ' +
        fileInfo.size +
        ' but got ' +
        bytesRead +
        ' bytes'
    );
}

return buffer;
}

async function get_bin_file(file) {
    file_bin = await readAll(file);

    return file_bin
};

(async function () {
    EXCEL_FILE_BIN = await get_bin_file(FILE);
})();
console.log(JSON.stringify(EXCEL_FILE_BIN));

const form_data = new FormData()
form_data.append('file', http.file(EXCEL_FILE_BIN, 'k6 test.xlsm', 'application/vnd.ms-excel.sheet.macroenabled.12'))

So I get error at form_data.append

INFO[0001] undefined                                     source=console
ERRO[0001] GoError: invalid type <nil>, expected string, []byte or ArrayBuffer
        at go.k6.io/k6/js/modules/k6/http.(*ModuleInstance).file-fm (native)
        at file:///Volumes/work/Yandex.Disk.localized/aurora/repos/aurora_k6/project-tests.js:56:67(122)  hint="script exception"

I’m not very familiar with JS and am probably doing something wrong?

Hello @nktedo001 You need to define main function which k6 can run as default function where you can put all vus operations FormData and read files. See example below

import http from 'k6/http';
import { check, fail } from 'k6';
import { FormData } from 'https://jslib.k6.io/formdata/0.0.2/index.js';
import exec from 'k6/execution';
import { open } from 'k6/experimental/fs';


let EXCEL_FILE_BIN
let FILE

(async function () {
    FILE = await open('sample.pdf');
  })();

async function readAll(file) {
    const fileInfo = await file.stat();
    const buffer = new Uint8Array(fileInfo.size);

    const bytesRead = await file.read(buffer);
    if (bytesRead !== fileInfo.size) {
        throw new Error(
        'unexpected number of bytes read; expected ' +
            fileInfo.size +
            ' but got ' +
            bytesRead +
            ' bytes'
        );
    }
    return buffer;
}


export default async function () {
    EXCEL_FILE_BIN = await readAll(FILE);
    console.log(JSON.stringify(EXCEL_FILE_BIN));
    const form_data = new FormData()
    form_data.append('file', http.file(EXCEL_FILE_BIN, 'k6 test.xlsm', 'application/vnd.ms-excel.sheet.macroenabled.12'))
}

Also file extension changed to pdf but when using .xlsm error appear.

1 Like

Hey, thanks for the reply.

Oh, I should have clarified that using it in INIT stage is to prepare form data once and share it in the tests.

@nktedo001

You can try this way:

import http from 'k6/http';
import { FormData } from 'https://jslib.k6.io/formdata/0.0.2/index.js';
import { open } from 'k6/experimental/fs';

let EXCEL_FILE_BIN;
let FILE;
const form_data = new FormData();

async function readAll(file) {
  const fileInfo = await file.stat();
  const buffer = new Uint8Array(fileInfo.size);

  const bytesRead = await file.read(buffer);
  if (bytesRead !== fileInfo.size) {
    throw new Error(
      'unexpected number of bytes read; expected ' +
      fileInfo.size +
      ' but got ' +
      bytesRead +
      ' bytes'
    );
  }

  return buffer;
}

(async function () {
  FILE = await open('./test.xlsm');
  EXCEL_FILE_BIN = await readAll(FILE);
  form_data.append('file', http.file(EXCEL_FILE_BIN, 'k6 test.xlsm', 'application/vnd.ms-excel.sheet.macroenabled.12'))
})();

export default async function () {
  console.log(JSON.stringify(form_data));
}
3 Likes

Thank you!
This one worked.

With fs module k6 has now not exceeded memory usage!
Great job!