xref: /aosp_15_r20/build/soong/python/python_test.go (revision 333d2b3687b3a337dbcca9d65000bca186795e39)
1*333d2b36SAndroid Build Coastguard Worker// Copyright 2017 Google Inc. All rights reserved.
2*333d2b36SAndroid Build Coastguard Worker//
3*333d2b36SAndroid Build Coastguard Worker// Licensed under the Apache License, Version 2.0 (the "License");
4*333d2b36SAndroid Build Coastguard Worker// you may not use this file except in compliance with the License.
5*333d2b36SAndroid Build Coastguard Worker// You may obtain a copy of the License at
6*333d2b36SAndroid Build Coastguard Worker//
7*333d2b36SAndroid Build Coastguard Worker//     http://www.apache.org/licenses/LICENSE-2.0
8*333d2b36SAndroid Build Coastguard Worker//
9*333d2b36SAndroid Build Coastguard Worker// Unless required by applicable law or agreed to in writing, software
10*333d2b36SAndroid Build Coastguard Worker// distributed under the License is distributed on an "AS IS" BASIS,
11*333d2b36SAndroid Build Coastguard Worker// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12*333d2b36SAndroid Build Coastguard Worker// See the License for the specific language governing permissions and
13*333d2b36SAndroid Build Coastguard Worker// limitations under the License.
14*333d2b36SAndroid Build Coastguard Worker
15*333d2b36SAndroid Build Coastguard Workerpackage python
16*333d2b36SAndroid Build Coastguard Worker
17*333d2b36SAndroid Build Coastguard Workerimport (
18*333d2b36SAndroid Build Coastguard Worker	"fmt"
19*333d2b36SAndroid Build Coastguard Worker	"os"
20*333d2b36SAndroid Build Coastguard Worker	"path/filepath"
21*333d2b36SAndroid Build Coastguard Worker	"strings"
22*333d2b36SAndroid Build Coastguard Worker	"testing"
23*333d2b36SAndroid Build Coastguard Worker
24*333d2b36SAndroid Build Coastguard Worker	"android/soong/android"
25*333d2b36SAndroid Build Coastguard Worker	"android/soong/cc"
26*333d2b36SAndroid Build Coastguard Worker
27*333d2b36SAndroid Build Coastguard Worker	"github.com/google/blueprint"
28*333d2b36SAndroid Build Coastguard Worker)
29*333d2b36SAndroid Build Coastguard Worker
30*333d2b36SAndroid Build Coastguard Workertype pyModule struct {
31*333d2b36SAndroid Build Coastguard Worker	name          string
32*333d2b36SAndroid Build Coastguard Worker	actualVersion string
33*333d2b36SAndroid Build Coastguard Worker	pyRunfiles    []string
34*333d2b36SAndroid Build Coastguard Worker	srcsZip       string
35*333d2b36SAndroid Build Coastguard Worker	depsSrcsZips  []string
36*333d2b36SAndroid Build Coastguard Worker}
37*333d2b36SAndroid Build Coastguard Worker
38*333d2b36SAndroid Build Coastguard Workervar (
39*333d2b36SAndroid Build Coastguard Worker	buildNamePrefix = "soong_python_test"
40*333d2b36SAndroid Build Coastguard Worker	// We allow maching almost anything before the actual variant so that the os/arch variant
41*333d2b36SAndroid Build Coastguard Worker	// is matched.
42*333d2b36SAndroid Build Coastguard Worker	moduleVariantErrTemplate = `%s: module %q variant "[a-zA-Z0-9_]*%s": `
43*333d2b36SAndroid Build Coastguard Worker	pkgPathErrTemplate       = moduleVariantErrTemplate +
44*333d2b36SAndroid Build Coastguard Worker		"pkg_path: %q must be a relative path contained in par file."
45*333d2b36SAndroid Build Coastguard Worker	badIdentifierErrTemplate = moduleVariantErrTemplate +
46*333d2b36SAndroid Build Coastguard Worker		"srcs: the path %q contains invalid subpath %q."
47*333d2b36SAndroid Build Coastguard Worker	dupRunfileErrTemplate = moduleVariantErrTemplate +
48*333d2b36SAndroid Build Coastguard Worker		"found two files to be placed at the same location within zip %q." +
49*333d2b36SAndroid Build Coastguard Worker		" First file: in module %s at path %q." +
50*333d2b36SAndroid Build Coastguard Worker		" Second file: in module %s at path %q."
51*333d2b36SAndroid Build Coastguard Worker	noSrcFileErr      = moduleVariantErrTemplate + "doesn't have any source files!"
52*333d2b36SAndroid Build Coastguard Worker	badSrcFileExtErr  = moduleVariantErrTemplate + "srcs: found non (.py|.proto) file: %q!"
53*333d2b36SAndroid Build Coastguard Worker	badDataFileExtErr = moduleVariantErrTemplate + "data: found (.py) file: %q!"
54*333d2b36SAndroid Build Coastguard Worker	bpFile            = "Android.bp"
55*333d2b36SAndroid Build Coastguard Worker
56*333d2b36SAndroid Build Coastguard Worker	data = []struct {
57*333d2b36SAndroid Build Coastguard Worker		desc      string
58*333d2b36SAndroid Build Coastguard Worker		mockFiles android.MockFS
59*333d2b36SAndroid Build Coastguard Worker
60*333d2b36SAndroid Build Coastguard Worker		errors           []string
61*333d2b36SAndroid Build Coastguard Worker		expectedBinaries []pyModule
62*333d2b36SAndroid Build Coastguard Worker	}{
63*333d2b36SAndroid Build Coastguard Worker		{
64*333d2b36SAndroid Build Coastguard Worker			desc: "module without any src files",
65*333d2b36SAndroid Build Coastguard Worker			mockFiles: map[string][]byte{
66*333d2b36SAndroid Build Coastguard Worker				filepath.Join("dir", bpFile): []byte(
67*333d2b36SAndroid Build Coastguard Worker					`python_library_host {
68*333d2b36SAndroid Build Coastguard Worker						name: "lib1",
69*333d2b36SAndroid Build Coastguard Worker					}`,
70*333d2b36SAndroid Build Coastguard Worker				),
71*333d2b36SAndroid Build Coastguard Worker			},
72*333d2b36SAndroid Build Coastguard Worker			errors: []string{
73*333d2b36SAndroid Build Coastguard Worker				fmt.Sprintf(noSrcFileErr,
74*333d2b36SAndroid Build Coastguard Worker					"dir/Android.bp:1:1", "lib1", "PY3"),
75*333d2b36SAndroid Build Coastguard Worker			},
76*333d2b36SAndroid Build Coastguard Worker		},
77*333d2b36SAndroid Build Coastguard Worker		{
78*333d2b36SAndroid Build Coastguard Worker			desc: "module with bad src file ext",
79*333d2b36SAndroid Build Coastguard Worker			mockFiles: map[string][]byte{
80*333d2b36SAndroid Build Coastguard Worker				filepath.Join("dir", bpFile): []byte(
81*333d2b36SAndroid Build Coastguard Worker					`python_library_host {
82*333d2b36SAndroid Build Coastguard Worker						name: "lib1",
83*333d2b36SAndroid Build Coastguard Worker						srcs: [
84*333d2b36SAndroid Build Coastguard Worker							"file1.exe",
85*333d2b36SAndroid Build Coastguard Worker						],
86*333d2b36SAndroid Build Coastguard Worker					}`,
87*333d2b36SAndroid Build Coastguard Worker				),
88*333d2b36SAndroid Build Coastguard Worker				"dir/file1.exe": nil,
89*333d2b36SAndroid Build Coastguard Worker			},
90*333d2b36SAndroid Build Coastguard Worker			errors: []string{
91*333d2b36SAndroid Build Coastguard Worker				fmt.Sprintf(badSrcFileExtErr,
92*333d2b36SAndroid Build Coastguard Worker					"dir/Android.bp:3:11", "lib1", "PY3", "dir/file1.exe"),
93*333d2b36SAndroid Build Coastguard Worker			},
94*333d2b36SAndroid Build Coastguard Worker		},
95*333d2b36SAndroid Build Coastguard Worker		{
96*333d2b36SAndroid Build Coastguard Worker			desc: "module with bad data file ext",
97*333d2b36SAndroid Build Coastguard Worker			mockFiles: map[string][]byte{
98*333d2b36SAndroid Build Coastguard Worker				filepath.Join("dir", bpFile): []byte(
99*333d2b36SAndroid Build Coastguard Worker					`python_library_host {
100*333d2b36SAndroid Build Coastguard Worker						name: "lib1",
101*333d2b36SAndroid Build Coastguard Worker						srcs: [
102*333d2b36SAndroid Build Coastguard Worker							"file1.py",
103*333d2b36SAndroid Build Coastguard Worker						],
104*333d2b36SAndroid Build Coastguard Worker						data: [
105*333d2b36SAndroid Build Coastguard Worker							"file2.py",
106*333d2b36SAndroid Build Coastguard Worker						],
107*333d2b36SAndroid Build Coastguard Worker					}`,
108*333d2b36SAndroid Build Coastguard Worker				),
109*333d2b36SAndroid Build Coastguard Worker				"dir/file1.py": nil,
110*333d2b36SAndroid Build Coastguard Worker				"dir/file2.py": nil,
111*333d2b36SAndroid Build Coastguard Worker			},
112*333d2b36SAndroid Build Coastguard Worker			errors: []string{
113*333d2b36SAndroid Build Coastguard Worker				fmt.Sprintf(badDataFileExtErr,
114*333d2b36SAndroid Build Coastguard Worker					"dir/Android.bp:6:11", "lib1", "PY3", "dir/file2.py"),
115*333d2b36SAndroid Build Coastguard Worker			},
116*333d2b36SAndroid Build Coastguard Worker		},
117*333d2b36SAndroid Build Coastguard Worker		{
118*333d2b36SAndroid Build Coastguard Worker			desc: "module with bad pkg_path format",
119*333d2b36SAndroid Build Coastguard Worker			mockFiles: map[string][]byte{
120*333d2b36SAndroid Build Coastguard Worker				filepath.Join("dir", bpFile): []byte(
121*333d2b36SAndroid Build Coastguard Worker					`python_library_host {
122*333d2b36SAndroid Build Coastguard Worker						name: "lib1",
123*333d2b36SAndroid Build Coastguard Worker						pkg_path: "a/c/../../",
124*333d2b36SAndroid Build Coastguard Worker						srcs: [
125*333d2b36SAndroid Build Coastguard Worker							"file1.py",
126*333d2b36SAndroid Build Coastguard Worker						],
127*333d2b36SAndroid Build Coastguard Worker					}
128*333d2b36SAndroid Build Coastguard Worker
129*333d2b36SAndroid Build Coastguard Worker					python_library_host {
130*333d2b36SAndroid Build Coastguard Worker						name: "lib2",
131*333d2b36SAndroid Build Coastguard Worker						pkg_path: "a/c/../../../",
132*333d2b36SAndroid Build Coastguard Worker						srcs: [
133*333d2b36SAndroid Build Coastguard Worker							"file1.py",
134*333d2b36SAndroid Build Coastguard Worker						],
135*333d2b36SAndroid Build Coastguard Worker					}
136*333d2b36SAndroid Build Coastguard Worker
137*333d2b36SAndroid Build Coastguard Worker					python_library_host {
138*333d2b36SAndroid Build Coastguard Worker						name: "lib3",
139*333d2b36SAndroid Build Coastguard Worker						pkg_path: "/a/c/../../",
140*333d2b36SAndroid Build Coastguard Worker						srcs: [
141*333d2b36SAndroid Build Coastguard Worker							"file1.py",
142*333d2b36SAndroid Build Coastguard Worker						],
143*333d2b36SAndroid Build Coastguard Worker					}`,
144*333d2b36SAndroid Build Coastguard Worker				),
145*333d2b36SAndroid Build Coastguard Worker				"dir/file1.py": nil,
146*333d2b36SAndroid Build Coastguard Worker			},
147*333d2b36SAndroid Build Coastguard Worker			errors: []string{
148*333d2b36SAndroid Build Coastguard Worker				fmt.Sprintf(pkgPathErrTemplate,
149*333d2b36SAndroid Build Coastguard Worker					"dir/Android.bp:11:15", "lib2", "PY3", "a/c/../../../"),
150*333d2b36SAndroid Build Coastguard Worker				fmt.Sprintf(pkgPathErrTemplate,
151*333d2b36SAndroid Build Coastguard Worker					"dir/Android.bp:19:15", "lib3", "PY3", "/a/c/../../"),
152*333d2b36SAndroid Build Coastguard Worker			},
153*333d2b36SAndroid Build Coastguard Worker		},
154*333d2b36SAndroid Build Coastguard Worker		{
155*333d2b36SAndroid Build Coastguard Worker			desc: "module with bad runfile src path format",
156*333d2b36SAndroid Build Coastguard Worker			mockFiles: map[string][]byte{
157*333d2b36SAndroid Build Coastguard Worker				filepath.Join("dir", bpFile): []byte(
158*333d2b36SAndroid Build Coastguard Worker					`python_library_host {
159*333d2b36SAndroid Build Coastguard Worker						name: "lib1",
160*333d2b36SAndroid Build Coastguard Worker						pkg_path: "a/b/c/",
161*333d2b36SAndroid Build Coastguard Worker						srcs: [
162*333d2b36SAndroid Build Coastguard Worker							".file1.py",
163*333d2b36SAndroid Build Coastguard Worker							"123/file1.py",
164*333d2b36SAndroid Build Coastguard Worker							"-e/f/file1.py",
165*333d2b36SAndroid Build Coastguard Worker						],
166*333d2b36SAndroid Build Coastguard Worker					}`,
167*333d2b36SAndroid Build Coastguard Worker				),
168*333d2b36SAndroid Build Coastguard Worker				"dir/.file1.py":     nil,
169*333d2b36SAndroid Build Coastguard Worker				"dir/123/file1.py":  nil,
170*333d2b36SAndroid Build Coastguard Worker				"dir/-e/f/file1.py": nil,
171*333d2b36SAndroid Build Coastguard Worker			},
172*333d2b36SAndroid Build Coastguard Worker			errors: []string{
173*333d2b36SAndroid Build Coastguard Worker				fmt.Sprintf(badIdentifierErrTemplate, "dir/Android.bp:4:11",
174*333d2b36SAndroid Build Coastguard Worker					"lib1", "PY3", "a/b/c/-e/f/file1.py", "-e"),
175*333d2b36SAndroid Build Coastguard Worker				fmt.Sprintf(badIdentifierErrTemplate, "dir/Android.bp:4:11",
176*333d2b36SAndroid Build Coastguard Worker					"lib1", "PY3", "a/b/c/.file1.py", ".file1"),
177*333d2b36SAndroid Build Coastguard Worker				fmt.Sprintf(badIdentifierErrTemplate, "dir/Android.bp:4:11",
178*333d2b36SAndroid Build Coastguard Worker					"lib1", "PY3", "a/b/c/123/file1.py", "123"),
179*333d2b36SAndroid Build Coastguard Worker			},
180*333d2b36SAndroid Build Coastguard Worker		},
181*333d2b36SAndroid Build Coastguard Worker		{
182*333d2b36SAndroid Build Coastguard Worker			desc: "module with duplicate runfile path",
183*333d2b36SAndroid Build Coastguard Worker			mockFiles: map[string][]byte{
184*333d2b36SAndroid Build Coastguard Worker				filepath.Join("dir", bpFile): []byte(
185*333d2b36SAndroid Build Coastguard Worker					`python_library_host {
186*333d2b36SAndroid Build Coastguard Worker						name: "lib1",
187*333d2b36SAndroid Build Coastguard Worker						pkg_path: "a/b/",
188*333d2b36SAndroid Build Coastguard Worker						srcs: [
189*333d2b36SAndroid Build Coastguard Worker							"c/file1.py",
190*333d2b36SAndroid Build Coastguard Worker						],
191*333d2b36SAndroid Build Coastguard Worker					}
192*333d2b36SAndroid Build Coastguard Worker
193*333d2b36SAndroid Build Coastguard Worker					python_library_host {
194*333d2b36SAndroid Build Coastguard Worker						name: "lib2",
195*333d2b36SAndroid Build Coastguard Worker						pkg_path: "a/b/c/",
196*333d2b36SAndroid Build Coastguard Worker						srcs: [
197*333d2b36SAndroid Build Coastguard Worker							"file1.py",
198*333d2b36SAndroid Build Coastguard Worker						],
199*333d2b36SAndroid Build Coastguard Worker						libs: [
200*333d2b36SAndroid Build Coastguard Worker							"lib1",
201*333d2b36SAndroid Build Coastguard Worker						],
202*333d2b36SAndroid Build Coastguard Worker					}
203*333d2b36SAndroid Build Coastguard Worker
204*333d2b36SAndroid Build Coastguard Worker					python_binary_host {
205*333d2b36SAndroid Build Coastguard Worker						name: "bin",
206*333d2b36SAndroid Build Coastguard Worker						pkg_path: "e/",
207*333d2b36SAndroid Build Coastguard Worker						srcs: [
208*333d2b36SAndroid Build Coastguard Worker							"bin.py",
209*333d2b36SAndroid Build Coastguard Worker						],
210*333d2b36SAndroid Build Coastguard Worker						libs: [
211*333d2b36SAndroid Build Coastguard Worker							"lib2",
212*333d2b36SAndroid Build Coastguard Worker						],
213*333d2b36SAndroid Build Coastguard Worker					}
214*333d2b36SAndroid Build Coastguard Worker					`,
215*333d2b36SAndroid Build Coastguard Worker				),
216*333d2b36SAndroid Build Coastguard Worker				"dir/c/file1.py": nil,
217*333d2b36SAndroid Build Coastguard Worker				"dir/file1.py":   nil,
218*333d2b36SAndroid Build Coastguard Worker				"dir/bin.py":     nil,
219*333d2b36SAndroid Build Coastguard Worker			},
220*333d2b36SAndroid Build Coastguard Worker			errors: []string{
221*333d2b36SAndroid Build Coastguard Worker				fmt.Sprintf(dupRunfileErrTemplate, "dir/Android.bp:20:6",
222*333d2b36SAndroid Build Coastguard Worker					"bin", "PY3", "a/b/c/file1.py", "bin", "dir/file1.py",
223*333d2b36SAndroid Build Coastguard Worker					"lib1", "dir/c/file1.py"),
224*333d2b36SAndroid Build Coastguard Worker			},
225*333d2b36SAndroid Build Coastguard Worker		},
226*333d2b36SAndroid Build Coastguard Worker		{
227*333d2b36SAndroid Build Coastguard Worker			desc: "module for testing dependencies",
228*333d2b36SAndroid Build Coastguard Worker			mockFiles: map[string][]byte{
229*333d2b36SAndroid Build Coastguard Worker				filepath.Join("dir", bpFile): []byte(
230*333d2b36SAndroid Build Coastguard Worker					`python_defaults {
231*333d2b36SAndroid Build Coastguard Worker						name: "default_lib",
232*333d2b36SAndroid Build Coastguard Worker						srcs: [
233*333d2b36SAndroid Build Coastguard Worker							"default.py",
234*333d2b36SAndroid Build Coastguard Worker						],
235*333d2b36SAndroid Build Coastguard Worker						version: {
236*333d2b36SAndroid Build Coastguard Worker							py2: {
237*333d2b36SAndroid Build Coastguard Worker								enabled: true,
238*333d2b36SAndroid Build Coastguard Worker								srcs: [
239*333d2b36SAndroid Build Coastguard Worker									"default_py2.py",
240*333d2b36SAndroid Build Coastguard Worker								],
241*333d2b36SAndroid Build Coastguard Worker							},
242*333d2b36SAndroid Build Coastguard Worker							py3: {
243*333d2b36SAndroid Build Coastguard Worker								enabled: false,
244*333d2b36SAndroid Build Coastguard Worker								srcs: [
245*333d2b36SAndroid Build Coastguard Worker									"default_py3.py",
246*333d2b36SAndroid Build Coastguard Worker								],
247*333d2b36SAndroid Build Coastguard Worker							},
248*333d2b36SAndroid Build Coastguard Worker						},
249*333d2b36SAndroid Build Coastguard Worker					}
250*333d2b36SAndroid Build Coastguard Worker
251*333d2b36SAndroid Build Coastguard Worker					python_library_host {
252*333d2b36SAndroid Build Coastguard Worker						name: "lib5",
253*333d2b36SAndroid Build Coastguard Worker						pkg_path: "a/b/",
254*333d2b36SAndroid Build Coastguard Worker						srcs: [
255*333d2b36SAndroid Build Coastguard Worker							"file1.py",
256*333d2b36SAndroid Build Coastguard Worker						],
257*333d2b36SAndroid Build Coastguard Worker						version: {
258*333d2b36SAndroid Build Coastguard Worker							py2: {
259*333d2b36SAndroid Build Coastguard Worker								enabled: true,
260*333d2b36SAndroid Build Coastguard Worker							},
261*333d2b36SAndroid Build Coastguard Worker							py3: {
262*333d2b36SAndroid Build Coastguard Worker								enabled: true,
263*333d2b36SAndroid Build Coastguard Worker							},
264*333d2b36SAndroid Build Coastguard Worker						},
265*333d2b36SAndroid Build Coastguard Worker					}
266*333d2b36SAndroid Build Coastguard Worker
267*333d2b36SAndroid Build Coastguard Worker					python_library_host {
268*333d2b36SAndroid Build Coastguard Worker						name: "lib6",
269*333d2b36SAndroid Build Coastguard Worker						pkg_path: "c/d/",
270*333d2b36SAndroid Build Coastguard Worker						srcs: [
271*333d2b36SAndroid Build Coastguard Worker							"file2.py",
272*333d2b36SAndroid Build Coastguard Worker						],
273*333d2b36SAndroid Build Coastguard Worker						libs: [
274*333d2b36SAndroid Build Coastguard Worker							"lib5",
275*333d2b36SAndroid Build Coastguard Worker						],
276*333d2b36SAndroid Build Coastguard Worker					}
277*333d2b36SAndroid Build Coastguard Worker
278*333d2b36SAndroid Build Coastguard Worker					python_binary_host {
279*333d2b36SAndroid Build Coastguard Worker						name: "bin",
280*333d2b36SAndroid Build Coastguard Worker						defaults: ["default_lib"],
281*333d2b36SAndroid Build Coastguard Worker						pkg_path: "e/",
282*333d2b36SAndroid Build Coastguard Worker						srcs: [
283*333d2b36SAndroid Build Coastguard Worker							"bin.py",
284*333d2b36SAndroid Build Coastguard Worker						],
285*333d2b36SAndroid Build Coastguard Worker						libs: [
286*333d2b36SAndroid Build Coastguard Worker							"lib5",
287*333d2b36SAndroid Build Coastguard Worker						],
288*333d2b36SAndroid Build Coastguard Worker						version: {
289*333d2b36SAndroid Build Coastguard Worker							py3: {
290*333d2b36SAndroid Build Coastguard Worker								enabled: true,
291*333d2b36SAndroid Build Coastguard Worker								srcs: [
292*333d2b36SAndroid Build Coastguard Worker									"file4.py",
293*333d2b36SAndroid Build Coastguard Worker								],
294*333d2b36SAndroid Build Coastguard Worker								libs: [
295*333d2b36SAndroid Build Coastguard Worker									"lib6",
296*333d2b36SAndroid Build Coastguard Worker								],
297*333d2b36SAndroid Build Coastguard Worker							},
298*333d2b36SAndroid Build Coastguard Worker						},
299*333d2b36SAndroid Build Coastguard Worker					}`,
300*333d2b36SAndroid Build Coastguard Worker				),
301*333d2b36SAndroid Build Coastguard Worker				filepath.Join("dir", "default.py"):     nil,
302*333d2b36SAndroid Build Coastguard Worker				filepath.Join("dir", "default_py2.py"): nil,
303*333d2b36SAndroid Build Coastguard Worker				filepath.Join("dir", "default_py3.py"): nil,
304*333d2b36SAndroid Build Coastguard Worker				filepath.Join("dir", "file1.py"):       nil,
305*333d2b36SAndroid Build Coastguard Worker				filepath.Join("dir", "file2.py"):       nil,
306*333d2b36SAndroid Build Coastguard Worker				filepath.Join("dir", "bin.py"):         nil,
307*333d2b36SAndroid Build Coastguard Worker				filepath.Join("dir", "file4.py"):       nil,
308*333d2b36SAndroid Build Coastguard Worker			},
309*333d2b36SAndroid Build Coastguard Worker			expectedBinaries: []pyModule{
310*333d2b36SAndroid Build Coastguard Worker				{
311*333d2b36SAndroid Build Coastguard Worker					name:          "bin",
312*333d2b36SAndroid Build Coastguard Worker					actualVersion: "PY3",
313*333d2b36SAndroid Build Coastguard Worker					pyRunfiles: []string{
314*333d2b36SAndroid Build Coastguard Worker						"e/default.py",
315*333d2b36SAndroid Build Coastguard Worker						"e/bin.py",
316*333d2b36SAndroid Build Coastguard Worker						"e/default_py3.py",
317*333d2b36SAndroid Build Coastguard Worker						"e/file4.py",
318*333d2b36SAndroid Build Coastguard Worker					},
319*333d2b36SAndroid Build Coastguard Worker					srcsZip: "out/soong/.intermediates/dir/bin/PY3/bin.py.srcszip",
320*333d2b36SAndroid Build Coastguard Worker				},
321*333d2b36SAndroid Build Coastguard Worker			},
322*333d2b36SAndroid Build Coastguard Worker		},
323*333d2b36SAndroid Build Coastguard Worker	}
324*333d2b36SAndroid Build Coastguard Worker)
325*333d2b36SAndroid Build Coastguard Worker
326*333d2b36SAndroid Build Coastguard Workerfunc TestPythonModule(t *testing.T) {
327*333d2b36SAndroid Build Coastguard Worker	for _, d := range data {
328*333d2b36SAndroid Build Coastguard Worker		if d.desc != "module with duplicate runfile path" {
329*333d2b36SAndroid Build Coastguard Worker			continue
330*333d2b36SAndroid Build Coastguard Worker		}
331*333d2b36SAndroid Build Coastguard Worker		d.mockFiles[filepath.Join("common", bpFile)] = []byte(`
332*333d2b36SAndroid Build Coastguard Workerpython_library {
333*333d2b36SAndroid Build Coastguard Worker  name: "py3-stdlib",
334*333d2b36SAndroid Build Coastguard Worker  host_supported: true,
335*333d2b36SAndroid Build Coastguard Worker}
336*333d2b36SAndroid Build Coastguard Workercc_binary {
337*333d2b36SAndroid Build Coastguard Worker  name: "py3-launcher",
338*333d2b36SAndroid Build Coastguard Worker  host_supported: true,
339*333d2b36SAndroid Build Coastguard Worker}
340*333d2b36SAndroid Build Coastguard Worker`)
341*333d2b36SAndroid Build Coastguard Worker
342*333d2b36SAndroid Build Coastguard Worker		t.Run(d.desc, func(t *testing.T) {
343*333d2b36SAndroid Build Coastguard Worker			result := android.GroupFixturePreparers(
344*333d2b36SAndroid Build Coastguard Worker				android.PrepareForTestWithDefaults,
345*333d2b36SAndroid Build Coastguard Worker				android.PrepareForTestWithArchMutator,
346*333d2b36SAndroid Build Coastguard Worker				android.PrepareForTestWithAllowMissingDependencies,
347*333d2b36SAndroid Build Coastguard Worker				cc.PrepareForTestWithCcDefaultModules,
348*333d2b36SAndroid Build Coastguard Worker				PrepareForTestWithPythonBuildComponents,
349*333d2b36SAndroid Build Coastguard Worker				d.mockFiles.AddToFixture(),
350*333d2b36SAndroid Build Coastguard Worker			).ExtendWithErrorHandler(android.FixtureExpectsAllErrorsToMatchAPattern(d.errors)).
351*333d2b36SAndroid Build Coastguard Worker				RunTest(t)
352*333d2b36SAndroid Build Coastguard Worker
353*333d2b36SAndroid Build Coastguard Worker			if len(result.Errs) > 0 {
354*333d2b36SAndroid Build Coastguard Worker				return
355*333d2b36SAndroid Build Coastguard Worker			}
356*333d2b36SAndroid Build Coastguard Worker
357*333d2b36SAndroid Build Coastguard Worker			for _, e := range d.expectedBinaries {
358*333d2b36SAndroid Build Coastguard Worker				t.Run(e.name, func(t *testing.T) {
359*333d2b36SAndroid Build Coastguard Worker					expectModule(t, result.TestContext, e.name, e.actualVersion, e.srcsZip, e.pyRunfiles)
360*333d2b36SAndroid Build Coastguard Worker				})
361*333d2b36SAndroid Build Coastguard Worker			}
362*333d2b36SAndroid Build Coastguard Worker		})
363*333d2b36SAndroid Build Coastguard Worker	}
364*333d2b36SAndroid Build Coastguard Worker}
365*333d2b36SAndroid Build Coastguard Worker
366*333d2b36SAndroid Build Coastguard Workerfunc TestTestOnlyProvider(t *testing.T) {
367*333d2b36SAndroid Build Coastguard Worker	t.Parallel()
368*333d2b36SAndroid Build Coastguard Worker	ctx := android.GroupFixturePreparers(
369*333d2b36SAndroid Build Coastguard Worker		PrepareForTestWithPythonBuildComponents,
370*333d2b36SAndroid Build Coastguard Worker		android.PrepareForTestWithAllowMissingDependencies,
371*333d2b36SAndroid Build Coastguard Worker	).RunTestWithBp(t, `
372*333d2b36SAndroid Build Coastguard Worker                // These should be test-only
373*333d2b36SAndroid Build Coastguard Worker                python_library { name: "py-lib-test", test_only: true }
374*333d2b36SAndroid Build Coastguard Worker                python_library { name: "py-lib-test-host", test_only: true, host_supported: true }
375*333d2b36SAndroid Build Coastguard Worker                python_test {    name: "py-test", srcs: ["py-test.py"] }
376*333d2b36SAndroid Build Coastguard Worker                python_test_host { name: "py-test-host", srcs: ["py-test-host.py"] }
377*333d2b36SAndroid Build Coastguard Worker                python_binary_host { name: "py-bin-test", srcs: ["py-bin-test.py"] }
378*333d2b36SAndroid Build Coastguard Worker
379*333d2b36SAndroid Build Coastguard Worker                // These should not be.
380*333d2b36SAndroid Build Coastguard Worker                python_library { name: "py-lib" }
381*333d2b36SAndroid Build Coastguard Worker                python_binary_host { name: "py-bin", srcs: ["py-bin.py"] }
382*333d2b36SAndroid Build Coastguard Worker	`)
383*333d2b36SAndroid Build Coastguard Worker
384*333d2b36SAndroid Build Coastguard Worker	// Visit all modules and ensure only the ones that should
385*333d2b36SAndroid Build Coastguard Worker	// marked as test-only are marked as test-only.
386*333d2b36SAndroid Build Coastguard Worker
387*333d2b36SAndroid Build Coastguard Worker	actualTestOnly := []string{}
388*333d2b36SAndroid Build Coastguard Worker	ctx.VisitAllModules(func(m blueprint.Module) {
389*333d2b36SAndroid Build Coastguard Worker		if provider, ok := android.OtherModuleProvider(ctx.TestContext.OtherModuleProviderAdaptor(), m, android.TestOnlyProviderKey); ok {
390*333d2b36SAndroid Build Coastguard Worker			if provider.TestOnly {
391*333d2b36SAndroid Build Coastguard Worker				actualTestOnly = append(actualTestOnly, m.Name())
392*333d2b36SAndroid Build Coastguard Worker			}
393*333d2b36SAndroid Build Coastguard Worker		}
394*333d2b36SAndroid Build Coastguard Worker	})
395*333d2b36SAndroid Build Coastguard Worker	expectedTestOnlyModules := []string{
396*333d2b36SAndroid Build Coastguard Worker		"py-lib-test",
397*333d2b36SAndroid Build Coastguard Worker		"py-lib-test-host",
398*333d2b36SAndroid Build Coastguard Worker		"py-test",
399*333d2b36SAndroid Build Coastguard Worker		"py-test-host",
400*333d2b36SAndroid Build Coastguard Worker	}
401*333d2b36SAndroid Build Coastguard Worker
402*333d2b36SAndroid Build Coastguard Worker	notEqual, left, right := android.ListSetDifference(expectedTestOnlyModules, actualTestOnly)
403*333d2b36SAndroid Build Coastguard Worker	if notEqual {
404*333d2b36SAndroid Build Coastguard Worker		t.Errorf("test-only: Expected but not found: %v, Found but not expected: %v", left, right)
405*333d2b36SAndroid Build Coastguard Worker	}
406*333d2b36SAndroid Build Coastguard Worker}
407*333d2b36SAndroid Build Coastguard Worker
408*333d2b36SAndroid Build Coastguard Worker// Don't allow setting test-only on things that are always tests or never tests.
409*333d2b36SAndroid Build Coastguard Workerfunc TestInvalidTestOnlyTargets(t *testing.T) {
410*333d2b36SAndroid Build Coastguard Worker	testCases := []string{
411*333d2b36SAndroid Build Coastguard Worker		` python_test { name: "py-test", test_only: true, srcs: ["py-test.py"] } `,
412*333d2b36SAndroid Build Coastguard Worker		` python_test_host { name: "py-test-host", test_only: true, srcs: ["py-test-host.py"] } `,
413*333d2b36SAndroid Build Coastguard Worker		` python_defaults { name: "py-defaults", test_only: true, srcs: ["foo.py"] } `,
414*333d2b36SAndroid Build Coastguard Worker	}
415*333d2b36SAndroid Build Coastguard Worker
416*333d2b36SAndroid Build Coastguard Worker	for i, bp := range testCases {
417*333d2b36SAndroid Build Coastguard Worker		ctx := android.GroupFixturePreparers(
418*333d2b36SAndroid Build Coastguard Worker			PrepareForTestWithPythonBuildComponents,
419*333d2b36SAndroid Build Coastguard Worker			android.FixtureRegisterWithContext(func(ctx android.RegistrationContext) {
420*333d2b36SAndroid Build Coastguard Worker
421*333d2b36SAndroid Build Coastguard Worker				ctx.RegisterModuleType("python_defaults", DefaultsFactory)
422*333d2b36SAndroid Build Coastguard Worker			}),
423*333d2b36SAndroid Build Coastguard Worker			android.PrepareForTestWithAllowMissingDependencies).
424*333d2b36SAndroid Build Coastguard Worker			ExtendWithErrorHandler(android.FixtureIgnoreErrors).
425*333d2b36SAndroid Build Coastguard Worker			RunTestWithBp(t, bp)
426*333d2b36SAndroid Build Coastguard Worker		if len(ctx.Errs) != 1 {
427*333d2b36SAndroid Build Coastguard Worker			t.Errorf("Expected err setting test_only in testcase #%d: %d errs", i, len(ctx.Errs))
428*333d2b36SAndroid Build Coastguard Worker			continue
429*333d2b36SAndroid Build Coastguard Worker		}
430*333d2b36SAndroid Build Coastguard Worker		if !strings.Contains(ctx.Errs[0].Error(), "unrecognized property \"test_only\"") {
431*333d2b36SAndroid Build Coastguard Worker			t.Errorf("ERR: %s bad bp: %s", ctx.Errs[0], bp)
432*333d2b36SAndroid Build Coastguard Worker		}
433*333d2b36SAndroid Build Coastguard Worker	}
434*333d2b36SAndroid Build Coastguard Worker}
435*333d2b36SAndroid Build Coastguard Worker
436*333d2b36SAndroid Build Coastguard Workerfunc expectModule(t *testing.T, ctx *android.TestContext, name, variant, expectedSrcsZip string, expectedPyRunfiles []string) {
437*333d2b36SAndroid Build Coastguard Worker	module := ctx.ModuleForTests(name, variant)
438*333d2b36SAndroid Build Coastguard Worker
439*333d2b36SAndroid Build Coastguard Worker	base, baseOk := module.Module().(*PythonLibraryModule)
440*333d2b36SAndroid Build Coastguard Worker	if !baseOk {
441*333d2b36SAndroid Build Coastguard Worker		t.Fatalf("%s is not Python module!", name)
442*333d2b36SAndroid Build Coastguard Worker	}
443*333d2b36SAndroid Build Coastguard Worker
444*333d2b36SAndroid Build Coastguard Worker	actualPyRunfiles := []string{}
445*333d2b36SAndroid Build Coastguard Worker	for _, path := range base.srcsPathMappings {
446*333d2b36SAndroid Build Coastguard Worker		actualPyRunfiles = append(actualPyRunfiles, path.dest)
447*333d2b36SAndroid Build Coastguard Worker	}
448*333d2b36SAndroid Build Coastguard Worker
449*333d2b36SAndroid Build Coastguard Worker	android.AssertDeepEquals(t, "pyRunfiles", expectedPyRunfiles, actualPyRunfiles)
450*333d2b36SAndroid Build Coastguard Worker
451*333d2b36SAndroid Build Coastguard Worker	android.AssertPathRelativeToTopEquals(t, "srcsZip", expectedSrcsZip, base.srcsZip)
452*333d2b36SAndroid Build Coastguard Worker}
453*333d2b36SAndroid Build Coastguard Worker
454*333d2b36SAndroid Build Coastguard Workerfunc TestMain(m *testing.M) {
455*333d2b36SAndroid Build Coastguard Worker	os.Exit(m.Run())
456*333d2b36SAndroid Build Coastguard Worker}
457