Skip to content

Commit

Permalink
Tests
Browse files Browse the repository at this point in the history
Tests
  • Loading branch information
lblackstone committed Jul 8, 2022
1 parent f188eb6 commit 4e2ba41
Show file tree
Hide file tree
Showing 9 changed files with 421 additions and 134 deletions.
3 changes: 0 additions & 3 deletions tests/sdk/nodejs/dry-run/step1/Pulumi.yaml

This file was deleted.

52 changes: 0 additions & 52 deletions tests/sdk/nodejs/dry-run/step1/index.ts

This file was deleted.

52 changes: 0 additions & 52 deletions tests/sdk/nodejs/dry-run/step2/index.ts

This file was deleted.

91 changes: 68 additions & 23 deletions tests/sdk/nodejs/nodejs_test.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright 2016-2021, Pulumi Corporation.
// Copyright 2016-2022, Pulumi Corporation.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -34,6 +34,7 @@ import (
"github.com/pulumi/pulumi/sdk/v3/go/common/resource"
"github.com/pulumi/pulumi/sdk/v3/go/common/tokens"
"github.com/stretchr/testify/assert"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
)

var baseOptions = &integration.ProgramTestOptions{
Expand Down Expand Up @@ -466,28 +467,6 @@ func TestDeploymentRollout(t *testing.T) {
integration.ProgramTest(t, &test)
}

func TestDryRun(t *testing.T) {
test := baseOptions.With(integration.ProgramTestOptions{
Dir: filepath.Join("dry-run", "step1"),
EditDirs: []integration.EditDir{
{
Dir: filepath.Join("dry-run", "step2"),
Additive: true,
},
},
ExtraRuntimeValidation: func(t *testing.T, stackInfo integration.RuntimeValidationStackInfo) {
for _, res := range stackInfo.Deployment.Resources {
if res.Type == "kubernetes:apps/v1:Deployment" {
annotations, _ := openapi.Pluck(res.Outputs, "metadata", "annotations")
assert.NotEmpty(t, annotations)
assert.NotContains(t, annotations, "kubectl.kubernetes.io/last-applied-configuration")
}
}
},
})
integration.ProgramTest(t, &test)
}

func TestEmptyArray(t *testing.T) {
test := baseOptions.With(integration.ProgramTestOptions{
Dir: filepath.Join("empty-array", "step1"),
Expand Down Expand Up @@ -1038,6 +1017,72 @@ func TestSecrets(t *testing.T) {
integration.ProgramTest(t, &test)
}

func TestServerSideApply(t *testing.T) {
test := baseOptions.With(integration.ProgramTestOptions{
Dir: filepath.Join("server-side-apply", "step1"),
ExpectRefreshChanges: true,
OrderedConfig: []integration.ConfigValue{
{
Key: "pulumi:disable-default-providers[0]",
Value: "kubernetes",
Path: true,
},
},
ExtraRuntimeValidation: func(t *testing.T, stackInfo integration.RuntimeValidationStackInfo) {
// Validate patched Namespace
nsPatched := stackInfo.Outputs["nsPatched"].(map[string]interface{})
fooV, ok, err := unstructured.NestedString(nsPatched, "metadata", "labels", "foo")
assert.True(t, ok)
assert.NoError(t, err)
assert.Equal(t, "foo", fooV)

// Validate patched CustomResource
crPatched := stackInfo.Outputs["crPatched"].(map[string]interface{})
fooV, ok, err = unstructured.NestedString(crPatched, "metadata", "labels", "foo")
assert.True(t, ok)
assert.NoError(t, err)
assert.Equal(t, "foo", fooV)

for _, res := range stackInfo.Deployment.Resources {
// Validate that the last-applied-configuration annotation is not present on SSA resources.
annotations, ok, err := unstructured.NestedStringMap(res.Outputs, "metadata", "labels")
assert.NoError(t, err)
if ok {
assert.NotContains(t, annotations, "kubectl.kubernetes.io/last-applied-configuration")
}

// Validate that the managed-by label is not present on SSA resources.
labels, ok, err := unstructured.NestedStringMap(res.Outputs, "metadata", "labels")
assert.NoError(t, err)
if ok {
assert.NotContains(t, labels, "app.kubernetes.io/managed-by")
}
}
},
EditDirs: []integration.EditDir{
{
Dir: filepath.Join("server-side-apply", "step2"),
Additive: true,
ExtraRuntimeValidation: func(t *testing.T, stackInfo integration.RuntimeValidationStackInfo) {
// Validate patched Deployment
deploymentPatched := stackInfo.Outputs["deploymentPatched"].(map[string]interface{})
containersV, ok, err := unstructured.NestedSlice(
deploymentPatched, "spec", "template", "spec", "containers")
assert.True(t, ok)
assert.NoError(t, err)
assert.Len(t, containersV, 1)
limitsV, ok, err := unstructured.NestedMap(
containersV[0].(map[string]interface{}), "resources", "limits")
assert.True(t, ok)
assert.NoError(t, err)
assert.Contains(t, limitsV, "memory")
},
},
},
})
integration.ProgramTest(t, &test)
}

func TestYAMLURL(t *testing.T) {
test := baseOptions.With(integration.ProgramTestOptions{
Dir: filepath.Join("yaml-url", "step1"),
Expand Down
3 changes: 3 additions & 0 deletions tests/sdk/nodejs/server-side-apply/step1/Pulumi.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
name: server-side-apply-tests
description: Tests Server-side Apply support
runtime: nodejs
160 changes: 160 additions & 0 deletions tests/sdk/nodejs/server-side-apply/step1/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,160 @@
// Copyright 2016-2022, Pulumi Corporation.
//
// 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.

import * as k8s from "@pulumi/kubernetes";
import * as random from "@pulumi/random";

// This test creates a Provider with `enableServerSideApply` enabled. The following scenarios are tested:
// 1. Patch a Namespace resource with fully-specified configuration.
// 2. Patch a CustomResource.
// 3. Upsert a Deployment resource that already exists.
// 4. Patch the Deployment with a partially-specified configuration.
// 5. Replace a statically-named ConfigMap resource by changing the data on a subsequent update.

// Create provider with SSA enabled.
const provider = new k8s.Provider("k8s", {enableServerSideApply: true});

// Create a randomly-named Namespace.
const nsName = new random.RandomPet("test");
const ns = new k8s.core.v1.Namespace("test", {
metadata: {
name: nsName.id
}
}, {provider});

// Patch the Namespace with additional labels.
export const nsPatched = new k8s.core.v1.NamespacePatch("test", {
metadata: {
labels: {
foo: "foo",
},
name: ns.metadata.name,
}
}, {provider});

const crd = new k8s.apiextensions.v1.CustomResourceDefinition("crontab", {
metadata: { name: "crontabs.stable.example.com" },
spec: {
group: "stable.example.com",
versions: [
{
name: "v1",
served: true,
storage: true,
schema: {
openAPIV3Schema: {
type: "object",
properties: {
spec: {
type: "object",
properties: {
cronSpec: {
type: "string"
},
image: {
type: "string"
},
replicas: {
type: "integer"
}
}
}
}
}
}
},
],
scope: "Namespaced",
names: {
plural: "crontabs",
singular: "crontab",
kind: "CronTab",
shortNames: ["ct"]
},
}
}, {provider});

// Create a k8s CustomResource of type "CronTab".
const cr = new k8s.apiextensions.CustomResource("my-new-cron-object",
{
apiVersion: "stable.example.com/v1",
kind: "CronTab",
metadata: {
name: "my-new-cron-object",
namespace: ns.metadata.name,
},
spec: { cronSpec: "* * * * */6", image: "my-awesome-cron-image" }
}, {provider, dependsOn: [crd]});

// Patch the CronTab CustomResource to add a label.
export const crPatched = new k8s.apiextensions.CustomResourcePatch("label-cr",
{
apiVersion: "stable.example.com/v1",
kind: "CronTab",
metadata: {
labels: {
foo: "foo",
},
name: "my-new-cron-object",
namespace: ns.metadata.name,
},
}, {provider, dependsOn: [cr]});

const appLabels = { app: "nginx" };
const deployment = new k8s.apps.v1.Deployment("nginx", {
metadata: {
namespace: ns.metadata.name,
},
spec: {
selector: { matchLabels: appLabels },
template: {
metadata: { labels: appLabels },
spec: {
containers: [{
name: "nginx",
image: "nginx:1.16",
}],
}
}
}
}, { provider });

// Upsert an identical Deployment to the one we just created.
const upsert = new k8s.apps.v1.Deployment("nginx-upsert", {
metadata: {
name: deployment.metadata.name,
namespace: ns.metadata.name,
},
spec: {
selector: { matchLabels: appLabels },
template: {
metadata: { labels: appLabels },
spec: {
containers: [{
name: "nginx",
image: "nginx:1.16",
}],
}
}
}
}, { provider, dependsOn: [deployment], retainOnDelete: true });

// TODO: Fix SSA replacement and uncomment
// new k8s.core.v1.ConfigMap("test", {
// metadata: {
// name: "foo", // Specify the name to force resource replacement on change.
// namespace: ns.metadata.name,
// },
// data: {foo: "baz"}, // <-- Updated value
// }, {provider});
Loading

0 comments on commit 4e2ba41

Please sign in to comment.