diff --git a/fission/function.go b/fission/function.go index cfe9ef20..d39428b7 100644 --- a/fission/function.go +++ b/fission/function.go @@ -790,9 +790,16 @@ func fnTest(c *cli.Context) error { functionUrl.RawQuery = query.Encode() } + ctx := context.Background() + if deadline := c.Duration("timeout"); deadline > 0 { + var closeCtx func() + ctx, closeCtx = context.WithTimeout(ctx, deadline) + defer closeCtx() + } + headers := c.StringSlice("header") - resp := httpRequest(c.String("method"), functionUrl.String(), c.String("body"), headers) + resp := doHTTPRequest(ctx, c.String("method"), functionUrl.String(), c.String("body"), headers) if resp.StatusCode < 400 { body, err := ioutil.ReadAll(resp.Body) util.CheckErr(err, "Function test") @@ -813,9 +820,9 @@ func fnTest(c *cli.Context) error { return nil } -func httpRequest(method, url, body string, headers []string) *http.Response { +func doHTTPRequest(ctx context.Context, method, url, body string, headers []string) *http.Response { if method == "" { - method = "GET" + method = http.MethodGet } if method != http.MethodGet && @@ -836,9 +843,7 @@ func httpRequest(method, url, body string, headers []string) *http.Response { } req.Header.Set(headerKeyValue[0], headerKeyValue[1]) } - - client := &http.Client{} - resp, err := client.Do(req) + resp, err := http.DefaultClient.Do(req.WithContext(ctx)) util.CheckErr(err, "execute HTTP request") return resp diff --git a/fission/main.go b/fission/main.go index d3ee8439..34689b59 100644 --- a/fission/main.go +++ b/fission/main.go @@ -21,6 +21,7 @@ import ( "fmt" "os" "strings" + "time" "github.com/pkg/errors" "github.com/urfave/cli" @@ -118,6 +119,7 @@ func newCliApp() *cli.App { fnLogCountFlag := cli.StringFlag{Name: "recordcount", Usage: "the n most recent log records"} fnForceFlag := cli.BoolFlag{Name: "force", Usage: "Force update a package even if it is used by one or more functions"} fnExecutorTypeFlag := cli.StringFlag{Name: "executortype", Value: fission.ExecutorTypePoolmgr, Usage: "Executor type for execution; one of 'poolmgr', 'newdeploy' defaults to 'poolmgr'"} + fnTimeoutFlag := cli.DurationFlag{Name: "timeout, t", Value: 30 * time.Second, Usage: "The length of time to wait for the response. If set to zero or negative number, no timeout is set."} fnSubcommands := []cli.Command{ {Name: "create", Usage: "Create new function (and optionally, an HTTP route to it)", Flags: []cli.Flag{fnNameFlag, fnNamespaceFlag, fnEnvNameFlag, envNamespaceFlag, specSaveFlag, fnCodeFlag, fnSrcArchiveFlag, fnDeployArchiveFlag, fnEntryPointFlag, fnBuildCmdFlag, fnPkgNameFlag, htUrlFlag, htMethodFlag, minCpu, maxCpu, minMem, maxMem, minScale, maxScale, fnExecutorTypeFlag, targetcpu, fnCfgMapFlag, fnSecretFlag}, Action: fnCreate}, @@ -129,7 +131,9 @@ func newCliApp() *cli.App { // so, in the future, if we end up using kubeconfig in fission cli and enforcing rolebindings to be created for users by admins etc, we can add this option at the time. {Name: "list", Usage: "List all functions in a namespace if specified, else, list functions across all namespaces", Flags: []cli.Flag{fnNamespaceFlag}, Action: fnList}, {Name: "logs", Usage: "Display function logs", Flags: []cli.Flag{fnNameFlag, fnNamespaceFlag, fnPodFlag, fnFollowFlag, fnDetailFlag, fnLogDBTypeFlag, fnLogCountFlag}, Action: fnLogs}, - {Name: "test", Usage: "Test a function", Flags: []cli.Flag{fnNameFlag, fnNamespaceFlag, fnEnvNameFlag, fnCodeFlag, fnSrcArchiveFlag, htMethodFlag, fnBodyFlag, fnHeaderFlag, fnQueryFlag}, Action: fnTest}, + {Name: "test", Usage: "Test a function", Flags: []cli.Flag{fnNameFlag, fnNamespaceFlag, fnEnvNameFlag, + fnCodeFlag, fnSrcArchiveFlag, htMethodFlag, fnBodyFlag, fnHeaderFlag, fnQueryFlag, fnTimeoutFlag}, + Action: fnTest}, } // httptriggers