• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1// Copyright 2019 Google Inc. All rights reserved.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//     http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15package sdk
16
17import (
18	"log"
19	"os"
20	"runtime"
21	"testing"
22
23	"android/soong/android"
24	"android/soong/java"
25
26	"github.com/google/blueprint/proptools"
27)
28
29// Needed in an _test.go file in this package to ensure tests run correctly, particularly in IDE.
30func TestMain(m *testing.M) {
31	if runtime.GOOS != "linux" {
32		// b/145598135 - Generating host snapshots for anything other than linux is not supported.
33		log.Printf("Skipping as sdk snapshot generation is only supported on linux not %s", runtime.GOOS)
34		os.Exit(0)
35	}
36
37	os.Exit(m.Run())
38}
39
40// Ensure that prebuilt modules have the same effective visibility as the source
41// modules.
42func TestSnapshotVisibility(t *testing.T) {
43	packageBp := `
44		package {
45			default_visibility: ["//other/foo"],
46		}
47
48		sdk {
49			name: "mysdk",
50			visibility: [
51				"//other/foo",
52				// This short form will be replaced with //package:__subpackages__ in the
53				// generated sdk_snapshot.
54				":__subpackages__",
55			],
56			prebuilt_visibility: [
57				"//prebuilts/mysdk",
58			],
59			java_header_libs: [
60				"myjavalib",
61				"mypublicjavalib",
62				"mydefaultedjavalib",
63				"myprivatejavalib",
64			],
65		}
66
67		java_library {
68			name: "myjavalib",
69			// Uses package default visibility
70			srcs: ["Test.java"],
71			system_modules: "none",
72			sdk_version: "none",
73		}
74
75		java_defaults {
76			name: "java-defaults",
77			visibility: ["//other/bar"],
78		}
79
80		java_library {
81			name: "mypublicjavalib",
82			defaults: ["java-defaults"],
83      visibility: ["//visibility:public"],
84			srcs: ["Test.java"],
85			system_modules: "none",
86			sdk_version: "none",
87		}
88
89		java_defaults {
90			name: "myjavadefaults",
91			visibility: ["//other/bar"],
92		}
93
94		java_library {
95			name: "mydefaultedjavalib",
96			defaults: ["myjavadefaults"],
97			srcs: ["Test.java"],
98			system_modules: "none",
99			sdk_version: "none",
100		}
101
102		java_library {
103			name: "myprivatejavalib",
104			srcs: ["Test.java"],
105			visibility: ["//visibility:private"],
106			system_modules: "none",
107			sdk_version: "none",
108		}
109	`
110
111	result := testSdkWithFs(t, ``,
112		map[string][]byte{
113			"package/Test.java":  nil,
114			"package/Android.bp": []byte(packageBp),
115		})
116
117	CheckSnapshot(t, result, "mysdk", "package",
118		checkAndroidBpContents(`
119// This is auto-generated. DO NOT EDIT.
120
121java_import {
122    name: "myjavalib",
123    prefer: false,
124    visibility: [
125        "//other/foo",
126        "//package",
127        "//prebuilts/mysdk",
128    ],
129    apex_available: ["//apex_available:platform"],
130    jars: ["java/myjavalib.jar"],
131}
132
133java_import {
134    name: "mypublicjavalib",
135    prefer: false,
136    visibility: ["//visibility:public"],
137    apex_available: ["//apex_available:platform"],
138    jars: ["java/mypublicjavalib.jar"],
139}
140
141java_import {
142    name: "mydefaultedjavalib",
143    prefer: false,
144    visibility: [
145        "//other/bar",
146        "//package",
147        "//prebuilts/mysdk",
148    ],
149    apex_available: ["//apex_available:platform"],
150    jars: ["java/mydefaultedjavalib.jar"],
151}
152
153java_import {
154    name: "myprivatejavalib",
155    prefer: false,
156    visibility: [
157        "//package",
158        "//prebuilts/mysdk",
159    ],
160    apex_available: ["//apex_available:platform"],
161    jars: ["java/myprivatejavalib.jar"],
162}
163`))
164}
165
166func TestPrebuiltVisibilityProperty_IsValidated(t *testing.T) {
167	testSdkError(t, `prebuilt_visibility: cannot mix "//visibility:private" with any other visibility rules`, `
168		sdk {
169			name: "mysdk",
170			prebuilt_visibility: [
171				"//foo",
172				"//visibility:private",
173			],
174		}
175`)
176}
177
178func TestPrebuiltVisibilityProperty_AddPrivate(t *testing.T) {
179	testSdkError(t, `prebuilt_visibility: "//visibility:private" does not widen the visibility`, `
180		sdk {
181			name: "mysdk",
182			prebuilt_visibility: [
183				"//visibility:private",
184			],
185			java_header_libs: [
186				"myjavalib",
187			],
188		}
189
190		java_library {
191			name: "myjavalib",
192			// Uses package default visibility
193			srcs: ["Test.java"],
194			system_modules: "none",
195			sdk_version: "none",
196		}
197`)
198}
199
200func TestSdkInstall(t *testing.T) {
201	sdk := `
202		sdk {
203			name: "mysdk",
204		}
205	`
206	result := testSdkWithFs(t, sdk, nil)
207
208	CheckSnapshot(t, result, "mysdk", "",
209		checkAllOtherCopyRules(`
210.intermediates/mysdk/common_os/mysdk-current.info -> mysdk-current.info
211.intermediates/mysdk/common_os/mysdk-current.zip -> mysdk-current.zip
212`))
213}
214
215type EmbeddedPropertiesStruct struct {
216	S_Embedded_Common    string `android:"arch_variant"`
217	S_Embedded_Different string `android:"arch_variant"`
218}
219
220type testPropertiesStruct struct {
221	name          string
222	private       string
223	Public_Ignore string `sdk:"ignore"`
224	Public_Keep   string `sdk:"keep"`
225	S_Common      string
226	S_Different   string `android:"arch_variant"`
227	A_Common      []string
228	A_Different   []string `android:"arch_variant"`
229	F_Common      *bool
230	F_Different   *bool `android:"arch_variant"`
231	EmbeddedPropertiesStruct
232}
233
234func (p *testPropertiesStruct) optimizableProperties() interface{} {
235	return p
236}
237
238func (p *testPropertiesStruct) String() string {
239	return p.name
240}
241
242var _ propertiesContainer = (*testPropertiesStruct)(nil)
243
244func TestCommonValueOptimization(t *testing.T) {
245	common := &testPropertiesStruct{name: "common"}
246	structs := []propertiesContainer{
247		&testPropertiesStruct{
248			name:          "struct-0",
249			private:       "common",
250			Public_Ignore: "common",
251			Public_Keep:   "keep",
252			S_Common:      "common",
253			S_Different:   "upper",
254			A_Common:      []string{"first", "second"},
255			A_Different:   []string{"alpha", "beta"},
256			F_Common:      proptools.BoolPtr(false),
257			F_Different:   proptools.BoolPtr(false),
258			EmbeddedPropertiesStruct: EmbeddedPropertiesStruct{
259				S_Embedded_Common:    "embedded_common",
260				S_Embedded_Different: "embedded_upper",
261			},
262		},
263		&testPropertiesStruct{
264			name:          "struct-1",
265			private:       "common",
266			Public_Ignore: "common",
267			Public_Keep:   "keep",
268			S_Common:      "common",
269			S_Different:   "lower",
270			A_Common:      []string{"first", "second"},
271			A_Different:   []string{"alpha", "delta"},
272			F_Common:      proptools.BoolPtr(false),
273			F_Different:   proptools.BoolPtr(true),
274			EmbeddedPropertiesStruct: EmbeddedPropertiesStruct{
275				S_Embedded_Common:    "embedded_common",
276				S_Embedded_Different: "embedded_lower",
277			},
278		},
279	}
280
281	extractor := newCommonValueExtractor(common)
282
283	err := extractor.extractCommonProperties(common, structs)
284	android.AssertDeepEquals(t, "unexpected error", nil, err)
285
286	android.AssertDeepEquals(t, "common properties not correct",
287		&testPropertiesStruct{
288			name:          "common",
289			private:       "",
290			Public_Ignore: "",
291			Public_Keep:   "keep",
292			S_Common:      "common",
293			S_Different:   "",
294			A_Common:      []string{"first", "second"},
295			A_Different:   []string(nil),
296			F_Common:      proptools.BoolPtr(false),
297			F_Different:   nil,
298			EmbeddedPropertiesStruct: EmbeddedPropertiesStruct{
299				S_Embedded_Common:    "embedded_common",
300				S_Embedded_Different: "",
301			},
302		},
303		common)
304
305	android.AssertDeepEquals(t, "updated properties[0] not correct",
306		&testPropertiesStruct{
307			name:          "struct-0",
308			private:       "common",
309			Public_Ignore: "common",
310			Public_Keep:   "keep",
311			S_Common:      "",
312			S_Different:   "upper",
313			A_Common:      nil,
314			A_Different:   []string{"alpha", "beta"},
315			F_Common:      nil,
316			F_Different:   proptools.BoolPtr(false),
317			EmbeddedPropertiesStruct: EmbeddedPropertiesStruct{
318				S_Embedded_Common:    "",
319				S_Embedded_Different: "embedded_upper",
320			},
321		},
322		structs[0])
323
324	android.AssertDeepEquals(t, "updated properties[1] not correct",
325		&testPropertiesStruct{
326			name:          "struct-1",
327			private:       "common",
328			Public_Ignore: "common",
329			Public_Keep:   "keep",
330			S_Common:      "",
331			S_Different:   "lower",
332			A_Common:      nil,
333			A_Different:   []string{"alpha", "delta"},
334			F_Common:      nil,
335			F_Different:   proptools.BoolPtr(true),
336			EmbeddedPropertiesStruct: EmbeddedPropertiesStruct{
337				S_Embedded_Common:    "",
338				S_Embedded_Different: "embedded_lower",
339			},
340		},
341		structs[1])
342}
343
344func TestCommonValueOptimization_InvalidArchSpecificVariants(t *testing.T) {
345	common := &testPropertiesStruct{name: "common"}
346	structs := []propertiesContainer{
347		&testPropertiesStruct{
348			name:     "struct-0",
349			S_Common: "should-be-but-is-not-common0",
350		},
351		&testPropertiesStruct{
352			name:     "struct-1",
353			S_Common: "should-be-but-is-not-common1",
354		},
355	}
356
357	extractor := newCommonValueExtractor(common)
358
359	err := extractor.extractCommonProperties(common, structs)
360	android.AssertErrorMessageEquals(t, "unexpected error", `field "S_Common" is not tagged as "arch_variant" but has arch specific properties:
361    "struct-0" has value "should-be-but-is-not-common0"
362    "struct-1" has value "should-be-but-is-not-common1"`, err)
363}
364
365// Ensure that sdk snapshot related environment variables work correctly.
366func TestSnapshot_EnvConfiguration(t *testing.T) {
367	bp := `
368		sdk {
369			name: "mysdk",
370			java_header_libs: ["myjavalib"],
371		}
372
373		java_library {
374			name: "myjavalib",
375			srcs: ["Test.java"],
376			system_modules: "none",
377			sdk_version: "none",
378			compile_dex: true,
379			host_supported: true,
380		}
381	`
382	preparer := android.GroupFixturePreparers(
383		prepareForSdkTestWithJava,
384		android.FixtureWithRootAndroidBp(bp),
385	)
386
387	checkZipFile := func(t *testing.T, result *android.TestResult, expected string) {
388		zipRule := result.ModuleForTests("mysdk", "common_os").Rule("SnapshotZipFiles")
389		android.AssertStringEquals(t, "snapshot zip file", expected, zipRule.Output.String())
390	}
391
392	t.Run("no env variables", func(t *testing.T) {
393		result := preparer.RunTest(t)
394
395		checkZipFile(t, result, "out/soong/.intermediates/mysdk/common_os/mysdk-current.zip")
396
397		CheckSnapshot(t, result, "mysdk", "",
398			checkAndroidBpContents(`
399// This is auto-generated. DO NOT EDIT.
400
401java_import {
402    name: "myjavalib",
403    prefer: false,
404    visibility: ["//visibility:public"],
405    apex_available: ["//apex_available:platform"],
406    jars: ["java/myjavalib.jar"],
407}
408			`),
409		)
410	})
411
412	t.Run("SOONG_SDK_SNAPSHOT_TARGET_BUILD_RELEASE=S", func(t *testing.T) {
413		result := android.GroupFixturePreparers(
414			prepareForSdkTestWithJava,
415			java.PrepareForTestWithJavaDefaultModules,
416			java.PrepareForTestWithJavaSdkLibraryFiles,
417			java.FixtureWithLastReleaseApis("mysdklibrary"),
418			android.FixtureWithRootAndroidBp(`
419			sdk {
420				name: "mysdk",
421				bootclasspath_fragments: ["mybootclasspathfragment"],
422			}
423
424			bootclasspath_fragment {
425				name: "mybootclasspathfragment",
426				apex_available: ["myapex"],
427				contents: ["mysdklibrary"],
428				hidden_api: {
429					split_packages: ["*"],
430				},
431			}
432
433			java_sdk_library {
434				name: "mysdklibrary",
435				srcs: ["Test.java"],
436				compile_dex: true,
437				sdk_version: "S",
438				public: {enabled: true},
439				permitted_packages: ["mysdklibrary"],
440			}
441		`),
442			android.FixtureMergeEnv(map[string]string{
443				"SOONG_SDK_SNAPSHOT_TARGET_BUILD_RELEASE": "S",
444			}),
445		).RunTest(t)
446
447		CheckSnapshot(t, result, "mysdk", "",
448			checkAndroidBpContents(`
449// This is auto-generated. DO NOT EDIT.
450
451prebuilt_bootclasspath_fragment {
452    name: "mybootclasspathfragment",
453    prefer: false,
454    visibility: ["//visibility:public"],
455    apex_available: ["myapex"],
456    contents: ["mysdklibrary"],
457    hidden_api: {
458        annotation_flags: "hiddenapi/annotation-flags.csv",
459        metadata: "hiddenapi/metadata.csv",
460        index: "hiddenapi/index.csv",
461        stub_flags: "hiddenapi/stub-flags.csv",
462        all_flags: "hiddenapi/all-flags.csv",
463    },
464}
465
466java_sdk_library_import {
467    name: "mysdklibrary",
468    prefer: false,
469    visibility: ["//visibility:public"],
470    apex_available: ["//apex_available:platform"],
471    shared_library: true,
472    compile_dex: true,
473    permitted_packages: ["mysdklibrary"],
474    public: {
475        jars: ["sdk_library/public/mysdklibrary-stubs.jar"],
476        stub_srcs: ["sdk_library/public/mysdklibrary_stub_sources"],
477        current_api: "sdk_library/public/mysdklibrary.txt",
478        removed_api: "sdk_library/public/mysdklibrary-removed.txt",
479        sdk_version: "current",
480    },
481}
482`),
483
484			checkAllCopyRules(`
485.intermediates/mybootclasspathfragment/android_common/modular-hiddenapi/annotation-flags.csv -> hiddenapi/annotation-flags.csv
486.intermediates/mybootclasspathfragment/android_common/modular-hiddenapi/metadata.csv -> hiddenapi/metadata.csv
487.intermediates/mybootclasspathfragment/android_common/modular-hiddenapi/index.csv -> hiddenapi/index.csv
488.intermediates/mybootclasspathfragment/android_common/modular-hiddenapi/stub-flags.csv -> hiddenapi/stub-flags.csv
489.intermediates/mybootclasspathfragment/android_common/modular-hiddenapi/all-flags.csv -> hiddenapi/all-flags.csv
490.intermediates/mysdklibrary.stubs/android_common/javac/mysdklibrary.stubs.jar -> sdk_library/public/mysdklibrary-stubs.jar
491.intermediates/mysdklibrary.stubs.source/android_common/metalava/mysdklibrary.stubs.source_api.txt -> sdk_library/public/mysdklibrary.txt
492.intermediates/mysdklibrary.stubs.source/android_common/metalava/mysdklibrary.stubs.source_removed.txt -> sdk_library/public/mysdklibrary-removed.txt
493`),
494		)
495	})
496
497}
498