github.com/ActiveState/cli@v0.0.0-20240508170324-6801f60cd051/test/integration/init_int_test.go (about) 1 package integration 2 3 import ( 4 "fmt" 5 "os" 6 "path/filepath" 7 "runtime" 8 "testing" 9 10 "github.com/ActiveState/cli/internal/assets" 11 "github.com/ActiveState/cli/internal/constants" 12 "github.com/ActiveState/cli/internal/fileutils" 13 "github.com/ActiveState/cli/internal/language" 14 "github.com/ActiveState/cli/internal/strutils" 15 "github.com/ActiveState/cli/internal/testhelpers/e2e" 16 "github.com/ActiveState/cli/internal/testhelpers/suite" 17 "github.com/ActiveState/cli/internal/testhelpers/tagsuite" 18 "github.com/ActiveState/cli/pkg/sysinfo" 19 ) 20 21 type InitIntegrationTestSuite struct { 22 tagsuite.Suite 23 } 24 25 func (suite *InitIntegrationTestSuite) TestInit() { 26 suite.OnlyRunForTags(tagsuite.Init, tagsuite.Critical) 27 suite.runInitTest(false, "python", "python3") 28 } 29 30 func (suite *InitIntegrationTestSuite) TestInit_Path() { 31 suite.OnlyRunForTags(tagsuite.Init) 32 suite.runInitTest(true, "python", "python3") 33 } 34 35 func (suite *InitIntegrationTestSuite) TestInit_DisambiguatePython() { 36 suite.OnlyRunForTags(tagsuite.Init) 37 suite.runInitTest(false, "python", "python3") 38 suite.runInitTest(false, "python@3.10.0", "python3") 39 suite.runInitTest(false, "python@2.7.18", "python2") 40 } 41 42 func (suite *InitIntegrationTestSuite) TestInit_PartialVersions() { 43 suite.OnlyRunForTags(tagsuite.Init) 44 suite.runInitTest(false, "python@3.10", "python3") 45 suite.runInitTest(false, "python@3.10.x", "python3") 46 suite.runInitTest(false, "python@>=3", "python3") 47 suite.runInitTest(false, "python@2", "python2") 48 } 49 50 func (suite *InitIntegrationTestSuite) runInitTest(addPath bool, lang string, expectedConfigLanguage string, args ...string) { 51 ts := e2e.New(suite.T(), false) 52 defer ts.Close() 53 ts.LoginAsPersistentUser() 54 55 // Generate a new namespace for the project to be created. 56 pname := strutils.UUID() 57 namespace := fmt.Sprintf("%s/%s", e2e.PersistentUsername, pname) 58 computedArgs := append([]string{"init", "--language", lang, namespace}, args...) 59 if addPath { 60 computedArgs = append(computedArgs, ts.Dirs.Work) 61 } 62 63 // Run `state init`, creating the project. 64 cp := ts.Spawn(computedArgs...) 65 cp.Expect("Initializing Project") 66 cp.Expect("Skipping runtime setup") 67 cp.Expect(fmt.Sprintf("Project '%s' has been successfully initialized", namespace)) 68 cp.ExpectExitCode(0) 69 ts.NotifyProjectCreated(e2e.PersistentUsername, pname.String()) 70 71 // Verify the config template contains the correct shell, language, and content. 72 configFilepath := filepath.Join(ts.Dirs.Work, constants.ConfigFileName) 73 suite.Require().FileExists(configFilepath) 74 75 templateFile, err := assets.ReadFileBytes("activestate.yaml.python.tpl") 76 if err != nil { 77 panic(err.Error()) 78 } 79 shell := "bash" 80 if runtime.GOOS == "windows" { 81 shell = "batch" 82 } 83 yaml, err := strutils.ParseTemplate( 84 string(templateFile), 85 map[string]interface{}{ 86 "Owner": e2e.PersistentUsername, 87 "Project": pname.String(), 88 "Shell": shell, 89 "Language": expectedConfigLanguage, 90 "LangExe": language.MakeByName(expectedConfigLanguage).Executable().Filename(), 91 }, nil) 92 suite.Require().NoError(err) 93 94 content, err := os.ReadFile(configFilepath) 95 suite.Require().NoError(err) 96 suite.Contains(string(content), yaml) 97 } 98 99 func (suite *InitIntegrationTestSuite) TestInit_NoLanguage() { 100 suite.OnlyRunForTags(tagsuite.Init) 101 ts := e2e.New(suite.T(), false) 102 defer ts.Close() 103 104 cp := ts.Spawn("init", "test-user/test-project") 105 cp.ExpectNotExitCode(0) 106 ts.IgnoreLogErrors() 107 } 108 109 func (suite *InitIntegrationTestSuite) TestInit_InferLanguageFromUse() { 110 suite.OnlyRunForTags(tagsuite.Init) 111 ts := e2e.New(suite.T(), false) 112 defer ts.Close() 113 ts.LoginAsPersistentUser() 114 115 cp := ts.Spawn("checkout", "ActiveState-CLI/Python3") 116 cp.Expect("Skipping runtime setup") 117 cp.Expect("Checked out project") 118 cp.ExpectExitCode(0) 119 120 cp = ts.SpawnWithOpts( 121 e2e.OptArgs("use", "Python3"), 122 e2e.OptAppendEnv(constants.DisableRuntime+"=false"), 123 ) 124 cp.Expect("Switched to project", e2e.RuntimeSourcingTimeoutOpt) 125 cp.ExpectExitCode(0) 126 127 pname := strutils.UUID() 128 namespace := fmt.Sprintf("%s/%s", e2e.PersistentUsername, pname) 129 cp = ts.Spawn("init", namespace) 130 cp.Expect("Skipping runtime setup") 131 cp.Expect("successfully initialized") 132 cp.ExpectExitCode(0) 133 ts.NotifyProjectCreated(e2e.PersistentUsername, pname.String()) 134 135 suite.Contains(string(fileutils.ReadFileUnsafe(filepath.Join(ts.Dirs.Work, constants.ConfigFileName))), "language: python3") 136 } 137 138 func (suite *InitIntegrationTestSuite) TestInit_NotAuthenticated() { 139 suite.OnlyRunForTags(tagsuite.Init) 140 ts := e2e.New(suite.T(), false) 141 defer ts.Close() 142 143 cp := ts.Spawn("init", "test-user/test-project", "python3") 144 cp.Expect("You need to be authenticated to initialize a project.") 145 } 146 147 func (suite *InitIntegrationTestSuite) TestInit_AlreadyExists() { 148 suite.OnlyRunForTags(tagsuite.Init) 149 ts := e2e.New(suite.T(), false) 150 defer ts.Close() 151 ts.LoginAsPersistentUser() 152 153 cp := ts.Spawn("init", fmt.Sprintf("%s/test-project", e2e.PersistentUsername), "--language", "python@3") 154 cp.Expect("The project 'test-project' already exists under 'cli-integration-tests'") 155 cp.ExpectExitCode(1) 156 } 157 158 func (suite *InitIntegrationTestSuite) TestInit_Resolved() { 159 suite.OnlyRunForTags(tagsuite.Init, tagsuite.Languages) 160 ts := e2e.New(suite.T(), false) 161 defer ts.Close() 162 ts.LoginAsPersistentUser() 163 164 // Generate a new namespace for the project to be created. 165 pname := strutils.UUID() 166 namespace := fmt.Sprintf("%s/%s", e2e.PersistentUsername, pname) 167 168 // Run `state init`, creating the project. 169 cp := ts.SpawnWithOpts( 170 e2e.OptArgs("init", namespace, "--language", "python@3.10"), 171 e2e.OptAppendEnv(constants.DisableRuntime+"=false"), 172 ) 173 cp.Expect(fmt.Sprintf("Project '%s' has been successfully initialized", namespace), e2e.RuntimeSourcingTimeoutOpt) 174 cp.ExpectExitCode(0) 175 ts.NotifyProjectCreated(e2e.PersistentUsername, pname.String()) 176 177 // Run `state languages` to verify a full language version was resolved. 178 cp = ts.Spawn("languages") 179 cp.Expect("python") 180 cp.Expect(">=3.10,<3.11 → 3.10.") // note: the patch version is variable, so just expect that it exists 181 cp.ExpectExitCode(0) 182 } 183 184 func (suite *InitIntegrationTestSuite) TestInit_NoOrg() { 185 suite.OnlyRunForTags(tagsuite.Init) 186 ts := e2e.New(suite.T(), false) 187 defer ts.Close() 188 ts.LoginAsPersistentUser() 189 190 cp := ts.Spawn("init", "random-org/test-project", "--language", "python@3") 191 cp.Expect("The organization 'random-org' either does not exist, or you do not have permissions to create a project in it.") 192 cp.ExpectExitCode(1) 193 } 194 195 func (suite *InitIntegrationTestSuite) TestInit_InferredOrg() { 196 suite.OnlyRunForTags(tagsuite.Init) 197 ts := e2e.New(suite.T(), false) 198 defer ts.Close() 199 ts.LoginAsPersistentUser() 200 ts.IgnoreLogErrors() 201 202 org := "ActiveState-CLI" 203 projectName := fmt.Sprintf("test-project-%s", sysinfo.OS().String()) 204 205 // First, checkout project to set last used org. 206 cp := ts.Spawn("checkout", fmt.Sprintf("%s/Python3", org)) 207 cp.Expect("Skipping runtime setup") 208 cp.Expect("Checked out project") 209 210 // Now, run `state init` without specifying the org. 211 cp = ts.Spawn("init", projectName, "--language", "python@3") 212 cp.Expect(fmt.Sprintf("%s/%s", org, projectName)) 213 cp.Expect("to track changes for this environment") 214 cp.Expect("successfully initialized") 215 cp.ExpectExitCode(0) 216 ts.NotifyProjectCreated(org, projectName) 217 218 // Verify the config file has the correct project owner. 219 suite.Contains(string(fileutils.ReadFileUnsafe(filepath.Join(ts.Dirs.Work, constants.ConfigFileName))), "ActiveState-CLI") 220 } 221 222 func TestInitIntegrationTestSuite(t *testing.T) { 223 suite.Run(t, new(InitIntegrationTestSuite)) 224 }