Skip to content

Commit 749b716

Browse files
committed
Merge pull request #1445 from rafaelweingartner/lrg-cs-hackday-025
Fixed Profiler's unit tests bugs.### **Problem:** The TestProfiler class was using Java Thread methods to test the Profiler's functionality. That was causing the tests to fail sometimes since the JVM's thread priority could be low on some OS. ### **Fix:** Using PowerMockito to mock the System calls, the threads could be removed. This makes the tests considerably faster, OS independent and still guarantees the correct implementation of the Profiler class. The changes on the Profiler's class was only to shorten the class's line size by not assigning the return value to a variable returning it straight out. * pr/1445: Fixed changes to match code conventions Fixed Profiler's unit tests bugs. Signed-off-by: Will Stevens <williamstevens@gmail.com>
2 parents 0dcaf19 + c2afa58 commit 749b716

2 files changed

Lines changed: 41 additions & 49 deletions

File tree

utils/src/main/java/com/cloud/utils/Profiler.java

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@ public class Profiler {
2424
private static final long MILLIS_FACTOR = 1000l;
2525
private static final double EXPONENT = 2d;
2626

27-
2827
private Long startTickNanoSeconds;
2928
private Long stopTickNanoSeconds;
3029

@@ -46,8 +45,7 @@ public long stop() {
4645
*/
4746
public long getDuration() {
4847
if (startTickNanoSeconds != null && stopTickNanoSeconds != null) {
49-
final long timeInNanoSeconds = stopTickNanoSeconds - startTickNanoSeconds;
50-
return timeInNanoSeconds;
48+
return stopTickNanoSeconds - startTickNanoSeconds;
5149
}
5250

5351
return -1;
@@ -61,8 +59,7 @@ public long getDuration() {
6159
*/
6260
public long getDurationInMillis() {
6361
if (startTickNanoSeconds != null && stopTickNanoSeconds != null) {
64-
final long timeInMillis = (stopTickNanoSeconds - startTickNanoSeconds) / (long)Math.pow(MILLIS_FACTOR, EXPONENT);
65-
return timeInMillis;
62+
return (stopTickNanoSeconds - startTickNanoSeconds) / (long)Math.pow(MILLIS_FACTOR, EXPONENT);
6663
}
6764

6865
return -1;

utils/src/test/java/com/cloud/utils/TestProfiler.java

Lines changed: 39 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -19,84 +19,79 @@
1919

2020
package com.cloud.utils;
2121

22-
import org.apache.log4j.Logger;
2322
import org.junit.Assert;
23+
import org.junit.Before;
2424
import org.junit.Test;
25+
import org.junit.runner.RunWith;
26+
import org.powermock.api.mockito.PowerMockito;
27+
import org.powermock.core.classloader.annotations.PrepareForTest;
28+
import org.powermock.modules.junit4.PowerMockRunner;
2529

2630
import com.cloud.utils.testcase.Log4jEnabledTestCase;
2731

32+
@RunWith(PowerMockRunner.class)
33+
@PrepareForTest({Profiler.class})
2834
public class TestProfiler extends Log4jEnabledTestCase {
29-
protected final static Logger s_logger = Logger.getLogger(TestProfiler.class);
3035

31-
private static final long MILLIS_FACTOR = 1000l;
32-
private static final int MARGIN = 100;
33-
// Profiler uses System.nanoTime which is not reliable on the millisecond
34-
// A sleep of 1000 milliseconds CAN be measured as 999 milliseconds
35-
// Therefore make the second larger, by 10% of the margin
36-
private static final long ONE_SECOND = 1000l + (MARGIN / 10);
37-
private static final double EXPONENT = 3d;
36+
private static final long SLEEP_TIME_NANO = 1000000000L;
37+
private static Profiler pf;
38+
39+
@Before
40+
public void setUp() {
41+
pf = new Profiler();
42+
PowerMockito.mockStatic(System.class);
43+
PowerMockito.when(System.nanoTime()).thenReturn(0L, SLEEP_TIME_NANO);
44+
}
3845

3946
@Test
4047
public void testProfilerInMillis() {
41-
s_logger.info("testProfiler() started");
48+
//Given
49+
final long sleepTimeMillis = SLEEP_TIME_NANO / 1000000L;
4250

43-
final Profiler pf = new Profiler();
51+
//When
4452
pf.start();
45-
try {
46-
Thread.sleep(ONE_SECOND);
47-
} catch (final InterruptedException e) {
48-
}
4953
pf.stop();
5054

51-
final long durationInMillis = pf.getDurationInMillis();
52-
s_logger.info("Duration in Millis: " + durationInMillis);
53-
54-
// An error margin in order to cover the time taken by the star/stop calls.
55-
// 100 milliseconds margin seems too much, but it will avoid assertion error
56-
// and also fail in case a duration in nanoseconds is used instead.
57-
Assert.assertTrue(durationInMillis >= MILLIS_FACTOR && durationInMillis <= MILLIS_FACTOR + MARGIN);
58-
59-
s_logger.info("testProfiler() stopped");
55+
//Then
56+
Assert.assertTrue(pf.getDurationInMillis() == sleepTimeMillis);
6057
}
6158

6259
@Test
6360
public void testProfilerInNano() {
64-
final Profiler pf = new Profiler();
61+
//Given
62+
final long sleepTimeNano = SLEEP_TIME_NANO;
63+
64+
//When
6565
pf.start();
66-
try {
67-
Thread.sleep(ONE_SECOND);
68-
} catch (final InterruptedException e) {
69-
}
7066
pf.stop();
7167

72-
final long duration = pf.getDuration();
73-
s_logger.info("Duration in Nano: " + duration);
74-
Assert.assertTrue(duration >= Math.pow(MILLIS_FACTOR, EXPONENT));
68+
//Then
69+
Assert.assertTrue(pf.getDuration() == sleepTimeNano);
7570
}
7671

7772
@Test
7873
public void testProfilerNoStart() {
79-
final Profiler pf = new Profiler();
80-
try {
81-
Thread.sleep(20);
82-
} catch (final InterruptedException e) {
83-
}
74+
//Given
75+
final long expectedAnswer = -1;
76+
77+
//When
8478
pf.stop();
8579

86-
Assert.assertTrue(pf.getDurationInMillis() == -1);
80+
//Then
81+
Assert.assertTrue(pf.getDurationInMillis() == expectedAnswer);
8782
Assert.assertFalse(pf.isStarted());
8883
}
8984

9085
@Test
9186
public void testProfilerNoStop() {
92-
final Profiler pf = new Profiler();
87+
//Given
88+
final long expectedAnswer = -1;
89+
90+
//When
9391
pf.start();
94-
try {
95-
Thread.sleep(20);
96-
} catch (final InterruptedException e) {
97-
}
9892

99-
Assert.assertTrue(pf.getDurationInMillis() == -1);
93+
//Then
94+
Assert.assertTrue(pf.getDurationInMillis() == expectedAnswer);
10095
Assert.assertFalse(pf.isStopped());
10196
}
10297
}

0 commit comments

Comments
 (0)