1 package getambassadorio_test
2
3 import (
4 "encoding/json"
5 "os"
6 "path"
7 "path/filepath"
8 "reflect"
9 "testing"
10
11 "github.com/pmezard/go-difflib/difflib"
12 "github.com/stretchr/testify/require"
13 "k8s.io/apimachinery/pkg/runtime"
14 "sigs.k8s.io/yaml"
15
16 getambassadorio "github.com/datawire/ambassador/v2/pkg/api/getambassador.io"
17 "github.com/datawire/ambassador/v2/pkg/api/getambassador.io/v1"
18 "github.com/datawire/ambassador/v2/pkg/api/getambassador.io/v2"
19 "github.com/datawire/ambassador/v2/pkg/api/getambassador.io/v3alpha1"
20 "github.com/datawire/ambassador/v2/pkg/kates"
21 )
22
23 func marshalNormalized(t *testing.T, typed interface{}) string {
24 t.Helper()
25
26
27
28
29 bs, err := json.Marshal(typed)
30 require.NoError(t, err)
31
32 var untyped interface{}
33 err = json.Unmarshal(bs, &untyped)
34 require.NoError(t, err)
35
36
37
38 out, err := json.MarshalIndent(untyped, "", "\t")
39 require.NoError(t, err)
40
41 return string(out)
42 }
43
44 func requireEqualNormalized(t *testing.T, exp, act interface{}) {
45 t.Helper()
46 expStr := marshalNormalized(t, exp)
47 actStr := marshalNormalized(t, act)
48
49
50 if expStr != actStr {
51 diff, _ := difflib.GetUnifiedDiffString(difflib.UnifiedDiff{
52 A: difflib.SplitLines(expStr),
53 B: difflib.SplitLines(actStr),
54 FromFile: "Expected",
55 FromDate: "",
56 ToFile: "Actual",
57 ToDate: "",
58 Context: 3,
59 })
60 t.Errorf("Not equal\n%s", diff)
61 }
62 }
63
64 func TestConvert(t *testing.T) {
65 testcases := map[string]map[string]interface{}{
66 "authsvc": {
67 "getambassador.io/v1": v1.AuthService{},
68 "getambassador.io/v2": v2.AuthService{},
69 "getambassador.io/v3alpha1": v3alpha1.AuthService{},
70 },
71 "devportals": {
72 "getambassador.io/v1": v1.DevPortal{},
73 "getambassador.io/v2": v2.DevPortal{},
74 "getambassador.io/v3alpha1": v3alpha1.DevPortal{},
75 },
76 "hosts": {
77 "getambassador.io/v2": v2.Host{},
78 "getambassador.io/v3alpha1": v3alpha1.Host{},
79 },
80 "logsvc": {
81 "getambassador.io/v1": v1.LogService{},
82 "getambassador.io/v2": v2.LogService{},
83 "getambassador.io/v3alpha1": v3alpha1.LogService{},
84 },
85 "mappings": {
86 "getambassador.io/v1": v1.Mapping{},
87 "getambassador.io/v2": v2.Mapping{},
88 "getambassador.io/v3alpha1": v3alpha1.Mapping{},
89 },
90 "modules": {
91 "getambassador.io/v1": v1.Module{},
92 "getambassador.io/v2": v2.Module{},
93 "getambassador.io/v3alpha1": v3alpha1.Module{},
94 },
95 "ratelimitsvc": {
96 "getambassador.io/v1": v1.RateLimitService{},
97 "getambassador.io/v2": v2.RateLimitService{},
98 "getambassador.io/v3alpha1": v3alpha1.RateLimitService{},
99 },
100 "tcpmappings": {
101 "getambassador.io/v1": v1.TCPMapping{},
102 "getambassador.io/v2": v2.TCPMapping{},
103 "getambassador.io/v3alpha1": v3alpha1.TCPMapping{},
104 },
105 "tlscontexts": {
106 "getambassador.io/v1": v1.TLSContext{},
107 "getambassador.io/v2": v2.TLSContext{},
108 "getambassador.io/v3alpha1": v3alpha1.TLSContext{},
109 },
110 "tracingsvc": {
111 "getambassador.io/v1": v1.TracingService{},
112 "getambassador.io/v2": v2.TracingService{},
113 "getambassador.io/v3alpha1": v3alpha1.TracingService{},
114 },
115 }
116
117 scheme := getambassadorio.BuildScheme()
118
119 v2.MangleAmbassadorID = false
120 t.Cleanup(func() {
121 v2.MangleAmbassadorID = true
122 })
123
124 t.Run("RoundTrip", func(t *testing.T) {
125 t.Parallel()
126 for typename := range testcases {
127 typename := typename
128 t.Run(typename, func(t *testing.T) {
129 t.Parallel()
130 for mainAPIVersion := range testcases[typename] {
131 for throughAPIVersion := range testcases[typename] {
132 if mainAPIVersion == throughAPIVersion {
133 continue
134 }
135 mainAPIVersion := mainAPIVersion
136 throughAPIVersion := throughAPIVersion
137 testname := path.Base(mainAPIVersion) + "_through_" + path.Base(throughAPIVersion)
138 t.Run(testname, func(t *testing.T) {
139 t.Parallel()
140 inBytes, err := os.ReadFile(filepath.Join(path.Base(mainAPIVersion), "testdata", typename+".yaml"))
141 require.NoError(t, err)
142 inListPtr := reflect.New(reflect.SliceOf(reflect.TypeOf(testcases[typename][mainAPIVersion])))
143 require.NoError(t, yaml.Unmarshal(inBytes, inListPtr.Interface()))
144 inList := inListPtr.Elem()
145 listLen := inList.Len()
146
147 midList := reflect.MakeSlice(reflect.SliceOf(reflect.TypeOf(testcases[typename][throughAPIVersion])), listLen, listLen)
148 for i := 0; i < listLen; i++ {
149 midList.Index(i).FieldByName("TypeMeta").FieldByName("APIVersion").Set(reflect.ValueOf(throughAPIVersion))
150 midList.Index(i).FieldByName("TypeMeta").FieldByName("Kind").Set(inList.Index(i).FieldByName("TypeMeta").FieldByName("Kind"))
151 require.NoError(t, kates.ConvertObject(scheme, inList.Index(i).Addr().Interface().(runtime.Object), midList.Index(i).Addr().Interface().(runtime.Object)))
152 }
153
154 outList := reflect.MakeSlice(reflect.SliceOf(reflect.TypeOf(testcases[typename][mainAPIVersion])), listLen, listLen)
155 for i := 0; i < listLen; i++ {
156 outList.Index(i).FieldByName("TypeMeta").Set(inList.Index(i).FieldByName("TypeMeta"))
157 require.NoError(t, kates.ConvertObject(scheme, midList.Index(i).Addr().Interface().(runtime.Object), outList.Index(i).Addr().Interface().(runtime.Object)))
158 }
159
160 requireEqualNormalized(t, inList.Interface(), outList.Interface())
161 })
162 }
163 }
164 })
165 }
166 })
167 }
168
View as plain text