xref: /aosp_15_r20/build/make/tools/compliance/projectmetadata/projectmetadata_test.go (revision 9e94795a3d4ef5c1d47486f9a02bb378756cea8a)
1*9e94795aSAndroid Build Coastguard Worker// Copyright 2022 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 projectmetadata
16*9e94795aSAndroid Build Coastguard Worker
17*9e94795aSAndroid Build Coastguard Workerimport (
18*9e94795aSAndroid Build Coastguard Worker	"fmt"
19*9e94795aSAndroid Build Coastguard Worker	"strings"
20*9e94795aSAndroid Build Coastguard Worker	"testing"
21*9e94795aSAndroid Build Coastguard Worker
22*9e94795aSAndroid Build Coastguard Worker	"android/soong/compliance/project_metadata_proto"
23*9e94795aSAndroid Build Coastguard Worker	"android/soong/tools/compliance/testfs"
24*9e94795aSAndroid Build Coastguard Worker)
25*9e94795aSAndroid Build Coastguard Worker
26*9e94795aSAndroid Build Coastguard Workerconst (
27*9e94795aSAndroid Build Coastguard Worker	// EMPTY represents a METADATA file with no recognized fields
28*9e94795aSAndroid Build Coastguard Worker	EMPTY = ``
29*9e94795aSAndroid Build Coastguard Worker
30*9e94795aSAndroid Build Coastguard Worker	// INVALID_NAME represents a METADATA file with the wrong type of name
31*9e94795aSAndroid Build Coastguard Worker	INVALID_NAME = `name: a library\n`
32*9e94795aSAndroid Build Coastguard Worker
33*9e94795aSAndroid Build Coastguard Worker	// INVALID_DESCRIPTION represents a METADATA file with the wrong type of description
34*9e94795aSAndroid Build Coastguard Worker	INVALID_DESCRIPTION = `description: unquoted text\n`
35*9e94795aSAndroid Build Coastguard Worker
36*9e94795aSAndroid Build Coastguard Worker	// INVALID_VERSION represents a METADATA file with the wrong type of version
37*9e94795aSAndroid Build Coastguard Worker	INVALID_VERSION = `third_party { version: 1 }`
38*9e94795aSAndroid Build Coastguard Worker
39*9e94795aSAndroid Build Coastguard Worker	// MY_LIB_1_0 represents a METADATA file for version 1.0 of mylib
40*9e94795aSAndroid Build Coastguard Worker	MY_LIB_1_0 = `name: "mylib" description: "my library" third_party { version: "1.0" }`
41*9e94795aSAndroid Build Coastguard Worker
42*9e94795aSAndroid Build Coastguard Worker	// NO_NAME_0_1 represents a METADATA file with a description but no name
43*9e94795aSAndroid Build Coastguard Worker	NO_NAME_0_1 = `description: "my library" third_party { version: "0.1" }`
44*9e94795aSAndroid Build Coastguard Worker
45*9e94795aSAndroid Build Coastguard Worker	// URL values per type
46*9e94795aSAndroid Build Coastguard Worker	GIT_URL          = "http://example.github.com/my_lib"
47*9e94795aSAndroid Build Coastguard Worker	SVN_URL          = "http://example.svn.com/my_lib"
48*9e94795aSAndroid Build Coastguard Worker	HG_URL           = "http://example.hg.com/my_lib"
49*9e94795aSAndroid Build Coastguard Worker	DARCS_URL        = "http://example.darcs.com/my_lib"
50*9e94795aSAndroid Build Coastguard Worker	PIPER_URL        = "http://google3/third_party/my/package"
51*9e94795aSAndroid Build Coastguard Worker	HOMEPAGE_URL     = "http://example.com/homepage"
52*9e94795aSAndroid Build Coastguard Worker	OTHER_URL        = "http://google.com/"
53*9e94795aSAndroid Build Coastguard Worker	ARCHIVE_URL      = "http://ftp.example.com/"
54*9e94795aSAndroid Build Coastguard Worker	LOCAL_SOURCE_URL = "https://android.googlesource.com/platform/external/apache-http/"
55*9e94795aSAndroid Build Coastguard Worker)
56*9e94795aSAndroid Build Coastguard Worker
57*9e94795aSAndroid Build Coastguard Worker// libWithUrl returns a METADATA file with the right download url
58*9e94795aSAndroid Build Coastguard Workerfunc libWithUrl(urlTypes ...string) string {
59*9e94795aSAndroid Build Coastguard Worker	var sb strings.Builder
60*9e94795aSAndroid Build Coastguard Worker
61*9e94795aSAndroid Build Coastguard Worker	fmt.Fprintln(&sb, `name: "mylib" description: "my library"
62*9e94795aSAndroid Build Coastguard Worker	 third_party {
63*9e94795aSAndroid Build Coastguard Worker	 	version: "1.0"`)
64*9e94795aSAndroid Build Coastguard Worker
65*9e94795aSAndroid Build Coastguard Worker	for _, urltype := range urlTypes {
66*9e94795aSAndroid Build Coastguard Worker		var urlValue string
67*9e94795aSAndroid Build Coastguard Worker		switch urltype {
68*9e94795aSAndroid Build Coastguard Worker		case "GIT":
69*9e94795aSAndroid Build Coastguard Worker			urlValue = GIT_URL
70*9e94795aSAndroid Build Coastguard Worker		case "SVN":
71*9e94795aSAndroid Build Coastguard Worker			urlValue = SVN_URL
72*9e94795aSAndroid Build Coastguard Worker		case "HG":
73*9e94795aSAndroid Build Coastguard Worker			urlValue = HG_URL
74*9e94795aSAndroid Build Coastguard Worker		case "DARCS":
75*9e94795aSAndroid Build Coastguard Worker			urlValue = DARCS_URL
76*9e94795aSAndroid Build Coastguard Worker		case "PIPER":
77*9e94795aSAndroid Build Coastguard Worker			urlValue = PIPER_URL
78*9e94795aSAndroid Build Coastguard Worker		case "HOMEPAGE":
79*9e94795aSAndroid Build Coastguard Worker			urlValue = HOMEPAGE_URL
80*9e94795aSAndroid Build Coastguard Worker		case "OTHER":
81*9e94795aSAndroid Build Coastguard Worker			urlValue = OTHER_URL
82*9e94795aSAndroid Build Coastguard Worker		case "ARCHIVE":
83*9e94795aSAndroid Build Coastguard Worker			urlValue = ARCHIVE_URL
84*9e94795aSAndroid Build Coastguard Worker		case "LOCAL_SOURCE":
85*9e94795aSAndroid Build Coastguard Worker			urlValue = LOCAL_SOURCE_URL
86*9e94795aSAndroid Build Coastguard Worker		default:
87*9e94795aSAndroid Build Coastguard Worker			panic(fmt.Errorf("unknown url type: %q. Please update libWithUrl() in build/make/tools/compliance/projectmetadata/projectmetadata_test.go", urltype))
88*9e94795aSAndroid Build Coastguard Worker		}
89*9e94795aSAndroid Build Coastguard Worker		fmt.Fprintf(&sb, "  url { type: %s value: %q }\n", urltype, urlValue)
90*9e94795aSAndroid Build Coastguard Worker	}
91*9e94795aSAndroid Build Coastguard Worker	fmt.Fprintln(&sb, `}`)
92*9e94795aSAndroid Build Coastguard Worker
93*9e94795aSAndroid Build Coastguard Worker	return sb.String()
94*9e94795aSAndroid Build Coastguard Worker}
95*9e94795aSAndroid Build Coastguard Worker
96*9e94795aSAndroid Build Coastguard Workerfunc TestVerifyAllUrlTypes(t *testing.T) {
97*9e94795aSAndroid Build Coastguard Worker	t.Run("verifyAllUrlTypes", func(t *testing.T) {
98*9e94795aSAndroid Build Coastguard Worker		types := make([]string, 0, len(project_metadata_proto.URL_Type_value))
99*9e94795aSAndroid Build Coastguard Worker		for t := range project_metadata_proto.URL_Type_value {
100*9e94795aSAndroid Build Coastguard Worker			types = append(types, t)
101*9e94795aSAndroid Build Coastguard Worker		}
102*9e94795aSAndroid Build Coastguard Worker		libWithUrl(types...)
103*9e94795aSAndroid Build Coastguard Worker	})
104*9e94795aSAndroid Build Coastguard Worker}
105*9e94795aSAndroid Build Coastguard Worker
106*9e94795aSAndroid Build Coastguard Workerfunc TestUnknownPanics(t *testing.T) {
107*9e94795aSAndroid Build Coastguard Worker	t.Run("Unknown panics", func(t *testing.T) {
108*9e94795aSAndroid Build Coastguard Worker		defer func() {
109*9e94795aSAndroid Build Coastguard Worker			if r := recover(); r == nil {
110*9e94795aSAndroid Build Coastguard Worker				t.Errorf("unexpected success: got no error, want panic")
111*9e94795aSAndroid Build Coastguard Worker			}
112*9e94795aSAndroid Build Coastguard Worker		}()
113*9e94795aSAndroid Build Coastguard Worker		libWithUrl("SOME WILD VALUE THAT DOES NOT EXIST")
114*9e94795aSAndroid Build Coastguard Worker	})
115*9e94795aSAndroid Build Coastguard Worker}
116*9e94795aSAndroid Build Coastguard Worker
117*9e94795aSAndroid Build Coastguard Workerfunc TestReadMetadataForProjects(t *testing.T) {
118*9e94795aSAndroid Build Coastguard Worker	tests := []struct {
119*9e94795aSAndroid Build Coastguard Worker		name          string
120*9e94795aSAndroid Build Coastguard Worker		fs            *testfs.TestFS
121*9e94795aSAndroid Build Coastguard Worker		projects      []string
122*9e94795aSAndroid Build Coastguard Worker		expectedError string
123*9e94795aSAndroid Build Coastguard Worker		expected      []pmeta
124*9e94795aSAndroid Build Coastguard Worker	}{
125*9e94795aSAndroid Build Coastguard Worker		{
126*9e94795aSAndroid Build Coastguard Worker			name: "trivial",
127*9e94795aSAndroid Build Coastguard Worker			fs: &testfs.TestFS{
128*9e94795aSAndroid Build Coastguard Worker				"/a/METADATA": []byte("name: \"Android\"\n"),
129*9e94795aSAndroid Build Coastguard Worker			},
130*9e94795aSAndroid Build Coastguard Worker			projects: []string{"/a"},
131*9e94795aSAndroid Build Coastguard Worker			expected: []pmeta{{
132*9e94795aSAndroid Build Coastguard Worker				project:       "/a",
133*9e94795aSAndroid Build Coastguard Worker				versionedName: "Android",
134*9e94795aSAndroid Build Coastguard Worker				name:          "Android",
135*9e94795aSAndroid Build Coastguard Worker				version:       "",
136*9e94795aSAndroid Build Coastguard Worker				downloadUrl:   "",
137*9e94795aSAndroid Build Coastguard Worker			}},
138*9e94795aSAndroid Build Coastguard Worker		},
139*9e94795aSAndroid Build Coastguard Worker		{
140*9e94795aSAndroid Build Coastguard Worker			name: "versioned",
141*9e94795aSAndroid Build Coastguard Worker			fs: &testfs.TestFS{
142*9e94795aSAndroid Build Coastguard Worker				"/a/METADATA": []byte(MY_LIB_1_0),
143*9e94795aSAndroid Build Coastguard Worker			},
144*9e94795aSAndroid Build Coastguard Worker			projects: []string{"/a"},
145*9e94795aSAndroid Build Coastguard Worker			expected: []pmeta{{
146*9e94795aSAndroid Build Coastguard Worker				project:       "/a",
147*9e94795aSAndroid Build Coastguard Worker				versionedName: "mylib_v_1.0",
148*9e94795aSAndroid Build Coastguard Worker				name:          "mylib",
149*9e94795aSAndroid Build Coastguard Worker				version:       "1.0",
150*9e94795aSAndroid Build Coastguard Worker				downloadUrl:   "",
151*9e94795aSAndroid Build Coastguard Worker			}},
152*9e94795aSAndroid Build Coastguard Worker		},
153*9e94795aSAndroid Build Coastguard Worker		{
154*9e94795aSAndroid Build Coastguard Worker			name: "lib_with_homepage",
155*9e94795aSAndroid Build Coastguard Worker			fs: &testfs.TestFS{
156*9e94795aSAndroid Build Coastguard Worker				"/a/METADATA": []byte(libWithUrl("HOMEPAGE")),
157*9e94795aSAndroid Build Coastguard Worker			},
158*9e94795aSAndroid Build Coastguard Worker			projects: []string{"/a"},
159*9e94795aSAndroid Build Coastguard Worker			expected: []pmeta{{
160*9e94795aSAndroid Build Coastguard Worker				project:       "/a",
161*9e94795aSAndroid Build Coastguard Worker				versionedName: "mylib_v_1.0",
162*9e94795aSAndroid Build Coastguard Worker				name:          "mylib",
163*9e94795aSAndroid Build Coastguard Worker				version:       "1.0",
164*9e94795aSAndroid Build Coastguard Worker				downloadUrl:   "",
165*9e94795aSAndroid Build Coastguard Worker			}},
166*9e94795aSAndroid Build Coastguard Worker		},
167*9e94795aSAndroid Build Coastguard Worker		{
168*9e94795aSAndroid Build Coastguard Worker			name: "lib_with_git",
169*9e94795aSAndroid Build Coastguard Worker			fs: &testfs.TestFS{
170*9e94795aSAndroid Build Coastguard Worker				"/a/METADATA": []byte(libWithUrl("GIT")),
171*9e94795aSAndroid Build Coastguard Worker			},
172*9e94795aSAndroid Build Coastguard Worker			projects: []string{"/a"},
173*9e94795aSAndroid Build Coastguard Worker			expected: []pmeta{{
174*9e94795aSAndroid Build Coastguard Worker				project:       "/a",
175*9e94795aSAndroid Build Coastguard Worker				versionedName: "mylib_v_1.0",
176*9e94795aSAndroid Build Coastguard Worker				name:          "mylib",
177*9e94795aSAndroid Build Coastguard Worker				version:       "1.0",
178*9e94795aSAndroid Build Coastguard Worker				downloadUrl:   GIT_URL,
179*9e94795aSAndroid Build Coastguard Worker			}},
180*9e94795aSAndroid Build Coastguard Worker		},
181*9e94795aSAndroid Build Coastguard Worker		{
182*9e94795aSAndroid Build Coastguard Worker			name: "lib_with_svn",
183*9e94795aSAndroid Build Coastguard Worker			fs: &testfs.TestFS{
184*9e94795aSAndroid Build Coastguard Worker				"/a/METADATA": []byte(libWithUrl("SVN")),
185*9e94795aSAndroid Build Coastguard Worker			},
186*9e94795aSAndroid Build Coastguard Worker			projects: []string{"/a"},
187*9e94795aSAndroid Build Coastguard Worker			expected: []pmeta{{
188*9e94795aSAndroid Build Coastguard Worker				project:       "/a",
189*9e94795aSAndroid Build Coastguard Worker				versionedName: "mylib_v_1.0",
190*9e94795aSAndroid Build Coastguard Worker				name:          "mylib",
191*9e94795aSAndroid Build Coastguard Worker				version:       "1.0",
192*9e94795aSAndroid Build Coastguard Worker				downloadUrl:   SVN_URL,
193*9e94795aSAndroid Build Coastguard Worker			}},
194*9e94795aSAndroid Build Coastguard Worker		},
195*9e94795aSAndroid Build Coastguard Worker		{
196*9e94795aSAndroid Build Coastguard Worker			name: "lib_with_hg",
197*9e94795aSAndroid Build Coastguard Worker			fs: &testfs.TestFS{
198*9e94795aSAndroid Build Coastguard Worker				"/a/METADATA": []byte(libWithUrl("HG")),
199*9e94795aSAndroid Build Coastguard Worker			},
200*9e94795aSAndroid Build Coastguard Worker			projects: []string{"/a"},
201*9e94795aSAndroid Build Coastguard Worker			expected: []pmeta{{
202*9e94795aSAndroid Build Coastguard Worker				project:       "/a",
203*9e94795aSAndroid Build Coastguard Worker				versionedName: "mylib_v_1.0",
204*9e94795aSAndroid Build Coastguard Worker				name:          "mylib",
205*9e94795aSAndroid Build Coastguard Worker				version:       "1.0",
206*9e94795aSAndroid Build Coastguard Worker				downloadUrl:   HG_URL,
207*9e94795aSAndroid Build Coastguard Worker			}},
208*9e94795aSAndroid Build Coastguard Worker		},
209*9e94795aSAndroid Build Coastguard Worker		{
210*9e94795aSAndroid Build Coastguard Worker			name: "lib_with_darcs",
211*9e94795aSAndroid Build Coastguard Worker			fs: &testfs.TestFS{
212*9e94795aSAndroid Build Coastguard Worker				"/a/METADATA": []byte(libWithUrl("DARCS")),
213*9e94795aSAndroid Build Coastguard Worker			},
214*9e94795aSAndroid Build Coastguard Worker			projects: []string{"/a"},
215*9e94795aSAndroid Build Coastguard Worker			expected: []pmeta{{
216*9e94795aSAndroid Build Coastguard Worker				project:       "/a",
217*9e94795aSAndroid Build Coastguard Worker				versionedName: "mylib_v_1.0",
218*9e94795aSAndroid Build Coastguard Worker				name:          "mylib",
219*9e94795aSAndroid Build Coastguard Worker				version:       "1.0",
220*9e94795aSAndroid Build Coastguard Worker				downloadUrl:   DARCS_URL,
221*9e94795aSAndroid Build Coastguard Worker			}},
222*9e94795aSAndroid Build Coastguard Worker		},
223*9e94795aSAndroid Build Coastguard Worker		{
224*9e94795aSAndroid Build Coastguard Worker			name: "lib_with_piper",
225*9e94795aSAndroid Build Coastguard Worker			fs: &testfs.TestFS{
226*9e94795aSAndroid Build Coastguard Worker				"/a/METADATA": []byte(libWithUrl("PIPER")),
227*9e94795aSAndroid Build Coastguard Worker			},
228*9e94795aSAndroid Build Coastguard Worker			projects: []string{"/a"},
229*9e94795aSAndroid Build Coastguard Worker			expected: []pmeta{{
230*9e94795aSAndroid Build Coastguard Worker				project:       "/a",
231*9e94795aSAndroid Build Coastguard Worker				versionedName: "mylib_v_1.0",
232*9e94795aSAndroid Build Coastguard Worker				name:          "mylib",
233*9e94795aSAndroid Build Coastguard Worker				version:       "1.0",
234*9e94795aSAndroid Build Coastguard Worker				downloadUrl:   "",
235*9e94795aSAndroid Build Coastguard Worker			}},
236*9e94795aSAndroid Build Coastguard Worker		},
237*9e94795aSAndroid Build Coastguard Worker		{
238*9e94795aSAndroid Build Coastguard Worker			name: "lib_with_other",
239*9e94795aSAndroid Build Coastguard Worker			fs: &testfs.TestFS{
240*9e94795aSAndroid Build Coastguard Worker				"/a/METADATA": []byte(libWithUrl("OTHER")),
241*9e94795aSAndroid Build Coastguard Worker			},
242*9e94795aSAndroid Build Coastguard Worker			projects: []string{"/a"},
243*9e94795aSAndroid Build Coastguard Worker			expected: []pmeta{{
244*9e94795aSAndroid Build Coastguard Worker				project:       "/a",
245*9e94795aSAndroid Build Coastguard Worker				versionedName: "mylib_v_1.0",
246*9e94795aSAndroid Build Coastguard Worker				name:          "mylib",
247*9e94795aSAndroid Build Coastguard Worker				version:       "1.0",
248*9e94795aSAndroid Build Coastguard Worker				downloadUrl:   "",
249*9e94795aSAndroid Build Coastguard Worker			}},
250*9e94795aSAndroid Build Coastguard Worker		},
251*9e94795aSAndroid Build Coastguard Worker		{
252*9e94795aSAndroid Build Coastguard Worker			name: "lib_with_local_source",
253*9e94795aSAndroid Build Coastguard Worker			fs: &testfs.TestFS{
254*9e94795aSAndroid Build Coastguard Worker				"/a/METADATA": []byte(libWithUrl("LOCAL_SOURCE")),
255*9e94795aSAndroid Build Coastguard Worker			},
256*9e94795aSAndroid Build Coastguard Worker			projects: []string{"/a"},
257*9e94795aSAndroid Build Coastguard Worker			expected: []pmeta{{
258*9e94795aSAndroid Build Coastguard Worker				project:       "/a",
259*9e94795aSAndroid Build Coastguard Worker				versionedName: "mylib_v_1.0",
260*9e94795aSAndroid Build Coastguard Worker				name:          "mylib",
261*9e94795aSAndroid Build Coastguard Worker				version:       "1.0",
262*9e94795aSAndroid Build Coastguard Worker				downloadUrl:   "",
263*9e94795aSAndroid Build Coastguard Worker			}},
264*9e94795aSAndroid Build Coastguard Worker		},
265*9e94795aSAndroid Build Coastguard Worker		{
266*9e94795aSAndroid Build Coastguard Worker			name: "lib_with_archive",
267*9e94795aSAndroid Build Coastguard Worker			fs: &testfs.TestFS{
268*9e94795aSAndroid Build Coastguard Worker				"/a/METADATA": []byte(libWithUrl("ARCHIVE")),
269*9e94795aSAndroid Build Coastguard Worker			},
270*9e94795aSAndroid Build Coastguard Worker			projects: []string{"/a"},
271*9e94795aSAndroid Build Coastguard Worker			expected: []pmeta{{
272*9e94795aSAndroid Build Coastguard Worker				project:       "/a",
273*9e94795aSAndroid Build Coastguard Worker				versionedName: "mylib_v_1.0",
274*9e94795aSAndroid Build Coastguard Worker				name:          "mylib",
275*9e94795aSAndroid Build Coastguard Worker				version:       "1.0",
276*9e94795aSAndroid Build Coastguard Worker				downloadUrl:   "",
277*9e94795aSAndroid Build Coastguard Worker			}},
278*9e94795aSAndroid Build Coastguard Worker		},
279*9e94795aSAndroid Build Coastguard Worker		{
280*9e94795aSAndroid Build Coastguard Worker			name: "lib_with_all_downloads",
281*9e94795aSAndroid Build Coastguard Worker			fs: &testfs.TestFS{
282*9e94795aSAndroid Build Coastguard Worker				"/a/METADATA": []byte(libWithUrl("DARCS", "HG", "SVN", "GIT")),
283*9e94795aSAndroid Build Coastguard Worker			},
284*9e94795aSAndroid Build Coastguard Worker			projects: []string{"/a"},
285*9e94795aSAndroid Build Coastguard Worker			expected: []pmeta{{
286*9e94795aSAndroid Build Coastguard Worker				project:       "/a",
287*9e94795aSAndroid Build Coastguard Worker				versionedName: "mylib_v_1.0",
288*9e94795aSAndroid Build Coastguard Worker				name:          "mylib",
289*9e94795aSAndroid Build Coastguard Worker				version:       "1.0",
290*9e94795aSAndroid Build Coastguard Worker				downloadUrl:   GIT_URL,
291*9e94795aSAndroid Build Coastguard Worker			}},
292*9e94795aSAndroid Build Coastguard Worker		},
293*9e94795aSAndroid Build Coastguard Worker		{
294*9e94795aSAndroid Build Coastguard Worker			name: "lib_with_all_downloads_in_different_order",
295*9e94795aSAndroid Build Coastguard Worker			fs: &testfs.TestFS{
296*9e94795aSAndroid Build Coastguard Worker				"/a/METADATA": []byte(libWithUrl("DARCS", "GIT", "SVN", "HG")),
297*9e94795aSAndroid Build Coastguard Worker			},
298*9e94795aSAndroid Build Coastguard Worker			projects: []string{"/a"},
299*9e94795aSAndroid Build Coastguard Worker			expected: []pmeta{{
300*9e94795aSAndroid Build Coastguard Worker				project:       "/a",
301*9e94795aSAndroid Build Coastguard Worker				versionedName: "mylib_v_1.0",
302*9e94795aSAndroid Build Coastguard Worker				name:          "mylib",
303*9e94795aSAndroid Build Coastguard Worker				version:       "1.0",
304*9e94795aSAndroid Build Coastguard Worker				downloadUrl:   GIT_URL,
305*9e94795aSAndroid Build Coastguard Worker			}},
306*9e94795aSAndroid Build Coastguard Worker		},
307*9e94795aSAndroid Build Coastguard Worker		{
308*9e94795aSAndroid Build Coastguard Worker			name: "lib_with_all_but_git",
309*9e94795aSAndroid Build Coastguard Worker			fs: &testfs.TestFS{
310*9e94795aSAndroid Build Coastguard Worker				"/a/METADATA": []byte(libWithUrl("DARCS", "HG", "SVN")),
311*9e94795aSAndroid Build Coastguard Worker			},
312*9e94795aSAndroid Build Coastguard Worker			projects: []string{"/a"},
313*9e94795aSAndroid Build Coastguard Worker			expected: []pmeta{{
314*9e94795aSAndroid Build Coastguard Worker				project:       "/a",
315*9e94795aSAndroid Build Coastguard Worker				versionedName: "mylib_v_1.0",
316*9e94795aSAndroid Build Coastguard Worker				name:          "mylib",
317*9e94795aSAndroid Build Coastguard Worker				version:       "1.0",
318*9e94795aSAndroid Build Coastguard Worker				downloadUrl:   SVN_URL,
319*9e94795aSAndroid Build Coastguard Worker			}},
320*9e94795aSAndroid Build Coastguard Worker		},
321*9e94795aSAndroid Build Coastguard Worker		{
322*9e94795aSAndroid Build Coastguard Worker			name: "lib_with_all_but_git_and_svn",
323*9e94795aSAndroid Build Coastguard Worker			fs: &testfs.TestFS{
324*9e94795aSAndroid Build Coastguard Worker				"/a/METADATA": []byte(libWithUrl("DARCS", "HG")),
325*9e94795aSAndroid Build Coastguard Worker			},
326*9e94795aSAndroid Build Coastguard Worker			projects: []string{"/a"},
327*9e94795aSAndroid Build Coastguard Worker			expected: []pmeta{{
328*9e94795aSAndroid Build Coastguard Worker				project:       "/a",
329*9e94795aSAndroid Build Coastguard Worker				versionedName: "mylib_v_1.0",
330*9e94795aSAndroid Build Coastguard Worker				name:          "mylib",
331*9e94795aSAndroid Build Coastguard Worker				version:       "1.0",
332*9e94795aSAndroid Build Coastguard Worker				downloadUrl:   HG_URL,
333*9e94795aSAndroid Build Coastguard Worker			}},
334*9e94795aSAndroid Build Coastguard Worker		},
335*9e94795aSAndroid Build Coastguard Worker		{
336*9e94795aSAndroid Build Coastguard Worker			name: "lib_with_all_nondownloads_and_git",
337*9e94795aSAndroid Build Coastguard Worker			fs: &testfs.TestFS{
338*9e94795aSAndroid Build Coastguard Worker				"/a/METADATA": []byte(libWithUrl("HOMEPAGE", "LOCAL_SOURCE", "PIPER", "ARCHIVE", "GIT")),
339*9e94795aSAndroid Build Coastguard Worker			},
340*9e94795aSAndroid Build Coastguard Worker			projects: []string{"/a"},
341*9e94795aSAndroid Build Coastguard Worker			expected: []pmeta{{
342*9e94795aSAndroid Build Coastguard Worker				project:       "/a",
343*9e94795aSAndroid Build Coastguard Worker				versionedName: "mylib_v_1.0",
344*9e94795aSAndroid Build Coastguard Worker				name:          "mylib",
345*9e94795aSAndroid Build Coastguard Worker				version:       "1.0",
346*9e94795aSAndroid Build Coastguard Worker				downloadUrl:   GIT_URL,
347*9e94795aSAndroid Build Coastguard Worker			}},
348*9e94795aSAndroid Build Coastguard Worker		},
349*9e94795aSAndroid Build Coastguard Worker		{
350*9e94795aSAndroid Build Coastguard Worker			name: "lib_with_all_nondownloads",
351*9e94795aSAndroid Build Coastguard Worker			fs: &testfs.TestFS{
352*9e94795aSAndroid Build Coastguard Worker				"/a/METADATA": []byte(libWithUrl("HOMEPAGE", "LOCAL_SOURCE", "PIPER", "ARCHIVE")),
353*9e94795aSAndroid Build Coastguard Worker			},
354*9e94795aSAndroid Build Coastguard Worker			projects: []string{"/a"},
355*9e94795aSAndroid Build Coastguard Worker			expected: []pmeta{{
356*9e94795aSAndroid Build Coastguard Worker				project:       "/a",
357*9e94795aSAndroid Build Coastguard Worker				versionedName: "mylib_v_1.0",
358*9e94795aSAndroid Build Coastguard Worker				name:          "mylib",
359*9e94795aSAndroid Build Coastguard Worker				version:       "1.0",
360*9e94795aSAndroid Build Coastguard Worker				downloadUrl:   "",
361*9e94795aSAndroid Build Coastguard Worker			}},
362*9e94795aSAndroid Build Coastguard Worker		},
363*9e94795aSAndroid Build Coastguard Worker		{
364*9e94795aSAndroid Build Coastguard Worker			name: "lib_with_all_nondownloads",
365*9e94795aSAndroid Build Coastguard Worker			fs: &testfs.TestFS{
366*9e94795aSAndroid Build Coastguard Worker				"/a/METADATA": []byte(libWithUrl()),
367*9e94795aSAndroid Build Coastguard Worker			},
368*9e94795aSAndroid Build Coastguard Worker			projects: []string{"/a"},
369*9e94795aSAndroid Build Coastguard Worker			expected: []pmeta{{
370*9e94795aSAndroid Build Coastguard Worker				project:       "/a",
371*9e94795aSAndroid Build Coastguard Worker				versionedName: "mylib_v_1.0",
372*9e94795aSAndroid Build Coastguard Worker				name:          "mylib",
373*9e94795aSAndroid Build Coastguard Worker				version:       "1.0",
374*9e94795aSAndroid Build Coastguard Worker				downloadUrl:   "",
375*9e94795aSAndroid Build Coastguard Worker			}},
376*9e94795aSAndroid Build Coastguard Worker		},
377*9e94795aSAndroid Build Coastguard Worker		{
378*9e94795aSAndroid Build Coastguard Worker			name: "versioneddesc",
379*9e94795aSAndroid Build Coastguard Worker			fs: &testfs.TestFS{
380*9e94795aSAndroid Build Coastguard Worker				"/a/METADATA": []byte(NO_NAME_0_1),
381*9e94795aSAndroid Build Coastguard Worker			},
382*9e94795aSAndroid Build Coastguard Worker			projects: []string{"/a"},
383*9e94795aSAndroid Build Coastguard Worker			expected: []pmeta{{
384*9e94795aSAndroid Build Coastguard Worker				project:       "/a",
385*9e94795aSAndroid Build Coastguard Worker				versionedName: "my library",
386*9e94795aSAndroid Build Coastguard Worker				name:          "",
387*9e94795aSAndroid Build Coastguard Worker				version:       "0.1",
388*9e94795aSAndroid Build Coastguard Worker				downloadUrl:   "",
389*9e94795aSAndroid Build Coastguard Worker			}},
390*9e94795aSAndroid Build Coastguard Worker		},
391*9e94795aSAndroid Build Coastguard Worker		{
392*9e94795aSAndroid Build Coastguard Worker			name: "unterminated",
393*9e94795aSAndroid Build Coastguard Worker			fs: &testfs.TestFS{
394*9e94795aSAndroid Build Coastguard Worker				"/a/METADATA": []byte("name: \"Android\n"),
395*9e94795aSAndroid Build Coastguard Worker			},
396*9e94795aSAndroid Build Coastguard Worker			projects:      []string{"/a"},
397*9e94795aSAndroid Build Coastguard Worker			expectedError: `invalid character '\n' in string`,
398*9e94795aSAndroid Build Coastguard Worker		},
399*9e94795aSAndroid Build Coastguard Worker		{
400*9e94795aSAndroid Build Coastguard Worker			name: "abc",
401*9e94795aSAndroid Build Coastguard Worker			fs: &testfs.TestFS{
402*9e94795aSAndroid Build Coastguard Worker				"/a/METADATA": []byte(EMPTY),
403*9e94795aSAndroid Build Coastguard Worker				"/b/METADATA": []byte(MY_LIB_1_0),
404*9e94795aSAndroid Build Coastguard Worker				"/c/METADATA": []byte(NO_NAME_0_1),
405*9e94795aSAndroid Build Coastguard Worker			},
406*9e94795aSAndroid Build Coastguard Worker			projects: []string{"/a", "/b", "/c"},
407*9e94795aSAndroid Build Coastguard Worker			expected: []pmeta{
408*9e94795aSAndroid Build Coastguard Worker				{
409*9e94795aSAndroid Build Coastguard Worker					project:       "/a",
410*9e94795aSAndroid Build Coastguard Worker					versionedName: "",
411*9e94795aSAndroid Build Coastguard Worker					name:          "",
412*9e94795aSAndroid Build Coastguard Worker					version:       "",
413*9e94795aSAndroid Build Coastguard Worker					downloadUrl:   "",
414*9e94795aSAndroid Build Coastguard Worker				},
415*9e94795aSAndroid Build Coastguard Worker				{
416*9e94795aSAndroid Build Coastguard Worker					project:       "/b",
417*9e94795aSAndroid Build Coastguard Worker					versionedName: "mylib_v_1.0",
418*9e94795aSAndroid Build Coastguard Worker					name:          "mylib",
419*9e94795aSAndroid Build Coastguard Worker					version:       "1.0",
420*9e94795aSAndroid Build Coastguard Worker					downloadUrl:   "",
421*9e94795aSAndroid Build Coastguard Worker				},
422*9e94795aSAndroid Build Coastguard Worker				{
423*9e94795aSAndroid Build Coastguard Worker					project:       "/c",
424*9e94795aSAndroid Build Coastguard Worker					versionedName: "my library",
425*9e94795aSAndroid Build Coastguard Worker					name:          "",
426*9e94795aSAndroid Build Coastguard Worker					version:       "0.1",
427*9e94795aSAndroid Build Coastguard Worker					downloadUrl:   "",
428*9e94795aSAndroid Build Coastguard Worker				},
429*9e94795aSAndroid Build Coastguard Worker			},
430*9e94795aSAndroid Build Coastguard Worker		},
431*9e94795aSAndroid Build Coastguard Worker		{
432*9e94795aSAndroid Build Coastguard Worker			name: "ab",
433*9e94795aSAndroid Build Coastguard Worker			fs: &testfs.TestFS{
434*9e94795aSAndroid Build Coastguard Worker				"/a/METADATA": []byte(EMPTY),
435*9e94795aSAndroid Build Coastguard Worker				"/b/METADATA": []byte(MY_LIB_1_0),
436*9e94795aSAndroid Build Coastguard Worker			},
437*9e94795aSAndroid Build Coastguard Worker			projects: []string{"/a", "/b", "/c"},
438*9e94795aSAndroid Build Coastguard Worker			expected: []pmeta{
439*9e94795aSAndroid Build Coastguard Worker				{
440*9e94795aSAndroid Build Coastguard Worker					project:       "/a",
441*9e94795aSAndroid Build Coastguard Worker					versionedName: "",
442*9e94795aSAndroid Build Coastguard Worker					name:          "",
443*9e94795aSAndroid Build Coastguard Worker					version:       "",
444*9e94795aSAndroid Build Coastguard Worker					downloadUrl:   "",
445*9e94795aSAndroid Build Coastguard Worker				},
446*9e94795aSAndroid Build Coastguard Worker				{
447*9e94795aSAndroid Build Coastguard Worker					project:       "/b",
448*9e94795aSAndroid Build Coastguard Worker					versionedName: "mylib_v_1.0",
449*9e94795aSAndroid Build Coastguard Worker					name:          "mylib",
450*9e94795aSAndroid Build Coastguard Worker					version:       "1.0",
451*9e94795aSAndroid Build Coastguard Worker					downloadUrl:   "",
452*9e94795aSAndroid Build Coastguard Worker				},
453*9e94795aSAndroid Build Coastguard Worker			},
454*9e94795aSAndroid Build Coastguard Worker		},
455*9e94795aSAndroid Build Coastguard Worker		{
456*9e94795aSAndroid Build Coastguard Worker			name: "ac",
457*9e94795aSAndroid Build Coastguard Worker			fs: &testfs.TestFS{
458*9e94795aSAndroid Build Coastguard Worker				"/a/METADATA": []byte(EMPTY),
459*9e94795aSAndroid Build Coastguard Worker				"/c/METADATA": []byte(NO_NAME_0_1),
460*9e94795aSAndroid Build Coastguard Worker			},
461*9e94795aSAndroid Build Coastguard Worker			projects: []string{"/a", "/b", "/c"},
462*9e94795aSAndroid Build Coastguard Worker			expected: []pmeta{
463*9e94795aSAndroid Build Coastguard Worker				{
464*9e94795aSAndroid Build Coastguard Worker					project:       "/a",
465*9e94795aSAndroid Build Coastguard Worker					versionedName: "",
466*9e94795aSAndroid Build Coastguard Worker					name:          "",
467*9e94795aSAndroid Build Coastguard Worker					version:       "",
468*9e94795aSAndroid Build Coastguard Worker					downloadUrl:   "",
469*9e94795aSAndroid Build Coastguard Worker				},
470*9e94795aSAndroid Build Coastguard Worker				{
471*9e94795aSAndroid Build Coastguard Worker					project:       "/c",
472*9e94795aSAndroid Build Coastguard Worker					versionedName: "my library",
473*9e94795aSAndroid Build Coastguard Worker					name:          "",
474*9e94795aSAndroid Build Coastguard Worker					version:       "0.1",
475*9e94795aSAndroid Build Coastguard Worker					downloadUrl:   "",
476*9e94795aSAndroid Build Coastguard Worker				},
477*9e94795aSAndroid Build Coastguard Worker			},
478*9e94795aSAndroid Build Coastguard Worker		},
479*9e94795aSAndroid Build Coastguard Worker		{
480*9e94795aSAndroid Build Coastguard Worker			name: "bc",
481*9e94795aSAndroid Build Coastguard Worker			fs: &testfs.TestFS{
482*9e94795aSAndroid Build Coastguard Worker				"/b/METADATA": []byte(MY_LIB_1_0),
483*9e94795aSAndroid Build Coastguard Worker				"/c/METADATA": []byte(NO_NAME_0_1),
484*9e94795aSAndroid Build Coastguard Worker			},
485*9e94795aSAndroid Build Coastguard Worker			projects: []string{"/a", "/b", "/c"},
486*9e94795aSAndroid Build Coastguard Worker			expected: []pmeta{
487*9e94795aSAndroid Build Coastguard Worker				{
488*9e94795aSAndroid Build Coastguard Worker					project:       "/b",
489*9e94795aSAndroid Build Coastguard Worker					versionedName: "mylib_v_1.0",
490*9e94795aSAndroid Build Coastguard Worker					name:          "mylib",
491*9e94795aSAndroid Build Coastguard Worker					version:       "1.0",
492*9e94795aSAndroid Build Coastguard Worker					downloadUrl:   "",
493*9e94795aSAndroid Build Coastguard Worker				},
494*9e94795aSAndroid Build Coastguard Worker				{
495*9e94795aSAndroid Build Coastguard Worker					project:       "/c",
496*9e94795aSAndroid Build Coastguard Worker					versionedName: "my library",
497*9e94795aSAndroid Build Coastguard Worker					name:          "",
498*9e94795aSAndroid Build Coastguard Worker					version:       "0.1",
499*9e94795aSAndroid Build Coastguard Worker					downloadUrl:   "",
500*9e94795aSAndroid Build Coastguard Worker				},
501*9e94795aSAndroid Build Coastguard Worker			},
502*9e94795aSAndroid Build Coastguard Worker		},
503*9e94795aSAndroid Build Coastguard Worker		{
504*9e94795aSAndroid Build Coastguard Worker			name: "wrongnametype",
505*9e94795aSAndroid Build Coastguard Worker			fs: &testfs.TestFS{
506*9e94795aSAndroid Build Coastguard Worker				"/a/METADATA": []byte(INVALID_NAME),
507*9e94795aSAndroid Build Coastguard Worker			},
508*9e94795aSAndroid Build Coastguard Worker			projects:      []string{"/a"},
509*9e94795aSAndroid Build Coastguard Worker			expectedError: `invalid value for string type`,
510*9e94795aSAndroid Build Coastguard Worker		},
511*9e94795aSAndroid Build Coastguard Worker		{
512*9e94795aSAndroid Build Coastguard Worker			name: "wrongdescriptiontype",
513*9e94795aSAndroid Build Coastguard Worker			fs: &testfs.TestFS{
514*9e94795aSAndroid Build Coastguard Worker				"/a/METADATA": []byte(INVALID_DESCRIPTION),
515*9e94795aSAndroid Build Coastguard Worker			},
516*9e94795aSAndroid Build Coastguard Worker			projects:      []string{"/a"},
517*9e94795aSAndroid Build Coastguard Worker			expectedError: `invalid value for string type`,
518*9e94795aSAndroid Build Coastguard Worker		},
519*9e94795aSAndroid Build Coastguard Worker		{
520*9e94795aSAndroid Build Coastguard Worker			name: "wrongversiontype",
521*9e94795aSAndroid Build Coastguard Worker			fs: &testfs.TestFS{
522*9e94795aSAndroid Build Coastguard Worker				"/a/METADATA": []byte(INVALID_VERSION),
523*9e94795aSAndroid Build Coastguard Worker			},
524*9e94795aSAndroid Build Coastguard Worker			projects:      []string{"/a"},
525*9e94795aSAndroid Build Coastguard Worker			expectedError: `invalid value for string type`,
526*9e94795aSAndroid Build Coastguard Worker		},
527*9e94795aSAndroid Build Coastguard Worker		{
528*9e94795aSAndroid Build Coastguard Worker			name: "wrongtype",
529*9e94795aSAndroid Build Coastguard Worker			fs: &testfs.TestFS{
530*9e94795aSAndroid Build Coastguard Worker				"/a/METADATA": []byte(INVALID_NAME + INVALID_DESCRIPTION + INVALID_VERSION),
531*9e94795aSAndroid Build Coastguard Worker			},
532*9e94795aSAndroid Build Coastguard Worker			projects:      []string{"/a"},
533*9e94795aSAndroid Build Coastguard Worker			expectedError: `invalid value for string type`,
534*9e94795aSAndroid Build Coastguard Worker		},
535*9e94795aSAndroid Build Coastguard Worker		{
536*9e94795aSAndroid Build Coastguard Worker			name: "empty",
537*9e94795aSAndroid Build Coastguard Worker			fs: &testfs.TestFS{
538*9e94795aSAndroid Build Coastguard Worker				"/a/METADATA": []byte(EMPTY),
539*9e94795aSAndroid Build Coastguard Worker			},
540*9e94795aSAndroid Build Coastguard Worker			projects: []string{"/a"},
541*9e94795aSAndroid Build Coastguard Worker			expected: []pmeta{{
542*9e94795aSAndroid Build Coastguard Worker				project:       "/a",
543*9e94795aSAndroid Build Coastguard Worker				versionedName: "",
544*9e94795aSAndroid Build Coastguard Worker				name:          "",
545*9e94795aSAndroid Build Coastguard Worker				version:       "",
546*9e94795aSAndroid Build Coastguard Worker				downloadUrl:   "",
547*9e94795aSAndroid Build Coastguard Worker			}},
548*9e94795aSAndroid Build Coastguard Worker		},
549*9e94795aSAndroid Build Coastguard Worker		{
550*9e94795aSAndroid Build Coastguard Worker			name: "emptyother",
551*9e94795aSAndroid Build Coastguard Worker			fs: &testfs.TestFS{
552*9e94795aSAndroid Build Coastguard Worker				"/a/METADATA.bp": []byte(EMPTY),
553*9e94795aSAndroid Build Coastguard Worker			},
554*9e94795aSAndroid Build Coastguard Worker			projects: []string{"/a"},
555*9e94795aSAndroid Build Coastguard Worker		},
556*9e94795aSAndroid Build Coastguard Worker		{
557*9e94795aSAndroid Build Coastguard Worker			name:     "emptyfs",
558*9e94795aSAndroid Build Coastguard Worker			fs:       &testfs.TestFS{},
559*9e94795aSAndroid Build Coastguard Worker			projects: []string{"/a"},
560*9e94795aSAndroid Build Coastguard Worker		},
561*9e94795aSAndroid Build Coastguard Worker		{
562*9e94795aSAndroid Build Coastguard Worker			name: "override",
563*9e94795aSAndroid Build Coastguard Worker			fs: &testfs.TestFS{
564*9e94795aSAndroid Build Coastguard Worker				"/a/METADATA":         []byte(INVALID_NAME + INVALID_DESCRIPTION + INVALID_VERSION),
565*9e94795aSAndroid Build Coastguard Worker				"/a/METADATA.android": []byte(MY_LIB_1_0),
566*9e94795aSAndroid Build Coastguard Worker			},
567*9e94795aSAndroid Build Coastguard Worker			projects: []string{"/a"},
568*9e94795aSAndroid Build Coastguard Worker			expected: []pmeta{{
569*9e94795aSAndroid Build Coastguard Worker				project:       "/a",
570*9e94795aSAndroid Build Coastguard Worker				versionedName: "mylib_v_1.0",
571*9e94795aSAndroid Build Coastguard Worker				name:          "mylib",
572*9e94795aSAndroid Build Coastguard Worker				version:       "1.0",
573*9e94795aSAndroid Build Coastguard Worker				downloadUrl:   "",
574*9e94795aSAndroid Build Coastguard Worker			}},
575*9e94795aSAndroid Build Coastguard Worker		},
576*9e94795aSAndroid Build Coastguard Worker		{
577*9e94795aSAndroid Build Coastguard Worker			name: "enchilada",
578*9e94795aSAndroid Build Coastguard Worker			fs: &testfs.TestFS{
579*9e94795aSAndroid Build Coastguard Worker				"/a/METADATA":         []byte(INVALID_NAME + INVALID_DESCRIPTION + INVALID_VERSION),
580*9e94795aSAndroid Build Coastguard Worker				"/a/METADATA.android": []byte(EMPTY),
581*9e94795aSAndroid Build Coastguard Worker				"/b/METADATA":         []byte(MY_LIB_1_0),
582*9e94795aSAndroid Build Coastguard Worker				"/c/METADATA":         []byte(NO_NAME_0_1),
583*9e94795aSAndroid Build Coastguard Worker			},
584*9e94795aSAndroid Build Coastguard Worker			projects: []string{"/a", "/b", "/c"},
585*9e94795aSAndroid Build Coastguard Worker			expected: []pmeta{
586*9e94795aSAndroid Build Coastguard Worker				{
587*9e94795aSAndroid Build Coastguard Worker					project:       "/a",
588*9e94795aSAndroid Build Coastguard Worker					versionedName: "",
589*9e94795aSAndroid Build Coastguard Worker					name:          "",
590*9e94795aSAndroid Build Coastguard Worker					version:       "",
591*9e94795aSAndroid Build Coastguard Worker					downloadUrl:   "",
592*9e94795aSAndroid Build Coastguard Worker				},
593*9e94795aSAndroid Build Coastguard Worker				{
594*9e94795aSAndroid Build Coastguard Worker					project:       "/b",
595*9e94795aSAndroid Build Coastguard Worker					versionedName: "mylib_v_1.0",
596*9e94795aSAndroid Build Coastguard Worker					name:          "mylib",
597*9e94795aSAndroid Build Coastguard Worker					version:       "1.0",
598*9e94795aSAndroid Build Coastguard Worker					downloadUrl:   "",
599*9e94795aSAndroid Build Coastguard Worker				},
600*9e94795aSAndroid Build Coastguard Worker				{
601*9e94795aSAndroid Build Coastguard Worker					project:       "/c",
602*9e94795aSAndroid Build Coastguard Worker					versionedName: "my library",
603*9e94795aSAndroid Build Coastguard Worker					name:          "",
604*9e94795aSAndroid Build Coastguard Worker					version:       "0.1",
605*9e94795aSAndroid Build Coastguard Worker					downloadUrl:   "",
606*9e94795aSAndroid Build Coastguard Worker				},
607*9e94795aSAndroid Build Coastguard Worker			},
608*9e94795aSAndroid Build Coastguard Worker		},
609*9e94795aSAndroid Build Coastguard Worker	}
610*9e94795aSAndroid Build Coastguard Worker	for _, tt := range tests {
611*9e94795aSAndroid Build Coastguard Worker		t.Run(tt.name, func(t *testing.T) {
612*9e94795aSAndroid Build Coastguard Worker			ix := NewIndex(tt.fs)
613*9e94795aSAndroid Build Coastguard Worker			pms, err := ix.MetadataForProjects(tt.projects...)
614*9e94795aSAndroid Build Coastguard Worker			if err != nil {
615*9e94795aSAndroid Build Coastguard Worker				if len(tt.expectedError) == 0 {
616*9e94795aSAndroid Build Coastguard Worker					t.Errorf("unexpected error: got %s, want no error", err)
617*9e94795aSAndroid Build Coastguard Worker				} else if !strings.Contains(err.Error(), tt.expectedError) {
618*9e94795aSAndroid Build Coastguard Worker					t.Errorf("unexpected error: got %s, want %q", err, tt.expectedError)
619*9e94795aSAndroid Build Coastguard Worker				}
620*9e94795aSAndroid Build Coastguard Worker				return
621*9e94795aSAndroid Build Coastguard Worker			}
622*9e94795aSAndroid Build Coastguard Worker			t.Logf("actual %d project metadata", len(pms))
623*9e94795aSAndroid Build Coastguard Worker			for _, pm := range pms {
624*9e94795aSAndroid Build Coastguard Worker				t.Logf("  %v", pm.String())
625*9e94795aSAndroid Build Coastguard Worker			}
626*9e94795aSAndroid Build Coastguard Worker			t.Logf("expected %d project metadata", len(tt.expected))
627*9e94795aSAndroid Build Coastguard Worker			for _, pm := range tt.expected {
628*9e94795aSAndroid Build Coastguard Worker				t.Logf("  %s", pm.String())
629*9e94795aSAndroid Build Coastguard Worker			}
630*9e94795aSAndroid Build Coastguard Worker			if len(tt.expectedError) > 0 {
631*9e94795aSAndroid Build Coastguard Worker				t.Errorf("unexpected success: got no error, want %q err", tt.expectedError)
632*9e94795aSAndroid Build Coastguard Worker				return
633*9e94795aSAndroid Build Coastguard Worker			}
634*9e94795aSAndroid Build Coastguard Worker			if len(pms) != len(tt.expected) {
635*9e94795aSAndroid Build Coastguard Worker				t.Errorf("missing project metadata: got %d project metadata, want %d", len(pms), len(tt.expected))
636*9e94795aSAndroid Build Coastguard Worker			}
637*9e94795aSAndroid Build Coastguard Worker			for i := 0; i < len(pms) && i < len(tt.expected); i++ {
638*9e94795aSAndroid Build Coastguard Worker				if msg := tt.expected[i].difference(pms[i]); msg != "" {
639*9e94795aSAndroid Build Coastguard Worker					t.Errorf("unexpected metadata starting at index %d: %s", i, msg)
640*9e94795aSAndroid Build Coastguard Worker					return
641*9e94795aSAndroid Build Coastguard Worker				}
642*9e94795aSAndroid Build Coastguard Worker			}
643*9e94795aSAndroid Build Coastguard Worker			if len(pms) < len(tt.expected) {
644*9e94795aSAndroid Build Coastguard Worker				t.Errorf("missing metadata starting at index %d: got nothing, want %s", len(pms), tt.expected[len(pms)].String())
645*9e94795aSAndroid Build Coastguard Worker			}
646*9e94795aSAndroid Build Coastguard Worker			if len(tt.expected) < len(pms) {
647*9e94795aSAndroid Build Coastguard Worker				t.Errorf("unexpected metadata starting at index %d: got %s, want nothing", len(tt.expected), pms[len(tt.expected)].String())
648*9e94795aSAndroid Build Coastguard Worker			}
649*9e94795aSAndroid Build Coastguard Worker		})
650*9e94795aSAndroid Build Coastguard Worker	}
651*9e94795aSAndroid Build Coastguard Worker}
652*9e94795aSAndroid Build Coastguard Worker
653*9e94795aSAndroid Build Coastguard Workertype pmeta struct {
654*9e94795aSAndroid Build Coastguard Worker	project       string
655*9e94795aSAndroid Build Coastguard Worker	versionedName string
656*9e94795aSAndroid Build Coastguard Worker	name          string
657*9e94795aSAndroid Build Coastguard Worker	version       string
658*9e94795aSAndroid Build Coastguard Worker	downloadUrl   string
659*9e94795aSAndroid Build Coastguard Worker}
660*9e94795aSAndroid Build Coastguard Worker
661*9e94795aSAndroid Build Coastguard Workerfunc (pm pmeta) String() string {
662*9e94795aSAndroid Build Coastguard Worker	return fmt.Sprintf("project: %q versionedName: %q name: %q version: %q downloadUrl: %q\n", pm.project, pm.versionedName, pm.name, pm.version, pm.downloadUrl)
663*9e94795aSAndroid Build Coastguard Worker}
664*9e94795aSAndroid Build Coastguard Worker
665*9e94795aSAndroid Build Coastguard Workerfunc (pm pmeta) equals(other *ProjectMetadata) bool {
666*9e94795aSAndroid Build Coastguard Worker	if pm.project != other.project {
667*9e94795aSAndroid Build Coastguard Worker		return false
668*9e94795aSAndroid Build Coastguard Worker	}
669*9e94795aSAndroid Build Coastguard Worker	if pm.versionedName != other.VersionedName() {
670*9e94795aSAndroid Build Coastguard Worker		return false
671*9e94795aSAndroid Build Coastguard Worker	}
672*9e94795aSAndroid Build Coastguard Worker	if pm.name != other.Name() {
673*9e94795aSAndroid Build Coastguard Worker		return false
674*9e94795aSAndroid Build Coastguard Worker	}
675*9e94795aSAndroid Build Coastguard Worker	if pm.version != other.Version() {
676*9e94795aSAndroid Build Coastguard Worker		return false
677*9e94795aSAndroid Build Coastguard Worker	}
678*9e94795aSAndroid Build Coastguard Worker	if pm.downloadUrl != other.UrlsByTypeName().DownloadUrl() {
679*9e94795aSAndroid Build Coastguard Worker		return false
680*9e94795aSAndroid Build Coastguard Worker	}
681*9e94795aSAndroid Build Coastguard Worker	return true
682*9e94795aSAndroid Build Coastguard Worker}
683*9e94795aSAndroid Build Coastguard Worker
684*9e94795aSAndroid Build Coastguard Workerfunc (pm pmeta) difference(other *ProjectMetadata) string {
685*9e94795aSAndroid Build Coastguard Worker	if pm.equals(other) {
686*9e94795aSAndroid Build Coastguard Worker		return ""
687*9e94795aSAndroid Build Coastguard Worker	}
688*9e94795aSAndroid Build Coastguard Worker	var sb strings.Builder
689*9e94795aSAndroid Build Coastguard Worker	fmt.Fprintf(&sb, "got")
690*9e94795aSAndroid Build Coastguard Worker	if pm.project != other.project {
691*9e94795aSAndroid Build Coastguard Worker		fmt.Fprintf(&sb, " project: %q", other.project)
692*9e94795aSAndroid Build Coastguard Worker	}
693*9e94795aSAndroid Build Coastguard Worker	if pm.versionedName != other.VersionedName() {
694*9e94795aSAndroid Build Coastguard Worker		fmt.Fprintf(&sb, " versionedName: %q", other.VersionedName())
695*9e94795aSAndroid Build Coastguard Worker	}
696*9e94795aSAndroid Build Coastguard Worker	if pm.name != other.Name() {
697*9e94795aSAndroid Build Coastguard Worker		fmt.Fprintf(&sb, " name: %q", other.Name())
698*9e94795aSAndroid Build Coastguard Worker	}
699*9e94795aSAndroid Build Coastguard Worker	if pm.version != other.Version() {
700*9e94795aSAndroid Build Coastguard Worker		fmt.Fprintf(&sb, " version: %q", other.Version())
701*9e94795aSAndroid Build Coastguard Worker	}
702*9e94795aSAndroid Build Coastguard Worker	if pm.downloadUrl != other.UrlsByTypeName().DownloadUrl() {
703*9e94795aSAndroid Build Coastguard Worker		fmt.Fprintf(&sb, " downloadUrl: %q", other.UrlsByTypeName().DownloadUrl())
704*9e94795aSAndroid Build Coastguard Worker	}
705*9e94795aSAndroid Build Coastguard Worker	fmt.Fprintf(&sb, ", want")
706*9e94795aSAndroid Build Coastguard Worker	if pm.project != other.project {
707*9e94795aSAndroid Build Coastguard Worker		fmt.Fprintf(&sb, " project: %q", pm.project)
708*9e94795aSAndroid Build Coastguard Worker	}
709*9e94795aSAndroid Build Coastguard Worker	if pm.versionedName != other.VersionedName() {
710*9e94795aSAndroid Build Coastguard Worker		fmt.Fprintf(&sb, " versionedName: %q", pm.versionedName)
711*9e94795aSAndroid Build Coastguard Worker	}
712*9e94795aSAndroid Build Coastguard Worker	if pm.name != other.Name() {
713*9e94795aSAndroid Build Coastguard Worker		fmt.Fprintf(&sb, " name: %q", pm.name)
714*9e94795aSAndroid Build Coastguard Worker	}
715*9e94795aSAndroid Build Coastguard Worker	if pm.version != other.Version() {
716*9e94795aSAndroid Build Coastguard Worker		fmt.Fprintf(&sb, " version: %q", pm.version)
717*9e94795aSAndroid Build Coastguard Worker	}
718*9e94795aSAndroid Build Coastguard Worker	if pm.downloadUrl != other.UrlsByTypeName().DownloadUrl() {
719*9e94795aSAndroid Build Coastguard Worker		fmt.Fprintf(&sb, " downloadUrl: %q", pm.downloadUrl)
720*9e94795aSAndroid Build Coastguard Worker	}
721*9e94795aSAndroid Build Coastguard Worker	return sb.String()
722*9e94795aSAndroid Build Coastguard Worker}
723