diff --git a/client/go/internal/cli/cmd/visit.go b/client/go/internal/cli/cmd/visit.go index 6f4280b1f58..cdd84ab659a 100644 --- a/client/go/internal/cli/cmd/visit.go +++ b/client/go/internal/cli/cmd/visit.go @@ -42,8 +42,9 @@ type visitArgs struct { headers []string stream bool - cli *CLI - header http.Header + cli *CLI + header http.Header + feedStarted bool } func (v *visitArgs) writeBytes(b []byte) { @@ -59,30 +60,25 @@ func (v *visitArgs) debugPrint(s string) { } func (v *visitArgs) dumpDocuments(documents []DocumentBlob) { - comma := false - pretty := false - if v.makeFeed { - comma = true - pretty = v.pretty - } else if !v.jsonLines { + if !v.makeFeed && !v.jsonLines { return } - for i, value := range documents { - if pretty { + for _, value := range documents { + blob := value.blob + if v.makeFeed && v.pretty { var prettyJSON bytes.Buffer - parseError := json.Indent(&prettyJSON, value.blob, "", " ") - if parseError != nil { - v.writeBytes(value.blob) - } else { - v.writeBytes(prettyJSON.Bytes()) + if err := json.Indent(&prettyJSON, value.blob, "", " "); err == nil { + blob = prettyJSON.Bytes() } - } else { - v.writeBytes(value.blob) } - var lastDocument = i == (len(documents) - 1) - if comma && !lastDocument { - v.writeString(",\n") + if v.makeFeed { + if v.feedStarted { + v.writeString(",\n") + } + v.feedStarted = true + v.writeBytes(blob) } else { + v.writeBytes(blob) v.writeString("\n") } } @@ -311,7 +307,7 @@ func visitClusters(vArgs *visitArgs, service *vespa.Service) (res OperationResul } } if vArgs.makeFeed { - vArgs.writeString("]\n") + vArgs.writeString("\n]\n") } return res } diff --git a/client/go/internal/cli/cmd/visit_test.go b/client/go/internal/cli/cmd/visit_test.go index 53fb5fc89e0..50182051618 100644 --- a/client/go/internal/cli/cmd/visit_test.go +++ b/client/go/internal/cli/cmd/visit_test.go @@ -3,6 +3,7 @@ package cmd import ( "bytes" + "encoding/json" "fmt" "net/http" "testing" @@ -319,6 +320,26 @@ func TestRemoveEntriesAreIgnored(t *testing.T) { assert.Equal(t, 2, len(client.Requests)) // probe + 1 visit } +func TestMakeFeedMultipleClusters(t *testing.T) { + clusterAResponse := normalpre + document1 + `],"documentCount":1}` + clusterBResponse := normalpre + document2 + `],"documentCount":1}` + client := &mock.HTTPClient{} + client.NextResponseString(200, handlersResponse) + client.NextResponseString(400, `{"pathId":"/document/v1/","message":"no content cluster '*', only 'clusterA', 'clusterB'"}`) + client.NextResponseString(200, clusterAResponse) + client.NextResponseString(200, clusterBResponse) + client.NextResponseString(200, clusterAResponse) + client.NextResponseString(200, clusterBResponse) + cli, stdout, _ := newTestCLI(t) + cli.httpClient = client + cli.sleeper = func(d time.Duration) {} + err := cli.Run("visit", "--make-feed", "-t", "http://127.0.0.1:8080") + assert.Nil(t, err) + var docs []json.RawMessage + assert.Nil(t, json.Unmarshal(stdout.Bytes(), &docs)) + assert.Equal(t, 4, len(docs)) +} + func inRangeMillis(v time.Duration, lo int64, hi int64) bool { return v.Milliseconds() >= lo && v.Milliseconds() <= hi }