Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add an override for generating long form tests #10162

Merged
merged 1 commit into from
Mar 13, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
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
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