1 // Copyright (c) 2017 Cisco and/or its affiliates.
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:
7 // http://www.apache.org/licenses/LICENSE-2.0
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.
23 "github.com/bennyscetbun/jsongo"
24 . "github.com/onsi/gomega"
27 func TestGetInputFiles(t *testing.T) {
29 result, err := getInputFiles("testdata")
30 Expect(err).ShouldNot(HaveOccurred())
31 Expect(result).To(HaveLen(5))
32 for _, file := range result {
33 Expect(file).To(BeAnExistingFile())
37 func TestGetInputFilesError(t *testing.T) {
39 result, err := getInputFiles("nonexisting_directory")
40 Expect(err).Should(HaveOccurred())
41 Expect(result).To(BeNil())
44 func TestGenerateFromFile(t *testing.T) {
46 outDir := "test_output_directory"
47 // remove directory created during test
48 defer os.RemoveAll(outDir)
49 err := generateFromFile("testdata/acl.api.json", outDir)
50 Expect(err).ShouldNot(HaveOccurred())
51 fileInfo, err := os.Stat(outDir + "/acl/acl.go")
52 Expect(err).ShouldNot(HaveOccurred())
53 Expect(fileInfo.IsDir()).To(BeFalse())
54 Expect(fileInfo.Name()).To(BeEquivalentTo("acl.go"))
57 func TestGenerateFromFileInputError(t *testing.T) {
59 outDir := "test_output_directory"
60 err := generateFromFile("testdata/nonexisting.json", outDir)
61 Expect(err).Should(HaveOccurred())
62 Expect(err.Error()).To(ContainSubstring("reading data from file failed"))
65 func TestGenerateFromFileReadJsonError(t *testing.T) {
67 outDir := "test_output_directory"
68 err := generateFromFile("testdata/input-read-json-error.json", outDir)
69 Expect(err).Should(HaveOccurred())
70 Expect(err.Error()).To(ContainSubstring("JSON unmarshall failed"))
73 func TestGenerateFromFileGeneratePackageError(t *testing.T) {
75 outDir := "test_output_directory"
76 // generate package throws panic, recover after it
78 if recovery := recover(); recovery != nil {
79 t.Logf("Recovered from panic: %v", recovery)
83 err := generateFromFile("testdata/input-generate-error.json", outDir)
84 Expect(err).Should(HaveOccurred())
87 func TestGetContext(t *testing.T) {
89 outDir := "test_output_directory"
90 result, err := getContext("testdata/af_packet.api.json", outDir)
91 Expect(err).ShouldNot(HaveOccurred())
92 Expect(result).ToNot(BeNil())
93 Expect(result.outputFile).To(BeEquivalentTo(outDir + "/af_packet/af_packet.go"))
96 func TestGetContextNoJsonFile(t *testing.T) {
98 outDir := "test_output_directory"
99 result, err := getContext("testdata/input.txt", outDir)
100 Expect(err).Should(HaveOccurred())
101 Expect(err.Error()).To(ContainSubstring("invalid input file name"))
102 Expect(result).To(BeNil())
105 func TestGetContextInterfaceJson(t *testing.T) {
107 outDir := "test_output_directory"
108 result, err := getContext("testdata/interface.json", outDir)
109 Expect(err).ShouldNot(HaveOccurred())
110 Expect(result).ToNot(BeNil())
111 Expect(result.outputFile)
112 Expect(result.outputFile).To(BeEquivalentTo(outDir + "/interfaces/interfaces.go"))
116 func TestReadJson(t *testing.T) {
118 inputData, err := readFile("testdata/af_packet.api.json")
119 Expect(err).ShouldNot(HaveOccurred())
120 result, err := parseJSON(inputData)
121 Expect(err).ShouldNot(HaveOccurred())
122 Expect(result).ToNot(BeNil())
123 Expect(result.Len()).To(BeEquivalentTo(3))
126 func TestReadJsonError(t *testing.T) {
128 inputData, err := readFile("testdata/input-read-json-error.json")
129 Expect(err).ShouldNot(HaveOccurred())
130 result, err := parseJSON(inputData)
131 Expect(err).Should(HaveOccurred())
132 Expect(err.Error()).To(ContainSubstring("JSON unmarshall failed"))
133 Expect(result).To(BeNil())
136 func TestGeneratePackage(t *testing.T) {
139 testCtx := new(context)
140 testCtx.packageName = "test-package-name"
142 // prepare input/output output files
143 inputData, err := readFile("testdata/ip.api.json")
144 Expect(err).ShouldNot(HaveOccurred())
145 testCtx.inputBuff = bytes.NewBuffer(inputData)
146 inFile, _ := parseJSON(inputData)
147 outDir := "test_output_directory"
148 outFile, _ := os.Create(outDir)
149 defer os.RemoveAll(outDir)
152 writer := bufio.NewWriter(outFile)
153 Expect(writer.Buffered()).To(BeZero())
154 err = generatePackage(testCtx, writer, inFile)
155 Expect(err).ShouldNot(HaveOccurred())
158 func TestGenerateMessageType(t *testing.T) {
161 testCtx := new(context)
162 testCtx.packageName = "test-package-name"
164 // prepare input/output output files
165 inputData, err := readFile("testdata/ip.api.json")
166 Expect(err).ShouldNot(HaveOccurred())
167 testCtx.inputBuff = bytes.NewBuffer(inputData)
168 inFile, _ := parseJSON(inputData)
169 outDir := "test_output_directory"
170 outFile, _ := os.Create(outDir)
171 defer os.RemoveAll(outDir)
174 writer := bufio.NewWriter(outFile)
176 types := inFile.Map("types")
177 testCtx.types = map[string]string{
178 "u32": "sw_if_index",
181 Expect(types.Len()).To(BeEquivalentTo(1))
182 for i := 0; i < types.Len(); i++ {
184 Expect(writer.Buffered()).To(BeZero())
185 err := generateMessage(testCtx, writer, typ, true)
186 Expect(err).ShouldNot(HaveOccurred())
187 Expect(writer.Buffered()).ToNot(BeZero())
192 func TestGenerateMessageName(t *testing.T) {
195 testCtx := new(context)
196 testCtx.packageName = "test-package-name"
198 // prepare input/output output files
199 inputData, err := readFile("testdata/ip.api.json")
200 Expect(err).ShouldNot(HaveOccurred())
201 testCtx.inputBuff = bytes.NewBuffer(inputData)
202 inFile, _ := parseJSON(inputData)
203 outDir := "test_output_directory"
204 outFile, err := os.Create(outDir)
205 Expect(err).ShouldNot(HaveOccurred())
206 defer os.RemoveAll(outDir)
209 writer := bufio.NewWriter(outFile)
211 types := inFile.Map("types")
212 Expect(types.Len()).To(BeEquivalentTo(1))
213 for i := 0; i < types.Len(); i++ {
215 Expect(writer.Buffered()).To(BeZero())
216 err := generateMessage(testCtx, writer, typ, false)
217 Expect(err).ShouldNot(HaveOccurred())
218 Expect(writer.Buffered()).ToNot(BeZero())
223 func TestGenerateMessageFieldTypes(t *testing.T) {
224 // expected results according to acl.api.json in testdata
225 expectedTypes := []string{"\tIsPermit uint8", "\tIsIpv6 uint8", "\tSrcIPAddr []byte `struc:\"[16]byte\"`",
226 "\tSrcIPPrefixLen uint8", "\tDstIPAddr []byte `struc:\"[16]byte\"`", "\tDstIPPrefixLen uint8", "\tProto uint8",
227 "\tSrcportOrIcmptypeFirst uint16", "\tSrcportOrIcmptypeLast uint16", "\tDstportOrIcmpcodeFirst uint16",
228 "\tDstportOrIcmpcodeLast uint16", "\tTCPFlagsMask uint8", "\tTCPFlagsValue uint8"}
231 testCtx := new(context)
232 testCtx.packageName = "test-package-name"
234 // prepare input/output output files
235 inputData, err := readFile("testdata/acl.api.json")
236 Expect(err).ShouldNot(HaveOccurred())
237 inFile, _ := parseJSON(inputData)
238 Expect(err).ShouldNot(HaveOccurred())
239 Expect(inFile).ToNot(BeNil())
242 types := inFile.Map("types")
243 fields := make([]string, 0)
244 for i := 0; i < types.Len(); i++ {
245 for j := 0; j < types.At(i).Len(); j++ {
246 field := types.At(i).At(j)
247 if jsongo.TypeArray == field.GetType() {
248 err := processMessageField(testCtx, &fields, field)
249 Expect(err).ShouldNot(HaveOccurred())
250 Expect(fields[j-1]).To(BeEquivalentTo(expectedTypes[j-1]))
256 func TestGenerateMessageFieldMessages(t *testing.T) {
257 // expected results according to acl.api.json in testdata
258 expectedTypes := []string{"\tMajor uint32", "\tMinor uint32", "\tACLIndex uint32",
259 "\tTag []byte `struc:\"[64]byte\"`", "\tACLIndex uint32", "\tRetval int32", "\tACLIndex uint32"}
262 testCtx := new(context)
263 testCtx.packageName = "test-package-name"
265 // prepare input/output output files
266 inputData, err := readFile("testdata/acl.api.json")
267 Expect(err).ShouldNot(HaveOccurred())
268 inFile, err := parseJSON(inputData)
269 Expect(err).ShouldNot(HaveOccurred())
270 Expect(inFile).ToNot(BeNil())
273 messages := inFile.Map("messages")
275 fields := make([]string, 0)
276 for i := 0; i < messages.Len(); i++ {
277 for j := 0; j < messages.At(i).Len(); j++ {
278 field := messages.At(i).At(j)
279 if jsongo.TypeArray == field.GetType() {
280 specificFieldName := field.At(1).Get().(string)
281 if specificFieldName == "crc" || specificFieldName == "_vl_msg_id" ||
282 specificFieldName == "client_index" || specificFieldName == "context" {
285 err := processMessageField(testCtx, &fields, field)
286 Expect(err).ShouldNot(HaveOccurred())
287 Expect(fields[customIndex]).To(BeEquivalentTo(expectedTypes[customIndex]))
294 func TestGeneratePackageHeader(t *testing.T) {
297 testCtx := new(context)
298 testCtx.packageName = "test-package-name"
300 // prepare input/output output files
301 inputData, err := readFile("testdata/acl.api.json")
302 Expect(err).ShouldNot(HaveOccurred())
303 inFile, err := parseJSON(inputData)
304 Expect(err).ShouldNot(HaveOccurred())
305 outDir := "test_output_directory"
306 outFile, err := os.Create(outDir)
307 Expect(err).ShouldNot(HaveOccurred())
308 defer os.RemoveAll(outDir)
310 writer := bufio.NewWriter(outFile)
311 Expect(writer.Buffered()).To(BeZero())
312 generatePackageHeader(testCtx, writer, inFile)
313 Expect(writer.Buffered()).ToNot(BeZero())
316 func TestGenerateMessageCommentType(t *testing.T) {
319 testCtx := new(context)
320 testCtx.packageName = "test-package-name"
321 testCtx.inputBuff = bytes.NewBuffer([]byte("test content"))
323 outDir := "test_output_directory"
324 outFile, err := os.Create(outDir)
325 Expect(err).ShouldNot(HaveOccurred())
326 writer := bufio.NewWriter(outFile)
327 defer os.RemoveAll(outDir)
328 Expect(writer.Buffered()).To(BeZero())
329 generateMessageComment(testCtx, writer, "test-struct", "msg-name", true)
330 Expect(writer.Buffered()).ToNot(BeZero())
333 func TestGenerateMessageCommentMessage(t *testing.T) {
336 testCtx := new(context)
337 testCtx.packageName = "test-package-name"
338 testCtx.inputBuff = bytes.NewBuffer([]byte("test content"))
340 outDir := "test_output_directory"
341 outFile, err := os.Create(outDir)
342 Expect(err).ShouldNot(HaveOccurred())
343 writer := bufio.NewWriter(outFile)
344 defer os.RemoveAll(outDir)
345 Expect(writer.Buffered()).To(BeZero())
346 generateMessageComment(testCtx, writer, "test-struct", "msg-name", false)
347 Expect(writer.Buffered()).ToNot(BeZero())
350 func TestGenerateMessageNameGetter(t *testing.T) {
352 outDir := "test_output_directory"
353 outFile, err := os.Create(outDir)
354 Expect(err).ShouldNot(HaveOccurred())
355 writer := bufio.NewWriter(outFile)
356 defer os.RemoveAll(outDir)
357 Expect(writer.Buffered()).To(BeZero())
358 generateMessageNameGetter(writer, "test-struct", "msg-name")
359 Expect(writer.Buffered()).ToNot(BeZero())
362 func TestGenerateTypeNameGetter(t *testing.T) {
364 outDir := "test_output_directory"
365 outFile, err := os.Create(outDir)
366 Expect(err).ShouldNot(HaveOccurred())
367 writer := bufio.NewWriter(outFile)
368 defer os.RemoveAll(outDir)
369 Expect(writer.Buffered()).To(BeZero())
370 generateTypeNameGetter(writer, "test-struct", "msg-name")
371 Expect(writer.Buffered()).ToNot(BeZero())
374 func TestGenerateCrcGetter(t *testing.T) {
376 outDir := "test_output_directory"
377 outFile, err := os.Create(outDir)
378 Expect(err).ShouldNot(HaveOccurred())
379 writer := bufio.NewWriter(outFile)
380 defer os.RemoveAll(outDir)
381 Expect(writer.Buffered()).To(BeZero())
382 generateCrcGetter(writer, "test-struct", "msg-name")
383 Expect(writer.Buffered()).ToNot(BeZero())
386 func TestTranslateVppType(t *testing.T) {
388 context := new(context)
389 typesToTranslate := []string{"u8", "i8", "u16", "i16", "u32", "i32", "u64", "i64", "f64"}
390 expected := []string{"uint8", "int8", "uint16", "int16", "uint32", "int32", "uint64", "int64", "float64"}
391 translated := []string{}
392 for _, value := range typesToTranslate {
393 translated = append(translated, translateVppType(context, value, false))
395 for index, value := range expected {
396 Expect(value).To(BeEquivalentTo(translated[index]))
401 func TestTranslateVppTypeArray(t *testing.T) {
403 context := new(context)
404 translated := translateVppType(context, "u8", true)
405 Expect(translated).To(BeEquivalentTo("byte"))
408 func TestTranslateVppUnknownType(t *testing.T) {
410 if recovery := recover(); recovery != nil {
411 t.Logf("Recovered from panic: %v", recovery)
414 context := new(context)
415 translateVppType(context, "?", false)
418 func TestCamelCase(t *testing.T) {
420 // test camel case functionality
421 expected := "allYourBaseAreBelongToUs"
422 result := camelCaseName("all_your_base_are_belong_to_us")
423 Expect(expected).To(BeEquivalentTo(result))
426 result = camelCaseName(expected)
427 Expect(expected).To(BeEquivalentTo(result))
430 result = camelCaseName(expected)
431 Expect(expected).To(BeEquivalentTo(result))
434 func TestCommonInitialisms(t *testing.T) {
437 for key, value := range commonInitialisms {
438 Expect(value).ShouldNot(BeFalse())
439 Expect(key).ShouldNot(BeEmpty())