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 44KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972
  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. 'network_availability_zone').\
  419. MultipleTimes().AndReturn(False)
  420. api.neutron.is_extension_supported(IsA(http.HttpRequest),
  421. 'subnet_allocation').\
  422. MultipleTimes().AndReturn(True)
  423. api.neutron.subnetpool_list(IsA(http.HttpRequest)).\
  424. AndReturn(self.subnetpools.list())
  425. api.neutron.network_create(IsA(http.HttpRequest), **params)\
  426. .AndReturn(network)
  427. self.mox.ReplayAll()
  428. form_data = {'tenant_id': tenant_id,
  429. 'name': network.name,
  430. 'admin_state': network.admin_state_up,
  431. 'external': True,
  432. 'shared': True,
  433. 'network_type': 'local'}
  434. url = reverse('horizon:admin:networks:create')
  435. res = self.client.post(url, form_data)
  436. self.assertNoFormErrors(res)
  437. self.assertRedirectsNoFollow(res, INDEX_URL)
  438. @test.create_stubs({api.neutron: ('network_create',
  439. 'is_extension_supported',
  440. 'list_availability_zones',
  441. 'subnetpool_list'),
  442. api.keystone: ('tenant_list',)})
  443. def test_network_create_post_with_az(self):
  444. tenants = self.tenants.list()
  445. tenant_id = self.tenants.first().id
  446. network = self.networks.first()
  447. api.keystone.tenant_list(IsA(http.HttpRequest))\
  448. .AndReturn([tenants, False])
  449. params = {'name': network.name,
  450. 'tenant_id': tenant_id,
  451. 'admin_state_up': network.admin_state_up,
  452. 'router:external': True,
  453. 'shared': True,
  454. 'provider:network_type': 'local',
  455. 'with_subnet': False,
  456. 'az_hints': ['nova']}
  457. api.neutron.is_extension_supported(IsA(http.HttpRequest), 'provider').\
  458. MultipleTimes().AndReturn(True)
  459. api.neutron.is_extension_supported(IsA(http.HttpRequest),
  460. 'network_availability_zone').\
  461. MultipleTimes().AndReturn(True)
  462. api.neutron.list_availability_zones(IsA(http.HttpRequest),
  463. "network", "available")\
  464. .AndReturn(self.neutron_availability_zones.list())
  465. api.neutron.is_extension_supported(IsA(http.HttpRequest),
  466. 'subnet_allocation').\
  467. MultipleTimes().AndReturn(True)
  468. api.neutron.subnetpool_list(IsA(http.HttpRequest)).\
  469. AndReturn(self.subnetpools.list())
  470. api.neutron.network_create(IsA(http.HttpRequest), **params)\
  471. .AndReturn(network)
  472. self.mox.ReplayAll()
  473. form_data = {'tenant_id': tenant_id,
  474. 'name': network.name,
  475. 'admin_state': network.admin_state_up,
  476. 'external': True,
  477. 'shared': True,
  478. 'network_type': 'local',
  479. 'availability_zone_hints': ['nova']}
  480. url = reverse('horizon:admin:networks:create')
  481. res = self.client.post(url, form_data)
  482. self.assertNoFormErrors(res)
  483. self.assertRedirectsNoFollow(res, INDEX_URL)
  484. @test.create_stubs({api.neutron: ('network_create',
  485. 'subnet_create',
  486. 'is_extension_supported',
  487. 'subnetpool_list'),
  488. api.keystone: ('tenant_list',)})
  489. def test_network_create_post_with_subnet(self):
  490. tenants = self.tenants.list()
  491. tenant_id = self.tenants.first().id
  492. network = self.networks.first()
  493. subnet = self.subnets.first()
  494. params = {'name': network.name,
  495. 'tenant_id': tenant_id,
  496. 'admin_state_up': network.admin_state_up,
  497. 'router:external': True,
  498. 'shared': True,
  499. 'provider:network_type': 'local',
  500. 'with_subnet': True}
  501. api.keystone.tenant_list(IsA(http.HttpRequest))\
  502. .AndReturn([tenants, False])
  503. api.neutron.is_extension_supported(IsA(http.HttpRequest), 'provider').\
  504. MultipleTimes().AndReturn(True)
  505. api.neutron.is_extension_supported(IsA(http.HttpRequest),
  506. 'network_availability_zone').\
  507. MultipleTimes().AndReturn(False)
  508. api.neutron.is_extension_supported(IsA(http.HttpRequest),
  509. 'subnet_allocation').\
  510. MultipleTimes().AndReturn(True)
  511. api.neutron.subnetpool_list(IsA(http.HttpRequest)).\
  512. AndReturn(self.subnetpools.list())
  513. api.neutron.network_create(IsA(http.HttpRequest), **params)\
  514. .AndReturn(network)
  515. self.mox.ReplayAll()
  516. form_data = {'tenant_id': tenant_id,
  517. 'name': network.name,
  518. 'admin_state': network.admin_state_up,
  519. 'external': True,
  520. 'shared': True,
  521. 'network_type': 'local',
  522. 'with_subnet': True}
  523. form_data.update(tests.form_data_subnet(subnet, allocation_pools=[]))
  524. url = reverse('horizon:admin:networks:create')
  525. res = self.client.post(url, form_data)
  526. self.assertNoFormErrors(res)
  527. self.assertRedirectsNoFollow(res, INDEX_URL)
  528. @test.create_stubs({api.neutron: ('network_create',
  529. 'is_extension_supported',
  530. 'subnetpool_list'),
  531. api.keystone: ('tenant_list',)})
  532. def test_network_create_post_network_exception(self):
  533. tenants = self.tenants.list()
  534. tenant_id = self.tenants.first().id
  535. network = self.networks.first()
  536. api.keystone.tenant_list(IsA(http.HttpRequest)).AndReturn([tenants,
  537. False])
  538. params = {'name': network.name,
  539. 'tenant_id': tenant_id,
  540. 'admin_state_up': network.admin_state_up,
  541. 'router:external': True,
  542. 'shared': False,
  543. 'provider:network_type': 'local',
  544. 'with_subnet': False}
  545. api.neutron.is_extension_supported(IsA(http.HttpRequest), 'provider').\
  546. MultipleTimes().AndReturn(True)
  547. api.neutron.is_extension_supported(IsA(http.HttpRequest),
  548. 'network_availability_zone').\
  549. MultipleTimes().AndReturn(False)
  550. api.neutron.is_extension_supported(IsA(http.HttpRequest),
  551. 'subnet_allocation').\
  552. MultipleTimes().AndReturn(True)
  553. api.neutron.subnetpool_list(IsA(http.HttpRequest)).\
  554. AndReturn(self.subnetpools.list())
  555. api.neutron.network_create(IsA(http.HttpRequest),
  556. **params).AndRaise(self.exceptions.neutron)
  557. self.mox.ReplayAll()
  558. form_data = {'tenant_id': tenant_id,
  559. 'name': network.name,
  560. 'admin_state': network.admin_state_up,
  561. 'external': True,
  562. 'shared': False,
  563. 'network_type': 'local'}
  564. url = reverse('horizon:admin:networks:create')
  565. res = self.client.post(url, form_data)
  566. self.assertNoFormErrors(res)
  567. self.assertRedirectsNoFollow(res, INDEX_URL)
  568. @test.create_stubs({api.neutron: ('is_extension_supported',),
  569. api.keystone: ('tenant_list',)})
  570. def test_network_create_vlan_segmentation_id_invalid(self):
  571. tenants = self.tenants.list()
  572. tenant_id = self.tenants.first().id
  573. network = self.networks.first()
  574. api.keystone.tenant_list(
  575. IsA(http.HttpRequest)
  576. ).MultipleTimes().AndReturn([tenants, False])
  577. api.neutron.is_extension_supported(IsA(http.HttpRequest),
  578. 'network_availability_zone').\
  579. MultipleTimes().AndReturn(False)
  580. api.neutron.is_extension_supported(IsA(http.HttpRequest), 'provider')\
  581. .MultipleTimes().AndReturn(True)
  582. self.mox.ReplayAll()
  583. form_data = {'tenant_id': tenant_id,
  584. 'name': network.name,
  585. 'admin_state': network.admin_state_up,
  586. 'external': True,
  587. 'shared': False,
  588. 'network_type': 'vlan',
  589. 'physical_network': 'default',
  590. 'segmentation_id': 4095}
  591. url = reverse('horizon:admin:networks:create')
  592. res = self.client.post(url, form_data)
  593. self.assertFormErrors(res, 1)
  594. self.assertContains(res, "1 through 4094")
  595. @test.create_stubs({api.neutron: ('is_extension_supported',),
  596. api.keystone: ('tenant_list',)})
  597. def test_network_create_gre_segmentation_id_invalid(self):
  598. tenants = self.tenants.list()
  599. tenant_id = self.tenants.first().id
  600. network = self.networks.first()
  601. api.keystone.tenant_list(
  602. IsA(http.HttpRequest)
  603. ).MultipleTimes().AndReturn([tenants, False])
  604. api.neutron.is_extension_supported(IsA(http.HttpRequest),
  605. 'network_availability_zone').\
  606. MultipleTimes().AndReturn(False)
  607. api.neutron.is_extension_supported(IsA(http.HttpRequest), 'provider').\
  608. MultipleTimes().AndReturn(True)
  609. self.mox.ReplayAll()
  610. form_data = {'tenant_id': tenant_id,
  611. 'name': network.name,
  612. 'admin_state': network.admin_state_up,
  613. 'external': True,
  614. 'shared': False,
  615. 'network_type': 'gre',
  616. 'physical_network': 'default',
  617. 'segmentation_id': (2 ** 32) + 1}
  618. url = reverse('horizon:admin:networks:create')
  619. res = self.client.post(url, form_data)
  620. self.assertFormErrors(res, 1)
  621. self.assertContains(res, "1 through %s" % ((2 ** 32) - 1))
  622. @test.create_stubs({api.neutron: ('is_extension_supported',),
  623. api.keystone: ('tenant_list',)})
  624. @test.update_settings(
  625. OPENSTACK_NEUTRON_NETWORK={
  626. 'segmentation_id_range': {'vxlan': [10, 20]}})
  627. def test_network_create_vxlan_segmentation_id_custom(self):
  628. tenants = self.tenants.list()
  629. tenant_id = self.tenants.first().id
  630. network = self.networks.first()
  631. api.keystone.tenant_list(
  632. IsA(http.HttpRequest)
  633. ).MultipleTimes().AndReturn([tenants, False])
  634. api.neutron.is_extension_supported(IsA(http.HttpRequest),
  635. 'network_availability_zone').\
  636. MultipleTimes().AndReturn(False)
  637. api.neutron.is_extension_supported(IsA(http.HttpRequest), 'provider')\
  638. .MultipleTimes().AndReturn(True)
  639. self.mox.ReplayAll()
  640. form_data = {'tenant_id': tenant_id,
  641. 'name': network.name,
  642. 'admin_state': network.admin_state_up,
  643. 'external': True,
  644. 'shared': False,
  645. 'network_type': 'vxlan',
  646. 'physical_network': 'default',
  647. 'segmentation_id': 9}
  648. url = reverse('horizon:admin:networks:create')
  649. res = self.client.post(url, form_data)
  650. self.assertFormErrors(res, 1)
  651. self.assertContains(res, "10 through 20")
  652. @test.create_stubs({api.neutron: ('is_extension_supported',),
  653. api.keystone: ('tenant_list',)})
  654. @test.update_settings(
  655. OPENSTACK_NEUTRON_NETWORK={
  656. 'supported_provider_types': []})
  657. def test_network_create_no_provider_types(self):
  658. tenants = self.tenants.list()
  659. api.keystone.tenant_list(IsA(http.HttpRequest)).AndReturn([tenants,
  660. False])
  661. api.neutron.is_extension_supported(IsA(http.HttpRequest), 'provider').\
  662. AndReturn(True)
  663. self.mox.ReplayAll()
  664. url = reverse('horizon:admin:networks:create')
  665. res = self.client.get(url)
  666. self.assertTemplateUsed(res, 'horizon/common/_workflow_base.html')
  667. self.assertContains(
  668. res,
  669. '<input type="hidden" name="network_type" id="id_network_type" />',
  670. html=True)
  671. @test.create_stubs({api.neutron: ('is_extension_supported',),
  672. api.keystone: ('tenant_list',)})
  673. @test.update_settings(
  674. OPENSTACK_NEUTRON_NETWORK={
  675. 'supported_provider_types': ['local', 'flat', 'gre']})
  676. def test_network_create_unsupported_provider_types(self):
  677. tenants = self.tenants.list()
  678. api.keystone.tenant_list(IsA(http.HttpRequest)).AndReturn([tenants,
  679. False])
  680. api.neutron.is_extension_supported(IsA(http.HttpRequest), 'provider').\
  681. AndReturn(True)
  682. self.mox.ReplayAll()
  683. url = reverse('horizon:admin:networks:create')
  684. res = self.client.get(url)
  685. self.assertTemplateUsed(res, 'horizon/common/_workflow_base.html')
  686. network_type = res.context['form'].fields['network_type']
  687. self.assertListEqual(list(network_type.choices), [('local', 'Local'),
  688. ('flat', 'Flat'),
  689. ('gre', 'GRE')])
  690. @test.create_stubs({api.neutron: ('network_get',)})
  691. def test_network_update_get(self):
  692. network = self.networks.first()
  693. api.neutron.network_get(IsA(http.HttpRequest), network.id,
  694. expand_subnet=False).AndReturn(network)
  695. self.mox.ReplayAll()
  696. url = reverse('horizon:admin:networks:update', args=[network.id])
  697. res = self.client.get(url)
  698. self.assertTemplateUsed(res, 'admin/networks/update.html')
  699. @test.create_stubs({api.neutron: ('network_get',)})
  700. def test_network_update_get_exception(self):
  701. network = self.networks.first()
  702. api.neutron.network_get(IsA(http.HttpRequest), network.id)\
  703. .AndRaise(self.exceptions.neutron)
  704. self.mox.ReplayAll()
  705. url = reverse('horizon:admin:networks:update', args=[network.id])
  706. res = self.client.get(url)
  707. redir_url = INDEX_URL
  708. self.assertRedirectsNoFollow(res, redir_url)
  709. @test.create_stubs({api.neutron: ('network_update',
  710. 'network_get',)})
  711. def test_network_update_post(self):
  712. network = self.networks.first()
  713. params = {'name': network.name,
  714. 'shared': True,
  715. 'admin_state_up': network.admin_state_up,
  716. 'router:external': True}
  717. api.neutron.network_update(IsA(http.HttpRequest), network.id,
  718. **params)\
  719. .AndReturn(network)
  720. api.neutron.network_get(IsA(http.HttpRequest), network.id,
  721. expand_subnet=False).AndReturn(network)
  722. self.mox.ReplayAll()
  723. form_data = {'network_id': network.id,
  724. 'name': network.name,
  725. 'tenant_id': network.tenant_id,
  726. 'admin_state': network.admin_state_up,
  727. 'shared': True,
  728. 'external': True}
  729. url = reverse('horizon:admin:networks:update', args=[network.id])
  730. res = self.client.post(url, form_data)
  731. self.assertRedirectsNoFollow(res, INDEX_URL)
  732. @test.create_stubs({api.neutron: ('network_update',
  733. 'network_get',)})
  734. def test_network_update_post_exception(self):
  735. network = self.networks.first()
  736. params = {'name': network.name,
  737. 'shared': False,
  738. 'admin_state_up': network.admin_state_up,
  739. 'router:external': False}
  740. api.neutron.network_update(IsA(http.HttpRequest), network.id,
  741. **params)\
  742. .AndRaise(self.exceptions.neutron)
  743. api.neutron.network_get(IsA(http.HttpRequest), network.id,
  744. expand_subnet=False).AndReturn(network)
  745. self.mox.ReplayAll()
  746. form_data = {'network_id': network.id,
  747. 'name': network.name,
  748. 'tenant_id': network.tenant_id,
  749. 'admin_state': network.admin_state_up,
  750. 'shared': False,
  751. 'external': False}
  752. url = reverse('horizon:admin:networks:update', args=[network.id])
  753. res = self.client.post(url, form_data)
  754. self.assertRedirectsNoFollow(res, INDEX_URL)
  755. @test.create_stubs({api.neutron: ('network_list',
  756. 'network_delete',
  757. 'list_dhcp_agent_hosting_networks',
  758. 'is_extension_supported'),
  759. api.keystone: ('tenant_list',)})
  760. def test_delete_network(self):
  761. tenants = self.tenants.list()
  762. network = self.networks.first()
  763. api.neutron.list_dhcp_agent_hosting_networks(IsA(http.HttpRequest),
  764. network.id).\
  765. AndReturn(self.agents.list())
  766. api.neutron.is_extension_supported(
  767. IsA(http.HttpRequest),
  768. 'network_availability_zone').AndReturn(True)
  769. api.neutron.is_extension_supported(
  770. IsA(http.HttpRequest),
  771. 'dhcp_agent_scheduler').AndReturn(True)
  772. api.neutron.is_extension_supported(
  773. IsA(http.HttpRequest),
  774. 'dhcp_agent_scheduler').AndReturn(True)
  775. api.keystone.tenant_list(IsA(http.HttpRequest))\
  776. .AndReturn([tenants, False])
  777. api.neutron.network_list(IsA(http.HttpRequest))\
  778. .AndReturn([network])
  779. api.neutron.network_delete(IsA(http.HttpRequest), network.id)
  780. self.mox.ReplayAll()
  781. form_data = {'action': 'networks__delete__%s' % network.id}
  782. res = self.client.post(INDEX_URL, form_data)
  783. self.assertRedirectsNoFollow(res, INDEX_URL)
  784. @test.create_stubs({api.neutron: ('network_list',
  785. 'network_delete',
  786. 'list_dhcp_agent_hosting_networks',
  787. 'is_extension_supported'),
  788. api.keystone: ('tenant_list',)})
  789. def test_delete_network_exception(self):
  790. tenants = self.tenants.list()
  791. network = self.networks.first()
  792. api.neutron.list_dhcp_agent_hosting_networks(IsA(http.HttpRequest),
  793. network.id).\
  794. AndReturn(self.agents.list())
  795. api.neutron.is_extension_supported(
  796. IsA(http.HttpRequest),
  797. 'network_availability_zone').AndReturn(True)
  798. api.neutron.is_extension_supported(
  799. IsA(http.HttpRequest),
  800. 'dhcp_agent_scheduler').AndReturn(True)
  801. api.neutron.is_extension_supported(
  802. IsA(http.HttpRequest),
  803. 'dhcp_agent_scheduler').AndReturn(True)
  804. api.keystone.tenant_list(IsA(http.HttpRequest))\
  805. .AndReturn([tenants, False])
  806. api.neutron.network_list(IsA(http.HttpRequest))\
  807. .AndReturn([network])
  808. api.neutron.network_delete(IsA(http.HttpRequest), network.id)\
  809. .AndRaise(self.exceptions.neutron)
  810. self.mox.ReplayAll()
  811. form_data = {'action': 'networks__delete__%s' % network.id}
  812. res = self.client.post(INDEX_URL, form_data)
  813. self.assertRedirectsNoFollow(res, INDEX_URL)
  814. @test.create_stubs({api.neutron: ('is_extension_supported',)})
  815. @test.update_settings(FILTER_DATA_FIRST={'admin.networks': True})
  816. def test_networks_list_with_admin_filter_first(self):
  817. api.neutron.is_extension_supported(
  818. IsA(http.HttpRequest),
  819. 'network_availability_zone').AndReturn(True)
  820. api.neutron.is_extension_supported(
  821. IsA(http.HttpRequest),
  822. 'dhcp_agent_scheduler').AndReturn(True)
  823. self.mox.ReplayAll()
  824. res = self.client.get(reverse('horizon:admin:networks:index'))
  825. self.assertTemplateUsed(res, INDEX_TEMPLATE)
  826. networks = res.context['networks_table'].data
  827. self.assertItemsEqual(networks, [])
  828. @test.create_stubs({api.neutron: ('is_extension_supported',),
  829. api.keystone: ('tenant_list',)})
  830. def test_network_create_without_physical_networks(self):
  831. tenants = self.tenants.list()
  832. api.keystone.tenant_list(IsA(http.HttpRequest)).AndReturn([tenants,
  833. False])
  834. api.neutron.is_extension_supported(IsA(http.HttpRequest), 'provider').\
  835. AndReturn(True)
  836. self.mox.ReplayAll()
  837. url = reverse('horizon:admin:networks:create')
  838. res = self.client.get(url)
  839. physical_network = res.context['form'].fields['physical_network']
  840. self.assertEqual(type(physical_network), forms.CharField)
  841. @test.create_stubs({api.neutron: ('is_extension_supported',),
  842. api.keystone: ('tenant_list',)})
  843. @test.update_settings(
  844. OPENSTACK_NEUTRON_NETWORK={
  845. 'physical_networks': ['default', 'test']})
  846. def test_network_create_with_physical_networks(self):
  847. tenants = self.tenants.list()
  848. api.keystone.tenant_list(IsA(http.HttpRequest)).AndReturn([tenants,
  849. False])
  850. api.neutron.is_extension_supported(IsA(http.HttpRequest), 'provider').\
  851. AndReturn(True)
  852. self.mox.ReplayAll()
  853. url = reverse('horizon:admin:networks:create')
  854. res = self.client.get(url)
  855. physical_network = res.context['form'].fields['physical_network']
  856. self.assertEqual(type(physical_network), forms.ThemableChoiceField)
  857. self.assertListEqual(list(physical_network.choices),
  858. [('default', 'default'), ('test', 'test')])