• 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	t.Parallel()
44	packageBp := `
45		package {
46			default_visibility: ["//other/foo"],
47		}
48
49		sdk {
50			name: "mysdk",
51			visibility: [
52				"//other/foo",
53				// This short form will be replaced with //package:__subpackages__ in the
54				// generated sdk_snapshot.
55				":__subpackages__",
56			],
57			java_header_libs: [
58				"myjavalib",
59				"mypublicjavalib",
60				"mydefaultedjavalib",
61				"myprivatejavalib",
62			],
63		}
64
65		java_library {
66			name: "myjavalib",
67			// Uses package default visibility
68			srcs: ["Test.java"],
69			system_modules: "none",
70			sdk_version: "none",
71		}
72
73		java_defaults {
74			name: "java-defaults",
75			visibility: ["//other/bar"],
76		}
77
78		java_library {
79			name: "mypublicjavalib",
80			defaults: ["java-defaults"],
81      visibility: ["//visibility:public"],
82			srcs: ["Test.java"],
83			system_modules: "none",
84			sdk_version: "none",
85		}
86
87		java_defaults {
88			name: "myjavadefaults",
89			visibility: ["//other/bar"],
90		}
91
92		java_library {
93			name: "mydefaultedjavalib",
94			defaults: ["myjavadefaults"],
95			srcs: ["Test.java"],
96			system_modules: "none",
97			sdk_version: "none",
98		}
99
100		java_library {
101			name: "myprivatejavalib",
102			srcs: ["Test.java"],
103			visibility: ["//visibility:private"],
104			system_modules: "none",
105			sdk_version: "none",
106		}
107	`
108
109	result := testSdkWithFs(t, ``,
110		map[string][]byte{
111			"package/Test.java":  nil,
112			"package/Android.bp": []byte(packageBp),
113		})
114
115	CheckSnapshot(t, result, "mysdk", "package",
116		checkAndroidBpContents(`
117// This is auto-generated. DO NOT EDIT.
118
119apex_contributions_defaults {
120    name: "mysdk.contributions",
121    contents: [
122        "prebuilt_myjavalib",
123        "prebuilt_mypublicjavalib",
124        "prebuilt_mydefaultedjavalib",
125        "prebuilt_myprivatejavalib",
126    ],
127}
128
129java_import {
130    name: "myjavalib",
131    prefer: false,
132    visibility: ["//visibility:public"],
133    apex_available: ["//apex_available:platform"],
134    jars: ["java/myjavalib.jar"],
135}
136
137java_import {
138    name: "mypublicjavalib",
139    prefer: false,
140    visibility: ["//visibility:public"],
141    apex_available: ["//apex_available:platform"],
142    jars: ["java/mypublicjavalib.jar"],
143}
144
145java_import {
146    name: "mydefaultedjavalib",
147    prefer: false,
148    visibility: ["//visibility:public"],
149    apex_available: ["//apex_available:platform"],
150    jars: ["java/mydefaultedjavalib.jar"],
151}
152
153java_import {
154    name: "myprivatejavalib",
155    prefer: false,
156    visibility: ["//visibility:public"],
157    apex_available: ["//apex_available:platform"],
158    jars: ["java/myprivatejavalib.jar"],
159}
160`))
161}
162
163func TestSdkInstall(t *testing.T) {
164	t.Parallel()
165	sdk := `
166		sdk {
167			name: "mysdk",
168		}
169	`
170	result := testSdkWithFs(t, sdk, nil)
171
172	CheckSnapshot(t, result, "mysdk", "",
173		checkAllOtherCopyRules(`
174.intermediates/mysdk/common_os/mysdk-current.info -> mysdk-current.info
175.intermediates/mysdk/common_os/mysdk-current.zip -> mysdk-current.zip
176`))
177}
178
179type EmbeddedPropertiesStruct struct {
180	S_Embedded_Common    string `android:"arch_variant"`
181	S_Embedded_Different string `android:"arch_variant"`
182}
183
184type testPropertiesStruct struct {
185	name          string
186	private       string
187	Public_Ignore string `sdk:"ignore"`
188	Public_Keep   string `sdk:"keep"`
189	S_Common      string
190	S_Different   string `android:"arch_variant"`
191	A_Common      []string
192	A_Different   []string `android:"arch_variant"`
193	F_Common      *bool
194	F_Different   *bool `android:"arch_variant"`
195	EmbeddedPropertiesStruct
196}
197
198func (p *testPropertiesStruct) optimizableProperties() interface{} {
199	return p
200}
201
202func (p *testPropertiesStruct) String() string {
203	return p.name
204}
205
206var _ propertiesContainer = (*testPropertiesStruct)(nil)
207
208func TestCommonValueOptimization(t *testing.T) {
209	common := &testPropertiesStruct{name: "common"}
210	structs := []propertiesContainer{
211		&testPropertiesStruct{
212			name:          "struct-0",
213			private:       "common",
214			Public_Ignore: "common",
215			Public_Keep:   "keep",
216			S_Common:      "common",
217			S_Different:   "upper",
218			A_Common:      []string{"first", "second"},
219			A_Different:   []string{"alpha", "beta"},
220			F_Common:      proptools.BoolPtr(false),
221			F_Different:   proptools.BoolPtr(false),
222			EmbeddedPropertiesStruct: EmbeddedPropertiesStruct{
223				S_Embedded_Common:    "embedded_common",
224				S_Embedded_Different: "embedded_upper",
225			},
226		},
227		&testPropertiesStruct{
228			name:          "struct-1",
229			private:       "common",
230			Public_Ignore: "common",
231			Public_Keep:   "keep",
232			S_Common:      "common",
233			S_Different:   "lower",
234			A_Common:      []string{"first", "second"},
235			A_Different:   []string{"alpha", "delta"},
236			F_Common:      proptools.BoolPtr(false),
237			F_Different:   proptools.BoolPtr(true),
238			EmbeddedPropertiesStruct: EmbeddedPropertiesStruct{
239				S_Embedded_Common:    "embedded_common",
240				S_Embedded_Different: "embedded_lower",
241			},
242		},
243	}
244
245	extractor := newCommonValueExtractor(common)
246
247	err := extractor.extractCommonProperties(common, structs)
248	android.AssertDeepEquals(t, "unexpected error", nil, err)
249
250	android.AssertDeepEquals(t, "common properties not correct",
251		&testPropertiesStruct{
252			name:          "common",
253			private:       "",
254			Public_Ignore: "",
255			Public_Keep:   "keep",
256			S_Common:      "common",
257			S_Different:   "",
258			A_Common:      []string{"first", "second"},
259			A_Different:   []string(nil),
260			F_Common:      proptools.BoolPtr(false),
261			F_Different:   nil,
262			EmbeddedPropertiesStruct: EmbeddedPropertiesStruct{
263				S_Embedded_Common:    "embedded_common",
264				S_Embedded_Different: "",
265			},
266		},
267		common)
268
269	android.AssertDeepEquals(t, "updated properties[0] not correct",
270		&testPropertiesStruct{
271			name:          "struct-0",
272			private:       "common",
273			Public_Ignore: "common",
274			Public_Keep:   "keep",
275			S_Common:      "",
276			S_Different:   "upper",
277			A_Common:      nil,
278			A_Different:   []string{"alpha", "beta"},
279			F_Common:      nil,
280			F_Different:   proptools.BoolPtr(false),
281			EmbeddedPropertiesStruct: EmbeddedPropertiesStruct{
282				S_Embedded_Common:    "",
283				S_Embedded_Different: "embedded_upper",
284			},
285		},
286		structs[0])
287
288	android.AssertDeepEquals(t, "updated properties[1] not correct",
289		&testPropertiesStruct{
290			name:          "struct-1",
291			private:       "common",
292			Public_Ignore: "common",
293			Public_Keep:   "keep",
294			S_Common:      "",
295			S_Different:   "lower",
296			A_Common:      nil,
297			A_Different:   []string{"alpha", "delta"},
298			F_Common:      nil,
299			F_Different:   proptools.BoolPtr(true),
300			EmbeddedPropertiesStruct: EmbeddedPropertiesStruct{
301				S_Embedded_Common:    "",
302				S_Embedded_Different: "embedded_lower",
303			},
304		},
305		structs[1])
306}
307
308func TestCommonValueOptimization_InvalidArchSpecificVariants(t *testing.T) {
309	common := &testPropertiesStruct{name: "common"}
310	structs := []propertiesContainer{
311		&testPropertiesStruct{
312			name:     "struct-0",
313			S_Common: "should-be-but-is-not-common0",
314		},
315		&testPropertiesStruct{
316			name:     "struct-1",
317			S_Common: "should-be-but-is-not-common1",
318		},
319	}
320
321	extractor := newCommonValueExtractor(common)
322
323	err := extractor.extractCommonProperties(common, structs)
324	android.AssertErrorMessageEquals(t, "unexpected error", `field "S_Common" is not tagged as "arch_variant" but has arch specific properties:
325    "struct-0" has value "should-be-but-is-not-common0"
326    "struct-1" has value "should-be-but-is-not-common1"`, err)
327}
328
329// Ensure that sdk snapshot related environment variables work correctly.
330func TestSnapshot_EnvConfiguration(t *testing.T) {
331	t.Parallel()
332	bp := `
333		sdk {
334			name: "mysdk",
335			java_header_libs: ["myjavalib"],
336		}
337
338		java_library {
339			name: "myjavalib",
340			srcs: ["Test.java"],
341			system_modules: "none",
342			sdk_version: "none",
343			compile_dex: true,
344			host_supported: true,
345		}
346	`
347	preparer := android.GroupFixturePreparers(
348		prepareForSdkTestWithJava,
349		android.FixtureWithRootAndroidBp(bp),
350	)
351
352	checkZipFile := func(t *testing.T, result *android.TestResult, expected string) {
353		zipRule := result.ModuleForTests(t, "mysdk", "common_os").Rule("SnapshotZipFiles")
354		android.AssertStringEquals(t, "snapshot zip file", expected, zipRule.Output.String())
355	}
356
357	t.Run("no env variables", func(t *testing.T) {
358		t.Parallel()
359		result := preparer.RunTest(t)
360
361		checkZipFile(t, result, "out/soong/.intermediates/mysdk/common_os/mysdk-current.zip")
362
363		CheckSnapshot(t, result, "mysdk", "",
364			checkAndroidBpContents(`
365// This is auto-generated. DO NOT EDIT.
366
367apex_contributions_defaults {
368    name: "mysdk.contributions",
369    contents: ["prebuilt_myjavalib"],
370}
371
372java_import {
373    name: "myjavalib",
374    prefer: false,
375    visibility: ["//visibility:public"],
376    apex_available: ["//apex_available:platform"],
377    jars: ["java/myjavalib.jar"],
378}
379			`),
380		)
381	})
382
383	t.Run("SOONG_SDK_SNAPSHOT_TARGET_BUILD_RELEASE=S", func(t *testing.T) {
384		t.Parallel()
385		result := android.GroupFixturePreparers(
386			prepareForSdkTestWithJava,
387			java.PrepareForTestWithJavaDefaultModules,
388			java.PrepareForTestWithJavaSdkLibraryFiles,
389			java.FixtureWithLastReleaseApis("mysdklibrary"),
390			android.FixtureWithRootAndroidBp(`
391			sdk {
392				name: "mysdk",
393				bootclasspath_fragments: ["mybootclasspathfragment"],
394			}
395
396			bootclasspath_fragment {
397				name: "mybootclasspathfragment",
398				apex_available: ["myapex"],
399				contents: ["mysdklibrary"],
400				hidden_api: {
401					split_packages: ["*"],
402				},
403			}
404
405			java_sdk_library {
406				name: "mysdklibrary",
407				srcs: ["Test.java"],
408				compile_dex: true,
409				sdk_version: "S",
410				public: {enabled: true},
411				permitted_packages: ["mysdklibrary"],
412			}
413		`),
414			android.FixtureMergeEnv(map[string]string{
415				"SOONG_SDK_SNAPSHOT_TARGET_BUILD_RELEASE": "S",
416			}),
417			android.PrepareForTestWithBuildFlag("RELEASE_HIDDEN_API_EXPORTABLE_STUBS", "true"),
418		).RunTest(t)
419
420		CheckSnapshot(t, result, "mysdk", "",
421			checkAndroidBpContents(`
422// This is auto-generated. DO NOT EDIT.
423
424apex_contributions_defaults {
425    name: "mysdk.contributions",
426    contents: ["prebuilt_mysdklibrary"],
427}
428
429prebuilt_bootclasspath_fragment {
430    name: "mybootclasspathfragment",
431    prefer: false,
432    visibility: ["//visibility:public"],
433    apex_available: ["myapex"],
434    contents: ["mysdklibrary"],
435    hidden_api: {
436        annotation_flags: "hiddenapi/annotation-flags.csv",
437        metadata: "hiddenapi/metadata.csv",
438        index: "hiddenapi/index.csv",
439        stub_flags: "hiddenapi/stub-flags.csv",
440        all_flags: "hiddenapi/all-flags.csv",
441    },
442}
443
444java_sdk_library_import {
445    name: "mysdklibrary",
446    prefer: false,
447    visibility: ["//visibility:public"],
448    apex_available: ["//apex_available:platform"],
449    shared_library: true,
450    compile_dex: true,
451    permitted_packages: ["mysdklibrary"],
452    public: {
453        jars: ["sdk_library/public/mysdklibrary-stubs.jar"],
454        stub_srcs: ["sdk_library/public/mysdklibrary_stub_sources"],
455        current_api: "sdk_library/public/mysdklibrary.txt",
456        removed_api: "sdk_library/public/mysdklibrary-removed.txt",
457        sdk_version: "current",
458    },
459}
460`),
461
462			checkAllCopyRules(`
463.intermediates/mybootclasspathfragment/android_common/modular-hiddenapi/annotation-flags.csv -> hiddenapi/annotation-flags.csv
464.intermediates/mybootclasspathfragment/android_common/modular-hiddenapi/metadata.csv -> hiddenapi/metadata.csv
465.intermediates/mybootclasspathfragment/android_common/modular-hiddenapi/index.csv -> hiddenapi/index.csv
466.intermediates/mybootclasspathfragment/android_common/modular-hiddenapi/stub-flags.csv -> hiddenapi/stub-flags.csv
467.intermediates/mybootclasspathfragment/android_common/modular-hiddenapi/all-flags.csv -> hiddenapi/all-flags.csv
468.intermediates/mysdklibrary.stubs.exportable/android_common/combined/mysdklibrary.stubs.exportable.jar -> sdk_library/public/mysdklibrary-stubs.jar
469.intermediates/mysdklibrary.stubs.source/android_common/exportable/mysdklibrary.stubs.source_api.txt -> sdk_library/public/mysdklibrary.txt
470.intermediates/mysdklibrary.stubs.source/android_common/exportable/mysdklibrary.stubs.source_removed.txt -> sdk_library/public/mysdklibrary-removed.txt
471`),
472		)
473	})
474
475	t.Run("test replacing exportable module", func(t *testing.T) {
476		t.Parallel()
477		result := android.GroupFixturePreparers(
478			prepareForSdkTestWithJava,
479			java.PrepareForTestWithJavaDefaultModules,
480			java.PrepareForTestWithJavaSdkLibraryFiles,
481			java.FixtureWithLastReleaseApis("mysdklibrary", "anothersdklibrary"),
482			android.FixtureWithRootAndroidBp(`
483			sdk {
484				name: "mysdk",
485				bootclasspath_fragments: ["mybootclasspathfragment"],
486			}
487
488			bootclasspath_fragment {
489				name: "mybootclasspathfragment",
490				apex_available: ["myapex"],
491				contents: ["mysdklibrary"],
492				hidden_api: {
493					split_packages: ["*"],
494				},
495				core_platform_api: {
496					stub_libs: [
497						"anothersdklibrary.stubs.exportable",
498					],
499				},
500				api: {
501					stub_libs: [
502						"anothersdklibrary",
503					],
504				},
505			}
506
507			java_sdk_library {
508				name: "mysdklibrary",
509				srcs: ["Test.java"],
510				compile_dex: true,
511				min_sdk_version: "S",
512				public: {enabled: true},
513				permitted_packages: ["mysdklibrary"],
514			}
515
516			java_sdk_library {
517				name: "anothersdklibrary",
518				srcs: ["Test.java"],
519				compile_dex: true,
520				min_sdk_version: "S",
521				public: {enabled: true},
522				system: {enabled: true},
523				module_lib: {enabled: true},
524			}
525		`),
526			android.FixtureMergeEnv(map[string]string{
527				"SOONG_SDK_SNAPSHOT_TARGET_BUILD_RELEASE": "S",
528			}),
529			android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
530				variables.Platform_version_active_codenames = []string{"UpsideDownCake", "Tiramisu", "S-V2"}
531			}),
532			android.PrepareForTestWithBuildFlag("RELEASE_HIDDEN_API_EXPORTABLE_STUBS", "true"),
533		).RunTest(t)
534
535		CheckSnapshot(t, result, "mysdk", "",
536			checkAndroidBpContents(`
537// This is auto-generated. DO NOT EDIT.
538
539prebuilt_bootclasspath_fragment {
540    name: "mybootclasspathfragment",
541    prefer: false,
542    visibility: ["//visibility:public"],
543    apex_available: ["myapex"],
544    contents: ["mysdklibrary"],
545    api: {
546        stub_libs: ["anothersdklibrary"],
547    },
548    core_platform_api: {
549        stub_libs: ["anothersdklibrary.stubs"],
550    },
551    hidden_api: {
552        annotation_flags: "hiddenapi/annotation-flags.csv",
553        metadata: "hiddenapi/metadata.csv",
554        index: "hiddenapi/index.csv",
555        stub_flags: "hiddenapi/stub-flags.csv",
556        all_flags: "hiddenapi/all-flags.csv",
557    },
558}
559
560java_sdk_library_import {
561    name: "mysdklibrary",
562    prefer: false,
563    visibility: ["//visibility:public"],
564    apex_available: ["//apex_available:platform"],
565    shared_library: true,
566    compile_dex: true,
567    permitted_packages: ["mysdklibrary"],
568    public: {
569        jars: ["sdk_library/public/mysdklibrary-stubs.jar"],
570        stub_srcs: ["sdk_library/public/mysdklibrary_stub_sources"],
571        current_api: "sdk_library/public/mysdklibrary.txt",
572        removed_api: "sdk_library/public/mysdklibrary-removed.txt",
573        sdk_version: "current",
574    },
575}
576
577java_sdk_library_import {
578    name: "anothersdklibrary",
579    prefer: false,
580    visibility: ["//visibility:public"],
581    apex_available: ["//apex_available:platform"],
582    shared_library: true,
583    compile_dex: true,
584    public: {
585        jars: ["sdk_library/public/anothersdklibrary-stubs.jar"],
586        stub_srcs: ["sdk_library/public/anothersdklibrary_stub_sources"],
587        current_api: "sdk_library/public/anothersdklibrary.txt",
588        removed_api: "sdk_library/public/anothersdklibrary-removed.txt",
589        sdk_version: "current",
590    },
591    system: {
592        jars: ["sdk_library/system/anothersdklibrary-stubs.jar"],
593        stub_srcs: ["sdk_library/system/anothersdklibrary_stub_sources"],
594        current_api: "sdk_library/system/anothersdklibrary.txt",
595        removed_api: "sdk_library/system/anothersdklibrary-removed.txt",
596        sdk_version: "system_current",
597    },
598    module_lib: {
599        jars: ["sdk_library/module-lib/anothersdklibrary-stubs.jar"],
600        stub_srcs: ["sdk_library/module-lib/anothersdklibrary_stub_sources"],
601        current_api: "sdk_library/module-lib/anothersdklibrary.txt",
602        removed_api: "sdk_library/module-lib/anothersdklibrary-removed.txt",
603        sdk_version: "module_current",
604    },
605}
606`),
607		)
608	})
609
610}
611