github.com/ouraigua/jenkins-library@v0.0.0-20231028010029-fbeaf2f3aa9b/cmd/gradleExecuteBuild_test.go (about) 1 //go:build unit 2 // +build unit 3 4 package cmd 5 6 import ( 7 "fmt" 8 "io/fs" 9 "path/filepath" 10 "testing" 11 12 "github.com/pkg/errors" 13 "github.com/stretchr/testify/assert" 14 15 "github.com/SAP/jenkins-library/pkg/mock" 16 "github.com/SAP/jenkins-library/pkg/piperenv" 17 ) 18 19 const moduleFileContent = `{"variants": [{"name": "apiElements","files": [{"name": "gradle-1.2.3-12234567890-plain.jar"}]}]}` 20 21 type gradleExecuteBuildMockUtils struct { 22 *mock.ExecMockRunner 23 *mock.FilesMock 24 Filepath 25 } 26 27 type isDirEntryMock func() bool 28 29 func (d isDirEntryMock) Name() string { 30 panic("not implemented") 31 } 32 33 func (d isDirEntryMock) IsDir() bool { 34 return d() 35 } 36 37 func (d isDirEntryMock) Type() fs.FileMode { 38 panic("not implemented") 39 } 40 func (d isDirEntryMock) Info() (fs.FileInfo, error) { 41 panic("not implemented") 42 } 43 44 func TestRunGradleExecuteBuild(t *testing.T) { 45 pipelineEnv := &gradleExecuteBuildCommonPipelineEnvironment{} 46 47 t.Run("failed case - build.gradle isn't present", func(t *testing.T) { 48 utils := gradleExecuteBuildMockUtils{ 49 ExecMockRunner: &mock.ExecMockRunner{}, 50 FilesMock: &mock.FilesMock{}, 51 } 52 options := &gradleExecuteBuildOptions{ 53 Path: "path/to", 54 Task: "build", 55 UseWrapper: false, 56 } 57 58 err := runGradleExecuteBuild(options, nil, utils, pipelineEnv) 59 assert.Error(t, err) 60 assert.Contains(t, err.Error(), "the specified gradle build script could not be found") 61 }) 62 63 t.Run("success case - only build", func(t *testing.T) { 64 utils := gradleExecuteBuildMockUtils{ 65 ExecMockRunner: &mock.ExecMockRunner{}, 66 FilesMock: &mock.FilesMock{}, 67 } 68 utils.FilesMock.AddFile("path/to/build.gradle", []byte{}) 69 options := &gradleExecuteBuildOptions{ 70 Path: "path/to", 71 Task: "build", 72 UseWrapper: false, 73 } 74 75 err := runGradleExecuteBuild(options, nil, utils, pipelineEnv) 76 assert.NoError(t, err) 77 assert.Equal(t, 1, len(utils.Calls)) 78 assert.Equal(t, mock.ExecCall{Exec: "gradle", Params: []string{"build", "-p", "path/to"}}, utils.Calls[0]) 79 }) 80 81 t.Run("success case - build with flags", func(t *testing.T) { 82 utils := gradleExecuteBuildMockUtils{ 83 ExecMockRunner: &mock.ExecMockRunner{}, 84 FilesMock: &mock.FilesMock{}, 85 } 86 utils.FilesMock.AddFile("path/to/build.gradle", []byte{}) 87 options := &gradleExecuteBuildOptions{ 88 Path: "path/to", 89 Task: "build", 90 BuildFlags: []string{"clean", "build", "-x", "test"}, 91 UseWrapper: false, 92 } 93 94 err := runGradleExecuteBuild(options, nil, utils, pipelineEnv) 95 assert.NoError(t, err) 96 assert.Equal(t, 1, len(utils.Calls)) 97 assert.Equal(t, mock.ExecCall{Exec: "gradle", Params: []string{"clean", "build", "-x", "test", "-p", "path/to"}}, utils.Calls[0]) 98 }) 99 100 t.Run("success case - bom creation", func(t *testing.T) { 101 utils := gradleExecuteBuildMockUtils{ 102 ExecMockRunner: &mock.ExecMockRunner{}, 103 FilesMock: &mock.FilesMock{}, 104 } 105 utils.FilesMock.AddFile("path/to/build.gradle", []byte{}) 106 options := &gradleExecuteBuildOptions{ 107 Path: "path/to", 108 Task: "build", 109 UseWrapper: false, 110 CreateBOM: true, 111 } 112 113 err := runGradleExecuteBuild(options, nil, utils, pipelineEnv) 114 assert.NoError(t, err) 115 assert.Equal(t, 3, len(utils.Calls)) 116 assert.Equal(t, mock.ExecCall{Exec: "gradle", Params: []string{"tasks", "-p", "path/to"}}, utils.Calls[0]) 117 assert.Equal(t, mock.ExecCall{Execution: (*mock.Execution)(nil), Async: false, Exec: "gradle", Params: []string{"cyclonedxBom", "-p", "path/to", "--init-script", "initScript.gradle.tmp"}}, utils.Calls[1]) 118 assert.Equal(t, mock.ExecCall{Exec: "gradle", Params: []string{"build", "-p", "path/to"}}, utils.Calls[2]) 119 assert.True(t, utils.HasWrittenFile("initScript.gradle.tmp")) 120 assert.True(t, utils.HasRemovedFile("initScript.gradle.tmp")) 121 }) 122 123 t.Run("success case - publishing of artifacts", func(t *testing.T) { 124 var walkDir WalkDirFunc = func(root string, fn fs.WalkDirFunc) error { 125 var dirMock isDirEntryMock = func() bool { 126 return false 127 } 128 return fn(filepath.Join("test_subproject_path", "build", "publications", "maven", "module.json"), dirMock, nil) 129 } 130 utils := gradleExecuteBuildMockUtils{ 131 ExecMockRunner: &mock.ExecMockRunner{}, 132 FilesMock: &mock.FilesMock{}, 133 Filepath: walkDir, 134 } 135 utils.FilesMock.AddFile("path/to/build.gradle", []byte{}) 136 utils.FilesMock.AddFile(filepath.Join("test_subproject_path", "build", "publications", "maven", "module.json"), []byte(moduleFileContent)) 137 options := &gradleExecuteBuildOptions{ 138 Path: "path/to", 139 Task: "build", 140 UseWrapper: false, 141 Publish: true, 142 } 143 144 err := runGradleExecuteBuild(options, nil, utils, pipelineEnv) 145 assert.NoError(t, err) 146 assert.Equal(t, 3, len(utils.Calls)) 147 assert.Equal(t, mock.ExecCall{Exec: "gradle", Params: []string{"build", "-p", "path/to"}}, utils.Calls[0]) 148 assert.Equal(t, mock.ExecCall{Exec: "gradle", Params: []string{"tasks", "-p", "path/to"}}, utils.Calls[1]) 149 assert.Equal(t, mock.ExecCall{Execution: (*mock.Execution)(nil), Async: false, Exec: "gradle", Params: []string{"publish", "-p", "path/to", "--init-script", "initScript.gradle.tmp"}}, utils.Calls[2]) 150 assert.Equal(t, "gradle-1.2.3-12234567890-plain.jar", pipelineEnv.custom.artifacts[0].Name) 151 assert.True(t, utils.HasWrittenFile("initScript.gradle.tmp")) 152 assert.True(t, utils.HasRemovedFile("initScript.gradle.tmp")) 153 }) 154 155 t.Run("success case - build using wrapper", func(t *testing.T) { 156 utils := gradleExecuteBuildMockUtils{ 157 ExecMockRunner: &mock.ExecMockRunner{}, 158 FilesMock: &mock.FilesMock{}, 159 } 160 utils.FilesMock.AddFile("path/to/build.gradle", []byte{}) 161 utils.FilesMock.AddFile("gradlew", []byte{}) 162 options := &gradleExecuteBuildOptions{ 163 Path: "path/to", 164 Task: "build", 165 UseWrapper: true, 166 } 167 168 err := runGradleExecuteBuild(options, nil, utils, pipelineEnv) 169 assert.NoError(t, err) 170 assert.Equal(t, 1, len(utils.Calls)) 171 assert.Equal(t, mock.ExecCall{Exec: "./gradlew", Params: []string{"build", "-p", "path/to"}}, utils.Calls[0]) 172 }) 173 174 t.Run("failed case - build", func(t *testing.T) { 175 utils := gradleExecuteBuildMockUtils{ 176 ExecMockRunner: &mock.ExecMockRunner{ 177 ShouldFailOnCommand: map[string]error{"gradle build -p path/to": errors.New("failed to build")}, 178 }, 179 FilesMock: &mock.FilesMock{}, 180 } 181 utils.FilesMock.AddFile("path/to/build.gradle", []byte{}) 182 options := &gradleExecuteBuildOptions{ 183 Path: "path/to", 184 Task: "build", 185 UseWrapper: false, 186 } 187 188 err := runGradleExecuteBuild(options, nil, utils, pipelineEnv) 189 assert.Error(t, err) 190 assert.Contains(t, err.Error(), "failed to build") 191 }) 192 193 t.Run("failed case - build with flags", func(t *testing.T) { 194 utils := gradleExecuteBuildMockUtils{ 195 ExecMockRunner: &mock.ExecMockRunner{ 196 ShouldFailOnCommand: map[string]error{"gradle clean build -x test -p path/to": errors.New("failed to build with flags")}, 197 }, 198 FilesMock: &mock.FilesMock{}, 199 } 200 utils.FilesMock.AddFile("path/to/build.gradle", []byte{}) 201 options := &gradleExecuteBuildOptions{ 202 Path: "path/to", 203 Task: "build", 204 BuildFlags: []string{"clean", "build", "-x", "test"}, 205 UseWrapper: false, 206 } 207 208 err := runGradleExecuteBuild(options, nil, utils, pipelineEnv) 209 assert.Error(t, err) 210 assert.Contains(t, err.Error(), "failed to build with flags") 211 }) 212 213 t.Run("failed case - bom creation", func(t *testing.T) { 214 utils := gradleExecuteBuildMockUtils{ 215 ExecMockRunner: &mock.ExecMockRunner{ 216 ShouldFailOnCommand: map[string]error{"./gradlew cyclonedxBom -p path/to --init-script initScript.gradle.tmp": errors.New("failed to create bom")}, 217 }, 218 FilesMock: &mock.FilesMock{}, 219 } 220 utils.FilesMock.AddFile("path/to/build.gradle", []byte{}) 221 utils.FilesMock.AddFile("gradlew", []byte{}) 222 options := &gradleExecuteBuildOptions{ 223 Path: "path/to", 224 Task: "build", 225 UseWrapper: true, 226 CreateBOM: true, 227 } 228 229 err := runGradleExecuteBuild(options, nil, utils, pipelineEnv) 230 assert.Error(t, err) 231 assert.Contains(t, err.Error(), "failed to create bom") 232 }) 233 234 t.Run("failed case - publish artifacts", func(t *testing.T) { 235 utils := gradleExecuteBuildMockUtils{ 236 ExecMockRunner: &mock.ExecMockRunner{ 237 ShouldFailOnCommand: map[string]error{"./gradlew publish -p path/to --init-script initScript.gradle.tmp": errors.New("failed to publish artifacts")}, 238 }, 239 FilesMock: &mock.FilesMock{}, 240 } 241 utils.FilesMock.AddFile("path/to/build.gradle", []byte{}) 242 utils.FilesMock.AddFile("gradlew", []byte{}) 243 options := &gradleExecuteBuildOptions{ 244 Path: "path/to", 245 Task: "build", 246 UseWrapper: true, 247 Publish: true, 248 } 249 250 err := runGradleExecuteBuild(options, nil, utils, pipelineEnv) 251 assert.Error(t, err) 252 assert.Contains(t, err.Error(), "failed to publish artifacts") 253 }) 254 } 255 256 func TestGetPublishedArtifactsNames(t *testing.T) { 257 tt := []struct { 258 name string 259 utils gradleExecuteBuildMockUtils 260 moduleFile string 261 moduleFileContent string 262 expectedResult piperenv.Artifacts 263 expectedErr error 264 }{ 265 { 266 name: "failed to check file existence", 267 utils: gradleExecuteBuildMockUtils{ 268 ExecMockRunner: &mock.ExecMockRunner{}, 269 FilesMock: &mock.FilesMock{ 270 FileExistsErrors: map[string]error{"module.json": fmt.Errorf("err")}, 271 }, 272 }, 273 moduleFile: "module.json", 274 moduleFileContent: "", 275 expectedErr: fmt.Errorf("failed to check existence of the file 'module.json': err"), 276 }, { 277 name: "failed to get file", 278 utils: gradleExecuteBuildMockUtils{ 279 ExecMockRunner: &mock.ExecMockRunner{}, 280 FilesMock: &mock.FilesMock{}, 281 }, 282 moduleFile: "", 283 moduleFileContent: "", 284 expectedErr: fmt.Errorf("failed to get '': file does not exist"), 285 }, { 286 name: "failed to read file", 287 utils: gradleExecuteBuildMockUtils{ 288 ExecMockRunner: &mock.ExecMockRunner{}, 289 FilesMock: &mock.FilesMock{ 290 FileReadErrors: map[string]error{"module.json": fmt.Errorf("err")}, 291 }, 292 }, 293 moduleFile: "module.json", 294 moduleFileContent: "", 295 expectedErr: fmt.Errorf("failed to read 'module.json': err"), 296 }, { 297 name: "failed to unmarshal file", 298 utils: gradleExecuteBuildMockUtils{ 299 ExecMockRunner: &mock.ExecMockRunner{}, 300 FilesMock: &mock.FilesMock{}, 301 }, 302 moduleFile: "module.json", 303 moduleFileContent: "", 304 expectedErr: fmt.Errorf("failed to unmarshal 'module.json': unexpected end of JSON input"), 305 }, { 306 name: "success - get name of published artifact", 307 utils: gradleExecuteBuildMockUtils{ 308 ExecMockRunner: &mock.ExecMockRunner{}, 309 FilesMock: &mock.FilesMock{}, 310 }, 311 moduleFile: "module.json", 312 moduleFileContent: moduleFileContent, 313 expectedResult: piperenv.Artifacts{piperenv.Artifact{Name: "gradle-1.2.3-12234567890-plain.jar"}}, 314 expectedErr: nil, 315 }, 316 } 317 318 for _, test := range tt { 319 test := test 320 t.Run(test.name, func(t *testing.T) { 321 t.Parallel() 322 if test.moduleFile != "" { 323 test.utils.FilesMock.AddFile(test.moduleFile, []byte(test.moduleFileContent)) 324 } 325 artifacts, err := getPublishedArtifactsNames(test.moduleFile, test.utils) 326 assert.Equal(t, test.expectedResult, artifacts) 327 assert.Equal(t, test.expectedErr, err) 328 }) 329 } 330 }