vitess.io/vitess@v0.16.2/go/vt/vtctl/grpcvtctldserver/testutil/test_backupstorage.go (about)

     1  /*
     2  Copyright 2021 The Vitess Authors.
     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 testutil
    18  
    19  import (
    20  	"context"
    21  	"fmt"
    22  	"sort"
    23  
    24  	"vitess.io/vitess/go/vt/mysqlctl/backupstorage"
    25  )
    26  
    27  type backupStorage struct {
    28  	backupstorage.BackupStorage
    29  
    30  	// Backups is a mapping of directory to list of backup names stored in that
    31  	// directory.
    32  	Backups map[string][]string
    33  	// ListBackupsError is returned from ListBackups when it is non-nil.
    34  	ListBackupsError error
    35  }
    36  
    37  // ListBackups is part of the backupstorage.BackupStorage interface.
    38  func (bs *backupStorage) ListBackups(ctx context.Context, dir string) ([]backupstorage.BackupHandle, error) {
    39  	if bs.ListBackupsError != nil {
    40  		return nil, bs.ListBackupsError
    41  	}
    42  
    43  	handles := []backupstorage.BackupHandle{}
    44  
    45  	for k, v := range bs.Backups {
    46  		if k == dir {
    47  			for _, name := range v {
    48  				handles = append(handles, &backupHandle{directory: k, name: name})
    49  			}
    50  		}
    51  	}
    52  
    53  	sort.Sort(handlesByName(handles))
    54  
    55  	return handles, nil
    56  }
    57  
    58  // RemoveBackup is part of the backupstorage.BackupStorage interface.
    59  func (bs *backupStorage) RemoveBackup(ctx context.Context, dir string, name string) error {
    60  	bucket, ok := bs.Backups[dir]
    61  	if !ok {
    62  		return fmt.Errorf("no bucket for key %s in testutil.BackupStorage", dir)
    63  	}
    64  
    65  	idx := -1
    66  	for i, backup := range bucket {
    67  		if backup == name {
    68  			idx = i
    69  			break
    70  		}
    71  	}
    72  
    73  	if idx == -1 {
    74  		return fmt.Errorf("no backup found for %s/%s", dir, name)
    75  	}
    76  
    77  	bs.Backups[dir] = append(bucket[:idx], bucket[idx+1:]...)
    78  	return nil
    79  }
    80  
    81  // Close is part of the backupstorage.BackupStorage interface.
    82  func (bs *backupStorage) Close() error { return nil }
    83  
    84  // backupHandle implements a subset of the backupstorage.backupHandle interface.
    85  type backupHandle struct {
    86  	backupstorage.BackupHandle
    87  
    88  	directory string
    89  	name      string
    90  }
    91  
    92  func (bh *backupHandle) Directory() string { return bh.directory }
    93  func (bh *backupHandle) Name() string      { return bh.name }
    94  
    95  // handlesByName implements the sort interface for backup handles by Name().
    96  type handlesByName []backupstorage.BackupHandle
    97  
    98  func (a handlesByName) Len() int           { return len(a) }
    99  func (a handlesByName) Swap(i, j int)      { a[i], a[j] = a[j], a[i] }
   100  func (a handlesByName) Less(i, j int) bool { return a[i].Name() < a[j].Name() }
   101  
   102  // BackupStorageImplementation is the name this package registers its test
   103  // backupstorage.BackupStorage implementation as. Users should set
   104  // *backupstorage.BackupStorageImplementation to this value before use.
   105  const BackupStorageImplementation = "grpcvtctldserver.testutil"
   106  
   107  // BackupStorage is the singleton test backupstorage.BackupStorage intastnce. It
   108  // is public and singleton to allow tests to both mutate and assert against its
   109  // state.
   110  var BackupStorage = &backupStorage{
   111  	Backups: map[string][]string{},
   112  }
   113  
   114  func init() {
   115  	backupstorage.BackupStorageMap[BackupStorageImplementation] = BackupStorage
   116  }