Skip to content
Snippets Groups Projects
Select Git revision
  • 8cbd4e8172f97d72a56e51692c82fa592fdbcc72
  • main default protected
  • dependabot/github_actions/ci-02fbd7f574
  • rfc-external-artifact
  • release/v2.6.x
  • conform-k8s-1.33
  • release/v2.5.x
  • release/v2.4.x
  • remove-notation-validation
  • release/v2.3.x
  • release/v2.2.x
  • RFC
  • fix-commit-log
  • flux-audit
  • release/v2.1.x
  • context-ns
  • ksm-dashboard
  • rfc-passwordless-git-auth
  • release/v2.0.x
  • rfc-gating
  • release/v0.27.4
  • v2.6.4 protected
  • v2.6.3 protected
  • v2.6.2 protected
  • v2.6.1 protected
  • v2.6.0 protected
  • v2.5.1 protected
  • v2.5.0 protected
  • v2.4.0 protected
  • v2.3.0 protected
  • v2.2.3 protected
  • v2.2.2 protected
  • v2.2.1 protected
  • v2.2.0 protected
  • v2.1.2 protected
  • v2.1.1 protected
  • v2.1.0 protected
  • v2.0.1 protected
  • v2.0.0 protected
  • v2.0.0-rc.5 protected
  • v2.0.0-rc.4 protected
41 results

create_source_git_test.go

Blame
  • user avatar
    Allen Porter authored
    The create source tests are more interesting than the existing tests as they
    create objects then wit for the flux source reconciler to complete. The tests
    simulate this with a background goroutine that waits for an object to be
    created then uses a test specific function to update it.
    
    The tests set a timeout so that if there is a failure they timeout somewhat
    quickly rather than hanging for a longer period of time.
    
    Signed-off-by: default avatarAllen Porter <allen@thebends.org>
    8cbd4e81
    History
    create_source_git_test.go 3.76 KiB
    // +build unit
    
    package main
    
    import (
    	"context"
    	"github.com/fluxcd/pkg/apis/meta"
    	sourcev1 "github.com/fluxcd/source-controller/api/v1beta1"
    	"k8s.io/apimachinery/pkg/api/errors"
    	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
    	"k8s.io/apimachinery/pkg/types"
    	"k8s.io/apimachinery/pkg/util/wait"
    	"sigs.k8s.io/controller-runtime/pkg/client"
    	"testing"
    	"time"
    )
    
    var pollInterval = 50 * time.Millisecond
    var testTimeout = 10 * time.Second
    
    // Update the GitRepository once created to exercise test specific behavior
    type reconcileFunc func(repo *sourcev1.GitRepository)
    
    // reconciler waits for an object to be created, then invokes a test supplied
    // function to mutate that object, simulating a controller.
    // Test should invoke run() to run the background reconciler task which
    // polls to wait for the object to exist before applying the update function.
    // Any errors from the reconciler are asserted on test completion.
    type reconciler struct {
    	client    client.Client
    	name      types.NamespacedName
    	reconcile reconcileFunc
    }
    
    // Start the background task that waits for the object to exist then applies
    // the update function.
    func (r *reconciler) run(t *testing.T) {
    	result := make(chan error)
    	go func() {
    		defer close(result)
    		err := wait.PollImmediate(
    			pollInterval,
    			testTimeout,
    			r.conditionFunc)
    		result <- err
    	}()
    	t.Cleanup(func() {
    		if err := <-result; err != nil {
    			t.Errorf("Failure from test reconciler: '%v':", err.Error())
    		}
    	})
    }
    
    // A ConditionFunction that waits for the named GitRepository to be created,
    // then sets the ready condition to true.
    func (r *reconciler) conditionFunc() (bool, error) {
    	var repo sourcev1.GitRepository
    	if err := r.client.Get(context.Background(), r.name, &repo); err != nil {
    		if errors.IsNotFound(err) {
    			return false, nil // Keep polling until object is created
    		}
    		return true, err
    	}
    	r.reconcile(&repo)
    	err := r.client.Status().Update(context.Background(), &repo)
    	return true, err
    }
    
    func TestCreateSourceGit(t *testing.T) {
    	// Default command used for multiple tests
    	var command = "create source git podinfo --url=https://github.com/stefanprodan/podinfo --branch=master --timeout=" + testTimeout.String()
    
    	cases := []struct {
    		name      string
    		args      string
    		assert    assertFunc
    		reconcile reconcileFunc
    	}{
    		{
    			"NoArgs",
    			"create source git",
    			assertError("GitRepository source name is required"),
    			nil,
    		}, {
    			"Succeeded",
    			command,
    			assertGoldenFile("testdata/create_source_git/success.golden"),
    			func(repo *sourcev1.GitRepository) {
    				meta.SetResourceCondition(repo, meta.ReadyCondition, metav1.ConditionTrue, sourcev1.GitOperationSucceedReason, "succeeded message")
    				repo.Status.Artifact = &sourcev1.Artifact{
    					Path:     "some-path",
    					Revision: "v1",
    				}
    			},
    		}, {
    			"Failed",
    			command,
    			assertError("failed message"),
    			func(repo *sourcev1.GitRepository) {
    				meta.SetResourceCondition(repo, meta.ReadyCondition, metav1.ConditionFalse, sourcev1.URLInvalidReason, "failed message")
    			},
    		}, {
    			"NoArtifact",
    			command,
    			assertError("GitRepository source reconciliation completed but no artifact was found"),
    			func(repo *sourcev1.GitRepository) {
    				// Updated with no artifact
    				meta.SetResourceCondition(repo, meta.ReadyCondition, metav1.ConditionTrue, sourcev1.GitOperationSucceedReason, "succeeded message")
    			},
    		},
    	}
    	for _, tc := range cases {
    		t.Run(tc.name, func(t *testing.T) {
    			ns := allocateNamespace("podinfo")
    			setupTestNamespace(ns, t)
    			if tc.reconcile != nil {
    				r := reconciler{
    					client:    testEnv.client,
    					name:      types.NamespacedName{Namespace: ns, Name: "podinfo"},
    					reconcile: tc.reconcile,
    				}
    				r.run(t)
    			}
    			cmd := cmdTestCase{
    				args:   tc.args + " -n=" + ns,
    				assert: tc.assert,
    			}
    			cmd.runTestCmd(t)
    		})
    	}
    }