@@ -11,6 +11,7 @@ import (
1111 "github.com/google/go-cmp/cmp"
1212 fuzz "github.com/google/gofuzz"
1313 "k8s.io/kube-openapi/pkg/internal"
14+ jsontesting "k8s.io/kube-openapi/pkg/util/jsontesting"
1415 "k8s.io/kube-openapi/pkg/validation/spec"
1516)
1617
@@ -71,6 +72,95 @@ func TestOpenAPIV3Deserialize(t *testing.T) {
7172 }
7273}
7374
75+ func TestOpenAPIV3Serialize (t * testing.T ) {
76+ swagFile , err := os .Open ("./testdata/appsv1spec.json" )
77+ if err != nil {
78+ t .Fatal (err )
79+ }
80+ defer swagFile .Close ()
81+ originalJSON , err := io .ReadAll (swagFile )
82+ if err != nil {
83+ t .Fatal (err )
84+ }
85+ var openapi * OpenAPI
86+ if err := json .Unmarshal (originalJSON , & openapi ); err != nil {
87+ t .Fatal (err )
88+ }
89+
90+ internal .UseOptimizedJSONUnmarshalingV3 = false
91+ want , err := json .Marshal (openapi )
92+ if err != nil {
93+ t .Fatal (err )
94+ }
95+ internal .UseOptimizedJSONUnmarshalingV3 = true
96+ got , err := openapi .MarshalJSON ()
97+ if err != nil {
98+ t .Fatal (err )
99+ }
100+ if err := jsontesting .JsonCompare (want , got ); err != nil {
101+ t .Errorf ("marshal doesn't match: %v" , err )
102+ }
103+ }
104+
105+ func TestOpenAPIV3SerializeFuzzed (t * testing.T ) {
106+ var fuzzer * fuzz.Fuzzer
107+ fuzzer = fuzz .NewWithSeed (1646791953 )
108+ fuzzer .MaxDepth (13 ).NilChance (0.075 ).NumElements (1 , 2 )
109+ fuzzer .Funcs (OpenAPIV3FuzzFuncs ... )
110+
111+ for i := 0 ; i < 100 ; i ++ {
112+ openapi := & OpenAPI {}
113+ fuzzer .Fuzz (openapi )
114+
115+ internal .UseOptimizedJSONUnmarshalingV3 = false
116+ want , err := json .Marshal (openapi )
117+ if err != nil {
118+ t .Fatal (err )
119+ }
120+ internal .UseOptimizedJSONUnmarshalingV3 = true
121+ got , err := openapi .MarshalJSON ()
122+ if err != nil {
123+ t .Fatal (err )
124+ }
125+ if err := jsontesting .JsonCompare (want , got ); err != nil {
126+ t .Errorf ("fuzzed marshal doesn't match: %v" , err )
127+ }
128+ }
129+ }
130+
131+ func TestOpenAPIV3SerializeStable (t * testing.T ) {
132+ swagFile , err := os .Open ("./testdata/appsv1spec.json" )
133+ if err != nil {
134+ t .Fatal (err )
135+ }
136+ defer swagFile .Close ()
137+ originalJSON , err := io .ReadAll (swagFile )
138+ if err != nil {
139+ t .Fatal (err )
140+ }
141+ var openapi * OpenAPI
142+ if err := json .Unmarshal (originalJSON , & openapi ); err != nil {
143+ t .Fatal (err )
144+ }
145+
146+ internal .UseOptimizedJSONUnmarshalingV3 = true
147+ for i := 0 ; i < 5 ; i ++ {
148+ t .Run (fmt .Sprintf ("%d" , i ), func (t * testing.T ) {
149+ want , err := openapi .MarshalJSON ()
150+ if err != nil {
151+ t .Fatal (err )
152+ }
153+ got , err := openapi .MarshalJSON ()
154+ if err != nil {
155+ t .Fatal (err )
156+ }
157+ if err := jsontesting .JsonCompare (want , got ); err != nil {
158+ t .Errorf ("marshal doesn't match: %v" , err )
159+ }
160+ })
161+ }
162+ }
163+
74164func BenchmarkOpenAPIV3Deserialize (b * testing.B ) {
75165 benchcases := []struct {
76166 file string
@@ -142,3 +232,61 @@ func BenchmarkOpenAPIV3Deserialize(b *testing.B) {
142232 })
143233 }
144234}
235+
236+ func BenchmarkOpenAPIV3Serialize (b * testing.B ) {
237+ benchcases := []struct {
238+ file string
239+ }{
240+ {
241+ file : "appsv1spec.json" ,
242+ },
243+ {
244+ file : "authorizationv1spec.json" ,
245+ },
246+ }
247+ for _ , bc := range benchcases {
248+ swagFile , err := os .Open ("./testdata/" + bc .file )
249+ if err != nil {
250+ b .Fatal (err )
251+ }
252+ defer swagFile .Close ()
253+ originalJSON , err := io .ReadAll (swagFile )
254+ if err != nil {
255+ b .Fatal (err )
256+ }
257+ var openapi * OpenAPI
258+ if err := json .Unmarshal (originalJSON , & openapi ); err != nil {
259+ b .Fatal (err )
260+ }
261+ b .ResetTimer ()
262+ b .Run (fmt .Sprintf ("%s jsonv1" , bc .file ), func (b2 * testing.B ) {
263+ b2 .ReportAllocs ()
264+ internal .UseOptimizedJSONMarshalingV3 = false
265+ for i := 0 ; i < b2 .N ; i ++ {
266+ if _ , err := json .Marshal (openapi ); err != nil {
267+ b2 .Fatal (err )
268+ }
269+ }
270+ })
271+
272+ b .Run (fmt .Sprintf ("%s jsonv2 via jsonv1 full spec" , bc .file ), func (b2 * testing.B ) {
273+ b2 .ReportAllocs ()
274+ internal .UseOptimizedJSONMarshalingV3 = true
275+ for i := 0 ; i < b2 .N ; i ++ {
276+ if _ , err := json .Marshal (openapi ); err != nil {
277+ b2 .Fatal (err )
278+ }
279+ }
280+ })
281+
282+ b .Run ("jsonv2" , func (b2 * testing.B ) {
283+ b2 .ReportAllocs ()
284+ internal .UseOptimizedJSONMarshalingV3 = true
285+ for i := 0 ; i < b2 .N ; i ++ {
286+ if _ , err := openapi .MarshalJSON (); err != nil {
287+ b2 .Fatal (err )
288+ }
289+ }
290+ })
291+ }
292+ }
0 commit comments