github.com/qri-io/qri@v0.10.1-0.20220104210721-c771715036cb/repo/test/spec/test_refstore.go (about)

     1  package spec
     2  
     3  import (
     4  	"context"
     5  	"fmt"
     6  	"testing"
     7  
     8  	"github.com/qri-io/qfs"
     9  	"github.com/qri-io/qri/profile"
    10  	"github.com/qri-io/qri/repo"
    11  	reporef "github.com/qri-io/qri/repo/ref"
    12  )
    13  
    14  func testRefstoreInvalidRefs(t *testing.T, rmf RepoMakerFunc) {
    15  	r, cleanup := rmf(t)
    16  	defer cleanup()
    17  
    18  	err := r.PutRef(reporef.DatasetRef{Name: "a", Path: "/path/to/a/thing"})
    19  	if err != repo.ErrPeerIDRequired {
    20  		t.Errorf("attempting to put empty peerID in refstore should return repo.ErrPeerIDRequired, got: %s", err)
    21  		return
    22  	}
    23  
    24  	err = r.PutRef(reporef.DatasetRef{ProfileID: profile.IDRawByteString("badProfileID"), Peername: "peer", Path: "/path/to/a/thing"})
    25  	if err != repo.ErrNameRequired {
    26  		t.Errorf("attempting to put empty name in refstore should return repo.ErrNameRequired, got: %s", err)
    27  		return
    28  	}
    29  
    30  	err = r.PutRef(reporef.DatasetRef{ProfileID: profile.IDRawByteString("badProfileID"), Peername: "peer", Name: "a", Path: ""})
    31  	if err != repo.ErrPathRequired {
    32  		t.Errorf("attempting to put empty path in refstore should return repo.ErrPathRequired, got: %s", err)
    33  		return
    34  	}
    35  
    36  	return
    37  }
    38  
    39  func testRefstoreRefs(t *testing.T, rmf RepoMakerFunc) {
    40  	ctx := context.Background()
    41  	r, cleanup := rmf(t)
    42  	defer cleanup()
    43  
    44  	path, err := r.Filesystem().DefaultWriteFS().Put(ctx, qfs.NewMemfileBytes("test", []byte(`{ "title": "test data" }`)))
    45  	if err != nil {
    46  		t.Errorf("error putting test file in datastore: %s", err.Error())
    47  		return
    48  	}
    49  
    50  	ref := reporef.DatasetRef{ProfileID: profile.IDB58MustDecode("QmZePf5LeXow3RW5U1AgEiNbW46YnRGhZ7HPvm1UmPFPwt"), Name: "test", Path: path, Peername: "peer"}
    51  
    52  	if err := r.PutRef(ref); err != nil {
    53  		t.Errorf("repo.PutName: %s", err.Error())
    54  		return
    55  	}
    56  
    57  	res, err := r.GetRef(reporef.DatasetRef{ProfileID: ref.ProfileID, Name: ref.Name})
    58  	if err != nil {
    59  		t.Errorf("repo.GetRef with peerID/name: %s, ref: %s", err.Error(), reporef.DatasetRef{ProfileID: ref.ProfileID, Name: ref.Name})
    60  		return
    61  	}
    62  	if !ref.Equal(res) {
    63  		t.Errorf("repo.GetRef with peerID/name response mistmatch. expected: %s, got: %s", ref, res)
    64  		return
    65  	}
    66  
    67  	res, err = r.GetRef(reporef.DatasetRef{Path: ref.Path})
    68  	if err != nil {
    69  		t.Errorf("repo.GetRef with path: %s", err.Error())
    70  		return
    71  	}
    72  	if !ref.Equal(res) {
    73  		t.Errorf("repo.GetRef with path response mismatch. expected: %s, got: %s", ref, res)
    74  		return
    75  	}
    76  
    77  	if err := r.DeleteRef(ref); err != nil {
    78  		t.Errorf("repo.DeleteName: %s", err.Error())
    79  		return
    80  	}
    81  
    82  	_, err = r.GetRef(ref)
    83  	if err != repo.ErrNotFound {
    84  		t.Errorf("repo.GetRef where ref is deleted should return ErrNotFound")
    85  		return
    86  	}
    87  	err = nil
    88  
    89  	if err := r.Filesystem().DefaultWriteFS().Delete(ctx, ref.Path); err != nil {
    90  		t.Errorf("error removing file from store")
    91  		return
    92  	}
    93  	return
    94  }
    95  
    96  func testRefstoreMain(t *testing.T, rmf RepoMakerFunc) {
    97  	ctx := context.Background()
    98  	r, cleanup := rmf(t)
    99  	defer cleanup()
   100  
   101  	refs := []reporef.DatasetRef{
   102  		{ProfileID: profile.IDB58MustDecode("QmZePf5LeXow3RW5U1AgEiNbW46YnRGhZ7HPvm1UmPFPwt"), Peername: "peer", Name: "test_namespace_a", Published: true},
   103  		{ProfileID: profile.IDB58MustDecode("QmZePf5LeXow3RW5U1AgEiNbW46YnRGhZ7HPvm1UmPFPwt"), Peername: "peer", Name: "test_namespace_b"},
   104  		{ProfileID: profile.IDB58MustDecode("QmZePf5LeXow3RW5U1AgEiNbW46YnRGhZ7HPvm1UmPFPwt"), Peername: "peer", Name: "test_namespace_c"},
   105  		{ProfileID: profile.IDB58MustDecode("QmZePf5LeXow3RW5U1AgEiNbW46YnRGhZ7HPvm1UmPFPwt"), Peername: "peer", Name: "test_namespace_d"},
   106  		{ProfileID: profile.IDB58MustDecode("QmZePf5LeXow3RW5U1AgEiNbW46YnRGhZ7HPvm1UmPFPwt"), Peername: "peer", Name: "test_namespace_e", Published: true},
   107  	}
   108  	for i, ref := range refs {
   109  		path, err := r.Filesystem().DefaultWriteFS().Put(ctx, qfs.NewMemfileBytes("test", []byte(fmt.Sprintf(`{ "title": "test_dataset_%s" }`, ref.Name))))
   110  		if err != nil {
   111  			t.Errorf("error putting test file in cafs: %s", err.Error())
   112  			return
   113  		}
   114  
   115  		ref.Path = path
   116  		// set path on input refs for later comparison
   117  		refs[i].Path = ref.Path
   118  
   119  		if err := r.PutRef(ref); err != nil {
   120  			t.Errorf("error putting name in repo for namespace test: %s", err.Error())
   121  			return
   122  		}
   123  	}
   124  
   125  	count, err := r.RefCount()
   126  	if err != nil {
   127  		t.Errorf("repo.NameCount: %s", err.Error())
   128  		return
   129  	}
   130  	if count != len(refs) {
   131  		t.Errorf("repo.NameCount should have returned %d results", len(refs))
   132  		return
   133  	}
   134  
   135  	names := []reporef.DatasetRef{}
   136  	pages := count
   137  	pageSize := count / pages
   138  	for i := 0; i <= pages; i++ {
   139  		res, err := r.References(i*pageSize, pageSize)
   140  		if err != nil {
   141  			t.Errorf("repo.References(%d,%d): %s", i*pageSize, pageSize, err.Error())
   142  			return
   143  		}
   144  		names = append(names, res...)
   145  	}
   146  	if len(names) != count {
   147  		t.Errorf("failed to read all paginated names. expected %d results, got %d", count, len(names))
   148  		return
   149  	}
   150  
   151  	idxs := map[string]int{}
   152  	for i, ref := range names {
   153  		idxs[ref.Name] = i
   154  		if err := repo.CompareDatasetRef(refs[i], names[i]); err != nil {
   155  			t.Errorf("ref %d error: %s", i, err)
   156  		}
   157  	}
   158  	for i, ref := range refs {
   159  		if i > 0 {
   160  			if idxs[ref.Name] < idxs[refs[i-1].Name] {
   161  				t.Errorf("expected results to be returned in lexographical order. %s:%d, %s:%d", ref.Name, idxs[ref.Name], refs[i-1].Name, idxs[refs[i-1].Name])
   162  				return
   163  			}
   164  		}
   165  	}
   166  
   167  	refs[0].Published = false
   168  	if err := r.PutRef(refs[0]); err != nil {
   169  		t.Errorf("updating existing ref err: %s", err)
   170  	}
   171  
   172  	unpublished, err := r.GetRef(refs[0])
   173  	if err != nil {
   174  		t.Error(err)
   175  	}
   176  	if unpublished.Published {
   177  		t.Error("expected setting published value to be retained")
   178  	}
   179  
   180  	for _, ref := range refs {
   181  		if err := r.Filesystem().DefaultWriteFS().Delete(ctx, ref.Path); err != nil {
   182  			t.Errorf("error removing path from repo store: %s", err.Error())
   183  			return
   184  		}
   185  		if err := r.DeleteRef(ref); err != nil {
   186  			t.Errorf("error removing test name from namespace: %s", err.Error())
   187  			return
   188  		}
   189  	}
   190  	return
   191  }