github.com/SmartMeshFoundation/Spectrum@v0.0.0-20220621030607-452a266fee1e/whisper/whisperv5/filter_test.go (about) 1 // Copyright 2016 The Spectrum Authors 2 // This file is part of the Spectrum library. 3 // 4 // The Spectrum 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 Spectrum 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 Spectrum library. If not, see <http://www.gnu.org/licenses/>. 16 17 package whisperv5 18 19 import ( 20 "math/big" 21 mrand "math/rand" 22 "testing" 23 "time" 24 25 "github.com/SmartMeshFoundation/Spectrum/common" 26 "github.com/SmartMeshFoundation/Spectrum/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 TestComparePubKey(t *testing.T) { 233 InitSingleTest() 234 235 key1, err := crypto.GenerateKey() 236 if err != nil { 237 t.Fatalf("failed to generate first key with seed %d: %s.", seed, err) 238 } 239 key2, err := crypto.GenerateKey() 240 if err != nil { 241 t.Fatalf("failed to generate second key with seed %d: %s.", seed, err) 242 } 243 if IsPubKeyEqual(&key1.PublicKey, &key2.PublicKey) { 244 t.Fatalf("public keys are equal, seed %d.", seed) 245 } 246 247 // generate key3 == key1 248 mrand.Seed(seed) 249 key3, err := crypto.GenerateKey() 250 if err != nil { 251 t.Fatalf("failed to generate third key with seed %d: %s.", seed, err) 252 } 253 if IsPubKeyEqual(&key1.PublicKey, &key3.PublicKey) { 254 t.Fatalf("key1 == key3, seed %d.", seed) 255 } 256 } 257 258 func TestMatchEnvelope(t *testing.T) { 259 InitSingleTest() 260 261 fsym, err := generateFilter(t, true) 262 if err != nil { 263 t.Fatalf("failed generateFilter with seed %d: %s.", seed, err) 264 } 265 266 fasym, err := generateFilter(t, false) 267 if err != nil { 268 t.Fatalf("failed generateFilter() with seed %d: %s.", seed, err) 269 } 270 271 params, err := generateMessageParams() 272 if err != nil { 273 t.Fatalf("failed generateMessageParams with seed %d: %s.", seed, err) 274 } 275 276 params.Topic[0] = 0xFF // ensure mismatch 277 278 // mismatch with pseudo-random data 279 msg, err := NewSentMessage(params) 280 if err != nil { 281 t.Fatalf("failed to create new message with seed %d: %s.", seed, err) 282 } 283 env, err := msg.Wrap(params) 284 if err != nil { 285 t.Fatalf("failed Wrap with seed %d: %s.", seed, err) 286 } 287 match := fsym.MatchEnvelope(env) 288 if match { 289 t.Fatalf("failed MatchEnvelope symmetric with seed %d.", seed) 290 } 291 match = fasym.MatchEnvelope(env) 292 if match { 293 t.Fatalf("failed MatchEnvelope asymmetric with seed %d.", seed) 294 } 295 296 // encrypt symmetrically 297 i := mrand.Int() % 4 298 fsym.Topics[i] = params.Topic[:] 299 fasym.Topics[i] = params.Topic[:] 300 msg, err = NewSentMessage(params) 301 if err != nil { 302 t.Fatalf("failed to create new message with seed %d: %s.", seed, err) 303 } 304 env, err = msg.Wrap(params) 305 if err != nil { 306 t.Fatalf("failed Wrap() with seed %d: %s.", seed, err) 307 } 308 309 // symmetric + matching topic: match 310 match = fsym.MatchEnvelope(env) 311 if !match { 312 t.Fatalf("failed MatchEnvelope() symmetric with seed %d.", seed) 313 } 314 315 // asymmetric + matching topic: mismatch 316 match = fasym.MatchEnvelope(env) 317 if match { 318 t.Fatalf("failed MatchEnvelope() asymmetric with seed %d.", seed) 319 } 320 321 // symmetric + matching topic + insufficient PoW: mismatch 322 fsym.PoW = env.PoW() + 1.0 323 match = fsym.MatchEnvelope(env) 324 if match { 325 t.Fatalf("failed MatchEnvelope(symmetric + matching topic + insufficient PoW) asymmetric with seed %d.", seed) 326 } 327 328 // symmetric + matching topic + sufficient PoW: match 329 fsym.PoW = env.PoW() / 2 330 match = fsym.MatchEnvelope(env) 331 if !match { 332 t.Fatalf("failed MatchEnvelope(symmetric + matching topic + sufficient PoW) with seed %d.", seed) 333 } 334 335 // symmetric + topics are nil (wildcard): match 336 prevTopics := fsym.Topics 337 fsym.Topics = nil 338 match = fsym.MatchEnvelope(env) 339 if !match { 340 t.Fatalf("failed MatchEnvelope(symmetric + topics are nil) with seed %d.", seed) 341 } 342 fsym.Topics = prevTopics 343 344 // encrypt asymmetrically 345 key, err := crypto.GenerateKey() 346 if err != nil { 347 t.Fatalf("failed GenerateKey with seed %d: %s.", seed, err) 348 } 349 params.KeySym = nil 350 params.Dst = &key.PublicKey 351 msg, err = NewSentMessage(params) 352 if err != nil { 353 t.Fatalf("failed to create new message with seed %d: %s.", seed, err) 354 } 355 env, err = msg.Wrap(params) 356 if err != nil { 357 t.Fatalf("failed Wrap() with seed %d: %s.", seed, err) 358 } 359 360 // encryption method mismatch 361 match = fsym.MatchEnvelope(env) 362 if match { 363 t.Fatalf("failed MatchEnvelope(encryption method mismatch) with seed %d.", seed) 364 } 365 366 // asymmetric + mismatching topic: mismatch 367 match = fasym.MatchEnvelope(env) 368 if !match { 369 t.Fatalf("failed MatchEnvelope(asymmetric + mismatching topic) with seed %d.", seed) 370 } 371 372 // asymmetric + matching topic: match 373 fasym.Topics[i] = fasym.Topics[i+1] 374 match = fasym.MatchEnvelope(env) 375 if match { 376 t.Fatalf("failed MatchEnvelope(asymmetric + matching topic) with seed %d.", seed) 377 } 378 379 // asymmetric + filter without topic (wildcard): match 380 fasym.Topics = nil 381 match = fasym.MatchEnvelope(env) 382 if !match { 383 t.Fatalf("failed MatchEnvelope(asymmetric + filter without topic) with seed %d.", seed) 384 } 385 386 // asymmetric + insufficient PoW: mismatch 387 fasym.PoW = env.PoW() + 1.0 388 match = fasym.MatchEnvelope(env) 389 if match { 390 t.Fatalf("failed MatchEnvelope(asymmetric + insufficient PoW) with seed %d.", seed) 391 } 392 393 // asymmetric + sufficient PoW: match 394 fasym.PoW = env.PoW() / 2 395 match = fasym.MatchEnvelope(env) 396 if !match { 397 t.Fatalf("failed MatchEnvelope(asymmetric + sufficient PoW) with seed %d.", seed) 398 } 399 400 // filter without topic + envelope without topic: match 401 env.Topic = TopicType{} 402 match = fasym.MatchEnvelope(env) 403 if !match { 404 t.Fatalf("failed MatchEnvelope(filter without topic + envelope without topic) with seed %d.", seed) 405 } 406 407 // filter with topic + envelope without topic: mismatch 408 fasym.Topics = fsym.Topics 409 match = fasym.MatchEnvelope(env) 410 if match { 411 t.Fatalf("failed MatchEnvelope(filter without topic + envelope without topic) with seed %d.", seed) 412 } 413 } 414 415 func TestMatchMessageSym(t *testing.T) { 416 InitSingleTest() 417 418 params, err := generateMessageParams() 419 if err != nil { 420 t.Fatalf("failed generateMessageParams with seed %d: %s.", seed, err) 421 } 422 423 f, err := generateFilter(t, true) 424 if err != nil { 425 t.Fatalf("failed generateFilter with seed %d: %s.", seed, err) 426 } 427 428 const index = 1 429 params.KeySym = f.KeySym 430 params.Topic = BytesToTopic(f.Topics[index]) 431 432 sentMessage, err := NewSentMessage(params) 433 if err != nil { 434 t.Fatalf("failed to create new message with seed %d: %s.", seed, err) 435 } 436 env, err := sentMessage.Wrap(params) 437 if err != nil { 438 t.Fatalf("failed Wrap with seed %d: %s.", seed, err) 439 } 440 msg := env.Open(f) 441 if msg == nil { 442 t.Fatalf("failed Open with seed %d.", seed) 443 } 444 445 // Src: match 446 *f.Src.X = *params.Src.PublicKey.X 447 *f.Src.Y = *params.Src.PublicKey.Y 448 if !f.MatchMessage(msg) { 449 t.Fatalf("failed MatchEnvelope(src match) with seed %d.", seed) 450 } 451 452 // insufficient PoW: mismatch 453 f.PoW = msg.PoW + 1.0 454 if f.MatchMessage(msg) { 455 t.Fatalf("failed MatchEnvelope(insufficient PoW) with seed %d.", seed) 456 } 457 458 // sufficient PoW: match 459 f.PoW = msg.PoW / 2 460 if !f.MatchMessage(msg) { 461 t.Fatalf("failed MatchEnvelope(sufficient PoW) with seed %d.", seed) 462 } 463 464 // topic mismatch 465 f.Topics[index][0]++ 466 if f.MatchMessage(msg) { 467 t.Fatalf("failed MatchEnvelope(topic mismatch) with seed %d.", seed) 468 } 469 f.Topics[index][0]-- 470 471 // key mismatch 472 f.SymKeyHash[0]++ 473 if f.MatchMessage(msg) { 474 t.Fatalf("failed MatchEnvelope(key mismatch) with seed %d.", seed) 475 } 476 f.SymKeyHash[0]-- 477 478 // Src absent: match 479 f.Src = nil 480 if !f.MatchMessage(msg) { 481 t.Fatalf("failed MatchEnvelope(src absent) with seed %d.", seed) 482 } 483 484 // key hash mismatch 485 h := f.SymKeyHash 486 f.SymKeyHash = common.Hash{} 487 if f.MatchMessage(msg) { 488 t.Fatalf("failed MatchEnvelope(key hash mismatch) with seed %d.", seed) 489 } 490 f.SymKeyHash = h 491 if !f.MatchMessage(msg) { 492 t.Fatalf("failed MatchEnvelope(key hash match) with seed %d.", seed) 493 } 494 495 // encryption method mismatch 496 f.KeySym = nil 497 f.KeyAsym, err = crypto.GenerateKey() 498 if err != nil { 499 t.Fatalf("failed GenerateKey with seed %d: %s.", seed, err) 500 } 501 if f.MatchMessage(msg) { 502 t.Fatalf("failed MatchEnvelope(encryption method mismatch) with seed %d.", seed) 503 } 504 } 505 506 func TestMatchMessageAsym(t *testing.T) { 507 InitSingleTest() 508 509 f, err := generateFilter(t, false) 510 if err != nil { 511 t.Fatalf("failed generateFilter with seed %d: %s.", seed, err) 512 } 513 514 params, err := generateMessageParams() 515 if err != nil { 516 t.Fatalf("failed generateMessageParams with seed %d: %s.", seed, err) 517 } 518 519 const index = 1 520 params.Topic = BytesToTopic(f.Topics[index]) 521 params.Dst = &f.KeyAsym.PublicKey 522 keySymOrig := params.KeySym 523 params.KeySym = nil 524 525 sentMessage, err := NewSentMessage(params) 526 if err != nil { 527 t.Fatalf("failed to create new message with seed %d: %s.", seed, err) 528 } 529 env, err := sentMessage.Wrap(params) 530 if err != nil { 531 t.Fatalf("failed Wrap with seed %d: %s.", seed, err) 532 } 533 msg := env.Open(f) 534 if msg == nil { 535 t.Fatalf("failed to open with seed %d.", seed) 536 } 537 538 // Src: match 539 *f.Src.X = *params.Src.PublicKey.X 540 *f.Src.Y = *params.Src.PublicKey.Y 541 if !f.MatchMessage(msg) { 542 t.Fatalf("failed MatchMessage(src match) with seed %d.", seed) 543 } 544 545 // insufficient PoW: mismatch 546 f.PoW = msg.PoW + 1.0 547 if f.MatchMessage(msg) { 548 t.Fatalf("failed MatchEnvelope(insufficient PoW) with seed %d.", seed) 549 } 550 551 // sufficient PoW: match 552 f.PoW = msg.PoW / 2 553 if !f.MatchMessage(msg) { 554 t.Fatalf("failed MatchEnvelope(sufficient PoW) with seed %d.", seed) 555 } 556 557 // topic mismatch 558 f.Topics[index][0]++ 559 if f.MatchMessage(msg) { 560 t.Fatalf("failed MatchEnvelope(topic mismatch) with seed %d.", seed) 561 } 562 f.Topics[index][0]-- 563 564 // key mismatch 565 prev := *f.KeyAsym.PublicKey.X 566 zero := *big.NewInt(0) 567 *f.KeyAsym.PublicKey.X = zero 568 if f.MatchMessage(msg) { 569 t.Fatalf("failed MatchEnvelope(key mismatch) with seed %d.", seed) 570 } 571 *f.KeyAsym.PublicKey.X = prev 572 573 // Src absent: match 574 f.Src = nil 575 if !f.MatchMessage(msg) { 576 t.Fatalf("failed MatchEnvelope(src absent) with seed %d.", seed) 577 } 578 579 // encryption method mismatch 580 f.KeySym = keySymOrig 581 f.KeyAsym = nil 582 if f.MatchMessage(msg) { 583 t.Fatalf("failed MatchEnvelope(encryption method mismatch) with seed %d.", seed) 584 } 585 } 586 587 func cloneFilter(orig *Filter) *Filter { 588 var clone Filter 589 clone.Messages = make(map[common.Hash]*ReceivedMessage) 590 clone.Src = orig.Src 591 clone.KeyAsym = orig.KeyAsym 592 clone.KeySym = orig.KeySym 593 clone.Topics = orig.Topics 594 clone.PoW = orig.PoW 595 clone.AllowP2P = orig.AllowP2P 596 clone.SymKeyHash = orig.SymKeyHash 597 return &clone 598 } 599 600 func generateCompatibeEnvelope(t *testing.T, f *Filter) *Envelope { 601 params, err := generateMessageParams() 602 if err != nil { 603 t.Fatalf("failed generateMessageParams with seed %d: %s.", seed, err) 604 return nil 605 } 606 607 params.KeySym = f.KeySym 608 params.Topic = BytesToTopic(f.Topics[2]) 609 sentMessage, err := NewSentMessage(params) 610 if err != nil { 611 t.Fatalf("failed to create new message with seed %d: %s.", seed, err) 612 } 613 env, err := sentMessage.Wrap(params) 614 if err != nil { 615 t.Fatalf("failed Wrap with seed %d: %s.", seed, err) 616 return nil 617 } 618 return env 619 } 620 621 func TestWatchers(t *testing.T) { 622 InitSingleTest() 623 624 const NumFilters = 16 625 const NumMessages = 256 626 var i int 627 var j uint32 628 var e *Envelope 629 var x, firstID string 630 var err error 631 632 w := New(&Config{}) 633 filters := NewFilters(w) 634 tst := generateTestCases(t, NumFilters) 635 for i = 0; i < NumFilters; i++ { 636 tst[i].f.Src = nil 637 x, err = filters.Install(tst[i].f) 638 if err != nil { 639 t.Fatalf("failed to install filter with seed %d: %s.", seed, err) 640 } 641 tst[i].id = x 642 if len(firstID) == 0 { 643 firstID = x 644 } 645 } 646 647 lastID := x 648 649 var envelopes [NumMessages]*Envelope 650 for i = 0; i < NumMessages; i++ { 651 j = mrand.Uint32() % NumFilters 652 e = generateCompatibeEnvelope(t, tst[j].f) 653 envelopes[i] = e 654 tst[j].msgCnt++ 655 } 656 657 for i = 0; i < NumMessages; i++ { 658 filters.NotifyWatchers(envelopes[i], false) 659 } 660 661 var total int 662 var mail []*ReceivedMessage 663 var count [NumFilters]int 664 665 for i = 0; i < NumFilters; i++ { 666 mail = tst[i].f.Retrieve() 667 count[i] = len(mail) 668 total += len(mail) 669 } 670 671 if total != NumMessages { 672 t.Fatalf("failed with seed %d: total = %d, want: %d.", seed, total, NumMessages) 673 } 674 675 for i = 0; i < NumFilters; i++ { 676 mail = tst[i].f.Retrieve() 677 if len(mail) != 0 { 678 t.Fatalf("failed with seed %d: i = %d.", seed, i) 679 } 680 681 if tst[i].msgCnt != count[i] { 682 t.Fatalf("failed with seed %d: count[%d]: get %d, want %d.", seed, i, tst[i].msgCnt, count[i]) 683 } 684 } 685 686 // another round with a cloned filter 687 688 clone := cloneFilter(tst[0].f) 689 filters.Uninstall(lastID) 690 total = 0 691 last := NumFilters - 1 692 tst[last].f = clone 693 filters.Install(clone) 694 for i = 0; i < NumFilters; i++ { 695 tst[i].msgCnt = 0 696 count[i] = 0 697 } 698 699 // make sure that the first watcher receives at least one message 700 e = generateCompatibeEnvelope(t, tst[0].f) 701 envelopes[0] = e 702 tst[0].msgCnt++ 703 for i = 1; i < NumMessages; i++ { 704 j = mrand.Uint32() % NumFilters 705 e = generateCompatibeEnvelope(t, tst[j].f) 706 envelopes[i] = e 707 tst[j].msgCnt++ 708 } 709 710 for i = 0; i < NumMessages; i++ { 711 filters.NotifyWatchers(envelopes[i], false) 712 } 713 714 for i = 0; i < NumFilters; i++ { 715 mail = tst[i].f.Retrieve() 716 count[i] = len(mail) 717 total += len(mail) 718 } 719 720 combined := tst[0].msgCnt + tst[last].msgCnt 721 if total != NumMessages+count[0] { 722 t.Fatalf("failed with seed %d: total = %d, count[0] = %d.", seed, total, count[0]) 723 } 724 725 if combined != count[0] { 726 t.Fatalf("failed with seed %d: combined = %d, count[0] = %d.", seed, combined, count[0]) 727 } 728 729 if combined != count[last] { 730 t.Fatalf("failed with seed %d: combined = %d, count[last] = %d.", seed, combined, count[last]) 731 } 732 733 for i = 1; i < NumFilters-1; i++ { 734 mail = tst[i].f.Retrieve() 735 if len(mail) != 0 { 736 t.Fatalf("failed with seed %d: i = %d.", seed, i) 737 } 738 739 if tst[i].msgCnt != count[i] { 740 t.Fatalf("failed with seed %d: i = %d, get %d, want %d.", seed, i, tst[i].msgCnt, count[i]) 741 } 742 } 743 744 // test AcceptP2P 745 746 total = 0 747 filters.NotifyWatchers(envelopes[0], true) 748 749 for i = 0; i < NumFilters; i++ { 750 mail = tst[i].f.Retrieve() 751 total += len(mail) 752 } 753 754 if total != 0 { 755 t.Fatalf("failed with seed %d: total: got %d, want 0.", seed, total) 756 } 757 758 f := filters.Get(firstID) 759 if f == nil { 760 t.Fatalf("failed to get the filter with seed %d.", seed) 761 } 762 f.AllowP2P = true 763 total = 0 764 filters.NotifyWatchers(envelopes[0], true) 765 766 for i = 0; i < NumFilters; i++ { 767 mail = tst[i].f.Retrieve() 768 total += len(mail) 769 } 770 771 if total != 1 { 772 t.Fatalf("failed with seed %d: total: got %d, want 1.", seed, total) 773 } 774 } 775 776 func TestVariableTopics(t *testing.T) { 777 InitSingleTest() 778 779 var match bool 780 params, err := generateMessageParams() 781 if err != nil { 782 t.Fatalf("failed generateMessageParams with seed %d: %s.", seed, err) 783 } 784 msg, err := NewSentMessage(params) 785 if err != nil { 786 t.Fatalf("failed to create new message with seed %d: %s.", seed, err) 787 } 788 env, err := msg.Wrap(params) 789 if err != nil { 790 t.Fatalf("failed Wrap with seed %d: %s.", seed, err) 791 } 792 793 f, err := generateFilter(t, true) 794 if err != nil { 795 t.Fatalf("failed generateFilter with seed %d: %s.", seed, err) 796 } 797 798 for i := 0; i < 4; i++ { 799 arr := make([]byte, i+1, 4) 800 copy(arr, env.Topic[:i+1]) 801 802 f.Topics[4] = arr 803 match = f.MatchEnvelope(env) 804 if !match { 805 t.Fatalf("failed MatchEnvelope symmetric with seed %d, step %d.", seed, i) 806 } 807 808 f.Topics[4][i]++ 809 match = f.MatchEnvelope(env) 810 if match { 811 t.Fatalf("MatchEnvelope symmetric with seed %d, step %d: false positive.", seed, i) 812 } 813 } 814 }