github.com/golang/dep@v0.5.4/gps/source_cache_bolt_test.go (about)

     1  // Copyright 2017 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  package gps
     6  
     7  import (
     8  	"io/ioutil"
     9  	"log"
    10  	"path"
    11  	"testing"
    12  	"time"
    13  
    14  	"github.com/golang/dep/gps/pkgtree"
    15  	"github.com/golang/dep/internal/test"
    16  )
    17  
    18  func TestBoltCacheTimeout(t *testing.T) {
    19  	const root = "example.com/test"
    20  	cpath, err := ioutil.TempDir("", "singlesourcecache")
    21  	if err != nil {
    22  		t.Fatalf("Failed to create temp cache dir: %s", err)
    23  	}
    24  	pi := ProjectIdentifier{ProjectRoot: root}
    25  	logger := log.New(test.Writer{TB: t}, "", 0)
    26  
    27  	start := time.Now()
    28  	bc, err := newBoltCache(cpath, start.Unix(), logger)
    29  	if err != nil {
    30  		t.Fatal(err)
    31  	}
    32  	defer bc.close()
    33  	c := bc.newSingleSourceCache(pi)
    34  
    35  	rev := Revision("test")
    36  	ai := ProjectAnalyzerInfo{Name: "name", Version: 42}
    37  
    38  	manifest := &simpleRootManifest{
    39  		c: ProjectConstraints{
    40  			ProjectRoot("foo"): ProjectProperties{
    41  				Constraint: Any(),
    42  			},
    43  			ProjectRoot("bar"): ProjectProperties{
    44  				Source:     "whatever",
    45  				Constraint: testSemverConstraint(t, "> 1.3"),
    46  			},
    47  		},
    48  		ovr: ProjectConstraints{
    49  			ProjectRoot("b"): ProjectProperties{
    50  				Constraint: testSemverConstraint(t, "2.0.0"),
    51  			},
    52  		},
    53  	}
    54  
    55  	lock := &safeLock{
    56  		p: []LockedProject{
    57  			NewLockedProject(mkPI("github.com/sdboyer/gps"), NewVersion("v0.10.0").Pair("foo"), []string{"gps"}),
    58  			NewLockedProject(mkPI("github.com/sdboyer/gps2"), NewVersion("v0.10.0").Pair("bar"), nil),
    59  			NewLockedProject(mkPI("github.com/sdboyer/gps3"), NewVersion("v0.10.0").Pair("baz"), []string{"gps", "flugle"}),
    60  			NewLockedProject(mkPI("foo"), NewVersion("nada").Pair("zero"), []string{"foo"}),
    61  			NewLockedProject(mkPI("github.com/sdboyer/gps4"), NewVersion("v0.10.0").Pair("qux"), []string{"flugle", "gps"}),
    62  		},
    63  	}
    64  
    65  	ptree := pkgtree.PackageTree{
    66  		ImportRoot: root,
    67  		Packages: map[string]pkgtree.PackageOrErr{
    68  			root: {
    69  				P: pkgtree.Package{
    70  					ImportPath:  root,
    71  					CommentPath: "comment",
    72  					Name:        "test",
    73  					Imports: []string{
    74  						"sort",
    75  					},
    76  				},
    77  			},
    78  			path.Join(root, "simple"): {
    79  				P: pkgtree.Package{
    80  					ImportPath:  path.Join(root, "simple"),
    81  					CommentPath: "comment",
    82  					Name:        "simple",
    83  					Imports: []string{
    84  						"github.com/golang/dep/gps",
    85  						"sort",
    86  					},
    87  				},
    88  			},
    89  			path.Join(root, "m1p"): {
    90  				P: pkgtree.Package{
    91  					ImportPath:  path.Join(root, "m1p"),
    92  					CommentPath: "",
    93  					Name:        "m1p",
    94  					Imports: []string{
    95  						"github.com/golang/dep/gps",
    96  						"os",
    97  						"sort",
    98  					},
    99  				},
   100  			},
   101  		},
   102  	}
   103  
   104  	pvs := []PairedVersion{
   105  		NewBranch("originalbranch").Pair("rev1"),
   106  		NewVersion("originalver").Pair("rev2"),
   107  	}
   108  
   109  	// Write values timestamped > `start`.
   110  	{
   111  		c.setManifestAndLock(rev, ai, manifest, lock)
   112  		c.setPackageTree(rev, ptree)
   113  		c.setVersionMap(pvs)
   114  	}
   115  	// Read back values timestamped > `start`.
   116  	{
   117  		gotM, gotL, ok := c.getManifestAndLock(rev, ai)
   118  		if !ok {
   119  			t.Error("no manifest and lock found for revision")
   120  		}
   121  		compareManifests(t, manifest, gotM)
   122  		// TODO(sdboyer) use DiffLocks after refactoring to avoid import cycles
   123  		if !locksAreEq(lock, gotL) {
   124  			t.Errorf("locks are different:\n\t(GOT): %s\n\t(WNT): %s", lock, gotL)
   125  		}
   126  
   127  		got, ok := c.getPackageTree(rev, root)
   128  		if !ok {
   129  			t.Errorf("no package tree found:\n\t(WNT): %#v", ptree)
   130  		}
   131  		comparePackageTree(t, ptree, got)
   132  
   133  		gotV, ok := c.getAllVersions()
   134  		if !ok || len(gotV) != len(pvs) {
   135  			t.Errorf("unexpected versions:\n\t(GOT): %#v\n\t(WNT): %#v", gotV, pvs)
   136  		} else {
   137  			SortPairedForDowngrade(gotV)
   138  			for i := range pvs {
   139  				if !pvs[i].identical(gotV[i]) {
   140  					t.Errorf("unexpected versions:\n\t(GOT): %#v\n\t(WNT): %#v", gotV, pvs)
   141  					break
   142  				}
   143  			}
   144  		}
   145  	}
   146  
   147  	if err := bc.close(); err != nil {
   148  		t.Fatal("failed to close cache:", err)
   149  	}
   150  
   151  	// Read with a later epoch. Expect no *timestamped* values, since all were < `after`.
   152  	{
   153  		after := start.Add(1000 * time.Hour)
   154  		bc, err = newBoltCache(cpath, after.Unix(), logger)
   155  		if err != nil {
   156  			t.Fatal(err)
   157  		}
   158  		c = bc.newSingleSourceCache(pi)
   159  
   160  		gotM, gotL, ok := c.getManifestAndLock(rev, ai)
   161  		if !ok {
   162  			t.Error("no manifest and lock found for revision")
   163  		}
   164  		compareManifests(t, manifest, gotM)
   165  		// TODO(sdboyer) use DiffLocks after refactoring to avoid import cycles
   166  		if !locksAreEq(lock, gotL) {
   167  			t.Errorf("locks are different:\n\t(GOT): %s\n\t(WNT): %s", lock, gotL)
   168  		}
   169  
   170  		gotPtree, ok := c.getPackageTree(rev, root)
   171  		if !ok {
   172  			t.Errorf("no package tree found:\n\t(WNT): %#v", ptree)
   173  		}
   174  		comparePackageTree(t, ptree, gotPtree)
   175  
   176  		pvs, ok := c.getAllVersions()
   177  		if ok || len(pvs) > 0 {
   178  			t.Errorf("expected no cached versions, but got:\n\t%#v", pvs)
   179  		}
   180  	}
   181  
   182  	if err := bc.close(); err != nil {
   183  		t.Fatal("failed to close cache:", err)
   184  	}
   185  
   186  	// Re-connect with the original epoch.
   187  	bc, err = newBoltCache(cpath, start.Unix(), logger)
   188  	if err != nil {
   189  		t.Fatal(err)
   190  	}
   191  	c = bc.newSingleSourceCache(pi)
   192  	// Read values timestamped > `start`.
   193  	{
   194  		gotM, gotL, ok := c.getManifestAndLock(rev, ai)
   195  		if !ok {
   196  			t.Error("no manifest and lock found for revision")
   197  		}
   198  		compareManifests(t, manifest, gotM)
   199  		// TODO(sdboyer) use DiffLocks after refactoring to avoid import cycles
   200  		if !locksAreEq(lock, gotL) {
   201  			t.Errorf("locks are different:\n\t(GOT): %s\n\t(WNT): %s", lock, gotL)
   202  		}
   203  
   204  		got, ok := c.getPackageTree(rev, root)
   205  		if !ok {
   206  			t.Errorf("no package tree found:\n\t(WNT): %#v", ptree)
   207  		}
   208  		comparePackageTree(t, ptree, got)
   209  
   210  		gotV, ok := c.getAllVersions()
   211  		if !ok || len(gotV) != len(pvs) {
   212  			t.Errorf("unexpected versions:\n\t(GOT): %#v\n\t(WNT): %#v", gotV, pvs)
   213  		} else {
   214  			SortPairedForDowngrade(gotV)
   215  			for i := range pvs {
   216  				if !pvs[i].identical(gotV[i]) {
   217  					t.Errorf("unexpected versions:\n\t(GOT): %#v\n\t(WNT): %#v", gotV, pvs)
   218  					break
   219  				}
   220  			}
   221  		}
   222  	}
   223  
   224  	// New values.
   225  	newManifest := &simpleRootManifest{
   226  		c: ProjectConstraints{
   227  			ProjectRoot("foo"): ProjectProperties{
   228  				Constraint: NewBranch("master"),
   229  			},
   230  			ProjectRoot("bar"): ProjectProperties{
   231  				Source:     "whatever",
   232  				Constraint: testSemverConstraint(t, "> 1.5"),
   233  			},
   234  		},
   235  	}
   236  
   237  	newLock := &safeLock{
   238  		p: []LockedProject{
   239  			NewLockedProject(mkPI("github.com/sdboyer/gps"), NewVersion("v1").Pair("rev1"), []string{"gps"}),
   240  		},
   241  		i: []string{"foo", "bar"},
   242  	}
   243  
   244  	newPtree := pkgtree.PackageTree{
   245  		ImportRoot: root,
   246  		Packages: map[string]pkgtree.PackageOrErr{
   247  			path.Join(root, "simple"): {
   248  				P: pkgtree.Package{
   249  					ImportPath:  path.Join(root, "simple"),
   250  					CommentPath: "newcomment",
   251  					Name:        "simple",
   252  					Imports: []string{
   253  						"github.com/golang/dep/gps42",
   254  						"test",
   255  					},
   256  				},
   257  			},
   258  			path.Join(root, "m1p"): {
   259  				P: pkgtree.Package{
   260  					ImportPath:  path.Join(root, "m1p"),
   261  					CommentPath: "",
   262  					Name:        "m1p",
   263  					Imports: []string{
   264  						"os",
   265  					},
   266  				},
   267  			},
   268  		},
   269  	}
   270  
   271  	newPVS := []PairedVersion{
   272  		NewBranch("newbranch").Pair("revA"),
   273  		NewVersion("newver").Pair("revB"),
   274  	}
   275  	// Overwrite with new values, and with timestamps > `after`.
   276  	{
   277  		c.setManifestAndLock(rev, ai, newManifest, newLock)
   278  		c.setPackageTree(rev, newPtree)
   279  		c.setVersionMap(newPVS)
   280  	}
   281  	// Read new values.
   282  	{
   283  		gotM, gotL, ok := c.getManifestAndLock(rev, ai)
   284  		if !ok {
   285  			t.Error("no manifest and lock found for revision")
   286  		}
   287  		compareManifests(t, newManifest, gotM)
   288  		// TODO(sdboyer) use DiffLocks after refactoring to avoid import cycles
   289  		if !locksAreEq(newLock, gotL) {
   290  			t.Errorf("locks are different:\n\t(GOT): %s\n\t(WNT): %s", newLock, gotL)
   291  		}
   292  
   293  		got, ok := c.getPackageTree(rev, root)
   294  		if !ok {
   295  			t.Errorf("no package tree found:\n\t(WNT): %#v", newPtree)
   296  		}
   297  		comparePackageTree(t, newPtree, got)
   298  
   299  		gotV, ok := c.getAllVersions()
   300  		if !ok || len(gotV) != len(newPVS) {
   301  			t.Errorf("unexpected versions:\n\t(GOT): %#v\n\t(WNT): %#v", gotV, newPVS)
   302  		} else {
   303  			SortPairedForDowngrade(gotV)
   304  			for i := range newPVS {
   305  				if !newPVS[i].identical(gotV[i]) {
   306  					t.Errorf("unexpected versions:\n\t(GOT): %#v\n\t(WNT): %#v", gotV, newPVS)
   307  					break
   308  				}
   309  			}
   310  		}
   311  	}
   312  }