We need some good, instructive and functional script examples
Imported from https://trello.com/c/Ft2pGnSe/93-scripting-examples
I'd like to see file upload examples 馃挴
@calvernaz I haven't tested but I add the example from a Slack support conversation.
import http from "k6/http";
let fput = open("acme.png");
export default function() {
var res = null;
res = http.batch([
{"method" : "PUT",
"url" : "https://requestb.in/11w2k1g1",
"body" : fput,
"params" : { headers: { "Content-Type" : "application/octet-strem"} }}
]);
return;
}
isn't the open function the window.open ? I think it is. That's how I end up doing it:
https://github.com/calvernaz/k6/blob/master/js/modules/k6/http/http.go#L368
We don't have a window object at all, since we're not a browser - the global open() function is instead available only in the init context (eg. outside of the default() function), and preloads the contents of a file.
By preloading all assets that will be used at runtime, we can guarantee constant performance (no disk IO congestion to bottleneck it), but can also pack up a whole test (including all requested resources) and send it to another machine - this is the basis of how clustering (#140) will work.
If you'd like to send a PR, the API I'd like to see would be something along the lines of:
import http from "k6/http";
// Preload the files.
let textdata = open("myfile.txt")
let pngdata = open("image.png")
export default function() {
k6.post("https://example.com/", {
// A normal form field; not an attachment.
"normal-field": "aaaaaa",
// A file; the presence of one makes the whole form a multipart body.
"myfile.txt": http.file(textdata, "text/plain"),
// If a MIME type isn't given, it's guessed, or defaults to octet-stream.
"image.png": http.file(pngdata),
})
}
Where http.file() simply returns a struct wrapper around the contents + MIME type, and the code that parses the request body does a v.Export().(type) check on each value to see if it's an instance of this struct.
We don't have a window object at all, since we're not a browser - the global open() function is instead available only in the init context (eg. outside of the default() function), and preloads the contents of a file.
Sorry, I misunderstood the open() function. I tried open a remote file and I was able to get the content, but for a local file I got this:
import http from "k6/http";
let fput = open("config.yml");
export default function() {}
ERRO[0000] GoError: Get https://config.yml?_k6=1: dial tcp: lookup config.yml: no such host
therefore my assumption.
I will give it a whirl for sure!
Ah, sorry, it's supposed to be open("./config.yml"). That error message really could use to be more descriptive.
Multipart is complex but can be coded like so:
bin1 = open("bin1.bin");
<snip>
export default function() {
http.batch([
{"method" : "POST", "url" : "https://web.somewhere.com/MMCCLoadTest/Telerik.Web.UI.WebResource.axd?type=rau", "body" : `
------WebKitFormBoundaryqHw9uCPWo96g1hQA
Content-Disposition: form-data; name="rauPostData"
ATTu5i4R+ViNFYO6kst0jC11wM/1iqH+W/isjhaDjNuCI7eJ/BY5d1E9eqZK27CJCMuon9u8/hgRIM/cTlgLlv4qOYjPBjs81Y3dAZAdtIr3TXiCmZi9M09a1BYMxjvGKfVky3b7PoOppeWS/3rglcF8wWZxbhVeaX6nnjb/2Gkrov6yenwO2WiScq7DnQZKLlkcS4dN+YiNXHgaJsxEEIHOjlZJsZSeyfk2gG/nD+9xl6xqADDDCJ7ScWKdXy4RetE6figpWNRJ4BCPQHtMD1IrO+TtFWQz0/ZVeMmZlYYQaPlgOul6BkBjRbzyH678RxKQA08ecYFdZAbJHwrQt7MpXJ+Wl7wHrA05LpNeE6e7jrwe7+f1oj/qZC085fAQTiilJTE2K+y9h+9gwUb/LY4ZB85epRVMIls2u2UnsAXqamQ37ol/mqX10O4P+TH7zaQfZGtCpDg0Tv1L3bs1eni/zRW+d4DdWI9W8AeseYrsmGntwN7hjUnwj4lG8dAG1J5p35G7EHkLdTPz4MGEUMnc9DSzoy6ON3tCkqR8Rc6bxOvCxJIxkWAnYS7zQazFbsiiXyF1fMDeSv+tyxkhIre0lsq9HlsyT8Qub9eso5dqKWgB1ZwFs5rPJAj2y5wk87Z5x2YHy05L3GKf3T0a1ReQrtxHyR0dbeodYV8is9AZ7mKoNPKpQAxMSg8YOMQjgkXoxovT3vlwcxnj3OOLeQlZKcyFOVmBAV26VHm8GB2x85CA8iIFQ8djFTywHrT8m0dEUumWTg++rOeecZFegOXotD6CPXofiqvrEvI3/EWB6znw+gy+VaJZR0lQpk30ODzG8dwt77brJK5o4StQTqcpqb757rdxfpfbDnpVN3HYuMDTcSkxXAgLY1nmH+5Vclju9SLbyZWhoebv0D8UbXVuM+YgMX17bJuQ8GLy4EDGoaLkO6ZsFLFSP95mn0JtgFDb4a0SZNqs/O9NcmQu237JIKsul18vSJlR6BC0x8p7DFbEm10K0w09JjDhjAD8Np1mX/jm+JfEnmYccuD2r4EkfYrpMB1UFLxlPnOut7mWGw/d8tcNW1PpX9RiPwUleEZTTD98TbaqLoDglNr3zNf4ULK147IGapvfVzim9K+pZkJn3yPVuZr6FoCg9/SoCg2aD8p+JQoupPOLGM1T3zq0zu801flAL/z9iRVsSkWCAStT9FCkkM6te52inetds//XxqQyqH3h/E9oaSqO/0rVxubVmcWVXhDr+1wnArCT+DOWyZfgst5wGylfyUNEKhmO+6lJW0wSz1UukfTX9ORrQaEsr9jyoY8KkPEr2exuXrCPGv22v7HUASpHRspnQcqysslLSzUYHsPtj9UbXWqq74vr3l9pLfxsJij2wnK0YG6apR1qRF+IMXRugbF1JSCpQcVQiIW6lsuSeX+q6YxB/YF6BILunZaMiSwzTtU=&6R/cGaqQeHVAzdJ9wTFOyCsrMSTtqcjLe8AHwiPckPDUwecnJyNlkDYwDQpxGYQ9hs6YxhupK310sbCbtXB4H6Dz5rGNL40nkkyo4j2clmRr08jtFsPQ0RpE5BGsulPT3l0MxyAvPFMs8bMybUyAP+9RB9LoHE3Xo8BqDadX3HQakpPfGtiDMp+wxkWRgaNpLTqLn39IBqaaMJdiQtd2eUoJD6UtFG7nTk0k75Ie47qzCVd7zOlFhYbqTgb/pbq7k52G5nCGZqAEHbgFWM44CtGMh3prePGBrSCP8VxwYPzuIcIyXouzxwdhS2YZtzBx/coQ1PFf4oC7N7an6igMqFKDaFHwzpDyZfbaSsQpWGA=
------WebKitFormBoundaryqHw9uCPWo96g1hQA
Content-Disposition: form-data; name="file"; filename="blob"
Content-Type: application/octet-stream
` + bin1 + `
------WebKitFormBoundaryqHw9uCPWo96g1hQA
Content-Disposition: form-data; name="fileName"
acme.png
------WebKitFormBoundaryqHw9uCPWo96g1hQA
Content-Disposition: form-data; name="contentType"
image/png
------WebKitFormBoundaryqHw9uCPWo96g1hQA
Content-Disposition: form-data; name="lastModifiedDate"
2016-05-31T13:33:27.707Z
------WebKitFormBoundaryqHw9uCPWo96g1hQA
Content-Disposition: form-data; name="metadata"
{\"TotalChunks\":1,\"ChunkIndex\":0,\"TotalFileSize\":4212,\"UploadID\":\"1479722200540acme.png\",\"IsSingleChunkUpload\":true}
------WebKitFormBoundaryqHw9uCPWo96g1hQA--`
, "params" : { headers: { "Content-Type" : "multipart/form-data; boundary=----WebKitFormBoundaryqHw9uCPWo96g1hQA"} }}
]);
}
It is a pain to keep track of the empty lines in the correct places though - but it works. Assuming open() would read a file binary some time in the near future and not be a string...
Added #269 for binary files