Skip to content

Commit a57c44e

Browse files
authored
Merge pull request #2906 from awesominat/add-kubectl-delete-tests
Add Kubectl delete tests
2 parents 5766caa + 137ccfe commit a57c44e

File tree

5 files changed

+559
-0
lines changed

5 files changed

+559
-0
lines changed
Lines changed: 224 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,224 @@
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+
package io.kubernetes.client.extended.kubectl;
14+
15+
import static com.github.tomakehurst.wiremock.client.WireMock.*;
16+
import static com.github.tomakehurst.wiremock.core.WireMockConfiguration.wireMockConfig;
17+
import static org.junit.Assert.assertThrows;
18+
19+
import com.github.tomakehurst.wiremock.junit.WireMockRule;
20+
import com.github.tomakehurst.wiremock.stubbing.Scenario;
21+
import io.kubernetes.client.extended.kubectl.Kubectl;
22+
import io.kubernetes.client.extended.kubectl.KubectlDelete;
23+
import io.kubernetes.client.extended.kubectl.exception.KubectlException;
24+
import io.kubernetes.client.openapi.ApiClient;
25+
import io.kubernetes.client.openapi.ApiException;
26+
import io.kubernetes.client.openapi.apis.BatchV1Api;
27+
import io.kubernetes.client.openapi.models.*;
28+
import io.kubernetes.client.util.ClientBuilder;
29+
import io.kubernetes.client.util.ModelMapper;
30+
import java.io.IOException;
31+
import java.util.Objects;
32+
33+
import org.apache.commons.io.IOUtils;
34+
import org.junit.Before;
35+
import org.junit.Rule;
36+
import org.junit.Test;
37+
38+
public class KubectlDeleteTest {
39+
40+
private ApiClient apiClient;
41+
42+
private final byte[] DISCOVERY_API;
43+
44+
{
45+
try {
46+
DISCOVERY_API = IOUtils.toByteArray(Objects.requireNonNull(KubectlDeleteTest.class
47+
.getClassLoader()
48+
.getResourceAsStream("discovery-api.json")));
49+
} catch (IOException e) {
50+
throw new RuntimeException(e);
51+
}
52+
}
53+
54+
private final byte[] DISCOVERY_APIV1;
55+
56+
{
57+
try {
58+
DISCOVERY_APIV1 = IOUtils.toByteArray(Objects.requireNonNull(KubectlDeleteTest.class
59+
.getClassLoader()
60+
.getResourceAsStream("discovery-api-v1.json")));
61+
} catch (IOException e) {
62+
throw new RuntimeException(e);
63+
}
64+
}
65+
66+
67+
private final byte[] ADD_JOB;
68+
69+
{
70+
try {
71+
ADD_JOB = IOUtils.toByteArray(Objects.requireNonNull(KubectlDeleteTest.class
72+
.getClassLoader()
73+
.getResourceAsStream("deleted-add-job.json")));
74+
} catch (IOException e) {
75+
throw new RuntimeException(e);
76+
}
77+
}
78+
79+
private final byte[] GET_BATCH;
80+
81+
{
82+
try {
83+
GET_BATCH = IOUtils.toByteArray(Objects.requireNonNull(KubectlDeleteTest.class
84+
.getClassLoader()
85+
.getResourceAsStream("deleted-get-batch.json")));
86+
} catch (IOException e) {
87+
throw new RuntimeException(e);
88+
}
89+
}
90+
91+
private final byte[] DELETED_FIRST;
92+
93+
{
94+
try {
95+
DELETED_FIRST = IOUtils.toByteArray(Objects.requireNonNull(KubectlDeleteTest.class
96+
.getClassLoader()
97+
.getResourceAsStream("deleted-success.json")));
98+
} catch (IOException e) {
99+
throw new RuntimeException(e);
100+
}
101+
}
102+
103+
private final byte[] DELETED_SECOND;
104+
105+
{
106+
try {
107+
DELETED_SECOND = IOUtils.toByteArray(Objects.requireNonNull(KubectlDeleteTest.class
108+
.getClassLoader()
109+
.getResourceAsStream("deleted-not-found.json")));
110+
} catch (IOException e) {
111+
throw new RuntimeException(e);
112+
}
113+
}
114+
115+
private final byte[] DISCOVERY_APIS;
116+
117+
{
118+
try {
119+
DISCOVERY_APIS = IOUtils.toByteArray(Objects.requireNonNull(KubectlDeleteTest.class
120+
.getClassLoader()
121+
.getResourceAsStream("discovery-apis.json")));
122+
} catch (IOException e) {
123+
throw new RuntimeException(e);
124+
}
125+
}
126+
127+
@Rule public WireMockRule wireMockRule = new WireMockRule(wireMockConfig().dynamicPort());
128+
129+
@Before
130+
public void setup() {
131+
apiClient = new ClientBuilder().setBasePath("http://localhost:" + wireMockRule.port()).build();
132+
}
133+
134+
@Test
135+
public void testKubectlDelete() throws KubectlException, IOException, ApiException {
136+
wireMockRule.stubFor(
137+
post(urlPathEqualTo("/apis/batch/v1/namespaces/foo/jobs"))
138+
.willReturn(
139+
aResponse()
140+
.withStatus(201)
141+
.withBody(ADD_JOB)));
142+
wireMockRule.stubFor(
143+
delete(urlPathEqualTo("/apis/batch%2Fv1/batch%2Fv1/namespaces/foo/jobs/bar"))
144+
.inScenario("JobDeletionScenario")
145+
.whenScenarioStateIs(Scenario.STARTED)
146+
.willReturn(aResponse()
147+
.withStatus(200)
148+
.withBody(DELETED_FIRST)
149+
)
150+
.willSetStateTo("SecondCall")
151+
);
152+
153+
wireMockRule.stubFor(
154+
delete(urlPathEqualTo("/apis/batch%2Fv1/batch%2Fv1/namespaces/foo/jobs/bar"))
155+
.inScenario("JobDeletionScenario")
156+
.whenScenarioStateIs("SecondCall")
157+
.willReturn(aResponse()
158+
.withStatus(404)
159+
.withBody(DELETED_SECOND)
160+
)
161+
);
162+
163+
164+
wireMockRule.stubFor(
165+
get(urlPathEqualTo("/api"))
166+
.willReturn(
167+
aResponse()
168+
.withStatus(200)
169+
.withBody(DISCOVERY_API)));
170+
wireMockRule.stubFor(
171+
get(urlPathEqualTo("/apis"))
172+
.willReturn(
173+
aResponse()
174+
.withStatus(200)
175+
.withBody(DISCOVERY_APIS)));
176+
wireMockRule.stubFor(
177+
get(urlPathEqualTo("/api/v1"))
178+
.willReturn(
179+
aResponse()
180+
.withStatus(200)
181+
.withBody(DISCOVERY_APIV1)));
182+
wireMockRule.stubFor(
183+
get(urlPathEqualTo("/apis/batch/v1/"))
184+
.willReturn(
185+
aResponse()
186+
.withStatus(200)
187+
.withBody(GET_BATCH)));
188+
189+
V1JobSpec v1JobSpec = new V1JobSpec()
190+
.template(new V1PodTemplateSpec()
191+
.spec(new V1PodSpec()
192+
.containers(java.util.Arrays.asList(new V1Container()
193+
.name("hello")
194+
.image("busybox")
195+
.command(java.util.Arrays.asList("sh", "-c", "echo Hello World!"))))
196+
.restartPolicy("Never")));
197+
V1Job job = new V1Job()
198+
.apiVersion("batch/v1")
199+
.kind("Job")
200+
.metadata(new V1ObjectMeta().name("bar"))
201+
.spec(v1JobSpec);
202+
BatchV1Api api = new BatchV1Api();
203+
api.setApiClient(apiClient);
204+
api.createNamespacedJob("foo", job, null, null, null, "Strict");
205+
ModelMapper.addModelMap(api.getAPIResources().getGroupVersion(), job.getApiVersion(), job.getKind(), "jobs", true, V1Job.class);
206+
207+
KubectlDelete<V1Job> kubectlDelete = Kubectl.delete(V1Job.class);
208+
kubectlDelete.apiClient(apiClient);
209+
kubectlDelete.namespace("foo").name("bar");
210+
kubectlDelete.execute();
211+
212+
assertThrows(KubectlException.class, () -> {
213+
KubectlDelete<V1Job> kubectlDelete2 = Kubectl.delete(V1Job.class);
214+
kubectlDelete2.apiClient(apiClient);
215+
kubectlDelete2.namespace("foo").name("bar");
216+
kubectlDelete2.execute();
217+
});
218+
219+
KubectlDelete<V1Job> kubectlDelete2 = Kubectl.delete(V1Job.class);
220+
kubectlDelete2.apiClient(apiClient);
221+
kubectlDelete2.namespace("foo").name("bar").ignoreNotFound(true);
222+
kubectlDelete2.execute();
223+
}
224+
}
Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
{
2+
"kind": "Job",
3+
"apiVersion": "batch/v1",
4+
"metadata": {
5+
"name": "bar",
6+
"namespace": "foo",
7+
"uid": "7f64e06e-d6a6-4598-b375-7c8773f3b0e7",
8+
"resourceVersion": "46205",
9+
"generation": 1,
10+
"creationTimestamp": "2023-11-23T15:38:18Z",
11+
"labels": {
12+
"batch.kubernetes.io/controller-uid": "7f64e06e-d6a6-4598-b375-7c8773f3b0e7",
13+
"batch.kubernetes.io/job-name": "bar",
14+
"controller-uid": "7f64e06e-d6a6-4598-b375-7c8773f3b0e7",
15+
"job-name": "bar"
16+
},
17+
"annotations": {
18+
"batch.kubernetes.io/job-tracking": ""
19+
},
20+
"managedFields": [
21+
{
22+
"manager": "Kubernetes Java Client",
23+
"operation": "Update",
24+
"apiVersion": "batch/v1",
25+
"time": "2023-11-23T15:38:18Z",
26+
"fieldsType": "FieldsV1",
27+
"fieldsV1": {
28+
"f:spec": {
29+
"f:backoffLimit": {},
30+
"f:completionMode": {},
31+
"f:completions": {},
32+
"f:parallelism": {},
33+
"f:suspend": {},
34+
"f:template": {
35+
"f:spec": {
36+
"f:containers": {
37+
"k:{\"name\":\"bar2\"}": {
38+
".": {},
39+
"f:command": {},
40+
"f:image": {},
41+
"f:imagePullPolicy": {},
42+
"f:name": {},
43+
"f:resources": {},
44+
"f:terminationMessagePath": {},
45+
"f:terminationMessagePolicy": {}
46+
}
47+
},
48+
"f:dnsPolicy": {},
49+
"f:restartPolicy": {},
50+
"f:schedulerName": {},
51+
"f:securityContext": {},
52+
"f:terminationGracePeriodSeconds": {}
53+
}
54+
}
55+
}
56+
}
57+
}
58+
]
59+
},
60+
"spec": {
61+
"parallelism": 1,
62+
"completions": 1,
63+
"backoffLimit": 6,
64+
"selector": {
65+
"matchLabels": {
66+
"batch.kubernetes.io/controller-uid": "7f64e06e-d6a6-4598-b375-7c8773f3b0e7"
67+
}
68+
},
69+
"template": {
70+
"metadata": {
71+
"creationTimestamp": null,
72+
"labels": {
73+
"batch.kubernetes.io/controller-uid": "7f64e06e-d6a6-4598-b375-7c8773f3b0e7",
74+
"batch.kubernetes.io/job-name": "bar",
75+
"controller-uid": "7f64e06e-d6a6-4598-b375-7c8773f3b0e7",
76+
"job-name": "bar"
77+
}
78+
},
79+
"spec": {
80+
"containers": [
81+
{
82+
"name": "bar2",
83+
"image": "busybox",
84+
"command": [
85+
"sh",
86+
"-c",
87+
"echo Hello World!"
88+
],
89+
"resources": {},
90+
"terminationMessagePath": "/dev/termination-log",
91+
"terminationMessagePolicy": "File",
92+
"imagePullPolicy": "Always"
93+
}
94+
],
95+
"restartPolicy": "Never",
96+
"terminationGracePeriodSeconds": 30,
97+
"dnsPolicy": "ClusterFirst",
98+
"securityContext": {},
99+
"schedulerName": "default-scheduler"
100+
}
101+
},
102+
"completionMode": "NonIndexed",
103+
"suspend": false
104+
},
105+
"status": {}
106+
}

0 commit comments

Comments
 (0)