1 # Copyright 2013 dotCloud inc.
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
7 # http://www.apache.org/licenses/LICENSE-2.0
9 # Unless required by applicable law or agreed to in writing, software
10 # distributed under the License is distributed on an "AS IS" BASIS,
11 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 # See the License for the specific language governing permissions and
13 # limitations under the License.
36 from unittest
import mock
41 def response(status_code
=200, content
='', headers
=None, reason
=None, elapsed
=0,
43 res
= requests
.Response()
44 res
.status_code
= status_code
45 if not isinstance(content
, six
.binary_type
):
46 content
= json
.dumps(content
).encode('ascii')
47 res
._content
= content
48 res
.headers
= requests
.structures
.CaseInsensitiveDict(headers
or {})
50 res
.elapsed
= datetime
.timedelta(elapsed
)
55 def fake_resolve_authconfig(authconfig
, registry
=None):
59 def fake_resp(url
, data
=None, **kwargs
):
60 status_code
, content
= fake_api
.fake_responses
[url
]()
61 return response(status_code
=status_code
, content
=content
)
64 fake_request
= mock
.Mock(side_effect
=fake_resp
)
65 url_prefix
= 'http+unix://var/run/docker.sock/v{0}/'.format(
66 docker
.client
.DEFAULT_DOCKER_API_VERSION
)
69 class Cleanup(object):
70 if sys
.version_info
< (2, 7):
71 # Provide a basic implementation of addCleanup for Python < 2.7
72 def __init__(self
, *args
, **kwargs
):
73 super(Cleanup
, self
).__init
__(*args
, **kwargs
)
77 super(Cleanup
, self
).tearDown()
80 fn
, args
, kwargs
= self
._cleanups
.pop(-1)
83 except KeyboardInterrupt:
90 def addCleanup(self
, function
, *args
, **kwargs
):
91 self
._cleanups
.append((function
, args
, kwargs
))
94 @mock.patch
.multiple('docker.Client', get
=fake_request
, post
=fake_request
,
95 put
=fake_request
, delete
=fake_request
)
96 class DockerClientTest(Cleanup
, unittest
.TestCase
):
98 self
.client
= docker
.Client()
99 # Force-clear authconfig to avoid tampering with the tests
100 self
.client
._cfg
= {'Configs': {}}
102 #########################
103 # INFORMATION TESTS #
104 #########################
105 def test_version(self
):
107 self
.client
.version()
108 except Exception as e
:
109 self
.fail('Command should not raise exception: {0}'.format(e
))
111 fake_request
.assert_called_with(
112 url_prefix
+ 'version',
113 timeout
=docker
.client
.DEFAULT_TIMEOUT_SECONDS
119 except Exception as e
:
120 self
.fail('Command should not raise exception: {0}'.format(e
))
122 fake_request
.assert_called_with(
124 timeout
=docker
.client
.DEFAULT_TIMEOUT_SECONDS
127 def test_search(self
):
129 self
.client
.search('busybox')
130 except Exception as e
:
131 self
.fail('Command should not raise exception: {0}'.format(e
))
133 fake_request
.assert_called_with(
134 url_prefix
+ 'images/search',
135 params
={'term': 'busybox'},
136 timeout
=docker
.client
.DEFAULT_TIMEOUT_SECONDS
139 def test_image_viz(self
):
141 self
.client
.images('busybox', viz
=True)
142 self
.fail('Viz output should not be supported!')
150 def test_images(self
):
152 self
.client
.images(all
=True)
153 except Exception as e
:
154 self
.fail('Command should not raise exception: {0}'.format(e
))
155 fake_request
.assert_called_with(
156 url_prefix
+ 'images/json',
157 params
={'filter': None, 'only_ids': 0, 'all': 1},
158 timeout
=docker
.client
.DEFAULT_TIMEOUT_SECONDS
161 def test_images_quiet(self
):
163 self
.client
.images(all
=True, quiet
=True)
164 except Exception as e
:
165 self
.fail('Command should not raise exception: {0}'.format(e
))
166 fake_request
.assert_called_with(
167 url_prefix
+ 'images/json',
168 params
={'filter': None, 'only_ids': 1, 'all': 1},
169 timeout
=docker
.client
.DEFAULT_TIMEOUT_SECONDS
172 def test_image_ids(self
):
174 self
.client
.images(quiet
=True)
175 except Exception as e
:
176 self
.fail('Command should not raise exception: {0}'.format(e
))
178 fake_request
.assert_called_with(
179 url_prefix
+ 'images/json',
180 params
={'filter': None, 'only_ids': 1, 'all': 0},
181 timeout
=docker
.client
.DEFAULT_TIMEOUT_SECONDS
184 def test_list_containers(self
):
186 self
.client
.containers(all
=True)
187 except Exception as e
:
188 self
.fail('Command should not raise exception: {0}'.format(e
))
190 fake_request
.assert_called_with(
191 url_prefix
+ 'containers/json',
200 timeout
=docker
.client
.DEFAULT_TIMEOUT_SECONDS
203 #####################
205 #####################
207 def test_create_container(self
):
209 self
.client
.create_container('busybox', 'true')
210 except Exception as e
:
211 self
.fail('Command should not raise exception: {0}'.format(e
))
213 args
= fake_request
.call_args
214 self
.assertEqual(args
[0][0],
215 url_prefix
+ 'containers/create')
216 self
.assertEqual(json
.loads(args
[1]['data']),
218 {"Tty": false, "Image": "busybox", "Cmd": ["true"],
219 "AttachStdin": false, "Memory": 0,
220 "AttachStderr": true, "AttachStdout": true,
222 "OpenStdin": false, "NetworkDisabled": false,
223 "MemorySwap": 0}'''))
224 self
.assertEqual(args
[1]['headers'],
225 {'Content-Type': 'application/json'})
227 def test_create_container_with_binds(self
):
231 self
.client
.create_container('busybox', ['ls', mount_dest
],
232 volumes
=[mount_dest
])
233 except Exception as e
:
234 self
.fail('Command should not raise exception: {0}'.format(e
))
236 args
= fake_request
.call_args
237 self
.assertEqual(args
[0][0],
238 url_prefix
+ 'containers/create')
239 self
.assertEqual(json
.loads(args
[1]['data']),
241 {"Tty": false, "Image": "busybox",
242 "Cmd": ["ls", "/mnt"], "AttachStdin": false,
243 "Volumes": {"/mnt": {}}, "Memory": 0,
244 "AttachStderr": true,
245 "AttachStdout": true, "OpenStdin": false,
247 "NetworkDisabled": false,
248 "MemorySwap": 0}'''))
249 self
.assertEqual(args
[1]['headers'],
250 {'Content-Type': 'application/json'})
252 def test_create_container_with_volume_string(self
):
256 self
.client
.create_container('busybox', ['ls', mount_dest
],
258 except Exception as e
:
259 self
.fail('Command should not raise exception: {0}'.format(e
))
261 args
= fake_request
.call_args
262 self
.assertEqual(args
[0][0],
263 url_prefix
+ 'containers/create')
264 self
.assertEqual(json
.loads(args
[1]['data']),
266 {"Tty": false, "Image": "busybox",
267 "Cmd": ["ls", "/mnt"], "AttachStdin": false,
268 "Volumes": {"/mnt": {}}, "Memory": 0,
269 "AttachStderr": true,
270 "AttachStdout": true, "OpenStdin": false,
272 "NetworkDisabled": false,
273 "MemorySwap": 0}'''))
274 self
.assertEqual(args
[1]['headers'],
275 {'Content-Type': 'application/json'})
277 def test_create_container_with_ports(self
):
279 self
.client
.create_container('busybox', 'ls',
280 ports
=[1111, (2222, 'udp'), (3333,)])
281 except Exception as e
:
282 self
.fail('Command should not raise exception: {0}'.format(e
))
284 args
= fake_request
.call_args
285 self
.assertEqual(args
[0][0],
286 url_prefix
+ 'containers/create')
287 self
.assertEqual(json
.loads(args
[1]['data']),
289 {"Tty": false, "Image": "busybox",
290 "Cmd": ["ls"], "AttachStdin": false,
291 "Memory": 0, "ExposedPorts": {
296 "AttachStderr": true,
297 "AttachStdout": true, "OpenStdin": false,
299 "NetworkDisabled": false,
300 "MemorySwap": 0}'''))
301 self
.assertEqual(args
[1]['headers'],
302 {'Content-Type': 'application/json'})
304 def test_create_container_with_entrypoint(self
):
306 self
.client
.create_container('busybox', 'hello',
308 except Exception as e
:
309 self
.fail('Command should not raise exception: {0}'.format(e
))
311 args
= fake_request
.call_args
312 self
.assertEqual(args
[0][0],
313 url_prefix
+ 'containers/create')
314 self
.assertEqual(json
.loads(args
[1]['data']),
316 {"Tty": false, "Image": "busybox",
317 "Cmd": ["hello"], "AttachStdin": false,
319 "AttachStderr": true,
320 "AttachStdout": true, "OpenStdin": false,
322 "NetworkDisabled": false,
323 "Entrypoint": "cowsay",
324 "MemorySwap": 0}'''))
325 self
.assertEqual(args
[1]['headers'],
326 {'Content-Type': 'application/json'})
328 def test_create_container_with_cpu_shares(self
):
330 self
.client
.create_container('busybox', 'ls',
332 except Exception as e
:
333 self
.fail('Command should not raise exception: {0}'.format(e
))
335 args
= fake_request
.call_args
336 self
.assertEqual(args
[0][0],
337 url_prefix
+ 'containers/create')
338 self
.assertEqual(json
.loads(args
[1]['data']),
340 {"Tty": false, "Image": "busybox",
341 "Cmd": ["ls"], "AttachStdin": false,
343 "AttachStderr": true,
344 "AttachStdout": true, "OpenStdin": false,
346 "NetworkDisabled": false,
348 "MemorySwap": 0}'''))
349 self
.assertEqual(args
[1]['headers'],
350 {'Content-Type': 'application/json'})
352 def test_create_container_with_working_dir(self
):
354 self
.client
.create_container('busybox', 'ls',
356 except Exception as e
:
357 self
.fail('Command should not raise exception: {0}'.format(e
))
359 args
= fake_request
.call_args
360 self
.assertEqual(args
[0][0],
361 url_prefix
+ 'containers/create')
362 self
.assertEqual(json
.loads(args
[1]['data']),
364 {"Tty": false, "Image": "busybox",
365 "Cmd": ["ls"], "AttachStdin": false,
367 "AttachStderr": true,
368 "AttachStdout": true, "OpenStdin": false,
370 "NetworkDisabled": false,
371 "WorkingDir": "/root",
372 "MemorySwap": 0}'''))
373 self
.assertEqual(args
[1]['headers'],
374 {'Content-Type': 'application/json'})
376 def test_create_container_with_stdin_open(self
):
378 self
.client
.create_container('busybox', 'true', stdin_open
=True)
379 except Exception as e
:
380 self
.fail('Command should not raise exception: {0}'.format(e
))
382 args
= fake_request
.call_args
383 self
.assertEqual(args
[0][0],
384 url_prefix
+ 'containers/create')
385 self
.assertEqual(json
.loads(args
[1]['data']),
387 {"Tty": false, "Image": "busybox", "Cmd": ["true"],
388 "AttachStdin": true, "Memory": 0,
389 "AttachStderr": true, "AttachStdout": true,
391 "OpenStdin": true, "NetworkDisabled": false,
392 "MemorySwap": 0}'''))
393 self
.assertEqual(args
[1]['headers'],
394 {'Content-Type': 'application/json'})
396 def test_create_container_with_volumes_from(self
):
397 vol_names
= ['foo', 'bar']
399 self
.client
.create_container('busybox', 'true',
400 volumes_from
=vol_names
)
401 except docker
.errors
.DockerException
as e
:
403 docker
.utils
.compare_version('1.10', self
.client
._version
) >= 0
406 except Exception as e
:
407 self
.fail('Command should not raise exception: {0}'.format(e
))
408 args
= fake_request
.call_args
409 self
.assertEqual(args
[0][0], url_prefix
+ 'containers/create')
410 self
.assertEqual(json
.loads(args
[1]['data'])['VolumesFrom'],
412 self
.assertEqual(args
[1]['headers'],
413 {'Content-Type': 'application/json'})
415 def test_create_container_empty_volumes_from(self
):
417 self
.client
.create_container('busybox', 'true', volumes_from
=[])
418 except Exception as e
:
419 self
.fail('Command should not raise exception: {0}'.format(e
))
421 args
= fake_request
.call_args
422 data
= json
.loads(args
[1]['data'])
423 self
.assertTrue('VolumesFrom' not in data
)
425 def test_create_named_container(self
):
427 self
.client
.create_container('busybox', 'true',
428 name
='marisa-kirisame')
429 except Exception as e
:
430 self
.fail('Command should not raise exception: {0}'.format(e
))
432 args
= fake_request
.call_args
433 self
.assertEqual(args
[0][0],
434 url_prefix
+ 'containers/create')
435 self
.assertEqual(json
.loads(args
[1]['data']),
437 {"Tty": false, "Image": "busybox", "Cmd": ["true"],
438 "AttachStdin": false, "Memory": 0,
439 "AttachStderr": true, "AttachStdout": true,
441 "OpenStdin": false, "NetworkDisabled": false,
442 "MemorySwap": 0}'''))
443 self
.assertEqual(args
[1]['headers'],
444 {'Content-Type': 'application/json'})
445 self
.assertEqual(args
[1]['params'], {'name': 'marisa-kirisame'})
447 def test_create_container_with_mem_limit_as_int(self
):
449 self
.client
.create_container('busybox', 'true',
451 except Exception as e
:
452 self
.fail('Command should not raise exception: {0}'.format(e
))
454 args
= fake_request
.call_args
455 data
= json
.loads(args
[1]['data'])
456 self
.assertEqual(data
['Memory'], 128.0)
458 def test_create_container_with_mem_limit_as_string(self
):
460 self
.client
.create_container('busybox', 'true',
462 except Exception as e
:
463 self
.fail('Command should not raise exception: {0}'.format(e
))
465 args
= fake_request
.call_args
466 data
= json
.loads(args
[1]['data'])
467 self
.assertEqual(data
['Memory'], 128.0)
469 def test_create_container_with_mem_limit_as_string_with_k_unit(self
):
471 self
.client
.create_container('busybox', 'true',
473 except Exception as e
:
474 self
.fail('Command should not raise exception: {0}'.format(e
))
476 args
= fake_request
.call_args
477 data
= json
.loads(args
[1]['data'])
478 self
.assertEqual(data
['Memory'], 128.0 * 1024)
480 def test_create_container_with_mem_limit_as_string_with_m_unit(self
):
482 self
.client
.create_container('busybox', 'true',
484 except Exception as e
:
485 self
.fail('Command should not raise exception: {0}'.format(e
))
487 args
= fake_request
.call_args
488 data
= json
.loads(args
[1]['data'])
489 self
.assertEqual(data
['Memory'], 128.0 * 1024 * 1024)
491 def test_create_container_with_mem_limit_as_string_with_g_unit(self
):
493 self
.client
.create_container('busybox', 'true',
495 except Exception as e
:
496 self
.fail('Command should not raise exception: {0}'.format(e
))
498 args
= fake_request
.call_args
499 data
= json
.loads(args
[1]['data'])
500 self
.assertEqual(data
['Memory'], 128.0 * 1024 * 1024 * 1024)
502 def test_create_container_with_mem_limit_as_string_with_wrong_value(self
):
503 self
.assertRaises(docker
.errors
.DockerException
,
504 self
.client
.create_container
,
505 'busybox', 'true', mem_limit
='128p')
507 self
.assertRaises(docker
.errors
.DockerException
,
508 self
.client
.create_container
,
509 'busybox', 'true', mem_limit
='1f28')
511 def test_start_container(self
):
513 self
.client
.start(fake_api
.FAKE_CONTAINER_ID
)
514 except Exception as e
:
516 self
.fail('Command should not raise exception: {0}'.format(e
))
517 args
= fake_request
.call_args
520 url_prefix
+ 'containers/3cc2351ab11b/start'
523 json
.loads(args
[1]['data']),
524 {"PublishAllPorts": False, "Privileged": False}
528 {'Content-Type': 'application/json'}
532 docker
.client
.DEFAULT_TIMEOUT_SECONDS
535 def test_start_container_with_lxc_conf(self
):
538 fake_api
.FAKE_CONTAINER_ID
,
539 lxc_conf
={'lxc.conf.k': 'lxc.conf.value'}
541 except Exception as e
:
542 self
.fail('Command should not raise exception: {0}'.format(e
))
543 args
= fake_request
.call_args
546 url_prefix
+ 'containers/3cc2351ab11b/start'
549 json
.loads(args
[1]['data']),
550 {"LxcConf": [{"Value": "lxc.conf.value", "Key": "lxc.conf.k"}],
551 "PublishAllPorts": False, "Privileged": False}
555 {'Content-Type': 'application/json'}
559 docker
.client
.DEFAULT_TIMEOUT_SECONDS
562 def test_start_container_with_lxc_conf_compat(self
):
565 fake_api
.FAKE_CONTAINER_ID
,
566 lxc_conf
=[{'Key': 'lxc.conf.k', 'Value': 'lxc.conf.value'}]
568 except Exception as e
:
569 self
.fail('Command should not raise exception: {0}'.format(e
))
571 args
= fake_request
.call_args
572 self
.assertEqual(args
[0][0], url_prefix
+
573 'containers/3cc2351ab11b/start')
575 json
.loads(args
[1]['data']),
577 "LxcConf": [{"Key": "lxc.conf.k", "Value": "lxc.conf.value"}],
578 "PublishAllPorts": False,
582 self
.assertEqual(args
[1]['headers'],
583 {'Content-Type': 'application/json'})
586 docker
.client
.DEFAULT_TIMEOUT_SECONDS
589 def test_start_container_with_binds_ro(self
):
592 mount_origin
= '/tmp'
593 self
.client
.start(fake_api
.FAKE_CONTAINER_ID
,
594 binds
={mount_origin
: {
598 except Exception as e
:
599 self
.fail('Command should not raise exception: {0}'.format(e
))
601 args
= fake_request
.call_args
602 self
.assertEqual(args
[0][0], url_prefix
+
603 'containers/3cc2351ab11b/start')
604 self
.assertEqual(json
.loads(args
[1]['data']),
605 {"Binds": ["/tmp:/mnt:ro"],
606 "PublishAllPorts": False,
607 "Privileged": False})
608 self
.assertEqual(args
[1]['headers'],
609 {'Content-Type': 'application/json'})
612 docker
.client
.DEFAULT_TIMEOUT_SECONDS
)
614 def test_start_container_with_binds_rw(self
):
617 mount_origin
= '/tmp'
618 self
.client
.start(fake_api
.FAKE_CONTAINER_ID
,
619 binds
={mount_origin
: {
620 "bind": mount_dest
, "ro": False}})
621 except Exception as e
:
622 self
.fail('Command should not raise exception: {0}'.format(e
))
624 args
= fake_request
.call_args
625 self
.assertEqual(args
[0][0], url_prefix
+
626 'containers/3cc2351ab11b/start')
627 self
.assertEqual(json
.loads(args
[1]['data']),
628 {"Binds": ["/tmp:/mnt:rw"],
629 "PublishAllPorts": False,
630 "Privileged": False})
631 self
.assertEqual(args
[1]['headers'],
632 {'Content-Type': 'application/json'})
635 docker
.client
.DEFAULT_TIMEOUT_SECONDS
638 def test_start_container_with_port_binds(self
):
641 self
.client
.start(fake_api
.FAKE_CONTAINER_ID
, port_bindings
={
645 4444: ('127.0.0.1',),
646 5555: ('127.0.0.1', 5555),
647 6666: [('127.0.0.1',), ('192.168.0.1',)]
649 except Exception as e
:
650 self
.fail('Command should not raise exception: {0}'.format(e
))
652 args
= fake_request
.call_args
653 self
.assertEqual(args
[0][0], url_prefix
+
654 'containers/3cc2351ab11b/start')
655 data
= json
.loads(args
[1]['data'])
656 self
.assertEqual(data
['PublishAllPorts'], False)
657 self
.assertTrue('1111/tcp' in data
['PortBindings'])
658 self
.assertTrue('2222/tcp' in data
['PortBindings'])
659 self
.assertTrue('3333/udp' in data
['PortBindings'])
660 self
.assertTrue('4444/tcp' in data
['PortBindings'])
661 self
.assertTrue('5555/tcp' in data
['PortBindings'])
662 self
.assertTrue('6666/tcp' in data
['PortBindings'])
664 [{"HostPort": "", "HostIp": ""}],
665 data
['PortBindings']['1111/tcp']
668 [{"HostPort": "2222", "HostIp": ""}],
669 data
['PortBindings']['2222/tcp']
672 [{"HostPort": "3333", "HostIp": ""}],
673 data
['PortBindings']['3333/udp']
676 [{"HostPort": "", "HostIp": "127.0.0.1"}],
677 data
['PortBindings']['4444/tcp']
680 [{"HostPort": "5555", "HostIp": "127.0.0.1"}],
681 data
['PortBindings']['5555/tcp']
683 self
.assertEqual(len(data
['PortBindings']['6666/tcp']), 2)
684 self
.assertEqual(args
[1]['headers'],
685 {'Content-Type': 'application/json'})
688 docker
.client
.DEFAULT_TIMEOUT_SECONDS
691 def test_start_container_with_links(self
):
696 self
.client
.start(fake_api
.FAKE_CONTAINER_ID
,
697 links
={link_path
: alias
})
698 except Exception as e
:
699 self
.fail('Command should not raise exception: {0}'.format(e
))
701 args
= fake_request
.call_args
704 url_prefix
+ 'containers/3cc2351ab11b/start'
707 json
.loads(args
[1]['data']),
708 {"PublishAllPorts": False, "Privileged": False,
709 "Links": ["path:alias"]}
713 {'Content-Type': 'application/json'}
716 def test_start_container_with_multiple_links(self
):
721 fake_api
.FAKE_CONTAINER_ID
,
723 link_path
+ '1': alias
+ '1',
724 link_path
+ '2': alias
+ '2'
727 except Exception as e
:
728 self
.fail('Command should not raise exception: {0}'.format(e
))
730 args
= fake_request
.call_args
733 url_prefix
+ 'containers/3cc2351ab11b/start'
736 json
.loads(args
[1]['data']),
738 "PublishAllPorts": False,
740 "Links": ["path1:alias1", "path2:alias2"]
745 {'Content-Type': 'application/json'}
748 def test_start_container_with_links_as_list_of_tuples(self
):
753 self
.client
.start(fake_api
.FAKE_CONTAINER_ID
,
754 links
=[(link_path
, alias
)])
755 except Exception as e
:
756 self
.fail('Command should not raise exception: {0}'.format(e
))
758 args
= fake_request
.call_args
761 url_prefix
+ 'containers/3cc2351ab11b/start'
764 json
.loads(args
[1]['data']),
765 {"PublishAllPorts": False, "Privileged": False,
766 "Links": ["path:alias"]}
770 {'Content-Type': 'application/json'}
773 def test_start_container_privileged(self
):
775 self
.client
.start(fake_api
.FAKE_CONTAINER_ID
, privileged
=True)
776 except Exception as e
:
777 self
.fail('Command should not raise exception: {0}'.format(e
))
779 args
= fake_request
.call_args
782 url_prefix
+ 'containers/3cc2351ab11b/start'
784 self
.assertEqual(json
.loads(args
[1]['data']),
785 {"PublishAllPorts": False, "Privileged": True})
786 self
.assertEqual(args
[1]['headers'],
787 {'Content-Type': 'application/json'})
790 docker
.client
.DEFAULT_TIMEOUT_SECONDS
793 def test_start_container_with_dict_instead_of_id(self
):
795 self
.client
.start({'Id': fake_api
.FAKE_CONTAINER_ID
})
796 except Exception as e
:
797 self
.fail('Command should not raise exception: {0}'.format(e
))
798 args
= fake_request
.call_args
801 url_prefix
+ 'containers/3cc2351ab11b/start'
804 json
.loads(args
[1]['data']),
805 {"PublishAllPorts": False, "Privileged": False}
809 {'Content-Type': 'application/json'}
813 docker
.client
.DEFAULT_TIMEOUT_SECONDS
816 def test_start_container_with_restart_policy(self
):
818 self
.client
.start(fake_api
.FAKE_CONTAINER_ID
,
821 "MaximumRetryCount": 0
823 except Exception as e
:
824 self
.fail('Command should not raise exception: {0}'.format(e
))
825 args
= fake_request
.call_args
828 url_prefix
+ 'containers/3cc2351ab11b/start'
831 json
.loads(args
[1]['data']),
832 {"PublishAllPorts": False, "Privileged": False,
833 "RestartPolicy": {"MaximumRetryCount": 0, "Name": "always"}}
837 {'Content-Type': 'application/json'}
841 docker
.client
.DEFAULT_TIMEOUT_SECONDS
844 def test_start_container_with_added_capabilities(self
):
846 self
.client
.start(fake_api
.FAKE_CONTAINER_ID
,
848 except Exception as e
:
849 self
.fail('Command should not raise exception: {0}'.format(e
))
850 args
= fake_request
.call_args
853 url_prefix
+ 'containers/3cc2351ab11b/start'
856 json
.loads(args
[1]['data']),
857 {"PublishAllPorts": False, "Privileged": False,
862 {'Content-Type': 'application/json'}
866 docker
.client
.DEFAULT_TIMEOUT_SECONDS
869 def test_start_container_with_dropped_capabilities(self
):
871 self
.client
.start(fake_api
.FAKE_CONTAINER_ID
,
873 except Exception as e
:
874 self
.fail('Command should not raise exception: {0}'.format(e
))
875 args
= fake_request
.call_args
878 url_prefix
+ 'containers/3cc2351ab11b/start'
881 json
.loads(args
[1]['data']),
882 {"PublishAllPorts": False, "Privileged": False,
883 "CapDrop": ["MKNOD"]}
887 {'Content-Type': 'application/json'}
891 docker
.client
.DEFAULT_TIMEOUT_SECONDS
894 def test_resize_container(self
):
897 {'Id': fake_api
.FAKE_CONTAINER_ID
},
901 except Exception as e
:
902 self
.fail('Command should not raise exception: {0}'.format(e
))
904 fake_request
.assert_called_with(
905 url_prefix
+ 'containers/3cc2351ab11b/resize',
906 params
={'h': 15, 'w': 120},
907 timeout
=docker
.client
.DEFAULT_TIMEOUT_SECONDS
912 self
.client
.wait(fake_api
.FAKE_CONTAINER_ID
)
913 except Exception as e
:
914 self
.fail('Command should not raise exception: {0}'.format(e
))
916 fake_request
.assert_called_with(
917 url_prefix
+ 'containers/3cc2351ab11b/wait',
921 def test_wait_with_dict_instead_of_id(self
):
923 self
.client
.wait({'Id': fake_api
.FAKE_CONTAINER_ID
})
924 except Exception as e
:
926 self
.fail('Command should not raise exception: {0}'.format(e
))
928 fake_request
.assert_called_with(
929 url_prefix
+ 'containers/3cc2351ab11b/wait',
933 def test_url_compatibility_unix(self
):
934 c
= docker
.Client(base_url
="unix://socket")
936 assert c
.base_url
== "http+unix://socket"
938 def test_url_compatibility_unix_triple_slash(self
):
939 c
= docker
.Client(base_url
="unix:///socket")
941 assert c
.base_url
== "http+unix://socket"
943 def test_url_compatibility_http_unix_triple_slash(self
):
944 c
= docker
.Client(base_url
="http+unix:///socket")
946 assert c
.base_url
== "http+unix://socket"
948 def test_url_compatibility_http(self
):
949 c
= docker
.Client(base_url
="http://hostname:1234")
951 assert c
.base_url
== "http://hostname:1234"
953 def test_url_compatibility_tcp(self
):
954 c
= docker
.Client(base_url
="tcp://hostname:1234")
956 assert c
.base_url
== "http://hostname:1234"
960 logs
= self
.client
.logs(fake_api
.FAKE_CONTAINER_ID
)
961 except Exception as e
:
962 self
.fail('Command should not raise exception: {0}'.format(e
))
964 fake_request
.assert_called_with(
965 url_prefix
+ 'containers/3cc2351ab11b/logs',
966 params
={'timestamps': 0, 'follow': 0, 'stderr': 1, 'stdout': 1},
967 timeout
=docker
.client
.DEFAULT_TIMEOUT_SECONDS
,
973 'Flowering Nights\n(Sakuya Iyazoi)\n'.encode('ascii')
976 def test_logs_with_dict_instead_of_id(self
):
978 logs
= self
.client
.logs({'Id': fake_api
.FAKE_CONTAINER_ID
})
979 except Exception as e
:
980 self
.fail('Command should not raise exception: {0}'.format(e
))
982 fake_request
.assert_called_with(
983 url_prefix
+ 'containers/3cc2351ab11b/logs',
984 params
={'timestamps': 0, 'follow': 0, 'stderr': 1, 'stdout': 1},
985 timeout
=docker
.client
.DEFAULT_TIMEOUT_SECONDS
,
991 'Flowering Nights\n(Sakuya Iyazoi)\n'.encode('ascii')
994 def test_log_streaming(self
):
996 self
.client
.logs(fake_api
.FAKE_CONTAINER_ID
, stream
=True)
997 except Exception as e
:
998 self
.fail('Command should not raise exception: {0}'.format(e
))
1000 fake_request
.assert_called_with(
1001 url_prefix
+ 'containers/3cc2351ab11b/logs',
1002 params
={'timestamps': 0, 'follow': 1, 'stderr': 1, 'stdout': 1},
1003 timeout
=docker
.client
.DEFAULT_TIMEOUT_SECONDS
,
1007 def test_diff(self
):
1009 self
.client
.diff(fake_api
.FAKE_CONTAINER_ID
)
1010 except Exception as e
:
1011 self
.fail('Command should not raise exception: {0}'.format(e
))
1013 fake_request
.assert_called_with(
1014 url_prefix
+ 'containers/3cc2351ab11b/changes',
1015 timeout
=docker
.client
.DEFAULT_TIMEOUT_SECONDS
1018 def test_diff_with_dict_instead_of_id(self
):
1020 self
.client
.diff({'Id': fake_api
.FAKE_CONTAINER_ID
})
1021 except Exception as e
:
1022 self
.fail('Command should not raise exception: {0}'.format(e
))
1024 fake_request
.assert_called_with(
1025 url_prefix
+ 'containers/3cc2351ab11b/changes',
1026 timeout
=docker
.client
.DEFAULT_TIMEOUT_SECONDS
1029 def test_port(self
):
1031 self
.client
.port({'Id': fake_api
.FAKE_CONTAINER_ID
}, 1111)
1032 except Exception as e
:
1033 self
.fail('Command should not raise exception: {0}'.format(e
))
1035 fake_request
.assert_called_with(
1036 url_prefix
+ 'containers/3cc2351ab11b/json',
1037 timeout
=docker
.client
.DEFAULT_TIMEOUT_SECONDS
1040 def test_stop_container(self
):
1043 self
.client
.stop(fake_api
.FAKE_CONTAINER_ID
, timeout
=timeout
)
1044 except Exception as e
:
1045 self
.fail('Command should not raise exception: {0}'.format(e
))
1047 fake_request
.assert_called_with(
1048 url_prefix
+ 'containers/3cc2351ab11b/stop',
1049 params
={'t': timeout
},
1050 timeout
=(docker
.client
.DEFAULT_TIMEOUT_SECONDS
+ timeout
)
1053 def test_stop_container_with_dict_instead_of_id(self
):
1056 self
.client
.stop({'Id': fake_api
.FAKE_CONTAINER_ID
},
1058 except Exception as e
:
1059 self
.fail('Command should not raise exception: {0}'.format(e
))
1061 fake_request
.assert_called_with(
1062 url_prefix
+ 'containers/3cc2351ab11b/stop',
1063 params
={'t': timeout
},
1064 timeout
=(docker
.client
.DEFAULT_TIMEOUT_SECONDS
+ timeout
)
1067 def test_kill_container(self
):
1069 self
.client
.kill(fake_api
.FAKE_CONTAINER_ID
)
1070 except Exception as e
:
1071 self
.fail('Command should not raise exception: {0}'.format(e
))
1073 fake_request
.assert_called_with(
1074 url_prefix
+ 'containers/3cc2351ab11b/kill',
1076 timeout
=docker
.client
.DEFAULT_TIMEOUT_SECONDS
1079 def test_kill_container_with_dict_instead_of_id(self
):
1081 self
.client
.kill({'Id': fake_api
.FAKE_CONTAINER_ID
})
1082 except Exception as e
:
1083 self
.fail('Command should not raise exception: {0}'.format(e
))
1085 fake_request
.assert_called_with(
1086 url_prefix
+ 'containers/3cc2351ab11b/kill',
1088 timeout
=docker
.client
.DEFAULT_TIMEOUT_SECONDS
1091 def test_kill_container_with_signal(self
):
1093 self
.client
.kill(fake_api
.FAKE_CONTAINER_ID
, signal
=signal
.SIGTERM
)
1094 except Exception as e
:
1095 self
.fail('Command should not raise exception: {0}'.format(e
))
1097 fake_request
.assert_called_with(
1098 url_prefix
+ 'containers/3cc2351ab11b/kill',
1099 params
={'signal': signal
.SIGTERM
},
1100 timeout
=docker
.client
.DEFAULT_TIMEOUT_SECONDS
1103 def test_restart_container(self
):
1105 self
.client
.restart(fake_api
.FAKE_CONTAINER_ID
, timeout
=2)
1106 except Exception as e
:
1107 self
.fail('Command should not raise exception : {0}'.format(e
))
1109 fake_request
.assert_called_with(
1110 url_prefix
+ 'containers/3cc2351ab11b/restart',
1112 timeout
=docker
.client
.DEFAULT_TIMEOUT_SECONDS
1115 def test_restart_container_with_dict_instead_of_id(self
):
1117 self
.client
.restart({'Id': fake_api
.FAKE_CONTAINER_ID
}, timeout
=2)
1118 except Exception as e
:
1119 self
.fail('Command should not raise exception: {0}'.format(e
))
1121 fake_request
.assert_called_with(
1122 url_prefix
+ 'containers/3cc2351ab11b/restart',
1124 timeout
=docker
.client
.DEFAULT_TIMEOUT_SECONDS
1127 def test_remove_container(self
):
1129 self
.client
.remove_container(fake_api
.FAKE_CONTAINER_ID
)
1130 except Exception as e
:
1131 self
.fail('Command should not raise exception: {0}'.format(e
))
1133 fake_request
.assert_called_with(
1134 url_prefix
+ 'containers/3cc2351ab11b',
1135 params
={'v': False, 'link': False, 'force': False},
1136 timeout
=docker
.client
.DEFAULT_TIMEOUT_SECONDS
1139 def test_remove_container_with_dict_instead_of_id(self
):
1141 self
.client
.remove_container({'Id': fake_api
.FAKE_CONTAINER_ID
})
1142 except Exception as e
:
1143 self
.fail('Command should not raise exception: {0}'.format(e
))
1145 fake_request
.assert_called_with(
1146 url_prefix
+ 'containers/3cc2351ab11b',
1147 params
={'v': False, 'link': False, 'force': False},
1148 timeout
=docker
.client
.DEFAULT_TIMEOUT_SECONDS
1151 def test_remove_link(self
):
1153 self
.client
.remove_container(fake_api
.FAKE_CONTAINER_ID
, link
=True)
1154 except Exception as e
:
1155 self
.fail('Command should not raise exception: {0}'.format(e
))
1157 fake_request
.assert_called_with(
1158 url_prefix
+ 'containers/3cc2351ab11b',
1159 params
={'v': False, 'link': True, 'force': False},
1160 timeout
=docker
.client
.DEFAULT_TIMEOUT_SECONDS
1163 def test_export(self
):
1165 self
.client
.export(fake_api
.FAKE_CONTAINER_ID
)
1166 except Exception as e
:
1167 self
.fail('Command should not raise exception: {0}'.format(e
))
1169 fake_request
.assert_called_with(
1170 url_prefix
+ 'containers/3cc2351ab11b/export',
1172 timeout
=docker
.client
.DEFAULT_TIMEOUT_SECONDS
1175 def test_export_with_dict_instead_of_id(self
):
1177 self
.client
.export({'Id': fake_api
.FAKE_CONTAINER_ID
})
1178 except Exception as e
:
1179 self
.fail('Command should not raise exception: {0}'.format(e
))
1181 fake_request
.assert_called_with(
1182 url_prefix
+ 'containers/3cc2351ab11b/export',
1184 timeout
=docker
.client
.DEFAULT_TIMEOUT_SECONDS
1187 def test_inspect_container(self
):
1189 self
.client
.inspect_container(fake_api
.FAKE_CONTAINER_ID
)
1190 except Exception as e
:
1191 self
.fail('Command should not raise exception: {0}'.format(e
))
1193 fake_request
.assert_called_with(
1194 url_prefix
+ 'containers/3cc2351ab11b/json',
1195 timeout
=docker
.client
.DEFAULT_TIMEOUT_SECONDS
1202 def test_pull(self
):
1204 self
.client
.pull('joffrey/test001')
1205 except Exception as e
:
1206 self
.fail('Command should not raise exception: {0}'.format(e
))
1208 args
= fake_request
.call_args
1211 url_prefix
+ 'images/create'
1215 {'tag': None, 'fromImage': 'joffrey/test001'}
1217 self
.assertFalse(args
[1]['stream'])
1219 def test_pull_stream(self
):
1221 self
.client
.pull('joffrey/test001', stream
=True)
1222 except Exception as e
:
1223 self
.fail('Command should not raise exception: {0}'.format(e
))
1225 args
= fake_request
.call_args
1228 url_prefix
+ 'images/create'
1232 {'tag': None, 'fromImage': 'joffrey/test001'}
1234 self
.assertTrue(args
[1]['stream'])
1236 def test_commit(self
):
1238 self
.client
.commit(fake_api
.FAKE_CONTAINER_ID
)
1239 except Exception as e
:
1240 self
.fail('Command should not raise exception: {0}'.format(e
))
1242 fake_request
.assert_called_with(
1243 url_prefix
+ 'commit',
1245 headers
={'Content-Type': 'application/json'},
1250 'container': '3cc2351ab11b',
1253 timeout
=docker
.client
.DEFAULT_TIMEOUT_SECONDS
1256 def test_remove_image(self
):
1258 self
.client
.remove_image(fake_api
.FAKE_IMAGE_ID
)
1259 except Exception as e
:
1260 self
.fail('Command should not raise exception: {0}'.format(e
))
1262 fake_request
.assert_called_with(
1263 url_prefix
+ 'images/e9aa60c60128',
1264 params
={'force': False, 'noprune': False},
1265 timeout
=docker
.client
.DEFAULT_TIMEOUT_SECONDS
1268 def test_image_history(self
):
1270 self
.client
.history(fake_api
.FAKE_IMAGE_NAME
)
1271 except Exception as e
:
1272 self
.fail('Command should not raise exception: {0}'.format(e
))
1274 fake_request
.assert_called_with(
1275 url_prefix
+ 'images/test_image/history',
1276 timeout
=docker
.client
.DEFAULT_TIMEOUT_SECONDS
1279 def test_import_image(self
):
1281 self
.client
.import_image(
1282 fake_api
.FAKE_TARBALL_PATH
,
1283 repository
=fake_api
.FAKE_REPO_NAME
,
1284 tag
=fake_api
.FAKE_TAG_NAME
1286 except Exception as e
:
1287 self
.fail('Command should not raise exception: {0}'.format(e
))
1289 fake_request
.assert_called_with(
1290 url_prefix
+ 'images/create',
1292 'repo': fake_api
.FAKE_REPO_NAME
,
1293 'tag': fake_api
.FAKE_TAG_NAME
,
1294 'fromSrc': fake_api
.FAKE_TARBALL_PATH
1297 timeout
=docker
.client
.DEFAULT_TIMEOUT_SECONDS
1300 def test_import_image_from_file(self
):
1301 buf
= tempfile
.NamedTemporaryFile(delete
=False)
1303 # pretent the buffer is a file
1304 self
.client
.import_image(
1306 repository
=fake_api
.FAKE_REPO_NAME
,
1307 tag
=fake_api
.FAKE_TAG_NAME
1309 except Exception as e
:
1310 self
.fail('Command should not raise exception: {0}'.format(e
))
1312 fake_request
.assert_called_with(
1313 url_prefix
+ 'images/create',
1315 'repo': fake_api
.FAKE_REPO_NAME
,
1316 'tag': fake_api
.FAKE_TAG_NAME
,
1320 timeout
=docker
.client
.DEFAULT_TIMEOUT_SECONDS
1325 def test_import_image_from_image(self
):
1327 self
.client
.import_image(
1328 image
=fake_api
.FAKE_IMAGE_NAME
,
1329 repository
=fake_api
.FAKE_REPO_NAME
,
1330 tag
=fake_api
.FAKE_TAG_NAME
1332 except Exception as e
:
1333 self
.fail('Command should not raise exception: {0}'.format(e
))
1335 fake_request
.assert_called_with(
1336 url_prefix
+ 'images/create',
1338 'repo': fake_api
.FAKE_REPO_NAME
,
1339 'tag': fake_api
.FAKE_TAG_NAME
,
1340 'fromImage': fake_api
.FAKE_IMAGE_NAME
1343 timeout
=docker
.client
.DEFAULT_TIMEOUT_SECONDS
1346 def test_inspect_image(self
):
1348 self
.client
.inspect_image(fake_api
.FAKE_IMAGE_NAME
)
1349 except Exception as e
:
1350 self
.fail('Command should not raise exception: {0}'.format(e
))
1352 fake_request
.assert_called_with(
1353 url_prefix
+ 'images/test_image/json',
1354 timeout
=docker
.client
.DEFAULT_TIMEOUT_SECONDS
1357 def test_insert_image(self
):
1359 self
.client
.insert(fake_api
.FAKE_IMAGE_NAME
,
1360 fake_api
.FAKE_URL
, fake_api
.FAKE_PATH
)
1361 except docker
.errors
.DeprecatedMethod
as e
:
1363 docker
.utils
.compare_version('1.12', self
.client
._version
) >= 0
1366 except Exception as e
:
1367 self
.fail('Command should not raise exception: {0}'.format(e
))
1369 fake_request
.assert_called_with(
1370 url_prefix
+ 'images/test_image/insert',
1372 'url': fake_api
.FAKE_URL
,
1373 'path': fake_api
.FAKE_PATH
1375 timeout
=docker
.client
.DEFAULT_TIMEOUT_SECONDS
1378 def test_push_image(self
):
1380 with mock
.patch('docker.auth.auth.resolve_authconfig',
1381 fake_resolve_authconfig
):
1382 self
.client
.push(fake_api
.FAKE_IMAGE_NAME
)
1383 except Exception as e
:
1384 self
.fail('Command should not raise exception: {0}'.format(e
))
1386 fake_request
.assert_called_with(
1387 url_prefix
+ 'images/test_image/push',
1392 headers
={'Content-Type': 'application/json'},
1394 timeout
=docker
.client
.DEFAULT_TIMEOUT_SECONDS
1397 def test_push_image_with_tag(self
):
1399 with mock
.patch('docker.auth.auth.resolve_authconfig',
1400 fake_resolve_authconfig
):
1402 fake_api
.FAKE_IMAGE_NAME
, tag
=fake_api
.FAKE_TAG_NAME
1404 except Exception as e
:
1405 self
.fail('Command should not raise exception: {0}'.format(e
))
1407 fake_request
.assert_called_with(
1408 url_prefix
+ 'images/test_image/push',
1410 'tag': fake_api
.FAKE_TAG_NAME
,
1413 headers
={'Content-Type': 'application/json'},
1415 timeout
=docker
.client
.DEFAULT_TIMEOUT_SECONDS
1418 def test_push_image_stream(self
):
1420 with mock
.patch('docker.auth.auth.resolve_authconfig',
1421 fake_resolve_authconfig
):
1422 self
.client
.push(fake_api
.FAKE_IMAGE_NAME
, stream
=True)
1423 except Exception as e
:
1424 self
.fail('Command should not raise exception: {0}'.format(e
))
1426 fake_request
.assert_called_with(
1427 url_prefix
+ 'images/test_image/push',
1432 headers
={'Content-Type': 'application/json'},
1434 timeout
=docker
.client
.DEFAULT_TIMEOUT_SECONDS
1437 def test_tag_image(self
):
1439 self
.client
.tag(fake_api
.FAKE_IMAGE_ID
, fake_api
.FAKE_REPO_NAME
)
1440 except Exception as e
:
1441 self
.fail('Command should not raise exception: {0}'.format(e
))
1443 fake_request
.assert_called_with(
1444 url_prefix
+ 'images/e9aa60c60128/tag',
1450 timeout
=docker
.client
.DEFAULT_TIMEOUT_SECONDS
1453 def test_tag_image_tag(self
):
1456 fake_api
.FAKE_IMAGE_ID
,
1457 fake_api
.FAKE_REPO_NAME
,
1458 tag
=fake_api
.FAKE_TAG_NAME
1460 except Exception as e
:
1461 self
.fail('Command should not raise exception: {0}'.format(e
))
1463 fake_request
.assert_called_with(
1464 url_prefix
+ 'images/e9aa60c60128/tag',
1470 timeout
=docker
.client
.DEFAULT_TIMEOUT_SECONDS
1473 def test_tag_image_force(self
):
1476 fake_api
.FAKE_IMAGE_ID
, fake_api
.FAKE_REPO_NAME
, force
=True)
1477 except Exception as e
:
1478 self
.fail('Command should not raise exception: {0}'.format(e
))
1480 fake_request
.assert_called_with(
1481 url_prefix
+ 'images/e9aa60c60128/tag',
1487 timeout
=docker
.client
.DEFAULT_TIMEOUT_SECONDS
1490 def test_get_image(self
):
1492 self
.client
.get_image(fake_api
.FAKE_IMAGE_ID
)
1493 except Exception as e
:
1494 self
.fail('Command should not raise exception: {0}'.format(e
))
1496 fake_request
.assert_called_with(
1497 url_prefix
+ 'images/e9aa60c60128/get',
1499 timeout
=docker
.client
.DEFAULT_TIMEOUT_SECONDS
1502 def test_load_image(self
):
1504 self
.client
.load_image('Byte Stream....')
1505 except Exception as e
:
1506 self
.fail('Command should not raise exception: {0}'.format(e
))
1508 fake_request
.assert_called_with(
1509 url_prefix
+ 'images/load',
1510 data
='Byte Stream....',
1511 timeout
=docker
.client
.DEFAULT_TIMEOUT_SECONDS
1518 def test_build_container(self
):
1519 script
= io
.BytesIO('\n'.join([
1521 'MAINTAINER docker-py',
1522 'RUN mkdir -p /tmp/test',
1524 'ADD https://dl.dropboxusercontent.com/u/20637798/silence.tar.gz'
1525 ' /tmp/silence.tar.gz'
1528 self
.client
.build(fileobj
=script
)
1529 except Exception as e
:
1530 self
.fail('Command should not raise exception: {0}'.format(e
))
1532 def test_build_container_stream(self
):
1533 script
= io
.BytesIO('\n'.join([
1535 'MAINTAINER docker-py',
1536 'RUN mkdir -p /tmp/test',
1538 'ADD https://dl.dropboxusercontent.com/u/20637798/silence.tar.gz'
1539 ' /tmp/silence.tar.gz'
1542 self
.client
.build(fileobj
=script
, stream
=True)
1543 except Exception as e
:
1544 self
.fail('Command should not raise exception: {0}'.format(e
))
1546 def test_build_container_custom_context(self
):
1547 script
= io
.BytesIO('\n'.join([
1549 'MAINTAINER docker-py',
1550 'RUN mkdir -p /tmp/test',
1552 'ADD https://dl.dropboxusercontent.com/u/20637798/silence.tar.gz'
1553 ' /tmp/silence.tar.gz'
1555 context
= docker
.utils
.mkbuildcontext(script
)
1557 self
.client
.build(fileobj
=context
, custom_context
=True)
1558 except Exception as e
:
1559 self
.fail('Command should not raise exception: {0}'.format(e
))
1561 def test_build_container_custom_context_gzip(self
):
1562 script
= io
.BytesIO('\n'.join([
1564 'MAINTAINER docker-py',
1565 'RUN mkdir -p /tmp/test',
1567 'ADD https://dl.dropboxusercontent.com/u/20637798/silence.tar.gz'
1568 ' /tmp/silence.tar.gz'
1570 context
= docker
.utils
.mkbuildcontext(script
)
1571 gz_context
= gzip
.GzipFile(fileobj
=context
)
1575 custom_context
=True,
1578 except Exception as e
:
1579 self
.fail('Command should not raise exception: {0}'.format(e
))
1581 #######################
1582 # PY SPECIFIC TESTS #
1583 #######################
1585 def test_load_config_no_file(self
):
1586 folder
= tempfile
.mkdtemp()
1587 self
.addCleanup(shutil
.rmtree
, folder
)
1588 cfg
= docker
.auth
.load_config(folder
)
1589 self
.assertTrue(cfg
is not None)
1591 def test_load_config(self
):
1592 folder
= tempfile
.mkdtemp()
1593 self
.addCleanup(shutil
.rmtree
, folder
)
1594 f
= open(os
.path
.join(folder
, '.dockercfg'), 'w')
1595 auth_
= base64
.b64encode(b
'sakuya:izayoi').decode('ascii')
1596 f
.write('auth = {0}\n'.format(auth_
))
1597 f
.write('email = sakuya@scarlet.net')
1599 cfg
= docker
.auth
.load_config(folder
)
1600 self
.assertTrue(docker
.auth
.INDEX_URL
in cfg
)
1601 self
.assertNotEqual(cfg
[docker
.auth
.INDEX_URL
], None)
1602 cfg
= cfg
[docker
.auth
.INDEX_URL
]
1603 self
.assertEqual(cfg
['username'], 'sakuya')
1604 self
.assertEqual(cfg
['password'], 'izayoi')
1605 self
.assertEqual(cfg
['email'], 'sakuya@scarlet.net')
1606 self
.assertEqual(cfg
.get('auth'), None)
1608 def test_tar_with_excludes(self
):
1609 base
= tempfile
.mkdtemp()
1610 self
.addCleanup(shutil
.rmtree
, base
)
1611 for d
in ['test/foo', 'bar']:
1612 os
.makedirs(os
.path
.join(base
, d
))
1613 for f
in ['a.txt', 'b.py', 'other.png']:
1614 with
open(os
.path
.join(base
, d
, f
), 'w') as f
:
1617 for exclude
, names
in (
1618 (['*.py'], ['bar/a.txt', 'bar/other.png',
1619 'test/foo/a.txt', 'test/foo/other.png']),
1620 (['*.png', 'bar'], ['test/foo/a.txt', 'test/foo/b.py']),
1621 (['test/foo', 'a.txt'], ['bar/a.txt', 'bar/b.py',
1624 archive
= docker
.utils
.tar(base
, exclude
=exclude
)
1625 tar
= tarfile
.open(fileobj
=archive
)
1626 self
.assertEqual(sorted(tar
.getnames()), names
)
1629 if __name__
== '__main__':