-
Notifications
You must be signed in to change notification settings - Fork 17
Expand file tree
/
Copy pathcrds_test.go
More file actions
159 lines (136 loc) · 5.77 KB
/
crds_test.go
File metadata and controls
159 lines (136 loc) · 5.77 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
// Copyright 2016-2020, 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.
package tests
import (
"fmt"
"io/fs"
"os"
"os/exec"
"path/filepath"
"testing"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
var languages = []string{"dotnet", "go", "nodejs", "python"}
const gkeManagedCertsUrl = "https://raw.githubusercontent.com/GoogleCloudPlatform/gke-managed-certs/master/deploy/managedcertificates-crd.yaml"
// execCrd2Pulumi runs the crd2pulumi binary in a temporary directory
func execCrd2Pulumi(t *testing.T, lang, path string, additionalValidation func(t *testing.T, path string)) {
tmpdir, err := os.MkdirTemp("", "crd2pulumi_test")
assert.Nil(t, err, "expected to create a temp dir for the CRD output")
t.Cleanup(func() {
t.Logf("removing temp dir %q for %s test", tmpdir, lang)
os.RemoveAll(tmpdir)
})
langFlag := fmt.Sprintf("--%sPath", lang) // e.g. --dotnetPath
binaryPath, err := filepath.Abs("../bin/crd2pulumi")
if err != nil {
t.Fatalf("unable to create absolute path to binary: %s", err)
}
t.Logf("%s %s=%s %s: running", binaryPath, langFlag, tmpdir, path)
crdCmd := exec.Command(binaryPath, langFlag, tmpdir, "--force", path)
crdOut, err := crdCmd.CombinedOutput()
t.Logf("%s %s=%s %s: output=\n%s", binaryPath, langFlag, tmpdir, path, crdOut)
if err != nil {
t.Fatalf("expected crd2pulumi for '%s=%s %s' to succeed", langFlag, tmpdir, path)
}
// Run additional validation if provided.
if additionalValidation != nil {
additionalValidation(t, tmpdir)
}
}
// TestCRDsFromFile enumerates all CRD YAML files, and generates them in each language.
func TestCRDsFromFile(t *testing.T) {
filepath.WalkDir("crds", func(path string, d fs.DirEntry, err error) error {
if !d.IsDir() && (filepath.Ext(path) == ".yml" || filepath.Ext(path) == ".yaml") {
for _, lang := range languages {
lang := lang
name := fmt.Sprintf("%s-%s", lang, filepath.Base(path))
t.Run(name, func(t *testing.T) {
t.Parallel()
execCrd2Pulumi(t, lang, path, nil)
})
}
}
return nil
})
}
// TestCRDsFromUrl pulls the CRD YAML file from a URL and generates it in each language
func TestCRDsFromUrl(t *testing.T) {
for _, lang := range languages {
lang := lang
t.Run(lang, func(t *testing.T) {
t.Parallel()
execCrd2Pulumi(t, lang, gkeManagedCertsUrl, nil)
})
}
}
// TestCRDsWithUnderscore tests that CRDs with underscores field names are camelCased for the
// generated types. Currently this test only runs for Python, and we're hardcoding the field name
// detection logic in the test for simplicity. This is brittle and we should improve this in the
// future.
// TODO: properly detect field names in the generated Python code instead of grep'ing for them.
func TestCRDsWithUnderscore(t *testing.T) {
// Callback function to run additional validation on the generated Python code after running
// crd2pulumi.
validateUnderscore := func(t *testing.T, path string) {
// Ensure inputs are camelCased.
filename := filepath.Join(path, "pulumi_crds", "juice", "v1alpha1", "_inputs.py")
t.Logf("validating underscored field names in %s", filename)
pythonInputs, err := os.ReadFile(filename)
if err != nil {
t.Fatalf("expected to read generated Python code: %s", err)
}
assert.Contains(t, string(pythonInputs), "NetworkPolicySpecAppsIncomingArgs", "expected to find camelCased field name in generated Python code")
assert.NotContains(t, string(pythonInputs), "NetworkPolicySpecApps_incomingArgs", "expected to not find underscored field name in generated Python code")
// Ensure outputs are camelCased.
filename = filepath.Join(path, "pulumi_crds", "juice", "v1alpha1", "outputs.py")
t.Logf("validating underscored field names in %s", filename)
pythonInputs, err = os.ReadFile(filename)
if err != nil {
t.Fatalf("expected to read generated Python code: %s", err)
}
assert.Contains(t, string(pythonInputs), "NetworkPolicySpecAppsIncoming", "expected to find camelCased field name in generated Python code")
assert.NotContains(t, string(pythonInputs), "NetworkPolicySpecApps_incoming", "expected to not find underscored field name in generated Python code")
}
execCrd2Pulumi(t, "python", "crds/underscored-types/networkpolicy.yaml", validateUnderscore)
}
func TestKubernetesVersionNodeJs(t *testing.T) {
validateVersion := func(t *testing.T, path string) {
// enter and build the generated package
withDir(t, path, func() {
require.NoError(t, exec.Command("npm", "i").Run())
require.NoError(t, exec.Command("npm", "run", "build").Run())
// extract the version returned by a resource
appendFile(t, "bin/index.js", "\nconsole.log((new k8sversion.test.TestResource('test')).__version)")
version, err := exec.Command("node", "bin/index.js").Output()
require.NoError(t, err)
assert.Equal(t, "4.5.5\n", string(version))
})
}
execCrd2Pulumi(t, "nodejs", "crds/k8sversion/mock_crd.yaml", validateVersion)
}
func withDir(t *testing.T, dir string, f func()) {
pwd, err := os.Getwd()
require.NoError(t, err)
defer os.Chdir(pwd)
require.NoError(t, os.Chdir(dir))
f()
}
func appendFile(t *testing.T, filename, content string) {
// extract the version returned by a resource
f, err := os.OpenFile(filename, os.O_APPEND|os.O_WRONLY, 0600)
require.NoError(t, err)
defer f.Close()
_, err = f.WriteString(content)
}