OpenStack Dashboard (Horizon)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

tests.py 41KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903
  1. # Copyright 2012 NEC Corporation
  2. #
  3. # Licensed under the Apache License, Version 2.0 (the "License"); you may
  4. # not use this file except in compliance with the License. You may obtain
  5. # a copy of the License at
  6. #
  7. # http://www.apache.org/licenses/LICENSE-2.0
  8. #
  9. # Unless required by applicable law or agreed to in writing, software
  10. # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
  11. # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
  12. # License for the specific language governing permissions and limitations
  13. # under the License.
  14. from django.core.urlresolvers import reverse
  15. from django import http
  16. from django.utils.http import urlunquote
  17. from mox3.mox import IsA
  18. from horizon import forms
  19. from openstack_dashboard import api
  20. from openstack_dashboard.dashboards.project.networks import tests
  21. from openstack_dashboard.test import helpers as test
  22. from openstack_dashboard import usage
  23. INDEX_TEMPLATE = 'horizon/common/_data_table_view.html'
  24. INDEX_URL = reverse('horizon:admin:networks:index')
  25. class NetworkTests(test.BaseAdminViewTests):
  26. @test.create_stubs({api.neutron: ('network_list',
  27. 'list_dhcp_agent_hosting_networks',
  28. 'is_extension_supported'),
  29. api.keystone: ('tenant_list',),
  30. usage.quotas: ('tenant_quota_usages',)})
  31. def test_index(self):
  32. tenants = self.tenants.list()
  33. quota_data = self.quota_usages.first()
  34. api.neutron.network_list(IsA(http.HttpRequest)) \
  35. .AndReturn(self.networks.list())
  36. api.keystone.tenant_list(IsA(http.HttpRequest))\
  37. .AndReturn([tenants, False])
  38. api.neutron.is_extension_supported(
  39. IsA(http.HttpRequest),
  40. 'network_availability_zone').AndReturn(True)
  41. for network in self.networks.list():
  42. usage.quotas.tenant_quota_usages(
  43. IsA(http.HttpRequest), tenant_id=network.tenant_id,
  44. targets=('subnets', )).AndReturn(quota_data)
  45. api.neutron.list_dhcp_agent_hosting_networks(IsA(http.HttpRequest),
  46. network.id)\
  47. .AndReturn(self.agents.list())
  48. api.neutron.is_extension_supported(
  49. IsA(http.HttpRequest),
  50. 'dhcp_agent_scheduler').AndReturn(True)
  51. api.neutron.is_extension_supported(
  52. IsA(http.HttpRequest),
  53. 'dhcp_agent_scheduler').AndReturn(True)
  54. self.mox.ReplayAll()
  55. res = self.client.get(INDEX_URL)
  56. self.assertTemplateUsed(res, INDEX_TEMPLATE)
  57. networks = res.context['networks_table'].data
  58. self.assertItemsEqual(networks, self.networks.list())
  59. @test.create_stubs({api.neutron: ('network_list',
  60. 'is_extension_supported',)})
  61. def test_index_network_list_exception(self):
  62. api.neutron.network_list(IsA(http.HttpRequest)) \
  63. .AndRaise(self.exceptions.neutron)
  64. api.neutron.is_extension_supported(
  65. IsA(http.HttpRequest),
  66. 'network_availability_zone').AndReturn(True)
  67. api.neutron.is_extension_supported(
  68. IsA(http.HttpRequest),
  69. 'dhcp_agent_scheduler').AndReturn(True)
  70. self.mox.ReplayAll()
  71. res = self.client.get(INDEX_URL)
  72. self.assertTemplateUsed(res, INDEX_TEMPLATE)
  73. self.assertEqual(len(res.context['networks_table'].data), 0)
  74. self.assertMessageCount(res, error=1)
  75. @test.create_stubs({api.neutron: ('network_get',
  76. 'subnet_list',
  77. 'port_list',
  78. 'show_network_ip_availability',
  79. 'list_dhcp_agent_hosting_networks',
  80. 'is_extension_supported'),
  81. usage.quotas: ('tenant_quota_usages',)})
  82. def test_network_detail_subnets_tab(self):
  83. self._test_network_detail_subnets_tab()
  84. @test.create_stubs({api.neutron: ('network_get',
  85. 'subnet_list',
  86. 'port_list',
  87. 'is_extension_supported',
  88. 'show_network_ip_availability',
  89. 'list_dhcp_agent_hosting_networks',),
  90. usage.quotas: ('tenant_quota_usages',)})
  91. def test_network_detail_subnets_tab_with_mac_learning(self):
  92. self._test_network_detail_subnets_tab(mac_learning=True)
  93. @test.create_stubs({api.neutron: ('network_get',
  94. 'is_extension_supported'),
  95. usage.quotas: ('tenant_quota_usages',)})
  96. def test_network_detail_new(self, mac_learning=False):
  97. network = self.networks.first()
  98. quota_data = self.quota_usages.first()
  99. api.neutron.network_get(IsA(http.HttpRequest), network.id) \
  100. .MultipleTimes().AndReturn(self.networks.first())
  101. api.neutron.is_extension_supported(IsA(http.HttpRequest),
  102. 'network-ip-availability') \
  103. .AndReturn(True)
  104. api.neutron.is_extension_supported(IsA(http.HttpRequest),
  105. 'mac-learning') \
  106. .AndReturn(mac_learning)
  107. api.neutron.is_extension_supported(
  108. IsA(http.HttpRequest),
  109. 'network_availability_zone').AndReturn(True)
  110. api.neutron.is_extension_supported(
  111. IsA(http.HttpRequest),
  112. 'dhcp_agent_scheduler').AndReturn(True)
  113. usage.quotas.tenant_quota_usages(
  114. IsA(http.HttpRequest), tenant_id=network.tenant_id,
  115. targets=('subnets',)).MultipleTimes().AndReturn(quota_data)
  116. self.mox.ReplayAll()
  117. url = urlunquote(reverse('horizon:admin:networks:detail',
  118. args=[network.id]))
  119. res = self.client.get(url)
  120. network = res.context['network']
  121. self.assertEqual(self.networks.first().name_or_id, network.name_or_id)
  122. self.assertEqual(self.networks.first().status_label,
  123. network.status_label)
  124. self.assertTemplateUsed(res, 'horizon/common/_detail.html')
  125. def _test_network_detail_subnets_tab(self, mac_learning=False):
  126. network = self.networks.first()
  127. ip_availability = self.ip_availability.get()
  128. quota_data = self.quota_usages.first()
  129. api.neutron.show_network_ip_availability(IsA(http.HttpRequest),
  130. network.id).\
  131. MultipleTimes().AndReturn(ip_availability)
  132. api.neutron.network_get(IsA(http.HttpRequest), network.id)\
  133. .MultipleTimes().AndReturn(self.networks.first())
  134. api.neutron.subnet_list(IsA(http.HttpRequest), network_id=network.id)\
  135. .AndReturn([self.subnets.first()])
  136. api.neutron.is_extension_supported(
  137. IsA(http.HttpRequest),
  138. 'network-ip-availability').AndReturn(True)
  139. api.neutron.is_extension_supported(IsA(http.HttpRequest),
  140. 'mac-learning')\
  141. .AndReturn(mac_learning)
  142. api.neutron.is_extension_supported(
  143. IsA(http.HttpRequest),
  144. 'network-ip-availability').AndReturn(True)
  145. api.neutron.is_extension_supported(
  146. IsA(http.HttpRequest),
  147. 'network_availability_zone').AndReturn(True)
  148. api.neutron.is_extension_supported(
  149. IsA(http.HttpRequest),
  150. 'dhcp_agent_scheduler').AndReturn(True)
  151. usage.quotas.tenant_quota_usages(
  152. IsA(http.HttpRequest), tenant_id=network.tenant_id,
  153. targets=('subnets',)).MultipleTimes().AndReturn(quota_data)
  154. self.mox.ReplayAll()
  155. url = urlunquote(reverse('horizon:admin:networks:subnets_tab',
  156. args=[network.id]))
  157. res = self.client.get(url)
  158. self.assertTemplateUsed(res, 'horizon/common/_detail.html')
  159. subnets = res.context['subnets_table'].data
  160. self.assertItemsEqual(subnets, [self.subnets.first()])
  161. @test.create_stubs({api.neutron: ('network_get',
  162. 'subnet_list',
  163. 'port_list',
  164. 'is_extension_supported',
  165. 'list_dhcp_agent_hosting_networks',),
  166. usage.quotas: ('tenant_quota_usages',)})
  167. def test_network_detail_ports_tab(self, mac_learning=False):
  168. network = self.networks.first()
  169. api.neutron.network_get(IsA(http.HttpRequest), network.id)\
  170. .MultipleTimes().AndReturn(self.networks.first())
  171. api.neutron.port_list(IsA(http.HttpRequest), network_id=network.id)\
  172. .AndReturn([self.ports.first()])
  173. quota_data = self.neutron_quota_usages.first()
  174. usage.quotas.tenant_quota_usages(
  175. IsA(http.HttpRequest), tenant_id=network.tenant_id,
  176. targets=('ports',)).MultipleTimes().AndReturn(quota_data)
  177. api.neutron.is_extension_supported(
  178. IsA(http.HttpRequest),
  179. 'network-ip-availability').AndReturn(True)
  180. api.neutron.is_extension_supported(IsA(http.HttpRequest),
  181. 'mac-learning')\
  182. .AndReturn(mac_learning)
  183. api.neutron.is_extension_supported(
  184. IsA(http.HttpRequest),
  185. 'network_availability_zone').AndReturn(True)
  186. api.neutron.is_extension_supported(
  187. IsA(http.HttpRequest),
  188. 'dhcp_agent_scheduler').AndReturn(True)
  189. usage.quotas.tenant_quota_usages(
  190. IsA(http.HttpRequest), tenant_id=network.tenant_id,
  191. targets=('subnets',)).MultipleTimes().AndReturn(quota_data)
  192. self.mox.ReplayAll()
  193. url = reverse('horizon:admin:networks:ports_tab',
  194. args=[network.id])
  195. res = self.client.get(urlunquote(url))
  196. self.assertTemplateUsed(res, 'horizon/common/_detail.html')
  197. ports = res.context['ports_table'].data
  198. self.assertItemsEqual(ports, [self.ports.first()])
  199. @test.create_stubs({api.neutron: ('network_get',
  200. 'subnet_list',
  201. 'port_list',
  202. 'is_extension_supported',
  203. 'list_dhcp_agent_hosting_networks',),
  204. usage.quotas: ('tenant_quota_usages',)})
  205. def test_network_detail_agents_tab(self, mac_learning=False):
  206. network = self.networks.first()
  207. quota_data = self.quota_usages.first()
  208. api.neutron.is_extension_supported(IsA(http.HttpRequest),
  209. 'network-ip-availability') \
  210. .AndReturn(True)
  211. api.neutron.is_extension_supported(IsA(http.HttpRequest),
  212. 'mac-learning')\
  213. .AndReturn(mac_learning)
  214. api.neutron.list_dhcp_agent_hosting_networks(IsA(http.HttpRequest),
  215. network.id)\
  216. .AndReturn(self.agents.list())
  217. api.neutron.network_get(IsA(http.HttpRequest), network.id)\
  218. .MultipleTimes().AndReturn(self.networks.first())
  219. api.neutron.is_extension_supported(
  220. IsA(http.HttpRequest),
  221. 'dhcp_agent_scheduler').AndReturn(True)
  222. api.neutron.is_extension_supported(
  223. IsA(http.HttpRequest),
  224. 'network_availability_zone').AndReturn(True)
  225. api.neutron.is_extension_supported(
  226. IsA(http.HttpRequest),
  227. 'dhcp_agent_scheduler').AndReturn(True)
  228. usage.quotas.tenant_quota_usages(
  229. IsA(http.HttpRequest), tenant_id=network.tenant_id,
  230. targets=('subnets',)).MultipleTimes().AndReturn(quota_data)
  231. self.mox.ReplayAll()
  232. url = reverse('horizon:admin:networks:agents_tab', args=[network.id])
  233. res = self.client.get(urlunquote(url))
  234. self.assertTemplateUsed(res, 'horizon/common/_detail.html')
  235. result_agents = res.context['agents_table'].data
  236. expected_agents = self.agents.list()
  237. self.assertItemsEqual(result_agents, expected_agents)
  238. @test.create_stubs({api.neutron: ('network_get',
  239. 'subnet_list',
  240. 'port_list',
  241. 'is_extension_supported',
  242. 'show_network_ip_availability',
  243. 'list_dhcp_agent_hosting_networks',)})
  244. def test_network_detail_subnets_tab_network_exception(self):
  245. self._test_network_detail_subnets_tab_network_exception()
  246. @test.create_stubs({api.neutron: ('network_get',
  247. 'subnet_list',
  248. 'port_list',
  249. 'is_extension_supported',
  250. 'show_network_ip_availability',
  251. 'list_dhcp_agent_hosting_networks',)})
  252. def test_network_detail_network_exception_with_mac_learning(self):
  253. self._test_network_detail_subnets_tab_network_exception(
  254. mac_learning=True)
  255. def _test_network_detail_subnets_tab_network_exception(self,
  256. mac_learning=False):
  257. network_id = self.networks.first().id
  258. ip_availability = self.ip_availability.get()
  259. api.neutron.show_network_ip_availability(IsA(http.HttpRequest),
  260. network_id).\
  261. MultipleTimes().AndReturn(ip_availability)
  262. api.neutron.network_get(IsA(http.HttpRequest), network_id)\
  263. .AndRaise(self.exceptions.neutron)
  264. api.neutron.subnet_list(IsA(http.HttpRequest), network_id=network_id)\
  265. .AndReturn([self.subnets.first()])
  266. api.neutron.is_extension_supported(
  267. IsA(http.HttpRequest),
  268. 'network-ip-availability').AndReturn(True)
  269. api.neutron.is_extension_supported(IsA(http.HttpRequest),
  270. 'mac-learning')\
  271. .AndReturn(mac_learning)
  272. api.neutron.is_extension_supported(
  273. IsA(http.HttpRequest),
  274. 'network-ip-availability').AndReturn(True)
  275. self.mox.ReplayAll()
  276. url = urlunquote(reverse('horizon:admin:networks:subnets_tab',
  277. args=[network_id]))
  278. res = self.client.get(url)
  279. redir_url = INDEX_URL
  280. self.assertRedirectsNoFollow(res, redir_url)
  281. @test.create_stubs({api.neutron: ('network_get',
  282. 'subnet_list',
  283. 'port_list',
  284. 'list_dhcp_agent_hosting_networks',
  285. 'is_extension_supported'),
  286. usage.quotas: ('tenant_quota_usages',)})
  287. def test_network_detail_subnets_tab_subnet_exception(self):
  288. self._test_network_detail_subnets_tab_subnet_exception()
  289. @test.create_stubs({api.neutron: ('network_get',
  290. 'subnet_list',
  291. 'port_list',
  292. 'is_extension_supported',
  293. 'list_dhcp_agent_hosting_networks',),
  294. usage.quotas: ('tenant_quota_usages',)})
  295. def test_network_detail_subnets_tab_subnet_exception_w_mac_learning(self):
  296. self._test_network_detail_subnets_tab_subnet_exception(
  297. mac_learning=True)
  298. def _test_network_detail_subnets_tab_subnet_exception(self,
  299. mac_learning=False):
  300. network = self.networks.first()
  301. quota_data = self.quota_usages.first()
  302. api.neutron.network_get(IsA(http.HttpRequest), network.id)\
  303. .MultipleTimes().AndReturn(self.networks.first())
  304. api.neutron.subnet_list(IsA(http.HttpRequest), network_id=network.id).\
  305. AndRaise(self.exceptions.neutron)
  306. api.neutron.is_extension_supported(
  307. IsA(http.HttpRequest),
  308. 'network-ip-availability').AndReturn(True)
  309. api.neutron.is_extension_supported(IsA(http.HttpRequest),
  310. 'mac-learning')\
  311. .AndReturn(mac_learning)
  312. api.neutron.is_extension_supported(
  313. IsA(http.HttpRequest),
  314. 'dhcp_agent_scheduler').AndReturn(True)
  315. api.neutron.is_extension_supported(
  316. IsA(http.HttpRequest),
  317. 'network_availability_zone').AndReturn(True)
  318. api.neutron.is_extension_supported(
  319. IsA(http.HttpRequest),
  320. 'dhcp_agent_scheduler').AndReturn(True)
  321. usage.quotas.tenant_quota_usages(
  322. IsA(http.HttpRequest), tenant_id=network.tenant_id,
  323. targets=('subnets',)).MultipleTimes().AndReturn(quota_data)
  324. self.mox.ReplayAll()
  325. url = urlunquote(reverse('horizon:admin:networks:subnets_tab',
  326. args=[network.id]))
  327. res = self.client.get(url)
  328. self.assertTemplateUsed(res, 'horizon/common/_detail.html')
  329. subnets = res.context['subnets_table'].data
  330. self.assertEqual(len(subnets), 0)
  331. @test.create_stubs({api.neutron: ('network_get',
  332. 'subnet_list',
  333. 'port_list',
  334. 'is_extension_supported',
  335. 'show_network_ip_availability',
  336. 'list_dhcp_agent_hosting_networks',),
  337. usage.quotas: ('tenant_quota_usages',)})
  338. def test_network_detail_port_exception(self):
  339. self._test_network_detail_subnets_tab_port_exception()
  340. @test.create_stubs({api.neutron: ('network_get',
  341. 'subnet_list',
  342. 'port_list',
  343. 'is_extension_supported',
  344. 'show_network_ip_availability',
  345. 'list_dhcp_agent_hosting_networks',),
  346. usage.quotas: ('tenant_quota_usages',)})
  347. def test_network_detail_subnets_tab_port_exception_with_mac_learning(self):
  348. self._test_network_detail_subnets_tab_port_exception(mac_learning=True)
  349. def _test_network_detail_subnets_tab_port_exception(self,
  350. mac_learning=False):
  351. network = self.networks.first()
  352. ip_availability = self.ip_availability.get()
  353. quota_data = self.quota_usages.first()
  354. api.neutron.show_network_ip_availability(IsA(http.HttpRequest),
  355. network.id). \
  356. MultipleTimes().AndReturn(ip_availability)
  357. api.neutron.network_get(IsA(http.HttpRequest), network.id)\
  358. .MultipleTimes().AndReturn(self.networks.first())
  359. api.neutron.subnet_list(IsA(http.HttpRequest), network_id=network.id).\
  360. AndReturn([self.subnets.first()])
  361. api.neutron.is_extension_supported(
  362. IsA(http.HttpRequest),
  363. 'network-ip-availability').AndReturn(True)
  364. api.neutron.is_extension_supported(IsA(http.HttpRequest),
  365. 'mac-learning')\
  366. .AndReturn(mac_learning)
  367. api.neutron.is_extension_supported(
  368. IsA(http.HttpRequest),
  369. 'network-ip-availability').AndReturn(True)
  370. api.neutron.is_extension_supported(
  371. IsA(http.HttpRequest),
  372. 'network_availability_zone').AndReturn(True)
  373. api.neutron.is_extension_supported(IsA(http.HttpRequest),
  374. 'dhcp_agent_scheduler')\
  375. .AndReturn(True)
  376. usage.quotas.tenant_quota_usages(
  377. IsA(http.HttpRequest), tenant_id=network.tenant_id,
  378. targets=('subnets',)).MultipleTimes().AndReturn(quota_data)
  379. self.mox.ReplayAll()
  380. url = urlunquote(reverse('horizon:admin:networks:subnets_tab',
  381. args=[network.id]))
  382. res = self.client.get(url)
  383. self.assertTemplateUsed(res, 'horizon/common/_detail.html')
  384. subnets = res.context['subnets_table'].data
  385. self.assertItemsEqual(subnets, [self.subnets.first()])
  386. @test.create_stubs({api.neutron: ('is_extension_supported',),
  387. api.keystone: ('tenant_list',)})
  388. def test_network_create_get(self):
  389. tenants = self.tenants.list()
  390. api.keystone.tenant_list(IsA(
  391. http.HttpRequest)).AndReturn([tenants, False])
  392. api.neutron.is_extension_supported(IsA(http.HttpRequest), 'provider').\
  393. AndReturn(True)
  394. self.mox.ReplayAll()
  395. url = reverse('horizon:admin:networks:create')
  396. res = self.client.get(url)
  397. self.assertTemplateUsed(res, 'horizon/common/_workflow_base.html')
  398. @test.create_stubs({api.neutron: ('network_create',
  399. 'is_extension_supported',
  400. 'subnetpool_list'),
  401. api.keystone: ('tenant_list',)})
  402. def test_network_create_post(self):
  403. tenants = self.tenants.list()
  404. tenant_id = self.tenants.first().id
  405. network = self.networks.first()
  406. api.keystone.tenant_list(IsA(http.HttpRequest))\
  407. .AndReturn([tenants, False])
  408. params = {'name': network.name,
  409. 'tenant_id': tenant_id,
  410. 'admin_state_up': network.admin_state_up,
  411. 'router:external': True,
  412. 'shared': True,
  413. 'provider:network_type': 'local',
  414. 'with_subnet': False}
  415. api.neutron.is_extension_supported(IsA(http.HttpRequest), 'provider').\
  416. MultipleTimes().AndReturn(True)
  417. api.neutron.is_extension_supported(IsA(http.HttpRequest),
  418. 'subnet_allocation').\
  419. MultipleTimes().AndReturn(True)
  420. api.neutron.subnetpool_list(IsA(http.HttpRequest)).\
  421. AndReturn(self.subnetpools.list())
  422. api.neutron.network_create(IsA(http.HttpRequest), **params)\
  423. .AndReturn(network)
  424. self.mox.ReplayAll()
  425. form_data = {'tenant_id': tenant_id,
  426. 'name': network.name,
  427. 'admin_state': network.admin_state_up,
  428. 'external': True,
  429. 'shared': True,
  430. 'network_type': 'local'}
  431. url = reverse('horizon:admin:networks:create')
  432. res = self.client.post(url, form_data)
  433. self.assertNoFormErrors(res)
  434. self.assertRedirectsNoFollow(res, INDEX_URL)
  435. @test.create_stubs({api.neutron: ('network_create',
  436. 'subnet_create',
  437. 'is_extension_supported',
  438. 'subnetpool_list'),
  439. api.keystone: ('tenant_list',)})
  440. def test_network_create_post_with_subnet(self):
  441. tenants = self.tenants.list()
  442. tenant_id = self.tenants.first().id
  443. network = self.networks.first()
  444. subnet = self.subnets.first()
  445. params = {'name': network.name,
  446. 'tenant_id': tenant_id,
  447. 'admin_state_up': network.admin_state_up,
  448. 'router:external': True,
  449. 'shared': True,
  450. 'provider:network_type': 'local',
  451. 'with_subnet': True}
  452. api.keystone.tenant_list(IsA(http.HttpRequest))\
  453. .AndReturn([tenants, False])
  454. api.neutron.is_extension_supported(IsA(http.HttpRequest), 'provider').\
  455. MultipleTimes().AndReturn(True)
  456. api.neutron.is_extension_supported(IsA(http.HttpRequest),
  457. 'subnet_allocation').\
  458. MultipleTimes().AndReturn(True)
  459. api.neutron.subnetpool_list(IsA(http.HttpRequest)).\
  460. AndReturn(self.subnetpools.list())
  461. api.neutron.network_create(IsA(http.HttpRequest), **params)\
  462. .AndReturn(network)
  463. self.mox.ReplayAll()
  464. form_data = {'tenant_id': tenant_id,
  465. 'name': network.name,
  466. 'admin_state': network.admin_state_up,
  467. 'external': True,
  468. 'shared': True,
  469. 'network_type': 'local',
  470. 'with_subnet': True}
  471. form_data.update(tests.form_data_subnet(subnet, allocation_pools=[]))
  472. url = reverse('horizon:admin:networks:create')
  473. res = self.client.post(url, form_data)
  474. self.assertNoFormErrors(res)
  475. self.assertRedirectsNoFollow(res, INDEX_URL)
  476. @test.create_stubs({api.neutron: ('network_create',
  477. 'is_extension_supported',
  478. 'subnetpool_list'),
  479. api.keystone: ('tenant_list',)})
  480. def test_network_create_post_network_exception(self):
  481. tenants = self.tenants.list()
  482. tenant_id = self.tenants.first().id
  483. network = self.networks.first()
  484. api.keystone.tenant_list(IsA(http.HttpRequest)).AndReturn([tenants,
  485. False])
  486. params = {'name': network.name,
  487. 'tenant_id': tenant_id,
  488. 'admin_state_up': network.admin_state_up,
  489. 'router:external': True,
  490. 'shared': False,
  491. 'provider:network_type': 'local',
  492. 'with_subnet': False}
  493. api.neutron.is_extension_supported(IsA(http.HttpRequest), 'provider').\
  494. MultipleTimes().AndReturn(True)
  495. api.neutron.is_extension_supported(IsA(http.HttpRequest),
  496. 'subnet_allocation').\
  497. MultipleTimes().AndReturn(True)
  498. api.neutron.subnetpool_list(IsA(http.HttpRequest)).\
  499. AndReturn(self.subnetpools.list())
  500. api.neutron.network_create(IsA(http.HttpRequest),
  501. **params).AndRaise(self.exceptions.neutron)
  502. self.mox.ReplayAll()
  503. form_data = {'tenant_id': tenant_id,
  504. 'name': network.name,
  505. 'admin_state': network.admin_state_up,
  506. 'external': True,
  507. 'shared': False,
  508. 'network_type': 'local'}
  509. url = reverse('horizon:admin:networks:create')
  510. res = self.client.post(url, form_data)
  511. self.assertNoFormErrors(res)
  512. self.assertRedirectsNoFollow(res, INDEX_URL)
  513. @test.create_stubs({api.neutron: ('is_extension_supported',),
  514. api.keystone: ('tenant_list',)})
  515. def test_network_create_vlan_segmentation_id_invalid(self):
  516. tenants = self.tenants.list()
  517. tenant_id = self.tenants.first().id
  518. network = self.networks.first()
  519. api.keystone.tenant_list(
  520. IsA(http.HttpRequest)
  521. ).MultipleTimes().AndReturn([tenants, False])
  522. api.neutron.is_extension_supported(IsA(http.HttpRequest), 'provider')\
  523. .MultipleTimes().AndReturn(True)
  524. self.mox.ReplayAll()
  525. form_data = {'tenant_id': tenant_id,
  526. 'name': network.name,
  527. 'admin_state': network.admin_state_up,
  528. 'external': True,
  529. 'shared': False,
  530. 'network_type': 'vlan',
  531. 'physical_network': 'default',
  532. 'segmentation_id': 4095}
  533. url = reverse('horizon:admin:networks:create')
  534. res = self.client.post(url, form_data)
  535. self.assertFormErrors(res, 1)
  536. self.assertContains(res, "1 through 4094")
  537. @test.create_stubs({api.neutron: ('is_extension_supported',),
  538. api.keystone: ('tenant_list',)})
  539. def test_network_create_gre_segmentation_id_invalid(self):
  540. tenants = self.tenants.list()
  541. tenant_id = self.tenants.first().id
  542. network = self.networks.first()
  543. api.keystone.tenant_list(
  544. IsA(http.HttpRequest)
  545. ).MultipleTimes().AndReturn([tenants, False])
  546. api.neutron.is_extension_supported(IsA(http.HttpRequest), 'provider').\
  547. MultipleTimes().AndReturn(True)
  548. self.mox.ReplayAll()
  549. form_data = {'tenant_id': tenant_id,
  550. 'name': network.name,
  551. 'admin_state': network.admin_state_up,
  552. 'external': True,
  553. 'shared': False,
  554. 'network_type': 'gre',
  555. 'physical_network': 'default',
  556. 'segmentation_id': (2 ** 32) + 1}
  557. url = reverse('horizon:admin:networks:create')
  558. res = self.client.post(url, form_data)
  559. self.assertFormErrors(res, 1)
  560. self.assertContains(res, "1 through %s" % ((2 ** 32) - 1))
  561. @test.create_stubs({api.neutron: ('is_extension_supported',),
  562. api.keystone: ('tenant_list',)})
  563. @test.update_settings(
  564. OPENSTACK_NEUTRON_NETWORK={
  565. 'segmentation_id_range': {'vxlan': [10, 20]}})
  566. def test_network_create_vxlan_segmentation_id_custom(self):
  567. tenants = self.tenants.list()
  568. tenant_id = self.tenants.first().id
  569. network = self.networks.first()
  570. api.keystone.tenant_list(
  571. IsA(http.HttpRequest)
  572. ).MultipleTimes().AndReturn([tenants, False])
  573. api.neutron.is_extension_supported(IsA(http.HttpRequest), 'provider')\
  574. .MultipleTimes().AndReturn(True)
  575. self.mox.ReplayAll()
  576. form_data = {'tenant_id': tenant_id,
  577. 'name': network.name,
  578. 'admin_state': network.admin_state_up,
  579. 'external': True,
  580. 'shared': False,
  581. 'network_type': 'vxlan',
  582. 'physical_network': 'default',
  583. 'segmentation_id': 9}
  584. url = reverse('horizon:admin:networks:create')
  585. res = self.client.post(url, form_data)
  586. self.assertFormErrors(res, 1)
  587. self.assertContains(res, "10 through 20")
  588. @test.create_stubs({api.neutron: ('is_extension_supported',),
  589. api.keystone: ('tenant_list',)})
  590. @test.update_settings(
  591. OPENSTACK_NEUTRON_NETWORK={
  592. 'supported_provider_types': []})
  593. def test_network_create_no_provider_types(self):
  594. tenants = self.tenants.list()
  595. api.keystone.tenant_list(IsA(http.HttpRequest)).AndReturn([tenants,
  596. False])
  597. api.neutron.is_extension_supported(IsA(http.HttpRequest), 'provider').\
  598. AndReturn(True)
  599. self.mox.ReplayAll()
  600. url = reverse('horizon:admin:networks:create')
  601. res = self.client.get(url)
  602. self.assertTemplateUsed(res, 'horizon/common/_workflow_base.html')
  603. self.assertContains(
  604. res,
  605. '<input type="hidden" name="network_type" id="id_network_type" />',
  606. html=True)
  607. @test.create_stubs({api.neutron: ('is_extension_supported',),
  608. api.keystone: ('tenant_list',)})
  609. @test.update_settings(
  610. OPENSTACK_NEUTRON_NETWORK={
  611. 'supported_provider_types': ['local', 'flat', 'gre']})
  612. def test_network_create_unsupported_provider_types(self):
  613. tenants = self.tenants.list()
  614. api.keystone.tenant_list(IsA(http.HttpRequest)).AndReturn([tenants,
  615. False])
  616. api.neutron.is_extension_supported(IsA(http.HttpRequest), 'provider').\
  617. AndReturn(True)
  618. self.mox.ReplayAll()
  619. url = reverse('horizon:admin:networks:create')
  620. res = self.client.get(url)
  621. self.assertTemplateUsed(res, 'horizon/common/_workflow_base.html')
  622. network_type = res.context['form'].fields['network_type']
  623. self.assertListEqual(list(network_type.choices), [('local', 'Local'),
  624. ('flat', 'Flat'),
  625. ('gre', 'GRE')])
  626. @test.create_stubs({api.neutron: ('network_get',)})
  627. def test_network_update_get(self):
  628. network = self.networks.first()
  629. api.neutron.network_get(IsA(http.HttpRequest), network.id,
  630. expand_subnet=False).AndReturn(network)
  631. self.mox.ReplayAll()
  632. url = reverse('horizon:admin:networks:update', args=[network.id])
  633. res = self.client.get(url)
  634. self.assertTemplateUsed(res, 'admin/networks/update.html')
  635. @test.create_stubs({api.neutron: ('network_get',)})
  636. def test_network_update_get_exception(self):
  637. network = self.networks.first()
  638. api.neutron.network_get(IsA(http.HttpRequest), network.id)\
  639. .AndRaise(self.exceptions.neutron)
  640. self.mox.ReplayAll()
  641. url = reverse('horizon:admin:networks:update', args=[network.id])
  642. res = self.client.get(url)
  643. redir_url = INDEX_URL
  644. self.assertRedirectsNoFollow(res, redir_url)
  645. @test.create_stubs({api.neutron: ('network_update',
  646. 'network_get',)})
  647. def test_network_update_post(self):
  648. network = self.networks.first()
  649. params = {'name': network.name,
  650. 'shared': True,
  651. 'admin_state_up': network.admin_state_up,
  652. 'router:external': True}
  653. api.neutron.network_update(IsA(http.HttpRequest), network.id,
  654. **params)\
  655. .AndReturn(network)
  656. api.neutron.network_get(IsA(http.HttpRequest), network.id,
  657. expand_subnet=False).AndReturn(network)
  658. self.mox.ReplayAll()
  659. form_data = {'network_id': network.id,
  660. 'name': network.name,
  661. 'tenant_id': network.tenant_id,
  662. 'admin_state': network.admin_state_up,
  663. 'shared': True,
  664. 'external': True}
  665. url = reverse('horizon:admin:networks:update', args=[network.id])
  666. res = self.client.post(url, form_data)
  667. self.assertRedirectsNoFollow(res, INDEX_URL)
  668. @test.create_stubs({api.neutron: ('network_update',
  669. 'network_get',)})
  670. def test_network_update_post_exception(self):
  671. network = self.networks.first()
  672. params = {'name': network.name,
  673. 'shared': False,
  674. 'admin_state_up': network.admin_state_up,
  675. 'router:external': False}
  676. api.neutron.network_update(IsA(http.HttpRequest), network.id,
  677. **params)\
  678. .AndRaise(self.exceptions.neutron)
  679. api.neutron.network_get(IsA(http.HttpRequest), network.id,
  680. expand_subnet=False).AndReturn(network)
  681. self.mox.ReplayAll()
  682. form_data = {'network_id': network.id,
  683. 'name': network.name,
  684. 'tenant_id': network.tenant_id,
  685. 'admin_state': network.admin_state_up,
  686. 'shared': False,
  687. 'external': False}
  688. url = reverse('horizon:admin:networks:update', args=[network.id])
  689. res = self.client.post(url, form_data)
  690. self.assertRedirectsNoFollow(res, INDEX_URL)
  691. @test.create_stubs({api.neutron: ('network_list',
  692. 'network_delete',
  693. 'list_dhcp_agent_hosting_networks',
  694. 'is_extension_supported'),
  695. api.keystone: ('tenant_list',)})
  696. def test_delete_network(self):
  697. tenants = self.tenants.list()
  698. network = self.networks.first()
  699. api.neutron.list_dhcp_agent_hosting_networks(IsA(http.HttpRequest),
  700. network.id).\
  701. AndReturn(self.agents.list())
  702. api.neutron.is_extension_supported(
  703. IsA(http.HttpRequest),
  704. 'network_availability_zone').AndReturn(True)
  705. api.neutron.is_extension_supported(
  706. IsA(http.HttpRequest),
  707. 'dhcp_agent_scheduler').AndReturn(True)
  708. api.neutron.is_extension_supported(
  709. IsA(http.HttpRequest),
  710. 'dhcp_agent_scheduler').AndReturn(True)
  711. api.keystone.tenant_list(IsA(http.HttpRequest))\
  712. .AndReturn([tenants, False])
  713. api.neutron.network_list(IsA(http.HttpRequest))\
  714. .AndReturn([network])
  715. api.neutron.network_delete(IsA(http.HttpRequest), network.id)
  716. self.mox.ReplayAll()
  717. form_data = {'action': 'networks__delete__%s' % network.id}
  718. res = self.client.post(INDEX_URL, form_data)
  719. self.assertRedirectsNoFollow(res, INDEX_URL)
  720. @test.create_stubs({api.neutron: ('network_list',
  721. 'network_delete',
  722. 'list_dhcp_agent_hosting_networks',
  723. 'is_extension_supported'),
  724. api.keystone: ('tenant_list',)})
  725. def test_delete_network_exception(self):
  726. tenants = self.tenants.list()
  727. network = self.networks.first()
  728. api.neutron.list_dhcp_agent_hosting_networks(IsA(http.HttpRequest),
  729. network.id).\
  730. AndReturn(self.agents.list())
  731. api.neutron.is_extension_supported(
  732. IsA(http.HttpRequest),
  733. 'network_availability_zone').AndReturn(True)
  734. api.neutron.is_extension_supported(
  735. IsA(http.HttpRequest),
  736. 'dhcp_agent_scheduler').AndReturn(True)
  737. api.neutron.is_extension_supported(
  738. IsA(http.HttpRequest),
  739. 'dhcp_agent_scheduler').AndReturn(True)
  740. api.keystone.tenant_list(IsA(http.HttpRequest))\
  741. .AndReturn([tenants, False])
  742. api.neutron.network_list(IsA(http.HttpRequest))\
  743. .AndReturn([network])
  744. api.neutron.network_delete(IsA(http.HttpRequest), network.id)\
  745. .AndRaise(self.exceptions.neutron)
  746. self.mox.ReplayAll()
  747. form_data = {'action': 'networks__delete__%s' % network.id}
  748. res = self.client.post(INDEX_URL, form_data)
  749. self.assertRedirectsNoFollow(res, INDEX_URL)
  750. @test.create_stubs({api.neutron: ('is_extension_supported',)})
  751. @test.update_settings(FILTER_DATA_FIRST={'admin.networks': True})
  752. def test_networks_list_with_admin_filter_first(self):
  753. api.neutron.is_extension_supported(
  754. IsA(http.HttpRequest),
  755. 'network_availability_zone').AndReturn(True)
  756. api.neutron.is_extension_supported(
  757. IsA(http.HttpRequest),
  758. 'dhcp_agent_scheduler').AndReturn(True)
  759. self.mox.ReplayAll()
  760. res = self.client.get(reverse('horizon:admin:networks:index'))
  761. self.assertTemplateUsed(res, INDEX_TEMPLATE)
  762. networks = res.context['networks_table'].data
  763. self.assertItemsEqual(networks, [])
  764. @test.create_stubs({api.neutron: ('is_extension_supported',),
  765. api.keystone: ('tenant_list',)})
  766. def test_network_create_without_physical_networks(self):
  767. tenants = self.tenants.list()
  768. api.keystone.tenant_list(IsA(http.HttpRequest)).AndReturn([tenants,
  769. False])
  770. api.neutron.is_extension_supported(IsA(http.HttpRequest), 'provider').\
  771. AndReturn(True)
  772. self.mox.ReplayAll()
  773. url = reverse('horizon:admin:networks:create')
  774. res = self.client.get(url)
  775. physical_network = res.context['form'].fields['physical_network']
  776. self.assertEqual(type(physical_network), forms.CharField)
  777. @test.create_stubs({api.neutron: ('is_extension_supported',),
  778. api.keystone: ('tenant_list',)})
  779. @test.update_settings(
  780. OPENSTACK_NEUTRON_NETWORK={
  781. 'physical_networks': ['default', 'test']})
  782. def test_network_create_with_physical_networks(self):
  783. tenants = self.tenants.list()
  784. api.keystone.tenant_list(IsA(http.HttpRequest)).AndReturn([tenants,
  785. False])
  786. api.neutron.is_extension_supported(IsA(http.HttpRequest), 'provider').\
  787. AndReturn(True)
  788. self.mox.ReplayAll()
  789. url = reverse('horizon:admin:networks:create')
  790. res = self.client.get(url)
  791. physical_network = res.context['form'].fields['physical_network']
  792. self.assertEqual(type(physical_network), forms.ThemableChoiceField)
  793. self.assertListEqual(list(physical_network.choices),
  794. [('default', 'default'), ('test', 'test')])