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/onsi/gomega"
26 func TestGetInputFiles(t *testing.T) {
28 result, err := getInputFiles("testdata")
29 Expect(err).ShouldNot(HaveOccurred())
30 Expect(result).To(HaveLen(3))
31 for _, file := range result {
32 Expect(file).To(BeAnExistingFile())
36 func TestGetInputFilesError(t *testing.T) {
38 result, err := getInputFiles("nonexisting_directory")
39 Expect(err).Should(HaveOccurred())
40 Expect(result).To(BeNil())
43 func TestGenerateFromFile(t *testing.T) {
45 outDir := "test_output_directory"
46 // remove directory created during test
47 defer os.RemoveAll(outDir)
48 err := generateFromFile("testdata/acl.api.json", outDir)
49 Expect(err).ShouldNot(HaveOccurred())
50 fileInfo, err := os.Stat(outDir + "/acl/acl.ba.go")
51 Expect(err).ShouldNot(HaveOccurred())
52 Expect(fileInfo.IsDir()).To(BeFalse())
53 Expect(fileInfo.Name()).To(BeEquivalentTo("acl.ba.go"))
56 func TestGenerateFromFileInputError(t *testing.T) {
58 outDir := "test_output_directory"
59 err := generateFromFile("testdata/nonexisting.json", outDir)
60 Expect(err).Should(HaveOccurred())
61 Expect(err.Error()).To(ContainSubstring("invalid input file name"))
64 func TestGenerateFromFileReadJsonError(t *testing.T) {
66 outDir := "test_output_directory"
67 err := generateFromFile("testdata/input-read-json-error.json", outDir)
68 Expect(err).Should(HaveOccurred())
69 Expect(err.Error()).To(ContainSubstring("invalid input file name"))
72 func TestGenerateFromFileGeneratePackageError(t *testing.T) {
74 outDir := "test_output_directory"
75 // generate package throws panic, recover after it
77 if recovery := recover(); recovery != nil {
78 t.Logf("Recovered from panic: %v", recovery)
82 err := generateFromFile("testdata/input-generate-error.json", outDir)
83 Expect(err).Should(HaveOccurred())
86 func TestGetContext(t *testing.T) {
88 outDir := "test_output_directory"
89 result, err := getContext("testdata/af_packet.api.json", outDir)
90 Expect(err).ShouldNot(HaveOccurred())
91 Expect(result).ToNot(BeNil())
92 Expect(result.outputFile).To(BeEquivalentTo(outDir + "/af_packet/af_packet.ba.go"))
95 func TestGetContextNoJsonFile(t *testing.T) {
97 outDir := "test_output_directory"
98 result, err := getContext("testdata/input.txt", outDir)
99 Expect(err).Should(HaveOccurred())
100 Expect(err.Error()).To(ContainSubstring("invalid input file name"))
101 Expect(result).To(BeNil())
104 func TestGetContextInterfaceJson(t *testing.T) {
106 outDir := "test_output_directory"
107 result, err := getContext("testdata/ip.api.json", outDir)
108 Expect(err).ShouldNot(HaveOccurred())
109 Expect(result).ToNot(BeNil())
110 Expect(result.outputFile)
111 Expect(result.outputFile).To(BeEquivalentTo(outDir + "/ip/ip.ba.go"))
114 func TestReadJson(t *testing.T) {
116 inputData, err := readFile("testdata/af_packet.api.json")
117 Expect(err).ShouldNot(HaveOccurred())
118 result, err := parseJSON(inputData)
119 Expect(err).ShouldNot(HaveOccurred())
120 Expect(result).ToNot(BeNil())
121 Expect(result.Len()).To(BeEquivalentTo(5))
124 func TestReadJsonError(t *testing.T) {
126 inputData, err := readFile("testdata/input-read-json-error.json")
127 Expect(err).ShouldNot(HaveOccurred())
128 result, err := parseJSON(inputData)
129 Expect(err).Should(HaveOccurred())
130 Expect(result).To(BeNil())
133 func TestGeneratePackage(t *testing.T) {
136 testCtx := new(context)
137 testCtx.packageName = "test-package-name"
139 // prepare input/output output files
140 inputData, err := readFile("testdata/ip.api.json")
141 Expect(err).ShouldNot(HaveOccurred())
142 testCtx.inputBuff = bytes.NewBuffer(inputData)
143 jsonRoot, err := parseJSON(inputData)
144 Expect(err).ShouldNot(HaveOccurred())
145 testCtx.packageData, err = parsePackage(testCtx, jsonRoot)
146 Expect(err).ShouldNot(HaveOccurred())
147 outDir := "test_output_directory"
148 outFile, err := os.Create(outDir)
149 Expect(err).ShouldNot(HaveOccurred())
150 defer os.RemoveAll(outDir)
153 writer := bufio.NewWriter(outFile)
154 Expect(writer.Buffered()).To(BeZero())
155 err = generatePackage(testCtx, writer)
156 Expect(err).ShouldNot(HaveOccurred())
159 func TestGenerateMessageType(t *testing.T) {
162 testCtx := new(context)
163 testCtx.packageName = "test-package-name"
165 // prepare input/output output files
166 inputData, err := readFile("testdata/ip.api.json")
167 Expect(err).ShouldNot(HaveOccurred())
168 testCtx.inputBuff = bytes.NewBuffer(inputData)
169 jsonRoot, err := parseJSON(inputData)
170 Expect(err).ShouldNot(HaveOccurred())
171 outDir := "test_output_directory"
172 outFile, err := os.Create(outDir)
173 Expect(err).ShouldNot(HaveOccurred())
174 testCtx.packageData, err = parsePackage(testCtx, jsonRoot)
175 Expect(err).ShouldNot(HaveOccurred())
176 defer os.RemoveAll(outDir)
179 writer := bufio.NewWriter(outFile)
181 for _, msg := range testCtx.packageData.Messages {
182 generateMessage(testCtx, writer, &msg)
183 Expect(writer.Buffered()).ToNot(BeZero())
187 /*func TestGenerateMessageName(t *testing.T) {
190 testCtx := new(context)
191 testCtx.packageName = "test-package-name"
193 // prepare input/output output files
194 inputData, err := readFile("testdata/ip.api.json")
195 Expect(err).ShouldNot(HaveOccurred())
196 testCtx.inputBuff = bytes.NewBuffer(inputData)
197 inFile, _ := parseJSON(inputData)
198 outDir := "test_output_directory"
199 outFile, err := os.Create(outDir)
200 Expect(err).ShouldNot(HaveOccurred())
201 defer os.RemoveAll(outDir)
204 writer := bufio.NewWriter(outFile)
206 types := inFile.Map("types")
207 Expect(types.Len()).To(BeEquivalentTo(1))
208 for i := 0; i < types.Len(); i++ {
210 Expect(writer.Buffered()).To(BeZero())
211 err := generateMessage(testCtx, writer, typ, false)
212 Expect(err).ShouldNot(HaveOccurred())
213 Expect(writer.Buffered()).ToNot(BeZero())
218 func TestGenerateMessageFieldTypes(t *testing.T) {
219 // expected results according to acl.api.json in testdata
220 expectedTypes := []string{
223 "\tSrcIPAddr []byte `struc:\"[16]byte\"`",
224 "\tSrcIPPrefixLen uint8",
225 "\tDstIPAddr []byte `struc:\"[16]byte\"`",
226 "\tDstIPPrefixLen uint8",
228 "\tSrcportOrIcmptypeFirst uint16",
229 "\tSrcportOrIcmptypeLast uint16",
230 "\tDstportOrIcmpcodeFirst uint16",
231 "\tDstportOrIcmpcodeLast uint16",
232 "\tTCPFlagsMask uint8",
233 "\tTCPFlagsValue uint8"}
236 testCtx := new(context)
237 testCtx.packageName = "test-package-name"
239 // prepare input/output output files
240 inputData, err := readFile("testdata/acl.api.json")
241 Expect(err).ShouldNot(HaveOccurred())
242 inFile, err := parseJSON(inputData)
243 Expect(err).ShouldNot(HaveOccurred())
244 Expect(inFile).ToNot(BeNil())
247 types := inFile.Map("types")
248 fields := make([]string, 0)
249 for i := 0; i < types.Len(); i++ {
250 for j := 0; j < types.At(i).Len(); j++ {
251 field := types.At(i).At(j)
252 if field.GetType() == jsongo.TypeArray {
253 err := processMessageField(testCtx, &fields, field, false)
254 Expect(err).ShouldNot(HaveOccurred())
255 Expect(fields[j-1]).To(BeEquivalentTo(expectedTypes[j-1]))
261 func TestGenerateMessageFieldMessages(t *testing.T) {
262 // expected results according to acl.api.json in testdata
263 expectedFields := []string{"\tMajor uint32", "\tMinor uint32", "\tRetval int32",
264 "\tVpePid uint32", "\tACLIndex uint32", "\tTag []byte `struc:\"[64]byte\"`",
268 testCtx := new(context)
269 testCtx.packageName = "test-package-name"
271 // prepare input/output output files
272 inputData, err := readFile("testdata/acl.api.json")
273 Expect(err).ShouldNot(HaveOccurred())
274 inFile, err := parseJSON(inputData)
275 Expect(err).ShouldNot(HaveOccurred())
276 Expect(inFile).ToNot(BeNil())
278 // test message fields
279 messages := inFile.Map("messages")
281 fields := make([]string, 0)
282 for i := 0; i < messages.Len(); i++ {
283 for j := 0; j < messages.At(i).Len(); j++ {
284 field := messages.At(i).At(j)
285 if field.GetType() == jsongo.TypeArray {
286 specificFieldName := field.At(1).Get().(string)
287 if specificFieldName == "crc" || specificFieldName == "_vl_msg_id" ||
288 specificFieldName == "client_index" || specificFieldName == "context" {
291 err := processMessageField(testCtx, &fields, field, false)
292 Expect(err).ShouldNot(HaveOccurred())
293 Expect(fields[customIndex]).To(BeEquivalentTo(expectedFields[customIndex]))
295 if customIndex >= len(expectedFields) {
296 // there is too much fields now for one UT...
304 func TestGeneratePackageHeader(t *testing.T) {
307 testCtx := new(context)
308 testCtx.packageName = "test-package-name"
310 // prepare input/output output files
311 inputData, err := readFile("testdata/acl.api.json")
312 Expect(err).ShouldNot(HaveOccurred())
313 inFile, err := parseJSON(inputData)
314 Expect(err).ShouldNot(HaveOccurred())
315 outDir := "test_output_directory"
316 outFile, err := os.Create(outDir)
317 Expect(err).ShouldNot(HaveOccurred())
318 defer os.RemoveAll(outDir)
320 writer := bufio.NewWriter(outFile)
321 Expect(writer.Buffered()).To(BeZero())
322 generateHeader(testCtx, writer, inFile)
323 Expect(writer.Buffered()).ToNot(BeZero())
326 func TestGenerateMessageCommentType(t *testing.T) {
329 testCtx := new(context)
330 testCtx.packageName = "test-package-name"
331 testCtx.inputBuff = bytes.NewBuffer([]byte("test content"))
333 outDir := "test_output_directory"
334 outFile, err := os.Create(outDir)
335 Expect(err).ShouldNot(HaveOccurred())
336 writer := bufio.NewWriter(outFile)
337 defer os.RemoveAll(outDir)
338 Expect(writer.Buffered()).To(BeZero())
339 generateMessageComment(testCtx, writer, "test-struct", "msg-name", true)
340 Expect(writer.Buffered()).ToNot(BeZero())
343 func TestGenerateMessageCommentMessage(t *testing.T) {
346 testCtx := new(context)
347 testCtx.packageName = "test-package-name"
348 testCtx.inputBuff = bytes.NewBuffer([]byte("test content"))
350 outDir := "test_output_directory"
351 outFile, err := os.Create(outDir)
352 Expect(err).ShouldNot(HaveOccurred())
353 writer := bufio.NewWriter(outFile)
354 defer os.RemoveAll(outDir)
355 Expect(writer.Buffered()).To(BeZero())
356 generateMessageComment(testCtx, writer, "test-struct", "msg-name", false)
357 Expect(writer.Buffered()).ToNot(BeZero())
360 func TestGenerateMessageNameGetter(t *testing.T) {
362 outDir := "test_output_directory"
363 outFile, err := os.Create(outDir)
364 Expect(err).ShouldNot(HaveOccurred())
365 writer := bufio.NewWriter(outFile)
366 defer os.RemoveAll(outDir)
367 Expect(writer.Buffered()).To(BeZero())
368 generateMessageNameGetter(writer, "test-struct", "msg-name")
369 Expect(writer.Buffered()).ToNot(BeZero())
372 func TestGenerateTypeNameGetter(t *testing.T) {
374 outDir := "test_output_directory"
375 outFile, err := os.Create(outDir)
376 Expect(err).ShouldNot(HaveOccurred())
377 writer := bufio.NewWriter(outFile)
378 defer os.RemoveAll(outDir)
379 Expect(writer.Buffered()).To(BeZero())
380 generateTypeNameGetter(writer, "test-struct", "msg-name")
381 Expect(writer.Buffered()).ToNot(BeZero())
384 func TestGenerateCrcGetter(t *testing.T) {
386 outDir := "test_output_directory"
387 outFile, err := os.Create(outDir)
388 Expect(err).ShouldNot(HaveOccurred())
389 writer := bufio.NewWriter(outFile)
390 defer os.RemoveAll(outDir)
391 Expect(writer.Buffered()).To(BeZero())
392 generateCrcGetter(writer, "test-struct", "msg-name")
393 Expect(writer.Buffered()).ToNot(BeZero())
396 func TestTranslateVppType(t *testing.T) {
398 context := new(context)
399 typesToTranslate := []string{"u8", "i8", "u16", "i16", "u32", "i32", "u64", "i64", "f64"}
400 expected := []string{"uint8", "int8", "uint16", "int16", "uint32", "int32", "uint64", "int64", "float64"}
401 var translated []string
402 for _, value := range typesToTranslate {
403 translated = append(translated, convertToGoType(context, value, false))
405 for index, value := range expected {
406 Expect(value).To(BeEquivalentTo(translated[index]))
411 func TestTranslateVppTypeArray(t *testing.T) {
413 context := new(context)
414 translated := convertToGoType(context, "u8", true)
415 Expect(translated).To(BeEquivalentTo("byte"))
418 func TestTranslateVppUnknownType(t *testing.T) {
420 if recovery := recover(); recovery != nil {
421 t.Logf("Recovered from panic: %v", recovery)
424 context := new(context)
425 convertToGoType(context, "?", false)
428 func TestCamelCase(t *testing.T) {
430 // test camel case functionality
431 expected := "allYourBaseAreBelongToUs"
432 result := camelCaseName("all_your_base_are_belong_to_us")
433 Expect(expected).To(BeEquivalentTo(result))
436 result = camelCaseName(expected)
437 Expect(expected).To(BeEquivalentTo(result))
440 result = camelCaseName(expected)
441 Expect(expected).To(BeEquivalentTo(result))
444 func TestCommonInitialisms(t *testing.T) {
447 for key, value := range commonInitialisms {
448 Expect(value).ShouldNot(BeFalse())
449 Expect(key).ShouldNot(BeEmpty())