github.com/GoogleContainerTools/skaffold@v1.39.18/pkg/skaffold/build/jib/maven_test.go (about)

     1  /*
     2  Copyright 2019 The Skaffold Authors
     3  
     4  Licensed under the Apache License, Version 2.0 (the "License");
     5  you may not use this file except in compliance with the License.
     6  You may obtain a copy of the License at
     7  
     8      http://www.apache.org/licenses/LICENSE-2.0
     9  
    10  Unless required by applicable law or agreed to in writing, software
    11  distributed under the License is distributed on an "AS IS" BASIS,
    12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  See the License for the specific language governing permissions and
    14  limitations under the License.
    15  */
    16  
    17  package jib
    18  
    19  import (
    20  	"context"
    21  	"errors"
    22  	"fmt"
    23  	"io/ioutil"
    24  	"os"
    25  	"os/exec"
    26  	"runtime"
    27  	"strings"
    28  	"testing"
    29  	"time"
    30  
    31  	v1 "github.com/opencontainers/image-spec/specs-go/v1"
    32  
    33  	"github.com/GoogleContainerTools/skaffold/pkg/skaffold/docker"
    34  	"github.com/GoogleContainerTools/skaffold/pkg/skaffold/platform"
    35  	"github.com/GoogleContainerTools/skaffold/pkg/skaffold/schema/latest"
    36  	"github.com/GoogleContainerTools/skaffold/pkg/skaffold/util"
    37  	"github.com/GoogleContainerTools/skaffold/testutil"
    38  )
    39  
    40  func TestBuildJibMavenToDocker(t *testing.T) {
    41  	tests := []struct {
    42  		description   string
    43  		artifact      *latest.JibArtifact
    44  		commands      util.Command
    45  		shouldErr     bool
    46  		expectedError string
    47  	}{
    48  		{
    49  			description: "build",
    50  			artifact:    &latest.JibArtifact{},
    51  			commands: testutil.CmdRun(
    52  				"mvn fake-mavenBuildArgs-for-dockerBuild -Dimage=img:tag",
    53  			),
    54  		},
    55  		{
    56  			description: "build with module",
    57  			artifact:    &latest.JibArtifact{Project: "module"},
    58  			commands: testutil.CmdRun(
    59  				"mvn fake-mavenBuildArgs-for-module-for-dockerBuild -Dimage=img:tag",
    60  			),
    61  		},
    62  		{
    63  			description: "build with custom base image",
    64  			artifact:    &latest.JibArtifact{BaseImage: "docker://busybox"},
    65  			commands: testutil.CmdRun(
    66  				"mvn fake-mavenBuildArgs-for-dockerBuild -Djib.from.image=docker://busybox -Dimage=img:tag",
    67  			),
    68  		},
    69  		{
    70  			description: "fail build",
    71  			artifact:    &latest.JibArtifact{},
    72  			commands: testutil.CmdRunErr(
    73  				"mvn fake-mavenBuildArgs-for-dockerBuild -Dimage=img:tag",
    74  				errors.New("BUG"),
    75  			),
    76  			shouldErr:     true,
    77  			expectedError: "maven build failed",
    78  		},
    79  	}
    80  
    81  	for _, test := range tests {
    82  		testutil.Run(t, test.description, func(t *testutil.T) {
    83  			t.Override(&mavenBuildArgsFunc, getMavenBuildArgsFuncFake(t, MinimumJibMavenVersion))
    84  			t.NewTempDir().Touch("pom.xml").Chdir()
    85  			t.Override(&util.DefaultExecCommand, test.commands)
    86  			api := (&testutil.FakeAPIClient{}).Add("img:tag", "imageID")
    87  			localDocker := fakeLocalDaemon(api)
    88  
    89  			builder := NewArtifactBuilder(localDocker, &mockConfig{}, false, false, mockArtifactResolver{})
    90  			result, err := builder.Build(context.Background(), ioutil.Discard, &latest.Artifact{
    91  				ArtifactType: latest.ArtifactType{
    92  					JibArtifact: test.artifact,
    93  				},
    94  			}, "img:tag", platform.Matcher{})
    95  
    96  			t.CheckError(test.shouldErr, err)
    97  			if test.shouldErr {
    98  				t.CheckErrorContains(test.expectedError, err)
    99  			} else {
   100  				t.CheckDeepEqual("imageID", result)
   101  			}
   102  		})
   103  	}
   104  }
   105  
   106  func TestBuildJibMavenToRegistry(t *testing.T) {
   107  	tests := []struct {
   108  		description   string
   109  		artifact      *latest.JibArtifact
   110  		commands      util.Command
   111  		shouldErr     bool
   112  		expectedError string
   113  	}{
   114  		{
   115  			description: "build",
   116  			artifact:    &latest.JibArtifact{},
   117  			commands:    testutil.CmdRun("mvn fake-mavenBuildArgs-for-build -Dimage=img:tag"),
   118  		},
   119  		{
   120  			description: "build with module",
   121  			artifact:    &latest.JibArtifact{Project: "module"},
   122  			commands:    testutil.CmdRun("mvn fake-mavenBuildArgs-for-module-for-build -Dimage=img:tag"),
   123  		},
   124  		{
   125  			description: "build with custom base image",
   126  			artifact:    &latest.JibArtifact{BaseImage: "docker://busybox"},
   127  			commands:    testutil.CmdRun("mvn fake-mavenBuildArgs-for-build -Djib.from.image=docker://busybox -Dimage=img:tag"),
   128  		},
   129  		{
   130  			description: "fail build",
   131  			artifact:    &latest.JibArtifact{},
   132  			commands: testutil.CmdRunErr(
   133  				"mvn fake-mavenBuildArgs-for-build -Dimage=img:tag",
   134  				errors.New("BUG"),
   135  			),
   136  			shouldErr:     true,
   137  			expectedError: "maven build failed",
   138  		},
   139  	}
   140  
   141  	for _, test := range tests {
   142  		testutil.Run(t, test.description, func(t *testutil.T) {
   143  			t.Override(&mavenBuildArgsFunc, getMavenBuildArgsFuncFake(t, MinimumJibMavenVersion))
   144  			t.NewTempDir().Touch("pom.xml").Chdir()
   145  			t.Override(&util.DefaultExecCommand, test.commands)
   146  			t.Override(&docker.RemoteDigest, func(identifier string, _ docker.Config, _ []v1.Platform) (string, error) {
   147  				if identifier == "img:tag" {
   148  					return "digest", nil
   149  				}
   150  				return "", errors.New("unknown remote tag")
   151  			})
   152  			localDocker := fakeLocalDaemon(&testutil.FakeAPIClient{})
   153  
   154  			builder := NewArtifactBuilder(localDocker, &mockConfig{}, true, false, mockArtifactResolver{})
   155  			result, err := builder.Build(context.Background(), ioutil.Discard, &latest.Artifact{
   156  				ArtifactType: latest.ArtifactType{
   157  					JibArtifact: test.artifact,
   158  				},
   159  			}, "img:tag", platform.Matcher{})
   160  
   161  			t.CheckError(test.shouldErr, err)
   162  			if test.shouldErr {
   163  				t.CheckErrorContains(test.expectedError, err)
   164  			} else {
   165  				t.CheckDeepEqual("digest", result)
   166  			}
   167  		})
   168  	}
   169  }
   170  
   171  func TestMinimumMavenVersion(t *testing.T) {
   172  	testutil.CheckDeepEqual(t, "1.4.0", MinimumJibMavenVersion)
   173  }
   174  
   175  func TestMavenWrapperDefinition(t *testing.T) {
   176  	testutil.CheckDeepEqual(t, "mvn", MavenCommand.Executable)
   177  	testutil.CheckDeepEqual(t, "mvnw", MavenCommand.Wrapper)
   178  }
   179  
   180  func TestGetDependenciesMaven(t *testing.T) {
   181  	tmpDir := testutil.NewTempDir(t)
   182  
   183  	tmpDir.Touch("build", "dep1", "dep2")
   184  	build := tmpDir.Path("build")
   185  	dep1 := tmpDir.Path("dep1")
   186  	dep2 := tmpDir.Path("dep2")
   187  
   188  	ctx := context.Background()
   189  
   190  	tests := []struct {
   191  		description string
   192  		stdout      string
   193  		modTime     time.Time
   194  		expected    []string
   195  		err         error
   196  	}{
   197  		{
   198  			description: "failure",
   199  			stdout:      "",
   200  			modTime:     time.Unix(0, 0),
   201  			err:         errors.New("error"),
   202  		},
   203  		{
   204  			description: "success",
   205  			stdout:      fmt.Sprintf("BEGIN JIB JSON\n{\"build\":[\"%s\"],\"inputs\":[\"%s\"],\"ignore\":[]}", build, dep1),
   206  			modTime:     time.Unix(0, 0),
   207  			expected:    []string{"build", "dep1"},
   208  		},
   209  		{
   210  			// Expected output differs from stdout since build file hasn't change, thus maven command won't run
   211  			description: "success",
   212  			stdout:      fmt.Sprintf("BEGIN JIB JSON\n{\"build\":[\"%s\"],\"inputs\":[\"%s\", \"%s\"],\"ignore\":[]}", build, dep1, dep2),
   213  			modTime:     time.Unix(0, 0),
   214  			expected:    []string{"build", "dep1"},
   215  		},
   216  		{
   217  			description: "success",
   218  			stdout:      fmt.Sprintf("BEGIN JIB JSON\n{\"build\":[\"%s\"],\"inputs\":[\"%s\", \"%s\"],\"ignore\":[]}", build, dep1, dep2),
   219  			modTime:     time.Unix(10000, 0),
   220  			expected:    []string{"build", "dep1", "dep2"},
   221  		},
   222  	}
   223  	for _, test := range tests {
   224  		testutil.Run(t, test.description, func(t *testutil.T) {
   225  			t.Override(&util.DefaultExecCommand, testutil.CmdRunOutErr(
   226  				strings.Join(getCommandMaven(ctx, tmpDir.Root(), &latest.JibArtifact{Project: "maven-test"}).Args, " "),
   227  				test.stdout,
   228  				test.err,
   229  			))
   230  
   231  			// Change build file mod time
   232  			if err := os.Chtimes(build, test.modTime, test.modTime); err != nil {
   233  				t.Fatal(err)
   234  			}
   235  			ws := tmpDir.Root()
   236  			deps, err := getDependenciesMaven(ctx, ws, &latest.JibArtifact{Project: "maven-test"})
   237  			if test.err != nil {
   238  				prefix := fmt.Sprintf("could not fetch dependencies for workspace %s: initial Jib dependency refresh failed: failed to get Jib dependencies: ", ws)
   239  				t.CheckErrorAndDeepEqual(true, err, prefix+test.err.Error(), err.Error())
   240  			} else {
   241  				t.CheckDeepEqual(test.expected, deps)
   242  			}
   243  		})
   244  	}
   245  }
   246  
   247  func TestGetCommandMaven(t *testing.T) {
   248  	ctx := context.Background()
   249  	tests := []struct {
   250  		description      string
   251  		jibArtifact      latest.JibArtifact
   252  		filesInWorkspace []string
   253  		expectedCmd      func(workspace string) exec.Cmd
   254  	}{
   255  		{
   256  			description:      "maven basic",
   257  			jibArtifact:      latest.JibArtifact{},
   258  			filesInWorkspace: []string{},
   259  			expectedCmd: func(workspace string) exec.Cmd {
   260  				return MavenCommand.CreateCommand(ctx, workspace, []string{"fake-mavenArgs", "jib:_skaffold-files-v2", "--quiet", "--batch-mode"})
   261  			},
   262  		},
   263  		{
   264  			description:      "maven with wrapper",
   265  			jibArtifact:      latest.JibArtifact{},
   266  			filesInWorkspace: []string{"mvnw", "mvnw.bat"},
   267  			expectedCmd: func(workspace string) exec.Cmd {
   268  				return MavenCommand.CreateCommand(ctx, workspace, []string{"fake-mavenArgs", "jib:_skaffold-files-v2", "--quiet", "--batch-mode"})
   269  			},
   270  		},
   271  		{
   272  			description:      "maven with multi-modules",
   273  			jibArtifact:      latest.JibArtifact{Project: "module"},
   274  			filesInWorkspace: []string{"mvnw", "mvnw.bat"},
   275  			expectedCmd: func(workspace string) exec.Cmd {
   276  				return MavenCommand.CreateCommand(ctx, workspace, []string{"fake-mavenArgs-for-module", "jib:_skaffold-files-v2", "--quiet", "--batch-mode"})
   277  			},
   278  		},
   279  	}
   280  	for _, test := range tests {
   281  		testutil.Run(t, test.description, func(t *testutil.T) {
   282  			t.Override(&mavenArgsFunc, getMavenArgsFuncFake(t, MinimumJibMavenVersion))
   283  			tmpDir := t.NewTempDir().
   284  				Touch(test.filesInWorkspace...)
   285  
   286  			cmd := getCommandMaven(ctx, tmpDir.Root(), &test.jibArtifact)
   287  
   288  			expectedCmd := test.expectedCmd(tmpDir.Root())
   289  			t.CheckDeepEqual(expectedCmd.Path, cmd.Path)
   290  			t.CheckDeepEqual(expectedCmd.Args, cmd.Args)
   291  			t.CheckDeepEqual(expectedCmd.Dir, cmd.Dir)
   292  		})
   293  	}
   294  }
   295  
   296  func TestGetSyncMapCommandMaven(t *testing.T) {
   297  	ctx := context.Background()
   298  	tests := []struct {
   299  		description string
   300  		workspace   string
   301  		jibArtifact latest.JibArtifact
   302  		expectedCmd func(workspace string) exec.Cmd
   303  	}{
   304  		{
   305  			description: "single module",
   306  			jibArtifact: latest.JibArtifact{},
   307  			expectedCmd: func(workspace string) exec.Cmd {
   308  				return MavenCommand.CreateCommand(ctx, workspace, []string{"fake-mavenBuildArgs-for-_skaffold-sync-map-skipTests"})
   309  			},
   310  		},
   311  		{
   312  			description: "multi module",
   313  			jibArtifact: latest.JibArtifact{Project: "module"},
   314  			expectedCmd: func(workspace string) exec.Cmd {
   315  				return MavenCommand.CreateCommand(ctx, workspace, []string{"fake-mavenBuildArgs-for-module-for-_skaffold-sync-map-skipTests"})
   316  			},
   317  		},
   318  	}
   319  	for _, test := range tests {
   320  		testutil.Run(t, test.description, func(t *testutil.T) {
   321  			t.Override(&mavenBuildArgsFunc, getMavenBuildArgsFuncFake(t, MinimumJibMavenVersionForSync))
   322  			cmd := getSyncMapCommandMaven(ctx, test.workspace, &test.jibArtifact)
   323  			expectedCmd := test.expectedCmd(test.workspace)
   324  			t.CheckDeepEqual(expectedCmd.Path, cmd.Path)
   325  			t.CheckDeepEqual(expectedCmd.Args, cmd.Args)
   326  			t.CheckDeepEqual(expectedCmd.Dir, cmd.Dir)
   327  		})
   328  	}
   329  }
   330  
   331  func TestGenerateMavenBuildArgs(t *testing.T) {
   332  	tests := []struct {
   333  		description        string
   334  		a                  latest.JibArtifact
   335  		platforms          platform.Matcher
   336  		deps               []*latest.ArtifactDependency
   337  		image              string
   338  		expectedMinVersion string
   339  		r                  ArtifactResolver
   340  		skipTests          bool
   341  		pushImages         bool
   342  		insecureRegistries map[string]bool
   343  		out                []string
   344  	}{
   345  		{description: "single module", image: "image", out: []string{"fake-mavenBuildArgs-for-test-goal", "-Dimage=image"}},
   346  		{description: "single module without tests", image: "image", skipTests: true, out: []string{"fake-mavenBuildArgs-for-test-goal-skipTests", "-Dimage=image"}},
   347  		{description: "multi module", a: latest.JibArtifact{Project: "module"}, image: "image", out: []string{"fake-mavenBuildArgs-for-module-for-test-goal", "-Dimage=image"}},
   348  		{description: "multi module without tests", a: latest.JibArtifact{Project: "module"}, image: "image", skipTests: true, out: []string{"fake-mavenBuildArgs-for-module-for-test-goal-skipTests", "-Dimage=image"}},
   349  		{description: "multi module without tests with insecure-registry", a: latest.JibArtifact{Project: "module"}, image: "registry.tld/image", skipTests: true, insecureRegistries: map[string]bool{"registry.tld": true}, out: []string{"fake-mavenBuildArgs-for-module-for-test-goal-skipTests", "-Djib.allowInsecureRegistries=true", "-Dimage=registry.tld/image"}},
   350  		{description: "single module with custom base image", a: latest.JibArtifact{BaseImage: "docker://busybox"}, image: "image", out: []string{"fake-mavenBuildArgs-for-test-goal", "-Djib.from.image=docker://busybox", "-Dimage=image"}},
   351  		{description: "multi module with custom base image", a: latest.JibArtifact{Project: "module", BaseImage: "docker://busybox"}, image: "image", out: []string{"fake-mavenBuildArgs-for-module-for-test-goal", "-Djib.from.image=docker://busybox", "-Dimage=image"}},
   352  		{description: "host platform", image: "image", platforms: platform.Matcher{Platforms: []v1.Platform{{OS: runtime.GOOS, Architecture: runtime.GOARCH}}}, out: []string{"fake-mavenBuildArgs-for-test-goal", fmt.Sprintf("-Djib.from.platforms=%s/%s", runtime.GOOS, runtime.GOARCH), "-Dimage=image"}},
   353  		{description: "cross-platform", image: "image", platforms: platform.Matcher{Platforms: []v1.Platform{{OS: "freebsd", Architecture: "arm"}}}, out: []string{"fake-mavenBuildArgs-for-test-goal", "-Djib.from.platforms=freebsd/arm", "-Dimage=image"}, expectedMinVersion: MinimumJibMavenVersionForCrossPlatform},
   354  		{description: "multi-platform", image: "image", platforms: platform.Matcher{Platforms: []v1.Platform{{OS: "linux", Architecture: "amd64"}, {OS: "darwin", Architecture: "arm64"}}}, out: []string{"fake-mavenBuildArgs-for-test-goal", "-Djib.from.platforms=linux/amd64,darwin/arm64", "-Dimage=image"}, expectedMinVersion: MinimumJibMavenVersionForCrossPlatform},
   355  		{
   356  			description: "single module with local base image from required artifacts",
   357  			a:           latest.JibArtifact{BaseImage: "alias"},
   358  			deps:        []*latest.ArtifactDependency{{ImageName: "img", Alias: "alias"}},
   359  			image:       "image",
   360  			r:           mockArtifactResolver{m: map[string]string{"img": "img:tag"}},
   361  			out:         []string{"fake-mavenBuildArgs-for-test-goal", "-Djib.from.image=docker://img:tag", "-Dimage=image"},
   362  		},
   363  		{
   364  			description: "multi module with local base image from required artifacts",
   365  			a:           latest.JibArtifact{Project: "module", BaseImage: "alias"},
   366  			deps:        []*latest.ArtifactDependency{{ImageName: "img", Alias: "alias"}},
   367  			image:       "image",
   368  			r:           mockArtifactResolver{m: map[string]string{"img": "img:tag"}},
   369  			out:         []string{"fake-mavenBuildArgs-for-module-for-test-goal", "-Djib.from.image=docker://img:tag", "-Dimage=image"},
   370  		},
   371  		{
   372  			description: "single module with remote base image from required artifacts",
   373  			a:           latest.JibArtifact{BaseImage: "alias"},
   374  			deps:        []*latest.ArtifactDependency{{ImageName: "img", Alias: "alias"}},
   375  			image:       "image",
   376  			pushImages:  true,
   377  			r:           mockArtifactResolver{m: map[string]string{"img": "img:tag"}},
   378  			out:         []string{"fake-mavenBuildArgs-for-test-goal", "-Djib.from.image=img:tag", "-Dimage=image"},
   379  		},
   380  		{
   381  			description: "multi module with remote base image from required artifacts",
   382  			a:           latest.JibArtifact{Project: "module", BaseImage: "alias"},
   383  			deps:        []*latest.ArtifactDependency{{ImageName: "img", Alias: "alias"}},
   384  			image:       "image",
   385  			pushImages:  true,
   386  			r:           mockArtifactResolver{m: map[string]string{"img": "img:tag"}},
   387  			out:         []string{"fake-mavenBuildArgs-for-module-for-test-goal", "-Djib.from.image=img:tag", "-Dimage=image"},
   388  		},
   389  	}
   390  	for _, test := range tests {
   391  		testutil.Run(t, test.description, func(t *testutil.T) {
   392  			minVersion := MinimumJibMavenVersion
   393  			if test.expectedMinVersion != "" {
   394  				minVersion = test.expectedMinVersion
   395  			}
   396  			t.Override(&mavenBuildArgsFunc, getMavenBuildArgsFuncFake(t, minVersion))
   397  			args := GenerateMavenBuildArgs("test-goal", test.image, &test.a, test.platforms, test.skipTests, test.pushImages, test.deps, test.r, test.insecureRegistries, false)
   398  			t.CheckDeepEqual(test.out, args)
   399  		})
   400  	}
   401  }
   402  
   403  func TestMavenBuildArgs(t *testing.T) {
   404  	tests := []struct {
   405  		description string
   406  		jibArtifact latest.JibArtifact
   407  		skipTests   bool
   408  		showColors  bool
   409  		expected    []string
   410  	}{
   411  		{
   412  			description: "single module",
   413  			jibArtifact: latest.JibArtifact{},
   414  			skipTests:   false,
   415  			showColors:  true,
   416  			expected:    []string{"-Dstyle.color=always", "-Djansi.passthrough=true", "-Djib.console=plain", "fake-mavenArgs", "prepare-package", "jib:test-goal"},
   417  		},
   418  		{
   419  			description: "single module skip tests",
   420  			jibArtifact: latest.JibArtifact{},
   421  			skipTests:   true,
   422  			showColors:  true,
   423  			expected:    []string{"-Dstyle.color=always", "-Djansi.passthrough=true", "-Djib.console=plain", "fake-mavenArgs", "-DskipTests=true", "prepare-package", "jib:test-goal"},
   424  		},
   425  		{
   426  			description: "single module plain console",
   427  			jibArtifact: latest.JibArtifact{},
   428  			skipTests:   true,
   429  			showColors:  false,
   430  			expected:    []string{"--batch-mode", "fake-mavenArgs", "-DskipTests=true", "prepare-package", "jib:test-goal"},
   431  		},
   432  		{
   433  			description: "multi module",
   434  			jibArtifact: latest.JibArtifact{Project: "module"},
   435  			skipTests:   false,
   436  			showColors:  true,
   437  			expected:    []string{"-Dstyle.color=always", "-Djansi.passthrough=true", "-Djib.console=plain", "fake-mavenArgs-for-module", "package", "jib:test-goal", "-Djib.containerize=module"},
   438  		},
   439  		{
   440  			description: "single module skip tests",
   441  			jibArtifact: latest.JibArtifact{Project: "module"},
   442  			skipTests:   true,
   443  			showColors:  true,
   444  			expected:    []string{"-Dstyle.color=always", "-Djansi.passthrough=true", "-Djib.console=plain", "fake-mavenArgs-for-module", "-DskipTests=true", "package", "jib:test-goal", "-Djib.containerize=module"},
   445  		},
   446  	}
   447  	for _, test := range tests {
   448  		testutil.Run(t, test.description, func(t *testutil.T) {
   449  			t.Override(&mavenArgsFunc, getMavenArgsFuncFake(t, "test-version"))
   450  			args := mavenBuildArgs("test-goal", &test.jibArtifact, test.skipTests, test.showColors, "test-version")
   451  			t.CheckDeepEqual(test.expected, args)
   452  		})
   453  	}
   454  }
   455  
   456  func TestMavenArgs(t *testing.T) {
   457  	tests := []struct {
   458  		description string
   459  		jibArtifact latest.JibArtifact
   460  		expected    []string
   461  	}{
   462  		{
   463  			description: "single module",
   464  			jibArtifact: latest.JibArtifact{},
   465  			expected:    []string{"jib:_skaffold-fail-if-jib-out-of-date", "-Djib.requiredVersion=test-version", "--non-recursive"},
   466  		},
   467  		{
   468  			description: "single module with extra flags",
   469  			jibArtifact: latest.JibArtifact{
   470  				Flags: []string{"--flag1", "--flag2"},
   471  			},
   472  			expected: []string{"jib:_skaffold-fail-if-jib-out-of-date", "-Djib.requiredVersion=test-version", "--flag1", "--flag2", "--non-recursive"},
   473  		},
   474  		{
   475  			description: "multi module",
   476  			jibArtifact: latest.JibArtifact{Project: "module"},
   477  			expected:    []string{"jib:_skaffold-fail-if-jib-out-of-date", "-Djib.requiredVersion=test-version", "--projects", "module", "--also-make"},
   478  		},
   479  		{
   480  			description: "multi module with extra falgs",
   481  			jibArtifact: latest.JibArtifact{
   482  				Project: "module",
   483  				Flags:   []string{"--flag1", "--flag2"},
   484  			},
   485  			expected: []string{"jib:_skaffold-fail-if-jib-out-of-date", "-Djib.requiredVersion=test-version", "--flag1", "--flag2", "--projects", "module", "--also-make"},
   486  		},
   487  	}
   488  	for _, test := range tests {
   489  		args := mavenArgs(&test.jibArtifact, "test-version")
   490  		testutil.CheckDeepEqual(t, test.expected, args)
   491  	}
   492  }
   493  
   494  func getMavenArgsFuncFake(t *testutil.T, expectedMinimumVersion string) func(*latest.JibArtifact, string) []string {
   495  	return func(a *latest.JibArtifact, minimumVersion string) []string {
   496  		t.CheckDeepEqual(expectedMinimumVersion, minimumVersion)
   497  		if a.Project == "" {
   498  			return []string{"fake-mavenArgs"}
   499  		}
   500  		return []string{"fake-mavenArgs-for-" + a.Project}
   501  	}
   502  }
   503  
   504  func getMavenBuildArgsFuncFake(t *testutil.T, expectedMinimumVersion string) func(string, *latest.JibArtifact, bool, bool, string) []string {
   505  	return func(goal string, a *latest.JibArtifact, skipTests, showColors bool, minimumVersion string) []string {
   506  		t.CheckDeepEqual(expectedMinimumVersion, minimumVersion)
   507  		testString := ""
   508  		if skipTests {
   509  			testString = "-skipTests"
   510  		}
   511  
   512  		if a.Project == "" {
   513  			return []string{"fake-mavenBuildArgs-for-" + goal + testString}
   514  		}
   515  		return []string{"fake-mavenBuildArgs-for-" + a.Project + "-for-" + goal + testString}
   516  	}
   517  }