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
46JAR=hoststubgen-test-tiny-framework.jar
47STUB=$TEMP/stub.jar
48IMPL=$TEMP/impl.jar
49
50ANNOTATION_FILTER=$TEMP/annotation-filter.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
71  echo "# Test: $test_name"
72
73  cleanup_temp
74
75  local filter_arg=""
76
77  if [[ "$annotation_filter" != "" ]] ; then
78    echo "$annotation_filter" > $ANNOTATION_FILTER
79    filter_arg="--annotation-allowed-classes-file $ANNOTATION_FILTER"
80    echo "=== filter ==="
81    cat $ANNOTATION_FILTER
82  fi
83
84  local stub_arg=""
85  local impl_arg=""
86
87  if [[ "$STUB" != "" ]] ; then
88    stub_arg="--out-stub-jar $STUB"
89  fi
90  if [[ "$IMPL" != "" ]] ; then
91    impl_arg="--out-impl-jar $IMPL"
92  fi
93
94  hoststubgen \
95      --debug \
96      --in-jar $JAR \
97      $stub_arg \
98      $impl_arg \
99      --stub-annotation \
100          android.hosttest.annotation.HostSideTestStub \
101      --keep-annotation \
102          android.hosttest.annotation.HostSideTestKeep \
103      --stub-class-annotation \
104          android.hosttest.annotation.HostSideTestWholeClassStub \
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      --native-substitute-annotation \
114          android.hosttest.annotation.HostSideTestNativeSubstitutionClass \
115      --class-load-hook-annotation \
116          android.hosttest.annotation.HostSideTestClassLoadHook \
117      --keep-static-initializer-annotation \
118          android.hosttest.annotation.HostSideTestStaticInitializerKeep \
119      $filter_arg \
120      $EXTRA_ARGS \
121      |& tee $HOSTSTUBGEN_OUT
122  HOSTSTUBGEN_RC=${PIPESTATUS[0]}
123  echo "HostStubGen exited with $HOSTSTUBGEN_RC"
124  return 0
125}
126
127assert_file_generated() {
128  local file="$1"
129  if [[ "$file" == "" ]] ; then
130    if [[ -f "$file" ]] ; then
131      echo "HostStubGen shouldn't have generated $file"
132      return 1
133    fi
134  else
135    if ! [[ -f "$file" ]] ; then
136      echo "HostStubGen didn't generate $file"
137      return 1
138    fi
139  fi
140}
141
142run_hoststubgen_for_success() {
143  run_hoststubgen "$@"
144
145  if (( $HOSTSTUBGEN_RC != 0 )) ; then
146    echo "HostStubGen expected to finish successfully, but failed with $rc"
147    return 1
148  fi
149
150  assert_file_generated "$STUB"
151  assert_file_generated "$IMPL"
152}
153
154run_hoststubgen_for_failure() {
155  local test_name="$1"
156  local expected_error_message="$2"
157  shift 2
158
159  run_hoststubgen "$test_name" "$@"
160
161  if (( $HOSTSTUBGEN_RC == 0 )) ; then
162    echo "HostStubGen expected to fail, but it didn't fail"
163    return 1
164  fi
165
166  # The output should contain the expected message. (note we se fgrep here.)
167  grep -Fq "$expected_error_message" $HOSTSTUBGEN_OUT
168}
169
170# Start the tests...
171
172# Pass "" as a filter to _not_ add `--annotation-allowed-classes-file`.
173run_hoststubgen_for_success "No annotation filter" ""
174
175# Now, we use " ", so we do add `--annotation-allowed-classes-file`.
176run_hoststubgen_for_failure "No classes are allowed to have annotations" \
177    "not allowed to have Ravenwood annotations" \
178    " "
179
180run_hoststubgen_for_success "All classes allowed (wildcard)" \
181    "
182* # Allow all classes
183"
184
185run_hoststubgen_for_failure "All classes disallowed (wildcard)" \
186    "not allowed to have Ravenwood annotations" \
187    "
188!* # Disallow all classes
189"
190
191run_hoststubgen_for_failure "Some classes not allowed (1)" \
192    "not allowed to have Ravenwood annotations" \
193    "
194android.hosttest.*
195com.android.hoststubgen.*
196com.supported.*
197"
198
199run_hoststubgen_for_failure "Some classes not allowed (2)" \
200    "not allowed to have Ravenwood annotations" \
201    "
202android.hosttest.*
203com.android.hoststubgen.*
204com.unsupported.*
205"
206
207run_hoststubgen_for_success "All classes allowed (package wildcard)" \
208    "
209android.hosttest.*
210com.android.hoststubgen.*
211com.supported.*
212com.unsupported.*
213"
214
215run_hoststubgen_for_failure "One specific class disallowed" \
216    "TinyFrameworkClassAnnotations is not allowed to have Ravenwood annotations" \
217    "
218!com.android.hoststubgen.test.tinyframework.TinyFrameworkClassAnnotations
219* # All other classes allowed
220"
221
222run_hoststubgen_for_success "One specific class disallowed, but it doesn't use annotations" \
223    "
224!com.android.hoststubgen.test.tinyframework.TinyFrameworkForTextPolicy
225* # All other classes allowed
226"
227
228STUB="" run_hoststubgen_for_success "No stub generation" ""
229
230IMPL="" run_hoststubgen_for_success "No impl generation" ""
231
232STUB="" IMPL="" run_hoststubgen_for_success "No stub, no impl generation" ""
233
234EXTRA_ARGS="--in-jar abc" run_hoststubgen_for_failure "Duplicate arg" \
235    "Duplicate or conflicting argument found: --in-jar" \
236    ""
237
238
239echo "All tests passed"
240exit 0