diff --git a/cmd/restic/cmd_ls_integration_test.go b/cmd/restic/cmd_ls_integration_test.go index b9d565364..c0008c586 100644 --- a/cmd/restic/cmd_ls_integration_test.go +++ b/cmd/restic/cmd_ls_integration_test.go @@ -1,12 +1,14 @@ package main import ( + "bytes" "context" "encoding/json" "fmt" "strings" "testing" + "github.com/restic/restic/internal/restic" rtest "github.com/restic/restic/internal/test" ) @@ -101,3 +103,65 @@ func TestRunLsSort(t *testing.T) { rtest.Equals(t, test.expected, fileList, fmt.Sprintf("mismatch for mode %v", test.mode)) } } + +// JSON lines test +func TestRunLsJson(t *testing.T) { + pathList := []string{ + "/0", + "/0/for_cmd_ls", + "/0/for_cmd_ls/file1.txt", + "/0/for_cmd_ls/file2.txt", + "/0/for_cmd_ls/python.py", + } + + env, cleanup := withTestEnvironment(t) + defer cleanup() + + testSetupBackupData(t, env) + opts := BackupOptions{} + testRunBackup(t, env.testdata, []string{"0/for_cmd_ls"}, opts, env.gopts) + snapshotIDs := testRunList(t, "snapshots", env.gopts) + rtest.Assert(t, len(snapshotIDs) == 1, "expected one snapshot, got %v", snapshotIDs) + + buf, err := withCaptureStdout(func() error { + env.gopts.Quiet = true + env.gopts.JSON = true + return runLs(context.TODO(), LsOptions{}, env.gopts, []string{"latest"}) + }) + rtest.OK(t, err) + byteLines := bytes.Split(buf.Bytes(), []byte{'\n'}) + + // the snapshot structure from cmd_ls + type lsSnapshot struct { + *restic.Snapshot + ID *restic.ID `json:"id"` + ShortID string `json:"short_id"` // deprecated + MessageType string `json:"message_type"` // "snapshot" + StructType string `json:"struct_type"` // "snapshot", deprecated + } + + var snappy lsSnapshot + rtest.OK(t, json.Unmarshal(byteLines[0], &snappy)) + rtest.Equals(t, snappy.ShortID, snapshotIDs[0].Str(), "expected snap IDs to be identical") + + // the node structure from cmd_ls + type lsNode struct { + Name string `json:"name"` + Type string `json:"type"` + Path string `json:"path"` + Permissions string `json:"permissions,omitempty"` + Inode uint64 `json:"inode,omitempty"` + MessageType string `json:"message_type"` // "node" + StructType string `json:"struct_type"` // "node", deprecated + } + + var testNode lsNode + for i, nodeLine := range byteLines[1:] { + if len(nodeLine) == 0 { + break + } + + rtest.OK(t, json.Unmarshal(nodeLine, &testNode)) + rtest.Assert(t, testNode.Path == pathList[i], "expected %s actual %s", pathList[i], testNode.Path) + } +}