Skip to content

Commit 871fb15

Browse files
author
guyplusplus
committed
Stress JUnit test
1 parent 74ab9c6 commit 871fb15

File tree

3 files changed

+120
-41
lines changed

3 files changed

+120
-41
lines changed

README.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,11 @@ SVC1.failureRateThreshold=20
6868
SVC1.slidingWindowSize=150
6969
```
7070

71+
## Overhead
72+
Load test, included in the JUnit tests, shows an overhead less than 0.05ms per wrapped logic.
73+
74+
The load test is based on 4 concurrent threads running with a CLOSED circuit breaker, with a wrapped logic around 6.5ms.
75+
7176
## Concurrency
7277
The code has 3 synchronized methods, it has minimum impact to initial code performance. Actual business logic is not included in the synchronized code, so blocking time is minimum
7378
- `boolean isClosedForThisCall()` to check the state of the breaker for this current call
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
package com.geckotechnology.simpleCircuitBreaker;
2+
3+
public class DoubleHolder {
4+
5+
private double d = 0;
6+
private int count = 0;
7+
8+
public synchronized void addDouble(double value) {
9+
d += value;
10+
count++;
11+
}
12+
public double getDoubleAverage() {
13+
return d/(double)count;
14+
}
15+
}

src/test/java/com/geckotechnology/simpleCircuitBreaker/OverheadTest.java

Lines changed: 100 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -1,57 +1,116 @@
11
package com.geckotechnology.simpleCircuitBreaker;
22

3+
import static org.junit.Assert.assertTrue;
4+
import static org.junit.Assert.fail;
5+
6+
import org.junit.Before;
7+
import org.junit.Test;
8+
39
public class OverheadTest {
410

5-
CircuitBreaker breaker;
611
private static final int ARRAY_SIZE = 5017;
7-
private static final int LOOP_CALC_COUNT = 500000;
8-
private static final int LOOP_TEST = 1000;
12+
private static final int LOOP_ONE_CALL = 500000;
13+
private static final int LOOP_TEST = 5000;
914
private static final int LOOP_TEST_WARMUP = 10000;
15+
private static final int THREAD_COUNT = 4;
16+
17+
@Before
18+
public void warmUp() {
19+
System.out.println("Starting warmUp");
20+
int array[] = createArray();
21+
for(int i = 0; i<LOOP_TEST_WARMUP; i++)
22+
oneCall(array);
23+
}
1024

11-
public static void main(String[] args) {
12-
new OverheadTest().go();
13-
25+
@Test
26+
public void overHeadTestSingleThread() {
27+
System.out.println("Starting OverheadTest.overHeadTestSingleThread");
28+
//no breaker
29+
double durationPerCallNoBreaker = singleThreadNoBreaker();
30+
//with breaker
31+
CircuitBreakerConfig config = new CircuitBreakerConfig();
32+
config.setSlidingWindowSize(10);
33+
CircuitBreaker breaker = new CircuitBreaker(config);
34+
double durationPerCallWithBreaker = singleThreadWithBreaker(breaker);
35+
//summary
36+
double overHead = durationPerCallWithBreaker - durationPerCallNoBreaker;
37+
System.out.println("duration (ms) per oneCall - NO BREAKER: " + durationPerCallNoBreaker);
38+
System.out.println("duration (ms) per oneCall - WITH BREAKER: " + durationPerCallWithBreaker);
39+
System.out.println("Overhead (ms) per oneCall of breaker: " + overHead);
40+
assertTrue(overHead < 0.1);
1441
}
15-
16-
public void go() {
42+
43+
@Test
44+
public void overHeadTestMultiThread() {
45+
System.out.println("Starting OverheadTest.overHeadTestMultiThread");
46+
//no breaker
47+
final DoubleHolder durationPerCallNoBreakerHolder = new DoubleHolder();
48+
Thread threads[] = new Thread[THREAD_COUNT];
49+
for(int t = 0; t<THREAD_COUNT; t++) {
50+
threads[t] = new Thread() {
51+
public void run() {
52+
double durationPerCallNoBreaker = singleThreadNoBreaker();
53+
durationPerCallNoBreakerHolder.addDouble(durationPerCallNoBreaker);
54+
}
55+
};
56+
threads[t].start();
57+
}
58+
for(int t = 0; t<THREAD_COUNT; t++)
59+
try {
60+
threads[t].join();
61+
} catch (InterruptedException e) {
62+
fail("InterruptedException catched: " + e);
63+
}
64+
//with breaker
1765
CircuitBreakerConfig config = new CircuitBreakerConfig();
1866
config.setSlidingWindowSize(10);
19-
breaker = new CircuitBreaker(config);
20-
21-
int array[] = null;
22-
long start, end = 0;
23-
24-
//warm-up
25-
array = createArray();
26-
for(int i = 0; i<LOOP_TEST_WARMUP; i++)
67+
final CircuitBreaker breaker = new CircuitBreaker(config);
68+
final DoubleHolder durationPerCallWithBreakerHolder = new DoubleHolder();
69+
threads = new Thread[THREAD_COUNT];
70+
for(int t = 0; t<THREAD_COUNT; t++) {
71+
threads[t] = new Thread() {
72+
public void run() {
73+
double durationPerCallWithBreaker = singleThreadWithBreaker(breaker);
74+
durationPerCallWithBreakerHolder.addDouble(durationPerCallWithBreaker);
75+
}
76+
};
77+
threads[t].start();
78+
}
79+
for(int t = 0; t<THREAD_COUNT; t++)
80+
try {
81+
threads[t].join();
82+
} catch (InterruptedException e) {
83+
fail("InterruptedException catched: " + e);
84+
}
85+
//summary
86+
double overHead = durationPerCallWithBreakerHolder.getDoubleAverage() - durationPerCallNoBreakerHolder.getDoubleAverage();
87+
System.out.println("duration (ms) per oneCall - NO BREAKER: " + durationPerCallNoBreakerHolder.getDoubleAverage());
88+
System.out.println("duration (ms) per oneCall - WITH BREAKER: " + durationPerCallWithBreakerHolder.getDoubleAverage());
89+
System.out.println("Overhead (ms) per oneCall of breaker: " + overHead);
90+
assertTrue(overHead < 0.1);
91+
}
92+
93+
private double singleThreadNoBreaker() {
94+
int array[] = createArray();
95+
long start = System.currentTimeMillis();
96+
for(int i = 0; i<LOOP_TEST; i++)
2797
oneCall(array);
28-
29-
for(int j = 0; j<5; j++) {
30-
//no breaker
31-
array = createArray();
32-
start = System.currentTimeMillis();
33-
for(int i = 0; i<LOOP_TEST; i++)
98+
long end = System.currentTimeMillis();
99+
return (double)(end-start)/(double)LOOP_TEST;
100+
}
101+
102+
private double singleThreadWithBreaker(CircuitBreaker breaker) {
103+
int array[] = createArray();
104+
long start = System.currentTimeMillis();
105+
for(int i = 0; i<LOOP_TEST; i++) {
106+
if(breaker.isClosedForThisCall()) {
107+
long startCall = System.currentTimeMillis();
34108
oneCall(array);
35-
end = System.currentTimeMillis();
36-
double durationPerCallNoBreaker = (double)(end-start)/(double)LOOP_TEST;
37-
System.out.println("duration (ms) per oneCall - NO BREAKER: " + durationPerCallNoBreaker);
38-
39-
//breaker
40-
array = createArray();
41-
start = System.currentTimeMillis();
42-
for(int i = 0; i<LOOP_TEST; i++) {
43-
if(breaker.isClosedForThisCall()) {
44-
long startCall = System.currentTimeMillis();
45-
oneCall(array);
46-
breaker.callSucceeded(System.currentTimeMillis() - startCall);
47-
}
109+
breaker.callSucceeded(System.currentTimeMillis() - startCall);
48110
}
49-
end = System.currentTimeMillis();
50-
double durationPerCallWithBreaker = (double)(end-start)/(double)LOOP_TEST;
51-
System.out.println("duration (ms) per oneCall - WITH BREAKER: " + durationPerCallWithBreaker);
52-
System.out.println("Overhead (ms) per oneCall of breaker: " + (durationPerCallWithBreaker - durationPerCallNoBreaker));
53111
}
54-
System.out.println("Done");
112+
long end = System.currentTimeMillis();
113+
return (double)(end-start)/(double)LOOP_TEST;
55114
}
56115

57116
private int[] createArray() {
@@ -64,7 +123,7 @@ private int[] createArray() {
64123
private void oneCall(int array[]) {
65124
// long start = System.currentTimeMillis();
66125
int s = array.length;
67-
for(int i = 0; i<LOOP_CALC_COUNT; i++)
126+
for(int i = 0; i<LOOP_ONE_CALL; i++)
68127
array[(7 * i) % s] = array[(3 * i) % s] * array [i % s] + array [(5 * i) % s];
69128
// long end = System.currentTimeMillis();
70129
// System.out.println("duration: " + (end-start));

0 commit comments

Comments
 (0)