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