diff options
author | Jon Marius Venstad <venstad@gmail.com> | 2021-11-22 18:26:55 +0100 |
---|---|---|
committer | Jon Marius Venstad <venstad@gmail.com> | 2021-11-23 10:17:52 +0100 |
commit | ececd82c625a2dbe0e0071e8e1930400fc47b9a3 (patch) | |
tree | 67d66373af3579c07c4f2e4227774fb3b351c5c7 | |
parent | 6dcfb15408ff18f36093322ed47f6feaea9006c3 (diff) |
Use ENV for overrides, allow cluster for cloudTarget service, add test cmd
-rw-r--r-- | client/go/cmd/config.go | 4 | ||||
-rw-r--r-- | client/go/cmd/curl.go | 2 | ||||
-rw-r--r-- | client/go/cmd/document.go | 2 | ||||
-rw-r--r-- | client/go/cmd/document_test.go | 2 | ||||
-rw-r--r-- | client/go/cmd/helpers.go | 44 | ||||
-rw-r--r-- | client/go/cmd/query.go | 2 | ||||
-rw-r--r-- | client/go/cmd/query_test.go | 2 | ||||
-rw-r--r-- | client/go/cmd/test.go | 363 | ||||
-rw-r--r-- | client/go/vespa/deploy.go | 2 | ||||
-rw-r--r-- | client/go/vespa/target.go | 18 | ||||
-rw-r--r-- | client/go/vespa/target_test.go | 14 | ||||
-rw-r--r-- | vespa-osgi-testrunner/src/main/java/com/yahoo/vespa/testrunner/VespaCliTestRunner.java | 4 | ||||
-rw-r--r-- | vespa-osgi-testrunner/src/test/java/com/yahoo/vespa/testrunner/VespaCliTestRunnerTest.java | 4 |
13 files changed, 379 insertions, 84 deletions
diff --git a/client/go/cmd/config.go b/client/go/cmd/config.go index ac23eb8d59d..966080dbdc2 100644 --- a/client/go/cmd/config.go +++ b/client/go/cmd/config.go @@ -133,14 +133,14 @@ func (c *Config) Write() error { } func (c *Config) CertificatePath(app vespa.ApplicationID) (string, error) { - if override, _ := c.Get(dataPlaneCertFlag); override != "" { + if override, ok := os.LookupEnv("VESPA_CLI_DATA_PLANE_CERT_FILE"); ok { return override, nil } return c.applicationFilePath(app, "data-plane-public-cert.pem") } func (c *Config) PrivateKeyPath(app vespa.ApplicationID) (string, error) { - if override, _ := c.Get(dataPlaneKeyFlag); override != "" { + if override, ok := os.LookupEnv("VESPA_CLI_DATA_PLANE_KEY_FILE"); ok { return override, nil } return c.applicationFilePath(app, "data-plane-private-key.pem") diff --git a/client/go/cmd/curl.go b/client/go/cmd/curl.go index bd9fad1b47e..2496ddc3abc 100644 --- a/client/go/cmd/curl.go +++ b/client/go/cmd/curl.go @@ -46,7 +46,7 @@ $ vespa curl -t local -- -v /search/?yql=query fatalErr(err) return } - service := getService("query", 0) + service := getService("query", 0, "") url := joinURL(service.BaseURL, args[len(args)-1]) rawArgs := args[:len(args)-1] c, err := curl.RawArgs(url, rawArgs...) diff --git a/client/go/cmd/document.go b/client/go/cmd/document.go index cd0170684cf..84c384e701e 100644 --- a/client/go/cmd/document.go +++ b/client/go/cmd/document.go @@ -118,7 +118,7 @@ var documentGetCmd = &cobra.Command{ }, } -func documentService() *vespa.Service { return getService("document", 0) } +func documentService() *vespa.Service { return getService("document", 0, "") } func operationOptions() vespa.OperationOptions { return vespa.OperationOptions{ diff --git a/client/go/cmd/document_test.go b/client/go/cmd/document_test.go index 649aca8703a..f3a5fbe9543 100644 --- a/client/go/cmd/document_test.go +++ b/client/go/cmd/document_test.go @@ -161,5 +161,5 @@ func assertDocumentServerError(t *testing.T, status int, errorMessage string) { } func documentServiceURL(client *mockHttpClient) string { - return getService("document", 0).BaseURL + return getService("document", 0, "").BaseURL } diff --git a/client/go/cmd/helpers.go b/client/go/cmd/helpers.go index 79ba1fcef26..9ccc4513ce3 100644 --- a/client/go/cmd/helpers.go +++ b/client/go/cmd/helpers.go @@ -6,6 +6,7 @@ package cmd import ( "crypto/tls" + "encoding/json" "fmt" "io/ioutil" "log" @@ -129,19 +130,21 @@ func getTargetType() string { return target } -func getService(service string, sessionOrRunID int64) *vespa.Service { +func getService(service string, sessionOrRunID int64, cluster string) *vespa.Service { t := getTarget() timeout := time.Duration(waitSecsArg) * time.Second if timeout > 0 { log.Printf("Waiting up to %d %s for service to become available ...", color.Cyan(waitSecsArg), color.Cyan("seconds")) } - s, err := t.Service(service, timeout, sessionOrRunID) + s, err := t.Service(service, timeout, sessionOrRunID, cluster) if err != nil { fatalErr(err, "Invalid service: ", service) } return s } +func getEndpointsOverride() string { return os.Getenv("VESPA_CLI_ENDPOINTS") } + func getSystem() string { return os.Getenv("VESPA_CLI_CLOUD_SYSTEM") } func getSystemName() string { @@ -175,12 +178,13 @@ func getTarget() vespa.Target { case "local": return vespa.LocalTarget() case "cloud": - deployment := deploymentFromArgs() cfg, err := LoadConfig() if err != nil { fatalErr(err, "Could not load config") return nil } + deployment := deploymentFromArgs() + var apiKey []byte = nil apiKey, err = ioutil.ReadFile(cfg.APIKeyPath(deployment.Application.Tenant)) if !vespa.Auth0AccessTokenEnabled() { @@ -228,14 +232,15 @@ func getTarget() vespa.Target { }, cfg.AuthConfigPath(), getSystemName(), - cloudAuth) + cloudAuth, + getEndpointsFromEnv()) } fatalErrHint(fmt.Errorf("Invalid target: %s", targetType), "Valid targets are 'local', 'cloud' or an URL") return nil } func waitForService(service string, sessionOrRunID int64) { - s := getService(service, sessionOrRunID) + s := getService(service, sessionOrRunID, "") timeout := time.Duration(waitSecsArg) * time.Second if timeout > 0 { log.Printf("Waiting up to %d %s for service to become ready ...", color.Cyan(waitSecsArg), color.Cyan("seconds")) @@ -271,3 +276,32 @@ func getDeploymentOpts(cfg *Config, pkg vespa.ApplicationPackage, target vespa.T } return opts } + +func getEndpointsFromEnv() map[string]string { + endpointsString := getEndpointsOverride() + if endpointsString == "" { + return nil + } + + var endpoints endpoints + urlsByCluster := make(map[string]string) + if err := json.Unmarshal([]byte(endpointsString), &endpoints); err != nil { + fatalErrHint(err, "Endpoints must be valid JSON") + } + if len(endpoints.Endpoints) == 0 { + fatalErr(fmt.Errorf("endpoints must be non-empty")) + } + for _, endpoint := range endpoints.Endpoints { + urlsByCluster[endpoint.Cluster] = endpoint.URL + } + return urlsByCluster +} + +type endpoints struct { + Endpoints []endpoint `json:"endpoints"` +} + +type endpoint struct { + Cluster string `json:"cluster"` + URL string `json:"url"` +} diff --git a/client/go/cmd/query.go b/client/go/cmd/query.go index 76688438fb4..6638c275330 100644 --- a/client/go/cmd/query.go +++ b/client/go/cmd/query.go @@ -39,7 +39,7 @@ can be set by the syntax [parameter-name]=[value].`, } func query(arguments []string) { - service := getService("query", 0) + service := getService("query", 0, "") url, _ := url.Parse(service.BaseURL + "/search/") urlQuery := url.Query() for i := 0; i < len(arguments); i++ { diff --git a/client/go/cmd/query_test.go b/client/go/cmd/query_test.go index ec6c3063906..55046ae49ba 100644 --- a/client/go/cmd/query_test.go +++ b/client/go/cmd/query_test.go @@ -75,5 +75,5 @@ func assertQueryServiceError(t *testing.T, status int, errorMessage string) { } func queryServiceURL(client *mockHttpClient) string { - return getService("query", 0).BaseURL + return getService("query", 0, "").BaseURL } diff --git a/client/go/cmd/test.go b/client/go/cmd/test.go index a13fd999be9..6e6ac048650 100644 --- a/client/go/cmd/test.go +++ b/client/go/cmd/test.go @@ -5,31 +5,25 @@ package cmd import ( + "bytes" "encoding/json" "fmt" - "github.com/vespa-engine/vespa/client/go/vespa" - "log" - "github.com/spf13/cobra" -) - -const ( - endpointsFlag = "endpoints" - dataPlaneCertFlag = "data-plane-public-cert" - dataPlaneKeyFlag = "data-plane-private-key" -) - -var ( - endpointsArg string - dataPlaneCertArg string - dataPlaneKeyArg string + "github.com/vespa-engine/vespa/client/go/util" + "github.com/vespa-engine/vespa/client/go/vespa" + "io" + "io/ioutil" + "math" + "net/http" + "net/url" + "os" + "path" + "strings" + "time" ) func init() { rootCmd.AddCommand(testCmd) - testCmd.PersistentFlags().StringVar(&endpointsArg, endpointsFlag, "", "The endpoints to use, for each container cluster") - testCmd.PersistentFlags().StringVar(&dataPlaneCertArg, dataPlaneCertFlag, "", "Override for location of data plane public certificate") - testCmd.PersistentFlags().StringVar(&dataPlaneKeyArg, dataPlaneKeyFlag, "", "Override for location of data plane private key") } var testCmd = &cobra.Command{ @@ -46,55 +40,318 @@ $ vespa test src/test/application/tests/system-test/feed-and-query.json`, Args: cobra.MaximumNArgs(1), DisableAutoGenTag: true, Run: func(cmd *cobra.Command, args []string) { - cfg, err := LoadConfig() + target := getTarget() + testPath := "." + if len(args) > 0 { + testPath = args[0] + } + if count, failed := runTests(testPath, target); len(failed) != 0 { + _, _ = fmt.Fprintf(stdout, "\nFailed %d of %d tests:\n", len(failed), count) + for _, test := range failed { + _, _ = fmt.Fprintln(stdout, test) + } + exitFunc(3) + } else if count == 0 { + _, _ = fmt.Fprintf(stdout, "Failed to find any tests at '%v'\n", testPath) + exitFunc(3) + } else { + _, _ = fmt.Fprintf(stdout, "%d tests completed successfully\n", count) + } + }, +} + +func runTests(rootPath string, target vespa.Target) (int, []string) { + count := 0 + failed := make([]string, 0) + if stat, err := os.Stat(rootPath); err != nil { + fatalErr(err, "Failed reading specified test path") + } else if stat.IsDir() { + tests, err := os.ReadDir(rootPath) if err != nil { - fatalErr(err, "Could not load config") - return + fatalErr(err, "Failed reading specified test directory") + } + for _, test := range tests { + if !test.IsDir() && strings.HasSuffix(test.Name(), ".json") { + testPath := path.Join(rootPath, test.Name()) + failure := runTest(testPath, target) + if failure != "" { + failed = append(failed, failure) + } + count++ + } + } + } else if strings.HasSuffix(stat.Name(), ".json") { + failure := runTest(rootPath, target) + if failure != "" { + failed = append(failed, failure) } + count++ + } + return count, failed +} - app, endpoints := getApplicationOrEndpoints(cfg) - keyPath, _ := cfg.PrivateKeyPath(app) - certPath, _ := cfg.CertificatePath(app) - log.Printf("Key path: %q, Cert path: %q, Endpoints: %q", keyPath, certPath, endpoints) +// Runs the test at the given path, and returns the specified test name if the test fails +func runTest(testPath string, target vespa.Target) string { + var test test + bytes := readFile(testPath) + if err := json.Unmarshal(bytes, &test); err != nil { + fatalErr(err, fmt.Sprintf("Failed to parse test file '%s", testPath)) + } - exitFunc(3) - }, -} + testName := test.Name + if test.Name == "" { + testName = testPath + } + _, _ = fmt.Fprintf(stdout, "Running %s: ", testName) -func getApplicationOrEndpoints(cfg *Config) (vespa.ApplicationID, map[string]string) { - appString, _ := cfg.Get(applicationFlag) - endpointsString, _ := cfg.Get(endpointsFlag) - if (appString == "") == (endpointsString == "") { - fatalErr(fmt.Errorf("must specify exactly one of application or endpoints")) + defaultParameters, err := getParameters(test.Defaults.ParametersRaw, path.Dir(testPath)) + if err != nil { + fatalErr(err, fmt.Sprintf("Invalid default parameters for '%s'", testName)) } - if endpointsString == "" { - app, err := vespa.ApplicationFromString(appString) + + for i, assertion := range test.Assertions { + assertionName := assertion.Name + if assertionName == "" { + assertionName = fmt.Sprintf("assertion %d", i) + } + failure, err := verify(assertion, path.Dir(testPath), test.Defaults.Cluster, defaultParameters, target) if err != nil { - fatalErrHint(err, "Application format is <tenant>.<app>.<instance>") + fatalErr(err, fmt.Sprintf("\nError verifying %s", assertionName)) } - return app, nil - } else { - var endpoints deploymentResponse - urlsByCluster := make(map[string]string) - if err := json.Unmarshal([]byte(endpointsString), &endpoints); err != nil { - fatalErrHint(err, "Endpoints must be valid JSON") + if failure != "" { + _, _ = fmt.Fprintf(stdout, "\nFailed verifying %s: \n%s\n", assertionName, failure) + return fmt.Sprintf("%v: %v", testName, assertionName) } - if len(endpoints.Endpoints) == 0 { - fatalErr(fmt.Errorf("endpoints must be non-empty")) + fmt.Print(".") + } + fmt.Println(" OK!") + return "" +} + +// Asserts specified response is obtained for request, or returns a failure message, or an error if this fails +func verify(assertion assertion, testsPath string, defaultCluster string, defaultParameters map[string]string, target vespa.Target) (string, error) { + requestBody, err := getBody(assertion.Request.BodyRaw, testsPath) + if err != nil { + return "", err + } + + parameters, err := getParameters(assertion.Request.ParametersRaw, testsPath) + if err != nil { + return "", err + } + for name, value := range defaultParameters { + if _, present := parameters[name]; !present { + parameters[name] = value } - for _, endpoint := range endpoints.Endpoints { - urlsByCluster[endpoint.Cluster] = endpoint.URL + } + + cluster := assertion.Request.Cluster + if cluster == "" { + cluster = defaultCluster + } + + service, err := target.Service("query", 0, 0, cluster) + if err != nil { + return "", err + } + + method := assertion.Request.Method + if method == "" { + method = "GET" + } + + pathAndQuery := assertion.Request.URI + if pathAndQuery == "" { + pathAndQuery = "/search/" + } + requestUrl, err := url.ParseRequestURI(service.BaseURL + pathAndQuery) + if err != nil { + return "", err + } + query := requestUrl.Query() + for name, value := range parameters { + query.Add(name, value) + } + requestUrl.RawQuery = query.Encode() + + header := http.Header{} + header.Add("Content-Type", "application/json") + + request := &http.Request{ + URL: requestUrl, + Method: method, + Header: header, + Body: ioutil.NopCloser(bytes.NewReader(requestBody)), + } + defer request.Body.Close() + + response, err := service.Do(request, 600*time.Second) // Vespa should provide a response within the given request timeout + if err != nil { + return "", err + } + defer response.Body.Close() + + statusCode := assertion.Response.Code + if statusCode == 0 { + statusCode = 200 + } + if statusCode != response.StatusCode { + return fmt.Sprintf("Expected status code %d, but got %d, and body:\n%s", statusCode, response.StatusCode, util.ReaderToJSON(response.Body)), nil + } + + responseBodySpecBytes, err := getBody(assertion.Response.BodyRaw, testsPath) + if err != nil { + return "", err + } + if responseBodySpecBytes == nil { + return "", nil + } + var responseBodySpec interface{} + err = json.Unmarshal(responseBodySpecBytes, &responseBodySpec) + if err != nil { + return "", err + } + + responseBodyBytes, err := ioutil.ReadAll(response.Body) + if err != nil { + return "", err + } + var responseBody interface{} + err = json.Unmarshal(responseBodyBytes, &responseBody) + if err != nil { + return "", err + } + + return compare(responseBodySpec, responseBody, "") +} + +func compare(expected interface{}, actual interface{}, path string) (string, error) { + typeMatch := false + valueMatch := false + switch u := expected.(type) { + case nil: + typeMatch = actual == nil + valueMatch = actual == nil + case bool: + v, ok := actual.(bool) + typeMatch = ok + valueMatch = ok && u == v + case float64: + v, ok := actual.(float64) + typeMatch = ok + valueMatch = ok && math.Abs(u-v) < 1e-9 + case string: + v, ok := actual.(string) + typeMatch = ok + valueMatch = ok && (u == v) + case []interface{}: + v, ok := actual.([]interface{}) + typeMatch = ok + if ok && len(u) == len(v) { + for i, e := range u { + result, err := compare(e, v[i], fmt.Sprintf("%s[%d]", path, i)) + if result != "" || err != nil { + return result, err + } + } + valueMatch = true + } + case map[string]interface{}: + v, ok := actual.(map[string]interface{}) + typeMatch = ok + if ok { + for n, e := range u { + result, err := compare(e, v[n], fmt.Sprintf("%s['%s']", path, n)) + if result != "" || err != nil { + return result, err + } + } + valueMatch = true + } + default: + return "", fmt.Errorf("unexpected expected JSON type for value '%v'", expected) + } + + if !(typeMatch && valueMatch) { + if path == "" { + path = "root" } - return vespa.ApplicationID{}, urlsByCluster + expectedJson, _ := json.MarshalIndent(expected, "", " ") + actualJson, _ := json.MarshalIndent(actual, "", " ") + mismatched := "Type" + if typeMatch { + mismatched = "Value" + } + return fmt.Sprintf("%s mismatch at %s: <<< expected === actual >>>\n<<<\n%s\n===\n%s\n>>>\n", mismatched, path, expectedJson, actualJson), nil + } + return "", nil +} + +func getParameters(parametersRaw []byte, testsPath string) (map[string]string, error) { + if parametersRaw != nil { + var parametersPath string + if err := json.Unmarshal(parametersRaw, ¶metersPath); err == nil { + parametersRaw = readFile(path.Join(testsPath, parametersPath)) + } + var parameters map[string]string + if err := json.Unmarshal(parametersRaw, ¶meters); err != nil { + return nil, fmt.Errorf("request parameters must be JSON with only string values: %v", err) + } + return parameters, nil + } + return make(map[string]string), nil +} + +func getBody(bodyRaw []byte, testsPath string) ([]byte, error) { + var bodyPath string + if err := json.Unmarshal(bodyRaw, &bodyPath); err == nil { + return readFile(path.Join(testsPath, bodyPath)), nil + } + return bodyRaw, nil +} + +func readFile(filePath string) []byte { + file, err := os.Open(filePath) + if err != nil { + fatalErr(err, fmt.Sprintf("Failed to open file at '%v'", filePath)) + } + fileBytes, err := io.ReadAll(file) + if err != nil { + fatalErr(err, fmt.Sprintf("Failed to read file at '%v'", filePath)) } + err = file.Close() + if err != nil { + fatalErr(err, fmt.Sprintf("Failed to closse file at '%v'", filePath)) + } + return fileBytes +} + +type test struct { + Name string `json:"name"` + Defaults defaults `json:"defaults"` + Assertions []assertion `json:"assertions"` +} + +type defaults struct { + Cluster string `json:"cluster"` + ParametersRaw json.RawMessage `json:"parameters"` +} + +type assertion struct { + Name string `json:"name"` + Request request `json:"request"` + Response response `json:"response"` } -type deploymentEndpoint struct { - Cluster string `json:"cluster"` - URL string `json:"url"` - Scope string `json:"scope"` +type request struct { + Cluster string `json:"cluster"` + Method string `json:"method"` + URI string `json:"uri"` + ParametersRaw json.RawMessage `json:"parameters"` + BodyRaw json.RawMessage `json:"body"` } -type deploymentResponse struct { - Endpoints []deploymentEndpoint `json:"endpoints"` +type response struct { + Code int `json:"code"` + BodyRaw json.RawMessage `json:"body"` } diff --git a/client/go/vespa/deploy.go b/client/go/vespa/deploy.go index 252a646bcfc..c1cc868e16f 100644 --- a/client/go/vespa/deploy.go +++ b/client/go/vespa/deploy.go @@ -73,7 +73,7 @@ func (d DeploymentOpts) String() string { func (d *DeploymentOpts) IsCloud() bool { return d.Target.Type() == cloudTargetType } func (d *DeploymentOpts) url(path string) (*url.URL, error) { - service, err := d.Target.Service(deployService, 0, 0) + service, err := d.Target.Service(deployService, 0, 0, "") if err != nil { return nil, err } diff --git a/client/go/vespa/target.go b/client/go/vespa/target.go index 093cb2b5cad..72b62b505fd 100644 --- a/client/go/vespa/target.go +++ b/client/go/vespa/target.go @@ -39,7 +39,6 @@ type Service struct { BaseURL string Name string TLSOptions TLSOptions - Target *Target } // Target represents a Vespa platform, running named Vespa services. @@ -48,7 +47,7 @@ type Target interface { Type() string // Service returns the service for given name. If timeout is non-zero, wait for the service to converge. - Service(name string, timeout time.Duration, sessionOrRunID int64) (*Service, error) + Service(name string, timeout time.Duration, sessionOrRunID int64, cluster string) (*Service, error) // PrintLog writes the logs of this deployment using given options to control output. PrintLog(options LogOptions) error @@ -129,7 +128,7 @@ func (s *Service) Description() string { func (t *customTarget) Type() string { return t.targetType } -func (t *customTarget) Service(name string, timeout time.Duration, sessionID int64) (*Service, error) { +func (t *customTarget) Service(name string, timeout time.Duration, _ int64, _ string) (*Service, error) { if timeout > 0 && name != deployService { if err := t.waitForConvergence(timeout); err != nil { return nil, err @@ -171,7 +170,7 @@ func (t *customTarget) urlWithPort(serviceName string) (string, error) { } func (t *customTarget) waitForConvergence(timeout time.Duration) error { - deployer, err := t.Service(deployService, 0, 0) + deployer, err := t.Service(deployService, 0, 0, "") if err != nil { return err } @@ -241,8 +240,8 @@ func (t *cloudTarget) resolveEndpoint(cluster string) (string, error) { func (t *cloudTarget) Type() string { return t.targetType } -func (t *cloudTarget) Service(name string, timeout time.Duration, runID int64) (*Service, error) { - if name != deployService { +func (t *cloudTarget) Service(name string, timeout time.Duration, runID int64, cluster string) (*Service, error) { + if name != deployService && t.urlsByCluster == nil { if err := t.waitForEndpoints(timeout, runID); err != nil { return nil, err } @@ -251,13 +250,13 @@ func (t *cloudTarget) Service(name string, timeout time.Duration, runID int64) ( case deployService: return &Service{Name: name, BaseURL: t.apiURL}, nil case queryService: - queryURL, err := t.resolveEndpoint("") + queryURL, err := t.resolveEndpoint(cluster) if err != nil { return nil, err } return &Service{Name: name, BaseURL: queryURL, TLSOptions: t.tlsOptions}, nil case documentService: - documentURL, err := t.resolveEndpoint("") + documentURL, err := t.resolveEndpoint(cluster) if err != nil { return nil, err } @@ -489,7 +488,7 @@ func CustomTarget(baseURL string) Target { // CloudTarget creates a Target for the Vespa Cloud platform. func CloudTarget(apiURL string, deployment Deployment, apiKey []byte, tlsOptions TLSOptions, logOptions LogOptions, - authConfigPath string, systemName string, cloudAuth string) Target { + authConfigPath string, systemName string, cloudAuth string, urlsByCluster map[string]string) Target { return &cloudTarget{ apiURL: apiURL, targetType: cloudTargetType, @@ -500,6 +499,7 @@ func CloudTarget(apiURL string, deployment Deployment, apiKey []byte, tlsOptions authConfigPath: authConfigPath, systemName: systemName, cloudAuth: cloudAuth, + urlsByCluster: urlsByCluster, } } diff --git a/client/go/vespa/target_test.go b/client/go/vespa/target_test.go index 9d2418897e3..0cfe9f1962c 100644 --- a/client/go/vespa/target_test.go +++ b/client/go/vespa/target_test.go @@ -82,11 +82,11 @@ func TestCustomTargetWait(t *testing.T) { defer srv.Close() target := CustomTarget(srv.URL) - _, err := target.Service("query", time.Millisecond, 42) + _, err := target.Service("query", time.Millisecond, 42, "") assert.NotNil(t, err) vc.deploymentConverged = true - _, err = target.Service("query", time.Millisecond, 42) + _, err = target.Service("query", time.Millisecond, 42, "") assert.Nil(t, err) assertServiceWait(t, 200, target, "deploy") @@ -104,11 +104,11 @@ func TestCloudTargetWait(t *testing.T) { target := createCloudTarget(t, srv.URL, &logWriter) assertServiceWait(t, 200, target, "deploy") - _, err := target.Service("query", time.Millisecond, 42) + _, err := target.Service("query", time.Millisecond, 42, "") assert.NotNil(t, err) vc.deploymentConverged = true - _, err = target.Service("query", time.Millisecond, 42) + _, err = target.Service("query", time.Millisecond, 42, "") assert.Nil(t, err) assertServiceWait(t, 500, target, "query") @@ -152,7 +152,7 @@ func createCloudTarget(t *testing.T, url string, logWriter io.Writer) Target { target := CloudTarget("https://example.com", Deployment{ Application: ApplicationID{Tenant: "t1", Application: "a1", Instance: "i1"}, Zone: ZoneID{Environment: "dev", Region: "us-north-1"}, - }, apiKey, TLSOptions{KeyPair: x509KeyPair}, LogOptions{Writer: logWriter}, "", "", "") + }, apiKey, TLSOptions{KeyPair: x509KeyPair}, LogOptions{Writer: logWriter}, "", "", "", nil) if ct, ok := target.(*cloudTarget); ok { ct.apiURL = url } else { @@ -162,13 +162,13 @@ func createCloudTarget(t *testing.T, url string, logWriter io.Writer) Target { } func assertServiceURL(t *testing.T, url string, target Target, service string) { - s, err := target.Service(service, 0, 42) + s, err := target.Service(service, 0, 42, "") assert.Nil(t, err) assert.Equal(t, url, s.BaseURL) } func assertServiceWait(t *testing.T, expectedStatus int, target Target, service string) { - s, err := target.Service(service, 0, 42) + s, err := target.Service(service, 0, 42, "") assert.Nil(t, err) status, err := s.Wait(0) diff --git a/vespa-osgi-testrunner/src/main/java/com/yahoo/vespa/testrunner/VespaCliTestRunner.java b/vespa-osgi-testrunner/src/main/java/com/yahoo/vespa/testrunner/VespaCliTestRunner.java index 29857102151..06df43be6a4 100644 --- a/vespa-osgi-testrunner/src/main/java/com/yahoo/vespa/testrunner/VespaCliTestRunner.java +++ b/vespa-osgi-testrunner/src/main/java/com/yahoo/vespa/testrunner/VespaCliTestRunner.java @@ -101,7 +101,9 @@ public class VespaCliTestRunner implements TestRunner { .flatMap(testsPath -> getChildDirectory(testsPath, toSuiteDirectoryName(suite))) .orElseThrow(() -> new IllegalStateException("No tests found, for suite '" + suite + "'")); - ProcessBuilder builder = new ProcessBuilder("vespa", "test", suitePath.toAbsolutePath().toString()); + ProcessBuilder builder = new ProcessBuilder("vespa", "test", suitePath.toAbsolutePath().toString(), + "--application", config.application().toFullString(), + "--zone", config.zone().value()); builder.redirectErrorStream(true); builder.environment().put("VESPA_CLI_ENDPOINTS", toEndpointsConfig(config)); builder.environment().put("VESPA_CLI_DATA_PLANE_KEY_FILE", artifactsPath.resolve("key").toAbsolutePath().toString()); diff --git a/vespa-osgi-testrunner/src/test/java/com/yahoo/vespa/testrunner/VespaCliTestRunnerTest.java b/vespa-osgi-testrunner/src/test/java/com/yahoo/vespa/testrunner/VespaCliTestRunnerTest.java index 54554bd3a2e..0b1420e85bf 100644 --- a/vespa-osgi-testrunner/src/test/java/com/yahoo/vespa/testrunner/VespaCliTestRunnerTest.java +++ b/vespa-osgi-testrunner/src/test/java/com/yahoo/vespa/testrunner/VespaCliTestRunnerTest.java @@ -55,7 +55,9 @@ class VespaCliTestRunnerTest { Path systemTests = Files.createDirectory(tests.resolve("system-test")); ProcessBuilder builder = runner.testRunProcessBuilder(TestRunner.Suite.SYSTEM_TEST, testConfig); - assertEquals(List.of("vespa", "test", systemTests.toAbsolutePath().toString()), + assertEquals(List.of("vespa", "test", systemTests.toAbsolutePath().toString(), + "--application", "t.a.i.", + "--zone", "dev.aws-us-east-1c"), builder.command()); assertEquals("{\"endpoints\":[{\"cluster\":\"default\",\"url\":\"https://dev.endpoint:443/\"}]}", builder.environment().get("VESPA_CLI_ENDPOINTS")); |