chore: Use t.Setenv in tests (#5321)

And enable the `tenv` linter for the future.

Also, bump version of golangci-lint and fix some new
warnings that came from that.

Signed-off-by: Anders Eknert <anders@eknert.com>
This commit is contained in:
Anders Eknert
2022-10-27 17:44:56 +02:00
committed by GitHub
parent 6ec07cabfb
commit 50d4e31d6b
24 changed files with 95 additions and 143 deletions
+1
View File
@@ -21,6 +21,7 @@ linters:
- varcheck
- deadcode
- misspell
- tenv
- typecheck
- structcheck
- staticcheck
+1 -1
View File
@@ -27,7 +27,7 @@ ifeq ($(WASM_ENABLED),1)
GO_TAGS = -tags=opa_wasm
endif
GOLANGCI_LINT_VERSION := v1.46.2
GOLANGCI_LINT_VERSION := v1.50.1
DOCKER_RUNNING ?= $(shell docker ps >/dev/null 2>&1 && echo 1 || echo 0)
+23 -23
View File
@@ -8,29 +8,29 @@
//
// Rego policies are typically defined in text files and then parsed and compiled by the policy engine at runtime. The parsing stage takes the text or string representation of the policy and converts it into an abstract syntax tree (AST) that consists of the types mentioned above. The AST is organized as follows:
//
// Module
// |
// +--- Package (Reference)
// |
// +--- Imports
// | |
// | +--- Import (Term)
// |
// +--- Rules
// |
// +--- Rule
// |
// +--- Head
// | |
// | +--- Name (Variable)
// | |
// | +--- Key (Term)
// | |
// | +--- Value (Term)
// |
// +--- Body
// |
// +--- Expression (Term | Terms | Variable Declaration)
// Module
// |
// +--- Package (Reference)
// |
// +--- Imports
// | |
// | +--- Import (Term)
// |
// +--- Rules
// |
// +--- Rule
// |
// +--- Head
// | |
// | +--- Name (Variable)
// | |
// | +--- Key (Term)
// | |
// | +--- Value (Term)
// |
// +--- Body
// |
// +--- Expression (Term | Terms | Variable Declaration)
//
// At query time, the policy engine expects policies to have been compiled. The compilation stage takes one or more modules and compiles them into a format that the policy engine supports.
package ast
+5 -2
View File
@@ -152,9 +152,12 @@ var bs []byte
// BenchmarkObjectString generates several objects of different sizes, and
// marshals them to JSON via two ways:
// map[string]int -> ast.Value -> .String()
//
// map[string]int -> ast.Value -> .String()
//
// and
// map[string]int -> json.Marshal()
//
// map[string]int -> json.Marshal()
//
// The difference between these two is relevant for feeding input into the
// wasm vm: when calling rego.New(...) with rego.Target("wasm"), it's up to
+1
View File
@@ -14,5 +14,6 @@ import (
// FS contains the embedded capabilities/ directory of the built version,
// which has all the capabilities of previous versions:
// "v0.18.0.json" contains the capabilities JSON of version v0.18.0, etc
//
//go:embed *.json
var FS embed.FS
+2 -3
View File
@@ -9,7 +9,6 @@ import (
"encoding/json"
"net/http"
"net/http/httptest"
"os"
"sort"
"strings"
"testing"
@@ -44,7 +43,7 @@ func TestGenerateCmdOutputWithCheckFlagNoError(t *testing.T) {
baseURL, teardown := getTestServer(exp, http.StatusOK)
defer teardown()
os.Setenv("OPA_TELEMETRY_SERVICE_URL", baseURL)
t.Setenv("OPA_TELEMETRY_SERVICE_URL", baseURL)
var stdout bytes.Buffer
@@ -66,7 +65,7 @@ func TestGenerateCmdOutputWithCheckFlagNoError(t *testing.T) {
func TestCheckOPAUpdateBadURL(t *testing.T) {
url := "http://foo:8112"
os.Setenv("OPA_TELEMETRY_SERVICE_URL", url)
t.Setenv("OPA_TELEMETRY_SERVICE_URL", url)
err := checkOPAUpdate(nil)
if err == nil {
+3 -3
View File
@@ -200,9 +200,9 @@ func filter(rs []ast.Ref, pred func(ast.Ref, ast.Ref) bool) (filtered []ast.Ref)
// complicated. It should be possible to compute all dependencies in two
// passes:
//
// 1) perform syntactic unification on vars
// 2) gather all refs rooted at data after plugging the head with substitution
// from (1)
// 1. perform syntactic unification on vars
// 2. gather all refs rooted at data after plugging the head with substitution
// from (1)
func ruleDeps(rule *ast.Rule) (resolved []ast.Ref) {
vars, others := extractEq(rule.Body)
joined := joinVarRefs(vars)
+1 -1
View File
@@ -19,7 +19,7 @@ import (
func setTestEnvVar(t *testing.T, name, value string) string {
envKey := fmt.Sprintf("%s_%s", t.Name(), name)
os.Setenv(envKey, value)
t.Setenv(envKey, value)
return envKey
}
-1
View File
@@ -73,7 +73,6 @@ func (d *Schema) SetRootSchemaName(name string) {
// Pretty long function ( sorry :) )... but pretty straight forward, repetitive and boring
// Not much magic involved here, most of the job is to validate the key names and their values,
// then the values are copied into SubSchema struct
//
func (d *Schema) parseSchema(documentNode interface{}, currentSchema *SubSchema) error {
if currentSchema.Draft == nil {
+1 -1
View File
@@ -119,7 +119,7 @@ func (sl *SchemaLoader) AddSchemas(loaders ...JSONLoader) error {
return nil
}
//AddSchema adds a schema under the provided URL to the schema cache
// AddSchema adds a schema under the provided URL to the schema cache
func (sl *SchemaLoader) AddSchema(url string, loader JSONLoader) error {
ref, err := gojsonreference.NewJsonReference(url)
+2 -3
View File
@@ -4,8 +4,8 @@
// If you do not care about the details, the only things that you
// would need to use are the following functions:
//
// jws.SignWithOption(Payload, algorithm, key)
// jws.Verify(encodedjws, algorithm, key)
// jws.SignWithOption(Payload, algorithm, key)
// jws.Verify(encodedjws, algorithm, key)
//
// To sign, simply use `jws.SignWithOption`. `Payload` is a []byte buffer that
// contains whatever data you want to sign. `alg` is one of the
@@ -38,7 +38,6 @@ import (
// SignLiteral generates a Signature for the given Payload and Headers, and serializes
// it in compact serialization format. In this format you may NOT use
// multiple signers.
//
func SignLiteral(payload []byte, alg jwa.SignatureAlgorithm, key interface{}, hdrBuf []byte, rnd io.Reader) ([]byte, error) {
encodedHdr := base64.RawURLEncoding.EncodeToString(hdrBuf)
encodedPayload := base64.RawURLEncoding.EncodeToString(payload)
+1 -1
View File
@@ -30,7 +30,7 @@ import (
//
// Override at build time via:
//
// -ldflags "-X github.com/open-policy-agent/opa/internal/report.ExternalServiceURL=<url>"
// -ldflags "-X github.com/open-policy-agent/opa/internal/report.ExternalServiceURL=<url>"
//
// This will be overridden if the OPA_TELEMETRY_SERVICE_URL environment variable
// is provided.
+4 -6
View File
@@ -9,13 +9,11 @@ import (
"encoding/json"
"net/http"
"net/http/httptest"
"os"
"reflect"
"testing"
)
func TestNewReportDefaultURL(t *testing.T) {
os.Unsetenv("OPA_TELEMETRY_SERVICE_URL")
reporter, err := New("", Options{})
if err != nil {
@@ -34,7 +32,7 @@ func TestSendReportBadRespStatus(t *testing.T) {
baseURL, teardown := getTestServer(nil, http.StatusBadRequest)
defer teardown()
os.Setenv("OPA_TELEMETRY_SERVICE_URL", baseURL)
t.Setenv("OPA_TELEMETRY_SERVICE_URL", baseURL)
reporter, err := New("", Options{})
if err != nil {
@@ -59,7 +57,7 @@ func TestSendReportDecodeError(t *testing.T) {
baseURL, teardown := getTestServer("foo", http.StatusOK)
defer teardown()
os.Setenv("OPA_TELEMETRY_SERVICE_URL", baseURL)
t.Setenv("OPA_TELEMETRY_SERVICE_URL", baseURL)
reporter, err := New("", Options{})
if err != nil {
@@ -85,7 +83,7 @@ func TestSendReportWithOPAUpdate(t *testing.T) {
baseURL, teardown := getTestServer(exp, http.StatusOK)
defer teardown()
os.Setenv("OPA_TELEMETRY_SERVICE_URL", baseURL)
t.Setenv("OPA_TELEMETRY_SERVICE_URL", baseURL)
reporter, err := New("", Options{})
if err != nil {
@@ -108,7 +106,7 @@ func TestReportWithHeapStats(t *testing.T) {
baseURL, teardown := getTestServer(nil, http.StatusOK)
defer teardown()
os.Setenv("OPA_TELEMETRY_SERVICE_URL", baseURL)
t.Setenv("OPA_TELEMETRY_SERVICE_URL", baseURL)
reporter, err := New("", Options{})
if err != nil {
+2 -1
View File
@@ -13,7 +13,8 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
/*Package strvals provides tools for working with strval lines.
/*
Package strvals provides tools for working with strval lines.
OPA runtime config supports a compressed format for YAML settings which we call strvals.
The format is roughly like this:
+5 -5
View File
@@ -38,11 +38,11 @@ import (
// configuration blob. If your plugin has not been configured, your
// factory will not be invoked.
//
// plugins:
// my_plugin1:
// some_key: foo
// # my_plugin2:
// # some_key2: bar
// plugins:
// my_plugin1:
// some_key: foo
// # my_plugin2:
// # some_key2: bar
//
// If OPA was started with the configuration above and received two
// calls to runtime.RegisterPlugins (one with NAME "my_plugin1" and
+19 -48
View File
@@ -46,31 +46,21 @@ func assertErr(expected string, actual error, t *testing.T) {
}
func TestEnvironmentCredentialService(t *testing.T) {
reset := func() {
os.Unsetenv("AWS_ACCESS_KEY_ID")
os.Unsetenv("AWS_SECRET_ACCESS_KEY")
os.Unsetenv("AWS_REGION")
os.Unsetenv("AWS_SECURITY_TOKEN")
os.Unsetenv("AWS_SESSION_TOKEN")
}
reset()
t.Cleanup(reset) // reset again when we're done
cs := &awsEnvironmentCredentialService{}
// wrong path: some required environment is missing
_, err := cs.credentials()
assertErr("no AWS_ACCESS_KEY_ID set in environment", err, t)
os.Setenv("AWS_ACCESS_KEY_ID", "MYAWSACCESSKEYGOESHERE")
t.Setenv("AWS_ACCESS_KEY_ID", "MYAWSACCESSKEYGOESHERE")
_, err = cs.credentials()
assertErr("no AWS_SECRET_ACCESS_KEY set in environment", err, t)
os.Setenv("AWS_SECRET_ACCESS_KEY", "MYAWSSECRETACCESSKEYGOESHERE")
t.Setenv("AWS_SECRET_ACCESS_KEY", "MYAWSSECRETACCESSKEYGOESHERE")
_, err = cs.credentials()
assertErr("no AWS_REGION set in environment", err, t)
os.Setenv("AWS_REGION", "us-east-1")
t.Setenv("AWS_REGION", "us-east-1")
expectedCreds := awsCredentials{
AccessKey: "MYAWSACCESSKEYGOESHERE",
@@ -91,7 +81,9 @@ func TestEnvironmentCredentialService(t *testing.T) {
}
for _, testCase := range testCases {
os.Setenv(testCase.tokenEnv, testCase.tokenValue)
if testCase.tokenEnv != "" {
t.Setenv(testCase.tokenEnv, testCase.tokenValue)
}
expectedCreds.SessionToken = testCase.tokenValue
envCreds, err := cs.credentials()
@@ -199,15 +191,9 @@ aws_session_token=%s
test.WithTempFS(files, func(path string) {
cfgPath := filepath.Join(path, "example.ini")
os.Setenv(awsCredentialsFileEnvVar, cfgPath)
os.Setenv(awsProfileEnvVar, profile)
os.Setenv(awsRegionEnvVar, defaultRegion)
t.Cleanup(func() {
os.Unsetenv(awsCredentialsFileEnvVar)
os.Unsetenv(awsProfileEnvVar)
os.Unsetenv(awsRegionEnvVar)
})
t.Setenv(awsCredentialsFileEnvVar, cfgPath)
t.Setenv(awsProfileEnvVar, profile)
t.Setenv(awsRegionEnvVar, defaultRegion)
cs := &awsProfileCredentialService{}
creds, err := cs.credentials()
@@ -242,18 +228,11 @@ aws_session_token=%s
`, defaultKey, defaultSecret, defaultSessionToken)
files := map[string]string{}
oldUserProfile := os.Getenv("USERPROFILE")
oldHome := os.Getenv("HOME")
test.WithTempFS(files, func(path string) {
os.Setenv("USERPROFILE", path)
os.Setenv("HOME", path)
t.Cleanup(func() {
os.Setenv("USERPROFILE", oldUserProfile)
os.Setenv("HOME", oldHome)
})
t.Setenv("USERPROFILE", path)
t.Setenv("HOME", path)
cfgDir := filepath.Join(path, ".aws")
err := os.MkdirAll(cfgDir, os.ModePerm)
@@ -797,15 +776,7 @@ func (t *ec2CredTestServer) stop() {
}
func TestWebIdentityCredentialService(t *testing.T) {
reset := func() {
os.Unsetenv("AWS_WEB_IDENTITY_TOKEN_FILE")
os.Unsetenv("AWS_ROLE_ARN")
os.Unsetenv("AWS_REGION")
}
reset()
t.Cleanup(reset)
os.Setenv("AWS_REGION", "us-west-1")
t.Setenv("AWS_REGION", "us-west-1")
testAccessKey := "ASgeIAIOSFODNN7EXAMPLE"
ts := stsTestServer{
@@ -831,12 +802,12 @@ func TestWebIdentityCredentialService(t *testing.T) {
// wrong path: no AWS_ROLE_ARN set
err := cs.populateFromEnv()
assertErr("no AWS_ROLE_ARN set in environment", err, t)
os.Setenv("AWS_ROLE_ARN", "role:arn")
t.Setenv("AWS_ROLE_ARN", "role:arn")
// wrong path: no AWS_WEB_IDENTITY_TOKEN_FILE set
err = cs.populateFromEnv()
assertErr("no AWS_WEB_IDENTITY_TOKEN_FILE set in environment", err, t)
os.Setenv("AWS_WEB_IDENTITY_TOKEN_FILE", "/nonsense")
t.Setenv("AWS_WEB_IDENTITY_TOKEN_FILE", "/nonsense")
// happy path: both env vars set
err = cs.populateFromEnv()
@@ -849,13 +820,13 @@ func TestWebIdentityCredentialService(t *testing.T) {
assertErr("unable to read web token for sts HTTP request: open /nonsense: no such file or directory", err, t)
// wrong path: refresh with "bad token"
os.Setenv("AWS_WEB_IDENTITY_TOKEN_FILE", badTokenFile)
t.Setenv("AWS_WEB_IDENTITY_TOKEN_FILE", badTokenFile)
_ = cs.populateFromEnv()
err = cs.refreshFromService()
assertErr("STS HTTP request returned unexpected status: 401 Unauthorized", err, t)
// happy path: refresh with "good token"
os.Setenv("AWS_WEB_IDENTITY_TOKEN_FILE", goodTokenFile)
t.Setenv("AWS_WEB_IDENTITY_TOKEN_FILE", goodTokenFile)
_ = cs.populateFromEnv()
err = cs.refreshFromService()
if err != nil {
@@ -878,7 +849,7 @@ func TestWebIdentityCredentialService(t *testing.T) {
assertEq(creds.AccessKey, testAccessKey, t)
// happy/wrong path: refresh with "bad token" but return previous credentials
os.Setenv("AWS_WEB_IDENTITY_TOKEN_FILE", badTokenFile)
t.Setenv("AWS_WEB_IDENTITY_TOKEN_FILE", badTokenFile)
_ = cs.populateFromEnv()
cs.expiration = time.Now()
creds, err = cs.credentials()
@@ -886,8 +857,8 @@ func TestWebIdentityCredentialService(t *testing.T) {
assertErr("STS HTTP request returned unexpected status: 401 Unauthorized", err, t)
// wrong path: refresh with "bad token" but return previous credentials
os.Setenv("AWS_WEB_IDENTITY_TOKEN_FILE", goodTokenFile)
os.Setenv("AWS_ROLE_ARN", "BrokenRole")
t.Setenv("AWS_WEB_IDENTITY_TOKEN_FILE", goodTokenFile)
t.Setenv("AWS_ROLE_ARN", "BrokenRole")
_ = cs.populateFromEnv()
cs.expiration = time.Now()
creds, err = cs.credentials()
+1 -7
View File
@@ -699,15 +699,9 @@ func TestNew(t *testing.T) {
for _, tc := range tests {
t.Run(tc.name, func(t *testing.T) {
for key, val := range tc.env {
_ = os.Setenv(key, val)
t.Setenv(key, val)
}
t.Cleanup(func() {
for key := range tc.env {
_ = os.Unsetenv(key)
}
})
client, err := New([]byte(tc.input), ks, AuthPluginLookup(mockAuthPluginLookup))
if err != nil {
// We never want an error here and cannot proceed if there is one.
+1 -1
View File
@@ -298,7 +298,7 @@ func (p *Plugin) Snapshot() *UpdateRequestV1 {
}
// Trigger can be used to control when the plugin attempts to upload
//status in manual triggering mode.
// status in manual triggering mode.
func (p *Plugin) Trigger(ctx context.Context) error {
done := make(chan error)
p.trigger <- trigger{ctx: ctx, done: done}
+6 -6
View File
@@ -1151,16 +1151,16 @@ func (r *REPL) evalPackage(p *ast.Package) error {
// converted into a rule and compiled, then it will be interpreted as such. This
// allows users to define constants in the REPL. For example:
//
// > a = 1
// > a
// 1
// > a = 1
// > a
// 1
//
// If the expression is a = statement, then an additional check on the left
// hand side occurs. For example:
//
// > b = 2
// > b = 2
// true # not redefined!
// > b = 2
// > b = 2
// true # not redefined!
func (r *REPL) interpretAsRule(ctx context.Context, compiler *ast.Compiler, body ast.Body) (bool, error) {
if len(body) != 1 {
+2 -2
View File
@@ -384,7 +384,7 @@ func getTestServer(update interface{}, statusCode int) (baseURL string, teardown
func testCheckOPAUpdate(t *testing.T, url string, expected *report.DataResponse) {
t.Helper()
os.Setenv("OPA_TELEMETRY_SERVICE_URL", url)
t.Setenv("OPA_TELEMETRY_SERVICE_URL", url)
ctx := context.Background()
rt := getTestRuntime(ctx, t, logging.NewNoOpLogger())
@@ -397,7 +397,7 @@ func testCheckOPAUpdate(t *testing.T, url string, expected *report.DataResponse)
func testCheckOPAUpdateLoop(t *testing.T, url, expected string) {
t.Helper()
os.Setenv("OPA_TELEMETRY_SERVICE_URL", url)
t.Setenv("OPA_TELEMETRY_SERVICE_URL", url)
ctx := context.Background()
+4 -2
View File
@@ -47,8 +47,10 @@ type testWriteError struct {
// testCount lets you assert the number of keys under a prefix.
// Note that we don't do exact matches, so the assertions should be
// as exact as possible:
// testCount{"/foo", 1}
// testCount{"/foo/bar", 1}
//
// testCount{"/foo", 1}
// testCount{"/foo/bar", 1}
//
// both of these would be true for one element under key `/foo/bar`.
type testCount struct {
key string
+7 -22
View File
@@ -1956,22 +1956,14 @@ func TestHTTPSClient(t *testing.T) {
if err != nil {
t.Fatal(err)
}
err = os.Setenv("CLIENT_CERT_ENV", string(clientCert))
if err != nil {
t.Fatal(err)
}
t.Setenv("CLIENT_CERT_ENV", string(clientCert))
clientKey, err := readKeyFromFile(localClientKeyFile)
if err != nil {
t.Fatal(err)
}
err = os.Setenv("CLIENT_KEY_ENV", string(clientKey))
if err != nil {
t.Fatal(err)
}
err = os.Setenv("CLIENT_CA_ENV", string(caCertPEM))
if err != nil {
t.Fatal(err)
}
t.Setenv("CLIENT_KEY_ENV", string(clientKey))
t.Setenv("CLIENT_CA_ENV", string(caCertPEM))
// Replicating some of what happens in the server's HTTPS listener
s := getTLSTestServer()
@@ -2253,10 +2245,7 @@ func TestHTTPSNoClientCerts(t *testing.T) {
t.Fatal(err)
}
err = os.Setenv("CLIENT_CA_ENV", string(caCertPEM))
if err != nil {
t.Fatal(err)
}
t.Setenv("CLIENT_CA_ENV", string(caCertPEM))
// Replicating some of what happens in the server's HTTPS listener
s := getTLSTestServer()
@@ -2462,10 +2451,7 @@ func TestCertSelectionLogic(t *testing.T) {
t.Fatal(err)
}
err = os.Setenv("CLIENT_CA_ENV", string(caCertPEM))
if err != nil {
t.Fatal(err)
}
t.Setenv("CLIENT_CA_ENV", string(caCertPEM))
getClientTLSConfig := func(obj ast.Object) *tls.Config {
_, client, err := createHTTPRequest(BuiltinContext{Context: context.Background()}, obj)
@@ -2624,8 +2610,7 @@ func TestHTTPSendMetrics(t *testing.T) {
}
func TestInitDefaults(t *testing.T) {
os.Setenv("HTTP_SEND_TIMEOUT", "300mss")
defer os.Unsetenv("HTTP_SEND_TIMEOUT")
t.Setenv("HTTP_SEND_TIMEOUT", "300mss")
defer func() {
if r := recover(); r == nil {
+3 -3
View File
@@ -72,9 +72,9 @@ func delimiterIndices(s string, delimiterStart, delimiterEnd byte) ([]int, error
// You can define your own delimiters. It is e.g. common to use curly braces {} but I recommend using characters
// which have no special meaning in Regex, e.g.: <, >
//
// reg, err := compiler.CompileRegex("foo:bar.baz:<[0-9]{2,10}>", '<', '>')
// // if err != nil ...
// reg.MatchString("foo:bar.baz:123")
// reg, err := compiler.CompileRegex("foo:bar.baz:<[0-9]{2,10}>", '<', '>')
// // if err != nil ...
// reg.MatchString("foo:bar.baz:123")
func compileRegexTemplate(tpl string, delimiterStart, delimiterEnd byte) (*regexp.Regexp, error) {
// Check if it is well-formed.
idxs, errBraces := delimiterIndices(tpl, delimiterStart, delimiterEnd)
-1
View File
@@ -17,7 +17,6 @@ import (
// nil < bool < int, float64 < string < []interface{} < map[string]interface{}. Slices and maps
// are compared recursively. If one slice or map is a subset of the other slice or map
// it is considered "less than". Nil is always equal to nil.
//
func Compare(a, b interface{}) int {
aSortOrder := sortOrder(a)
bSortOrder := sortOrder(b)