github.com/qri-io/qri@v0.10.1-0.20220104210721-c771715036cb/cmd/remove_integration_test.go (about)

     1  package cmd
     2  
     3  import (
     4  	"os"
     5  	"path/filepath"
     6  	"regexp"
     7  	"strings"
     8  	"testing"
     9  
    10  	"github.com/google/go-cmp/cmp"
    11  )
    12  
    13  func parsePathFromRef(ref string) string {
    14  	pos := strings.Index(ref, "@")
    15  	if pos == -1 {
    16  		return ref
    17  	}
    18  	return ref[pos+1:]
    19  }
    20  
    21  // Test that adding two versions, then deleting one, ends up with only the first version
    22  func TestRemoveOneRevisionFromRepo(t *testing.T) {
    23  	run := NewTestRunner(t, "test_peer_remote_one_rev_from_repo", "qri_test_remove_one_rev_from_repo")
    24  	defer run.Delete()
    25  
    26  	// Save a dataset containing a body.json, no meta, nothing special.
    27  	output := run.MustExecCombinedOutErr(t, "qri save --body=testdata/movies/body_two.json me/remove_test")
    28  	ref1 := parsePathFromRef(parseRefFromSave(output))
    29  	dsPath1 := run.GetPathForDataset(t, 0)
    30  	if ref1 != dsPath1 {
    31  		t.Fatalf("ref from first save should match what is in qri repo. got %q want %q", ref1, dsPath1)
    32  	}
    33  
    34  	// Save another version
    35  	output = run.MustExecCombinedOutErr(t, "qri save --body=testdata/movies/body_four.json me/remove_test")
    36  	ref2 := parsePathFromRef(parseRefFromSave(output))
    37  	dsPath2 := run.GetPathForDataset(t, 0)
    38  	if ref2 != dsPath2 {
    39  		t.Fatalf("ref from second save should match what is in qri repo. got %q want %q", ref2, dsPath2)
    40  	}
    41  
    42  	// Remove one version
    43  	run.MustExec(t, "qri remove --revisions=1 me/remove_test")
    44  
    45  	// Verify that dsref of HEAD is the same as the result of the first save command
    46  	dsPath3 := run.GetPathForDataset(t, 0)
    47  	if ref1 != dsPath3 {
    48  		t.Errorf("after delete, ref should match the first version, expected: %s\n, got: %s\n",
    49  			ref1, dsPath3)
    50  	}
    51  }
    52  
    53  // Test that adding two versions, then deleting all will end up with nothing left
    54  func TestRemoveAllRevisionsFromRepo(t *testing.T) {
    55  	run := NewTestRunner(t, "test_peer_remove_all_rev_", "qri_test_remove_all_rev_from_repo")
    56  	defer run.Delete()
    57  
    58  	// Save a dataset containing a body.json, no meta, nothing special.
    59  	output := run.MustExecCombinedOutErr(t, "qri save --body=testdata/movies/body_two.json me/remove_test")
    60  	ref1 := parsePathFromRef(parseRefFromSave(output))
    61  	dsPath1 := run.GetPathForDataset(t, 0)
    62  	if ref1 != dsPath1 {
    63  		t.Fatal("ref from first save should match what is in qri repo")
    64  	}
    65  
    66  	// Save another version
    67  	output = run.MustExecCombinedOutErr(t, "qri save --body=testdata/movies/body_four.json me/remove_test")
    68  	ref2 := parsePathFromRef(parseRefFromSave(output))
    69  	dsPath2 := run.GetPathForDataset(t, 0)
    70  	if ref2 != dsPath2 {
    71  		t.Fatal("ref from second save should match what is in qri repo")
    72  	}
    73  
    74  	// Remove one version
    75  	run.MustExec(t, "qri remove --all me/remove_test")
    76  
    77  	// Verify that dsref of HEAD is the same as the result of the first save command
    78  	dsPath3 := run.GetPathForDataset(t, 0)
    79  	if dsPath3 != "" {
    80  		t.Errorf("after delete, dataset should not exist, got: %s\n", dsPath3)
    81  	}
    82  }
    83  
    84  // Test that a dataset can be removed even if the logbook is missing
    85  func TestRemoveEvenIfLogbookGone(t *testing.T) {
    86  	run := NewTestRunner(t, "test_peer_remove_no_logbook", "qri_test_remove_no_logbook")
    87  	defer run.Delete()
    88  
    89  	// Save the new dataset
    90  	run.MustExec(t, "qri save --body testdata/movies/body_ten.csv me/movies")
    91  
    92  	// Remove the logbook
    93  	logbookFile := filepath.Join(run.RepoRoot.RootPath, "qri/logbook.qfb")
    94  	if _, err := os.Stat(logbookFile); os.IsNotExist(err) {
    95  		t.Fatal("logbook does not exist")
    96  	}
    97  	err := os.Remove(logbookFile)
    98  	if err != nil {
    99  		t.Fatal(err)
   100  	}
   101  
   102  	// Remove all should still work, even though the logbook is gone.
   103  	if err := run.ExecCommand("qri remove --revisions=all me/movies"); err != nil {
   104  		t.Error(err)
   105  	}
   106  }
   107  
   108  // Test that an added dataset can be removed, which removes it from the logbook
   109  func TestRemoveEvenIfForeignDataset(t *testing.T) {
   110  	run := NewTestRunnerWithMockRemoteClient(t, "test_peer_remove_foreign", "remove_foreign")
   111  	defer run.Delete()
   112  
   113  	// Regex that replaces the timestamp with just static text
   114  	fixTs := regexp.MustCompile(`"(timestamp|commitTime)":\s?"[0-9TZ.:+-]*?"`)
   115  
   116  	output := run.MustExec(t, "qri logbook --raw")
   117  	expectEmpty := `[{"ops":[{"type":"init","model":"user","name":"test_peer_remove_foreign","authorID":"QmeL2mdVka1eahKENjehK6tBxkkpk5dNQ1qMcgWi7Hrb4B","timestamp":"ts"}]}]`
   118  	actual := string(fixTs.ReplaceAll([]byte(output), []byte(`"timestamp":"ts"`)))
   119  	if diff := cmp.Diff(expectEmpty, actual); diff != "" {
   120  		t.Errorf("unexpected (-want +got):\n%s", diff)
   121  	}
   122  
   123  	// Save a foreign dataset
   124  	run.MustExec(t, "qri add other_peer/their_dataset")
   125  
   126  	output = run.MustExec(t, "qri logbook --raw")
   127  	expectHasForiegn := `[{"ops":[{"type":"init","model":"user","name":"test_peer_remove_foreign","authorID":"QmeL2mdVka1eahKENjehK6tBxkkpk5dNQ1qMcgWi7Hrb4B","timestamp":"ts"}]},{"ops":[{"type":"init","model":"user","name":"other_peer","authorID":"QmWYgD49r9HnuXEppQEq1a7SUUryja4QNs9E6XCH2PayCD","timestamp":"ts"}],"logs":[{"ops":[{"type":"init","model":"dataset","name":"their_dataset","authorID":"xstfcrqf26suws6dnjih4ugvmfk6w5o7e6b7rmflt7aso6htyufa","timestamp":"ts"}],"logs":[{"ops":[{"type":"init","model":"branch","name":"main","authorID":"xstfcrqf26suws6dnjih4ugvmfk6w5o7e6b7rmflt7aso6htyufa","timestamp":"ts"},{"type":"init","model":"commit","timestamp":"ts","size":2,"note":"created dataset"}]}]}]}]`
   128  	actual = string(fixTs.ReplaceAll([]byte(output), []byte(`"timestamp":"ts"`)))
   129  	if diff := cmp.Diff(expectHasForiegn, actual); diff != "" {
   130  		t.Errorf("unexpected (-want +got):\n%s", diff)
   131  	}
   132  
   133  	// Remove all should still work, even though the dataset is foreign
   134  	if err := run.ExecCommand("qri remove --revisions=all other_peer/their_dataset"); err != nil {
   135  		t.Error(err)
   136  	}
   137  
   138  	output = run.MustExec(t, "qri logbook --raw")
   139  	// Log is removed for the database, but author init still remains
   140  	expectEmptyAuthor := `[{"ops":[{"type":"init","model":"user","name":"test_peer_remove_foreign","authorID":"QmeL2mdVka1eahKENjehK6tBxkkpk5dNQ1qMcgWi7Hrb4B","timestamp":"ts"}]},{"ops":[{"type":"init","model":"user","name":"other_peer","authorID":"QmWYgD49r9HnuXEppQEq1a7SUUryja4QNs9E6XCH2PayCD","timestamp":"ts"}]}]`
   141  	actual = string(fixTs.ReplaceAll([]byte(output), []byte(`"timestamp":"ts"`)))
   142  	if diff := cmp.Diff(expectEmptyAuthor, actual); diff != "" {
   143  		t.Errorf("unexpected (-want +got):\n%s", diff)
   144  	}
   145  }
   146  
   147  // Test that an added dataset can be removed even if the logbook is missing
   148  func TestRemoveEvenIfForeignDatasetWithNoOplog(t *testing.T) {
   149  	run := NewTestRunnerWithMockRemoteClient(t, "test_peer_no_oplog", "remove_no_oplog")
   150  	defer run.Delete()
   151  
   152  	// Save a foreign dataset
   153  	run.MustExec(t, "qri add other_peer/their_dataset")
   154  
   155  	// Remove the logbook
   156  	logbookFile := filepath.Join(run.RepoRoot.RootPath, "qri/logbook.qfb")
   157  	if _, err := os.Stat(logbookFile); os.IsNotExist(err) {
   158  		t.Fatal("logbook does not exist")
   159  	}
   160  	err := os.Remove(logbookFile)
   161  	if err != nil {
   162  		t.Fatal(err)
   163  	}
   164  
   165  	// Remove all should still work, even though the dataset is foreign with no logbook
   166  	if err := run.ExecCommand("qri remove --revisions=all other_peer/their_dataset"); err != nil {
   167  		t.Error(err)
   168  	}
   169  }