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  }