github.com/xgoffin/jenkins-library@v1.154.0/cmd/newmanExecute_test.go (about)

     1  package cmd
     2  
     3  import (
     4  	"path/filepath"
     5  	"strings"
     6  	"testing"
     7  
     8  	sliceUtils "github.com/SAP/jenkins-library/pkg/piperutils"
     9  	"github.com/pkg/errors"
    10  	"github.com/stretchr/testify/assert"
    11  )
    12  
    13  type executedExecutables struct {
    14  	executable string
    15  	params     []string
    16  }
    17  
    18  type newmanExecuteMockUtils struct {
    19  	// *mock.ExecMockRunner
    20  	// *mock.FilesMock
    21  	errorOnGlob            bool
    22  	errorOnNewmanInstall   bool
    23  	errorOnRunShell        bool
    24  	errorOnNewmanExecution bool
    25  	errorOnLoggingNode     bool
    26  	errorOnLoggingNpm      bool
    27  	executedExecutables    []executedExecutables
    28  	filesToFind            []string
    29  	commandIndex           int
    30  }
    31  
    32  func newNewmanExecuteMockUtils() newmanExecuteMockUtils {
    33  	return newmanExecuteMockUtils{
    34  		filesToFind: []string{"localFile.json", "localFile2.json"},
    35  	}
    36  }
    37  
    38  func TestRunNewmanExecute(t *testing.T) {
    39  	t.Parallel()
    40  
    41  	allFineConfig := newmanExecuteOptions{
    42  		NewmanCollection:     "**.json",
    43  		NewmanEnvironment:    "env.json",
    44  		NewmanGlobals:        "globals.json",
    45  		NewmanInstallCommand: "npm install newman --global --quiet",
    46  		NewmanRunCommand:     "run {{.NewmanCollection}} --environment {{.Config.NewmanEnvironment}} --globals {{.Config.NewmanGlobals}} --reporters junit,html --reporter-junit-export target/newman/TEST-{{.CollectionDisplayName}}.xml --reporter-html-export target/newman/TEST-{{.CollectionDisplayName}}.html",
    47  	}
    48  
    49  	t.Run("happy path", func(t *testing.T) {
    50  		t.Parallel()
    51  		// init
    52  
    53  		utils := newNewmanExecuteMockUtils()
    54  
    55  		// test
    56  		err := runNewmanExecute(&allFineConfig, &utils)
    57  
    58  		// assert
    59  		assert.NoError(t, err)
    60  		assert.Contains(t, utils.executedExecutables, executedExecutables{executable: "node", params: []string{"--version"}})
    61  		assert.Contains(t, utils.executedExecutables, executedExecutables{executable: "npm", params: []string{"--version"}})
    62  		assert.Contains(t, utils.executedExecutables, executedExecutables{executable: "npm", params: []string{"install", "newman", "--global", "--quiet", "--prefix=~/.npm-global"}})
    63  		assert.Contains(t, utils.executedExecutables, executedExecutables{executable: filepath.FromSlash("/home/node/.npm-global/bin/newman"), params: []string{"run", "localFile.json", "--environment", "env.json", "--globals", "globals.json", "--reporters", "junit,html", "--reporter-junit-export", "target/newman/TEST-localFile.xml", "--reporter-html-export", "target/newman/TEST-localFile.html", "--suppress-exit-code"}})
    64  		assert.Contains(t, utils.executedExecutables, executedExecutables{executable: filepath.FromSlash("/home/node/.npm-global/bin/newman"), params: []string{"run", "localFile2.json", "--environment", "env.json", "--globals", "globals.json", "--reporters", "junit,html", "--reporter-junit-export", "target/newman/TEST-localFile2.xml", "--reporter-html-export", "target/newman/TEST-localFile2.html", "--suppress-exit-code"}})
    65  	})
    66  
    67  	t.Run("happy path with fail on error", func(t *testing.T) {
    68  		t.Parallel()
    69  		// init
    70  
    71  		utils := newNewmanExecuteMockUtils()
    72  		fineConfig := allFineConfig
    73  		fineConfig.FailOnError = true
    74  
    75  		// test
    76  		err := runNewmanExecute(&fineConfig, &utils)
    77  
    78  		// assert
    79  		assert.NoError(t, err)
    80  		assert.Contains(t, utils.executedExecutables, executedExecutables{executable: "node", params: []string{"--version"}})
    81  		assert.Contains(t, utils.executedExecutables, executedExecutables{executable: "npm", params: []string{"--version"}})
    82  		assert.Contains(t, utils.executedExecutables, executedExecutables{executable: "npm", params: []string{"install", "newman", "--global", "--quiet", "--prefix=~/.npm-global"}})
    83  		assert.Contains(t, utils.executedExecutables, executedExecutables{executable: filepath.FromSlash("/home/node/.npm-global/bin/newman"), params: []string{"run", "localFile.json", "--environment", "env.json", "--globals", "globals.json", "--reporters", "junit,html", "--reporter-junit-export", "target/newman/TEST-localFile.xml", "--reporter-html-export", "target/newman/TEST-localFile.html"}})
    84  		assert.Contains(t, utils.executedExecutables, executedExecutables{executable: filepath.FromSlash("/home/node/.npm-global/bin/newman"), params: []string{"run", "localFile2.json", "--environment", "env.json", "--globals", "globals.json", "--reporters", "junit,html", "--reporter-junit-export", "target/newman/TEST-localFile2.xml", "--reporter-html-export", "target/newman/TEST-localFile2.html"}})
    85  	})
    86  
    87  	t.Run("error on newman execution", func(t *testing.T) {
    88  		t.Parallel()
    89  		// init
    90  
    91  		utils := newNewmanExecuteMockUtils()
    92  		utils.errorOnNewmanExecution = true
    93  
    94  		// test
    95  		err := runNewmanExecute(&allFineConfig, &utils)
    96  
    97  		// assert
    98  		assert.EqualError(t, err, "The execution of the newman tests failed, see the log for details.: error on newman execution")
    99  	})
   100  
   101  	t.Run("error on newman installation", func(t *testing.T) {
   102  		t.Parallel()
   103  		// init
   104  
   105  		utils := newNewmanExecuteMockUtils()
   106  		utils.errorOnNewmanInstall = true
   107  
   108  		// test
   109  		err := runNewmanExecute(&allFineConfig, &utils)
   110  
   111  		// assert
   112  		assert.EqualError(t, err, "error installing newman: error on newman install")
   113  	})
   114  
   115  	t.Run("error on npm version logging", func(t *testing.T) {
   116  		t.Parallel()
   117  		// init
   118  
   119  		utils := newNewmanExecuteMockUtils()
   120  		utils.errorOnLoggingNpm = true
   121  
   122  		// test
   123  		err := runNewmanExecute(&allFineConfig, &utils)
   124  
   125  		// assert
   126  		assert.EqualError(t, err, "error logging npm version: error on RunExecutable")
   127  	})
   128  
   129  	t.Run("error on template resolution", func(t *testing.T) {
   130  		t.Parallel()
   131  		// init
   132  
   133  		utils := newNewmanExecuteMockUtils()
   134  		config := allFineConfig
   135  		config.NewmanRunCommand = "this is my erroneous command {{.collectionDisplayName}"
   136  
   137  		// test
   138  		err := runNewmanExecute(&config, &utils)
   139  
   140  		// assert
   141  		assert.EqualError(t, err, "could not parse newman command template: template: template:1: unexpected \"}\" in operand")
   142  	})
   143  
   144  	t.Run("error on file search", func(t *testing.T) {
   145  		t.Parallel()
   146  		// init
   147  
   148  		utils := newNewmanExecuteMockUtils()
   149  		utils.filesToFind = nil
   150  
   151  		// test
   152  		err := runNewmanExecute(&allFineConfig, &utils)
   153  
   154  		// assert
   155  		assert.EqualError(t, err, "no collection found with pattern '**.json'")
   156  	})
   157  
   158  	t.Run("no newman file", func(t *testing.T) {
   159  		t.Parallel()
   160  		// init
   161  
   162  		utils := newNewmanExecuteMockUtils()
   163  		utils.errorOnGlob = true
   164  
   165  		// test
   166  		err := runNewmanExecute(&allFineConfig, &utils)
   167  
   168  		// assert
   169  		assert.EqualError(t, err, "Could not execute global search for '**.json': error on Glob")
   170  	})
   171  }
   172  
   173  func TestDefineCollectionDisplayName(t *testing.T) {
   174  	t.Parallel()
   175  
   176  	t.Run("normal path", func(t *testing.T) {
   177  		t.Parallel()
   178  
   179  		path := filepath.Join("dir1", "dir2", "fancyFile.txt")
   180  		result := defineCollectionDisplayName(path)
   181  		assert.Equal(t, "dir1_dir2_fancyFile", result)
   182  	})
   183  
   184  	t.Run("directory", func(t *testing.T) {
   185  		t.Parallel()
   186  
   187  		path := filepath.Join("dir1", "dir2", "dir3")
   188  		result := defineCollectionDisplayName(path)
   189  		assert.Equal(t, "dir1_dir2_dir3", result)
   190  	})
   191  
   192  	t.Run("directory with dot prefix", func(t *testing.T) {
   193  		t.Parallel()
   194  
   195  		path := filepath.Join(".dir1", "dir2", "dir3", "file.json")
   196  		result := defineCollectionDisplayName(path)
   197  		assert.Equal(t, "dir1_dir2_dir3_file", result)
   198  	})
   199  
   200  	t.Run("empty path", func(t *testing.T) {
   201  		t.Parallel()
   202  
   203  		path := filepath.Join(".")
   204  		result := defineCollectionDisplayName(path)
   205  		assert.Equal(t, "", result)
   206  	})
   207  }
   208  
   209  func TestResolveTemplate(t *testing.T) {
   210  	t.Parallel()
   211  
   212  	t.Run("nothing to replace", func(t *testing.T) {
   213  		t.Parallel()
   214  
   215  		// config := newmanExecuteOptions{NewmanRunCommand: "this is my fancy command"}
   216  		config := newmanExecuteOptions{RunOptions: []string{"this", "is", "my", "fancy", "command"}}
   217  
   218  		cmd, err := resolveTemplate(&config, "collectionsDisplayName")
   219  		assert.NoError(t, err)
   220  		assert.Equal(t, []string{"this", "is", "my", "fancy", "command"}, cmd)
   221  	})
   222  
   223  	t.Run("replace display name", func(t *testing.T) {
   224  		t.Parallel()
   225  
   226  		config := newmanExecuteOptions{RunOptions: []string{"this", "is", "my", "fancy", "command", "{{.CollectionDisplayName}}"}}
   227  
   228  		cmd, err := resolveTemplate(&config, "theDisplayName")
   229  		assert.NoError(t, err)
   230  		assert.Equal(t, []string{"this", "is", "my", "fancy", "command", "theDisplayName"}, cmd)
   231  	})
   232  
   233  	t.Run("error when parameter cannot be resolved", func(t *testing.T) {
   234  		t.Parallel()
   235  
   236  		config := newmanExecuteOptions{RunOptions: []string{"this", "is", "my", "fancy", "command", "{{.collectionDisplayName}}"}}
   237  
   238  		_, err := resolveTemplate(&config, "theDisplayName")
   239  		assert.EqualError(t, err, "error on executing template: template: template:1:2: executing \"template\" at <.collectionDisplayName>: can't evaluate field collectionDisplayName in type cmd.TemplateConfig")
   240  	})
   241  
   242  	t.Run("error when template cannot be parsed", func(t *testing.T) {
   243  		t.Parallel()
   244  
   245  		config := newmanExecuteOptions{RunOptions: []string{"this", "is", "my", "fancy", "command", "{{.collectionDisplayName}"}}
   246  
   247  		_, err := resolveTemplate(&config, "theDisplayName")
   248  		assert.EqualError(t, err, "could not parse newman command template: template: template:1: unexpected \"}\" in operand")
   249  	})
   250  }
   251  
   252  func TestLogVersions(t *testing.T) {
   253  	t.Parallel()
   254  
   255  	t.Run("happy path", func(t *testing.T) {
   256  		utils := newNewmanExecuteMockUtils()
   257  
   258  		err := logVersions(&utils)
   259  		assert.NoError(t, err)
   260  		assert.Contains(t, utils.executedExecutables, executedExecutables{executable: "npm", params: []string{"--version"}})
   261  	})
   262  
   263  	t.Run("error in node execution", func(t *testing.T) {
   264  		utils := newNewmanExecuteMockUtils()
   265  		utils.errorOnLoggingNode = true
   266  
   267  		err := logVersions(&utils)
   268  		assert.EqualError(t, err, "error logging node version: error on RunExecutable")
   269  	})
   270  
   271  	t.Run("error in npm execution", func(t *testing.T) {
   272  		utils := newNewmanExecuteMockUtils()
   273  		utils.errorOnLoggingNpm = true
   274  
   275  		err := logVersions(&utils)
   276  		assert.EqualError(t, err, "error logging npm version: error on RunExecutable")
   277  		assert.Contains(t, utils.executedExecutables, executedExecutables{executable: "node", params: []string{"--version"}})
   278  	})
   279  }
   280  
   281  func (e *newmanExecuteMockUtils) Glob(string) (matches []string, err error) {
   282  	if e.errorOnGlob {
   283  		return nil, errors.New("error on Glob")
   284  	}
   285  
   286  	return e.filesToFind, nil
   287  }
   288  
   289  func (e *newmanExecuteMockUtils) RunExecutable(executable string, params ...string) error {
   290  	if e.errorOnRunShell {
   291  		return errors.New("error on RunExecutable")
   292  	}
   293  	if e.errorOnLoggingNode && executable == "node" && params[0] == "--version" {
   294  		return errors.New("error on RunExecutable")
   295  	}
   296  	if e.errorOnLoggingNpm && executable == "npm" && params[0] == "--version" {
   297  		return errors.New("error on RunExecutable")
   298  	}
   299  	if e.errorOnNewmanExecution && strings.Contains(executable, "newman") {
   300  		return errors.New("error on newman execution")
   301  	}
   302  	if e.errorOnNewmanInstall && sliceUtils.ContainsString(params, "install") {
   303  		return errors.New("error on newman install")
   304  	}
   305  
   306  	length := len(e.executedExecutables)
   307  	if length < e.commandIndex+1 {
   308  		e.executedExecutables = append(e.executedExecutables, executedExecutables{})
   309  		length++
   310  	}
   311  
   312  	e.executedExecutables[length-1].executable = executable
   313  	e.executedExecutables[length-1].params = params
   314  	e.commandIndex++
   315  
   316  	return nil
   317  }
   318  
   319  func (e *newmanExecuteMockUtils) Getenv(key string) string {
   320  	if key == "HOME" {
   321  		return "/home/node"
   322  	}
   323  	return ""
   324  }