github.com/ethersphere/bee/v2@v2.2.0/pkg/file/pipeline/builder/builder_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 builder_test
     6  
     7  import (
     8  	"bytes"
     9  	"context"
    10  	"encoding/hex"
    11  	"fmt"
    12  	"strconv"
    13  	"testing"
    14  
    15  	"github.com/ethersphere/bee/v2/pkg/file/pipeline/builder"
    16  	test "github.com/ethersphere/bee/v2/pkg/file/testing"
    17  	"github.com/ethersphere/bee/v2/pkg/storage/inmemchunkstore"
    18  	"github.com/ethersphere/bee/v2/pkg/swarm"
    19  	"github.com/ethersphere/bee/v2/pkg/util/testutil"
    20  )
    21  
    22  func TestPartialWrites(t *testing.T) {
    23  	t.Parallel()
    24  
    25  	m := inmemchunkstore.New()
    26  	p := builder.NewPipelineBuilder(context.Background(), m, false, 0)
    27  	_, _ = p.Write([]byte("hello "))
    28  	_, _ = p.Write([]byte("world"))
    29  
    30  	sum, err := p.Sum()
    31  	if err != nil {
    32  		t.Fatal(err)
    33  	}
    34  	exp := swarm.MustParseHexAddress("92672a471f4419b255d7cb0cf313474a6f5856fb347c5ece85fb706d644b630f")
    35  	if !bytes.Equal(exp.Bytes(), sum) {
    36  		t.Fatalf("expected %s got %s", exp.String(), hex.EncodeToString(sum))
    37  	}
    38  }
    39  
    40  func TestHelloWorld(t *testing.T) {
    41  	t.Parallel()
    42  
    43  	m := inmemchunkstore.New()
    44  	p := builder.NewPipelineBuilder(context.Background(), m, false, 0)
    45  
    46  	data := []byte("hello world")
    47  	_, err := p.Write(data)
    48  	if err != nil {
    49  		t.Fatal(err)
    50  	}
    51  
    52  	sum, err := p.Sum()
    53  	if err != nil {
    54  		t.Fatal(err)
    55  	}
    56  	exp := swarm.MustParseHexAddress("92672a471f4419b255d7cb0cf313474a6f5856fb347c5ece85fb706d644b630f")
    57  	if !bytes.Equal(exp.Bytes(), sum) {
    58  		t.Fatalf("expected %s got %s", exp.String(), hex.EncodeToString(sum))
    59  	}
    60  }
    61  
    62  // TestEmpty tests that a hash is generated for an empty file.
    63  func TestEmpty(t *testing.T) {
    64  	t.Parallel()
    65  
    66  	m := inmemchunkstore.New()
    67  	p := builder.NewPipelineBuilder(context.Background(), m, false, 0)
    68  
    69  	data := []byte{}
    70  	_, err := p.Write(data)
    71  	if err != nil {
    72  		t.Fatal(err)
    73  	}
    74  
    75  	sum, err := p.Sum()
    76  	if err != nil {
    77  		t.Fatal(err)
    78  	}
    79  	exp := swarm.MustParseHexAddress("b34ca8c22b9e982354f9c7f50b470d66db428d880c8a904d5fe4ec9713171526")
    80  	if !bytes.Equal(exp.Bytes(), sum) {
    81  		t.Fatalf("expected %s got %s", exp.String(), hex.EncodeToString(sum))
    82  	}
    83  }
    84  
    85  func TestAllVectors(t *testing.T) {
    86  	t.Parallel()
    87  
    88  	for i := 1; i <= 20; i++ {
    89  		data, expect := test.GetVector(t, i)
    90  		i := i
    91  		t.Run(fmt.Sprintf("data length %d, vector %d", len(data), i), func(t *testing.T) {
    92  			t.Parallel()
    93  
    94  			m := inmemchunkstore.New()
    95  			p := builder.NewPipelineBuilder(context.Background(), m, false, 0)
    96  
    97  			_, err := p.Write(data)
    98  			if err != nil {
    99  				t.Fatal(err)
   100  			}
   101  			sum, err := p.Sum()
   102  			if err != nil {
   103  				t.Fatal(err)
   104  			}
   105  			a := swarm.NewAddress(sum)
   106  			if !a.Equal(expect) {
   107  				t.Fatalf("failed run %d, expected address %s but got %s", i, expect.String(), a.String())
   108  			}
   109  		})
   110  	}
   111  }
   112  
   113  /*
   114  go test -v -bench=. -run Bench -benchmem
   115  goos: linux
   116  goarch: amd64
   117  pkg: github.com/ethersphere/bee/pkg/file/pipeline/builder
   118  BenchmarkPipeline
   119  BenchmarkPipeline/1000-bytes
   120  BenchmarkPipeline/1000-bytes-4         	   14475	     75170 ns/op	   63611 B/op	     333 allocs/op
   121  BenchmarkPipeline/10000-bytes
   122  BenchmarkPipeline/10000-bytes-4        	    2775	    459275 ns/op	  321825 B/op	    1826 allocs/op
   123  BenchmarkPipeline/100000-bytes
   124  BenchmarkPipeline/100000-bytes-4       	     334	   3523558 ns/op	 1891672 B/op	   11994 allocs/op
   125  BenchmarkPipeline/1000000-bytes
   126  BenchmarkPipeline/1000000-bytes-4      	      36	  33140883 ns/op	17745116 B/op	  114170 allocs/op
   127  BenchmarkPipeline/10000000-bytes
   128  BenchmarkPipeline/10000000-bytes-4     	       4	 304759595 ns/op	175378648 B/op	 1135082 allocs/op
   129  BenchmarkPipeline/100000000-bytes
   130  BenchmarkPipeline/100000000-bytes-4    	       1	3064439098 ns/op	1751509528 B/op	11342736 allocs/op
   131  PASS
   132  ok  	github.com/ethersphere/bee/pkg/file/pipeline/builder	17.599s
   133  */
   134  func BenchmarkPipeline(b *testing.B) {
   135  	for _, count := range []int{
   136  		1000,      // 1k
   137  		10000,     // 10 k
   138  		100000,    // 100 k
   139  		1000000,   // 1 mb
   140  		10000000,  // 10 mb
   141  		100000000, // 100 mb
   142  	} {
   143  		b.Run(strconv.Itoa(count)+"-bytes", func(b *testing.B) {
   144  			for n := 0; n < b.N; n++ {
   145  				benchmarkPipeline(b, count)
   146  			}
   147  		})
   148  	}
   149  }
   150  
   151  func benchmarkPipeline(b *testing.B, count int) {
   152  	b.Helper()
   153  
   154  	b.StopTimer()
   155  
   156  	data := testutil.RandBytes(b, count)
   157  	m := inmemchunkstore.New()
   158  	p := builder.NewPipelineBuilder(context.Background(), m, false, 0)
   159  
   160  	b.StartTimer()
   161  
   162  	_, err := p.Write(data)
   163  	if err != nil {
   164  		b.Fatal(err)
   165  	}
   166  	_, err = p.Sum()
   167  	if err != nil {
   168  		b.Fatal(err)
   169  	}
   170  }