mirror of https://github.com/fluxcd/flux2.git
				
				
				
			Merge pull request #1696 from allenporter/flux-cmd-create
Add tests for create source gitpull/1782/head
						commit
						06fa8f75c9
					
				| @ -0,0 +1,131 @@ | ||||
| // +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) | ||||
| 		}) | ||||
| 	} | ||||
| } | ||||
| @ -0,0 +1,6 @@ | ||||
| ✚ generating GitRepository source | ||||
| ► applying GitRepository source | ||||
| ✔ GitRepository source created | ||||
| ◎ waiting for GitRepository source reconciliation | ||||
| ✔ GitRepository source reconciliation completed | ||||
| ✔ fetched revision: v1 | ||||
					Loading…
					
					
				
		Reference in New Issue