blob: 265357abb3fad9c07d3d6c2812280ed1d6390f46 [file] [log] [blame]
Bob Badoura99ac622021-10-25 16:21:00 -07001// 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 "sort"
19 "testing"
20)
21
22var (
23 // bottomUp describes the bottom-up resolve of a hypothetical graph
24 // the graph has a container image, a couple binaries, and a couple
25 // libraries. bin1 statically links lib1 and dynamically links lib2;
26 // bin2 dynamically links lib1 and statically links lib2.
27 // binc represents a compiler or other toolchain binary used for
28 // building the other binaries.
29 bottomUp = []res{
30 {"image", "image", "image", "notice"},
31 {"image", "image", "bin2", "restricted"},
32 {"image", "bin1", "bin1", "reciprocal"},
33 {"image", "bin2", "bin2", "restricted"},
34 {"image", "lib1", "lib1", "notice"},
35 {"image", "lib2", "lib2", "notice"},
36 {"binc", "binc", "binc", "proprietary"},
37 {"bin1", "bin1", "bin1", "reciprocal"},
38 {"bin1", "lib1", "lib1", "notice"},
39 {"bin2", "bin2", "bin2", "restricted"},
40 {"bin2", "lib2", "lib2", "notice"},
41 {"lib1", "lib1", "lib1", "notice"},
42 {"lib2", "lib2", "lib2", "notice"},
43 }
44
45 // notice describes bottomUp after a top-down notice resolve.
46 notice = []res{
47 {"image", "image", "image", "notice"},
48 {"image", "image", "bin2", "restricted"},
49 {"image", "bin1", "bin1", "reciprocal"},
50 {"image", "bin2", "bin2", "restricted"},
51 {"image", "lib1", "lib1", "notice"},
52 {"image", "lib2", "bin2", "restricted"},
53 {"image", "lib2", "lib2", "notice"},
54 {"bin1", "bin1", "bin1", "reciprocal"},
55 {"bin1", "lib1", "lib1", "notice"},
56 {"bin2", "bin2", "bin2", "restricted"},
57 {"bin2", "lib2", "bin2", "restricted"},
58 {"bin2", "lib2", "lib2", "notice"},
59 {"lib1", "lib1", "lib1", "notice"},
60 {"lib2", "lib2", "lib2", "notice"},
61 }
62
63 // share describes bottomUp after a top-down share resolve.
64 share = []res{
65 {"image", "image", "bin2", "restricted"},
66 {"image", "bin1", "bin1", "reciprocal"},
67 {"image", "bin2", "bin2", "restricted"},
68 {"image", "lib2", "bin2", "restricted"},
69 {"bin1", "bin1", "bin1", "reciprocal"},
70 {"bin2", "bin2", "bin2", "restricted"},
71 {"bin2", "lib2", "bin2", "restricted"},
72 }
73
74 // proprietary describes bottomUp after a top-down proprietary resolve.
75 // Note that the proprietary binc is not reachable through the toolchain
76 // dependency.
77 proprietary = []res{}
78)
79
80func TestResolutionSet_JoinResolutionSets(t *testing.T) {
81 lg := newLicenseGraph()
82
83 rsNotice := toResolutionSet(lg, notice)
84 rsShare := toResolutionSet(lg, share)
85 rsExpected := toResolutionSet(lg, append(notice, share...))
86
87 rsActual := JoinResolutionSets(rsNotice, rsShare)
88 checkSame(rsActual, rsExpected, t)
89}
90
91func TestResolutionSet_JoinResolutionsEmpty(t *testing.T) {
92 lg := newLicenseGraph()
93
94 rsShare := toResolutionSet(lg, share)
95 rsProprietary := toResolutionSet(lg, proprietary)
96 rsExpected := toResolutionSet(lg, append(share, proprietary...))
97
98 rsActual := JoinResolutionSets(rsShare, rsProprietary)
99 checkSame(rsActual, rsExpected, t)
100}
101
102func TestResolutionSet_Origins(t *testing.T) {
103 lg := newLicenseGraph()
104
105 rsShare := toResolutionSet(lg, share)
106
107 origins := make([]string, 0)
108 for _, target := range rsShare.Origins() {
109 origins = append(origins, target.Name())
110 }
111 sort.Strings(origins)
112 if len(origins) != 2 {
113 t.Errorf("unexpected number of origins: got %v with %d elements, want [\"bin1\", \"bin2\"] with 2 elements", origins, len(origins))
114 }
115 if origins[0] != "bin1" {
116 t.Errorf("unexpected origin at element 0: got %s, want \"bin1\"", origins[0])
117 }
118 if origins[1] != "bin2" {
119 t.Errorf("unexpected origin at element 0: got %s, want \"bin2\"", origins[0])
120 }
121}
122
123func TestResolutionSet_AttachedToTarget(t *testing.T) {
124 lg := newLicenseGraph()
125
126 rsShare := toResolutionSet(lg, share)
127
128 if rsShare.AttachedToTarget(newTestNode(lg, "binc")) {
129 t.Errorf("unexpected AttachedToTarget(\"binc\"): got true, want false")
130 }
131 if !rsShare.AttachedToTarget(newTestNode(lg, "image")) {
132 t.Errorf("unexpected AttachedToTarget(\"image\"): got false want true")
133 }
134}
135
136func TestResolutionSet_AnyByNameAttachToTarget(t *testing.T) {
137 lg := newLicenseGraph()
138
139 rs := toResolutionSet(lg, bottomUp)
140
141 pandp := ConditionNames{"permissive", "proprietary"}
142 pandn := ConditionNames{"permissive", "notice"}
143 p := ConditionNames{"proprietary"}
144 r := ConditionNames{"restricted"}
145
146 if rs.AnyByNameAttachToTarget(newTestNode(lg, "image"), pandp, p) {
147 t.Errorf("unexpected AnyByNameAttachToTarget(\"image\", \"proprietary\", \"permissive\"): want false, got true")
148 }
149 if !rs.AnyByNameAttachToTarget(newTestNode(lg, "binc"), p) {
150 t.Errorf("unexpected AnyByNameAttachToTarget(\"binc\", \"proprietary\"): want true, got false")
151 }
152 if !rs.AnyByNameAttachToTarget(newTestNode(lg, "image"), pandn) {
153 t.Errorf("unexpected AnyByNameAttachToTarget(\"image\", \"permissive\", \"notice\"): want true, got false")
154 }
155 if !rs.AnyByNameAttachToTarget(newTestNode(lg, "image"), r, pandn) {
156 t.Errorf("unexpected AnyByNameAttachToTarget(\"image\", \"restricted\", \"notice\"): want true, got false")
157 }
158 if !rs.AnyByNameAttachToTarget(newTestNode(lg, "image"), r, p) {
159 t.Errorf("unexpected AnyByNameAttachToTarget(\"image\", \"restricted\", \"proprietary\"): want true, got false")
160 }
161}
162
163func TestResolutionSet_AllByNameAttachToTarget(t *testing.T) {
164 lg := newLicenseGraph()
165
166 rs := toResolutionSet(lg, bottomUp)
167
168 pandp := ConditionNames{"permissive", "proprietary"}
169 pandn := ConditionNames{"permissive", "notice"}
170 p := ConditionNames{"proprietary"}
171 r := ConditionNames{"restricted"}
172
173 if rs.AllByNameAttachToTarget(newTestNode(lg, "image"), pandp, p) {
174 t.Errorf("unexpected AllByNameAttachToTarget(\"image\", \"proprietary\", \"permissive\"): want false, got true")
175 }
176 if !rs.AllByNameAttachToTarget(newTestNode(lg, "binc"), p) {
177 t.Errorf("unexpected AllByNameAttachToTarget(\"binc\", \"proprietary\"): want true, got false")
178 }
179 if !rs.AllByNameAttachToTarget(newTestNode(lg, "image"), pandn) {
180 t.Errorf("unexpected AllByNameAttachToTarget(\"image\", \"notice\"): want true, got false")
181 }
182 if !rs.AllByNameAttachToTarget(newTestNode(lg, "image"), r, pandn) {
183 t.Errorf("unexpected AllByNameAttachToTarget(\"image\", \"restricted\", \"notice\"): want true, got false")
184 }
185 if rs.AllByNameAttachToTarget(newTestNode(lg, "image"), r, p) {
186 t.Errorf("unexpected AllByNameAttachToTarget(\"image\", \"restricted\", \"proprietary\"): want false, got true")
187 }
188}
189
190func TestResolutionSet_AttachesToTarget(t *testing.T) {
191 lg := newLicenseGraph()
192
193 rsShare := toResolutionSet(lg, share)
194
195 if rsShare.AttachesToTarget(newTestNode(lg, "binc")) {
196 t.Errorf("unexpected hasTarget(\"binc\"): got true, want false")
197 }
198 if !rsShare.AttachesToTarget(newTestNode(lg, "image")) {
199 t.Errorf("unexpected AttachesToTarget(\"image\"): got false want true")
200 }
201}