github.com/arunkumar7540/cli@v6.45.0+incompatible/integration/v6/isolated/verbose_flag_test.go (about) 1 package isolated 2 3 import ( 4 "io/ioutil" 5 "os" 6 "path/filepath" 7 "runtime" 8 "strconv" 9 "strings" 10 11 "code.cloudfoundry.org/cli/integration/helpers" 12 "code.cloudfoundry.org/cli/util/configv3" 13 . "github.com/onsi/ginkgo" 14 . "github.com/onsi/ginkgo/extensions/table" 15 . "github.com/onsi/gomega" 16 . "github.com/onsi/gomega/gbytes" 17 . "github.com/onsi/gomega/gexec" 18 ) 19 20 var _ = Describe("Verbose", func() { 21 Context("v2 legacy", func() { 22 DescribeTable("displays verbose output", 23 func(command func() *Session) { 24 helpers.LoginCF() 25 26 session := command() 27 Eventually(session).Should(Say("REQUEST:")) 28 Eventually(session).Should(Say("GET /v2/organizations")) 29 Eventually(session).Should(Say("RESPONSE:")) 30 Eventually(session).Should(Exit(0)) 31 }, 32 33 Entry("when the -v option is provided with additional command", func() *Session { 34 return helpers.CF("-v", "orgs") 35 }), 36 37 Entry("when the CF_TRACE env variable is set", func() *Session { 38 return helpers.CFWithEnv(map[string]string{"CF_TRACE": "true"}, "orgs") 39 }), 40 ) 41 }) 42 43 Context("v2 refactor", func() { 44 DescribeTable("displays verbose output to terminal", 45 func(env string, configTrace string, flag bool) { 46 tmpDir, err := ioutil.TempDir("", "") 47 defer os.RemoveAll(tmpDir) 48 Expect(err).NotTo(HaveOccurred()) 49 50 helpers.LoginCF() 51 helpers.TargetOrgAndSpace(ReadOnlyOrg, ReadOnlySpace) 52 53 var envMap map[string]string 54 if env != "" { 55 if string(env[0]) == "/" { 56 env = filepath.Join(tmpDir, env) 57 } 58 envMap = map[string]string{"CF_TRACE": env} 59 } 60 61 // We use 'create-user' because it makes a request via the UAA client 62 // and a request via the CC client, testing the logging wrapper in both 63 // clients. 64 randomUsername := helpers.NewUsername() 65 randomPassword := helpers.NewPassword() 66 command := []string{"create-user", randomUsername, randomPassword} 67 68 if flag { 69 command = append(command, "-v") 70 } 71 72 if configTrace != "" { 73 if string(configTrace[0]) == "/" { 74 configTrace = filepath.Join(tmpDir, configTrace) 75 } 76 session := helpers.CF("config", "--trace", configTrace) 77 Eventually(session).Should(Exit(0)) 78 } 79 80 session := helpers.CFWithEnv(envMap, command...) 81 82 Eventually(session).Should(Say("REQUEST:")) 83 Eventually(session).Should(Say("GET /v2/info")) 84 Eventually(session).Should(Say("RESPONSE:")) 85 Eventually(session).Should(Say(`"token_endpoint": "http.*"`)) 86 Eventually(session).Should(Say("REQUEST:")) 87 Eventually(session).Should(Say("POST /Users")) 88 Eventually(session).Should(Say(`User-Agent: cf/[\w.+-]+ \(go\d+\.\d+(\.\d+)?; %s %s\)`, runtime.GOARCH, runtime.GOOS)) 89 Eventually(session).Should(Say("RESPONSE:")) 90 Eventually(session).Should(Say("REQUEST:")) 91 Eventually(session).Should(Say("POST /v2/users")) 92 Eventually(session).Should(Say(`User-Agent: cf/[\w.+-]+ \(go\d+\.\d+(\.\d+)?; %s %s\)`, runtime.GOARCH, runtime.GOOS)) 93 Eventually(session).Should(Say("RESPONSE:")) 94 Eventually(session).Should(Exit(0)) 95 }, 96 97 Entry("CF_TRACE true: enables verbose", "true", "", false), 98 Entry("CF_TRACE true, config trace false: enables verbose", "true", "false", false), 99 Entry("CF_TRACE true, config trace file path: enables verbose AND logging to file", "true", "/foo", false), 100 101 Entry("CF_TRACE false, '-v': enables verbose", "false", "", true), 102 Entry("CF_TRACE false, config trace file path, '-v': enables verbose AND logging to file", "false", "/foo", true), 103 104 Entry("CF_TRACE empty:, '-v': enables verbose", "", "", true), 105 Entry("CF_TRACE empty, config trace true: enables verbose", "", "true", false), 106 Entry("CF_TRACE empty, config trace file path, '-v': enables verbose AND logging to file", "", "/foo", true), 107 108 Entry("CF_TRACE filepath, '-v': enables logging to file", "/foo", "", true), 109 Entry("CF_TRACE filepath, config trace true: enables verbose AND logging to file", "/foo", "true", false), 110 Entry("CF_TRACE filepath, config trace filepath, '-v': enables verbose AND logging to file for BOTH paths", "/foo", "/bar", true), 111 ) 112 113 DescribeTable("displays verbose output to multiple files", 114 func(env string, configTrace string, flag bool, location []string) { 115 tmpDir, err := ioutil.TempDir("", "") 116 defer os.RemoveAll(tmpDir) 117 Expect(err).NotTo(HaveOccurred()) 118 119 helpers.LoginCF() 120 helpers.TargetOrgAndSpace(ReadOnlyOrg, ReadOnlySpace) 121 122 var envMap map[string]string 123 if env != "" { 124 if string(env[0]) == "/" { 125 env = filepath.Join(tmpDir, env) 126 } 127 envMap = map[string]string{"CF_TRACE": env} 128 } 129 130 // We use 'create-user' because it makes a request via the UAA client 131 // and a request via the CC client, testing the logging wrapper in both 132 // clients. 133 randomUsername := helpers.NewUsername() 134 randomPassword := helpers.NewPassword() 135 command := []string{"create-user", randomUsername, randomPassword} 136 137 if flag { 138 command = append(command, "-v") 139 } 140 141 if configTrace != "" { 142 if string(configTrace[0]) == "/" { 143 configTrace = filepath.Join(tmpDir, configTrace) 144 } 145 session := helpers.CF("config", "--trace", configTrace) 146 Eventually(session).Should(Exit(0)) 147 } 148 149 session := helpers.CFWithEnv(envMap, command...) 150 Eventually(session).Should(Exit(0)) 151 152 for _, filePath := range location { 153 contents, err := ioutil.ReadFile(tmpDir + filePath) 154 Expect(err).ToNot(HaveOccurred()) 155 156 Expect(string(contents)).To(MatchRegexp("REQUEST:")) 157 Expect(string(contents)).To(MatchRegexp("POST /Users")) 158 Expect(string(contents)).To(MatchRegexp("RESPONSE:")) 159 Expect(string(contents)).To(MatchRegexp("REQUEST:")) 160 Expect(string(contents)).To(MatchRegexp("POST /v2/users")) 161 Expect(string(contents)).To(MatchRegexp("RESPONSE:")) 162 163 stat, err := os.Stat(tmpDir + filePath) 164 Expect(err).ToNot(HaveOccurred()) 165 166 if runtime.GOOS == "windows" { 167 Expect(stat.Mode().String()).To(Equal(os.FileMode(0666).String())) 168 } else { 169 Expect(stat.Mode().String()).To(Equal(os.FileMode(0600).String())) 170 } 171 } 172 }, 173 174 Entry("CF_Trace true, config trace file path: enables verbose AND logging to file", "true", "/foo", false, []string{"/foo"}), 175 176 Entry("CF_TRACE false, config trace file path: enables logging to file", "false", "/foo", false, []string{"/foo"}), 177 Entry("CF_TRACE false, config trace file path, '-v': enables verbose AND logging to file", "false", "/foo", true, []string{"/foo"}), 178 179 Entry("CF_TRACE empty, config trace file path: enables logging to file", "", "/foo", false, []string{"/foo"}), 180 Entry("CF_TRACE empty, config trace file path, '-v': enables verbose AND logging to file", "", "/foo", true, []string{"/foo"}), 181 182 Entry("CF_TRACE filepath: enables logging to file", "/foo", "", false, []string{"/foo"}), 183 Entry("CF_TRACE filepath, '-v': enables logging to file", "/foo", "", true, []string{"/foo"}), 184 Entry("CF_TRACE filepath, config trace true: enables verbose AND logging to file", "/foo", "true", false, []string{"/foo"}), 185 Entry("CF_TRACE filepath, config trace filepath: enables logging to file for BOTH paths", "/foo", "/bar", false, []string{"/foo", "/bar"}), 186 Entry("CF_TRACE filepath, config trace filepath, '-v': enables verbose AND logging to file for BOTH paths", "/foo", "/bar", true, []string{"/foo", "/bar"}), 187 ) 188 }) 189 190 Context("v3", func() { 191 DescribeTable("displays verbose output to terminal", 192 func(env string, configTrace string, flag bool) { 193 tmpDir, err := ioutil.TempDir("", "") 194 defer os.RemoveAll(tmpDir) 195 Expect(err).NotTo(HaveOccurred()) 196 197 helpers.SetupCF(ReadOnlyOrg, ReadOnlySpace) 198 199 // Invalidate the access token to cause a token refresh in order to 200 // test the call to the UAA. 201 helpers.SetConfig(func(config *configv3.Config) { 202 config.ConfigFile.AccessToken = helpers.ExpiredAccessToken() 203 }) 204 205 var envMap map[string]string 206 if env != "" { 207 if string(env[0]) == "/" { 208 env = filepath.Join(tmpDir, env) 209 } 210 envMap = map[string]string{"CF_TRACE": env} 211 } 212 213 command := []string{"run-task", "app", "echo"} 214 215 if flag { 216 command = append(command, "-v") 217 } 218 219 if configTrace != "" { 220 if string(configTrace[0]) == "/" { 221 configTrace = filepath.Join(tmpDir, configTrace) 222 } 223 session := helpers.CF("config", "--trace", configTrace) 224 Eventually(session).Should(Exit(0)) 225 } 226 227 session := helpers.CFWithEnv(envMap, command...) 228 // implicit access token refresh 229 Eventually(session).Should(Say("REQUEST:")) 230 Eventually(session).Should(Say("POST /oauth/token")) 231 Eventually(session).Should(Say(`User-Agent: cf/[\w.+-]+ \(go\d+\.\d+(\.\d+)?; %s %s\)`, runtime.GOARCH, runtime.GOOS)) 232 Eventually(session).Should(Say(`\[PRIVATE DATA HIDDEN\]`)) //This is required to test the previous line. If it fails, the previous matcher went too far. 233 Eventually(session).Should(Say("RESPONSE:")) 234 // actual request 235 Eventually(session).Should(Say("REQUEST:")) 236 Eventually(session).Should(Say("GET /v3/apps")) 237 Eventually(session).Should(Say(`User-Agent: cf/[\w.+-]+ \(go\d+\.\d+(\.\d+)?; %s %s\)`, runtime.GOARCH, runtime.GOOS)) 238 Eventually(session).Should(Say("RESPONSE:")) 239 240 Eventually(session).Should(Exit(1)) 241 }, 242 243 Entry("CF_TRACE true: enables verbose", "true", "", false), 244 Entry("CF_Trace true, config trace false: enables verbose", "true", "false", false), 245 Entry("CF_Trace true, config trace file path: enables verbose AND logging to file", "true", "/foo", false), 246 247 Entry("CF_TRACE false, '-v': enables verbose", "false", "", true), 248 Entry("CF_TRACE false, config trace file path, '-v': enables verbose AND logging to file", "false", "/foo", true), 249 250 Entry("CF_TRACE empty:, '-v': enables verbose", "", "", true), 251 Entry("CF_TRACE empty, config trace true: enables verbose", "", "true", false), 252 Entry("CF_TRACE empty, config trace file path, '-v': enables verbose AND logging to file", "", "/foo", true), 253 254 Entry("CF_TRACE filepath, '-v': enables logging to file", "/foo", "", true), 255 Entry("CF_TRACE filepath, config trace true: enables verbose AND logging to file", "/foo", "true", false), 256 Entry("CF_TRACE filepath, config trace filepath, '-v': enables verbose AND logging to file for BOTH paths", "/foo", "/bar", true), 257 ) 258 259 DescribeTable("displays verbose output to multiple files", 260 func(env string, configTrace string, flag bool, location []string) { 261 tmpDir, err := ioutil.TempDir("", "") 262 defer os.RemoveAll(tmpDir) 263 Expect(err).NotTo(HaveOccurred()) 264 265 helpers.SetupCF(ReadOnlyOrg, ReadOnlySpace) 266 267 // Invalidate the access token to cause a token refresh in order to 268 // test the call to the UAA. 269 helpers.SetConfig(func(config *configv3.Config) { 270 config.ConfigFile.AccessToken = helpers.ExpiredAccessToken() 271 }) 272 273 var envMap map[string]string 274 if env != "" { 275 if string(env[0]) == "/" { 276 env = filepath.Join(tmpDir, env) 277 } 278 envMap = map[string]string{"CF_TRACE": env} 279 } 280 281 command := []string{"run-task", "app", "echo"} 282 283 if flag { 284 command = append(command, "-v") 285 } 286 287 if configTrace != "" { 288 if string(configTrace[0]) == "/" { 289 configTrace = filepath.Join(tmpDir, configTrace) 290 } 291 session := helpers.CF("config", "--trace", configTrace) 292 Eventually(session).Should(Exit(0)) 293 } 294 295 session := helpers.CFWithEnv(envMap, command...) 296 Eventually(session).Should(Exit(1)) 297 298 for _, filePath := range location { 299 contents, err := ioutil.ReadFile(tmpDir + filePath) 300 Expect(err).ToNot(HaveOccurred()) 301 302 Expect(string(contents)).To(MatchRegexp("REQUEST:")) 303 Expect(string(contents)).To(MatchRegexp("GET /v3/apps")) 304 Expect(string(contents)).To(MatchRegexp("RESPONSE:")) 305 Expect(string(contents)).To(MatchRegexp("REQUEST:")) 306 Expect(string(contents)).To(MatchRegexp("POST /oauth/token")) 307 Expect(string(contents)).To(MatchRegexp("RESPONSE:")) 308 309 stat, err := os.Stat(tmpDir + filePath) 310 Expect(err).ToNot(HaveOccurred()) 311 312 if runtime.GOOS == "windows" { 313 Expect(stat.Mode().String()).To(Equal(os.FileMode(0666).String())) 314 } else { 315 Expect(stat.Mode().String()).To(Equal(os.FileMode(0600).String())) 316 } 317 } 318 }, 319 320 Entry("CF_Trace true, config trace file path: enables verbose AND logging to file", "true", "/foo", false, []string{"/foo"}), 321 322 Entry("CF_TRACE false, config trace file path: enables logging to file", "false", "/foo", false, []string{"/foo"}), 323 Entry("CF_TRACE false, config trace file path, '-v': enables verbose AND logging to file", "false", "/foo", true, []string{"/foo"}), 324 325 Entry("CF_TRACE empty, config trace file path: enables logging to file", "", "/foo", false, []string{"/foo"}), 326 Entry("CF_TRACE empty, config trace file path, '-v': enables verbose AND logging to file", "", "/foo", true, []string{"/foo"}), 327 328 Entry("CF_TRACE filepath: enables logging to file", "/foo", "", false, []string{"/foo"}), 329 Entry("CF_TRACE filepath, '-v': enables logging to file", "/foo", "", true, []string{"/foo"}), 330 Entry("CF_TRACE filepath, config trace true: enables verbose AND logging to file", "/foo", "true", false, []string{"/foo"}), 331 Entry("CF_TRACE filepath, config trace filepath: enables logging to file for BOTH paths", "/foo", "/bar", false, []string{"/foo", "/bar"}), 332 Entry("CF_TRACE filepath, config trace filepath, '-v': enables verbose AND logging to file for BOTH paths", "/foo", "/bar", true, []string{"/foo", "/bar"}), 333 ) 334 }) 335 336 Describe("NOAA", func() { 337 var orgName string 338 339 BeforeEach(func() { 340 orgName = helpers.NewOrgName() 341 spaceName := helpers.NewSpaceName() 342 343 helpers.SetupCF(orgName, spaceName) 344 }) 345 346 AfterEach(func() { 347 Eventually(helpers.CF("config", "--trace", "false")).Should(Exit(0)) 348 helpers.QuickDeleteOrg(orgName) 349 }) 350 351 DescribeTable("displays verbose output to terminal", 352 func(env string, configTrace string, flag bool) { 353 tmpDir, err := ioutil.TempDir("", "") 354 defer os.RemoveAll(tmpDir) 355 Expect(err).NotTo(HaveOccurred()) 356 357 appName := helpers.PrefixedRandomName("app") 358 359 helpers.WithHelloWorldApp(func(appDir string) { 360 Eventually(helpers.CF("push", appName, "--no-start", "-p", appDir, "-b", "staticfile_buildpack", "--no-route")).Should(Exit(0)) 361 }) 362 363 var envMap map[string]string 364 if env != "" { 365 if string(env[0]) == "/" { 366 env = filepath.Join(tmpDir, env) 367 } 368 envMap = map[string]string{"CF_TRACE": env} 369 } 370 371 command := []string{"logs", appName} 372 373 if flag { 374 command = append(command, "-v") 375 } 376 377 if configTrace != "" { 378 if string(configTrace[0]) == "/" { 379 configTrace = filepath.Join(tmpDir, configTrace) 380 } 381 session := helpers.CF("config", "--trace", configTrace) 382 Eventually(session).Should(Exit(0)) 383 } 384 385 session := helpers.CFWithEnv(envMap, command...) 386 387 Eventually(session).Should(Say("REQUEST:")) 388 Eventually(session).Should(Say("GET /v2/info")) 389 Eventually(session).Should(Say("WEBSOCKET REQUEST:")) 390 Eventually(session).Should(Say(`Authorization: \[PRIVATE DATA HIDDEN\]`)) 391 Eventually(session.Kill()).Should(Exit()) 392 }, 393 394 Entry("CF_TRACE true: enables verbose", "true", "", false), 395 Entry("CF_Trace true, config trace false: enables verbose", "true", "false", false), 396 Entry("CF_Trace true, config trace file path: enables verbose AND logging to file", "true", "/foo", false), 397 398 Entry("CF_TRACE false, '-v': enables verbose", "false", "", true), 399 Entry("CF_TRACE false, config trace file path, '-v': enables verbose AND logging to file", "false", "/foo", true), 400 401 Entry("CF_TRACE empty:, '-v': enables verbose", "", "", true), 402 Entry("CF_TRACE empty, config trace true: enables verbose", "", "true", false), 403 Entry("CF_TRACE empty, config trace file path, '-v': enables verbose AND logging to file", "", "/foo", true), 404 405 Entry("CF_TRACE filepath, '-v': enables logging to file", "/foo", "", true), 406 Entry("CF_TRACE filepath, config trace true: enables verbose AND logging to file", "/foo", "true", false), 407 Entry("CF_TRACE filepath, config trace filepath, '-v': enables verbose AND logging to file for BOTH paths", "/foo", "/bar", true), 408 ) 409 410 DescribeTable("displays verbose output to multiple files", 411 func(env string, configTrace string, location []string) { 412 tmpDir, err := ioutil.TempDir("", "") 413 defer os.RemoveAll(tmpDir) 414 Expect(err).NotTo(HaveOccurred()) 415 416 appName := helpers.PrefixedRandomName("app") 417 418 helpers.WithHelloWorldApp(func(appDir string) { 419 Eventually(helpers.CF("push", appName, "--no-start", "-p", appDir, "-b", "staticfile_buildpack", "--no-route")).Should(Exit(0)) 420 }) 421 422 var envMap map[string]string 423 if env != "" { 424 if string(env[0]) == "/" { 425 env = filepath.Join(tmpDir, env) 426 } 427 envMap = map[string]string{"CF_TRACE": env} 428 } 429 430 if configTrace != "" { 431 if strings.HasPrefix(configTrace, "/") { 432 configTrace = filepath.Join(tmpDir, configTrace) 433 } 434 session := helpers.CF("config", "--trace", configTrace) 435 Eventually(session).Should(Exit(0)) 436 } 437 438 session := helpers.CFWithEnv(envMap, "logs", "-v", appName) 439 440 Eventually(session).Should(Say("WEBSOCKET RESPONSE")) 441 Eventually(session.Kill()).Should(Exit()) 442 443 for _, filePath := range location { 444 contents, err := ioutil.ReadFile(tmpDir + filePath) 445 Expect(err).ToNot(HaveOccurred()) 446 447 Expect(string(contents)).To(MatchRegexp("REQUEST:")) 448 Expect(string(contents)).To(MatchRegexp("GET /v2/info")) 449 Expect(string(contents)).To(MatchRegexp("WEBSOCKET REQUEST:")) 450 Expect(string(contents)).To(MatchRegexp(`Authorization: \[PRIVATE DATA HIDDEN\]`)) 451 452 stat, err := os.Stat(tmpDir + filePath) 453 Expect(err).ToNot(HaveOccurred()) 454 455 if runtime.GOOS == "windows" { 456 Expect(stat.Mode().String()).To(Equal(os.FileMode(0666).String())) 457 } else { 458 Expect(stat.Mode().String()).To(Equal(os.FileMode(0600).String())) 459 } 460 } 461 }, 462 463 Entry("CF_Trace true, config trace file path: enables verbose AND logging to file", "true", "/foo", []string{"/foo"}), 464 465 Entry("CF_TRACE false, config trace file path: enables logging to file", "false", "/foo", []string{"/foo"}), 466 Entry("CF_TRACE false, config trace file path, '-v': enables verbose AND logging to file", "false", "/foo", []string{"/foo"}), 467 468 Entry("CF_TRACE empty, config trace file path: enables logging to file", "", "/foo", []string{"/foo"}), 469 Entry("CF_TRACE empty, config trace file path, '-v': enables verbose AND logging to file", "", "/foo", []string{"/foo"}), 470 471 Entry("CF_TRACE filepath: enables logging to file", "/foo", "", []string{"/foo"}), 472 Entry("CF_TRACE filepath, '-v': enables logging to file", "/foo", "", []string{"/foo"}), 473 Entry("CF_TRACE filepath, config trace true: enables verbose AND logging to file", "/foo", "true", []string{"/foo"}), 474 Entry("CF_TRACE filepath, config trace filepath: enables logging to file for BOTH paths", "/foo", "/bar", []string{"/foo", "/bar"}), 475 Entry("CF_TRACE filepath, config trace filepath, '-v': enables verbose AND logging to file for BOTH paths", "/foo", "/bar", []string{"/foo", "/bar"}), 476 ) 477 }) 478 479 Describe("routing", func() { 480 BeforeEach(func() { 481 helpers.SkipIfNoRoutingAPI() 482 }) 483 484 When("the user does not provide the -v flag, the CF_TRACE env var, or the --trace config option", func() { 485 It("should not log requests", func() { 486 tmpDir, err := ioutil.TempDir("", "") 487 defer os.RemoveAll(tmpDir) 488 Expect(err).NotTo(HaveOccurred()) 489 490 helpers.LoginCF() 491 helpers.TargetOrgAndSpace(ReadOnlyOrg, ReadOnlySpace) 492 493 command := []string{"create-shared-domain", helpers.NewDomainName(), "--router-group", "default-tcp"} 494 495 session := helpers.CF(command...) 496 497 Consistently(session).ShouldNot(Say(`GET /routing/v1`)) 498 Eventually(session).Should(Exit(0)) 499 }) 500 }) 501 502 DescribeTable("verbose logging to stdout", 503 func(cfTraceEnvVar string, configTraceValue string, vFlagSet bool) { 504 tmpDir, err := ioutil.TempDir("", "") 505 defer os.RemoveAll(tmpDir) 506 Expect(err).NotTo(HaveOccurred()) 507 508 helpers.LoginCF() 509 helpers.TargetOrgAndSpace(ReadOnlyOrg, ReadOnlySpace) 510 511 var envTraceFile string 512 if _, err := strconv.ParseBool(cfTraceEnvVar); err != nil && len(cfTraceEnvVar) > 0 { 513 cfTraceEnvVar = filepath.Join(tmpDir, cfTraceEnvVar) 514 envTraceFile = cfTraceEnvVar 515 } 516 envMap := map[string]string{"CF_TRACE": cfTraceEnvVar} 517 518 command := []string{"create-shared-domain", helpers.NewDomainName(), "--router-group", "default-tcp"} 519 520 if vFlagSet { 521 command = append(command, "-v") 522 } 523 524 var configTraceFile string 525 if configTraceValue != "" { 526 if _, err := strconv.ParseBool(configTraceValue); err != nil && len(configTraceValue) > 0 { 527 configTraceValue = filepath.Join(tmpDir, configTraceValue) 528 configTraceFile = configTraceValue 529 } 530 session := helpers.CF("config", "--trace", configTraceValue) 531 Eventually(session).Should(Exit(0)) 532 } 533 534 session := helpers.CFWithEnv(envMap, command...) 535 536 Eventually(session).Should(Say(`GET /routing/v1/router_groups\?name=default-tcp`)) 537 Eventually(session).Should(Exit(0)) 538 539 if len(envTraceFile) > 0 { 540 assertLogsWrittenToFile(envTraceFile, "GET /routing/v1/router_groups?name=default-tcp") 541 } 542 543 if len(configTraceFile) > 0 { 544 assertLogsWrittenToFile(configTraceFile, "GET /routing/v1/router_groups?name=default-tcp") 545 } 546 }, 547 548 Entry("CF_TRACE=true, enables verbose", "true", "", false), 549 Entry("CF_TRACE=true, config trace false: enables verbose", "true", "false", false), 550 Entry("CF_TRACE=true, config trace file path: enables verbose AND logging to file", "true", "/foo", false), 551 552 Entry("CF_TRACE=false, '-v': enables verbose", "false", "", true), 553 Entry("CF_TRACE=false, config trace file path, '-v': enables verbose AND logging to file", "false", "/foo", true), 554 555 Entry("CF_TRACE unset, '-v': enables verbose", "", "", true), 556 Entry("CF_TRACE unset, config trace true: enables verbose", "", "true", false), 557 Entry("CF_TRACE unset, config trace file path, '-v': enables verbose AND logging to file", "", "/foo", true), 558 559 Entry("CF_TRACE=filepath, '-v': enables logging to file", "/foo", "", true), 560 Entry("CF_TRACE=filepath, config trace true: enables verbose AND logging to file", "/foo", "true", false), 561 ) 562 563 DescribeTable("verbose logging to a file", 564 func(cfTraceEnvVar string, configTraceValue string, vFlagSet bool) { 565 tmpDir, err := ioutil.TempDir("", "") 566 defer os.RemoveAll(tmpDir) 567 Expect(err).NotTo(HaveOccurred()) 568 569 helpers.LoginCF() 570 helpers.TargetOrgAndSpace(ReadOnlyOrg, ReadOnlySpace) 571 572 var envMap map[string]string 573 574 var envTraceFile string 575 if cfTraceEnvVar != "" { 576 if _, err := strconv.ParseBool(cfTraceEnvVar); err != nil { 577 cfTraceEnvVar = filepath.Join(tmpDir, cfTraceEnvVar) 578 envTraceFile = cfTraceEnvVar 579 } 580 envMap = map[string]string{"CF_TRACE": cfTraceEnvVar} 581 } 582 583 var configTraceFile string 584 if configTraceValue != "" { 585 if _, err := strconv.ParseBool(configTraceValue); err != nil { 586 configTraceValue = filepath.Join(tmpDir, configTraceValue) 587 configTraceFile = configTraceValue 588 } 589 session := helpers.CF("config", "--trace", configTraceValue) 590 Eventually(session).Should(Exit(0)) 591 } 592 593 command := []string{"create-shared-domain", helpers.NewDomainName(), "--router-group", "default-tcp"} 594 595 if vFlagSet { 596 command = append(command, "-v") 597 } 598 599 session := helpers.CFWithEnv(envMap, command...) 600 Eventually(session).Should(Exit(0)) 601 602 if len(envTraceFile) > 0 { 603 assertLogsWrittenToFile(envTraceFile, "GET /routing/v1/router_groups?name=default-tcp") 604 } 605 606 if len(configTraceFile) > 0 { 607 assertLogsWrittenToFile(configTraceFile, "GET /routing/v1/router_groups?name=default-tcp") 608 } 609 }, 610 611 Entry("CF_TRACE=false, config trace file path: enables logging to file", "false", "/foo", false), 612 Entry("CF_TRACE unset, config trace file path: enables logging to file", "", "/foo", false), 613 Entry("CF_TRACE=filepath: enables logging to file", "/foo", "", false), 614 ) 615 616 When("the values of CF_TRACE and config.trace are two different filepaths", func() { 617 var ( 618 configTraceFile, envTraceFile string 619 cfEnv map[string]string 620 ) 621 622 BeforeEach(func() { 623 helpers.LoginCF() 624 helpers.TargetOrgAndSpace(ReadOnlyOrg, ReadOnlySpace) 625 626 tmpDir, err := ioutil.TempDir("", "") 627 defer os.RemoveAll(tmpDir) 628 Expect(err).NotTo(HaveOccurred()) 629 630 configTraceFile = filepath.Join(tmpDir, "/foo") 631 session := helpers.CF("config", "--trace", configTraceFile) 632 Eventually(session).Should(Exit(0)) 633 634 envTraceFile = filepath.Join(tmpDir, "/bar") 635 cfEnv = map[string]string{ 636 "CF_TRACE": envTraceFile, 637 } 638 }) 639 640 It("logs verbose output to both files", func() { 641 command := []string{"create-shared-domain", helpers.NewDomainName(), "--router-group", "default-tcp"} 642 643 session := helpers.CFWithEnv(cfEnv, command...) 644 Eventually(session).Should(Exit(0)) 645 646 assertLogsWrittenToFile(envTraceFile, "GET /routing/v1/router_groups?name=default-tcp") 647 assertLogsWrittenToFile(configTraceFile, "GET /routing/v1/router_groups?name=default-tcp") 648 649 configStat, err := os.Stat(configTraceFile) 650 Expect(err).ToNot(HaveOccurred()) 651 652 envStat, err := os.Stat(envTraceFile) 653 Expect(err).ToNot(HaveOccurred()) 654 655 var fileMode os.FileMode 656 if runtime.GOOS == "windows" { 657 fileMode = os.FileMode(0666) 658 } else { 659 fileMode = os.FileMode(0600) 660 } 661 662 Expect(configStat.Mode().String()).To(Equal(fileMode.String())) 663 Expect(envStat.Mode().String()).To(Equal(fileMode.String())) 664 }) 665 }) 666 }) 667 }) 668 669 func assertLogsWrittenToFile(filepath string, expected string) { 670 contents, err := ioutil.ReadFile(filepath) 671 Expect(err).ToNot(HaveOccurred()) 672 Expect(string(contents)).To(ContainSubstring(expected), "Logging to a file failed") 673 }