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