github.com/ethereumproject/go-ethereum@v5.5.2+incompatible/whisper/topic_test.go (about) 1 // Copyright 2015 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 whisper 18 19 import ( 20 "bytes" 21 "testing" 22 ) 23 24 var topicCreationTests = []struct { 25 data []byte 26 hash [4]byte 27 }{ 28 {hash: [4]byte{0x8f, 0x9a, 0x2b, 0x7d}, data: []byte("test name")}, 29 {hash: [4]byte{0xf2, 0x6e, 0x77, 0x79}, data: []byte("some other test")}, 30 } 31 32 func TestTopicCreation(t *testing.T) { 33 // Create the topics individually 34 for i, tt := range topicCreationTests { 35 topic := NewTopic(tt.data) 36 if bytes.Compare(topic[:], tt.hash[:]) != 0 { 37 t.Errorf("binary test %d: hash mismatch: have %v, want %v.", i, topic, tt.hash) 38 } 39 } 40 for i, tt := range topicCreationTests { 41 topic := newTopicFromString(string(tt.data)) 42 if bytes.Compare(topic[:], tt.hash[:]) != 0 { 43 t.Errorf("textual test %d: hash mismatch: have %v, want %v.", i, topic, tt.hash) 44 } 45 } 46 // Create the topics in batches 47 binaryData := make([][]byte, len(topicCreationTests)) 48 for i, tt := range topicCreationTests { 49 binaryData[i] = tt.data 50 } 51 textualData := make([]string, len(topicCreationTests)) 52 for i, tt := range topicCreationTests { 53 textualData[i] = string(tt.data) 54 } 55 56 topics := NewTopics(binaryData...) 57 for i, tt := range topicCreationTests { 58 if bytes.Compare(topics[i][:], tt.hash[:]) != 0 { 59 t.Errorf("binary batch test %d: hash mismatch: have %v, want %v.", i, topics[i], tt.hash) 60 } 61 } 62 topics = newTopicsFromStrings(textualData...) 63 for i, tt := range topicCreationTests { 64 if bytes.Compare(topics[i][:], tt.hash[:]) != 0 { 65 t.Errorf("textual batch test %d: hash mismatch: have %v, want %v.", i, topics[i], tt.hash) 66 } 67 } 68 } 69 70 var topicMatcherCreationTest = struct { 71 binary [][][]byte 72 textual [][]string 73 matcher []map[[4]byte]struct{} 74 }{ 75 binary: [][][]byte{ 76 {}, 77 { 78 []byte("Topic A"), 79 }, 80 { 81 []byte("Topic B1"), 82 []byte("Topic B2"), 83 []byte("Topic B3"), 84 }, 85 }, 86 textual: [][]string{ 87 {}, 88 {"Topic A"}, 89 {"Topic B1", "Topic B2", "Topic B3"}, 90 }, 91 matcher: []map[[4]byte]struct{}{ 92 {}, 93 { 94 [4]byte{0x25, 0xfc, 0x95, 0x66}: {}, 95 }, 96 { 97 [4]byte{0x93, 0x6d, 0xec, 0x09}: {}, 98 [4]byte{0x25, 0x23, 0x34, 0xd3}: {}, 99 [4]byte{0x6b, 0xc2, 0x73, 0xd1}: {}, 100 }, 101 }, 102 } 103 104 func TestTopicMatcherCreation(t *testing.T) { 105 test := topicMatcherCreationTest 106 107 matcher := newTopicMatcherFromBinary(test.binary...) 108 for i, cond := range matcher.conditions { 109 for topic := range cond { 110 if _, ok := test.matcher[i][topic]; !ok { 111 t.Errorf("condition %d; extra topic found: 0x%x", i, topic[:]) 112 } 113 } 114 } 115 for i, cond := range test.matcher { 116 for topic := range cond { 117 if _, ok := matcher.conditions[i][topic]; !ok { 118 t.Errorf("condition %d; topic not found: 0x%x", i, topic[:]) 119 } 120 } 121 } 122 123 matcher = newTopicMatcherFromStrings(test.textual...) 124 for i, cond := range matcher.conditions { 125 for topic := range cond { 126 if _, ok := test.matcher[i][topic]; !ok { 127 t.Errorf("condition %d; extra topic found: 0x%x", i, topic[:]) 128 } 129 } 130 } 131 for i, cond := range test.matcher { 132 for topic := range cond { 133 if _, ok := matcher.conditions[i][topic]; !ok { 134 t.Errorf("condition %d; topic not found: 0x%x", i, topic[:]) 135 } 136 } 137 } 138 } 139 140 var topicMatcherTests = []struct { 141 filter [][]string 142 topics []string 143 match bool 144 }{ 145 // Empty topic matcher should match everything 146 { 147 filter: [][]string{}, 148 topics: []string{}, 149 match: true, 150 }, 151 { 152 filter: [][]string{}, 153 topics: []string{"a", "b", "c"}, 154 match: true, 155 }, 156 // Fixed topic matcher should match strictly, but only prefix 157 { 158 filter: [][]string{{"a"}, {"b"}}, 159 topics: []string{"a"}, 160 match: false, 161 }, 162 { 163 filter: [][]string{{"a"}, {"b"}}, 164 topics: []string{"a", "b"}, 165 match: true, 166 }, 167 { 168 filter: [][]string{{"a"}, {"b"}}, 169 topics: []string{"a", "b", "c"}, 170 match: true, 171 }, 172 // Multi-matcher should match any from a sub-group 173 { 174 filter: [][]string{{"a1", "a2"}}, 175 topics: []string{"a"}, 176 match: false, 177 }, 178 { 179 filter: [][]string{{"a1", "a2"}}, 180 topics: []string{"a1"}, 181 match: true, 182 }, 183 { 184 filter: [][]string{{"a1", "a2"}}, 185 topics: []string{"a2"}, 186 match: true, 187 }, 188 // Wild-card condition should match anything 189 { 190 filter: [][]string{{}, {"b"}}, 191 topics: []string{"a"}, 192 match: false, 193 }, 194 { 195 filter: [][]string{{}, {"b"}}, 196 topics: []string{"a", "b"}, 197 match: true, 198 }, 199 { 200 filter: [][]string{{}, {"b"}}, 201 topics: []string{"b", "b"}, 202 match: true, 203 }, 204 } 205 206 func TestTopicMatcher(t *testing.T) { 207 for i, tt := range topicMatcherTests { 208 topics := newTopicsFromStrings(tt.topics...) 209 210 matcher := newTopicMatcherFromStrings(tt.filter...) 211 if match := matcher.Matches(topics); match != tt.match { 212 t.Errorf("test %d: match mismatch: have %v, want %v", i, match, tt.match) 213 } 214 } 215 } 216 217 // NewTopicFromString creates a topic using the binary data contents of the 218 // specified string. 219 func newTopicFromString(data string) Topic { 220 return NewTopic([]byte(data)) 221 } 222 223 // NewTopicsFromStrings creates a list of topics from a list of textual data 224 // elements, by iteratively calling NewTopicFromString on each of them. 225 func newTopicsFromStrings(data ...string) []Topic { 226 topics := make([]Topic, len(data)) 227 for i, element := range data { 228 topics[i] = newTopicFromString(element) 229 } 230 return topics 231 } 232 233 // newTopicMatcherFromStrings creates a topic matcher from a list of textual 234 // conditions. 235 func newTopicMatcherFromStrings(data ...[]string) *topicMatcher { 236 topics := make([][]Topic, len(data)) 237 for i, condition := range data { 238 topics[i] = newTopicsFromStrings(condition...) 239 } 240 return newTopicMatcher(topics...) 241 } 242 243 // newTopicMatcherFromBinary create a topic matcher from a list of binary conditions. 244 func newTopicMatcherFromBinary(data ...[][]byte) *topicMatcher { 245 topics := make([][]Topic, len(data)) 246 for i, condition := range data { 247 topics[i] = NewTopics(condition...) 248 } 249 return newTopicMatcher(topics...) 250 }