github.com/swaros/contxt/module/taskrun@v0.0.0-20240305083542-3dbd4436ac40/cmdflow_test.go (about) 1 package taskrun_test 2 3 import ( 4 "os" 5 "strings" 6 "testing" 7 8 "github.com/swaros/contxt/module/configure" 9 "github.com/swaros/contxt/module/dirhandle" 10 "github.com/swaros/contxt/module/taskrun" 11 ) 12 13 type RuntimeGroupExpected struct { 14 Contains []string 15 } 16 17 type TestRuntimeGroup struct { 18 tests []RuntimeGroupExpected 19 } 20 21 func listHaveString(lookFor string, list []string) bool { 22 for _, s := range list { 23 if s == lookFor { 24 return true 25 } 26 } 27 return false 28 } 29 30 func listContainsEach(lista, listb []string) (string, bool) { 31 for _, chk := range lista { 32 if !listHaveString(chk, listb) { 33 return chk, false 34 } 35 } 36 return "", true 37 } 38 39 func sliceList(offset int, list []string) ([]string, []string) { 40 var newList []string 41 var restList []string 42 for i, cont := range list { 43 if i < offset { 44 newList = append(newList, cont) 45 } else { 46 restList = append(restList, cont) 47 } 48 } 49 return newList, restList 50 } 51 52 func assertRuntimeGroup(t *testing.T, path string, target string, testGroup TestRuntimeGroup) bool { 53 tresult := true 54 folderRunner(path, t, func(t *testing.T) { 55 taskrun.RunTargets(target, true) 56 result := taskrun.GetPH("teststr") 57 resultArr := strings.Split(result, ":") 58 59 //offset := 0 60 for tbIndex, runtimeCheck := range testGroup.tests { 61 var checkList []string 62 testLen := len(runtimeCheck.Contains) // how many entries we have to check 63 if testLen <= len(resultArr) { // do we have enough entries in the result array? 64 checkList, resultArr = sliceList(len(runtimeCheck.Contains), resultArr) 65 if missingStr, ok := listContainsEach(checkList, runtimeCheck.Contains); ok == false { 66 t.Error("missing ", missingStr, " in test block ", tbIndex, " got ", checkList, " expected", runtimeCheck.Contains) 67 tresult = false 68 } 69 } 70 } 71 72 }) 73 74 return tresult 75 } 76 77 func TestIssue58(t *testing.T) { 78 folderRunner("./../../docs/test/issue58", t, func(t *testing.T) { 79 80 taskrun.RunTargets("test1", true) 81 res := taskrun.GetPH("RUN.test1.LOG.LAST") 82 if res != "full check john miller" { 83 t.Error("unexpected result [", res, "]") 84 } 85 86 taskrun.RunTargets("start", true) 87 test1Result := taskrun.GetPH("RUN.start.LOG.LAST") 88 if test1Result != "hello world" { 89 t.Error("result 2 should be 'hello world'.[", test1Result, "]") 90 } 91 92 taskrun.RunTargets("replace", true) 93 rep := taskrun.GetPH("RUN.replace.LOG.LAST") 94 if rep != "[testcase /usr - mother]" { 95 t.Error("the replacing of inline variables in defined variables is not working") 96 } 97 }) 98 } 99 100 func TestMultipleTargets(t *testing.T) { 101 folderRunner("./../../docs/test/01multi", t, func(t *testing.T) { 102 taskrun.RunTargets("task", true) 103 test1Result := taskrun.GetPH("RUN.task.LOG.LAST") 104 if test1Result != "hello 2" { 105 t.Error("result 2 should be 'hello 2'.", test1Result) 106 } 107 }) 108 } 109 110 func TestMultipleTargetsOs(t *testing.T) { 111 folderRunner("./../../docs/test/02multi", t, func(t *testing.T) { 112 taskrun.RunTargets("task", true) 113 test1Result := taskrun.GetPH("RUN.task.LOG.LAST") 114 if configure.GetOs() == "linux" { 115 if test1Result != "hello linux" { 116 t.Error("result 2 should be 'hello 2'. got[", test1Result, "]") 117 } 118 } 119 }) 120 } 121 122 func TestRunIfEquals(t *testing.T) { 123 folderRunner("./../../docs/test/ifequals", t, func(t *testing.T) { 124 taskrun.RunTargets("check-eq", true) 125 test1Result := taskrun.GetPH("RUN.check-eq.LOG.LAST") 126 if test1Result != "inline" { 127 t.Error("result 2 should be 'inline'.", test1Result) 128 } 129 130 taskrun.RunTargets("check-noeq", true) 131 test2Result := taskrun.GetPH("RUN.check-noeq.LOG.LAST") 132 if test2Result != "start2" { 133 t.Error("result 2 should be 'start2'.", test2Result) 134 } 135 }) 136 } 137 138 func TestVariableReset(t *testing.T) { 139 folderRunner("./../../docs/test/valueRedefine", t, func(t *testing.T) { 140 taskrun.RunTargets("case1", true) 141 test1Result := taskrun.GetPH("RUN.case1.LOG.LAST") 142 if test1Result != "initial" { 143 t.Error("result 1 should be 'initial'.", test1Result) 144 } 145 146 taskrun.RunTargets("case2", true) 147 test2Result := taskrun.GetPH("RUN.case2.LOG.LAST") 148 if test2Result != "in-case-2" { 149 t.Error("result 2 should be 'in-case-2'.", test1Result) 150 } 151 152 taskrun.RunTargets("case1,case2", true) 153 test3Result := taskrun.GetPH("RUN.case2.LOG.LAST") 154 if test3Result != "in-case-2" { 155 t.Error("result 2 should be 'in-case-2'.", test1Result) 156 } 157 158 // testing main variables do not reset already changes variables 159 taskrun.RunTargets("case2,case1", true) 160 test4Result := taskrun.GetPH("RUN.case2.LOG.LAST") 161 if test4Result != "in-case-2" { 162 t.Error("result 2 should be 'in-case-2'.", test1Result) 163 } 164 165 test5Result := taskrun.GetPH("RUN.case1.LOG.LAST") 166 if test5Result != "in-case-2" { 167 t.Error("result 2 should be 'in-case-2'.", test1Result) 168 } 169 }) 170 } 171 172 func TestCase0(t *testing.T) { 173 caseRunner("0", t, func(t *testing.T) { 174 taskrun.RunTargets("test1,test2", true) 175 test1Result := taskrun.GetPH("RUN.test1.LOG.LAST") 176 if test1Result == "" { 177 t.Error("result 1 should not be empty.", test1Result) 178 } 179 180 test2Result := taskrun.GetPH("RUN.test2.LOG.LAST") 181 if test2Result == "" { 182 t.Error("result 2 should not be empty.", test2Result) 183 } 184 185 if test2Result != "runs" { 186 t.Error("result 2 should be 'runs' instead we got.", "["+test2Result+"]") 187 } 188 }) 189 } 190 191 func TestRunTargetCase1(t *testing.T) { 192 193 caseRunner("1", t, func(t *testing.T) { 194 taskrun.RunTargets("case1_1,case1_2", true) 195 test1Result := taskrun.GetPH("RUN.case1_1.LOG.LAST") 196 if test1Result == "" { 197 t.Error("result 1 should not be empty.", test1Result) 198 } 199 200 test2Result := taskrun.GetPH("RUN.case1_2.LOG.LAST") 201 if test2Result == "" { 202 t.Error("result 2 should not be empty.", test2Result) 203 } 204 205 if test2Result != "runs" { 206 t.Error("result 2 should be 'runs' instead we got.", test2Result) 207 } 208 209 scriptLast := taskrun.GetPH("RUN.SCRIPT_LINE") 210 if scriptLast != "echo runs" { 211 t.Error("unexpected result [", scriptLast, "]") 212 } 213 }) 214 215 } 216 217 func TestRunTargetCase2(t *testing.T) { 218 219 caseRunner("2", t, func(t *testing.T) { 220 taskrun.RunTargets("base", true) 221 test1Result := taskrun.GetPH("RUN.base.LOG.HIT") 222 if test1Result != "start-task-2" { 223 t.Error("unexpected result ", test1Result) 224 } 225 226 test2Result := taskrun.GetPH("RUN.task-2.LOG.LAST") 227 if test2Result != "im-task-2" { 228 t.Error("unexpected result [", test2Result, "]") 229 } 230 }) 231 } 232 233 // TBH: not sure if these is not too specific 234 /* 235 func TestRunTargetCase3(t *testing.T) { 236 // testing PID of my own and the parent process 237 if configure.GetOs() == "windows" { 238 return 239 } 240 caseRunner("3", t, func(t *testing.T) { 241 taskrun.RunTargets("base", true) 242 test1Result := taskrun.GetPH("RUN.base.LOG.HIT") 243 if test1Result != "launch" { 244 t.Error("unexpected result ", test1Result) 245 } 246 pid_1 := taskrun.GetPH("RUN.base.LOG.LAST") 247 pid_2 := taskrun.GetPH("RUN.task-2.LOG.LAST") 248 if pid_2 != pid_1 { 249 t.Error("PID should be the same [", pid_1, " != ", pid_2, "]") 250 } 251 }) 252 253 }*/ 254 255 func TestCase4(t *testing.T) { 256 caseRunner("4", t, func(t *testing.T) { 257 //stopped because log entrie to big 258 taskrun.RunTargets("base", true) 259 log := taskrun.GetPH("RUN.base.LOG.LAST") 260 if log != "sub 4-6" { 261 t.Error("last log entrie should not be:", log) 262 } 263 264 taskrun.RunTargets("contains", true) 265 log = taskrun.GetPH("RUN.contains.LOG.LAST") 266 if log != "come and die" { 267 t.Error("last log entrie should not be", log) 268 } 269 }) 270 } 271 272 func TestCase5(t *testing.T) { 273 caseRunner("5", t, func(t *testing.T) { 274 //contains a mutliline shell script 275 taskrun.RunTargets("base", true) 276 log := taskrun.GetPH("RUN.base.LOG.LAST") 277 if log == "" { 278 t.Error("got empty result. that is not expected") 279 } 280 if log != "line4" { 281 t.Error("expected 'line4'...but got ", log) 282 } 283 }) 284 } 285 286 // testing the thread run. do we wait for the subjobs also if they run longer then then main Task? 287 func TestCase6(t *testing.T) { 288 caseRunner("6", t, func(t *testing.T) { 289 taskrun.RunTargets("base", true) 290 log := taskrun.GetPH("RUN.sub.LOG.LAST") 291 if log != "sub-end" { 292 t.Error("failed wait for ending subrun. last log entrie should be 'sub-end' got [", log, "] instead") 293 } 294 295 }) 296 } 297 298 // testing error handling by script fails 299 func TestCase7(t *testing.T) { 300 caseRunner("7", t, func(t *testing.T) { 301 taskrun.RunTargets("base", true) 302 logMain := taskrun.GetPH("RUN.base.LOG.LAST") 303 if logMain != "done-main" { 304 t.Error("last runstep should be excuted. but stopped on:", logMain) 305 } 306 307 log := taskrun.GetPH("RUN.sub.LOG.LAST") 308 if log == "sub-end" { 309 t.Error("the script runs without erros, but hey have an error. script have to stop. log=", log) 310 } 311 312 }) 313 } 314 315 // testing on error behavior for the stop reasons 316 func TestCase71(t *testing.T) { 317 assertCaseLogLastEquals(t, "7", "trigger", "two") // testing outpout match 318 assertCaseLogLastEquals(t, "7", "len", "123") // test onoutLess 319 assertCaseLogLastEquals(t, "7", "lenmore", "b123456abcdefghijklmn") // test onoutMore 320 } 321 322 // test variables. replace set at config variables to hallo-welt 323 func TestCase8(t *testing.T) { 324 caseRunner("8", t, func(t *testing.T) { 325 taskrun.RunTargets("base", true) 326 logMain := taskrun.GetPH("RUN.base.LOG.LAST") 327 if logMain != "hallo-welt" { 328 t.Error("variable should be replaced. but got:", logMain) 329 } 330 }) 331 } 332 333 // test variables. replace set at config variables to hallo-welt but then overwrittn in task to hello-world 334 func TestCase9(t *testing.T) { 335 caseRunner("9", t, func(t *testing.T) { 336 taskrun.RunTargets("base,test2", true) 337 logMain := taskrun.GetPH("RUN.base.LOG.LAST") 338 if logMain != "hello-world" { 339 t.Error("variable should be replaced. but got:", logMain) 340 } 341 test2 := taskrun.GetPH("RUN.test2.LOG.LAST") 342 if test2 != "lets go" { 343 t.Error("placeholder was not used in task variables. got:[", test2, "]") 344 } 345 }) 346 } 347 348 func TestCase12Requires(t *testing.T) { 349 caseRunner("12", t, func(t *testing.T) { 350 os.Setenv("TESTCASE_12_VAL", "HELLO") 351 taskrun.RunTargets("test1,test2,test3,test4,test5,test6", true) 352 logMain := taskrun.GetPH("RUN.test1.LOG.LAST") 353 if logMain != "run_a" { 354 t.Error("got unexpected result:", logMain) 355 } 356 357 test2 := taskrun.GetPH("RUN.test2.LOG.LAST") 358 if test2 != "" { 359 t.Error("got unexpected result for test2. got:", test2, "test should not run because of checking file") 360 } 361 362 test3 := taskrun.GetPH("RUN.test3.LOG.LAST") 363 if test3 != "" { 364 t.Error("got unexpected result for test3. got:", test3, "test should not run because env-var check") 365 } 366 367 test4 := taskrun.GetPH("RUN.test4.LOG.LAST") 368 if test4 != "run_d" { 369 t.Error("got unexpected result for test4. got:", test4, "test should run because env-var check") 370 } 371 372 test5 := taskrun.GetPH("RUN.test5.LOG.LAST") 373 if test5 != "" { 374 t.Error("got unexpected result for test5. got:", test5, "test should not run because variable check") 375 } 376 377 varValue := taskrun.GetPH("test_var") 378 if varValue == "HELLO_KLAUS" { 379 t.Error("Expected value 'HELLO_KLAUS' not in placeholder 'test_var'. got instead: ", varValue) 380 } 381 test6 := taskrun.GetPH("RUN.test6.LOG.LAST") 382 if test6 != "" { 383 t.Error("got unexpected result for test6. got:[", test6, "]test should run because variable check") 384 } 385 }) 386 } 387 388 func TestCase13Next(t *testing.T) { 389 caseRunner("13", t, func(t *testing.T) { 390 391 taskrun.RunTargets("start", true) 392 logMain := taskrun.GetPH("RUN.start.LOG.LAST") 393 if logMain != "start" { 394 t.Error("got unexpected result:(", logMain, ")") 395 } 396 397 test2 := taskrun.GetPH("RUN.next_a.LOG.LAST") 398 if test2 != "run-a" { 399 t.Error("got unexpected result for test2. got:(", test2, ")") 400 } 401 402 test := taskrun.GetPH("RUN.next_b.LOG.LAST") 403 if test != "run-b" { 404 t.Error("got unexpected result for test3. got:(", test, ")") 405 } 406 407 test = taskrun.GetPH("RUN.next_c.LOG.LAST") 408 if test != "run-c" { 409 t.Error("got unexpected result for test4. got:(", test, ")") 410 } 411 412 }) 413 } 414 415 func TestCase14Imports(t *testing.T) { 416 caseRunner("14", t, func(t *testing.T) { 417 418 taskrun.RunTargets("start,usertest", true) 419 check := taskrun.GetJSONPathValueString("import.yaml", "testdata.check") 420 if check != "hello" { 421 t.Error("expect hello but got", check) 422 } 423 424 outcome := taskrun.GetPH("RUN.start.LOG.LAST") 425 if outcome != "hello world" { 426 t.Error("import looks not working. got ", outcome) 427 } 428 429 usertest := taskrun.GetPH("RUN.usertest.LOG.LAST") 430 if usertest != "hello john miller" { 431 t.Error("user data import looks not working. got ", usertest) 432 } 433 }) 434 } 435 436 func TestCase15Needs(t *testing.T) { 437 caseRunner("15", t, func(t *testing.T) { 438 439 taskrun.RunTargets("start", true) 440 441 usertest := taskrun.GetPH("RUN.start.LOG.LAST") 442 needOneRuns := taskrun.GetPH("RUN.need_one.LOG.LAST") 443 needTwoRuns := taskrun.GetPH("RUN.need_two.LOG.LAST") 444 if needOneRuns != "<<< 1 >>> done need_one" { 445 t.Error("NEEDS needOne should be executed [done need_one] we got : ", needOneRuns) 446 } 447 if needTwoRuns != "<<< 2 >>> done need_two" { 448 t.Error("NEEDS needTwo should be executed [done need_two] we got : ", needTwoRuns) 449 } 450 451 if usertest != "the-main-task" { 452 t.Error("did not get expected result instead [the-main-task] we got : ", usertest) 453 } 454 }) 455 } 456 457 func TestCase16WorkingDir(t *testing.T) { 458 caseRunner("16", t, func(t *testing.T) { 459 old, derr := dirhandle.Current() 460 if derr != nil { 461 t.Error(derr) 462 } 463 taskrun.RunTargets("origin_dir", true) 464 origin_dir := clearStrings(taskrun.GetPH("RUN.origin_dir.LOG.LAST")) 465 oldChkStr := clearStrings(old) 466 467 // strToUpper required on windows because of differents in drive letter 468 if !strings.EqualFold(strings.ToUpper(origin_dir), strings.ToUpper(oldChkStr)) { 469 t.Error("do not get the expected folder ", oldChkStr, origin_dir) 470 } 471 472 taskrun.RunTargets("sub_a", true) 473 expected := "testcase_run_check_7725569sjghfghf" 474 current := taskrun.GetPH("RUN.sub_a.LOG.LAST") 475 if current != expected { 476 t.Error("we expected file content from test.txt in subfolder sub_a which is ", expected, " but got ", current) 477 } 478 479 newDir, nerr := dirhandle.Current() 480 if nerr != nil { 481 t.Error(derr) 482 } 483 484 if newDir != old { 485 t.Error("directory have to beeing set back to old dir after rinning task with a workingdir. but we are still at ", newDir) 486 } 487 488 }) 489 } 490 491 func TestStringMatcher(t *testing.T) { 492 // positive expectations 493 if !taskrun.StringMatchTest("=test", "test") { 494 t.Error("expect TRUE, =test should match with test") 495 } 496 497 if !taskrun.StringMatchTest("test", "test") { 498 t.Error("expect TRUE, test should not match with test") 499 } 500 501 if !taskrun.StringMatchTest(">50", "51") { 502 t.Error("expect TRUE, 51 should accepted as greater then 50") 503 } 504 505 if !taskrun.StringMatchTest("<50", "49") { 506 t.Error("expect TRUE, 49 should accepted as lower then 50") 507 } 508 if !taskrun.StringMatchTest("?", "something") { 509 t.Error("expect TRUE, ? should match with anything") 510 } 511 512 // negative tests result expected 513 if taskrun.StringMatchTest("=test", "test2") { 514 t.Error("expect FALSE, =test should not match with test2") 515 } 516 517 if taskrun.StringMatchTest("!test", "test") { 518 t.Error("expect FALSE, !test should (not) match with test by condition") 519 } 520 521 if taskrun.StringMatchTest(">test20", "test15") { 522 t.Error("expect FALSE, test20 is greater then test15") 523 } 524 525 if taskrun.StringMatchTest("<test20", "test35") { 526 t.Error("expect FALSE, test20 is lower then test35") 527 } 528 529 if taskrun.StringMatchTest("", "something") { 530 t.Error("expect FALSE, empty should not match") 531 } 532 533 if !taskrun.StringMatchTest("", "") { 534 t.Error("expect TRUE, empty should match to empty") 535 } 536 537 if taskrun.StringMatchTest("*", "") { 538 t.Error("expect FALSE, not-empty (*) placeholder should not match with empty") 539 } 540 541 if !taskrun.StringMatchTest("*", "something") { 542 t.Error("expect TRUE, not-empty placeholder should match with something") 543 } 544 } 545 546 func TestNeedWithArgs(t *testing.T) { 547 folderRunner("./../../docs/test/needWArgs", t, func(t *testing.T) { 548 taskrun.RunTargets("test-need", false) 549 550 }) 551 } 552 553 func TestJsonExec(t *testing.T) { 554 folderRunner("./../../docs/test/execjson", t, func(t *testing.T) { 555 taskrun.RunTargets("test-load", false) 556 found, json := taskrun.GetData("JSON") 557 if !found { 558 t.Error("expected to find JSON data") 559 } else { 560 if _, ok := json["0"]; !ok { 561 t.Error("expected to find key 0 in JSON data") 562 } 563 } 564 565 lastLogLine := taskrun.GetPH("RUN.test-load.LOG.LAST") 566 if lastLogLine != "buildkit.dockerfile.v0" { 567 t.Error("expected to find buildkit.dockerfile.v0 in log") 568 } 569 }) 570 } 571 572 func TestConcurrent(t *testing.T) { 573 expected := "" 574 folderRunner("./../../docs/test/01concurrent", t, func(t *testing.T) { 575 taskrun.RunTargets("main_a", false) 576 main_a := taskrun.GetPH("teststr") 577 expected = "BASE:MA:" 578 if main_a != expected { 579 t.Error("expected:", expected, " instead:", main_a) 580 } 581 }) 582 } 583 584 func TestConcurrentMainB(t *testing.T) { 585 var test TestRuntimeGroup = TestRuntimeGroup{ 586 []RuntimeGroupExpected{ 587 { 588 Contains: []string{"BASE"}, 589 }, 590 { 591 Contains: []string{"NB", "NA", "NC"}, 592 }, 593 { 594 Contains: []string{"MB"}, 595 }, 596 }, 597 } 598 assertRuntimeGroup(t, "./../../docs/test/01concurrent", "main_b", test) 599 } 600 601 func TestConcurrentMainC(t *testing.T) { 602 var test TestRuntimeGroup = TestRuntimeGroup{ 603 []RuntimeGroupExpected{ 604 { 605 Contains: []string{"BASE"}, // base fiirst at all 606 }, 607 { 608 Contains: []string{"NB", "NA", "NC"}, // needs as second 609 }, 610 { 611 Contains: []string{"MC", "TC", "TA", "TB"}, //anything else at the end unordered MC:TC:TA:TB: 612 }, 613 }, 614 } 615 assertRuntimeGroup(t, "./../../docs/test/01concurrent", "main_c", test) 616 } 617 618 func TestConcurrentMainD(t *testing.T) { 619 // BASE:NB:MC:TC:NA:TA:TB:NC:MD: 620 /* 621 - id: main_d 622 needs: 623 - need_a 624 - main_c 625 - need_c 626 script: 627 - "#@add teststr MD:" 628 - echo ${teststr} 629 */ 630 var test TestRuntimeGroup = TestRuntimeGroup{ 631 []RuntimeGroupExpected{ 632 { 633 Contains: []string{"BASE"}, // base first at all 634 }, 635 { 636 Contains: []string{"NB"}, // need b first as it is a need of main_c 637 }, 638 { 639 Contains: []string{"MC", "NC", "NA", "TC", "TA", "TB"}, //anything else at the end unordered 640 }, 641 { 642 Contains: []string{"MD"}, // the last is main_d 643 }, 644 }, 645 } 646 647 // have to investigate why, but on windows 648 // the order of execution seems different. 649 // but the imortant order seems beeing intact 650 if configure.GetOs() == "windows" { 651 test = TestRuntimeGroup{ 652 []RuntimeGroupExpected{ 653 { 654 Contains: []string{"BASE"}, // base first at all 655 }, 656 { 657 Contains: []string{"NB", "MC", "NC", "NA", "TC", "TA", "TB"}, //anything else at the end unordered 658 }, 659 { 660 Contains: []string{"MD"}, // the last is main_d 661 }, 662 }, 663 } 664 } 665 666 assertRuntimeGroup(t, "./../../docs/test/01concurrent", "main_d", test) 667 }