Skip to content

Commit

Permalink
Add an override for generating long form tests (GoogleCloudPlatform#1…
Browse files Browse the repository at this point in the history
  • Loading branch information
trodge authored and balanaguharsha committed May 2, 2024
1 parent 28dd458 commit ba38c76
Show file tree
Hide file tree
Showing 6 changed files with 57 additions and 14 deletions.
1 change: 1 addition & 0 deletions tpgtools/override.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ const (
TerraformProductName = "CUSTOM_TERRAFORM_PRODUCT_NAME"
CustomTimeout = "CUSTOM_TIMEOUT"
StateUpgrade = "STATE_UPGRADE"
GenerateLongFormTests = "GENERATE_LONG_FORM_TESTS"
)

// Field-level Overrides
Expand Down
20 changes: 14 additions & 6 deletions tpgtools/property.go
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,11 @@ type Property struct {
// the field being unset and being set to false.
EnumBool bool

// Whether this field is only used as a url parameter
Parameter bool
// Whether this field has long form behavior in the DCL
HasLongForm bool

// An IdentityGetter is a function to retrieve the value of an "identity" field
// from state. Identity fields will sometimes allow retrieval from multiple
// fields or from the user's environment variables.
Expand Down Expand Up @@ -210,7 +215,7 @@ func (t Type) IsSet() bool {
}

// Complex map is for maps of string --> object that are supported in DCL but
// not in Terraform. We handle this by adding a field in the Terraform schema
// not in Terraform. We handle this by adding a field in the Terraform schema
// for the key in the map. This must be added via a COMPLEX_MAP_KEY_NAME
// override
func (t Type) IsComplexMap() bool {
Expand Down Expand Up @@ -618,6 +623,9 @@ func createPropertiesFromSchema(schema *openapi.Schema, typeFetcher *TypeFetcher
}
}

p.Parameter, _ = v.Extension["x-dcl-parameter"].(bool)
p.HasLongForm, _ = v.Extension["x-dcl-has-long-form"].(bool)

// Handle object properties
if len(v.Properties) > 0 {
props, err := createPropertiesFromSchema(v, typeFetcher, overrides, resource, &p, location)
Expand Down Expand Up @@ -691,11 +699,11 @@ func createPropertiesFromSchema(schema *openapi.Schema, typeFetcher *TypeFetcher
return nil, fmt.Errorf("failed to find complex map key name for map named: %s", p.Name())
}
keyProp := Property{
title: cm.KeyName,
Type: Type{&openapi.Schema{Type: "string"}},
resource: resource,
parent: &p,
Required: true,
title: cm.KeyName,
Type: Type{&openapi.Schema{Type: "string"}},
resource: resource,
parent: &p,
Required: true,
Description: "The name for the key in the map for which this object is mapped to in the API",
}
props = append([]Property{keyProp}, props...)
Expand Down
23 changes: 23 additions & 0 deletions tpgtools/resource.go
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,9 @@ type Resource struct {
SchemaVersion int
// The schema versions from 0 to the current schema version
SchemaVersions []int

// Whether to generate long form versions of resource sample tests
GenerateLongFormTests bool
}

type Link struct {
Expand Down Expand Up @@ -711,6 +714,10 @@ func createResource(schema *openapi.Schema, info *openapi.Info, typeFetcher *Typ
}
}

if overrides.ResourceOverride(GenerateLongFormTests, location) {
res.GenerateLongFormTests = true
}

res.Samples = res.loadSamples()

return &res, nil
Expand Down Expand Up @@ -977,7 +984,23 @@ func (r *Resource) loadDCLSamples() []Sample {
sample.IgnoreRead = append(sample.IgnoreRead, "annotations")
}

if r.GenerateLongFormTests {
longFormSample := sample
longFormSample.LongForm = true
var longFormDependencies []Dependency
mainResourceLongForm := longFormSample.generateSampleDependencyWithName(primaryResource, "primary")
longFormDependencies = append(longFormDependencies, mainResourceLongForm)
for _, dFileName := range longFormSample.DependencyFileNames {
longFormDependency := sample.generateSampleDependency(dFileName)
longFormDependencies = append(longFormDependencies, longFormDependency)
}
longFormSample.DependencyList = longFormDependencies
longFormSample.TestSlug += "LongForm"
samples = append(samples, longFormSample)
}

samples = append(samples, sample)

}

return samples
Expand Down
9 changes: 6 additions & 3 deletions tpgtools/sample.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,9 @@ type Sample struct {
// in the testcase. (if the test doesn't have a ga version of the test)
HasGAEquivalent bool

// LongForm is whether this sample is a copy with long form fields expanded to include `/`
LongForm bool

// SamplesPath is the path to the directory where the original sample data is stored
SamplesPath Filepath

Expand Down Expand Up @@ -165,7 +168,7 @@ func findDCLReferencePackage(product SnakeCaseProductName) (DCLPackageName, erro
}

// BuildDependency produces a Dependency using a file and filename
func BuildDependency(fileName string, product SnakeCaseProductName, localname, version string, hasGAEquivalent bool, b []byte) (*Dependency, error) {
func BuildDependency(fileName string, product SnakeCaseProductName, localname, version string, hasGAEquivalent, makeLongForm bool, b []byte) (*Dependency, error) {
// Miscellaneous name rather than "resource name" because this is the name in the sample json file - which might not match the TF name!
// we have to account for that.
var resourceName miscellaneousNameSnakeCase
Expand Down Expand Up @@ -194,7 +197,7 @@ func BuildDependency(fileName string, product SnakeCaseProductName, localname, v
return nil, fmt.Errorf("Error generating sample dependency reference %s: %s", fileName, err)
}

block, err := ConvertSampleJSONToHCL(packageName, resourceName, version, hasGAEquivalent, b)
block, err := ConvertSampleJSONToHCL(packageName, resourceName, version, hasGAEquivalent, makeLongForm, b)
if err != nil {
glog.Errorf("failed to convert %q", fileName)
return nil, fmt.Errorf("Error generating sample dependency %s: %s", fileName, err)
Expand Down Expand Up @@ -223,7 +226,7 @@ func (s *Sample) generateSampleDependencyWithName(fileName, localname string) De
dependencyBytes, err := ioutil.ReadFile(path.Join(string(s.SamplesPath), fileName))
version := s.resourceReference.versionMetadata.V
product := s.resourceReference.productMetadata.ProductName
d, err := BuildDependency(fileName, product, localname, version, s.HasGAEquivalent, dependencyBytes)
d, err := BuildDependency(fileName, product, localname, version, s.HasGAEquivalent, s.LongForm, dependencyBytes)
if err != nil {
glog.Exit(err)
}
Expand Down
2 changes: 1 addition & 1 deletion tpgtools/serialization.go.base
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ func DCLToTerraformReference(product DCLPackageName, resource miscellaneousNameS
return "", fmt.Errorf("unimplemented - did you run `make serialize`?")
}

func ConvertSampleJSONToHCL(product DCLPackageName, resource miscellaneousNameSnakeCase, version string, hasGAEquivalent bool, b []byte) (string, error) {
func ConvertSampleJSONToHCL(product DCLPackageName, resource miscellaneousNameSnakeCase, version string, hasGAEquivalent, makeLongForm bool, b []byte) (string, error) {
return "", fmt.Errorf("unimplemented - did you run `make serialize`?")
}

Expand Down
16 changes: 12 additions & 4 deletions tpgtools/templates/serialization.go.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ func DCLToTerraformReference(product DCLPackageName, resource miscellaneousNameS
}

// ConvertSampleJSONToHCL unmarshals json to an HCL string.
func ConvertSampleJSONToHCL(product DCLPackageName, resource miscellaneousNameSnakeCase, version string, hasGAEquivalent bool, b []byte) (string, error) {
func ConvertSampleJSONToHCL(product DCLPackageName, resource miscellaneousNameSnakeCase, version string, hasGAEquivalent, makeLongForm bool, b []byte) (string, error) {
{{- range $version, $resList := $.Resources }}
{{- if not (eq $version.V "ga") }}
if version == "{{$version.V}}" {
Expand All @@ -86,7 +86,7 @@ func ConvertSampleJSONToHCL(product DCLPackageName, resource miscellaneousNameSn
{{- if $res.CustomSerializer }}
return {{$res.CustomSerializer}}(*r, hasGAEquivalent)
{{- else }}
return {{$res.TitleCaseFullName}}{{$version.SerializationSuffix}}AsHCL(*r, hasGAEquivalent)
return {{$res.TitleCaseFullName}}{{$version.SerializationSuffix}}AsHCL(*r, hasGAEquivalent, makeLongForm)
{{- end }}
{{- end }}
}
Expand All @@ -103,7 +103,7 @@ func ConvertSampleJSONToHCL(product DCLPackageName, resource miscellaneousNameSn
{{- if $res.CustomSerializer }}
return {{$res.CustomSerializer}}(*r, hasGAEquivalent)
{{- else }}
return {{$res.TitleCaseFullName}}{{$version.SerializationSuffix}}AsHCL(*r, hasGAEquivalent)
return {{$res.TitleCaseFullName}}{{$version.SerializationSuffix}}AsHCL(*r, hasGAEquivalent, makeLongForm)
{{- end }}
{{- end }}
default:
Expand All @@ -123,7 +123,7 @@ func ConvertSampleJSONToHCL(product DCLPackageName, resource miscellaneousNameSn
// the crucial point is that `terraform import; terraform apply` will not produce
// any changes. We do not validate that the resource specified will pass terraform
// validation unless is an object returned from the API after an Apply.
func {{ $res.TitleCaseFullName }}{{$version.SerializationSuffix}}AsHCL(r {{$res.Package}}{{$version.SerializationSuffix}}.{{$res.DCLStructName}}, hasGAEquivalent bool) (string, error) {
func {{ $res.TitleCaseFullName }}{{$version.SerializationSuffix}}AsHCL(r {{$res.Package}}{{$version.SerializationSuffix}}.{{$res.DCLStructName}}, hasGAEquivalent, makeLongForm bool) (string, error) {
outputConfig := "resource \"{{$res.TerraformName}}\" \"output\" {\n"
{{- range $field := $res.Properties}}
{{- if $field.ShouldShowUpInSamples }}
Expand All @@ -138,7 +138,15 @@ func {{ $res.TitleCaseFullName }}{{$version.SerializationSuffix}}AsHCL(r {{$res.
}
{{- else }}
if r.{{$field.PackageName}} != nil {
{{- if or $field.Parameter $field.HasLongForm }}
if makeLongForm {
outputConfig += fmt.Sprintf("\t{{$field.Name}} = %#v\n", "long/form/" + *r.{{$field.PackageName}})
} else {
outputConfig += fmt.Sprintf("\t{{$field.Name}} = %#v\n", *r.{{$field.PackageName}})
}
{{- else }}
outputConfig += fmt.Sprintf("\t{{$field.Name}} = %#v\n", *r.{{$field.PackageName}})
{{- end }}
}
{{- end}}
{{- else if $field.Type.IsObject }}
Expand Down

0 comments on commit ba38c76

Please sign in to comment.