Repository: kubernetes-sigs/controller-tools

Issue:
Applyconfiguration testdata doesn't build
Trying to build the applyconfiguration testdata in pkg/applyconfiguration/testdata/cronjob/api/v1/applyconfiguration/api/v1 fails with the following error:

```
api/v1/cronjobspec.go:74:2: undefined: unexportedStructApplyConfiguration
api/v1/cronjobspec.go:816:75: cannot use *values[i] (variable of struct type intstr.IntOrString) as *intstr.IntOrString value in argument to append
```

These look like bugs in the upstream AC generation, however we should get these fixed and test that this can be built.

/kind bug



Discussion:
@sbueringer: Yeah, would be great to have some sort of unit test that uses the generated apply configurations (at the very least to ensure they compile)

Solution patch:
diff --git a/test.sh b/test.sh
index df668fd5..c91647d1 100755
--- a/test.sh
+++ b/test.sh
@@ -119,4 +119,14 @@ make lint
 
 header_text "running go test"
 
-go test -race ./pkg/... ./cmd/... -parallel 4
+for dir in $(find . -name go.mod -exec dirname {} \;); do
+  # Includes "BadDeepCopy" types that are not supposed to result in
+  # valid code generation
+  if [[ "$dir" == "./pkg/deepcopy/testdata" ]]; then continue; fi
+
+  # https://github.com/kubernetes-sigs/controller-tools/issues/1227
+  if [[ "$dir" == "./pkg/webhook/testdata" ]]; then continue; fi
+
+  echo "Testing module in $dir"
+  (cd "$dir" && go test -race ./... -parallel 4)
+done



Test patch:
diff --git a/pkg/applyconfiguration/testdata/cronjob/api/v1/applyconfiguration/api/v1/cronjobspec.go b/pkg/applyconfiguration/testdata/cronjob/api/v1/applyconfiguration/api/v1/cronjobspec.go
index d57a2dbb..1b0479d4 100644
--- a/pkg/applyconfiguration/testdata/cronjob/api/v1/applyconfiguration/api/v1/cronjobspec.go
+++ b/pkg/applyconfiguration/testdata/cronjob/api/v1/applyconfiguration/api/v1/cronjobspec.go
@@ -71,7 +71,6 @@ type CronJobSpecApplyConfiguration struct {
 	Float64WithValidations                    *float64                                         `json:"float64WithValidations,omitempty"`
 	IntWithValidations                        *int                                             `json:"intWithValidations,omitempty"`
 	Int32WithValidations                      *int32                                           `json:"int32WithValidations,omitempty"`
-	unexportedStructApplyConfiguration        `json:",inline"`
 	ExportedStructApplyConfiguration          `json:",inline"`
 	StringWithEvenLength                      *string                `json:"stringWithEvenLength,omitempty"`
 	StringWithEvenLengthAndMessageExpression  *string                `json:"stringWithEvenLengthAndMessageExpression,omitempty"`
@@ -89,7 +88,6 @@ type CronJobSpecApplyConfiguration struct {
 	StringAliasAlreadyValidated               *string                `json:"stringAliasAlreadyValidated,omitempty"`
 	StringPair                                []string               `json:"stringPair,omitempty"`
 	LongerStringArray                         []apiv1.LongerString   `json:"longerStringArray,omitempty"`
-	IntOrStringArrayWithAPattern              []*intstr.IntOrString  `json:"intOrStringArrayWithAPattern,omitempty"`
 	Protocol                                  *corev1.Protocol       `json:"protocol,omitempty"`
 	SelectableFieldString                     *string                `json:"selectableFieldString,omitempty"`
 	EmbeddedStructApplyConfiguration          `json:",inline"`
@@ -654,14 +652,6 @@ func (b *CronJobSpecApplyConfiguration) WithInt32WithValidations(value int32) *C
 	return b
 }
 
-// WithFoo sets the Foo field in the declarative configuration to the given value
-// and returns the receiver, so that objects can be built by chaining "With" function invocations.
-// If called multiple times, the Foo field is set to the value of the last call.
-func (b *CronJobSpecApplyConfiguration) WithFoo(value string) *CronJobSpecApplyConfiguration {
-	b.unexportedStructApplyConfiguration.Foo = &value
-	return b
-}
-
 // WithBaz sets the Baz field in the declarative configuration to the given value
 // and returns the receiver, so that objects can be built by chaining "With" function invocations.
 // If called multiple times, the Baz field is set to the value of the last call.
@@ -806,19 +796,6 @@ func (b *CronJobSpecApplyConfiguration) WithLongerStringArray(values ...apiv1.Lo
 	return b
 }
 
-// WithIntOrStringArrayWithAPattern adds the given value to the IntOrStringArrayWithAPattern field in the declarative configuration
-// and returns the receiver, so that objects can be build by chaining "With" function invocations.
-// If called multiple times, values provided by each call will be appended to the IntOrStringArrayWithAPattern field.
-func (b *CronJobSpecApplyConfiguration) WithIntOrStringArrayWithAPattern(values ...*intstr.IntOrString) *CronJobSpecApplyConfiguration {
-	for i := range values {
-		if values[i] == nil {
-			panic("nil value passed to WithIntOrStringArrayWithAPattern")
-		}
-		b.IntOrStringArrayWithAPattern = append(b.IntOrStringArrayWithAPattern, *values[i])
-	}
-	return b
-}
-
 // WithProtocol sets the Protocol field in the declarative configuration to the given value
 // and returns the receiver, so that objects can be built by chaining "With" function invocations.
 // If called multiple times, the Protocol field is set to the value of the last call.
diff --git a/pkg/applyconfiguration/testdata/cronjob/api/v1/applyconfiguration/api/v1/unexportedstruct.go b/pkg/applyconfiguration/testdata/cronjob/api/v1/applyconfiguration/api/v1/unexportedstruct.go
deleted file mode 100644
index 8bbcc3d9..00000000
--- a/pkg/applyconfiguration/testdata/cronjob/api/v1/applyconfiguration/api/v1/unexportedstruct.go
+++ /dev/null
@@ -1,24 +0,0 @@
-// Code generated by applyconfiguration. DO NOT EDIT.
-
-package v1
-
-// UnexportedStructApplyConfiguration represents a declarative configuration of the UnexportedStruct type for use
-// with apply.
-type UnexportedStructApplyConfiguration struct {
-	Foo *string `json:"foo,omitempty"`
-}
-
-// UnexportedStructApplyConfiguration constructs a declarative configuration of the UnexportedStruct type for use with
-// apply.
-func UnexportedStruct() *UnexportedStructApplyConfiguration {
-	return &UnexportedStructApplyConfiguration{}
-}
-func (b UnexportedStructApplyConfiguration) IsApplyConfiguration() {}
-
-// WithFoo sets the Foo field in the declarative configuration to the given value
-// and returns the receiver, so that objects can be built by chaining "With" function invocations.
-// If called multiple times, the Foo field is set to the value of the last call.
-func (b *UnexportedStructApplyConfiguration) WithFoo(value string) *UnexportedStructApplyConfiguration {
-	b.Foo = &value
-	return b
-}
diff --git a/pkg/applyconfiguration/testdata/cronjob/api/v1/applyconfiguration/utils.go b/pkg/applyconfiguration/testdata/cronjob/api/v1/applyconfiguration/utils.go
index 3b35ac23..e7221c7c 100644
--- a/pkg/applyconfiguration/testdata/cronjob/api/v1/applyconfiguration/utils.go
+++ b/pkg/applyconfiguration/testdata/cronjob/api/v1/applyconfiguration/utils.go
@@ -46,8 +46,6 @@ func ForKind(kind schema.GroupVersionKind) interface{} {
 		return &apiv1.PreservedApplyConfiguration{}
 	case v1.SchemeGroupVersion.WithKind("RootObject"):
 		return &apiv1.RootObjectApplyConfiguration{}
-	case v1.SchemeGroupVersion.WithKind("UnexportedStruct"):
-		return &apiv1.unexportedStructApplyConfiguration{}
 
 	}
 	return nil
diff --git a/pkg/applyconfiguration/testdata/cronjob/api/v1/cronjob_types.go b/pkg/applyconfiguration/testdata/cronjob/api/v1/cronjob_types.go
index b63ddb53..edf63ae8 100644
--- a/pkg/applyconfiguration/testdata/cronjob/api/v1/cronjob_types.go
+++ b/pkg/applyconfiguration/testdata/cronjob/api/v1/cronjob_types.go
@@ -294,8 +294,10 @@ type CronJobSpec struct {
 	unexportedField string
 
 	// This tests that both unexported and exported inline fields are not skipped in the schema generation
-	unexportedStruct `json:",inline"`
-	ExportedStruct   `json:",inline"`
+	//
+	// This currently does not work
+	//unexportedStruct `json:",inline"`
+	ExportedStruct `json:",inline"`
 
 	// Test of the expression-based validation rule marker, with optional message.
 	// +kubebuilder:validation:XValidation:rule="self.size() % 2 == 0",message="must have even length"
@@ -363,11 +365,13 @@ type CronJobSpec struct {
 	// This tests that a slice of IntOrString can also have string validation.
 	// This can be useful if you want to limit the string to a percentage or integer.
 	// The XIntOrString marker is a requirement for having a pattern on this type.
-	// +kubebuilder:validation:items:XIntOrString
-	// +kubebuilder:validation:items:MaxLength=10
-	// +kubebuilder:validation:items:MinLength=1
-	// +kubebuilder:validation:items:Pattern="^((100|[0-9]{1,2})%|[0-9]+)$"
-	IntOrStringArrayWithAPattern []*intstr.IntOrString `json:"intOrStringArrayWithAPattern,omitempty"`
+	// -+kubebuilder:validation:items:XIntOrString
+	// -+kubebuilder:validation:items:MaxLength=10
+	// -+kubebuilder:validation:items:MinLength=1
+	// -+kubebuilder:validation:items:Pattern="^((100|[0-9]{1,2})%|[0-9]+)$"
+	//
+	// This currently does not work. Remove the leading '-' in the above markers when fixing.
+	// IntOrStringArrayWithAPattern []*intstr.IntOrString `json:"intOrStringArrayWithAPattern,omitempty"`
 
 	// This tests that we can embed protocol correctly (without ending up with allOf).
 	// Context: https://github.com/kubernetes-sigs/controller-tools/issues/1027
diff --git a/pkg/applyconfiguration/testdata/cronjob/api/v1/groupversion_info.go b/pkg/applyconfiguration/testdata/cronjob/api/v1/groupversion_info.go
index 569e35bb..434c225b 100644
--- a/pkg/applyconfiguration/testdata/cronjob/api/v1/groupversion_info.go
+++ b/pkg/applyconfiguration/testdata/cronjob/api/v1/groupversion_info.go
@@ -27,9 +27,10 @@ import (
 )
 
 var (
-	GroupName     = "testdata.kubebuilder.io"
-	GroupVersion  = schema.GroupVersion{Group: GroupName, Version: "v1"}
-	SchemeBuilder = runtime.NewSchemeBuilder(addKnownTypes)
+	GroupName          = "testdata.kubebuilder.io"
+	GroupVersion       = schema.GroupVersion{Group: GroupName, Version: "v1"}
+	SchemeGroupVersion = GroupVersion
+	SchemeBuilder      = runtime.NewSchemeBuilder(addKnownTypes)
 
 	// AddToScheme exists solely to keep the old generators creating valid code
 	AddToScheme = SchemeBuilder.AddToScheme
diff --git a/pkg/crd/testdata/internal_version/internal_types.go b/pkg/crd/testdata/internal_version/internal_types.go
index 51a98880..7c9a2d41 100644
--- a/pkg/crd/testdata/internal_version/internal_types.go
+++ b/pkg/crd/testdata/internal_version/internal_types.go
@@ -72,7 +72,3 @@ type CronJobList struct {
 	metav1.ListMeta
 	Items []CronJob
 }
-
-func init() {
-	SchemeBuilder.Register(&CronJob{}, &CronJobList{})
-}