Some mainline modules provide an `sdk` and one or more set of module_exports. When the snapshots are unpacked into separate prebuilts directories (one per snapshot) then any dependencies from a member of one snapshot to a member of another may require the latter to have additional visibility rules. Previously, these rules had to be added to each source module. This change allows additional visibility rules to be specified on the sdk/module_exports that are added to all the prebuilts in its snapshot. Bug: 155921753 Bug: 168301990 Test: m nothing Change-Id: Ia3eacb5749981f04770ae9872a8013e43c5c6ef1
467 lines
11 KiB
Go
467 lines
11 KiB
Go
// Copyright 2019 Google Inc. All rights reserved.
|
|
//
|
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
// you may not use this file except in compliance with the License.
|
|
// You may obtain a copy of the License at
|
|
//
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
//
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
// See the License for the specific language governing permissions and
|
|
// limitations under the License.
|
|
|
|
package sdk
|
|
|
|
import (
|
|
"android/soong/android"
|
|
"log"
|
|
"os"
|
|
"testing"
|
|
|
|
"github.com/google/blueprint/proptools"
|
|
)
|
|
|
|
// Needed in an _test.go file in this package to ensure tests run correctly, particularly in IDE.
|
|
func TestMain(m *testing.M) {
|
|
if android.BuildOs != android.Linux {
|
|
// b/145598135 - Generating host snapshots for anything other than linux is not supported.
|
|
log.Printf("Skipping as sdk snapshot generation is only supported on %s not %s", android.Linux, android.BuildOs)
|
|
os.Exit(0)
|
|
}
|
|
|
|
runTestWithBuildDir(m)
|
|
}
|
|
|
|
func TestDepNotInRequiredSdks(t *testing.T) {
|
|
testSdkError(t, `module "myjavalib".*depends on "otherlib".*that isn't part of the required SDKs:.*`, `
|
|
sdk {
|
|
name: "mysdk",
|
|
java_header_libs: ["sdkmember"],
|
|
}
|
|
|
|
sdk_snapshot {
|
|
name: "mysdk@1",
|
|
java_header_libs: ["sdkmember_mysdk_1"],
|
|
}
|
|
|
|
java_import {
|
|
name: "sdkmember",
|
|
prefer: false,
|
|
host_supported: true,
|
|
}
|
|
|
|
java_import {
|
|
name: "sdkmember_mysdk_1",
|
|
sdk_member_name: "sdkmember",
|
|
host_supported: true,
|
|
}
|
|
|
|
java_library {
|
|
name: "myjavalib",
|
|
srcs: ["Test.java"],
|
|
libs: [
|
|
"sdkmember",
|
|
"otherlib",
|
|
],
|
|
system_modules: "none",
|
|
sdk_version: "none",
|
|
compile_dex: true,
|
|
host_supported: true,
|
|
apex_available: ["myapex"],
|
|
}
|
|
|
|
// this lib is no in mysdk
|
|
java_library {
|
|
name: "otherlib",
|
|
srcs: ["Test.java"],
|
|
system_modules: "none",
|
|
sdk_version: "none",
|
|
compile_dex: true,
|
|
host_supported: true,
|
|
}
|
|
|
|
apex {
|
|
name: "myapex",
|
|
java_libs: ["myjavalib"],
|
|
uses_sdks: ["mysdk@1"],
|
|
key: "myapex.key",
|
|
certificate: ":myapex.cert",
|
|
}
|
|
`)
|
|
}
|
|
|
|
// Ensure that prebuilt modules have the same effective visibility as the source
|
|
// modules.
|
|
func TestSnapshotVisibility(t *testing.T) {
|
|
packageBp := `
|
|
package {
|
|
default_visibility: ["//other/foo"],
|
|
}
|
|
|
|
sdk {
|
|
name: "mysdk",
|
|
visibility: [
|
|
"//other/foo",
|
|
// This short form will be replaced with //package:__subpackages__ in the
|
|
// generated sdk_snapshot.
|
|
":__subpackages__",
|
|
],
|
|
prebuilt_visibility: [
|
|
"//prebuilts/mysdk",
|
|
],
|
|
java_header_libs: [
|
|
"myjavalib",
|
|
"mypublicjavalib",
|
|
"mydefaultedjavalib",
|
|
"myprivatejavalib",
|
|
],
|
|
}
|
|
|
|
java_library {
|
|
name: "myjavalib",
|
|
// Uses package default visibility
|
|
srcs: ["Test.java"],
|
|
system_modules: "none",
|
|
sdk_version: "none",
|
|
}
|
|
|
|
java_defaults {
|
|
name: "java-defaults",
|
|
visibility: ["//other/bar"],
|
|
}
|
|
|
|
java_library {
|
|
name: "mypublicjavalib",
|
|
defaults: ["java-defaults"],
|
|
visibility: ["//visibility:public"],
|
|
srcs: ["Test.java"],
|
|
system_modules: "none",
|
|
sdk_version: "none",
|
|
}
|
|
|
|
java_defaults {
|
|
name: "myjavadefaults",
|
|
visibility: ["//other/bar"],
|
|
}
|
|
|
|
java_library {
|
|
name: "mydefaultedjavalib",
|
|
defaults: ["myjavadefaults"],
|
|
srcs: ["Test.java"],
|
|
system_modules: "none",
|
|
sdk_version: "none",
|
|
}
|
|
|
|
java_library {
|
|
name: "myprivatejavalib",
|
|
srcs: ["Test.java"],
|
|
visibility: ["//visibility:private"],
|
|
system_modules: "none",
|
|
sdk_version: "none",
|
|
}
|
|
`
|
|
|
|
result := testSdkWithFs(t, ``,
|
|
map[string][]byte{
|
|
"package/Test.java": nil,
|
|
"package/Android.bp": []byte(packageBp),
|
|
})
|
|
|
|
result.CheckSnapshot("mysdk", "package",
|
|
checkAndroidBpContents(`
|
|
// This is auto-generated. DO NOT EDIT.
|
|
|
|
java_import {
|
|
name: "mysdk_myjavalib@current",
|
|
sdk_member_name: "myjavalib",
|
|
visibility: [
|
|
"//other/foo",
|
|
"//package",
|
|
"//prebuilts/mysdk",
|
|
],
|
|
jars: ["java/myjavalib.jar"],
|
|
}
|
|
|
|
java_import {
|
|
name: "myjavalib",
|
|
prefer: false,
|
|
visibility: [
|
|
"//other/foo",
|
|
"//package",
|
|
"//prebuilts/mysdk",
|
|
],
|
|
jars: ["java/myjavalib.jar"],
|
|
}
|
|
|
|
java_import {
|
|
name: "mysdk_mypublicjavalib@current",
|
|
sdk_member_name: "mypublicjavalib",
|
|
visibility: ["//visibility:public"],
|
|
jars: ["java/mypublicjavalib.jar"],
|
|
}
|
|
|
|
java_import {
|
|
name: "mypublicjavalib",
|
|
prefer: false,
|
|
visibility: ["//visibility:public"],
|
|
jars: ["java/mypublicjavalib.jar"],
|
|
}
|
|
|
|
java_import {
|
|
name: "mysdk_mydefaultedjavalib@current",
|
|
sdk_member_name: "mydefaultedjavalib",
|
|
visibility: [
|
|
"//other/bar",
|
|
"//package",
|
|
"//prebuilts/mysdk",
|
|
],
|
|
jars: ["java/mydefaultedjavalib.jar"],
|
|
}
|
|
|
|
java_import {
|
|
name: "mydefaultedjavalib",
|
|
prefer: false,
|
|
visibility: [
|
|
"//other/bar",
|
|
"//package",
|
|
"//prebuilts/mysdk",
|
|
],
|
|
jars: ["java/mydefaultedjavalib.jar"],
|
|
}
|
|
|
|
java_import {
|
|
name: "mysdk_myprivatejavalib@current",
|
|
sdk_member_name: "myprivatejavalib",
|
|
visibility: [
|
|
"//package",
|
|
"//prebuilts/mysdk",
|
|
],
|
|
jars: ["java/myprivatejavalib.jar"],
|
|
}
|
|
|
|
java_import {
|
|
name: "myprivatejavalib",
|
|
prefer: false,
|
|
visibility: [
|
|
"//package",
|
|
"//prebuilts/mysdk",
|
|
],
|
|
jars: ["java/myprivatejavalib.jar"],
|
|
}
|
|
|
|
sdk_snapshot {
|
|
name: "mysdk@current",
|
|
visibility: [
|
|
"//other/foo",
|
|
"//package:__subpackages__",
|
|
],
|
|
java_header_libs: [
|
|
"mysdk_myjavalib@current",
|
|
"mysdk_mypublicjavalib@current",
|
|
"mysdk_mydefaultedjavalib@current",
|
|
"mysdk_myprivatejavalib@current",
|
|
],
|
|
}
|
|
`))
|
|
}
|
|
|
|
func TestPrebuiltVisibilityProperty_IsValidated(t *testing.T) {
|
|
testSdkError(t, `prebuilt_visibility: cannot mix "//visibility:private" with any other visibility rules`, `
|
|
sdk {
|
|
name: "mysdk",
|
|
prebuilt_visibility: [
|
|
"//foo",
|
|
"//visibility:private",
|
|
],
|
|
}
|
|
`)
|
|
}
|
|
|
|
func TestPrebuiltVisibilityProperty_AddPrivate(t *testing.T) {
|
|
testSdkError(t, `prebuilt_visibility: "//visibility:private" does not widen the visibility`, `
|
|
sdk {
|
|
name: "mysdk",
|
|
prebuilt_visibility: [
|
|
"//visibility:private",
|
|
],
|
|
java_header_libs: [
|
|
"myjavalib",
|
|
],
|
|
}
|
|
|
|
java_library {
|
|
name: "myjavalib",
|
|
// Uses package default visibility
|
|
srcs: ["Test.java"],
|
|
system_modules: "none",
|
|
sdk_version: "none",
|
|
}
|
|
`)
|
|
}
|
|
|
|
func TestSDkInstall(t *testing.T) {
|
|
sdk := `
|
|
sdk {
|
|
name: "mysdk",
|
|
}
|
|
`
|
|
result := testSdkWithFs(t, ``,
|
|
map[string][]byte{
|
|
"Android.bp": []byte(sdk),
|
|
})
|
|
|
|
result.CheckSnapshot("mysdk", "",
|
|
checkAllOtherCopyRules(`.intermediates/mysdk/common_os/mysdk-current.zip -> mysdk-current.zip`),
|
|
)
|
|
}
|
|
|
|
type EmbeddedPropertiesStruct struct {
|
|
S_Embedded_Common string `android:"arch_variant"`
|
|
S_Embedded_Different string `android:"arch_variant"`
|
|
}
|
|
|
|
type testPropertiesStruct struct {
|
|
name string
|
|
private string
|
|
Public_Kept string `sdk:"keep"`
|
|
S_Common string
|
|
S_Different string `android:"arch_variant"`
|
|
A_Common []string
|
|
A_Different []string `android:"arch_variant"`
|
|
F_Common *bool
|
|
F_Different *bool `android:"arch_variant"`
|
|
EmbeddedPropertiesStruct
|
|
}
|
|
|
|
func (p *testPropertiesStruct) optimizableProperties() interface{} {
|
|
return p
|
|
}
|
|
|
|
func (p *testPropertiesStruct) String() string {
|
|
return p.name
|
|
}
|
|
|
|
var _ propertiesContainer = (*testPropertiesStruct)(nil)
|
|
|
|
func TestCommonValueOptimization(t *testing.T) {
|
|
common := &testPropertiesStruct{name: "common"}
|
|
structs := []propertiesContainer{
|
|
&testPropertiesStruct{
|
|
name: "struct-0",
|
|
private: "common",
|
|
Public_Kept: "common",
|
|
S_Common: "common",
|
|
S_Different: "upper",
|
|
A_Common: []string{"first", "second"},
|
|
A_Different: []string{"alpha", "beta"},
|
|
F_Common: proptools.BoolPtr(false),
|
|
F_Different: proptools.BoolPtr(false),
|
|
EmbeddedPropertiesStruct: EmbeddedPropertiesStruct{
|
|
S_Embedded_Common: "embedded_common",
|
|
S_Embedded_Different: "embedded_upper",
|
|
},
|
|
},
|
|
&testPropertiesStruct{
|
|
name: "struct-1",
|
|
private: "common",
|
|
Public_Kept: "common",
|
|
S_Common: "common",
|
|
S_Different: "lower",
|
|
A_Common: []string{"first", "second"},
|
|
A_Different: []string{"alpha", "delta"},
|
|
F_Common: proptools.BoolPtr(false),
|
|
F_Different: proptools.BoolPtr(true),
|
|
EmbeddedPropertiesStruct: EmbeddedPropertiesStruct{
|
|
S_Embedded_Common: "embedded_common",
|
|
S_Embedded_Different: "embedded_lower",
|
|
},
|
|
},
|
|
}
|
|
|
|
extractor := newCommonValueExtractor(common)
|
|
|
|
h := TestHelper{t}
|
|
|
|
err := extractor.extractCommonProperties(common, structs)
|
|
h.AssertDeepEquals("unexpected error", nil, err)
|
|
|
|
h.AssertDeepEquals("common properties not correct",
|
|
&testPropertiesStruct{
|
|
name: "common",
|
|
private: "",
|
|
Public_Kept: "",
|
|
S_Common: "common",
|
|
S_Different: "",
|
|
A_Common: []string{"first", "second"},
|
|
A_Different: []string(nil),
|
|
F_Common: proptools.BoolPtr(false),
|
|
F_Different: nil,
|
|
EmbeddedPropertiesStruct: EmbeddedPropertiesStruct{
|
|
S_Embedded_Common: "embedded_common",
|
|
S_Embedded_Different: "",
|
|
},
|
|
},
|
|
common)
|
|
|
|
h.AssertDeepEquals("updated properties[0] not correct",
|
|
&testPropertiesStruct{
|
|
name: "struct-0",
|
|
private: "common",
|
|
Public_Kept: "common",
|
|
S_Common: "",
|
|
S_Different: "upper",
|
|
A_Common: nil,
|
|
A_Different: []string{"alpha", "beta"},
|
|
F_Common: nil,
|
|
F_Different: proptools.BoolPtr(false),
|
|
EmbeddedPropertiesStruct: EmbeddedPropertiesStruct{
|
|
S_Embedded_Common: "",
|
|
S_Embedded_Different: "embedded_upper",
|
|
},
|
|
},
|
|
structs[0])
|
|
|
|
h.AssertDeepEquals("updated properties[1] not correct",
|
|
&testPropertiesStruct{
|
|
name: "struct-1",
|
|
private: "common",
|
|
Public_Kept: "common",
|
|
S_Common: "",
|
|
S_Different: "lower",
|
|
A_Common: nil,
|
|
A_Different: []string{"alpha", "delta"},
|
|
F_Common: nil,
|
|
F_Different: proptools.BoolPtr(true),
|
|
EmbeddedPropertiesStruct: EmbeddedPropertiesStruct{
|
|
S_Embedded_Common: "",
|
|
S_Embedded_Different: "embedded_lower",
|
|
},
|
|
},
|
|
structs[1])
|
|
}
|
|
|
|
func TestCommonValueOptimization_InvalidArchSpecificVariants(t *testing.T) {
|
|
common := &testPropertiesStruct{name: "common"}
|
|
structs := []propertiesContainer{
|
|
&testPropertiesStruct{
|
|
name: "struct-0",
|
|
S_Common: "should-be-but-is-not-common0",
|
|
},
|
|
&testPropertiesStruct{
|
|
name: "struct-1",
|
|
S_Common: "should-be-but-is-not-common1",
|
|
},
|
|
}
|
|
|
|
extractor := newCommonValueExtractor(common)
|
|
|
|
h := TestHelper{t}
|
|
|
|
err := extractor.extractCommonProperties(common, structs)
|
|
h.AssertErrorMessageEquals("unexpected error", `field "S_Common" is not tagged as "arch_variant" but has arch specific properties:
|
|
"struct-0" has value "should-be-but-is-not-common0"
|
|
"struct-1" has value "should-be-but-is-not-common1"`, err)
|
|
}
|