1// Copyright 2023 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 etc 16 17import ( 18 "android/soong/android" 19 "strings" 20 "testing" 21) 22 23var prepareForInstallSymlinkTest = android.GroupFixturePreparers( 24 android.PrepareForTestWithArchMutator, 25 android.FixtureRegisterWithContext(RegisterInstallSymlinkBuildComponents), 26) 27 28func TestInstallSymlinkBasic(t *testing.T) { 29 result := prepareForInstallSymlinkTest.RunTestWithBp(t, ` 30 install_symlink { 31 name: "foo", 32 installed_location: "bin/foo", 33 symlink_target: "/system/system_ext/bin/foo", 34 } 35 `) 36 37 foo_variants := result.ModuleVariantsForTests("foo") 38 if len(foo_variants) != 1 { 39 t.Fatalf("expected 1 variant, got %#v", foo_variants) 40 } 41 42 foo := result.ModuleForTests("foo", "android_common").Module() 43 androidMkEntries := android.AndroidMkEntriesForTest(t, result.TestContext, foo) 44 if len(androidMkEntries) != 1 { 45 t.Fatalf("expected 1 androidmkentry, got %d", len(androidMkEntries)) 46 } 47 48 symlinks := androidMkEntries[0].EntryMap["LOCAL_SOONG_INSTALL_SYMLINKS"] 49 if len(symlinks) != 1 { 50 t.Fatalf("Expected 1 symlink, got %d", len(symlinks)) 51 } 52 53 if !strings.HasSuffix(symlinks[0], "system/bin/foo") { 54 t.Fatalf("Expected symlink install path to end in system/bin/foo, got: %s", symlinks[0]) 55 } 56} 57 58func TestInstallSymlinkToRecovery(t *testing.T) { 59 result := prepareForInstallSymlinkTest.RunTestWithBp(t, ` 60 install_symlink { 61 name: "foo", 62 installed_location: "bin/foo", 63 symlink_target: "/system/system_ext/bin/foo", 64 recovery: true, 65 } 66 `) 67 68 foo_variants := result.ModuleVariantsForTests("foo") 69 if len(foo_variants) != 1 { 70 t.Fatalf("expected 1 variant, got %#v", foo_variants) 71 } 72 73 foo := result.ModuleForTests("foo", "android_common").Module() 74 androidMkEntries := android.AndroidMkEntriesForTest(t, result.TestContext, foo) 75 if len(androidMkEntries) != 1 { 76 t.Fatalf("expected 1 androidmkentry, got %d", len(androidMkEntries)) 77 } 78 79 symlinks := androidMkEntries[0].EntryMap["LOCAL_SOONG_INSTALL_SYMLINKS"] 80 if len(symlinks) != 1 { 81 t.Fatalf("Expected 1 symlink, got %d", len(symlinks)) 82 } 83 84 if !strings.HasSuffix(symlinks[0], "recovery/root/system/bin/foo") { 85 t.Fatalf("Expected symlink install path to end in recovery/root/system/bin/foo, got: %s", symlinks[0]) 86 } 87} 88 89func TestErrorOnNonCleanTarget(t *testing.T) { 90 prepareForInstallSymlinkTest. 91 ExtendWithErrorHandler(android.FixtureExpectsOneErrorPattern("Should be a clean filepath")). 92 RunTestWithBp(t, ` 93 install_symlink { 94 name: "foo", 95 installed_location: "bin/foo", 96 symlink_target: "/system/system_ext/../bin/foo", 97 } 98 `) 99} 100 101func TestErrorOnNonCleanInstalledLocation(t *testing.T) { 102 prepareForInstallSymlinkTest. 103 ExtendWithErrorHandler(android.FixtureExpectsOneErrorPattern("Should be a clean filepath")). 104 RunTestWithBp(t, ` 105 install_symlink { 106 name: "foo", 107 installed_location: "bin/../foo", 108 symlink_target: "/system/system_ext/bin/foo", 109 } 110 `) 111} 112 113func TestErrorOnInstalledPathStartingWithDotDot(t *testing.T) { 114 prepareForInstallSymlinkTest. 115 ExtendWithErrorHandler(android.FixtureExpectsOneErrorPattern("Should not start with / or \\.\\./")). 116 RunTestWithBp(t, ` 117 install_symlink { 118 name: "foo", 119 installed_location: "../bin/foo", 120 symlink_target: "/system/system_ext/bin/foo", 121 } 122 `) 123} 124 125func TestErrorOnInstalledPathStartingWithSlash(t *testing.T) { 126 prepareForInstallSymlinkTest. 127 ExtendWithErrorHandler(android.FixtureExpectsOneErrorPattern("Should not start with / or \\.\\./")). 128 RunTestWithBp(t, ` 129 install_symlink { 130 name: "foo", 131 installed_location: "/bin/foo", 132 symlink_target: "/system/system_ext/bin/foo", 133 } 134 `) 135} 136 137var prepareForInstallSymlinkHostTest = android.GroupFixturePreparers( 138 android.PrepareForTestWithAndroidBuildComponents, 139 android.FixtureRegisterWithContext(RegisterInstallSymlinkBuildComponents), 140) 141 142func TestInstallSymlinkHostBasic(t *testing.T) { 143 result := prepareForInstallSymlinkHostTest.RunTestWithBp(t, ` 144 install_symlink_host { 145 name: "foo", 146 installed_location: "bin/foo", 147 symlink_target: "aa/bb/cc", 148 } 149 `) 150 151 buildOS := result.Config.BuildOS.String() 152 foo := result.ModuleForTests("foo", buildOS+"_common").Module() 153 154 androidMkEntries := android.AndroidMkEntriesForTest(t, result.TestContext, foo) 155 if len(androidMkEntries) != 1 { 156 t.Fatalf("expected 1 androidmkentry, got %d", len(androidMkEntries)) 157 } 158 159 symlinks := androidMkEntries[0].EntryMap["LOCAL_SOONG_INSTALL_SYMLINKS"] 160 if len(symlinks) != 1 { 161 t.Fatalf("Expected 1 symlink, got %d", len(symlinks)) 162 } 163 164 if !strings.HasSuffix(symlinks[0], "bin/foo") { 165 t.Fatalf("Expected symlink install path to end in bin/foo, got: %s", symlinks[0]) 166 } 167 168 if !strings.Contains(symlinks[0], "host") { 169 t.Fatalf("Expected symlink install path to contain `host`, got: %s", symlinks[0]) 170 } 171} 172