github.com/joshdk/godel@v0.0.0-20170529232908-862138a45aee/apps/distgo/cmd/run/run_test.go (about) 1 // Copyright 2016 Palantir Technologies, Inc. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package run_test 16 17 import ( 18 "fmt" 19 "io/ioutil" 20 "os" 21 "path" 22 "regexp" 23 "strings" 24 "testing" 25 26 "github.com/nmiyake/pkg/dirs" 27 "github.com/stretchr/testify/assert" 28 "github.com/stretchr/testify/require" 29 30 "github.com/palantir/godel/apps/distgo/cmd/run" 31 "github.com/palantir/godel/apps/distgo/params" 32 "github.com/palantir/godel/apps/distgo/pkg/git" 33 ) 34 35 const ( 36 runTestMain = `package main 37 38 import ( 39 "fmt" 40 "io/ioutil" 41 "os" 42 "path" 43 ) 44 45 func main() { 46 fmt.Println("testMainOutput") 47 ioutil.WriteFile(path.Join("{{OUTPUT_PATH}}", "runTestMainOutput.txt"), []byte(fmt.Sprintf("%v", os.Args[1:])), 0644) 48 } 49 ` 50 runTestMainBar = `package main 51 52 import ( 53 "fmt" 54 "io/ioutil" 55 "os" 56 "path" 57 ) 58 59 func main() { 60 bar("testMainOutput") 61 ioutil.WriteFile(path.Join("{{OUTPUT_PATH}}", "runTestMainOutput.txt"), []byte(fmt.Sprintf("%v", os.Args[1:])), 0644) 62 } 63 ` 64 ) 65 66 func TestRun(t *testing.T) { 67 tmp, cleanup, err := dirs.TempDir("", "") 68 defer cleanup() 69 require.NoError(t, err) 70 71 for i, currCase := range []struct { 72 spec func(projectDir string) params.ProductBuildSpec 73 runArgs []string 74 preRunAction func(projectDir string) 75 validate func(runErr error, caseNum int, projectDir string) 76 }{ 77 { 78 // "run" runs main file 79 spec: func(projectDir string) params.ProductBuildSpec { 80 return params.NewProductBuildSpec( 81 projectDir, 82 "foo", 83 git.ProjectInfo{}, 84 params.Product{ 85 Build: params.Build{ 86 MainPkg: "./.", 87 }, 88 }, 89 params.Project{}, 90 ) 91 }, 92 preRunAction: func(projectDir string) { 93 err := ioutil.WriteFile(path.Join(projectDir, "main.go"), []byte(strings.Replace(runTestMain, "{{OUTPUT_PATH}}", projectDir, -1)), 0644) 94 require.NoError(t, err) 95 }, 96 validate: func(runErr error, caseNum int, projectDir string) { 97 assert.NoError(t, runErr, "Case %d", caseNum) 98 bytes, err := ioutil.ReadFile(path.Join(projectDir, "runTestMainOutput.txt")) 99 require.NoError(t, err, "Case %d", caseNum) 100 assert.Equal(t, "[]", string(bytes)) 101 }, 102 }, 103 { 104 // "run" uses arguments provided in configuration (but does not evaluate them) 105 spec: func(projectDir string) params.ProductBuildSpec { 106 return params.NewProductBuildSpec( 107 projectDir, 108 "foo", 109 git.ProjectInfo{}, 110 params.Product{ 111 Build: params.Build{ 112 MainPkg: "./.", 113 }, 114 Run: params.Run{ 115 Args: []string{ 116 "foo", 117 "bar", 118 "$GOPATH", 119 }, 120 }, 121 }, 122 params.Project{}, 123 ) 124 }, 125 preRunAction: func(projectDir string) { 126 err := ioutil.WriteFile(path.Join(projectDir, "main.go"), []byte(strings.Replace(runTestMain, "{{OUTPUT_PATH}}", projectDir, -1)), 0644) 127 require.NoError(t, err) 128 }, 129 validate: func(runErr error, caseNum int, projectDir string) { 130 assert.NoError(t, runErr, "Case %d", caseNum) 131 bytes, err := ioutil.ReadFile(path.Join(projectDir, "runTestMainOutput.txt")) 132 require.NoError(t, err, "Case %d", caseNum) 133 assert.Equal(t, "[foo bar $GOPATH]", string(bytes)) 134 }, 135 }, 136 { 137 // "run" uses arguments provided in slice 138 spec: func(projectDir string) params.ProductBuildSpec { 139 return params.NewProductBuildSpec( 140 projectDir, 141 "foo", 142 git.ProjectInfo{}, 143 params.Product{ 144 Build: params.Build{ 145 MainPkg: "./.", 146 }, 147 }, 148 params.Project{}, 149 ) 150 }, 151 runArgs: []string{"foo", "bar", "$GOPATH"}, 152 preRunAction: func(projectDir string) { 153 err := ioutil.WriteFile(path.Join(projectDir, "main.go"), []byte(strings.Replace(runTestMain, "{{OUTPUT_PATH}}", projectDir, -1)), 0644) 154 require.NoError(t, err) 155 }, 156 validate: func(runErr error, caseNum int, projectDir string) { 157 assert.NoError(t, runErr, "Case %d", caseNum) 158 bytes, err := ioutil.ReadFile(path.Join(projectDir, "runTestMainOutput.txt")) 159 require.NoError(t, err, "Case %d", caseNum) 160 assert.Equal(t, "[foo bar $GOPATH]", string(bytes)) 161 }, 162 }, 163 { 164 // "run" combines arguments in configuration with provided arguments 165 spec: func(projectDir string) params.ProductBuildSpec { 166 return params.NewProductBuildSpec( 167 projectDir, 168 "foo", 169 git.ProjectInfo{}, 170 params.Product{ 171 Build: params.Build{ 172 MainPkg: "./.", 173 }, 174 Run: params.Run{ 175 Args: []string{ 176 "cfgArg_foo", 177 "cfgArg_bar", 178 "$cfgArg", 179 }, 180 }, 181 }, 182 params.Project{}, 183 ) 184 }, 185 runArgs: []string{"runArg_foo", "runArg_bar", "$runArg"}, 186 preRunAction: func(projectDir string) { 187 err := ioutil.WriteFile(path.Join(projectDir, "main.go"), []byte(strings.Replace(runTestMain, "{{OUTPUT_PATH}}", projectDir, -1)), 0644) 188 require.NoError(t, err) 189 }, 190 validate: func(runErr error, caseNum int, projectDir string) { 191 assert.NoError(t, runErr, "Case %d", caseNum) 192 bytes, err := ioutil.ReadFile(path.Join(projectDir, "runTestMainOutput.txt")) 193 require.NoError(t, err, "Case %d", caseNum) 194 assert.Equal(t, "[cfgArg_foo cfgArg_bar $cfgArg runArg_foo runArg_bar $runArg]", string(bytes)) 195 }, 196 }, 197 { 198 // "run" works with multiple main package files as long as there is a single main function 199 spec: func(projectDir string) params.ProductBuildSpec { 200 return params.NewProductBuildSpec( 201 projectDir, 202 "foo", 203 git.ProjectInfo{}, 204 params.Product{ 205 Build: params.Build{ 206 MainPkg: "./foo", 207 }, 208 }, 209 params.Project{}, 210 ) 211 }, 212 preRunAction: func(projectDir string) { 213 err := os.MkdirAll(path.Join(projectDir, "foo"), 0755) 214 require.NoError(t, err) 215 216 err = ioutil.WriteFile(path.Join(projectDir, "foo", "main_file.go"), []byte(strings.Replace(runTestMainBar, "{{OUTPUT_PATH}}", projectDir, -1)), 0644) 217 require.NoError(t, err) 218 err = ioutil.WriteFile(path.Join(projectDir, "foo", "other_main_file.go"), []byte(`package main 219 import "fmt" 220 func bar(a ...interface{}) (n int, err error) { 221 return fmt.Println(a...) 222 } 223 `), 0644) 224 require.NoError(t, err) 225 err = ioutil.WriteFile(path.Join(projectDir, "foo", "main_test.go"), []byte(`package main_test 226 func Bar() string { 227 return "bar" 228 } 229 `), 0644) 230 require.NoError(t, err) 231 }, 232 validate: func(runErr error, caseNum int, projectDir string) { 233 assert.NoError(t, runErr, "Case %d", caseNum) 234 bytes, err := ioutil.ReadFile(path.Join(projectDir, "runTestMainOutput.txt")) 235 require.NoError(t, err, "Case %d", caseNum) 236 assert.Equal(t, "[]", string(bytes)) 237 }, 238 }, 239 { 240 // "run" works with multiple main package files with tests 241 spec: func(projectDir string) params.ProductBuildSpec { 242 return params.NewProductBuildSpec( 243 projectDir, 244 "foo", 245 git.ProjectInfo{}, 246 params.Product{ 247 Build: params.Build{ 248 MainPkg: "./foo", 249 }, 250 }, 251 params.Project{}, 252 ) 253 }, 254 preRunAction: func(projectDir string) { 255 err := os.MkdirAll(path.Join(projectDir, "foo"), 0755) 256 require.NoError(t, err) 257 258 err = ioutil.WriteFile(path.Join(projectDir, "foo", "main_file.go"), []byte(strings.Replace(runTestMain, "{{OUTPUT_PATH}}", projectDir, -1)), 0644) 259 require.NoError(t, err) 260 err = ioutil.WriteFile(path.Join(projectDir, "foo", "main_test.go"), []byte(`package main 261 import "testing" 262 func TestBar(t *testing.T) { 263 } 264 `), 0644) 265 require.NoError(t, err) 266 }, 267 validate: func(runErr error, caseNum int, projectDir string) { 268 assert.NoError(t, runErr, "Case %d", caseNum) 269 bytes, err := ioutil.ReadFile(path.Join(projectDir, "runTestMainOutput.txt")) 270 require.NoError(t, err, "Case %d", caseNum) 271 assert.Equal(t, "[]", string(bytes)) 272 }, 273 }, 274 { 275 // "run" fails if a main package does not exist 276 spec: func(projectDir string) params.ProductBuildSpec { 277 return params.NewProductBuildSpec( 278 projectDir, 279 "foo", 280 git.ProjectInfo{}, 281 params.Product{ 282 Build: params.Build{ 283 MainPkg: "./foo", 284 }, 285 }, 286 params.Project{}, 287 ) 288 }, 289 preRunAction: func(projectDir string) { 290 err := os.MkdirAll(path.Join(projectDir, "foo"), 0755) 291 require.NoError(t, err) 292 293 err = ioutil.WriteFile(path.Join(projectDir, "foo", "not_main_pkg.go"), []byte(`package foo 294 func main() { 295 } 296 `), 0644) 297 require.NoError(t, err) 298 }, 299 validate: func(runErr error, caseNum int, projectDir string) { 300 assert.Error(t, runErr, fmt.Sprintf("Case %d", caseNum)) 301 assert.Regexp(t, regexp.MustCompile(`^failed to find main file: no go file with main package and main function exists in directory .+/foo$`), runErr.Error(), "Case %d", caseNum) 302 }, 303 }, 304 { 305 // "run" fails if main function does not exist in a main pkg 306 spec: func(projectDir string) params.ProductBuildSpec { 307 return params.NewProductBuildSpec( 308 projectDir, 309 "foo", 310 git.ProjectInfo{}, 311 params.Product{ 312 Build: params.Build{ 313 MainPkg: "./foo", 314 }, 315 }, 316 params.Project{}, 317 ) 318 }, 319 preRunAction: func(projectDir string) { 320 err := os.MkdirAll(path.Join(projectDir, "foo"), 0755) 321 require.NoError(t, err) 322 323 err = ioutil.WriteFile(path.Join(projectDir, "foo", "no_main_func.go"), []byte(`package main 324 func Foo() string { 325 return "foo" 326 } 327 `), 0644) 328 require.NoError(t, err) 329 330 err = ioutil.WriteFile(path.Join(projectDir, "foo", "main_func_not_main_pkg.go"), []byte(`package main_test 331 func main() { 332 } 333 `), 0644) 334 require.NoError(t, err) 335 }, 336 validate: func(runErr error, caseNum int, projectDir string) { 337 assert.Error(t, runErr, fmt.Sprintf("Case %d", caseNum)) 338 assert.Regexp(t, regexp.MustCompile(`^failed to find main file: no go file with main package and main function exists in directory .+/foo$`), runErr.Error(), "Case %d", caseNum) 339 }, 340 }, 341 } { 342 currTmpDir, err := ioutil.TempDir(tmp, "") 343 require.NoError(t, err, "Case %d", i) 344 345 if currCase.preRunAction != nil { 346 currCase.preRunAction(currTmpDir) 347 } 348 349 err = run.DoRun(currCase.spec(currTmpDir), currCase.runArgs, ioutil.Discard, ioutil.Discard) 350 if currCase.validate != nil { 351 currCase.validate(err, i, currTmpDir) 352 } 353 } 354 }