gce-containers-startup/command/mock_runner.go (107 lines of code) (raw):

// Copyright 2018 Google Inc. All Rights Reserved. // // 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 command import ( "fmt" "os" "strings" "testing" "time" ) type MockCommand struct { callCount int returnedOutput string returnedError error } type MockRunner struct { FailOnUnexpectedCalls bool commands map[string]MockCommand statFiles map[string]os.FileInfo expectedMkdirAlls map[string]bool t *testing.T } type minimalFileInfo struct { name string size int64 fileMode os.FileMode modTime time.Time } func (f minimalFileInfo) Name() string { return f.name } func (f minimalFileInfo) Size() int64 { return f.size } func (f minimalFileInfo) Mode() os.FileMode { return f.fileMode } func (f minimalFileInfo) ModTime() time.Time { return f.modTime } func (f minimalFileInfo) IsDir() bool { return f.fileMode.IsDir() } func (f minimalFileInfo) Sys() interface{} { return nil } func NewMockRunner(t *testing.T) *MockRunner { return &MockRunner{FailOnUnexpectedCalls: true, commands: map[string]MockCommand{}, statFiles: map[string]os.FileInfo{}, expectedMkdirAlls: map[string]bool{}, t: t} } func (m *MockRunner) Run(commandAndArgs ...string) (string, error) { commandString := strings.Join(commandAndArgs, " ") if _, found := m.commands[commandString]; !found && m.FailOnUnexpectedCalls { m.t.Fatal(fmt.Sprintf("Unexpected os command called: %s", commandString)) } m.incrementCallCount(commandString) return m.commands[commandString].returnedOutput, m.commands[commandString].returnedError } func (m *MockRunner) incrementCallCount(command string) { commandInfo := m.commands[command] commandInfo.callCount += 1 m.commands[command] = commandInfo } func (m *MockRunner) MkdirAll(path string, perm os.FileMode) error { if _, found := m.expectedMkdirAlls[path]; !found && m.FailOnUnexpectedCalls { return fmt.Errorf("MkdirAll() called on unexpected path: %s", path) } m.expectedMkdirAlls[path] = true return nil } func (m *MockRunner) Stat(path string) (os.FileInfo, error) { fileInfo, found := m.statFiles[path] if !found && m.FailOnUnexpectedCalls { return minimalFileInfo{}, fmt.Errorf("MockRunner.Stat(): No such file or directory: %s", path) } return fileInfo, nil } func (m *MockRunner) OutputOnCall(commandAndArgs string, output string) { m.commands[commandAndArgs] = MockCommand{callCount: 0, returnedOutput: output, returnedError: nil} } func (m *MockRunner) ErrorOnCall(commandAndArgs string, err error) { m.commands[commandAndArgs] = MockCommand{callCount: 0, returnedOutput: "", returnedError: err} } func (m *MockRunner) RegisterMkdirAll(path string) { m.expectedMkdirAlls[path] = false } func (m *MockRunner) RegisterDeviceForStat(path string) { m.statFiles[path] = minimalFileInfo{name: path, fileMode: os.ModeDevice} } func (m *MockRunner) RegisterDirectoryForStat(path string) { m.statFiles[path] = minimalFileInfo{name: path, fileMode: os.ModeDir} } func (m *MockRunner) AssertCalled(commandAndArgs string) { command, found := m.commands[commandAndArgs] if !found || command.callCount == 0 { m.t.Fatal(fmt.Sprintf("Expected os command not called: %s", commandAndArgs)) } } func (m *MockRunner) AssertAllCalled() { for commandAndArgs, command := range m.commands { if command.callCount == 0 { m.t.Fatal(fmt.Sprintf("Expected os command not called: %s", commandAndArgs)) } } for mkdirAllPath, called := range m.expectedMkdirAlls { if !called { m.t.Fatal(fmt.Sprintf("Expected os.MkdirAll() not called: %s", mkdirAllPath)) } } }