github.com/cockroachdb/pebble@v1.1.1-0.20240513155919-3622ade60459/cleaner_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 pebble
     6  
     7  import (
     8  	"fmt"
     9  	"sort"
    10  	"strings"
    11  	"testing"
    12  
    13  	"github.com/cockroachdb/datadriven"
    14  	"github.com/cockroachdb/pebble/internal/base"
    15  	"github.com/cockroachdb/pebble/vfs"
    16  	"github.com/stretchr/testify/require"
    17  )
    18  
    19  func TestCleaner(t *testing.T) {
    20  	dbs := make(map[string]*DB)
    21  	defer func() {
    22  		for _, db := range dbs {
    23  			require.NoError(t, db.Close())
    24  		}
    25  	}()
    26  
    27  	mem := vfs.NewMem()
    28  	var memLog base.InMemLogger
    29  	fs := vfs.WithLogging(mem, memLog.Infof)
    30  	datadriven.RunTest(t, "testdata/cleaner", func(t *testing.T, td *datadriven.TestData) string {
    31  		memLog.Reset()
    32  		switch td.Cmd {
    33  		case "batch":
    34  			if len(td.CmdArgs) != 1 {
    35  				return "batch <db>"
    36  			}
    37  			d := dbs[td.CmdArgs[0].String()]
    38  			b := d.NewBatch()
    39  			if err := runBatchDefineCmd(td, b); err != nil {
    40  				return err.Error()
    41  			}
    42  			if err := b.Commit(Sync); err != nil {
    43  				return err.Error()
    44  			}
    45  			return memLog.String()
    46  
    47  		case "compact":
    48  			if len(td.CmdArgs) != 1 {
    49  				return "compact <db>"
    50  			}
    51  			d := dbs[td.CmdArgs[0].String()]
    52  			if err := d.Compact(nil, []byte("\xff"), false); err != nil {
    53  				return err.Error()
    54  			}
    55  			return memLog.String()
    56  
    57  		case "flush":
    58  			if len(td.CmdArgs) != 1 {
    59  				return "flush <db>"
    60  			}
    61  			d := dbs[td.CmdArgs[0].String()]
    62  			if err := d.Flush(); err != nil {
    63  				return err.Error()
    64  			}
    65  			return memLog.String()
    66  
    67  		case "close":
    68  			if len(td.CmdArgs) != 1 {
    69  				return "close <db>"
    70  			}
    71  			dbDir := td.CmdArgs[0].String()
    72  			d := dbs[dbDir]
    73  			if err := d.Close(); err != nil {
    74  				return err.Error()
    75  			}
    76  			delete(dbs, dbDir)
    77  			return memLog.String()
    78  
    79  		case "list":
    80  			if len(td.CmdArgs) != 1 {
    81  				return "list <dir>"
    82  			}
    83  			paths, err := mem.List(td.CmdArgs[0].String())
    84  			if err != nil {
    85  				return err.Error()
    86  			}
    87  			sort.Strings(paths)
    88  			return fmt.Sprintf("%s\n", strings.Join(paths, "\n"))
    89  
    90  		case "open":
    91  			if len(td.CmdArgs) < 1 || len(td.CmdArgs) > 3 {
    92  				return "open <dir> [archive] [readonly]"
    93  			}
    94  			dir := td.CmdArgs[0].String()
    95  			opts := (&Options{
    96  				FS:     fs,
    97  				WALDir: dir + "_wal",
    98  			}).WithFSDefaults()
    99  
   100  			for i := 1; i < len(td.CmdArgs); i++ {
   101  				switch td.CmdArgs[i].String() {
   102  				case "readonly":
   103  					opts.ReadOnly = true
   104  				case "archive":
   105  					opts.Cleaner = ArchiveCleaner{}
   106  				default:
   107  					return "open <dir> [archive] [readonly]"
   108  				}
   109  			}
   110  			// Asynchronous table stats retrieval makes the output flaky.
   111  			opts.private.disableTableStats = true
   112  			opts.private.testingAlwaysWaitForCleanup = true
   113  			d, err := Open(dir, opts)
   114  			if err != nil {
   115  				return err.Error()
   116  			}
   117  			d.TestOnlyWaitForCleaning()
   118  			dbs[dir] = d
   119  			return memLog.String()
   120  
   121  		case "create-bogus-file":
   122  			if len(td.CmdArgs) != 1 {
   123  				return "create-bogus-file <db/file>"
   124  			}
   125  			dst, err := fs.Create(td.CmdArgs[0].String())
   126  			require.NoError(t, err)
   127  			_, err = dst.Write([]byte("bogus data"))
   128  			require.NoError(t, err)
   129  			require.NoError(t, dst.Sync())
   130  			require.NoError(t, dst.Close())
   131  			return memLog.String()
   132  
   133  		default:
   134  			return fmt.Sprintf("unknown command: %s", td.Cmd)
   135  		}
   136  	})
   137  }