• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1#!/bin/bash
2
3# Copyright (C) 2021 The Android Open Source Project
4#
5# Licensed under the Apache License, Version 2.0 (the "License");
6# you may not use this file except in compliance with the License.
7# You may obtain a copy of the License at
8#
9#      http://www.apache.org/licenses/LICENSE-2.0
10#
11# Unless required by applicable law or agreed to in writing, software
12# distributed under the License is distributed on an "AS IS" BASIS,
13# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14# See the License for the specific language governing permissions and
15# limitations under the License.
16#
17
18set -xeuo pipefail
19
20apexer_tool_path="${RUNFILES_DIR}/__main__/external/make_injection/host/linux-x86/bin"
21avb_tool_path="${RUNFILES_DIR}/__main__/external/avb"
22android_jar="${RUNFILES_DIR}/__main__/prebuilts/sdk/current/public/android.jar"
23
24input_dir=$(mktemp -d)
25output_dir=$(mktemp -d)
26
27function cleanup {
28  rm -rf ${input_dir}
29  rm -rf ${output_dir}
30}
31
32trap cleanup ERR
33#############################################
34# prepare the inputs
35#############################################
36# Create the input directory with
37# 1. a file with random bits
38# 2. a file installed sub dir with random bits
39# 3. a one-level symlink
40# 4. a two-level symlink with "execroot/__main__" in the path
41# 5. a two-level sumlink without "execroot/__main__" in the path
42# 6. a three-level symlink with "execroot/__main__" in the path
43echo "test file1" > "${input_dir}/file1"
44echo "test file2" > "${input_dir}/file2"
45mkdir -p "${input_dir}/execroot/__main__"
46ln -s "${input_dir}/file1" "${input_dir}/one_level_sym"
47ln -s "${input_dir}/file2" "${input_dir}/execroot/__main__/middle_sym"
48ln -s "${input_dir}/execroot/__main__/middle_sym" "${input_dir}/two_level_sym_in_execroot"
49ln -s "${input_dir}/one_level_sym" "${input_dir}/two_level_sym_not_in_execroot"
50ln -s "${input_dir}/two_level_sym_in_execroot" "${input_dir}/three_level_sym_in_execroot"
51
52# Create the APEX manifest file
53manifest_dir=$(mktemp -d)
54manifest_file="${manifest_dir}/apex_manifest.pb"
55echo '{"name": "com.android.example.apex", "version": 1}' > "${manifest_dir}/apex_manifest.json"
56"${apexer_tool_path}/conv_apex_manifest" proto "${manifest_dir}/apex_manifest.json" -o ${manifest_file}
57
58# Create the file_contexts file
59file_contexts_file=$(mktemp)
60echo '
61(/.*)?           u:object_r:root_file:s0
62/execroot(/.*)?       u:object_r:execroot_file:s0
63' > ${file_contexts_file}
64
65output_file="${output_dir}/test.apex"
66
67# Create the wrapper manifest file
68bazel_apexer_wrapper_manifest_file=$(mktemp)
69echo "
70dir1,file1,"${input_dir}/file1"
71dir2/dir3,file2,"${input_dir}/file2"
72dir4,one_level_sym,"${input_dir}/one_level_sym"
73dir5,two_level_sym_in_execroot,"${input_dir}/two_level_sym_in_execroot"
74dir6,two_level_sym_not_in_execroot,"${input_dir}/two_level_sym_not_in_execroot"
75dir7,three_level_sym_in_execroot,"${input_dir}/three_level_sym_in_execroot"
76" > ${bazel_apexer_wrapper_manifest_file}
77
78#############################################
79# run bazel_apexer_wrapper
80#############################################
81"${RUNFILES_DIR}/__main__/build/bazel/rules/apex/bazel_apexer_wrapper" \
82  --manifest ${manifest_file} \
83  --file_contexts ${file_contexts_file} \
84  --key "${RUNFILES_DIR}/__main__/build/bazel/rules/apex/test.pem" \
85  --apexer_path ${apexer_tool_path} \
86  --apexer_tool_paths ${apexer_tool_path}:${avb_tool_path} \
87  --apex_output_file ${output_file} \
88  --bazel_apexer_wrapper_manifest ${bazel_apexer_wrapper_manifest_file} \
89  --android_jar_path ${android_jar}
90
91#############################################
92# check the result
93#############################################
94"${apexer_tool_path}/deapexer" --debugfs_path="${apexer_tool_path}/debugfs" extract ${output_file} ${output_dir}
95
96# The expected mounted tree should be something like this:
97# /tmp/tmp.9u7ViPlMr7
98# ├── apex_manifest.pb
99# ├── apex_payload.img
100# ├── mnt
101# │   ├── apex_manifest.pb
102# │   ├── dir1
103# │   │   └── file1
104# │   ├── dir2
105# │   │   └── dir3
106# │   │       └── file2
107# │   ├── dir4
108# │   │   └── one_level_sym
109#             (one level symlinks always resolve)
110# │   ├── dir5
111# │   │   └── two_level_sym_in_execroot
112#             (two level symlink resolve if the path contains execroot/__main__)
113# │   ├── dir6
114# │   │   └── two_level_sym_not_in_execroot -> /tmp/tmp.evJh21oYGG/file1
115#             (two level symlink resolve only one level otherwise)
116# │   ├── dir7
117# │   │   └── three_level_sym_in_execroot
118#             (three level symlink resolve if the path contains execroot/__main__)
119# └── test.apex
120
121# b/215129834:
122# https://android-review.googlesource.com/c/platform/system/apex/+/1944264 made
123# it such that the hash of non-payload files in the APEX (like
124# AndroidManifest.xml) will be included as part of the apex_manifest.pb via the
125# apexContainerFilesHash string to ensure that changes to AndroidManifest.xml
126# results in changes in content hash for the apex_payload.img. Since this is
127# potentially fragile, we skip diffing the apex_manifest.pb, and just check that
128# it exists.
129test -f "${output_dir}/apex_manifest.pb" || echo "expected apex_manifest.pb to exist"
130
131# check the contents with diff for the rest of the files
132diff ${input_dir}/file1 ${output_dir}/dir1/file1
133diff ${input_dir}/file2 ${output_dir}/dir2/dir3/file2
134diff ${input_dir}/file1 ${output_dir}/dir4/one_level_sym
135diff ${input_dir}/file2 ${output_dir}/dir5/two_level_sym_in_execroot
136[ `readlink ${output_dir}/dir6/two_level_sym_not_in_execroot` = "${input_dir}/file1" ]
137diff ${input_dir}/file2 ${output_dir}/dir7/three_level_sym_in_execroot
138
139cleanup
140
141echo "Passed for all test cases"
142