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 "testing" 21) 22 23// byConflict orders conflicts by target then share then privacy 24type byConflict []SourceSharePrivacyConflict 25 26// Len returns the count of elements in the slice. 27func (l byConflict) Len() int { return len(l) } 28 29// Swap rearranged 2 elements so that each occupies the other's former 30// position. 31func (l byConflict) Swap(i, j int) { l[i], l[j] = l[j], l[i] } 32 33// Less returns true when the `i`th element is lexicographically less than 34// the `j`th element. 35func (l byConflict) Less(i, j int) bool { 36 if l[i].SourceNode.Name() == l[j].SourceNode.Name() { 37 if l[i].ShareCondition.Name() == l[j].ShareCondition.Name() { 38 return l[i].PrivacyCondition.Name() < l[j].PrivacyCondition.Name() 39 } 40 return l[i].ShareCondition.Name() < l[j].ShareCondition.Name() 41 } 42 return l[i].SourceNode.Name() < l[j].SourceNode.Name() 43} 44 45func TestConflictingSharedPrivateSource(t *testing.T) { 46 tests := []struct { 47 name string 48 roots []string 49 edges []annotated 50 expectedConflicts []confl 51 }{ 52 { 53 name: "firstparty", 54 roots: []string{"apacheBin.meta_lic"}, 55 edges: []annotated{ 56 {"apacheBin.meta_lic", "apacheLib.meta_lic", []string{"static"}}, 57 }, 58 expectedConflicts: []confl{}, 59 }, 60 { 61 name: "notice", 62 roots: []string{"mitBin.meta_lic"}, 63 edges: []annotated{ 64 {"mitBin.meta_lic", "mitLib.meta_lic", []string{"static"}}, 65 }, 66 expectedConflicts: []confl{}, 67 }, 68 { 69 name: "lgpl", 70 roots: []string{"lgplBin.meta_lic"}, 71 edges: []annotated{ 72 {"lgplBin.meta_lic", "apacheLib.meta_lic", []string{"static"}}, 73 }, 74 expectedConflicts: []confl{}, 75 }, 76 { 77 name: "proprietaryonrestricted", 78 roots: []string{"proprietary.meta_lic"}, 79 edges: []annotated{ 80 {"proprietary.meta_lic", "gplLib.meta_lic", []string{"static"}}, 81 }, 82 expectedConflicts: []confl{ 83 {"proprietary.meta_lic", "gplLib.meta_lic:restricted", "proprietary.meta_lic:proprietary"}, 84 }, 85 }, 86 { 87 name: "restrictedonproprietary", 88 roots: []string{"gplBin.meta_lic"}, 89 edges: []annotated{ 90 {"gplBin.meta_lic", "proprietary.meta_lic", []string{"static"}}, 91 }, 92 expectedConflicts: []confl{ 93 {"proprietary.meta_lic", "gplBin.meta_lic:restricted", "proprietary.meta_lic:proprietary"}, 94 }, 95 }, 96 } 97 for _, tt := range tests { 98 t.Run(tt.name, func(t *testing.T) { 99 stderr := &bytes.Buffer{} 100 lg, err := toGraph(stderr, tt.roots, tt.edges) 101 if err != nil { 102 t.Errorf("unexpected test data error: got %s, want no error", err) 103 return 104 } 105 expectedConflicts := toConflictList(lg, tt.expectedConflicts) 106 actualConflicts := ConflictingSharedPrivateSource(lg) 107 sort.Sort(byConflict(expectedConflicts)) 108 sort.Sort(byConflict(actualConflicts)) 109 if len(expectedConflicts) != len(actualConflicts) { 110 t.Errorf("unexpected number of share/privacy conflicts: got %v with %d conflicts, want %v with %d conflicts", 111 actualConflicts, len(actualConflicts), expectedConflicts, len(expectedConflicts)) 112 } else { 113 for i := 0; i < len(actualConflicts); i++ { 114 if !actualConflicts[i].IsEqualTo(expectedConflicts[i]) { 115 t.Errorf("unexpected share/privacy conflict at element %d: got %q, want %q", 116 i, actualConflicts[i].Error(), expectedConflicts[i].Error()) 117 } 118 } 119 } 120 121 }) 122 } 123} 124