github.com/ethersphere/bee/v2@v2.2.0/pkg/file/pipeline/bmt/bmt_test.go (about)

     1  // Copyright 2020 The Swarm Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  package bmt_test
     6  
     7  import (
     8  	"bytes"
     9  	"encoding/binary"
    10  	"encoding/hex"
    11  	"errors"
    12  	"testing"
    13  
    14  	"github.com/ethersphere/bee/v2/pkg/file/pipeline"
    15  	"github.com/ethersphere/bee/v2/pkg/file/pipeline/bmt"
    16  	mock "github.com/ethersphere/bee/v2/pkg/file/pipeline/mock"
    17  )
    18  
    19  // TestStoreWriter tests that store writer stores the provided data and calls the next chain writer.
    20  func TestBmtWriter(t *testing.T) {
    21  	t.Parallel()
    22  
    23  	for _, tc := range []struct {
    24  		name    string
    25  		data    []byte
    26  		expHash []byte
    27  		expErr  error
    28  		noSpan  bool
    29  	}{
    30  		{
    31  			// this is a special case, since semantically it can be considered the hash
    32  			// of an empty file (since data is all zeros).
    33  			name:    "empty file",
    34  			data:    make([]byte, 0),
    35  			expHash: mustDecodeString(t, "b34ca8c22b9e982354f9c7f50b470d66db428d880c8a904d5fe4ec9713171526"),
    36  		},
    37  		{
    38  			name:    "hello world",
    39  			data:    []byte("hello world"),
    40  			expHash: mustDecodeString(t, "92672a471f4419b255d7cb0cf313474a6f5856fb347c5ece85fb706d644b630f"),
    41  		},
    42  		{
    43  			name:   "no data",
    44  			data:   []byte{},
    45  			noSpan: true,
    46  			expErr: bmt.ErrInvalidData,
    47  		},
    48  	} {
    49  		tc := tc
    50  		t.Run(tc.name, func(t *testing.T) {
    51  			t.Parallel()
    52  
    53  			mockChainWriter := mock.NewChainWriter()
    54  			writer := bmt.NewBmtWriter(mockChainWriter)
    55  
    56  			var data []byte
    57  
    58  			if !tc.noSpan {
    59  				data = make([]byte, 8)
    60  				binary.LittleEndian.PutUint64(data, uint64(len(tc.data)))
    61  			}
    62  
    63  			data = append(data, tc.data...)
    64  			args := pipeline.PipeWriteArgs{Data: data}
    65  
    66  			err := writer.ChainWrite(&args)
    67  			if err != nil && tc.expErr != nil && errors.Is(err, tc.expErr) {
    68  				return
    69  			}
    70  
    71  			if err != nil {
    72  				t.Fatal(err)
    73  			}
    74  			if !bytes.Equal(tc.expHash, args.Ref) {
    75  				t.Fatalf("ref mismatch. got %x want %x", args.Ref, tc.expHash)
    76  			}
    77  
    78  			if calls := mockChainWriter.ChainWriteCalls(); calls != 1 {
    79  				t.Errorf("wanted 1 ChainWrite call, got %d", calls)
    80  			}
    81  		})
    82  	}
    83  }
    84  
    85  // TestSum tests that calling Sum on the writer calls the next writer's Sum.
    86  func TestSum(t *testing.T) {
    87  	t.Parallel()
    88  
    89  	mockChainWriter := mock.NewChainWriter()
    90  	writer := bmt.NewBmtWriter(mockChainWriter)
    91  	_, err := writer.Sum()
    92  	if err != nil {
    93  		t.Fatal(err)
    94  	}
    95  	if calls := mockChainWriter.SumCalls(); calls != 1 {
    96  		t.Fatalf("wanted 1 Sum call but got %d", calls)
    97  	}
    98  }
    99  
   100  func mustDecodeString(t *testing.T, s string) []byte {
   101  	t.Helper()
   102  	v, err := hex.DecodeString(s)
   103  	if err != nil {
   104  		t.Fatal(err)
   105  	}
   106  
   107  	return v
   108  }