Skip to content

Commit 2cc33a9

Browse files
committed
fixes kubectl-drain failures and adding e2e tests
1 parent 1c0f0c8 commit 2cc33a9

File tree

6 files changed

+109
-35
lines changed

6 files changed

+109
-35
lines changed

e2e/src/test/groovy/io/kubernetes/client/e2e/informer/NamespaceInformerTest.groovy

Lines changed: 25 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -23,30 +23,30 @@ import spock.util.concurrent.PollingConditions
2323

2424
class NamespaceInformerTest extends Specification {
2525

26-
def "list-watching namespaces should work" () {
27-
given:
28-
def conditions = new PollingConditions();
29-
def apiClient = ClientBuilder.defaultClient();
30-
def api = new GenericKubernetesApi(
31-
V1Namespace.class,
32-
V1NamespaceList.class,
33-
"",
34-
"v1",
35-
"namespaces",
36-
apiClient)
37-
def informerFactory = new SharedInformerFactory();
38-
def nsInformer = informerFactory.sharedIndexInformerFor(
39-
api,
40-
V1Namespace.class,
41-
0)
42-
def nsLister = new Lister(nsInformer.getIndexer());
43-
when:
44-
informerFactory.startAllRegisteredInformers();
45-
then:
46-
conditions.eventually {
47-
nsInformer.hasSynced()
48-
nsLister.list().size() > 0
49-
}
50-
}
26+
def "list-watching namespaces should work"() {
27+
given:
28+
def conditions = new PollingConditions()
29+
def apiClient = ClientBuilder.defaultClient()
30+
def api = new GenericKubernetesApi(
31+
V1Namespace.class,
32+
V1NamespaceList.class,
33+
"",
34+
"v1",
35+
"namespaces",
36+
apiClient)
37+
def informerFactory = new SharedInformerFactory()
38+
def nsInformer = informerFactory.sharedIndexInformerFor(
39+
api,
40+
V1Namespace.class,
41+
0)
42+
def nsLister = new Lister(nsInformer.getIndexer())
43+
when:
44+
informerFactory.startAllRegisteredInformers()
45+
then:
46+
conditions.eventually {
47+
nsInformer.hasSynced()
48+
nsLister.list().size() > 0
49+
}
50+
}
5151

5252
}
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
/*
2+
Copyright 2020 The Kubernetes Authors.
3+
Licensed under the Apache License, Version 2.0 (the "License");
4+
you may not use this file except in compliance with the License.
5+
You may obtain a copy of the License at
6+
http://www.apache.org/licenses/LICENSE-2.0
7+
Unless required by applicable law or agreed to in writing, software
8+
distributed under the License is distributed on an "AS IS" BASIS,
9+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10+
See the License for the specific language governing permissions and
11+
limitations under the License.
12+
*/
13+
14+
package io.kubernetes.client.e2e.kubectl
15+
16+
import io.kubernetes.client.extended.kubectl.Kubectl
17+
import io.kubernetes.client.extended.kubectl.exception.KubectlException
18+
import io.kubernetes.client.openapi.ApiException
19+
import io.kubernetes.client.openapi.Configuration
20+
import io.kubernetes.client.openapi.models.V1Container
21+
import io.kubernetes.client.openapi.models.V1Node
22+
import io.kubernetes.client.openapi.models.V1ObjectMeta
23+
import io.kubernetes.client.openapi.models.V1Pod
24+
import io.kubernetes.client.openapi.models.V1PodSpec
25+
import io.kubernetes.client.util.ClientBuilder
26+
import spock.lang.Specification
27+
28+
class KubectlDrainTest extends Specification {
29+
def "Kubectl drain should work"() {
30+
given:
31+
def apiClient = ClientBuilder.defaultClient()
32+
Configuration.setDefaultApiClient(apiClient)
33+
def testNode = new V1Node()
34+
.metadata(new V1ObjectMeta().name("foo"))
35+
def testPod = new V1Pod()
36+
.metadata(new V1ObjectMeta()
37+
.namespace("default")
38+
.name("bar"))
39+
.spec(new V1PodSpec()
40+
.nodeName("foo")
41+
.containers(Arrays.asList(
42+
new V1Container().name("c1").image("nginx")
43+
)))
44+
when:
45+
V1Node createdNode = Kubectl.create(V1Node.class).resource(testNode).execute()
46+
V1Pod createdPod = Kubectl.create(V1Pod.class).resource(testPod).execute()
47+
then:
48+
createdNode != null
49+
createdPod != null
50+
when:
51+
V1Node drainedNode = Kubectl.drain().gracePeriod(0).name("foo").execute()
52+
then:
53+
drainedNode != null
54+
when:
55+
Kubectl.get(V1Pod.class).namespace("default").name("bar").execute()
56+
then:
57+
def e = thrown KubectlException
58+
e.getCause().class == ApiException.class
59+
cleanup:
60+
Kubectl.delete(V1Node.class).name("foo").execute()
61+
}
62+
63+
}

e2e/src/test/groovy/io/kubernetes/client/e2e/kubectl/KubectlNamespaceTest.groovy

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,23 @@
1+
/*
2+
Copyright 2020 The Kubernetes Authors.
3+
Licensed under the Apache License, Version 2.0 (the "License");
4+
you may not use this file except in compliance with the License.
5+
You may obtain a copy of the License at
6+
http://www.apache.org/licenses/LICENSE-2.0
7+
Unless required by applicable law or agreed to in writing, software
8+
distributed under the License is distributed on an "AS IS" BASIS,
9+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10+
See the License for the specific language governing permissions and
11+
limitations under the License.
12+
*/
13+
114
package io.kubernetes.client.e2e.kubectl
215

316
import io.kubernetes.client.extended.kubectl.Kubectl
4-
import io.kubernetes.client.extended.kubectl.exception.KubectlException
5-
import io.kubernetes.client.openapi.ApiException
617
import io.kubernetes.client.openapi.models.V1Namespace
718
import io.kubernetes.client.openapi.models.V1ObjectMeta
819
import io.kubernetes.client.util.ClientBuilder
920
import spock.lang.Specification
10-
import spock.util.concurrent.PollingConditions
1121

1222
class KubectlNamespaceTest extends Specification {
1323

extended/src/main/java/io/kubernetes/client/extended/kubectl/KubectlCordon.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
import io.kubernetes.client.openapi.ApiException;
1818
import io.kubernetes.client.openapi.models.V1Node;
1919

20-
public class KubectlCordon extends Kubectl.ResourceAndContainerBuilder<V1Node, KubectlCordon>
20+
public class KubectlCordon extends Kubectl.ResourceBuilder<V1Node, KubectlCordon>
2121
implements Kubectl.Executable<V1Node> {
2222

2323
static final String CORDON_PATCH_STR =

extended/src/main/java/io/kubernetes/client/extended/kubectl/KubectlDrain.java

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ public KubectlDrain ignoreDaemonSets() {
5151
@Override
5252
public V1Node execute() throws KubectlException {
5353
try {
54+
refreshDiscovery();
5455
return doDrain();
5556
} catch (ApiException | IOException ex) {
5657
throw new KubectlException(ex);
@@ -102,14 +103,14 @@ private void validatePods(List<V1Pod> pods) throws KubectlException {
102103

103104
private void deletePod(CoreV1Api api, String name, String namespace)
104105
throws ApiException, IOException, KubectlException {
105-
api.deleteNamespacedPod(name, namespace, null, null, null, null, null, null);
106+
api.deleteNamespacedPod(name, namespace, null, null, this.timeoutSeconds, null, null, null);
106107
waitForPodDelete(api, name, namespace);
107108
}
108109

109110
private void waitForPodDelete(CoreV1Api api, String name, String namespace)
110-
throws ApiException, IOException, KubectlException {
111+
throws KubectlException {
111112
long start = System.currentTimeMillis();
112-
while (System.currentTimeMillis() - start < timeoutSeconds * 1000) {
113+
do {
113114
try {
114115
api.readNamespacedPod(name, namespace, null, null, null);
115116
} catch (ApiException ex) {
@@ -118,7 +119,7 @@ private void waitForPodDelete(CoreV1Api api, String name, String namespace)
118119
}
119120
throw new KubectlException(ex);
120121
}
121-
}
122+
} while (System.currentTimeMillis() - start < timeoutSeconds * 1000);
122123
throw new KubectlException("Timed out waiting for Pod delete.");
123124
}
124125
}

extended/src/test/java/io/kubernetes/client/extended/kubectl/KubectlDrainTest.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ public void testDrainNodeNoPods() throws KubectlException, IOException {
6565
get(urlPathEqualTo("/api/v1/pods"))
6666
.withQueryParam("fieldSelector", equalTo("spec.nodeName=node1"))
6767
.willReturn(aResponse().withStatus(200).withBody("{}")));
68-
V1Node node = new KubectlDrain().apiClient(apiClient).name("node1").execute();
68+
V1Node node = new KubectlDrain().skipDiscovery().apiClient(apiClient).name("node1").execute();
6969
wireMockRule.verify(1, patchRequestedFor(urlPathEqualTo("/api/v1/nodes/node1")));
7070
wireMockRule.verify(1, getRequestedFor(urlPathEqualTo("/api/v1/pods")));
7171
assertEquals("node1", node.getMetadata().getName());
@@ -92,7 +92,7 @@ public void testDrainNodePods() throws KubectlException, IOException {
9292
get(urlPathEqualTo("/api/v1/namespaces/mssql/pods/mssql-75b8b44f6b-znftp"))
9393
.willReturn(aResponse().withStatus(404).withBody("{}")));
9494

95-
V1Node node = new KubectlDrain().apiClient(apiClient).name("node1").execute();
95+
V1Node node = new KubectlDrain().skipDiscovery().apiClient(apiClient).name("node1").execute();
9696
wireMockRule.verify(1, patchRequestedFor(urlPathEqualTo("/api/v1/nodes/node1")));
9797
wireMockRule.verify(1, getRequestedFor(urlPathEqualTo("/api/v1/pods")));
9898
wireMockRule.verify(

0 commit comments

Comments
 (0)