project_test.py 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316
  1. from __future__ import unicode_literals
  2. import docker
  3. from .. import mock
  4. from .. import unittest
  5. from compose.const import LABEL_SERVICE
  6. from compose.container import Container
  7. from compose.project import Project
  8. from compose.service import ContainerNet
  9. from compose.service import Net
  10. from compose.service import Service
  11. class ProjectTest(unittest.TestCase):
  12. def setUp(self):
  13. self.mock_client = mock.create_autospec(docker.Client)
  14. def test_from_dict(self):
  15. project = Project.from_dicts('composetest', [
  16. {
  17. 'name': 'web',
  18. 'image': 'busybox:latest'
  19. },
  20. {
  21. 'name': 'db',
  22. 'image': 'busybox:latest'
  23. },
  24. ], None)
  25. self.assertEqual(len(project.services), 2)
  26. self.assertEqual(project.get_service('web').name, 'web')
  27. self.assertEqual(project.get_service('web').options['image'], 'busybox:latest')
  28. self.assertEqual(project.get_service('db').name, 'db')
  29. self.assertEqual(project.get_service('db').options['image'], 'busybox:latest')
  30. def test_from_dict_sorts_in_dependency_order(self):
  31. project = Project.from_dicts('composetest', [
  32. {
  33. 'name': 'web',
  34. 'image': 'busybox:latest',
  35. 'links': ['db'],
  36. },
  37. {
  38. 'name': 'db',
  39. 'image': 'busybox:latest',
  40. 'volumes_from': ['volume']
  41. },
  42. {
  43. 'name': 'volume',
  44. 'image': 'busybox:latest',
  45. 'volumes': ['/tmp'],
  46. }
  47. ], None)
  48. self.assertEqual(project.services[0].name, 'volume')
  49. self.assertEqual(project.services[1].name, 'db')
  50. self.assertEqual(project.services[2].name, 'web')
  51. def test_from_config(self):
  52. dicts = [
  53. {
  54. 'name': 'web',
  55. 'image': 'busybox:latest',
  56. },
  57. {
  58. 'name': 'db',
  59. 'image': 'busybox:latest',
  60. },
  61. ]
  62. project = Project.from_dicts('composetest', dicts, None)
  63. self.assertEqual(len(project.services), 2)
  64. self.assertEqual(project.get_service('web').name, 'web')
  65. self.assertEqual(project.get_service('web').options['image'], 'busybox:latest')
  66. self.assertEqual(project.get_service('db').name, 'db')
  67. self.assertEqual(project.get_service('db').options['image'], 'busybox:latest')
  68. def test_get_service(self):
  69. web = Service(
  70. project='composetest',
  71. name='web',
  72. client=None,
  73. image="busybox:latest",
  74. )
  75. project = Project('test', [web], None)
  76. self.assertEqual(project.get_service('web'), web)
  77. def test_get_services_returns_all_services_without_args(self):
  78. web = Service(
  79. project='composetest',
  80. name='web',
  81. image='foo',
  82. )
  83. console = Service(
  84. project='composetest',
  85. name='console',
  86. image='foo',
  87. )
  88. project = Project('test', [web, console], None)
  89. self.assertEqual(project.get_services(), [web, console])
  90. def test_get_services_returns_listed_services_with_args(self):
  91. web = Service(
  92. project='composetest',
  93. name='web',
  94. image='foo',
  95. )
  96. console = Service(
  97. project='composetest',
  98. name='console',
  99. image='foo',
  100. )
  101. project = Project('test', [web, console], None)
  102. self.assertEqual(project.get_services(['console']), [console])
  103. def test_get_services_with_include_links(self):
  104. db = Service(
  105. project='composetest',
  106. name='db',
  107. image='foo',
  108. )
  109. web = Service(
  110. project='composetest',
  111. name='web',
  112. image='foo',
  113. links=[(db, 'database')]
  114. )
  115. cache = Service(
  116. project='composetest',
  117. name='cache',
  118. image='foo'
  119. )
  120. console = Service(
  121. project='composetest',
  122. name='console',
  123. image='foo',
  124. links=[(web, 'web')]
  125. )
  126. project = Project('test', [web, db, cache, console], None)
  127. self.assertEqual(
  128. project.get_services(['console'], include_deps=True),
  129. [db, web, console]
  130. )
  131. def test_get_services_removes_duplicates_following_links(self):
  132. db = Service(
  133. project='composetest',
  134. name='db',
  135. image='foo',
  136. )
  137. web = Service(
  138. project='composetest',
  139. name='web',
  140. image='foo',
  141. links=[(db, 'database')]
  142. )
  143. project = Project('test', [web, db], None)
  144. self.assertEqual(
  145. project.get_services(['web', 'db'], include_deps=True),
  146. [db, web]
  147. )
  148. def test_use_volumes_from_container(self):
  149. container_id = 'aabbccddee'
  150. container_dict = dict(Name='aaa', Id=container_id)
  151. self.mock_client.inspect_container.return_value = container_dict
  152. project = Project.from_dicts('test', [
  153. {
  154. 'name': 'test',
  155. 'image': 'busybox:latest',
  156. 'volumes_from': ['aaa']
  157. }
  158. ], self.mock_client)
  159. self.assertEqual(project.get_service('test')._get_volumes_from(), [container_id + ":rw"])
  160. def test_use_volumes_from_service_no_container(self):
  161. container_name = 'test_vol_1'
  162. self.mock_client.containers.return_value = [
  163. {
  164. "Name": container_name,
  165. "Names": [container_name],
  166. "Id": container_name,
  167. "Image": 'busybox:latest'
  168. }
  169. ]
  170. project = Project.from_dicts('test', [
  171. {
  172. 'name': 'vol',
  173. 'image': 'busybox:latest'
  174. },
  175. {
  176. 'name': 'test',
  177. 'image': 'busybox:latest',
  178. 'volumes_from': ['vol']
  179. }
  180. ], self.mock_client)
  181. self.assertEqual(project.get_service('test')._get_volumes_from(), [container_name + ":rw"])
  182. @mock.patch.object(Service, 'containers')
  183. def test_use_volumes_from_service_container(self, mock_return):
  184. container_ids = ['aabbccddee', '12345']
  185. mock_return.return_value = [
  186. mock.Mock(id=container_id, spec=Container)
  187. for container_id in container_ids]
  188. project = Project.from_dicts('test', [
  189. {
  190. 'name': 'vol',
  191. 'image': 'busybox:latest'
  192. },
  193. {
  194. 'name': 'test',
  195. 'image': 'busybox:latest',
  196. 'volumes_from': ['vol']
  197. }
  198. ], None)
  199. self.assertEqual(project.get_service('test')._get_volumes_from(), [container_ids[0] + ':rw'])
  200. def test_net_unset(self):
  201. project = Project.from_dicts('test', [
  202. {
  203. 'name': 'test',
  204. 'image': 'busybox:latest',
  205. }
  206. ], self.mock_client)
  207. service = project.get_service('test')
  208. self.assertEqual(service.net.id, None)
  209. self.assertNotIn('NetworkMode', service._get_container_host_config({}))
  210. def test_use_net_from_container(self):
  211. container_id = 'aabbccddee'
  212. container_dict = dict(Name='aaa', Id=container_id)
  213. self.mock_client.inspect_container.return_value = container_dict
  214. project = Project.from_dicts('test', [
  215. {
  216. 'name': 'test',
  217. 'image': 'busybox:latest',
  218. 'net': 'container:aaa'
  219. }
  220. ], self.mock_client)
  221. service = project.get_service('test')
  222. self.assertEqual(service.net.mode, 'container:' + container_id)
  223. def test_use_net_from_service(self):
  224. container_name = 'test_aaa_1'
  225. self.mock_client.containers.return_value = [
  226. {
  227. "Name": container_name,
  228. "Names": [container_name],
  229. "Id": container_name,
  230. "Image": 'busybox:latest'
  231. }
  232. ]
  233. project = Project.from_dicts('test', [
  234. {
  235. 'name': 'aaa',
  236. 'image': 'busybox:latest'
  237. },
  238. {
  239. 'name': 'test',
  240. 'image': 'busybox:latest',
  241. 'net': 'container:aaa'
  242. }
  243. ], self.mock_client)
  244. service = project.get_service('test')
  245. self.assertEqual(service.net.mode, 'container:' + container_name)
  246. def test_uses_default_network_true(self):
  247. web = Service('web', project='test', image="alpine", net=Net('test'))
  248. db = Service('web', project='test', image="alpine", net=Net('other'))
  249. project = Project('test', [web, db], None)
  250. assert project.uses_default_network()
  251. def test_uses_default_network_custom_name(self):
  252. web = Service('web', project='test', image="alpine", net=Net('other'))
  253. project = Project('test', [web], None)
  254. assert not project.uses_default_network()
  255. def test_uses_default_network_host(self):
  256. web = Service('web', project='test', image="alpine", net=Net('host'))
  257. project = Project('test', [web], None)
  258. assert not project.uses_default_network()
  259. def test_uses_default_network_container(self):
  260. container = mock.Mock(id='test')
  261. web = Service(
  262. 'web',
  263. project='test',
  264. image="alpine",
  265. net=ContainerNet(container))
  266. project = Project('test', [web], None)
  267. assert not project.uses_default_network()
  268. def test_container_without_name(self):
  269. self.mock_client.containers.return_value = [
  270. {'Image': 'busybox:latest', 'Id': '1', 'Name': '1'},
  271. {'Image': 'busybox:latest', 'Id': '2', 'Name': None},
  272. {'Image': 'busybox:latest', 'Id': '3'},
  273. ]
  274. self.mock_client.inspect_container.return_value = {
  275. 'Id': '1',
  276. 'Config': {
  277. 'Labels': {
  278. LABEL_SERVICE: 'web',
  279. },
  280. },
  281. }
  282. project = Project.from_dicts(
  283. 'test',
  284. [{
  285. 'name': 'web',
  286. 'image': 'busybox:latest',
  287. }],
  288. self.mock_client,
  289. )
  290. self.assertEqual([c.id for c in project.containers()], ['1'])