1*9e94795aSAndroid Build Coastguard Worker// Copyright 2021 Google LLC 2*9e94795aSAndroid Build Coastguard Worker// 3*9e94795aSAndroid Build Coastguard Worker// Licensed under the Apache License, Version 2.0 (the "License"); 4*9e94795aSAndroid Build Coastguard Worker// you may not use this file except in compliance with the License. 5*9e94795aSAndroid Build Coastguard Worker// You may obtain a copy of the License at 6*9e94795aSAndroid Build Coastguard Worker// 7*9e94795aSAndroid Build Coastguard Worker// http://www.apache.org/licenses/LICENSE-2.0 8*9e94795aSAndroid Build Coastguard Worker// 9*9e94795aSAndroid Build Coastguard Worker// Unless required by applicable law or agreed to in writing, software 10*9e94795aSAndroid Build Coastguard Worker// distributed under the License is distributed on an "AS IS" BASIS, 11*9e94795aSAndroid Build Coastguard Worker// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12*9e94795aSAndroid Build Coastguard Worker// See the License for the specific language governing permissions and 13*9e94795aSAndroid Build Coastguard Worker// limitations under the License. 14*9e94795aSAndroid Build Coastguard Worker 15*9e94795aSAndroid Build Coastguard Workerpackage compliance 16*9e94795aSAndroid Build Coastguard Worker 17*9e94795aSAndroid Build Coastguard Workerimport ( 18*9e94795aSAndroid Build Coastguard Worker "bytes" 19*9e94795aSAndroid Build Coastguard Worker "testing" 20*9e94795aSAndroid Build Coastguard Worker) 21*9e94795aSAndroid Build Coastguard Worker 22*9e94795aSAndroid Build Coastguard Workerfunc TestResolveSourceSharing(t *testing.T) { 23*9e94795aSAndroid Build Coastguard Worker tests := []struct { 24*9e94795aSAndroid Build Coastguard Worker name string 25*9e94795aSAndroid Build Coastguard Worker roots []string 26*9e94795aSAndroid Build Coastguard Worker edges []annotated 27*9e94795aSAndroid Build Coastguard Worker expectedResolutions []res 28*9e94795aSAndroid Build Coastguard Worker }{ 29*9e94795aSAndroid Build Coastguard Worker { 30*9e94795aSAndroid Build Coastguard Worker name: "independentmodulerestricted", 31*9e94795aSAndroid Build Coastguard Worker roots: []string{"apacheBin.meta_lic"}, 32*9e94795aSAndroid Build Coastguard Worker edges: []annotated{ 33*9e94795aSAndroid Build Coastguard Worker {"apacheBin.meta_lic", "gplWithClasspathException.meta_lic", []string{"dynamic"}}, 34*9e94795aSAndroid Build Coastguard Worker }, 35*9e94795aSAndroid Build Coastguard Worker expectedResolutions: []res{}, 36*9e94795aSAndroid Build Coastguard Worker }, 37*9e94795aSAndroid Build Coastguard Worker { 38*9e94795aSAndroid Build Coastguard Worker name: "independentmodulerestrictedshipped", 39*9e94795aSAndroid Build Coastguard Worker roots: []string{"apacheBin.meta_lic", "gplWithClasspathException.meta_lic"}, 40*9e94795aSAndroid Build Coastguard Worker edges: []annotated{ 41*9e94795aSAndroid Build Coastguard Worker {"apacheBin.meta_lic", "gplWithClasspathException.meta_lic", []string{"dynamic"}}, 42*9e94795aSAndroid Build Coastguard Worker }, 43*9e94795aSAndroid Build Coastguard Worker expectedResolutions: []res{}, 44*9e94795aSAndroid Build Coastguard Worker }, 45*9e94795aSAndroid Build Coastguard Worker { 46*9e94795aSAndroid Build Coastguard Worker name: "independentmodulestaticrestricted", 47*9e94795aSAndroid Build Coastguard Worker roots: []string{"apacheBin.meta_lic"}, 48*9e94795aSAndroid Build Coastguard Worker edges: []annotated{ 49*9e94795aSAndroid Build Coastguard Worker {"apacheBin.meta_lic", "gplWithClasspathException.meta_lic", []string{"static"}}, 50*9e94795aSAndroid Build Coastguard Worker }, 51*9e94795aSAndroid Build Coastguard Worker expectedResolutions: []res{}, 52*9e94795aSAndroid Build Coastguard Worker }, 53*9e94795aSAndroid Build Coastguard Worker { 54*9e94795aSAndroid Build Coastguard Worker name: "dependentmodulerestricted", 55*9e94795aSAndroid Build Coastguard Worker roots: []string{"dependentModule.meta_lic"}, 56*9e94795aSAndroid Build Coastguard Worker edges: []annotated{ 57*9e94795aSAndroid Build Coastguard Worker {"dependentModule.meta_lic", "gplWithClasspathException.meta_lic", []string{"dynamic"}}, 58*9e94795aSAndroid Build Coastguard Worker }, 59*9e94795aSAndroid Build Coastguard Worker expectedResolutions: []res{}, 60*9e94795aSAndroid Build Coastguard Worker }, 61*9e94795aSAndroid Build Coastguard Worker { 62*9e94795aSAndroid Build Coastguard Worker name: "dependentmodulerestrictedshipclasspath", 63*9e94795aSAndroid Build Coastguard Worker roots: []string{"dependentModule.meta_lic", "gplWithClasspathException.meta_lic"}, 64*9e94795aSAndroid Build Coastguard Worker edges: []annotated{ 65*9e94795aSAndroid Build Coastguard Worker {"dependentModule.meta_lic", "gplWithClasspathException.meta_lic", []string{"dynamic"}}, 66*9e94795aSAndroid Build Coastguard Worker }, 67*9e94795aSAndroid Build Coastguard Worker expectedResolutions: []res{}, 68*9e94795aSAndroid Build Coastguard Worker }, 69*9e94795aSAndroid Build Coastguard Worker { 70*9e94795aSAndroid Build Coastguard Worker name: "lgplonfprestricted", 71*9e94795aSAndroid Build Coastguard Worker roots: []string{"lgplBin.meta_lic"}, 72*9e94795aSAndroid Build Coastguard Worker edges: []annotated{ 73*9e94795aSAndroid Build Coastguard Worker {"lgplBin.meta_lic", "apacheLib.meta_lic", []string{"static"}}, 74*9e94795aSAndroid Build Coastguard Worker }, 75*9e94795aSAndroid Build Coastguard Worker expectedResolutions: []res{ 76*9e94795aSAndroid Build Coastguard Worker {"lgplBin.meta_lic", "lgplBin.meta_lic", "restricted_if_statically_linked"}, 77*9e94795aSAndroid Build Coastguard Worker {"lgplBin.meta_lic", "apacheLib.meta_lic", "restricted_if_statically_linked"}, 78*9e94795aSAndroid Build Coastguard Worker }, 79*9e94795aSAndroid Build Coastguard Worker }, 80*9e94795aSAndroid Build Coastguard Worker { 81*9e94795aSAndroid Build Coastguard Worker name: "lgplonfpdynamicrestricted", 82*9e94795aSAndroid Build Coastguard Worker roots: []string{"lgplBin.meta_lic"}, 83*9e94795aSAndroid Build Coastguard Worker edges: []annotated{ 84*9e94795aSAndroid Build Coastguard Worker {"lgplBin.meta_lic", "apacheLib.meta_lic", []string{"dynamic"}}, 85*9e94795aSAndroid Build Coastguard Worker }, 86*9e94795aSAndroid Build Coastguard Worker expectedResolutions: []res{ 87*9e94795aSAndroid Build Coastguard Worker {"lgplBin.meta_lic", "lgplBin.meta_lic", "restricted_if_statically_linked"}, 88*9e94795aSAndroid Build Coastguard Worker }, 89*9e94795aSAndroid Build Coastguard Worker }, 90*9e94795aSAndroid Build Coastguard Worker { 91*9e94795aSAndroid Build Coastguard Worker name: "lgplonfpdynamicrestrictedshiplib", 92*9e94795aSAndroid Build Coastguard Worker roots: []string{"lgplBin.meta_lic", "apacheLib.meta_lic"}, 93*9e94795aSAndroid Build Coastguard Worker edges: []annotated{ 94*9e94795aSAndroid Build Coastguard Worker {"lgplBin.meta_lic", "apacheLib.meta_lic", []string{"dynamic"}}, 95*9e94795aSAndroid Build Coastguard Worker }, 96*9e94795aSAndroid Build Coastguard Worker expectedResolutions: []res{ 97*9e94795aSAndroid Build Coastguard Worker {"lgplBin.meta_lic", "lgplBin.meta_lic", "restricted_if_statically_linked"}, 98*9e94795aSAndroid Build Coastguard Worker }, 99*9e94795aSAndroid Build Coastguard Worker }, 100*9e94795aSAndroid Build Coastguard Worker { 101*9e94795aSAndroid Build Coastguard Worker name: "gplonfprestricted", 102*9e94795aSAndroid Build Coastguard Worker roots: []string{"gplBin.meta_lic"}, 103*9e94795aSAndroid Build Coastguard Worker edges: []annotated{ 104*9e94795aSAndroid Build Coastguard Worker {"gplBin.meta_lic", "apacheLib.meta_lic", []string{"static"}}, 105*9e94795aSAndroid Build Coastguard Worker }, 106*9e94795aSAndroid Build Coastguard Worker expectedResolutions: []res{ 107*9e94795aSAndroid Build Coastguard Worker {"gplBin.meta_lic", "gplBin.meta_lic", "restricted"}, 108*9e94795aSAndroid Build Coastguard Worker {"gplBin.meta_lic", "apacheLib.meta_lic", "restricted"}, 109*9e94795aSAndroid Build Coastguard Worker }, 110*9e94795aSAndroid Build Coastguard Worker }, 111*9e94795aSAndroid Build Coastguard Worker { 112*9e94795aSAndroid Build Coastguard Worker name: "gplcontainerrestricted", 113*9e94795aSAndroid Build Coastguard Worker roots: []string{"gplContainer.meta_lic"}, 114*9e94795aSAndroid Build Coastguard Worker edges: []annotated{ 115*9e94795aSAndroid Build Coastguard Worker {"gplContainer.meta_lic", "apacheLib.meta_lic", []string{"static"}}, 116*9e94795aSAndroid Build Coastguard Worker }, 117*9e94795aSAndroid Build Coastguard Worker expectedResolutions: []res{ 118*9e94795aSAndroid Build Coastguard Worker {"gplContainer.meta_lic", "gplContainer.meta_lic", "restricted"}, 119*9e94795aSAndroid Build Coastguard Worker {"gplContainer.meta_lic", "apacheLib.meta_lic", "restricted"}, 120*9e94795aSAndroid Build Coastguard Worker {"apacheLib.meta_lic", "apacheLib.meta_lic", "restricted"}, 121*9e94795aSAndroid Build Coastguard Worker }, 122*9e94795aSAndroid Build Coastguard Worker }, 123*9e94795aSAndroid Build Coastguard Worker { 124*9e94795aSAndroid Build Coastguard Worker name: "gploncontainerrestricted", 125*9e94795aSAndroid Build Coastguard Worker roots: []string{"apacheContainer.meta_lic"}, 126*9e94795aSAndroid Build Coastguard Worker edges: []annotated{ 127*9e94795aSAndroid Build Coastguard Worker {"apacheContainer.meta_lic", "apacheLib.meta_lic", []string{"static"}}, 128*9e94795aSAndroid Build Coastguard Worker {"apacheContainer.meta_lic", "gplLib.meta_lic", []string{"static"}}, 129*9e94795aSAndroid Build Coastguard Worker }, 130*9e94795aSAndroid Build Coastguard Worker expectedResolutions: []res{ 131*9e94795aSAndroid Build Coastguard Worker {"apacheContainer.meta_lic", "apacheContainer.meta_lic", "restricted"}, 132*9e94795aSAndroid Build Coastguard Worker {"apacheContainer.meta_lic", "gplLib.meta_lic", "restricted"}, 133*9e94795aSAndroid Build Coastguard Worker {"gplLib.meta_lic", "gplLib.meta_lic", "restricted"}, 134*9e94795aSAndroid Build Coastguard Worker }, 135*9e94795aSAndroid Build Coastguard Worker }, 136*9e94795aSAndroid Build Coastguard Worker { 137*9e94795aSAndroid Build Coastguard Worker name: "gplonbinrestricted", 138*9e94795aSAndroid Build Coastguard Worker roots: []string{"apacheBin.meta_lic"}, 139*9e94795aSAndroid Build Coastguard Worker edges: []annotated{ 140*9e94795aSAndroid Build Coastguard Worker {"apacheBin.meta_lic", "apacheLib.meta_lic", []string{"static"}}, 141*9e94795aSAndroid Build Coastguard Worker {"apacheBin.meta_lic", "gplLib.meta_lic", []string{"static"}}, 142*9e94795aSAndroid Build Coastguard Worker }, 143*9e94795aSAndroid Build Coastguard Worker expectedResolutions: []res{ 144*9e94795aSAndroid Build Coastguard Worker {"apacheBin.meta_lic", "apacheBin.meta_lic", "restricted"}, 145*9e94795aSAndroid Build Coastguard Worker {"apacheBin.meta_lic", "gplLib.meta_lic", "restricted"}, 146*9e94795aSAndroid Build Coastguard Worker {"apacheBin.meta_lic", "apacheLib.meta_lic", "restricted"}, 147*9e94795aSAndroid Build Coastguard Worker }, 148*9e94795aSAndroid Build Coastguard Worker }, 149*9e94795aSAndroid Build Coastguard Worker { 150*9e94795aSAndroid Build Coastguard Worker name: "gplonfpdynamicrestricted", 151*9e94795aSAndroid Build Coastguard Worker roots: []string{"gplBin.meta_lic"}, 152*9e94795aSAndroid Build Coastguard Worker edges: []annotated{ 153*9e94795aSAndroid Build Coastguard Worker {"gplBin.meta_lic", "apacheLib.meta_lic", []string{"dynamic"}}, 154*9e94795aSAndroid Build Coastguard Worker }, 155*9e94795aSAndroid Build Coastguard Worker expectedResolutions: []res{ 156*9e94795aSAndroid Build Coastguard Worker {"gplBin.meta_lic", "gplBin.meta_lic", "restricted"}, 157*9e94795aSAndroid Build Coastguard Worker }, 158*9e94795aSAndroid Build Coastguard Worker }, 159*9e94795aSAndroid Build Coastguard Worker { 160*9e94795aSAndroid Build Coastguard Worker name: "gplonfpdynamicrestrictedshiplib", 161*9e94795aSAndroid Build Coastguard Worker roots: []string{"gplBin.meta_lic", "apacheLib.meta_lic"}, 162*9e94795aSAndroid Build Coastguard Worker edges: []annotated{ 163*9e94795aSAndroid Build Coastguard Worker {"gplBin.meta_lic", "apacheLib.meta_lic", []string{"dynamic"}}, 164*9e94795aSAndroid Build Coastguard Worker }, 165*9e94795aSAndroid Build Coastguard Worker expectedResolutions: []res{ 166*9e94795aSAndroid Build Coastguard Worker {"gplBin.meta_lic", "gplBin.meta_lic", "restricted"}, 167*9e94795aSAndroid Build Coastguard Worker {"gplBin.meta_lic", "apacheLib.meta_lic", "restricted"}, 168*9e94795aSAndroid Build Coastguard Worker {"apacheLib.meta_lic", "apacheLib.meta_lic", "restricted"}, 169*9e94795aSAndroid Build Coastguard Worker }, 170*9e94795aSAndroid Build Coastguard Worker }, 171*9e94795aSAndroid Build Coastguard Worker { 172*9e94795aSAndroid Build Coastguard Worker name: "independentmodulereverserestricted", 173*9e94795aSAndroid Build Coastguard Worker roots: []string{"gplWithClasspathException.meta_lic"}, 174*9e94795aSAndroid Build Coastguard Worker edges: []annotated{ 175*9e94795aSAndroid Build Coastguard Worker {"gplWithClasspathException.meta_lic", "apacheBin.meta_lic", []string{"dynamic"}}, 176*9e94795aSAndroid Build Coastguard Worker }, 177*9e94795aSAndroid Build Coastguard Worker expectedResolutions: []res{}, 178*9e94795aSAndroid Build Coastguard Worker }, 179*9e94795aSAndroid Build Coastguard Worker { 180*9e94795aSAndroid Build Coastguard Worker name: "independentmodulereversestaticrestricted", 181*9e94795aSAndroid Build Coastguard Worker roots: []string{"gplWithClasspathException.meta_lic"}, 182*9e94795aSAndroid Build Coastguard Worker edges: []annotated{ 183*9e94795aSAndroid Build Coastguard Worker {"gplWithClasspathException.meta_lic", "apacheBin.meta_lic", []string{"static"}}, 184*9e94795aSAndroid Build Coastguard Worker }, 185*9e94795aSAndroid Build Coastguard Worker expectedResolutions: []res{}, 186*9e94795aSAndroid Build Coastguard Worker }, 187*9e94795aSAndroid Build Coastguard Worker { 188*9e94795aSAndroid Build Coastguard Worker name: "dependentmodulereverserestricted", 189*9e94795aSAndroid Build Coastguard Worker roots: []string{"gplWithClasspathException.meta_lic"}, 190*9e94795aSAndroid Build Coastguard Worker edges: []annotated{ 191*9e94795aSAndroid Build Coastguard Worker {"gplWithClasspathException.meta_lic", "dependentModule.meta_lic", []string{"dynamic"}}, 192*9e94795aSAndroid Build Coastguard Worker }, 193*9e94795aSAndroid Build Coastguard Worker expectedResolutions: []res{}, 194*9e94795aSAndroid Build Coastguard Worker }, 195*9e94795aSAndroid Build Coastguard Worker { 196*9e94795aSAndroid Build Coastguard Worker name: "dependentmodulereverserestrictedshipdependent", 197*9e94795aSAndroid Build Coastguard Worker roots: []string{"gplWithClasspathException.meta_lic", "dependentModule.meta_lic"}, 198*9e94795aSAndroid Build Coastguard Worker edges: []annotated{ 199*9e94795aSAndroid Build Coastguard Worker {"gplWithClasspathException.meta_lic", "dependentModule.meta_lic", []string{"dynamic"}}, 200*9e94795aSAndroid Build Coastguard Worker }, 201*9e94795aSAndroid Build Coastguard Worker expectedResolutions: []res{}, 202*9e94795aSAndroid Build Coastguard Worker }, 203*9e94795aSAndroid Build Coastguard Worker { 204*9e94795aSAndroid Build Coastguard Worker name: "ponrrestricted", 205*9e94795aSAndroid Build Coastguard Worker roots: []string{"proprietary.meta_lic"}, 206*9e94795aSAndroid Build Coastguard Worker edges: []annotated{ 207*9e94795aSAndroid Build Coastguard Worker {"proprietary.meta_lic", "gplLib.meta_lic", []string{"static"}}, 208*9e94795aSAndroid Build Coastguard Worker }, 209*9e94795aSAndroid Build Coastguard Worker expectedResolutions: []res{ 210*9e94795aSAndroid Build Coastguard Worker {"proprietary.meta_lic", "proprietary.meta_lic", "restricted"}, 211*9e94795aSAndroid Build Coastguard Worker {"proprietary.meta_lic", "gplLib.meta_lic", "restricted"}, 212*9e94795aSAndroid Build Coastguard Worker }, 213*9e94795aSAndroid Build Coastguard Worker }, 214*9e94795aSAndroid Build Coastguard Worker { 215*9e94795aSAndroid Build Coastguard Worker name: "ronprestricted", 216*9e94795aSAndroid Build Coastguard Worker roots: []string{"gplBin.meta_lic"}, 217*9e94795aSAndroid Build Coastguard Worker edges: []annotated{ 218*9e94795aSAndroid Build Coastguard Worker {"gplBin.meta_lic", "proprietary.meta_lic", []string{"static"}}, 219*9e94795aSAndroid Build Coastguard Worker }, 220*9e94795aSAndroid Build Coastguard Worker expectedResolutions: []res{ 221*9e94795aSAndroid Build Coastguard Worker {"gplBin.meta_lic", "gplBin.meta_lic", "restricted"}, 222*9e94795aSAndroid Build Coastguard Worker {"gplBin.meta_lic", "proprietary.meta_lic", "restricted"}, 223*9e94795aSAndroid Build Coastguard Worker }, 224*9e94795aSAndroid Build Coastguard Worker }, 225*9e94795aSAndroid Build Coastguard Worker { 226*9e94795aSAndroid Build Coastguard Worker name: "noticeonb_e_orestricted", 227*9e94795aSAndroid Build Coastguard Worker roots: []string{"mitBin.meta_lic"}, 228*9e94795aSAndroid Build Coastguard Worker edges: []annotated{ 229*9e94795aSAndroid Build Coastguard Worker {"mitBin.meta_lic", "by_exception.meta_lic", []string{"static"}}, 230*9e94795aSAndroid Build Coastguard Worker }, 231*9e94795aSAndroid Build Coastguard Worker expectedResolutions: []res{}, 232*9e94795aSAndroid Build Coastguard Worker }, 233*9e94795aSAndroid Build Coastguard Worker { 234*9e94795aSAndroid Build Coastguard Worker name: "b_e_oonnoticerestricted", 235*9e94795aSAndroid Build Coastguard Worker roots: []string{"by_exception.meta_lic"}, 236*9e94795aSAndroid Build Coastguard Worker edges: []annotated{ 237*9e94795aSAndroid Build Coastguard Worker {"by_exception.meta_lic", "mitLib.meta_lic", []string{"static"}}, 238*9e94795aSAndroid Build Coastguard Worker }, 239*9e94795aSAndroid Build Coastguard Worker expectedResolutions: []res{}, 240*9e94795aSAndroid Build Coastguard Worker }, 241*9e94795aSAndroid Build Coastguard Worker { 242*9e94795aSAndroid Build Coastguard Worker name: "noticeonreciprecip", 243*9e94795aSAndroid Build Coastguard Worker roots: []string{"mitBin.meta_lic"}, 244*9e94795aSAndroid Build Coastguard Worker edges: []annotated{ 245*9e94795aSAndroid Build Coastguard Worker {"mitBin.meta_lic", "mplLib.meta_lic", []string{"static"}}, 246*9e94795aSAndroid Build Coastguard Worker }, 247*9e94795aSAndroid Build Coastguard Worker expectedResolutions: []res{ 248*9e94795aSAndroid Build Coastguard Worker {"mitBin.meta_lic", "mplLib.meta_lic", "reciprocal"}, 249*9e94795aSAndroid Build Coastguard Worker }, 250*9e94795aSAndroid Build Coastguard Worker }, 251*9e94795aSAndroid Build Coastguard Worker { 252*9e94795aSAndroid Build Coastguard Worker name: "reciponnoticerecip", 253*9e94795aSAndroid Build Coastguard Worker roots: []string{"mplBin.meta_lic"}, 254*9e94795aSAndroid Build Coastguard Worker edges: []annotated{ 255*9e94795aSAndroid Build Coastguard Worker {"mplBin.meta_lic", "mitLib.meta_lic", []string{"static"}}, 256*9e94795aSAndroid Build Coastguard Worker }, 257*9e94795aSAndroid Build Coastguard Worker expectedResolutions: []res{ 258*9e94795aSAndroid Build Coastguard Worker {"mplBin.meta_lic", "mplBin.meta_lic", "reciprocal"}, 259*9e94795aSAndroid Build Coastguard Worker }, 260*9e94795aSAndroid Build Coastguard Worker }, 261*9e94795aSAndroid Build Coastguard Worker } 262*9e94795aSAndroid Build Coastguard Worker for _, tt := range tests { 263*9e94795aSAndroid Build Coastguard Worker t.Run(tt.name, func(t *testing.T) { 264*9e94795aSAndroid Build Coastguard Worker stderr := &bytes.Buffer{} 265*9e94795aSAndroid Build Coastguard Worker lg, err := toGraph(stderr, tt.roots, tt.edges) 266*9e94795aSAndroid Build Coastguard Worker if err != nil { 267*9e94795aSAndroid Build Coastguard Worker t.Errorf("unexpected test data error: got %s, want no error", err) 268*9e94795aSAndroid Build Coastguard Worker return 269*9e94795aSAndroid Build Coastguard Worker } 270*9e94795aSAndroid Build Coastguard Worker expectedRs := toResolutionSet(lg, tt.expectedResolutions) 271*9e94795aSAndroid Build Coastguard Worker actualRs := ResolveSourceSharing(lg) 272*9e94795aSAndroid Build Coastguard Worker checkResolves(actualRs, expectedRs, t) 273*9e94795aSAndroid Build Coastguard Worker }) 274*9e94795aSAndroid Build Coastguard Worker } 275*9e94795aSAndroid Build Coastguard Worker} 276