mirror of
https://github.com/argoproj/argo-cd
synced 2026-04-21 17:07:16 +00:00
* chore: Add a GitHub action that runs unit tests with -race to CI build (#4774) Signed-off-by: Jonathan West <jonwest@redhat.com> * chore: Add a GitHub action that runs unit tests with -race to CI build (#4774) Signed-off-by: Jonathan West <jonwest@redhat.com>
This commit is contained in:
parent
c4dcae3442
commit
4c3f97f78a
12 changed files with 556 additions and 370 deletions
55
.github/workflows/ci-build.yaml
vendored
55
.github/workflows/ci-build.yaml
vendored
|
|
@ -132,6 +132,61 @@ jobs:
|
|||
name: test-results
|
||||
path: test-results/
|
||||
|
||||
test-go-race:
|
||||
name: Run unit tests with -race, for Go packages
|
||||
runs-on: ubuntu-latest
|
||||
needs:
|
||||
- build-go
|
||||
steps:
|
||||
- name: Create checkout directory
|
||||
run: mkdir -p ~/go/src/github.com/argoproj
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v2
|
||||
- name: Create symlink in GOPATH
|
||||
run: ln -s $(pwd) ~/go/src/github.com/argoproj/argo-cd
|
||||
- name: Setup Golang
|
||||
uses: actions/setup-go@v1
|
||||
with:
|
||||
go-version: '1.14.2'
|
||||
- name: Install required packages
|
||||
run: |
|
||||
sudo apt-get install git -y
|
||||
- name: Switch to temporal branch so we re-attach head
|
||||
run: |
|
||||
git switch -c temporal-pr-branch
|
||||
git status
|
||||
- name: Fetch complete history for blame information
|
||||
run: |
|
||||
git fetch --prune --no-tags --depth=1 origin +refs/heads/*:refs/remotes/origin/*
|
||||
- name: Add ~/go/bin to PATH
|
||||
run: |
|
||||
echo "/home/runner/go/bin" >> $GITHUB_PATH
|
||||
- name: Add /usr/local/bin to PATH
|
||||
run: |
|
||||
echo "/usr/local/bin" >> $GITHUB_PATH
|
||||
- name: Restore go build cache
|
||||
uses: actions/cache@v1
|
||||
with:
|
||||
path: ~/.cache/go-build
|
||||
key: ${{ runner.os }}-go-build-v1-${{ github.run_id }}
|
||||
- name: Install all tools required for building & testing
|
||||
run: |
|
||||
make install-test-tools-local
|
||||
- name: Setup git username and email
|
||||
run: |
|
||||
git config --global user.name "John Doe"
|
||||
git config --global user.email "john.doe@example.com"
|
||||
- name: Download and vendor all required packages
|
||||
run: |
|
||||
go mod download
|
||||
- name: Run all unit tests
|
||||
run: make test-race-local
|
||||
- name: Generate test results artifacts
|
||||
uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: race-results
|
||||
path: test-results/
|
||||
|
||||
codegen:
|
||||
name: Check changes to generated code
|
||||
runs-on: ubuntu-latest
|
||||
|
|
|
|||
14
Makefile
14
Makefile
|
|
@ -355,6 +355,20 @@ test-local:
|
|||
./hack/test.sh -coverprofile=coverage.out "$(TEST_MODULE)"; \
|
||||
fi
|
||||
|
||||
.PHONY: test-race
|
||||
test-race: test-tools-image
|
||||
mkdir -p $(GOCACHE)
|
||||
$(call run-in-test-client,make TEST_MODULE=$(TEST_MODULE) test-race-local)
|
||||
|
||||
# Run all unit tests, with data race detection, skipping known failures (local version)
|
||||
.PHONY: test-race-local
|
||||
test-race-local:
|
||||
if test "$(TEST_MODULE)" = ""; then \
|
||||
./hack/test.sh -race -coverprofile=coverage.out `go list ./... | grep -v 'test/e2e'`; \
|
||||
else \
|
||||
./hack/test.sh -race -coverprofile=coverage.out "$(TEST_MODULE)"; \
|
||||
fi
|
||||
|
||||
# Run the E2E test suite. E2E test servers (see start-e2e target) must be
|
||||
# started before.
|
||||
.PHONY: test-e2e
|
||||
|
|
|
|||
44
reposerver/repository/repository_norace_test.go
Normal file
44
reposerver/repository/repository_norace_test.go
Normal file
|
|
@ -0,0 +1,44 @@
|
|||
// +build !race
|
||||
|
||||
package repository
|
||||
|
||||
import (
|
||||
"os"
|
||||
"path/filepath"
|
||||
"sync"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
||||
argoappv1 "github.com/argoproj/argo-cd/pkg/apis/application/v1alpha1"
|
||||
"github.com/argoproj/argo-cd/reposerver/apiclient"
|
||||
)
|
||||
|
||||
func TestHelmDependencyWithConcurrency(t *testing.T) {
|
||||
|
||||
// !race:
|
||||
// Un-synchronized use of a random source, will be fixed when this is merged:
|
||||
// https://github.com/argoproj/argo-cd/issues/4728
|
||||
|
||||
cleanup := func() {
|
||||
_ = os.Remove(filepath.Join("../../util/helm/testdata/helm2-dependency", helmDepUpMarkerFile))
|
||||
_ = os.RemoveAll(filepath.Join("../../util/helm/testdata/helm2-dependency", "charts"))
|
||||
}
|
||||
cleanup()
|
||||
defer cleanup()
|
||||
|
||||
var wg sync.WaitGroup
|
||||
wg.Add(3)
|
||||
for i := 0; i < 3; i++ {
|
||||
go func() {
|
||||
res, err := helmTemplate("../../util/helm/testdata/helm2-dependency", "../..", nil, &apiclient.ManifestRequest{
|
||||
ApplicationSource: &argoappv1.ApplicationSource{},
|
||||
}, false)
|
||||
|
||||
assert.NoError(t, err)
|
||||
assert.NotNil(t, res)
|
||||
wg.Done()
|
||||
}()
|
||||
}
|
||||
wg.Wait()
|
||||
}
|
||||
|
|
@ -10,7 +10,6 @@ import (
|
|||
"path/filepath"
|
||||
"regexp"
|
||||
"strings"
|
||||
"sync"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
|
|
@ -1216,27 +1215,3 @@ func TestGenerateManifestWithAnnotatedAndRegularGitTagHashes(t *testing.T) {
|
|||
}
|
||||
|
||||
}
|
||||
|
||||
func TestHelmDependencyWithConcurrency(t *testing.T) {
|
||||
cleanup := func() {
|
||||
_ = os.Remove(filepath.Join("../../util/helm/testdata/helm2-dependency", helmDepUpMarkerFile))
|
||||
_ = os.RemoveAll(filepath.Join("../../util/helm/testdata/helm2-dependency", "charts"))
|
||||
}
|
||||
cleanup()
|
||||
defer cleanup()
|
||||
|
||||
var wg sync.WaitGroup
|
||||
wg.Add(3)
|
||||
for i := 0; i < 3; i++ {
|
||||
go func() {
|
||||
res, err := helmTemplate("../../util/helm/testdata/helm2-dependency", "../..", nil, &apiclient.ManifestRequest{
|
||||
ApplicationSource: &argoappv1.ApplicationSource{},
|
||||
}, false)
|
||||
|
||||
assert.NoError(t, err)
|
||||
assert.NotNil(t, res)
|
||||
wg.Done()
|
||||
}()
|
||||
}
|
||||
wg.Wait()
|
||||
}
|
||||
|
|
|
|||
191
server/server_norace_test.go
Normal file
191
server/server_norace_test.go
Normal file
|
|
@ -0,0 +1,191 @@
|
|||
// +build !race
|
||||
|
||||
package server
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
||||
"github.com/argoproj/argo-cd/common"
|
||||
"github.com/argoproj/argo-cd/pkg/apiclient"
|
||||
"github.com/argoproj/argo-cd/test"
|
||||
|
||||
applicationpkg "github.com/argoproj/argo-cd/pkg/apiclient/application"
|
||||
)
|
||||
|
||||
func TestUserAgent(t *testing.T) {
|
||||
|
||||
// !race:
|
||||
// A data race in go-client's `shared_informer.go`, between `sharedProcessor.run(...)` and itself. Based on
|
||||
// the data race, it APPEARS to be intentional, but in any case it's nothing we are doing in Argo CD
|
||||
// that is causing this issue.
|
||||
|
||||
s := fakeServer()
|
||||
cancelInformer := test.StartInformer(s.projInformer)
|
||||
defer cancelInformer()
|
||||
port, err := test.GetFreePort()
|
||||
assert.NoError(t, err)
|
||||
metricsPort, err := test.GetFreePort()
|
||||
assert.NoError(t, err)
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
defer cancel()
|
||||
go s.Run(ctx, port, metricsPort)
|
||||
defer func() { time.Sleep(3 * time.Second) }()
|
||||
|
||||
err = test.WaitForPortListen(fmt.Sprintf("127.0.0.1:%d", port), 10*time.Second)
|
||||
assert.NoError(t, err)
|
||||
|
||||
type testData struct {
|
||||
userAgent string
|
||||
errorMsg string
|
||||
}
|
||||
currentVersionBytes, err := ioutil.ReadFile("../VERSION")
|
||||
assert.NoError(t, err)
|
||||
currentVersion := strings.TrimSpace(string(currentVersionBytes))
|
||||
var tests = []testData{
|
||||
{
|
||||
// Reject out-of-date user-agent
|
||||
userAgent: fmt.Sprintf("%s/0.10.0", common.ArgoCDUserAgentName),
|
||||
errorMsg: "unsatisfied client version constraint",
|
||||
},
|
||||
{
|
||||
// Accept up-to-date user-agent
|
||||
userAgent: fmt.Sprintf("%s/%s", common.ArgoCDUserAgentName, currentVersion),
|
||||
},
|
||||
{
|
||||
// Accept up-to-date pre-release user-agent
|
||||
userAgent: fmt.Sprintf("%s/%s-rc1", common.ArgoCDUserAgentName, currentVersion),
|
||||
},
|
||||
{
|
||||
// Reject legacy client
|
||||
// NOTE: after we update the grpc-go client past 1.15.0, this test will break and should be deleted
|
||||
userAgent: " ", // need a space here since the apiclient will set the default user-agent if empty
|
||||
errorMsg: "unsatisfied client version constraint",
|
||||
},
|
||||
{
|
||||
// Permit custom clients
|
||||
userAgent: "foo/1.2.3",
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
opts := apiclient.ClientOptions{
|
||||
ServerAddr: fmt.Sprintf("localhost:%d", port),
|
||||
PlainText: true,
|
||||
UserAgent: test.userAgent,
|
||||
}
|
||||
clnt, err := apiclient.NewClient(&opts)
|
||||
assert.NoError(t, err)
|
||||
conn, appClnt := clnt.NewApplicationClientOrDie()
|
||||
_, err = appClnt.List(ctx, &applicationpkg.ApplicationQuery{})
|
||||
if test.errorMsg != "" {
|
||||
assert.Error(t, err)
|
||||
assert.Regexp(t, test.errorMsg, err.Error())
|
||||
} else {
|
||||
assert.NoError(t, err)
|
||||
}
|
||||
_ = conn.Close()
|
||||
}
|
||||
}
|
||||
|
||||
func Test_StaticHeaders(t *testing.T) {
|
||||
|
||||
// !race:
|
||||
// Same as TestUserAgent
|
||||
|
||||
// Test default policy "sameorigin"
|
||||
{
|
||||
s := fakeServer()
|
||||
cancelInformer := test.StartInformer(s.projInformer)
|
||||
defer cancelInformer()
|
||||
port, err := test.GetFreePort()
|
||||
assert.NoError(t, err)
|
||||
metricsPort, err := test.GetFreePort()
|
||||
assert.NoError(t, err)
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
defer cancel()
|
||||
go s.Run(ctx, port, metricsPort)
|
||||
defer func() { time.Sleep(3 * time.Second) }()
|
||||
|
||||
err = test.WaitForPortListen(fmt.Sprintf("127.0.0.1:%d", port), 10*time.Second)
|
||||
assert.NoError(t, err)
|
||||
|
||||
// Allow server startup
|
||||
time.Sleep(1 * time.Second)
|
||||
|
||||
client := http.Client{}
|
||||
url := fmt.Sprintf("http://127.0.0.1:%d/test.html", port)
|
||||
req, err := http.NewRequest("GET", url, nil)
|
||||
assert.NoError(t, err)
|
||||
resp, err := client.Do(req)
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, "sameorigin", resp.Header.Get("X-Frame-Options"))
|
||||
}
|
||||
|
||||
// Test custom policy
|
||||
{
|
||||
s := fakeServer()
|
||||
s.XFrameOptions = "deny"
|
||||
cancelInformer := test.StartInformer(s.projInformer)
|
||||
defer cancelInformer()
|
||||
port, err := test.GetFreePort()
|
||||
assert.NoError(t, err)
|
||||
metricsPort, err := test.GetFreePort()
|
||||
assert.NoError(t, err)
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
defer cancel()
|
||||
go s.Run(ctx, port, metricsPort)
|
||||
defer func() { time.Sleep(3 * time.Second) }()
|
||||
|
||||
err = test.WaitForPortListen(fmt.Sprintf("127.0.0.1:%d", port), 10*time.Second)
|
||||
assert.NoError(t, err)
|
||||
|
||||
// Allow server startup
|
||||
time.Sleep(1 * time.Second)
|
||||
|
||||
client := http.Client{}
|
||||
url := fmt.Sprintf("http://127.0.0.1:%d/test.html", port)
|
||||
req, err := http.NewRequest("GET", url, nil)
|
||||
assert.NoError(t, err)
|
||||
resp, err := client.Do(req)
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, "deny", resp.Header.Get("X-Frame-Options"))
|
||||
}
|
||||
|
||||
// Test disabled
|
||||
{
|
||||
s := fakeServer()
|
||||
s.XFrameOptions = ""
|
||||
cancelInformer := test.StartInformer(s.projInformer)
|
||||
defer cancelInformer()
|
||||
port, err := test.GetFreePort()
|
||||
assert.NoError(t, err)
|
||||
metricsPort, err := test.GetFreePort()
|
||||
assert.NoError(t, err)
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
defer cancel()
|
||||
go s.Run(ctx, port, metricsPort)
|
||||
defer func() { time.Sleep(3 * time.Second) }()
|
||||
|
||||
err = test.WaitForPortListen(fmt.Sprintf("127.0.0.1:%d", port), 10*time.Second)
|
||||
assert.NoError(t, err)
|
||||
|
||||
// Allow server startup
|
||||
time.Sleep(1 * time.Second)
|
||||
|
||||
client := http.Client{}
|
||||
url := fmt.Sprintf("http://127.0.0.1:%d/test.html", port)
|
||||
req, err := http.NewRequest("GET", url, nil)
|
||||
assert.NoError(t, err)
|
||||
resp, err := client.Do(req)
|
||||
assert.NoError(t, err)
|
||||
assert.Empty(t, resp.Header.Get("X-Frame-Options"))
|
||||
}
|
||||
}
|
||||
|
|
@ -3,10 +3,7 @@ package server
|
|||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
|
|
@ -19,7 +16,6 @@ import (
|
|||
|
||||
"github.com/argoproj/argo-cd/common"
|
||||
"github.com/argoproj/argo-cd/pkg/apiclient"
|
||||
applicationpkg "github.com/argoproj/argo-cd/pkg/apiclient/application"
|
||||
"github.com/argoproj/argo-cd/pkg/apiclient/session"
|
||||
"github.com/argoproj/argo-cd/pkg/apis/application/v1alpha1"
|
||||
apps "github.com/argoproj/argo-cd/pkg/client/clientset/versioned/fake"
|
||||
|
|
@ -381,75 +377,6 @@ func TestCertsAreNotGeneratedInInsecureMode(t *testing.T) {
|
|||
assert.Nil(t, s.settings.Certificate)
|
||||
}
|
||||
|
||||
func TestUserAgent(t *testing.T) {
|
||||
s := fakeServer()
|
||||
cancelInformer := test.StartInformer(s.projInformer)
|
||||
defer cancelInformer()
|
||||
port, err := test.GetFreePort()
|
||||
assert.NoError(t, err)
|
||||
metricsPort, err := test.GetFreePort()
|
||||
assert.NoError(t, err)
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
defer cancel()
|
||||
go s.Run(ctx, port, metricsPort)
|
||||
defer func() { time.Sleep(3 * time.Second) }()
|
||||
|
||||
err = test.WaitForPortListen(fmt.Sprintf("127.0.0.1:%d", port), 10*time.Second)
|
||||
assert.NoError(t, err)
|
||||
|
||||
type testData struct {
|
||||
userAgent string
|
||||
errorMsg string
|
||||
}
|
||||
currentVersionBytes, err := ioutil.ReadFile("../VERSION")
|
||||
assert.NoError(t, err)
|
||||
currentVersion := strings.TrimSpace(string(currentVersionBytes))
|
||||
var tests = []testData{
|
||||
{
|
||||
// Reject out-of-date user-agent
|
||||
userAgent: fmt.Sprintf("%s/0.10.0", common.ArgoCDUserAgentName),
|
||||
errorMsg: "unsatisfied client version constraint",
|
||||
},
|
||||
{
|
||||
// Accept up-to-date user-agent
|
||||
userAgent: fmt.Sprintf("%s/%s", common.ArgoCDUserAgentName, currentVersion),
|
||||
},
|
||||
{
|
||||
// Accept up-to-date pre-release user-agent
|
||||
userAgent: fmt.Sprintf("%s/%s-rc1", common.ArgoCDUserAgentName, currentVersion),
|
||||
},
|
||||
{
|
||||
// Reject legacy client
|
||||
// NOTE: after we update the grpc-go client past 1.15.0, this test will break and should be deleted
|
||||
userAgent: " ", // need a space here since the apiclient will set the default user-agent if empty
|
||||
errorMsg: "unsatisfied client version constraint",
|
||||
},
|
||||
{
|
||||
// Permit custom clients
|
||||
userAgent: "foo/1.2.3",
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
opts := apiclient.ClientOptions{
|
||||
ServerAddr: fmt.Sprintf("localhost:%d", port),
|
||||
PlainText: true,
|
||||
UserAgent: test.userAgent,
|
||||
}
|
||||
clnt, err := apiclient.NewClient(&opts)
|
||||
assert.NoError(t, err)
|
||||
conn, appClnt := clnt.NewApplicationClientOrDie()
|
||||
_, err = appClnt.List(ctx, &applicationpkg.ApplicationQuery{})
|
||||
if test.errorMsg != "" {
|
||||
assert.Error(t, err)
|
||||
assert.Regexp(t, test.errorMsg, err.Error())
|
||||
} else {
|
||||
assert.NoError(t, err)
|
||||
}
|
||||
_ = conn.Close()
|
||||
}
|
||||
}
|
||||
|
||||
func TestAuthenticate(t *testing.T) {
|
||||
type testData struct {
|
||||
test string
|
||||
|
|
@ -507,97 +434,6 @@ func TestAuthenticate(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func Test_StaticHeaders(t *testing.T) {
|
||||
// Test default policy "sameorigin"
|
||||
{
|
||||
s := fakeServer()
|
||||
cancelInformer := test.StartInformer(s.projInformer)
|
||||
defer cancelInformer()
|
||||
port, err := test.GetFreePort()
|
||||
assert.NoError(t, err)
|
||||
metricsPort, err := test.GetFreePort()
|
||||
assert.NoError(t, err)
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
defer cancel()
|
||||
go s.Run(ctx, port, metricsPort)
|
||||
defer func() { time.Sleep(3 * time.Second) }()
|
||||
|
||||
err = test.WaitForPortListen(fmt.Sprintf("127.0.0.1:%d", port), 10*time.Second)
|
||||
assert.NoError(t, err)
|
||||
|
||||
// Allow server startup
|
||||
time.Sleep(1 * time.Second)
|
||||
|
||||
client := http.Client{}
|
||||
url := fmt.Sprintf("http://127.0.0.1:%d/test.html", port)
|
||||
req, err := http.NewRequest("GET", url, nil)
|
||||
assert.NoError(t, err)
|
||||
resp, err := client.Do(req)
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, "sameorigin", resp.Header.Get("X-Frame-Options"))
|
||||
}
|
||||
|
||||
// Test custom policy
|
||||
{
|
||||
s := fakeServer()
|
||||
s.XFrameOptions = "deny"
|
||||
cancelInformer := test.StartInformer(s.projInformer)
|
||||
defer cancelInformer()
|
||||
port, err := test.GetFreePort()
|
||||
assert.NoError(t, err)
|
||||
metricsPort, err := test.GetFreePort()
|
||||
assert.NoError(t, err)
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
defer cancel()
|
||||
go s.Run(ctx, port, metricsPort)
|
||||
defer func() { time.Sleep(3 * time.Second) }()
|
||||
|
||||
err = test.WaitForPortListen(fmt.Sprintf("127.0.0.1:%d", port), 10*time.Second)
|
||||
assert.NoError(t, err)
|
||||
|
||||
// Allow server startup
|
||||
time.Sleep(1 * time.Second)
|
||||
|
||||
client := http.Client{}
|
||||
url := fmt.Sprintf("http://127.0.0.1:%d/test.html", port)
|
||||
req, err := http.NewRequest("GET", url, nil)
|
||||
assert.NoError(t, err)
|
||||
resp, err := client.Do(req)
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, "deny", resp.Header.Get("X-Frame-Options"))
|
||||
}
|
||||
|
||||
// Test disabled
|
||||
{
|
||||
s := fakeServer()
|
||||
s.XFrameOptions = ""
|
||||
cancelInformer := test.StartInformer(s.projInformer)
|
||||
defer cancelInformer()
|
||||
port, err := test.GetFreePort()
|
||||
assert.NoError(t, err)
|
||||
metricsPort, err := test.GetFreePort()
|
||||
assert.NoError(t, err)
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
defer cancel()
|
||||
go s.Run(ctx, port, metricsPort)
|
||||
defer func() { time.Sleep(3 * time.Second) }()
|
||||
|
||||
err = test.WaitForPortListen(fmt.Sprintf("127.0.0.1:%d", port), 10*time.Second)
|
||||
assert.NoError(t, err)
|
||||
|
||||
// Allow server startup
|
||||
time.Sleep(1 * time.Second)
|
||||
|
||||
client := http.Client{}
|
||||
url := fmt.Sprintf("http://127.0.0.1:%d/test.html", port)
|
||||
req, err := http.NewRequest("GET", url, nil)
|
||||
assert.NoError(t, err)
|
||||
resp, err := client.Do(req)
|
||||
assert.NoError(t, err)
|
||||
assert.Empty(t, resp.Header.Get("X-Frame-Options"))
|
||||
}
|
||||
}
|
||||
|
||||
func Test_getToken(t *testing.T) {
|
||||
token := "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c"
|
||||
t.Run("Empty", func(t *testing.T) {
|
||||
|
|
|
|||
83
util/db/cluster_norace_test.go
Normal file
83
util/db/cluster_norace_test.go
Normal file
|
|
@ -0,0 +1,83 @@
|
|||
// +build !race
|
||||
|
||||
package db
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"k8s.io/client-go/kubernetes/fake"
|
||||
|
||||
"github.com/argoproj/argo-cd/common"
|
||||
"github.com/argoproj/argo-cd/pkg/apis/application/v1alpha1"
|
||||
"github.com/argoproj/argo-cd/util/settings"
|
||||
)
|
||||
|
||||
func TestWatchClusters_CreateRemoveCluster(t *testing.T) {
|
||||
|
||||
// !race:
|
||||
// Intermittent failure when running TestWatchClusters_LocalClusterModifications with -race, likely due to race condition
|
||||
// https://github.com/argoproj/argo-cd/issues/4755
|
||||
|
||||
kubeclientset := fake.NewSimpleClientset()
|
||||
settingsManager := settings.NewSettingsManager(context.Background(), kubeclientset, fakeNamespace)
|
||||
db := NewDB(fakeNamespace, settingsManager, kubeclientset)
|
||||
runWatchTest(t, db, []func(old *v1alpha1.Cluster, new *v1alpha1.Cluster){
|
||||
func(old *v1alpha1.Cluster, new *v1alpha1.Cluster) {
|
||||
assert.Nil(t, old)
|
||||
assert.Equal(t, new.Server, common.KubernetesInternalAPIServerAddr)
|
||||
|
||||
_, err := db.CreateCluster(context.Background(), &v1alpha1.Cluster{
|
||||
Server: "https://minikube",
|
||||
Name: "minikube",
|
||||
})
|
||||
assert.NoError(t, err)
|
||||
},
|
||||
func(old *v1alpha1.Cluster, new *v1alpha1.Cluster) {
|
||||
assert.Nil(t, old)
|
||||
assert.Equal(t, new.Server, "https://minikube")
|
||||
assert.Equal(t, new.Name, "minikube")
|
||||
|
||||
assert.NoError(t, db.DeleteCluster(context.Background(), "https://minikube"))
|
||||
},
|
||||
func(old *v1alpha1.Cluster, new *v1alpha1.Cluster) {
|
||||
assert.Nil(t, new)
|
||||
assert.Equal(t, old.Server, "https://minikube")
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
func TestWatchClusters_LocalClusterModifications(t *testing.T) {
|
||||
|
||||
// !race:
|
||||
// Intermittent failure when running TestWatchClusters_LocalClusterModifications with -race, likely due to race condition
|
||||
// https://github.com/argoproj/argo-cd/issues/4755
|
||||
|
||||
kubeclientset := fake.NewSimpleClientset()
|
||||
settingsManager := settings.NewSettingsManager(context.Background(), kubeclientset, fakeNamespace)
|
||||
db := NewDB(fakeNamespace, settingsManager, kubeclientset)
|
||||
runWatchTest(t, db, []func(old *v1alpha1.Cluster, new *v1alpha1.Cluster){
|
||||
func(old *v1alpha1.Cluster, new *v1alpha1.Cluster) {
|
||||
assert.Nil(t, old)
|
||||
assert.Equal(t, new.Server, common.KubernetesInternalAPIServerAddr)
|
||||
|
||||
_, err := db.CreateCluster(context.Background(), &v1alpha1.Cluster{
|
||||
Server: common.KubernetesInternalAPIServerAddr,
|
||||
Name: "some name",
|
||||
})
|
||||
assert.NoError(t, err)
|
||||
},
|
||||
func(old *v1alpha1.Cluster, new *v1alpha1.Cluster) {
|
||||
assert.NotNil(t, old)
|
||||
assert.Equal(t, new.Server, common.KubernetesInternalAPIServerAddr)
|
||||
assert.Equal(t, new.Name, "some name")
|
||||
|
||||
assert.NoError(t, db.DeleteCluster(context.Background(), common.KubernetesInternalAPIServerAddr))
|
||||
},
|
||||
func(old *v1alpha1.Cluster, new *v1alpha1.Cluster) {
|
||||
assert.Equal(t, new.Server, common.KubernetesInternalAPIServerAddr)
|
||||
assert.Equal(t, new.Name, "in-cluster")
|
||||
},
|
||||
})
|
||||
}
|
||||
|
|
@ -118,64 +118,6 @@ func TestDeleteUnknownCluster(t *testing.T) {
|
|||
assert.EqualError(t, db.DeleteCluster(context.Background(), "http://unknown"), `rpc error: code = NotFound desc = cluster "http://unknown" not found`)
|
||||
}
|
||||
|
||||
func TestWatchClusters_CreateRemoveCluster(t *testing.T) {
|
||||
kubeclientset := fake.NewSimpleClientset()
|
||||
settingsManager := settings.NewSettingsManager(context.Background(), kubeclientset, fakeNamespace)
|
||||
db := NewDB(fakeNamespace, settingsManager, kubeclientset)
|
||||
runWatchTest(t, db, []func(old *v1alpha1.Cluster, new *v1alpha1.Cluster){
|
||||
func(old *v1alpha1.Cluster, new *v1alpha1.Cluster) {
|
||||
assert.Nil(t, old)
|
||||
assert.Equal(t, new.Server, common.KubernetesInternalAPIServerAddr)
|
||||
|
||||
_, err := db.CreateCluster(context.Background(), &v1alpha1.Cluster{
|
||||
Server: "https://minikube",
|
||||
Name: "minikube",
|
||||
})
|
||||
assert.NoError(t, err)
|
||||
},
|
||||
func(old *v1alpha1.Cluster, new *v1alpha1.Cluster) {
|
||||
assert.Nil(t, old)
|
||||
assert.Equal(t, new.Server, "https://minikube")
|
||||
assert.Equal(t, new.Name, "minikube")
|
||||
|
||||
assert.NoError(t, db.DeleteCluster(context.Background(), "https://minikube"))
|
||||
},
|
||||
func(old *v1alpha1.Cluster, new *v1alpha1.Cluster) {
|
||||
assert.Nil(t, new)
|
||||
assert.Equal(t, old.Server, "https://minikube")
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
func TestWatchClusters_LocalClusterModifications(t *testing.T) {
|
||||
kubeclientset := fake.NewSimpleClientset()
|
||||
settingsManager := settings.NewSettingsManager(context.Background(), kubeclientset, fakeNamespace)
|
||||
db := NewDB(fakeNamespace, settingsManager, kubeclientset)
|
||||
runWatchTest(t, db, []func(old *v1alpha1.Cluster, new *v1alpha1.Cluster){
|
||||
func(old *v1alpha1.Cluster, new *v1alpha1.Cluster) {
|
||||
assert.Nil(t, old)
|
||||
assert.Equal(t, new.Server, common.KubernetesInternalAPIServerAddr)
|
||||
|
||||
_, err := db.CreateCluster(context.Background(), &v1alpha1.Cluster{
|
||||
Server: common.KubernetesInternalAPIServerAddr,
|
||||
Name: "some name",
|
||||
})
|
||||
assert.NoError(t, err)
|
||||
},
|
||||
func(old *v1alpha1.Cluster, new *v1alpha1.Cluster) {
|
||||
assert.NotNil(t, old)
|
||||
assert.Equal(t, new.Server, common.KubernetesInternalAPIServerAddr)
|
||||
assert.Equal(t, new.Name, "some name")
|
||||
|
||||
assert.NoError(t, db.DeleteCluster(context.Background(), common.KubernetesInternalAPIServerAddr))
|
||||
},
|
||||
func(old *v1alpha1.Cluster, new *v1alpha1.Cluster) {
|
||||
assert.Equal(t, new.Server, common.KubernetesInternalAPIServerAddr)
|
||||
assert.Equal(t, new.Name, "in-cluster")
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
func runWatchTest(t *testing.T, db ArgoDB, actions []func(old *v1alpha1.Cluster, new *v1alpha1.Cluster)) {
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
defer cancel()
|
||||
|
|
|
|||
129
util/rbac/rbac_norace_test.go
Normal file
129
util/rbac/rbac_norace_test.go
Normal file
|
|
@ -0,0 +1,129 @@
|
|||
// +build !race
|
||||
|
||||
package rbac
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
apiv1 "k8s.io/api/core/v1"
|
||||
"k8s.io/client-go/kubernetes/fake"
|
||||
)
|
||||
|
||||
// TestPolicyInformer verifies the informer will get updated with a new configmap
|
||||
func TestPolicyInformer(t *testing.T) {
|
||||
|
||||
// !race:
|
||||
// A BUNCH of data race warnings thrown by running this test and the next... it's tough to guess to what degree this
|
||||
// is primarily a casbin issue or a Argo CD RBAC issue... A least one data race is an `rbac.go` with
|
||||
// itself, a bunch are in casbin. You can see the full list by doing a `go test -race github.com/argoproj/argo-cd/util/rbac`
|
||||
//
|
||||
// It couldn't hurt to take a look at this code to decide if Argo CD is properly handling concurrent data
|
||||
// access here, but in the mean time I have disabled data race testing of this test.
|
||||
|
||||
cm := fakeConfigMap()
|
||||
cm.Data[ConfigMapPolicyCSVKey] = "p, admin, applications, delete, */*, allow"
|
||||
kubeclientset := fake.NewSimpleClientset(cm)
|
||||
enf := NewEnforcer(kubeclientset, fakeNamespace, fakeConfigMapName, nil)
|
||||
|
||||
ctx := context.Background()
|
||||
ctx, cancel := context.WithCancel(ctx)
|
||||
defer cancel()
|
||||
go enf.runInformer(ctx, func(cm *apiv1.ConfigMap) error {
|
||||
return nil
|
||||
})
|
||||
|
||||
loaded := false
|
||||
for i := 1; i <= 20; i++ {
|
||||
if enf.Enforce("admin", "applications", "delete", "foo/bar") {
|
||||
loaded = true
|
||||
break
|
||||
}
|
||||
time.Sleep(50 * time.Millisecond)
|
||||
}
|
||||
assert.True(t, loaded, "Policy update failed to load")
|
||||
|
||||
// update the configmap and update policy
|
||||
delete(cm.Data, ConfigMapPolicyCSVKey)
|
||||
err := enf.syncUpdate(cm, noOpUpdate)
|
||||
assert.Nil(t, err)
|
||||
assert.False(t, enf.Enforce("admin", "applications", "delete", "foo/bar"))
|
||||
}
|
||||
|
||||
// TestResourceActionWildcards verifies the ability to use wildcards in resources and actions
|
||||
func TestResourceActionWildcards(t *testing.T) {
|
||||
|
||||
// !race:
|
||||
// Same as TestPolicyInformer
|
||||
|
||||
kubeclientset := fake.NewSimpleClientset(fakeConfigMap())
|
||||
enf := NewEnforcer(kubeclientset, fakeNamespace, fakeConfigMapName, nil)
|
||||
policy := `
|
||||
p, alice, *, get, foo/obj, allow
|
||||
p, bob, repositories, *, foo/obj, allow
|
||||
p, cathy, *, *, foo/obj, allow
|
||||
p, dave, applications, get, foo/obj, allow
|
||||
p, dave, applications/*, get, foo/obj, allow
|
||||
p, eve, *, get, foo/obj, deny
|
||||
p, mallory, repositories, *, foo/obj, deny
|
||||
p, mallory, repositories, *, foo/obj, allow
|
||||
p, mike, *, *, foo/obj, allow
|
||||
p, mike, *, *, foo/obj, deny
|
||||
p, trudy, applications, get, foo/obj, allow
|
||||
p, trudy, applications/*, get, foo/obj, allow
|
||||
p, trudy, applications/secrets, get, foo/obj, deny
|
||||
p, danny, applications, get, */obj, allow
|
||||
p, danny, applications, get, proj1/a*p1, allow
|
||||
`
|
||||
_ = enf.SetUserPolicy(policy)
|
||||
|
||||
// Verify the resource wildcard
|
||||
assert.True(t, enf.Enforce("alice", "applications", "get", "foo/obj"))
|
||||
assert.True(t, enf.Enforce("alice", "applications/resources", "get", "foo/obj"))
|
||||
assert.False(t, enf.Enforce("alice", "applications/resources", "delete", "foo/obj"))
|
||||
|
||||
// Verify action wildcards work
|
||||
assert.True(t, enf.Enforce("bob", "repositories", "get", "foo/obj"))
|
||||
assert.True(t, enf.Enforce("bob", "repositories", "delete", "foo/obj"))
|
||||
assert.False(t, enf.Enforce("bob", "applications", "get", "foo/obj"))
|
||||
|
||||
// Verify resource and action wildcards work in conjunction
|
||||
assert.True(t, enf.Enforce("cathy", "repositories", "get", "foo/obj"))
|
||||
assert.True(t, enf.Enforce("cathy", "repositories", "delete", "foo/obj"))
|
||||
assert.True(t, enf.Enforce("cathy", "applications", "get", "foo/obj"))
|
||||
assert.True(t, enf.Enforce("cathy", "applications/resources", "delete", "foo/obj"))
|
||||
|
||||
// Verify wildcards with sub-resources
|
||||
assert.True(t, enf.Enforce("dave", "applications", "get", "foo/obj"))
|
||||
assert.True(t, enf.Enforce("dave", "applications/logs", "get", "foo/obj"))
|
||||
|
||||
// Verify the resource wildcard
|
||||
assert.False(t, enf.Enforce("eve", "applications", "get", "foo/obj"))
|
||||
assert.False(t, enf.Enforce("eve", "applications/resources", "get", "foo/obj"))
|
||||
assert.False(t, enf.Enforce("eve", "applications/resources", "delete", "foo/obj"))
|
||||
|
||||
// Verify action wildcards work
|
||||
assert.False(t, enf.Enforce("mallory", "repositories", "get", "foo/obj"))
|
||||
assert.False(t, enf.Enforce("mallory", "repositories", "delete", "foo/obj"))
|
||||
assert.False(t, enf.Enforce("mallory", "applications", "get", "foo/obj"))
|
||||
|
||||
// Verify resource and action wildcards work in conjunction
|
||||
assert.False(t, enf.Enforce("mike", "repositories", "get", "foo/obj"))
|
||||
assert.False(t, enf.Enforce("mike", "repositories", "delete", "foo/obj"))
|
||||
assert.False(t, enf.Enforce("mike", "applications", "get", "foo/obj"))
|
||||
assert.False(t, enf.Enforce("mike", "applications/resources", "delete", "foo/obj"))
|
||||
|
||||
// Verify wildcards with sub-resources
|
||||
assert.True(t, enf.Enforce("trudy", "applications", "get", "foo/obj"))
|
||||
assert.True(t, enf.Enforce("trudy", "applications/logs", "get", "foo/obj"))
|
||||
assert.False(t, enf.Enforce("trudy", "applications/secrets", "get", "foo/obj"))
|
||||
|
||||
// Verify trailing wildcards don't grant full access
|
||||
assert.True(t, enf.Enforce("danny", "applications", "get", "foo/obj"))
|
||||
assert.True(t, enf.Enforce("danny", "applications", "get", "bar/obj"))
|
||||
assert.False(t, enf.Enforce("danny", "applications", "get", "foo/bar"))
|
||||
assert.True(t, enf.Enforce("danny", "applications", "get", "proj1/app1"))
|
||||
assert.False(t, enf.Enforce("danny", "applications", "get", "proj1/app2"))
|
||||
}
|
||||
|
|
@ -79,109 +79,6 @@ func TestBuiltinPolicyEnforcer(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
// TestPolicyInformer verifies the informer will get updated with a new configmap
|
||||
func TestPolicyInformer(t *testing.T) {
|
||||
cm := fakeConfigMap()
|
||||
cm.Data[ConfigMapPolicyCSVKey] = "p, admin, applications, delete, */*, allow"
|
||||
kubeclientset := fake.NewSimpleClientset(cm)
|
||||
enf := NewEnforcer(kubeclientset, fakeNamespace, fakeConfigMapName, nil)
|
||||
|
||||
ctx := context.Background()
|
||||
ctx, cancel := context.WithCancel(ctx)
|
||||
defer cancel()
|
||||
go enf.runInformer(ctx, func(cm *apiv1.ConfigMap) error {
|
||||
return nil
|
||||
})
|
||||
|
||||
loaded := false
|
||||
for i := 1; i <= 20; i++ {
|
||||
if enf.Enforce("admin", "applications", "delete", "foo/bar") {
|
||||
loaded = true
|
||||
break
|
||||
}
|
||||
time.Sleep(50 * time.Millisecond)
|
||||
}
|
||||
assert.True(t, loaded, "Policy update failed to load")
|
||||
|
||||
// update the configmap and update policy
|
||||
delete(cm.Data, ConfigMapPolicyCSVKey)
|
||||
err := enf.syncUpdate(cm, noOpUpdate)
|
||||
assert.Nil(t, err)
|
||||
assert.False(t, enf.Enforce("admin", "applications", "delete", "foo/bar"))
|
||||
}
|
||||
|
||||
// TestResourceActionWildcards verifies the ability to use wildcards in resources and actions
|
||||
func TestResourceActionWildcards(t *testing.T) {
|
||||
kubeclientset := fake.NewSimpleClientset(fakeConfigMap())
|
||||
enf := NewEnforcer(kubeclientset, fakeNamespace, fakeConfigMapName, nil)
|
||||
policy := `
|
||||
p, alice, *, get, foo/obj, allow
|
||||
p, bob, repositories, *, foo/obj, allow
|
||||
p, cathy, *, *, foo/obj, allow
|
||||
p, dave, applications, get, foo/obj, allow
|
||||
p, dave, applications/*, get, foo/obj, allow
|
||||
p, eve, *, get, foo/obj, deny
|
||||
p, mallory, repositories, *, foo/obj, deny
|
||||
p, mallory, repositories, *, foo/obj, allow
|
||||
p, mike, *, *, foo/obj, allow
|
||||
p, mike, *, *, foo/obj, deny
|
||||
p, trudy, applications, get, foo/obj, allow
|
||||
p, trudy, applications/*, get, foo/obj, allow
|
||||
p, trudy, applications/secrets, get, foo/obj, deny
|
||||
p, danny, applications, get, */obj, allow
|
||||
p, danny, applications, get, proj1/a*p1, allow
|
||||
`
|
||||
_ = enf.SetUserPolicy(policy)
|
||||
|
||||
// Verify the resource wildcard
|
||||
assert.True(t, enf.Enforce("alice", "applications", "get", "foo/obj"))
|
||||
assert.True(t, enf.Enforce("alice", "applications/resources", "get", "foo/obj"))
|
||||
assert.False(t, enf.Enforce("alice", "applications/resources", "delete", "foo/obj"))
|
||||
|
||||
// Verify action wildcards work
|
||||
assert.True(t, enf.Enforce("bob", "repositories", "get", "foo/obj"))
|
||||
assert.True(t, enf.Enforce("bob", "repositories", "delete", "foo/obj"))
|
||||
assert.False(t, enf.Enforce("bob", "applications", "get", "foo/obj"))
|
||||
|
||||
// Verify resource and action wildcards work in conjunction
|
||||
assert.True(t, enf.Enforce("cathy", "repositories", "get", "foo/obj"))
|
||||
assert.True(t, enf.Enforce("cathy", "repositories", "delete", "foo/obj"))
|
||||
assert.True(t, enf.Enforce("cathy", "applications", "get", "foo/obj"))
|
||||
assert.True(t, enf.Enforce("cathy", "applications/resources", "delete", "foo/obj"))
|
||||
|
||||
// Verify wildcards with sub-resources
|
||||
assert.True(t, enf.Enforce("dave", "applications", "get", "foo/obj"))
|
||||
assert.True(t, enf.Enforce("dave", "applications/logs", "get", "foo/obj"))
|
||||
|
||||
// Verify the resource wildcard
|
||||
assert.False(t, enf.Enforce("eve", "applications", "get", "foo/obj"))
|
||||
assert.False(t, enf.Enforce("eve", "applications/resources", "get", "foo/obj"))
|
||||
assert.False(t, enf.Enforce("eve", "applications/resources", "delete", "foo/obj"))
|
||||
|
||||
// Verify action wildcards work
|
||||
assert.False(t, enf.Enforce("mallory", "repositories", "get", "foo/obj"))
|
||||
assert.False(t, enf.Enforce("mallory", "repositories", "delete", "foo/obj"))
|
||||
assert.False(t, enf.Enforce("mallory", "applications", "get", "foo/obj"))
|
||||
|
||||
// Verify resource and action wildcards work in conjunction
|
||||
assert.False(t, enf.Enforce("mike", "repositories", "get", "foo/obj"))
|
||||
assert.False(t, enf.Enforce("mike", "repositories", "delete", "foo/obj"))
|
||||
assert.False(t, enf.Enforce("mike", "applications", "get", "foo/obj"))
|
||||
assert.False(t, enf.Enforce("mike", "applications/resources", "delete", "foo/obj"))
|
||||
|
||||
// Verify wildcards with sub-resources
|
||||
assert.True(t, enf.Enforce("trudy", "applications", "get", "foo/obj"))
|
||||
assert.True(t, enf.Enforce("trudy", "applications/logs", "get", "foo/obj"))
|
||||
assert.False(t, enf.Enforce("trudy", "applications/secrets", "get", "foo/obj"))
|
||||
|
||||
// Verify trailing wildcards don't grant full access
|
||||
assert.True(t, enf.Enforce("danny", "applications", "get", "foo/obj"))
|
||||
assert.True(t, enf.Enforce("danny", "applications", "get", "bar/obj"))
|
||||
assert.False(t, enf.Enforce("danny", "applications", "get", "foo/bar"))
|
||||
assert.True(t, enf.Enforce("danny", "applications", "get", "proj1/app1"))
|
||||
assert.False(t, enf.Enforce("danny", "applications", "get", "proj1/app2"))
|
||||
}
|
||||
|
||||
// TestProjectIsolationEnforcement verifies the ability to create Project specific policies
|
||||
func TestProjectIsolationEnforcement(t *testing.T) {
|
||||
kubeclientset := fake.NewSimpleClientset(fakeConfigMap())
|
||||
|
|
|
|||
40
util/session/sessionmanager_norace_test.go
Normal file
40
util/session/sessionmanager_norace_test.go
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
// +build !race
|
||||
|
||||
package session
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
||||
"github.com/argoproj/argo-cd/util/settings"
|
||||
)
|
||||
|
||||
func TestRandomPasswordVerificationDelay(t *testing.T) {
|
||||
|
||||
// !race:
|
||||
//`SessionManager.VerifyUsernamePassword` uses bcrypt to prevent against time-based attacks
|
||||
// and verify the hashed password; however this is a CPU intensive algorithm that is made
|
||||
// significantly slower due to data race detection being enabled, which breaks through
|
||||
// the maximum time limit required by `TestRandomPasswordVerificationDelay`.
|
||||
|
||||
var sleptFor time.Duration
|
||||
settingsMgr := settings.NewSettingsManager(context.Background(), getKubeClient("password", true), "argocd")
|
||||
mgr := newSessionManager(settingsMgr, NewInMemoryUserStateStorage())
|
||||
mgr.verificationDelayNoiseEnabled = true
|
||||
mgr.sleep = func(d time.Duration) {
|
||||
sleptFor = d
|
||||
}
|
||||
for i := 0; i < 10; i++ {
|
||||
sleptFor = 0
|
||||
start := time.Now()
|
||||
if !assert.NoError(t, mgr.VerifyUsernamePassword("admin", "password")) {
|
||||
return
|
||||
}
|
||||
totalDuration := time.Since(start) + sleptFor
|
||||
assert.GreaterOrEqual(t, totalDuration.Nanoseconds(), verificationDelayNoiseMin.Nanoseconds())
|
||||
assert.LessOrEqual(t, totalDuration.Nanoseconds(), verificationDelayNoiseMax.Nanoseconds())
|
||||
}
|
||||
}
|
||||
|
|
@ -233,26 +233,6 @@ func TestCacheValueGetters(t *testing.T) {
|
|||
|
||||
}
|
||||
|
||||
func TestRandomPasswordVerificationDelay(t *testing.T) {
|
||||
var sleptFor time.Duration
|
||||
settingsMgr := settings.NewSettingsManager(context.Background(), getKubeClient("password", true), "argocd")
|
||||
mgr := newSessionManager(settingsMgr, NewInMemoryUserStateStorage())
|
||||
mgr.verificationDelayNoiseEnabled = true
|
||||
mgr.sleep = func(d time.Duration) {
|
||||
sleptFor = d
|
||||
}
|
||||
for i := 0; i < 10; i++ {
|
||||
sleptFor = 0
|
||||
start := time.Now()
|
||||
if !assert.NoError(t, mgr.VerifyUsernamePassword("admin", "password")) {
|
||||
return
|
||||
}
|
||||
totalDuration := time.Since(start) + sleptFor
|
||||
assert.GreaterOrEqual(t, totalDuration.Nanoseconds(), verificationDelayNoiseMin.Nanoseconds())
|
||||
assert.LessOrEqual(t, totalDuration.Nanoseconds(), verificationDelayNoiseMax.Nanoseconds())
|
||||
}
|
||||
}
|
||||
|
||||
func TestLoginRateLimiter(t *testing.T) {
|
||||
settingsMgr := settings.NewSettingsManager(context.Background(), getKubeClient("password", true), "argocd")
|
||||
storage := NewInMemoryUserStateStorage()
|
||||
|
|
|
|||
Loading…
Reference in a new issue