Skip to content

Commit 4cb5ba3

Browse files
authored
CLOUDP-350358: Improve and increase crd2go test coverage (#2783)
1 parent ff1ee9d commit 4cb5ba3

File tree

19 files changed

+1244
-48
lines changed

19 files changed

+1244
-48
lines changed
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
// Copyright 2025 MongoDB Inc
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
//
15+
16+
package checkerr
17+
18+
import (
19+
"bytes"
20+
"log"
21+
"testing"
22+
23+
"github.com/stretchr/testify/assert"
24+
)
25+
26+
func TestCheckErr(t *testing.T) {
27+
var buf bytes.Buffer
28+
originalOutput := log.Writer()
29+
originalFlags := log.Flags()
30+
31+
log.SetOutput(&buf)
32+
log.SetFlags(0)
33+
34+
defer func() {
35+
log.SetOutput(originalOutput)
36+
log.SetFlags(originalFlags)
37+
}()
38+
39+
tests := map[string]struct {
40+
msg string
41+
f funcErrs
42+
expectedLog string
43+
}{
44+
"no error": {
45+
msg: "Operation",
46+
f: funcErrs(func() error {
47+
return nil
48+
}),
49+
expectedLog: "",
50+
},
51+
"with error": {
52+
msg: "Operation",
53+
f: funcErrs(func() error {
54+
return assert.AnError
55+
}),
56+
expectedLog: "Operation failed: assert.AnError general error for testing\n",
57+
},
58+
}
59+
for name, tt := range tests {
60+
t.Run(name, func(t *testing.T) {
61+
CheckErr(tt.msg, tt.f)
62+
logged := buf.String()
63+
buf.Reset()
64+
assert.Equal(t, tt.expectedLog, logged)
65+
})
66+
}
67+
}

tools/crd2go/internal/crd/hooks/array.go

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -33,15 +33,20 @@ func ArrayHookFn(td *gotype.TypeDict, hooks []crd.OpenAPI2GoHook, crdType *crd.C
3333
if crdType.Schema.Items.Schema == nil {
3434
return nil, fmt.Errorf("array %s has no items schema", crdType.Name)
3535
}
36-
elementType, err := crd.FromOpenAPIType(td, hooks, &crd.CRDType{
37-
Name: crdType.Name,
38-
Schema: crdType.Schema.Items.Schema,
39-
})
36+
elementType, err := crd.FromOpenAPIType(
37+
td,
38+
hooks,
39+
&crd.CRDType{
40+
Name: crdType.Name,
41+
Schema: crdType.Schema.Items.Schema,
42+
},
43+
)
4044
if err != nil {
4145
return nil, fmt.Errorf("failed to parse array %s element type: %w", crdType.Name, err)
4246
}
4347
if err := td.RenameType(crdType.Parents, elementType); err != nil {
4448
return nil, fmt.Errorf("failed to rename element type under %s: %w", crdType.Name, err)
4549
}
50+
4651
return gotype.NewArray(elementType), nil
4752
}
Lines changed: 145 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,145 @@
1+
// Copyright 2025 MongoDB Inc
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
//
15+
16+
package hooks
17+
18+
import (
19+
"fmt"
20+
"testing"
21+
22+
"github.com/stretchr/testify/assert"
23+
apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
24+
25+
"github.com/mongodb/mongodb-atlas-kubernetes/tools/crd2go/internal/crd"
26+
"github.com/mongodb/mongodb-atlas-kubernetes/tools/crd2go/internal/gotype"
27+
)
28+
29+
func TestArrayHookFn(t *testing.T) {
30+
tests := map[string]struct {
31+
hooks []crd.OpenAPI2GoHook
32+
crdType *crd.CRDType
33+
expectedType *gotype.GoType
34+
expectedErr error
35+
}{
36+
"not an array": {
37+
hooks: []crd.OpenAPI2GoHook{},
38+
crdType: &crd.CRDType{
39+
Name: "NotAnArray",
40+
Schema: &apiextensionsv1.JSONSchemaProps{
41+
Type: crd.OpenAPIString,
42+
},
43+
},
44+
expectedErr: fmt.Errorf("string is not an array: %w", crd.ErrNotProcessed),
45+
},
46+
"array with no items": {
47+
hooks: []crd.OpenAPI2GoHook{},
48+
crdType: &crd.CRDType{
49+
Name: "ArrayWithNoItems",
50+
Schema: &apiextensionsv1.JSONSchemaProps{
51+
Type: crd.OpenAPIArray,
52+
},
53+
},
54+
expectedErr: fmt.Errorf("array ArrayWithNoItems has no items"),
55+
},
56+
"array with no items schema": {
57+
hooks: []crd.OpenAPI2GoHook{},
58+
crdType: &crd.CRDType{
59+
Name: "ArrayWithNoItemsSchema",
60+
Schema: &apiextensionsv1.JSONSchemaProps{
61+
Type: crd.OpenAPIArray,
62+
Items: &apiextensionsv1.JSONSchemaPropsOrArray{},
63+
},
64+
},
65+
expectedErr: fmt.Errorf("array ArrayWithNoItemsSchema has no items schema"),
66+
},
67+
"failed to parse element type": {
68+
hooks: []crd.OpenAPI2GoHook{},
69+
crdType: &crd.CRDType{
70+
Name: "ArrayWithInvalidElementType",
71+
Schema: &apiextensionsv1.JSONSchemaProps{
72+
Type: crd.OpenAPIArray,
73+
Items: &apiextensionsv1.JSONSchemaPropsOrArray{
74+
Schema: &apiextensionsv1.JSONSchemaProps{
75+
Type: crd.OpenAPIString,
76+
},
77+
},
78+
},
79+
},
80+
expectedErr: fmt.Errorf(
81+
"failed to parse array %s element type: %w",
82+
"ArrayWithInvalidElementType",
83+
fmt.Errorf("unsupported Open API type %q", "ArrayWithInvalidElementType"),
84+
),
85+
},
86+
"failed to rename element type": {
87+
hooks: []crd.OpenAPI2GoHook{
88+
hookMock(t, &gotype.GoType{Name: "Object", Kind: gotype.StructKind}),
89+
},
90+
crdType: &crd.CRDType{
91+
Name: "Array",
92+
Schema: &apiextensionsv1.JSONSchemaProps{
93+
Type: crd.OpenAPIArray,
94+
Items: &apiextensionsv1.JSONSchemaPropsOrArray{
95+
Schema: &apiextensionsv1.JSONSchemaProps{
96+
Type: crd.OpenAPIObject,
97+
},
98+
},
99+
},
100+
Parents: []string{"Parent"},
101+
},
102+
expectedErr: fmt.Errorf(
103+
"failed to rename element type under %s: %w",
104+
"Array",
105+
fmt.Errorf("failed to find a free type name for type %v", &gotype.GoType{Name: "Data", Kind: gotype.StructKind}),
106+
),
107+
},
108+
"array of strings": {
109+
hooks: []crd.OpenAPI2GoHook{
110+
hookMock(t, &gotype.GoType{Kind: gotype.StringKind}),
111+
},
112+
crdType: &crd.CRDType{
113+
Name: "ArrayOfStrings",
114+
Schema: &apiextensionsv1.JSONSchemaProps{
115+
Type: crd.OpenAPIArray,
116+
Items: &apiextensionsv1.JSONSchemaPropsOrArray{
117+
Schema: &apiextensionsv1.JSONSchemaProps{
118+
Type: crd.OpenAPIString,
119+
},
120+
},
121+
},
122+
},
123+
expectedType: gotype.NewArray(&gotype.GoType{Kind: gotype.StringKind}),
124+
},
125+
}
126+
for name, tt := range tests {
127+
t.Run(name, func(t *testing.T) {
128+
td := gotype.NewTypeDict(map[string]string{"Object": "Data"}, gotype.KnownTypes()...)
129+
td.Add(&gotype.GoType{Name: "Data", Kind: gotype.ArrayKind})
130+
td.Add(&gotype.GoType{Name: "ParentData", Kind: gotype.ArrayKind})
131+
132+
got, err := ArrayHookFn(td, tt.hooks, tt.crdType)
133+
assert.Equal(t, tt.expectedErr, err)
134+
assert.Equal(t, tt.expectedType, got)
135+
})
136+
}
137+
}
138+
139+
func hookMock(t *testing.T, goType *gotype.GoType) crd.OpenAPI2GoHook {
140+
t.Helper()
141+
142+
return func(_ *gotype.TypeDict, _ []crd.OpenAPI2GoHook, _ *crd.CRDType) (*gotype.GoType, error) {
143+
return goType, nil
144+
}
145+
}

tools/crd2go/internal/crd/hooks/datetime.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,11 +22,11 @@ import (
2222
"github.com/mongodb/mongodb-atlas-kubernetes/tools/crd2go/internal/gotype"
2323
)
2424

25-
func DatetimeHookFn(td *gotype.TypeDict, _ []crd.OpenAPI2GoHook, crdType *crd.CRDType) (*gotype.GoType, error) {
25+
func DatetimeHookFn(_ *gotype.TypeDict, _ []crd.OpenAPI2GoHook, crdType *crd.CRDType) (*gotype.GoType, error) {
2626
if !crd.IsPrimitive(crdType) || !crd.IsDateTimeFormat(crdType) {
27-
return nil, fmt.Errorf("%s is not a date time (format is %s): %w",
28-
crdType.Schema.Type, crdType.Schema.Format, crd.ErrNotProcessed)
27+
return nil, fmt.Errorf("%s is not a date time (format is %s): %w", crdType.Schema.Type, crdType.Schema.Format, crd.ErrNotProcessed)
2928
}
29+
3030
return gotype.TimeType, nil
3131
}
3232

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
// Copyright 2025 MongoDB Inc
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
//
15+
16+
package hooks
17+
18+
import (
19+
"fmt"
20+
"testing"
21+
22+
"github.com/stretchr/testify/assert"
23+
apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
24+
25+
"github.com/mongodb/mongodb-atlas-kubernetes/tools/crd2go/internal/crd"
26+
"github.com/mongodb/mongodb-atlas-kubernetes/tools/crd2go/internal/gotype"
27+
)
28+
29+
func TestDatetimeHookFn(t *testing.T) {
30+
tests := map[string]struct {
31+
crdType *crd.CRDType
32+
expectedType *gotype.GoType
33+
expectedErr error
34+
}{
35+
"not a datetime string type": {
36+
crdType: &crd.CRDType{
37+
Name: "NotADatetime",
38+
Schema: &apiextensionsv1.JSONSchemaProps{
39+
Type: crd.OpenAPIString,
40+
},
41+
},
42+
expectedErr: fmt.Errorf("string is not a date time (format is ): %w", crd.ErrNotProcessed),
43+
},
44+
"string type with format date-time": {
45+
crdType: &crd.CRDType{
46+
Name: "DatetimeString",
47+
Schema: &apiextensionsv1.JSONSchemaProps{
48+
Type: crd.OpenAPIString,
49+
Format: "date-time",
50+
},
51+
},
52+
expectedType: gotype.TimeType,
53+
},
54+
}
55+
for name, tt := range tests {
56+
t.Run(name, func(t *testing.T) {
57+
got, err := DatetimeHookFn(nil, nil, tt.crdType)
58+
assert.Equal(t, tt.expectedErr, err)
59+
assert.Equal(t, tt.expectedType, got)
60+
})
61+
}
62+
}

tools/crd2go/internal/crd/hooks/dict.go

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ func DictHookFn(td *gotype.TypeDict, hooks []crd.OpenAPI2GoHook, crdType *crd.CR
2929
return nil, fmt.Errorf("%s is not a dictionary (additionalProperties is %v): %w",
3030
crdType.Schema.Type, crdType.Schema.AdditionalProperties, crd.ErrNotProcessed)
3131
}
32+
3233
return fromOpenAPIDict(td, hooks, crdType)
3334
}
3435

@@ -37,15 +38,20 @@ func fromOpenAPIDict(td *gotype.TypeDict, hooks []crd.OpenAPI2GoHook, crdType *c
3738
elemType := gotype.JSONType
3839
if crdType.Schema.AdditionalProperties.Schema != nil {
3940
var err error
40-
elemType, err = crd.FromOpenAPIType(td, hooks, &crd.CRDType{
41-
Name: crdType.Name,
42-
Parents: crdType.Parents,
43-
Schema: crdType.Schema.AdditionalProperties.Schema,
44-
})
41+
elemType, err = crd.FromOpenAPIType(
42+
td,
43+
hooks,
44+
&crd.CRDType{
45+
Name: crdType.Name,
46+
Parents: crdType.Parents,
47+
Schema: crdType.Schema.AdditionalProperties.Schema,
48+
},
49+
)
4550
if err != nil {
4651
return nil, fmt.Errorf("failed to check map value type: %w", err)
4752
}
4853
}
54+
4955
return &gotype.GoType{Name: gotype.MapKind, Kind: gotype.MapKind, Element: elemType}, nil
5056
}
5157

0 commit comments

Comments
 (0)