From 11c1fe3f948ec1fd541459197276107975d51a20 Mon Sep 17 00:00:00 2001 From: Winfried Plappert Date: Fri, 21 Feb 2025 18:41:52 +0000 Subject: [PATCH 1/4] cmd_ls: one more test: ls --json to check the JSON lines validate that the individual JSON lines are valid JSON statements. Check for snap ID and the path names in the backup. --- cmd/restic/cmd_ls_integration_test.go | 64 +++++++++++++++++++++++++++ 1 file changed, 64 insertions(+) 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) + } +} From 2846b96c6325e5c155225e5652358891ba5b9388 Mon Sep 17 00:00:00 2001 From: Winfried Plappert Date: Fri, 21 Feb 2025 19:03:42 +0000 Subject: [PATCH 2/4] add the changelog/unreleased/pull-5255 file. --- changelog/unreleased/pull-5255 | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 changelog/unreleased/pull-5255 diff --git a/changelog/unreleased/pull-5255 b/changelog/unreleased/pull-5255 new file mode 100644 index 000000000..e3ce5acd5 --- /dev/null +++ b/changelog/unreleased/pull-5255 @@ -0,0 +1,8 @@ +Change: add a test to cmd_ls_integration_test.go: test `rest ls --json` + +Create backup of 0/for_cmd_ls, which contains only a few files. +Compare first line of ls --json oytput with snapshotID coming back from +`testRunList()`. +Compare node.Path with expected results list. + +https://github.com/restic/restic/pull/5255 From b61b6ff53951d208bf0d89d7befed3cc89bdf8e6 Mon Sep 17 00:00:00 2001 From: Winfried Plappert Date: Fri, 21 Feb 2025 21:00:45 +0000 Subject: [PATCH 3/4] cmd_ls_integration_test: fixed white space issue (gofmt) --- cmd/restic/cmd_ls_integration_test.go | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/cmd/restic/cmd_ls_integration_test.go b/cmd/restic/cmd_ls_integration_test.go index c0008c586..b9d9649f0 100644 --- a/cmd/restic/cmd_ls_integration_test.go +++ b/cmd/restic/cmd_ls_integration_test.go @@ -146,13 +146,13 @@ func TestRunLsJson(t *testing.T) { // 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 + 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 From 6d22ed22ee36dc3a8926b635cb11c8290ae95f8c Mon Sep 17 00:00:00 2001 From: Winfried Plappert Date: Sun, 23 Feb 2025 21:39:21 +0000 Subject: [PATCH 4/4] cmd_ls_integration_test --json lines: implemented recommendations from Michael Eischer --- changelog/unreleased/pull-5255 | 8 -------- cmd/restic/cmd_ls_integration_test.go | 20 ++++++++------------ 2 files changed, 8 insertions(+), 20 deletions(-) delete mode 100644 changelog/unreleased/pull-5255 diff --git a/changelog/unreleased/pull-5255 b/changelog/unreleased/pull-5255 deleted file mode 100644 index e3ce5acd5..000000000 --- a/changelog/unreleased/pull-5255 +++ /dev/null @@ -1,8 +0,0 @@ -Change: add a test to cmd_ls_integration_test.go: test `rest ls --json` - -Create backup of 0/for_cmd_ls, which contains only a few files. -Compare first line of ls --json oytput with snapshotID coming back from -`testRunList()`. -Compare node.Path with expected results list. - -https://github.com/restic/restic/pull/5255 diff --git a/cmd/restic/cmd_ls_integration_test.go b/cmd/restic/cmd_ls_integration_test.go index b9d9649f0..f72a4533a 100644 --- a/cmd/restic/cmd_ls_integration_test.go +++ b/cmd/restic/cmd_ls_integration_test.go @@ -120,18 +120,14 @@ func TestRunLsJson(t *testing.T) { 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) + snapshotIDs := testListSnapshots(t, env.gopts, 1) - 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'}) + env.gopts.Quiet = true + env.gopts.JSON = true + buf := testRunLsWithOpts(t, env.gopts, LsOptions{}, []string{"latest"}) + byteLines := bytes.Split(buf, []byte{'\n'}) - // the snapshot structure from cmd_ls + // partial copy of snapshot structure from cmd_ls type lsSnapshot struct { *restic.Snapshot ID *restic.ID `json:"id"` @@ -144,7 +140,7 @@ func TestRunLsJson(t *testing.T) { 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 + // partial copy of node structure from cmd_ls type lsNode struct { Name string `json:"name"` Type string `json:"type"` @@ -162,6 +158,6 @@ func TestRunLsJson(t *testing.T) { } rtest.OK(t, json.Unmarshal(nodeLine, &testNode)) - rtest.Assert(t, testNode.Path == pathList[i], "expected %s actual %s", pathList[i], testNode.Path) + rtest.Equals(t, pathList[i], testNode.Path) } }