Skip to content

Commit

Permalink
Alternate fallback runner (#234)
Browse files Browse the repository at this point in the history
Taking a different approach, instead of the more obscure fallbackRunner we moved the raw Xcode runner fallback to the InstallDeps method.
  • Loading branch information
lpusok authored Aug 9, 2023
1 parent ddb42f1 commit df755f3
Show file tree
Hide file tree
Showing 7 changed files with 95 additions and 104 deletions.
11 changes: 3 additions & 8 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,10 +45,7 @@ func run() int {
return 1
}

if err := xcodeTestRunner.InstallDeps(); err != nil {
logger.Errorf(errorutil.FormattedError(fmt.Errorf("Failed to install Step dependencies: %w", err)))
return 1
}
xcodeTestRunner.InstallDeps()

res, runErr := xcodeTestRunner.Run(config)
exportErr := xcodeTestRunner.Export(res, runErr != nil)
Expand Down Expand Up @@ -99,7 +96,6 @@ func createStep(logger log.Logger, logFormatter string) (step.XcodeTestRunner, e
utils := step.NewUtils(logger)

xcodeCommandRunner := xcodecommand.Runner(nil)

switch logFormatter {
case step.XcodebuildTool:
xcodeCommandRunner = xcodecommand.NewRawCommandRunner(logger, commandFactory)
Expand All @@ -118,8 +114,7 @@ func createStep(logger log.Logger, logFormatter string) (step.XcodeTestRunner, e
panic(fmt.Sprintf("Unknown log formatter: %s", logFormatter))
}

fallbackRunner := xcodecommand.NewFallbackRunner(xcodeCommandRunner, logger, commandFactory)
xcodebuilder := xcodebuild.NewXcodebuild(logger, fileManager, xcconfigWriter, fallbackRunner)
xcodebuilder := xcodebuild.NewXcodebuild(logger, fileManager, xcconfigWriter, xcodeCommandRunner)

return step.NewXcodeTestRunner(logger, fallbackRunner, xcodebuilder, simulatorManager, swiftCache, exporter, pathModifier, pathProvider, utils), nil
return step.NewXcodeTestRunner(logger, commandFactory, xcodebuilder, simulatorManager, swiftCache, exporter, pathModifier, pathProvider, utils), nil
}
38 changes: 31 additions & 7 deletions step/mocks/Xcodebuild.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

59 changes: 29 additions & 30 deletions step/step.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import (
"github.com/bitrise-io/go-steputils/v2/stepconf"
"github.com/bitrise-io/go-utils/progress"
"github.com/bitrise-io/go-utils/sliceutil"
"github.com/bitrise-io/go-utils/v2/command"
"github.com/bitrise-io/go-utils/v2/log"
"github.com/bitrise-io/go-utils/v2/pathutil"
"github.com/bitrise-io/go-xcode/v2/destination"
Expand Down Expand Up @@ -131,29 +132,29 @@ func NewXcodeTestConfigParser(inputParser stepconf.InputParser, logger log.Logge

// XcodeTestRunner ...
type XcodeTestRunner struct {
logger log.Logger
logFormatterInstaller xcodecommand.Runner
xcodebuild xcodebuild.Xcodebuild
simulatorManager simulator.Manager
cache cache.SwiftPackageCache
outputExporter output.Exporter
pathModifier pathutil.PathModifier
pathProvider pathutil.PathProvider
utils Utils
logger log.Logger
commandFactory command.Factory
xcodebuild xcodebuild.Xcodebuild
simulatorManager simulator.Manager
cache cache.SwiftPackageCache
outputExporter output.Exporter
pathModifier pathutil.PathModifier
pathProvider pathutil.PathProvider
utils Utils
}

// NewXcodeTestRunner ...
func NewXcodeTestRunner(logger log.Logger, logFormatterInstaller xcodecommand.Runner, xcodebuild xcodebuild.Xcodebuild, simulatorManager simulator.Manager, cache cache.SwiftPackageCache, outputExporter output.Exporter, pathModifier pathutil.PathModifier, pathProvider pathutil.PathProvider, utils Utils) XcodeTestRunner {
func NewXcodeTestRunner(logger log.Logger, commandFactory command.Factory, xcodebuild xcodebuild.Xcodebuild, simulatorManager simulator.Manager, cache cache.SwiftPackageCache, outputExporter output.Exporter, pathModifier pathutil.PathModifier, pathProvider pathutil.PathProvider, utils Utils) XcodeTestRunner {
return XcodeTestRunner{
logger: logger,
logFormatterInstaller: logFormatterInstaller,
xcodebuild: xcodebuild,
simulatorManager: simulatorManager,
cache: cache,
outputExporter: outputExporter,
pathModifier: pathModifier,
pathProvider: pathProvider,
utils: utils,
logger: logger,
commandFactory: commandFactory,
xcodebuild: xcodebuild,
simulatorManager: simulatorManager,
cache: cache,
outputExporter: outputExporter,
pathModifier: pathModifier,
pathProvider: pathProvider,
utils: utils,
}
}

Expand Down Expand Up @@ -220,22 +221,19 @@ func (s XcodeTestConfigParser) ProcessConfig() (Config, error) {
}

// InstallDeps ...
func (s XcodeTestRunner) InstallDeps() error {
if s.logFormatterInstaller == nil {
return nil
}

logFormatterVersion, err := s.logFormatterInstaller.CheckInstall()
func (s XcodeTestRunner) InstallDeps() {
logFormatterVersion, err := s.xcodebuild.GetXcodeCommadRunner().CheckInstall()
if err != nil {
return fmt.Errorf("installing log formatter failed: %w", err)
s.logger.Errorf("Selected log formatter is unavailable:: %s", err)
s.logger.Infof("Switching back to xcodebuild log formatter.")
s.xcodebuild.SetXcodeCommandRunner(xcodecommand.NewRawCommandRunner(s.logger, s.commandFactory))

return
}

if logFormatterVersion != nil {
if logFormatterVersion != nil { // raw xcodebuild runner returns nil
s.logger.Printf("- log formatter version: %s", logFormatterVersion.String())
}
s.logger.Println()

return nil
}

// Result ...
Expand All @@ -257,6 +255,7 @@ func (s XcodeTestRunner) Run(cfg Config) (Result, error) {
return Result{}, err
}

s.logger.Println()
var testErr error
var testExitCode int
result, code, err := s.runTests(cfg)
Expand Down
41 changes: 21 additions & 20 deletions step/step_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,13 @@ type configParserMocks struct {
}

type stepMocks struct {
xcodeRunnerInstaller *commonMocks.XcodeCommandRunner
xcodebuilder *mocks.Xcodebuild
simulatorManager *mocks.SimulatorManager
cache *mocks.SwiftPackageCache
outputExporter *mocks.Exporter
pathModifier *mocks.PathModifier
pathProvider *mocks.PathProvider
commandFactory *commonMocks.CommandFactory
xcodebuilder *mocks.Xcodebuild
simulatorManager *mocks.SimulatorManager
cache *mocks.SwiftPackageCache
outputExporter *mocks.Exporter
pathModifier *mocks.PathModifier
pathProvider *mocks.PathProvider
}

func Test_GivenStep_WhenRuns_ThenXcodebuildGetsCalled(t *testing.T) {
Expand Down Expand Up @@ -146,14 +146,15 @@ func Test_GivenStep_WhenInstallXcpretty_ThenInstallIt(t *testing.T) {
assert.Fail(t, fmt.Sprintf("%s", err))
}

mocks.xcodeRunnerInstaller.On("CheckInstall", mock.Anything).Return(ver, nil)
xcodeRunner := commonMocks.NewXcodeCommandRunner(t)
mocks.xcodebuilder.On("GetXcodeCommadRunner").Return(xcodeRunner).Once()
xcodeRunner.On("CheckInstall", mock.Anything).Return(ver, nil).Once()

// When
err = step.InstallDeps()
step.InstallDeps()

// Then
assert.NoError(t, err)
mocks.xcodeRunnerInstaller.AssertExpectations(t)
xcodeRunner.AssertCalled(t, "CheckInstall")
}

func Test_GivenLogFormatterIsXcbeautify_WhenParsesConfig_ThenAdditionalOptionsWork(t *testing.T) {
Expand Down Expand Up @@ -333,7 +334,7 @@ func createConfigParser(t *testing.T, envValues map[string]string, xcodeVersion

func createStepAndMocks(t *testing.T) (XcodeTestRunner, stepMocks) {
logger := log.NewLogger()
xcodeRunnerInstaller := commonMocks.NewXcodeCommandRunner(t)
commandFactory := new(commonMocks.CommandFactory)
xcodebuilder := mocks.NewXcodebuild(t)
simulatorManager := mocks.NewSimulatorManager(t)
cache := mocks.NewSwiftPackageCache(t)
Expand All @@ -342,15 +343,15 @@ func createStepAndMocks(t *testing.T) (XcodeTestRunner, stepMocks) {
pathProvider := mocks.NewPathProvider(t)
utils := NewUtils(logger)

step := NewXcodeTestRunner(logger, xcodeRunnerInstaller, xcodebuilder, simulatorManager, cache, outputExporter, pathModifier, pathProvider, utils)
step := NewXcodeTestRunner(logger, commandFactory, xcodebuilder, simulatorManager, cache, outputExporter, pathModifier, pathProvider, utils)
mocks := stepMocks{
xcodeRunnerInstaller: xcodeRunnerInstaller,
xcodebuilder: xcodebuilder,
simulatorManager: simulatorManager,
cache: cache,
outputExporter: outputExporter,
pathModifier: pathModifier,
pathProvider: pathProvider,
commandFactory: commandFactory,
xcodebuilder: xcodebuilder,
simulatorManager: simulatorManager,
cache: cache,
outputExporter: outputExporter,
pathModifier: pathModifier,
pathProvider: pathProvider,
}

return step, mocks
Expand Down
2 changes: 1 addition & 1 deletion xcodebuild/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import (
)

// On performance limited OS X hosts (ex: VMs) the iPhone/iOS Simulator might time out
// while booting. So far it seems that a simple retry solves these issues.
// while booting. So far it seems that a simple retry solves these issues.
const (
// This boot timeout can happen when running Unit Tests with Xcode Command Line `xcodebuild`.
timeOutMessageIPhoneSimulator = "iPhoneSimulator: Timed out waiting"
Expand Down
10 changes: 10 additions & 0 deletions xcodebuild/xcodebuild.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ const (
// Xcodebuild ....
type Xcodebuild interface {
RunTest(params TestRunParams) (string, int, error)
GetXcodeCommadRunner() xcodecommand.Runner
SetXcodeCommandRunner(runner xcodecommand.Runner)
}

type xcodebuild struct {
Expand Down Expand Up @@ -49,3 +51,11 @@ type TestRunParams struct {
func (b *xcodebuild) RunTest(params TestRunParams) (string, int, error) {
return b.runTest(params)
}

func (b *xcodebuild) GetXcodeCommadRunner() xcodecommand.Runner {
return b.xcodeCommandRunner
}

func (b *xcodebuild) SetXcodeCommandRunner(runner xcodecommand.Runner) {
b.xcodeCommandRunner = runner
}
38 changes: 0 additions & 38 deletions xcodecommand/fallbackRunner.go

This file was deleted.

0 comments on commit df755f3

Please sign in to comment.