Skip to content

Commit

Permalink
Fix intermittent test failures
Browse files Browse the repository at this point in the history
Tests' mock actor was being called in parallel and sometimes, race
conditions were occurring which caused rare unit test flakiness.

Signed-off-by: Blaine Gardner <[email protected]>
  • Loading branch information
BlaineEXE committed Nov 12, 2018
1 parent 6ba2823 commit 6973f5b
Showing 1 changed file with 12 additions and 0 deletions.
12 changes: 12 additions & 0 deletions internal/remote/test/actor.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"fmt"
"os"
"strings"
"sync"
)

// MockRemoteActor is a reusable mock remote.Actor to be used for testing.
Expand All @@ -28,13 +29,18 @@ type MockRemoteActor struct {
// shortcut for bytes.NewBufferString
var bs = bytes.NewBufferString

// Actor may be called in parallel
var actorMutex = sync.Mutex{}

// RunCommand is a mock function that appends each command to Commands.
// It will return Hostname if the command is "hostname", or an error if HostnameError is true.
// It will always return data on stdout and stderr in the form below where command is the command
// intput, stdout/stderr is the buffer on which the data is returned, and ok unless CommandError is
// true, in which case err:
// <command>: <stdout|stderr> <ok|err>
func (m *MockRemoteActor) RunCommand(command string) (stdout, stderr *bytes.Buffer, err error) {
actorMutex.Lock()
defer actorMutex.Unlock()
app(&m.Commands, command)

if command == "hostname" {
Expand Down Expand Up @@ -65,6 +71,8 @@ func ExpectedCommandOutput(command string, err bool) (stdout, stderr string) {
// CreateRemoteDir is a mock function that appends each remote dir path to DirCreates.
// It will return an error after it has been called CreateDirErrorAfter number of times.
func (m *MockRemoteActor) CreateRemoteDir(dirPath string) error {
actorMutex.Lock()
defer actorMutex.Unlock()
app(&m.DirCreates, dirPath)

if m.CreateDirErrorOn != "" && strings.Contains(dirPath, m.CreateDirErrorOn) {
Expand All @@ -77,6 +85,8 @@ func (m *MockRemoteActor) CreateRemoteDir(dirPath string) error {
// CopyFileToRemote is a mock function that appends each remote file path to FileCopies.
// It will return an error after it has been called CopyFileErrorAfter number of times.
func (m *MockRemoteActor) CopyFileToRemote(localSource *os.File, remoteFilePath string) error {
actorMutex.Lock()
defer actorMutex.Unlock()
app(&m.FileCopies, remoteFilePath)

if m.CopyFileErrorOn != "" && strings.Contains(remoteFilePath, m.CopyFileErrorOn) {
Expand All @@ -89,6 +99,8 @@ func (m *MockRemoteActor) CopyFileToRemote(localSource *os.File, remoteFilePath
// Close is a mock function that increments CloseCalled each time it is called.
// It does not return an error.
func (m *MockRemoteActor) Close() error {
actorMutex.Lock()
defer actorMutex.Unlock()
m.CloseCalled++
return nil
}

0 comments on commit 6973f5b

Please sign in to comment.