Best Venom code snippet using http.writeFile
client_test.go
Source:client_test.go
1// Copyright © 2019 The Things Network Foundation, The Things Industries B.V.2//3// Licensed under the Apache License, Version 2.0 (the "License");4// you may not use this file except in compliance with the License.5// You may obtain a copy of the License at6//7// http://www.apache.org/licenses/LICENSE-2.08//9// Unless required by applicable law or agreed to in writing, software10// distributed under the License is distributed on an "AS IS" BASIS,11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.12// See the License for the specific language governing permissions and13// limitations under the License.14package interop_test15import (16 "context"17 "crypto/tls"18 "fmt"19 "io/ioutil"20 "net/http"21 "net/http/httptest"22 "net/url"23 "os"24 "path/filepath"25 "strconv"26 "strings"27 "testing"28 "github.com/smartystreets/assertions"29 "go.thethings.network/lorawan-stack/pkg/config"30 "go.thethings.network/lorawan-stack/pkg/errors"31 . "go.thethings.network/lorawan-stack/pkg/interop"32 "go.thethings.network/lorawan-stack/pkg/log"33 "go.thethings.network/lorawan-stack/pkg/ttnpb"34 "go.thethings.network/lorawan-stack/pkg/types"35 "go.thethings.network/lorawan-stack/pkg/util/test"36 "go.thethings.network/lorawan-stack/pkg/util/test/assertions/should"37)38func TestJoinServerFQDN(t *testing.T) {39 for _, tc := range []struct {40 JoinEUI types.EUI6441 Expected string42 }{43 {44 JoinEUI: types.EUI64{0x70, 0xb3, 0xd5, 0x7e, 0xd0, 0x00, 0x00, 0x00},45 Expected: "0.0.0.0.0.0.0.d.e.7.5.d.3.b.0.7.joineuis.lora-alliance.org",46 },47 } {48 a := assertions.New(t)49 a.So(JoinServerFQDN(tc.JoinEUI, LoRaAllianceJoinEUIDomain), should.Equal, tc.Expected)50 }51}52func TestGetAppSKey(t *testing.T) {53 makeSessionKeyRequest := func() *ttnpb.SessionKeyRequest {54 return &ttnpb.SessionKeyRequest{55 JoinEUI: types.EUI64{0x70, 0xb3, 0xd5, 0x7e, 0xd0, 0x00, 0x00, 0x00},56 DevEUI: types.EUI64{0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08},57 SessionKeyID: []byte{0x01, 0x6b, 0xfa, 0x7b, 0xad, 0x47, 0x56, 0x34, 0x6a, 0x67, 0x49, 0x81, 0xe7, 0x5c, 0xdb, 0xdc},58 }59 }60 for _, tc := range []struct {61 Name string62 NewServer func(*testing.T) *httptest.Server63 NewClientConfig func(fqdn string, port uint32) (config.InteropClient, func() error)64 AsID string65 Request *ttnpb.SessionKeyRequest66 ResponseAssertion func(*testing.T, *ttnpb.AppSKeyResponse) bool67 ErrorAssertion func(*testing.T, error) bool68 }{69 {70 Name: "Backend Interfaces 1.0/UnknownDevEUI",71 NewServer: func(t *testing.T) *httptest.Server {72 return newTLSServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {73 a := assertions.New(t)74 a.So(r.Method, should.Equal, http.MethodPost)75 b, err := ioutil.ReadAll(r.Body)76 a.So(err, should.BeNil)77 a.So(string(b), should.Equal, `{"ProtocolVersion":"1.0","TransactionID":0,"MessageType":"AppSKeyReq","SenderID":"test-as","ReceiverID":"70B3D57ED0000000","DevEUI":"0102030405060708","SessionKeyID":"016BFA7BAD4756346A674981E75CDBDC"}78`)79 a.So(r.Body.Close(), should.BeNil)80 _, err = w.Write([]byte(`{81 "Result": {82 "ResultCode": "UnknownDevEUI"83 }84}`))85 a.So(err, should.BeNil)86 }))87 },88 NewClientConfig: func(fqdn string, port uint32) (config.InteropClient, func() error) {89 confDir := test.Must(ioutil.TempDir("", "lorawan-stack-js-interop-test")).(string)90 confPath := filepath.Join(confDir, InteropClientConfigurationName)91 js1Path := filepath.Join(confDir, "test-js-1.yml")92 js2Path := filepath.Join(confDir, "foo", "test-js-2.yml")93 js3Path := filepath.Join(confDir, "test-js-3.yml")94 test.MustMultiple(os.Mkdir(filepath.Join(confDir, "testdata"), 0755))95 test.MustMultiple(ioutil.WriteFile(filepath.Join(confDir, ClientCertPath), ClientCert, 0644))96 test.MustMultiple(ioutil.WriteFile(filepath.Join(confDir, ClientKeyPath), ClientKey, 0644))97 test.MustMultiple(ioutil.WriteFile(filepath.Join(confDir, ServerCertPath), ServerCert, 0644))98 test.MustMultiple(ioutil.WriteFile(filepath.Join(confDir, ServerKeyPath), ServerKey, 0644))99 test.MustMultiple(ioutil.WriteFile(filepath.Join(confDir, RootCAPath), RootCA, 0644))100 rel := func(path string) string {101 return test.Must(filepath.Rel(confDir, path)).(string)102 }103 test.MustMultiple(ioutil.WriteFile(confPath, []byte(fmt.Sprintf(`join-servers:104 - file: %s105 join-euis:106 - 0000000000000000/0107 - 70b3d57ed0001000/52108 - file: %s109 join-euis:110 - 70b3d57ed0000000/40111 - file: %s112 join-euis:113 - 70b3d57ed0000000/39114 - 70b3d83ed0000000/30`,115 rel(js1Path),116 rel(js2Path),117 rel(js3Path),118 )), 0644))119 test.MustMultiple(ioutil.WriteFile(js1Path, []byte(fmt.Sprintf(`fqdn: test-js.fqdn120port: 12345121protocol: BI1.1122tls:123 root-ca: %s124 certificate: %s125 key: %s126headers:127 SomeHeader: Some foo bar128 TestHeader: baz`,129 RootCAPath,130 ClientCertPath,131 ClientKeyPath,132 )), 0644))133 test.MustMultiple(os.Mkdir(filepath.Join(confDir, "foo"), 0755))134 test.MustMultiple(ioutil.WriteFile(js2Path, []byte(fmt.Sprintf(`fqdn: %s135port: %d136protocol: BI1.0137paths:138 app-s-key: test-app-s-key-path139 home-ns: test-home-ns-path140tls:141 root-ca: %s142 certificate: %s143 key: %s144headers:145 Authorization: Custom foo bar146 TestHeader: baz`,147 fqdn,148 port,149 filepath.Join("..", RootCAPath),150 filepath.Join("..", ClientCertPath),151 filepath.Join("..", ClientKeyPath),152 )), 0644))153 test.MustMultiple(ioutil.WriteFile(js3Path, []byte(`dns: invalid.dns154protocol: BI1.1155paths:156 join: test-join-path157 rejoin: test-rejoin-path`,158 ), 0644))159 return config.InteropClient{160 Directory: confDir,161 GetFallbackTLSConfig: func(context.Context) (*tls.Config, error) { return nil, nil },162 }, func() error {163 return os.RemoveAll(confDir)164 }165 },166 AsID: "test-as",167 Request: makeSessionKeyRequest(),168 ResponseAssertion: func(t *testing.T, resp *ttnpb.AppSKeyResponse) bool {169 return assertions.New(t).So(resp, should.BeNil)170 },171 ErrorAssertion: func(t *testing.T, err error) bool {172 return assertions.New(t).So(err, should.HaveSameErrorDefinitionAs, ErrUnknownDevEUI)173 },174 },175 {176 Name: "Backend Interfaces 1.1/UnknownDevEUI",177 NewServer: func(t *testing.T) *httptest.Server {178 return newTLSServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {179 a := assertions.New(t)180 a.So(r.Method, should.Equal, http.MethodPost)181 b, err := ioutil.ReadAll(r.Body)182 a.So(err, should.BeNil)183 a.So(string(b), should.Equal, `{"ProtocolVersion":"1.1","TransactionID":0,"MessageType":"AppSKeyReq","SenderID":"test-as","ReceiverID":"70B3D57ED0000000","DevEUI":"0102030405060708","SessionKeyID":"016BFA7BAD4756346A674981E75CDBDC"}184`)185 a.So(r.Body.Close(), should.BeNil)186 _, err = w.Write([]byte(`{187 "Result": {188 "ResultCode": "UnknownDevEUI"189 }190}`))191 a.So(err, should.BeNil)192 }))193 },194 NewClientConfig: func(fqdn string, port uint32) (config.InteropClient, func() error) {195 confDir := test.Must(ioutil.TempDir("", "lorawan-stack-js-interop-test")).(string)196 confPath := filepath.Join(confDir, InteropClientConfigurationName)197 js1Path := filepath.Join(confDir, "test-js-1.yml")198 js2Path := filepath.Join(confDir, "foo", "test-js-2.yml")199 js3Path := filepath.Join(confDir, "test-js-3.yml")200 test.MustMultiple(os.Mkdir(filepath.Join(confDir, "testdata"), 0755))201 test.MustMultiple(ioutil.WriteFile(filepath.Join(confDir, ClientCertPath), ClientCert, 0644))202 test.MustMultiple(ioutil.WriteFile(filepath.Join(confDir, ClientKeyPath), ClientKey, 0644))203 test.MustMultiple(ioutil.WriteFile(filepath.Join(confDir, ServerCertPath), ServerCert, 0644))204 test.MustMultiple(ioutil.WriteFile(filepath.Join(confDir, ServerKeyPath), ServerKey, 0644))205 test.MustMultiple(ioutil.WriteFile(filepath.Join(confDir, RootCAPath), RootCA, 0644))206 rel := func(path string) string {207 return test.Must(filepath.Rel(confDir, path)).(string)208 }209 test.MustMultiple(ioutil.WriteFile(confPath, []byte(fmt.Sprintf(`join-servers:210 - file: %s211 join-euis:212 - 0000000000000000/0213 - 70b3d57ed0001000/52214 - file: %s215 join-euis:216 - 70b3d57ed0000000/40217 - file: %s218 join-euis:219 - 70b3d57ed0000000/39220 - 70b3d83ed0000000/30`,221 rel(js1Path),222 rel(js2Path),223 rel(js3Path),224 )), 0644))225 test.MustMultiple(ioutil.WriteFile(js1Path, []byte(fmt.Sprintf(`fqdn: test-js.fqdn226port: 12345227protocol: BI1.0228tls:229 root-ca: %s230 certificate: %s231 key: %s232headers:233 SomeHeader: Some foo bar234 TestHeader: baz`,235 RootCAPath,236 ClientCertPath,237 ClientKeyPath,238 )), 0644))239 test.MustMultiple(os.Mkdir(filepath.Join(confDir, "foo"), 0755))240 test.MustMultiple(ioutil.WriteFile(js2Path, []byte(fmt.Sprintf(`fqdn: %s241port: %d242protocol: BI1.1243paths:244 app-s-key: test-app-s-key-path245 home-ns: test-home-ns-path246tls:247 root-ca: %s248 certificate: %s249 key: %s250headers:251 Authorization: Custom foo bar252 TestHeader: baz`,253 fqdn,254 port,255 filepath.Join("..", RootCAPath),256 filepath.Join("..", ClientCertPath),257 filepath.Join("..", ClientKeyPath),258 )), 0644))259 test.MustMultiple(ioutil.WriteFile(js3Path, []byte(`dns: invalid.dns260protocol: BI1.0261paths:262 join: test-join-path263 rejoin: test-rejoin-path`,264 ), 0644))265 return config.InteropClient{266 Directory: confDir,267 GetFallbackTLSConfig: func(context.Context) (*tls.Config, error) { return nil, nil },268 }, func() error {269 return os.RemoveAll(confDir)270 }271 },272 AsID: "test-as",273 Request: makeSessionKeyRequest(),274 ResponseAssertion: func(t *testing.T, resp *ttnpb.AppSKeyResponse) bool {275 return assertions.New(t).So(resp, should.BeNil)276 },277 ErrorAssertion: func(t *testing.T, err error) bool {278 return assertions.New(t).So(err, should.HaveSameErrorDefinitionAs, ErrUnknownDevEUI)279 },280 },281 {282 Name: "Backend Interfaces 1.0/Success",283 NewServer: func(t *testing.T) *httptest.Server {284 return newTLSServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {285 a := assertions.New(t)286 a.So(r.Method, should.Equal, http.MethodPost)287 b, err := ioutil.ReadAll(r.Body)288 a.So(err, should.BeNil)289 a.So(string(b), should.Equal, `{"ProtocolVersion":"1.0","TransactionID":0,"MessageType":"AppSKeyReq","SenderID":"test-as","ReceiverID":"70B3D57ED0000000","DevEUI":"0102030405060708","SessionKeyID":"016BFA7BAD4756346A674981E75CDBDC"}290`)291 a.So(r.Body.Close(), should.BeNil)292 _, err = w.Write([]byte(`{293 "ProtocolVersion": "1.0",294 "TransactionID": 0,295 "MessageType": "AppSKeyAns",296 "ReceiverToken": "01",297 "SenderID": "70B3D57ED0000000",298 "ReceiverID": "test-as",299 "Result": {300 "ResultCode": "Success"301 },302 "Lifetime": 0,303 "AppSKey": {304 "KEKLabel": "as:010042",305 "AESKey": "2A195CC93CA54AD82CFB36C83D91450F3D2D523556F13E69"306 },307 "SessionKeyID": "016BFA7BAD4756346A674981E75CDBDC"308}`))309 a.So(err, should.BeNil)310 }))311 },312 NewClientConfig: func(fqdn string, port uint32) (config.InteropClient, func() error) {313 confDir := test.Must(ioutil.TempDir("", "lorawan-stack-js-interop-test")).(string)314 confPath := filepath.Join(confDir, InteropClientConfigurationName)315 js1Path := filepath.Join(confDir, "test-js-1.yml")316 js2Path := filepath.Join(confDir, "foo", "test-js-2.yml")317 js3Path := filepath.Join(confDir, "test-js-3.yml")318 test.MustMultiple(os.Mkdir(filepath.Join(confDir, "testdata"), 0755))319 test.MustMultiple(ioutil.WriteFile(filepath.Join(confDir, ClientCertPath), ClientCert, 0644))320 test.MustMultiple(ioutil.WriteFile(filepath.Join(confDir, ClientKeyPath), ClientKey, 0644))321 test.MustMultiple(ioutil.WriteFile(filepath.Join(confDir, ServerCertPath), ServerCert, 0644))322 test.MustMultiple(ioutil.WriteFile(filepath.Join(confDir, ServerKeyPath), ServerKey, 0644))323 test.MustMultiple(ioutil.WriteFile(filepath.Join(confDir, RootCAPath), RootCA, 0644))324 rel := func(path string) string {325 return test.Must(filepath.Rel(confDir, path)).(string)326 }327 test.MustMultiple(ioutil.WriteFile(confPath, []byte(fmt.Sprintf(`join-servers:328 - file: %s329 join-euis:330 - 0000000000000000/0331 - 70b3d57ed0001000/52332 - file: %s333 join-euis:334 - 70b3d57ed0000000/40335 - file: %s336 join-euis:337 - 70b3d57ed0000000/39338 - 70b3d83ed0000000/30`,339 rel(js1Path),340 rel(js2Path),341 rel(js3Path),342 )), 0644))343 test.MustMultiple(ioutil.WriteFile(js1Path, []byte(fmt.Sprintf(`fqdn: test-js.fqdn344port: 12345345protocol: BI1.1346tls:347 root-ca: %s348 certificate: %s349 key: %s350headers:351 SomeHeader: Some foo bar352 TestHeader: baz`,353 RootCAPath,354 ClientCertPath,355 ClientKeyPath,356 )), 0644))357 test.MustMultiple(os.Mkdir(filepath.Join(confDir, "foo"), 0755))358 test.MustMultiple(ioutil.WriteFile(js2Path, []byte(fmt.Sprintf(`fqdn: %s359port: %d360protocol: BI1.0361paths:362 app-s-key: test-app-s-key-path363 home-ns: test-home-ns-path364tls:365 root-ca: %s366 certificate: %s367 key: %s368headers:369 Authorization: Custom foo bar370 TestHeader: baz`,371 fqdn,372 port,373 filepath.Join("..", RootCAPath),374 filepath.Join("..", ClientCertPath),375 filepath.Join("..", ClientKeyPath),376 )), 0644))377 test.MustMultiple(ioutil.WriteFile(js3Path, []byte(`dns: invalid.dns378protocol: BI1.1379paths:380 join: test-join-path381 rejoin: test-rejoin-path`,382 ), 0644))383 return config.InteropClient{384 Directory: confDir,385 GetFallbackTLSConfig: func(context.Context) (*tls.Config, error) { return nil, nil },386 }, func() error {387 return os.RemoveAll(confDir)388 }389 },390 AsID: "test-as",391 Request: makeSessionKeyRequest(),392 ResponseAssertion: func(t *testing.T, resp *ttnpb.AppSKeyResponse) bool {393 return assertions.New(t).So(resp, should.Resemble, &ttnpb.AppSKeyResponse{394 AppSKey: ttnpb.KeyEnvelope{395 KEKLabel: "as:010042",396 EncryptedKey: []byte{0x2a, 0x19, 0x5c, 0xc9, 0x3c, 0xa5, 0x4a, 0xd8, 0x2c, 0xfb, 0x36, 0xc8, 0x3d, 0x91, 0x45, 0x0f, 0x3d, 0x2d, 0x52, 0x35, 0x56, 0xf1, 0x3e, 0x69},397 },398 })399 },400 ErrorAssertion: func(t *testing.T, err error) bool {401 return assertions.New(t).So(err, should.BeNil)402 },403 },404 {405 Name: "Backend Interfaces 1.1/Success",406 NewServer: func(t *testing.T) *httptest.Server {407 return newTLSServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {408 a := assertions.New(t)409 a.So(r.Method, should.Equal, http.MethodPost)410 b, err := ioutil.ReadAll(r.Body)411 a.So(err, should.BeNil)412 a.So(string(b), should.Equal, `{"ProtocolVersion":"1.1","TransactionID":0,"MessageType":"AppSKeyReq","SenderID":"test-as","ReceiverID":"70B3D57ED0000000","DevEUI":"0102030405060708","SessionKeyID":"016BFA7BAD4756346A674981E75CDBDC"}413`)414 a.So(r.Body.Close(), should.BeNil)415 _, err = w.Write([]byte(`{416 "ProtocolVersion": "1.1",417 "TransactionID": 0,418 "MessageType": "AppSKeyAns",419 "ReceiverToken": "01",420 "SenderID": "70B3D57ED0000000",421 "ReceiverID": "test-as",422 "Result": {423 "ResultCode": "Success"424 },425 "Lifetime": 0,426 "AppSKey": {427 "KEKLabel": "as:010042",428 "AESKey": "2A195CC93CA54AD82CFB36C83D91450F3D2D523556F13E69"429 },430 "SessionKeyID": "016BFA7BAD4756346A674981E75CDBDC"431}`))432 a.So(err, should.BeNil)433 }))434 },435 NewClientConfig: func(fqdn string, port uint32) (config.InteropClient, func() error) {436 confDir := test.Must(ioutil.TempDir("", "lorawan-stack-js-interop-test")).(string)437 confPath := filepath.Join(confDir, InteropClientConfigurationName)438 js1Path := filepath.Join(confDir, "test-js-1.yml")439 js2Path := filepath.Join(confDir, "foo", "test-js-2.yml")440 js3Path := filepath.Join(confDir, "test-js-3.yml")441 test.MustMultiple(os.Mkdir(filepath.Join(confDir, "testdata"), 0755))442 test.MustMultiple(ioutil.WriteFile(filepath.Join(confDir, ClientCertPath), ClientCert, 0644))443 test.MustMultiple(ioutil.WriteFile(filepath.Join(confDir, ClientKeyPath), ClientKey, 0644))444 test.MustMultiple(ioutil.WriteFile(filepath.Join(confDir, ServerCertPath), ServerCert, 0644))445 test.MustMultiple(ioutil.WriteFile(filepath.Join(confDir, ServerKeyPath), ServerKey, 0644))446 test.MustMultiple(ioutil.WriteFile(filepath.Join(confDir, RootCAPath), RootCA, 0644))447 rel := func(path string) string {448 return test.Must(filepath.Rel(confDir, path)).(string)449 }450 test.MustMultiple(ioutil.WriteFile(confPath, []byte(fmt.Sprintf(`join-servers:451 - file: %s452 join-euis:453 - 0000000000000000/0454 - 70b3d57ed0001000/52455 - file: %s456 join-euis:457 - 70b3d57ed0000000/40458 - file: %s459 join-euis:460 - 70b3d57ed0000000/39461 - 70b3d83ed0000000/30`,462 rel(js1Path),463 rel(js2Path),464 rel(js3Path),465 )), 0644))466 test.MustMultiple(ioutil.WriteFile(js1Path, []byte(fmt.Sprintf(`fqdn: test-js.fqdn467port: 12345468protocol: BI1.0469tls:470 root-ca: %s471 certificate: %s472 key: %s473headers:474 SomeHeader: Some foo bar475 TestHeader: baz`,476 RootCAPath,477 ClientCertPath,478 ClientKeyPath,479 )), 0644))480 test.MustMultiple(os.Mkdir(filepath.Join(confDir, "foo"), 0755))481 test.MustMultiple(ioutil.WriteFile(js2Path, []byte(fmt.Sprintf(`fqdn: %s482port: %d483protocol: BI1.1484paths:485 app-s-key: test-app-s-key-path486 home-ns: test-home-ns-path487tls:488 root-ca: %s489 certificate: %s490 key: %s491headers:492 Authorization: Custom foo bar493 TestHeader: baz`,494 fqdn,495 port,496 filepath.Join("..", RootCAPath),497 filepath.Join("..", ClientCertPath),498 filepath.Join("..", ClientKeyPath),499 )), 0644))500 test.MustMultiple(ioutil.WriteFile(js3Path, []byte(`dns: invalid.dns501protocol: BI1.0502paths:503 join: test-join-path504 rejoin: test-rejoin-path`,505 ), 0644))506 return config.InteropClient{507 Directory: confDir,508 GetFallbackTLSConfig: func(context.Context) (*tls.Config, error) { return nil, nil },509 }, func() error {510 return os.RemoveAll(confDir)511 }512 },513 AsID: "test-as",514 Request: makeSessionKeyRequest(),515 ResponseAssertion: func(t *testing.T, resp *ttnpb.AppSKeyResponse) bool {516 return assertions.New(t).So(resp, should.Resemble, &ttnpb.AppSKeyResponse{517 AppSKey: ttnpb.KeyEnvelope{518 KEKLabel: "as:010042",519 EncryptedKey: []byte{0x2a, 0x19, 0x5c, 0xc9, 0x3c, 0xa5, 0x4a, 0xd8, 0x2c, 0xfb, 0x36, 0xc8, 0x3d, 0x91, 0x45, 0x0f, 0x3d, 0x2d, 0x52, 0x35, 0x56, 0xf1, 0x3e, 0x69},520 },521 })522 },523 ErrorAssertion: func(t *testing.T, err error) bool {524 return assertions.New(t).So(err, should.BeNil)525 },526 },527 } {528 t.Run(tc.Name, func(t *testing.T) {529 a := assertions.New(t)530 ctx := test.Context()531 ctx = log.NewContext(ctx, test.GetLogger(t))532 srv := tc.NewServer(t)533 defer srv.Close()534 host := strings.Split(test.Must(url.Parse(srv.URL)).(*url.URL).Host, ":")535 if len(host) != 2 {536 t.Fatalf("Invalid server host: %s", host)537 }538 conf, flush := tc.NewClientConfig(host[0], uint32(test.Must(strconv.ParseUint(host[1], 10, 32)).(uint64)))539 defer flush()540 cl, err := NewClient(ctx, conf)541 if !a.So(err, should.BeNil) {542 t.Fatalf("Failed to create new client: %s", err)543 }544 res, err := cl.GetAppSKey(ctx, tc.AsID, tc.Request)545 if a.So(tc.ErrorAssertion(t, err), should.BeTrue) {546 a.So(tc.ResponseAssertion(t, res), should.BeTrue)547 } else if err != nil {548 t.Errorf("Received unexpected error: %v", errors.Stack(err))549 }550 })551 }552}553func TestHandleJoinRequest(t *testing.T) {554 makeJoinRequest := func() *ttnpb.JoinRequest {555 return &ttnpb.JoinRequest{556 SelectedMACVersion: ttnpb.MAC_V1_0_3,557 DevAddr: types.DevAddr{0x01, 0x02, 0x03, 0x04},558 RxDelay: ttnpb.RX_DELAY_5,559 Payload: &ttnpb.Message{560 Payload: &ttnpb.Message_JoinRequestPayload{561 JoinRequestPayload: &ttnpb.JoinRequestPayload{562 JoinEUI: types.EUI64{0x70, 0xb3, 0xd5, 0x7e, 0xd0, 0x00, 0x00, 0x00},563 DevEUI: types.EUI64{0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08},564 },565 },566 },567 RawPayload: []byte{0x00, 0x00, 0x00, 0x00, 0xd0, 0x7e, 0xd5, 0xb3, 0x70, 0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00, 0x00, 0x38, 0x51, 0xf0, 0xb6},568 }569 }570 for _, tc := range []struct {571 Name string572 NewServer func(*testing.T) *httptest.Server573 NewClientConfig func(fqdn string, port uint32) (config.InteropClient, func() error)574 NetID types.NetID575 Request *ttnpb.JoinRequest576 ResponseAssertion func(*testing.T, *ttnpb.JoinResponse) bool577 ErrorAssertion func(*testing.T, error) bool578 }{579 {580 Name: "Backend Interfaces 1.0/MICFailed",581 NewServer: func(t *testing.T) *httptest.Server {582 return newTLSServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {583 a := assertions.New(t)584 a.So(r.Method, should.Equal, http.MethodPost)585 b, err := ioutil.ReadAll(r.Body)586 a.So(err, should.BeNil)587 a.So(string(b), should.Equal, `{"ProtocolVersion":"1.0","TransactionID":0,"MessageType":"JoinReq","SenderID":"42FFFF","ReceiverID":"70B3D57ED0000000","SenderNSID":"42FFFF","MACVersion":"1.0.3","PHYPayload":"00000000D07ED5B370080706050403020100003851F0B6","DevEUI":"0102030405060708","DevAddr":"01020304","DLSettings":"00","RxDelay":5,"CFList":""}588`)589 a.So(r.Body.Close(), should.BeNil)590 _, err = w.Write([]byte(`{591 "Result": {592 "ResultCode": "MICFailed"593 }594}`))595 a.So(err, should.BeNil)596 }))597 },598 NewClientConfig: func(fqdn string, port uint32) (config.InteropClient, func() error) {599 confDir := test.Must(ioutil.TempDir("", "lorawan-stack-js-interop-test")).(string)600 confPath := filepath.Join(confDir, InteropClientConfigurationName)601 js1Path := filepath.Join(confDir, "test-js-1.yml")602 js2Path := filepath.Join(confDir, "foo", "test-js-2.yml")603 js3Path := filepath.Join(confDir, "test-js-3.yml")604 test.MustMultiple(os.Mkdir(filepath.Join(confDir, "testdata"), 0755))605 test.MustMultiple(ioutil.WriteFile(filepath.Join(confDir, ClientCertPath), ClientCert, 0644))606 test.MustMultiple(ioutil.WriteFile(filepath.Join(confDir, ClientKeyPath), ClientKey, 0644))607 test.MustMultiple(ioutil.WriteFile(filepath.Join(confDir, ServerCertPath), ServerCert, 0644))608 test.MustMultiple(ioutil.WriteFile(filepath.Join(confDir, ServerKeyPath), ServerKey, 0644))609 test.MustMultiple(ioutil.WriteFile(filepath.Join(confDir, RootCAPath), RootCA, 0644))610 rel := func(path string) string {611 return test.Must(filepath.Rel(confDir, path)).(string)612 }613 test.MustMultiple(ioutil.WriteFile(confPath, []byte(fmt.Sprintf(`join-servers:614 - file: %s615 join-euis:616 - 0000000000000000/0617 - 70b3d57ed0001000/52618 - file: %s619 join-euis:620 - 70b3d57ed0000000/40621 - file: %s622 join-euis:623 - 70b3d57ed0000000/39624 - 70b3d83ed0000000/30`,625 rel(js1Path),626 rel(js2Path),627 rel(js3Path),628 )), 0644))629 test.MustMultiple(ioutil.WriteFile(js1Path, []byte(fmt.Sprintf(`fqdn: test-js.fqdn630port: 12345631protocol: BI1.1632tls:633 root-ca: %s634 certificate: %s635 key: %s636headers:637 SomeHeader: Some foo bar638 TestHeader: baz`,639 RootCAPath,640 ClientCertPath,641 ClientKeyPath,642 )), 0644))643 test.MustMultiple(os.Mkdir(filepath.Join(confDir, "foo"), 0755))644 test.MustMultiple(ioutil.WriteFile(js2Path, []byte(fmt.Sprintf(`fqdn: %s645port: %d646protocol: BI1.0647paths:648 app-s-key: test-app-s-key-path649 home-ns: test-home-ns-path650tls:651 root-ca: %s652 certificate: %s653 key: %s654headers:655 Authorization: Custom foo bar656 TestHeader: baz`,657 fqdn,658 port,659 filepath.Join("..", RootCAPath),660 filepath.Join("..", ClientCertPath),661 filepath.Join("..", ClientKeyPath),662 )), 0644))663 test.MustMultiple(ioutil.WriteFile(js3Path, []byte(`dns: invalid.dns664protocol: BI1.1665paths:666 join: test-join-path667 rejoin: test-rejoin-path`,668 ), 0644))669 return config.InteropClient{670 Directory: confDir,671 GetFallbackTLSConfig: func(context.Context) (*tls.Config, error) { return nil, nil },672 }, func() error {673 return os.RemoveAll(confDir)674 }675 },676 NetID: types.NetID{0x42, 0xff, 0xff},677 Request: makeJoinRequest(),678 ResponseAssertion: func(t *testing.T, resp *ttnpb.JoinResponse) bool {679 return assertions.New(t).So(resp, should.BeNil)680 },681 ErrorAssertion: func(t *testing.T, err error) bool {682 return assertions.New(t).So(err, should.HaveSameErrorDefinitionAs, ErrMIC)683 },684 },685 {686 Name: "Backend Interfaces 1.1/MICFailed",687 NewServer: func(t *testing.T) *httptest.Server {688 return newTLSServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {689 a := assertions.New(t)690 a.So(r.Method, should.Equal, http.MethodPost)691 b, err := ioutil.ReadAll(r.Body)692 a.So(err, should.BeNil)693 a.So(string(b), should.Equal, `{"ProtocolVersion":"1.1","TransactionID":0,"MessageType":"JoinReq","SenderID":"42FFFF","ReceiverID":"70B3D57ED0000000","SenderNSID":"42FFFF","MACVersion":"1.0.3","PHYPayload":"00000000D07ED5B370080706050403020100003851F0B6","DevEUI":"0102030405060708","DevAddr":"01020304","DLSettings":"00","RxDelay":5,"CFList":""}694`)695 a.So(r.Body.Close(), should.BeNil)696 _, err = w.Write([]byte(`{697 "Result": {698 "ResultCode": "MICFailed"699 }700}`))701 a.So(err, should.BeNil)702 }))703 },704 NewClientConfig: func(fqdn string, port uint32) (config.InteropClient, func() error) {705 confDir := test.Must(ioutil.TempDir("", "lorawan-stack-js-interop-test")).(string)706 confPath := filepath.Join(confDir, InteropClientConfigurationName)707 js1Path := filepath.Join(confDir, "test-js-1.yml")708 js2Path := filepath.Join(confDir, "foo", "test-js-2.yml")709 js3Path := filepath.Join(confDir, "test-js-3.yml")710 test.MustMultiple(os.Mkdir(filepath.Join(confDir, "testdata"), 0755))711 test.MustMultiple(ioutil.WriteFile(filepath.Join(confDir, ClientCertPath), ClientCert, 0644))712 test.MustMultiple(ioutil.WriteFile(filepath.Join(confDir, ClientKeyPath), ClientKey, 0644))713 test.MustMultiple(ioutil.WriteFile(filepath.Join(confDir, ServerCertPath), ServerCert, 0644))714 test.MustMultiple(ioutil.WriteFile(filepath.Join(confDir, ServerKeyPath), ServerKey, 0644))715 test.MustMultiple(ioutil.WriteFile(filepath.Join(confDir, RootCAPath), RootCA, 0644))716 rel := func(path string) string {717 return test.Must(filepath.Rel(confDir, path)).(string)718 }719 test.MustMultiple(ioutil.WriteFile(confPath, []byte(fmt.Sprintf(`join-servers:720 - file: %s721 join-euis:722 - 0000000000000000/0723 - 70b3d57ed0001000/52724 - file: %s725 join-euis:726 - 70b3d57ed0000000/40727 - file: %s728 join-euis:729 - 70b3d57ed0000000/39730 - 70b3d83ed0000000/30`,731 rel(js1Path),732 rel(js2Path),733 rel(js3Path),734 )), 0644))735 test.MustMultiple(ioutil.WriteFile(js1Path, []byte(fmt.Sprintf(`fqdn: test-js.fqdn736port: 12345737protocol: BI1.0738tls:739 root-ca: %s740 certificate: %s741 key: %s742headers:743 SomeHeader: Some foo bar744 TestHeader: baz`,745 RootCAPath,746 ClientCertPath,747 ClientKeyPath,748 )), 0644))749 test.MustMultiple(os.Mkdir(filepath.Join(confDir, "foo"), 0755))750 test.MustMultiple(ioutil.WriteFile(js2Path, []byte(fmt.Sprintf(`fqdn: %s751port: %d752protocol: BI1.1753paths:754 app-s-key: test-app-s-key-path755 home-ns: test-home-ns-path756tls:757 root-ca: %s758 certificate: %s759 key: %s760headers:761 Authorization: Custom foo bar762 TestHeader: baz`,763 fqdn,764 port,765 filepath.Join("..", RootCAPath),766 filepath.Join("..", ClientCertPath),767 filepath.Join("..", ClientKeyPath),768 )), 0644))769 test.MustMultiple(ioutil.WriteFile(js3Path, []byte(`dns: invalid.dns770protocol: BI1.0771paths:772 join: test-join-path773 rejoin: test-rejoin-path`,774 ), 0644))775 return config.InteropClient{776 Directory: confDir,777 GetFallbackTLSConfig: func(context.Context) (*tls.Config, error) { return nil, nil },778 }, func() error {779 return os.RemoveAll(confDir)780 }781 },782 NetID: types.NetID{0x42, 0xff, 0xff},783 Request: makeJoinRequest(),784 ResponseAssertion: func(t *testing.T, resp *ttnpb.JoinResponse) bool {785 return assertions.New(t).So(resp, should.BeNil)786 },787 ErrorAssertion: func(t *testing.T, err error) bool {788 return assertions.New(t).So(err, should.HaveSameErrorDefinitionAs, ErrMIC)789 },790 },791 {792 Name: "Backend Interfaces 1.0/Success",793 NewServer: func(t *testing.T) *httptest.Server {794 return newTLSServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {795 a := assertions.New(t)796 a.So(r.Method, should.Equal, http.MethodPost)797 b, err := ioutil.ReadAll(r.Body)798 a.So(err, should.BeNil)799 a.So(string(b), should.Equal, `{"ProtocolVersion":"1.0","TransactionID":0,"MessageType":"JoinReq","SenderID":"42FFFF","ReceiverID":"70B3D57ED0000000","SenderNSID":"42FFFF","MACVersion":"1.0.3","PHYPayload":"00000000D07ED5B370080706050403020100003851F0B6","DevEUI":"0102030405060708","DevAddr":"01020304","DLSettings":"00","RxDelay":5,"CFList":""}800`)801 a.So(r.Body.Close(), should.BeNil)802 _, err = w.Write([]byte(`{803 "ProtocolVersion": "1.0",804 "TransactionID": 0,805 "MessageType": "JoinAns",806 "ReceiverToken": "01",807 "SenderID": "70B3D57ED0000000",808 "ReceiverID": "000000",809 "ReceiverNSID": "000000",810 "PHYPayload": "204D675073BB4153B23653EFA82C1F3A49E19C2A8696C9A34BF492674779E4BEFA",811 "Result": {812 "ResultCode": "Success"813 },814 "Lifetime": 0,815 "NwkSKey": {816 "KEKLabel": "ns:000000",817 "AESKey": "EB56FE6681999F25D548CFEDD4A6528B331BB5ADE1CAF17F"818 },819 "AppSKey": {820 "KEKLabel": "as:010042",821 "AESKey": "2A195CC93CA54AD82CFB36C83D91450F3D2D523556F13E69"822 },823 "SessionKeyID": "016BFA7BAD4756346A674981E75CDBDC"824}`))825 a.So(err, should.BeNil)826 }))827 },828 NewClientConfig: func(fqdn string, port uint32) (config.InteropClient, func() error) {829 confDir := test.Must(ioutil.TempDir("", "lorawan-stack-js-interop-test")).(string)830 confPath := filepath.Join(confDir, InteropClientConfigurationName)831 js1Path := filepath.Join(confDir, "test-js-1.yml")832 js2Path := filepath.Join(confDir, "foo", "test-js-2.yml")833 js3Path := filepath.Join(confDir, "test-js-3.yml")834 test.MustMultiple(os.Mkdir(filepath.Join(confDir, "testdata"), 0755))835 test.MustMultiple(ioutil.WriteFile(filepath.Join(confDir, ClientCertPath), ClientCert, 0644))836 test.MustMultiple(ioutil.WriteFile(filepath.Join(confDir, ClientKeyPath), ClientKey, 0644))837 test.MustMultiple(ioutil.WriteFile(filepath.Join(confDir, ServerCertPath), ServerCert, 0644))838 test.MustMultiple(ioutil.WriteFile(filepath.Join(confDir, ServerKeyPath), ServerKey, 0644))839 test.MustMultiple(ioutil.WriteFile(filepath.Join(confDir, RootCAPath), RootCA, 0644))840 rel := func(path string) string {841 return test.Must(filepath.Rel(confDir, path)).(string)842 }843 test.MustMultiple(ioutil.WriteFile(confPath, []byte(fmt.Sprintf(`join-servers:844 - file: %s845 join-euis:846 - 0000000000000000/0847 - 70b3d57ed0001000/52848 - file: %s849 join-euis:850 - 70b3d57ed0000000/40851 - file: %s852 join-euis:853 - 70b3d57ed0000000/39854 - 70b3d83ed0000000/30`,855 rel(js1Path),856 rel(js2Path),857 rel(js3Path),858 )), 0644))859 test.MustMultiple(ioutil.WriteFile(js1Path, []byte(fmt.Sprintf(`fqdn: test-js.fqdn860port: 12345861protocol: BI1.1862tls:863 root-ca: %s864 certificate: %s865 key: %s866headers:867 SomeHeader: Some foo bar868 TestHeader: baz`,869 RootCAPath,870 ClientCertPath,871 ClientKeyPath,872 )), 0644))873 test.MustMultiple(os.Mkdir(filepath.Join(confDir, "foo"), 0755))874 test.MustMultiple(ioutil.WriteFile(js2Path, []byte(fmt.Sprintf(`fqdn: %s875port: %d876protocol: BI1.0877paths:878 app-s-key: test-app-s-key-path879 home-ns: test-home-ns-path880tls:881 root-ca: %s882 certificate: %s883 key: %s884headers:885 Authorization: Custom foo bar886 TestHeader: baz`,887 fqdn,888 port,889 filepath.Join("..", RootCAPath),890 filepath.Join("..", ClientCertPath),891 filepath.Join("..", ClientKeyPath),892 )), 0644))893 test.MustMultiple(ioutil.WriteFile(js3Path, []byte(`dns: invalid.dns894protocol: BI1.1895paths:896 join: test-join-path897 rejoin: test-rejoin-path`,898 ), 0644))899 return config.InteropClient{900 Directory: confDir,901 GetFallbackTLSConfig: func(context.Context) (*tls.Config, error) { return nil, nil },902 }, func() error {903 return os.RemoveAll(confDir)904 }905 },906 NetID: types.NetID{0x42, 0xff, 0xff},907 Request: makeJoinRequest(),908 ResponseAssertion: func(t *testing.T, resp *ttnpb.JoinResponse) bool {909 return assertions.New(t).So(resp, should.Resemble, &ttnpb.JoinResponse{910 RawPayload: []byte{0x20, 0x4d, 0x67, 0x50, 0x73, 0xbb, 0x41, 0x53, 0xb2, 0x36, 0x53, 0xef, 0xa8, 0x2c, 0x1f, 0x3a, 0x49, 0xe1, 0x9c, 0x2a, 0x86, 0x96, 0xc9, 0xa3, 0x4b, 0xf4, 0x92, 0x67, 0x47, 0x79, 0xe4, 0xbe, 0xfa},911 SessionKeys: ttnpb.SessionKeys{912 SessionKeyID: []byte{0x01, 0x6b, 0xfa, 0x7b, 0xad, 0x47, 0x56, 0x34, 0x6a, 0x67, 0x49, 0x81, 0xe7, 0x5c, 0xdb, 0xdc},913 FNwkSIntKey: &ttnpb.KeyEnvelope{914 KEKLabel: "ns:000000",915 EncryptedKey: []byte{0xeb, 0x56, 0xfe, 0x66, 0x81, 0x99, 0x9f, 0x25, 0xd5, 0x48, 0xcf, 0xed, 0xd4, 0xa6, 0x52, 0x8b, 0x33, 0x1b, 0xb5, 0xad, 0xe1, 0xca, 0xf1, 0x7f},916 },917 AppSKey: &ttnpb.KeyEnvelope{918 KEKLabel: "as:010042",919 EncryptedKey: []byte{0x2a, 0x19, 0x5c, 0xc9, 0x3c, 0xa5, 0x4a, 0xd8, 0x2c, 0xfb, 0x36, 0xc8, 0x3d, 0x91, 0x45, 0x0f, 0x3d, 0x2d, 0x52, 0x35, 0x56, 0xf1, 0x3e, 0x69},920 },921 },922 })923 },924 ErrorAssertion: func(t *testing.T, err error) bool {925 return assertions.New(t).So(err, should.BeNil)926 },927 },928 {929 Name: "Backend Interfaces 1.1/Success",930 NewServer: func(t *testing.T) *httptest.Server {931 return newTLSServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {932 a := assertions.New(t)933 a.So(r.Method, should.Equal, http.MethodPost)934 b, err := ioutil.ReadAll(r.Body)935 a.So(err, should.BeNil)936 a.So(string(b), should.Equal, `{"ProtocolVersion":"1.1","TransactionID":0,"MessageType":"JoinReq","SenderID":"42FFFF","ReceiverID":"70B3D57ED0000000","SenderNSID":"42FFFF","MACVersion":"1.0.3","PHYPayload":"00000000D07ED5B370080706050403020100003851F0B6","DevEUI":"0102030405060708","DevAddr":"01020304","DLSettings":"00","RxDelay":5,"CFList":""}937`)938 a.So(r.Body.Close(), should.BeNil)939 _, err = w.Write([]byte(`{940 "ProtocolVersion": "1.1",941 "TransactionID": 0,942 "MessageType": "JoinAns",943 "ReceiverToken": "01",944 "SenderID": "70B3D57ED0000000",945 "ReceiverID": "000000",946 "ReceiverNSID": "000000",947 "PHYPayload": "204D675073BB4153B23653EFA82C1F3A49E19C2A8696C9A34BF492674779E4BEFA",948 "Result": {949 "ResultCode": "Success"950 },951 "Lifetime": 0,952 "NwkSKey": {953 "KEKLabel": "ns:000000",954 "AESKey": "EB56FE6681999F25D548CFEDD4A6528B331BB5ADE1CAF17F"955 },956 "AppSKey": {957 "KEKLabel": "as:010042",958 "AESKey": "2A195CC93CA54AD82CFB36C83D91450F3D2D523556F13E69"959 },960 "SessionKeyID": "016BFA7BAD4756346A674981E75CDBDC"961}`))962 a.So(err, should.BeNil)963 }))964 },965 NewClientConfig: func(fqdn string, port uint32) (config.InteropClient, func() error) {966 confDir := test.Must(ioutil.TempDir("", "lorawan-stack-js-interop-test")).(string)967 confPath := filepath.Join(confDir, InteropClientConfigurationName)968 js1Path := filepath.Join(confDir, "test-js-1.yml")969 js2Path := filepath.Join(confDir, "foo", "test-js-2.yml")970 js3Path := filepath.Join(confDir, "test-js-3.yml")971 test.MustMultiple(os.Mkdir(filepath.Join(confDir, "testdata"), 0755))972 test.MustMultiple(ioutil.WriteFile(filepath.Join(confDir, ClientCertPath), ClientCert, 0644))973 test.MustMultiple(ioutil.WriteFile(filepath.Join(confDir, ClientKeyPath), ClientKey, 0644))974 test.MustMultiple(ioutil.WriteFile(filepath.Join(confDir, ServerCertPath), ServerCert, 0644))975 test.MustMultiple(ioutil.WriteFile(filepath.Join(confDir, ServerKeyPath), ServerKey, 0644))976 test.MustMultiple(ioutil.WriteFile(filepath.Join(confDir, RootCAPath), RootCA, 0644))977 rel := func(path string) string {978 return test.Must(filepath.Rel(confDir, path)).(string)979 }980 test.MustMultiple(ioutil.WriteFile(confPath, []byte(fmt.Sprintf(`join-servers:981 - file: %s982 join-euis:983 - 0000000000000000/0984 - 70b3d57ed0001000/52985 - file: %s986 join-euis:987 - 70b3d57ed0000000/40988 - file: %s989 join-euis:990 - 70b3d57ed0000000/39991 - 70b3d83ed0000000/30`,992 rel(js1Path),993 rel(js2Path),994 rel(js3Path),995 )), 0644))996 test.MustMultiple(ioutil.WriteFile(js1Path, []byte(fmt.Sprintf(`fqdn: test-js.fqdn997port: 12345998protocol: BI1.0999tls:1000 root-ca: %s1001 certificate: %s1002 key: %s1003headers:1004 SomeHeader: Some foo bar1005 TestHeader: baz`,1006 RootCAPath,1007 ClientCertPath,1008 ClientKeyPath,1009 )), 0644))1010 test.MustMultiple(os.Mkdir(filepath.Join(confDir, "foo"), 0755))1011 test.MustMultiple(ioutil.WriteFile(js2Path, []byte(fmt.Sprintf(`fqdn: %s1012port: %d1013protocol: BI1.11014paths:1015 app-s-key: test-app-s-key-path1016 home-ns: test-home-ns-path1017tls:1018 root-ca: %s1019 certificate: %s1020 key: %s1021headers:1022 Authorization: Custom foo bar1023 TestHeader: baz`,1024 fqdn,1025 port,1026 filepath.Join("..", RootCAPath),1027 filepath.Join("..", ClientCertPath),1028 filepath.Join("..", ClientKeyPath),1029 )), 0644))1030 test.MustMultiple(ioutil.WriteFile(js3Path, []byte(`dns: invalid.dns1031protocol: BI1.01032paths:1033 join: test-join-path1034 rejoin: test-rejoin-path`,1035 ), 0644))1036 return config.InteropClient{1037 Directory: confDir,1038 GetFallbackTLSConfig: func(context.Context) (*tls.Config, error) { return nil, nil },1039 }, func() error {1040 return os.RemoveAll(confDir)1041 }1042 },1043 NetID: types.NetID{0x42, 0xff, 0xff},1044 Request: makeJoinRequest(),1045 ResponseAssertion: func(t *testing.T, resp *ttnpb.JoinResponse) bool {1046 return assertions.New(t).So(resp, should.Resemble, &ttnpb.JoinResponse{1047 RawPayload: []byte{0x20, 0x4d, 0x67, 0x50, 0x73, 0xbb, 0x41, 0x53, 0xb2, 0x36, 0x53, 0xef, 0xa8, 0x2c, 0x1f, 0x3a, 0x49, 0xe1, 0x9c, 0x2a, 0x86, 0x96, 0xc9, 0xa3, 0x4b, 0xf4, 0x92, 0x67, 0x47, 0x79, 0xe4, 0xbe, 0xfa},1048 SessionKeys: ttnpb.SessionKeys{1049 SessionKeyID: []byte{0x01, 0x6b, 0xfa, 0x7b, 0xad, 0x47, 0x56, 0x34, 0x6a, 0x67, 0x49, 0x81, 0xe7, 0x5c, 0xdb, 0xdc},1050 FNwkSIntKey: &ttnpb.KeyEnvelope{1051 KEKLabel: "ns:000000",1052 EncryptedKey: []byte{0xeb, 0x56, 0xfe, 0x66, 0x81, 0x99, 0x9f, 0x25, 0xd5, 0x48, 0xcf, 0xed, 0xd4, 0xa6, 0x52, 0x8b, 0x33, 0x1b, 0xb5, 0xad, 0xe1, 0xca, 0xf1, 0x7f},1053 },1054 AppSKey: &ttnpb.KeyEnvelope{1055 KEKLabel: "as:010042",1056 EncryptedKey: []byte{0x2a, 0x19, 0x5c, 0xc9, 0x3c, 0xa5, 0x4a, 0xd8, 0x2c, 0xfb, 0x36, 0xc8, 0x3d, 0x91, 0x45, 0x0f, 0x3d, 0x2d, 0x52, 0x35, 0x56, 0xf1, 0x3e, 0x69},1057 },1058 },1059 })1060 },1061 ErrorAssertion: func(t *testing.T, err error) bool {1062 return assertions.New(t).So(err, should.BeNil)1063 },1064 },1065 } {1066 t.Run(tc.Name, func(t *testing.T) {1067 a := assertions.New(t)1068 ctx := test.Context()1069 ctx = log.NewContext(ctx, test.GetLogger(t))1070 srv := tc.NewServer(t)1071 defer srv.Close()1072 host := strings.Split(test.Must(url.Parse(srv.URL)).(*url.URL).Host, ":")1073 if len(host) != 2 {1074 t.Fatalf("Invalid server host: %s", host)1075 }1076 conf, flush := tc.NewClientConfig(host[0], uint32(test.Must(strconv.ParseUint(host[1], 10, 32)).(uint64)))1077 defer flush()1078 cl, err := NewClient(ctx, conf)1079 if !a.So(err, should.BeNil) {1080 t.Fatalf("Failed to create new client: %s", err)1081 }1082 res, err := cl.HandleJoinRequest(ctx, tc.NetID, tc.Request)1083 if a.So(tc.ErrorAssertion(t, err), should.BeTrue) {1084 a.So(tc.ResponseAssertion(t, res), should.BeTrue)1085 } else if err != nil {1086 t.Errorf("Received unexpected error: %v", errors.Stack(err))1087 }1088 })1089 }1090}...
config_test.go
Source:config_test.go
1package config2import (3 "io/ioutil"4 "net/http"5 "os"6 "path/filepath"7 "testing"8)9func TestSetEnvVar(t *testing.T) {10 k1 := "value1"11 k2 := "value2"12 os.Setenv("KEY1", "new_value")13 setEnvVar("KEY1", &k1)14 setEnvVar("KEY2", &k2)15 if k1 != "new_value" {16 t.Errorf("setEnvVar failed. expect new_value, but got %s", k1)17 }18 if k2 != "value2" {19 t.Errorf("setEnvVar failed. expect value2, but got %s", k2)20 }21}22func TestGetConfigFileName(t *testing.T) {23 tt := []struct {24 args []string25 expectOK bool26 fname string27 }{28 {29 args: []string{},30 expectOK: true,31 fname: "",32 },33 {34 args: []string{"--config=test.yaml"},35 expectOK: true,36 fname: "test.yaml",37 },38 {39 args: []string{"-config=test.yaml"},40 expectOK: true,41 fname: "test.yaml",42 },43 {44 args: []string{"--config", "test.yaml"},45 expectOK: true,46 fname: "test.yaml",47 },48 {49 args: []string{"-config", "test.yaml"},50 expectOK: true,51 fname: "test.yaml",52 },53 {54 args: []string{"--test=test.yaml"},55 expectOK: true,56 fname: "",57 },58 {59 args: []string{"--config"},60 expectOK: false,61 },62 {63 args: []string{"--config", "--test"},64 expectOK: false,65 },66 }67 for _, tc := range tt {68 f, err := getConfigFileName(tc.args)69 if tc.expectOK && err != nil {70 t.Errorf("getConfigFileName returns wrong response. input: %v, got %v, want nil", tc.args, err)71 }72 if !tc.expectOK && err == nil {73 t.Errorf("getConfigFileName returns wrong response. input: %v, got nil, but want not nil", tc.args)74 }75 if tc.expectOK && f != tc.fname {76 t.Errorf("getConfigFileName returns wrong file name. expect %s, but got %s", tc.fname, f)77 }78 }79}80func TestCheckLoginResDirStruct(t *testing.T) {81 dir, err := ioutil.TempDir("", "")82 if err != nil {83 t.Errorf("Failed to create tmp dir: %v", err)84 return85 }86 defer os.RemoveAll(dir)87 c := &GlobalConfig{88 UserLoginResourceDir: dir,89 }90 consentFile := filepath.Join(dir, "consent.html")91 otpVerifyFile := filepath.Join(dir, "otp_verify.html")92 indexFile := filepath.Join(dir, "index.html")93 deviceFile := filepath.Join(dir, "devicelogin.html")94 deviceCompFile := filepath.Join(dir, "devicelogin_complete.html")95 data := []byte("data")96 // Test no consent page97 // Error check only once98 if err := ioutil.WriteFile(otpVerifyFile, data, 0644); err != nil {99 t.Errorf("Failed to create OTP verify file: %v", err)100 return101 }102 ioutil.WriteFile(indexFile, data, 0644)103 ioutil.WriteFile(deviceFile, data, 0644)104 ioutil.WriteFile(deviceCompFile, data, 0644)105 if err := c.setLoginResource(); err == nil {106 t.Errorf("CheckLoginResDirStruct returns nil, but expect is no consent page")107 }108 t.Logf("no consent page error: %v", err)109 // Error check only once110 if err := os.Remove(otpVerifyFile); err != nil {111 t.Errorf("Failed to delete OTP verify file: %v", err)112 return113 }114 os.Remove(indexFile)115 os.Remove(deviceFile)116 os.Remove(deviceCompFile)117 // Test no OTP verify page118 ioutil.WriteFile(consentFile, data, 0644)119 ioutil.WriteFile(indexFile, data, 0644)120 ioutil.WriteFile(deviceFile, data, 0644)121 ioutil.WriteFile(deviceCompFile, data, 0644)122 if err := c.setLoginResource(); err == nil {123 t.Errorf("CheckLoginResDirStruct returns nil, but expect is no OTP verify page")124 }125 os.Remove(consentFile)126 os.Remove(indexFile)127 os.Remove(deviceFile)128 os.Remove(deviceCompFile)129 // Test no login page130 ioutil.WriteFile(consentFile, data, 0644)131 ioutil.WriteFile(otpVerifyFile, data, 0644)132 ioutil.WriteFile(deviceFile, data, 0644)133 ioutil.WriteFile(deviceCompFile, data, 0644)134 if err := c.setLoginResource(); err == nil {135 t.Errorf("CheckLoginResDirStruct returns nil, but expect is no login page")136 }137 os.Remove(consentFile)138 os.Remove(otpVerifyFile)139 os.Remove(deviceFile)140 os.Remove(deviceCompFile)141 // Test no device login page142 ioutil.WriteFile(consentFile, data, 0644)143 ioutil.WriteFile(otpVerifyFile, data, 0644)144 ioutil.WriteFile(indexFile, data, 0644)145 ioutil.WriteFile(deviceCompFile, data, 0644)146 if err := c.setLoginResource(); err == nil {147 t.Errorf("CheckLoginResDirStruct returns nil, but expect is no device login page")148 }149 os.Remove(consentFile)150 os.Remove(otpVerifyFile)151 os.Remove(indexFile)152 os.Remove(deviceCompFile)153 // Test no device login complete page154 ioutil.WriteFile(consentFile, data, 0644)155 ioutil.WriteFile(otpVerifyFile, data, 0644)156 ioutil.WriteFile(indexFile, data, 0644)157 ioutil.WriteFile(deviceFile, data, 0644)158 if err := c.setLoginResource(); err == nil {159 t.Errorf("CheckLoginResDirStruct returns nil, but expect is no device login complete page")160 }161 os.Remove(consentFile)162 os.Remove(otpVerifyFile)163 os.Remove(indexFile)164 os.Remove(deviceFile)165 // Test ok166 ioutil.WriteFile(consentFile, data, 0644)167 ioutil.WriteFile(otpVerifyFile, data, 0644)168 ioutil.WriteFile(indexFile, data, 0644)169 ioutil.WriteFile(deviceFile, data, 0644)170 ioutil.WriteFile(deviceCompFile, data, 0644)171 if err := c.setLoginResource(); err != nil {172 t.Errorf("CheckLoginResDirStruct returns error %v, but expect is nil", err)173 }174 os.Remove(consentFile)175 os.Remove(otpVerifyFile)176 os.Remove(indexFile)177 os.Remove(deviceFile)178 os.Remove(deviceCompFile)179}180func TestGetServerAddr(t *testing.T) {181 tt := []struct {182 Env string183 Host string184 Expect string185 }{186 {187 Env: "",188 Host: "localhost",189 Expect: "http://localhost",190 },191 {192 Env: "http://localhost",193 Host: "",194 Expect: "http://localhost",195 },196 {197 Env: "http://localhost:8080",198 Host: "localhost",199 Expect: "http://localhost:8080",200 },201 }202 for _, tc := range tt {203 if tc.Env != "" {204 os.Setenv("HEKATE_SERVER_ADDR", tc.Env)205 }206 r, _ := http.NewRequest("GET", "http://"+tc.Host, nil)207 res := GetServerAddr(r)208 if res != tc.Expect {209 t.Errorf("GetServerAddr returns wrong addr. expect %s, but got %s", tc.Expect, res)210 }211 os.Clearenv()212 }213}...
writeFile
Using AI Code Generation
1import (2func main() {3 if err != nil {4 }5 defer resp.Body.Close()6 body, err := ioutil.ReadAll(resp.Body)7 if err != nil {8 }9 err = ioutil.WriteFile("robots.txt", body, 0644)10 if err != nil {11 }12}13import (14func main() {15 if err != nil {16 }17 defer resp.Body.Close()18 body, err := ioutil.ReadAll(resp.Body)19 if err != nil {20 }21 fmt.Printf("%s", body)22}
writeFile
Using AI Code Generation
1import (2func main() {3 if err != nil {4 panic(err)5 }6 f, err := os.Create("robots.txt")7 if err != nil {8 panic(err)9 }10 n, err := io.Copy(f, r.Body)11 if err != nil {12 panic(err)13 }14 fmt.Println("Number of bytes written:", n)15}16import (17func main() {18 if err != nil {19 panic(err)20 }21 defer resp.Body.Close()22 fmt.Println("Response status:", resp.Status)23 fmt.Println("Response headers:", resp.Header)24 body, err := ioutil.ReadAll(resp.Body)25 if err != nil {26 panic(err)27 }28 fmt.Println("Response body:", string(body))29}30import (31func main() {32 if err != nil {33 panic(err)34 }35 defer resp.Body.Close()36 fmt.Println("Response status:", resp.Status)37 fmt.Println("Response headers:", resp.Header)38 body, err := ioutil.ReadAll(resp.Body)39 if err != nil {40 panic(err)41 }42 fmt.Println("Response body:", string(body))43}44import (45func main() {46 if err != nil {47 panic(err)48 }49 defer resp.Body.Close()50 fmt.Println("Response status:", resp.Status)51 fmt.Println("Response headers:", resp.Header)52 body, err := ioutil.ReadAll(resp.Body)53 if err != nil {54 panic(err)55 }56 fmt.Println("Response body:", string(body))57}
writeFile
Using AI Code Generation
1import (2func main() {3 if err != nil {4 fmt.Println(err)5 }6 fmt.Println("Response Status:", resp.Status)7 fmt.Println("Response Headers:", resp.Header)8 body, err := ioutil.ReadAll(resp.Body)9 if err != nil {10 fmt.Println(err)11 }12 fmt.Println("Response Body:", string(body))13}14import (15func main() {16 if err != nil {17 fmt.Println(err)18 }19 defer resp.Body.Close()20 robots, err := ioutil.ReadAll(resp.Body)21 if err != nil {22 fmt.Println(err)23 }24 fmt.Printf("%s", robots)25}26import (27func main() {28 if err != nil {29 fmt.Println(err)30 }31 defer resp.Body.Close()32 robots, err := ioutil.ReadAll(resp.Body)33 if err != nil {34 fmt.Println(err)35 }36 fmt.Printf("%s", robots)37}38import (39func main() {40 if err != nil {41 fmt.Println(err)42 }43 defer resp.Body.Close()44 robots, err := ioutil.ReadAll(resp.Body)45 if err != nil {46 fmt.Println(err)47 }48 fmt.Printf("%s", robots)49}50import (51func main() {52 if err != nil {53 fmt.Println(err)54 }55 defer resp.Body.Close()56 robots, err := ioutil.ReadAll(resp.Body)57 if err != nil {58 fmt.Println(err)59 }60 fmt.Printf("%s", robots)
writeFile
Using AI Code Generation
1import (2func main() {3 err := ioutil.WriteFile("test.txt", []byte("Hello World\n"), 0644)4 if err != nil {5 fmt.Println(err)6 }7 http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {8 data, err := ioutil.ReadFile("test.txt")9 if err != nil {10 fmt.Println(err)11 }12 fmt.Fprintf(w, "Hello World\n")13 fmt.Fprintf(w, string(data))14 })15 http.ListenAndServe(":8080", nil)16}
writeFile
Using AI Code Generation
1import (2func main() {3 if err != nil {4 fmt.Println("Error in reading response")5 }6 defer resp.Body.Close()7 body, err := ioutil.ReadAll(resp.Body)8 if err != nil {9 fmt.Println("Error in reading body")10 }11 fmt.Println(string(body))12}13import (14func main() {15 if err != nil {16 fmt.Println("Error in reading response")17 }18 defer resp.Body.Close()19 body, err := ioutil.ReadAll(resp.Body)20 if err != nil {21 fmt.Println("Error in reading body")22 }23 fmt.Println(string(body))24}
writeFile
Using AI Code Generation
1import (2func main() {3 if err != nil {4 log.Fatalln(err)5 }6 file, err := os.Create("google.txt")7 if err != nil {8 log.Fatalln(err)9 }10 _, err = io.Copy(file, res.Body)11 if err != nil {12 log.Fatalln(err)13 }14 err = file.Close()15 if err != nil {16 log.Fatalln(err)17 }18 err = res.Body.Close()19 if err != nil {20 log.Fatalln(err)21 }22}23import (24func main() {25 if err != nil {26 log.Fatalln(err)27 }28 body, err := ioutil.ReadAll(res.Body)29 if err != nil {30 log.Fatalln(err)31 }32 err = res.Body.Close()33 if err != nil {34 log.Fatalln(err)35 }36 fmt.Printf("%s", body)37}38import (39func main() {40 if err != nil {41 log.Fatalln(err)42 }43 body, err := ioutil.ReadAll(res.Body)44 if err != nil {45 log.Fatalln(err)46 }47 err = res.Body.Close()48 if err != nil {
writeFile
Using AI Code Generation
1func main() {2 resp, err := http.Get(url)3 if err != nil {4 log.Fatal(err)5 }6 defer resp.Body.Close()7 body, err := ioutil.ReadAll(resp.Body)8 if err != nil {9 log.Fatal(err)10 }11 err = ioutil.WriteFile("1.go", body, 0644)12 if err != nil {13 log.Fatal(err)14 }15}16func main() {17 resp, err := http.Get(url)18 if err != nil {19 log.Fatal(err)20 }21 defer resp.Body.Close()22 body, err := ioutil.ReadAll(resp.Body)23 if err != nil {24 log.Fatal(err)25 }26 err = ioutil.WriteFile("2.go", body, 0644)27 if err != nil {28 log.Fatal(err)29 }30}31func main() {32 resp, err := http.Get(url)33 if err != nil {34 log.Fatal(err)35 }36 defer resp.Body.Close()37 body, err := ioutil.ReadAll(resp.Body)38 if err != nil {39 log.Fatal(err)40 }41 err = ioutil.WriteFile("3.go", body, 0644)42 if err != nil {43 log.Fatal(err)44 }45}46func main() {47 resp, err := http.Get(url)48 if err != nil {49 log.Fatal(err)50 }51 defer resp.Body.Close()52 body, err := ioutil.ReadAll(resp.Body)53 if err != nil {54 log.Fatal(err)55 }56 err = ioutil.WriteFile("4.go", body, 0644)57 if err != nil {58 log.Fatal(err)59 }60}
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!!