gitee.com/mirrors/gauge@v1.0.6/cmd/run_test.go (about) 1 package cmd 2 3 import ( 4 "bytes" 5 "fmt" 6 "os" 7 "os/exec" 8 "path/filepath" 9 "testing" 10 11 "github.com/getgauge/gauge/gauge" 12 13 "github.com/getgauge/gauge/execution" 14 "github.com/getgauge/gauge/execution/rerun" 15 16 "github.com/spf13/pflag" 17 18 "reflect" 19 20 "github.com/getgauge/gauge/config" 21 "github.com/spf13/cobra" 22 ) 23 24 var projectPath = "" 25 26 func before() { 27 projectPath, _ = filepath.Abs("_testData") 28 config.ProjectRoot = projectPath 29 } 30 31 func after() { 32 os.RemoveAll(projectPath) 33 } 34 35 func TestMain(m *testing.M) { 36 before() 37 runTests := m.Run() 38 after() 39 os.Exit(runTests) 40 } 41 42 func TestSaveCommandArgs(t *testing.T) { 43 if os.Getenv("TEST_EXITS") == "1" { 44 args := []string{"gauge", "run", "specs"} 45 46 rerun.WritePrevArgs(args) 47 48 prevArgs := rerun.ReadPrevArgs() 49 if !reflect.DeepEqual(prevArgs, args) { 50 fmt.Printf("Expected %v Got %v\n", args, prevArgs) 51 os.Exit(1) 52 } 53 return 54 } 55 cmd := exec.Command(os.Args[0], fmt.Sprintf("-test.run=%s", t.Name())) 56 cmd.Env = subEnv() 57 err := cmd.Run() 58 if err != nil { 59 t.Fatalf("process ran with err %v, want exit status 0", err) 60 } 61 } 62 63 func TestExecuteWritesPrevCommandArgs(t *testing.T) { 64 if os.Getenv("TEST_EXITS") == "1" { 65 args := []string{"gauge", "run", "specs"} 66 67 installPlugins = false 68 execution.ExecuteSpecs = func(s []string) int { return 0 } 69 cmd := &cobra.Command{} 70 71 os.Args = args 72 execute(cmd, args) 73 prevArgs := rerun.ReadPrevArgs() 74 if !reflect.DeepEqual(prevArgs, args) { 75 fmt.Printf("Expected %v Got %v\n", args, prevArgs) 76 os.Exit(1) 77 } 78 return 79 } 80 cmd := exec.Command(os.Args[0], fmt.Sprintf("-test.run=%s", t.Name())) 81 cmd.Env = subEnv() 82 err := cmd.Run() 83 if err != nil { 84 t.Fatalf("process ran with err %v, want exit status 0", err) 85 } 86 } 87 88 func TestRepeatShouldPreservePreviousArgs(t *testing.T) { 89 if os.Getenv("TEST_EXITS") == "1" { 90 cmd := &cobra.Command{} 91 92 var called bool 93 rerun.WritePrevArgs = func(x []string) { 94 called = true 95 } 96 rerun.ReadPrevArgs = func() []string { 97 return []string{"gauge", "run", "specs", "-l", "debug"} 98 } 99 installPlugins = false 100 repeatLastExecution(cmd) 101 102 if called { 103 panic("Unexpected call to writePrevArgs while repeat") 104 } 105 return 106 } 107 cmd := exec.Command(os.Args[0], fmt.Sprintf("-test.run=%s", t.Name())) 108 cmd.Env = subEnv() 109 err := cmd.Run() 110 if err != nil { 111 t.Fatalf("process ran with err %v, want exit status 0", err) 112 } 113 } 114 115 func TestSaveCommandArgsForFailed(t *testing.T) { 116 if os.Getenv("TEST_EXITS") == "1" { 117 execution.ExecuteSpecs = func(s []string) int { return 0 } 118 rerun.GetLastFailedState = func() ([]string, error) { 119 return []string{"run", "specs"}, nil 120 } 121 var args = []string{"gauge", "run", "--failed"} 122 123 rerun.WritePrevArgs = func(a []string) { 124 if !reflect.DeepEqual(a, args) { 125 panic(fmt.Sprintf("Expected %v Got %v", args, a)) 126 } 127 } 128 129 os.Args = args 130 executeFailed(runCmd) 131 return 132 } 133 134 cmd := exec.Command(os.Args[0], fmt.Sprintf("-test.run=%s", t.Name())) 135 cmd.Env = subEnv() 136 err := cmd.Run() 137 if err != nil { 138 t.Fatalf("process ran with err %v, want exit status 0", err) 139 } 140 } 141 142 func TestHandleConflictingParamsWithOtherArguments(t *testing.T) { 143 if os.Getenv("TEST_EXITS") == "1" { 144 args := []string{"specs"} 145 146 var flags = pflag.FlagSet{} 147 flags.BoolP("repeat", "r", false, "") 148 flags.Set("repeat", "true") 149 150 repeat = true 151 expectedErrorMessage := "Invalid Command. Usage: gauge run --repeat" 152 err := handleConflictingParams(&flags, args) 153 154 if !reflect.DeepEqual(err.Error(), expectedErrorMessage) { 155 fmt.Printf("Expected %v Got %v\n", expectedErrorMessage, err) 156 panic("assert failed") 157 } 158 return 159 } 160 var stdout bytes.Buffer 161 cmd := exec.Command(os.Args[0], fmt.Sprintf("-test.run=%s", t.Name())) 162 cmd.Env = subEnv() 163 cmd.Stdout = &stdout 164 err := cmd.Run() 165 if err != nil { 166 t.Fatalf("process ran with err %v, want exit status 0. Stdout:\n%s", err, stdout.Bytes()) 167 } 168 } 169 170 func TestHandleConflictingParamsWithOtherFlags(t *testing.T) { 171 args := []string{} 172 173 var flags = pflag.FlagSet{} 174 flags.BoolP("repeat", "r", false, "") 175 flags.Set("repeat", "true") 176 177 flags.StringP("tags", "", "", "") 178 flags.Set("tags", "abcd") 179 180 repeat = true 181 expectedErrorMessage := "Invalid Command. Usage: gauge run --repeat" 182 err := handleConflictingParams(&flags, args) 183 184 if !reflect.DeepEqual(err.Error(), expectedErrorMessage) { 185 t.Errorf("Expected %v Got %v", expectedErrorMessage, err) 186 } 187 } 188 189 func TestHandleConflictingParamsWithJustRepeatFlag(t *testing.T) { 190 args := []string{} 191 192 var flags = pflag.FlagSet{} 193 flags.BoolP("repeat", "r", false, "") 194 flags.Set("repeat", "true") 195 196 repeat = true 197 err := handleConflictingParams(&flags, args) 198 199 if err != nil { 200 t.Errorf("Expected %v Got %v", nil, err.Error()) 201 } 202 } 203 204 func TestHandleRerunFlagsWithVerbose(t *testing.T) { 205 if os.Getenv("TEST_EXITS") == "1" { 206 cmd := &cobra.Command{} 207 208 cmd.Flags().BoolP(verboseName, "v", verboseDefault, "Enable step level reporting on console, default being scenario level") 209 cmd.Flags().BoolP(simpleConsoleName, "", simpleConsoleDefault, "Removes colouring and simplifies the console output") 210 cmd.Flags().StringP(environmentName, "e", environmentDefault, "Specifies the environment to use") 211 cmd.Flags().StringP(tagsName, "t", tagsDefault, "Executes the specs and scenarios tagged with given tags") 212 cmd.Flags().StringP(rowsName, "r", rowsDefault, "Executes the specs and scenarios only for the selected rows. It can be specified by range as 2-4 or as list 2,4") 213 cmd.Flags().BoolP(parallelName, "p", parallelDefault, "Execute specs in parallel") 214 cmd.Flags().IntP(streamsName, "n", streamsDefault, "Specify number of parallel execution streams") 215 cmd.Flags().IntP(groupName, "g", groupDefault, "Specify which group of specification to execute based on -n flag") 216 cmd.Flags().StringP(strategyName, "", strategyDefault, "Set the parallelization strategy for execution. Possible options are: `eager`, `lazy`") 217 cmd.Flags().BoolP(sortName, "s", sortDefault, "Run specs in Alphabetical Order") 218 cmd.Flags().BoolP(installPluginsName, "i", installPluginsDefault, "Install All Missing Plugins") 219 cmd.Flags().BoolP(failedName, "f", failedDefault, "Run only the scenarios failed in previous run. This is an exclusive flag, it cannot be used in conjunction with any other argument") 220 cmd.Flags().BoolP(repeatName, "", repeatDefault, "Repeat last run. This is an exclusive flag, it cannot be used in conjunction with any other argument") 221 cmd.Flags().BoolP(hideSuggestionName, "", hideSuggestionDefault, "Prints a step implementation stub for every unimplemented step") 222 cmd.Flags().Set(repeatName, "true") 223 cmd.Flags().Set(verboseName, "true") 224 225 handleFlags(cmd, []string{"--repeat", "--verbose"}) 226 overridenFlagValue := cmd.Flag(verboseName).Value.String() 227 expectedFlag := "true" 228 229 if !reflect.DeepEqual(overridenFlagValue, expectedFlag) { 230 fmt.Printf("Expected %v Got %v\n", expectedFlag, overridenFlagValue) 231 os.Exit(1) 232 } 233 return 234 } 235 var stdout bytes.Buffer 236 cmd := exec.Command(os.Args[0], fmt.Sprintf("-test.run=%s", t.Name())) 237 cmd.Env = subEnv() 238 cmd.Stdout = &stdout 239 err := cmd.Run() 240 if err != nil { 241 t.Fatalf("process ran with err %v, want exit status 0. Stdout:\n%s", err, stdout.Bytes()) 242 } 243 } 244 245 func TestHandleFailedCommandForNonGaugeProject(t *testing.T) { 246 if os.Getenv("TEST_EXITS") == "1" { 247 config.ProjectRoot = "" 248 currDir, _ := os.Getwd() 249 defer os.Chdir(currDir) 250 testdir := filepath.Join(currDir, "dotGauge") 251 dotgaugeDir := filepath.Join(testdir, ".gauge") 252 os.Chdir(testdir) 253 exit = func(err error, i string) { 254 if _, e := os.Stat(dotgaugeDir); os.IsExist(e) { 255 panic("Folder .gauge is created") 256 } 257 os.Exit(0) 258 } 259 260 os.Args = []string{"gauge", "run", "-f"} 261 262 runCmd.Execute() 263 return 264 } 265 cmd := exec.Command(os.Args[0], fmt.Sprintf("-test.run=%s", t.Name())) 266 cmd.Env = subEnv() 267 err := cmd.Run() 268 if err != nil { 269 t.Fatalf("process ran with err %v, want exit status 0", err) 270 } 271 } 272 273 func TestHandleConflictingParamsWithLogLevelFlag(t *testing.T) { 274 args := []string{} 275 var flags = pflag.FlagSet{} 276 277 flags.StringP("log-level", "l", "info", "") 278 flags.Set("log-level", "debug") 279 280 flags.BoolP("repeat", "r", false, "") 281 flags.Set("repeat", "true") 282 repeat = true 283 284 err := handleConflictingParams(&flags, args) 285 286 if err != nil { 287 t.Errorf("Expected %v Got %v", nil, err.Error()) 288 } 289 } 290 291 func TestNoExitCodeShouldForceReturnZero(t *testing.T) { 292 if os.Getenv("TEST_EXITS") == "1" { 293 installPlugins = false 294 // simulate failure 295 execution.ExecuteSpecs = func(s []string) int { return execution.ExecutionFailed } 296 297 os.Args = []string{"gauge", "run", "--fail-safe", "specs"} 298 299 failSafe = true 300 runCmd.Execute() 301 return 302 } 303 var stdout bytes.Buffer 304 cmd := exec.Command(os.Args[0], fmt.Sprintf("-test.run=%s", t.Name())) 305 cmd.Env = subEnv() 306 cmd.Stdout = &stdout 307 err := cmd.Run() 308 if err != nil { 309 t.Fatalf("%s process ran with err %v, want exit status 0. Stdout:\n%s", os.Args, err, stdout.Bytes()) 310 } 311 } 312 313 func TestFailureShouldReturnExitCodeForParseErrors(t *testing.T) { 314 if os.Getenv("TEST_EXITS") == "1" { 315 // simulate parse failure 316 execution.ExecuteSpecs = func(s []string) int { return execution.ParseFailed } 317 318 os.Args = []string{"gauge", "run", "--fail-safe", "specs"} 319 failSafe = true 320 runCmd.Execute() 321 } 322 323 cmd := exec.Command(os.Args[0], fmt.Sprintf("-test.run=%s", t.Name())) 324 cmd.Env = append(os.Environ(), "TEST_EXITS=1") 325 err := cmd.Run() 326 if e, ok := err.(*exec.ExitError); ok && !e.Success() { 327 return 328 } 329 t.Fatalf("process ran with err %v, want exit status 2", err) 330 } 331 332 func TestFailureShouldReturnExitCode(t *testing.T) { 333 if os.Getenv("TEST_EXITS") == "1" { 334 // simulate execution failure 335 execution.ExecuteSpecs = func(s []string) int { return execution.ExecutionFailed } 336 os.Args = []string{"gauge", "run", "specs"} 337 runCmd.Execute() 338 } 339 340 var stdout bytes.Buffer 341 cmd := exec.Command(os.Args[0], fmt.Sprintf("-test.run=%s", t.Name())) 342 cmd.Env = subEnv() 343 cmd.Stdout = &stdout 344 err := cmd.Run() 345 if e, ok := err.(*exec.ExitError); ok && !e.Success() { 346 return 347 } 348 t.Fatalf("process ran with err %v, want exit status 1. Stdout:\n%s", err, stdout.Bytes()) 349 } 350 351 func TestLogLevelCanBeOverriddenForFailed(t *testing.T) { 352 if os.Getenv("TEST_EXITS") == "1" { 353 // expect log level to be overridden 354 execution.ExecuteSpecs = func(s []string) int { 355 f, err := runCmd.Flags().GetString(logLevelName) 356 if err != nil { 357 fmt.Printf("Error parsing flags. %s\n", err.Error()) 358 panic(err) 359 } 360 if f != "info" { 361 fmt.Printf("Expecting log-level=info, got %s\n", f) 362 panic("assert failure") 363 } 364 return 0 365 } 366 367 rerun.ReadPrevArgs = func() []string { 368 return []string{"gauge", "run", "specs", "-l", "debug"} 369 } 370 os.Args = []string{"gauge", "run", "--failed", "-l", "info"} 371 os.MkdirAll(filepath.Join(projectPath, ".gauge"), 0755) 372 file, err := os.OpenFile(filepath.Join(projectPath, ".gauge", "failures.json"), os.O_CREATE|os.O_WRONLY, 0644) 373 _, err = file.Write([]byte("{\"Args\": [\"run\",\"-v\"],\"FailedItems\": [\"specs\"]}")) 374 if err != nil { 375 fmt.Println(err) 376 } 377 file.Close() 378 executeFailed(runCmd) 379 return 380 } 381 var stdout bytes.Buffer 382 cmd := exec.Command(os.Args[0], fmt.Sprintf("-test.run=%s", t.Name())) 383 cmd.Env = subEnv() 384 cmd.Stdout = &stdout 385 err := cmd.Run() 386 if err != nil { 387 t.Fatalf("process ran with err %v, want exit status 0.Stdout:\n%s", err, stdout.Bytes()) 388 } 389 } 390 391 func TestLogLevelCanBeOverriddenForRepeat(t *testing.T) { 392 if os.Getenv("TEST_EXITS") == "1" { 393 // expect log level to be overridden 394 execution.ExecuteSpecs = func(s []string) int { 395 f, err := runCmd.Flags().GetString(logLevelName) 396 if err != nil { 397 fmt.Printf("Error parsing flags. %s\n", err.Error()) 398 panic(err) 399 } 400 if f != "info" { 401 fmt.Printf("Expecting log-level=info, got %s\n", f) 402 panic("assert failure") 403 } 404 return 0 405 } 406 407 rerun.ReadPrevArgs = func() []string { 408 return []string{"gauge", "run", "specs", "-l=debug"} 409 } 410 os.Args = []string{"gauge", "run", "--failed", "-l=info"} 411 runCmd.ParseFlags(os.Args) 412 repeatLastExecution(runCmd) 413 return 414 } 415 var stdout bytes.Buffer 416 cmd := exec.Command(os.Args[0], fmt.Sprintf("-test.run=%s", t.Name()), "-test.v") 417 cmd.Env = subEnv() 418 cmd.Stdout = &stdout 419 err := cmd.Run() 420 if err != nil { 421 t.Fatalf("process ran with err %v, want exit status 0.Stdout:\n%s", err, stdout.Bytes()) 422 } 423 } 424 425 func TestCorrectFlagsAreSetForRepeat(t *testing.T) { 426 if os.Getenv("TEST_EXITS") == "1" { 427 // expect "env" to be set to "test" 428 os.MkdirAll(filepath.Join(projectPath, "env", "test"), 0755) 429 execution.ExecuteSpecs = func(s []string) int { 430 f, err := runCmd.Flags().GetString(environmentName) 431 if err != nil { 432 fmt.Printf("Error parsing flags. %s\n", err.Error()) 433 panic(err) 434 } 435 if f != "test" { 436 fmt.Printf("Expecting env=test, got %s\n", f) 437 panic("assert failure") 438 } 439 return 0 440 } 441 442 rerun.ReadPrevArgs = func() []string { 443 return []string{"gauge", "run", "specs", "--env=test"} 444 } 445 os.Args = []string{"gauge", "run", "--failed"} 446 runCmd.ParseFlags(os.Args) 447 repeatLastExecution(runCmd) 448 return 449 } 450 var stdout bytes.Buffer 451 cmd := exec.Command(os.Args[0], fmt.Sprintf("-test.run=%s", t.Name())) 452 cmd.Env = subEnv() 453 cmd.Stdout = &stdout 454 err := cmd.Run() 455 if err != nil { 456 t.Fatalf("process ran with err %v, want exit status 0.Stdout:\n%s", err, stdout.Bytes()) 457 } 458 } 459 460 func TestCorrectFlagsAreSetForFailed(t *testing.T) { 461 if os.Getenv("TEST_EXITS") == "1" { 462 // expect "env" to be set to "test" 463 execution.ExecuteSpecs = func(s []string) int { 464 f, err := runCmd.Flags().GetString(environmentName) 465 if err != nil { 466 fmt.Printf("Error parsing flags. %s\n", err.Error()) 467 panic(err) 468 } 469 if f != "test" { 470 fmt.Printf("Expecting env=test, got %s\n", f) 471 panic("assert failure") 472 } 473 return 0 474 } 475 476 rerun.GetLastFailedState = func() ([]string, error) { 477 return []string{"run", "specs", "--env=test"}, nil 478 } 479 os.Args = []string{"gauge", "run", "--failed"} 480 executeFailed(runCmd) 481 return 482 } 483 var stdout bytes.Buffer 484 cmd := exec.Command(os.Args[0], fmt.Sprintf("-test.run=%s", t.Name()), "-test.v") 485 cmd.Env = subEnv() 486 cmd.Stdout = &stdout 487 err := cmd.Run() 488 if err != nil { 489 t.Fatalf("process ran with err %v, want exit status 0.Stdout:\n%s", err, stdout.Bytes()) 490 } 491 } 492 493 func subEnv() []string { 494 return append(os.Environ(), []string{"TEST_EXITS=1", "GAUGE_PLUGIN_INSTALL=false"}...) 495 } 496 497 func TestAddingFlagsToExecutionArgs(t *testing.T) { 498 var flags = &pflag.FlagSet{} 499 flags.BoolP("parallel", "p", false, "") 500 flags.Set("parallel", "true") 501 502 execution.ExecutionArgs = []*gauge.ExecutionArg{} 503 addFlagsToExecutionArgs(flags) 504 if execution.ExecutionArgs[0].Name != "parallel" { 505 t.Fatalf("Expecting execution arg name parallel but found %s", execution.ExecutionArgs[0].Name) 506 } 507 if execution.ExecutionArgs[0].Value[0] != "true" { 508 t.Fatalf("Expecting execution arg value true but found %s", execution.ExecutionArgs[0].Value[0]) 509 } 510 } 511 512 func TestAddingMultipleFlagsToExecutionArgs(t *testing.T) { 513 var flags = &pflag.FlagSet{} 514 flags.BoolP("parallel", "p", false, "") 515 flags.Set("parallel", "true") 516 flags.StringP("tags", "", "", "") 517 flags.Set("tags", "tag1") 518 519 execution.ExecutionArgs = []*gauge.ExecutionArg{} 520 addFlagsToExecutionArgs(flags) 521 522 if execution.ExecutionArgs[0].Name != "parallel" { 523 t.Fatalf("Expecting execution arg name parallel but found %s", execution.ExecutionArgs[0].Name) 524 } 525 if execution.ExecutionArgs[1].Name != "tags" { 526 t.Fatalf("Expecting execution arg name tags but found %s", execution.ExecutionArgs[1].Name) 527 } 528 if execution.ExecutionArgs[1].Value[0] != "tag1" { 529 t.Fatalf("Expecting execution arg value tag1 but found %s", execution.ExecutionArgs[1].Value[0]) 530 } 531 }