This test isn't exhaustive, but it covers the basics.
This commit is contained in:
sam boyer 2017-04-03 11:28:07 -04:00
Родитель 749cf21e50
Коммит 00e87fec03
5 изменённых файлов: 214 добавлений и 2 удалений

Просмотреть файл

@ -524,6 +524,17 @@ func (m vcsExtensionDeducer) deduceSource(path string, u *url.URL) (maybeSource,
}
}
// A deducer takes an import path and inspects it to determine where the
// corresponding project root should be. It applies a number of matching
// techniques, eventually falling back to an HTTP request for go-get metadata if
// none of the explicit rules succeed.
//
// The only real implementation is deductionCoordinator. The interface is
// primarily intended for testing purposes.
type deducer interface {
deduceRootPath(ctx context.Context, path string) (pathDeduction, error)
}
type deductionCoordinator struct {
suprvsr *supervisor
mut sync.RWMutex

Просмотреть файл

@ -43,11 +43,11 @@ type sourceCoordinator struct {
nameToURL map[string]string
psrcmut sync.Mutex // guards protoSrcs map
protoSrcs map[string][]srcReturnChans
deducer *deductionCoordinator
deducer deducer
cachedir string
}
func newSourceCoordinator(superv *supervisor, deducer *deductionCoordinator, cachedir string) *sourceCoordinator {
func newSourceCoordinator(superv *supervisor, deducer deducer, cachedir string) *sourceCoordinator {
return &sourceCoordinator{
supervisor: superv,
deducer: deducer,

149
source_test.go Normal file
Просмотреть файл

@ -0,0 +1,149 @@
package gps
import (
"context"
"io/ioutil"
"reflect"
"testing"
"github.com/sdboyer/gps/pkgtree"
)
// Executed in parallel by TestSlowVcs
func testSourceGateway(t *testing.T) {
t.Parallel()
if testing.Short() {
t.Skip("Skipping gateway testing in short mode")
}
requiresBins(t, "git")
cachedir, err := ioutil.TempDir("", "smcache")
if err != nil {
t.Fatalf("failed to create temp dir: %s", err)
}
bgc := context.Background()
ctx, cancelFunc := context.WithCancel(bgc)
defer func() {
removeAll(cachedir)
cancelFunc()
}()
do := func(wantstate sourceState) func(t *testing.T) {
return func(t *testing.T) {
superv := newSupervisor(ctx)
sc := newSourceCoordinator(superv, newDeductionCoordinator(superv), cachedir)
id := mkPI("github.com/sdboyer/deptest")
sg, err := sc.getSourceGatewayFor(ctx, id)
if err != nil {
t.Fatal(err)
}
if _, ok := sg.src.(*gitSource); !ok {
t.Fatalf("Expected a gitSource, got a %T", sg.src)
}
if sg.srcState != wantstate {
t.Fatalf("expected state on initial create to be %v, got %v", wantstate, sg.srcState)
}
if err := sg.syncLocal(ctx); err != nil {
t.Fatalf("error on cloning git repo: %s", err)
}
cvlist := sg.cache.getAllVersions()
if len(cvlist) != 4 {
t.Fatalf("repo setup should've cached four versions, got %v: %s", len(cvlist), cvlist)
}
wanturl := "https://" + id.normalizedSource()
goturl, err := sg.sourceURL(ctx)
if err != nil {
t.Fatalf("got err from sourceURL: %s", err)
}
if wanturl != goturl {
t.Fatalf("Expected %s as source URL, got %s", wanturl, goturl)
}
vlist, err := sg.listVersions(ctx)
if err != nil {
t.Fatalf("Unexpected error getting version pairs from git repo: %s", err)
}
if len(vlist) != 4 {
t.Fatalf("git test repo should've produced four versions, got %v: vlist was %s", len(vlist), vlist)
} else {
sortForUpgrade(vlist)
evl := []PairedVersion{
NewVersion("v1.0.0").Is(Revision("ff2948a2ac8f538c4ecd55962e919d1e13e74baf")),
NewVersion("v0.8.1").Is(Revision("3f4c3bea144e112a69bbe5d8d01c1b09a544253f")),
NewVersion("v0.8.0").Is(Revision("ff2948a2ac8f538c4ecd55962e919d1e13e74baf")),
newDefaultBranch("master").Is(Revision("3f4c3bea144e112a69bbe5d8d01c1b09a544253f")),
}
if !reflect.DeepEqual(vlist, evl) {
t.Fatalf("Version list was not what we expected:\n\t(GOT): %s\n\t(WNT): %s", vlist, evl)
}
}
rev := Revision("c575196502940c07bf89fd6d95e83b999162e051")
// check that an expected rev is not in cache
_, has := sg.cache.getVersionsFor(rev)
if has {
t.Fatal("shouldn't have bare revs in cache without specifically requesting them")
}
is, err := sg.revisionPresentIn(ctx, Revision("c575196502940c07bf89fd6d95e83b999162e051"))
if err != nil {
t.Fatalf("unexpected error while checking revision presence: %s", err)
} else if !is {
t.Fatalf("revision that should exist was not present")
}
// check that an expected rev is not in cache
_, has = sg.cache.getVersionsFor(rev)
if !has {
t.Fatal("bare rev should be in cache after specific request for it")
}
_, err = sg.listPackages(ctx, ProjectRoot("github.com/sdboyer/deptest"), NewVersion("notexist"))
if err == nil {
t.Fatal("should have errored on nonexistent version")
}
wantptree := pkgtree.PackageTree{
ImportRoot: "github.com/sdboyer/deptest",
Packages: map[string]pkgtree.PackageOrErr{
"github.com/sdboyer/deptest": pkgtree.PackageOrErr{
P: pkgtree.Package{
ImportPath: "github.com/sdboyer/deptest",
Name: "deptest",
Imports: []string{},
},
},
},
}
ptree, err := sg.listPackages(ctx, ProjectRoot("github.com/sdboyer/deptest"), Revision("ff2948a2ac8f538c4ecd55962e919d1e13e74baf"))
if err != nil {
t.Fatalf("unexpected err when getting package tree with known rev: %s", err)
}
if !reflect.DeepEqual(wantptree, ptree) {
t.Fatalf("got incorrect PackageTree:\n\t(GOT): %#v\n\t(WNT): %#v", wantptree, ptree)
}
ptree, err = sg.listPackages(ctx, ProjectRoot("github.com/sdboyer/deptest"), NewVersion("v1.0.0"))
if err != nil {
t.Fatalf("unexpected err when getting package tree with unpaired good version: %s", err)
}
if !reflect.DeepEqual(wantptree, ptree) {
t.Fatalf("got incorrect PackageTree:\n\t(GOT): %#v\n\t(WNT): %#v", wantptree, ptree)
}
}
}
// Run test twice so that we cover both the existing and non-existing case;
// only difference in results is the initial setup state.
t.Run("empty", do(sourceIsSetUp|sourceExistsUpstream|sourceHasLatestVersionList))
t.Run("exists", do(sourceIsSetUp|sourceExistsLocally|sourceExistsUpstream|sourceHasLatestVersionList))
}

Просмотреть файл

@ -13,9 +13,11 @@ import (
// Parent test that executes all the slow vcs interaction tests in parallel.
func TestSlowVcs(t *testing.T) {
t.Run("write-deptree", testWriteDepTree)
t.Run("source-gateway", testSourceGateway)
t.Run("bzr-repo", testBzrRepo)
t.Run("bzr-source", testBzrSourceInteractions)
t.Run("svn-repo", testSvnRepo)
// TODO(sdboyer) svn-source
t.Run("hg-repo", testHgRepo)
t.Run("hg-source", testHgSourceInteractions)
t.Run("git-repo", testGitRepo)

Просмотреть файл

@ -610,6 +610,56 @@ func SortForUpgrade(vl []Version) {
sort.Sort(upgradeVersionSorter(vl))
}
// temporary shim until this can replace SortForUpgrade, after #202
func sortForUpgrade(vl []PairedVersion) {
sort.Slice(vl, func(i, j int) bool {
var l, r Version = vl[i], vl[j]
if tl, ispair := l.(versionPair); ispair {
l = tl.v
}
if tr, ispair := r.(versionPair); ispair {
r = tr.v
}
switch compareVersionType(l, r) {
case -1:
return true
case 1:
return false
case 0:
break
default:
panic("unreachable")
}
switch tl := l.(type) {
case branchVersion:
tr := r.(branchVersion)
if tl.isDefault != tr.isDefault {
// If they're not both defaults, then return the left val: if left
// is the default, then it is "less" (true) b/c we want it earlier.
// Else the right is the default, and so the left should be later
// (false).
return tl.isDefault
}
return l.String() < r.String()
case Revision, plainVersion:
// All that we can do now is alpha sort
return l.String() < r.String()
}
// This ensures that pre-release versions are always sorted after ALL
// full-release versions
lsv, rsv := l.(semVersion).sv, r.(semVersion).sv
lpre, rpre := lsv.Prerelease() == "", rsv.Prerelease() == ""
if (lpre && !rpre) || (!lpre && rpre) {
return lpre
}
return lsv.GreaterThan(rsv)
})
}
// SortForDowngrade sorts a slice of []Version in roughly ascending order, so
// that presumably older versions are visited first.
//