diff --git a/README.md b/README.md index 80d6227..e932e7a 100644 --- a/README.md +++ b/README.md @@ -1,10 +1,6 @@ # xk6-sse A [k6](https://go.k6.io/k6) extension for [Server-Sent Events (SSE)](https://en.wikipedia.org/wiki/Server-sent_events) using the [xk6](https://github.com/grafana/xk6) system. - -| /!\ This is a proof of concept, isn't supported by the k6 team, and may break in the future. USE AT YOUR OWN RISK! | -|--------------------------------------------------------------------------------------------------------------------| - See the [K6 SSE Extension design](docs/design/021-sse-api.md). ## k6 version @@ -36,30 +32,42 @@ xk6 build master \ ## Example ```javascript -import sse from "k6/x/sse"; -import {check} from "k6"; +import sse from "k6/x/sse" +import {check} from "k6" export default function () { - var url = "https://echo.websocket.org/.sse"; - var params = {"tags": {"my_tag": "hello"}}; - - var response = sse.open(url, params, function (client) { + const url = "https://echo.websocket.org/.sse" + const params = { + method: 'GET', + headers: { + "Authorization": "Bearer XXXX" + }, + tags: {"my_k6s_tag": "hello sse"} + } + + const response = sse.open(url, params, function (client) { client.on('open', function open() { - console.log('connected'); - }); + console.log('connected') + }) client.on('event', function (event) { - console.log(`event id=${event.id}, name=${event.name}, data=${event.data}`); - if (parseInt(event.id) === 10) { - client.close(); + console.log(`event id=${event.id}, name=${event.name}, data=${event.data}`) + if (parseInt(event.id) === 4) { + client.close() } - }); + }) client.on('error', function (e) { - console.log('An unexpected error occurred: ', e.error()); - }); - }); + console.log('An unexpected error occurred: ', e.error()) + }) + }) - check(response, {"status is 200": (r) => r && r.status === 200}); -}; + check(response, {"status is 200": (r) => r && r.status === 200}) +} ``` + +### License + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ \ No newline at end of file diff --git a/examples/sse.js b/examples/sse.js index 3dd1b30..97e859f 100644 --- a/examples/sse.js +++ b/examples/sse.js @@ -1,26 +1,32 @@ -import sse from "k6/x/sse"; -import {check} from "k6"; +import sse from "k6/x/sse" +import {check} from "k6" export default function () { - var url = "https://echo.websocket.org/.sse"; - var params = {"tags": {"my_tag": "hello"}}; + const url = "https://echo.websocket.org/.sse" + const params = { + method: 'GET', + headers: { + "Authorization": "Bearer XXXX" + }, + tags: {"my_k6s_tag": "hello sse"} + } - var response = sse.open(url, params, function (client) { - client.on('open', function open() { - console.log('connected'); - }); + const response = sse.open(url, params, function (client) { + client.on('open', function open() { + console.log('connected') + }) - client.on('event', function (event) { - console.log(`event id=${event.id}, name=${event.name}, data=${event.data}`); - if (parseInt(event.id) === 10) { - client.close(); - } - }); + client.on('event', function (event) { + console.log(`event id=${event.id}, name=${event.name}, data=${event.data}`) + if (parseInt(event.id) === 4) { + client.close() + } + }) - client.on('error', function (e) { - console.log('An unexpected error occurred: ', e.error()); - }); - }); + client.on('error', function (e) { + console.log('An unexpected error occurred: ', e.error()) + }) + }) - check(response, {"status is 200": (r) => r && r.status === 200}); -}; + check(response, {"status is 200": (r) => r && r.status === 200}) +} diff --git a/examples/sse_post.js b/examples/sse_post.js new file mode 100644 index 0000000..38adacd --- /dev/null +++ b/examples/sse_post.js @@ -0,0 +1,25 @@ +import sse from "k6/x/sse"; +import {check} from "k6"; + +export default function () { + const url = "https://echo.websocket.org/.sse"; + const params = { + method: 'POST', + body: '{"ping": true}', + headers: { + "content-type": "application/json", + "Authorization": "Bearer XXXX" + } + } + + const response = sse.open(url, params, function (client) { + client.on('event', function (event) { + console.log(`event id=${event.id}, name=${event.name}, data=${event.data}`); + if (parseInt(event.id) === 2) { + client.close() + } + }) + }) + + check(response, {"status is 200": (r) => r && r.status === 200}) +} diff --git a/sse.go b/sse.go index ae94b0c..6f27ebd 100644 --- a/sse.go +++ b/sse.go @@ -210,9 +210,12 @@ func (mi *sse) open(ctx context.Context, state *lib.State, return &sseClient, nil, err } - req.Header.Set("Cache-Control", "no-cache") req.Header.Set("Accept", "text/event-stream") - req.Header.Set("Connection", "keep-alive") + for headerName, headerValues := range args.headers { + for _, headerValue := range headerValues { + req.Header.Set(headerName, headerValue) + } + } // Wrap the request to retrieve the server IP tag trace := &httptrace.ClientTrace{ diff --git a/sse_test.go b/sse_test.go index 3780e4a..3f82890 100644 --- a/sse_test.go +++ b/sse_test.go @@ -184,7 +184,7 @@ func TestOpen(t *testing.T) { sr := test.tb.Replacer.Replace _, err := test.VU.Runtime().RunString(sr(` var events = []; - var res = sse.open("HTTPBIN_IP_URL/sse", {method: 'POST', body: '{"ping": true}'}, function(client){ + var res = sse.open("HTTPBIN_IP_URL/sse", {method: 'POST', body: '{"ping": true}', headers: {"content-type": "application/json", "Authorization": "Bearer XXXX"}}, function(client){ client.on("event", function(event) { events.push(event); }); @@ -293,7 +293,7 @@ func TestUserAgent(t *testing.T) { if (userAgent == undefined) { throw new Error("user agent is not echoed back by test server"); } - if (userAgent != "Go-http-client/1.1") { + if (userAgent != "TestUserAgent") { throw new Error("incorrect user agent: " + userAgent); } `)) @@ -392,6 +392,9 @@ func sseHandler(t testing.TB, generateErrors bool) http.Handler { _, _ = w.Write([]byte("junk\n")) } else { if req.Method == http.MethodPost { + assert.Equal(t, "application/json", req.Header.Get("Content-Type")) + assert.Equal(t, "Bearer XXXX", req.Header.Get("Authorization")) + body, err := io.ReadAll(req.Body) require.NoError(t, err) if `{"ping": true}` != string(body) { diff --git a/tests.sh b/tests.sh index 2ae5902..423915a 100755 --- a/tests.sh +++ b/tests.sh @@ -1,3 +1,9 @@ #!/bin/bash -xk6 build --with github.com/phymbert/xk6-sse=. && ./k6 run --vus 5 --duration 10s examples/sse.js \ No newline at end of file +set -eux + +xk6 build --with github.com/phymbert/xk6-sse=. +for script in examples/* +do + ./k6 run --vus 5 --duration 10s "${script}" +done \ No newline at end of file