github.com/Jeffail/benthos/v3@v3.65.0/lib/processor/hash_test.go (about) 1 package processor 2 3 import ( 4 "crypto/hmac" 5 "crypto/md5" 6 "crypto/sha1" 7 "crypto/sha256" 8 "crypto/sha512" 9 "reflect" 10 "strconv" 11 "testing" 12 13 "github.com/Jeffail/benthos/v3/lib/log" 14 "github.com/Jeffail/benthos/v3/lib/message" 15 "github.com/Jeffail/benthos/v3/lib/metrics" 16 "github.com/OneOfOne/xxhash" 17 ) 18 19 func TestHashBadAlgo(t *testing.T) { 20 conf := NewConfig() 21 conf.Hash.Algorithm = "does not exist" 22 23 _, err := NewHash(conf, nil, log.Noop(), metrics.Noop()) 24 if err == nil { 25 t.Error("Expected error from bad algo") 26 } 27 } 28 29 func TestHashHMACSha1(t *testing.T) { 30 conf := NewConfig() 31 conf.Hash.Algorithm = "hmac-sha1" 32 conf.Hash.Key = "c5f68503-b723-488e-9be0-7b024ba91e20" 33 34 input := [][]byte{ 35 []byte("hello world first part"), 36 []byte("hello world second part"), 37 []byte("third part"), 38 []byte("fourth"), 39 []byte("5"), 40 } 41 42 exp := [][]byte{} 43 44 for i := range input { 45 h := hmac.New(sha1.New, []byte(conf.Hash.Key)) 46 h.Write(input[i]) 47 exp = append(exp, h.Sum(nil)) 48 } 49 50 if reflect.DeepEqual(input, exp) { 51 t.Fatal("Input and exp output are the same") 52 } 53 54 proc, err := NewHash(conf, nil, log.Noop(), metrics.Noop()) 55 if err != nil { 56 t.Fatal(err) 57 } 58 59 msgs, res := proc.ProcessMessage(message.New(input)) 60 if len(msgs) != 1 { 61 t.Error("Hash failed") 62 } else if res != nil { 63 t.Errorf("Expected nil response: %v", res) 64 } 65 for i, part := range message.GetAllBytes(msgs[0]) { 66 if !hmac.Equal(part, exp[i]) { 67 t.Errorf("Unexpected output for input (%s): %s != %s", input[i], part, exp[i]) 68 } 69 } 70 if act := message.GetAllBytes(msgs[0]); !reflect.DeepEqual(exp, act) { 71 t.Errorf("Unexpected output: %s != %s", act, exp) 72 } 73 } 74 75 func TestHashHMACSha256(t *testing.T) { 76 conf := NewConfig() 77 conf.Hash.Algorithm = "hmac-sha256" 78 conf.Hash.Key = "c5f68503-b723-488e-9be0-7b024ba91e20" 79 80 input := [][]byte{ 81 []byte("hello world first part"), 82 []byte("hello world second part"), 83 []byte("third part"), 84 []byte("fourth"), 85 []byte("5"), 86 } 87 88 exp := [][]byte{} 89 90 for i := range input { 91 h := hmac.New(sha256.New, []byte(conf.Hash.Key)) 92 h.Write(input[i]) 93 exp = append(exp, h.Sum(nil)) 94 } 95 96 if reflect.DeepEqual(input, exp) { 97 t.Fatal("Input and exp output are the same") 98 } 99 100 proc, err := NewHash(conf, nil, log.Noop(), metrics.Noop()) 101 if err != nil { 102 t.Fatal(err) 103 } 104 105 msgs, res := proc.ProcessMessage(message.New(input)) 106 if len(msgs) != 1 { 107 t.Error("Hash failed") 108 } else if res != nil { 109 t.Errorf("Expected nil response: %v", res) 110 } 111 for i, part := range message.GetAllBytes(msgs[0]) { 112 if !hmac.Equal(part, exp[i]) { 113 t.Errorf("Unexpected output for input (%s): %s != %s", input[i], part, exp[i]) 114 } 115 } 116 if act := message.GetAllBytes(msgs[0]); !reflect.DeepEqual(exp, act) { 117 t.Errorf("Unexpected output: %s != %s", act, exp) 118 } 119 } 120 121 func TestHashHMACSha512(t *testing.T) { 122 conf := NewConfig() 123 conf.Hash.Algorithm = "hmac-sha512" 124 conf.Hash.Key = "c5f68503-b723-488e-9be0-7b024ba91e20" 125 126 input := [][]byte{ 127 []byte("hello world first part"), 128 []byte("hello world second part"), 129 []byte("third part"), 130 []byte("fourth"), 131 []byte("5"), 132 } 133 134 exp := [][]byte{} 135 136 for i := range input { 137 h := hmac.New(sha512.New, []byte(conf.Hash.Key)) 138 h.Write(input[i]) 139 exp = append(exp, h.Sum(nil)) 140 } 141 142 if reflect.DeepEqual(input, exp) { 143 t.Fatal("Input and exp output are the same") 144 } 145 146 proc, err := NewHash(conf, nil, log.Noop(), metrics.Noop()) 147 if err != nil { 148 t.Fatal(err) 149 } 150 151 msgs, res := proc.ProcessMessage(message.New(input)) 152 if len(msgs) != 1 { 153 t.Error("Hash failed") 154 } else if res != nil { 155 t.Errorf("Expected nil response: %v", res) 156 } 157 for i, part := range message.GetAllBytes(msgs[0]) { 158 if !hmac.Equal(part, exp[i]) { 159 t.Errorf("Unexpected output for input (%s): %s != %s", input[i], part, exp[i]) 160 } 161 } 162 if act := message.GetAllBytes(msgs[0]); !reflect.DeepEqual(exp, act) { 163 t.Errorf("Unexpected output: %s != %s", act, exp) 164 } 165 } 166 167 func TestHashSha1(t *testing.T) { 168 conf := NewConfig() 169 conf.Hash.Algorithm = "sha1" 170 171 input := [][]byte{ 172 []byte("hello world first part"), 173 []byte("hello world second part"), 174 []byte("third part"), 175 []byte("fourth"), 176 []byte("5"), 177 } 178 179 exp := [][]byte{} 180 181 for i := range input { 182 h := sha1.New() 183 h.Write(input[i]) 184 exp = append(exp, h.Sum(nil)) 185 } 186 187 if reflect.DeepEqual(input, exp) { 188 t.Fatal("Input and exp output are the same") 189 } 190 191 proc, err := NewHash(conf, nil, log.Noop(), metrics.Noop()) 192 if err != nil { 193 t.Fatal(err) 194 } 195 196 msgs, res := proc.ProcessMessage(message.New(input)) 197 if len(msgs) != 1 { 198 t.Error("Hash failed") 199 } else if res != nil { 200 t.Errorf("Expected nil response: %v", res) 201 } 202 if act := message.GetAllBytes(msgs[0]); !reflect.DeepEqual(exp, act) { 203 t.Errorf("Unexpected output: %s != %s", act, exp) 204 } 205 } 206 207 func TestHashSha256(t *testing.T) { 208 conf := NewConfig() 209 conf.Hash.Algorithm = "sha256" 210 211 input := [][]byte{ 212 []byte("hello world first part"), 213 []byte("hello world second part"), 214 []byte("third part"), 215 []byte("fourth"), 216 []byte("5"), 217 } 218 219 exp := [][]byte{} 220 221 for i := range input { 222 h := sha256.New() 223 h.Write(input[i]) 224 exp = append(exp, h.Sum(nil)) 225 } 226 227 if reflect.DeepEqual(input, exp) { 228 t.Fatal("Input and exp output are the same") 229 } 230 231 proc, err := NewHash(conf, nil, log.Noop(), metrics.Noop()) 232 if err != nil { 233 t.Fatal(err) 234 } 235 236 msgs, res := proc.ProcessMessage(message.New(input)) 237 if len(msgs) != 1 { 238 t.Error("Hash failed") 239 } else if res != nil { 240 t.Errorf("Expected nil response: %v", res) 241 } 242 if act := message.GetAllBytes(msgs[0]); !reflect.DeepEqual(exp, act) { 243 t.Errorf("Unexpected output: %s != %s", act, exp) 244 } 245 } 246 247 func TestHashSha512(t *testing.T) { 248 conf := NewConfig() 249 conf.Hash.Algorithm = "sha512" 250 251 input := [][]byte{ 252 []byte("hello world first part"), 253 []byte("hello world second part"), 254 []byte("third part"), 255 []byte("fourth"), 256 []byte("5"), 257 } 258 259 exp := [][]byte{} 260 261 for i := range input { 262 h := sha512.New() 263 h.Write(input[i]) 264 exp = append(exp, h.Sum(nil)) 265 } 266 267 if reflect.DeepEqual(input, exp) { 268 t.Fatal("Input and exp output are the same") 269 } 270 271 proc, err := NewHash(conf, nil, log.Noop(), metrics.Noop()) 272 if err != nil { 273 t.Fatal(err) 274 } 275 276 msgs, res := proc.ProcessMessage(message.New(input)) 277 if len(msgs) != 1 { 278 t.Error("Hash failed") 279 } else if res != nil { 280 t.Errorf("Expected nil response: %v", res) 281 } 282 if act := message.GetAllBytes(msgs[0]); !reflect.DeepEqual(exp, act) { 283 t.Errorf("Unexpected output: %s != %s", act, exp) 284 } 285 } 286 287 func TestHashXXHash64(t *testing.T) { 288 conf := NewConfig() 289 conf.Hash.Algorithm = "xxhash64" 290 291 input := [][]byte{ 292 []byte("hello world first part"), 293 []byte("hello world second part"), 294 []byte("third part"), 295 []byte("fourth"), 296 []byte("5"), 297 } 298 299 exp := [][]byte{} 300 301 for i := range input { 302 h := xxhash.New64() 303 h.Write(input[i]) 304 exp = append(exp, []byte(strconv.FormatUint(h.Sum64(), 10))) 305 } 306 307 if reflect.DeepEqual(input, exp) { 308 t.Fatal("Input and exp output are the same") 309 } 310 311 proc, err := NewHash(conf, nil, log.Noop(), metrics.Noop()) 312 if err != nil { 313 t.Fatal(err) 314 } 315 316 msgs, res := proc.ProcessMessage(message.New(input)) 317 if len(msgs) != 1 { 318 t.Error("Hash failed") 319 } else if res != nil { 320 t.Errorf("Expected nil response: %v", res) 321 } 322 if act := message.GetAllBytes(msgs[0]); !reflect.DeepEqual(exp, act) { 323 t.Errorf("Unexpected output: %s != %s", act, exp) 324 } 325 } 326 327 func TestHashMD5(t *testing.T) { 328 conf := NewConfig() 329 conf.Hash.Algorithm = "md5" 330 331 input := [][]byte{ 332 []byte("hello world first part"), 333 []byte("hello world second part"), 334 []byte("third part"), 335 []byte("fourth"), 336 []byte("5"), 337 } 338 339 exp := [][]byte{} 340 341 for i := range input { 342 h := md5.New() 343 h.Write(input[i]) 344 exp = append(exp, h.Sum(nil)) 345 } 346 347 if reflect.DeepEqual(input, exp) { 348 t.Fatal("Input and exp output are the same") 349 } 350 351 proc, err := NewHash(conf, nil, log.Noop(), metrics.Noop()) 352 if err != nil { 353 t.Fatal(err) 354 } 355 356 msgs, res := proc.ProcessMessage(message.New(input)) 357 if len(msgs) != 1 { 358 t.Error("Hash failed") 359 } else if res != nil { 360 t.Errorf("Expected nil response: %v", res) 361 } 362 for i, part := range message.GetAllBytes(msgs[0]) { 363 if !hmac.Equal(part, exp[i]) { 364 t.Errorf("Unexpected output for input (%s): %s != %s", input[i], part, exp[i]) 365 } 366 } 367 if act := message.GetAllBytes(msgs[0]); !reflect.DeepEqual(exp, act) { 368 t.Errorf("Unexpected output: %s != %s", act, exp) 369 } 370 } 371 372 func TestHashIndexBounds(t *testing.T) { 373 conf := NewConfig() 374 375 input := [][]byte{ 376 []byte("0"), 377 []byte("1"), 378 []byte("2"), 379 []byte("3"), 380 []byte("4"), 381 } 382 383 hashed := [][]byte{} 384 385 for i := range input { 386 h := sha256.New() 387 h.Write(input[i]) 388 hashed = append(hashed, h.Sum(nil)) 389 } 390 391 tests := map[int]int{ 392 -5: 0, 393 -4: 1, 394 -3: 2, 395 -2: 3, 396 -1: 4, 397 0: 0, 398 1: 1, 399 2: 2, 400 3: 3, 401 4: 4, 402 } 403 404 for i, expIndex := range tests { 405 conf.Hash.Parts = []int{i} 406 proc, err := NewHash(conf, nil, log.Noop(), metrics.Noop()) 407 if err != nil { 408 t.Fatal(err) 409 } 410 411 msgs, res := proc.ProcessMessage(message.New(input)) 412 if len(msgs) != 1 { 413 t.Errorf("Hash failed on index: %v", i) 414 } else if res != nil { 415 t.Errorf("Expected nil response: %v", res) 416 } 417 if exp, act := string(hashed[expIndex]), string(message.GetAllBytes(msgs[0])[expIndex]); exp != act { 418 t.Errorf("Unexpected output for index %v: %v != %v", i, act, exp) 419 } 420 if exp, act := string(hashed[expIndex]), string(message.GetAllBytes(msgs[0])[(expIndex+1)%5]); exp == act { 421 t.Errorf("Processor was applied to wrong index %v: %v != %v", (expIndex+1)%5, act, exp) 422 } 423 } 424 } 425 426 func TestHashEmpty(t *testing.T) { 427 conf := NewConfig() 428 conf.Hash.Parts = []int{0, 1} 429 430 testLog := log.Noop() 431 proc, err := NewHash(conf, nil, testLog, metrics.Noop()) 432 if err != nil { 433 t.Error(err) 434 return 435 } 436 437 msgs, _ := proc.ProcessMessage(message.New([][]byte{})) 438 if len(msgs) > 0 { 439 t.Error("Expected failure with zero part message") 440 } 441 } 442 443 func BenchmarkHashSha256(b *testing.B) { 444 conf := NewConfig() 445 conf.Hash.Algorithm = "sha256" 446 447 input := [][]byte{ 448 []byte("hello world first part"), 449 []byte("hello world second part"), 450 []byte("third part"), 451 []byte("fourth"), 452 []byte("5"), 453 } 454 455 exp := [][]byte{} 456 457 for i := range input { 458 h := sha256.New() 459 h.Write(input[i]) 460 exp = append(exp, h.Sum(nil)) 461 } 462 463 if reflect.DeepEqual(input, exp) { 464 b.Fatal("Input and exp output are the same") 465 } 466 467 proc, err := NewHash(conf, nil, log.Noop(), metrics.Noop()) 468 if err != nil { 469 b.Fatal(err) 470 } 471 472 b.ReportAllocs() 473 b.ResetTimer() 474 475 for i := 0; i < b.N; i++ { 476 msgs, res := proc.ProcessMessage(message.New(input)) 477 if len(msgs) != 1 { 478 b.Error("Hash failed") 479 } else if res != nil { 480 b.Errorf("Expected nil response: %v", res) 481 } 482 if act := message.GetAllBytes(msgs[0]); !reflect.DeepEqual(exp, act) { 483 b.Errorf("Unexpected output: %s != %s", act, exp) 484 } 485 } 486 }