1515package tests
1616
1717import (
18+ "fmt"
1819 "io/fs"
1920 "io/ioutil"
2021 "os"
@@ -30,28 +31,44 @@ var languages = []string{"dotnet", "go", "nodejs", "python"}
3031const gkeManagedCertsUrl = "https://raw.githubusercontent.com/GoogleCloudPlatform/gke-managed-certs/master/deploy/managedcertificates-crd.yaml"
3132
3233// execCrd2Pulumi runs the crd2pulumi binary in a temporary directory
33- func execCrd2Pulumi (t * testing.T , lang , path string ) {
34- tmpdir , err := ioutil .TempDir ("" , "" )
34+ func execCrd2Pulumi (t * testing.T , lang , path string , additionalValidation func ( t * testing. T , path string ) ) {
35+ tmpdir , err := ioutil .TempDir ("" , "crd2pulumi_test " )
3536 assert .Nil (t , err , "expected to create a temp dir for the CRD output" )
36- defer os .RemoveAll (tmpdir )
37- langFlag := "--" + lang + "Path"
37+ t .Cleanup (func () {
38+ t .Logf ("removing temp dir %q for %s test" , tmpdir , lang )
39+ os .RemoveAll (tmpdir )
40+ })
41+ langFlag := fmt .Sprintf ("--%sPath" , lang ) // e.g. --dotnetPath
3842 binaryPath , err := filepath .Abs ("../bin/crd2pulumi" )
3943 if err != nil {
40- panic ( err )
44+ t . Fatalf ( "unable to create absolute path to binary: %s" , err )
4145 }
46+
4247 t .Logf ("%s %s=%s %s: running" , binaryPath , langFlag , tmpdir , path )
4348 crdCmd := exec .Command (binaryPath , langFlag , tmpdir , "--force" , path )
4449 crdOut , err := crdCmd .CombinedOutput ()
4550 t .Logf ("%s %s=%s %s: output=\n %s" , binaryPath , langFlag , tmpdir , path , crdOut )
46- assert .Nil (t , err , "expected crd2pulumi for '%s=%s %s' to succeed" , langFlag , tmpdir , path )
51+ if err != nil {
52+ t .Fatalf ("expected crd2pulumi for '%s=%s %s' to succeed" , langFlag , tmpdir , path )
53+ }
54+
55+ // Run additional validation if provided.
56+ if additionalValidation != nil {
57+ additionalValidation (t , tmpdir )
58+ }
4759}
4860
4961// TestCRDsFromFile enumerates all CRD YAML files, and generates them in each language.
5062func TestCRDsFromFile (t * testing.T ) {
5163 filepath .WalkDir ("crds" , func (path string , d fs.DirEntry , err error ) error {
5264 if ! d .IsDir () && (filepath .Ext (path ) == ".yml" || filepath .Ext (path ) == ".yaml" ) {
5365 for _ , lang := range languages {
54- execCrd2Pulumi (t , lang , path )
66+ lang := lang
67+ name := fmt .Sprintf ("%s-%s" , lang , filepath .Base (path ))
68+ t .Run (name , func (t * testing.T ) {
69+ t .Parallel ()
70+ execCrd2Pulumi (t , lang , path , nil )
71+ })
5572 }
5673 }
5774 return nil
@@ -61,6 +78,43 @@ func TestCRDsFromFile(t *testing.T) {
6178// TestCRDsFromUrl pulls the CRD YAML file from a URL and generates it in each language
6279func TestCRDsFromUrl (t * testing.T ) {
6380 for _ , lang := range languages {
64- execCrd2Pulumi (t , lang , gkeManagedCertsUrl )
81+ lang := lang
82+ t .Run (lang , func (t * testing.T ) {
83+ t .Parallel ()
84+ execCrd2Pulumi (t , lang , gkeManagedCertsUrl , nil )
85+ })
6586 }
6687}
88+
89+ // TestCRDsWithUnderscore tests that CRDs with underscores field names are camelCased for the
90+ // generated types. Currently this test only runs for Python, and we're hardcoding the field name
91+ // detection logic in the test for simplicity. This is brittle and we should improve this in the
92+ // future.
93+ // TODO: properly detect field names in the generated Python code instead of grep'ing for them.
94+ func TestCRDsWithUnderscore (t * testing.T ) {
95+ // Callback function to run additional validation on the generated Python code after running
96+ // crd2pulumi.
97+ validateUnderscore := func (t * testing.T , path string ) {
98+ // Ensure inputs are camelCased.
99+ filename := filepath .Join (path , "pulumi_crds" , "juice" , "v1alpha1" , "_inputs.py" )
100+ t .Logf ("validating underscored field names in %s" , filename )
101+ pythonInputs , err := ioutil .ReadFile (filename )
102+ if err != nil {
103+ t .Fatalf ("expected to read generated Python code: %s" , err )
104+ }
105+ assert .Contains (t , string (pythonInputs ), "NetworkPolicySpecAppsIncomingArgs" , "expected to find camelCased field name in generated Python code" )
106+ assert .NotContains (t , string (pythonInputs ), "NetworkPolicySpecApps_incomingArgs" , "expected to not find underscored field name in generated Python code" )
107+
108+ // Ensure outputs are camelCased.
109+ filename = filepath .Join (path , "pulumi_crds" , "juice" , "v1alpha1" , "outputs.py" )
110+ t .Logf ("validating underscored field names in %s" , filename )
111+ pythonInputs , err = ioutil .ReadFile (filename )
112+ if err != nil {
113+ t .Fatalf ("expected to read generated Python code: %s" , err )
114+ }
115+ assert .Contains (t , string (pythonInputs ), "NetworkPolicySpecAppsIncoming" , "expected to find camelCased field name in generated Python code" )
116+ assert .NotContains (t , string (pythonInputs ), "NetworkPolicySpecApps_incoming" , "expected to not find underscored field name in generated Python code" )
117+ }
118+
119+ execCrd2Pulumi (t , "python" , "crds/underscored-types/networkpolicy.yaml" , validateUnderscore )
120+ }
0 commit comments