...

Source file src/github.com/theupdateframework/go-tuf/client/file_store_test.go

Documentation: github.com/theupdateframework/go-tuf/client

     1  package client
     2  
     3  import (
     4  	"bytes"
     5  	"io"
     6  	"io/fs"
     7  	"os"
     8  	"path/filepath"
     9  	"runtime"
    10  	"strings"
    11  	"testing"
    12  )
    13  
    14  const targetsDir = "targets"
    15  
    16  func TestCreates(t *testing.T) {
    17  	runningWindows := false
    18  	if runtime.GOOS == "windows" {
    19  		runningWindows = true
    20  	}
    21  	tmpDir := t.TempDir()
    22  	defer os.RemoveAll(tmpDir)
    23  	dir := filepath.Join(tmpDir, "repository")
    24  	os.Mkdir(dir, os.ModePerm)
    25  	os.Mkdir(filepath.Join(dir, "targets"), os.ModePerm)
    26  	if !runningWindows {
    27  		targetDirThatIsFile := filepath.Join(dir, "targets-that-isfile")
    28  		f, err := os.Create(targetDirThatIsFile)
    29  		if err != nil {
    30  			t.Fatalf("failed to create file: %s: %v", targetDirThatIsFile, err)
    31  		}
    32  		defer f.Close()
    33  	}
    34  	t.Cleanup(func() { rmrf(dir, t.Logf) })
    35  	t.Cleanup(func() { rmrf(tmpDir, t.Logf) })
    36  
    37  	tests := []struct {
    38  		name              string
    39  		fsys              fs.FS
    40  		td                string
    41  		wantErr           string
    42  		doNotRunOnWindows bool
    43  	}{{
    44  		name:    "nil, error",
    45  		wantErr: "nil fs.FS",
    46  	}, {
    47  		name:    "missing targets directory",
    48  		fsys:    os.DirFS(dir),
    49  		td:      "targets-not-there",
    50  		wantErr: "failed to open targets directory targets-not-there",
    51  	}, {
    52  		name:              "targets directory is not a file",
    53  		fsys:              os.DirFS(dir),
    54  		td:                "targets-that-isfile",
    55  		wantErr:           "targets directory not a directory targets-that-isfile",
    56  		doNotRunOnWindows: true,
    57  	}, {
    58  		name: "works, explicit targets",
    59  		fsys: os.DirFS(dir),
    60  		td:   "targets",
    61  	}, {
    62  		name: "works, explicit targets",
    63  		fsys: os.DirFS(dir),
    64  		td:   "targets",
    65  	}}
    66  
    67  	for _, tc := range tests {
    68  		if tc.doNotRunOnWindows {
    69  			t.Skip("Can't figure out how to make this work on windows")
    70  		}
    71  		_, err := NewFileRemoteStore(tc.fsys, tc.td)
    72  		if tc.wantErr != "" && err == nil {
    73  			t.Errorf("%q wanted error %s, got none", tc.name, tc.wantErr)
    74  		} else if tc.wantErr == "" && err != nil {
    75  			t.Errorf("%q did not want error, got: %v", tc.name, err)
    76  		} else if err != nil && !strings.Contains(err.Error(), tc.wantErr) {
    77  			t.Errorf("%q wanted error %s but got: %s", tc.name, tc.wantErr, err)
    78  		}
    79  	}
    80  }
    81  
    82  func TestBasicOps(t *testing.T) {
    83  	metas := map[string][]byte{
    84  		"root.json":     []byte("root"),
    85  		"snapshot.json": []byte("snapshot"),
    86  		"timestamp":     []byte("timestamp"),
    87  	}
    88  
    89  	fsys, dir, err := newTestFileStoreFS()
    90  	if err != nil {
    91  		t.Fatalf("Failed to create test FileStore")
    92  	}
    93  	t.Cleanup(func() { rmrf(dir, t.Logf) })
    94  	defer os.RemoveAll(dir)
    95  
    96  	// Add targets and metas and check them.
    97  	for k, v := range targetFiles {
    98  		if err := fsys.addTarget(k, v); err != nil {
    99  			t.Errorf("failed to add target %s: %v", k, err)
   100  		}
   101  		rc, size, err := fsys.GetTarget(k)
   102  		if err != nil {
   103  			t.Errorf("failed to GetTarget %s: %v", k, err)
   104  		}
   105  		if size != int64(len(v)) {
   106  			t.Errorf("unexpected size returned for GetTarget: %s want %d got %d", k, len(v), size)
   107  		}
   108  		got, err := io.ReadAll(rc)
   109  		if err != nil {
   110  			t.Errorf("failed to ReadAll returned ReacCloser %s: %v", k, err)
   111  		}
   112  		if !bytes.Equal(v, got) {
   113  			t.Errorf("Read unexpected bytes, want: %s got: %s", string(k), string(got))
   114  		}
   115  	}
   116  	for k, v := range metas {
   117  		if err := fsys.addMeta(k, v); err != nil {
   118  			t.Errorf("failed to add meta %s %v", k, err)
   119  		}
   120  		rc, size, err := fsys.GetMeta(k)
   121  		if err != nil {
   122  			t.Errorf("failed to GetMeta %s: %v", k, err)
   123  		}
   124  		if size != int64(len(v)) {
   125  			t.Errorf("unexpected size returned for GetMeta: %s want %d got %d", k, len(v), size)
   126  		}
   127  		got, err := io.ReadAll(rc)
   128  		if err != nil {
   129  			t.Errorf("failed to ReadAll returned ReacCloser %s: %v", k, err)
   130  		}
   131  		if !bytes.Equal(v, got) {
   132  			t.Errorf("Read unexpected bytes, want: %s got: %s", string(k), string(got))
   133  		}
   134  	}
   135  }
   136  
   137  // Test helper methods
   138  func (f *FileRemoteStore) addMeta(name string, data []byte) error {
   139  	return os.WriteFile(filepath.Join(f.testDir, name), data, os.ModePerm)
   140  }
   141  
   142  func (f *FileRemoteStore) addTarget(name string, data []byte) error {
   143  	fname := filepath.Join(f.testDir, targetsDir, name)
   144  	err := os.WriteFile(fname, data, os.ModePerm)
   145  	return err
   146  }
   147  
   148  func (f *FileRemoteStore) deleteMeta(name string) error {
   149  	return os.Remove(filepath.Join(f.testDir, name))
   150  }
   151  
   152  func (f *FileRemoteStore) deleteTarget(name string) error {
   153  	return os.Remove(filepath.Join(f.testDir, targetsDir, name))
   154  }
   155  
   156  func newTestFileStoreFS() (*FileRemoteStore, string, error) {
   157  	tmpDir := os.TempDir()
   158  	tufDir := filepath.Join(tmpDir, "tuf-file-store-test")
   159  	// Clean it in case there is cruft left around
   160  	os.RemoveAll(tufDir)
   161  	os.Mkdir(tufDir, os.ModePerm)
   162  	os.Mkdir(filepath.Join(tufDir, targetsDir), os.ModePerm)
   163  	fs, err := NewFileRemoteStore(os.DirFS(tufDir), targetsDir)
   164  	fs.testDir = tufDir
   165  	return fs, tufDir, err
   166  }
   167  
   168  // goes through a dir and removes everything. This is to work around:
   169  // https://github.com/golang/go/issues/51442
   170  func rmrf(dir string, logger func(string, ...interface{})) {
   171  	if dir == "" {
   172  		logger("cowardly refusing to remove a not fully specified fir")
   173  		return
   174  	}
   175  	logger("Removing %s", dir)
   176  	d, err := os.Open(dir)
   177  	if err != nil {
   178  		logger("Failed to open %s: %v", dir, err)
   179  		return
   180  	}
   181  	defer d.Close()
   182  	// -1 means give me everything, we don't have that many entries, so
   183  	// fine here.
   184  	names, err := d.Readdirnames(-1)
   185  	if err != nil {
   186  		logger("Failed to ReaddirNames %s: %v", dir, err)
   187  		return
   188  	}
   189  	for _, name := range names {
   190  		toRemove := filepath.Join(dir, name)
   191  		err = os.RemoveAll(toRemove)
   192  		if err != nil {
   193  			logger("Failed to RemoveAll %s: %v", toRemove, err)
   194  			// Do not want to fail here, just keep doing the best we can
   195  		}
   196  	}
   197  }
   198  

View as plain text