From b16ab05607bad6a1c17aa561f575a3cefaeca869 Mon Sep 17 00:00:00 2001 From: Nick Freyaldenhoven Date: Thu, 10 Nov 2022 13:02:32 -0600 Subject: [PATCH] Adding rough test case for known condition and support to mock the timeout required. A reproduceable instance of this condition is observed when Flagger executes test too seen after a --wait or --atomic install by an outside source. https://github.com/fluxcd/flagger/issues/816 Signed-off-by: Nick Freyaldenhoven --- pkg/action/release_testing_test.go | 86 ++++++++++++++++++++++++++++++ pkg/kube/fake/fake.go | 2 + 2 files changed, 88 insertions(+) create mode 100644 pkg/action/release_testing_test.go diff --git a/pkg/action/release_testing_test.go b/pkg/action/release_testing_test.go new file mode 100644 index 000000000..a08419bf2 --- /dev/null +++ b/pkg/action/release_testing_test.go @@ -0,0 +1,86 @@ +/* +Copyright The Helm Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package action + +import ( + "testing" + "time" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + + kubefake "helm.sh/helm/v3/pkg/kube/fake" + "helm.sh/helm/v3/pkg/release" +) + +func testingActions(t *testing.T) *ReleaseTesting { + config := actionConfigFixture(t) + + tester := config.KubeClient.(*kubefake.FailingKubeClient) + tester.WatchDuration = 5 * time.Second + config.KubeClient = tester + + relTesting := NewReleaseTesting(config) + relTesting.Namespace = "spaced" + + return relTesting +} + +func TestReleaseTesting_RaceWithAWaitInstall(t *testing.T) { + is := assert.New(t) + req := require.New(t) + + releaseTestingAction := testingActions(t) + + err := releaseTestingAction.cfg.Releases.Create(getTestRelease()) + req.NoError(err) + + rel, err := releaseTestingAction.cfg.Releases.Get(getTestRelease().Name, 2) + req.NoError(err) + req.Equal(rel.Info.Status, release.StatusPendingUpgrade) + + done := make(chan bool) + go func() { + _, err := releaseTestingAction.Run(rel.Name) + req.NoError(err) + done <- true + }() + + time.Sleep(time.Second * 1) + + updageTestRelease := getTestRelease() //Recreate cause mem otherwise shares same release -- Data race and shared resource + updageTestRelease.Info.Status = release.StatusDeployed + err = releaseTestingAction.cfg.Releases.Update(updageTestRelease) + req.NoError(err) + + finalRelease, err := releaseTestingAction.cfg.Releases.Get(updageTestRelease.Name, 2) + req.NoError(err) + is.Equal(release.StatusDeployed, finalRelease.Info.Status) + + <-done + + finalRelease, err = releaseTestingAction.cfg.Releases.Get(updageTestRelease.Name, 2) + req.NoError(err) + is.Equal(release.StatusDeployed, finalRelease.Info.Status) +} + +func getTestRelease() *release.Release { + testRelease := releaseStub() + testRelease.Info.Status = release.StatusPendingUpgrade + testRelease.Version = 2 + return testRelease +} diff --git a/pkg/kube/fake/fake.go b/pkg/kube/fake/fake.go index 267020d57..e9512bd00 100644 --- a/pkg/kube/fake/fake.go +++ b/pkg/kube/fake/fake.go @@ -47,6 +47,7 @@ type FailingKubeClient struct { BuildUnstructuredError error WaitAndGetCompletedPodPhaseError error WaitDuration time.Duration + WatchDuration time.Duration } // Create returns the configured error if set or prints @@ -100,6 +101,7 @@ func (f *FailingKubeClient) Delete(resources kube.ResourceList) (*kube.Result, [ // WatchUntilReady returns the configured error if set or prints func (f *FailingKubeClient) WatchUntilReady(resources kube.ResourceList, d time.Duration) error { + time.Sleep(f.WatchDuration) if f.WatchUntilReadyError != nil { return f.WatchUntilReadyError }