github.com/pingcap/badger@v1.5.1-0.20230103063557-828f39b09b6d/backup_test.go (about)

     1  /*
     2   * Copyright 2017 Dgraph Labs, Inc. and Contributors
     3   *
     4   * Licensed under the Apache License, Version 2.0 (the "License");
     5   * you may not use this file except in compliance with the License.
     6   * You may obtain a copy of the License at
     7   *
     8   *     http://www.apache.org/licenses/LICENSE-2.0
     9   *
    10   * Unless required by applicable law or agreed to in writing, software
    11   * distributed under the License is distributed on an "AS IS" BASIS,
    12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13   * See the License for the specific language governing permissions and
    14   * limitations under the License.
    15   */
    16  
    17  package badger
    18  
    19  import (
    20  	"bytes"
    21  	"fmt"
    22  	"io/ioutil"
    23  	"os"
    24  	"path/filepath"
    25  	"reflect"
    26  	"testing"
    27  
    28  	"github.com/stretchr/testify/require"
    29  )
    30  
    31  func TestDumpLoad(t *testing.T) {
    32  	dir, err := ioutil.TempDir("", "badger")
    33  	require.NoError(t, err)
    34  	defer os.RemoveAll(dir)
    35  	db, err := Open(getTestOptions(dir))
    36  	require.NoError(t, err)
    37  
    38  	// Write some stuff
    39  	entries := []struct {
    40  		key      []byte
    41  		val      []byte
    42  		userMeta byte
    43  		version  uint64
    44  	}{
    45  		{key: []byte("answer1"), val: []byte("42"), version: 1},
    46  		{key: []byte("answer2"), val: []byte("43"), userMeta: 1, version: 2},
    47  	}
    48  
    49  	err = db.Update(func(txn *Txn) error {
    50  		e := entries[0]
    51  		err := txn.SetWithMeta(e.key, e.val, e.userMeta)
    52  		if err != nil {
    53  			return err
    54  		}
    55  		return nil
    56  	})
    57  	require.NoError(t, err)
    58  
    59  	err = db.Update(func(txn *Txn) error {
    60  		e := entries[1]
    61  		err := txn.SetWithMeta(e.key, e.val, e.userMeta)
    62  		if err != nil {
    63  			return err
    64  		}
    65  		return nil
    66  	})
    67  	require.NoError(t, err)
    68  
    69  	// Use different directory.
    70  	dir, err = ioutil.TempDir("", "badger")
    71  	require.NoError(t, err)
    72  	defer os.RemoveAll(dir)
    73  	bak, err := ioutil.TempFile(dir, "badgerbak")
    74  	require.NoError(t, err)
    75  	ts, err := db.Backup(bak, 0)
    76  	t.Logf("New ts: %d\n", ts)
    77  	require.NoError(t, err)
    78  	require.NoError(t, bak.Close())
    79  	require.NoError(t, db.Close())
    80  
    81  	db, err = Open(getTestOptions(dir))
    82  	require.NoError(t, err)
    83  	defer db.Close()
    84  	bak, err = os.Open(bak.Name())
    85  	require.NoError(t, err)
    86  	defer bak.Close()
    87  
    88  	require.NoError(t, db.Load(bak))
    89  
    90  	err = db.View(func(txn *Txn) error {
    91  		opts := DefaultIteratorOptions
    92  		opts.AllVersions = true
    93  		it := txn.NewIterator(opts)
    94  		defer it.Close()
    95  		var count int
    96  		for it.Rewind(); it.Valid(); it.Next() {
    97  			item := it.Item()
    98  			val, err := item.Value()
    99  			if err != nil {
   100  				return err
   101  			}
   102  			require.Equal(t, entries[count].key, item.Key())
   103  			require.Equal(t, entries[count].val, val)
   104  			require.Equal(t, entries[count].version, item.Version())
   105  			require.Equal(t, []byte{entries[count].userMeta}, item.UserMeta())
   106  			count++
   107  		}
   108  		require.Equal(t, count, 2)
   109  		return nil
   110  	})
   111  	require.NoError(t, err)
   112  }
   113  
   114  func Test_BackupRestore(t *testing.T) {
   115  	tmpdir, err := ioutil.TempDir("", "badger-test")
   116  	if err != nil {
   117  		t.Fatal(err)
   118  	}
   119  	defer func() {
   120  		os.RemoveAll(tmpdir)
   121  	}()
   122  
   123  	s1Path := filepath.Join(tmpdir, "test1")
   124  	s2Path := filepath.Join(tmpdir, "test2")
   125  	s3Path := filepath.Join(tmpdir, "test3")
   126  
   127  	db1, err := Open(getTestOptions(s1Path))
   128  	if err != nil {
   129  		t.Fatal(err)
   130  	}
   131  	key1 := []byte("key1")
   132  	key2 := []byte("key2")
   133  	rawValue := []byte("NotLongValue")
   134  	N := byte(251)
   135  	err = db1.Update(func(tx *Txn) error {
   136  		if err := tx.Set(key1, rawValue); err != nil {
   137  			return err
   138  		}
   139  		return tx.Set(key2, rawValue)
   140  	})
   141  	if err != nil {
   142  		t.Fatal(err)
   143  	}
   144  	for i := byte(0); i < N; i++ {
   145  		err = db1.Update(func(tx *Txn) error {
   146  			if err := tx.Set(append(key1, i), rawValue); err != nil {
   147  				return err
   148  			}
   149  			return tx.Set(append(key2, i), rawValue)
   150  		})
   151  		if err != nil {
   152  			t.Fatal(err)
   153  		}
   154  	}
   155  	var backup bytes.Buffer
   156  	_, err = db1.Backup(&backup, 0)
   157  	if err != nil {
   158  		t.Fatal(err)
   159  	}
   160  	fmt.Println("backup1 length:", backup.Len())
   161  	require.NoError(t, db1.Close())
   162  
   163  	db2, err := Open(getTestOptions(s2Path))
   164  	if err != nil {
   165  		t.Fatal(err)
   166  	}
   167  	err = db2.Load(&backup)
   168  	if err != nil {
   169  		t.Fatal(err)
   170  	}
   171  
   172  	for i := byte(0); i < N; i++ {
   173  		err = db2.View(func(tx *Txn) error {
   174  			k := append(key1, i)
   175  			item, err := tx.Get(k)
   176  			if err != nil {
   177  				if err == ErrKeyNotFound {
   178  					return fmt.Errorf("Key %q has been not found, but was set\n", k)
   179  				}
   180  				return err
   181  			}
   182  			v, err := item.Value()
   183  			if err != nil {
   184  				return err
   185  			}
   186  			if !reflect.DeepEqual(v, rawValue) {
   187  				return fmt.Errorf("Values not match, got %v, expected %v", v, rawValue)
   188  			}
   189  			return nil
   190  		})
   191  		if err != nil {
   192  			t.Fatal(err)
   193  		}
   194  	}
   195  
   196  	for i := byte(0); i < N; i++ {
   197  		err = db2.Update(func(tx *Txn) error {
   198  			if err := tx.Set(append(key1, i), rawValue); err != nil {
   199  				return err
   200  			}
   201  			return tx.Set(append(key2, i), rawValue)
   202  		})
   203  		if err != nil {
   204  			t.Fatal(err)
   205  		}
   206  	}
   207  
   208  	backup.Reset()
   209  	_, err = db2.Backup(&backup, 0)
   210  	if err != nil {
   211  		t.Fatal(err)
   212  	}
   213  	fmt.Println("backup2 length:", backup.Len())
   214  	db3, err := Open(getTestOptions(s3Path))
   215  	if err != nil {
   216  		t.Fatal(err)
   217  	}
   218  
   219  	err = db3.Load(&backup)
   220  	if err != nil {
   221  		t.Fatal(err)
   222  	}
   223  
   224  	for i := byte(0); i < N; i++ {
   225  		err = db3.View(func(tx *Txn) error {
   226  			k := append(key1, i)
   227  			item, err := tx.Get(k)
   228  			if err != nil {
   229  				if err == ErrKeyNotFound {
   230  					return fmt.Errorf("Key %q has been not found, but was set\n", k)
   231  				}
   232  				return err
   233  			}
   234  			v, err := item.Value()
   235  			if err != nil {
   236  				return err
   237  			}
   238  			if !reflect.DeepEqual(v, rawValue) {
   239  				return fmt.Errorf("Values not match, got %v, expected %v", v, rawValue)
   240  			}
   241  			return nil
   242  		})
   243  		if err != nil {
   244  			t.Fatal(err)
   245  		}
   246  	}
   247  	require.NoError(t, db3.Close())
   248  
   249  }