1
0
mirror of https://github.com/golang/go synced 2024-10-01 04:08:32 -06:00
go/internal/imports/mod_cache_test.go
Heschi Kreinick d2fffb4b84 internal/imports: cache things outside the mod cache
Since a user's module cache is generally going to be much bigger than
their main module, one would expect that caching just information about
the module cache would be sufficient. It turns out that's not correct.
When we discover something in the module cache, we have to make sure
that a different version of it isn't already in scope. Doing that can
require information about the main module or replace targets, so that
needs to be cached too.

Concretely, when I'm working in x/tools, if a scan discovers a version
of x/tools in the module cache, it should usually ignore that version.
But that might not be true in more complicated cases, especially those
involving nested modules whose boundaries change.

So, cache everything except GOROOT. Since the new data is mutable,
we store it separately from the module cache data so that it can be
discarded easily between runs.

Change-Id: I47364f6c0270fee03af8898fec6c85d1b9c8d780
Reviewed-on: https://go-review.googlesource.com/c/tools/+/202045
Reviewed-by: Rebecca Stambler <rstambler@golang.org>
2019-10-21 20:45:41 +00:00

124 lines
2.4 KiB
Go

package imports
import (
"fmt"
"sort"
"testing"
)
func TestDirectoryPackageInfoReachedStatus(t *testing.T) {
tests := []struct {
info directoryPackageInfo
target directoryPackageStatus
wantStatus bool
wantError bool
}{
{
info: directoryPackageInfo{
status: directoryScanned,
err: nil,
},
target: directoryScanned,
wantStatus: true,
},
{
info: directoryPackageInfo{
status: directoryScanned,
err: fmt.Errorf("error getting to directory scanned"),
},
target: directoryScanned,
wantStatus: true,
wantError: true,
},
{
info: directoryPackageInfo{},
target: directoryScanned,
wantStatus: false,
},
}
for _, tt := range tests {
gotStatus, gotErr := tt.info.reachedStatus(tt.target)
if gotErr != nil {
if !tt.wantError {
t.Errorf("unexpected error: %s", gotErr)
}
continue
}
if tt.wantStatus != gotStatus {
t.Errorf("reached status expected: %v, got: %v", tt.wantStatus, gotStatus)
}
}
}
func TestModCacheInfo(t *testing.T) {
m := &dirInfoCache{
dirs: make(map[string]*directoryPackageInfo),
}
dirInfo := []struct {
dir string
info directoryPackageInfo
}{
{
dir: "mypackage",
info: directoryPackageInfo{
status: directoryScanned,
dir: "mypackage",
nonCanonicalImportPath: "example.com/mypackage",
needsReplace: false,
},
},
{
dir: "bad package",
info: directoryPackageInfo{
status: directoryScanned,
err: fmt.Errorf("bad package"),
},
},
{
dir: "mypackage/other",
info: directoryPackageInfo{
dir: "mypackage/other",
nonCanonicalImportPath: "example.com/mypackage/other",
needsReplace: false,
},
},
}
for _, d := range dirInfo {
m.Store(d.dir, d.info)
}
for _, d := range dirInfo {
val, ok := m.Load(d.dir)
if !ok {
t.Errorf("directory not loaded: %s", d.dir)
}
if val != d.info {
t.Errorf("expected: %v, got: %v", d.info, val)
}
}
var wantKeys []string
for _, d := range dirInfo {
wantKeys = append(wantKeys, d.dir)
}
sort.Strings(wantKeys)
gotKeys := m.Keys()
sort.Strings(gotKeys)
if len(gotKeys) != len(wantKeys) {
t.Errorf("different length of keys. expected: %d, got: %d", len(wantKeys), len(gotKeys))
}
for i, want := range wantKeys {
if want != gotKeys[i] {
t.Errorf("%d: expected %s, got %s", i, want, gotKeys[i])
}
}
}