github.com/yaman/gauge@v0.1.1-0.20181130223501-7b7ae34faf33/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/execution" 12 "github.com/getgauge/gauge/execution/rerun" 13 14 "github.com/spf13/pflag" 15 16 "reflect" 17 18 "github.com/getgauge/gauge/config" 19 "github.com/spf13/cobra" 20 ) 21 22 var path = "" 23 24 func before() { 25 path, _ = filepath.Abs("_testData") 26 config.ProjectRoot = path 27 } 28 29 func after() { 30 os.RemoveAll(path) 31 } 32 33 func TestMain(m *testing.M) { 34 before() 35 runTests := m.Run() 36 after() 37 os.Exit(runTests) 38 } 39 40 func TestSaveCommandArgs(t *testing.T) { 41 if os.Getenv("TEST_EXITS") == "1" { 42 args := []string{"gauge", "run", "specs"} 43 44 writePrevArgs(args) 45 46 prevArgs := readPrevArgs() 47 if !reflect.DeepEqual(prevArgs, args) { 48 fmt.Printf("Expected %v Got %v\n", args, prevArgs) 49 os.Exit(1) 50 } 51 return 52 } 53 cmd := exec.Command(os.Args[0], fmt.Sprintf("-test.run=%s", t.Name())) 54 cmd.Env = subEnv() 55 err := cmd.Run() 56 if err != nil { 57 t.Fatalf("process ran with err %v, want exit status 0", err) 58 } 59 } 60 61 func TestExecuteWritesPrevCommandArgs(t *testing.T) { 62 if os.Getenv("TEST_EXITS") == "1" { 63 args := []string{"gauge", "run", "specs"} 64 65 installPlugins = false 66 execution.ExecuteSpecs = func(s []string) int { return 0 } 67 cmd := &cobra.Command{} 68 69 os.Args = args 70 execute(cmd, args) 71 prevArgs := readPrevArgs() 72 if !reflect.DeepEqual(prevArgs, args) { 73 fmt.Printf("Expected %v Got %v\n", args, prevArgs) 74 os.Exit(1) 75 } 76 return 77 } 78 cmd := exec.Command(os.Args[0], fmt.Sprintf("-test.run=%s", t.Name())) 79 cmd.Env = subEnv() 80 err := cmd.Run() 81 if err != nil { 82 t.Fatalf("process ran with err %v, want exit status 0", err) 83 } 84 } 85 86 func TestRepeatShouldPreservePreviousArgs(t *testing.T) { 87 if os.Getenv("TEST_EXITS") == "1" { 88 cmd := &cobra.Command{} 89 90 var called bool 91 writePrevArgs = func(x []string) { 92 called = true 93 } 94 readPrevArgs = func() []string { 95 return []string{"gauge", "run", "specs", "-l", "debug"} 96 } 97 installPlugins = false 98 repeatLastExecution(cmd) 99 100 if called { 101 panic("Unexpected call to writePrevArgs while repeat") 102 } 103 return 104 } 105 cmd := exec.Command(os.Args[0], fmt.Sprintf("-test.run=%s", t.Name())) 106 cmd.Env = subEnv() 107 err := cmd.Run() 108 if err != nil { 109 t.Fatalf("process ran with err %v, want exit status 0", err) 110 } 111 } 112 113 func TestSaveCommandArgsForFailed(t *testing.T) { 114 if os.Getenv("TEST_EXITS") == "1" { 115 execution.ExecuteSpecs = func(s []string) int { return 0 } 116 rerun.GetLastState = func() ([]string, error) { 117 return []string{"run", "specs"}, nil 118 } 119 var args = []string{"gauge", "run", "--failed"} 120 121 writePrevArgs = func(a []string) { 122 if !reflect.DeepEqual(a, args) { 123 panic(fmt.Sprintf("Expected %v Got %v", args, a)) 124 } 125 } 126 127 os.Args = args 128 executeFailed(runCmd) 129 return 130 } 131 132 cmd := exec.Command(os.Args[0], fmt.Sprintf("-test.run=%s", t.Name())) 133 cmd.Env = subEnv() 134 err := cmd.Run() 135 if err != nil { 136 t.Fatalf("process ran with err %v, want exit status 0", err) 137 } 138 } 139 140 func TestHandleConflictingParamsWithOtherArguments(t *testing.T) { 141 if os.Getenv("TEST_EXITS") == "1" { 142 args := []string{"specs"} 143 144 var flags = pflag.FlagSet{} 145 flags.BoolP("repeat", "r", false, "") 146 flags.Set("repeat", "true") 147 148 repeat = true 149 expectedErrorMessage := "Invalid Command. Usage: gauge run --repeat" 150 err := handleConflictingParams(&flags, args) 151 152 if !reflect.DeepEqual(err.Error(), expectedErrorMessage) { 153 fmt.Printf("Expected %v Got %v\n", expectedErrorMessage, err) 154 panic("assert failed") 155 } 156 return 157 } 158 var stdout bytes.Buffer 159 cmd := exec.Command(os.Args[0], fmt.Sprintf("-test.run=%s", t.Name())) 160 cmd.Env = subEnv() 161 cmd.Stdout = &stdout 162 err := cmd.Run() 163 if err != nil { 164 t.Fatalf("process ran with err %v, want exit status 0. Stdout:\n%s", err, stdout.Bytes()) 165 } 166 } 167 168 func TestHandleConflictingParamsWithOtherFlags(t *testing.T) { 169 args := []string{} 170 171 var flags = pflag.FlagSet{} 172 flags.BoolP("repeat", "r", false, "") 173 flags.Set("repeat", "true") 174 175 flags.StringP("tags", "", "", "") 176 flags.Set("tags", "abcd") 177 178 repeat = true 179 expectedErrorMessage := "Invalid Command. Usage: gauge run --repeat" 180 err := handleConflictingParams(&flags, args) 181 182 if !reflect.DeepEqual(err.Error(), expectedErrorMessage) { 183 t.Errorf("Expected %v Got %v", expectedErrorMessage, err) 184 } 185 } 186 187 func TestHandleConflictingParamsWithJustRepeatFlag(t *testing.T) { 188 args := []string{} 189 190 var flags = pflag.FlagSet{} 191 flags.BoolP("repeat", "r", false, "") 192 flags.Set("repeat", "true") 193 194 repeat = true 195 err := handleConflictingParams(&flags, args) 196 197 if err != nil { 198 t.Errorf("Expected %v Got %v", nil, err.Error()) 199 } 200 } 201 202 func TestHandleRerunFlagsWithVerbose(t *testing.T) { 203 if os.Getenv("TEST_EXITS") == "1" { 204 cmd := &cobra.Command{} 205 206 cmd.Flags().BoolP(verboseName, "v", verboseDefault, "Enable step level reporting on console, default being scenario level") 207 cmd.Flags().BoolP(simpleConsoleName, "", simpleConsoleDefault, "Removes colouring and simplifies the console output") 208 cmd.Flags().StringP(environmentName, "e", environmentDefault, "Specifies the environment to use") 209 cmd.Flags().StringP(tagsName, "t", tagsDefault, "Executes the specs and scenarios tagged with given tags") 210 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") 211 cmd.Flags().BoolP(parallelName, "p", parallelDefault, "Execute specs in parallel") 212 cmd.Flags().IntP(streamsName, "n", streamsDefault, "Specify number of parallel execution streams") 213 cmd.Flags().IntP(groupName, "g", groupDefault, "Specify which group of specification to execute based on -n flag") 214 cmd.Flags().StringP(strategyName, "", strategyDefault, "Set the parallelization strategy for execution. Possible options are: `eager`, `lazy`") 215 cmd.Flags().BoolP(sortName, "s", sortDefault, "Run specs in Alphabetical Order") 216 cmd.Flags().BoolP(installPluginsName, "i", installPluginsDefault, "Install All Missing Plugins") 217 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") 218 cmd.Flags().BoolP(repeatName, "", repeatDefault, "Repeat last run. This is an exclusive flag, it cannot be used in conjunction with any other argument") 219 cmd.Flags().BoolP(hideSuggestionName, "", hideSuggestionDefault, "Prints a step implementation stub for every unimplemented step") 220 cmd.Flags().Set(repeatName, "true") 221 cmd.Flags().Set(verboseName, "true") 222 223 handleFlags(cmd, []string{"--repeat", "--verbose"}) 224 overridenFlagValue := cmd.Flag(verboseName).Value.String() 225 expectedFlag := "true" 226 227 if !reflect.DeepEqual(overridenFlagValue, expectedFlag) { 228 fmt.Printf("Expected %v Got %v\n", expectedFlag, overridenFlagValue) 229 os.Exit(1) 230 } 231 return 232 } 233 var stdout bytes.Buffer 234 cmd := exec.Command(os.Args[0], fmt.Sprintf("-test.run=%s", t.Name())) 235 cmd.Env = subEnv() 236 cmd.Stdout = &stdout 237 err := cmd.Run() 238 if err != nil { 239 t.Fatalf("process ran with err %v, want exit status 0. Stdout:\n%s", err, stdout.Bytes()) 240 } 241 } 242 243 func TestHandleFailedCommandForNonGaugeProject(t *testing.T) { 244 if os.Getenv("TEST_EXITS") == "1" { 245 config.ProjectRoot = "" 246 currDir, _ := os.Getwd() 247 defer os.Chdir(currDir) 248 testdir := filepath.Join(currDir, "dotGauge") 249 dotgaugeDir := filepath.Join(testdir, ".gauge") 250 os.Chdir(testdir) 251 exit = func(err error, i string) { 252 if _, e := os.Stat(dotgaugeDir); os.IsExist(e) { 253 panic("Folder .gauge is created") 254 } 255 os.Exit(0) 256 } 257 258 os.Args = []string{"gauge", "run", "-f"} 259 260 runCmd.Execute() 261 return 262 } 263 cmd := exec.Command(os.Args[0], fmt.Sprintf("-test.run=%s", t.Name())) 264 cmd.Env = subEnv() 265 err := cmd.Run() 266 if err != nil { 267 t.Fatalf("process ran with err %v, want exit status 0", err) 268 } 269 } 270 271 func TestHandleConflictingParamsWithLogLevelFlag(t *testing.T) { 272 args := []string{} 273 var flags = pflag.FlagSet{} 274 275 flags.StringP("log-level", "l", "info", "") 276 flags.Set("log-level", "debug") 277 278 flags.BoolP("repeat", "r", false, "") 279 flags.Set("repeat", "true") 280 repeat = true 281 282 err := handleConflictingParams(&flags, args) 283 284 if err != nil { 285 t.Errorf("Expected %v Got %v", nil, err.Error()) 286 } 287 } 288 289 func TestNoExitCodeShouldForceReturnZero(t *testing.T) { 290 if os.Getenv("TEST_EXITS") == "1" { 291 installPlugins = false 292 // simulate failure 293 execution.ExecuteSpecs = func(s []string) int { return execution.ExecutionFailed } 294 295 os.Args = []string{"gauge", "run", "--fail-safe", "specs"} 296 297 failSafe = true 298 runCmd.Execute() 299 return 300 } 301 var stdout bytes.Buffer 302 cmd := exec.Command(os.Args[0], fmt.Sprintf("-test.run=%s", t.Name())) 303 cmd.Env = subEnv() 304 cmd.Stdout = &stdout 305 err := cmd.Run() 306 if err != nil { 307 t.Fatalf("%s process ran with err %v, want exit status 0. Stdout:\n%s", os.Args, err, stdout.Bytes()) 308 } 309 } 310 311 func TestFailureShouldReturnExitCodeForParseErrors(t *testing.T) { 312 if os.Getenv("TEST_EXITS") == "1" { 313 // simulate parse failure 314 execution.ExecuteSpecs = func(s []string) int { return execution.ParseFailed } 315 316 os.Args = []string{"gauge", "run", "--fail-safe", "specs"} 317 failSafe = true 318 runCmd.Execute() 319 } 320 321 cmd := exec.Command(os.Args[0], fmt.Sprintf("-test.run=%s", t.Name())) 322 cmd.Env = append(os.Environ(), "TEST_EXITS=1") 323 err := cmd.Run() 324 if e, ok := err.(*exec.ExitError); ok && !e.Success() { 325 return 326 } 327 t.Fatalf("process ran with err %v, want exit status 2", err) 328 } 329 330 func TestFailureShouldReturnExitCode(t *testing.T) { 331 if os.Getenv("TEST_EXITS") == "1" { 332 // simulate execution failure 333 execution.ExecuteSpecs = func(s []string) int { return execution.ExecutionFailed } 334 os.Args = []string{"gauge", "run", "specs"} 335 runCmd.Execute() 336 } 337 338 var stdout bytes.Buffer 339 cmd := exec.Command(os.Args[0], fmt.Sprintf("-test.run=%s", t.Name())) 340 cmd.Env = subEnv() 341 cmd.Stdout = &stdout 342 err := cmd.Run() 343 if e, ok := err.(*exec.ExitError); ok && !e.Success() { 344 return 345 } 346 t.Fatalf("process ran with err %v, want exit status 1. Stdout:\n%s", err, stdout.Bytes()) 347 } 348 349 func TestLogLevelCanBeOverriddenForFailed(t *testing.T) { 350 if os.Getenv("TEST_EXITS") == "1" { 351 // expect log level to be overridden 352 execution.ExecuteSpecs = func(s []string) int { 353 f, err := runCmd.Flags().GetString(logLevelName) 354 if err != nil { 355 fmt.Printf("Error parsing flags. %s\n", err.Error()) 356 panic(err) 357 } 358 if f != "info" { 359 fmt.Printf("Expecting log-level=info, got %s\n", f) 360 panic("assert failure") 361 } 362 return 0 363 } 364 365 readPrevArgs = func() []string { 366 return []string{"gauge", "run", "specs", "-l", "debug"} 367 } 368 os.Args = []string{"gauge", "run", "--failed", "-l", "info"} 369 executeFailed(runCmd) 370 return 371 } 372 var stdout bytes.Buffer 373 cmd := exec.Command(os.Args[0], fmt.Sprintf("-test.run=%s", t.Name())) 374 cmd.Env = subEnv() 375 cmd.Stdout = &stdout 376 err := cmd.Run() 377 if err != nil { 378 t.Fatalf("process ran with err %v, want exit status 0.Stdout:\n%s", err, stdout.Bytes()) 379 } 380 } 381 382 func TestLogLevelCanBeOverriddenForRepeat(t *testing.T) { 383 if os.Getenv("TEST_EXITS") == "1" { 384 // expect log level to be overridden 385 execution.ExecuteSpecs = func(s []string) int { 386 f, err := runCmd.Flags().GetString(logLevelName) 387 if err != nil { 388 fmt.Printf("Error parsing flags. %s\n", err.Error()) 389 panic(err) 390 } 391 if f != "info" { 392 fmt.Printf("Expecting log-level=info, got %s\n", f) 393 panic("assert failure") 394 } 395 return 0 396 } 397 398 rerun.GetLastState = func() ([]string, error) { 399 return []string{"gauge", "run", "specs", "-l", "debug"}, nil 400 } 401 os.Args = []string{"gauge", "run", "--failed", "-l", "info"} 402 repeatLastExecution(runCmd) 403 return 404 } 405 var stdout bytes.Buffer 406 cmd := exec.Command(os.Args[0], fmt.Sprintf("-test.run=%s", t.Name())) 407 cmd.Env = subEnv() 408 cmd.Stdout = &stdout 409 err := cmd.Run() 410 if err != nil { 411 t.Fatalf("process ran with err %v, want exit status 0.Stdout:\n%s", err, stdout.Bytes()) 412 } 413 } 414 415 func subEnv() []string { 416 return append(os.Environ(), []string{"TEST_EXITS=1", "GAUGE_PLUGIN_INSTALL=false"}...) 417 }