github.com/cloudfoundry-attic/cli-with-i18n@v6.32.1-0.20171002233121-7401370d3b85+incompatible/integration/isolated/verbose_flag_test.go (about)

     1  package isolated
     2  
     3  import (
     4  	"io/ioutil"
     5  	"os"
     6  	"path/filepath"
     7  	"runtime"
     8  	"strings"
     9  
    10  	"code.cloudfoundry.org/cli/integration/helpers"
    11  	"code.cloudfoundry.org/cli/util/configv3"
    12  	. "github.com/onsi/ginkgo"
    13  	. "github.com/onsi/ginkgo/extensions/table"
    14  	. "github.com/onsi/gomega"
    15  	. "github.com/onsi/gomega/gbytes"
    16  	. "github.com/onsi/gomega/gexec"
    17  )
    18  
    19  var _ = Describe("Verbose", func() {
    20  	Context("v2 legacy", func() {
    21  		DescribeTable("displays verbose output",
    22  			func(command func() *Session) {
    23  				helpers.LoginCF()
    24  
    25  				session := command()
    26  				Eventually(session).Should(Say("REQUEST:"))
    27  				Eventually(session).Should(Say("GET /v2/organizations"))
    28  				Eventually(session).Should(Say("RESPONSE:"))
    29  				Eventually(session).Should(Exit(0))
    30  			},
    31  
    32  			Entry("when the -v option is provided with additional command", func() *Session {
    33  				return helpers.CF("-v", "orgs")
    34  			}),
    35  
    36  			Entry("when the CF_TRACE env variable is set", func() *Session {
    37  				return helpers.CFWithEnv(map[string]string{"CF_TRACE": "true"}, "orgs")
    38  			}),
    39  		)
    40  	})
    41  
    42  	Context("v2 refactor", func() {
    43  		DescribeTable("displays verbose output to terminal",
    44  			func(env string, configTrace string, flag bool) {
    45  				tmpDir, err := ioutil.TempDir("", "")
    46  				defer os.RemoveAll(tmpDir)
    47  				Expect(err).NotTo(HaveOccurred())
    48  
    49  				setupCF(ReadOnlyOrg, ReadOnlySpace)
    50  
    51  				var envMap map[string]string
    52  				if env != "" {
    53  					if string(env[0]) == "/" {
    54  						env = filepath.Join(tmpDir, env)
    55  					}
    56  					envMap = map[string]string{"CF_TRACE": env}
    57  				}
    58  
    59  				// We use 'create-user' because it makes a request via the UAA client
    60  				// and a request via the CC client, testing the logging wrapper in both
    61  				// clients.
    62  				randomUsername := helpers.NewUsername()
    63  				randomPassword := helpers.NewPassword()
    64  				command := []string{"create-user", randomUsername, randomPassword}
    65  
    66  				if flag {
    67  					command = append(command, "-v")
    68  				}
    69  
    70  				if configTrace != "" {
    71  					if string(configTrace[0]) == "/" {
    72  						configTrace = filepath.Join(tmpDir, configTrace)
    73  					}
    74  					session := helpers.CF("config", "--trace", configTrace)
    75  					Eventually(session).Should(Exit(0))
    76  				}
    77  
    78  				session := helpers.CFWithEnv(envMap, command...)
    79  
    80  				Eventually(session).Should(Say("REQUEST:"))
    81  				Eventually(session).Should(Say("GET /v2/info"))
    82  				Eventually(session).Should(Say("RESPONSE:"))
    83  				Eventually(session).Should(Say(`"token_endpoint": "http.*"`))
    84  				Eventually(session).Should(Say("REQUEST:"))
    85  				Eventually(session).Should(Say("POST /Users"))
    86  				Eventually(session).Should(Say("User-Agent: cf/[\\w.+-]+ \\(go\\d+\\.\\d+(\\.\\d+)?; %s %s\\)", runtime.GOARCH, runtime.GOOS))
    87  				Eventually(session).Should(Say("RESPONSE:"))
    88  				Eventually(session).Should(Say("REQUEST:"))
    89  				Eventually(session).Should(Say("POST /v2/users"))
    90  				Eventually(session).Should(Say("User-Agent: cf/[\\w.+-]+ \\(go\\d+\\.\\d+(\\.\\d+)?; %s %s\\)", runtime.GOARCH, runtime.GOOS))
    91  				Eventually(session).Should(Say("RESPONSE:"))
    92  				Eventually(session).Should(Exit(0))
    93  			},
    94  
    95  			Entry("CF_TRACE true: enables verbose", "true", "", false),
    96  			Entry("CF_TRACE true, config trace false: enables verbose", "true", "false", false),
    97  			Entry("CF_TRACE true, config trace file path: enables verbose AND logging to file", "true", "/foo", false),
    98  
    99  			Entry("CF_TRACE false, '-v': enables verbose", "false", "", true),
   100  			Entry("CF_TRACE false, config trace file path, '-v': enables verbose AND logging to file", "false", "/foo", true),
   101  
   102  			Entry("CF_TRACE empty:, '-v': enables verbose", "", "", true),
   103  			Entry("CF_TRACE empty, config trace true: enables verbose", "", "true", false),
   104  			Entry("CF_TRACE empty, config trace file path, '-v': enables verbose AND logging to file", "", "/foo", true),
   105  
   106  			Entry("CF_TRACE filepath, '-v': enables logging to file", "/foo", "", true),
   107  			Entry("CF_TRACE filepath, config trace true: enables verbose AND logging to file", "/foo", "true", false),
   108  			Entry("CF_TRACE filepath, config trace filepath, '-v': enables verbose AND logging to file for BOTH paths", "/foo", "/bar", true),
   109  		)
   110  
   111  		DescribeTable("displays verbose output to multiple files",
   112  			func(env string, configTrace string, flag bool, location []string) {
   113  				tmpDir, err := ioutil.TempDir("", "")
   114  				defer os.RemoveAll(tmpDir)
   115  				Expect(err).NotTo(HaveOccurred())
   116  
   117  				setupCF(ReadOnlyOrg, ReadOnlySpace)
   118  
   119  				var envMap map[string]string
   120  				if env != "" {
   121  					if string(env[0]) == "/" {
   122  						env = filepath.Join(tmpDir, env)
   123  					}
   124  					envMap = map[string]string{"CF_TRACE": env}
   125  				}
   126  
   127  				// We use 'create-user' because it makes a request via the UAA client
   128  				// and a request via the CC client, testing the logging wrapper in both
   129  				// clients.
   130  				randomUsername := helpers.NewUsername()
   131  				randomPassword := helpers.NewPassword()
   132  				command := []string{"create-user", randomUsername, randomPassword}
   133  
   134  				if flag {
   135  					command = append(command, "-v")
   136  				}
   137  
   138  				if configTrace != "" {
   139  					if string(configTrace[0]) == "/" {
   140  						configTrace = filepath.Join(tmpDir, configTrace)
   141  					}
   142  					session := helpers.CF("config", "--trace", configTrace)
   143  					Eventually(session).Should(Exit(0))
   144  				}
   145  
   146  				session := helpers.CFWithEnv(envMap, command...)
   147  				Eventually(session).Should(Exit(0))
   148  
   149  				for _, filePath := range location {
   150  					contents, err := ioutil.ReadFile(tmpDir + filePath)
   151  					Expect(err).ToNot(HaveOccurred())
   152  
   153  					Expect(string(contents)).To(MatchRegexp("REQUEST:"))
   154  					Expect(string(contents)).To(MatchRegexp("POST /Users"))
   155  					Expect(string(contents)).To(MatchRegexp("RESPONSE:"))
   156  					Expect(string(contents)).To(MatchRegexp("REQUEST:"))
   157  					Expect(string(contents)).To(MatchRegexp("POST /v2/users"))
   158  					Expect(string(contents)).To(MatchRegexp("RESPONSE:"))
   159  
   160  					stat, err := os.Stat(tmpDir + filePath)
   161  					Expect(err).ToNot(HaveOccurred())
   162  
   163  					if runtime.GOOS == "windows" {
   164  						Expect(stat.Mode().String()).To(Equal(os.FileMode(0666).String()))
   165  					} else {
   166  						Expect(stat.Mode().String()).To(Equal(os.FileMode(0600).String()))
   167  					}
   168  				}
   169  			},
   170  
   171  			Entry("CF_Trace true, config trace file path: enables verbose AND logging to file", "true", "/foo", false, []string{"/foo"}),
   172  
   173  			Entry("CF_TRACE false, config trace file path: enables logging to file", "false", "/foo", false, []string{"/foo"}),
   174  			Entry("CF_TRACE false, config trace file path, '-v': enables verbose AND logging to file", "false", "/foo", true, []string{"/foo"}),
   175  
   176  			Entry("CF_TRACE empty, config trace file path: enables logging to file", "", "/foo", false, []string{"/foo"}),
   177  			Entry("CF_TRACE empty, config trace file path, '-v': enables verbose AND logging to file", "", "/foo", true, []string{"/foo"}),
   178  
   179  			Entry("CF_TRACE filepath: enables logging to file", "/foo", "", false, []string{"/foo"}),
   180  			Entry("CF_TRACE filepath, '-v': enables logging to file", "/foo", "", true, []string{"/foo"}),
   181  			Entry("CF_TRACE filepath, config trace true: enables verbose AND logging to file", "/foo", "true", false, []string{"/foo"}),
   182  			Entry("CF_TRACE filepath, config trace filepath: enables logging to file for BOTH paths", "/foo", "/bar", false, []string{"/foo", "/bar"}),
   183  			Entry("CF_TRACE filepath, config trace filepath, '-v': enables verbose AND logging to file for BOTH paths", "/foo", "/bar", true, []string{"/foo", "/bar"}),
   184  		)
   185  	})
   186  
   187  	Context("v3", func() {
   188  		DescribeTable("displays verbose output to terminal",
   189  			func(env string, configTrace string, flag bool) {
   190  				tmpDir, err := ioutil.TempDir("", "")
   191  				defer os.RemoveAll(tmpDir)
   192  				Expect(err).NotTo(HaveOccurred())
   193  
   194  				setupCF(ReadOnlyOrg, ReadOnlySpace)
   195  
   196  				// Invalidate the access token to cause a token refresh in order to
   197  				// test the call to the UAA.
   198  				helpers.SetConfig(func(config *configv3.Config) {
   199  					config.ConfigFile.AccessToken = helpers.InvalidAccessToken()
   200  				})
   201  
   202  				var envMap map[string]string
   203  				if env != "" {
   204  					if string(env[0]) == "/" {
   205  						env = filepath.Join(tmpDir, env)
   206  					}
   207  					envMap = map[string]string{"CF_TRACE": env}
   208  				}
   209  
   210  				command := []string{"run-task", "app", "echo"}
   211  
   212  				if flag {
   213  					command = append(command, "-v")
   214  				}
   215  
   216  				if configTrace != "" {
   217  					if string(configTrace[0]) == "/" {
   218  						configTrace = filepath.Join(tmpDir, configTrace)
   219  					}
   220  					session := helpers.CF("config", "--trace", configTrace)
   221  					Eventually(session).Should(Exit(0))
   222  				}
   223  
   224  				session := helpers.CFWithEnv(envMap, command...)
   225  
   226  				Eventually(session).Should(Say("REQUEST:"))
   227  				Eventually(session).Should(Say("GET /v3/apps"))
   228  				Eventually(session).Should(Say("User-Agent: cf/[\\w.+-]+ \\(go\\d+\\.\\d+(\\.\\d+)?; %s %s\\)", runtime.GOARCH, runtime.GOOS))
   229  				Eventually(session).Should(Say("RESPONSE:"))
   230  				Eventually(session).Should(Say("REQUEST:"))
   231  				Eventually(session).Should(Say("POST /oauth/token"))
   232  				Eventually(session).Should(Say("User-Agent: cf/[\\w.+-]+ \\(go\\d+\\.\\d+(\\.\\d+)?; %s %s\\)", runtime.GOARCH, runtime.GOOS))
   233  				Eventually(session).Should(Say("\\[PRIVATE DATA HIDDEN\\]")) //This is required to test the previous line. If it fails, the previous matcher went too far.
   234  				Eventually(session).Should(Say("RESPONSE:"))
   235  				Eventually(session).Should(Exit(1))
   236  			},
   237  
   238  			Entry("CF_TRACE true: enables verbose", "true", "", false),
   239  			Entry("CF_Trace true, config trace false: enables verbose", "true", "false", false),
   240  			Entry("CF_Trace true, config trace file path: enables verbose AND logging to file", "true", "/foo", false),
   241  
   242  			Entry("CF_TRACE false, '-v': enables verbose", "false", "", true),
   243  			Entry("CF_TRACE false, config trace file path, '-v': enables verbose AND logging to file", "false", "/foo", true),
   244  
   245  			Entry("CF_TRACE empty:, '-v': enables verbose", "", "", true),
   246  			Entry("CF_TRACE empty, config trace true: enables verbose", "", "true", false),
   247  			Entry("CF_TRACE empty, config trace file path, '-v': enables verbose AND logging to file", "", "/foo", true),
   248  
   249  			Entry("CF_TRACE filepath, '-v': enables logging to file", "/foo", "", true),
   250  			Entry("CF_TRACE filepath, config trace true: enables verbose AND logging to file", "/foo", "true", false),
   251  			Entry("CF_TRACE filepath, config trace filepath, '-v': enables verbose AND logging to file for BOTH paths", "/foo", "/bar", true),
   252  		)
   253  
   254  		DescribeTable("displays verbose output to multiple files",
   255  			func(env string, configTrace string, flag bool, location []string) {
   256  				tmpDir, err := ioutil.TempDir("", "")
   257  				defer os.RemoveAll(tmpDir)
   258  				Expect(err).NotTo(HaveOccurred())
   259  
   260  				setupCF(ReadOnlyOrg, ReadOnlySpace)
   261  
   262  				// Invalidate the access token to cause a token refresh in order to
   263  				// test the call to the UAA.
   264  				helpers.SetConfig(func(config *configv3.Config) {
   265  					config.ConfigFile.AccessToken = helpers.InvalidAccessToken()
   266  				})
   267  
   268  				var envMap map[string]string
   269  				if env != "" {
   270  					if string(env[0]) == "/" {
   271  						env = filepath.Join(tmpDir, env)
   272  					}
   273  					envMap = map[string]string{"CF_TRACE": env}
   274  				}
   275  
   276  				command := []string{"run-task", "app", "echo"}
   277  
   278  				if flag {
   279  					command = append(command, "-v")
   280  				}
   281  
   282  				if configTrace != "" {
   283  					if string(configTrace[0]) == "/" {
   284  						configTrace = filepath.Join(tmpDir, configTrace)
   285  					}
   286  					session := helpers.CF("config", "--trace", configTrace)
   287  					Eventually(session).Should(Exit(0))
   288  				}
   289  
   290  				session := helpers.CFWithEnv(envMap, command...)
   291  				Eventually(session).Should(Exit(1))
   292  
   293  				for _, filePath := range location {
   294  					contents, err := ioutil.ReadFile(tmpDir + filePath)
   295  					Expect(err).ToNot(HaveOccurred())
   296  
   297  					Expect(string(contents)).To(MatchRegexp("REQUEST:"))
   298  					Expect(string(contents)).To(MatchRegexp("GET /v3/apps"))
   299  					Expect(string(contents)).To(MatchRegexp("RESPONSE:"))
   300  					Expect(string(contents)).To(MatchRegexp("REQUEST:"))
   301  					Expect(string(contents)).To(MatchRegexp("POST /oauth/token"))
   302  					Expect(string(contents)).To(MatchRegexp("RESPONSE:"))
   303  
   304  					stat, err := os.Stat(tmpDir + filePath)
   305  					Expect(err).ToNot(HaveOccurred())
   306  
   307  					if runtime.GOOS == "windows" {
   308  						Expect(stat.Mode().String()).To(Equal(os.FileMode(0666).String()))
   309  					} else {
   310  						Expect(stat.Mode().String()).To(Equal(os.FileMode(0600).String()))
   311  					}
   312  				}
   313  			},
   314  
   315  			Entry("CF_Trace true, config trace file path: enables verbose AND logging to file", "true", "/foo", false, []string{"/foo"}),
   316  
   317  			Entry("CF_TRACE false, config trace file path: enables logging to file", "false", "/foo", false, []string{"/foo"}),
   318  			Entry("CF_TRACE false, config trace file path, '-v': enables verbose AND logging to file", "false", "/foo", true, []string{"/foo"}),
   319  
   320  			Entry("CF_TRACE empty, config trace file path: enables logging to file", "", "/foo", false, []string{"/foo"}),
   321  			Entry("CF_TRACE empty, config trace file path, '-v': enables verbose AND logging to file", "", "/foo", true, []string{"/foo"}),
   322  
   323  			Entry("CF_TRACE filepath: enables logging to file", "/foo", "", false, []string{"/foo"}),
   324  			Entry("CF_TRACE filepath, '-v': enables logging to file", "/foo", "", true, []string{"/foo"}),
   325  			Entry("CF_TRACE filepath, config trace true: enables verbose AND logging to file", "/foo", "true", false, []string{"/foo"}),
   326  			Entry("CF_TRACE filepath, config trace filepath: enables logging to file for BOTH paths", "/foo", "/bar", false, []string{"/foo", "/bar"}),
   327  			Entry("CF_TRACE filepath, config trace filepath, '-v': enables verbose AND logging to file for BOTH paths", "/foo", "/bar", true, []string{"/foo", "/bar"}),
   328  		)
   329  	})
   330  
   331  	Describe("NOAA", func() {
   332  		var orgName string
   333  
   334  		BeforeEach(func() {
   335  			orgName = helpers.NewOrgName()
   336  			spaceName := helpers.NewSpaceName()
   337  
   338  			setupCF(orgName, spaceName)
   339  		})
   340  
   341  		AfterEach(func() {
   342  			Eventually(helpers.CF("config", "--trace", "false")).Should(Exit(0))
   343  			helpers.QuickDeleteOrg(orgName)
   344  		})
   345  
   346  		DescribeTable("displays verbose output to terminal",
   347  			func(env string, configTrace string, flag bool) {
   348  				tmpDir, err := ioutil.TempDir("", "")
   349  				defer os.RemoveAll(tmpDir)
   350  				Expect(err).NotTo(HaveOccurred())
   351  
   352  				appName := helpers.PrefixedRandomName("app")
   353  
   354  				helpers.WithHelloWorldApp(func(appDir string) {
   355  					Eventually(helpers.CF("push", appName, "--no-start", "-p", appDir, "-b", "staticfile_buildpack", "--no-route")).Should(Exit(0))
   356  				})
   357  
   358  				var envMap map[string]string
   359  				if env != "" {
   360  					if string(env[0]) == "/" {
   361  						env = filepath.Join(tmpDir, env)
   362  					}
   363  					envMap = map[string]string{"CF_TRACE": env}
   364  				}
   365  
   366  				command := []string{"logs", appName}
   367  
   368  				if flag {
   369  					command = append(command, "-v")
   370  				}
   371  
   372  				if configTrace != "" {
   373  					if string(configTrace[0]) == "/" {
   374  						configTrace = filepath.Join(tmpDir, configTrace)
   375  					}
   376  					session := helpers.CF("config", "--trace", configTrace)
   377  					Eventually(session).Should(Exit(0))
   378  				}
   379  
   380  				session := helpers.CFWithEnv(envMap, command...)
   381  
   382  				Eventually(session).Should(Say("REQUEST:"))
   383  				Eventually(session).Should(Say("POST /oauth/token"))
   384  				Eventually(session).Should(Say("\\[PRIVATE DATA HIDDEN\\]"))
   385  				Eventually(session).Should(Say("WEBSOCKET REQUEST:"))
   386  				Eventually(session).Should(Say("Authorization: \\[PRIVATE DATA HIDDEN\\]"))
   387  				Eventually(session.Kill()).Should(Exit())
   388  			},
   389  
   390  			Entry("CF_TRACE true: enables verbose", "true", "", false),
   391  			Entry("CF_Trace true, config trace false: enables verbose", "true", "false", false),
   392  			Entry("CF_Trace true, config trace file path: enables verbose AND logging to file", "true", "/foo", false),
   393  
   394  			Entry("CF_TRACE false, '-v': enables verbose", "false", "", true),
   395  			Entry("CF_TRACE false, config trace file path, '-v': enables verbose AND logging to file", "false", "/foo", true),
   396  
   397  			Entry("CF_TRACE empty:, '-v': enables verbose", "", "", true),
   398  			Entry("CF_TRACE empty, config trace true: enables verbose", "", "true", false),
   399  			Entry("CF_TRACE empty, config trace file path, '-v': enables verbose AND logging to file", "", "/foo", true),
   400  
   401  			Entry("CF_TRACE filepath, '-v': enables logging to file", "/foo", "", true),
   402  			Entry("CF_TRACE filepath, config trace true: enables verbose AND logging to file", "/foo", "true", false),
   403  			Entry("CF_TRACE filepath, config trace filepath, '-v': enables verbose AND logging to file for BOTH paths", "/foo", "/bar", true),
   404  		)
   405  
   406  		DescribeTable("displays verbose output to multiple files",
   407  			func(env string, configTrace string, location []string) {
   408  				tmpDir, err := ioutil.TempDir("", "")
   409  				defer os.RemoveAll(tmpDir)
   410  				Expect(err).NotTo(HaveOccurred())
   411  
   412  				appName := helpers.PrefixedRandomName("app")
   413  
   414  				helpers.WithHelloWorldApp(func(appDir string) {
   415  					Eventually(helpers.CF("push", appName, "--no-start", "-p", appDir, "-b", "staticfile_buildpack", "--no-route")).Should(Exit(0))
   416  				})
   417  
   418  				var envMap map[string]string
   419  				if env != "" {
   420  					if string(env[0]) == "/" {
   421  						env = filepath.Join(tmpDir, env)
   422  					}
   423  					envMap = map[string]string{"CF_TRACE": env}
   424  				}
   425  
   426  				if configTrace != "" {
   427  					if strings.HasPrefix(configTrace, "/") {
   428  						configTrace = filepath.Join(tmpDir, configTrace)
   429  					}
   430  					session := helpers.CF("config", "--trace", configTrace)
   431  					Eventually(session).Should(Exit(0))
   432  				}
   433  
   434  				session := helpers.CFWithEnv(envMap, "logs", "-v", appName)
   435  
   436  				Eventually(session).Should(Say("WEBSOCKET RESPONSE"))
   437  				Eventually(session.Kill()).Should(Exit())
   438  
   439  				for _, filePath := range location {
   440  					contents, err := ioutil.ReadFile(tmpDir + filePath)
   441  					Expect(err).ToNot(HaveOccurred())
   442  
   443  					Expect(string(contents)).To(MatchRegexp("REQUEST:"))
   444  					Expect(string(contents)).To(MatchRegexp("POST /oauth/token"))
   445  					Expect(string(contents)).To(MatchRegexp("\\[PRIVATE DATA HIDDEN\\]"))
   446  					Expect(string(contents)).To(MatchRegexp("WEBSOCKET REQUEST:"))
   447  					Expect(string(contents)).To(MatchRegexp("Authorization: \\[PRIVATE DATA HIDDEN\\]"))
   448  
   449  					stat, err := os.Stat(tmpDir + filePath)
   450  					Expect(err).ToNot(HaveOccurred())
   451  
   452  					if runtime.GOOS == "windows" {
   453  						Expect(stat.Mode().String()).To(Equal(os.FileMode(0666).String()))
   454  					} else {
   455  						Expect(stat.Mode().String()).To(Equal(os.FileMode(0600).String()))
   456  					}
   457  				}
   458  			},
   459  
   460  			Entry("CF_Trace true, config trace file path: enables verbose AND logging to file", "true", "/foo", []string{"/foo"}),
   461  
   462  			Entry("CF_TRACE false, config trace file path: enables logging to file", "false", "/foo", []string{"/foo"}),
   463  			Entry("CF_TRACE false, config trace file path, '-v': enables verbose AND logging to file", "false", "/foo", []string{"/foo"}),
   464  
   465  			Entry("CF_TRACE empty, config trace file path: enables logging to file", "", "/foo", []string{"/foo"}),
   466  			Entry("CF_TRACE empty, config trace file path, '-v': enables verbose AND logging to file", "", "/foo", []string{"/foo"}),
   467  
   468  			Entry("CF_TRACE filepath: enables logging to file", "/foo", "", []string{"/foo"}),
   469  			Entry("CF_TRACE filepath, '-v': enables logging to file", "/foo", "", []string{"/foo"}),
   470  			Entry("CF_TRACE filepath, config trace true: enables verbose AND logging to file", "/foo", "true", []string{"/foo"}),
   471  			Entry("CF_TRACE filepath, config trace filepath: enables logging to file for BOTH paths", "/foo", "/bar", []string{"/foo", "/bar"}),
   472  			Entry("CF_TRACE filepath, config trace filepath, '-v': enables verbose AND logging to file for BOTH paths", "/foo", "/bar", []string{"/foo", "/bar"}),
   473  		)
   474  	})
   475  })