blob: 2d9721803cac2d9fe4631589ffa0cf5fccd97e05 [file] [log] [blame]
Mathew Inwood63956902018-07-09 15:07:56 +01001/*
2 * Copyright (C) 2018 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
17package com.android.javac;
18
19import static com.google.common.truth.Truth.assertThat;
20
21import static org.mockito.ArgumentMatchers.any;
22import static org.mockito.Mockito.never;
23import static org.mockito.Mockito.times;
24import static org.mockito.Mockito.verify;
25import static org.mockito.MockitoAnnotations.initMocks;
26
27import com.android.class2greylist.Status;
28import com.android.class2greylist.AnnotationVisitor;
29
30import com.google.common.base.Joiner;
31
32import org.junit.Before;
33import org.junit.Test;
34import org.mockito.ArgumentCaptor;
35import org.mockito.Mock;
36
37import java.io.IOException;
38
39public class AnnotationVisitorTest {
40
41 private static final String ANNOTATION = "Lannotation/Anno;";
42
43 private Javac mJavac;
44 @Mock
45 private Status mStatus;
46
47 @Before
48 public void setup() throws IOException {
49 initMocks(this);
50 mJavac = new Javac();
51 mJavac.addSource("annotation.Anno", Joiner.on('\n').join(
52 "package annotation;",
53 "import static java.lang.annotation.RetentionPolicy.CLASS;",
54 "import java.lang.annotation.Retention;",
55 "import java.lang.annotation.Target;",
56 "@Retention(CLASS)",
57 "public @interface Anno {",
58 " String expectedSignature() default \"\";",
59 "}"));
60 }
61
62 private void assertNoErrors() {
63 verify(mStatus, never()).error(any(Throwable.class));
64 verify(mStatus, never()).error(any(String.class));
65 }
66
67 @Test
68 public void testGreylistMethod() throws IOException {
69 mJavac.addSource("a.b.Class", Joiner.on('\n').join(
70 "package a.b;",
71 "import annotation.Anno;",
72 "public class Class {",
73 " @Anno",
74 " public void method() {}",
75 "}"));
76 assertThat(mJavac.compile()).isTrue();
77
78 new AnnotationVisitor(mJavac.getCompiledClass("a.b.Class"), ANNOTATION, mStatus)
79 .visit();
80
81 assertNoErrors();
82 ArgumentCaptor<String> greylist = ArgumentCaptor.forClass(String.class);
83 verify(mStatus, times(1)).greylistEntry(greylist.capture());
84 assertThat(greylist.getValue()).isEqualTo("La/b/Class;->method()V");
85 }
86
87 @Test
88 public void testGreylistConstructor() throws IOException {
89 mJavac.addSource("a.b.Class", Joiner.on('\n').join(
90 "package a.b;",
91 "import annotation.Anno;",
92 "public class Class {",
93 " @Anno",
94 " public Class() {}",
95 "}"));
96 assertThat(mJavac.compile()).isTrue();
97
98 new AnnotationVisitor(mJavac.getCompiledClass("a.b.Class"), ANNOTATION, mStatus)
99 .visit();
100
101 assertNoErrors();
102 ArgumentCaptor<String> greylist = ArgumentCaptor.forClass(String.class);
103 verify(mStatus, times(1)).greylistEntry(greylist.capture());
104 assertThat(greylist.getValue()).isEqualTo("La/b/Class;-><init>()V");
105 }
106
107 @Test
108 public void testGreylistField() throws IOException {
109 mJavac.addSource("a.b.Class", Joiner.on('\n').join(
110 "package a.b;",
111 "import annotation.Anno;",
112 "public class Class {",
113 " @Anno",
114 " public int i;",
115 "}"));
116 assertThat(mJavac.compile()).isTrue();
117
118 new AnnotationVisitor(mJavac.getCompiledClass("a.b.Class"), ANNOTATION, mStatus)
119 .visit();
120
121 assertNoErrors();
122 ArgumentCaptor<String> greylist = ArgumentCaptor.forClass(String.class);
123 verify(mStatus, times(1)).greylistEntry(greylist.capture());
124 assertThat(greylist.getValue()).isEqualTo("La/b/Class;->i:I");
125 }
126
127 @Test
128 public void testGreylistMethodExpectedSignature() throws IOException {
129 mJavac.addSource("a.b.Class", Joiner.on('\n').join(
130 "package a.b;",
131 "import annotation.Anno;",
132 "public class Class {",
133 " @Anno(expectedSignature=\"La/b/Class;->method()V\")",
134 " public void method() {}",
135 "}"));
136 assertThat(mJavac.compile()).isTrue();
137
138 new AnnotationVisitor(mJavac.getCompiledClass("a.b.Class"), ANNOTATION, mStatus)
139 .visit();
140
141 assertNoErrors();
142 ArgumentCaptor<String> greylist = ArgumentCaptor.forClass(String.class);
143 verify(mStatus, times(1)).greylistEntry(greylist.capture());
144 assertThat(greylist.getValue()).isEqualTo("La/b/Class;->method()V");
145 }
146
147 @Test
148 public void testGreylistMethodExpectedSignatureWrong() throws IOException {
149 mJavac.addSource("a.b.Class", Joiner.on('\n').join(
150 "package a.b;",
151 "import annotation.Anno;",
152 "public class Class {",
153 " @Anno(expectedSignature=\"La/b/Class;->nomethod()V\")",
154 " public void method() {}",
155 "}"));
156 assertThat(mJavac.compile()).isTrue();
157
158 new AnnotationVisitor(mJavac.getCompiledClass("a.b.Class"), ANNOTATION, mStatus)
159 .visit();
160
161 verify(mStatus, times(1)).error(any(String.class));
162 }
163
164 @Test
165 public void testGreylistInnerClassMethod() throws IOException {
166 mJavac.addSource("a.b.Class", Joiner.on('\n').join(
167 "package a.b;",
168 "import annotation.Anno;",
169 "public class Class {",
170 " public class Inner {",
171 " @Anno",
172 " public void method() {}",
173 " }",
174 "}"));
175 assertThat(mJavac.compile()).isTrue();
176
177 new AnnotationVisitor(mJavac.getCompiledClass("a.b.Class$Inner"), ANNOTATION,
178 mStatus).visit();
179
180 assertNoErrors();
181 ArgumentCaptor<String> greylist = ArgumentCaptor.forClass(String.class);
182 verify(mStatus, times(1)).greylistEntry(greylist.capture());
183 assertThat(greylist.getValue()).isEqualTo("La/b/Class$Inner;->method()V");
184 }
185
186 @Test
187 public void testMethodNotGreylisted() throws IOException {
188 mJavac.addSource("a.b.Class", Joiner.on('\n').join(
189 "package a.b;",
190 "public class Class {",
191 " public void method() {}",
192 "}"));
193 assertThat(mJavac.compile()).isTrue();
194
195 new AnnotationVisitor(mJavac.getCompiledClass("a.b.Class"), ANNOTATION, mStatus)
196 .visit();
197
198 assertNoErrors();
199 verify(mStatus, never()).greylistEntry(any(String.class));
200 }
201
202}