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", 1)
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", 1)
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 := newContext("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 := newContext("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 := newContext("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 := ioutil.ReadFile("testdata/af_packet.api.json")
117 Expect(err).ShouldNot(HaveOccurred())
118 result, err := parseInputJSON(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 := ioutil.ReadFile("testdata/input-read-json-error.json")
127 Expect(err).ShouldNot(HaveOccurred())
128 result, err := parseInputJSON(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 := ioutil.ReadFile("testdata/ip.api.json")
141 Expect(err).ShouldNot(HaveOccurred())
142 jsonRoot, err := parseInputJSON(inputData)
143 Expect(err).ShouldNot(HaveOccurred())
144 testCtx.packageData, err = parsePackage(testCtx, jsonRoot)
145 Expect(err).ShouldNot(HaveOccurred())
146 outDir := "test_output_directory"
147 outFile, err := os.Create(outDir)
148 Expect(err).ShouldNot(HaveOccurred())
149 defer os.RemoveAll(outDir)
152 writer := bufio.NewWriter(outFile)
153 Expect(writer.Buffered()).To(BeZero())
154 err = generatePackage(testCtx, writer)
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 := ioutil.ReadFile("testdata/ip.api.json")
166 Expect(err).ShouldNot(HaveOccurred())
167 jsonRoot, err := parseInputJSON(inputData)
168 Expect(err).ShouldNot(HaveOccurred())
169 outDir := "test_output_directory"
170 outFile, err := os.Create(outDir)
171 Expect(err).ShouldNot(HaveOccurred())
172 testCtx.packageData, err = parsePackage(testCtx, jsonRoot)
173 Expect(err).ShouldNot(HaveOccurred())
174 defer os.RemoveAll(outDir)
177 writer := bufio.NewWriter(outFile)
179 for _, msg := range testCtx.packageData.Messages {
180 generateMessage(testCtx, writer, &msg)
181 Expect(writer.Buffered()).ToNot(BeZero())
185 /*func TestGenerateMessageName(t *testing.T) {
188 testCtx := new(context)
189 testCtx.packageName = "test-package-name"
191 // prepare input/output output files
192 inputData, err := readFile("testdata/ip.api.json")
193 Expect(err).ShouldNot(HaveOccurred())
194 testCtx.inputBuff = bytes.NewBuffer(inputData)
195 inFile, _ := parseJSON(inputData)
196 outDir := "test_output_directory"
197 outFile, err := os.Create(outDir)
198 Expect(err).ShouldNot(HaveOccurred())
199 defer os.RemoveAll(outDir)
202 writer := bufio.NewWriter(outFile)
204 types := inFile.Map("types")
205 Expect(types.Len()).To(BeEquivalentTo(1))
206 for i := 0; i < types.Len(); i++ {
208 Expect(writer.Buffered()).To(BeZero())
209 err := generateMessage(testCtx, writer, typ, false)
210 Expect(err).ShouldNot(HaveOccurred())
211 Expect(writer.Buffered()).ToNot(BeZero())
216 func TestGenerateMessageFieldTypes(t *testing.T) {
217 // expected results according to acl.api.json in testdata
218 expectedTypes := []string{
221 "\tSrcIPAddr []byte `struc:\"[16]byte\"`",
222 "\tSrcIPPrefixLen uint8",
223 "\tDstIPAddr []byte `struc:\"[16]byte\"`",
224 "\tDstIPPrefixLen uint8",
226 "\tSrcportOrIcmptypeFirst uint16",
227 "\tSrcportOrIcmptypeLast uint16",
228 "\tDstportOrIcmpcodeFirst uint16",
229 "\tDstportOrIcmpcodeLast uint16",
230 "\tTCPFlagsMask uint8",
231 "\tTCPFlagsValue uint8"}
234 testCtx := new(context)
235 testCtx.packageName = "test-package-name"
237 // prepare input/output output files
238 inputData, err := readFile("testdata/acl.api.json")
239 Expect(err).ShouldNot(HaveOccurred())
240 inFile, err := parseJSON(inputData)
241 Expect(err).ShouldNot(HaveOccurred())
242 Expect(inFile).ToNot(BeNil())
245 types := inFile.Map("types")
246 fields := make([]string, 0)
247 for i := 0; i < types.Len(); i++ {
248 for j := 0; j < types.At(i).Len(); j++ {
249 field := types.At(i).At(j)
250 if field.GetType() == jsongo.TypeArray {
251 err := processMessageField(testCtx, &fields, field, false)
252 Expect(err).ShouldNot(HaveOccurred())
253 Expect(fields[j-1]).To(BeEquivalentTo(expectedTypes[j-1]))
259 func TestGenerateMessageFieldMessages(t *testing.T) {
260 // expected results according to acl.api.json in testdata
261 expectedFields := []string{"\tMajor uint32", "\tMinor uint32", "\tRetval int32",
262 "\tVpePid uint32", "\tACLIndex uint32", "\tTag []byte `struc:\"[64]byte\"`",
266 testCtx := new(context)
267 testCtx.packageName = "test-package-name"
269 // prepare input/output output files
270 inputData, err := readFile("testdata/acl.api.json")
271 Expect(err).ShouldNot(HaveOccurred())
272 inFile, err := parseJSON(inputData)
273 Expect(err).ShouldNot(HaveOccurred())
274 Expect(inFile).ToNot(BeNil())
276 // test message fields
277 messages := inFile.Map("messages")
279 fields := make([]string, 0)
280 for i := 0; i < messages.Len(); i++ {
281 for j := 0; j < messages.At(i).Len(); j++ {
282 field := messages.At(i).At(j)
283 if field.GetType() == jsongo.TypeArray {
284 specificFieldName := field.At(1).Get().(string)
285 if specificFieldName == "crc" || specificFieldName == "_vl_msg_id" ||
286 specificFieldName == "client_index" || specificFieldName == "context" {
289 err := processMessageField(testCtx, &fields, field, false)
290 Expect(err).ShouldNot(HaveOccurred())
291 Expect(fields[customIndex]).To(BeEquivalentTo(expectedFields[customIndex]))
293 if customIndex >= len(expectedFields) {
294 // there is too much fields now for one UT...
302 func TestGeneratePackageHeader(t *testing.T) {
305 testCtx := new(context)
306 testCtx.packageName = "test-package-name"
308 // prepare input/output output files
309 inputData, err := readFile("testdata/acl.api.json")
310 Expect(err).ShouldNot(HaveOccurred())
311 inFile, err := parseJSON(inputData)
312 Expect(err).ShouldNot(HaveOccurred())
313 outDir := "test_output_directory"
314 outFile, err := os.Create(outDir)
315 Expect(err).ShouldNot(HaveOccurred())
316 defer os.RemoveAll(outDir)
318 writer := bufio.NewWriter(outFile)
319 Expect(writer.Buffered()).To(BeZero())
320 generateHeader(testCtx, writer, inFile)
321 Expect(writer.Buffered()).ToNot(BeZero())
324 func TestGenerateMessageCommentType(t *testing.T) {
327 testCtx := new(context)
328 testCtx.packageName = "test-package-name"
329 testCtx.inputBuff = bytes.NewBuffer([]byte("test content"))
331 outDir := "test_output_directory"
332 outFile, err := os.Create(outDir)
333 Expect(err).ShouldNot(HaveOccurred())
334 writer := bufio.NewWriter(outFile)
335 defer os.RemoveAll(outDir)
336 Expect(writer.Buffered()).To(BeZero())
337 generateMessageComment(testCtx, writer, "test-struct", "msg-name", true)
338 Expect(writer.Buffered()).ToNot(BeZero())
341 func TestGenerateMessageCommentMessage(t *testing.T) {
344 testCtx := new(context)
345 testCtx.packageName = "test-package-name"
346 testCtx.inputBuff = bytes.NewBuffer([]byte("test content"))
348 outDir := "test_output_directory"
349 outFile, err := os.Create(outDir)
350 Expect(err).ShouldNot(HaveOccurred())
351 writer := bufio.NewWriter(outFile)
352 defer os.RemoveAll(outDir)
353 Expect(writer.Buffered()).To(BeZero())
354 generateMessageComment(testCtx, writer, "test-struct", "msg-name", false)
355 Expect(writer.Buffered()).ToNot(BeZero())
358 func TestGenerateMessageNameGetter(t *testing.T) {
360 outDir := "test_output_directory"
361 outFile, err := os.Create(outDir)
362 Expect(err).ShouldNot(HaveOccurred())
363 writer := bufio.NewWriter(outFile)
364 defer os.RemoveAll(outDir)
365 Expect(writer.Buffered()).To(BeZero())
366 generateMessageNameGetter(writer, "test-struct", "msg-name")
367 Expect(writer.Buffered()).ToNot(BeZero())
370 func TestGenerateTypeNameGetter(t *testing.T) {
372 outDir := "test_output_directory"
373 outFile, err := os.Create(outDir)
374 Expect(err).ShouldNot(HaveOccurred())
375 writer := bufio.NewWriter(outFile)
376 defer os.RemoveAll(outDir)
377 Expect(writer.Buffered()).To(BeZero())
378 generateTypeNameGetter(writer, "test-struct", "msg-name")
379 Expect(writer.Buffered()).ToNot(BeZero())
382 func TestGenerateCrcGetter(t *testing.T) {
384 outDir := "test_output_directory"
385 outFile, err := os.Create(outDir)
386 Expect(err).ShouldNot(HaveOccurred())
387 writer := bufio.NewWriter(outFile)
388 defer os.RemoveAll(outDir)
389 Expect(writer.Buffered()).To(BeZero())
390 generateCrcGetter(writer, "test-struct", "msg-name")
391 Expect(writer.Buffered()).ToNot(BeZero())
394 func TestTranslateVppType(t *testing.T) {
396 context := new(context)
397 typesToTranslate := []string{"u8", "i8", "u16", "i16", "u32", "i32", "u64", "i64", "f64"}
398 expected := []string{"uint8", "int8", "uint16", "int16", "uint32", "int32", "uint64", "int64", "float64"}
399 var translated []string
400 for _, value := range typesToTranslate {
401 translated = append(translated, convertToGoType(context, value, false))
403 for index, value := range expected {
404 Expect(value).To(BeEquivalentTo(translated[index]))
409 func TestTranslateVppTypeArray(t *testing.T) {
411 context := new(context)
412 translated := convertToGoType(context, "u8", true)
413 Expect(translated).To(BeEquivalentTo("byte"))
416 func TestTranslateVppUnknownType(t *testing.T) {
418 if recovery := recover(); recovery != nil {
419 t.Logf("Recovered from panic: %v", recovery)
422 context := new(context)
423 convertToGoType(context, "?", false)
426 func TestCamelCase(t *testing.T) {
428 // test camel case functionality
429 expected := "allYourBaseAreBelongToUs"
430 result := camelCaseName("all_your_base_are_belong_to_us")
431 Expect(expected).To(BeEquivalentTo(result))
434 result = camelCaseName(expected)
435 Expect(expected).To(BeEquivalentTo(result))
438 result = camelCaseName(expected)
439 Expect(expected).To(BeEquivalentTo(result))
442 func TestCommonInitialisms(t *testing.T) {
445 for key, value := range commonInitialisms {
446 Expect(value).ShouldNot(BeFalse())
447 Expect(key).ShouldNot(BeEmpty())