1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 package testrunner
16
17 import (
18 "context"
19 "testing"
20
21 "github.com/GoogleCloudPlatform/k8s-config-connector/pkg/dcl/clientconfig"
22 dclconversion "github.com/GoogleCloudPlatform/k8s-config-connector/pkg/dcl/conversion"
23 dclmetadata "github.com/GoogleCloudPlatform/k8s-config-connector/pkg/dcl/metadata"
24 "github.com/GoogleCloudPlatform/k8s-config-connector/pkg/dcl/schema/dclschemaloader"
25 "github.com/GoogleCloudPlatform/k8s-config-connector/pkg/k8s"
26 "github.com/GoogleCloudPlatform/k8s-config-connector/pkg/servicemapping/servicemappingloader"
27 "github.com/GoogleCloudPlatform/k8s-config-connector/pkg/test"
28 testcontroller "github.com/GoogleCloudPlatform/k8s-config-connector/pkg/test/controller"
29 testreconciler "github.com/GoogleCloudPlatform/k8s-config-connector/pkg/test/controller/reconciler"
30 testgcp "github.com/GoogleCloudPlatform/k8s-config-connector/pkg/test/gcp"
31 "github.com/GoogleCloudPlatform/k8s-config-connector/pkg/test/resourcefixture"
32 testvariable "github.com/GoogleCloudPlatform/k8s-config-connector/pkg/test/resourcefixture/variable"
33 testservicemappingloader "github.com/GoogleCloudPlatform/k8s-config-connector/pkg/test/servicemappingloader"
34 testyaml "github.com/GoogleCloudPlatform/k8s-config-connector/pkg/test/yaml"
35 tfprovider "github.com/GoogleCloudPlatform/k8s-config-connector/pkg/tf/provider"
36
37 mmdcl "github.com/GoogleCloudPlatform/declarative-resource-client-library/dcl"
38 "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
39 "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
40 "k8s.io/apimachinery/pkg/types"
41 "sigs.k8s.io/controller-runtime/pkg/manager"
42 )
43
44 type TestContext struct {
45 CreateUnstruct *unstructured.Unstructured
46 UpdateUnstruct *unstructured.Unstructured
47 DependencyUnstructs []*unstructured.Unstructured
48 ResourceFixture resourcefixture.ResourceFixture
49 NamespacedName types.NamespacedName
50 UniqueId string
51 }
52
53 type SystemContext struct {
54 Manager manager.Manager
55 SMLoader *servicemappingloader.ServiceMappingLoader
56 Reconciler *testreconciler.TestReconciler
57 TFProvider *schema.Provider
58 DCLConfig *mmdcl.Config
59 DCLConverter *dclconversion.Converter
60 }
61
62 type ShouldRunFunc func(fixture resourcefixture.ResourceFixture, mgr manager.Manager) bool
63 type TestCaseFunc func(t *testing.T, testContext TestContext, sysContext SystemContext)
64
65 func RunAllWithObjectCreated(t *testing.T, mgr manager.Manager, shouldRunFunc ShouldRunFunc, testCaseFunc TestCaseFunc) {
66 testFunc := func(t *testing.T, testContext TestContext, sysContext SystemContext) {
67 if err := sysContext.Manager.GetClient().Create(context.TODO(), testContext.CreateUnstruct); err != nil {
68 t.Fatalf("error creating resource: %v", err)
69 }
70 resourceCleanup := sysContext.Reconciler.BuildCleanupFunc(testContext.CreateUnstruct, testreconciler.CleanupPolicyAlways)
71 defer resourceCleanup()
72 sysContext.Reconciler.Reconcile(testContext.CreateUnstruct, testreconciler.ExpectedSuccessfulReconcileResultFor(sysContext.Reconciler, testContext.CreateUnstruct), nil)
73 testCaseFunc(t, testContext, sysContext)
74 }
75 RunAllWithDependenciesCreatedButNotObject(t, mgr, shouldRunFunc, testFunc)
76
77 }
78
79 func RunAllWithDependenciesCreatedButNotObject(t *testing.T, mgr manager.Manager, shouldRunFunc ShouldRunFunc, testCaseFunc TestCaseFunc) {
80 testFunc := func(t *testing.T, testContext TestContext, sysContext SystemContext) {
81 dependencyCleanup := sysContext.Reconciler.CreateAndReconcile(testContext.DependencyUnstructs, testreconciler.CleanupPolicyAlways)
82 defer dependencyCleanup()
83 testCaseFunc(t, testContext, sysContext)
84 }
85 RunAll(t, mgr, shouldRunFunc, testFunc)
86 }
87
88 func RunAll(t *testing.T, mgr manager.Manager, shouldRunFunc ShouldRunFunc, testCaseFunc TestCaseFunc) {
89 project := testgcp.GetDefaultProject(t)
90 shouldRun := func(resourceFixture resourcefixture.ResourceFixture) bool {
91 return shouldRunFunc(resourceFixture, mgr)
92 }
93 testFunc := func(t *testing.T, fixture resourcefixture.ResourceFixture) {
94 systemContext := newSystemContext(t, mgr)
95 testContext := NewTestContext(t, fixture, project)
96 setupNamespaces(t, testContext, systemContext)
97 testCaseFunc(t, testContext, systemContext)
98 }
99 resourcefixture.RunTests(t, shouldRun, testFunc)
100 }
101
102 func RunSpecific(t *testing.T, fixture []resourcefixture.ResourceFixture, testCaseFunc func(t *testing.T, testContext TestContext)) {
103 project := testgcp.GetDefaultProject(t)
104 testFunc := func(t *testing.T, fixture resourcefixture.ResourceFixture) {
105 testContext := NewTestContext(t, fixture, project)
106 testCaseFunc(t, testContext)
107 }
108 resourcefixture.RunSpecificTests(t, fixture, testFunc)
109 }
110
111
112
113
114 func NewTestContext(t *testing.T, fixture resourcefixture.ResourceFixture, project testgcp.GCPProject) TestContext {
115 testId := testvariable.NewUniqueId()
116 initialUnstruct := bytesToUnstructured(t, fixture.Create, testId, project)
117 name := k8s.GetNamespacedName(initialUnstruct)
118 var updateUnstruct *unstructured.Unstructured
119 if fixture.Update != nil {
120 updateUnstruct = bytesToUnstructured(t, fixture.Update, testId, project)
121 }
122 var dependencyUnstructs []*unstructured.Unstructured
123 if fixture.Dependencies != nil {
124 dependencyYamls := testyaml.SplitYAML(t, fixture.Dependencies)
125 dependencyUnstructs = make([]*unstructured.Unstructured, 0, len(dependencyYamls))
126 for _, dependBytes := range dependencyYamls {
127 depUnstruct := bytesToUnstructured(t, dependBytes, testId, project)
128 dependencyUnstructs = append(dependencyUnstructs, depUnstruct)
129 }
130 }
131 return TestContext{
132 CreateUnstruct: initialUnstruct,
133 UpdateUnstruct: updateUnstruct,
134 DependencyUnstructs: dependencyUnstructs,
135 ResourceFixture: fixture,
136 NamespacedName: name,
137 UniqueId: testId,
138 }
139 }
140
141 func bytesToUnstructured(t *testing.T, bytes []byte, testId string, project testgcp.GCPProject) *unstructured.Unstructured {
142 t.Helper()
143 updatedBytes := testcontroller.ReplaceTestVars(t, bytes, testId, project)
144 return test.ToUnstructWithNamespace(t, updatedBytes, testId)
145 }
146
147 func newSystemContext(t *testing.T, mgr manager.Manager) SystemContext {
148 smLoader := testservicemappingloader.New(t)
149 tfProvider := tfprovider.NewOrLogFatal(tfprovider.DefaultConfig)
150 dclConfig := clientconfig.NewForIntegrationTest()
151 reconciler := testreconciler.NewForDCLAndTFTestReconciler(t, mgr, tfProvider, dclConfig)
152 serviceMetadataLoader := dclmetadata.New()
153 dclSchemaLoader, err := dclschemaloader.New()
154 if err != nil {
155 t.Fatalf("error creating a new DCL schema laoder: %v", dclSchemaLoader)
156 }
157 dclConverter := dclconversion.New(dclSchemaLoader, serviceMetadataLoader)
158 return SystemContext{
159 Manager: mgr,
160 Reconciler: reconciler,
161 SMLoader: smLoader,
162 TFProvider: tfProvider,
163 DCLConfig: dclConfig,
164 DCLConverter: dclConverter,
165 }
166 }
167
168 func setupNamespaces(t *testing.T, testContext TestContext, systemContext SystemContext) {
169 namespacesAlreadySetup := make(map[string]bool)
170 testcontroller.SetupNamespaceForDefaultProject(t, systemContext.Manager.GetClient(), testContext.CreateUnstruct.GetNamespace())
171 namespacesAlreadySetup[testContext.CreateUnstruct.GetNamespace()] = true
172 for _, depUnstruct := range testContext.DependencyUnstructs {
173 if _, ok := namespacesAlreadySetup[depUnstruct.GetNamespace()]; ok {
174 continue
175 }
176 testcontroller.SetupNamespaceForDefaultProject(t, systemContext.Manager.GetClient(), depUnstruct.GetNamespace())
177 namespacesAlreadySetup[depUnstruct.GetNamespace()] = true
178 }
179 }
180
View as plain text