Skip to content

Commit b54a325

Browse files
committed
Add tests for secret API implementation
Signed-off-by: Joffrey F <[email protected]>
1 parent 18e61e8 commit b54a325

File tree

6 files changed

+154
-4
lines changed

6 files changed

+154
-4
lines changed

docker/api/secret.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
import base64
22

3+
import six
4+
35
from .. import utils
46

57

@@ -20,6 +22,8 @@ def create_secret(self, name, data, labels=None):
2022
data = data.encode('utf-8')
2123

2224
data = base64.b64encode(data)
25+
if six.PY3:
26+
data = data.decode('ascii')
2327
body = {
2428
'Data': data,
2529
'Name': name,
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
# -*- coding: utf-8 -*-
2+
3+
import docker
4+
import pytest
5+
6+
from ..helpers import force_leave_swarm, requires_api_version
7+
from .base import BaseAPIIntegrationTest
8+
9+
10+
@requires_api_version('1.25')
11+
class SecretAPITest(BaseAPIIntegrationTest):
12+
def setUp(self):
13+
super(SecretAPITest, self).setUp()
14+
self.init_swarm()
15+
16+
def tearDown(self):
17+
super(SecretAPITest, self).tearDown()
18+
force_leave_swarm(self.client)
19+
20+
def test_create_secret(self):
21+
secret_id = self.client.create_secret(
22+
'favorite_character', 'sakuya izayoi'
23+
)
24+
self.tmp_secrets.append(secret_id)
25+
assert 'ID' in secret_id
26+
data = self.client.inspect_secret(secret_id)
27+
assert data['Spec']['Name'] == 'favorite_character'
28+
29+
def test_create_secret_unicode_data(self):
30+
secret_id = self.client.create_secret(
31+
'favorite_character', u'いざよいさくや'
32+
)
33+
self.tmp_secrets.append(secret_id)
34+
assert 'ID' in secret_id
35+
data = self.client.inspect_secret(secret_id)
36+
assert data['Spec']['Name'] == 'favorite_character'
37+
38+
def test_inspect_secret(self):
39+
secret_name = 'favorite_character'
40+
secret_id = self.client.create_secret(
41+
secret_name, 'sakuya izayoi'
42+
)
43+
self.tmp_secrets.append(secret_id)
44+
data = self.client.inspect_secret(secret_id)
45+
assert data['Spec']['Name'] == secret_name
46+
assert 'ID' in data
47+
assert 'Version' in data
48+
49+
def test_remove_secret(self):
50+
secret_name = 'favorite_character'
51+
secret_id = self.client.create_secret(
52+
secret_name, 'sakuya izayoi'
53+
)
54+
self.tmp_secrets.append(secret_id)
55+
56+
assert self.client.remove_secret(secret_id)
57+
with pytest.raises(docker.errors.NotFound):
58+
self.client.inspect_secret(secret_id)
59+
60+
def test_list_secrets(self):
61+
secret_name = 'favorite_character'
62+
secret_id = self.client.create_secret(
63+
secret_name, 'sakuya izayoi'
64+
)
65+
self.tmp_secrets.append(secret_id)
66+
67+
data = self.client.secrets(filters={'names': ['favorite_character']})
68+
assert len(data) == 1
69+
assert data[0]['ID'] == secret_id['ID']

tests/integration/api_service_test.py

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
1+
# -*- coding: utf-8 -*-
2+
13
import random
4+
import time
25

36
import docker
47

@@ -24,6 +27,21 @@ def tearDown(self):
2427
def get_service_name(self):
2528
return 'dockerpytest_{0:x}'.format(random.getrandbits(64))
2629

30+
def get_service_container(self, service_name, attempts=20, interval=0.5):
31+
# There is some delay between the service's creation and the creation
32+
# of the service's containers. This method deals with the uncertainty
33+
# when trying to retrieve the container associated with a service.
34+
while True:
35+
containers = self.client.containers(
36+
filters={'name': [service_name]}, quiet=True
37+
)
38+
if len(containers) > 0:
39+
return containers[0]
40+
attempts -= 1
41+
if attempts <= 0:
42+
return None
43+
time.sleep(interval)
44+
2745
def create_simple_service(self, name=None):
2846
if name:
2947
name = 'dockerpytest_{0}'.format(name)
@@ -317,3 +335,55 @@ def test_update_service_force_update(self):
317335
new_index = svc_info['Version']['Index']
318336
assert new_index > version_index
319337
assert svc_info['Spec']['TaskTemplate']['ForceUpdate'] == 10
338+
339+
@requires_api_version('1.25')
340+
def test_create_service_with_secret(self):
341+
secret_name = 'favorite_touhou'
342+
secret_data = b'phantasmagoria of flower view'
343+
secret_id = self.client.create_secret(secret_name, secret_data)
344+
self.tmp_secrets.append(secret_id)
345+
secret_ref = docker.types.SecretReference(secret_id, secret_name)
346+
container_spec = docker.types.ContainerSpec(
347+
'busybox', ['top'], secrets=[secret_ref]
348+
)
349+
task_tmpl = docker.types.TaskTemplate(container_spec)
350+
name = self.get_service_name()
351+
svc_id = self.client.create_service(task_tmpl, name=name)
352+
svc_info = self.client.inspect_service(svc_id)
353+
assert 'Secrets' in svc_info['Spec']['TaskTemplate']['ContainerSpec']
354+
secrets = svc_info['Spec']['TaskTemplate']['ContainerSpec']['Secrets']
355+
assert secrets[0] == secret_ref
356+
357+
container = self.get_service_container(name)
358+
assert container is not None
359+
exec_id = self.client.exec_create(
360+
container, 'cat /run/secrets/{0}'.format(secret_name)
361+
)
362+
assert self.client.exec_start(exec_id) == secret_data
363+
364+
@requires_api_version('1.25')
365+
def test_create_service_with_unicode_secret(self):
366+
secret_name = 'favorite_touhou'
367+
secret_data = u'東方花映塚'
368+
secret_id = self.client.create_secret(secret_name, secret_data)
369+
self.tmp_secrets.append(secret_id)
370+
secret_ref = docker.types.SecretReference(secret_id, secret_name)
371+
container_spec = docker.types.ContainerSpec(
372+
'busybox', ['top'], secrets=[secret_ref]
373+
)
374+
task_tmpl = docker.types.TaskTemplate(container_spec)
375+
name = self.get_service_name()
376+
svc_id = self.client.create_service(task_tmpl, name=name)
377+
svc_info = self.client.inspect_service(svc_id)
378+
assert 'Secrets' in svc_info['Spec']['TaskTemplate']['ContainerSpec']
379+
secrets = svc_info['Spec']['TaskTemplate']['ContainerSpec']['Secrets']
380+
assert secrets[0] == secret_ref
381+
382+
container = self.get_service_container(name)
383+
assert container is not None
384+
exec_id = self.client.exec_create(
385+
container, 'cat /run/secrets/{0}'.format(secret_name)
386+
)
387+
container_secret = self.client.exec_start(exec_id)
388+
container_secret = container_secret.decode('utf-8')
389+
assert container_secret == secret_data

tests/integration/base.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ def setUp(self):
2828
self.tmp_volumes = []
2929
self.tmp_networks = []
3030
self.tmp_plugins = []
31+
self.tmp_secrets = []
3132

3233
def tearDown(self):
3334
client = docker.from_env(version=TEST_API_VERSION)
@@ -52,6 +53,12 @@ def tearDown(self):
5253
except docker.errors.APIError:
5354
pass
5455

56+
for secret in self.tmp_secrets:
57+
try:
58+
client.api.remove_secret(secret)
59+
except docker.errors.APIError:
60+
pass
61+
5562
for folder in self.tmp_folders:
5663
shutil.rmtree(folder)
5764

tests/unit/api_container_test.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -45,15 +45,15 @@ def test_start_container_none(self):
4545

4646
self.assertEqual(
4747
str(excinfo.value),
48-
'image or container param is undefined',
48+
'Resource ID was not provided',
4949
)
5050

5151
with pytest.raises(ValueError) as excinfo:
5252
self.client.start(None)
5353

5454
self.assertEqual(
5555
str(excinfo.value),
56-
'image or container param is undefined',
56+
'Resource ID was not provided',
5757
)
5858

5959
def test_start_container_regression_573(self):
@@ -1559,7 +1559,7 @@ def test_inspect_container_undefined_id(self):
15591559
self.client.inspect_container(arg)
15601560

15611561
self.assertEqual(
1562-
excinfo.value.args[0], 'image or container param is undefined'
1562+
excinfo.value.args[0], 'Resource ID was not provided'
15631563
)
15641564

15651565
def test_container_stats(self):

tests/unit/api_image_test.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -204,7 +204,7 @@ def test_inspect_image_undefined_id(self):
204204
self.client.inspect_image(arg)
205205

206206
self.assertEqual(
207-
excinfo.value.args[0], 'image or container param is undefined'
207+
excinfo.value.args[0], 'Resource ID was not provided'
208208
)
209209

210210
def test_insert_image(self):

0 commit comments

Comments
 (0)