4d3d6be34b84b8a3c3fa8c85c68319c38ee175c2
[sdc.git] /
1 /*
2  * Copyright © 2016-2017 European Support Limited
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
17 package org.openecomp.sdc.logging.aspects;
18
19 import org.aspectj.lang.ProceedingJoinPoint;
20 import org.aspectj.lang.Signature;
21 import org.aspectj.lang.reflect.SourceLocation;
22 import org.aspectj.runtime.internal.AroundClosure;
23 import org.easymock.EasyMock;
24 import org.openecomp.sdc.logging.api.AuditData;
25 import org.openecomp.sdc.logging.api.Logger;
26 import org.openecomp.sdc.logging.api.LoggerFactory;
27 import org.powermock.api.easymock.PowerMock;
28 import org.powermock.core.classloader.annotations.PrepareForTest;
29 import org.powermock.modules.testng.PowerMockTestCase;
30 import org.testng.Assert;
31 import org.testng.annotations.Test;
32
33 import java.util.ArrayList;
34 import java.util.Collections;
35 import java.util.List;
36 import java.util.UUID;
37 import java.util.concurrent.atomic.AtomicInteger;
38 import java.util.function.Predicate;
39
40 /**
41  * @author EVITALIY
42  * @since 17/08/2016.
43  */
44 @PrepareForTest(LoggerFactory.class)
45 public class MetricsAspectTest extends PowerMockTestCase {
46
47   private static final Object OBJ_TO_RETURN = new Object();
48   private static final String EXPECTED_MESSAGE = "'{}' took {} milliseconds";
49
50   @Test
51   public void testLogExecutionTime() throws Throwable {
52
53     String className = UUID.randomUUID().toString();
54     String methodName = UUID.randomUUID().toString();
55
56     TestLogger logger = initLogging(className, true);
57
58     MetricsAspect aspect = new MetricsAspect();
59     MockProceedingJoinPoint pjp = new MockProceedingJoinPoint(className, methodName);
60     Object returned = aspect.logExecutionTime(pjp);
61
62     Assert.assertEquals(OBJ_TO_RETURN, returned);
63     assertExecution(methodName, pjp, logger);
64   }
65
66   @Test
67   public void testMetricsDisabled() throws Throwable {
68
69     String className = UUID.randomUUID().toString();
70     String methodName = UUID.randomUUID().toString();
71
72     TestLogger logger = initLogging(className, false);
73
74     MetricsAspect aspect = new MetricsAspect();
75     MockProceedingJoinPoint pjp = new MockProceedingJoinPoint(className, methodName);
76     Object returned = aspect.logExecutionTime(pjp);
77
78     Assert.assertEquals(OBJ_TO_RETURN, returned);
79     Assert.assertEquals(1, pjp.getCount());
80     // return any event - must be empty
81     Assert.assertFalse(logger.contains((event) -> true));
82   }
83
84   @Test(expectedExceptions = IllegalArgumentException.class)
85   public void testThrowingError() throws Throwable {
86
87     String className = UUID.randomUUID().toString();
88     String methodName = UUID.randomUUID().toString();
89
90     final TestLogger logger = initLogging(className, true);
91
92     MetricsAspect aspect = new MetricsAspect();
93     MockProceedingJoinPoint pjp = new MockProceedingJoinPointWithException(className, methodName);
94
95     try {
96       aspect.logExecutionTime(pjp);
97     } finally {
98       assertExecution(methodName, pjp, logger);
99     }
100   }
101
102   private TestLogger initLogging(String className, boolean enabled) {
103     TestLogger logger = new TestLogger(enabled);
104     PowerMock.mockStatic(LoggerFactory.class);
105     EasyMock.expect(LoggerFactory.getLogger(className)).andReturn(logger);
106     PowerMock.replay(LoggerFactory.class);
107     return logger;
108   }
109
110   private void assertExecution(String methodName, MockProceedingJoinPoint pjp, TestLogger logger) {
111
112     Assert.assertEquals(1, pjp.getCount());
113     Assert.assertTrue(logger.contains((event) ->
114         (event != null) && (event.length == 3) && EXPECTED_MESSAGE.equals(event[0])
115             && methodName.equals(event[1]) && (event[2] instanceof Long)));
116   }
117
118   private static class MockSignature implements Signature {
119
120     private final String className;
121     private final String methodName;
122
123     private MockSignature(String className, String methodName) {
124       this.className = className;
125       this.methodName = methodName;
126     }
127
128     @Override
129     public String toShortString() {
130       return null;
131     }
132
133     @Override
134     public String toLongString() {
135       return null;
136     }
137
138     @Override
139     public String getName() {
140       return methodName;
141     }
142
143     @Override
144     public int getModifiers() {
145       return 0;
146     }
147
148     @Override
149     public Class getDeclaringType() {
150       return null;
151     }
152
153     @Override
154     public String getDeclaringTypeName() {
155       return className;
156     }
157   }
158
159   private static class MockProceedingJoinPoint implements ProceedingJoinPoint {
160
161     private AtomicInteger count = new AtomicInteger(0);
162     private Signature signature;
163
164     MockProceedingJoinPoint(String className, String methodName) {
165       this.signature = new MockSignature(className, methodName);
166     }
167
168     int getCount() {
169       return count.get();
170     }
171
172     @Override
173     public Object proceed() throws Throwable {
174       count.incrementAndGet();
175       return OBJ_TO_RETURN;
176     }
177
178     @Override
179     public void set$AroundClosure(AroundClosure aroundClosure) {
180
181     }
182
183     @Override
184     public Object proceed(Object[] objects) throws Throwable {
185       return null;
186     }
187
188     @Override
189     public String toShortString() {
190       return null;
191     }
192
193     @Override
194     public String toLongString() {
195       return null;
196     }
197
198     @Override
199     public Object getThis() {
200       return null;
201     }
202
203     @Override
204     public Object getTarget() {
205       return null;
206     }
207
208     @Override
209     public Object[] getArgs() {
210       return new Object[0];
211     }
212
213     @Override
214     public Signature getSignature() {
215       return this.signature;
216     }
217
218     @Override
219     public SourceLocation getSourceLocation() {
220       return null;
221     }
222
223     @Override
224     public String getKind() {
225       return null;
226     }
227
228     @Override
229     public StaticPart getStaticPart() {
230       return null;
231     }
232   }
233
234   private static class MockProceedingJoinPointWithException extends MockProceedingJoinPoint {
235
236     MockProceedingJoinPointWithException(String className, String methodName) {
237       super(className, methodName);
238     }
239
240     @Override
241     public Object proceed() throws Throwable {
242       super.proceed();
243       throw new IllegalArgumentException();
244     }
245   }
246
247   private class TestLogger implements Logger {
248
249     private final boolean enabled;
250     private List<Object[]> events = Collections.synchronizedList(new ArrayList<>(10));
251
252     TestLogger(boolean enabled) {
253       this.enabled = enabled;
254     }
255
256     @Override
257     public String getName() {
258       throw new RuntimeException("Not implemented");
259     }
260
261     @Override
262     public boolean isMetricsEnabled() {
263       return this.enabled;
264     }
265
266     @Override
267     public void metrics(String var1) {
268       throw new RuntimeException("Not implemented");
269     }
270
271     @Override
272     public void metrics(String var1, Object var2) {
273       throw new RuntimeException("Not implemented");
274     }
275
276     @Override
277     public void metrics(String var1, Object var2, Object var3) {
278
279       if (this.enabled) {
280         events.add(new Object[]{var1, var2, var3});
281       }
282     }
283
284     @Override
285     public void metrics(String var1, Object... var2) {
286       throw new RuntimeException("Not implemented");
287     }
288
289     @Override
290     public void metrics(String var1, Throwable throwable) {
291       throw new RuntimeException("Not implemented");
292     }
293
294     @Override
295     public boolean isAuditEnabled() {
296       throw new RuntimeException("Not implemented");
297     }
298
299     @Override
300     public void audit(AuditData var1) {
301       throw new RuntimeException("Not implemented");
302     }
303
304     @Override
305     public boolean isDebugEnabled() {
306       throw new RuntimeException("Not implemented");
307     }
308
309     @Override
310     public void debug(String var1) {
311       throw new RuntimeException("Not implemented");
312     }
313
314     @Override
315     public void debug(String var1, Object var2) {
316       throw new RuntimeException("Not implemented");
317     }
318
319     @Override
320     public void debug(String var1, Object var2, Object var3) {
321       throw new RuntimeException("Not implemented");
322     }
323
324     @Override
325     public void debug(String var1, Object... var2) {
326       throw new RuntimeException("Not implemented");
327     }
328
329     @Override
330     public void debug(String var1, Throwable throwable) {
331       throw new RuntimeException("Not implemented");
332     }
333
334     @Override
335     public boolean isInfoEnabled() {
336       throw new RuntimeException("Not implemented");
337     }
338
339     @Override
340     public void info(String var1) {
341       throw new RuntimeException("Not implemented");
342     }
343
344     @Override
345     public void info(String var1, Object var2) {
346       throw new RuntimeException("Not implemented");
347     }
348
349     @Override
350     public void info(String var1, Object var2, Object var3) {
351       throw new RuntimeException("Not implemented");
352     }
353
354     @Override
355     public void info(String var1, Object... var2) {
356       throw new RuntimeException("Not implemented");
357     }
358
359     @Override
360     public void info(String var1, Throwable throwable) {
361       throw new RuntimeException("Not implemented");
362     }
363
364     @Override
365     public boolean isWarnEnabled() {
366       throw new RuntimeException("Not implemented");
367     }
368
369     @Override
370     public void warn(String var1) {
371       throw new RuntimeException("Not implemented");
372     }
373
374     @Override
375     public void warn(String var1, Object var2) {
376       throw new RuntimeException("Not implemented");
377     }
378
379     @Override
380     public void warn(String var1, Object... var2) {
381       throw new RuntimeException("Not implemented");
382     }
383
384     @Override
385     public void warn(String var1, Object var2, Object var3) {
386       throw new RuntimeException("Not implemented");
387     }
388
389     @Override
390     public void warn(String var1, Throwable throwable) {
391       throw new RuntimeException("Not implemented");
392     }
393
394     @Override
395     public boolean isErrorEnabled() {
396       throw new RuntimeException("Not implemented");
397     }
398
399     @Override
400     public void error(String var1) {
401       throw new RuntimeException("Not implemented");
402     }
403
404     @Override
405     public void error(String var1, Object var2) {
406       throw new RuntimeException("Not implemented");
407     }
408
409     @Override
410     public void error(String var1, Object var2, Object var3) {
411       throw new RuntimeException("Not implemented");
412     }
413
414     @Override
415     public void error(String var1, Object... var2) {
416       throw new RuntimeException("Not implemented");
417     }
418
419     @Override
420     public void error(String var1, Throwable throwable) {
421       throw new RuntimeException("Not implemented");
422     }
423
424     public boolean contains(Predicate<Object[]> predicate) {
425       return events.stream().anyMatch(predicate);
426     }
427   }
428 }