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