From d8d9157afc887c9fd87f625cf85a3b46c9e0338c Mon Sep 17 00:00:00 2001 From: Jeffrey Regan Date: Tue, 30 Jan 2018 11:15:34 -0800 Subject: [PATCH] Tweak the fakes, add a test of fake. --- .../util/fs/{fake/file.go => fakefile.go} | 25 +++++++--- .../util/fs/{fake/fs.go => fakefs.go} | 37 ++++++++------ pkg/kinflate/util/fs/fakefs_test.go | 50 +++++++++++++++++++ pkg/kinflate/util/fs/fs.go | 24 ++++----- pkg/kinflate/util/fs/{file.go => realfile.go} | 25 +++++++--- .../util/fs/{interface.go => realfs.go} | 24 ++++----- 6 files changed, 130 insertions(+), 55 deletions(-) rename pkg/kinflate/util/fs/{fake/file.go => fakefile.go} (66%) rename pkg/kinflate/util/fs/{fake/fs.go => fakefs.go} (53%) create mode 100644 pkg/kinflate/util/fs/fakefs_test.go rename pkg/kinflate/util/fs/{file.go => realfile.go} (55%) rename pkg/kinflate/util/fs/{interface.go => realfs.go} (58%) diff --git a/pkg/kinflate/util/fs/fake/file.go b/pkg/kinflate/util/fs/fakefile.go similarity index 66% rename from pkg/kinflate/util/fs/fake/file.go rename to pkg/kinflate/util/fs/fakefile.go index 53b8cf203..0bc9157b2 100644 --- a/pkg/kinflate/util/fs/fake/file.go +++ b/pkg/kinflate/util/fs/fakefile.go @@ -17,37 +17,46 @@ limitations under the License. package fs import ( + "bytes" "os" - - "k8s.io/kubectl/pkg/kinflate/util/fs" ) -var _ fs.File = &FakeFile{} +var _ File = &FakeFile{} -// FakeFile implements FileSystem using a fake in-memory filesystem. +// FakeFile implements File in-memory for tests. type FakeFile struct { content []byte open bool } -// Close closes a file. +// MakeFakeFile makes a fake file. +func MakeFakeFile() *FakeFile { + return &FakeFile{} +} + +// Close marks the fake file closed. func (f *FakeFile) Close() error { f.open = false return nil } -// Read reads a file's content. +// Read never fails, and doesn't mutate p. func (f *FakeFile) Read(p []byte) (n int, err error) { return len(p), nil } -// Write writes bytes to a file +// Write saves the contents of the argument to memory. func (f *FakeFile) Write(p []byte) (n int, err error) { f.content = p return len(p), nil } -// Stat returns an interface which has all the information regarding the file. +// ContentMatches returns true if v matches fake file's content. +func (f *FakeFile) ContentMatches(v []byte) bool { + return bytes.Equal(v, f.content) +} + +// Stat returns nil. func (f *FakeFile) Stat() (os.FileInfo, error) { return nil, nil } diff --git a/pkg/kinflate/util/fs/fake/fs.go b/pkg/kinflate/util/fs/fakefs.go similarity index 53% rename from pkg/kinflate/util/fs/fake/fs.go rename to pkg/kinflate/util/fs/fakefs.go index 1500e2adc..94b31ffe2 100644 --- a/pkg/kinflate/util/fs/fake/fs.go +++ b/pkg/kinflate/util/fs/fakefs.go @@ -17,33 +17,38 @@ limitations under the License. package fs import ( + "errors" "os" - - "k8s.io/kubectl/pkg/kinflate/util/fs" ) -var _ fs.FileSystem = &FakeFS{} +var _ FileSystem = &FakeFS{} // FakeFS implements FileSystem using a fake in-memory filesystem. -type FakeFS struct{ m map[string]*FakeFile } +type FakeFS struct { + m map[string]*FakeFile +} -// Create creates a file given the filename. -func (fs *FakeFS) Create(name string) (fs.File, error) { - if fs.m == nil { - fs.m = map[string]*FakeFile{} - } +// MakeFakeFS returns an instance of FakeFS with no files in it. +func MakeFakeFS() *FakeFS { + return &FakeFS{m: map[string]*FakeFile{}} +} + +// Create assures a fake file appears in the in-memory file system. +func (fs *FakeFS) Create(name string) (File, error) { fs.m[name] = &FakeFile{} return fs.m[name], nil } -// Open opens a file given the filename. -func (fs *FakeFS) Open(name string) (fs.File, error) { - if fs.m == nil { - fs.m = map[string]*FakeFile{} - } +// Open returns a fake file in the open state. +func (fs *FakeFS) Open(name string) (File, error) { fs.m[name] = &FakeFile{open: true} return fs.m[name], nil } -// Stat return an interface which has all the information regarding the file. -func (fs *FakeFS) Stat(name string) (os.FileInfo, error) { return os.Stat(name) } +// Stat always returns nil FileInfo, and returns an error if file does not exist. +func (fs *FakeFS) Stat(name string) (os.FileInfo, error) { + if _, found := fs.m[name]; found { + return nil, nil + } + return nil, errors.New("file does not exist") +} diff --git a/pkg/kinflate/util/fs/fakefs_test.go b/pkg/kinflate/util/fs/fakefs_test.go new file mode 100644 index 000000000..cc50ed838 --- /dev/null +++ b/pkg/kinflate/util/fs/fakefs_test.go @@ -0,0 +1,50 @@ +/* +Copyright 2018 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package fs + +import ( + "testing" +) + +func TestStat(t *testing.T) { + x := MakeFakeFS() + info, err := x.Stat("foo") + if info != nil { + t.Fatalf("expected nil info") + } + if err == nil { + t.Fatalf("expected error") + } +} + +func TestCreate(t *testing.T) { + x := MakeFakeFS() + f, err := x.Create("foo") + if f == nil { + t.Fatalf("expected file") + } + if err != nil { + t.Fatalf("unexpected error") + } + info, err := x.Stat("foo") + if info != nil { + t.Fatalf("expected nil info") + } + if err != nil { + t.Fatalf("expected no error") + } +} diff --git a/pkg/kinflate/util/fs/fs.go b/pkg/kinflate/util/fs/fs.go index 6435f8759..8a6d53c44 100644 --- a/pkg/kinflate/util/fs/fs.go +++ b/pkg/kinflate/util/fs/fs.go @@ -17,19 +17,19 @@ limitations under the License. package fs import ( + "io" "os" ) -var _ FileSystem = OSFS{} +// FileSystem groups basic os filesystem methods. +type FileSystem interface { + Create(name string) (File, error) + Open(name string) (File, error) + Stat(name string) (os.FileInfo, error) +} -// OSFS implements FileSystem using the local filesystem. -type OSFS struct{} - -// Create creates a file given the filename. -func (OSFS) Create(name string) (File, error) { return os.Create(name) } - -// Open opens a file given the filename. -func (OSFS) Open(name string) (File, error) { return os.Open(name) } - -// Stat return an interface which has all the information regarding the file. -func (OSFS) Stat(name string) (os.FileInfo, error) { return os.Stat(name) } +// File groups the basic os.File methods. +type File interface { + io.ReadWriteCloser + Stat() (os.FileInfo, error) +} diff --git a/pkg/kinflate/util/fs/file.go b/pkg/kinflate/util/fs/realfile.go similarity index 55% rename from pkg/kinflate/util/fs/file.go rename to pkg/kinflate/util/fs/realfile.go index 1a27787be..d6bd21046 100644 --- a/pkg/kinflate/util/fs/file.go +++ b/pkg/kinflate/util/fs/realfile.go @@ -17,22 +17,33 @@ limitations under the License. package fs import ( + "errors" "os" ) -var _ File = &OSFile{} +var _ File = &realFile{} -// OSFile implements File using the local filesystem. -type OSFile struct{ file *os.File } +// realFile implements File using the local filesystem. +type realFile struct { + file *os.File +} + +// MakeRealFile makes an instance of realFile. +func MakeRealFile(f *os.File) (File, error) { + if f == nil { + return nil, errors.New("file argument may not be nil") + } + return &realFile{file: f}, nil +} // Close closes a file. -func (f *OSFile) Close() error { return f.file.Close() } +func (f *realFile) Close() error { return f.file.Close() } // Read reads a file's content. -func (f *OSFile) Read(p []byte) (n int, err error) { return f.file.Read(p) } +func (f *realFile) Read(p []byte) (n int, err error) { return f.file.Read(p) } // Write writes bytes to a file -func (f *OSFile) Write(p []byte) (n int, err error) { return f.file.Write(p) } +func (f *realFile) Write(p []byte) (n int, err error) { return f.file.Write(p) } // Stat returns an interface which has all the information regarding the file. -func (f *OSFile) Stat() (os.FileInfo, error) { return f.file.Stat() } +func (f *realFile) Stat() (os.FileInfo, error) { return f.file.Stat() } diff --git a/pkg/kinflate/util/fs/interface.go b/pkg/kinflate/util/fs/realfs.go similarity index 58% rename from pkg/kinflate/util/fs/interface.go rename to pkg/kinflate/util/fs/realfs.go index e130b014b..64381a804 100644 --- a/pkg/kinflate/util/fs/interface.go +++ b/pkg/kinflate/util/fs/realfs.go @@ -17,19 +17,19 @@ limitations under the License. package fs import ( - "io" "os" ) -// FileSystem is the interface that groups the basic filesystem methods. -type FileSystem interface { - Create(name string) (File, error) - Open(name string) (File, error) - Stat(name string) (os.FileInfo, error) -} +var _ FileSystem = RealFS{} -// File is the interface that groups the basic file methods. -type File interface { - io.ReadWriteCloser - Stat() (os.FileInfo, error) -} +// RealFS implements FileSystem using the local filesystem. +type RealFS struct{} + +// Create delegates to os.Create. +func (RealFS) Create(name string) (File, error) { return os.Create(name) } + +// Open delegates to os.Open. +func (RealFS) Open(name string) (File, error) { return os.Open(name) } + +// Stat delegates to os.Stat. +func (RealFS) Stat(name string) (os.FileInfo, error) { return os.Stat(name) }