Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Introduce analysistest testdata convention. #278

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,3 +26,19 @@ information on using pull requests.

This project follows [Google's Open Source Community
Guidelines](https://opensource.google/conduct/).

## Project Conventions

### Use Go Modules in `testdata`

The analyzer testing package `analysistest` executes a build of the Go code it tests.
This treats the `testdata` folder as a synthetic GOPATH, and Go code tested within will look for imported packages in `testdata/src/...`.
Unfortunately, this tends to break IDE linking, making test development difficult.

To ameliorate this issue, we group a given test's `testdata` into a synthetic root package and use Go modules to identify it for the IDE.
This allows your IDE to correctly link imports while adhering to the expectation of `analysistest`.

Specifically, `testdata` should be grouped under `testdata/src/NAME_analysistest`, where `NAME` is the name of the analyzer being tested.
Initialize a trivial Go module file with `go mod init NAME_analysistest`.
Any imports used within this `testdata` will begin with `NAME_analysistest`.
See [`levee_analysistest`](internal/pkg/levee/testdata/src/levee_analysistest) for an example.
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,9 @@
package crosspkg

import (
"example.com/core"
"example.com/notcore"
necore "notexample.com/core"
"config_analysistest/example/core"
"config_analysistest/example/notcore"
necore "config_analysistest/notexample/core"
)

func CoreCalls() {
Expand Down
3 changes: 3 additions & 0 deletions internal/pkg/config/testdata/src/config_analysistest/go.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
module config_analysistest

go 1.15
16 changes: 8 additions & 8 deletions internal/pkg/config/testdata/test-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -13,15 +13,15 @@
# limitations under the License.
---
sinks:
- packageRE: "^example.com/core"
methodRE: "^Sink$"
- packageRE: "^example.com/core"
methodRE: "^Do$"
receiverRE: "^Sinker$"
- package: "config_analysistest/example/core"
method: "Sink"
- package: "config_analysistest/example/core"
method: "Do"
receiver: "Sinker"
fieldTags:
- key: example
value: sensitive
exclude:
- packageRE: "^example.com/exclusion$"
methodRE: "^Foo$"
- packageRE: "^notexample.com/exclusion$"
- package: "config_analysistest/example/exclusion"
method: "Foo"
- package: "config_analysistest/notexample/exclusion"
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
module fieldpropagator_analysistest

go 1.15
6 changes: 3 additions & 3 deletions internal/pkg/fieldpropagator/testdata/test-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,12 @@ Sources:
- PackageRE: source
TypeRE: "^Source$"
FieldRE: "^data"
- Package: proto
- PackageRE: proto
Type: KeyPair
Field: Private
- Package: proto
- PackageRE: proto
Type: TLS
Field: Cert
- Package: proto
- PackageRE: proto
Type: BasicAuth
Field: Password
2 changes: 1 addition & 1 deletion internal/pkg/fieldtags/analyzer_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ func TestFieldTagsAnalysis(t *testing.T) {
t.Error(err)
}

results := analysistest.Run(t, testdata, Analyzer, "example.com/core", "example.com/crosspkg")
results := analysistest.Run(t, testdata, Analyzer, "fieldtags_analysistest/core", "fieldtags_analysistest/crosspkg")

if len(results) != 2 {
t.Fatalf("expected 2 results, got %d", len(results))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@

package crosspkg

import "example.com/core"
import "fieldtags_analysistest/core"

type PersonWrapper struct {
p core.Person
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
module fieldtags_analysistest

go 1.15
8 changes: 4 additions & 4 deletions internal/pkg/levee/levee_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ func TestLevee(t *testing.T) {
if *debugging {
Analyzer.Requires = append(Analyzer.Requires, debug.Analyzer)
}
analysistest.Run(t, dataDir, Analyzer, "./src/example.com/...")
analysistest.Run(t, dataDir, Analyzer, "./src/levee_analysistest/example/...")
}

func TestLeveeDoesNotCreateReportsForPanicIfPanicingOnTaintedValuesIsAllowed(t *testing.T) {
Expand All @@ -43,21 +43,21 @@ func TestLeveeDoesNotCreateReportsForPanicIfPanicingOnTaintedValuesIsAllowed(t *
if *debugging {
Analyzer.Requires = append(Analyzer.Requires, debug.Analyzer)
}
analysistest.Run(t, dataDir, Analyzer, "./src/nopanic.com/...")
analysistest.Run(t, dataDir, Analyzer, "./src/levee_analysistest/nopanic.com/...")
}

func TestFormattingWithCustomReportMessage(t *testing.T) {
dataDir := analysistest.TestData()
if err := Analyzer.Flags.Set("config", dataDir+"/with-custom-message.yaml"); err != nil {
t.Error(err)
}
analysistest.Run(t, dataDir, Analyzer, "./src/custom.message.com/withcustom")
analysistest.Run(t, dataDir, Analyzer, "./src/levee_analysistest/custom.message.com/withcustom")
}

func TestFormattingWithoutCustomReportMessage(t *testing.T) {
dataDir := analysistest.TestData()
if err := Analyzer.Flags.Set("config", dataDir+"/no-custom-message.yaml"); err != nil {
t.Error(err)
}
analysistest.Run(t, dataDir, Analyzer, "./src/custom.message.com/nocustom")
analysistest.Run(t, dataDir, Analyzer, "./src/levee_analysistest/custom.message.com/nocustom")
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,9 @@
---
AllowPanicOnTaintedValues: true
Sources:
- Package: "nopanic.com/core"
- Package: "levee_analysistest/nopanic.com/core"
Type: "Source"
Field: "Data"
Sinks:
- Package: "nopanic.com/core"
- Package: "levee_analysistest/nopanic.com/core"
Method: "Sink"
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
package arguments

import (
"example.com/core"
"levee_analysistest/example/core"
)

func TestSourceFromParamByReference(s *core.Source) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ package binop
import (
"fmt"

"example.com/core"
"levee_analysistest/example/core"
)

func TestConcatenatingTaintedAndNonTaintedStrings(prefix string) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
package inlining

import (
"example.com/core"
"levee_analysistest/example/core"
)

func HasSecret(s core.Source) bool {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
package callorder

import (
"example.com/core"
"levee_analysistest/example/core"
)

// This type should *not* be identified as a Source.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
package callorder

import (
"example.com/core"
"levee_analysistest/example/core"
)

func TestTaintedColocatedArgumentDoesNotReachSinkThatPrecedesColocation() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ import (
"fmt"
"io"

"example.com/core"
"levee_analysistest/example/core"
)

func TestSinkInIfBeforeTaint(s core.Source, w io.Writer) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ import (
"fmt"
"io"

"example.com/core"
"levee_analysistest/example/core"
)

func TestTaintBeforeSinking(s core.Source, w io.Writer) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
package closures

import (
"example.com/core"
"levee_analysistest/example/core"
)

func TesCapturedSourceReachesSinkInClosure() func() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
package collections

import (
"example.com/core"
"levee_analysistest/example/core"
)

func TestArrayLiteralContainingSourceIsTainted(s core.Source) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
package collections

import (
"example.com/core"
"levee_analysistest/example/core"
)

func TestSourceReceivedFromChannelIsTainted(sources <-chan core.Source) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
package collections

import (
"example.com/core"
"levee_analysistest/example/core"
)

func TestMapLiteralContainingSourceKeyIsTainted(s core.Source) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
package collections

import (
"example.com/core"
"levee_analysistest/example/core"
)

func TestSlices(s core.Source) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
package collections

import (
"example.com/core"
"levee_analysistest/example/core"
)

func TestSourceMapIsSource() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ import (
"encoding/json"
"reflect"

"example.com/core"
"levee_analysistest/example/core"
)

func colocateString(core.Source, string) {}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
package declarations

import (
"example.com/core"
"levee_analysistest/example/core"
)

func TestSourceDeclaredInBody() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
package eface

import (
"example.com/core"
"levee_analysistest/example/core"
)

func TestEfaceSource(s core.Source) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
package embedding

import (
"example.com/core"
"levee_analysistest/example/core"
)

type EmbedsSource struct {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
package excludedpackage

import (
"example.com/core"
"levee_analysistest/example/core"
)

func Oops(s core.Source) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
package extracts

import (
"example.com/core"
"levee_analysistest/example/core"
)

func CreateSource() (core.Source, error) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ package fields
import (
"strconv"

"example.com/core"
"levee_analysistest/example/core"
)

func TestFieldAccessors(s core.Source, ptr *core.Source) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
package includedpackage

import (
"example.com/core"
"levee_analysistest/example/core"
)

func Oops(s core.Source) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
package inlining

import (
"example.com/core"
"levee_analysistest/example/core"
)

func NewSource() *core.Source {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
package loops

import (
"example.com/core"
"levee_analysistest/example/core"
)

func TestTaintInThenBlockInLoopSinkAfterLoop() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
package deletethis

import (
"example.com/core"
"levee_analysistest/example/core"
)

func TestTaintingInterfaceValueDoesNotTaintContainedValue(s *core.Source, str string) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
package method

import (
"example.com/core"
"levee_analysistest/example/core"
)

func TestMethodCallOnStaticallyKnownReceiverPropagatesTaint(s core.Source) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
package namedreturn

import (
"example.com/core"
"levee_analysistest/example/core"
)

func TestNamedReturnValue() (s core.Source) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
package panic

import (
"example.com/core"
"levee_analysistest/example/core"
)

func TestPanicIsASink(source core.Source) {
Expand Down
Loading