blob: b73927211823a807c777febb55cd2e3fa9a6288b [file] [log] [blame]
Kent Hagerman433a31a2020-05-20 19:04:48 -04001/*
2 * Copyright 2020-present Open Networking Foundation
3
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7
8 * http://www.apache.org/licenses/LICENSE-2.0
9
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package flow
18
19import (
20 "bufio"
21 "fmt"
22 "os"
23 "regexp"
24 "strconv"
25 "strings"
26 "testing"
27)
28
29// TestLoadersIdentical ensures that the group, flow, and meter loaders always have an identical implementation.
30func TestLoadersIdentical(t *testing.T) {
31 identical := [][]string{
32 {"ofp\\.OfpFlowStats", "ofp\\.OfpGroupEntry", "ofp\\.OfpMeterEntry"},
33 {"\\.Id", "\\.Desc\\.GroupId", "\\.Config.MeterId"},
34 {"uint64", "uint32", "uint32"},
35 {"Flow", "Group", "Meter"},
36 {"flow", "group", "meter"},
37 }
38
39 regexes := make([]*regexp.Regexp, len(identical))
40 for i, group := range identical {
41 regexes[i] = regexp.MustCompile(strings.Join(group, "|"))
42 }
43
44 for i := 1; i < len(identical[0]); i++ {
45 if err := compare(regexes, "../"+identical[4][0]+"/loader.go", "../"+identical[4][i]+"/loader.go"); err != nil {
46 t.Error(err)
47 return
48 }
49 }
50}
51
52func compare(regexes []*regexp.Regexp, fileNameA, fileNameB string) error {
53 fileA, err := os.Open(fileNameA)
54 if err != nil {
55 return err
56 }
57 defer fileA.Close()
58
59 fileB, err := os.Open(fileNameB)
60 if err != nil {
61 return err
62 }
63 defer fileB.Close()
64
65 scannerA, scannerB := bufio.NewScanner(fileA), bufio.NewScanner(fileB)
66
67 spaceRegex := regexp.MustCompile(" +")
68
69 line := 1
70 for {
71 if continueA, continueB := scannerA.Scan(), scannerB.Scan(); continueA != continueB {
72 if !continueA && continueB {
73 if err := scannerA.Err(); err != nil {
74 return err
75 }
76 }
77 if continueA && !continueB {
78 if err := scannerB.Err(); err != nil {
79 return err
80 }
81 }
82 return fmt.Errorf("line %d: files are not the same length", line)
83 } else if !continueA {
84 // EOF from both files
85 break
86 }
87
88 textA, textB := scannerA.Text(), scannerB.Text()
89
90 replacedA, replacedB := textA, textB
91 for i, regex := range regexes {
92 replacement := "{{type" + strconv.Itoa(i) + "}}"
93 replacedA, replacedB = regex.ReplaceAllString(replacedA, replacement), regex.ReplaceAllString(replacedB, replacement)
94 }
95
96 // replace multiple spaces with single space
97 replacedA, replacedB = spaceRegex.ReplaceAllString(replacedA, " "), spaceRegex.ReplaceAllString(replacedB, " ")
98
99 if replacedA != replacedB {
100 return fmt.Errorf("line %d: files %s and %s do not match: \n\t%s\n\t%s\n\n\t%s\n\t%s", line, fileNameA, fileNameB, textA, textB, replacedA, replacedB)
101 }
102
103 line++
104 }
105
106 if err := scannerA.Err(); err != nil {
107 return err
108 }
109 if err := scannerB.Err(); err != nil {
110 return err
111 }
112 return nil
113}