| // Copyright 2024 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 apex | 
 |  | 
 | import ( | 
 | 	"testing" | 
 |  | 
 | 	"android/soong/aconfig/codegen" | 
 | 	"android/soong/android" | 
 | 	"android/soong/cc" | 
 | 	"android/soong/genrule" | 
 | 	"android/soong/java" | 
 | 	"android/soong/rust" | 
 |  | 
 | 	"github.com/google/blueprint/proptools" | 
 | ) | 
 |  | 
 | var withAconfigValidationError = android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) { | 
 | 	variables.AconfigContainerValidation = "error" | 
 | 	variables.BuildId = proptools.StringPtr("TEST.BUILD_ID") | 
 | }) | 
 |  | 
 | func TestValidationAcrossContainersExportedPass(t *testing.T) { | 
 | 	t.Parallel() | 
 | 	testCases := []struct { | 
 | 		name string | 
 | 		bp   string | 
 | 	}{ | 
 | 		{ | 
 | 			name: "Java lib passes for exported containers cross", | 
 | 			bp: apex_default_bp + ` | 
 | 				apex { | 
 | 					name: "myapex", | 
 | 					manifest: ":myapex.manifest", | 
 | 					androidManifest: ":myapex.androidmanifest", | 
 | 					key: "myapex.key", | 
 | 					java_libs: [ | 
 | 						"my_java_library_foo", | 
 | 					], | 
 | 					updatable: false, | 
 | 				} | 
 | 				java_library { | 
 | 					name: "my_java_library_foo", | 
 | 					srcs: ["foo/bar/MyClass.java"], | 
 | 					sdk_version: "none", | 
 | 					system_modules: "none", | 
 | 					static_libs: ["my_java_aconfig_library_foo"], | 
 | 					apex_available: [ | 
 | 						"myapex", | 
 | 					], | 
 | 					compile_dex: true, | 
 | 				} | 
 | 				aconfig_declarations { | 
 | 					name: "my_aconfig_declarations_foo", | 
 | 					package: "com.example.package", | 
 | 					container: "otherapex", | 
 | 					srcs: ["foo.aconfig"], | 
 | 					exportable: true, | 
 | 				} | 
 | 				java_aconfig_library { | 
 | 					name: "my_java_aconfig_library_foo", | 
 | 					aconfig_declarations: "my_aconfig_declarations_foo", | 
 | 					mode: "exported", | 
 | 					apex_available: [ | 
 | 						"myapex", | 
 | 					], | 
 | 					sdk_version: "none", | 
 | 					system_modules: "none", | 
 | 				}`, | 
 | 		}, | 
 | 		{ | 
 | 			name: "Android app passes for exported containers cross", | 
 | 			bp: apex_default_bp + ` | 
 | 				apex { | 
 | 					name: "myapex", | 
 | 					manifest: ":myapex.manifest", | 
 | 					androidManifest: ":myapex.androidmanifest", | 
 | 					key: "myapex.key", | 
 | 					apps: [ | 
 | 						"my_android_app_foo", | 
 | 					], | 
 | 					updatable: false, | 
 | 				} | 
 | 				android_app { | 
 | 					name: "my_android_app_foo", | 
 | 					srcs: ["foo/MyClass.java"], | 
 | 					sdk_version: "none", | 
 | 					system_modules: "none", | 
 | 					stl: "none", | 
 | 					static_libs: ["my_java_library_bar"], | 
 | 					apex_available: [ "myapex" ], | 
 | 				} | 
 | 				java_library { | 
 | 					name: "my_java_library_bar", | 
 | 					srcs: ["foo/bar/MyClass.java"], | 
 | 					sdk_version: "none", | 
 | 					system_modules: "none", | 
 | 					static_libs: ["my_java_aconfig_library_bar"], | 
 | 					apex_available: [ | 
 | 						"myapex", | 
 | 					], | 
 | 				} | 
 | 				aconfig_declarations { | 
 | 					name: "my_aconfig_declarations_bar", | 
 | 					package: "com.example.package", | 
 | 					container: "otherapex", | 
 | 					srcs: ["bar.aconfig"], | 
 | 					exportable: true, | 
 | 				} | 
 | 				java_aconfig_library { | 
 | 					name: "my_java_aconfig_library_bar", | 
 | 					aconfig_declarations: "my_aconfig_declarations_bar", | 
 | 					mode: "exported", | 
 | 					apex_available: [ | 
 | 						"myapex", | 
 | 					], | 
 | 					sdk_version: "none", | 
 | 					system_modules: "none", | 
 | 				}`, | 
 | 		}, | 
 | 		{ | 
 | 			name: "Cc lib passes for exported containers cross", | 
 | 			bp: apex_default_bp + ` | 
 | 				apex { | 
 | 					name: "myapex", | 
 | 					manifest: ":myapex.manifest", | 
 | 					androidManifest: ":myapex.androidmanifest", | 
 | 					key: "myapex.key", | 
 | 					native_shared_libs: [ | 
 | 						"my_cc_library_bar", | 
 | 					], | 
 | 					binaries: [ | 
 | 						"my_cc_binary_baz", | 
 | 					], | 
 | 					updatable: false, | 
 | 				} | 
 | 				cc_library { | 
 | 					name: "my_cc_library_bar", | 
 | 					srcs: ["foo/bar/MyClass.cc"], | 
 | 					static_libs: [ | 
 | 						"my_cc_aconfig_library_bar", | 
 | 						"my_cc_aconfig_library_baz", | 
 | 					], | 
 | 					apex_available: [ | 
 | 						"myapex", | 
 | 					], | 
 | 				} | 
 | 				cc_binary { | 
 | 					name: "my_cc_binary_baz", | 
 | 					srcs: ["foo/bar/MyClass.cc"], | 
 | 					static_libs: ["my_cc_aconfig_library_baz"], | 
 | 					apex_available: [ | 
 | 						"myapex", | 
 | 					], | 
 | 				} | 
 | 				cc_library { | 
 | 					name: "server_configurable_flags", | 
 | 					srcs: ["server_configurable_flags.cc"], | 
 | 				} | 
 | 				cc_library { | 
 | 					name: "libbase", | 
 | 					srcs: ["libbase.cc"], | 
 | 			                apex_available: [ | 
 | 				            "myapex", | 
 | 			                ], | 
 | 				} | 
 | 				cc_library { | 
 | 					name: "libaconfig_storage_read_api_cc", | 
 | 					srcs: ["libaconfig_storage_read_api_cc.cc"], | 
 | 				} | 
 | 				aconfig_declarations { | 
 | 					name: "my_aconfig_declarations_bar", | 
 | 					package: "com.example.package", | 
 | 					container: "otherapex", | 
 | 					srcs: ["bar.aconfig"], | 
 | 					exportable: true, | 
 | 				} | 
 | 				cc_aconfig_library { | 
 | 					name: "my_cc_aconfig_library_bar", | 
 | 					aconfig_declarations: "my_aconfig_declarations_bar", | 
 | 					apex_available: [ | 
 | 						"myapex", | 
 | 					], | 
 | 					mode: "exported", | 
 | 				} | 
 | 				aconfig_declarations { | 
 | 					name: "my_aconfig_declarations_baz", | 
 | 					package: "com.example.package", | 
 | 					container: "otherapex", | 
 | 					srcs: ["baz.aconfig"], | 
 | 					exportable: true, | 
 | 				} | 
 | 				cc_aconfig_library { | 
 | 					name: "my_cc_aconfig_library_baz", | 
 | 					aconfig_declarations: "my_aconfig_declarations_baz", | 
 | 					apex_available: [ | 
 | 						"myapex", | 
 | 					], | 
 | 					mode: "exported", | 
 | 				}`, | 
 | 		}, | 
 | 		{ | 
 | 			name: "Rust lib passes for exported containers cross", | 
 | 			bp: apex_default_bp + ` | 
 | 			apex { | 
 | 				name: "myapex", | 
 | 				manifest: ":myapex.manifest", | 
 | 				androidManifest: ":myapex.androidmanifest", | 
 | 				key: "myapex.key", | 
 | 				native_shared_libs: ["libmy_rust_library"], | 
 | 				binaries: ["my_rust_binary"], | 
 | 				updatable: false, | 
 | 			} | 
 | 			rust_library { | 
 | 				name: "libflags_rust", // test mock | 
 | 				crate_name: "flags_rust", | 
 | 				srcs: ["lib.rs"], | 
 | 				apex_available: ["myapex"], | 
 | 			} | 
 | 			rust_library { | 
 | 				name: "liblazy_static", // test mock | 
 | 				crate_name: "lazy_static", | 
 | 				srcs: ["src/lib.rs"], | 
 | 				apex_available: ["myapex"], | 
 | 			} | 
 | 			rust_library { | 
 | 				name: "libaconfig_storage_read_api", // test mock | 
 | 				crate_name: "aconfig_storage_read_api", | 
 | 				srcs: ["src/lib.rs"], | 
 | 				apex_available: ["myapex"], | 
 | 			} | 
 | 			rust_library { | 
 | 				name: "liblogger", // test mock | 
 | 				crate_name: "logger", | 
 | 				srcs: ["src/lib.rs"], | 
 | 				apex_available: ["myapex"], | 
 | 			} | 
 | 			rust_library { | 
 | 				name: "liblog_rust", // test mock | 
 | 				crate_name: "log_rust", | 
 | 				srcs: ["src/lib.rs"], | 
 | 				apex_available: ["myapex"], | 
 |                         } | 
 | 			rust_ffi_shared { | 
 | 				name: "libmy_rust_library", | 
 | 				srcs: ["src/lib.rs"], | 
 | 				rustlibs: ["libmy_rust_aconfig_library_foo"], | 
 | 				crate_name: "my_rust_library", | 
 | 				apex_available: ["myapex"], | 
 | 			} | 
 | 			rust_binary { | 
 | 				name: "my_rust_binary", | 
 | 				srcs: ["foo/bar/MyClass.rs"], | 
 | 				rustlibs: ["libmy_rust_aconfig_library_bar"], | 
 | 				apex_available: ["myapex"], | 
 | 			} | 
 | 			aconfig_declarations { | 
 | 				name: "my_aconfig_declarations_foo", | 
 | 				package: "com.example.package", | 
 | 				container: "otherapex", | 
 | 				srcs: ["foo.aconfig"], | 
 | 			} | 
 | 			aconfig_declarations { | 
 | 				name: "my_aconfig_declarations_bar", | 
 | 				package: "com.example.package", | 
 | 				container: "otherapex", | 
 | 				srcs: ["bar.aconfig"], | 
 | 			} | 
 | 			rust_aconfig_library { | 
 | 				name: "libmy_rust_aconfig_library_foo", | 
 | 				aconfig_declarations: "my_aconfig_declarations_foo", | 
 | 				crate_name: "my_rust_aconfig_library_foo", | 
 | 				apex_available: ["myapex"], | 
 | 				mode: "exported", | 
 | 			} | 
 | 			rust_aconfig_library { | 
 | 				name: "libmy_rust_aconfig_library_bar", | 
 | 				aconfig_declarations: "my_aconfig_declarations_bar", | 
 | 				crate_name: "my_rust_aconfig_library_bar", | 
 | 				apex_available: ["myapex"], | 
 | 				mode: "exported", | 
 | 			}`, | 
 | 		}, | 
 | 	} | 
 | 	for _, test := range testCases { | 
 | 		t.Run(test.name, func(t *testing.T) { | 
 | 			t.Parallel() | 
 | 			android.GroupFixturePreparers( | 
 | 				java.PrepareForTestWithJavaDefaultModules, | 
 | 				cc.PrepareForTestWithCcBuildComponents, | 
 | 				rust.PrepareForTestWithRustDefaultModules, | 
 | 				codegen.PrepareForTestWithAconfigBuildComponents, | 
 | 				PrepareForTestWithApexBuildComponents, | 
 | 				prepareForTestWithMyapex, | 
 | 				withAconfigValidationError, | 
 | 			). | 
 | 				RunTestWithBp(t, test.bp) | 
 | 		}) | 
 | 	} | 
 | } | 
 |  | 
 | func TestValidationAcrossContainersNotExportedFail(t *testing.T) { | 
 | 	t.Parallel() | 
 | 	testCases := []struct { | 
 | 		name          string | 
 | 		expectedError string | 
 | 		bp            string | 
 | 	}{ | 
 | 		{ | 
 | 			name: "Java lib fails for non-exported containers cross", | 
 | 			bp: apex_default_bp + ` | 
 | 				apex { | 
 | 					name: "myapex", | 
 | 					manifest: ":myapex.manifest", | 
 | 					androidManifest: ":myapex.androidmanifest", | 
 | 					key: "myapex.key", | 
 | 					java_libs: [ | 
 | 						"my_java_library_foo", | 
 | 					], | 
 | 					updatable: false, | 
 | 				} | 
 | 				java_library { | 
 | 					name: "my_java_library_foo", | 
 | 					srcs: ["foo/bar/MyClass.java"], | 
 | 					sdk_version: "none", | 
 | 					system_modules: "none", | 
 | 					static_libs: ["my_java_aconfig_library_foo"], | 
 | 					apex_available: [ | 
 | 						"myapex", | 
 | 					], | 
 | 					compile_dex: true, | 
 | 				} | 
 | 				aconfig_declarations { | 
 | 					name: "my_aconfig_declarations_foo", | 
 | 					package: "com.example.package", | 
 | 					container: "otherapex", | 
 | 					srcs: ["foo.aconfig"], | 
 | 				} | 
 | 				java_aconfig_library { | 
 | 					name: "my_java_aconfig_library_foo", | 
 | 					aconfig_declarations: "my_aconfig_declarations_foo", | 
 | 					apex_available: [ | 
 | 						"myapex", | 
 | 					], | 
 | 					sdk_version: "none", | 
 | 					system_modules: "none", | 
 | 				}`, | 
 | 			expectedError: `.*my_java_library_foo/myapex depends on my_java_aconfig_library_foo/otherapex/production across containers`, | 
 | 		}, | 
 | 		{ | 
 | 			name: "Android app fails for non-exported containers cross", | 
 | 			bp: apex_default_bp + ` | 
 | 				apex { | 
 | 					name: "myapex", | 
 | 					manifest: ":myapex.manifest", | 
 | 					androidManifest: ":myapex.androidmanifest", | 
 | 					key: "myapex.key", | 
 | 					apps: [ | 
 | 						"my_android_app_foo", | 
 | 					], | 
 | 					updatable: false, | 
 | 				} | 
 | 				android_app { | 
 | 					name: "my_android_app_foo", | 
 | 					srcs: ["foo/MyClass.java"], | 
 | 					sdk_version: "none", | 
 | 					system_modules: "none", | 
 | 					stl: "none", | 
 | 					static_libs: ["my_java_library_foo"], | 
 | 					apex_available: [ "myapex" ], | 
 | 				} | 
 | 				java_library { | 
 | 					name: "my_java_library_foo", | 
 | 					srcs: ["foo/bar/MyClass.java"], | 
 | 					sdk_version: "none", | 
 | 					system_modules: "none", | 
 | 					static_libs: ["my_java_aconfig_library_foo"], | 
 | 					apex_available: [ | 
 | 						"myapex", | 
 | 					], | 
 | 				} | 
 | 				aconfig_declarations { | 
 | 					name: "my_aconfig_declarations_foo", | 
 | 					package: "com.example.package", | 
 | 					container: "otherapex", | 
 | 					srcs: ["bar.aconfig"], | 
 | 				} | 
 | 				java_aconfig_library { | 
 | 					name: "my_java_aconfig_library_foo", | 
 | 					aconfig_declarations: "my_aconfig_declarations_foo", | 
 | 					apex_available: [ | 
 | 						"myapex", | 
 | 					], | 
 | 					sdk_version: "none", | 
 | 					system_modules: "none", | 
 | 				}`, | 
 | 			expectedError: `.*my_android_app_foo/myapex depends on my_java_aconfig_library_foo/otherapex/production across containers`, | 
 | 		}, | 
 | 		{ | 
 | 			name: "Cc lib fails for non-exported containers cross", | 
 | 			bp: apex_default_bp + ` | 
 | 				apex { | 
 | 					name: "myapex", | 
 | 					manifest: ":myapex.manifest", | 
 | 					androidManifest: ":myapex.androidmanifest", | 
 | 					key: "myapex.key", | 
 | 					native_shared_libs: [ | 
 | 						"my_cc_library_foo", | 
 | 					], | 
 | 					updatable: false, | 
 | 				} | 
 | 				cc_library { | 
 | 					name: "my_cc_library_foo", | 
 | 					srcs: ["foo/bar/MyClass.cc"], | 
 | 					shared_libs: [ | 
 | 						"my_cc_aconfig_library_foo", | 
 | 					], | 
 | 					apex_available: [ | 
 | 						"myapex", | 
 | 					], | 
 | 				} | 
 | 				cc_library { | 
 | 					name: "server_configurable_flags", | 
 | 					srcs: ["server_configurable_flags.cc"], | 
 | 				} | 
 | 				cc_library { | 
 | 					name: "libbase", | 
 | 					srcs: ["libbase.cc"], | 
 | 			                apex_available: [ | 
 | 				            "myapex", | 
 | 			                ], | 
 | 				} | 
 | 				cc_library { | 
 | 					name: "libaconfig_storage_read_api_cc", | 
 | 					srcs: ["libaconfig_storage_read_api_cc.cc"], | 
 | 				} | 
 | 				aconfig_declarations { | 
 | 					name: "my_aconfig_declarations_foo", | 
 | 					package: "com.example.package", | 
 | 					container: "otherapex", | 
 | 					srcs: ["foo.aconfig"], | 
 | 				} | 
 | 				cc_aconfig_library { | 
 | 					name: "my_cc_aconfig_library_foo", | 
 | 					aconfig_declarations: "my_aconfig_declarations_foo", | 
 | 					apex_available: [ | 
 | 						"myapex", | 
 | 					], | 
 | 				}`, | 
 | 			expectedError: `.*my_cc_library_foo/myapex depends on my_cc_aconfig_library_foo/otherapex/production across containers`, | 
 | 		}, | 
 | 		{ | 
 | 			name: "Cc binary fails for non-exported containers cross", | 
 | 			bp: apex_default_bp + ` | 
 | 				apex { | 
 | 					name: "myapex", | 
 | 					manifest: ":myapex.manifest", | 
 | 					androidManifest: ":myapex.androidmanifest", | 
 | 					key: "myapex.key", | 
 | 					binaries: [ | 
 | 						"my_cc_binary_foo", | 
 | 					], | 
 | 					updatable: false, | 
 | 				} | 
 | 				cc_library { | 
 | 					name: "my_cc_library_foo", | 
 | 					srcs: ["foo/bar/MyClass.cc"], | 
 | 					static_libs: [ | 
 | 						"my_cc_aconfig_library_foo", | 
 | 					], | 
 | 					apex_available: [ | 
 | 						"myapex", | 
 | 					], | 
 | 				} | 
 | 				cc_binary { | 
 | 					name: "my_cc_binary_foo", | 
 | 					srcs: ["foo/bar/MyClass.cc"], | 
 | 					static_libs: ["my_cc_library_foo"], | 
 | 					apex_available: [ | 
 | 						"myapex", | 
 | 					], | 
 | 				} | 
 | 				cc_library { | 
 | 					name: "server_configurable_flags", | 
 | 					srcs: ["server_configurable_flags.cc"], | 
 | 				} | 
 | 				cc_library { | 
 | 					name: "libbase", | 
 | 					srcs: ["libbase.cc"], | 
 | 			                apex_available: [ | 
 | 				            "myapex", | 
 | 			                ], | 
 | 				} | 
 | 				cc_library { | 
 | 					name: "libaconfig_storage_read_api_cc", | 
 | 					srcs: ["libaconfig_storage_read_api_cc.cc"], | 
 | 				} | 
 | 				aconfig_declarations { | 
 | 					name: "my_aconfig_declarations_foo", | 
 | 					package: "com.example.package", | 
 | 					container: "otherapex", | 
 | 					srcs: ["foo.aconfig"], | 
 | 				} | 
 | 				cc_aconfig_library { | 
 | 					name: "my_cc_aconfig_library_foo", | 
 | 					aconfig_declarations: "my_aconfig_declarations_foo", | 
 | 					apex_available: [ | 
 | 						"myapex", | 
 | 					], | 
 | 				}`, | 
 | 			expectedError: `.*my_cc_binary_foo/myapex depends on my_cc_aconfig_library_foo/otherapex/production across containers`, | 
 | 		}, | 
 | 		{ | 
 | 			name: "Rust lib fails for non-exported containers cross", | 
 | 			bp: apex_default_bp + ` | 
 | 			apex { | 
 | 				name: "myapex", | 
 | 				manifest: ":myapex.manifest", | 
 | 				androidManifest: ":myapex.androidmanifest", | 
 | 				key: "myapex.key", | 
 | 				native_shared_libs: ["libmy_rust_library"], | 
 | 				updatable: false, | 
 | 			} | 
 | 			rust_library { | 
 | 				name: "libflags_rust", // test mock | 
 | 				crate_name: "flags_rust", | 
 | 				srcs: ["lib.rs"], | 
 | 				apex_available: ["myapex"], | 
 | 			} | 
 | 			rust_library { | 
 | 				name: "liblazy_static", // test mock | 
 | 				crate_name: "lazy_static", | 
 | 				srcs: ["src/lib.rs"], | 
 | 				apex_available: ["myapex"], | 
 | 			} | 
 | 			rust_library { | 
 | 				name: "libaconfig_storage_read_api", // test mock | 
 | 				crate_name: "aconfig_storage_read_api", | 
 | 				srcs: ["src/lib.rs"], | 
 | 				apex_available: ["myapex"], | 
 | 			} | 
 | 			rust_library { | 
 | 				name: "liblogger", // test mock | 
 | 				crate_name: "logger", | 
 | 				srcs: ["src/lib.rs"], | 
 | 				apex_available: ["myapex"], | 
 | 			} | 
 | 			rust_library { | 
 | 				name: "liblog_rust", // test mock | 
 | 				crate_name: "log_rust", | 
 | 				srcs: ["src/lib.rs"], | 
 | 				apex_available: ["myapex"], | 
 | 			} | 
 | 			rust_ffi_shared { | 
 | 				name: "libmy_rust_library", | 
 | 				srcs: ["src/lib.rs"], | 
 | 				rustlibs: ["libmy_rust_aconfig_library_foo"], | 
 | 				crate_name: "my_rust_library", | 
 | 				apex_available: ["myapex"], | 
 | 			} | 
 | 			aconfig_declarations { | 
 | 				name: "my_aconfig_declarations_foo", | 
 | 				package: "com.example.package", | 
 | 				container: "otherapex", | 
 | 				srcs: ["foo.aconfig"], | 
 | 			} | 
 | 			rust_aconfig_library { | 
 | 				name: "libmy_rust_aconfig_library_foo", | 
 | 				aconfig_declarations: "my_aconfig_declarations_foo", | 
 | 				crate_name: "my_rust_aconfig_library_foo", | 
 | 				apex_available: ["myapex"], | 
 | 			}`, | 
 | 			expectedError: `.*libmy_rust_aconfig_library_foo/myapex depends on libmy_rust_aconfig_library_foo/otherapex/production across containers`, | 
 | 		}, | 
 | 		{ | 
 | 			name: "Rust binary fails for non-exported containers cross", | 
 | 			bp: apex_default_bp + ` | 
 | 			apex { | 
 | 				name: "myapex", | 
 | 				manifest: ":myapex.manifest", | 
 | 				androidManifest: ":myapex.androidmanifest", | 
 | 				key: "myapex.key", | 
 | 				binaries: ["my_rust_binary"], | 
 | 				updatable: false, | 
 | 			} | 
 | 			rust_library { | 
 | 				name: "libflags_rust", // test mock | 
 | 				crate_name: "flags_rust", | 
 | 				srcs: ["lib.rs"], | 
 | 				apex_available: ["myapex"], | 
 | 			} | 
 | 			rust_library { | 
 | 				name: "liblazy_static", // test mock | 
 | 				crate_name: "lazy_static", | 
 | 				srcs: ["src/lib.rs"], | 
 | 				apex_available: ["myapex"], | 
 | 			} | 
 | 			rust_library { | 
 | 				name: "libaconfig_storage_read_api", // test mock | 
 | 				crate_name: "aconfig_storage_read_api", | 
 | 				srcs: ["src/lib.rs"], | 
 | 				apex_available: ["myapex"], | 
 | 			} | 
 | 			rust_library { | 
 | 				name: "liblogger", // test mock | 
 | 				crate_name: "logger", | 
 | 				srcs: ["src/lib.rs"], | 
 | 				apex_available: ["myapex"], | 
 | 			} | 
 | 			rust_library { | 
 | 				name: "liblog_rust", // test mock | 
 | 				crate_name: "log_rust", | 
 | 				srcs: ["src/lib.rs"], | 
 | 				apex_available: ["myapex"], | 
 | 			} | 
 | 			rust_binary { | 
 | 				name: "my_rust_binary", | 
 | 				srcs: ["foo/bar/MyClass.rs"], | 
 | 				rustlibs: ["libmy_rust_aconfig_library_bar"], | 
 | 				apex_available: ["myapex"], | 
 | 			} | 
 | 			aconfig_declarations { | 
 | 				name: "my_aconfig_declarations_bar", | 
 | 				package: "com.example.package", | 
 | 				container: "otherapex", | 
 | 				srcs: ["bar.aconfig"], | 
 | 			} | 
 | 			rust_aconfig_library { | 
 | 				name: "libmy_rust_aconfig_library_bar", | 
 | 				aconfig_declarations: "my_aconfig_declarations_bar", | 
 | 				crate_name: "my_rust_aconfig_library_bar", | 
 | 				apex_available: ["myapex"], | 
 | 			}`, | 
 | 			expectedError: `.*libmy_rust_aconfig_library_bar/myapex depends on libmy_rust_aconfig_library_bar/otherapex/production across containers`, | 
 | 		}, | 
 | 		{ | 
 | 			name: "Aconfig validation propagate along sourceOrOutputDependencyTag", | 
 | 			bp: apex_default_bp + ` | 
 | 				apex { | 
 | 					name: "myapex", | 
 | 					manifest: ":myapex.manifest", | 
 | 					androidManifest: ":myapex.androidmanifest", | 
 | 					key: "myapex.key", | 
 | 					apps: [ | 
 | 						"my_android_app_foo", | 
 | 					], | 
 | 					updatable: false, | 
 | 				} | 
 | 				android_app { | 
 | 					name: "my_android_app_foo", | 
 | 					srcs: ["foo/MyClass.java"], | 
 | 					sdk_version: "none", | 
 | 					system_modules: "none", | 
 | 					stl: "none", | 
 | 					static_libs: ["my_java_library_foo"], | 
 | 					apex_available: [ "myapex" ], | 
 | 				} | 
 | 				java_library { | 
 | 					name: "my_java_library_foo", | 
 | 					srcs: [":my_genrule_foo"], | 
 | 					sdk_version: "none", | 
 | 					system_modules: "none", | 
 | 					apex_available: [ | 
 | 						"myapex", | 
 | 					], | 
 | 				} | 
 | 				aconfig_declarations_group { | 
 | 						name: "my_aconfig_declarations_group_foo", | 
 | 						java_aconfig_libraries: [ | 
 | 								"my_java_aconfig_library_foo", | 
 | 						], | 
 | 				} | 
 | 				filegroup { | 
 | 						name: "my_filegroup_foo_srcjars", | 
 | 						device_common_srcs: [ | 
 | 								":my_aconfig_declarations_group_foo{.srcjars}", | 
 | 						], | 
 | 				} | 
 | 				genrule { | 
 | 						name: "my_genrule_foo", | 
 | 						srcs: [":my_filegroup_foo_srcjars"], | 
 | 						cmd: "cp $(in) $(out)", | 
 | 						out: ["my_genrule_foo.srcjar"], | 
 | 				} | 
 | 				aconfig_declarations { | 
 | 					name: "my_aconfig_declarations_foo", | 
 | 					package: "com.example.package", | 
 | 					container: "otherapex", | 
 | 					srcs: ["bar.aconfig"], | 
 | 				} | 
 | 				java_aconfig_library { | 
 | 					name: "my_java_aconfig_library_foo", | 
 | 					aconfig_declarations: "my_aconfig_declarations_foo", | 
 | 					apex_available: [ | 
 | 						"myapex", | 
 | 					], | 
 | 					sdk_version: "none", | 
 | 					system_modules: "none", | 
 | 				}`, | 
 | 			expectedError: `.*my_android_app_foo/myapex depends on my_java_aconfig_library_foo/otherapex/production across containers`, | 
 | 		}, | 
 | 	} | 
 | 	for _, test := range testCases { | 
 | 		t.Run(test.name, func(t *testing.T) { | 
 | 			t.Parallel() | 
 | 			errorHandler := android.FixtureExpectsNoErrors | 
 | 			if test.expectedError != "" { | 
 | 				errorHandler = android.FixtureExpectsAtLeastOneErrorMatchingPattern(test.expectedError) | 
 | 			} | 
 | 			android.GroupFixturePreparers( | 
 | 				java.PrepareForTestWithJavaDefaultModules, | 
 | 				cc.PrepareForTestWithCcBuildComponents, | 
 | 				rust.PrepareForTestWithRustDefaultModules, | 
 | 				codegen.PrepareForTestWithAconfigBuildComponents, | 
 | 				genrule.PrepareForIntegrationTestWithGenrule, | 
 | 				PrepareForTestWithApexBuildComponents, | 
 | 				prepareForTestWithMyapex, | 
 | 				withAconfigValidationError, | 
 | 			). | 
 | 				ExtendWithErrorHandler(errorHandler). | 
 | 				RunTestWithBp(t, test.bp) | 
 | 		}) | 
 | 	} | 
 | } | 
 |  | 
 | func TestValidationNotPropagateAcrossShared(t *testing.T) { | 
 | 	t.Parallel() | 
 | 	testCases := []struct { | 
 | 		name string | 
 | 		bp   string | 
 | 	}{ | 
 | 		{ | 
 | 			name: "Java shared lib not propagate aconfig validation", | 
 | 			bp: apex_default_bp + ` | 
 | 				apex { | 
 | 					name: "myapex", | 
 | 					manifest: ":myapex.manifest", | 
 | 					androidManifest: ":myapex.androidmanifest", | 
 | 					key: "myapex.key", | 
 | 					java_libs: [ | 
 | 						"my_java_library_bar", | 
 | 					], | 
 | 					updatable: false, | 
 | 				} | 
 | 				java_library { | 
 | 					name: "my_java_library_bar", | 
 | 					srcs: ["foo/bar/MyClass.java"], | 
 | 					sdk_version: "none", | 
 | 					system_modules: "none", | 
 | 					libs: ["my_java_library_foo"], | 
 | 					apex_available: [ | 
 | 						"myapex", | 
 | 					], | 
 | 					compile_dex: true, | 
 | 				} | 
 | 				java_library { | 
 | 					name: "my_java_library_foo", | 
 | 					srcs: ["foo/bar/MyClass.java"], | 
 | 					sdk_version: "none", | 
 | 					system_modules: "none", | 
 | 					static_libs: ["my_java_aconfig_library_foo"], | 
 | 					apex_available: [ | 
 | 						"myapex", | 
 | 					], | 
 | 				} | 
 | 				aconfig_declarations { | 
 | 					name: "my_aconfig_declarations_foo", | 
 | 					package: "com.example.package", | 
 | 					container: "otherapex", | 
 | 					srcs: ["foo.aconfig"], | 
 | 				} | 
 | 				java_aconfig_library { | 
 | 					name: "my_java_aconfig_library_foo", | 
 | 					aconfig_declarations: "my_aconfig_declarations_foo", | 
 | 					apex_available: [ | 
 | 						"myapex", | 
 | 					], | 
 | 					sdk_version: "none", | 
 | 					system_modules: "none", | 
 | 				}`, | 
 | 		}, | 
 | 	} | 
 | 	for _, test := range testCases { | 
 | 		t.Run(test.name, func(t *testing.T) { | 
 | 			t.Parallel() | 
 | 			android.GroupFixturePreparers( | 
 | 				java.PrepareForTestWithJavaDefaultModules, | 
 | 				cc.PrepareForTestWithCcBuildComponents, | 
 | 				rust.PrepareForTestWithRustDefaultModules, | 
 | 				codegen.PrepareForTestWithAconfigBuildComponents, | 
 | 				PrepareForTestWithApexBuildComponents, | 
 | 				prepareForTestWithMyapex, | 
 | 				withAconfigValidationError, | 
 | 			). | 
 | 				RunTestWithBp(t, test.bp) | 
 | 		}) | 
 | 	} | 
 | } |