Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make label validation optional for recipe functional tests #5530

Merged
merged 7 commits into from
May 11, 2023
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions test/functional/corerp/cli/cli_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -476,7 +476,7 @@ func Test_CLI_Delete(t *testing.T) {
validation.NewK8sPodForResource(appName, "containerb-app-with-resources"),
},
},
})
}, false)

err = cli.ApplicationDelete(ctx, appName)
require.NoErrorf(t, err, "failed to delete %s", appName)
Expand Down Expand Up @@ -510,7 +510,7 @@ func Test_CLI_Delete(t *testing.T) {
validation.NewK8sPodForResource(appName, "containerb-app-with-resources"),
},
},
})
}, false)

//ignore response for tests
_, err = options.ManagementClient.DeleteResource(ctx, "Applications.Core/containers", "containerb-app-with-resources")
Expand Down
3 changes: 2 additions & 1 deletion test/functional/corerp/corerptest.go
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ type TestStep struct {
SkipKubernetesOutputResourceValidation bool
SkipObjectValidation bool
SkipResourceDeletion bool
SkipLabelValidation bool
}

type CoreRPTest struct {
Expand Down Expand Up @@ -280,7 +281,7 @@ func (ct CoreRPTest) Test(t *testing.T) {
} else {
if step.K8sObjects != nil {
t.Logf("validating creation of objects for %s", step.Executor.GetDescription())
validation.ValidateObjectsRunning(ctx, t, ct.Options.K8sClient, ct.Options.DynamicClient, *step.K8sObjects)
validation.ValidateObjectsRunning(ctx, t, ct.Options.K8sClient, ct.Options.DynamicClient, *step.K8sObjects, step.SkipLabelValidation)
t.Logf("finished validating creation of objects for %s", step.Executor.GetDescription())
}
}
Expand Down
19 changes: 3 additions & 16 deletions test/functional/corerp/resources/mongodb_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ func Test_MongoDBUserSecrets(t *testing.T) {
// the creation of a mongoDB from recipe
// container using the mongoDB link to connect to the mongoDB resource
func Test_MongoDB_Recipe(t *testing.T) {
t.Skipf("Enable this test once test flakiness is fixed. - https://github.com/project-radius/radius/issues/5053")
// template using recipe testdata/recipes/test-recipes/mongodb-recipe-kubernetes.bicep
template := "testdata/corerp-resources-mongodb-recipe.bicep"
name := "corerp-resources-mongodb-recipe"
appNamespace := "corerp-resources-mongodb-recipe-app"
Expand All @@ -140,30 +140,17 @@ func Test_MongoDB_Recipe(t *testing.T) {
Type: validation.ContainersResource,
App: name,
},
{
Name: "mongo-recipe-db",
Type: validation.MongoDatabasesResource,
App: name,
OutputResources: []validation.OutputResourceResponse{
{
Provider: resourcemodel.ProviderAzure,
LocalID: rpv1.LocalIDAzureCosmosAccount,
},
{
Provider: resourcemodel.ProviderAzure,
LocalID: rpv1.LocalIDAzureCosmosDBMongo,
},
},
},
},
},
K8sObjects: &validation.K8sObjectSet{
Namespaces: map[string][]validation.K8sObject{
appNamespace: {
validation.NewK8sPodForResource(name, "mongodb-recipe-app-ctnr"),
validation.NewK8sPodForResource(name, "mongo-recipe-resource"),
},
},
},
SkipLabelValidation: true,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Instead of skipping validation for whole steps, what if we skipped it for individual pods? That seems like a better fit for the scenario.

For example in this test we'd still validate the application container, but not the pod created by the recipe.

},
})

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ resource env 'Applications.Core/environments@2022-03-15-privatepreview' = {
recipes: {
'Applications.Link/mongoDatabases':{
mongodb: {
templatePath: 'radiusdev.azurecr.io/recipes/functionaltest/basic/mongodatabases/azure:1.0'
templatePath: 'radiusdev.azurecr.io/recipes/functionaltest/valuebacked/mongodatabases/kubernetes:1.0'
shalabhms marked this conversation as resolved.
Show resolved Hide resolved
}
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
import kubernetes as kubernetes {
kubeConfig: ''
namespace: context.runtime.kubernetes.namespace
}

param context object

@description('Admin username for the Mongo database. Default is "admin"')
param username string = 'admin'

@description('Admin password for the Mongo database')
@secure()
param password string = newGuid()

resource mongo 'apps/Deployment@v1' = {
metadata: {
name: 'mongo-recipe-resource'
}
spec: {
selector: {
matchLabels: {
app: 'mongo'
resource: context.resource.name
}
}
template: {
metadata: {
labels: {
app: 'mongo'
resource: context.resource.name
}
}
spec: {
containers: [
{
name: 'mongo'
image: 'mongo:4.2'
ports: [
{
containerPort: 27017
}
]
env: [
{
name: 'MONGO_INITDB_ROOT_USERNAME'
value: username
}
{
name: 'MONGO_INITDB_ROOT_PASSWORD'
value: password
}
]
}
]
}
}
}
}

resource svc 'core/Service@v1' = {
metadata: {
name: 'mongo-recipe-svc'
labels: {
name: 'mongo-recipe-svc'
}
}
spec: {
type: 'ClusterIP'
selector: {
app: 'mongo'
resource: context.resource.name
}
ports: [
{
port: 27017
}
]
}
}

output result object = {
// This workaround is needed because the deployment engine omits Kubernetes resources from its output.
//
// Once this gap is addressed, users won't need to do this.
resources: [
'/planes/kubernetes/local/namespaces/${svc.metadata.namespace}/providers/core/Service/${svc.metadata.name}'
'/planes/kubernetes/local/namespaces/${mongo.metadata.namespace}/providers/apps/Deployment/${mongo.metadata.name}'
]
values: {
host: '${svc.metadata.name}.${svc.metadata.namespace}.svc.cluster.local'
port: 27017

}
secrets: {
connectionString: 'mongodb://${username}:${password}@${svc.metadata.name}.${svc.metadata.namespace}.svc.cluster.local:27017'
username: username
password: password
}
}
7 changes: 4 additions & 3 deletions test/validation/k8s.go
Original file line number Diff line number Diff line change
Expand Up @@ -267,7 +267,7 @@ func streamLogFile(ctx context.Context, podClient v1.PodInterface, pod corev1.Po
}

// ValidateObjectsRunning validates the namespaces and objects specified in each namespace are running
func ValidateObjectsRunning(ctx context.Context, t *testing.T, k8s *kubernetes.Clientset, dynamic dynamic.Interface, expected K8sObjectSet) {
func ValidateObjectsRunning(ctx context.Context, t *testing.T, k8s *kubernetes.Clientset, dynamic dynamic.Interface, expected K8sObjectSet, skipLabelValidation bool) {
restMapper := restmapper.NewDeferredDiscoveryRESTMapper(memory.NewMemCacheClient(k8s.DiscoveryClient))
for namespace, expectedObjects := range expected.Namespaces {
log.Printf("validating objects in namespace %v", namespace)
Expand Down Expand Up @@ -298,8 +298,9 @@ func ValidateObjectsRunning(ctx context.Context, t *testing.T, k8s *kubernetes.C
deployedResources, err = dynamic.Resource(mapping.Resource).List(ctx, metav1.ListOptions{})
}
assert.NoErrorf(t, err, "could not list deployed resources of type %s in namespace %s", resourceGVR.GroupResource(), namespace)

validated = validated && matchesActualLabels(expectedInNamespace, deployedResources.Items)
if !skipLabelValidation {
validated = validated && matchesActualLabels(expectedInNamespace, deployedResources.Items)
}
}
case <-ctx.Done():
assert.Fail(t, "timed out after waiting for services to be created")
Expand Down