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