Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
Prev Previous commit
Next Next commit
Add tests for camelCased type generation
  • Loading branch information
rquitales committed May 25, 2023
commit f2d468942162305dda16594df340076aa83b5be1
123 changes: 123 additions & 0 deletions tests/crds/underscored-types/networkpolicy.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
# Ensure generated nested types are not underscored.
# See https://github.com/pulumi/crd2pulumi/issues/107
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
annotations:
myinfo: abcdefghijkl
generation: 4
labels:
creator.ac.com: myinfo
name: networkpolicies.juice.box.com
spec:
conversion:
strategy: None
group: juice.box.com
names:
kind: NetworkPolicy
listKind: NetworkPolicyList
plural: networkpolicies
shortNames:
- anp
- anps
singular: networkpolicy
preserveUnknownFields: true
scope: Namespaced
versions:
- name: v1alpha1
schema:
openAPIV3Schema:
properties:
spec:
type: object
description: NetworkPolicySpec is a specification of the network
entitlements for a pod.
properties:
apps_incoming:
description: apps_incoming specifies which applications are permitted
to establish a TCP connection to a POD.
items:
properties:
app:
pattern: ^(__kubernetes__|plb\.juice-plb\.juice-prod|((([A-Za-z0-9]+[-A-Za-z0-9]?)*[A-Za-z0-9])\.){2}(kk|kube))$
type: string
cluster:
description: cluster that this policy applies to. Defaults to
the local cluster. Setting cluster to 'ALL' will match all
clusters
type: string
required:
- app
type: object
type: array
apps_outgoing:
description: apps_outgoing specifies what applications a pod may attempt
to make TCP connections to.
items:
properties:
app:
pattern: ^(__kubernetes__|plb\.juice-plb\.juice-prod|((([A-Za-z0-9]+[-A-Za-z0-9]?)*[A-Za-z0-9])\.){2}(kk|kube))$
type: string
cluster:
description: cluster that this policy applies to. Defaults to
the local cluster. Setting cluster to 'ALL' will match all
clusters
type: string
required:
- app
type: object
type: array
namespaces_incoming:
description: namespaces_incoming specifies which kubernetes namespace
are permitted to establish incoming TCP sessions.
items:
properties:
cluster:
description: cluster that this policy applies to. Defaults to
the local cluster. Setting cluster to 'ALL' will match all
clusters
type: string
namespace:
pattern: ^(((([A-Za-z0-9]+[-A-Za-z0-9]?)*[A-Za-z0-9])\.)(kk|kube))$
type: string
required:
- namespace
type: object
type: array
namespaces_outgoing:
description: namespaces_outgoing specifies which kubernetes namespace
are permitted to establish outgoing TCP sessions.
items:
properties:
cluster:
description: cluster that this policy applies to. Defaults to
the local cluster. Setting cluster to 'ALL' will match all
clusters
type: string
namespace:
pattern: ^(((([A-Za-z0-9]+[-A-Za-z0-9]?)*[A-Za-z0-9])\.)(kk|kube))$
type: string
required:
- namespace
type: object
type: array
selector:
additionalProperties:
type: string
description: selector is a set of label selectors
type: object
required:
- selector
served: true
storage: true
status:
acceptedNames:
kind: NetworkPolicy
listKind: NetworkPolicyList
plural: networkpolicies
shortNames:
- anp
- anps
singular: networkpolicy
storedVersions:
- v1alpha1
48 changes: 44 additions & 4 deletions tests/crds_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ 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) {
func execCrd2Pulumi(t *testing.T, lang, path string, additionalValidation func(t *testing.T, path string)) {
tmpdir, err := ioutil.TempDir("", "crd2pulumi_test")
assert.Nil(t, err, "expected to create a temp dir for the CRD output")
t.Cleanup(func() {
Expand All @@ -48,7 +48,14 @@ func execCrd2Pulumi(t *testing.T, lang, path string) {
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)
assert.Nil(t, err, "expected crd2pulumi for '%s=%s %s' to succeed", langFlag, tmpdir, path)
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.
Expand All @@ -60,7 +67,7 @@ func TestCRDsFromFile(t *testing.T) {
name := fmt.Sprintf("%s-%s", lang, filepath.Base(path))
t.Run(name, func(t *testing.T) {
t.Parallel()
execCrd2Pulumi(t, lang, path)
execCrd2Pulumi(t, lang, path, nil)
})
}
}
Expand All @@ -74,7 +81,40 @@ func TestCRDsFromUrl(t *testing.T) {
lang := lang
t.Run(lang, func(t *testing.T) {
t.Parallel()
execCrd2Pulumi(t, lang, gkeManagedCertsUrl)
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 := ioutil.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 = ioutil.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)
}