github.com/ActiveState/cli@v0.0.0-20240508170324-6801f60cd051/test/integration/package_int_test.go (about)

     1  package integration
     2  
     3  import (
     4  	"fmt"
     5  	"path/filepath"
     6  	"runtime"
     7  	"strings"
     8  	"testing"
     9  	"time"
    10  
    11  	"github.com/ActiveState/cli/internal/testhelpers/suite"
    12  	"github.com/ActiveState/termtest"
    13  
    14  	"github.com/ActiveState/cli/internal/constants"
    15  	"github.com/ActiveState/cli/internal/fileutils"
    16  	"github.com/ActiveState/cli/internal/testhelpers/e2e"
    17  	"github.com/ActiveState/cli/internal/testhelpers/tagsuite"
    18  )
    19  
    20  type PackageIntegrationTestSuite struct {
    21  	tagsuite.Suite
    22  }
    23  
    24  func (suite *PackageIntegrationTestSuite) TestPackage_listingSimple() {
    25  	suite.OnlyRunForTags(tagsuite.Package)
    26  	ts := e2e.New(suite.T(), false)
    27  	defer ts.Close()
    28  
    29  	suite.PrepareActiveStateYAML(ts)
    30  
    31  	cp := ts.Spawn("packages")
    32  	cp.Expect("Operating on project")
    33  	cp.Expect("ActiveState-CLI/List")
    34  	cp.Expect("Name")
    35  	cp.Expect("pytest")
    36  	cp.ExpectExitCode(0)
    37  }
    38  
    39  func (suite *PackageIntegrationTestSuite) TestPackages_project() {
    40  	suite.OnlyRunForTags(tagsuite.Package)
    41  	ts := e2e.New(suite.T(), false)
    42  	defer ts.Close()
    43  
    44  	cp := ts.Spawn("packages", "--namespace", "ActiveState-CLI/List")
    45  	cp.Expect("Name")
    46  	cp.Expect("numpy")
    47  	cp.Expect("pytest")
    48  	cp.ExpectExitCode(0)
    49  }
    50  
    51  func (suite *PackageIntegrationTestSuite) TestPackages_name() {
    52  	suite.OnlyRunForTags(tagsuite.Package)
    53  	ts := e2e.New(suite.T(), false)
    54  	defer ts.Close()
    55  
    56  	suite.PrepareActiveStateYAML(ts)
    57  
    58  	cp := ts.Spawn("packages", "--package", "py")
    59  	cp.Expect("Name")
    60  	cp.Expect("pytest")
    61  	cp.ExpectExitCode(0)
    62  }
    63  
    64  func (suite *PackageIntegrationTestSuite) TestPackages_project_name() {
    65  	suite.OnlyRunForTags(tagsuite.Package)
    66  	ts := e2e.New(suite.T(), false)
    67  	defer ts.Close()
    68  
    69  	cp := ts.Spawn("packages", "--namespace", "ActiveState-CLI/List", "--package", "py")
    70  	cp.Expect("Name")
    71  	cp.Expect("pytest")
    72  	cp.ExpectExitCode(0)
    73  }
    74  
    75  func (suite *PackageIntegrationTestSuite) TestPackages_project_name_noData() {
    76  	suite.OnlyRunForTags(tagsuite.Package)
    77  	ts := e2e.New(suite.T(), false)
    78  	defer ts.Close()
    79  
    80  	cp := ts.Spawn("packages", "--namespace", "ActiveState-CLI/List", "--package", "req")
    81  	cp.Expect("The project has no packages to list.")
    82  	cp.ExpectExitCode(0)
    83  }
    84  
    85  func (suite *PackageIntegrationTestSuite) TestPackages_project_invalid() {
    86  	suite.OnlyRunForTags(tagsuite.Package)
    87  	ts := e2e.New(suite.T(), false)
    88  	defer ts.Close()
    89  
    90  	cp := ts.Spawn("packages", "--namespace", "junk/junk")
    91  	cp.Expect("The requested project junk does not exist under junk")
    92  	cp.ExpectExitCode(1)
    93  	ts.IgnoreLogErrors()
    94  }
    95  
    96  func (suite *PackageIntegrationTestSuite) TestPackage_listingWithCommitValid() {
    97  	suite.OnlyRunForTags(tagsuite.Package)
    98  	ts := e2e.New(suite.T(), false)
    99  	defer ts.Close()
   100  
   101  	suite.PrepareActiveStateYAML(ts)
   102  
   103  	cp := ts.Spawn("packages", "--commit", "b350c879-b72a-48da-bbc2-d8d709a6182a")
   104  	cp.Expect("Name")
   105  	cp.Expect("numpy")
   106  	cp.ExpectExitCode(0)
   107  }
   108  
   109  func (suite *PackageIntegrationTestSuite) TestPackage_listingWithCommitInvalid() {
   110  	suite.OnlyRunForTags(tagsuite.Package)
   111  	ts := e2e.New(suite.T(), false)
   112  	defer ts.Close()
   113  
   114  	suite.PrepareActiveStateYAML(ts)
   115  
   116  	cp := ts.Spawn("packages", "--commit", "junk")
   117  	cp.Expect("Cannot obtain")
   118  	cp.ExpectExitCode(1)
   119  	ts.IgnoreLogErrors()
   120  }
   121  
   122  func (suite *PackageIntegrationTestSuite) TestPackage_listingWithCommitUnknown() {
   123  	suite.OnlyRunForTags(tagsuite.Package)
   124  	ts := e2e.New(suite.T(), false)
   125  	defer ts.Close()
   126  
   127  	suite.PrepareActiveStateYAML(ts)
   128  
   129  	cp := ts.Spawn("packages", "--commit", "00010001-0001-0001-0001-000100010001")
   130  	cp.Expect("No data")
   131  	cp.ExpectExitCode(1)
   132  	ts.IgnoreLogErrors()
   133  }
   134  
   135  func (suite *PackageIntegrationTestSuite) TestPackage_listingWithCommitValidNoPackages() {
   136  	suite.OnlyRunForTags(tagsuite.Package)
   137  	ts := e2e.New(suite.T(), false)
   138  	defer ts.Close()
   139  
   140  	suite.PrepareActiveStateYAML(ts)
   141  
   142  	cp := ts.Spawn("packages", "--commit", "cd674adb-e89a-48ff-95c6-ad52a177537b")
   143  	cp.Expect("The project has no packages to list.")
   144  	cp.ExpectExitCode(0)
   145  }
   146  
   147  func (suite *PackageIntegrationTestSuite) TestPackage_searchSimple() {
   148  	suite.OnlyRunForTags(tagsuite.Package)
   149  	ts := e2e.New(suite.T(), false)
   150  	defer ts.Close()
   151  	suite.PrepareActiveStateYAML(ts)
   152  
   153  	// Note that the expected strings might change due to inventory changes
   154  	cp := ts.Spawn("search", "requests")
   155  	expectations := []string{
   156  		"requests2",
   157  		"2.16.0",
   158  	}
   159  	for _, expectation := range expectations {
   160  		cp.Expect(expectation)
   161  	}
   162  	cp.Send("q")
   163  	cp.ExpectExitCode(0)
   164  }
   165  
   166  func (suite *PackageIntegrationTestSuite) TestPackage_searchWithExactTerm() {
   167  	suite.OnlyRunForTags(tagsuite.Package)
   168  	ts := e2e.New(suite.T(), false)
   169  	defer ts.Close()
   170  	suite.PrepareActiveStateYAML(ts)
   171  
   172  	cp := ts.Spawn("search", "requests", "--exact-term")
   173  	expectations := []string{
   174  		"Name",
   175  		"requests",
   176  		"more",
   177  	}
   178  	for _, expectation := range expectations {
   179  		cp.Expect(expectation)
   180  	}
   181  	cp.Send("q")
   182  	cp.ExpectExitCode(0)
   183  }
   184  
   185  func (suite *PackageIntegrationTestSuite) TestPackage_searchWithExactTermWrongTerm() {
   186  	suite.OnlyRunForTags(tagsuite.Package)
   187  	ts := e2e.New(suite.T(), false)
   188  	defer ts.Close()
   189  	suite.PrepareActiveStateYAML(ts)
   190  
   191  	cp := ts.Spawn("search", "Requests", "--exact-term")
   192  	cp.Expect("No packages in our catalog match")
   193  	cp.ExpectExitCode(1)
   194  	ts.IgnoreLogErrors()
   195  
   196  	cp = ts.Spawn("search", "xxxrequestsxxx", "--exact-term")
   197  	cp.Expect("No packages in our catalog match")
   198  	cp.ExpectExitCode(1)
   199  }
   200  
   201  func (suite *PackageIntegrationTestSuite) TestPackage_searchWithLang() {
   202  	suite.OnlyRunForTags(tagsuite.Package)
   203  	ts := e2e.New(suite.T(), false)
   204  	defer ts.Close()
   205  	suite.PrepareActiveStateYAML(ts)
   206  
   207  	cp := ts.Spawn("search", "Moose", "--language=perl")
   208  	cp.Expect("Name")
   209  	cp.Expect("Moose")
   210  	cp.Expect("Moose-Autobox")
   211  	cp.Expect("MooseFS")
   212  	cp.Send("q")
   213  	cp.ExpectExitCode(0)
   214  }
   215  
   216  func (suite *PackageIntegrationTestSuite) TestPackage_searchModules() {
   217  	suite.OnlyRunForTags(tagsuite.Package)
   218  	ts := e2e.New(suite.T(), false)
   219  	defer ts.Close()
   220  	suite.PrepareActiveStateYAML(ts)
   221  
   222  	cp := ts.Spawn("search", "leapsecond", "--language=perl")
   223  	cp.Expect("Date-Leapsecond")
   224  	cp.Expect("DateTime-LeapSecond")
   225  	cp.Expect("DateTime-Lite")
   226  	cp.Send("q")
   227  	cp.ExpectExitCode(0)
   228  }
   229  
   230  func (suite *PackageIntegrationTestSuite) TestPackage_searchWithWrongLang() {
   231  	suite.OnlyRunForTags(tagsuite.Package)
   232  	ts := e2e.New(suite.T(), false)
   233  	defer ts.Close()
   234  	suite.PrepareActiveStateYAML(ts)
   235  
   236  	cp := ts.Spawn("search", "xxxjunkxxx", "--language=perl")
   237  	cp.Expect("No packages in our catalog match")
   238  	cp.ExpectExitCode(1)
   239  	ts.IgnoreLogErrors()
   240  }
   241  
   242  func (suite *PackageIntegrationTestSuite) TestPackage_searchWithBadLang() {
   243  	suite.OnlyRunForTags(tagsuite.Package)
   244  	ts := e2e.New(suite.T(), false)
   245  	defer ts.Close()
   246  	suite.PrepareActiveStateYAML(ts)
   247  
   248  	cp := ts.Spawn("search", "numpy", "--language=bad")
   249  	cp.Expect("Cannot obtain search")
   250  	cp.ExpectExitCode(1)
   251  	ts.IgnoreLogErrors()
   252  }
   253  
   254  func (suite *PackageIntegrationTestSuite) TestPackage_info() {
   255  	suite.OnlyRunForTags(tagsuite.Package)
   256  	ts := e2e.New(suite.T(), false)
   257  	defer ts.Close()
   258  	suite.PrepareActiveStateYAML(ts)
   259  
   260  	cp := ts.Spawn("info", "pexpect")
   261  	cp.Expect("Package Information")
   262  	cp.Expect("Authors")
   263  	cp.Expect("Version")
   264  	cp.Expect("Available")
   265  	cp.Expect("What's next?")
   266  	cp.Expect("run 'state install")
   267  	cp.ExpectExitCode(0)
   268  }
   269  
   270  func (suite *PackageIntegrationTestSuite) TestPackage_detached_operation() {
   271  	suite.OnlyRunForTags(tagsuite.Package)
   272  	ts := e2e.New(suite.T(), false)
   273  	defer ts.Close()
   274  
   275  	cp := ts.Spawn("checkout", "ActiveState-CLI/small-python", ".")
   276  	cp.Expect("Skipping runtime setup")
   277  	cp.Expect("Checked out project")
   278  	cp.ExpectExitCode(0)
   279  
   280  	suite.Run("install non-existing", func() {
   281  		cp := ts.Spawn("install", "json")
   282  		cp.Expect("No results found for search term")
   283  		cp.Expect("json2")
   284  		cp.Wait()
   285  	})
   286  
   287  	suite.Run("install", func() {
   288  		cp := ts.Spawn("install", "dateparser@0.7.2")
   289  		cp.ExpectRe("(?:Package added|being built)", termtest.OptExpectTimeout(30*time.Second))
   290  		cp.Wait()
   291  	})
   292  
   293  	suite.Run("install (update)", func() {
   294  		cp := ts.Spawn("install", "dateparser@0.7.6")
   295  		cp.ExpectRe("(?:Package updated|being built)", termtest.OptExpectTimeout(50*time.Second))
   296  		cp.Wait()
   297  	})
   298  
   299  	suite.Run("uninstall", func() {
   300  		cp := ts.Spawn("uninstall", "dateparser")
   301  		cp.ExpectRe("(?:Package uninstalled|being built)", termtest.OptExpectTimeout(30*time.Second))
   302  		cp.Wait()
   303  	})
   304  }
   305  
   306  func (suite *PackageIntegrationTestSuite) TestPackage_operation() {
   307  	suite.OnlyRunForTags(tagsuite.Package)
   308  	if runtime.GOOS == "darwin" {
   309  		suite.T().Skip("Skipping mac for now as the builds are still too unreliable")
   310  		return
   311  	}
   312  	ts := e2e.New(suite.T(), false)
   313  	defer ts.Close()
   314  
   315  	user := ts.CreateNewUser()
   316  	namespace := fmt.Sprintf("%s/%s", user.Username, "python3-pkgtest")
   317  
   318  	cp := ts.Spawn("fork", "ActiveState-CLI/Packages", "--org", user.Username, "--name", "python3-pkgtest")
   319  	cp.ExpectExitCode(0)
   320  
   321  	cp = ts.Spawn("checkout", namespace, ".")
   322  	cp.Expect("Skipping runtime setup")
   323  	cp.Expect("Checked out project")
   324  	cp.ExpectExitCode(0)
   325  
   326  	cp = ts.Spawn("history", "--output=json")
   327  	cp.ExpectExitCode(0)
   328  
   329  	suite.Run("install", func() {
   330  		cp := ts.Spawn("install", "urllib3@1.25.6")
   331  		cp.Expect(fmt.Sprintf("Operating on project %s/python3-pkgtest", user.Username))
   332  		cp.ExpectRe("(?:Package added|being built)", termtest.OptExpectTimeout(30*time.Second))
   333  		cp.Wait()
   334  	})
   335  
   336  	suite.Run("install (update)", func() {
   337  		cp := ts.Spawn("install", "urllib3@1.25.8")
   338  		cp.Expect(fmt.Sprintf("Operating on project %s/python3-pkgtest", user.Username))
   339  		cp.ExpectRe("(?:Package updated|being built)", termtest.OptExpectTimeout(30*time.Second))
   340  		cp.Wait()
   341  	})
   342  
   343  	suite.Run("uninstall", func() {
   344  		cp := ts.Spawn("uninstall", "urllib3")
   345  		cp.Expect(fmt.Sprintf("Operating on project %s/python3-pkgtest", user.Username))
   346  		cp.ExpectRe("(?:Package uninstalled|being built)", termtest.OptExpectTimeout(30*time.Second))
   347  		cp.Wait()
   348  	})
   349  }
   350  
   351  func (suite *PackageIntegrationTestSuite) TestPackage_operation_multiple() {
   352  	suite.OnlyRunForTags(tagsuite.Package)
   353  	if runtime.GOOS == "darwin" {
   354  		suite.T().Skip("Skipping mac for now as the builds are still too unreliable")
   355  		return
   356  	}
   357  	ts := e2e.New(suite.T(), false)
   358  	defer ts.Close()
   359  
   360  	user := ts.CreateNewUser()
   361  	namespace := fmt.Sprintf("%s/%s", user.Username, "python3-pkgtest")
   362  
   363  	cp := ts.Spawn("fork", "ActiveState-CLI/Packages", "--org", user.Username, "--name", "python3-pkgtest")
   364  	cp.ExpectExitCode(0)
   365  
   366  	cp = ts.Spawn("checkout", namespace, ".")
   367  	cp.Expect("Skipping runtime setup")
   368  	cp.Expect("Checked out project")
   369  	cp.ExpectExitCode(0)
   370  
   371  	cp = ts.Spawn("history", "--output=json")
   372  	cp.ExpectExitCode(0)
   373  
   374  	suite.Run("install", func() {
   375  		cp := ts.Spawn("install", "requests", "urllib3@1.25.6")
   376  		cp.Expect(fmt.Sprintf("Operating on project %s/python3-pkgtest", user.Username))
   377  		cp.ExpectRe("(?:Package added|being built)", termtest.OptExpectTimeout(30*time.Second))
   378  		cp.Wait()
   379  	})
   380  
   381  	suite.Run("install (update)", func() {
   382  		cp := ts.Spawn("install", "urllib3@1.25.8")
   383  		cp.Expect(fmt.Sprintf("Operating on project %s/python3-pkgtest", user.Username))
   384  		cp.ExpectRe("(?:Package updated|being built)", termtest.OptExpectTimeout(30*time.Second))
   385  		cp.Wait()
   386  	})
   387  
   388  	suite.Run("uninstall", func() {
   389  		cp := ts.Spawn("uninstall", "requests", "urllib3")
   390  		cp.Expect(fmt.Sprintf("Operating on project %s/python3-pkgtest", user.Username))
   391  		cp.ExpectRe("(?:Package uninstalled|being built)", termtest.OptExpectTimeout(30*time.Second))
   392  		cp.Wait()
   393  	})
   394  }
   395  
   396  func (suite *PackageIntegrationTestSuite) TestPackage_Duplicate() {
   397  	suite.OnlyRunForTags(tagsuite.Package)
   398  
   399  	ts := e2e.New(suite.T(), false)
   400  	defer ts.Close()
   401  
   402  	cp := ts.Spawn("checkout", "ActiveState-CLI/small-python", ".")
   403  	cp.Expect("Skipping runtime setup")
   404  	cp.Expect("Checked out project")
   405  	cp.ExpectExitCode(0)
   406  
   407  	cp = ts.Spawn("install", "requests") // install
   408  	cp.ExpectExitCode(0)
   409  
   410  	cp = ts.Spawn("install", "requests") // install again
   411  	cp.Expect("already installed")
   412  	cp.ExpectNotExitCode(0)
   413  	ts.IgnoreLogErrors()
   414  
   415  	if strings.Count(cp.Snapshot(), " x ") != 2 { // 2 because "Creating commit x Failed" is also printed
   416  		suite.Fail("Expected exactly ONE error message, got: ", cp.Snapshot())
   417  	}
   418  }
   419  
   420  func (suite *PackageIntegrationTestSuite) PrepareActiveStateYAML(ts *e2e.Session) {
   421  	asyData := `project: "https://platform.activestate.com/ActiveState-CLI/List"
   422  scripts:
   423    - name: test-pyparsing
   424      language: python3
   425      value: |
   426        from pyparsing import Word, alphas
   427        print(Word(alphas).parseString("TEST"))
   428  `
   429  	ts.PrepareActiveStateYAML(asyData)
   430  	ts.PrepareCommitIdFile("a9d0bc88-585a-49cf-89c1-6c07af781cff")
   431  }
   432  
   433  func (suite *PackageIntegrationTestSuite) TestPackage_UninstallDoesNotExist() {
   434  	suite.OnlyRunForTags(tagsuite.Package)
   435  
   436  	ts := e2e.New(suite.T(), false)
   437  	defer ts.Close()
   438  
   439  	suite.PrepareActiveStateYAML(ts)
   440  
   441  	cp := ts.Spawn("uninstall", "doesNotExist")
   442  	cp.Expect("does not exist")
   443  	cp.ExpectExitCode(1)
   444  	ts.IgnoreLogErrors()
   445  
   446  	if strings.Count(cp.Snapshot(), " x ") != 2 { // 2 because "Creating commit x Failed" is also printed
   447  		suite.Fail("Expected exactly ONE error message, got: ", cp.Snapshot())
   448  	}
   449  }
   450  
   451  func (suite *PackageIntegrationTestSuite) TestJSON() {
   452  	suite.OnlyRunForTags(tagsuite.Package, tagsuite.JSON)
   453  	ts := e2e.New(suite.T(), false)
   454  	defer ts.Close()
   455  
   456  	cp := ts.Spawn("search", "Text-CSV", "--exact-term", "--language", "Perl", "-o", "json")
   457  	cp.Expect(`"Name":"Text-CSV"`)
   458  	cp.ExpectExitCode(0)
   459  	// AssertValidJSON(suite.T(), cp) // currently too large to fit terminal window to validate
   460  
   461  	cp = ts.SpawnWithOpts(
   462  		e2e.OptArgs("checkout", "ActiveState-CLI/Packages-Perl", "."),
   463  		e2e.OptAppendEnv("ACTIVESTATE_CLI_DISABLE_RUNTIME=false"),
   464  	)
   465  	cp.Expect("Checked out project")
   466  	cp.ExpectExitCode(0)
   467  
   468  	cp = ts.SpawnWithOpts(
   469  		e2e.OptArgs("install", "Text-CSV", "-o", "json"),
   470  	)
   471  	cp.Expect(`{"name":"Text-CSV"`)
   472  	cp.ExpectExitCode(0)
   473  	AssertValidJSON(suite.T(), cp)
   474  
   475  	cp = ts.Spawn("packages", "-o", "json")
   476  	cp.Expect(`[{"package":"Text-CSV","version":"Auto","resolved_version":"`)
   477  	cp.ExpectExitCode(0)
   478  	AssertValidJSON(suite.T(), cp)
   479  
   480  	cp = ts.SpawnWithOpts(
   481  		e2e.OptArgs("uninstall", "Text-CSV", "-o", "json"),
   482  	)
   483  	cp.Expect(`{"name":"Text-CSV"`)
   484  	cp.ExpectExitCode(0)
   485  	AssertValidJSON(suite.T(), cp)
   486  }
   487  
   488  func (suite *PackageIntegrationTestSuite) TestNormalize() {
   489  	suite.OnlyRunForTags(tagsuite.Package)
   490  	if runtime.GOOS == "darwin" {
   491  		suite.T().Skip("Skipping mac for now as the builds are still too unreliable")
   492  		return
   493  	}
   494  	ts := e2e.New(suite.T(), false)
   495  	defer ts.Close()
   496  
   497  	dir := filepath.Join(ts.Dirs.Work, "normalized")
   498  	suite.Require().NoError(fileutils.Mkdir(dir))
   499  	cp := ts.SpawnWithOpts(
   500  		e2e.OptArgs("checkout", "ActiveState-CLI/small-python", "."),
   501  		e2e.OptWD(dir),
   502  	)
   503  	cp.Expect("Skipping runtime setup")
   504  	cp.Expect("Checked out project")
   505  	cp.ExpectExitCode(0)
   506  
   507  	cp = ts.SpawnWithOpts(
   508  		e2e.OptArgs("install", "Charset_normalizer"),
   509  		e2e.OptWD(dir),
   510  		e2e.OptAppendEnv(constants.DisableRuntime+"=false"),
   511  	)
   512  	// Even though we are not sourcing a runtime it can still take time to resolve
   513  	// the dependencies and create the commit
   514  	cp.Expect("charset-normalizer", e2e.RuntimeSourcingTimeoutOpt)
   515  	cp.Expect("is different")
   516  	cp.Expect("Charset_normalizer")
   517  	cp.ExpectExitCode(0)
   518  
   519  	anotherDir := filepath.Join(ts.Dirs.Work, "not-normalized")
   520  	suite.Require().NoError(fileutils.Mkdir(anotherDir))
   521  	cp = ts.SpawnWithOpts(
   522  		e2e.OptArgs("checkout", "ActiveState-CLI/small-python", "."),
   523  		e2e.OptWD(anotherDir),
   524  	)
   525  	cp.Expect("Skipping runtime setup")
   526  	cp.Expect("Checked out project")
   527  	cp.ExpectExitCode(0)
   528  
   529  	cp = ts.SpawnWithOpts(
   530  		e2e.OptArgs("install", "charset-normalizer"),
   531  		e2e.OptWD(anotherDir),
   532  		e2e.OptAppendEnv(constants.DisableRuntime+"=false"),
   533  	)
   534  	cp.Expect("charset-normalizer", e2e.RuntimeSourcingTimeoutOpt)
   535  	cp.ExpectExitCode(0, e2e.RuntimeSourcingTimeoutOpt)
   536  	suite.NotContains(cp.Output(), "is different")
   537  }
   538  
   539  func (suite *PackageIntegrationTestSuite) TestInstall_InvalidVersion() {
   540  	suite.OnlyRunForTags(tagsuite.Package)
   541  	ts := e2e.New(suite.T(), false)
   542  	defer ts.Close()
   543  
   544  	cp := ts.Spawn("checkout", "ActiveState-CLI/small-python", ".")
   545  	cp.Expect("Skipping runtime setup")
   546  	cp.Expect("Checked out project")
   547  	cp.ExpectExitCode(0)
   548  
   549  	cp = ts.SpawnWithOpts(
   550  		e2e.OptArgs("install", "pytest@999.9999.9999"),
   551  		e2e.OptAppendEnv(constants.DisableRuntime+"=false"),
   552  	)
   553  	// User facing error from build planner
   554  	// We only assert the state tool curated part of the error as the underlying build planner error may change
   555  	cp.Expect("Could not plan build")
   556  	cp.ExpectExitCode(1)
   557  	ts.IgnoreLogErrors()
   558  }
   559  
   560  func (suite *PackageIntegrationTestSuite) TestUpdate_InvalidVersion() {
   561  	suite.OnlyRunForTags(tagsuite.Package)
   562  	ts := e2e.New(suite.T(), false)
   563  	defer ts.Close()
   564  
   565  	cp := ts.Spawn("checkout", "ActiveState-CLI/small-python", ".")
   566  	cp.Expect("Skipping runtime setup")
   567  	cp.Expect("Checked out project")
   568  	cp.ExpectExitCode(0)
   569  
   570  	cp = ts.Spawn("install", "pytest") // install
   571  	cp.ExpectExitCode(0)
   572  
   573  	cp = ts.SpawnWithOpts(
   574  		e2e.OptArgs("install", "pytest@999.9999.9999"),      // update
   575  		e2e.OptAppendEnv(constants.DisableRuntime+"=false"), // We DO want to test the runtime part, just not for every step
   576  	)
   577  	// User facing error from build planner
   578  	// We only assert the state tool curated part of the error as the underlying build planner error may change
   579  	cp.Expect("Could not plan build")
   580  	cp.ExpectExitCode(1)
   581  	ts.IgnoreLogErrors()
   582  }
   583  
   584  func (suite *PackageIntegrationTestSuite) TestUpdate() {
   585  	suite.OnlyRunForTags(tagsuite.Package)
   586  	ts := e2e.New(suite.T(), false)
   587  	defer ts.Close()
   588  
   589  	cp := ts.Spawn("checkout", "ActiveState-CLI/small-python", ".")
   590  	cp.Expect("Skipping runtime setup")
   591  	cp.Expect("Checked out project")
   592  	cp.ExpectExitCode(0)
   593  
   594  	cp = ts.Spawn("install", "pytest@7.3.2") // install
   595  	cp.ExpectExitCode(0)
   596  
   597  	cp = ts.Spawn("history")
   598  	cp.Expect("pytest")
   599  	cp.Expect("7.3.2")
   600  	cp.ExpectExitCode(0)
   601  
   602  	cp = ts.Spawn("packages")
   603  	cp.Expect("pytest")
   604  	cp.Expect("7.3.2")
   605  	cp.ExpectExitCode(0)
   606  
   607  	cp = ts.SpawnWithOpts(
   608  		e2e.OptArgs("install", "pytest@7.4.0"),              // update
   609  		e2e.OptAppendEnv(constants.DisableRuntime+"=false"), // We DO want to test the runtime part, just not for every step
   610  	)
   611  	cp.ExpectExitCode(0, e2e.RuntimeSourcingTimeoutOpt)
   612  
   613  	cp = ts.Spawn("history")
   614  	cp.Expect("pytest")
   615  	cp.Expect("7.4.0")
   616  	cp.ExpectExitCode(0)
   617  
   618  	cp = ts.Spawn("packages")
   619  	cp.Expect("pytest")
   620  	cp.Expect("7.4.0")
   621  	cp.ExpectExitCode(0)
   622  }
   623  
   624  func (suite *PackageIntegrationTestSuite) TestRuby() {
   625  	suite.OnlyRunForTags(tagsuite.Package)
   626  	ts := e2e.New(suite.T(), false)
   627  	defer ts.Close()
   628  
   629  	cp := ts.SpawnWithOpts(
   630  		e2e.OptArgs("checkout", "ActiveState-CLI-Testing/Ruby", "."),
   631  		e2e.OptAppendEnv(constants.DisableRuntime+"=false"),
   632  	)
   633  	cp.ExpectExitCode(0, e2e.RuntimeSourcingTimeoutOpt)
   634  
   635  	cp = ts.SpawnWithOpts(
   636  		e2e.OptArgs("install", "rake"),
   637  		e2e.OptAppendEnv(constants.DisableRuntime+"=false"),
   638  	)
   639  	cp.ExpectExitCode(0, e2e.RuntimeSourcingTimeoutOpt)
   640  
   641  	cp = ts.SpawnWithOpts(
   642  		e2e.OptArgs("exec", "rake", "--", "--version"),
   643  		e2e.OptAppendEnv(constants.DisableRuntime+"=false"),
   644  	)
   645  	cp.ExpectRe(`rake, version \d+\.\d+\.\d+`)
   646  	cp.ExpectExitCode(0)
   647  }
   648  
   649  // TestProjectWithOfflineInstallerAndDocker just makes sure we can checkout and install/uninstall
   650  // packages for projects with offline installers and docker runtimes.
   651  func (suite *PackageIntegrationTestSuite) TestProjectWithOfflineInstallerAndDocker() {
   652  	suite.OnlyRunForTags(tagsuite.Package)
   653  	ts := e2e.New(suite.T(), false)
   654  	defer ts.Close()
   655  
   656  	ts.LoginAsPersistentUser() // needed for Enterprise-tier features
   657  
   658  	cp := ts.Spawn("checkout", "ActiveState-CLI/Python-OfflineInstaller-Docker", ".")
   659  	cp.Expect("Skipping runtime setup")
   660  	cp.Expect("Checked out project")
   661  	cp.ExpectExitCode(0)
   662  }
   663  
   664  func (suite *PackageIntegrationTestSuite) TestResolved() {
   665  	suite.OnlyRunForTags(tagsuite.Package)
   666  	ts := e2e.New(suite.T(), false)
   667  	defer ts.Close()
   668  
   669  	cp := ts.Spawn("checkout", "ActiveState-CLI/small-python", ".")
   670  	cp.Expect("Skipping runtime setup")
   671  	cp.Expect("Checked out project")
   672  	cp.ExpectExitCode(0)
   673  
   674  	cp = ts.SpawnWithOpts(
   675  		e2e.OptArgs("install", "requests"),
   676  		e2e.OptAppendEnv(constants.DisableRuntime+"=false"),
   677  	)
   678  	cp.ExpectExitCode(0)
   679  
   680  	cp = ts.Spawn("packages")
   681  	cp.Expect("Auto →")
   682  	cp.ExpectExitCode(0)
   683  }
   684  
   685  func (suite *PackageIntegrationTestSuite) TestCVE_NoPrompt() {
   686  	suite.OnlyRunForTags(tagsuite.Package)
   687  	ts := e2e.New(suite.T(), false)
   688  	defer ts.Close()
   689  
   690  	ts.LoginAsPersistentUser()
   691  
   692  	cp := ts.Spawn("checkout", "ActiveState-CLI/small-python", ".")
   693  	cp.Expect("Skipping runtime setup")
   694  	cp.Expect("Checked out project")
   695  	cp.ExpectExitCode(0)
   696  
   697  	cp = ts.SpawnWithOpts(
   698  		e2e.OptArgs("install", "urllib3@2.0.2"),
   699  		e2e.OptAppendEnv(constants.DisableRuntime+"=false"),
   700  	)
   701  	cp.Expect("Warning: Dependency has 2 known vulnerabilities")
   702  	cp.ExpectExitCode(0)
   703  }
   704  
   705  func (suite *PackageIntegrationTestSuite) TestCVE_Prompt() {
   706  	suite.OnlyRunForTags(tagsuite.Package)
   707  	ts := e2e.New(suite.T(), false)
   708  	defer ts.Close()
   709  
   710  	ts.LoginAsPersistentUser()
   711  
   712  	cp := ts.Spawn("checkout", "ActiveState-CLI/small-python", ".")
   713  	cp.Expect("Skipping runtime setup")
   714  	cp.Expect("Checked out project")
   715  	cp.ExpectExitCode(0)
   716  
   717  	cp = ts.Spawn("config", "set", "security.prompt.level", "high")
   718  	cp.ExpectExitCode(0)
   719  
   720  	cp = ts.Spawn("config", "set", "security.prompt.enabled", "true")
   721  	cp.ExpectExitCode(0)
   722  
   723  	cp = ts.SpawnWithOpts(
   724  		e2e.OptArgs("install", "urllib3@2.0.2"),
   725  		e2e.OptAppendEnv(constants.DisableRuntime+"=false"),
   726  	)
   727  	cp.Expect("Warning: Dependency has 2 known vulnerabilities")
   728  	cp.Expect("Do you want to continue")
   729  	cp.SendLine("y")
   730  	cp.ExpectExitCode(0)
   731  
   732  	cp = ts.Spawn("config", "set", "security.prompt.enabled", "false")
   733  	cp.ExpectExitCode(0)
   734  }
   735  
   736  func (suite *PackageIntegrationTestSuite) TestCVE_Indirect() {
   737  	suite.OnlyRunForTags(tagsuite.Package)
   738  	ts := e2e.New(suite.T(), false)
   739  	defer ts.Close()
   740  
   741  	ts.LoginAsPersistentUser()
   742  
   743  	cp := ts.Spawn("checkout", "ActiveState-CLI/small-python", ".")
   744  	cp.Expect("Skipping runtime setup")
   745  	cp.Expect("Checked out project")
   746  	cp.ExpectExitCode(0)
   747  
   748  	cp = ts.SpawnWithOpts(
   749  		e2e.OptArgs("install", "private/ActiveState-CLI-Testing/language/python:django_dep", "--ts=now"),
   750  		e2e.OptAppendEnv(constants.DisableRuntime+"=false"),
   751  	)
   752  	cp.ExpectRe(`Warning: Dependency has \d indirect known vulnerabilities`, e2e.RuntimeSourcingTimeoutOpt)
   753  	cp.Expect("Do you want to continue")
   754  	cp.SendLine("n")
   755  	cp.ExpectExitCode(1)
   756  }
   757  
   758  func (suite *InstallIntegrationTestSuite) TestNamespace() {
   759  	suite.OnlyRunForTags(tagsuite.Install)
   760  	ts := e2e.New(suite.T(), false)
   761  	defer ts.Close()
   762  
   763  	ts.PrepareProject("ActiveState-CLI/small-python", "5a1e49e5-8ceb-4a09-b605-ed334474855b")
   764  	cp := ts.SpawnWithOpts(
   765  		e2e.OptArgs("install", "language/python:requests"),
   766  		e2e.OptAppendEnv(constants.DisableRuntime+"=false"),
   767  	)
   768  	cp.Expect("Package added: requests", e2e.RuntimeSourcingTimeoutOpt)
   769  	cp.ExpectExitCode(0)
   770  }
   771  
   772  func TestPackageIntegrationTestSuite(t *testing.T) {
   773  	suite.Run(t, new(PackageIntegrationTestSuite))
   774  }