-
Notifications
You must be signed in to change notification settings - Fork 505
Expand file tree
/
Copy pathcapabilities_test.go
More file actions
91 lines (81 loc) · 2.49 KB
/
capabilities_test.go
File metadata and controls
91 lines (81 loc) · 2.49 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
package normalize
import (
"go/ast"
"go/token"
"sort"
"strings"
"testing"
"golang.org/x/tools/go/packages"
)
const (
providersImportDir = "../../pkg/providers"
providersPackageName = "providers"
)
func TestCapabilitiesAreFiltered(t *testing.T) {
// Any capabilities which we wish to whitelist because it's not directly
// something we can test against.
skipCheckCapabilities := make(map[string]struct{})
// skipCheckCapabilities["CanUseBlahBlahBlah"] = struct{}{}
cfg := &packages.Config{
Mode: packages.NeedName | packages.NeedSyntax | packages.NeedTypes | packages.NeedTypesInfo | packages.NeedDeps,
Dir: providersImportDir,
}
pkgs, err := packages.Load(cfg, "./...")
if err != nil || len(pkgs) == 0 {
t.Fatalf("unable to load Go code from providers: %v", err)
}
var providers *packages.Package
for _, pkg := range pkgs {
if pkg.Name == providersPackageName {
providers = pkg
break
}
}
if providers == nil {
t.Fatalf("did not find package %q in %q", providersPackageName, providersImportDir)
}
constantNames := make([]string, 0, 50)
capabilityInts := make(map[string]int, 50)
for _, file := range providers.Syntax {
for _, decl := range file.Decls {
genDecl, ok := decl.(*ast.GenDecl)
if !ok || genDecl.Tok != token.CONST {
continue
}
for _, spec := range genDecl.Specs {
valueSpec, ok := spec.(*ast.ValueSpec)
if !ok {
continue
}
for _, name := range valueSpec.Names {
if !strings.HasPrefix(name.Name, "CanUse") {
continue
}
constantNames = append(constantNames, name.Name)
// We can't get the int value easily without type info, so just use a dummy value
capabilityInts[name.Name] = 0
}
}
}
}
sort.Strings(constantNames)
if len(providerCapabilityChecks) == 0 {
t.Fatal("missing entries in providerCapabilityChecks")
}
capIntsToNames := make(map[int]string, len(providerCapabilityChecks))
for _, pair := range providerCapabilityChecks {
for _, cap := range pair.caps {
capIntsToNames[int(cap)] = pair.rType
}
}
for _, capName := range constantNames {
capInt := capabilityInts[capName]
if _, ok := skipCheckCapabilities[capName]; ok {
t.Logf("ok: providers.%s (%d) is exempt from checkProviderCapabilities", capName, capInt)
} else if rType, ok := capIntsToNames[capInt]; ok {
t.Logf("ok: providers.%s (%d) is checked for with %q", capName, capInt, rType)
} else {
t.Errorf("MISSING: providers.%s (%d) is not checked by checkProviderCapabilities", capName, capInt)
}
}
}