Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions pkg/daemon/fsclient.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ type FileSystemClient interface {
Chmod(string, os.FileMode) error
Chown(string, int, int) error
WriteFile(filename string, data []byte, perm os.FileMode) error
ReadFile(filename string) ([]byte, error)
}

// FsClient is used to hang the FileSystemClient functions on.
Expand Down Expand Up @@ -66,6 +67,11 @@ func (f FsClient) WriteFile(filename string, data []byte, perm os.FileMode) erro
return ioutil.WriteFile(filename, data, perm)
}

// ReadFile implements ioutil.WriteFile
func (f FsClient) ReadFile(filename string) ([]byte, error) {
return ioutil.ReadFile(filename)
}

// NewFileSystemClient creates a new file system client using the default
// implementations provided by the os package.
func NewFileSystemClient() FileSystemClient {
Expand Down
23 changes: 20 additions & 3 deletions pkg/daemon/fsclient_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,13 @@ type StatReturn struct {
Error error
}

// ReadFileReturn is a structure used for testing. It holds a single return value
// set for a mocked ReadFile call.
type ReadFileReturn struct {
Bytes []byte
Error error
}

// FsClientMockMock is used as a mock of FsClientMock for testing.
type FsClientMock struct {
CreateReturns []CreateReturn
Expand All @@ -27,14 +34,15 @@ type FsClientMock struct {
ChmodReturns []error
ChownReturns []error
WriteFileReturns []error
ReadFileReturns []ReadFileReturn
}

// updateErrorReturns is a shortcut to pop out the error and shift
// around the Returns array.
func updateErrorReturns(returns *[]error) error {
r := *returns
returnValues := r[0]
if len(r) > 0 {
if len(r) > 1 {
*returns = r[1:]
}
return returnValues
Expand All @@ -43,7 +51,7 @@ func updateErrorReturns(returns *[]error) error {
// Create provides a mocked implemention
func (f FsClientMock) Create(name string) (*os.File, error) {
returnValues := f.CreateReturns[0]
if len(f.RemoveReturns) > 0 {
if len(f.RemoveReturns) > 1 {
f.CreateReturns = f.CreateReturns[1:]
}
return returnValues.OsFilePointer, returnValues.Error
Expand All @@ -67,7 +75,7 @@ func (f FsClientMock) MkdirAll(name string, perm os.FileMode) error {
// Stat provides a mocked implemention
func (f FsClientMock) Stat(name string) (os.FileInfo, error) {
returnValues := f.StatReturns[0]
if len(f.RemoveReturns) > 0 {
if len(f.RemoveReturns) > 1 {
f.StatReturns = f.StatReturns[1:]
}
return returnValues.OsFileInfo, returnValues.Error
Expand All @@ -92,3 +100,12 @@ func (f FsClientMock) Chown(name string, uid, gid int) error {
func (f FsClientMock) WriteFile(filename string, data []byte, perm os.FileMode) error {
return updateErrorReturns(&f.WriteFileReturns)
}

// ReadFile provides a mocked implemention
func (f FsClientMock) ReadFile(filename string) ([]byte, error) {
returnValues := f.ReadFileReturns[0]
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shouldn't this be under the if statement to make sure the array is not empty first? E.g.

	if len(f....) > 0 {
		returnValues := f....[0]
		f.... = f.ReadFileReturns[1:]
		return returnValues
	}
	panic("no more values!")

?

I guess, as it is it'll panic anyway with index out of range, which I suppose was the intent since the unit test knows exactly how many times it should be called? But then it seems unnecessary to do the len check since if we got to there it means there definitely is at least one element. So an alternative is to just simplify it to:

	returnValues := f....[0]
	f.... = f.ReadFileReturns[1:]
	return returnValues

? (Though I still prefer the explicitness of the first alternative!)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The idea behind this is that:

  • If you provide nothing it panics
  • If you provide N returns and use N+X then X+1 will return the same last element (for example if I want everything to return no error I can just give it one nil, not 2, 5, 50, etc..)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm happy to do a follow on PR to make the panic explicit :-).

if len(f.ReadFileReturns) > 1 {
f.ReadFileReturns = f.ReadFileReturns[1:]
}
return returnValues.Bytes, returnValues.Error
}
4 changes: 2 additions & 2 deletions pkg/daemon/rpm-ostree_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ type RpmOstreeClientMock struct {
// It returns an OsImageURL, Version, and Error as defined in GetBootedOSImageURLReturns in order.
func (r RpmOstreeClientMock) GetBootedOSImageURL(string) (string, string, error) {
returnValues := r.GetBootedOSImageURLReturns[0]
if len(r.GetBootedOSImageURLReturns) > 0 {
if len(r.GetBootedOSImageURLReturns) > 1 {
r.GetBootedOSImageURLReturns = r.GetBootedOSImageURLReturns[1:]
}
return returnValues.OsImageURL, returnValues.Version, returnValues.Error
Expand All @@ -35,7 +35,7 @@ func (r RpmOstreeClientMock) GetBootedOSImageURL(string) (string, string, error)
// in the instances RunPivotReturns field in order.
func (r RpmOstreeClientMock) RunPivot(string) error {
err := r.RunPivotReturns[0]
if len(r.RunPivotReturns) > 0 {
if len(r.RunPivotReturns) > 1 {
r.RunPivotReturns = r.RunPivotReturns[1:]
}
return err
Expand Down