Skip to content

Commit 07d8325

Browse files
committed
[WIP] Add several unit tests
1 parent 92ebb3a commit 07d8325

File tree

3 files changed

+242
-6
lines changed

3 files changed

+242
-6
lines changed

lib/build.gradle

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ dependencies {
88
testImplementation(platform("org.junit:junit-bom:${junitVersion}"))
99
testImplementation 'org.junit.jupiter:junit-jupiter'
1010
testImplementation "org.mockito:mockito-core:${mockitoVersion}"
11+
testImplementation "org.mockito:mockito-inline:${mockitoVersion}"
1112
}
1213

1314
test {

lib/src/main/java/com/scalar/admin/kubernetes/Pauser.java

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -78,12 +78,7 @@ public PausedDuration pause(int pauseDuration, @Nullable Long maxPauseWaitTime)
7878
"pauseDuration is required to be greater than 0 millisecond.");
7979
}
8080

81-
TargetSnapshot target;
82-
try {
83-
target = targetSelector.select();
84-
} catch (Exception e) {
85-
throw new PauserException("Failed to find the target pods to pause.", e);
86-
}
81+
TargetSnapshot target = getTarget();
8782

8883
RequestCoordinator coordinator;
8984
try {
@@ -160,6 +155,14 @@ void unpauseWithRetry(RequestCoordinator coordinator, int maxRetryCount, TargetS
160155
}
161156
}
162157

158+
TargetSnapshot getTarget() throws PauserException {
159+
try {
160+
return targetSelector.select();
161+
} catch (Exception e) {
162+
throw new PauserException("Failed to find the target pods to pause.", e);
163+
}
164+
}
165+
163166
RequestCoordinator getRequestCoordinator(TargetSnapshot target) {
164167
return new RequestCoordinator(
165168
target.getPods().stream()
Lines changed: 232 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,232 @@
1+
package com.scalar.admin.kubernetes;
2+
3+
import static com.scalar.admin.kubernetes.Pauser.MAX_UNPAUSE_RETRY_COUNT;
4+
import static org.junit.jupiter.api.Assertions.*;
5+
import static org.mockito.Mockito.*;
6+
7+
import com.scalar.admin.RequestCoordinator;
8+
import io.kubernetes.client.openapi.models.V1Deployment;
9+
import io.kubernetes.client.openapi.models.V1ObjectMeta;
10+
import io.kubernetes.client.util.Config;
11+
import java.io.IOException;
12+
import org.junit.jupiter.api.AfterEach;
13+
import org.junit.jupiter.api.BeforeEach;
14+
import org.junit.jupiter.api.Nested;
15+
import org.junit.jupiter.api.Test;
16+
import org.mockito.MockedStatic;
17+
18+
class PauserTest {
19+
20+
private MockedStatic<Config> mockedConfig;
21+
private RequestCoordinator requestCoordinator;
22+
private TargetSnapshot targetSnapshot;
23+
private TargetSelector targetSelector;
24+
private V1Deployment deployment;
25+
private V1ObjectMeta objectMeta;
26+
private final String dummyObjectName = "dummyObjectName";
27+
28+
@BeforeEach
29+
void beforeEach() throws PauserException {
30+
mockedConfig = mockStatic(Config.class);
31+
mockedConfig.when(() -> Config.defaultClient()).thenReturn(null);
32+
requestCoordinator = mock(RequestCoordinator.class);
33+
targetSnapshot = mock(TargetSnapshot.class);
34+
targetSelector = mock(TargetSelector.class);
35+
deployment = mock(V1Deployment.class);
36+
objectMeta = mock(V1ObjectMeta.class);
37+
38+
when(targetSnapshot.getDeployment()).thenReturn(deployment);
39+
when(deployment.getMetadata()).thenReturn(objectMeta);
40+
when(objectMeta.getName()).thenReturn(dummyObjectName);
41+
when(targetSelector.select()).thenReturn(targetSnapshot);
42+
}
43+
44+
@AfterEach
45+
void afterEach() {
46+
mockedConfig.close();
47+
}
48+
49+
@Nested
50+
class ConstructorPauser {
51+
@Test
52+
void WithCorrectArgsReturnPauser() throws PauserException, IOException {
53+
// Arrange
54+
String namespace = "dummyNs";
55+
String helmReleaseName = "dummyRelease";
56+
57+
// Act & Assert
58+
assertDoesNotThrow(() -> new Pauser(namespace, helmReleaseName));
59+
}
60+
61+
@Test
62+
void WithNullNamespaceShouldThrowException() {
63+
// Arrange
64+
String namespace = null;
65+
String helmReleaseName = "dummyRelease";
66+
67+
// Act & Assert
68+
IllegalArgumentException thrown =
69+
assertThrows(
70+
IllegalArgumentException.class, () -> new Pauser(namespace, helmReleaseName));
71+
assertEquals("namespace is required", thrown.getMessage());
72+
}
73+
74+
@Test
75+
void WithNullHelmReleaseNameShouldThrowException() {
76+
// Arrange
77+
String namespace = "dummyNs";
78+
String helmReleaseName = null;
79+
80+
// Act & Assert
81+
IllegalArgumentException thrown =
82+
assertThrows(
83+
IllegalArgumentException.class, () -> new Pauser(namespace, helmReleaseName));
84+
assertEquals("helmReleaseName is required", thrown.getMessage());
85+
}
86+
87+
@Test
88+
void WhenSetDefaultApiClientThrowIOExceptionShouldThrowException() {
89+
// Arrange
90+
mockedConfig.when(() -> Config.defaultClient()).thenThrow(IOException.class);
91+
String namespace = "dummyNs";
92+
String helmReleaseName = "dummyRelease";
93+
94+
// Act & Assert
95+
PauserException thrown =
96+
assertThrows(PauserException.class, () -> new Pauser(namespace, helmReleaseName));
97+
assertEquals("Failed to set default Kubernetes client.", thrown.getMessage());
98+
}
99+
}
100+
101+
@Nested
102+
class MethodPause {
103+
@Test
104+
void LessThanOnePauseDurationShouldThrowException() throws PauserException {
105+
// Arrange
106+
String namespace = "dummyNs";
107+
String helmReleaseName = "dummyRelease";
108+
int pauseDuration = 0;
109+
Pauser pauser = new Pauser(namespace, helmReleaseName);
110+
111+
// Act & Assert
112+
IllegalArgumentException thrown =
113+
assertThrows(IllegalArgumentException.class, () -> pauser.pause(pauseDuration, null));
114+
assertEquals(
115+
"pauseDuration is required to be greater than 0 millisecond.", thrown.getMessage());
116+
}
117+
118+
@Test
119+
void WhenFirstTargetSelectorThrowExceptionShouldThrowException() throws PauserException {
120+
// Arrange
121+
String namespace = "dummyNs";
122+
String helmReleaseName = "dummyRelease";
123+
int pauseDuration = 1;
124+
Pauser pauser = new Pauser(namespace, helmReleaseName);
125+
when(targetSelector.select()).thenThrow(RuntimeException.class);
126+
127+
// Act & Assert
128+
PauserException thrown =
129+
assertThrows(PauserException.class, () -> pauser.pause(pauseDuration, null));
130+
assertEquals("Failed to find the target pods to pause.", thrown.getMessage());
131+
}
132+
133+
@Test
134+
void WhenGetRequestCoordinatorThrowExceptionShouldThrowException() throws PauserException {
135+
// Arrange
136+
String namespace = "dummyNs";
137+
String helmReleaseName = "dummyRelease";
138+
int pauseDuration = 1;
139+
Pauser pauser = spy(new Pauser(namespace, helmReleaseName));
140+
doReturn(targetSnapshot).when(pauser).getTarget();
141+
doThrow(RuntimeException.class).when(pauser).getRequestCoordinator(targetSnapshot);
142+
doNothing().when(requestCoordinator).unpause();
143+
144+
// Act & Assert
145+
PauserException thrown =
146+
assertThrows(PauserException.class, () -> pauser.pause(pauseDuration, null));
147+
assertEquals("Failed to initialize the coordinator.", thrown.getMessage());
148+
}
149+
150+
@Test
151+
void WhenCoordinatorPauseThrowExceptionShouldRunUnpause() throws PauserException {
152+
// Arrange
153+
String namespace = "dummyNs";
154+
String helmReleaseName = "dummyRelease";
155+
int pauseDuration = 1;
156+
Pauser pauser = spy(new Pauser(namespace, helmReleaseName));
157+
doReturn(targetSnapshot).when(pauser).getTarget();
158+
doReturn(requestCoordinator).when(pauser).getRequestCoordinator(targetSnapshot);
159+
doThrow(RuntimeException.class).when(requestCoordinator).pause(true, null);
160+
doNothing().when(requestCoordinator).unpause();
161+
162+
// Act & Assert
163+
RuntimeException thrown =
164+
assertThrows(RuntimeException.class, () -> pauser.pause(pauseDuration, null));
165+
verify(pauser, times(1))
166+
.unpauseWithRetry(
167+
any(RequestCoordinator.class),
168+
eq(MAX_UNPAUSE_RETRY_COUNT),
169+
any(TargetSnapshot.class));
170+
}
171+
172+
@Test
173+
void WhenInstantNowThrowExceptionShouldRunUnpause() {}
174+
175+
@Test
176+
void WhenSleepThrowExceptionShouldRunUnpause() {}
177+
178+
@Test
179+
void WhenUnpauseThrowExceptionShouldRunUnpauseAgain() {}
180+
181+
@Test
182+
void WhenSecondTargetSelectorThrowExceptionShouldThrowException() {}
183+
184+
@Test
185+
void WhenTargetPodStatusChangedShouldThrowException() {}
186+
187+
@Test
188+
void WhenPauseSucceededReturnPausedDuration() {}
189+
}
190+
191+
@Nested
192+
class MethodUnpauseWithRetry {
193+
@Test
194+
void WhenUnpauseSucceededReturnWithoutException() throws PauserException {
195+
// Arrange
196+
String namespace = "dummyNs";
197+
String helmReleaseName = "dummyRelease";
198+
Pauser pauser = new Pauser(namespace, helmReleaseName);
199+
doNothing().when(requestCoordinator).unpause();
200+
201+
// Act & Assert
202+
assertDoesNotThrow(
203+
() ->
204+
pauser.unpauseWithRetry(requestCoordinator, MAX_UNPAUSE_RETRY_COUNT, targetSnapshot));
205+
}
206+
207+
@Test
208+
void WhenExceptionOccurShouldRetryThreeTimes() throws PauserException {
209+
// Arrange
210+
String namespace = "dummyNs";
211+
String helmReleaseName = "dummyRelease";
212+
Pauser pauser = new Pauser(namespace, helmReleaseName);
213+
doThrow(RuntimeException.class).when(requestCoordinator).unpause();
214+
215+
// Act & Assert
216+
PauserException thrown =
217+
assertThrows(
218+
PauserException.class,
219+
() ->
220+
pauser.unpauseWithRetry(
221+
requestCoordinator, MAX_UNPAUSE_RETRY_COUNT, targetSnapshot));
222+
assertEquals(
223+
"Failed to unpause Scalar product. They are still in paused. You must restart related"
224+
+ " pods by using the `kubectl rollout restart deployment "
225+
+ dummyObjectName
226+
+ "` command to"
227+
+ " unpause all pods.",
228+
thrown.getMessage());
229+
verify(requestCoordinator, times(MAX_UNPAUSE_RETRY_COUNT)).unpause();
230+
}
231+
}
232+
}

0 commit comments

Comments
 (0)