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