Skip to content
This repository was archived by the owner on Mar 13, 2022. It is now read-only.

Commit 33e2153

Browse files
committed
Add custom resource tests
1 parent 72c1fbc commit 33e2153

File tree

1 file changed

+188
-88
lines changed

1 file changed

+188
-88
lines changed

dynamic/test_client.py

+188-88
Original file line numberDiff line numberDiff line change
@@ -14,120 +14,221 @@
1414
# See the License for the specific language governing permissions and
1515
# limitations under the License.
1616

17-
import json
1817
import time
1918
import unittest
2019
import uuid
2120

2221
from kubernetes.e2e_test import base
2322
from kubernetes.client import api_client
24-
from kubernetes.dynamic import DynamicClient
25-
from kubernetes.stream import stream
26-
from kubernetes.stream.ws_client import ERROR_CHANNEL
23+
24+
from . import DynamicClient
25+
from .exceptions import ResourceNotFoundError
2726

2827

2928
def short_uuid():
3029
id = str(uuid.uuid4())
3130
return id[-12:]
3231

3332

34-
class TestClient(unittest.TestCase):
33+
class TestDynamicClient(unittest.TestCase):
3534

3635
@classmethod
3736
def setUpClass(cls):
3837
cls.config = base.get_e2e_configuration()
3938

40-
def test_pod_apis(self):
39+
def test_cluster_custom_resources(self):
4140
client = DynamicClient(api_client.ApiClient(configuration=self.config))
42-
api = client.resources.get(api_version='v1', kind='Pod')
4341

44-
name = 'busybox-test-' + short_uuid()
45-
pod_manifest = {
46-
'apiVersion': 'v1',
47-
'kind': 'Pod',
42+
with self.assertRaises(ResourceNotFoundError):
43+
changeme_api = client.resources.get(api_version='apps.example.com/v1', kind='ClusterChangeMe')
44+
45+
crd_api = client.resources.get(kind='CustomResourceDefinition')
46+
name = 'clusterchangemes.apps.example.com'
47+
crd_manifest = {
48+
'apiVersion': 'apiextensions.k8s.io/v1beta1',
49+
'kind': 'CustomResourceDefinition',
50+
'metadata': {
51+
'name': name,
52+
},
53+
'spec': {
54+
'group': 'apps.example.com',
55+
'names': {
56+
'kind': 'ClusterChangeMe',
57+
'listKind': 'ClusterChangeMeList',
58+
'plural': 'clusterchangemes',
59+
'singular': 'clusterchangeme',
60+
},
61+
'scope': 'Cluster',
62+
'version': 'v1',
63+
'subresources': {
64+
'status': {}
65+
}
66+
}
67+
}
68+
resp = crd_api.create(crd_manifest)
69+
70+
self.assertEqual(name, resp.metadata.name)
71+
self.assertTrue(resp.status)
72+
73+
resp = crd_api.get(
74+
name=name,
75+
)
76+
self.assertEqual(name, resp.metadata.name)
77+
self.assertTrue(resp.status)
78+
79+
try:
80+
changeme_api = client.resources.get(api_version='apps.example.com/v1', kind='ClusterChangeMe')
81+
except ResourceNotFoundError:
82+
# Sometimes need to wait a sec for the discovery layer to get updated
83+
time.sleep(2)
84+
changeme_api = client.resources.get(api_version='apps.example.com/v1', kind='ClusterChangeMe')
85+
resp = changeme_api.get()
86+
self.assertEqual(resp.items, [])
87+
changeme_name = 'custom-resource' + short_uuid()
88+
changeme_manifest = {
89+
'apiVersion': 'apps.example.com/v1',
90+
'kind': 'ClusterChangeMe',
91+
'metadata': {
92+
'name': changeme_name,
93+
},
94+
'spec': {}
95+
}
96+
97+
resp = changeme_api.create(body=changeme_manifest)
98+
self.assertEqual(resp.metadata.name, changeme_name)
99+
100+
resp = changeme_api.get(name=changeme_name)
101+
self.assertEqual(resp.metadata.name, changeme_name)
102+
103+
changeme_manifest['spec']['size'] = 3
104+
resp = changeme_api.patch(
105+
body=changeme_manifest,
106+
content_type='application/merge-patch+json'
107+
)
108+
self.assertEqual(resp.spec.size, 3)
109+
110+
resp = changeme_api.get(name=changeme_name)
111+
self.assertEqual(resp.spec.size, 3)
112+
113+
resp = changeme_api.get()
114+
self.assertEqual(len(resp.items), 1)
115+
116+
resp = changeme_api.delete(
117+
name=changeme_name,
118+
)
119+
120+
resp = changeme_api.get()
121+
self.assertEqual(len(resp.items), 0)
122+
123+
resp = crd_api.delete(
124+
name=name,
125+
)
126+
127+
time.sleep(2)
128+
client.resources.invalidate_cache()
129+
with self.assertRaises(ResourceNotFoundError):
130+
changeme_api = client.resources.get(api_version='apps.example.com/v1', kind='ClusterChangeMe')
131+
132+
def test_namespaced_custom_resources(self):
133+
client = DynamicClient(api_client.ApiClient(configuration=self.config))
134+
135+
with self.assertRaises(ResourceNotFoundError):
136+
changeme_api = client.resources.get(api_version='apps.example.com/v1', kind='ChangeMe')
137+
138+
crd_api = client.resources.get(kind='CustomResourceDefinition')
139+
name = 'changemes.apps.example.com'
140+
crd_manifest = {
141+
'apiVersion': 'apiextensions.k8s.io/v1beta1',
142+
'kind': 'CustomResourceDefinition',
48143
'metadata': {
49-
'name': name
144+
'name': name,
50145
},
51146
'spec': {
52-
'containers': [{
53-
'image': 'busybox',
54-
'name': 'sleep',
55-
"args": [
56-
"/bin/sh",
57-
"-c",
58-
"while true;do date;sleep 5; done"
59-
]
60-
}]
147+
'group': 'apps.example.com',
148+
'names': {
149+
'kind': 'ChangeMe',
150+
'listKind': 'ChangeMeList',
151+
'plural': 'changemes',
152+
'singular': 'changeme',
153+
},
154+
'scope': 'Namespaced',
155+
'version': 'v1',
156+
'subresources': {
157+
'status': {}
158+
}
61159
}
62160
}
161+
resp = crd_api.create(crd_manifest)
63162

64-
resp = api.create(body=pod_manifest, namespace='default')
65163
self.assertEqual(name, resp.metadata.name)
66-
self.assertTrue(resp.status.phase)
67-
68-
while True:
69-
resp = api.get(name=name, namespace='default')
70-
self.assertEqual(name, resp.metadata.name)
71-
self.assertTrue(resp.status.phase)
72-
if resp.status.phase != 'Pending':
73-
break
74-
time.sleep(1)
75-
76-
exec_command = ['/bin/sh',
77-
'-c',
78-
'for i in $(seq 1 3); do date; done']
79-
resp = stream(
80-
api.subresources['exec'],
81-
name,
82-
'default',
83-
command=exec_command,
84-
stderr=False, stdin=False,
85-
stdout=True, tty=False
164+
self.assertTrue(resp.status)
165+
166+
resp = crd_api.get(
167+
name=name,
168+
)
169+
self.assertEqual(name, resp.metadata.name)
170+
self.assertTrue(resp.status)
171+
172+
try:
173+
changeme_api = client.resources.get(api_version='apps.example.com/v1', kind='ChangeMe')
174+
except ResourceNotFoundError:
175+
# Sometimes need to wait a sec for the discovery layer to get updated
176+
time.sleep(2)
177+
changeme_api = client.resources.get(api_version='apps.example.com/v1', kind='ChangeMe')
178+
resp = changeme_api.get()
179+
self.assertEqual(resp.items, [])
180+
changeme_name = 'custom-resource' + short_uuid()
181+
changeme_manifest = {
182+
'apiVersion': 'apps.example.com/v1',
183+
'kind': 'ChangeMe',
184+
'metadata': {
185+
'name': changeme_name,
186+
},
187+
'spec': {}
188+
}
189+
190+
resp = changeme_api.create(body=changeme_manifest, namespace='default')
191+
self.assertEqual(resp.metadata.name, changeme_name)
192+
193+
resp = changeme_api.get(name=changeme_name, namespace='default')
194+
self.assertEqual(resp.metadata.name, changeme_name)
195+
196+
changeme_manifest['spec']['size'] = 3
197+
resp = changeme_api.patch(
198+
body=changeme_manifest,
199+
namespace='default',
200+
content_type='application/merge-patch+json'
86201
)
87-
print('EXEC response : %s' % resp)
88-
self.assertEqual(3, len(resp.splitlines()))
89-
90-
exec_command = 'uptime'
91-
resp = stream(
92-
api.subresources['exec'],
93-
name,
94-
'default',
95-
command=exec_command,
96-
stderr=False, stdin=False,
97-
stdout=True, tty=False
202+
self.assertEqual(resp.spec.size, 3)
203+
204+
resp = changeme_api.get(name=changeme_name, namespace='default')
205+
self.assertEqual(resp.spec.size, 3)
206+
207+
resp = changeme_api.get(namespace='default')
208+
self.assertEqual(len(resp.items), 1)
209+
210+
resp = changeme_api.get()
211+
self.assertEqual(len(resp.items), 1)
212+
213+
resp = changeme_api.delete(
214+
name=changeme_name,
215+
namespace='default'
98216
)
99-
print('EXEC response : %s' % resp)
100-
self.assertEqual(1, len(resp.splitlines()))
101-
102-
resp = stream(
103-
api.subresources['exec'],
104-
name,
105-
'default',
106-
command='/bin/sh',
107-
stderr=False, stdin=False,
108-
stdout=True, tty=False,
109-
_preload_content=False
217+
218+
resp = changeme_api.get(namespace='default')
219+
self.assertEqual(len(resp.items), 0)
220+
221+
resp = changeme_api.get()
222+
self.assertEqual(len(resp.items), 0)
223+
224+
resp = crd_api.delete(
225+
name=name,
110226
)
111-
resp.write_stdin("echo test string 1\n")
112-
line = resp.readline_stdout(timeout=5)
113-
self.assertFalse(resp.peek_stderr())
114-
self.assertEqual("test string 1", line)
115-
resp.write_stdin("echo test string 2 >&2\n")
116-
line = resp.readline_stderr(timeout=5)
117-
self.assertFalse(resp.peek_stdout())
118-
self.assertEqual("test string 2", line)
119-
resp.write_stdin("exit\n")
120-
resp.update(timeout=5)
121-
line = resp.read_channel(ERROR_CHANNEL)
122-
status = json.loads(line)
123-
self.assertEqual(status['status'], 'Success')
124-
resp.update(timeout=5)
125-
self.assertFalse(resp.is_open())
126-
127-
number_of_pods = len(api.get().items)
128-
self.assertTrue(number_of_pods > 0)
129-
130-
resp = api.delete(name=name, body={}, namespace='default')
227+
228+
time.sleep(2)
229+
client.resources.invalidate_cache()
230+
with self.assertRaises(ResourceNotFoundError):
231+
changeme_api = client.resources.get(api_version='apps.example.com/v1', kind='ChangeMe')
131232

132233
def test_service_apis(self):
133234
client = DynamicClient(api_client.ApiClient(configuration=self.config))
@@ -242,14 +343,13 @@ def test_configmap_apis(self):
242343
resp = api.delete(
243344
name=name, body={}, namespace='default')
244345

245-
resp = api.get('default', pretty=True)
346+
resp = api.get(namespace='default', pretty=True)
246347
self.assertEqual([], resp.items)
247348

248349
def test_node_apis(self):
249350
client = DynamicClient(api_client.ApiClient(configuration=self.config))
250351
api = client.resources.get(api_version='v1', kind='Node')
251352

252353
for item in api.get().items:
253-
node = api.read_node(name=item.metadata.name)
254-
self.assertTrue(len(node.metadata.labels) > 0)
255-
self.assertTrue(isinstance(node.metadata.labels, dict))
354+
node = api.get(name=item.metadata.name)
355+
self.assertTrue(len(dict(node.metadata.labels)) > 0)

0 commit comments

Comments
 (0)