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  }