Skip to content

Commit

Permalink
Warn on not setting binarytype (#64)
Browse files Browse the repository at this point in the history
* Warn on not setting binarytype

This is the first part of #35.

But even if #35 is not finished after this warning is an error we can
safely move this extension in k6.
  • Loading branch information
mstoykov authored Apr 25, 2024
1 parent 7031d02 commit 0c7823e
Show file tree
Hide file tree
Showing 3 changed files with 43 additions and 9 deletions.
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ require (
github.com/dop251/goja v0.0.0-20230919151941-fc55792775de
github.com/gorilla/websocket v1.5.0
github.com/mstoykov/k6-taskqueue-lib v0.1.0
github.com/sirupsen/logrus v1.9.3
github.com/stretchr/testify v1.8.4
go.k6.io/k6 v0.47.1-0.20231012091148-de19a6a1bc53
go.uber.org/goleak v1.2.1
Expand Down Expand Up @@ -37,7 +38,6 @@ require (
github.com/onsi/gomega v1.20.2 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/serenize/snaker v0.0.0-20201027110005-a7ad2135616e // indirect
github.com/sirupsen/logrus v1.9.3 // indirect
github.com/spf13/afero v1.1.2 // indirect
github.com/tidwall/gjson v1.17.0 // indirect
github.com/tidwall/match v1.1.1 // indirect
Expand Down
28 changes: 24 additions & 4 deletions websockets/websockets.go
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ type webSocket struct {
// fields that should be seen by js only be updated on the event loop
readyState ReadyState
bufferedAmount int
binaryType string
}

type ping struct {
Expand Down Expand Up @@ -146,6 +147,11 @@ func parseURL(urlValue goja.Value) (*url.URL, error) {
return url, nil
}

const (
arraybufferBinaryType = "arraybuffer"
blobBinaryType = "blob"
)

// defineWebsocket defines all properties and methods for the WebSocket
func defineWebsocket(rt *goja.Runtime, w *webSocket) {
must(rt, w.obj.DefineDataProperty(
Expand All @@ -168,10 +174,17 @@ func defineWebsocket(rt *goja.Runtime, w *webSocket) {
// protocol
must(rt, w.obj.DefineAccessorProperty(
"binaryType", rt.ToValue(func() goja.Value {
return rt.ToValue("ArrayBuffer")
}), rt.ToValue(func() goja.Value {
common.Throw(rt, errors.New("binaryType is not settable in k6 as it doesn't support Blob"))
return nil // it never gets to here
return rt.ToValue(w.binaryType)
}), rt.ToValue(func(s string) error {
switch s {
case blobBinaryType:
return errors.New("blob is currently not supported, only arraybuffer is")
case arraybufferBinaryType:
w.binaryType = s
return nil
default:
return fmt.Errorf("unknown binaryType %s, the supported one is arraybuffer", s)
}
}), goja.FLAG_FALSE, goja.FLAG_TRUE))

setOn := func(property string, el *eventListener) {
Expand Down Expand Up @@ -382,6 +395,9 @@ func (w *webSocket) loop() {
}
}

const binarytypeWarning = `You have not set a Websocket binaryType to "arraybuffer", but you got a binary response. ` +
`This has been done automatically now, but in the future this will not work.`

func (w *webSocket) queueMessage(msg *message) {
w.tq.Queue(func() error {
if w.readyState != OPEN {
Expand All @@ -402,6 +418,10 @@ func (w *webSocket) queueMessage(msg *message) {
ev := w.newEvent(events.MESSAGE, msg.t)

if msg.mtype == websocket.BinaryMessage {
if w.binaryType == "" {
w.binaryType = arraybufferBinaryType
w.vu.State().Logger.Warn(binarytypeWarning)
}
// TODO this technically could be BLOB , but we don't support that
ab := rt.NewArrayBuffer(msg.data)
must(rt, ev.DefineDataProperty("data", rt.ToValue(ab), goja.FLAG_FALSE, goja.FLAG_FALSE, goja.FLAG_TRUE))
Expand Down
22 changes: 18 additions & 4 deletions websockets/websockets_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,15 @@ import (
"testing"

"github.com/gorilla/websocket"
"github.com/sirupsen/logrus"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"gopkg.in/guregu/null.v3"

httpModule "go.k6.io/k6/js/modules/k6/http"
"go.k6.io/k6/js/modulestest"
"go.k6.io/k6/lib"
"go.k6.io/k6/lib/testutils"
"go.k6.io/k6/lib/testutils/httpmultibin"
"go.k6.io/k6/metrics"
)
Expand Down Expand Up @@ -264,12 +266,21 @@ func TestReadyState(t *testing.T) {
func TestBinaryState(t *testing.T) {
t.Parallel()
ts := newTestState(t)
logger, hook := testutils.NewLoggerWithHook(t, logrus.WarnLevel)
ts.runtime.VU.StateField.Logger = logger
_, err := ts.runtime.RunOnEventLoop(ts.tb.Replacer.Replace(`
var ws = new WebSocket("WSBIN_URL/ws-echo")
ws.addEventListener("open", () => ws.close())
var ws = new WebSocket("WSBIN_URL/ws-echo-invalid")
ws.addEventListener("open", () => {
ws.send(new Uint8Array([164,41]).buffer)
ws.send("k6")
ws.onmessage = (e) => {
ws.close()
call(JSON.stringify(e))
}
})
if (ws.binaryType != "ArrayBuffer") {
throw new Error("Wrong binaryType value, expected ArrayBuffer got "+ ws.binaryType)
if (ws.binaryType != "") {
throw new Error("Wrong binaryType value, expected empty got "+ ws.binaryType)
}
var thrown = false;
Expand All @@ -283,6 +294,9 @@ func TestBinaryState(t *testing.T) {
}
`))
require.NoError(t, err)
logs := hook.Drain()
require.Len(t, logs, 1)
require.Contains(t, logs[0].Message, binarytypeWarning)
}

func TestExceptionDontPanic(t *testing.T) {
Expand Down

0 comments on commit 0c7823e

Please sign in to comment.