github.com/shyftnetwork/go-empyrean@v1.8.3-0.20191127201940-fbfca9338f04/whisper/whisperv5/filter_test.go (about) 1 // Copyright 2016 The go-ethereum Authors 2 // This file is part of the go-ethereum library. 3 // 4 // The go-ethereum library is free software: you can redistribute it and/or modify 5 // it under the terms of the GNU Lesser General Public License as published by 6 // the Free Software Foundation, either version 3 of the License, or 7 // (at your option) any later version. 8 // 9 // The go-ethereum library is distributed in the hope that it will be useful, 10 // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 // GNU Lesser General Public License for more details. 13 // 14 // You should have received a copy of the GNU Lesser General Public License 15 // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>. 16 17 package whisperv5 18 19 import ( 20 "math/big" 21 mrand "math/rand" 22 "os" 23 "testing" 24 "time" 25 26 "github.com/ShyftNetwork/go-empyrean/common" 27 "github.com/ShyftNetwork/go-empyrean/crypto" 28 ) 29 30 var seed int64 31 32 func TestMain(m *testing.M) { 33 retCode := m.Run() 34 os.Exit(retCode) 35 } 36 37 // InitSingleTest should be called in the beginning of every 38 // test, which uses RNG, in order to make the tests 39 // reproduciblity independent of their sequence. 40 func InitSingleTest() { 41 seed = time.Now().Unix() 42 mrand.Seed(seed) 43 } 44 45 func InitDebugTest(i int64) { 46 seed = i 47 mrand.Seed(seed) 48 } 49 50 type FilterTestCase struct { 51 f *Filter 52 id string 53 alive bool 54 msgCnt int 55 } 56 57 func generateFilter(t *testing.T, symmetric bool) (*Filter, error) { 58 var f Filter 59 f.Messages = make(map[common.Hash]*ReceivedMessage) 60 61 const topicNum = 8 62 f.Topics = make([][]byte, topicNum) 63 for i := 0; i < topicNum; i++ { 64 f.Topics[i] = make([]byte, 4) 65 mrand.Read(f.Topics[i]) 66 f.Topics[i][0] = 0x01 67 } 68 69 key, err := crypto.GenerateKey() 70 if err != nil { 71 t.Fatalf("generateFilter 1 failed with seed %d.", seed) 72 return nil, err 73 } 74 f.Src = &key.PublicKey 75 76 if symmetric { 77 f.KeySym = make([]byte, aesKeyLength) 78 mrand.Read(f.KeySym) 79 f.SymKeyHash = crypto.Keccak256Hash(f.KeySym) 80 } else { 81 f.KeyAsym, err = crypto.GenerateKey() 82 if err != nil { 83 t.Fatalf("generateFilter 2 failed with seed %d.", seed) 84 return nil, err 85 } 86 } 87 88 // AcceptP2P & PoW are not set 89 return &f, nil 90 } 91 92 func generateTestCases(t *testing.T, SizeTestFilters int) []FilterTestCase { 93 cases := make([]FilterTestCase, SizeTestFilters) 94 for i := 0; i < SizeTestFilters; i++ { 95 f, _ := generateFilter(t, true) 96 cases[i].f = f 97 cases[i].alive = mrand.Int()&int(1) == 0 98 } 99 return cases 100 } 101 102 func TestInstallFilters(t *testing.T) { 103 InitSingleTest() 104 105 const SizeTestFilters = 256 106 w := New(&Config{}) 107 filters := NewFilters(w) 108 tst := generateTestCases(t, SizeTestFilters) 109 110 var err error 111 var j string 112 for i := 0; i < SizeTestFilters; i++ { 113 j, err = filters.Install(tst[i].f) 114 if err != nil { 115 t.Fatalf("seed %d: failed to install filter: %s", seed, err) 116 } 117 tst[i].id = j 118 if len(j) != keyIdSize*2 { 119 t.Fatalf("seed %d: wrong filter id size [%d]", seed, len(j)) 120 } 121 } 122 123 for _, testCase := range tst { 124 if !testCase.alive { 125 filters.Uninstall(testCase.id) 126 } 127 } 128 129 for i, testCase := range tst { 130 fil := filters.Get(testCase.id) 131 exist := fil != nil 132 if exist != testCase.alive { 133 t.Fatalf("seed %d: failed alive: %d, %v, %v", seed, i, exist, testCase.alive) 134 } 135 if exist && fil.PoW != testCase.f.PoW { 136 t.Fatalf("seed %d: failed Get: %d, %v, %v", seed, i, exist, testCase.alive) 137 } 138 } 139 } 140 141 func TestInstallSymKeyGeneratesHash(t *testing.T) { 142 InitSingleTest() 143 144 w := New(&Config{}) 145 filters := NewFilters(w) 146 filter, _ := generateFilter(t, true) 147 148 // save the current SymKeyHash for comparison 149 initialSymKeyHash := filter.SymKeyHash 150 151 // ensure the SymKeyHash is invalid, for Install to recreate it 152 var invalid common.Hash 153 filter.SymKeyHash = invalid 154 155 _, err := filters.Install(filter) 156 157 if err != nil { 158 t.Fatalf("Error installing the filter: %s", err) 159 } 160 161 for i, b := range filter.SymKeyHash { 162 if b != initialSymKeyHash[i] { 163 t.Fatalf("The filter's symmetric key hash was not properly generated by Install") 164 } 165 } 166 } 167 168 func TestInstallIdenticalFilters(t *testing.T) { 169 InitSingleTest() 170 171 w := New(&Config{}) 172 filters := NewFilters(w) 173 filter1, _ := generateFilter(t, true) 174 175 // Copy the first filter since some of its fields 176 // are randomly gnerated. 177 filter2 := &Filter{ 178 KeySym: filter1.KeySym, 179 Topics: filter1.Topics, 180 PoW: filter1.PoW, 181 AllowP2P: filter1.AllowP2P, 182 Messages: make(map[common.Hash]*ReceivedMessage), 183 } 184 185 _, err := filters.Install(filter1) 186 187 if err != nil { 188 t.Fatalf("Error installing the first filter with seed %d: %s", seed, err) 189 } 190 191 _, err = filters.Install(filter2) 192 193 if err != nil { 194 t.Fatalf("Error installing the second filter with seed %d: %s", seed, err) 195 } 196 197 params, err := generateMessageParams() 198 if err != nil { 199 t.Fatalf("Error generating message parameters with seed %d: %s", seed, err) 200 } 201 202 params.KeySym = filter1.KeySym 203 params.Topic = BytesToTopic(filter1.Topics[0]) 204 205 filter1.Src = ¶ms.Src.PublicKey 206 filter2.Src = ¶ms.Src.PublicKey 207 208 sentMessage, err := NewSentMessage(params) 209 if err != nil { 210 t.Fatalf("failed to create new message with seed %d: %s.", seed, err) 211 } 212 env, err := sentMessage.Wrap(params) 213 if err != nil { 214 t.Fatalf("failed Wrap with seed %d: %s.", seed, err) 215 } 216 msg := env.Open(filter1) 217 if msg == nil { 218 t.Fatalf("failed to Open with filter1") 219 } 220 221 if !filter1.MatchEnvelope(env) { 222 t.Fatalf("failed matching with the first filter") 223 } 224 225 if !filter2.MatchEnvelope(env) { 226 t.Fatalf("failed matching with the first filter") 227 } 228 229 if !filter1.MatchMessage(msg) { 230 t.Fatalf("failed matching with the second filter") 231 } 232 233 if !filter2.MatchMessage(msg) { 234 t.Fatalf("failed matching with the second filter") 235 } 236 } 237 238 func TestComparePubKey(t *testing.T) { 239 InitSingleTest() 240 241 key1, err := crypto.GenerateKey() 242 if err != nil { 243 t.Fatalf("failed to generate first key with seed %d: %s.", seed, err) 244 } 245 key2, err := crypto.GenerateKey() 246 if err != nil { 247 t.Fatalf("failed to generate second key with seed %d: %s.", seed, err) 248 } 249 if IsPubKeyEqual(&key1.PublicKey, &key2.PublicKey) { 250 t.Fatalf("public keys are equal, seed %d.", seed) 251 } 252 253 // generate key3 == key1 254 mrand.Seed(seed) 255 key3, err := crypto.GenerateKey() 256 if err != nil { 257 t.Fatalf("failed to generate third key with seed %d: %s.", seed, err) 258 } 259 if IsPubKeyEqual(&key1.PublicKey, &key3.PublicKey) { 260 t.Fatalf("key1 == key3, seed %d.", seed) 261 } 262 } 263 264 func TestMatchEnvelope(t *testing.T) { 265 InitSingleTest() 266 267 fsym, err := generateFilter(t, true) 268 if err != nil { 269 t.Fatalf("failed generateFilter with seed %d: %s.", seed, err) 270 } 271 272 fasym, err := generateFilter(t, false) 273 if err != nil { 274 t.Fatalf("failed generateFilter() with seed %d: %s.", seed, err) 275 } 276 277 params, err := generateMessageParams() 278 if err != nil { 279 t.Fatalf("failed generateMessageParams with seed %d: %s.", seed, err) 280 } 281 282 params.Topic[0] = 0xFF // ensure mismatch 283 284 // mismatch with pseudo-random data 285 msg, err := NewSentMessage(params) 286 if err != nil { 287 t.Fatalf("failed to create new message with seed %d: %s.", seed, err) 288 } 289 env, err := msg.Wrap(params) 290 if err != nil { 291 t.Fatalf("failed Wrap with seed %d: %s.", seed, err) 292 } 293 match := fsym.MatchEnvelope(env) 294 if match { 295 t.Fatalf("failed MatchEnvelope symmetric with seed %d.", seed) 296 } 297 match = fasym.MatchEnvelope(env) 298 if match { 299 t.Fatalf("failed MatchEnvelope asymmetric with seed %d.", seed) 300 } 301 302 // encrypt symmetrically 303 i := mrand.Int() % 4 304 fsym.Topics[i] = params.Topic[:] 305 fasym.Topics[i] = params.Topic[:] 306 msg, err = NewSentMessage(params) 307 if err != nil { 308 t.Fatalf("failed to create new message with seed %d: %s.", seed, err) 309 } 310 env, err = msg.Wrap(params) 311 if err != nil { 312 t.Fatalf("failed Wrap() with seed %d: %s.", seed, err) 313 } 314 315 // symmetric + matching topic: match 316 match = fsym.MatchEnvelope(env) 317 if !match { 318 t.Fatalf("failed MatchEnvelope() symmetric with seed %d.", seed) 319 } 320 321 // asymmetric + matching topic: mismatch 322 match = fasym.MatchEnvelope(env) 323 if match { 324 t.Fatalf("failed MatchEnvelope() asymmetric with seed %d.", seed) 325 } 326 327 // symmetric + matching topic + insufficient PoW: mismatch 328 fsym.PoW = env.PoW() + 1.0 329 match = fsym.MatchEnvelope(env) 330 if match { 331 t.Fatalf("failed MatchEnvelope(symmetric + matching topic + insufficient PoW) asymmetric with seed %d.", seed) 332 } 333 334 // symmetric + matching topic + sufficient PoW: match 335 fsym.PoW = env.PoW() / 2 336 match = fsym.MatchEnvelope(env) 337 if !match { 338 t.Fatalf("failed MatchEnvelope(symmetric + matching topic + sufficient PoW) with seed %d.", seed) 339 } 340 341 // symmetric + topics are nil (wildcard): match 342 prevTopics := fsym.Topics 343 fsym.Topics = nil 344 match = fsym.MatchEnvelope(env) 345 if !match { 346 t.Fatalf("failed MatchEnvelope(symmetric + topics are nil) with seed %d.", seed) 347 } 348 fsym.Topics = prevTopics 349 350 // encrypt asymmetrically 351 key, err := crypto.GenerateKey() 352 if err != nil { 353 t.Fatalf("failed GenerateKey with seed %d: %s.", seed, err) 354 } 355 params.KeySym = nil 356 params.Dst = &key.PublicKey 357 msg, err = NewSentMessage(params) 358 if err != nil { 359 t.Fatalf("failed to create new message with seed %d: %s.", seed, err) 360 } 361 env, err = msg.Wrap(params) 362 if err != nil { 363 t.Fatalf("failed Wrap() with seed %d: %s.", seed, err) 364 } 365 366 // encryption method mismatch 367 match = fsym.MatchEnvelope(env) 368 if match { 369 t.Fatalf("failed MatchEnvelope(encryption method mismatch) with seed %d.", seed) 370 } 371 372 // asymmetric + mismatching topic: mismatch 373 match = fasym.MatchEnvelope(env) 374 if !match { 375 t.Fatalf("failed MatchEnvelope(asymmetric + mismatching topic) with seed %d.", seed) 376 } 377 378 // asymmetric + matching topic: match 379 fasym.Topics[i] = fasym.Topics[i+1] 380 match = fasym.MatchEnvelope(env) 381 if match { 382 t.Fatalf("failed MatchEnvelope(asymmetric + matching topic) with seed %d.", seed) 383 } 384 385 // asymmetric + filter without topic (wildcard): match 386 fasym.Topics = nil 387 match = fasym.MatchEnvelope(env) 388 if !match { 389 t.Fatalf("failed MatchEnvelope(asymmetric + filter without topic) with seed %d.", seed) 390 } 391 392 // asymmetric + insufficient PoW: mismatch 393 fasym.PoW = env.PoW() + 1.0 394 match = fasym.MatchEnvelope(env) 395 if match { 396 t.Fatalf("failed MatchEnvelope(asymmetric + insufficient PoW) with seed %d.", seed) 397 } 398 399 // asymmetric + sufficient PoW: match 400 fasym.PoW = env.PoW() / 2 401 match = fasym.MatchEnvelope(env) 402 if !match { 403 t.Fatalf("failed MatchEnvelope(asymmetric + sufficient PoW) with seed %d.", seed) 404 } 405 406 // filter without topic + envelope without topic: match 407 env.Topic = TopicType{} 408 match = fasym.MatchEnvelope(env) 409 if !match { 410 t.Fatalf("failed MatchEnvelope(filter without topic + envelope without topic) with seed %d.", seed) 411 } 412 413 // filter with topic + envelope without topic: mismatch 414 fasym.Topics = fsym.Topics 415 match = fasym.MatchEnvelope(env) 416 if match { 417 t.Fatalf("failed MatchEnvelope(filter without topic + envelope without topic) with seed %d.", seed) 418 } 419 } 420 421 func TestMatchMessageSym(t *testing.T) { 422 InitSingleTest() 423 424 params, err := generateMessageParams() 425 if err != nil { 426 t.Fatalf("failed generateMessageParams with seed %d: %s.", seed, err) 427 } 428 429 f, err := generateFilter(t, true) 430 if err != nil { 431 t.Fatalf("failed generateFilter with seed %d: %s.", seed, err) 432 } 433 434 const index = 1 435 params.KeySym = f.KeySym 436 params.Topic = BytesToTopic(f.Topics[index]) 437 438 sentMessage, err := NewSentMessage(params) 439 if err != nil { 440 t.Fatalf("failed to create new message with seed %d: %s.", seed, err) 441 } 442 env, err := sentMessage.Wrap(params) 443 if err != nil { 444 t.Fatalf("failed Wrap with seed %d: %s.", seed, err) 445 } 446 msg := env.Open(f) 447 if msg == nil { 448 t.Fatalf("failed Open with seed %d.", seed) 449 } 450 451 // Src: match 452 *f.Src.X = *params.Src.PublicKey.X 453 *f.Src.Y = *params.Src.PublicKey.Y 454 if !f.MatchMessage(msg) { 455 t.Fatalf("failed MatchEnvelope(src match) with seed %d.", seed) 456 } 457 458 // insufficient PoW: mismatch 459 f.PoW = msg.PoW + 1.0 460 if f.MatchMessage(msg) { 461 t.Fatalf("failed MatchEnvelope(insufficient PoW) with seed %d.", seed) 462 } 463 464 // sufficient PoW: match 465 f.PoW = msg.PoW / 2 466 if !f.MatchMessage(msg) { 467 t.Fatalf("failed MatchEnvelope(sufficient PoW) with seed %d.", seed) 468 } 469 470 // topic mismatch 471 f.Topics[index][0]++ 472 if f.MatchMessage(msg) { 473 t.Fatalf("failed MatchEnvelope(topic mismatch) with seed %d.", seed) 474 } 475 f.Topics[index][0]-- 476 477 // key mismatch 478 f.SymKeyHash[0]++ 479 if f.MatchMessage(msg) { 480 t.Fatalf("failed MatchEnvelope(key mismatch) with seed %d.", seed) 481 } 482 f.SymKeyHash[0]-- 483 484 // Src absent: match 485 f.Src = nil 486 if !f.MatchMessage(msg) { 487 t.Fatalf("failed MatchEnvelope(src absent) with seed %d.", seed) 488 } 489 490 // key hash mismatch 491 h := f.SymKeyHash 492 f.SymKeyHash = common.Hash{} 493 if f.MatchMessage(msg) { 494 t.Fatalf("failed MatchEnvelope(key hash mismatch) with seed %d.", seed) 495 } 496 f.SymKeyHash = h 497 if !f.MatchMessage(msg) { 498 t.Fatalf("failed MatchEnvelope(key hash match) with seed %d.", seed) 499 } 500 501 // encryption method mismatch 502 f.KeySym = nil 503 f.KeyAsym, err = crypto.GenerateKey() 504 if err != nil { 505 t.Fatalf("failed GenerateKey with seed %d: %s.", seed, err) 506 } 507 if f.MatchMessage(msg) { 508 t.Fatalf("failed MatchEnvelope(encryption method mismatch) with seed %d.", seed) 509 } 510 } 511 512 func TestMatchMessageAsym(t *testing.T) { 513 InitSingleTest() 514 515 f, err := generateFilter(t, false) 516 if err != nil { 517 t.Fatalf("failed generateFilter with seed %d: %s.", seed, err) 518 } 519 520 params, err := generateMessageParams() 521 if err != nil { 522 t.Fatalf("failed generateMessageParams with seed %d: %s.", seed, err) 523 } 524 525 const index = 1 526 params.Topic = BytesToTopic(f.Topics[index]) 527 params.Dst = &f.KeyAsym.PublicKey 528 keySymOrig := params.KeySym 529 params.KeySym = nil 530 531 sentMessage, err := NewSentMessage(params) 532 if err != nil { 533 t.Fatalf("failed to create new message with seed %d: %s.", seed, err) 534 } 535 env, err := sentMessage.Wrap(params) 536 if err != nil { 537 t.Fatalf("failed Wrap with seed %d: %s.", seed, err) 538 } 539 msg := env.Open(f) 540 if msg == nil { 541 t.Fatalf("failed to open with seed %d.", seed) 542 } 543 544 // Src: match 545 *f.Src.X = *params.Src.PublicKey.X 546 *f.Src.Y = *params.Src.PublicKey.Y 547 if !f.MatchMessage(msg) { 548 t.Fatalf("failed MatchMessage(src match) with seed %d.", seed) 549 } 550 551 // insufficient PoW: mismatch 552 f.PoW = msg.PoW + 1.0 553 if f.MatchMessage(msg) { 554 t.Fatalf("failed MatchEnvelope(insufficient PoW) with seed %d.", seed) 555 } 556 557 // sufficient PoW: match 558 f.PoW = msg.PoW / 2 559 if !f.MatchMessage(msg) { 560 t.Fatalf("failed MatchEnvelope(sufficient PoW) with seed %d.", seed) 561 } 562 563 // topic mismatch 564 f.Topics[index][0]++ 565 if f.MatchMessage(msg) { 566 t.Fatalf("failed MatchEnvelope(topic mismatch) with seed %d.", seed) 567 } 568 f.Topics[index][0]-- 569 570 // key mismatch 571 prev := *f.KeyAsym.PublicKey.X 572 zero := *big.NewInt(0) 573 *f.KeyAsym.PublicKey.X = zero 574 if f.MatchMessage(msg) { 575 t.Fatalf("failed MatchEnvelope(key mismatch) with seed %d.", seed) 576 } 577 *f.KeyAsym.PublicKey.X = prev 578 579 // Src absent: match 580 f.Src = nil 581 if !f.MatchMessage(msg) { 582 t.Fatalf("failed MatchEnvelope(src absent) with seed %d.", seed) 583 } 584 585 // encryption method mismatch 586 f.KeySym = keySymOrig 587 f.KeyAsym = nil 588 if f.MatchMessage(msg) { 589 t.Fatalf("failed MatchEnvelope(encryption method mismatch) with seed %d.", seed) 590 } 591 } 592 593 func cloneFilter(orig *Filter) *Filter { 594 var clone Filter 595 clone.Messages = make(map[common.Hash]*ReceivedMessage) 596 clone.Src = orig.Src 597 clone.KeyAsym = orig.KeyAsym 598 clone.KeySym = orig.KeySym 599 clone.Topics = orig.Topics 600 clone.PoW = orig.PoW 601 clone.AllowP2P = orig.AllowP2P 602 clone.SymKeyHash = orig.SymKeyHash 603 return &clone 604 } 605 606 func generateCompatibeEnvelope(t *testing.T, f *Filter) *Envelope { 607 params, err := generateMessageParams() 608 if err != nil { 609 t.Fatalf("failed generateMessageParams with seed %d: %s.", seed, err) 610 return nil 611 } 612 613 params.KeySym = f.KeySym 614 params.Topic = BytesToTopic(f.Topics[2]) 615 sentMessage, err := NewSentMessage(params) 616 if err != nil { 617 t.Fatalf("failed to create new message with seed %d: %s.", seed, err) 618 } 619 env, err := sentMessage.Wrap(params) 620 if err != nil { 621 t.Fatalf("failed Wrap with seed %d: %s.", seed, err) 622 return nil 623 } 624 return env 625 } 626 627 func TestWatchers(t *testing.T) { 628 InitSingleTest() 629 630 const NumFilters = 16 631 const NumMessages = 256 632 var i int 633 var j uint32 634 var e *Envelope 635 var x, firstID string 636 var err error 637 638 w := New(&Config{}) 639 filters := NewFilters(w) 640 tst := generateTestCases(t, NumFilters) 641 for i = 0; i < NumFilters; i++ { 642 tst[i].f.Src = nil 643 x, err = filters.Install(tst[i].f) 644 if err != nil { 645 t.Fatalf("failed to install filter with seed %d: %s.", seed, err) 646 } 647 tst[i].id = x 648 if len(firstID) == 0 { 649 firstID = x 650 } 651 } 652 653 lastID := x 654 655 var envelopes [NumMessages]*Envelope 656 for i = 0; i < NumMessages; i++ { 657 j = mrand.Uint32() % NumFilters 658 e = generateCompatibeEnvelope(t, tst[j].f) 659 envelopes[i] = e 660 tst[j].msgCnt++ 661 } 662 663 for i = 0; i < NumMessages; i++ { 664 filters.NotifyWatchers(envelopes[i], false) 665 } 666 667 var total int 668 var mail []*ReceivedMessage 669 var count [NumFilters]int 670 671 for i = 0; i < NumFilters; i++ { 672 mail = tst[i].f.Retrieve() 673 count[i] = len(mail) 674 total += len(mail) 675 } 676 677 if total != NumMessages { 678 t.Fatalf("failed with seed %d: total = %d, want: %d.", seed, total, NumMessages) 679 } 680 681 for i = 0; i < NumFilters; i++ { 682 mail = tst[i].f.Retrieve() 683 if len(mail) != 0 { 684 t.Fatalf("failed with seed %d: i = %d.", seed, i) 685 } 686 687 if tst[i].msgCnt != count[i] { 688 t.Fatalf("failed with seed %d: count[%d]: get %d, want %d.", seed, i, tst[i].msgCnt, count[i]) 689 } 690 } 691 692 // another round with a cloned filter 693 694 clone := cloneFilter(tst[0].f) 695 filters.Uninstall(lastID) 696 total = 0 697 last := NumFilters - 1 698 tst[last].f = clone 699 filters.Install(clone) 700 for i = 0; i < NumFilters; i++ { 701 tst[i].msgCnt = 0 702 count[i] = 0 703 } 704 705 // make sure that the first watcher receives at least one message 706 e = generateCompatibeEnvelope(t, tst[0].f) 707 envelopes[0] = e 708 tst[0].msgCnt++ 709 for i = 1; i < NumMessages; i++ { 710 j = mrand.Uint32() % NumFilters 711 e = generateCompatibeEnvelope(t, tst[j].f) 712 envelopes[i] = e 713 tst[j].msgCnt++ 714 } 715 716 for i = 0; i < NumMessages; i++ { 717 filters.NotifyWatchers(envelopes[i], false) 718 } 719 720 for i = 0; i < NumFilters; i++ { 721 mail = tst[i].f.Retrieve() 722 count[i] = len(mail) 723 total += len(mail) 724 } 725 726 combined := tst[0].msgCnt + tst[last].msgCnt 727 if total != NumMessages+count[0] { 728 t.Fatalf("failed with seed %d: total = %d, count[0] = %d.", seed, total, count[0]) 729 } 730 731 if combined != count[0] { 732 t.Fatalf("failed with seed %d: combined = %d, count[0] = %d.", seed, combined, count[0]) 733 } 734 735 if combined != count[last] { 736 t.Fatalf("failed with seed %d: combined = %d, count[last] = %d.", seed, combined, count[last]) 737 } 738 739 for i = 1; i < NumFilters-1; i++ { 740 mail = tst[i].f.Retrieve() 741 if len(mail) != 0 { 742 t.Fatalf("failed with seed %d: i = %d.", seed, i) 743 } 744 745 if tst[i].msgCnt != count[i] { 746 t.Fatalf("failed with seed %d: i = %d, get %d, want %d.", seed, i, tst[i].msgCnt, count[i]) 747 } 748 } 749 750 // test AcceptP2P 751 752 total = 0 753 filters.NotifyWatchers(envelopes[0], true) 754 755 for i = 0; i < NumFilters; i++ { 756 mail = tst[i].f.Retrieve() 757 total += len(mail) 758 } 759 760 if total != 0 { 761 t.Fatalf("failed with seed %d: total: got %d, want 0.", seed, total) 762 } 763 764 f := filters.Get(firstID) 765 if f == nil { 766 t.Fatalf("failed to get the filter with seed %d.", seed) 767 } 768 f.AllowP2P = true 769 total = 0 770 filters.NotifyWatchers(envelopes[0], true) 771 772 for i = 0; i < NumFilters; i++ { 773 mail = tst[i].f.Retrieve() 774 total += len(mail) 775 } 776 777 if total != 1 { 778 t.Fatalf("failed with seed %d: total: got %d, want 1.", seed, total) 779 } 780 } 781 782 func TestVariableTopics(t *testing.T) { 783 InitSingleTest() 784 785 const lastTopicByte = 3 786 var match bool 787 params, err := generateMessageParams() 788 if err != nil { 789 t.Fatalf("failed generateMessageParams with seed %d: %s.", seed, err) 790 } 791 msg, err := NewSentMessage(params) 792 if err != nil { 793 t.Fatalf("failed to create new message with seed %d: %s.", seed, err) 794 } 795 env, err := msg.Wrap(params) 796 if err != nil { 797 t.Fatalf("failed Wrap with seed %d: %s.", seed, err) 798 } 799 800 f, err := generateFilter(t, true) 801 if err != nil { 802 t.Fatalf("failed generateFilter with seed %d: %s.", seed, err) 803 } 804 805 for i := 0; i < 4; i++ { 806 env.Topic = BytesToTopic(f.Topics[i]) 807 match = f.MatchEnvelope(env) 808 if !match { 809 t.Fatalf("failed MatchEnvelope symmetric with seed %d, step %d.", seed, i) 810 } 811 812 f.Topics[i][lastTopicByte]++ 813 match = f.MatchEnvelope(env) 814 if match { 815 t.Fatalf("MatchEnvelope symmetric with seed %d, step %d: false positive.", seed, i) 816 } 817 } 818 } 819 820 func TestMatchSingleTopic_ReturnTrue(t *testing.T) { 821 bt := []byte("test") 822 topic := BytesToTopic(bt) 823 824 if !matchSingleTopic(topic, bt) { 825 t.FailNow() 826 } 827 } 828 829 func TestMatchSingleTopic_WithTail_ReturnTrue(t *testing.T) { 830 bt := []byte("test with tail") 831 topic := BytesToTopic([]byte("test")) 832 833 if !matchSingleTopic(topic, bt) { 834 t.FailNow() 835 } 836 } 837 838 func TestMatchSingleTopic_PartialTopic_ReturnTrue(t *testing.T) { 839 bt := []byte("tes") 840 topic := BytesToTopic([]byte("test")) 841 842 if !matchSingleTopic(topic, bt) { 843 t.FailNow() 844 } 845 } 846 847 func TestMatchSingleTopic_NotEquals_ReturnFalse(t *testing.T) { 848 bt := []byte("test") 849 topic := BytesToTopic([]byte("not_equal")) 850 851 if matchSingleTopic(topic, bt) { 852 t.FailNow() 853 } 854 }