github.com/jfrog/jfrog-cli-go@v1.22.1-0.20200318093948-4826ef344ffd/docker_test.go (about) 1 package main 2 3 import ( 4 "io" 5 "os" 6 "os/exec" 7 "path" 8 "path/filepath" 9 "strings" 10 "testing" 11 12 "github.com/stretchr/testify/assert" 13 14 gofrogcmd "github.com/jfrog/gofrog/io" 15 "github.com/jfrog/jfrog-cli-go/artifactory/commands/generic" 16 "github.com/jfrog/jfrog-cli-go/artifactory/spec" 17 "github.com/jfrog/jfrog-cli-go/artifactory/utils/docker" 18 "github.com/jfrog/jfrog-cli-go/inttestutils" 19 "github.com/jfrog/jfrog-cli-go/utils/cliutils" 20 "github.com/jfrog/jfrog-cli-go/utils/tests" 21 ) 22 23 const DockerTestImage string = "jfrog_cli_test_image" 24 25 // Image get parent image id command 26 type buildDockerImage struct { 27 dockerFilePath string 28 dockerTag string 29 } 30 31 func (image *buildDockerImage) GetCmd() *exec.Cmd { 32 var cmd []string 33 cmd = append(cmd, "docker") 34 cmd = append(cmd, "build") 35 cmd = append(cmd, image.dockerFilePath) 36 cmd = append(cmd, "--tag", image.dockerTag) 37 return exec.Command(cmd[0], cmd[1:]...) 38 } 39 40 func (image *buildDockerImage) GetEnv() map[string]string { 41 return map[string]string{} 42 } 43 44 func (image *buildDockerImage) GetStdWriter() io.WriteCloser { 45 return nil 46 } 47 48 func (image *buildDockerImage) GetErrWriter() io.WriteCloser { 49 return nil 50 } 51 52 type deleteDockerImage struct { 53 dockerImageTag string 54 } 55 56 func (image *deleteDockerImage) GetCmd() *exec.Cmd { 57 var cmd []string 58 cmd = append(cmd, "docker") 59 cmd = append(cmd, "image") 60 cmd = append(cmd, "rm") 61 cmd = append(cmd, image.dockerImageTag) 62 return exec.Command(cmd[0], cmd[1:]...) 63 } 64 65 func (image *deleteDockerImage) GetEnv() map[string]string { 66 return map[string]string{} 67 } 68 69 func (image *deleteDockerImage) GetStdWriter() io.WriteCloser { 70 return nil 71 } 72 73 func (image *deleteDockerImage) GetErrWriter() io.WriteCloser { 74 return nil 75 } 76 77 func TestDockerPush(t *testing.T) { 78 if !*tests.TestDocker { 79 t.Skip("Skipping docker test. To run docker test add the '-test.docker=true' option.") 80 } 81 runDockerPushTest(DockerTestImage, DockerTestImage+":1", false, t) 82 } 83 84 func TestDockerPushWithModuleName(t *testing.T) { 85 if !*tests.TestDocker { 86 t.Skip("Skipping docker test. To run docker test add the '-test.docker=true' option.") 87 } 88 runDockerPushTest(DockerTestImage, ModuleNameJFrogTest, true, t) 89 } 90 91 func TestDockerPushWithMultipleSlash(t *testing.T) { 92 if !*tests.TestDocker { 93 t.Skip("Skipping docker test. To run docker test add the '-test.docker=true' option.") 94 } 95 runDockerPushTest(DockerTestImage+"/multiple", "multiple:1", false, t) 96 } 97 98 // Run docker push to Artifactory 99 func runDockerPushTest(imageName, module string, withModule bool, t *testing.T) { 100 imageTag := buildTestDockerImage(imageName) 101 buildName := "docker-build" 102 buildNumber := "1" 103 104 // Push docker image using docker client 105 if withModule { 106 artifactoryCli.Exec("docker-push", imageTag, *tests.DockerTargetRepo, "--build-name="+buildName, "--build-number="+buildNumber, "--module="+module) 107 } else { 108 artifactoryCli.Exec("docker-push", imageTag, *tests.DockerTargetRepo, "--build-name="+buildName, "--build-number="+buildNumber) 109 } 110 artifactoryCli.Exec("build-publish", buildName, buildNumber) 111 112 imagePath := path.Join(*tests.DockerTargetRepo, imageName, "1") + "/" 113 validateDockerBuild(buildName, buildNumber, imagePath, module, 7, 5, 7, t) 114 115 dockerTestCleanup(imageName, buildName) 116 } 117 118 func TestDockerPushBuildNameNumberFromEnv(t *testing.T) { 119 if !*tests.TestDocker { 120 t.Skip("Skipping docker test. To run docker test add the '-test.docker=true' option.") 121 } 122 123 imageName := DockerTestImage 124 imageTag := buildTestDockerImage(imageName) 125 buildName := "docker-build" 126 buildNumber := "1" 127 os.Setenv(cliutils.BuildName, buildName) 128 os.Setenv(cliutils.BuildNumber, buildNumber) 129 defer os.Unsetenv(cliutils.BuildName) 130 defer os.Unsetenv(cliutils.BuildNumber) 131 132 // Push docker image using docker client 133 artifactoryCli.Exec("docker-push", imageTag, *tests.DockerTargetRepo) 134 artifactoryCli.Exec("build-publish") 135 136 imagePath := path.Join(*tests.DockerTargetRepo, imageName, "1") + "/" 137 validateDockerBuild(buildName, buildNumber, imagePath, DockerTestImage+":1", 7, 5, 7, t) 138 139 dockerTestCleanup(imageName, buildName) 140 } 141 142 func TestDockerPull(t *testing.T) { 143 if !*tests.TestDocker { 144 t.Skip("Skipping docker test. To run docker test add the '-test.docker=true' option.") 145 } 146 147 imageName := DockerTestImage 148 imageTag := buildTestDockerImage(imageName) 149 150 // Push docker image using docker client 151 artifactoryCli.Exec("docker-push", imageTag, *tests.DockerTargetRepo) 152 153 buildName := "docker-pull" 154 buildNumber := "1" 155 156 // Pull docker image using docker client 157 artifactoryCli.Exec("docker-pull", imageTag, *tests.DockerTargetRepo, "--build-name="+buildName, "--build-number="+buildNumber) 158 artifactoryCli.Exec("build-publish", buildName, buildNumber) 159 160 imagePath := path.Join(*tests.DockerTargetRepo, imageName, "1") + "/" 161 validateDockerBuild(buildName, buildNumber, imagePath, imageName+":1", 0, 7, 7, t) 162 163 buildNumber = "2" 164 artifactoryCli.Exec("docker-pull", imageTag, *tests.DockerTargetRepo, "--build-name="+buildName, "--build-number="+buildNumber, "--module="+ModuleNameJFrogTest) 165 artifactoryCli.Exec("build-publish", buildName, buildNumber) 166 validateDockerBuild(buildName, buildNumber, imagePath, ModuleNameJFrogTest, 0, 7, 7, t) 167 168 dockerTestCleanup(imageName, buildName) 169 } 170 171 func buildTestDockerImage(imageName string) string { 172 imageTag := path.Join(*tests.DockerRepoDomain, imageName+":1") 173 dockerFilePath := filepath.Join(filepath.FromSlash(tests.GetTestResourcesPath()), "docker") 174 imageBuilder := &buildDockerImage{dockerTag: imageTag, dockerFilePath: dockerFilePath} 175 gofrogcmd.RunCmd(imageBuilder) 176 return imageTag 177 } 178 179 func deleteTestDockerImage(imageTag string) { 180 imageBuilder := &deleteDockerImage{dockerImageTag: imageTag} 181 gofrogcmd.RunCmd(imageBuilder) 182 } 183 184 func validateDockerBuild(buildName, buildNumber, imagePath, module string, expectedArtifacts, expectedDependencies, expectedItemsInArtifactory int, t *testing.T) { 185 specFile := spec.NewBuilder().Pattern(imagePath + "*").BuildSpec() 186 searchCmd := generic.NewSearchCommand() 187 searchCmd.SetRtDetails(artifactoryDetails).SetSpec(specFile) 188 assert.NoError(t, searchCmd.Search()) 189 assert.Len(t, searchCmd.SearchResult(), expectedItemsInArtifactory, "Docker build info was not pushed correctly") 190 191 buildInfo := inttestutils.GetBuildInfo(artifactoryDetails.Url, buildName, buildNumber, t, artHttpDetails) 192 validateBuildInfo(buildInfo, t, expectedDependencies, expectedArtifacts, module) 193 } 194 195 func dockerTestCleanup(imageName, buildName string) { 196 // Remove build from Artifactory 197 inttestutils.DeleteBuild(artifactoryDetails.Url, buildName, artHttpDetails) 198 199 // Remove image from Artifactory 200 deleteSpec := spec.NewBuilder().Pattern(path.Join(*tests.DockerTargetRepo, imageName)).BuildSpec() 201 tests.DeleteFiles(deleteSpec, artifactoryDetails) 202 } 203 204 func TestDockerClientApiVersionCmd(t *testing.T) { 205 if !*tests.TestDocker { 206 t.Skip("Skipping docker test. To run docker test add the '-test.docker=true' option.") 207 } 208 209 // Run docker version command and expect no errors 210 cmd := &docker.VersionCmd{} 211 content, err := gofrogcmd.RunCmdOutput(cmd) 212 assert.NoError(t, err) 213 214 // Expect VersionRegex to match the output API version 215 content = strings.TrimSpace(content) 216 assert.True(t, docker.ApiVersionRegex.Match([]byte(content))) 217 218 // Assert docker min API version 219 assert.True(t, docker.IsCompatibleApiVersion(content)) 220 } 221 222 func TestDockerFatManifestPull(t *testing.T) { 223 if !*tests.TestDocker { 224 t.Skip("Skipping docker test. To run docker test add the '-test.docker=true' option.") 225 } 226 227 imageName := "traefik" 228 imageTag := path.Join(*tests.DockerRepoDomain, imageName+":2.2") 229 buildName := "docker-pull" 230 buildNumber := "1" 231 232 // Pull docker image using docker client 233 artifactoryCli.Exec("docker-pull", imageTag, *tests.DockerTargetRepo, "--build-name="+buildName, "--build-number="+buildNumber) 234 artifactoryCli.Exec("build-publish", buildName, buildNumber) 235 236 //Validate 237 buildInfo := inttestutils.GetBuildInfo(artifactoryDetails.Url, buildName, buildNumber, t, artHttpDetails) 238 validateBuildInfo(buildInfo, t, 6, 0, imageName+":2.2") 239 240 dockerTestCleanup(imageName, buildName) 241 deleteTestDockerImage(imageTag) 242 }