github.com/ethersphere/bee/v2@v2.2.0/pkg/storer/debug_test.go (about)

     1  // Copyright 2023 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 storer_test
     6  
     7  import (
     8  	"context"
     9  	"testing"
    10  	"time"
    11  
    12  	chunktest "github.com/ethersphere/bee/v2/pkg/storage/testing"
    13  	storer "github.com/ethersphere/bee/v2/pkg/storer"
    14  	"github.com/ethersphere/bee/v2/pkg/swarm"
    15  	"github.com/google/go-cmp/cmp"
    16  )
    17  
    18  func emptyBinIDs() []uint64 {
    19  	return make([]uint64, swarm.MaxBins)
    20  }
    21  
    22  func testDebugInfo(t *testing.T, newStorer func() (*storer.DB, swarm.Address, error)) {
    23  	t.Helper()
    24  
    25  	t.Run("upload and pin", func(t *testing.T) {
    26  		t.Parallel()
    27  
    28  		lstore, _, err := newStorer()
    29  		if err != nil {
    30  			t.Fatal(err)
    31  		}
    32  
    33  		_, epoch, err := lstore.ReserveLastBinIDs()
    34  		if err != nil {
    35  			t.Fatal(err)
    36  		}
    37  
    38  		tag, err := lstore.NewSession()
    39  		if err != nil {
    40  			t.Fatalf("NewSession(): unexpected error: %v", err)
    41  		}
    42  
    43  		session, err := lstore.Upload(context.Background(), true, tag.TagID)
    44  		if err != nil {
    45  			t.Fatalf("Upload(...): unexpected error: %v", err)
    46  		}
    47  
    48  		chunks := chunktest.GenerateTestRandomChunks(10)
    49  		for _, ch := range chunks {
    50  			err := session.Put(context.Background(), ch)
    51  			if err != nil {
    52  				t.Fatalf("session.Put(...): unexpected error: %v", err)
    53  			}
    54  		}
    55  
    56  		err = session.Done(chunks[0].Address())
    57  		if err != nil {
    58  			t.Fatalf("session.Done(...): unexpected error: %v", err)
    59  		}
    60  
    61  		info, err := lstore.DebugInfo(context.Background())
    62  		if err != nil {
    63  			t.Fatalf("DebugInfo(...): unexpected error: %v", err)
    64  		}
    65  
    66  		// Because the chunks in the session where never 'Reported' as synced, the pending upload will be non-zero.
    67  
    68  		wantInfo := storer.Info{
    69  			Upload: storer.UploadStat{
    70  				TotalUploaded: 10,
    71  				TotalSynced:   0,
    72  				PendingUpload: 10,
    73  			},
    74  			Pinning: storer.PinningStat{
    75  				TotalCollections: 1,
    76  				TotalChunks:      10,
    77  			},
    78  			ChunkStore: storer.ChunkStoreStat{
    79  				TotalChunks:    10,
    80  				SharedSlots:    10,
    81  				ReferenceCount: 20,
    82  			},
    83  			Cache: storer.CacheStat{
    84  				Capacity: 1000000,
    85  			},
    86  			Reserve: storer.ReserveStat{
    87  				Capacity:   100,
    88  				LastBinIDs: emptyBinIDs(),
    89  				Epoch:      epoch,
    90  			},
    91  		}
    92  
    93  		if diff := cmp.Diff(wantInfo, info); diff != "" {
    94  			t.Fatalf("invalid info (+want -have):\n%s", diff)
    95  		}
    96  	})
    97  
    98  	t.Run("cache", func(t *testing.T) {
    99  		t.Parallel()
   100  
   101  		lstore, _, err := newStorer()
   102  		if err != nil {
   103  			t.Fatal(err)
   104  		}
   105  
   106  		_, epoch, err := lstore.ReserveLastBinIDs()
   107  		if err != nil {
   108  			t.Fatal(err)
   109  		}
   110  
   111  		chunks := chunktest.GenerateTestRandomChunks(10)
   112  		for _, ch := range chunks {
   113  			err := lstore.Cache().Put(context.Background(), ch)
   114  			if err != nil {
   115  				t.Fatalf("session.Put(...): unexpected error: %v", err)
   116  			}
   117  		}
   118  
   119  		info, err := lstore.DebugInfo(context.Background())
   120  		if err != nil {
   121  			t.Fatalf("DebugInfo(...): unexpected error: %v", err)
   122  		}
   123  
   124  		wantInfo := storer.Info{
   125  			ChunkStore: storer.ChunkStoreStat{
   126  				TotalChunks:    10,
   127  				ReferenceCount: 10,
   128  			},
   129  			Cache: storer.CacheStat{
   130  				Size:     10,
   131  				Capacity: 1000000,
   132  			},
   133  			Reserve: storer.ReserveStat{
   134  				Capacity:   100,
   135  				LastBinIDs: emptyBinIDs(),
   136  				Epoch:      epoch,
   137  			},
   138  		}
   139  
   140  		if diff := cmp.Diff(wantInfo, info); diff != "" {
   141  			t.Fatalf("invalid info (+want -have):\n%s", diff)
   142  		}
   143  	})
   144  
   145  	t.Run("reserve", func(t *testing.T) {
   146  		t.Parallel()
   147  
   148  		lstore, addr, err := newStorer()
   149  		if err != nil {
   150  			t.Fatal(err)
   151  		}
   152  
   153  		_, epoch, err := lstore.ReserveLastBinIDs()
   154  		if err != nil {
   155  			t.Fatal(err)
   156  		}
   157  
   158  		putter := lstore.ReservePutter()
   159  
   160  		for i := 0; i < 10; i++ {
   161  			chunk := chunktest.GenerateTestRandomChunkAt(t, addr, 0)
   162  			err := putter.Put(context.Background(), chunk)
   163  			if err != nil {
   164  				t.Fatalf("session.Put(...): unexpected error: %v", err)
   165  			}
   166  		}
   167  
   168  		info, err := lstore.DebugInfo(context.Background())
   169  		if err != nil {
   170  			t.Fatalf("DebugInfo(...): unexpected error: %v", err)
   171  		}
   172  
   173  		ids := emptyBinIDs()
   174  		ids[0] = 10
   175  
   176  		wantInfo := storer.Info{
   177  			ChunkStore: storer.ChunkStoreStat{
   178  				TotalChunks:    10,
   179  				ReferenceCount: 10,
   180  			},
   181  			Cache: storer.CacheStat{
   182  				Capacity: 1000000,
   183  			},
   184  			Reserve: storer.ReserveStat{
   185  				SizeWithinRadius: 10,
   186  				TotalSize:        10,
   187  				Capacity:         100,
   188  				LastBinIDs:       ids,
   189  				Epoch:            epoch,
   190  			},
   191  		}
   192  
   193  		if diff := cmp.Diff(wantInfo, info); diff != "" {
   194  			t.Fatalf("invalid info (+want -have):\n%s", diff)
   195  		}
   196  	})
   197  
   198  }
   199  
   200  func TestDebugInfo(t *testing.T) {
   201  	t.Parallel()
   202  
   203  	t.Run("inmem", func(t *testing.T) {
   204  		t.Parallel()
   205  
   206  		testDebugInfo(t, func() (*storer.DB, swarm.Address, error) {
   207  			addr := swarm.RandAddress(t)
   208  			store, err := storer.New(context.Background(), "", dbTestOps(addr, 100, nil, nil, time.Second))
   209  			return store, addr, err
   210  		})
   211  	})
   212  	t.Run("disk", func(t *testing.T) {
   213  		t.Parallel()
   214  
   215  		testDebugInfo(t, func() (*storer.DB, swarm.Address, error) {
   216  			addr := swarm.RandAddress(t)
   217  			store, err := diskStorer(t, dbTestOps(addr, 100, nil, nil, time.Second))()
   218  			return store, addr, err
   219  		})
   220  	})
   221  }