Best K6 code snippet using ws.newTestState
ws_test.go
Source:ws_test.go
...89 tb *httpmultibin.HTTPMultiBin90 state *lib.State91 samples chan metrics.SampleContainer92}93func newTestState(t testing.TB) testState {94 tb := httpmultibin.NewHTTPMultiBin(t)95 root, err := lib.NewGroup("", nil)96 require.NoError(t, err)97 rt := goja.New()98 rt.SetFieldNameMapper(common.FieldNameMapper{})99 samples := make(chan metrics.SampleContainer, 1000)100 state := &lib.State{101 Group: root,102 Dialer: tb.Dialer,103 Options: lib.Options{104 SystemTags: metrics.NewSystemTagSet(105 metrics.TagURL,106 metrics.TagProto,107 metrics.TagStatus,108 metrics.TagSubproto,109 ),110 UserAgent: null.StringFrom("TestUserAgent"),111 },112 Samples: samples,113 TLSConfig: tb.TLSClientConfig,114 BuiltinMetrics: metrics.RegisterBuiltinMetrics(metrics.NewRegistry()),115 Tags: lib.NewTagMap(nil),116 }117 m := New().NewModuleInstance(&modulestest.VU{118 CtxField: tb.Context,119 InitEnvField: &common.InitEnvironment{},120 RuntimeField: rt,121 StateField: state,122 })123 require.NoError(t, rt.Set("ws", m.Exports().Default))124 return testState{125 rt: rt,126 tb: tb,127 state: state,128 samples: samples,129 }130}131func TestSession(t *testing.T) {132 // TODO: split and paralelize tests133 t.Parallel()134 tb := httpmultibin.NewHTTPMultiBin(t)135 sr := tb.Replacer.Replace136 root, err := lib.NewGroup("", nil)137 require.NoError(t, err)138 rt := goja.New()139 rt.SetFieldNameMapper(common.FieldNameMapper{})140 samples := make(chan metrics.SampleContainer, 1000)141 state := &lib.State{142 Group: root,143 Dialer: tb.Dialer,144 Options: lib.Options{145 SystemTags: metrics.NewSystemTagSet(146 metrics.TagURL,147 metrics.TagProto,148 metrics.TagStatus,149 metrics.TagSubproto,150 ),151 },152 Samples: samples,153 TLSConfig: tb.TLSClientConfig,154 BuiltinMetrics: metrics.RegisterBuiltinMetrics(metrics.NewRegistry()),155 Tags: lib.NewTagMap(nil),156 }157 m := New().NewModuleInstance(&modulestest.VU{158 CtxField: context.Background(),159 InitEnvField: &common.InitEnvironment{},160 RuntimeField: rt,161 StateField: state,162 })163 require.NoError(t, rt.Set("ws", m.Exports().Default))164 t.Run("connect_ws", func(t *testing.T) {165 _, err := rt.RunString(sr(`166 var res = ws.connect("WSBIN_URL/ws-echo", function(socket){167 socket.close()168 });169 if (res.status != 101) { throw new Error("connection failed with status: " + res.status); }170 `))171 require.NoError(t, err)172 })173 assertSessionMetricsEmitted(t, metrics.GetBufferedSamples(samples), "", sr("WSBIN_URL/ws-echo"), statusProtocolSwitch, "")174 t.Run("connect_wss", func(t *testing.T) {175 _, err := rt.RunString(sr(`176 var res = ws.connect("WSSBIN_URL/ws-echo", function(socket){177 socket.close()178 });179 if (res.status != 101) { throw new Error("TLS connection failed with status: " + res.status); }180 `))181 require.NoError(t, err)182 })183 assertSessionMetricsEmitted(t, metrics.GetBufferedSamples(samples), "", sr("WSSBIN_URL/ws-echo"), statusProtocolSwitch, "")184 t.Run("open", func(t *testing.T) {185 _, err := rt.RunString(sr(`186 var opened = false;187 var res = ws.connect("WSBIN_URL/ws-echo", function(socket){188 socket.on("open", function() {189 opened = true;190 socket.close()191 })192 });193 if (!opened) { throw new Error ("open event not fired"); }194 `))195 require.NoError(t, err)196 })197 assertSessionMetricsEmitted(t, metrics.GetBufferedSamples(samples), "", sr("WSBIN_URL/ws-echo"), statusProtocolSwitch, "")198 t.Run("send_receive", func(t *testing.T) {199 _, err := rt.RunString(sr(`200 var res = ws.connect("WSBIN_URL/ws-echo", function(socket){201 socket.on("open", function() {202 socket.send("test")203 })204 socket.on("message", function (data) {205 if (!data=="test") {206 throw new Error ("echo'd data doesn't match our message!");207 }208 socket.close()209 });210 });211 `))212 require.NoError(t, err)213 })214 samplesBuf := metrics.GetBufferedSamples(samples)215 assertSessionMetricsEmitted(t, samplesBuf, "", sr("WSBIN_URL/ws-echo"), statusProtocolSwitch, "")216 assertMetricEmittedCount(t, metrics.WSMessagesSentName, samplesBuf, sr("WSBIN_URL/ws-echo"), 1)217 assertMetricEmittedCount(t, metrics.WSMessagesReceivedName, samplesBuf, sr("WSBIN_URL/ws-echo"), 1)218 t.Run("interval", func(t *testing.T) {219 _, err := rt.RunString(sr(`220 var counter = 0;221 var res = ws.connect("WSBIN_URL/ws-echo", function(socket){222 socket.setInterval(function () {223 counter += 1;224 if (counter > 2) { socket.close(); }225 }, 100);226 });227 if (counter < 3) {throw new Error ("setInterval should have been called at least 3 times, counter=" + counter);}228 `))229 require.NoError(t, err)230 })231 assertSessionMetricsEmitted(t, metrics.GetBufferedSamples(samples), "", sr("WSBIN_URL/ws-echo"), statusProtocolSwitch, "")232 t.Run("bad interval", func(t *testing.T) {233 _, err := rt.RunString(sr(`234 var counter = 0;235 var res = ws.connect("WSBIN_URL/ws-echo", function(socket){236 socket.setInterval(function () {237 counter += 1;238 if (counter > 2) { socket.close(); }239 }, -1.23);240 });241 `))242 require.Error(t, err)243 require.Contains(t, err.Error(), "setInterval requires a >0 timeout parameter, received -1.23 ")244 })245 t.Run("timeout", func(t *testing.T) {246 _, err := rt.RunString(sr(`247 var start = new Date().getTime();248 var ellapsed = new Date().getTime() - start;249 var res = ws.connect("WSBIN_URL/ws-echo", function(socket){250 socket.setTimeout(function () {251 ellapsed = new Date().getTime() - start;252 socket.close();253 }, 500);254 });255 if (ellapsed > 3000 || ellapsed < 500) {256 throw new Error ("setTimeout occurred after " + ellapsed + "ms, expected 500<T<3000");257 }258 `))259 require.NoError(t, err)260 })261 t.Run("bad timeout", func(t *testing.T) {262 _, err := rt.RunString(sr(`263 var start = new Date().getTime();264 var ellapsed = new Date().getTime() - start;265 var res = ws.connect("WSBIN_URL/ws-echo", function(socket){266 socket.setTimeout(function () {267 ellapsed = new Date().getTime() - start;268 socket.close();269 }, 0);270 });271 `))272 require.Error(t, err)273 require.Contains(t, err.Error(), "setTimeout requires a >0 timeout parameter, received 0.00 ")274 })275 assertSessionMetricsEmitted(t, metrics.GetBufferedSamples(samples), "", sr("WSBIN_URL/ws-echo"), statusProtocolSwitch, "")276 t.Run("ping", func(t *testing.T) {277 _, err := rt.RunString(sr(`278 var pongReceived = false;279 var res = ws.connect("WSBIN_URL/ws-echo", function(socket){280 socket.on("open", function(data) {281 socket.ping();282 });283 socket.on("pong", function() {284 pongReceived = true;285 socket.close();286 });287 socket.setTimeout(function (){socket.close();}, 3000);288 });289 if (!pongReceived) {290 throw new Error ("sent ping but didn't get pong back");291 }292 `))293 require.NoError(t, err)294 })295 samplesBuf = metrics.GetBufferedSamples(samples)296 assertSessionMetricsEmitted(t, samplesBuf, "", sr("WSBIN_URL/ws-echo"), statusProtocolSwitch, "")297 assertMetricEmittedCount(t, metrics.WSPingName, samplesBuf, sr("WSBIN_URL/ws-echo"), 1)298 t.Run("multiple_handlers", func(t *testing.T) {299 _, err := rt.RunString(sr(`300 var pongReceived = false;301 var otherPongReceived = false;302 var res = ws.connect("WSBIN_URL/ws-echo", function(socket){303 socket.on("open", function(data) {304 socket.ping();305 });306 socket.on("pong", function() {307 pongReceived = true;308 if (otherPongReceived) {309 socket.close();310 }311 });312 socket.on("pong", function() {313 otherPongReceived = true;314 if (pongReceived) {315 socket.close();316 }317 });318 socket.setTimeout(function (){socket.close();}, 3000);319 });320 if (!pongReceived || !otherPongReceived) {321 throw new Error ("sent ping but didn't get pong back");322 }323 `))324 require.NoError(t, err)325 })326 samplesBuf = metrics.GetBufferedSamples(samples)327 assertSessionMetricsEmitted(t, samplesBuf, "", sr("WSBIN_URL/ws-echo"), statusProtocolSwitch, "")328 assertMetricEmittedCount(t, metrics.WSPingName, samplesBuf, sr("WSBIN_URL/ws-echo"), 1)329 t.Run("client_close", func(t *testing.T) {330 _, err := rt.RunString(sr(`331 var closed = false;332 var res = ws.connect("WSBIN_URL/ws-echo", function(socket){333 socket.on("open", function() {334 socket.close()335 })336 socket.on("close", function() {337 closed = true;338 })339 });340 if (!closed) { throw new Error ("close event not fired"); }341 `))342 require.NoError(t, err)343 })344 assertSessionMetricsEmitted(t, metrics.GetBufferedSamples(samples), "", sr("WSBIN_URL/ws-echo"), statusProtocolSwitch, "")345 serverCloseTests := []struct {346 name string347 endpoint string348 }{349 {"server_close_ok", "/ws-echo"},350 // Ensure we correctly handle invalid WS server351 // implementations that close the connection prematurely352 // without sending a close control frame first.353 {"server_close_invalid", "/ws-close-invalid"},354 }355 for _, tc := range serverCloseTests {356 tc := tc357 t.Run(tc.name, func(t *testing.T) {358 _, err := rt.RunString(sr(fmt.Sprintf(`359 var closed = false;360 var res = ws.connect("WSBIN_URL%s", function(socket){361 socket.on("open", function() {362 socket.send("test");363 })364 socket.on("close", function() {365 closed = true;366 })367 });368 if (!closed) { throw new Error ("close event not fired"); }369 `, tc.endpoint)))370 require.NoError(t, err)371 })372 }373 t.Run("multi_message", func(t *testing.T) {374 t.Parallel()375 tb.Mux.HandleFunc("/ws-echo-multi", http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {376 conn, err := (&websocket.Upgrader{}).Upgrade(w, req, w.Header())377 if err != nil {378 return379 }380 for {381 messageType, r, e := conn.NextReader()382 if e != nil {383 return384 }385 var wc io.WriteCloser386 wc, err = conn.NextWriter(messageType)387 if err != nil {388 return389 }390 if _, err = io.Copy(wc, r); err != nil {391 return392 }393 if err = wc.Close(); err != nil {394 return395 }396 }397 }))398 t.Run("send_receive_multiple_ws", func(t *testing.T) {399 _, err := rt.RunString(sr(`400 var msg1 = "test1"401 var msg2 = "test2"402 var msg3 = "test3"403 var allMsgsRecvd = false404 var res = ws.connect("WSBIN_URL/ws-echo-multi", (socket) => {405 socket.on("open", () => {406 socket.send(msg1)407 })408 socket.on("message", (data) => {409 if (data == msg1){410 socket.send(msg2)411 }412 if (data == msg2){413 socket.send(msg3)414 }415 if (data == msg3){416 allMsgsRecvd = true417 socket.close()418 }419 });420 });421 if (!allMsgsRecvd) {422 throw new Error ("messages 1,2,3 in sequence, was not received from server");423 }424 `))425 require.NoError(t, err)426 })427 samplesBuf = metrics.GetBufferedSamples(samples)428 assertSessionMetricsEmitted(t, samplesBuf, "", sr("WSBIN_URL/ws-echo-multi"), statusProtocolSwitch, "")429 assertMetricEmittedCount(t, metrics.WSMessagesSentName, samplesBuf, sr("WSBIN_URL/ws-echo-multi"), 3)430 assertMetricEmittedCount(t, metrics.WSMessagesReceivedName, samplesBuf, sr("WSBIN_URL/ws-echo-multi"), 3)431 t.Run("send_receive_multiple_wss", func(t *testing.T) {432 _, err := rt.RunString(sr(`433 var msg1 = "test1"434 var msg2 = "test2"435 var secondMsgReceived = false436 var res = ws.connect("WSSBIN_URL/ws-echo-multi", (socket) => {437 socket.on("open", () => {438 socket.send(msg1)439 })440 socket.on("message", (data) => {441 if (data == msg1){442 socket.send(msg2)443 }444 if (data == msg2){445 secondMsgReceived = true446 socket.close()447 }448 });449 });450 if (!secondMsgReceived) {451 throw new Error ("second test message was not received from server!");452 }453 `))454 require.NoError(t, err)455 })456 samplesBuf = metrics.GetBufferedSamples(samples)457 assertSessionMetricsEmitted(t, samplesBuf, "", sr("WSSBIN_URL/ws-echo-multi"), statusProtocolSwitch, "")458 assertMetricEmittedCount(t, metrics.WSMessagesSentName, samplesBuf, sr("WSSBIN_URL/ws-echo-multi"), 2)459 assertMetricEmittedCount(t, metrics.WSMessagesReceivedName, samplesBuf, sr("WSSBIN_URL/ws-echo-multi"), 2)460 t.Run("send_receive_text_binary", func(t *testing.T) {461 _, err := rt.RunString(sr(`462 var msg1 = "test1"463 var msg2 = new Uint8Array([116, 101, 115, 116, 50]); // 'test2'464 var secondMsgReceived = false465 var res = ws.connect("WSBIN_URL/ws-echo-multi", (socket) => {466 socket.on("open", () => {467 socket.send(msg1)468 })469 socket.on("message", (data) => {470 if (data == msg1){471 socket.sendBinary(msg2.buffer)472 }473 });474 socket.on("binaryMessage", (data) => {475 let data2 = new Uint8Array(data)476 if(JSON.stringify(msg2) == JSON.stringify(data2)){477 secondMsgReceived = true478 }479 socket.close()480 })481 });482 if (!secondMsgReceived) {483 throw new Error ("second test message was not received from server!");484 }485 `))486 require.NoError(t, err)487 })488 samplesBuf = metrics.GetBufferedSamples(samples)489 assertSessionMetricsEmitted(t, samplesBuf, "", sr("WSBIN_URL/ws-echo-multi"), statusProtocolSwitch, "")490 assertMetricEmittedCount(t, metrics.WSMessagesSentName, samplesBuf, sr("WSBIN_URL/ws-echo-multi"), 2)491 assertMetricEmittedCount(t, metrics.WSMessagesReceivedName, samplesBuf, sr("WSBIN_URL/ws-echo-multi"), 2)492 })493}494func TestSocketSendBinary(t *testing.T) { //nolint: tparallel495 t.Parallel()496 tb := httpmultibin.NewHTTPMultiBin(t)497 sr := tb.Replacer.Replace498 root, err := lib.NewGroup("", nil)499 require.NoError(t, err)500 rt := goja.New()501 rt.SetFieldNameMapper(common.FieldNameMapper{})502 samples := make(chan metrics.SampleContainer, 1000)503 state := &lib.State{ //nolint: exhaustivestruct504 Group: root,505 Dialer: tb.Dialer,506 Options: lib.Options{ //nolint: exhaustivestruct507 SystemTags: metrics.NewSystemTagSet(508 metrics.TagURL,509 metrics.TagProto,510 metrics.TagStatus,511 metrics.TagSubproto,512 ),513 },514 Samples: samples,515 TLSConfig: tb.TLSClientConfig,516 BuiltinMetrics: metrics.RegisterBuiltinMetrics(metrics.NewRegistry()),517 Tags: lib.NewTagMap(nil),518 }519 m := New().NewModuleInstance(&modulestest.VU{520 CtxField: context.Background(),521 InitEnvField: &common.InitEnvironment{},522 RuntimeField: rt,523 StateField: state,524 })525 require.NoError(t, rt.Set("ws", m.Exports().Default))526 t.Run("ok", func(t *testing.T) {527 _, err = rt.RunString(sr(`528 var gotMsg = false;529 var res = ws.connect('WSBIN_URL/ws-echo', function(socket){530 var data = new Uint8Array([104, 101, 108, 108, 111]); // 'hello'531 socket.on('open', function() {532 socket.sendBinary(data.buffer);533 })534 socket.on('binaryMessage', function(msg) {535 gotMsg = true;536 let decText = String.fromCharCode.apply(null, new Uint8Array(msg));537 decText = decodeURIComponent(escape(decText));538 if (decText !== 'hello') {539 throw new Error('received unexpected binary message: ' + decText);540 }541 socket.close()542 });543 });544 if (!gotMsg) {545 throw new Error("the 'binaryMessage' handler wasn't called")546 }547 `))548 require.NoError(t, err)549 })550 errTestCases := []struct {551 in, expErrType string552 }{553 {"", ""},554 {"undefined", "undefined"},555 {"null", "null"},556 {"true", "Boolean"},557 {"1", "Number"},558 {"3.14", "Number"},559 {"'str'", "String"},560 {"[1, 2, 3]", "Array"},561 {"new Uint8Array([1, 2, 3])", "Object"},562 {"Symbol('a')", "Symbol"},563 {"function() {}", "Function"},564 }565 for _, tc := range errTestCases { //nolint: paralleltest566 tc := tc567 t.Run(fmt.Sprintf("err_%s", tc.expErrType), func(t *testing.T) {568 _, err = rt.RunString(fmt.Sprintf(sr(`569 var res = ws.connect('WSBIN_URL/ws-echo', function(socket){570 socket.on('open', function() {571 socket.sendBinary(%s);572 })573 });574 `), tc.in))575 require.Error(t, err)576 if tc.in == "" {577 assert.Contains(t, err.Error(), "missing argument, expected ArrayBuffer")578 } else {579 assert.Contains(t, err.Error(), fmt.Sprintf("expected ArrayBuffer as argument, received: %s", tc.expErrType))580 }581 })582 }583}584func TestErrors(t *testing.T) {585 t.Parallel()586 tb := httpmultibin.NewHTTPMultiBin(t)587 sr := tb.Replacer.Replace588 root, err := lib.NewGroup("", nil)589 require.NoError(t, err)590 rt := goja.New()591 rt.SetFieldNameMapper(common.FieldNameMapper{})592 samples := make(chan metrics.SampleContainer, 1000)593 state := &lib.State{594 Group: root,595 Dialer: tb.Dialer,596 Options: lib.Options{597 SystemTags: &metrics.DefaultSystemTagSet,598 },599 Samples: samples,600 BuiltinMetrics: metrics.RegisterBuiltinMetrics(metrics.NewRegistry()),601 Tags: lib.NewTagMap(nil),602 }603 m := New().NewModuleInstance(&modulestest.VU{604 CtxField: context.Background(),605 InitEnvField: &common.InitEnvironment{},606 RuntimeField: rt,607 StateField: state,608 })609 require.NoError(t, rt.Set("ws", m.Exports().Default))610 t.Run("invalid_url", func(t *testing.T) {611 _, err := rt.RunString(`612 var res = ws.connect("INVALID", function(socket){613 socket.on("open", function() {614 socket.close();615 });616 });617 `)618 assert.Error(t, err)619 })620 t.Run("invalid_url_message_panic", func(t *testing.T) {621 // Attempting to send a message to a non-existent socket shouldn't panic622 _, err := rt.RunString(`623 var res = ws.connect("INVALID", function(socket){624 socket.send("new message");625 });626 `)627 assert.Error(t, err)628 })629 t.Run("error_in_setup", func(t *testing.T) {630 _, err := rt.RunString(sr(`631 var res = ws.connect("WSBIN_URL/ws-echo-invalid", function(socket){632 throw new Error("error in setup");633 });634 `))635 assert.Error(t, err)636 })637 t.Run("send_after_close", func(t *testing.T) {638 _, err := rt.RunString(sr(`639 var hasError = false;640 var res = ws.connect("WSBIN_URL/ws-echo-invalid", function(socket){641 socket.on("open", function() {642 socket.close();643 socket.send("test");644 });645 socket.on("error", function(errorEvent) {646 hasError = true;647 });648 });649 if (!hasError) {650 throw new Error ("no error emitted for send after close");651 }652 `))653 require.NoError(t, err)654 assertSessionMetricsEmitted(t, metrics.GetBufferedSamples(samples), "", sr("WSBIN_URL/ws-echo-invalid"), statusProtocolSwitch, "")655 })656 t.Run("error on close", func(t *testing.T) {657 _, err := rt.RunString(sr(`658 var closed = false;659 var res = ws.connect("WSBIN_URL/ws-close", function(socket){660 socket.on('open', function open() {661 socket.setInterval(function timeout() {662 socket.ping();663 }, 1000);664 });665 socket.on("ping", function() {666 socket.close();667 });668 socket.on("error", function(errorEvent) {669 if (errorEvent == null) {670 throw new Error(JSON.stringify(errorEvent));671 }672 if (!closed) {673 closed = true;674 socket.close();675 }676 });677 });678 `))679 require.NoError(t, err)680 assertSessionMetricsEmitted(t, metrics.GetBufferedSamples(samples), "", sr("WSBIN_URL/ws-close"), statusProtocolSwitch, "")681 })682}683func TestSystemTags(t *testing.T) {684 tb := httpmultibin.NewHTTPMultiBin(t)685 sr := tb.Replacer.Replace686 root, err := lib.NewGroup("", nil)687 require.NoError(t, err)688 rt := goja.New()689 rt.SetFieldNameMapper(common.FieldNameMapper{})690 // TODO: test for actual tag values after removing the dependency on the691 // external service demos.kaazing.com (https://github.com/k6io/k6/issues/537)692 testedSystemTags := []string{"group", "status", "subproto", "url", "ip"}693 samples := make(chan metrics.SampleContainer, 1000)694 state := &lib.State{695 Group: root,696 Dialer: tb.Dialer,697 Options: lib.Options{SystemTags: metrics.ToSystemTagSet(testedSystemTags)},698 Samples: samples,699 TLSConfig: tb.TLSClientConfig,700 BuiltinMetrics: metrics.RegisterBuiltinMetrics(metrics.NewRegistry()),701 Tags: lib.NewTagMap(nil),702 }703 m := New().NewModuleInstance(&modulestest.VU{704 CtxField: context.Background(),705 InitEnvField: &common.InitEnvironment{},706 RuntimeField: rt,707 StateField: state,708 })709 require.NoError(t, rt.Set("ws", m.Exports().Default))710 for _, expectedTag := range testedSystemTags {711 expectedTag := expectedTag712 t.Run("only "+expectedTag, func(t *testing.T) {713 state.Options.SystemTags = metrics.ToSystemTagSet([]string{expectedTag})714 _, err := rt.RunString(sr(`715 var res = ws.connect("WSBIN_URL/ws-echo", function(socket){716 socket.on("open", function() {717 socket.send("test")718 })719 socket.on("message", function (data){720 if (!data=="test") {721 throw new Error ("echo'd data doesn't match our message!");722 }723 socket.close()724 });725 });726 `))727 require.NoError(t, err)728 for _, sampleContainer := range metrics.GetBufferedSamples(samples) {729 for _, sample := range sampleContainer.GetSamples() {730 for emittedTag := range sample.Tags.CloneTags() {731 assert.Equal(t, expectedTag, emittedTag)732 }733 }734 }735 })736 }737}738func TestTLSConfig(t *testing.T) {739 root, err := lib.NewGroup("", nil)740 require.NoError(t, err)741 tb := httpmultibin.NewHTTPMultiBin(t)742 sr := tb.Replacer.Replace743 rt := goja.New()744 rt.SetFieldNameMapper(common.FieldNameMapper{})745 samples := make(chan metrics.SampleContainer, 1000)746 state := &lib.State{747 Group: root,748 Dialer: tb.Dialer,749 Options: lib.Options{750 SystemTags: metrics.NewSystemTagSet(751 metrics.TagURL,752 metrics.TagProto,753 metrics.TagStatus,754 metrics.TagSubproto,755 metrics.TagIP,756 ),757 },758 Samples: samples,759 BuiltinMetrics: metrics.RegisterBuiltinMetrics(metrics.NewRegistry()),760 Tags: lib.NewTagMap(nil),761 }762 m := New().NewModuleInstance(&modulestest.VU{763 CtxField: context.Background(),764 InitEnvField: &common.InitEnvironment{},765 RuntimeField: rt,766 StateField: state,767 })768 require.NoError(t, rt.Set("ws", m.Exports().Default))769 t.Run("insecure skip verify", func(t *testing.T) {770 state.TLSConfig = &tls.Config{771 InsecureSkipVerify: true,772 }773 _, err := rt.RunString(sr(`774 var res = ws.connect("WSSBIN_URL/ws-close", function(socket){775 socket.close()776 });777 if (res.status != 101) { throw new Error("TLS connection failed with status: " + res.status); }778 `))779 require.NoError(t, err)780 })781 assertSessionMetricsEmitted(t, metrics.GetBufferedSamples(samples), "", sr("WSSBIN_URL/ws-close"), statusProtocolSwitch, "")782 t.Run("custom certificates", func(t *testing.T) {783 state.TLSConfig = tb.TLSClientConfig784 _, err := rt.RunString(sr(`785 var res = ws.connect("WSSBIN_URL/ws-close", function(socket){786 socket.close()787 });788 if (res.status != 101) {789 throw new Error("TLS connection failed with status: " + res.status);790 }791 `))792 require.NoError(t, err)793 })794 assertSessionMetricsEmitted(t, metrics.GetBufferedSamples(samples), "", sr("WSSBIN_URL/ws-close"), statusProtocolSwitch, "")795}796func TestReadPump(t *testing.T) {797 var closeCode int798 srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {799 conn, err := (&websocket.Upgrader{}).Upgrade(w, r, w.Header())800 require.NoError(t, err)801 closeMsg := websocket.FormatCloseMessage(closeCode, "")802 _ = conn.WriteControl(websocket.CloseMessage, closeMsg, time.Now().Add(time.Second))803 }))804 defer srv.Close()805 closeCodes := []int{websocket.CloseNormalClosure, websocket.CloseGoingAway, websocket.CloseInternalServerErr}806 numAsserts := 0807 srvURL := "ws://" + srv.Listener.Addr().String()808 // Ensure readPump returns the response close code sent by the server809 for _, code := range closeCodes {810 code := code811 t.Run(strconv.Itoa(code), func(t *testing.T) {812 closeCode = code813 conn, resp, err := websocket.DefaultDialer.Dial(srvURL, nil)814 require.NoError(t, err)815 defer func() {816 _ = resp.Body.Close()817 _ = conn.Close()818 }()819 msgChan := make(chan *message)820 errChan := make(chan error)821 closeChan := make(chan int)822 s := &Socket{conn: conn}823 go s.readPump(msgChan, errChan, closeChan)824 readChans:825 for {826 select {827 case responseCode := <-closeChan:828 assert.Equal(t, code, responseCode)829 numAsserts++830 break readChans831 case <-errChan:832 continue833 case <-time.After(time.Second):834 t.Errorf("Read timed out")835 break readChans836 }837 }838 })839 }840 // Ensure all close code asserts passed841 assert.Equal(t, numAsserts, len(closeCodes))842}843func TestUserAgent(t *testing.T) {844 t.Parallel()845 tb := httpmultibin.NewHTTPMultiBin(t)846 sr := tb.Replacer.Replace847 tb.Mux.HandleFunc("/ws-echo-useragent", http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {848 // Echo back User-Agent header if it exists849 responseHeaders := w.Header().Clone()850 if ua := req.Header.Get("User-Agent"); ua != "" {851 responseHeaders.Add("Echo-User-Agent", req.Header.Get("User-Agent"))852 }853 conn, err := (&websocket.Upgrader{}).Upgrade(w, req, responseHeaders)854 if err != nil {855 t.Fatalf("/ws-echo-useragent cannot upgrade request: %v", err)856 return857 }858 err = conn.Close()859 if err != nil {860 t.Logf("error while closing connection in /ws-echo-useragent: %v", err)861 return862 }863 }))864 root, err := lib.NewGroup("", nil)865 require.NoError(t, err)866 rt := goja.New()867 rt.SetFieldNameMapper(common.FieldNameMapper{})868 samples := make(chan metrics.SampleContainer, 1000)869 state := &lib.State{870 Group: root,871 Dialer: tb.Dialer,872 Options: lib.Options{873 SystemTags: metrics.NewSystemTagSet(874 metrics.TagURL,875 metrics.TagProto,876 metrics.TagStatus,877 metrics.TagSubproto,878 ),879 UserAgent: null.StringFrom("TestUserAgent"),880 },881 Samples: samples,882 TLSConfig: tb.TLSClientConfig,883 BuiltinMetrics: metrics.RegisterBuiltinMetrics(metrics.NewRegistry()),884 Tags: lib.NewTagMap(nil),885 }886 m := New().NewModuleInstance(&modulestest.VU{887 CtxField: context.Background(),888 InitEnvField: &common.InitEnvironment{},889 RuntimeField: rt,890 StateField: state,891 })892 require.NoError(t, rt.Set("ws", m.Exports().Default))893 // websocket handler should echo back User-Agent as Echo-User-Agent for this test to work894 _, err = rt.RunString(sr(`895 var res = ws.connect("WSBIN_URL/ws-echo-useragent", function(socket){896 socket.close()897 })898 var userAgent = res.headers["Echo-User-Agent"];899 if (userAgent == undefined) {900 throw new Error("user agent is not echoed back by test server");901 }902 if (userAgent != "TestUserAgent") {903 throw new Error("incorrect user agent: " + userAgent);904 }905 `))906 require.NoError(t, err)907 assertSessionMetricsEmitted(t, metrics.GetBufferedSamples(samples), "", sr("WSBIN_URL/ws-echo-useragent"), statusProtocolSwitch, "")908}909func TestCompression(t *testing.T) {910 t.Parallel()911 t.Run("session", func(t *testing.T) {912 t.Parallel()913 const text string = `Lorem ipsum dolor sit amet, consectetur adipiscing elit. Maecenas sed pharetra sapien. Nunc laoreet molestie ante ac gravida. Etiam interdum dui viverra posuere egestas. Pellentesque at dolor tristique, mattis turpis eget, commodo purus. Nunc orci aliquam.`914 ts := newTestState(t)915 sr := ts.tb.Replacer.Replace916 ts.tb.Mux.HandleFunc("/ws-compression", http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {917 upgrader := websocket.Upgrader{918 EnableCompression: true,919 ReadBufferSize: 1024,920 WriteBufferSize: 1024,921 }922 conn, e := upgrader.Upgrade(w, req, w.Header())923 if e != nil {924 t.Fatalf("/ws-compression cannot upgrade request: %v", e)925 return926 }927 // send a message and exit928 if e = conn.WriteMessage(websocket.TextMessage, []byte(text)); e != nil {929 t.Logf("error while sending message in /ws-compression: %v", e)930 return931 }932 e = conn.Close()933 if e != nil {934 t.Logf("error while closing connection in /ws-compression: %v", e)935 return936 }937 }))938 _, err := ts.rt.RunString(sr(`939 // if client supports compression, it has to send the header940 // 'Sec-Websocket-Extensions:permessage-deflate; server_no_context_takeover; client_no_context_takeover' to server.941 // if compression is negotiated successfully, server will reply with header942 // 'Sec-Websocket-Extensions:permessage-deflate; server_no_context_takeover; client_no_context_takeover'943 var params = {944 "compression": "deflate"945 }946 var res = ws.connect("WSBIN_URL/ws-compression", params, function(socket){947 socket.on('message', (data) => {948 if(data != "` + text + `"){949 throw new Error("wrong message received from server: ", data)950 }951 socket.close()952 })953 });954 var wsExtensions = res.headers["Sec-Websocket-Extensions"].split(';').map(e => e.trim())955 if (!(wsExtensions.includes("permessage-deflate") && wsExtensions.includes("server_no_context_takeover") && wsExtensions.includes("client_no_context_takeover"))){956 throw new Error("websocket compression negotiation failed");957 }958 `))959 require.NoError(t, err)960 assertSessionMetricsEmitted(t, metrics.GetBufferedSamples(ts.samples), "", sr("WSBIN_URL/ws-compression"), statusProtocolSwitch, "")961 })962 t.Run("params", func(t *testing.T) {963 t.Parallel()964 testCases := []struct {965 compression string966 expectedError string967 }{968 {compression: ""},969 {compression: " "},970 {compression: "deflate"},971 {compression: "deflate "},972 {973 compression: "gzip",974 expectedError: `unsupported compression algorithm 'gzip', supported algorithm is 'deflate'`,975 },976 {977 compression: "deflate, gzip",978 expectedError: `unsupported compression algorithm 'deflate, gzip', supported algorithm is 'deflate'`,979 },980 {981 compression: "deflate, deflate",982 expectedError: `unsupported compression algorithm 'deflate, deflate', supported algorithm is 'deflate'`,983 },984 {985 compression: "deflate, ",986 expectedError: `unsupported compression algorithm 'deflate,', supported algorithm is 'deflate'`,987 },988 }989 for _, testCase := range testCases {990 testCase := testCase991 t.Run(testCase.compression, func(t *testing.T) {992 t.Parallel()993 ts := newTestState(t)994 sr := ts.tb.Replacer.Replace995 ts.tb.Mux.HandleFunc("/ws-compression-param", http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {996 upgrader := websocket.Upgrader{997 EnableCompression: true,998 ReadBufferSize: 1024,999 WriteBufferSize: 1024,1000 }1001 conn, e := upgrader.Upgrade(w, req, w.Header())1002 if e != nil {1003 t.Fatalf("/ws-compression-param cannot upgrade request: %v", e)1004 return1005 }1006 e = conn.Close()1007 if e != nil {1008 t.Logf("error while closing connection in /ws-compression-param: %v", e)1009 return1010 }1011 }))1012 _, err := ts.rt.RunString(sr(`1013 var res = ws.connect("WSBIN_URL/ws-compression-param", {"compression":"` + testCase.compression + `"}, function(socket){1014 socket.close()1015 });1016 `))1017 if testCase.expectedError == "" {1018 require.NoError(t, err)1019 } else {1020 require.Error(t, err)1021 require.Contains(t, err.Error(), testCase.expectedError)1022 }1023 })1024 }1025 })1026}1027func clearSamples(tb *httpmultibin.HTTPMultiBin, samples chan metrics.SampleContainer) {1028 ctxDone := tb.Context.Done()1029 for {1030 select {1031 case <-samples:1032 case <-ctxDone:1033 return1034 }1035 }1036}1037func BenchmarkCompression(b *testing.B) {1038 const textMessage = 11039 ts := newTestState(b)1040 sr := ts.tb.Replacer.Replace1041 go clearSamples(ts.tb, ts.samples)1042 testCodes := []string{1043 sr(`1044 var res = ws.connect("WSBIN_URL/ws-compression", {"compression":"deflate"}, (socket) => {1045 socket.on('message', (data) => {1046 socket.close()1047 })1048 });1049 `),1050 sr(`1051 var res = ws.connect("WSBIN_URL/ws-compression", {}, (socket) => {1052 socket.on('message', (data) => {1053 socket.close()1054 })1055 });1056 `),1057 }1058 ts.tb.Mux.HandleFunc("/ws-compression", http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {1059 kbData := bytes.Repeat([]byte("0123456789"), 100)1060 // upgrade connection, send the first (long) message, disconnect1061 upgrader := websocket.Upgrader{1062 EnableCompression: true,1063 ReadBufferSize: 1024,1064 WriteBufferSize: 1024,1065 }1066 conn, e := upgrader.Upgrade(w, req, w.Header())1067 if e != nil {1068 b.Fatalf("/ws-compression cannot upgrade request: %v", e)1069 return1070 }1071 if e = conn.WriteMessage(textMessage, kbData); e != nil {1072 b.Fatalf("/ws-compression cannot write message: %v", e)1073 return1074 }1075 e = conn.Close()1076 if e != nil {1077 b.Logf("error while closing connection in /ws-compression: %v", e)1078 return1079 }1080 }))1081 b.ResetTimer()1082 b.Run("compression-enabled", func(b *testing.B) {1083 for i := 0; i < b.N; i++ {1084 if _, err := ts.rt.RunString(testCodes[0]); err != nil {1085 b.Error(err)1086 }1087 }1088 })1089 b.Run("compression-disabled", func(b *testing.B) {1090 for i := 0; i < b.N; i++ {1091 if _, err := ts.rt.RunString(testCodes[1]); err != nil {1092 b.Error(err)1093 }1094 }1095 })1096}1097func TestCookieJar(t *testing.T) {1098 t.Parallel()1099 ts := newTestState(t)1100 sr := ts.tb.Replacer.Replace1101 ts.tb.Mux.HandleFunc("/ws-echo-someheader", http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {1102 responseHeaders := w.Header().Clone()1103 if sh, err := req.Cookie("someheader"); err == nil {1104 responseHeaders.Add("Echo-Someheader", sh.Value)1105 }1106 conn, err := (&websocket.Upgrader{}).Upgrade(w, req, responseHeaders)1107 if err != nil {1108 t.Fatalf("/ws-echo-someheader cannot upgrade request: %v", err)1109 }1110 err = conn.Close()1111 if err != nil {1112 t.Logf("error while closing connection in /ws-echo-someheader: %v", err)1113 }...
websockets_test.go
Source:websockets_test.go
...50 state *lib.State51 samples chan metrics.SampleContainer52 ev *eventloop.EventLoop53}54func newTestState(t testing.TB) testState {55 tb := httpmultibin.NewHTTPMultiBin(t)56 root, err := lib.NewGroup("", nil)57 require.NoError(t, err)58 rt := goja.New()59 rt.SetFieldNameMapper(common.FieldNameMapper{})60 samples := make(chan metrics.SampleContainer, 1000)61 state := &lib.State{62 Group: root,63 Dialer: tb.Dialer,64 Options: lib.Options{65 SystemTags: metrics.NewSystemTagSet(66 metrics.TagURL,67 metrics.TagProto,68 metrics.TagStatus,69 metrics.TagSubproto,70 ),71 UserAgent: null.StringFrom("TestUserAgent"),72 },73 Samples: samples,74 TLSConfig: tb.TLSClientConfig,75 BuiltinMetrics: metrics.RegisterBuiltinMetrics(metrics.NewRegistry()),76 Tags: lib.NewTagMap(nil),77 }78 vu := &modulestest.VU{79 CtxField: tb.Context,80 InitEnvField: &common.InitEnvironment{},81 RuntimeField: rt,82 StateField: state,83 }84 m := new(RootModule).NewModuleInstance(vu)85 require.NoError(t, rt.Set("WebSocket", m.Exports().Named["WebSocket"]))86 ev := eventloop.New(vu)87 vu.RegisterCallbackField = ev.RegisterCallback88 return testState{89 rt: rt,90 tb: tb,91 state: state,92 samples: samples,93 ev: ev,94 }95}96func TestBasic(t *testing.T) {97 t.Parallel()98 ts := newTestState(t)99 sr := ts.tb.Replacer.Replace100 err := ts.ev.Start(func() error {101 _, err := ts.rt.RunString(sr(`102 var ws = new WebSocket("WSBIN_URL/ws-echo")103 ws.addEventListener("open", () => {104 ws.send("something")105 ws.close()106 })107 `))108 return err109 })110 require.NoError(t, err)111 samples := metrics.GetBufferedSamples(ts.samples)112 assertSessionMetricsEmitted(t, samples, "", sr("WSBIN_URL/ws-echo"), http.StatusSwitchingProtocols, "")113}114func TestReadyState(t *testing.T) {115 t.Parallel()116 ts := newTestState(t)117 err := ts.ev.Start(func() error {118 _, err := ts.rt.RunString(ts.tb.Replacer.Replace(`119 var ws = new WebSocket("WSBIN_URL/ws-echo")120 ws.addEventListener("open", () => {121 if (ws.readyState != 1){122 throw new Error("Expected ready state 1 got "+ ws.readyState)123 }124 ws.addEventListener("close", () => {125 if (ws.readyState != 3){126 throw new Error("Expected ready state 3 got "+ ws.readyState)127 }128 })129 ws.send("something")130 ws.close()131 })132 if (ws.readyState != 0){133 throw new Error("Expected ready state 0 got "+ ws.readyState)134 }135 `))136 return err137 })138 require.NoError(t, err)139}140func TestBinaryState(t *testing.T) {141 t.Parallel()142 ts := newTestState(t)143 err := ts.ev.Start(func() error {144 _, err := ts.rt.RunString(ts.tb.Replacer.Replace(`145 var ws = new WebSocket("WSBIN_URL/ws-echo")146 ws.addEventListener("open", () => ws.close())147 if (ws.binaryType != "ArrayBuffer") {148 throw new Error("Wrong binaryType value, expected ArrayBuffer got "+ ws.binaryType)149 }150 var thrown = false;151 try {152 ws.binaryType = "something"153 } catch(e) {154 thrown = true155 }156 if (!thrown) {157 throw new Error("Expects ws.binaryType to not be writable")158 }159 `))160 return err161 })162 require.NoError(t, err)163}164func TestExceptionDontPanic(t *testing.T) {165 t.Parallel()166 cases := map[string]struct {167 script, expectedError string168 }{169 "open": {170 script: `171 var ws = new WebSocket("WSBIN_URL/ws/echo")172 ws.addEventListener("open", () => {173 oops174 })`,175 expectedError: "oops is not defined at <eval>:4:7",176 },177 "error": {178 script: `179 var ws = new WebSocket("WSBIN_URL/badurl")180 ws.addEventListener("error", ()=>{181 inerroridf182 })183 `,184 expectedError: "inerroridf is not defined at <eval>:4:7",185 },186 "close": {187 script: `188 var ws = new WebSocket("WSBIN_URL/ws/echo")189 ws.addEventListener("open", () => {190 ws.close()191 })192 ws.addEventListener("close", ()=>{193 incloseidf194 })`,195 expectedError: "incloseidf is not defined at <eval>:7:7",196 },197 "message": {198 script: `199 var ws = new WebSocket("WSBIN_URL/ws/echo")200 ws.addEventListener("open", () => {201 ws.send("something")202 })203 ws.addEventListener("message", ()=>{204 inmessageidf205 })`,206 expectedError: "inmessageidf is not defined at <eval>:7:7",207 },208 }209 for name, testcase := range cases {210 testcase := testcase211 t.Run(name, func(t *testing.T) {212 t.Parallel()213 ts := newTestState(t)214 // This is here as the on in k6 echos and closes, which races to whether we will get the message or not. And that seems like the correct thing to happen either way.215 ts.tb.Mux.HandleFunc("/ws/echo", func(w http.ResponseWriter, req *http.Request) {216 conn, err := (&websocket.Upgrader{}).Upgrade(w, req, w.Header())217 if err != nil {218 return219 }220 defer func() {221 _ = conn.Close()222 }()223 for {224 msgt, msg, err := conn.ReadMessage()225 if err != nil {226 return227 }228 err = conn.WriteMessage(msgt, msg)229 if err != nil {230 return231 }232 }233 })234 sr := ts.tb.Replacer.Replace235 err := ts.ev.Start(func() error {236 _, err := ts.rt.RunString(sr(testcase.script))237 return err238 })239 require.Error(t, err)240 require.Contains(t, err.Error(), testcase.expectedError)241 })242 }243}244func TestTwoTalking(t *testing.T) {245 t.Parallel()246 ts := newTestState(t)247 sr := ts.tb.Replacer.Replace248 ch1 := make(chan message)249 ch2 := make(chan message)250 ts.tb.Mux.HandleFunc("/ws/couple/", func(w http.ResponseWriter, req *http.Request) {251 path := strings.TrimPrefix(req.URL.Path, "/ws/couple/")252 var wch chan message253 var rch chan message254 switch path {255 case "1":256 wch = ch1257 rch = ch2258 case "2":259 wch = ch2260 rch = ch1261 default:262 w.WriteHeader(418)263 }264 conn, err := (&websocket.Upgrader{}).Upgrade(w, req, w.Header())265 if err != nil {266 return267 }268 defer func() {269 _ = conn.Close()270 }()271 go func() {272 defer close(wch)273 for {274 msgT, msg, err := conn.ReadMessage()275 if err != nil {276 return277 }278 wch <- message{279 data: msg,280 mtype: msgT,281 }282 }283 }()284 for msg := range rch {285 err := conn.WriteMessage(msg.mtype, msg.data)286 if err != nil {287 return288 }289 }290 // fmt.Println(path, "ending")291 })292 err := ts.ev.Start(func() error {293 _, err := ts.rt.RunString(sr(`294 var count = 0;295 var ws1 = new WebSocket("WSBIN_URL/ws/couple/1");296 ws1.addEventListener("open", () => {297 ws1.send("I am 1");298 })299 ws1.addEventListener("message", (e)=>{300 if (e.data != "I am 2") {301 throw "oops";302 }303 count++;304 if (count == 2) {305 ws1.close();306 }307 })308 var ws2 = new WebSocket("WSBIN_URL/ws/couple/2");309 ws2.addEventListener("open", () => {310 ws2.send("I am 2");311 })312 ws2.addEventListener("message", (e)=>{313 if (e.data != "I am 1") {314 throw "oops";315 }316 count++;317 if (count == 2) {318 ws2.close();319 }320 })321 `))322 return err323 })324 require.NoError(t, err)325 samples := metrics.GetBufferedSamples(ts.samples)326 assertSessionMetricsEmitted(t, samples, "", sr("WSBIN_URL/ws/couple/1"), http.StatusSwitchingProtocols, "")327 assertSessionMetricsEmitted(t, samples, "", sr("WSBIN_URL/ws/couple/2"), http.StatusSwitchingProtocols, "")328}329func TestDialError(t *testing.T) {330 t.Parallel()331 ts := newTestState(t)332 sr := ts.tb.Replacer.Replace333 // without listeners334 err := ts.ev.Start(func() error {335 _, runErr := ts.rt.RunString(sr(`336 var ws = new WebSocket("ws://127.0.0.2");337 `))338 return runErr339 })340 require.NoError(t, err)341 // with the error listener342 ts.ev.WaitOnRegistered()343 err = ts.ev.Start(func() error {344 _, runErr := ts.rt.RunString(sr(`345 var ws = new WebSocket("ws://127.0.0.2");...
state_test.go
Source:state_test.go
...6 "github.com/hashicorp/go-memdb"7 "github.com/stretchr/testify/assert"8 "github.com/umbracle/eth2-validator/internal/server/proto"9)10func newTestState(t *testing.T) *State {11 dir, err := os.MkdirTemp("/tmp", "eth2-state-")12 if err != nil {13 t.Fatal(err)14 }15 state, err := NewState(path.Join(dir, "my.db"))16 if err != nil {17 t.Fatal(err)18 }19 t.Cleanup(func() {20 if err := os.RemoveAll(dir); err != nil {21 t.Fatal(err)22 }23 })24 return state25}26func TestState_InsertDuty(t *testing.T) {27 state := newTestState(t)28 duty1 := &proto.Duty{29 Id: "a",30 Slot: 1,31 Job: &proto.Duty_BlockProposal{32 BlockProposal: &proto.BlockProposal{33 Root: "abc",34 },35 },36 }37 err := state.InsertDuty(duty1)38 assert.NoError(t, err)39 duty2 := &proto.Duty{40 Id: "b",41 Job: &proto.Duty_Attestation{42 Attestation: &proto.Attestation{43 Root: "def",44 },45 },46 }47 err = state.InsertDuty(duty2)48 assert.NoError(t, err)49 ws := memdb.NewWatchSet()50 iter, err := state.DutiesList(ws)51 assert.NoError(t, err)52 // return two results53 assert.NotNil(t, iter.Next())54 assert.NotNil(t, iter.Next())55 assert.Nil(t, iter.Next())56 found, err := state.DutyByID("b")57 assert.Nil(t, err)58 assert.Equal(t, found.Id, "b")59}60func TestState_ValidatorWorkflow(t *testing.T) {61 state := newTestState(t)62 val := &proto.Validator{63 PubKey: "a",64 Index: 1,65 ActivationEpoch: 5,66 }67 assert.NoError(t, state.UpsertValidator(val))68 val = &proto.Validator{69 PubKey: "b",70 Index: 2,71 ActivationEpoch: 2,72 }73 assert.NoError(t, state.UpsertValidator(val))74 vals, err := state.GetValidatorsActiveAt(4)75 assert.NoError(t, err)...
newTestState
Using AI Code Generation
1import (2type ws struct {3}4func (w *ws) newTestState() {5 for {6 msg := []byte("hello")7 time.Sleep(1 * time.Second)8 }9}10func (w *ws) reader() {11 for {12 _, msg, err := w.conn.ReadMessage()13 if err != nil {14 }15 fmt.Printf("%s16 }17}18func (w *ws) writer() {19 for msg := range w.send {20 err := w.conn.WriteMessage(websocket.TextMessage, msg)21 if err != nil {22 }23 }24}25func serveWs(w http.ResponseWriter, r *http.Request) {26 conn, err := websocket.Upgrade(w, r, nil, 1024, 1024)27 if _, ok := err.(websocket.HandshakeError); ok {28 http.Error(w, "Not a websocket handshake", 400)29 } else if err != nil {30 }31 ws := &ws{conn: conn, send: make(chan []byte)}32 go ws.writer()33 go ws.reader()34 go ws.newTestState()35}36func main() {37 http.HandleFunc("/ws", serveWs)38 http.ListenAndServe(":8080", nil)39}
newTestState
Using AI Code Generation
1import (2func main() {3 fmt.Println("Hello, playground")4 ws := new(ws)5 ws.newTestState()6 fmt.Println(ws.state)7}8import (9func main() {10 fmt.Println("Hello, playground")11 ws := new(ws)12 ws.newTestState()13 fmt.Println(ws.state)14}15import (16func main() {17 fmt.Println("Hello, playground")18 ws := new(ws)19 ws.newTestState()20 fmt.Println(ws.state)21}22import (23func main() {24 fmt.Println("Hello, playground")25 ws := new(ws)26 ws.newTestState()27 fmt.Println(ws.state)28}29import (30func main() {31 fmt.Println("Hello, playground")32 ws := new(ws)33 ws.newTestState()34 fmt.Println(ws.state)35}36import (37func main() {38 fmt.Println("Hello, playground")39 ws := new(ws)40 ws.newTestState()41 fmt.Println(ws.state)42}43import (44func main() {45 fmt.Println("Hello, playground")46 ws := new(ws)47 ws.newTestState()48 fmt.Println(ws.state)49}50import (51func main() {52 fmt.Println("Hello, playground")53 ws := new(ws)54 ws.newTestState()55 fmt.Println(ws.state)56}57import (58func main() {59 fmt.Println("
newTestState
Using AI Code Generation
1import (2func main() {3 fmt.Println("Hello, playground")4}5import (6type ws struct {7}8func (w *ws) newTestState() *testState {9 return &testState{}10}11type testState struct {12}13func main() {14 fmt.Println("Hello, playground")15}16func (w *ws) newTestState() *testState {17func (w *ws) newTestState() *testState {
newTestState
Using AI Code Generation
1import "fmt"2func main() {3 ws.newTestState("abc")4 fmt.Println(ws)5}6import "fmt"7func main() {8 ws.newTestState("abc")9 fmt.Println(ws)10}11import "fmt"12func main() {13 ws.newTestState("abc")14 fmt.Println(ws)15}16import "fmt"17func main() {18 ws.newTestState("abc")19 fmt.Println(ws)20}21import "fmt"22func main() {23 ws.newTestState("abc")24 fmt.Println(ws)25}26import "fmt"27func main() {28 ws.newTestState("abc")29 fmt.Println(ws)30}31import "fmt"32func main() {33 ws.newTestState("abc")34 fmt.Println(ws)35}36import "fmt"37func main() {38 ws.newTestState("abc")39 fmt.Println(ws)40}41import "fmt"42func main() {43 ws.newTestState("abc")44 fmt.Println(ws)45}46import "fmt"47func main() {48 ws.newTestState("abc")49 fmt.Println(ws)50}51import "fmt"
newTestState
Using AI Code Generation
1import (2type TestState struct {3}4func main() {5 fmt.Println("Hello World")6 ts := TestState{TestName: "Hello World"}7 tmpl, err := template.New("test").Parse("package main8import (9type TestState struct {10}11func main() {12 fmt.Println(\"Hello World\")13 ts := TestState{TestName: \"Hello World\"}14 tmpl, err := template.New(\"test\").Parse({{.}})15 if err != nil {16 fmt.Println(err)17 }18 tmpl.Execute(os.Stdout, ts)19}20 if err != nil {21 fmt.Println(err)22 }23 tmpl.Execute(os.Stdout, ts)24}25import (26type TestState struct {27}28func main() {29 fmt.Println("Hello World")30 ts := TestState{TestName: "Hello World"}31 tmpl, err := template.New("test").Parse("package main32import (33type TestState struct {34}35func main() {36 fmt.Println(\"Hello World\")37 ts := TestState{TestName: \"Hello World\"}38 tmpl, err := template.New(\"test\").Parse({{.}})39 if err != nil {40 fmt.Println(err)41 }42 tmpl.Execute(os.Stdout, ts)43}44 if err != nil {45 fmt.Println(err)46 }47 tmpl.Execute(os.Stdout, ts)48}49import (50type TestState struct {51}52func main() {53 fmt.Println("Hello World")54 ts := TestState{TestName: "Hello World"}
newTestState
Using AI Code Generation
1import (2func main() {3 ws := ws.newTestState(1)4 fmt.Println(ws)5}6type ws struct {7}8func newTestState(id int) ws {9 return ws{id}10}
Learn to execute automation testing from scratch with LambdaTest Learning Hub. Right from setting up the prerequisites to run your first automation test, to following best practices and diving deeper into advanced test scenarios. LambdaTest Learning Hubs compile a list of step-by-step guides to help you be proficient with different test automation frameworks i.e. Selenium, Cypress, TestNG etc.
You could also refer to video tutorials over LambdaTest YouTube channel to get step by step demonstration from industry experts.
Get 100 minutes of automation test minutes FREE!!