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