github.com/arunkumar7540/cli@v6.45.0+incompatible/integration/v6/isolated/curl_command_test.go (about)

     1  package isolated
     2  
     3  import (
     4  	"fmt"
     5  	"io/ioutil"
     6  	"os"
     7  	"path/filepath"
     8  	"regexp"
     9  	"strings"
    10  
    11  	"code.cloudfoundry.org/cli/integration/helpers"
    12  	. "github.com/onsi/ginkgo"
    13  	. "github.com/onsi/gomega"
    14  	. "github.com/onsi/gomega/gbytes"
    15  	. "github.com/onsi/gomega/gexec"
    16  )
    17  
    18  var _ = Describe("curl command", func() {
    19  	var ExpectHelpText = func(session *Session) {
    20  		Eventually(session).Should(Say(`NAME:\n`))
    21  		Eventually(session).Should(Say(`curl - Executes a request to the targeted API endpoint\n`))
    22  		Eventually(session).Should(Say(`\n`))
    23  
    24  		Eventually(session).Should(Say(`USAGE:\n`))
    25  		Eventually(session).Should(Say(`\s+cf curl PATH \[-iv\] \[-X METHOD\] \[-H HEADER\]\.\.\. \[-d DATA\] \[--output FILE\]`))
    26  		Eventually(session).Should(Say(`\s+By default 'cf curl' will perform a GET to the specified PATH. If data`))
    27  		Eventually(session).Should(Say(`\s+is provided via -d, a POST will be performed instead, and the Content-Type\n`))
    28  		Eventually(session).Should(Say(`\s+will be set to application/json. You may override headers with -H and the\n`))
    29  		Eventually(session).Should(Say(`\s+request method with -X.\n`))
    30  		Eventually(session).Should(Say(`\s+For API documentation, please visit http://apidocs.cloudfoundry.org.\n`))
    31  		Eventually(session).Should(Say(`\n`))
    32  
    33  		Eventually(session).Should(Say(`EXAMPLES:\n`))
    34  		Eventually(session).Should(Say(`\s+cf curl \"/v2/apps\" -X GET -H \"Content-Type: application/x-www-form-urlencoded\" -d 'q=name:myapp'`))
    35  		Eventually(session).Should(Say(`\s+cf curl \"/v2/apps\" -d @/path/to/file`))
    36  		Eventually(session).Should(Say(`\n`))
    37  
    38  		Eventually(session).Should(Say(`OPTIONS:\n`))
    39  		Eventually(session).Should(Say(`\s+-H\s+Custom headers to include in the request, flag can be specified multiple times`))
    40  		Eventually(session).Should(Say(`\s+-X\s+HTTP method \(GET,POST,PUT,DELETE,etc\)`))
    41  		Eventually(session).Should(Say(`\s+-d\s+HTTP data to include in the request body, or '@' followed by a file name to read the data from`))
    42  		Eventually(session).Should(Say(`\s+--fail,\s+-f\s+Server errors return exit code 22`))
    43  		Eventually(session).Should(Say(`\s+-i\s+Include response headers in the output`))
    44  		Eventually(session).Should(Say(`\s+--output\s+Write curl body to FILE instead of stdout`))
    45  	}
    46  
    47  	var ExpectRequestHeaders = func(session *Session) {
    48  		Eventually(session).Should(Say(`REQUEST: .+`))
    49  		Eventually(session).Should(Say(`(GET|POST|PUT|DELETE) /v2/apps HTTP/1.1`))
    50  		Eventually(session).Should(Say(`Host: .+`))
    51  		Eventually(session).Should(Say(`Accept: .+`))
    52  		Eventually(session).Should(Say(`Authorization:\s+\[PRIVATE DATA HIDDEN\]`))
    53  		Eventually(session).Should(Say(`Content-Type: .+`))
    54  		Eventually(session).Should(Say(`User-Agent: .+`))
    55  	}
    56  
    57  	var ExpectResponseHeaders = func(session *Session) {
    58  		Eventually(session).Should(Say("HTTP/1.1 200 OK"))
    59  		Eventually(session).Should(Say(`Connection: .+`))
    60  		Eventually(session).Should(Say(`Content-Length: .+`))
    61  		Eventually(session).Should(Say(`Content-Type: .+`))
    62  		Eventually(session).Should(Say(`Date: .+`))
    63  		Eventually(session).Should(Say(`Server: .+`))
    64  		Eventually(session).Should(Say(`X-Content-Type-Options: .+`))
    65  		Eventually(session).Should(Say(`X-Vcap-Request-Id: .+`))
    66  	}
    67  
    68  	Describe("Help Text", func() {
    69  		When("--help flag is set", func() {
    70  			It("Displays command usage to the output", func() {
    71  				session := helpers.CF("curl", "--help")
    72  				ExpectHelpText(session)
    73  				Eventually(session).Should(Exit(0))
    74  			})
    75  		})
    76  	})
    77  
    78  	Describe("Incorrect Usage", func() {
    79  		When("no arguments are provided", func() {
    80  			It("fails and displays the help text", func() {
    81  				session := helpers.CF("curl")
    82  				Eventually(session.Err).Should(Say("Incorrect Usage: the required argument `PATH` was not provided"))
    83  				ExpectHelpText(session)
    84  				Eventually(session).Should(Exit(1))
    85  			})
    86  		})
    87  
    88  		When("unknown flag is specified", func() {
    89  			It("fails and displays the help text", func() {
    90  				session := helpers.CF("curl", "--test")
    91  				Eventually(session.Err).Should(Say("Incorrect Usage: unknown flag `test'"))
    92  				ExpectHelpText(session)
    93  				Eventually(session).Should(Exit(1))
    94  			})
    95  		})
    96  
    97  		When("more than one path is specified", func() {
    98  			It("fails and displays the help text", func() {
    99  				session := helpers.CF("curl", "/v2/apps", "/v2/apps")
   100  				Eventually(session).Should(Say("FAILED\n"))
   101  				Eventually(session).Should(Say("Incorrect Usage. An argument is missing or not correctly enclosed."))
   102  				ExpectHelpText(session)
   103  				Eventually(session).Should(Exit(1))
   104  			})
   105  		})
   106  	})
   107  
   108  	When("the user is not logged in", func() {
   109  		It("makes the request and receives an unauthenticated error", func() {
   110  			session := helpers.CF("curl", "/v2/apps")
   111  			expectedJSON := `{
   112  				 "description": "Authentication error",
   113  				 "error_code": "CF-NotAuthenticated",
   114  				 "code": 10002
   115  			}`
   116  			Eventually(session).Should(Exit(0))
   117  			Expect(session.Out.Contents()).To(MatchJSON(expectedJSON))
   118  		})
   119  	})
   120  
   121  	Describe("User Agent", func() {
   122  		It("sets the User-Agent Header to contain the CLI version", func() {
   123  			getVersionNumber := func() string {
   124  				versionSession := helpers.CF("version")
   125  				Eventually(versionSession).Should(Exit(0))
   126  				versionPattern := regexp.MustCompile("cf version (.+)")
   127  				version := versionPattern.FindStringSubmatch(string(versionSession.Out.Contents()))
   128  				return regexp.QuoteMeta(version[1])
   129  			}
   130  			session := helpers.CF("curl", "/v2/info", "-v")
   131  			Eventually(session).Should(Exit(0))
   132  
   133  			Expect(session).To(Say(`User-Agent: go-cli %s`, getVersionNumber()))
   134  		})
   135  	})
   136  
   137  	When("the user is logged in", func() {
   138  		var orgName string
   139  
   140  		BeforeEach(func() {
   141  			orgName = helpers.NewOrgName()
   142  			spaceName := helpers.NewSpaceName()
   143  
   144  			helpers.SetupCF(orgName, spaceName)
   145  			helpers.SwitchToOrgRole(orgName, "OrgManager")
   146  			helpers.TargetOrg(orgName)
   147  		})
   148  
   149  		When("the path is valid", func() {
   150  			var expectedJSON string
   151  
   152  			BeforeEach(func() {
   153  				expectedJSON = `{
   154              "total_results": 0,
   155              "total_pages": 1,
   156              "prev_url": null,
   157              "next_url": null,
   158              "resources": []
   159  				}`
   160  			})
   161  
   162  			When("the path has multiple initial slashes", func() {
   163  				It("changes the path to use only one slash", func() {
   164  					session := helpers.CF("curl", "////v2/apps", "-v")
   165  					Eventually(session).Should(Exit(0))
   166  
   167  					Eventually(session).Should(Say(`GET /v2/apps HTTP/1.1`))
   168  				})
   169  			})
   170  
   171  			When("the path has no initial slashes", func() {
   172  				It("prepends a slash to the path", func() {
   173  					session := helpers.CF("curl", "v2/apps", "-v")
   174  					Eventually(session).Should(Exit(0))
   175  
   176  					Eventually(session).Should(Say(`GET /v2/apps HTTP/1.1`))
   177  				})
   178  			})
   179  
   180  			When("no flag is set", func() {
   181  				It("makes the request and displays the json response", func() {
   182  					session := helpers.CF("curl", "/v2/apps")
   183  					Eventually(session).Should(Exit(0))
   184  					Expect(session.Out.Contents()).To(MatchJSON(expectedJSON))
   185  				})
   186  			})
   187  
   188  			When("-i flag is set", func() {
   189  				It("displays the response headers", func() {
   190  					session := helpers.CF("curl", "/v2/apps", "-i")
   191  					Eventually(session).Should(Exit(0))
   192  
   193  					ExpectResponseHeaders(session)
   194  					contents := string(session.Out.Contents())
   195  					jsonStartsAt := strings.Index(contents, "{")
   196  
   197  					actualJSON := contents[jsonStartsAt:]
   198  					Expect(actualJSON).To(MatchJSON(expectedJSON))
   199  				})
   200  			})
   201  
   202  			When("-v flag is set", func() {
   203  				It("displays the request headers and response headers", func() {
   204  					session := helpers.CF("curl", "/v2/apps", "-v")
   205  					Eventually(session).Should(Exit(0))
   206  
   207  					ExpectRequestHeaders(session)
   208  					ExpectResponseHeaders(session)
   209  
   210  					contents := string(session.Out.Contents())
   211  					jsonStartsAt := strings.Index(contents, "{")
   212  
   213  					actualJSON := contents[jsonStartsAt:]
   214  					Expect(actualJSON).To(MatchJSON(expectedJSON))
   215  				})
   216  			})
   217  
   218  			When("-H is passed with a custom header", func() {
   219  				When("the custom header is valid", func() {
   220  					It("add the custom header to the request", func() {
   221  						session := helpers.CF("curl", "/v2/apps", "-H", "X-Foo: bar", "-v")
   222  						Eventually(session).Should(Exit(0))
   223  
   224  						Expect(session).To(Say("REQUEST:"))
   225  						Expect(session).To(Say("X-Foo: bar"))
   226  						Expect(session).To(Say("RESPONSE:"))
   227  					})
   228  
   229  					When("multiple headers are provided", func() {
   230  						It("adds all the custom headers to the request", func() {
   231  							session := helpers.CF("curl", "/v2/apps", "-H", "X-Bar: bar", "-H", "X-Foo: foo", "-v")
   232  							Eventually(session).Should(Exit(0))
   233  
   234  							Expect(session).To(Say("REQUEST:"))
   235  							Expect(session).To(Say("X-Bar: bar"))
   236  							Expect(session).To(Say("X-Foo: foo"))
   237  							Expect(session).To(Say("RESPONSE:"))
   238  						})
   239  
   240  						When("the same header field is passed", func() {
   241  							It("adds the same header field twice", func() {
   242  								session := helpers.CF("curl", "/v2/apps", "-H", "X-Foo: bar", "-H", "X-Foo: foo", "-v")
   243  								Eventually(session).Should(Exit(0))
   244  
   245  								Expect(session).To(Say("REQUEST:"))
   246  								Expect(session).To(Say("X-Foo: bar"))
   247  								Expect(session).To(Say("X-Foo: foo"))
   248  								Expect(session).To(Say("RESPONSE:"))
   249  							})
   250  						})
   251  					})
   252  
   253  					When("-H is provided with a default header", func() {
   254  						It("overrides the value of User-Agent header", func() {
   255  							session := helpers.CF("curl", "/v2/apps", "-H", "User-Agent: smith", "-v")
   256  							Eventually(session).Should(Exit(0))
   257  
   258  							Expect(session).To(Say("REQUEST:"))
   259  							Expect(session).To(Say("User-Agent: smith"))
   260  							Expect(session).To(Say("RESPONSE:"))
   261  						})
   262  
   263  						It("does not override the Host header", func() {
   264  							getHost := func() string {
   265  								apiSession := helpers.CF("api")
   266  								Eventually(apiSession).Should(Exit(0))
   267  								output := string(apiSession.Out.Contents())
   268  								lines := strings.Split(output, "\n")
   269  								Expect(len(lines)).To(BeNumerically(">=", 1))
   270  								parts := strings.Split(lines[0], "//")
   271  								Expect(len(parts)).To(BeNumerically(">=", 2))
   272  								return parts[1]
   273  							}
   274  							session := helpers.CF("curl", "/v2/apps", "-H", "Host: example.com", "-v")
   275  							Eventually(session).Should(Exit(0))
   276  							Expect(session).To(Say("Host: " + getHost()))
   277  						})
   278  
   279  						It("overrides the value of Accept header", func() {
   280  							session := helpers.CF("curl", "/v2/apps", "-H", "Accept: application/xml", "-v")
   281  							Eventually(session).Should(Exit(0))
   282  
   283  							Expect(session).To(Say("REQUEST:"))
   284  							Expect(session).To(Say("Accept: application/xml"))
   285  							Expect(session).To(Say("RESPONSE:"))
   286  						})
   287  
   288  						It("overrides the value of Content-Type header", func() {
   289  							session := helpers.CF("curl", "/v2/apps", "-H", "Content-Type: application/xml", "-v")
   290  							Eventually(session).Should(Exit(0))
   291  
   292  							Expect(session).To(Say("REQUEST:"))
   293  							Expect(session).To(Say("Content-Type: application/xml"))
   294  							Expect(session).To(Say("RESPONSE:"))
   295  						})
   296  					})
   297  				})
   298  
   299  				When("the custom header is not valid", func() {
   300  					It("tells the user that the header is not valid", func() {
   301  						session := helpers.CF("curl", "/v2/apps", "-H", "not-a-valid-header", "-v")
   302  						Eventually(session).Should(Exit(1))
   303  
   304  						Expect(session).Should(Say("FAILED"))
   305  						Expect(session).Should(Say("Error creating request:"))
   306  						Expect(session).Should(Say("Error parsing headers: malformed MIME header line: not-a-valid-header"))
   307  					})
   308  				})
   309  			})
   310  
   311  			When("-d is passed with a request body", func() {
   312  				When("the request body is passed as a string", func() {
   313  					It("sets the method to POST and sends the body", func() {
   314  						orgGUID := helpers.GetOrgGUID(orgName)
   315  						spaceName := helpers.NewSpaceName()
   316  						jsonBody := fmt.Sprintf(`{"name":"%s", "organization_guid":"%s"}`, spaceName, orgGUID)
   317  						session := helpers.CF("curl", "/v2/spaces", "-d", jsonBody)
   318  						Eventually(session).Should(Exit(0))
   319  						Eventually(helpers.CF("space", spaceName)).Should(Exit(0))
   320  					})
   321  				})
   322  
   323  				When("the request body is passed as a file", func() {
   324  					var spaceName, filePath, dir string
   325  
   326  					BeforeEach(func() {
   327  						var err error
   328  						dir, err = ioutil.TempDir("", "curl-command")
   329  						Expect(err).ToNot(HaveOccurred())
   330  
   331  						filePath = filepath.Join(dir, "request_body.json")
   332  						orgGUID := helpers.GetOrgGUID(orgName)
   333  						spaceName = helpers.NewSpaceName()
   334  
   335  						jsonBody := fmt.Sprintf(`{"name":"%s", "organization_guid":"%s"}`, spaceName, orgGUID)
   336  						err = ioutil.WriteFile(filePath, []byte(jsonBody), 0666)
   337  						Expect(err).ToNot(HaveOccurred())
   338  					})
   339  
   340  					AfterEach(func() {
   341  						os.RemoveAll(dir)
   342  					})
   343  
   344  					It("sets the method to POST and sends the body", func() {
   345  						session := helpers.CF("curl", "/v2/spaces", "-d", "@"+filePath)
   346  						Eventually(session).Should(Exit(0))
   347  						Eventually(helpers.CF("space", spaceName)).Should(Exit(0))
   348  					})
   349  
   350  					When("the file does not exist", func() {
   351  						It("fails and displays an error message", func() {
   352  							_, err := os.Stat("this-file-does-not-exist")
   353  							Expect(os.IsExist(err)).To(BeFalse())
   354  
   355  							session := helpers.CF("curl", "/v2/spaces", "-d", "@this-file-does-not-exist")
   356  							Eventually(session).Should(Exit(1))
   357  							Expect(session).To(Say("FAILED"))
   358  						})
   359  					})
   360  
   361  					When("the file is a symlink", func() {
   362  						It("follows the symlink", func() {
   363  							linkPath := filepath.Join(dir, "link-name.json")
   364  							Expect(os.Symlink(filePath, linkPath)).To(Succeed())
   365  							session := helpers.CF("curl", "-d", "@"+linkPath, "/v2/spaces")
   366  							Eventually(session).Should(Exit(0))
   367  							Eventually(helpers.CF("space", spaceName)).Should(Exit(0))
   368  						})
   369  					})
   370  				})
   371  			})
   372  
   373  			When("-X is passed with the HTTP method", func() {
   374  				var spaceGUID, spaceName string
   375  
   376  				BeforeEach(func() {
   377  					spaceName = helpers.NewSpaceName()
   378  					helpers.CreateSpace(spaceName)
   379  					spaceGUID = helpers.GetSpaceGUID(spaceName)
   380  				})
   381  
   382  				It("changes the HTTP method of the request", func() {
   383  					path := fmt.Sprintf("/v2/spaces/%s", spaceGUID)
   384  					session := helpers.CF("curl", path, "-X", "DELETE", "-v")
   385  					Eventually(session).Should(Exit(0))
   386  
   387  					Eventually(helpers.CF("space", spaceName)).Should(Exit(1))
   388  				})
   389  			})
   390  
   391  			When("--output is passed with a file name", func() {
   392  				It("writes the response body to the file but the other output to stdout", func() {
   393  					outFile, err := ioutil.TempFile("", "output*.json")
   394  					Expect(err).ToNot(HaveOccurred())
   395  					session := helpers.CF("curl", "/v2/apps", "-i", "--output", outFile.Name())
   396  					Eventually(session).Should(Exit(0))
   397  					ExpectResponseHeaders(session)
   398  					body, err := ioutil.ReadFile(outFile.Name())
   399  					Expect(err).ToNot(HaveOccurred())
   400  					Expect(string(body)).To(MatchJSON(expectedJSON))
   401  				})
   402  
   403  				When("--output is passed and CF_TRACE is set to a file", func() {
   404  					var tempDir, traceFile, outFile string
   405  					BeforeEach(func() {
   406  						var err error
   407  						tempDir, err = ioutil.TempDir("", "")
   408  						Expect(err).ToNot(HaveOccurred())
   409  						traceFile = filepath.Join(tempDir, "trace.log")
   410  						outFile = filepath.Join(tempDir, "output")
   411  					})
   412  
   413  					AfterEach(func() {
   414  						Expect(os.RemoveAll(tempDir)).To(Succeed())
   415  					})
   416  
   417  					It("writes the response body to the --output file and everything to the trace file", func() {
   418  						session := helpers.CFWithEnv(map[string]string{"CF_TRACE": traceFile}, "curl", "/v2/apps", "--output", outFile)
   419  						Eventually(session).Should(Exit(0))
   420  
   421  						outBytes, err := ioutil.ReadFile(outFile)
   422  						Expect(err).ToNot(HaveOccurred())
   423  						Expect(string(outBytes)).To(MatchJSON(expectedJSON))
   424  
   425  						traceBytes, err := ioutil.ReadFile(traceFile)
   426  						Expect(traceBytes).To(ContainSubstring("REQUEST: "))
   427  						Expect(traceBytes).To(ContainSubstring("HTTP/1.1 200 OK"))
   428  					})
   429  				})
   430  			})
   431  
   432  			Describe("Flag combinations", func() {
   433  				When("-i and -v flags are set", func() {
   434  					It("prints both the request and response headers", func() {
   435  						session := helpers.CF("curl", "/v2/apps", "-v", "-i")
   436  						Eventually(session).Should(Exit(0))
   437  
   438  						ExpectRequestHeaders(session)
   439  						ExpectResponseHeaders(session)
   440  
   441  						contents := string(session.Out.Contents())
   442  						jsonStartsAt := strings.Index(contents, "{")
   443  
   444  						actualJSON := contents[jsonStartsAt:]
   445  						Expect(actualJSON).To(MatchJSON(expectedJSON))
   446  					})
   447  				})
   448  
   449  				XWhen("-v and --output flags are passed", func() {
   450  					It("prints the headers to the terminal and the response to the file", func() {
   451  						// TODO This is a bug in the legacy CLI. Please write the test and fix the bug after refactor [#162432878]
   452  					})
   453  				})
   454  
   455  				When("-X, -H and -d flags are passed", func() {
   456  					var spaceName, filePath, dir, jsonBody string
   457  
   458  					BeforeEach(func() {
   459  						var err error
   460  						dir, err = ioutil.TempDir("", "curl-command")
   461  						Expect(err).ToNot(HaveOccurred())
   462  
   463  						filePath = filepath.Join(dir, "request_body.json")
   464  						orgGUID := helpers.GetOrgGUID(orgName)
   465  						spaceName = helpers.NewSpaceName()
   466  
   467  						jsonBody = fmt.Sprintf(`{"name":"%s", "organization_guid":"%s"}`, spaceName, orgGUID)
   468  						err = ioutil.WriteFile(filePath, []byte(jsonBody), 0666)
   469  						Expect(err).ToNot(HaveOccurred())
   470  					})
   471  
   472  					AfterEach(func() {
   473  						os.RemoveAll(dir)
   474  					})
   475  
   476  					It("sets the custom header and use the request body from -d", func() {
   477  						session := helpers.CF("curl", "/v2/spaces", "-X", "POST", "-H", "X-Foo: foo", "-H", "X-Bar: bar", "-d", "@"+filePath, "-v")
   478  						Eventually(session).Should(Exit(0))
   479  
   480  						Expect(session).Should(Say("REQUEST:"))
   481  						Expect(session).Should(Say("POST"))
   482  
   483  						Expect(session).Should(Say("X-Bar: bar"))
   484  						Expect(session).Should(Say("X-Foo: foo"))
   485  
   486  						contents := string(session.Out.Contents())
   487  						outputContents := contents[strings.Index(contents, "X-Foo: foo"):]
   488  						jsonStartsAt := strings.Index(outputContents, "{")
   489  						jsonEndsAt := strings.Index(outputContents[jsonStartsAt:], "}")
   490  
   491  						actualJSON := outputContents[jsonStartsAt : jsonStartsAt+jsonEndsAt+1]
   492  						Expect(actualJSON).To(MatchJSON(jsonBody))
   493  
   494  						Expect(session).Should(Say("RESPONSE:"))
   495  
   496  						Eventually(helpers.CF("space", spaceName)).Should(Exit(0))
   497  					})
   498  				})
   499  			})
   500  
   501  			When("the auth token is invalid", func() {
   502  				var spaceGUID, spaceName string
   503  
   504  				BeforeEach(func() {
   505  					spaceName = helpers.NewSpaceName()
   506  					helpers.CreateSpace(spaceName)
   507  					spaceGUID = helpers.GetSpaceGUID(spaceName)
   508  				})
   509  
   510  				It("generates a new auth token by using the refresh token", func() {
   511  					path := fmt.Sprintf("/v2/spaces/%s", spaceGUID)
   512  					authHeader := fmt.Sprintf("Authorization: %s", helpers.ExpiredAccessToken())
   513  					session := helpers.CF("curl", path, "-H", authHeader, "-X", "DELETE", "-v")
   514  					Eventually(session).Should(Exit(0))
   515  
   516  					Expect(session).To(Say("POST /oauth/token"))
   517  
   518  					Eventually(helpers.CF("space", spaceName)).Should(Exit(1))
   519  				})
   520  			})
   521  		})
   522  
   523  		When("the path is invalid", func() {
   524  			It("makes the request and displays the unknown request json", func() {
   525  				expectedJSON := `{
   526  				 "description": "Unknown request",
   527  				 "error_code": "CF-NotFound",
   528  				 "code": 10000
   529  				}`
   530  				session := helpers.CF("curl", "/some-random-path")
   531  				Eventually(session).Should(Exit(0))
   532  				Expect(session.Out.Contents()).To(MatchJSON(expectedJSON))
   533  			})
   534  
   535  			When("the -f flag is passed", func() {
   536  				It("should exit 22", func() {
   537  					session := helpers.CF("curl", "/v2/garbage-endpoint", "-f")
   538  					Eventually(session).Should(Exit(22))
   539  				})
   540  			})
   541  		})
   542  	})
   543  })