github.com/drone/runner-go@v1.12.0/environ/environ_test.go (about) 1 // Copyright 2019 Drone.IO Inc. All rights reserved. 2 // Use of this source code is governed by the Polyform License 3 // that can be found in the LICENSE file. 4 5 package environ 6 7 import ( 8 "testing" 9 10 "github.com/drone/drone-go/drone" 11 12 "github.com/google/go-cmp/cmp" 13 ) 14 15 func TestRepo(t *testing.T) { 16 v := &drone.Repo{ 17 ID: 1, 18 UID: "2", 19 UserID: 3, 20 Namespace: "octocat", 21 Name: "hello-world", 22 Slug: "octocat/hello-world", 23 SCM: "git", 24 HTTPURL: "https://github.com/octocat/hello-world.git", 25 SSHURL: "git@github.com:octocat/hello-world", 26 Link: "https://github.com/octocat/hello-world", 27 Branch: "master", 28 Private: true, 29 Visibility: "internal", 30 } 31 a := Repo(v) 32 b := map[string]string{ 33 "DRONE_REPO": "octocat/hello-world", 34 "DRONE_REPO_SCM": "git", 35 "DRONE_REPO_OWNER": "octocat", 36 "DRONE_REPO_NAMESPACE": "octocat", 37 "DRONE_REPO_NAME": "hello-world", 38 "DRONE_REPO_LINK": "https://github.com/octocat/hello-world", 39 "DRONE_REPO_BRANCH": "master", 40 "DRONE_REMOTE_URL": "https://github.com/octocat/hello-world.git", 41 "DRONE_GIT_HTTP_URL": "https://github.com/octocat/hello-world.git", 42 "DRONE_GIT_SSH_URL": "git@github.com:octocat/hello-world", 43 "DRONE_REPO_VISIBILITY": "internal", 44 "DRONE_REPO_PRIVATE": "true", 45 46 "CI_REMOTE_URL": "https://github.com/octocat/hello-world.git", 47 "CI_REPO": "octocat/hello-world", 48 "CI_REPO_LINK": "https://github.com/octocat/hello-world", 49 "CI_REPO_NAME": "octocat/hello-world", 50 "CI_REPO_PRIVATE": "true", 51 "CI_REPO_REMOTE": "https://github.com/octocat/hello-world.git", 52 } 53 if diff := cmp.Diff(a, b); diff != "" { 54 t.Fail() 55 t.Log(diff) 56 } 57 } 58 59 func TestBuild(t *testing.T) { 60 v := &drone.Build{ 61 Trigger: "root", 62 Source: "develop", 63 Target: "master", 64 After: "762941318ee16e59dabbacb1b4049eec22f0d303", 65 Before: "7fd1a60b01f91b314f59955a4e4d4e80d8edf11d", 66 Ref: "refs/pull/32/head", 67 Link: "https://github.com/octocat/Hello-World/commit/762941318ee16e59dabbacb1b4049eec22f0d303", 68 Title: "feat: update README", 69 Message: "updated README", 70 Author: "octocat", 71 AuthorAvatar: "https://avatars0.githubusercontent.com/u/583231", 72 AuthorEmail: "octocat@github.com", 73 AuthorName: "The Octocat", 74 Number: 1, 75 Parent: 2, 76 Event: "pull_request", 77 Action: "opened", 78 Deploy: "prod", 79 DeployID: 235634642, 80 Debug: true, 81 Status: drone.StatusFailing, 82 Created: 1561421740, 83 Started: 1561421746, 84 Finished: 1561421753, 85 Stages: []*drone.Stage{ 86 { 87 Name: "backend", 88 Number: 1, 89 Status: drone.StatusPassing, 90 }, 91 { 92 Name: "frontend", 93 Number: 2, 94 Status: drone.StatusFailing, 95 }, 96 }, 97 } 98 99 a := Build(v) 100 b := map[string]string{ 101 "DRONE_BRANCH": "master", 102 "DRONE_BUILD_NUMBER": "1", 103 "DRONE_BUILD_PARENT": "2", 104 "DRONE_BUILD_STATUS": "failure", 105 "DRONE_BUILD_EVENT": "pull_request", 106 "DRONE_BUILD_DEBUG": "true", 107 "DRONE_BUILD_ACTION": "opened", 108 "DRONE_BUILD_CREATED": "1561421740", 109 "DRONE_BUILD_STARTED": "1561421746", 110 "DRONE_BUILD_FINISHED": "1561421753", 111 "DRONE_COMMIT": "762941318ee16e59dabbacb1b4049eec22f0d303", 112 "DRONE_COMMIT_BEFORE": "7fd1a60b01f91b314f59955a4e4d4e80d8edf11d", 113 "DRONE_COMMIT_AFTER": "762941318ee16e59dabbacb1b4049eec22f0d303", 114 "DRONE_COMMIT_BRANCH": "master", 115 "DRONE_COMMIT_LINK": "https://github.com/octocat/Hello-World/commit/762941318ee16e59dabbacb1b4049eec22f0d303", 116 "DRONE_COMMIT_MESSAGE": "updated README", 117 "DRONE_COMMIT_REF": "refs/pull/32/head", 118 "DRONE_COMMIT_AUTHOR": "octocat", 119 "DRONE_COMMIT_AUTHOR_AVATAR": "https://avatars0.githubusercontent.com/u/583231", 120 "DRONE_COMMIT_AUTHOR_EMAIL": "octocat@github.com", 121 "DRONE_COMMIT_AUTHOR_NAME": "The Octocat", 122 "DRONE_COMMIT_SHA": "762941318ee16e59dabbacb1b4049eec22f0d303", 123 "DRONE_DEPLOY_TO": "prod", 124 "DRONE_DEPLOY_ID": "235634642", 125 "DRONE_FAILED_STAGES": "frontend", 126 "DRONE_PULL_REQUEST": "32", 127 "DRONE_PULL_REQUEST_TITLE": "feat: update README", 128 "DRONE_SOURCE_BRANCH": "develop", 129 "DRONE_TARGET_BRANCH": "master", 130 "DRONE_BUILD_TRIGGER": "root", 131 132 "CI_BUILD_CREATED": "1561421740", 133 "CI_BUILD_EVENT": "pull_request", 134 "CI_BUILD_FINISHED": "1561421753", 135 "CI_BUILD_LINK": "https://github.com/octocat/Hello-World/commit/762941318ee16e59dabbacb1b4049eec22f0d303", 136 "CI_BUILD_NUMBER": "1", 137 "CI_BUILD_STARTED": "1561421746", 138 "CI_BUILD_STATUS": "failure", 139 "CI_BUILD_TARGET": "prod", 140 "CI_COMMIT_AUTHOR": "octocat", 141 "CI_COMMIT_AUTHOR_AVATAR": "https://avatars0.githubusercontent.com/u/583231", 142 "CI_COMMIT_AUTHOR_EMAIL": "octocat@github.com", 143 "CI_COMMIT_AUTHOR_NAME": "The Octocat", 144 "CI_COMMIT_BRANCH": "master", 145 "CI_COMMIT_MESSAGE": "updated README", 146 "CI_COMMIT_REF": "refs/pull/32/head", 147 "CI_COMMIT_SHA": "762941318ee16e59dabbacb1b4049eec22f0d303", 148 "CI_PARENT_BUILD_NUMBER": "2", 149 } 150 if diff := cmp.Diff(a, b); diff != "" { 151 t.Fail() 152 t.Log(diff) 153 } 154 155 v.Started = 0 156 v.Finished = 0 157 a = Build(v) 158 if a["DRONE_BUILD_STARTED"] == "0" { 159 t.Errorf("Expect non-zero started time") 160 } 161 if a["DRONE_BUILD_FINISHED"] == "0" { 162 t.Errorf("Expect non-zero stopped time") 163 } 164 165 v.Ref = "refs/tags/v1.2.3" 166 a = Build(v) 167 if a["DRONE_TAG"] != "v1.2.3" { 168 t.Errorf("Expect tag extraced from ref") 169 } 170 if a["DRONE_SEMVER"] != "1.2.3" { 171 t.Errorf("Expect semver from ref") 172 } 173 if a["DRONE_SEMVER_MAJOR"] != "1" { 174 t.Errorf("Expect semver major") 175 } 176 if a["DRONE_SEMVER_MINOR"] != "2" { 177 t.Errorf("Expect semver minor") 178 } 179 if a["DRONE_SEMVER_PATCH"] != "3" { 180 t.Errorf("Expect semver patch") 181 } 182 } 183 184 func TestSystem(t *testing.T) { 185 v := &drone.System{ 186 Proto: "http", 187 Host: "drone.company.com", 188 Link: "http://drone.company.com", 189 Version: "v1.0.0", 190 } 191 a := System(v) 192 b := map[string]string{ 193 "CI": "true", 194 "DRONE": "true", 195 "DRONE_SYSTEM_HOST": "drone.company.com", 196 "DRONE_SYSTEM_HOSTNAME": "drone.company.com", 197 "DRONE_SYSTEM_PROTO": "http", 198 "DRONE_SYSTEM_VERSION": "v1.0.0", 199 } 200 if diff := cmp.Diff(a, b); diff != "" { 201 t.Fail() 202 t.Log(diff) 203 } 204 } 205 206 func TestStep(t *testing.T) { 207 v := &drone.Step{ 208 Name: "clone", 209 Number: 1, 210 } 211 a := Step(v) 212 b := map[string]string{ 213 "DRONE_STEP_NAME": "clone", 214 "DRONE_STEP_NUMBER": "1", 215 } 216 if diff := cmp.Diff(a, b); diff != "" { 217 t.Fail() 218 t.Log(diff) 219 } 220 } 221 222 func TestStage(t *testing.T) { 223 v := &drone.Stage{ 224 Kind: "pipeline", 225 Type: "docker", 226 Name: "deploy", 227 Number: 1, 228 Machine: "laptop", 229 OS: "linux", 230 Arch: "arm64", 231 Variant: "7", 232 Version: 2004, 233 Status: drone.StatusFailing, 234 Started: 1561421746, 235 Stopped: 1561421753, 236 DependsOn: []string{"backend", "frontend"}, 237 Steps: []*drone.Step{ 238 { 239 Name: "clone", 240 Number: 1, 241 Status: drone.StatusPassing, 242 }, 243 { 244 Name: "test", 245 Number: 2, 246 Status: drone.StatusFailing, 247 }, 248 }, 249 } 250 251 a := Stage(v) 252 b := map[string]string{ 253 "DRONE_STAGE_KIND": "pipeline", 254 "DRONE_STAGE_TYPE": "docker", 255 "DRONE_STAGE_NAME": "deploy", 256 "DRONE_STAGE_NUMBER": "1", 257 "DRONE_STAGE_MACHINE": "laptop", 258 "DRONE_STAGE_OS": "linux", 259 "DRONE_STAGE_ARCH": "arm64", 260 "DRONE_STAGE_VARIANT": "7", 261 "DRONE_STAGE_VERSION": "2004", 262 "DRONE_STAGE_STATUS": "failure", 263 "DRONE_STAGE_STARTED": "1561421746", 264 "DRONE_STAGE_FINISHED": "1561421753", 265 "DRONE_STAGE_DEPENDS_ON": "backend,frontend", 266 "DRONE_FAILED_STEPS": "test", 267 "DRONE_CARD_PATH": "/dev/stdout", 268 } 269 if diff := cmp.Diff(a, b); diff != "" { 270 t.Fail() 271 t.Log(diff) 272 } 273 274 v.Started = 0 275 v.Stopped = 0 276 a = Stage(v) 277 if a["DRONE_STAGE_STARTED"] == "0" { 278 t.Errorf("Expect non-zero started time") 279 } 280 if a["DRONE_STAGE_FINISHED"] == "0" { 281 t.Errorf("Expect non-zero stopped time") 282 } 283 } 284 285 func TestLink(t *testing.T) { 286 sys := &drone.System{ 287 Proto: "http", 288 Host: "drone.company.com", 289 } 290 build := &drone.Build{Number: 42} 291 repo := &drone.Repo{Slug: "octocat/hello-world"} 292 a := Link(repo, build, sys) 293 b := map[string]string{ 294 "DRONE_BUILD_LINK": "http://drone.company.com/octocat/hello-world/42", 295 } 296 if diff := cmp.Diff(a, b); diff != "" { 297 t.Fail() 298 t.Log(diff) 299 } 300 } 301 302 func TestSlice(t *testing.T) { 303 v := map[string]string{ 304 "CI": "true", 305 "DRONE": "true", 306 } 307 a := Slice(v) 308 b := []string{"CI=true", "DRONE=true"} 309 if diff := cmp.Diff(a, b); diff != "" { 310 t.Fail() 311 t.Log(diff) 312 } 313 } 314 315 func TestCombine(t *testing.T) { 316 v1 := map[string]string{ 317 "CI": "true", 318 "DRONE": "true", 319 } 320 v2 := map[string]string{ 321 "CI": "false", 322 "DRONE_SYSTEM_HOST": "drone.company.com", 323 "DRONE_SYSTEM_HOSTNAME": "drone.company.com", 324 "DRONE_SYSTEM_PROTO": "http", 325 "DRONE_SYSTEM_VERSION": "v1.0.0", 326 } 327 a := Combine(v1, v2) 328 b := map[string]string{ 329 "CI": "false", 330 "DRONE": "true", 331 "DRONE_SYSTEM_HOST": "drone.company.com", 332 "DRONE_SYSTEM_HOSTNAME": "drone.company.com", 333 "DRONE_SYSTEM_PROTO": "http", 334 "DRONE_SYSTEM_VERSION": "v1.0.0", 335 } 336 if diff := cmp.Diff(a, b); diff != "" { 337 t.Fail() 338 t.Log(diff) 339 } 340 } 341 342 func Test_isStageFailing(t *testing.T) { 343 s := &drone.Stage{ 344 Status: drone.StatusPassing, 345 Steps: []*drone.Step{ 346 { 347 Status: drone.StatusPassing, 348 }, 349 { 350 ErrIgnore: true, 351 Status: drone.StatusFailing, 352 }, 353 }, 354 } 355 if isStageFailing(s) { 356 t.Errorf("Expect stage not failing if ErrIgnore") 357 } 358 359 s = &drone.Stage{ 360 Status: drone.StatusFailing, 361 } 362 if isStageFailing(s) == false { 363 t.Errorf("Expect stage failing") 364 } 365 366 s = &drone.Stage{ 367 Status: drone.StatusRunning, 368 Steps: []*drone.Step{ 369 { 370 Status: drone.StatusPassing, 371 }, 372 { 373 ErrIgnore: false, 374 Status: drone.StatusFailing, 375 }, 376 }, 377 } 378 if isStageFailing(s) == false { 379 t.Errorf("Expect stage failing if step failing") 380 } 381 } 382 383 func Test_isBuildFailing(t *testing.T) { 384 v := &drone.Build{ 385 Status: drone.StatusPassing, 386 } 387 if isBuildFailing(v) == true { 388 t.Errorf("Expect build passing") 389 } 390 391 v.Status = drone.StatusFailing 392 if isBuildFailing(v) == false { 393 t.Errorf("Expect build failing") 394 } 395 396 v.Status = drone.StatusRunning 397 v.Stages = []*drone.Stage{ 398 {Status: drone.StatusPassing}, 399 {Status: drone.StatusFailing}, 400 } 401 if isBuildFailing(v) == false { 402 t.Errorf("Expect build failing if stage failing") 403 } 404 405 v.Stages = []*drone.Stage{ 406 {Status: drone.StatusPassing}, 407 {Status: drone.StatusRunning}, 408 {Status: drone.StatusPending}, 409 } 410 if isBuildFailing(v) == true { 411 t.Errorf("Expect build passing if all stages passing") 412 } 413 } 414 415 func Test_failedSteps(t *testing.T) { 416 s := &drone.Stage{ 417 Status: drone.StatusRunning, 418 Steps: []*drone.Step{ 419 { 420 Name: "clone", 421 Status: drone.StatusPassing, 422 }, 423 { 424 Name: "test", 425 Status: drone.StatusFailing, 426 }, 427 { 428 Name: "integration", 429 Status: drone.StatusFailing, 430 }, 431 { 432 Name: "experimental", 433 ErrIgnore: true, 434 Status: drone.StatusFailing, 435 }, 436 }, 437 } 438 a, b := failedSteps(s), []string{"test", "integration"} 439 if diff := cmp.Diff(a, b); diff != "" { 440 t.Fail() 441 t.Log(diff) 442 } 443 } 444 445 func Test_failedStages(t *testing.T) { 446 v := &drone.Build{ 447 Status: drone.StatusRunning, 448 Stages: []*drone.Stage{ 449 { 450 Name: "step_blocked", 451 Status: drone.StatusBlocked, 452 }, 453 { 454 Name: "step_declined", 455 Status: drone.StatusDeclined, 456 }, 457 { 458 Name: "step_error", 459 Status: drone.StatusError, 460 }, 461 { 462 Name: "step_failing", 463 Status: drone.StatusFailing, 464 }, 465 { 466 Name: "step_killed", 467 Status: drone.StatusKilled, 468 }, 469 { 470 Name: "step_passing", 471 Status: drone.StatusPassing, 472 }, 473 { 474 Name: "step_pending", 475 Status: drone.StatusPending, 476 }, 477 { 478 Name: "step_running", 479 Status: drone.StatusRunning, 480 }, 481 { 482 Name: "step_skipped", 483 Status: drone.StatusSkipped, 484 }, 485 { 486 Name: "step_waiting", 487 Status: drone.StatusWaiting, 488 }, 489 }, 490 } 491 a, b := failedStages(v), []string{"step_error", "step_failing", "step_killed"} 492 if diff := cmp.Diff(a, b); diff != "" { 493 t.Fail() 494 t.Log(diff) 495 } 496 }