Merge pull request #233 from monopole/tweakfakes

Tweak the fakes, add a test of fake.
This commit is contained in:
k8s-ci-robot 2018-01-30 11:32:07 -08:00 committed by GitHub
commit 572d4edcd6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 130 additions and 55 deletions

View File

@ -17,37 +17,46 @@ limitations under the License.
package fs package fs
import ( import (
"bytes"
"os" "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 { type FakeFile struct {
content []byte content []byte
open bool 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 { func (f *FakeFile) Close() error {
f.open = false f.open = false
return nil 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) { func (f *FakeFile) Read(p []byte) (n int, err error) {
return len(p), nil 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) { func (f *FakeFile) Write(p []byte) (n int, err error) {
f.content = p f.content = p
return len(p), nil 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) { func (f *FakeFile) Stat() (os.FileInfo, error) {
return nil, nil return nil, nil
} }

View File

@ -17,33 +17,38 @@ limitations under the License.
package fs package fs
import ( import (
"errors"
"os" "os"
"k8s.io/kubectl/pkg/kinflate/util/fs"
) )
var _ fs.FileSystem = &FakeFS{} var _ FileSystem = &FakeFS{}
// FakeFS implements FileSystem using a fake in-memory filesystem. // 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{} fs.m[name] = &FakeFile{}
return fs.m[name], nil return fs.m[name], nil
} }
// Open opens a file given the filename. // Open returns a fake file in the open state.
func (fs *FakeFS) Open(name string) (fs.File, error) { func (fs *FakeFS) Open(name string) (File, error) {
if fs.m == nil {
fs.m = map[string]*FakeFile{}
}
fs.m[name] = &FakeFile{open: true} fs.m[name] = &FakeFile{open: true}
return fs.m[name], nil return fs.m[name], nil
} }
// Stat return an interface which has all the information regarding the file. // Stat always returns nil FileInfo, and returns an error if file does not exist.
func (fs *FakeFS) Stat(name string) (os.FileInfo, error) { return os.Stat(name) } 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")
}

View File

@ -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")
}
}

View File

@ -17,19 +17,19 @@ limitations under the License.
package fs package fs
import ( import (
"io"
"os" "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. // File groups the basic os.File methods.
type OSFS struct{} type File interface {
io.ReadWriteCloser
// Create creates a file given the filename. Stat() (os.FileInfo, error)
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) }

View File

@ -17,22 +17,33 @@ limitations under the License.
package fs package fs
import ( import (
"errors"
"os" "os"
) )
var _ File = &OSFile{} var _ File = &realFile{}
// OSFile implements File using the local filesystem. // realFile implements File using the local filesystem.
type OSFile struct{ file *os.File } 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. // 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. // 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 // 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. // 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() }

View File

@ -17,19 +17,19 @@ limitations under the License.
package fs package fs
import ( import (
"io"
"os" "os"
) )
// FileSystem is the interface that groups the basic filesystem methods. var _ FileSystem = RealFS{}
type FileSystem interface {
Create(name string) (File, error)
Open(name string) (File, error)
Stat(name string) (os.FileInfo, error)
}
// File is the interface that groups the basic file methods. // RealFS implements FileSystem using the local filesystem.
type File interface { type RealFS struct{}
io.ReadWriteCloser
Stat() (os.FileInfo, error) // 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) }