• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1// Copyright 2021 Google LLC
2//
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
6//
7//      http://www.apache.org/licenses/LICENSE-2.0
8//
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.
14
15package compliance
16
17import (
18	"bytes"
19	"sort"
20	"strings"
21	"testing"
22)
23
24func TestReadLicenseGraph(t *testing.T) {
25	tests := []struct {
26		name            string
27		fs              *testFS
28		roots           []string
29		expectedError   string
30		expectedEdges   []edge
31		expectedTargets []string
32	}{
33		{
34			name: "trivial",
35			fs: &testFS{
36				"app.meta_lic": []byte("package_name: \"Android\"\n"),
37			},
38			roots:           []string{"app.meta_lic"},
39			expectedEdges:   []edge{},
40			expectedTargets: []string{"app.meta_lic"},
41		},
42		{
43			name: "unterminated",
44			fs: &testFS{
45				"app.meta_lic": []byte("package_name: \"Android\n"),
46			},
47			roots:         []string{"app.meta_lic"},
48			expectedError: `invalid character '\n' in string`,
49		},
50		{
51			name: "danglingref",
52			fs: &testFS{
53				"app.meta_lic": []byte(AOSP + "deps: {\n  file: \"lib.meta_lic\"\n}\n"),
54			},
55			roots:         []string{"app.meta_lic"},
56			expectedError: `unknown file "lib.meta_lic"`,
57		},
58		{
59			name: "singleedge",
60			fs: &testFS{
61				"app.meta_lic": []byte(AOSP + "deps: {\n  file: \"lib.meta_lic\"\n}\n"),
62				"lib.meta_lic": []byte(AOSP),
63			},
64			roots:           []string{"app.meta_lic"},
65			expectedEdges:   []edge{{"app.meta_lic", "lib.meta_lic"}},
66			expectedTargets: []string{"app.meta_lic", "lib.meta_lic"},
67		},
68		{
69			name: "fullgraph",
70			fs: &testFS{
71				"apex.meta_lic": []byte(AOSP + "deps: {\n  file: \"app.meta_lic\"\n}\ndeps: {\n  file: \"bin.meta_lic\"\n}\n"),
72				"app.meta_lic":  []byte(AOSP),
73				"bin.meta_lic":  []byte(AOSP + "deps: {\n  file: \"lib.meta_lic\"\n}\n"),
74				"lib.meta_lic":  []byte(AOSP),
75			},
76			roots: []string{"apex.meta_lic"},
77			expectedEdges: []edge{
78				{"apex.meta_lic", "app.meta_lic"},
79				{"apex.meta_lic", "bin.meta_lic"},
80				{"bin.meta_lic", "lib.meta_lic"},
81			},
82			expectedTargets: []string{"apex.meta_lic", "app.meta_lic", "bin.meta_lic", "lib.meta_lic"},
83		},
84	}
85	for _, tt := range tests {
86		t.Run(tt.name, func(t *testing.T) {
87			stderr := &bytes.Buffer{}
88			lg, err := ReadLicenseGraph(tt.fs, stderr, tt.roots)
89			if err != nil {
90				if len(tt.expectedError) == 0 {
91					t.Errorf("unexpected error: got %s, want no error", err)
92				} else if !strings.Contains(err.Error(), tt.expectedError) {
93					t.Errorf("unexpected error: got %s, want %q", err, tt.expectedError)
94				}
95				return
96			}
97			if len(tt.expectedError) > 0 {
98				t.Errorf("unexpected success: got no error, want %q err", tt.expectedError)
99				return
100			}
101			if lg == nil {
102				t.Errorf("missing license graph: got nil, want license graph")
103				return
104			}
105			actualEdges := make([]edge, 0)
106			for _, e := range lg.Edges() {
107				actualEdges = append(actualEdges, edge{e.Target().Name(), e.Dependency().Name()})
108			}
109			sort.Sort(byEdge(tt.expectedEdges))
110			sort.Sort(byEdge(actualEdges))
111			t.Logf("actualEdges:")
112			for _, edge := range actualEdges {
113				t.Logf("  %s", edge.String())
114			}
115			t.Logf("expectedEdges:")
116			for _, edge := range actualEdges {
117				t.Logf("  %s", edge.String())
118			}
119			if len(tt.expectedEdges) != len(actualEdges) {
120				t.Errorf("len(actualEdges): got %d, want %d", len(actualEdges), len(tt.expectedEdges))
121			} else {
122				for i := 0; i < len(actualEdges); i++ {
123					if tt.expectedEdges[i] != actualEdges[i] {
124						t.Errorf("actualEdges[%d]: got %s, want %s", i, actualEdges[i], tt.expectedEdges[i])
125					}
126				}
127			}
128
129			actualTargets := make([]string, 0)
130			for _, t := range lg.Targets() {
131				actualTargets = append(actualTargets, t.Name())
132			}
133			sort.Strings(tt.expectedTargets)
134			sort.Strings(actualTargets)
135
136			t.Logf("actualTargets: %v", actualTargets)
137			t.Logf("expectedTargets: %v", tt.expectedTargets)
138
139			if len(tt.expectedTargets) != len(actualTargets) {
140				t.Errorf("len(actualTargets): got %d, want %d", len(actualTargets), len(tt.expectedTargets))
141			} else {
142				for i := 0; i < len(actualTargets); i++ {
143					if tt.expectedTargets[i] != actualTargets[i] {
144						t.Errorf("actualTargets[%d]: got %s, want %s", i, actualTargets[i], tt.expectedTargets[i])
145					}
146				}
147			}
148		})
149	}
150}
151