// Copyright 2023 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 etc import ( "android/soong/android" "strings" "testing" ) var prepareForInstallSymlinkTest = android.GroupFixturePreparers( android.PrepareForTestWithArchMutator, android.FixtureRegisterWithContext(RegisterInstallSymlinkBuildComponents), ) func TestInstallSymlinkBasic(t *testing.T) { result := prepareForInstallSymlinkTest.RunTestWithBp(t, ` install_symlink { name: "foo", installed_location: "bin/foo", symlink_target: "/system/system_ext/bin/foo", } `) foo_variants := result.ModuleVariantsForTests("foo") if len(foo_variants) != 1 { t.Fatalf("expected 1 variant, got %#v", foo_variants) } foo := result.ModuleForTests("foo", "android_common").Module() androidMkEntries := android.AndroidMkEntriesForTest(t, result.TestContext, foo) if len(androidMkEntries) != 1 { t.Fatalf("expected 1 androidmkentry, got %d", len(androidMkEntries)) } symlinks := androidMkEntries[0].EntryMap["LOCAL_SOONG_INSTALL_SYMLINKS"] if len(symlinks) != 1 { t.Fatalf("Expected 1 symlink, got %d", len(symlinks)) } if !strings.HasSuffix(symlinks[0], "system/bin/foo") { t.Fatalf("Expected symlink install path to end in system/bin/foo, got: %s", symlinks[0]) } } func TestInstallSymlinkToRecovery(t *testing.T) { result := prepareForInstallSymlinkTest.RunTestWithBp(t, ` install_symlink { name: "foo", installed_location: "bin/foo", symlink_target: "/system/system_ext/bin/foo", recovery: true, } `) foo_variants := result.ModuleVariantsForTests("foo") if len(foo_variants) != 1 { t.Fatalf("expected 1 variant, got %#v", foo_variants) } foo := result.ModuleForTests("foo", "android_common").Module() androidMkEntries := android.AndroidMkEntriesForTest(t, result.TestContext, foo) if len(androidMkEntries) != 1 { t.Fatalf("expected 1 androidmkentry, got %d", len(androidMkEntries)) } symlinks := androidMkEntries[0].EntryMap["LOCAL_SOONG_INSTALL_SYMLINKS"] if len(symlinks) != 1 { t.Fatalf("Expected 1 symlink, got %d", len(symlinks)) } if !strings.HasSuffix(symlinks[0], "recovery/root/system/bin/foo") { t.Fatalf("Expected symlink install path to end in recovery/root/system/bin/foo, got: %s", symlinks[0]) } } func TestErrorOnNonCleanTarget(t *testing.T) { prepareForInstallSymlinkTest. ExtendWithErrorHandler(android.FixtureExpectsOneErrorPattern("Should be a clean filepath")). RunTestWithBp(t, ` install_symlink { name: "foo", installed_location: "bin/foo", symlink_target: "/system/system_ext/../bin/foo", } `) } func TestErrorOnNonCleanInstalledLocation(t *testing.T) { prepareForInstallSymlinkTest. ExtendWithErrorHandler(android.FixtureExpectsOneErrorPattern("Should be a clean filepath")). RunTestWithBp(t, ` install_symlink { name: "foo", installed_location: "bin/../foo", symlink_target: "/system/system_ext/bin/foo", } `) } func TestErrorOnInstalledPathStartingWithDotDot(t *testing.T) { prepareForInstallSymlinkTest. ExtendWithErrorHandler(android.FixtureExpectsOneErrorPattern("Should not start with / or \\.\\./")). RunTestWithBp(t, ` install_symlink { name: "foo", installed_location: "../bin/foo", symlink_target: "/system/system_ext/bin/foo", } `) } func TestErrorOnInstalledPathStartingWithSlash(t *testing.T) { prepareForInstallSymlinkTest. ExtendWithErrorHandler(android.FixtureExpectsOneErrorPattern("Should not start with / or \\.\\./")). RunTestWithBp(t, ` install_symlink { name: "foo", installed_location: "/bin/foo", symlink_target: "/system/system_ext/bin/foo", } `) }