github.com/weaviate/weaviate@v1.24.6/test/modules/backup-filesystem/backup_backend_test.go (about)

     1  //                           _       _
     2  // __      _____  __ ___   ___  __ _| |_ ___
     3  // \ \ /\ / / _ \/ _` \ \ / / |/ _` | __/ _ \
     4  //  \ V  V /  __/ (_| |\ V /| | (_| | ||  __/
     5  //   \_/\_/ \___|\__,_| \_/ |_|\__,_|\__\___|
     6  //
     7  //  Copyright © 2016 - 2024 Weaviate B.V. All rights reserved.
     8  //
     9  //  CONTACT: hello@weaviate.io
    10  //
    11  
    12  package test
    13  
    14  import (
    15  	"context"
    16  	"encoding/json"
    17  	"fmt"
    18  	"os"
    19  	"path/filepath"
    20  	"testing"
    21  	"time"
    22  
    23  	"github.com/sirupsen/logrus/hooks/test"
    24  	"github.com/stretchr/testify/assert"
    25  	"github.com/stretchr/testify/require"
    26  	"github.com/weaviate/weaviate/entities/backup"
    27  	"github.com/weaviate/weaviate/entities/moduletools"
    28  	modstgfs "github.com/weaviate/weaviate/modules/backup-filesystem"
    29  	moduleshelper "github.com/weaviate/weaviate/test/helper/modules"
    30  	ubak "github.com/weaviate/weaviate/usecases/backup"
    31  	"github.com/weaviate/weaviate/usecases/config"
    32  )
    33  
    34  func Test_FilesystemBackend_Backup(t *testing.T) {
    35  	t.Run("store backup meta", moduleLevelStoreBackupMeta)
    36  	t.Run("copy objects", moduleLevelCopyObjects)
    37  	t.Run("copy files", moduleLevelCopyFiles)
    38  }
    39  
    40  func moduleLevelStoreBackupMeta(t *testing.T) {
    41  	testCtx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
    42  	defer cancel()
    43  
    44  	dataDir := t.TempDir()
    45  	backupDir := t.TempDir()
    46  	className := "BackupClass"
    47  	backupID := "backup_id"
    48  	metadataFilename := "backup.json"
    49  
    50  	t.Setenv("BACKUP_FILESYSTEM_PATH", backupDir)
    51  
    52  	t.Run("store backup meta in fs", func(t *testing.T) {
    53  		logger, _ := test.NewNullLogger()
    54  		sp := fakeStorageProvider{dataDir}
    55  		params := moduletools.NewInitParams(sp, nil, config.Config{}, logger)
    56  
    57  		fs := modstgfs.New()
    58  		err := fs.Init(testCtx, params)
    59  		require.Nil(t, err)
    60  
    61  		t.Run("access permissions", func(t *testing.T) {
    62  			err := fs.Initialize(testCtx, backupID)
    63  			assert.Nil(t, err)
    64  		})
    65  
    66  		t.Run("backup meta does not exist yet", func(t *testing.T) {
    67  			meta, err := fs.GetObject(testCtx, backupID, metadataFilename)
    68  			assert.Nil(t, meta)
    69  			assert.NotNil(t, err)
    70  			assert.IsType(t, backup.ErrNotFound{}, err)
    71  		})
    72  
    73  		t.Run("put backup meta on backend", func(t *testing.T) {
    74  			desc := &backup.BackupDescriptor{
    75  				StartedAt:   time.Now(),
    76  				CompletedAt: time.Time{},
    77  				ID:          backupID,
    78  				Classes: []backup.ClassDescriptor{
    79  					{
    80  						Name: className,
    81  					},
    82  				},
    83  				Status:  string(backup.Started),
    84  				Version: ubak.Version,
    85  			}
    86  
    87  			b, err := json.Marshal(desc)
    88  			require.Nil(t, err)
    89  
    90  			err = fs.PutObject(testCtx, backupID, metadataFilename, b)
    91  			require.Nil(t, err)
    92  
    93  			dest := fs.HomeDir(backupID)
    94  			expected := fmt.Sprintf("%s/%s", backupDir, backupID)
    95  			assert.Equal(t, expected, dest)
    96  		})
    97  	})
    98  }
    99  
   100  func moduleLevelCopyObjects(t *testing.T) {
   101  	testCtx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
   102  	defer cancel()
   103  
   104  	dataDir := t.TempDir()
   105  	backupDir := t.TempDir()
   106  	key := "moduleLevelCopyObjects"
   107  	backupID := "backup_id"
   108  
   109  	t.Setenv("BACKUP_FILESYSTEM_PATH", backupDir)
   110  
   111  	t.Run("copy objects", func(t *testing.T) {
   112  		logger, _ := test.NewNullLogger()
   113  		sp := fakeStorageProvider{dataDir}
   114  		params := moduletools.NewInitParams(sp, nil, config.Config{}, logger)
   115  
   116  		fs := modstgfs.New()
   117  		err := fs.Init(testCtx, params)
   118  		require.Nil(t, err)
   119  
   120  		t.Run("put object to bucket", func(t *testing.T) {
   121  			err := fs.PutObject(testCtx, backupID, key, []byte("hello"))
   122  			assert.Nil(t, err)
   123  		})
   124  
   125  		t.Run("get object from bucket", func(t *testing.T) {
   126  			meta, err := fs.GetObject(testCtx, backupID, key)
   127  			assert.Nil(t, err)
   128  			assert.Equal(t, []byte("hello"), meta)
   129  		})
   130  	})
   131  }
   132  
   133  func moduleLevelCopyFiles(t *testing.T) {
   134  	testCtx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
   135  	defer cancel()
   136  
   137  	dataDir := t.TempDir()
   138  	backupDir := t.TempDir()
   139  	key := "moduleLevelCopyFiles"
   140  	backupID := "backup_id"
   141  
   142  	t.Setenv("BACKUP_FILESYSTEM_PATH", backupDir)
   143  
   144  	t.Run("copy files", func(t *testing.T) {
   145  		fpaths := moduleshelper.CreateTestFiles(t, dataDir)
   146  		fpath := fpaths[0]
   147  		expectedContents, err := os.ReadFile(fpath)
   148  		require.Nil(t, err)
   149  		require.NotNil(t, expectedContents)
   150  
   151  		logger, _ := test.NewNullLogger()
   152  		sp := fakeStorageProvider{dataDir}
   153  		params := moduletools.NewInitParams(sp, nil, config.Config{}, logger)
   154  
   155  		fs := modstgfs.New()
   156  		err = fs.Init(testCtx, params)
   157  		require.Nil(t, err)
   158  
   159  		t.Run("verify source data path", func(t *testing.T) {
   160  			assert.Equal(t, dataDir, fs.SourceDataPath())
   161  		})
   162  
   163  		t.Run("copy file to backend", func(t *testing.T) {
   164  			srcPath, _ := filepath.Rel(dataDir, fpath)
   165  			err := fs.PutFile(testCtx, backupID, key, srcPath)
   166  			require.Nil(t, err)
   167  
   168  			contents, err := fs.GetObject(testCtx, backupID, key)
   169  			require.Nil(t, err)
   170  			assert.Equal(t, expectedContents, contents)
   171  		})
   172  
   173  		t.Run("fetch file from backend", func(t *testing.T) {
   174  			destPath := dataDir + "/file_0.copy.db"
   175  
   176  			err := fs.WriteToFile(testCtx, backupID, key, destPath)
   177  			require.Nil(t, err)
   178  
   179  			contents, err := os.ReadFile(destPath)
   180  			require.Nil(t, err)
   181  			assert.Equal(t, expectedContents, contents)
   182  		})
   183  	})
   184  }
   185  
   186  type fakeStorageProvider struct {
   187  	dataPath string
   188  }
   189  
   190  func (sp fakeStorageProvider) Storage(name string) (moduletools.Storage, error) {
   191  	return nil, nil
   192  }
   193  
   194  func (sp fakeStorageProvider) DataPath() string {
   195  	return sp.dataPath
   196  }