github.com/Jeffail/benthos/v3@v3.65.0/lib/message/message_test.go (about) 1 package message 2 3 import ( 4 "reflect" 5 "testing" 6 7 "github.com/Jeffail/benthos/v3/lib/message/metadata" 8 "github.com/Jeffail/benthos/v3/lib/types" 9 "github.com/stretchr/testify/assert" 10 ) 11 12 func TestMessageSerialization(t *testing.T) { 13 m := New([][]byte{ 14 []byte("hello"), 15 []byte("world"), 16 []byte("12345"), 17 }) 18 19 b := ToBytes(m) 20 21 m2, err := FromBytes(b) 22 23 if err != nil { 24 t.Error(err) 25 return 26 } 27 28 if !reflect.DeepEqual(GetAllBytes(m), GetAllBytes(m2)) { 29 t.Errorf("Messages not equal: %v != %v", m, m2) 30 } 31 } 32 33 func TestNew(t *testing.T) { 34 m := New(nil) 35 if act := m.Len(); act > 0 { 36 t.Errorf("New returned more than zero message parts: %v", act) 37 } 38 } 39 40 func TestIter(t *testing.T) { 41 parts := [][]byte{ 42 []byte(`foo`), 43 []byte(`bar`), 44 []byte(`baz`), 45 } 46 m := New(parts) 47 iters := 0 48 m.Iter(func(index int, b types.Part) error { 49 if exp, act := string(parts[index]), string(b.Get()); exp != act { 50 t.Errorf("Unexpected part: %v != %v", act, exp) 51 } 52 iters++ 53 return nil 54 }) 55 if exp, act := 3, iters; exp != act { 56 t.Errorf("Wrong count of iterations: %v != %v", act, exp) 57 } 58 } 59 60 func TestMessageInvalidBytesFormat(t *testing.T) { 61 cases := [][]byte{ 62 []byte(``), 63 []byte(`this is invalid`), 64 {0x00, 0x00}, 65 {0x00, 0x00, 0x00, 0x05}, 66 {0x00, 0x00, 0x00, 0x01, 0x00, 0x00}, 67 {0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02}, 68 {0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00}, 69 } 70 71 for _, c := range cases { 72 if _, err := FromBytes(c); err == nil { 73 t.Errorf("Received nil error from invalid byte sequence: %s", c) 74 } 75 } 76 } 77 78 func TestMessageIncompleteJSON(t *testing.T) { 79 tests := []struct { 80 message string 81 err string 82 }{ 83 {message: "{}"}, 84 { 85 message: "{} not foo", 86 err: "invalid character 'o' in literal null (expecting 'u')", 87 }, 88 { 89 message: "{} {}", 90 err: "message contains multiple valid documents", 91 }, 92 {message: `["foo"] `}, 93 {message: ` ["foo"] `}, 94 {message: ` ["foo"] 95 96 `}, 97 { 98 message: ` ["foo"] 99 100 101 102 {}`, 103 err: "message contains multiple valid documents", 104 }, 105 } 106 107 for _, test := range tests { 108 msg := New([][]byte{[]byte(test.message)}) 109 _, err := msg.Get(0).JSON() 110 if test.err == "" { 111 assert.NoError(t, err) 112 } else { 113 assert.EqualError(t, err, test.err) 114 } 115 } 116 } 117 118 func TestMessageJSONGet(t *testing.T) { 119 msg := New( 120 [][]byte{[]byte(`{"foo":{"bar":"baz"}}`)}, 121 ) 122 123 if _, err := msg.Get(1).JSON(); err == nil { 124 t.Error("Error not returned on bad part") 125 } 126 127 jObj, err := msg.Get(0).JSON() 128 if err != nil { 129 t.Error(err) 130 } 131 132 exp := map[string]interface{}{ 133 "foo": map[string]interface{}{ 134 "bar": "baz", 135 }, 136 } 137 if act := jObj; !reflect.DeepEqual(act, exp) { 138 t.Errorf("Wrong output from jsonGet: %v != %v", act, exp) 139 } 140 141 msg.Get(0).Set([]byte(`{"foo":{"bar":"baz2"}}`)) 142 143 jObj, err = msg.Get(0).JSON() 144 if err != nil { 145 t.Error(err) 146 } 147 148 exp = map[string]interface{}{ 149 "foo": map[string]interface{}{ 150 "bar": "baz2", 151 }, 152 } 153 if act := jObj; !reflect.DeepEqual(act, exp) { 154 t.Errorf("Wrong output from jsonGet: %v != %v", act, exp) 155 } 156 } 157 158 func TestMessageJSONSet(t *testing.T) { 159 msg := New([][]byte{[]byte(`hello world`)}) 160 161 msg.Get(1).SetJSON(nil) 162 163 p1Obj := map[string]interface{}{ 164 "foo": map[string]interface{}{ 165 "bar": "baz", 166 }, 167 } 168 p1Str := `{"foo":{"bar":"baz"}}` 169 170 p2Obj := map[string]interface{}{ 171 "baz": map[string]interface{}{ 172 "bar": "foo", 173 }, 174 } 175 p2Str := `{"baz":{"bar":"foo"}}` 176 177 if err := msg.Get(0).SetJSON(p1Obj); err != nil { 178 t.Fatal(err) 179 } 180 if exp, act := p1Str, string(msg.Get(0).Get()); exp != act { 181 t.Errorf("Wrong json blob: %v != %v", act, exp) 182 } 183 184 if err := msg.Get(0).SetJSON(p2Obj); err != nil { 185 t.Fatal(err) 186 } 187 if exp, act := p2Str, string(msg.Get(0).Get()); exp != act { 188 t.Errorf("Wrong json blob: %v != %v", act, exp) 189 } 190 191 if err := msg.Get(0).SetJSON(p1Obj); err != nil { 192 t.Fatal(err) 193 } 194 if exp, act := p1Str, string(msg.Get(0).Get()); exp != act { 195 t.Errorf("Wrong json blob: %v != %v", act, exp) 196 } 197 } 198 199 func TestMessageMetadata(t *testing.T) { 200 m := New([][]byte{ 201 []byte("foo"), 202 []byte("bar"), 203 }) 204 205 m.Get(0).Metadata().Set("foo", "bar") 206 if exp, act := "bar", m.Get(0).Metadata().Get("foo"); exp != act { 207 t.Errorf("Wrong result: %v != %v", act, exp) 208 } 209 210 m.Get(0).Metadata().Set("foo", "bar2") 211 if exp, act := "bar2", m.Get(0).Metadata().Get("foo"); exp != act { 212 t.Errorf("Wrong result: %v != %v", act, exp) 213 } 214 215 m.Get(0).Metadata().Set("bar", "baz") 216 m.Get(0).Metadata().Set("baz", "qux") 217 218 exp := map[string]string{ 219 "foo": "bar2", 220 "bar": "baz", 221 "baz": "qux", 222 } 223 act := map[string]string{} 224 m.Get(0).Metadata().Iter(func(k, v string) error { 225 act[k] = v 226 return nil 227 }) 228 if !reflect.DeepEqual(exp, act) { 229 t.Errorf("Wrong result: %s != %s", act, exp) 230 } 231 232 newMetadata := metadata.New(map[string]string{ 233 "foo": "new1", 234 "bar": "new2", 235 "baz": "new3", 236 }) 237 m.Get(0).SetMetadata(newMetadata) 238 if exp, act := "new1", m.Get(0).Metadata().Get("foo"); exp != act { 239 t.Errorf("Wrong result: %v != %v", act, exp) 240 } 241 if exp, act := "new2", m.Get(0).Metadata().Get("bar"); exp != act { 242 t.Errorf("Wrong result: %v != %v", act, exp) 243 } 244 if exp, act := "", m.Get(-1).Metadata().Get("foo"); exp != act { 245 t.Errorf("Wrong result: %v != %v", act, exp) 246 } 247 if exp, act := "", m.Get(100).Metadata().Get("foo"); exp != act { 248 t.Errorf("Wrong result: %v != %v", act, exp) 249 } 250 251 m.Get(0).SetMetadata(newMetadata) 252 m.Get(1).SetMetadata(newMetadata) 253 if exp, act := "new1", m.Get(0).Metadata().Get("foo"); exp != act { 254 t.Errorf("Wrong result: %v != %v", act, exp) 255 } 256 if exp, act := "new1", m.Get(1).Metadata().Get("foo"); exp != act { 257 t.Errorf("Wrong result: %v != %v", act, exp) 258 } 259 260 newMetadata = metadata.New(map[string]string{ 261 "foo": "more_new", 262 }) 263 m.Iter(func(i int, p types.Part) error { 264 p.SetMetadata(newMetadata) 265 return nil 266 }) 267 if exp, act := "more_new", m.Get(0).Metadata().Get("foo"); exp != act { 268 t.Errorf("Wrong result: %v != %v", act, exp) 269 } 270 if exp, act := "more_new", m.Get(1).Metadata().Get("foo"); exp != act { 271 t.Errorf("Wrong result: %v != %v", act, exp) 272 } 273 } 274 275 func TestMessageCopy(t *testing.T) { 276 m := New([][]byte{ 277 []byte(`foo`), 278 []byte(`bar`), 279 }) 280 m.Get(0).Metadata().Set("foo", "bar") 281 282 m2 := m.Copy() 283 if exp, act := [][]byte{[]byte(`foo`), []byte(`bar`)}, GetAllBytes(m2); !reflect.DeepEqual(exp, act) { 284 t.Errorf("Wrong result: %s != %s", act, exp) 285 } 286 if exp, act := "bar", m2.Get(0).Metadata().Get("foo"); exp != act { 287 t.Errorf("Wrong result: %v != %v", act, exp) 288 } 289 290 m2.Get(0).Metadata().Set("foo", "bar2") 291 m2.Get(0).Set([]byte(`baz`)) 292 if exp, act := [][]byte{[]byte(`baz`), []byte(`bar`)}, GetAllBytes(m2); !reflect.DeepEqual(exp, act) { 293 t.Errorf("Wrong result: %s != %s", act, exp) 294 } 295 if exp, act := "bar2", m2.Get(0).Metadata().Get("foo"); exp != act { 296 t.Errorf("Wrong result: %v != %v", act, exp) 297 } 298 if exp, act := [][]byte{[]byte(`foo`), []byte(`bar`)}, GetAllBytes(m); !reflect.DeepEqual(exp, act) { 299 t.Errorf("Wrong result: %s != %s", act, exp) 300 } 301 if exp, act := "bar", m.Get(0).Metadata().Get("foo"); exp != act { 302 t.Errorf("Wrong result: %v != %v", act, exp) 303 } 304 } 305 306 func TestMessageDeepCopy(t *testing.T) { 307 m := New([][]byte{ 308 []byte(`foo`), 309 []byte(`bar`), 310 }) 311 m.Get(0).Metadata().Set("foo", "bar") 312 313 m2 := m.DeepCopy() 314 if exp, act := [][]byte{[]byte(`foo`), []byte(`bar`)}, GetAllBytes(m2); !reflect.DeepEqual(exp, act) { 315 t.Errorf("Wrong result: %s != %s", act, exp) 316 } 317 if exp, act := "bar", m2.Get(0).Metadata().Get("foo"); exp != act { 318 t.Errorf("Wrong result: %v != %v", act, exp) 319 } 320 321 m2.Get(0).Metadata().Set("foo", "bar2") 322 m2.Get(0).Set([]byte(`baz`)) 323 if exp, act := [][]byte{[]byte(`baz`), []byte(`bar`)}, GetAllBytes(m2); !reflect.DeepEqual(exp, act) { 324 t.Errorf("Wrong result: %s != %s", act, exp) 325 } 326 if exp, act := "bar2", m2.Get(0).Metadata().Get("foo"); exp != act { 327 t.Errorf("Wrong result: %v != %v", act, exp) 328 } 329 if exp, act := [][]byte{[]byte(`foo`), []byte(`bar`)}, GetAllBytes(m); !reflect.DeepEqual(exp, act) { 330 t.Errorf("Wrong result: %s != %s", act, exp) 331 } 332 if exp, act := "bar", m.Get(0).Metadata().Get("foo"); exp != act { 333 t.Errorf("Wrong result: %v != %v", act, exp) 334 } 335 } 336 337 func TestMessageJSONSetGet(t *testing.T) { 338 msg := New([][]byte{[]byte(`hello world`)}) 339 340 p1Obj := map[string]interface{}{ 341 "foo": map[string]interface{}{ 342 "bar": "baz", 343 }, 344 } 345 p1Str := `{"foo":{"bar":"baz"}}` 346 347 p2Obj := map[string]interface{}{ 348 "baz": map[string]interface{}{ 349 "bar": "foo", 350 }, 351 } 352 p2Str := `{"baz":{"bar":"foo"}}` 353 354 var err error 355 var jObj interface{} 356 357 if err = msg.Get(0).SetJSON(p1Obj); err != nil { 358 t.Fatal(err) 359 } 360 if exp, act := p1Str, string(msg.Get(0).Get()); exp != act { 361 t.Errorf("Wrong json blob: %v != %v", act, exp) 362 } 363 if jObj, err = msg.Get(0).JSON(); err != nil { 364 t.Fatal(err) 365 } 366 if exp, act := p1Obj, jObj; !reflect.DeepEqual(exp, act) { 367 t.Errorf("Wrong json obj: %v != %v", act, exp) 368 } 369 370 if err := msg.Get(0).SetJSON(p2Obj); err != nil { 371 t.Fatal(err) 372 } 373 if exp, act := p2Str, string(msg.Get(0).Get()); exp != act { 374 t.Errorf("Wrong json blob: %v != %v", act, exp) 375 } 376 if jObj, err = msg.Get(0).JSON(); err != nil { 377 t.Fatal(err) 378 } 379 if exp, act := p2Obj, jObj; !reflect.DeepEqual(exp, act) { 380 t.Errorf("Wrong json obj: %v != %v", act, exp) 381 } 382 383 if err := msg.Get(0).SetJSON(p1Obj); err != nil { 384 t.Fatal(err) 385 } 386 if exp, act := p1Str, string(msg.Get(0).Get()); exp != act { 387 t.Errorf("Wrong json blob: %v != %v", act, exp) 388 } 389 if jObj, err = msg.Get(0).JSON(); err != nil { 390 t.Fatal(err) 391 } 392 if exp, act := p1Obj, jObj; !reflect.DeepEqual(exp, act) { 393 t.Errorf("Wrong json obj: %v != %v", act, exp) 394 } 395 } 396 397 func TestMessageSplitJSON(t *testing.T) { 398 msg1 := New([][]byte{ 399 []byte("Foo plain text"), 400 []byte(`nothing here`), 401 }) 402 403 if err := msg1.Get(1).SetJSON(map[string]interface{}{"foo": "bar"}); err != nil { 404 t.Fatal(err) 405 } 406 407 msg2 := msg1.Copy() 408 409 if exp, act := GetAllBytes(msg1), GetAllBytes(msg2); !reflect.DeepEqual(exp, act) { 410 t.Errorf("Parts unmatched from shallow copy: %s != %s", act, exp) 411 } 412 413 msg2.Get(0).Set([]byte("Bar different text")) 414 415 if exp, act := "Foo plain text", string(msg1.Get(0).Get()); exp != act { 416 t.Errorf("Original content was changed from shallow copy: %v != %v", act, exp) 417 } 418 419 //------------------ 420 421 if err := msg1.Get(1).SetJSON(map[string]interface{}{"foo": "baz"}); err != nil { 422 t.Fatal(err) 423 } 424 425 jCont, err := msg1.Get(1).JSON() 426 if err != nil { 427 t.Fatal(err) 428 } 429 if exp, act := map[string]interface{}{"foo": "baz"}, jCont; !reflect.DeepEqual(exp, act) { 430 t.Errorf("Unexpected json content: %v != %v", exp, act) 431 } 432 if exp, act := `{"foo":"baz"}`, string(msg1.Get(1).Get()); exp != act { 433 t.Errorf("Unexpected original content: %v != %v", act, exp) 434 } 435 436 jCont, err = msg2.Get(1).JSON() 437 if err != nil { 438 t.Fatal(err) 439 } 440 if exp, act := map[string]interface{}{"foo": "bar"}, jCont; !reflect.DeepEqual(exp, act) { 441 t.Errorf("Unexpected json content: %v != %v", exp, act) 442 } 443 if exp, act := `{"foo":"bar"}`, string(msg2.Get(1).Get()); exp != act { 444 t.Errorf("Unexpected shallow content: %v != %v", act, exp) 445 } 446 447 //------------------ 448 449 if err = msg2.Get(1).SetJSON(map[string]interface{}{"foo": "baz2"}); err != nil { 450 t.Fatal(err) 451 } 452 453 jCont, err = msg2.Get(1).JSON() 454 if err != nil { 455 t.Fatal(err) 456 } 457 if exp, act := map[string]interface{}{"foo": "baz2"}, jCont; !reflect.DeepEqual(exp, act) { 458 t.Errorf("Unexpected json content: %v != %v", exp, act) 459 } 460 if exp, act := `{"foo":"baz2"}`, string(msg2.Get(1).Get()); exp != act { 461 t.Errorf("Unexpected shallow copy content: %v != %v", act, exp) 462 } 463 464 jCont, err = msg1.Get(1).JSON() 465 if err != nil { 466 t.Fatal(err) 467 } 468 if exp, act := map[string]interface{}{"foo": "baz"}, jCont; !reflect.DeepEqual(exp, act) { 469 t.Errorf("Unexpected original json content: %v != %v", exp, act) 470 } 471 if exp, act := `{"foo":"baz"}`, string(msg1.Get(1).Get()); exp != act { 472 t.Errorf("Unexpected original content: %v != %v", act, exp) 473 } 474 } 475 476 /* 477 type dummyCond struct { 478 call func(m types.Message) bool 479 calls int 480 } 481 482 func (d *dummyCond) Check(m types.Message) bool { 483 d.calls++ 484 return d.call(m) 485 } 486 487 func TestMessageConditionCaching(t *testing.T) { 488 msg := New([][]byte{ 489 []byte(`foo`), 490 }) 491 492 dummyCond1 := &dummyCond{ 493 call: func(m types.Message) bool { 494 return string(m.Get(0).Get()) == "foo" 495 }, 496 } 497 dummyCond2 := &dummyCond{ 498 call: func(m types.Message) bool { 499 return string(m.Get(0).Get()) == "bar" 500 }, 501 } 502 503 if !msg.LazyCondition("1", dummyCond1) { 504 t.Error("Wrong result from cond 1") 505 } 506 if !msg.LazyCondition("1", dummyCond1) { 507 t.Error("Wrong result from cached cond 1") 508 } 509 if !msg.LazyCondition("1", dummyCond2) { 510 t.Error("Wrong result from cached cond 1 with cond 2") 511 } 512 513 if msg.LazyCondition("2", dummyCond2) { 514 t.Error("Wrong result from cond 2") 515 } 516 if msg.LazyCondition("2", dummyCond2) { 517 t.Error("Wrong result from cached cond 2") 518 } 519 520 if exp, act := 1, dummyCond1.calls; exp != act { 521 t.Errorf("Wrong count of calls for cond 1: %v != %v", act, exp) 522 } 523 if exp, act := 1, dummyCond2.calls; exp != act { 524 t.Errorf("Wrong count of calls for cond 2: %v != %v", act, exp) 525 } 526 527 msg.Get(0).Set([]byte("bar")) 528 529 if msg.LazyCondition("1", dummyCond1) { 530 t.Error("Wrong result from cond 1") 531 } 532 if msg.LazyCondition("1", dummyCond1) { 533 t.Error("Wrong result from cached cond 1") 534 } 535 if msg.LazyCondition("1", dummyCond2) { 536 t.Error("Wrong result from cached cond 1 with cond 2") 537 } 538 539 if !msg.LazyCondition("2", dummyCond2) { 540 t.Error("Wrong result from cond 2") 541 } 542 if !msg.LazyCondition("2", dummyCond2) { 543 t.Error("Wrong result from cached cond 2") 544 } 545 546 if exp, act := 2, dummyCond1.calls; exp != act { 547 t.Errorf("Wrong count of calls for cond 1: %v != %v", act, exp) 548 } 549 if exp, act := 2, dummyCond2.calls; exp != act { 550 t.Errorf("Wrong count of calls for cond 2: %v != %v", act, exp) 551 } 552 } 553 */ 554 555 func TestMessageCrossContaminateJSON(t *testing.T) { 556 msg1 := New([][]byte{ 557 []byte(`{"foo":"bar"}`), 558 }) 559 560 var jCont1, jCont2 interface{} 561 var err error 562 563 if jCont1, err = msg1.Get(0).JSON(); err != nil { 564 t.Fatal(err) 565 } 566 567 msg2 := msg1.DeepCopy() 568 569 jMap1, ok := jCont1.(map[string]interface{}) 570 if !ok { 571 t.Fatal("Couldnt cast to map") 572 } 573 jMap1["foo"] = "baz" 574 575 if err = msg1.Get(0).SetJSON(jMap1); err != nil { 576 t.Fatal(err) 577 } 578 579 if jCont1, err = msg1.Get(0).JSON(); err != nil { 580 t.Fatal(err) 581 } 582 if exp, act := map[string]interface{}{"foo": "baz"}, jCont1; !reflect.DeepEqual(exp, act) { 583 t.Errorf("Unexpected json content: %v != %v", exp, act) 584 } 585 if exp, act := `{"foo":"baz"}`, string(msg1.Get(0).Get()); exp != act { 586 t.Errorf("Unexpected raw content: %v != %v", exp, act) 587 } 588 589 if jCont2, err = msg2.Get(0).JSON(); err != nil { 590 t.Fatal(err) 591 } 592 if exp, act := map[string]interface{}{"foo": "bar"}, jCont2; !reflect.DeepEqual(exp, act) { 593 t.Errorf("Unexpected json content: %v != %v", exp, act) 594 } 595 if exp, act := `{"foo":"bar"}`, string(msg2.Get(0).Get()); exp != act { 596 t.Errorf("Unexpected raw content: %v != %v", exp, act) 597 } 598 } 599 600 func BenchmarkJSONGet(b *testing.B) { 601 sample1 := []byte(`{ 602 "foo":{ 603 "bar":"baz", 604 "this":{ 605 "will":{ 606 "be":{ 607 "very":{ 608 "nested":true 609 } 610 }, 611 "dont_forget":"me" 612 }, 613 "dont_forget":"me" 614 }, 615 "dont_forget":"me" 616 }, 617 "numbers": [0,1,2,3,4,5,6,7] 618 }`) 619 sample2 := []byte(`{ 620 "foo2":{ 621 "bar":"baz2", 622 "this":{ 623 "will":{ 624 "be":{ 625 "very":{ 626 "nested":false 627 } 628 }, 629 "dont_forget":"me too" 630 }, 631 "dont_forget":"me too" 632 }, 633 "dont_forget":"me too" 634 }, 635 "numbers": [0,1,2,3,4,5,6,7] 636 }`) 637 638 b.ReportAllocs() 639 b.ResetTimer() 640 for i := 0; i < b.N; i++ { 641 msg := New([][]byte{sample1}) 642 643 jObj, err := msg.Get(0).JSON() 644 if err != nil { 645 b.Error(err) 646 } 647 if _, ok := jObj.(map[string]interface{}); !ok { 648 b.Error("Couldn't cast to map") 649 } 650 651 jObj, err = msg.Get(0).JSON() 652 if err != nil { 653 b.Error(err) 654 } 655 if _, ok := jObj.(map[string]interface{}); !ok { 656 b.Error("Couldn't cast to map") 657 } 658 659 msg.Get(0).Set(sample2) 660 661 jObj, err = msg.Get(0).JSON() 662 if err != nil { 663 b.Error(err) 664 } 665 if _, ok := jObj.(map[string]interface{}); !ok { 666 b.Error("Couldn't cast to map") 667 } 668 } 669 }