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