github.com/zuoyebang/bitalostable@v1.0.1-0.20240229032404-e3b99a834294/internal/metamorphic/generator_test.go (about)

     1  // Copyright 2019 The LevelDB-Go and Pebble Authors. All rights reserved. Use
     2  // of this source code is governed by a BSD-style license that can be found in
     3  // the LICENSE file.
     4  
     5  package metamorphic
     6  
     7  import (
     8  	"testing"
     9  	"time"
    10  
    11  	"github.com/pmezard/go-difflib/difflib"
    12  	"github.com/stretchr/testify/require"
    13  	"github.com/zuoyebang/bitalostable/internal/randvar"
    14  	"golang.org/x/exp/rand"
    15  )
    16  
    17  func TestGenerator(t *testing.T) {
    18  	rng := randvar.NewRand()
    19  	g := newGenerator(rng, defaultConfig(), newKeyManager())
    20  
    21  	g.newBatch()
    22  	g.newBatch()
    23  	g.newBatch()
    24  	require.EqualValues(t, 3, len(g.liveBatches))
    25  	require.EqualValues(t, 0, len(g.batches))
    26  
    27  	g.newIndexedBatch()
    28  	g.newIndexedBatch()
    29  	g.newIndexedBatch()
    30  	require.EqualValues(t, 6, len(g.liveBatches))
    31  	require.EqualValues(t, 3, len(g.batches))
    32  	require.EqualValues(t, 3, len(g.readers))
    33  
    34  	g.newIter()
    35  	g.newIter()
    36  	g.newIter()
    37  	require.EqualValues(t, 3, len(g.liveIters))
    38  
    39  	g.batchAbort()
    40  	g.batchAbort()
    41  	g.batchAbort()
    42  	g.batchAbort()
    43  	g.batchAbort()
    44  	g.batchAbort()
    45  
    46  	require.EqualValues(t, 0, len(g.liveBatches))
    47  	require.EqualValues(t, 0, len(g.batches))
    48  	require.EqualValues(t, 0, len(g.iters))
    49  	require.EqualValues(t, 1, len(g.liveReaders))
    50  	require.EqualValues(t, 0, len(g.readers))
    51  	require.EqualValues(t, 0, len(g.liveSnapshots))
    52  	require.EqualValues(t, 0, len(g.snapshots))
    53  	require.EqualValues(t, 1, len(g.liveWriters))
    54  
    55  	g.randIter(g.iterClose)()
    56  	g.randIter(g.iterClose)()
    57  	g.randIter(g.iterClose)()
    58  	require.EqualValues(t, 0, len(g.liveIters))
    59  
    60  	if testing.Verbose() {
    61  		t.Logf("\n%s", g)
    62  	}
    63  
    64  	g = newGenerator(rng, defaultConfig(), newKeyManager())
    65  
    66  	g.newSnapshot()
    67  	g.newSnapshot()
    68  	g.newSnapshot()
    69  	require.EqualValues(t, 3, len(g.liveSnapshots))
    70  	require.EqualValues(t, 3, len(g.snapshots))
    71  
    72  	g.newIter()
    73  	g.newIter()
    74  	g.newIter()
    75  	g.snapshotClose()
    76  	g.snapshotClose()
    77  	g.snapshotClose()
    78  
    79  	require.EqualValues(t, 0, len(g.liveBatches))
    80  	require.EqualValues(t, 0, len(g.batches))
    81  	require.EqualValues(t, 0, len(g.iters))
    82  	require.EqualValues(t, 1, len(g.liveReaders))
    83  	require.EqualValues(t, 0, len(g.readers))
    84  	require.EqualValues(t, 0, len(g.liveSnapshots))
    85  	require.EqualValues(t, 0, len(g.snapshots))
    86  	require.EqualValues(t, 1, len(g.liveWriters))
    87  
    88  	g.randIter(g.iterClose)()
    89  	g.randIter(g.iterClose)()
    90  	g.randIter(g.iterClose)()
    91  	require.EqualValues(t, 0, len(g.liveIters))
    92  
    93  	if testing.Verbose() {
    94  		t.Logf("\n%s", g)
    95  	}
    96  
    97  	g = newGenerator(rng, defaultConfig(), newKeyManager())
    98  
    99  	g.newIndexedBatch()
   100  	g.newIndexedBatch()
   101  	g.newIndexedBatch()
   102  	g.newIter()
   103  	g.newIter()
   104  	g.newIter()
   105  	g.writerApply()
   106  	g.writerApply()
   107  	g.writerApply()
   108  	g.randIter(g.iterClose)()
   109  	g.randIter(g.iterClose)()
   110  	g.randIter(g.iterClose)()
   111  
   112  	require.EqualValues(t, 0, len(g.liveBatches))
   113  	require.EqualValues(t, 0, len(g.batches))
   114  	require.EqualValues(t, 0, len(g.liveIters))
   115  	require.EqualValues(t, 0, len(g.iters))
   116  	require.EqualValues(t, 1, len(g.liveReaders))
   117  	require.EqualValues(t, 0, len(g.readers))
   118  	require.EqualValues(t, 0, len(g.liveSnapshots))
   119  	require.EqualValues(t, 0, len(g.snapshots))
   120  	require.EqualValues(t, 1, len(g.liveWriters))
   121  
   122  	if testing.Verbose() {
   123  		t.Logf("\n%s", g)
   124  	}
   125  }
   126  
   127  func TestGeneratorRandom(t *testing.T) {
   128  	seed := uint64(time.Now().UnixNano())
   129  	generateFromSeed := func() string {
   130  		rng := rand.New(rand.NewSource(seed))
   131  		count := ops.Uint64(rng)
   132  		return formatOps(generate(rng, count, defaultConfig(), newKeyManager()))
   133  	}
   134  
   135  	// Ensure that generate doesn't use any other source of randomness other
   136  	// than rng.
   137  	referenceOps := generateFromSeed()
   138  	for i := 0; i < 10; i++ {
   139  		regeneratedOps := generateFromSeed()
   140  		diff, err := difflib.GetUnifiedDiffString(difflib.UnifiedDiff{
   141  			A:       difflib.SplitLines(referenceOps),
   142  			B:       difflib.SplitLines(regeneratedOps),
   143  			Context: 1,
   144  		})
   145  		require.NoError(t, err)
   146  		if len(diff) > 0 {
   147  			t.Fatalf("Diff:\n%s", diff)
   148  		}
   149  	}
   150  	if testing.Verbose() {
   151  		t.Logf("\nOps:\n%s", referenceOps)
   152  	}
   153  }