Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitaly.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPatrick Steinhardt <psteinhardt@gitlab.com>2022-04-26 09:29:24 +0300
committerPatrick Steinhardt <psteinhardt@gitlab.com>2022-04-26 11:14:14 +0300
commitfcc3c5e76691eeed51aa9aeba37065cf31b30e01 (patch)
tree2ed7852f817fc24b641b73e33be2c3ce59d9bf93
parent8339301f386ec041fac36d9a1098d89141672225 (diff)
gittest: Optionally intercept Git version in intercepting factory
The intercepting Git command factory is currently always using the intercepting script to derive the current Git version. This only works alright because we typically don't check for the Git version in most callsites, and thus the intercepting script's output is never used to determine the version except for some limited cases. This is about to change though given that we'll introduce a Git version check into the command factory itself, which will then break all tests which use the intercepting command factory. Add a new option to the intercepting command factory that allows the caller to only optionally intercept the Git version. By default, we'll now use the real Git version so that users will continue to work.
-rw-r--r--internal/git/command_factory_test.go2
-rw-r--r--internal/git/gittest/intercepting_command_factory.go19
-rw-r--r--internal/git/gittest/intercepting_command_factory_test.go66
3 files changed, 85 insertions, 2 deletions
diff --git a/internal/git/command_factory_test.go b/internal/git/command_factory_test.go
index b8ae02ad9..e9eee0a40 100644
--- a/internal/git/command_factory_test.go
+++ b/internal/git/command_factory_test.go
@@ -361,6 +361,7 @@ func TestExecCommandFactory_GitVersion(t *testing.T) {
gitCmdFactory := gittest.NewInterceptingCommandFactory(
ctx, t, testcfg.Build(t), generateVersionScript(tc.versionString),
gittest.WithRealCommandFactoryOptions(git.WithSkipHooks()),
+ gittest.WithInterceptedVersion(),
)
actualVersion, err := gitCmdFactory.GitVersion(ctx)
@@ -377,6 +378,7 @@ func TestExecCommandFactory_GitVersion(t *testing.T) {
gitCmdFactory := gittest.NewInterceptingCommandFactory(
ctx, t, testcfg.Build(t), generateVersionScript("git version 1.2.3"),
gittest.WithRealCommandFactoryOptions(git.WithSkipHooks()),
+ gittest.WithInterceptedVersion(),
)
gitPath := gitCmdFactory.GetExecutionEnvironment(ctx).BinaryPath
diff --git a/internal/git/gittest/intercepting_command_factory.go b/internal/git/gittest/intercepting_command_factory.go
index 393ff38e5..ebc162487 100644
--- a/internal/git/gittest/intercepting_command_factory.go
+++ b/internal/git/gittest/intercepting_command_factory.go
@@ -19,10 +19,12 @@ var _ git.CommandFactory = &InterceptingCommandFactory{}
type InterceptingCommandFactory struct {
realCommandFactory git.CommandFactory
interceptingCommandFactory git.CommandFactory
+ interceptVersion bool
}
type interceptingCommandFactoryConfig struct {
- opts []git.ExecCommandFactoryOption
+ opts []git.ExecCommandFactoryOption
+ interceptVersion bool
}
// InterceptingCommandFactoryOption is an option that can be passed to
@@ -37,6 +39,15 @@ func WithRealCommandFactoryOptions(opts ...git.ExecCommandFactoryOption) Interce
}
}
+// WithInterceptedVersion will cause `GitVersion()` to use the intercepting Git command factory
+// instead of the real Git command factory. This allows the caller to explicitly test version
+// detection.
+func WithInterceptedVersion() InterceptingCommandFactoryOption {
+ return func(cfg *interceptingCommandFactoryConfig) {
+ cfg.interceptVersion = true
+ }
+}
+
// NewInterceptingCommandFactory creates a new command factory which intercepts Git commands. The
// given configuration must point to the real Git executable. The function will be executed to
// generate the script and receives as input the Git execution environment pointing to the real Git
@@ -66,6 +77,7 @@ func NewInterceptingCommandFactory(
return &InterceptingCommandFactory{
realCommandFactory: gitCmdFactory,
interceptingCommandFactory: NewCommandFactory(tb, cfg, git.WithGitBinaryPath(scriptPath)),
+ interceptVersion: interceptingCommandFactoryCfg.interceptVersion,
}
}
@@ -107,5 +119,8 @@ func (f *InterceptingCommandFactory) HooksPath(ctx context.Context) string {
// GitVersion returns the Git version as returned by the intercepted command.
func (f *InterceptingCommandFactory) GitVersion(ctx context.Context) (git.Version, error) {
- return f.interceptingCommandFactory.GitVersion(ctx)
+ if f.interceptVersion {
+ return f.interceptingCommandFactory.GitVersion(ctx)
+ }
+ return f.realCommandFactory.GitVersion(ctx)
}
diff --git a/internal/git/gittest/intercepting_command_factory_test.go b/internal/git/gittest/intercepting_command_factory_test.go
index f3005f86b..6b0cc136f 100644
--- a/internal/git/gittest/intercepting_command_factory_test.go
+++ b/internal/git/gittest/intercepting_command_factory_test.go
@@ -58,3 +58,69 @@ func TestInterceptingCommandFactory(t *testing.T) {
require.Equal(t, expectedString, stdout.String())
})
}
+
+func TestInterceptingCommandFactory_GitVersion(t *testing.T) {
+ cfg, _, _ := setup(t)
+ ctx := testhelper.Context(t)
+
+ generateVersionScript := func(execEnv git.ExecutionEnvironment) string {
+ return `#!/usr/bin/env bash
+ echo "git version 1.2.3"
+ `
+ }
+
+ // Obtain the real Git version so that we can compare that it matches what we expect.
+ realFactory, cleanup, err := git.NewExecCommandFactory(cfg)
+ require.NoError(t, err)
+ defer cleanup()
+
+ realVersion, err := realFactory.GitVersion(ctx)
+ require.NoError(t, err)
+
+ // Furthermore, we need to obtain the intercepted version here because we cannot construct
+ // `git.Version` structs ourselves.
+ fakeVersion, err := NewInterceptingCommandFactory(ctx, t, cfg, generateVersionScript, WithInterceptedVersion()).GitVersion(ctx)
+ require.NoError(t, err)
+ require.Equal(t, "1.2.3", fakeVersion.String())
+
+ for _, tc := range []struct {
+ desc string
+ opts []InterceptingCommandFactoryOption
+ expectedVersion git.Version
+ }{
+ {
+ desc: "without version interception",
+ expectedVersion: realVersion,
+ },
+ {
+ desc: "with version interception",
+ opts: []InterceptingCommandFactoryOption{
+ WithInterceptedVersion(),
+ },
+ expectedVersion: fakeVersion,
+ },
+ } {
+ t.Run(tc.desc, func(t *testing.T) {
+ factory := NewInterceptingCommandFactory(ctx, t, cfg, generateVersionScript, tc.opts...)
+
+ version, err := factory.GitVersion(ctx)
+ require.NoError(t, err)
+ require.Equal(t, tc.expectedVersion, version)
+
+ // The real command factory should always return the real Git version.
+ version, err = factory.realCommandFactory.GitVersion(ctx)
+ require.NoError(t, err)
+ require.Equal(t, realVersion, version)
+
+ // On the other hand, the intercepting command factory should return
+ // different versions depending on whether the version is intercepted or
+ // not. This is required such that it correctly handles version checks in
+ // case it calls `GitVersion()` on itself.
+ //
+ // Right now, this doesn't work correctly though.
+ version, err = factory.interceptingCommandFactory.GitVersion(ctx)
+ require.NoError(t, err)
+ require.Equal(t, fakeVersion, version)
+ })
+ }
+}