summaryrefslogtreecommitdiffstats
path: root/client/go/internal/cli/cmd/status_test.go
diff options
context:
space:
mode:
Diffstat (limited to 'client/go/internal/cli/cmd/status_test.go')
-rw-r--r--client/go/internal/cli/cmd/status_test.go193
1 files changed, 152 insertions, 41 deletions
diff --git a/client/go/internal/cli/cmd/status_test.go b/client/go/internal/cli/cmd/status_test.go
index 76efea55503..36f51ff5073 100644
--- a/client/go/internal/cli/cmd/status_test.go
+++ b/client/go/internal/cli/cmd/status_test.go
@@ -5,10 +5,12 @@
package cmd
import (
+ "io"
"testing"
"github.com/stretchr/testify/assert"
"github.com/vespa-engine/vespa/client/go/internal/mock"
+ "github.com/vespa-engine/vespa/client/go/internal/vespa"
)
func TestStatusDeployCommand(t *testing.T) {
@@ -23,63 +25,184 @@ func TestStatusDeployCommandWithLocalTarget(t *testing.T) {
assertDeployStatus("http://127.0.0.1:19071", []string{"-t", "local"}, t)
}
-func TestStatusQueryCommand(t *testing.T) {
- assertQueryStatus("http://127.0.0.1:8080", []string{}, t)
+func TestStatusCommand(t *testing.T) {
+ assertStatus("http://127.0.0.1:8080", []string{}, t)
}
-func TestStatusQueryCommandWithUrlTarget(t *testing.T) {
- assertQueryStatus("http://mycontainertarget:8080", []string{"-t", "http://mycontainertarget:8080"}, t)
+func TestStatusCommandMultiCluster(t *testing.T) {
+ client := &mock.HTTPClient{}
+ cli, stdout, stderr := newTestCLI(t)
+ cli.httpClient = client
+
+ mockServiceStatus(client)
+ assert.NotNil(t, cli.Run("status"))
+ assert.Equal(t, "Error: no services exist\nHint: Deployment may not be ready yet\nHint: Try 'vespa status deployment'\n", stderr.String())
+
+ mockServiceStatus(client, "foo", "bar")
+ assert.Nil(t, cli.Run("status"))
+ assert.Equal(t, `Container bar at http://127.0.0.1:8080 is ready
+Container foo at http://127.0.0.1:8080 is ready
+`, stdout.String())
+
+ stdout.Reset()
+ mockServiceStatus(client, "foo", "bar")
+ assert.Nil(t, cli.Run("status", "--cluster", "foo"))
+ assert.Equal(t, "Container foo at http://127.0.0.1:8080 is ready\n", stdout.String())
+}
+
+func TestStatusCommandWithUrlTarget(t *testing.T) {
+ assertStatus("http://mycontainertarget:8080", []string{"-t", "http://mycontainertarget:8080"}, t)
+}
+
+func TestStatusCommandWithLocalTarget(t *testing.T) {
+ assertStatus("http://127.0.0.1:8080", []string{"-t", "local"}, t)
+}
+
+func TestStatusError(t *testing.T) {
+ client := &mock.HTTPClient{}
+ mockServiceStatus(client, "default")
+ client.NextStatus(500)
+ cli, _, stderr := newTestCLI(t)
+ cli.httpClient = client
+ assert.NotNil(t, cli.Run("status", "container"))
+ assert.Equal(t,
+ "Error: unhealthy container default: status 500 at http://127.0.0.1:8080/ApplicationStatus: wait timed out\n",
+ stderr.String())
+
+ stderr.Reset()
+ client.NextResponseError(io.EOF)
+ assert.NotNil(t, cli.Run("status", "container", "-t", "http://example.com"))
+ assert.Equal(t,
+ "Error: unhealthy container at http://example.com/ApplicationStatus: EOF\n",
+ stderr.String())
}
-func TestStatusQueryCommandWithLocalTarget(t *testing.T) {
- assertQueryStatus("http://127.0.0.1:8080", []string{"-t", "local"}, t)
+func TestStatusLocalDeployment(t *testing.T) {
+ client := &mock.HTTPClient{}
+ cli, stdout, stderr := newTestCLI(t)
+ cli.httpClient = client
+ resp := mock.HTTPResponse{
+ URI: "/application/v2/tenant/default/application/default/environment/prod/region/default/instance/default/serviceconverge",
+ Status: 200,
+ }
+ // Latest generation
+ resp.Body = []byte(`{"currentGeneration": 42, "converged": true}`)
+ client.NextResponse(resp)
+ assert.Nil(t, cli.Run("status", "deployment"))
+ assert.Equal(t, "", stderr.String())
+ assert.Equal(t, "Deployment is ready on config generation 42\n", stdout.String())
+
+ // Latest generation without convergence
+ resp.Body = []byte(`{"currentGeneration": 42, "converged": false}`)
+ client.NextResponse(resp)
+ assert.NotNil(t, cli.Run("status", "deployment"))
+ assert.Equal(t, "Error: deployment not converged on latest generation after waiting 0s: wait timed out\n", stderr.String())
+
+ // Explicit generation
+ stderr.Reset()
+ client.NextResponse(resp)
+ assert.NotNil(t, cli.Run("status", "deployment", "41"))
+ assert.Equal(t, "Error: deployment not converged on generation 41 after waiting 0s: wait timed out\n", stderr.String())
}
-func TestStatusDocumentCommandWithLocalTarget(t *testing.T) {
- assertDocumentStatus("http://127.0.0.1:8080", []string{"-t", "local"}, t)
+func TestStatusCloudDeployment(t *testing.T) {
+ cli, stdout, stderr := newTestCLI(t, "CI=true")
+ app := vespa.ApplicationID{Tenant: "t1", Application: "a1", Instance: "i1"}
+ assert.Nil(t, cli.Run("config", "set", "application", app.String()))
+ assert.Nil(t, cli.Run("config", "set", "target", "cloud"))
+ assert.Nil(t, cli.Run("config", "set", "zone", "dev.us-north-1"))
+ assert.Nil(t, cli.Run("auth", "api-key"))
+ stdout.Reset()
+ client := &mock.HTTPClient{}
+ cli.httpClient = client
+ // Latest run
+ client.NextResponse(mock.HTTPResponse{
+ URI: "/application/v4/tenant/t1/application/a1/instance/i1/job/dev-us-north-1?limit=1",
+ Status: 200,
+ Body: []byte(`{"runs": [{"id": 1337}]}`),
+ })
+ client.NextResponse(mock.HTTPResponse{
+ URI: "/application/v4/tenant/t1/application/a1/instance/i1/job/dev-us-north-1/run/1337?after=-1",
+ Status: 200,
+ Body: []byte(`{"active": false, "status": "success"}`),
+ })
+ assert.Nil(t, cli.Run("status", "deployment"))
+ assert.Equal(t, "", stderr.String())
+ assert.Equal(t,
+ "Deployment run 1337 has completed\nSee https://console.vespa-cloud.com/tenant/t1/application/a1/dev/instance/i1/job/dev-us-north-1/run/1337 for more details\n",
+ stdout.String())
+ // Explicit run
+ client.NextResponse(mock.HTTPResponse{
+ URI: "/application/v4/tenant/t1/application/a1/instance/i1/job/dev-us-north-1/run/42?after=-1",
+ Status: 200,
+ Body: []byte(`{"active": false, "status": "failure"}`),
+ })
+ assert.NotNil(t, cli.Run("status", "deployment", "42"))
+ assert.Equal(t, "Error: deployment run 42 incomplete after waiting 0s: run 42 ended with unsuccessful status: failure\n", stderr.String())
}
-func TestStatusErrorResponse(t *testing.T) {
- assertQueryStatusError("http://127.0.0.1:8080", []string{}, t)
+func isLocalTarget(args []string) bool {
+ for i := 0; i < len(args)-1; i++ {
+ if args[i] == "-t" {
+ return args[i+1] == "local"
+ }
+ }
+ return true // local is default
}
-func assertDeployStatus(target string, args []string, t *testing.T) {
+func assertDeployStatus(expectedTarget string, args []string, t *testing.T) {
+ t.Helper()
client := &mock.HTTPClient{}
+ client.NextResponse(mock.HTTPResponse{
+ URI: "/status.html",
+ Status: 200,
+ })
cli, stdout, _ := newTestCLI(t)
cli.httpClient = client
statusArgs := []string{"status", "deploy"}
assert.Nil(t, cli.Run(append(statusArgs, args...)...))
assert.Equal(t,
- "Deploy API at "+target+" is ready\n",
- stdout.String(),
- "vespa status config-server")
- assert.Equal(t, target+"/status.html", client.LastRequest.URL.String())
+ "Deploy API at "+expectedTarget+" is ready\n",
+ stdout.String())
+ assert.Equal(t, expectedTarget+"/status.html", client.LastRequest.URL.String())
}
-func assertQueryStatus(target string, args []string, t *testing.T) {
+func assertStatus(expectedTarget string, args []string, t *testing.T) {
+ t.Helper()
client := &mock.HTTPClient{}
+ clusterName := ""
+ for i := 0; i < 2; i++ {
+ if isLocalTarget(args) {
+ clusterName = "foo"
+ mockServiceStatus(client, clusterName)
+ }
+ client.NextResponse(mock.HTTPResponse{URI: "/ApplicationStatus", Status: 200})
+ }
cli, stdout, _ := newTestCLI(t)
cli.httpClient = client
- statusArgs := []string{"status", "query"}
+ statusArgs := []string{"status"}
assert.Nil(t, cli.Run(append(statusArgs, args...)...))
- assert.Equal(t,
- "Container (query API) at "+target+" is ready\n",
- stdout.String(),
- "vespa status container")
- assert.Equal(t, target+"/ApplicationStatus", client.LastRequest.URL.String())
-
- statusArgs = []string{"status"}
+ prefix := "Container"
+ if clusterName != "" {
+ prefix += " " + clusterName
+ }
+ assert.Equal(t, prefix+" at "+expectedTarget+" is ready\n", stdout.String())
+ assert.Equal(t, expectedTarget+"/ApplicationStatus", client.LastRequest.URL.String())
+
+ // Test legacy command
+ statusArgs = []string{"status query"}
stdout.Reset()
assert.Nil(t, cli.Run(append(statusArgs, args...)...))
- assert.Equal(t,
- "Container (query API) at "+target+" is ready\n",
- stdout.String(),
- "vespa status (the default)")
- assert.Equal(t, target+"/ApplicationStatus", client.LastRequest.URL.String())
+ assert.Equal(t, prefix+" at "+expectedTarget+" is ready\n", stdout.String())
+ assert.Equal(t, expectedTarget+"/ApplicationStatus", client.LastRequest.URL.String())
}
func assertDocumentStatus(target string, args []string, t *testing.T) {
+ t.Helper()
client := &mock.HTTPClient{}
+ if isLocalTarget(args) {
+ mockServiceStatus(client, "default")
+ }
cli, stdout, _ := newTestCLI(t)
cli.httpClient = client
assert.Nil(t, cli.Run("status", "document"))
@@ -89,15 +212,3 @@ func assertDocumentStatus(target string, args []string, t *testing.T) {
"vespa status container")
assert.Equal(t, target+"/ApplicationStatus", client.LastRequest.URL.String())
}
-
-func assertQueryStatusError(target string, args []string, t *testing.T) {
- client := &mock.HTTPClient{}
- client.NextStatus(500)
- cli, _, stderr := newTestCLI(t)
- cli.httpClient = client
- assert.NotNil(t, cli.Run("status", "container"))
- assert.Equal(t,
- "Error: Container (query API) at "+target+" is not ready: status 500\n",
- stderr.String(),
- "vespa status container")
-}