Skip to content

Commit e2b4601

Browse files
scrocqueselmetacosm
authored andcommitted
feat(junit): allow to forward port of local pods
1 parent d71fd4b commit e2b4601

File tree

2 files changed

+95
-25
lines changed

2 files changed

+95
-25
lines changed

operator-framework-junit5/src/main/java/io/javaoperatorsdk/operator/junit/OperatorExtension.java

Lines changed: 77 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
import org.slf4j.LoggerFactory;
1414

1515
import io.fabric8.kubernetes.api.model.HasMetadata;
16+
import io.fabric8.kubernetes.client.LocalPortForward;
1617
import io.javaoperatorsdk.operator.Operator;
1718
import io.javaoperatorsdk.operator.api.config.ConfigurationService;
1819
import io.javaoperatorsdk.operator.api.config.ControllerConfigurationOverrider;
@@ -29,11 +30,14 @@ public class OperatorExtension extends AbstractOperatorExtension {
2930

3031
private final Operator operator;
3132
private final List<ReconcilerSpec> reconcilers;
33+
private List<PortFowardSpec> portForwards;
34+
private List<LocalPortForward> localPortForwards;
3235

3336
private OperatorExtension(
3437
ConfigurationService configurationService,
3538
List<ReconcilerSpec> reconcilers,
3639
List<HasMetadata> infrastructure,
40+
List<PortFowardSpec> portForwards,
3741
Duration infrastructureTimeout,
3842
boolean preserveNamespaceOnError,
3943
boolean waitForNamespaceDeletion,
@@ -46,6 +50,8 @@ private OperatorExtension(
4650
preserveNamespaceOnError,
4751
waitForNamespaceDeletion);
4852
this.reconcilers = reconcilers;
53+
this.portForwards = portForwards;
54+
this.localPortForwards = new ArrayList<>(portForwards.size());
4955
this.operator = new Operator(getKubernetesClient(), this.configurationService);
5056
}
5157

@@ -83,6 +89,22 @@ public <T extends Reconciler> T getControllerOfType(Class<T> type) {
8389
protected void before(ExtensionContext context) {
8490
super.before(context);
8591

92+
final var kubernetesClient = getKubernetesClient();
93+
94+
for (var ref : portForwards) {
95+
String podName = kubernetesClient.pods()
96+
.inNamespace(ref.getNamespace())
97+
.withLabel(ref.getLabelKey(), ref.getLabelValue())
98+
.list()
99+
.getItems()
100+
.get(0)
101+
.getMetadata()
102+
.getName();
103+
104+
localPortForwards.add(kubernetesClient.pods().inNamespace(ref.getNamespace())
105+
.withName(podName).portForward(ref.getPort(), ref.getLocalPort()));
106+
}
107+
86108
for (var ref : reconcilers) {
87109
final var config = configurationService.getConfigurationFor(ref.reconciler);
88110
final var oconfig = override(config).settingNamespace(namespace);
@@ -95,7 +117,6 @@ protected void before(ExtensionContext context) {
95117
ref.controllerConfigurationOverrider.accept(oconfig);
96118
}
97119

98-
final var kubernetesClient = getKubernetesClient();
99120
try (InputStream is = getClass().getResourceAsStream(path)) {
100121
final var crd = kubernetesClient.load(is);
101122
crd.createOrReplace();
@@ -127,15 +148,26 @@ protected void after(ExtensionContext context) {
127148
} catch (Exception e) {
128149
// ignored
129150
}
151+
152+
for (var ref : localPortForwards) {
153+
try {
154+
ref.close();
155+
} catch (Exception e) {
156+
// ignored
157+
}
158+
}
159+
localPortForwards.clear();
130160
}
131161

132162
@SuppressWarnings("rawtypes")
133163
public static class Builder extends AbstractBuilder<Builder> {
134164
private final List<ReconcilerSpec> reconcilers;
165+
private final List<PortFowardSpec> portForwards;
135166

136167
protected Builder() {
137168
super();
138169
this.reconcilers = new ArrayList<>();
170+
this.portForwards = new ArrayList<>();
139171
}
140172

141173
public Builder withReconciler(
@@ -173,18 +205,62 @@ public Builder withReconciler(Class<? extends Reconciler> value) {
173205
return this;
174206
}
175207

208+
public Builder withPortForward(String namespace, String labelKey, String labelValue, int port,
209+
int localPort) {
210+
portForwards.add(new PortFowardSpec(namespace, labelKey, labelValue, port, localPort));
211+
return this;
212+
}
213+
176214
public OperatorExtension build() {
177215
return new OperatorExtension(
178216
configurationService,
179217
reconcilers,
180218
infrastructure,
219+
portForwards,
181220
infrastructureTimeout,
182221
preserveNamespaceOnError,
183222
waitForNamespaceDeletion,
184223
oneNamespacePerClass);
185224
}
186225
}
187226

227+
private static class PortFowardSpec {
228+
final String namespace;
229+
final String labelKey;
230+
final String labelValue;
231+
final int port;
232+
final int localPort;
233+
234+
public PortFowardSpec(String namespace, String labelKey, String labelValue, int port,
235+
int localPort) {
236+
this.namespace = namespace;
237+
this.labelKey = labelKey;
238+
this.labelValue = labelValue;
239+
this.port = port;
240+
this.localPort = localPort;
241+
}
242+
243+
public String getNamespace() {
244+
return namespace;
245+
}
246+
247+
public String getLabelKey() {
248+
return labelKey;
249+
}
250+
251+
public String getLabelValue() {
252+
return labelValue;
253+
}
254+
255+
public int getPort() {
256+
return port;
257+
}
258+
259+
public int getLocalPort() {
260+
return localPort;
261+
}
262+
}
263+
188264
@SuppressWarnings("rawtypes")
189265
private static class ReconcilerSpec {
190266
final Reconciler reconciler;

sample-operators/mysql-schema/src/test/java/io/javaoperatorsdk/operator/sample/MySQLSchemaOperatorE2E.java

Lines changed: 18 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@
1616
import io.fabric8.kubernetes.api.model.ObjectMetaBuilder;
1717
import io.fabric8.kubernetes.client.DefaultKubernetesClient;
1818
import io.fabric8.kubernetes.client.KubernetesClient;
19-
import io.fabric8.kubernetes.client.LocalPortForward;
2019
import io.javaoperatorsdk.operator.junit.AbstractOperatorExtension;
2120
import io.javaoperatorsdk.operator.junit.E2EOperatorExtension;
2221
import io.javaoperatorsdk.operator.junit.OperatorExtension;
@@ -29,6 +28,7 @@
2928
import static org.hamcrest.CoreMatchers.is;
3029
import static org.hamcrest.MatcherAssert.assertThat;
3130
import static org.hamcrest.Matchers.notNullValue;
31+
import static org.hamcrest.Matchers.nullValue;
3232

3333
class MySQLSchemaOperatorE2E {
3434

@@ -70,9 +70,10 @@ boolean isLocal() {
7070
c.replaceDependentResourceConfig(
7171
SchemaDependentResource.class,
7272
new ResourcePollerConfig(
73-
700, new MySQLDbConfig("127.0.0.1", "3306", "root", "password")));
73+
700, new MySQLDbConfig("127.0.0.1", "3307", "root", "password")));
7474
})
7575
.withInfrastructure(infrastructure)
76+
.withPortForward(MY_SQL_NS, "app", "mysql", 3306, 3307)
7677
.build()
7778
: E2EOperatorExtension.builder()
7879
.withOperatorDeployment(client.load(new FileInputStream("k8s/operator.yaml")).get())
@@ -83,8 +84,6 @@ public MySQLSchemaOperatorE2E() throws FileNotFoundException {}
8384

8485
@Test
8586
void test() throws IOException {
86-
// Opening a port-forward if running locally
87-
LocalPortForward portForward = createLocalPortForward();
8887

8988
MySQLSchema testSchema = new MySQLSchema();
9089
testSchema.setMetadata(
@@ -114,26 +113,21 @@ void test() throws IOException {
114113
assertThat(updatedSchema.getStatus().getUserName(), is(notNullValue()));
115114
});
116115

117-
if (portForward != null) {
118-
portForward.close();
119-
}
120-
}
116+
client.resources(MySQLSchema.class).inNamespace(operator.getNamespace())
117+
.withName(testSchema.getMetadata().getName()).delete();
121118

122-
private LocalPortForward createLocalPortForward() {
123-
if (isLocal()) {
124-
String podName =
125-
client
126-
.pods()
127-
.inNamespace(MY_SQL_NS)
128-
.withLabel("app", "mysql")
129-
.list()
130-
.getItems()
131-
.get(0)
132-
.getMetadata()
133-
.getName();
134-
135-
return client.pods().inNamespace(MY_SQL_NS).withName(podName).portForward(3306, 3306);
136-
}
137-
return null;
119+
await()
120+
.atMost(2, MINUTES)
121+
.ignoreExceptions()
122+
.untilAsserted(
123+
() -> {
124+
MySQLSchema updatedSchema =
125+
client
126+
.resources(MySQLSchema.class)
127+
.inNamespace(operator.getNamespace())
128+
.withName(testSchema.getMetadata().getName())
129+
.get();
130+
assertThat(updatedSchema, is(nullValue()));
131+
});
138132
}
139133
}

0 commit comments

Comments
 (0)