1#!/bin/bash 2# Copyright (C) 2023 The Android Open Source Project 3# 4# Licensed under the Apache License, Version 2.0 (the "License"); 5# you may not use this file except in compliance with the License. 6# You may obtain a copy of the License at 7# 8# http://www.apache.org/licenses/LICENSE-2.0 9# 10# Unless required by applicable law or agreed to in writing, software 11# distributed under the License is distributed on an "AS IS" BASIS, 12# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13# See the License for the specific language governing permissions and 14# limitations under the License. 15 16# This command is expected to be executed with: atest hoststubgen-invoke-test 17 18set -e # Exit when any command files 19 20# This script runs HostStubGen directly with various arguments and make sure 21# the tool behaves in the expected way. 22 23 24echo "# Listing files in the test environment" 25ls -lR 26 27echo "# Dumping the environment variables" 28env 29 30# Set up the constants and variables 31 32# Bazel sets $TEST_TMPDIR. 33export TEMP=$TEST_TMPDIR 34 35if [[ "$TEMP" == "" ]] ; then 36 TEMP=./tmp 37 mkdir -p $TEMP 38fi 39 40cleanup_temp() { 41 rm -fr $TEMP/* 42} 43 44cleanup_temp 45 46INJAR=hoststubgen-test-tiny-framework.jar 47OUTJAR=$TEMP/host.jar 48 49ANNOTATION_FILTER=$TEMP/annotation-filter.txt 50POLICY_FILE=$TEMP/policy-file.txt 51 52HOSTSTUBGEN_OUT=$TEMP/output.txt 53 54EXTRA_ARGS="" 55 56# Because of `set -e`, we can't return non-zero from functions, so we store 57# HostStubGen result in it. 58HOSTSTUBGEN_RC=0 59 60# Note, because the build rule will only install hoststubgen.jar, but not the wrapper script, 61# we need to execute it manually with the java command. 62hoststubgen() { 63 echo "Running hoststubgen with: $*" 64 java -jar ./hoststubgen.jar "$@" 65} 66 67run_hoststubgen() { 68 local test_name="$1" 69 local annotation_filter="$2" 70 local policy="$3" 71 72 echo "# Test: $test_name" 73 74 cleanup_temp 75 76 local filter_arg="" 77 local policy_arg="" 78 79 if [[ "$annotation_filter" != "" ]] ; then 80 echo "$annotation_filter" > $ANNOTATION_FILTER 81 filter_arg="--annotation-allowed-classes-file $ANNOTATION_FILTER" 82 echo "=== filter ===" 83 cat $ANNOTATION_FILTER 84 fi 85 86 if [[ "$policy" != "" ]] ; then 87 echo "$policy" > $POLICY_FILE 88 policy_arg="--policy-override-file $POLICY_FILE" 89 echo "=== policy ===" 90 cat $POLICY_FILE 91 fi 92 93 local out_arg="" 94 95 if [[ "$OUTJAR" != "" ]] ; then 96 out_arg="--out-jar $OUTJAR" 97 fi 98 99 hoststubgen \ 100 --debug \ 101 --in-jar $INJAR \ 102 $out_arg \ 103 --keep-annotation \ 104 android.hosttest.annotation.HostSideTestKeep \ 105 --keep-class-annotation \ 106 android.hosttest.annotation.HostSideTestWholeClassKeep \ 107 --throw-annotation \ 108 android.hosttest.annotation.HostSideTestThrow \ 109 --remove-annotation \ 110 android.hosttest.annotation.HostSideTestRemove \ 111 --substitute-annotation \ 112 android.hosttest.annotation.HostSideTestSubstitute \ 113 --redirect-annotation \ 114 android.hosttest.annotation.HostSideTestRedirect \ 115 --redirection-class-annotation \ 116 android.hosttest.annotation.HostSideTestRedirectionClass \ 117 --class-load-hook-annotation \ 118 android.hosttest.annotation.HostSideTestClassLoadHook \ 119 --keep-static-initializer-annotation \ 120 android.hosttest.annotation.HostSideTestStaticInitializerKeep \ 121 --partially-allowed-annotation \ 122 android.hosttest.annotation.HostSideTestPartiallyAllowlisted \ 123 $filter_arg \ 124 $policy_arg \ 125 $EXTRA_ARGS \ 126 |& tee $HOSTSTUBGEN_OUT 127 HOSTSTUBGEN_RC=${PIPESTATUS[0]} 128 echo "HostStubGen exited with $HOSTSTUBGEN_RC" 129 return 0 130} 131 132assert_file_generated() { 133 local file="$1" 134 if [[ "$file" == "" ]] ; then 135 if [[ -f "$file" ]] ; then 136 echo "HostStubGen shouldn't have generated $file" 137 return 1 138 fi 139 else 140 if ! [[ -f "$file" ]] ; then 141 echo "HostStubGen didn't generate $file" 142 return 1 143 fi 144 fi 145} 146 147run_hoststubgen_for_success() { 148 local test_name="$1" 149 run_hoststubgen "$@" 150 151 if (( $HOSTSTUBGEN_RC != 0 )) ; then 152 echo "HostStubGen expected to finish successfully, but failed with $HOSTSTUBGEN_RC: Test=$test_name" 153 return 1 154 fi 155 156 assert_file_generated "$STUB" 157 assert_file_generated "$IMPL" 158} 159 160run_hoststubgen_for_failure() { 161 local test_name="$1" 162 local expected_error_message="$2" 163 shift 2 164 165 run_hoststubgen "$test_name" "$@" 166 167 if (( $HOSTSTUBGEN_RC == 0 )) ; then 168 echo "HostStubGen expected to fail, but it didn't fail. Test=$test_name" 169 return 1 170 fi 171 172 # The output should contain the expected message. (note we se fgrep here.) 173 grep -Fq "$expected_error_message" $HOSTSTUBGEN_OUT 174} 175 176# Start the tests... 177 178# These classes require special care, so let's delete them in most tests... 179DELETE_PARTIAL_ANNOTATION_CLASSESS=' 180class com.android.hoststubgen.test.tinyframework.TinyFrameworkPartiallyAllowlisted$PartiallyAllowlisted remove 181class com.android.hoststubgen.test.tinyframework.TinyFrameworkPartiallyAllowlisted$PartialWithWholeClass_bad remove 182class com.android.hoststubgen.test.tinyframework.TinyFrameworkPartiallyAllowlisted$PartiallyAllowlistedWithoutAnnot_bad remove 183' 184 185# Pass "" as a filter to _not_ add `--annotation-allowed-classes-file`. 186run_hoststubgen_for_success "No annotation filter" "" "$DELETE_PARTIAL_ANNOTATION_CLASSESS" 187 188# Now, we use " ", so we do add `--annotation-allowed-classes-file`. 189run_hoststubgen_for_failure "No classes are allowed to have annotations" \ 190 "not allowed to have Ravenwood annotations" \ 191 " " "$DELETE_PARTIAL_ANNOTATION_CLASSESS" 192 193run_hoststubgen_for_success "All classes allowed (wildcard)" \ 194 " 195* # Allow all classes 196" "$DELETE_PARTIAL_ANNOTATION_CLASSESS" 197 198run_hoststubgen_for_failure "All classes disallowed (wildcard)" \ 199 "not allowed to have Ravenwood annotations" \ 200 " 201!* # Disallow all classes 202" "$DELETE_PARTIAL_ANNOTATION_CLASSESS" 203 204run_hoststubgen_for_failure "Some classes not allowed (1)" \ 205 "not allowed to have Ravenwood annotations" \ 206 " 207android.hosttest.* 208com.android.hoststubgen.* 209com.supported.* 210" "$DELETE_PARTIAL_ANNOTATION_CLASSESS" 211 212run_hoststubgen_for_failure "Some classes not allowed (2)" \ 213 "not allowed to have Ravenwood annotations" \ 214 " 215android.hosttest.* 216com.android.hoststubgen.* 217com.unsupported.* 218" "$DELETE_PARTIAL_ANNOTATION_CLASSESS" 219 220run_hoststubgen_for_success "All classes allowed (package wildcard)" \ 221 " 222android.hosttest.* 223com.android.hoststubgen.* 224com.supported.* 225com.unsupported.* 226" "$DELETE_PARTIAL_ANNOTATION_CLASSESS" 227 228run_hoststubgen_for_failure "One specific class disallowed" \ 229 "TinyFrameworkAnnotations is not allowed to have Ravenwood annotations" \ 230 " 231!com.android.hoststubgen.test.tinyframework.TinyFrameworkAnnotations 232* # All other classes allowed 233" "$DELETE_PARTIAL_ANNOTATION_CLASSESS" 234 235run_hoststubgen_for_success "One specific class disallowed, but it doesn't use annotations" \ 236 " 237!com.android.hoststubgen.test.tinyframework.TinyFrameworkForTextPolicy 238* # All other classes allowed 239" "$DELETE_PARTIAL_ANNOTATION_CLASSESS" 240 241OUTJAR="" run_hoststubgen_for_success "No output generation" "" "$DELETE_PARTIAL_ANNOTATION_CLASSESS" 242 243EXTRA_ARGS="--in-jar abc" run_hoststubgen_for_failure "Duplicate arg" \ 244 "Duplicate or conflicting argument found: --in-jar" \ 245 "" 246 247# --------------------------------------------------------------------------------------------- 248# Tests for "partially-allowlisted". 249# --------------------------------------------------------------------------------------------- 250 251# Allowlist used by hoststubgen-test-tiny-test. 252ALLOWLIST=' 253com.android.hoststubgen.test.tinyframework.* 254com.supported.* 255com.unsupported.* 256!* 257' 258 259run_hoststubgen_for_success 'The settings used by hoststubgen-test-tiny-test' \ 260 "$ALLOWLIST" \ 261 ' 262class com.android.hoststubgen.test.tinyframework.TinyFrameworkPartiallyAllowlisted$PartiallyAllowlisted allow-annotation 263 method foo2 allow-annotation 264 265class com.android.hoststubgen.test.tinyframework.TinyFrameworkPartiallyAllowlisted$PartialWithWholeClass_bad remove 266class com.android.hoststubgen.test.tinyframework.TinyFrameworkPartiallyAllowlisted$PartiallyAllowlistedWithoutAnnot_bad remove 267' 268 269run_hoststubgen_for_failure 'PartiallyAllowlisted does not have allow-annotation' \ 270 "PartiallyAllowlisted has annotation android.hosttest.annotation.HostSideTestPartiallyAllowlisted, but" \ 271 "$ALLOWLIST" \ 272 ' 273#class com.android.hoststubgen.test.tinyframework.TinyFrameworkPartiallyAllowlisted$PartiallyAllowlisted allow-annotation 274# method foo2 allow-annotation 275 276class com.android.hoststubgen.test.tinyframework.TinyFrameworkPartiallyAllowlisted$PartialWithWholeClass_bad remove 277class com.android.hoststubgen.test.tinyframework.TinyFrameworkPartiallyAllowlisted$PartiallyAllowlistedWithoutAnnot_bad remove 278' 279 280 281run_hoststubgen_for_failure 'PartiallyAllowlisted.foo2 does not have allow-annotation' \ 282 "foo2(I)I is not allowed to have Ravenwood annotations. (Class is partially allowlisted.)" \ 283 "$ALLOWLIST" \ 284 ' 285class com.android.hoststubgen.test.tinyframework.TinyFrameworkPartiallyAllowlisted$PartiallyAllowlisted allow-annotation 286# method foo2 allow-annotation 287 288class com.android.hoststubgen.test.tinyframework.TinyFrameworkPartiallyAllowlisted$PartialWithWholeClass_bad remove 289class com.android.hoststubgen.test.tinyframework.TinyFrameworkPartiallyAllowlisted$PartiallyAllowlistedWithoutAnnot_bad remove 290' 291 292run_hoststubgen_for_failure 'Partially-allowlisted classes cannot have class-wide policies' \ 293 "PartialWithWholeClass_bad has class wide annotation android.hosttest.annotation.HostSideTestWholeClassKeep" \ 294 "$ALLOWLIST" \ 295 ' 296class com.android.hoststubgen.test.tinyframework.TinyFrameworkPartiallyAllowlisted$PartiallyAllowlisted allow-annotation 297 method foo2 allow-annotation 298 299# Now with allow-annotation 300class com.android.hoststubgen.test.tinyframework.TinyFrameworkPartiallyAllowlisted$PartialWithWholeClass_bad allow-annotation 301 302class com.android.hoststubgen.test.tinyframework.TinyFrameworkPartiallyAllowlisted$PartiallyAllowlistedWithoutAnnot_bad remove 303' 304 305run_hoststubgen_for_failure 'Partially-allowlisted classes cannot have class-wide policies' \ 306 "PartiallyAllowlistedWithoutAnnot_bad must have android.hosttest.annotation.HostSideTestPartiallyAllowlisted" \ 307 "$ALLOWLIST" \ 308 ' 309class com.android.hoststubgen.test.tinyframework.TinyFrameworkPartiallyAllowlisted$PartiallyAllowlisted allow-annotation 310 method foo2 allow-annotation 311class com.android.hoststubgen.test.tinyframework.TinyFrameworkPartiallyAllowlisted$PartialWithWholeClass_bad remove 312 313# Now with allow-annotation 314class com.android.hoststubgen.test.tinyframework.TinyFrameworkPartiallyAllowlisted$PartiallyAllowlistedWithoutAnnot_bad allow-annotation 315' 316 317run_hoststubgen_for_success 'The settings used by hoststubgen-test-tiny-test' \ 318 "$ALLOWLIST" \ 319 ' 320class com.android.hoststubgen.test.tinyframework.TinyFrameworkPartiallyAllowlisted$PartiallyAllowlisted allow-annotation 321 method foo2 allow-annotation 322class com.android.hoststubgen.test.tinyframework.TinyFrameworkPartiallyAllowlisted$PartialWithWholeClass_bad remove 323class com.android.hoststubgen.test.tinyframework.TinyFrameworkPartiallyAllowlisted$PartiallyAllowlistedWithoutAnnot_bad remove 324 325# NoAnnotations has no annotations at all. Setting "allow-annotation" to it is okay even though 326# it does not have an @HostSideTestPartiallyAllowlisted, because it does nott have any other annotations anyway. 327class com.android.hoststubgen.test.tinyframework.TinyFrameworkPartiallyAllowlisted$NoAnnotations allow-annotation 328' 329 330echo "All tests passed" 331exit 0 332