How to use return_value method in Playwright Python

Best Python code snippet using playwright-python

tests.py

Source:tests.py Github

copy

Full Screen

1# Copyright 2012 Nebula, Inc.2#3# Licensed under the Apache License, Version 2.0 (the "License"); you may4# not use this file except in compliance with the License. You may obtain5# a copy of the License at6#7# http://www.apache.org/licenses/LICENSE-2.08#9# Unless required by applicable law or agreed to in writing, software10# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT11# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the12# License for the specific language governing permissions and limitations13# under the License.14import copy15import mock16import six17from django.conf import settings18from django.forms import widgets19from django.template.defaultfilters import slugify20from django.test.utils import override_settings21from django.urls import reverse22from django.utils.http import urlunquote23from openstack_dashboard import api24from openstack_dashboard.api import cinder25from openstack_dashboard.dashboards.project.volumes \26 import tables as volume_tables27from openstack_dashboard.test import helpers as test28from openstack_dashboard.usage import quotas29DETAIL_URL = ('horizon:project:volumes:detail')30INDEX_URL = reverse('horizon:project:volumes:index')31SEARCH_OPTS = dict(status=api.cinder.VOLUME_STATE_AVAILABLE)32ATTACHMENT_ID = '6061364b-6612-48a9-8fee-1a38fe072547'33class VolumeIndexViewTests(test.ResetImageAPIVersionMixin, test.TestCase):34 @test.create_mocks({35 api.nova: ['server_get', 'server_list'],36 api.cinder: ['volume_backup_supported',37 'volume_snapshot_list',38 'volume_list_paged',39 'tenant_absolute_limits',40 'group_list'],41 })42 def _test_index(self, with_attachments=False, with_groups=False):43 vol_snaps = self.cinder_volume_snapshots.list()44 volumes = self.cinder_volumes.list()45 if with_attachments:46 server = self.servers.first()47 else:48 for volume in volumes:49 volume.attachments = []50 self.mock_volume_backup_supported.return_value = False51 if with_groups:52 self.mock_group_list.return_value = self.cinder_groups.list()53 volumes = self.cinder_group_volumes.list()54 self.mock_volume_list_paged.return_value = [volumes, False, False]55 if with_attachments:56 self.mock_server_get.return_value = server57 self.mock_server_list.return_value = [self.servers.list(), False]58 self.mock_volume_snapshot_list.return_value = vol_snaps59 self.mock_tenant_absolute_limits.return_value = \60 self.cinder_limits['absolute']61 res = self.client.get(INDEX_URL)62 if with_attachments:63 self.mock_server_list.assert_called_once_with(test.IsHttpRequest(),64 search_opts=None)65 self.mock_volume_snapshot_list.assert_called_once()66 if with_groups:67 self.mock_group_list.assert_called_once_with(test.IsHttpRequest(),68 search_opts=None)69 self.mock_volume_backup_supported.assert_called_with(70 test.IsHttpRequest())71 self.mock_volume_list_paged.assert_called_once_with(72 test.IsHttpRequest(), marker=None, search_opts=None,73 sort_dir='desc', paginate=True)74 self.mock_tenant_absolute_limits.assert_called_with(75 test.IsHttpRequest())76 self.assertEqual(res.status_code, 200)77 self.assertTemplateUsed(res, 'horizon/common/_data_table_view.html')78 def test_index_with_volume_attachments(self):79 self._test_index(True)80 def test_index_no_volume_attachments(self):81 self._test_index(False)82 def test_index_with_volume_groups(self):83 self._test_index(with_groups=True)84 @test.create_mocks({85 api.nova: ['server_get', 'server_list'],86 cinder: ['tenant_absolute_limits',87 'volume_list_paged',88 'volume_backup_supported',89 'volume_snapshot_list'],90 })91 def _test_index_paginated(self, marker, sort_dir, volumes, url,92 has_more, has_prev):93 backup_supported = True94 vol_snaps = self.cinder_volume_snapshots.list()95 server = self.servers.first()96 self.mock_volume_backup_supported.return_value = backup_supported97 self.mock_volume_list_paged.return_value = [volumes,98 has_more, has_prev]99 self.mock_volume_snapshot_list.return_value = vol_snaps100 self.mock_server_list.return_value = [self.servers.list(), False]101 self.mock_server_get.return_value = server102 self.mock_tenant_absolute_limits.return_value = \103 self.cinder_limits['absolute']104 res = self.client.get(urlunquote(url))105 self.assertEqual(2, self.mock_volume_backup_supported.call_count)106 self.mock_volume_list_paged.assert_called_once_with(107 test.IsHttpRequest(), marker=marker, sort_dir=sort_dir,108 search_opts=None, paginate=True)109 self.mock_volume_snapshot_list.assert_called_once_with(110 test.IsHttpRequest(), search_opts=None)111 self.mock_tenant_absolute_limits.assert_called_with(112 test.IsHttpRequest())113 self.mock_server_list.assert_called_once_with(test.IsHttpRequest(),114 search_opts=None)115 self.assertEqual(res.status_code, 200)116 self.assertTemplateUsed(res, 'horizon/common/_data_table_view.html')117 return res118 def ensure_attachments_exist(self, volumes):119 volumes = copy.copy(volumes)120 for volume in volumes:121 if not volume.attachments:122 volume.attachments.append({123 "id": "1", "server_id": '1', "device": "/dev/hda",124 "attachment_id": ATTACHMENT_ID})125 return volumes126 @override_settings(API_RESULT_PAGE_SIZE=2)127 def test_index_paginated(self):128 volumes = self.ensure_attachments_exist(self.cinder_volumes.list())129 size = settings.API_RESULT_PAGE_SIZE130 # get first page131 expected_volumes = volumes[:size]132 url = INDEX_URL133 res = self._test_index_paginated(None, "desc", expected_volumes, url,134 True, False)135 result = res.context['volumes_table'].data136 self.assertItemsEqual(result, expected_volumes)137 # get second page138 expected_volumes = volumes[size:2 * size]139 marker = expected_volumes[0].id140 next = volume_tables.VolumesTable._meta.pagination_param141 url = "?".join([INDEX_URL, "=".join([next, marker])])142 res = self._test_index_paginated(marker, "desc", expected_volumes, url,143 True, True)144 result = res.context['volumes_table'].data145 self.assertItemsEqual(result, expected_volumes)146 # get last page147 expected_volumes = volumes[-size:]148 marker = expected_volumes[0].id149 next = volume_tables.VolumesTable._meta.pagination_param150 url = "?".join([INDEX_URL, "=".join([next, marker])])151 res = self._test_index_paginated(marker, "desc", expected_volumes, url,152 False, True)153 result = res.context['volumes_table'].data154 self.assertItemsEqual(result, expected_volumes)155 @override_settings(API_RESULT_PAGE_SIZE=2)156 def test_index_paginated_prev_page(self):157 volumes = self.ensure_attachments_exist(self.cinder_volumes.list())158 size = settings.API_RESULT_PAGE_SIZE159 # prev from some page160 expected_volumes = volumes[size:2 * size]161 marker = expected_volumes[0].id162 prev = volume_tables.VolumesTable._meta.prev_pagination_param163 url = "?".join([INDEX_URL, "=".join([prev, marker])])164 res = self._test_index_paginated(marker, "asc", expected_volumes, url,165 True, True)166 result = res.context['volumes_table'].data167 self.assertItemsEqual(result, expected_volumes)168 # back to first page169 expected_volumes = volumes[:size]170 marker = expected_volumes[0].id171 prev = volume_tables.VolumesTable._meta.prev_pagination_param172 url = "?".join([INDEX_URL, "=".join([prev, marker])])173 res = self._test_index_paginated(marker, "asc", expected_volumes, url,174 True, False)175 result = res.context['volumes_table'].data176 self.assertItemsEqual(result, expected_volumes)177class VolumeViewTests(test.ResetImageAPIVersionMixin, test.TestCase):178 def tearDown(self):179 for volume in self.cinder_volumes.list():180 # VolumeTableMixIn._set_volume_attributes mutates data181 # and cinder_volumes.list() doesn't deep copy182 for att in volume.attachments:183 if 'instance' in att:184 del att['instance']185 super(VolumeViewTests, self).tearDown()186 @test.create_mocks({187 cinder: ['volume_create', 'volume_snapshot_list',188 'volume_type_list', 'volume_type_default',189 'volume_list', 'availability_zone_list',190 'extension_supported', 'group_list'],191 quotas: ['tenant_quota_usages'],192 api.glance: ['image_list_detailed'],193 })194 def test_create_volume(self):195 volume = self.cinder_volumes.first()196 volume_type = self.cinder_volume_types.first()197 az = self.cinder_availability_zones.first().zoneName198 formData = {'name': u'A Volume I Am Making',199 'description': u'This is a volume I am making for a test.',200 'method': u'CreateForm',201 'type': volume_type.name,202 'size': 50,203 'snapshot_source': '',204 'availability_zone': az}205 self.mock_volume_type_default.return_value = \206 self.cinder_volume_types.first()207 self.mock_volume_type_list.return_value = \208 self.cinder_volume_types.list()209 self.mock_tenant_quota_usages.return_value = \210 self.cinder_quota_usages.first()211 self.mock_volume_snapshot_list.return_value = \212 self.cinder_volume_snapshots.list()213 self.mock_image_list_detailed.return_value = [[], False, False]214 self.mock_availability_zone_list.return_value = \215 self.cinder_availability_zones.list()216 self.mock_extension_supported.return_value = True217 self.mock_volume_list.return_value = self.cinder_volumes.list()218 self.mock_volume_create.return_value = volume219 self.mock_group_list.return_value = []220 url = reverse('horizon:project:volumes:create')221 res = self.client.post(url, formData)222 self.assertNoFormErrors(res)223 redirect_url = INDEX_URL224 self.assertRedirectsNoFollow(res, redirect_url)225 self.mock_volume_type_default.assert_called_once()226 self.mock_volume_type_list.assert_called_once()227 self.mock_volume_snapshot_list.assert_called_once_with(228 test.IsHttpRequest(), search_opts=SEARCH_OPTS)229 self.mock_availability_zone_list.assert_called_once()230 self.mock_extension_supported.assert_called_once_with(231 test.IsHttpRequest(), 'AvailabilityZones')232 self.mock_volume_list.assert_called_once_with(test.IsHttpRequest(),233 search_opts=SEARCH_OPTS)234 self.mock_volume_create.assert_called_once_with(235 test.IsHttpRequest(), formData['size'], formData['name'],236 formData['description'], formData['type'], metadata={},237 snapshot_id=None, group_id=None, image_id=None,238 availability_zone=formData['availability_zone'], source_volid=None)239 self.mock_image_list_detailed.assert_called_with(240 test.IsHttpRequest(),241 filters={'visibility': 'shared', 'status': 'active'})242 self.mock_tenant_quota_usages.assert_called_once_with(243 test.IsHttpRequest(),244 targets=('volumes', 'gigabytes'))245 self.mock_group_list.assert_called_with(test.IsHttpRequest())246 @test.create_mocks({247 quotas: ['tenant_quota_usages'],248 api.glance: ['image_list_detailed'],249 cinder: ['extension_supported',250 'availability_zone_list',251 'volume_list',252 'volume_type_default',253 'volume_type_list',254 'volume_snapshot_list',255 'volume_create',256 'group_list'],257 })258 def test_create_volume_without_name(self):259 volume = self.cinder_volumes.first()260 volume_type = self.cinder_volume_types.first()261 az = self.cinder_availability_zones.first().zoneName262 formData = {'name': '',263 'description': u'This is a volume I am making for a test.',264 'method': u'CreateForm',265 'type': volume_type.name,266 'size': 50,267 'snapshot_source': '',268 'availability_zone': az}269 self.mock_volume_type_list.return_value = \270 self.cinder_volume_types.list()271 self.mock_tenant_quota_usages.return_value = \272 self.cinder_quota_usages.first()273 self.mock_volume_snapshot_list.return_value = \274 self.cinder_volume_snapshots.list()275 self.mock_image_list_detailed.return_value = [self.images.list(),276 False, False]277 self.mock_availability_zone_list.return_value = \278 self.cinder_availability_zones.list()279 self.mock_extension_supported.return_value = True280 self.mock_volume_type_default.return_value = \281 self.cinder_volume_types.first()282 self.mock_volume_list.return_value = self.cinder_volumes.list()283 self.mock_volume_create.return_value = volume284 self.mock_group_list.return_value = []285 url = reverse('horizon:project:volumes:create')286 res = self.client.post(url, formData)287 redirect_url = INDEX_URL288 self.assertRedirectsNoFollow(res, redirect_url)289 self.mock_volume_type_list.assert_called_once()290 self.mock_volume_snapshot_list.assert_called_once_with(291 test.IsHttpRequest(), search_opts=SEARCH_OPTS)292 self.mock_image_list_detailed.assert_called_with(293 test.IsHttpRequest(),294 filters={'visibility': 'shared', 'status': 'active'})295 self.mock_availability_zone_list.assert_called_once()296 self.mock_extension_supported.assert_called_once_with(297 test.IsHttpRequest(), 'AvailabilityZones')298 self.mock_volume_type_default.assert_called_once()299 self.mock_volume_list.assert_called_once()300 self.mock_volume_create.assert_called_once_with(301 test.IsHttpRequest(), formData['size'], formData['name'],302 formData['description'], formData['type'], metadata={},303 snapshot_id=None, group_id=None, image_id=None,304 availability_zone=formData['availability_zone'], source_volid=None)305 self.mock_group_list.assert_called_once_with(test.IsHttpRequest())306 @test.create_mocks({307 quotas: ['tenant_quota_usages'],308 api.glance: ['image_list_detailed'],309 cinder: ['extension_supported',310 'availability_zone_list',311 'volume_list',312 'volume_type_default',313 'volume_type_list',314 'volume_snapshot_list',315 'volume_create',316 'group_list'],317 })318 def test_create_volume_dropdown(self):319 volume = self.cinder_volumes.first()320 formData = {'name': u'A Volume I Am Making',321 'description': u'This is a volume I am making for a test.',322 'method': u'CreateForm',323 'size': 50,324 'type': '',325 'volume_source_type': 'no_source_type',326 'snapshot_source': self.cinder_volume_snapshots.first().id,327 'image_source': self.images.first().id}328 self.mock_volume_type_default.return_value = \329 self.cinder_volume_types.first()330 self.mock_volume_type_list.return_value = \331 self.cinder_volume_types.list()332 self.mock_volume_snapshot_list.return_value = \333 self.cinder_volume_snapshots.list()334 self.mock_image_list_detailed.return_value = \335 [self.images.list(), False, False]336 self.mock_volume_list.return_value = self.cinder_volumes.list()337 self.mock_tenant_quota_usages.return_value = \338 self.cinder_quota_usages.first()339 self.mock_extension_supported.return_value = True340 self.mock_availability_zone_list.return_value = \341 self.cinder_availability_zones.list()342 self.mock_group_list.return_value = []343 self.mock_volume_create.return_value = volume344 url = reverse('horizon:project:volumes:create')345 res = self.client.post(url, formData)346 redirect_url = INDEX_URL347 self.assertRedirectsNoFollow(res, redirect_url)348 self.mock_volume_type_default.assert_called_once()349 self.mock_volume_type_list.assert_called_once()350 self.mock_volume_snapshot_list.assert_called_once_with(351 test.IsHttpRequest(), search_opts=SEARCH_OPTS)352 self.mock_image_list_detailed.assert_called_with(353 test.IsHttpRequest(),354 filters={'visibility': 'shared', 'status': 'active'})355 self.mock_volume_list.assert_called_once_with(test.IsHttpRequest(),356 search_opts=SEARCH_OPTS)357 self.mock_tenant_quota_usages.assert_called_once()358 self.mock_extension_supported.assert_called_once_with(359 test.IsHttpRequest(), 'AvailabilityZones')360 self.mock_availability_zone_list.assert_called_once()361 self.mock_volume_create.assert_called_once_with(362 test.IsHttpRequest(), formData['size'], formData['name'],363 formData['description'], '', metadata={}, snapshot_id=None,364 group_id=None, image_id=None, availability_zone=None,365 source_volid=None)366 self.mock_group_list.assert_called_with(test.IsHttpRequest())367 @test.create_mocks({368 quotas: ['tenant_quota_usages'],369 cinder: ['volume_type_list',370 'volume_type_default',371 'volume_get',372 'volume_snapshot_get',373 'volume_create',374 'group_list'],375 })376 def test_create_volume_from_snapshot(self):377 volume = self.cinder_volumes.first()378 snapshot = self.cinder_volume_snapshots.first()379 formData = {'name': u'A Volume I Am Making',380 'description': u'This is a volume I am making for a test.',381 'method': u'CreateForm',382 'size': 50,383 'type': '',384 'snapshot_source': snapshot.id}385 self.mock_volume_type_default.return_value = \386 self.cinder_volume_types.first()387 self.mock_volume_type_list.return_value = \388 self.cinder_volume_types.list()389 self.mock_tenant_quota_usages.return_value = \390 self.cinder_quota_usages.first()391 self.mock_volume_snapshot_get.return_value = snapshot392 self.mock_volume_get.return_value = self.cinder_volumes.first()393 self.mock_volume_create.return_value = volume394 self.mock_group_list.return_value = []395 # get snapshot from url396 url = reverse('horizon:project:volumes:create')397 res = self.client.post("?".join([url,398 "snapshot_id=" + str(snapshot.id)]),399 formData)400 redirect_url = INDEX_URL401 self.assertRedirectsNoFollow(res, redirect_url)402 self.mock_volume_type_default.assert_called_once()403 self.mock_volume_type_list.assert_called_once()404 self.mock_tenant_quota_usages.assert_called_once()405 self.mock_volume_snapshot_get.assert_called_once_with(406 test.IsHttpRequest(), str(snapshot.id))407 self.mock_volume_get.assert_called_once_with(test.IsHttpRequest(),408 snapshot.volume_id)409 self.mock_volume_create.assert_called_once_with(410 test.IsHttpRequest(), formData['size'], formData['name'],411 formData['description'], '', metadata={}, snapshot_id=snapshot.id,412 group_id=None, image_id=None, availability_zone=None,413 source_volid=None)414 self.mock_group_list.assert_called_once_with(test.IsHttpRequest())415 @test.create_mocks({416 quotas: ['tenant_quota_usages'],417 api.glance: ['image_list_detailed'],418 cinder: ['extension_supported',419 'volume_snapshot_list',420 'volume_snapshot_get',421 'availability_zone_list',422 'volume_type_list',423 'volume_list',424 'volume_type_default',425 'volume_get',426 'volume_create',427 'group_list'],428 })429 def test_create_volume_from_volume(self):430 volume = self.cinder_volumes.first()431 formData = {'name': u'A copy of a volume',432 'description': u'This is a volume I am making for a test.',433 'method': u'CreateForm',434 'size': 50,435 'type': '',436 'volume_source_type': 'volume_source',437 'volume_source': volume.id}438 self.mock_volume_type_default.return_value = \439 self.cinder_volume_types.first()440 self.mock_volume_list.return_value = self.cinder_volumes.list()441 self.mock_volume_type_list.return_value = \442 self.cinder_volume_types.list()443 self.mock_volume_snapshot_list.return_value = \444 self.cinder_volume_snapshots.list()445 self.mock_tenant_quota_usages.return_value = \446 self.cinder_quota_usages.first()447 self.mock_volume_get.return_value = self.cinder_volumes.first()448 self.mock_extension_supported.return_value = True449 self.mock_availability_zone_list.return_value = \450 self.cinder_availability_zones.list()451 self.mock_image_list_detailed.return_value = \452 [self.images.list(), False, False]453 self.mock_volume_create.return_value = volume454 self.mock_group_list.return_value = []455 url = reverse('horizon:project:volumes:create')456 redirect_url = INDEX_URL457 res = self.client.post(url, formData)458 self.assertNoFormErrors(res)459 self.assertMessageCount(info=1)460 self.assertRedirectsNoFollow(res, redirect_url)461 self.mock_volume_type_default.assert_called_once()462 self.mock_volume_list.assert_called_once_with(test.IsHttpRequest(),463 search_opts=SEARCH_OPTS)464 self.mock_volume_type_list.assert_called_once()465 self.mock_volume_snapshot_list.assert_called_once_with(466 test.IsHttpRequest(), search_opts=SEARCH_OPTS)467 self.mock_tenant_quota_usages.assert_called_once()468 self.mock_volume_get.assert_called_once_with(test.IsHttpRequest(),469 volume.id)470 self.mock_extension_supported.assert_called_once_with(471 test.IsHttpRequest(), 'AvailabilityZones')472 self.mock_availability_zone_list.assert_called_once()473 self.mock_image_list_detailed.assert_called_with(474 test.IsHttpRequest(),475 filters={'visibility': 'shared', 'status': 'active'})476 self.mock_volume_create.assert_called_once_with(477 test.IsHttpRequest(), formData['size'], formData['name'],478 formData['description'], None, metadata={}, snapshot_id=None,479 group_id=None, image_id=None, availability_zone=None,480 source_volid=volume.id)481 self.mock_group_list.assert_called_once_with(test.IsHttpRequest())482 @test.create_mocks({483 quotas: ['tenant_quota_usages'],484 api.glance: ['image_list_detailed'],485 cinder: ['extension_supported',486 'availability_zone_list',487 'volume_type_list',488 'volume_list',489 'volume_type_default',490 'volume_get',491 'volume_snapshot_get',492 'volume_snapshot_list',493 'volume_create',494 'group_list'],495 })496 def test_create_volume_from_snapshot_dropdown(self):497 volume = self.cinder_volumes.first()498 snapshot = self.cinder_volume_snapshots.first()499 formData = {'name': u'A Volume I Am Making',500 'description': u'This is a volume I am making for a test.',501 'method': u'CreateForm',502 'size': 50,503 'type': '',504 'volume_source_type': 'snapshot_source',505 'snapshot_source': snapshot.id}506 self.mock_volume_type_list.return_value = \507 self.cinder_volume_types.list()508 self.mock_volume_snapshot_list.return_value = \509 self.cinder_volume_snapshots.list()510 self.mock_image_list_detailed.return_value = [self.images.list(),511 False, False]512 self.mock_volume_type_default.return_value = \513 self.cinder_volume_types.first()514 self.mock_volume_list.return_value = self.cinder_volumes.list()515 self.mock_tenant_quota_usages.return_value = \516 self.cinder_quota_usages.first()517 self.mock_volume_snapshot_get.return_value = snapshot518 self.mock_extension_supported.return_value = True519 self.mock_availability_zone_list.return_value = \520 self.cinder_availability_zones.list()521 self.mock_volume_create.return_value = volume522 self.mock_group_list.return_value = []523 # get snapshot from dropdown list524 url = reverse('horizon:project:volumes:create')525 res = self.client.post(url, formData)526 redirect_url = INDEX_URL527 self.assertRedirectsNoFollow(res, redirect_url)528 self.mock_volume_type_list.assert_called_once()529 self.mock_volume_snapshot_list.assert_called_once_with(530 test.IsHttpRequest(), search_opts=SEARCH_OPTS)531 self.mock_image_list_detailed.assert_called_with(532 test.IsHttpRequest(),533 filters={'visibility': 'shared', 'status': 'active'})534 self.mock_volume_type_default.assert_called_once()535 self.mock_volume_list.assert_called_once_with(test.IsHttpRequest(),536 search_opts=SEARCH_OPTS)537 self.mock_tenant_quota_usages.assert_called_once()538 self.mock_volume_snapshot_get.assert_called_once_with(539 test.IsHttpRequest(), str(snapshot.id))540 self.mock_extension_supported.assert_called_once_with(541 test.IsHttpRequest(), 'AvailabilityZones')542 self.mock_availability_zone_list.assert_called_once()543 self.mock_volume_create.assert_called_once_with(544 test.IsHttpRequest(), formData['size'], formData['name'],545 formData['description'], '', metadata={}, snapshot_id=snapshot.id,546 group_id=None, image_id=None, availability_zone=None,547 source_volid=None)548 self.mock_group_list.assert_called_once_with(test.IsHttpRequest())549 @test.create_mocks({550 quotas: ['tenant_quota_usages'],551 api.glance: ['image_list_detailed'],552 cinder: ['volume_snapshot_get',553 'volume_type_list',554 'volume_type_default',555 'volume_get',556 'group_list'],557 })558 def test_create_volume_from_snapshot_invalid_size(self):559 snapshot = self.cinder_volume_snapshots.first()560 formData = {'name': u'A Volume I Am Making',561 'description': u'This is a volume I am making for a test.',562 'method': u'CreateForm',563 'size': 20, 'snapshot_source': snapshot.id}564 self.mock_volume_type_list.return_value = \565 self.cinder_volume_types.list()566 self.mock_volume_type_default.return_value = \567 self.cinder_volume_types.first()568 self.mock_tenant_quota_usages.return_value = \569 self.cinder_quota_usages.first()570 self.mock_volume_snapshot_get.return_value = snapshot571 self.mock_volume_get.return_value = self.cinder_volumes.first()572 self.mock_group_list.return_value = []573 url = reverse('horizon:project:volumes:create')574 res = self.client.post("?".join([url,575 "snapshot_id=" + str(snapshot.id)]),576 formData, follow=True)577 self.assertEqual(res.redirect_chain, [])578 self.assertFormError(res, 'form', None,579 "The volume size cannot be less than the "580 "snapshot size (40GiB)")581 self.assertEqual(3, self.mock_volume_type_list.call_count)582 self.assertEqual(2, self.mock_volume_type_default.call_count)583 self.mock_volume_snapshot_get.assert_called_with(test.IsHttpRequest(),584 str(snapshot.id))585 self.mock_volume_get.assert_called_with(test.IsHttpRequest(),586 snapshot.volume_id)587 self.mock_group_list.assert_called_with(test.IsHttpRequest())588 @test.create_mocks({589 quotas: ['tenant_quota_usages'],590 api.glance: ['image_get'],591 cinder: ['extension_supported',592 'availability_zone_list',593 'volume_type_default',594 'volume_type_list',595 'volume_create',596 'group_list'],597 })598 def test_create_volume_from_image(self):599 volume = self.cinder_volumes.first()600 image = self.images.first()601 formData = {'name': u'A Volume I Am Making',602 'description': u'This is a volume I am making for a test.',603 'method': u'CreateForm',604 'size': 40,605 'type': '',606 'image_source': image.id}607 self.mock_volume_type_default.return_value = \608 self.cinder_volume_types.first()609 self.mock_volume_type_list.ret = self.cinder_volume_types.list()610 self.mock_tenant_quota_usages.return_value = \611 self.cinder_quota_usages.first()612 self.mock_image_get.return_value = image613 self.mock_extension_supported.return_value = True614 self.mock_availability_zone_list.return_value = \615 self.cinder_availability_zones.list()616 self.mock_group_list.return_value = []617 self.mock_volume_create.return_value = volume618 # get image from url619 url = reverse('horizon:project:volumes:create')620 res = self.client.post("?".join([url,621 "image_id=" + str(image.id)]),622 formData)623 redirect_url = INDEX_URL624 self.assertRedirectsNoFollow(res, redirect_url)625 self.mock_volume_type_default.assert_called_once()626 self.mock_volume_type_list.assert_called_once()627 self.mock_tenant_quota_usages.assert_called_once()628 self.mock_image_get.assert_called_once_with(test.IsHttpRequest(),629 str(image.id))630 self.mock_extension_supported.assert_called_once_with(631 test.IsHttpRequest(), 'AvailabilityZones')632 self.mock_availability_zone_list.assert_called_once()633 self.mock_volume_create.assert_called_once_with(634 test.IsHttpRequest(), formData['size'], formData['name'],635 formData['description'], '', metadata={}, snapshot_id=None,636 group_id=None, image_id=image.id, availability_zone=None,637 source_volid=None)638 self.mock_group_list.assert_called_with(test.IsHttpRequest())639 @test.create_mocks({640 quotas: ['tenant_quota_usages'],641 api.glance: ['image_list_detailed',642 'image_get'],643 cinder: ['extension_supported',644 'availability_zone_list',645 'volume_snapshot_list',646 'volume_list',647 'volume_type_list',648 'volume_type_default',649 'volume_create',650 'group_list'],651 })652 def test_create_volume_from_image_dropdown(self):653 volume = self.cinder_volumes.first()654 image = self.images.first()655 formData = {'name': u'A Volume I Am Making',656 'description': u'This is a volume I am making for a test.',657 'method': u'CreateForm',658 'size': 30,659 'type': '',660 'volume_source_type': 'image_source',661 'snapshot_source': self.cinder_volume_snapshots.first().id,662 'image_source': image.id}663 self.mock_volume_type_list.return_value = \664 self.cinder_volume_types.list()665 self.mock_volume_snapshot_list.return_value = \666 self.cinder_volume_snapshots.list()667 self.mock_image_list_detailed.return_value = [self.images.list(),668 False, False]669 self.mock_volume_type_default.return_value = \670 self.cinder_volume_types.first()671 self.mock_volume_list.return_value = self.cinder_volumes.list()672 self.mock_tenant_quota_usages.return_value = \673 self.cinder_quota_usages.first()674 self.mock_image_get.return_value = image675 self.mock_extension_supported.return_value = True676 self.mock_availability_zone_list.return_value = \677 self.cinder_availability_zones.list()678 self.mock_group_list.return_value = []679 self.mock_volume_create.return_value = volume680 # get image from dropdown list681 url = reverse('horizon:project:volumes:create')682 res = self.client.post(url, formData)683 redirect_url = INDEX_URL684 self.assertRedirectsNoFollow(res, redirect_url)685 self.mock_volume_type_list.assert_called_once()686 self.mock_volume_snapshot_list.assert_called_once_with(687 test.IsHttpRequest(), search_opts=SEARCH_OPTS)688 self.mock_image_list_detailed.assert_called_with(689 test.IsHttpRequest(),690 filters={'visibility': 'shared', 'status': 'active'})691 self.mock_volume_type_default.assert_called_once()692 self.mock_volume_list.assert_called_once_with(test.IsHttpRequest(),693 search_opts=SEARCH_OPTS)694 self.mock_tenant_quota_usages.assert_called_once()695 self.mock_image_get.assert_called_with(test.IsHttpRequest(),696 str(image.id))697 self.mock_extension_supported.assert_called_once_with(698 test.IsHttpRequest(), 'AvailabilityZones')699 self.mock_availability_zone_list.assert_called_once()700 self.mock_volume_create.assert_called_once_with(701 test.IsHttpRequest(), formData['size'], formData['name'],702 formData['description'], '', metadata={}, snapshot_id=None,703 group_id=None, image_id=image.id, availability_zone=None,704 source_volid=None)705 self.mock_group_list.assert_called_with(test.IsHttpRequest())706 @test.create_mocks({707 quotas: ['tenant_quota_usages'],708 api.glance: ['image_get'],709 cinder: ['extension_supported',710 'availability_zone_list',711 'volume_type_list',712 'volume_type_default',713 'group_list'],714 })715 def test_create_volume_from_image_under_image_size(self):716 image = self.images.first()717 formData = {'name': u'A Volume I Am Making',718 'description': u'This is a volume I am making for a test.',719 'method': u'CreateForm',720 'size': 1, 'image_source': image.id}721 self.mock_volume_type_list.return_value = \722 self.cinder_volume_types.list()723 self.mock_volume_type_default.return_value = \724 self.cinder_volume_types.first()725 self.mock_tenant_quota_usages.return_value = \726 self.cinder_quota_usages.first()727 self.mock_image_get.return_value = image728 self.mock_extension_supported.return_value = True729 self.mock_group_list.return_value = []730 url = reverse('horizon:project:volumes:create')731 res = self.client.post("?".join([url,732 "image_id=" + str(image.id)]),733 formData, follow=True)734 self.assertEqual(res.redirect_chain, [])735 msg = (u"The volume size cannot be less than the "736 u"image size (20.0\xa0GB)")737 self.assertFormError(res, 'form', None, msg)738 self.assertEqual(3, self.mock_volume_type_list.call_count)739 self.assertEqual(2, self.mock_volume_type_default.call_count)740 self.assertEqual(2, self.mock_tenant_quota_usages.call_count)741 self.mock_image_get.assert_called_with(test.IsHttpRequest(),742 str(image.id))743 self.mock_extension_supported.assert_called_with(test.IsHttpRequest(),744 'AvailabilityZones')745 self.mock_group_list.assert_called_with(test.IsHttpRequest())746 @test.create_mocks({747 quotas: ['tenant_quota_usages'],748 api.glance: ['image_get'],749 cinder: ['extension_supported',750 'availability_zone_list',751 'volume_type_list',752 'volume_type_default',753 'group_list'],754 })755 def _test_create_volume_from_image_under_image_min_disk_size(self, image):756 formData = {'name': u'A Volume I Am Making',757 'description': u'This is a volume I am making for a test.',758 'method': u'CreateForm',759 'size': 5, 'image_source': image.id}760 self.mock_volume_type_list.return_value = \761 self.cinder_volume_types.list()762 self.mock_volume_type_default.return_value = \763 self.cinder_volume_types.first()764 self.mock_tenant_quota_usages.return_value = \765 self.cinder_quota_usages.first()766 self.mock_image_get.return_value = image767 self.mock_extension_supported.return_value = True768 self.mock_availability_zone_list.return_value = \769 self.cinder_availability_zones.list()770 self.mock_group_list.return_value = []771 url = reverse('horizon:project:volumes:create')772 res = self.client.post("?".join([url,773 "image_id=" + str(image.id)]),774 formData, follow=True)775 self.assertEqual(res.redirect_chain, [])776 self.assertFormError(res, 'form', None,777 "The volume size cannot be less than the "778 "image minimum disk size (30GiB)")779 self.assertEqual(3, self.mock_volume_type_list.call_count)780 self.assertEqual(2, self.mock_volume_type_default.call_count)781 self.assertEqual(2, self.mock_availability_zone_list.call_count)782 self.mock_image_get.assert_called_with(test.IsHttpRequest(),783 str(image.id))784 self.mock_extension_supported.assert_called_with(test.IsHttpRequest(),785 'AvailabilityZones')786 self.mock_group_list.assert_called_with(test.IsHttpRequest())787 def test_create_volume_from_image_under_image_min_disk_size(self):788 image = self.images.get(name="protected_images")789 image.min_disk = 30790 self._test_create_volume_from_image_under_image_min_disk_size(image)791 def test_create_volume_from_image_under_image_prop_min_disk_size_v2(self):792 image = self.imagesV2.get(name="protected_images")793 self._test_create_volume_from_image_under_image_min_disk_size(image)794 @test.create_mocks({795 quotas: ['tenant_quota_usages'],796 api.glance: ['image_list_detailed'],797 cinder: ['extension_supported',798 'availability_zone_list',799 'volume_list',800 'volume_type_list',801 'volume_type_default',802 'volume_snapshot_list',803 'group_list'],804 })805 def test_create_volume_gb_used_over_alloted_quota(self):806 formData = {'name': u'This Volume Is Huge!',807 'description': u'This is a volume that is just too big!',808 'method': u'CreateForm',809 'size': 5000}810 usage_limit = self.cinder_quota_usages.first()811 usage_limit.add_quota(api.base.Quota('volumes', 6))812 usage_limit.tally('volumes', len(self.cinder_volumes.list()))813 usage_limit.add_quota(api.base.Quota('gigabytes', 100))814 usage_limit.tally('gigabytes', 80)815 self.mock_volume_type_list.return_value = \816 self.cinder_volume_types.list()817 self.mock_volume_type_default.return_value = \818 self.cinder_volume_types.first()819 self.mock_tenant_quota_usages.return_value = usage_limit820 self.mock_volume_snapshot_list.return_value = \821 self.cinder_volume_snapshots.list()822 self.mock_image_list_detailed.return_value = [self.images.list(),823 False, False]824 self.mock_volume_list.return_value = self.cinder_volumes.list()825 self.mock_extension_supported.return_value = True826 self.mock_availability_zone_list.return_value = \827 self.cinder_availability_zones.list()828 self.mock_group_list.return_value = []829 url = reverse('horizon:project:volumes:create')830 res = self.client.post(url, formData)831 expected_error = [u'A volume of 5000GiB cannot be created as you only'832 ' have 20GiB of your quota available.']833 self.assertEqual(res.context['form'].errors['__all__'], expected_error)834 self.assertEqual(3, self.mock_volume_type_list.call_count)835 self.assertEqual(2, self.mock_volume_type_default.call_count)836 self.assertEqual(2, self.mock_volume_list.call_count)837 self.assertEqual(2, self.mock_availability_zone_list.call_count)838 self.assertEqual(2, self.mock_tenant_quota_usages.call_count)839 self.mock_volume_snapshot_list.assert_called_with(840 test.IsHttpRequest(), search_opts=SEARCH_OPTS)841 self.mock_image_list_detailed.assert_called_with(842 test.IsHttpRequest(),843 filters={'visibility': 'shared', 'status': 'active'})844 self.mock_extension_supported.assert_called_with(test.IsHttpRequest(),845 'AvailabilityZones')846 self.mock_group_list.assert_called_with(test.IsHttpRequest())847 @test.create_mocks({848 quotas: ['tenant_quota_usages'],849 api.glance: ['image_list_detailed'],850 cinder: ['extension_supported',851 'availability_zone_list',852 'volume_list',853 'volume_type_list',854 'volume_type_default',855 'volume_snapshot_list',856 'group_list'],857 })858 def test_create_volume_number_over_alloted_quota(self):859 formData = {'name': u'Too Many...',860 'description': u'We have no volumes left!',861 'method': u'CreateForm',862 'size': 10}863 usage_limit = self.cinder_quota_usages.first()864 usage_limit.add_quota(api.base.Quota('volumes',865 len(self.cinder_volumes.list())))866 usage_limit.tally('volumes', len(self.cinder_volumes.list()))867 usage_limit.add_quota(api.base.Quota('gigabytes', 100))868 usage_limit.tally('gigabytes', 20)869 self.mock_volume_type_list.return_value = \870 self.cinder_volume_types.list()871 self.mock_volume_type_default.return_value = \872 self.cinder_volume_types.first()873 self.mock_tenant_quota_usages.return_value = usage_limit874 self.mock_volume_snapshot_list.return_value = \875 self.cinder_volume_snapshots.list()876 self.mock_image_list_detailed.return_value = [self.images.list(),877 False, False]878 self.mock_volume_list.return_value = self.cinder_volumes.list()879 self.mock_extension_supported.return_value = True880 self.mock_availability_zone_list.return_value = \881 self.cinder_availability_zones.list()882 self.mock_group_list.return_value = []883 url = reverse('horizon:project:volumes:create')884 res = self.client.post(url, formData)885 expected_error = [u'You are already using all of your available'886 ' volumes.']887 self.assertEqual(res.context['form'].errors['__all__'], expected_error)888 self.assertEqual(3, self.mock_volume_type_list.call_count)889 self.assertEqual(2, self.mock_volume_type_default.call_count)890 self.assertEqual(2, self.mock_availability_zone_list.call_count)891 self.mock_volume_snapshot_list.assert_called_with(892 test.IsHttpRequest(), search_opts=SEARCH_OPTS)893 self.mock_image_list_detailed.assert_called_with(894 test.IsHttpRequest(),895 filters={'visibility': 'shared', 'status': 'active'})896 self.mock_volume_list.assert_called_with(test.IsHttpRequest(),897 search_opts=SEARCH_OPTS)898 self.mock_extension_supported.assert_called_with(test.IsHttpRequest(),899 'AvailabilityZones')900 self.mock_group_list.assert_called_with(test.IsHttpRequest())901 @test.create_mocks({902 cinder: ['volume_create', 'volume_snapshot_list',903 'volume_type_list', 'volume_type_default',904 'volume_list', 'availability_zone_list',905 'extension_supported', 'group_list'],906 quotas: ['tenant_quota_usages'],907 api.glance: ['image_list_detailed'],908 })909 def test_create_volume_with_group(self):910 volume = self.cinder_volumes.first()911 volume_type = self.cinder_volume_types.first()912 az = self.cinder_availability_zones.first().zoneName913 volume_group = self.cinder_groups.list()[0]914 formData = {'name': u'A Volume I Am Making',915 'description': u'This is a volume I am making for a test.',916 'method': u'CreateForm',917 'type': volume_type.name,918 'size': 50,919 'snapshot_source': '',920 'availability_zone': az,921 'group': volume_group.id}922 self.mock_volume_type_default.return_value = \923 self.cinder_volume_types.first()924 self.mock_volume_type_list.return_value = \925 self.cinder_volume_types.list()926 self.mock_tenant_quota_usages.return_value = \927 self.cinder_quota_usages.first()928 self.mock_volume_snapshot_list.return_value = \929 self.cinder_volume_snapshots.list()930 self.mock_image_list_detailed.return_value = [[], False, False]931 self.mock_availability_zone_list.return_value = \932 self.cinder_availability_zones.list()933 self.mock_extension_supported.return_value = True934 self.mock_volume_list.return_value = self.cinder_volumes.list()935 self.mock_volume_create.return_value = volume936 self.mock_group_list.return_value = self.cinder_groups.list()937 url = reverse('horizon:project:volumes:create')938 res = self.client.post(url, formData)939 self.assertNoFormErrors(res)940 redirect_url = INDEX_URL941 self.assertRedirectsNoFollow(res, redirect_url)942 self.mock_volume_type_default.assert_called_once()943 self.mock_volume_type_list.assert_called_once()944 self.mock_volume_snapshot_list.assert_called_once_with(945 test.IsHttpRequest(), search_opts=SEARCH_OPTS)946 self.mock_availability_zone_list.assert_called_once()947 self.mock_extension_supported.assert_called_once_with(948 test.IsHttpRequest(), 'AvailabilityZones')949 self.mock_volume_list.assert_called_once_with(test.IsHttpRequest(),950 search_opts=SEARCH_OPTS)951 self.mock_volume_create.assert_called_once_with(952 test.IsHttpRequest(), formData['size'], formData['name'],953 formData['description'], formData['type'], metadata={},954 snapshot_id=None, group_id=volume_group.id, image_id=None,955 availability_zone=formData['availability_zone'], source_volid=None)956 self.mock_image_list_detailed.assert_called_with(957 test.IsHttpRequest(),958 filters={'visibility': 'shared', 'status': 'active'})959 self.mock_tenant_quota_usages.assert_called_once_with(960 test.IsHttpRequest(),961 targets=('volumes', 'gigabytes'))962 self.mock_group_list.assert_called_with(test.IsHttpRequest())963 @test.create_mocks({964 api.nova: ['server_list'],965 cinder: ['volume_delete',966 'volume_snapshot_list',967 'volume_list_paged',968 'tenant_absolute_limits'],969 })970 def test_delete_volume(self):971 volumes = self.cinder_volumes.list()972 volume = self.cinder_volumes.first()973 formData = {'action':974 'volumes__delete__%s' % volume.id}975 self.mock_volume_list_paged.return_value = [volumes, False, False]976 self.mock_volume_snapshot_list.return_value = []977 self.mock_server_list.return_value = [self.servers.list(), False]978 self.mock_volume_list_paged.return_value = [volumes, False, False]979 self.mock_tenant_absolute_limits.return_value = \980 self.cinder_limits['absolute']981 url = INDEX_URL982 res = self.client.post(url, formData, follow=True)983 self.assertIn("Scheduled deletion of Volume: Volume name",984 [m.message for m in res.context['messages']])985 self.mock_volume_list_paged.assert_called_with(986 test.IsHttpRequest(), marker=None,987 paginate=True, sort_dir='desc',988 search_opts=None)989 self.assertEqual(2, self.mock_volume_snapshot_list.call_count)990 self.mock_volume_delete.assert_called_once_with(test.IsHttpRequest(),991 volume.id)992 self.mock_server_list.assert_called_with(test.IsHttpRequest(),993 search_opts=None)994 self.assertEqual(8, self.mock_tenant_absolute_limits.call_count)995 @mock.patch.object(quotas, 'tenant_quota_usages')996 @mock.patch.object(cinder, 'tenant_absolute_limits')997 @mock.patch.object(cinder, 'volume_get')998 def test_delete_volume_with_snap_no_action_item(self, mock_get,999 mock_limits,1000 mock_quotas):1001 volume = self.cinder_volumes.get(name='Volume name')1002 setattr(volume, 'has_snapshot', True)1003 limits = self.cinder_limits['absolute']1004 mock_get.return_value = volume1005 mock_limits.return_value = limits1006 mock_quotas.return_value = self.cinder_quota_usages.first()1007 url = (INDEX_URL +1008 "?action=row_update&table=volumes&obj_id=" + volume.id)1009 res = self.client.get(url, {}, HTTP_X_REQUESTED_WITH='XMLHttpRequest')1010 self.assertEqual(res.status_code, 200)1011 mock_quotas.assert_called_once_with(test.IsHttpRequest(),1012 targets=('volumes', 'gigabytes'))1013 self.assert_mock_multiple_calls_with_same_arguments(1014 mock_limits, 2,1015 mock.call(test.IsHttpRequest()))1016 self.assertNotContains(res, 'Delete Volume')1017 self.assertNotContains(res, 'delete')1018 @mock.patch.object(api.nova, 'server_list')1019 @mock.patch.object(cinder, 'volume_get')1020 @override_settings(OPENSTACK_HYPERVISOR_FEATURES={'can_set_mount_point':1021 True})1022 def test_edit_attachments(self, mock_get, mock_server_list):1023 volume = self.cinder_volumes.first()1024 servers = [s for s in self.servers.list()1025 if s.tenant_id == self.request.user.tenant_id]1026 volume.attachments = [{'id': volume.id,1027 'volume_id': volume.id,1028 'volume_name': volume.name,1029 "attachment_id": ATTACHMENT_ID,1030 'instance': servers[0],1031 'device': '/dev/vdb',1032 'server_id': servers[0].id}]1033 mock_get.return_value = volume1034 mock_server_list.return_value = [servers, False]1035 url = reverse('horizon:project:volumes:attach',1036 args=[volume.id])1037 res = self.client.get(url)1038 msg = 'Volume %s on instance %s' % (volume.name, servers[0].name)1039 self.assertContains(res, msg)1040 # Asserting length of 2 accounts for the one instance option,1041 # and the one 'Choose Instance' option.1042 form = res.context['form']1043 self.assertEqual(len(form.fields['instance']._choices),1044 1)1045 self.assertEqual(res.status_code, 200)1046 self.assertIsInstance(form.fields['device'].widget,1047 widgets.TextInput)1048 self.assertFalse(form.fields['device'].required)1049 mock_get.assert_called_once_with(test.IsHttpRequest(), volume.id)1050 mock_server_list.assert_called_once()1051 @mock.patch.object(api.nova, 'server_list')1052 @mock.patch.object(cinder, 'volume_get')1053 @override_settings(OPENSTACK_HYPERVISOR_FEATURES={'can_set_mount_point':1054 True})1055 def test_edit_attachments_auto_device_name(self, mock_get,1056 mock_server_list):1057 volume = self.cinder_volumes.first()1058 servers = [s for s in self.servers.list()1059 if s.tenant_id == self.request.user.tenant_id]1060 volume.attachments = [{'id': volume.id,1061 'volume_id': volume.id,1062 'volume_name': volume.name,1063 "attachment_id": ATTACHMENT_ID,1064 'instance': servers[0],1065 'device': '',1066 'server_id': servers[0].id}]1067 mock_get.return_value = volume1068 mock_server_list.return_value = [servers, False]1069 url = reverse('horizon:project:volumes:attach',1070 args=[volume.id])1071 res = self.client.get(url)1072 form = res.context['form']1073 self.assertIsInstance(form.fields['device'].widget,1074 widgets.TextInput)1075 self.assertFalse(form.fields['device'].required)1076 mock_get.assert_called_once_with(test.IsHttpRequest(), volume.id)1077 mock_server_list.assert_called_once()1078 @mock.patch.object(api.nova, 'server_list')1079 @mock.patch.object(cinder, 'volume_get')1080 def test_edit_attachments_cannot_set_mount_point(self, mock_get,1081 mock_server_list):1082 volume = self.cinder_volumes.first()1083 url = reverse('horizon:project:volumes:attach',1084 args=[volume.id])1085 res = self.client.get(url)1086 # Assert the device field is hidden.1087 form = res.context['form']1088 self.assertIsInstance(form.fields['device'].widget,1089 widgets.HiddenInput)1090 mock_get.assert_called_once_with(test.IsHttpRequest(), volume.id)1091 mock_server_list.assert_called_once()1092 @mock.patch.object(api.nova, 'server_list')1093 @mock.patch.object(cinder, 'volume_get')1094 def test_edit_attachments_attached_volume(self, mock_get,1095 mock_server_list):1096 servers = [s for s in self.servers.list()1097 if s.tenant_id == self.request.user.tenant_id]1098 server = servers[0]1099 volume = self.cinder_volumes.list()[0]1100 mock_get.return_value = volume1101 mock_server_list.return_value = [servers, False]1102 url = reverse('horizon:project:volumes:attach',1103 args=[volume.id])1104 res = self.client.get(url)1105 self.assertEqual(res.context['form'].fields['instance']._choices[0][1],1106 "Select an instance")1107 self.assertEqual(len(res.context['form'].fields['instance'].choices),1108 2)1109 self.assertEqual(res.context['form'].fields['instance']._choices[1][0],1110 server.id)1111 self.assertEqual(res.status_code, 200)1112 mock_get.assert_called_once_with(test.IsHttpRequest(), volume.id)1113 mock_server_list.assert_called_once()1114 @mock.patch.object(quotas, 'tenant_quota_usages')1115 @mock.patch.object(cinder, 'tenant_absolute_limits')1116 @mock.patch.object(cinder, 'volume_get')1117 def test_create_snapshot_button_attributes(self, mock_get,1118 mock_limits,1119 mock_quotas):1120 limits = {'maxTotalSnapshots': 2}1121 limits['totalSnapshotsUsed'] = 11122 volume = self.cinder_volumes.first()1123 mock_get.return_value = volume1124 mock_limits.return_value = limits1125 mock_quotas.return_value = self.cinder_quota_usages.first()1126 res_url = (INDEX_URL +1127 "?action=row_update&table=volumes&obj_id=" + volume.id)1128 res = self.client.get(res_url, {},1129 HTTP_X_REQUESTED_WITH='XMLHttpRequest')1130 action_name = ('%(table)s__row_%(id)s__action_%(action)s' %1131 {'table': 'volumes', 'id': volume.id,1132 'action': 'snapshots'})1133 content = res.content.decode('utf-8')1134 self.assertIn(action_name, content)1135 self.assertIn('Create Snapshot', content)1136 self.assertIn(reverse('horizon:project:volumes:create_snapshot',1137 args=[volume.id]),1138 content)1139 self.assertNotIn('disabled', content)1140 mock_get.assert_called_once_with(test.IsHttpRequest(), volume.id)1141 mock_quotas.assert_called_once_with(test.IsHttpRequest(),1142 targets=('volumes', 'gigabytes'))1143 self.assert_mock_multiple_calls_with_same_arguments(1144 mock_limits, 2,1145 mock.call(test.IsHttpRequest()))1146 @mock.patch.object(quotas, 'tenant_quota_usages')1147 @mock.patch.object(cinder, 'tenant_absolute_limits')1148 @mock.patch.object(cinder, 'volume_get')1149 def test_create_snapshot_button_disabled_when_quota_exceeded(1150 self, mock_get, mock_limits, mock_quotas):1151 limits = {'maxTotalSnapshots': 1}1152 limits['totalSnapshotsUsed'] = limits['maxTotalSnapshots']1153 volume = self.cinder_volumes.first()1154 mock_get.return_value = volume1155 mock_limits.return_value = limits1156 mock_quotas.return_value = self.cinder_quota_usages.first()1157 res_url = (INDEX_URL +1158 "?action=row_update&table=volumes&obj_id=" + volume.id)1159 res = self.client.get(res_url, {},1160 HTTP_X_REQUESTED_WITH='XMLHttpRequest')1161 action_name = ('%(table)s__row_%(id)s__action_%(action)s' %1162 {'table': 'volumes', 'id': volume.id,1163 'action': 'snapshots'})1164 content = res.content.decode('utf-8')1165 self.assertIn(action_name, content)1166 self.assertIn('Create Snapshot (Quota exceeded)', content)1167 self.assertIn(reverse('horizon:project:volumes:create_snapshot',1168 args=[volume.id]),1169 content)1170 self.assertIn('disabled', content,1171 'The create snapshot button should be disabled')1172 mock_get.assert_called_once_with(test.IsHttpRequest(), volume.id)1173 mock_quotas.assert_called_once_with(test.IsHttpRequest(),1174 targets=('volumes', 'gigabytes'))1175 self.assert_mock_multiple_calls_with_same_arguments(1176 mock_limits, 2,1177 mock.call(test.IsHttpRequest()))1178 @test.create_mocks({1179 api.nova: ['server_list'],1180 cinder: ['volume_backup_supported',1181 'volume_snapshot_list',1182 'volume_list_paged',1183 'tenant_absolute_limits'],1184 })1185 def test_create_button_attributes(self):1186 limits = self.cinder_limits['absolute']1187 limits['maxTotalVolumes'] = 101188 limits['totalVolumesUsed'] = 11189 volumes = self.cinder_volumes.list()1190 self.mock_volume_backup_supported.return_value = True1191 self.mock_volume_list_paged.return_value = [volumes, False, False]1192 self.mock_volume_snapshot_list.return_value = []1193 self.mock_server_list.return_value = [self.servers.list(), False]1194 self.mock_tenant_absolute_limits.return_value = limits1195 res = self.client.get(INDEX_URL)1196 self.assertTemplateUsed(res, 'horizon/common/_data_table_view.html')1197 volumes = res.context['volumes_table'].data1198 self.assertItemsEqual(volumes, self.cinder_volumes.list())1199 create_action = self.getAndAssertTableAction(res, 'volumes', 'create')1200 self.assertEqual(set(['ajax-modal', 'ajax-update', 'btn-create']),1201 set(create_action.classes))1202 self.assertEqual('Create Volume',1203 six.text_type(create_action.verbose_name))1204 self.assertEqual('horizon:project:volumes:create',1205 create_action.url)1206 self.assertEqual((('volume', 'volume:create'),),1207 create_action.policy_rules)1208 self.assertEqual(5, self.mock_volume_backup_supported.call_count)1209 self.mock_volume_list_paged.assert_called_once_with(1210 test.IsHttpRequest(), sort_dir='desc', marker=None,1211 paginate=True, search_opts=None)1212 self.mock_volume_snapshot_list.assert_called_once_with(1213 test.IsHttpRequest(), search_opts=None)1214 self.mock_server_list.assert_called_once_with(test.IsHttpRequest(),1215 search_opts=None)1216 self.assertEqual(9, self.mock_tenant_absolute_limits.call_count)1217 @test.create_mocks({1218 api.nova: ['server_list'],1219 cinder: ['volume_backup_supported',1220 'volume_snapshot_list',1221 'volume_list_paged',1222 'tenant_absolute_limits'],1223 })1224 def test_create_button_disabled_when_quota_exceeded(self):1225 limits = self.cinder_limits['absolute']1226 limits['totalVolumesUsed'] = limits['maxTotalVolumes']1227 volumes = self.cinder_volumes.list()1228 self.mock_volume_backup_supported.return_value = True1229 self.mock_volume_list_paged.return_value = [volumes, False, False]1230 self.mock_volume_snapshot_list.return_value = []1231 self.mock_server_list.return_value = [self.servers.list(), False]1232 self.mock_tenant_absolute_limits.return_value = limits1233 res = self.client.get(INDEX_URL)1234 self.assertTemplateUsed(res, 'horizon/common/_data_table_view.html')1235 volumes = res.context['volumes_table'].data1236 self.assertItemsEqual(volumes, self.cinder_volumes.list())1237 create_action = self.getAndAssertTableAction(res, 'volumes', 'create')1238 self.assertIn('disabled', create_action.classes,1239 'The create button should be disabled')1240 self.assertEqual(5, self.mock_volume_backup_supported.call_count)1241 self.mock_volume_list_paged.assert_called_once_with(1242 test.IsHttpRequest(), marker=None,1243 paginate=True, sort_dir='desc',1244 search_opts=None)1245 self.mock_server_list.assert_called_once_with(test.IsHttpRequest(),1246 search_opts=None)1247 self.assertEqual(9, self.mock_tenant_absolute_limits.call_count)1248 @test.create_mocks({1249 api.nova: ['server_get'],1250 cinder: ['message_list',1251 'volume_snapshot_list',1252 'volume_get',1253 'tenant_absolute_limits'],1254 })1255 def test_detail_view(self):1256 volume = self.cinder_volumes.first()1257 server = self.servers.first()1258 snapshots = self.cinder_volume_snapshots.list()1259 volume.attachments = [{"server_id": server.id,1260 "attachment_id": ATTACHMENT_ID}]1261 self.mock_volume_get.return_value = volume1262 self.mock_volume_snapshot_list.return_value = snapshots1263 self.mock_server_get.return_value = server1264 self.mock_tenant_absolute_limits.return_value = \1265 self.cinder_limits['absolute']1266 self.mock_message_list.return_value = []1267 url = reverse('horizon:project:volumes:detail',1268 args=[volume.id])1269 res = self.client.get(url)1270 self.assertTemplateUsed(res, 'horizon/common/_detail.html')1271 self.assertEqual(res.context['volume'].id, volume.id)1272 self.assertNoMessages()1273 self.mock_volume_get.assert_called_once_with(test.IsHttpRequest(),1274 volume.id)1275 self.mock_volume_snapshot_list.assert_called_once_with(1276 test.IsHttpRequest(), search_opts={'volume_id': volume.id})1277 self.mock_server_get.assert_called_once_with(test.IsHttpRequest(),1278 server.id)1279 self.mock_tenant_absolute_limits.assert_called_once()1280 self.mock_message_list.assert_called_once_with(1281 test.IsHttpRequest(),1282 {1283 'resource_uuid': '11023e92-8008-4c8b-8059-7f2293ff3887',1284 'resource_type': 'volume',1285 })1286 @mock.patch.object(cinder, 'volume_get_encryption_metadata')1287 @mock.patch.object(cinder, 'volume_get')1288 def test_encryption_detail_view_encrypted(self, mock_get, mock_encryption):1289 enc_meta = self.cinder_volume_encryption.first()1290 volume = self.cinder_volumes.get(name='my_volume2')1291 mock_encryption.return_value = enc_meta1292 mock_get.return_value = volume1293 url = reverse('horizon:project:volumes:encryption_detail',1294 args=[volume.id])1295 res = self.client.get(url)1296 self.assertContains(res,1297 "Volume Encryption Details: %s" % volume.name,1298 2, 200)1299 self.assertContains(res, "<dd>%s</dd>" % volume.volume_type, 1, 200)1300 self.assertContains(res, "<dd>%s</dd>" % enc_meta.provider, 1, 200)1301 self.assertContains(res, "<dd>%s</dd>" % enc_meta.control_location, 1,1302 200)1303 self.assertContains(res, "<dd>%s</dd>" % enc_meta.cipher, 1, 200)1304 self.assertContains(res, "<dd>%s</dd>" % enc_meta.key_size, 1, 200)1305 self.assertNoMessages()1306 mock_encryption.assert_called_once_with(test.IsHttpRequest(),1307 volume.id)1308 mock_get.assert_called_once_with(test.IsHttpRequest(), volume.id)1309 @mock.patch.object(cinder, 'volume_get_encryption_metadata')1310 @mock.patch.object(cinder, 'volume_get')1311 def test_encryption_detail_view_unencrypted(self, mock_get,1312 mock_encryption):1313 enc_meta = self.cinder_volume_encryption.list()[1]1314 volume = self.cinder_volumes.get(name='my_volume2')1315 mock_encryption.return_value = enc_meta1316 mock_get.return_value = volume1317 url = reverse('horizon:project:volumes:encryption_detail',1318 args=[volume.id])1319 res = self.client.get(url)1320 self.assertContains(res,1321 "Volume Encryption Details: %s" % volume.name,1322 2, 200)1323 self.assertContains(res, "<h3>Volume is Unencrypted</h3>", 1, 200)1324 self.assertNoMessages()1325 mock_encryption.assert_called_once_with(test.IsHttpRequest(),1326 volume.id)1327 mock_get.assert_called_once_with(test.IsHttpRequest(), volume.id)1328 @mock.patch.object(quotas, 'tenant_quota_usages')1329 @mock.patch.object(cinder, 'tenant_absolute_limits')1330 @mock.patch.object(cinder, 'volume_get')1331 def test_get_data(self, mock_get, mock_limits, mock_quotas):1332 volume = self.cinder_volumes.get(name='v2_volume')1333 volume._apiresource.name = ""1334 mock_get.return_value = volume1335 mock_limits.return_value = self.cinder_limits['absolute']1336 mock_quotas.return_value = self.cinder_quota_usages.first()1337 url = (INDEX_URL +1338 "?action=row_update&table=volumes&obj_id=" + volume.id)1339 res = self.client.get(url, {},1340 HTTP_X_REQUESTED_WITH='XMLHttpRequest')1341 self.assertEqual(res.status_code, 200)1342 self.assertEqual(volume.name, volume.id)1343 mock_get.assert_called_once_with(test.IsHttpRequest(), volume.id)1344 mock_quotas.assert_called_once_with(test.IsHttpRequest(),1345 targets=('volumes', 'gigabytes'))1346 self.assert_mock_multiple_calls_with_same_arguments(1347 mock_limits, 2,1348 mock.call(test.IsHttpRequest()))1349 @test.create_mocks({1350 api.nova: ['server_get'],1351 cinder: ['tenant_absolute_limits',1352 'volume_get',1353 'volume_snapshot_list',1354 'message_list'],1355 })1356 def test_detail_view_snapshot_tab(self):1357 volume = self.cinder_volumes.first()1358 server = self.servers.first()1359 snapshots = self.cinder_volume_snapshots.list()1360 this_volume_snapshots = [snapshot for snapshot in snapshots1361 if snapshot.volume_id == volume.id]1362 volume.attachments = [{"server_id": server.id,1363 "attachment_id": ATTACHMENT_ID}]1364 self.mock_volume_get.return_value = volume1365 self.mock_server_get.return_value = server1366 self.mock_tenant_absolute_limits.return_value = \1367 self.cinder_limits['absolute']1368 self.mock_message_list.return_value = []1369 self.mock_volume_snapshot_list.return_value = this_volume_snapshots1370 url = '?'.join([reverse(DETAIL_URL, args=[volume.id]),1371 '='.join(['tab', 'volume_details__snapshots_tab'])])1372 res = self.client.get(url)1373 self.assertTemplateUsed(res, 'horizon/common/_detail.html')1374 self.assertEqual(res.context['volume'].id, volume.id)1375 self.assertEqual(len(res.context['table'].data),1376 len(this_volume_snapshots))1377 self.assertNoMessages()1378 self.mock_volume_get.assert_called_once_with(test.IsHttpRequest(),1379 volume.id)1380 self.mock_volume_snapshot_list.assert_called_once_with(1381 test.IsHttpRequest(), search_opts={'volume_id': volume.id})1382 self.mock_tenant_absolute_limits.assert_called_once()1383 self.mock_message_list.assert_called_once_with(1384 test.IsHttpRequest(),1385 {1386 'resource_uuid': volume.id,1387 'resource_type': 'volume'1388 })1389 @mock.patch.object(cinder, 'volume_get')1390 def test_detail_view_with_exception(self, mock_get):1391 volume = self.cinder_volumes.first()1392 server = self.servers.first()1393 volume.attachments = [{"server_id": server.id,1394 "attachment_id": ATTACHMENT_ID}]1395 mock_get.side_effect = self.exceptions.cinder1396 url = reverse('horizon:project:volumes:detail',1397 args=[volume.id])1398 res = self.client.get(url)1399 self.assertRedirectsNoFollow(res, INDEX_URL)1400 mock_get.assert_called_once_with(test.IsHttpRequest(), volume.id)1401 @test.create_mocks({cinder: ['volume_update',1402 'volume_set_bootable',1403 'volume_get']})1404 def test_update_volume(self):1405 volume = self.cinder_volumes.get(name="my_volume")1406 self.mock_volume_get.return_value = volume1407 formData = {'method': 'UpdateForm',1408 'name': volume.name,1409 'description': volume.description,1410 'bootable': False}1411 url = reverse('horizon:project:volumes:update',1412 args=[volume.id])1413 res = self.client.post(url, formData)1414 self.assertRedirectsNoFollow(res, INDEX_URL)1415 self.mock_volume_get.assert_called_once_with(1416 test.IsHttpRequest(), volume.id)1417 self.mock_volume_update.assert_called_once_with(1418 test.IsHttpRequest(), volume.id, volume.name, volume.description)1419 self.mock_volume_set_bootable.assert_called_once_with(1420 test.IsHttpRequest(), volume.id, False)1421 @test.create_mocks({cinder: ['volume_update',1422 'volume_set_bootable',1423 'volume_get']})1424 def test_update_volume_without_name(self):1425 volume = self.cinder_volumes.get(name="my_volume")1426 self.mock_volume_get.return_value = volume1427 formData = {'method': 'UpdateForm',1428 'name': '',1429 'description': volume.description,1430 'bootable': False}1431 url = reverse('horizon:project:volumes:update',1432 args=[volume.id])1433 res = self.client.post(url, formData)1434 self.assertRedirectsNoFollow(res, INDEX_URL)1435 self.mock_volume_get.assert_called_once_with(test.IsHttpRequest(),1436 volume.id)1437 self.mock_volume_update.assert_called_once_with(1438 test.IsHttpRequest(), volume.id, '', volume.description)1439 self.mock_volume_set_bootable.assert_called_once_with(1440 test.IsHttpRequest(), volume.id, False)1441 @test.create_mocks({cinder: ['volume_update',1442 'volume_set_bootable',1443 'volume_get']})1444 def test_update_volume_bootable_flag(self):1445 volume = self.cinder_bootable_volumes.get(name="my_volume")1446 self.mock_volume_get.return_value = volume1447 formData = {'method': 'UpdateForm',1448 'name': volume.name,1449 'description': 'update bootable flag',1450 'bootable': True}1451 url = reverse('horizon:project:volumes:update',1452 args=[volume.id])1453 res = self.client.post(url, formData)1454 self.assertRedirectsNoFollow(res, INDEX_URL)1455 self.mock_volume_get.assert_called_once_with(test.IsHttpRequest(),1456 volume.id)1457 self.mock_volume_update.assert_called_once_with(1458 test.IsHttpRequest(), volume.id, volume.name,1459 'update bootable flag')1460 self.mock_volume_set_bootable.assert_called_once_with(1461 test.IsHttpRequest(), volume.id, True)1462 @mock.patch.object(cinder, 'volume_upload_to_image')1463 @mock.patch.object(cinder, 'volume_get')1464 def test_upload_to_image(self, mock_get, mock_upload):1465 volume = self.cinder_volumes.get(name='v2_volume')1466 loaded_resp = {'container_format': 'bare',1467 'disk_format': 'raw',1468 'id': '741fe2ac-aa2f-4cec-82a9-4994896b43fb',1469 'image_id': '2faa080b-dd56-4bf0-8f0a-0d4627d8f306',1470 'image_name': 'test',1471 'size': '2',1472 'status': 'uploading'}1473 form_data = {'id': volume.id,1474 'name': volume.name,1475 'image_name': 'testimage',1476 'force': True,1477 'container_format': 'bare',1478 'disk_format': 'raw'}1479 mock_get.return_value = volume1480 mock_upload.return_value = loaded_resp1481 url = reverse('horizon:project:volumes:upload_to_image',1482 args=[volume.id])1483 res = self.client.post(url, form_data)1484 self.assertNoFormErrors(res)1485 self.assertMessageCount(info=1)1486 redirect_url = INDEX_URL1487 self.assertRedirectsNoFollow(res, redirect_url)1488 mock_get.assert_called_once_with(test.IsHttpRequest(), volume.id)1489 mock_upload.assert_called_once_with(test.IsHttpRequest(),1490 form_data['id'],1491 form_data['force'],1492 form_data['image_name'],1493 form_data['container_format'],1494 form_data['disk_format'])1495 @mock.patch.object(quotas, 'tenant_quota_usages')1496 @mock.patch.object(cinder, 'volume_extend')1497 @mock.patch.object(cinder, 'volume_get')1498 def test_extend_volume(self, mock_get, mock_extend, mock_quotas):1499 volume = self.cinder_volumes.first()1500 formData = {'name': u'A Volume I Am Making',1501 'orig_size': volume.size,1502 'new_size': 120}1503 mock_get.return_value = volume1504 mock_quotas.return_value = self.cinder_quota_usages.first()1505 mock_extend.return_value = volume1506 url = reverse('horizon:project:volumes:extend',1507 args=[volume.id])1508 res = self.client.post(url, formData)1509 redirect_url = INDEX_URL1510 self.assertRedirectsNoFollow(res, redirect_url)1511 mock_get.assert_called_once_with(test.IsHttpRequest(), volume.id)1512 mock_quotas.assert_called_once()1513 mock_extend.assert_called_once_with(test.IsHttpRequest(), volume.id,1514 formData['new_size'])1515 @mock.patch.object(quotas, 'tenant_quota_usages')1516 @mock.patch.object(cinder, 'volume_get')1517 def test_extend_volume_with_wrong_size(self, mock_get, mock_quotas):1518 volume = self.cinder_volumes.first()1519 formData = {'name': u'A Volume I Am Making',1520 'orig_size': volume.size,1521 'new_size': 10}1522 mock_get.return_value = volume1523 mock_quotas.return_value = self.cinder_quota_usages.first()1524 url = reverse('horizon:project:volumes:extend',1525 args=[volume.id])1526 res = self.client.post(url, formData)1527 self.assertFormErrors(res, 1,1528 "New size must be greater than "1529 "current size.")1530 mock_get.assert_called_once_with(test.IsHttpRequest(), volume.id)1531 mock_quotas.assert_called_once()1532 @mock.patch.object(quotas, 'tenant_quota_usages')1533 @mock.patch.object(cinder, 'tenant_absolute_limits')1534 @mock.patch.object(cinder, 'volume_get')1535 def test_retype_volume_supported_action_item(self, mock_get,1536 mock_limits, mock_quotas):1537 volume = self.cinder_volumes.get(name='v2_volume')1538 limits = self.cinder_limits['absolute']1539 mock_get.return_value = volume1540 mock_limits.return_value = limits1541 mock_quotas.return_value = self.cinder_quota_usages.first()1542 url = (INDEX_URL +1543 "?action=row_update&table=volumes&obj_id=" + volume.id)1544 res = self.client.get(url, {}, HTTP_X_REQUESTED_WITH='XMLHttpRequest')1545 self.assertEqual(res.status_code, 200)1546 self.assertContains(res, 'Change Volume Type')1547 self.assertContains(res, 'retype')1548 mock_get.assert_called_once_with(test.IsHttpRequest(), volume.id)1549 mock_quotas.assert_called_once_with(test.IsHttpRequest(),1550 targets=('volumes', 'gigabytes'))1551 self.assert_mock_multiple_calls_with_same_arguments(1552 mock_limits, 2,1553 mock.call(test.IsHttpRequest()))1554 @test.create_mocks({1555 cinder: ['volume_type_list',1556 'volume_retype',1557 'volume_get']1558 })1559 def test_retype_volume(self):1560 volume = self.cinder_volumes.get(name='my_volume2')1561 volume_type = self.cinder_volume_types.get(name='vol_type_1')1562 form_data = {'id': volume.id,1563 'name': volume.name,1564 'volume_type': volume_type.name,1565 'migration_policy': 'on-demand'}1566 self.mock_volume_get.return_value = volume1567 self.mock_volume_type_list.return_value = \1568 self.cinder_volume_types.list()1569 self.mock_volume_retype.return_value = True1570 url = reverse('horizon:project:volumes:retype',1571 args=[volume.id])1572 res = self.client.post(url, form_data)1573 self.assertNoFormErrors(res)1574 redirect_url = INDEX_URL1575 self.assertRedirectsNoFollow(res, redirect_url)1576 self.mock_volume_get.assert_called_once_with(test.IsHttpRequest(),1577 volume.id)1578 self.mock_volume_type_list.assert_called_once()1579 self.mock_volume_retype.assert_called_once_with(1580 test.IsHttpRequest(), volume.id,1581 form_data['volume_type'], form_data['migration_policy'])1582 def test_encryption_false(self):1583 self._test_encryption(False)1584 def test_encryption_true(self):1585 self._test_encryption(True)1586 @test.create_mocks({1587 api.nova: ['server_list'],1588 cinder: ['volume_backup_supported',1589 'volume_list_paged',1590 'volume_snapshot_list',1591 'tenant_absolute_limits'],1592 })1593 def _test_encryption(self, encryption):1594 volumes = self.cinder_volumes.list()1595 for volume in volumes:1596 volume.encrypted = encryption1597 limits = self.cinder_limits['absolute']1598 self.mock_volume_backup_supported.return_value = False1599 self.mock_volume_list_paged.return_value = [self.cinder_volumes.list(),1600 False, False]1601 self.mock_volume_snapshot_list.return_value = \1602 self.cinder_volume_snapshots.list()1603 self.mock_server_list.return_value = [self.servers.list(), False]1604 self.mock_tenant_absolute_limits.return_value = limits1605 res = self.client.get(INDEX_URL)1606 rows = res.context['volumes_table'].get_rows()1607 column_value = 'Yes' if encryption else 'No'1608 for row in rows:1609 self.assertEqual(row.cells['encryption'].data, column_value)1610 self.assertEqual(10, self.mock_volume_backup_supported.call_count)1611 self.mock_volume_list_paged.assert_called_once_with(1612 test.IsHttpRequest(), marker=None,1613 sort_dir='desc', search_opts=None,1614 paginate=True)1615 self.mock_volume_snapshot_list.assert_called_once_with(1616 test.IsHttpRequest(), search_opts=None)1617 self.assertEqual(13, self.mock_tenant_absolute_limits.call_count)1618 @mock.patch.object(quotas, 'tenant_quota_usages')1619 @mock.patch.object(cinder, 'volume_get')1620 def test_extend_volume_with_size_out_of_quota(self, mock_get, mock_quotas):1621 volume = self.cinder_volumes.first()1622 usage_limit = self.cinder_quota_usages.first()1623 usage_limit.add_quota(api.base.Quota('gigabytes', 100))1624 usage_limit.tally('gigabytes', 20)1625 usage_limit.tally('volumes', len(self.cinder_volumes.list()))1626 formData = {'name': u'A Volume I Am Making',1627 'orig_size': volume.size,1628 'new_size': 1000}1629 mock_quotas.return_value = usage_limit1630 mock_get.return_value = volume1631 url = reverse('horizon:project:volumes:extend',1632 args=[volume.id])1633 res = self.client.post(url, formData)1634 self.assertFormError(res, "form", "new_size",1635 "Volume cannot be extended to 1000GiB as "1636 "the maximum size it can be extended to is "1637 "120GiB.")1638 mock_get.assert_called_once_with(test.IsHttpRequest(), volume.id)1639 self.assertEqual(2, mock_quotas.call_count)1640 @test.create_mocks({1641 api.nova: ['server_list'],1642 cinder: ['volume_backup_supported',1643 'volume_list_paged',1644 'volume_snapshot_list',1645 'tenant_absolute_limits'],1646 })1647 def test_create_transfer_availability(self):1648 limits = self.cinder_limits['absolute']1649 self.mock_volume_backup_supported.return_value = False1650 self.mock_volume_list_paged.return_value = [self.cinder_volumes.list(),1651 False, False]1652 self.mock_volume_snapshot_list.return_value = []1653 self.mock_server_list.return_value = [self.servers.list(), False]1654 self.mock_tenant_absolute_limits.return_value = limits1655 res = self.client.get(INDEX_URL)1656 table = res.context['volumes_table']1657 # Verify that the create transfer action is present if and only if1658 # the volume is available1659 for vol in table.data:1660 actions = [a.name for a in table.get_row_actions(vol)]1661 self.assertEqual('create_transfer' in actions,1662 vol.status == 'available')1663 self.assertEqual(10, self.mock_volume_backup_supported.call_count)1664 self.mock_volume_list_paged.assert_called_once_with(1665 test.IsHttpRequest(), marker=None,1666 sort_dir='desc', search_opts=None,1667 paginate=True)1668 self.mock_volume_snapshot_list.assert_called_once_with(1669 test.IsHttpRequest(), search_opts=None)1670 self.mock_server_list.assert_called_once_with(test.IsHttpRequest(),1671 search_opts=None)1672 self.assertEqual(13, self.mock_tenant_absolute_limits.call_count)1673 @mock.patch.object(cinder, 'transfer_get')1674 @mock.patch.object(cinder, 'transfer_create')1675 def test_create_transfer(self, mock_transfer_create, mock_transfer_get):1676 volumes = self.cinder_volumes.list()1677 volToTransfer = [v for v in volumes if v.status == 'available'][0]1678 formData = {'volume_id': volToTransfer.id,1679 'name': u'any transfer name'}1680 transfer = self.cinder_volume_transfers.first()1681 mock_transfer_create.return_value = transfer1682 mock_transfer_get.return_value = transfer1683 # Create a transfer for the first available volume1684 url = reverse('horizon:project:volumes:create_transfer',1685 args=[volToTransfer.id])1686 res = self.client.post(url, formData)1687 self.assertNoFormErrors(res)1688 mock_transfer_create.assert_called_once_with(test.IsHttpRequest(),1689 formData['volume_id'],1690 formData['name'])1691 mock_transfer_get.assert_called_once_with(test.IsHttpRequest(),1692 transfer.id)1693 @test.create_mocks({1694 api.nova: ['server_list'],1695 cinder: ['volume_backup_supported',1696 'volume_list_paged',1697 'volume_snapshot_list',1698 'transfer_delete',1699 'tenant_absolute_limits'],1700 })1701 def test_delete_transfer(self):1702 transfer = self.cinder_volume_transfers.first()1703 volumes = []1704 # Attach the volume transfer to the relevant volume1705 for v in self.cinder_volumes.list():1706 if v.id == transfer.volume_id:1707 v.status = 'awaiting-transfer'1708 v.transfer = transfer1709 volumes.append(v)1710 formData = {'action':1711 'volumes__delete_transfer__%s' % transfer.volume_id}1712 self.mock_volume_backup_supported.return_value = False1713 self.mock_volume_list_paged.return_value = [volumes, False, False]1714 self.mock_volume_snapshot_list.return_value = []1715 self.mock_server_list.return_value = [self.servers.list(), False]1716 self.mock_tenant_absolute_limits.return_value = \1717 self.cinder_limits['absolute']1718 url = INDEX_URL1719 res = self.client.post(url, formData, follow=True)1720 self.assertNoFormErrors(res)1721 self.assertIn('Successfully deleted volume transfer "test transfer"',1722 [m.message for m in res.context['messages']])1723 self.assertEqual(5, self.mock_volume_backup_supported.call_count)1724 self.mock_volume_list_paged.assert_called_once_with(1725 test.IsHttpRequest(), marker=None,1726 search_opts=None, sort_dir='desc',1727 paginate=True)1728 self.mock_volume_snapshot_list.assert_called_once_with(1729 test.IsHttpRequest(), search_opts=None)1730 self.mock_transfer_delete.assert_called_once_with(test.IsHttpRequest(),1731 transfer.id)1732 self.mock_server_list.assert_called_once_with(test.IsHttpRequest(),1733 search_opts=None)1734 self.assertEqual(8, self.mock_tenant_absolute_limits.call_count)1735 @test.create_mocks({1736 api.nova: ['server_list'],1737 cinder: ['volume_list_paged',1738 'volume_snapshot_list',1739 'tenant_absolute_limits',1740 'transfer_accept']1741 })1742 def test_accept_transfer(self):1743 transfer = self.cinder_volume_transfers.first()1744 self.mock_tenant_absolute_limits.return_value = \1745 self.cinder_limits['absolute']1746 formData = {'transfer_id': transfer.id, 'auth_key': transfer.auth_key}1747 url = reverse('horizon:project:volumes:accept_transfer')1748 res = self.client.post(url, formData, follow=True)1749 self.assertNoFormErrors(res)1750 self.mock_transfer_accept.assert_called_once_with(test.IsHttpRequest(),1751 transfer.id,1752 transfer.auth_key)1753 self.assertEqual(3, self.mock_tenant_absolute_limits.call_count)1754 self.mock_server_list.assert_called_once()1755 self.mock_volume_list_paged.assert_called_once()1756 self.mock_volume_snapshot_list.assert_called_once()1757 self.mock_transfer_accept.assert_called_once()1758 @mock.patch.object(cinder, 'transfer_get')1759 def test_download_transfer_credentials(self, mock_transfer):1760 transfer = self.cinder_volume_transfers.first()1761 filename = "{}.txt".format(slugify(transfer.id))1762 url = reverse('horizon:project:volumes:'1763 'download_transfer_creds',1764 kwargs={'transfer_id': transfer.id,1765 'auth_key': transfer.auth_key})1766 res = self.client.get(url)1767 self.assertTrue(res.has_header('content-disposition'))1768 self.assertTrue(res.has_header('content-type'))1769 self.assertEqual(res.get('content-disposition'),1770 'attachment; filename={}'.format(filename))1771 self.assertEqual(res.get('content-type'), 'application/text')1772 self.assertIn(transfer.id, res.content.decode('utf-8'))1773 self.assertIn(transfer.auth_key, res.content.decode('utf-8'))1774 mock_transfer.assert_called_once_with(test.IsHttpRequest(),1775 transfer.id)1776 @test.create_mocks({1777 api.nova: ['server_list'],1778 cinder: ['volume_backup_supported',1779 'volume_list_paged',1780 'volume_snapshot_list',1781 'tenant_absolute_limits',1782 'volume_get'],1783 })1784 def test_create_backup_availability(self):1785 limits = self.cinder_limits['absolute']1786 self.mock_volume_backup_supported.return_value = True1787 self.mock_volume_list_paged.return_value = [self.cinder_volumes.list(),1788 False, False]1789 self.mock_volume_snapshot_list.return_value = []1790 self.mock_server_list.return_value = [self.servers.list(), False]1791 self.mock_tenant_absolute_limits.return_value = limits1792 res = self.client.get(INDEX_URL)1793 table = res.context['volumes_table']1794 # Verify that the create backup action is present if and only if1795 # the volume is available or in-use1796 for vol in table.data:1797 actions = [a.name for a in table.get_row_actions(vol)]1798 self.assertEqual('backups' in actions,1799 vol.status in ('available', 'in-use'))1800 self.assertEqual(10, self.mock_volume_backup_supported.call_count)1801 self.mock_volume_list_paged.assert_called_once_with(1802 test.IsHttpRequest(), marker=None,1803 sort_dir='desc', search_opts=None,1804 paginate=True)1805 self.mock_volume_snapshot_list.assert_called_once_with(1806 test.IsHttpRequest(), search_opts=None)1807 self.mock_server_list.assert_called_once_with(test.IsHttpRequest(),1808 search_opts=None)...

Full Screen

Full Screen

test_nova.py

Source:test_nova.py Github

copy

Full Screen

1# Copyright 2014, Rackspace, US, Inc.2#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 at6#7# http://www.apache.org/licenses/LICENSE-2.08#9# Unless required by applicable law or agreed to in writing, software10# 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 and13# limitations under the License.14import json15from json import loads as to_json16import uuid17from django.conf import settings18import mock19from openstack_dashboard import api20from openstack_dashboard.api.base import Quota21from openstack_dashboard.api.rest import nova22from openstack_dashboard.test import helpers as test23from openstack_dashboard.usage import quotas24# NOTE(flwang): mock.Mock and mock.MagicMock do not support sort, so the test25# case involved sorted will fail. This fake class is for the flavor test cases26# related to sort.27class FakeFlavor(object):28 def __init__(self, id, ram=1):29 self.id = id30 self.ram = ram31 self.extras = {}32 def to_dict(self):33 return {"id": self.id}34class NovaRestTestCase(test.TestCase):35 #36 # Snapshots37 #38 @test.create_mocks({api.nova: ['snapshot_create']})39 def test_snapshots_create(self):40 body = '{"instance_id": "1234", "name": "foo"}'41 request = self.mock_rest_request(body=body)42 self.mock_snapshot_create.return_value = {'id': 'abcd', 'name': 'foo'}43 response = nova.Snapshots().post(request)44 self.assertStatusCode(response, 200)45 self.assertEqual(response.json, {'id': 'abcd', 'name': 'foo'})46 self.mock_snapshot_create.assert_called_once_with(request,47 instance_id='1234',48 name='foo')49 #50 # Server Actions51 #52 @test.create_mocks({api.nova: ['instance_action_list']})53 def test_serveractions_list(self):54 request = self.mock_rest_request()55 self.mock_instance_action_list.return_value = [56 mock.Mock(**{'to_dict.return_value': {'id': '1'}}),57 mock.Mock(**{'to_dict.return_value': {'id': '2'}}),58 ]59 response = nova.ServerActions().get(request, 'MegaMan')60 self.assertStatusCode(response, 200)61 self.assertEqual(response.json, {'items': [{'id': '1'}, {'id': '2'}]})62 self.mock_instance_action_list.assert_called_once_with(request,63 'MegaMan')64 @test.create_mocks({api.nova: ['server_start']})65 def test_server_start(self):66 self.mock_server_start.return_value = None67 request = self.mock_rest_request(body='{"operation": "start"}')68 response = nova.Server().post(request, 'MegaMan')69 self.assertStatusCode(response, 204)70 self.mock_server_start.assert_called_once_with(request, 'MegaMan')71 @test.create_mocks({api.nova: ['server_stop']})72 def test_server_stop(self):73 self.mock_server_stop.return_value = None74 request = self.mock_rest_request(body='{"operation": "stop"}')75 response = nova.Server().post(request, 'MegaMan')76 self.assertStatusCode(response, 204)77 self.mock_server_stop.assert_called_once_with(request, 'MegaMan')78 @test.create_mocks({api.nova: ['server_pause']})79 def test_server_pause(self):80 self.mock_server_pause.return_value = None81 request = self.mock_rest_request(body='{"operation": "pause"}')82 response = nova.Server().post(request, 'MegaMan')83 self.assertStatusCode(response, 204)84 self.mock_server_pause.assert_called_once_with(request, 'MegaMan')85 @test.create_mocks({api.nova: ['server_unpause']})86 def test_server_unpause(self):87 self.mock_server_unpause.return_value = None88 request = self.mock_rest_request(body='{"operation": "unpause"}')89 response = nova.Server().post(request, 'MegaMan')90 self.assertStatusCode(response, 204)91 self.mock_server_unpause.assert_called_once_with(request, 'MegaMan')92 @test.create_mocks({api.nova: ['server_suspend']})93 def test_server_suspend(self):94 self.mock_server_suspend.return_value = None95 request = self.mock_rest_request(body='{"operation": "suspend"}')96 response = nova.Server().post(request, 'MegaMan')97 self.assertStatusCode(response, 204)98 self.mock_server_suspend.assert_called_once_with(request, 'MegaMan')99 @test.create_mocks({api.nova: ['server_resume']})100 def test_server_resume(self):101 self.mock_server_resume.return_value = None102 request = self.mock_rest_request(body='{"operation": "resume"}')103 response = nova.Server().post(request, 'MegaMan')104 self.assertStatusCode(response, 204)105 self.mock_server_resume.assert_called_once_with(request, 'MegaMan')106 @test.create_mocks({api.nova: ['server_reboot']})107 def test_server_hard_reboot(self):108 self.mock_server_reboot.return_value = None109 request = self.mock_rest_request(body='{"operation": "hard_reboot"}')110 response = nova.Server().post(request, 'MegaMan')111 self.assertStatusCode(response, 204)112 self.mock_server_reboot.assert_called_once_with(request, 'MegaMan',113 False)114 @test.create_mocks({api.nova: ['server_reboot']})115 def test_server_soft_reboot(self):116 self.mock_server_reboot.return_value = None117 request = self.mock_rest_request(body='{"operation": "soft_reboot"}')118 response = nova.Server().post(request, 'MegaMan')119 self.assertStatusCode(response, 204)120 self.mock_server_reboot.assert_called_once_with(request, 'MegaMan',121 True)122 #123 # Security Groups124 #125 @test.create_mocks({api.neutron: ['server_security_groups']})126 def test_securitygroups_list(self):127 request = self.mock_rest_request()128 self.mock_server_security_groups.return_value = [129 mock.Mock(**{'to_dict.return_value': {'id': '1'}}),130 mock.Mock(**{'to_dict.return_value': {'id': '2'}}),131 ]132 response = nova.SecurityGroups().get(request, 'MegaMan')133 self.assertStatusCode(response, 200)134 self.assertEqual(response.json, {'items': [{'id': '1'}, {'id': '2'}]})135 self.mock_server_security_groups.assert_called_once_with(request,136 'MegaMan')137 #138 # Console Output139 #140 @test.create_mocks({api.nova: ['server_console_output']})141 def test_console_output(self):142 request = self.mock_rest_request(body='{"length": 50}')143 self.mock_server_console_output.return_value = "this\nis\ncool"144 response = nova.ConsoleOutput().post(request, 'MegaMan')145 self.assertStatusCode(response, 200)146 self.assertEqual(response.json, {'lines': ["this", "is", "cool"]})147 self.mock_server_console_output.assert_called_once_with(request,148 'MegaMan',149 tail_length=50)150 #151 # Remote Console Info152 #153 @test.create_mocks({api.nova: ['server_serial_console']})154 def test_console_info(self):155 request = self.mock_rest_request(body='{"console_type": "SERIAL"}')156 retval = mock.Mock(**{"url": "http://here.com"})157 self.mock_server_serial_console.return_value = retval158 response = nova.RemoteConsoleInfo().post(request, 'MegaMan')159 self.assertStatusCode(response, 200)160 self.assertEqual(response.json,161 {"type": "SERIAL", "url": "http://here.com"})162 self.mock_server_serial_console.assert_called_once_with(request,163 'MegaMan')164 #165 # Volumes166 #167 @test.create_mocks({api.nova: ['instance_volumes_list']})168 def test_volumes_list(self):169 request = self.mock_rest_request()170 self.mock_instance_volumes_list.return_value = [171 mock.Mock(**{'to_dict.return_value': {'id': '1'}}),172 mock.Mock(**{'to_dict.return_value': {'id': '2'}}),173 ]174 response = nova.Volumes().get(request, 'MegaMan')175 self.assertStatusCode(response, 200)176 self.assertEqual(response.json, {'items': [{'id': '1'}, {'id': '2'}]})177 self.mock_instance_volumes_list.assert_called_once_with(request,178 'MegaMan')179 #180 # Keypairs181 #182 @test.create_mocks({api.nova: ['keypair_list']})183 def test_keypair_list(self):184 request = self.mock_rest_request()185 self.mock_keypair_list.return_value = [186 mock.Mock(**{'to_dict.return_value': {'id': 'one'}}),187 mock.Mock(**{'to_dict.return_value': {'id': 'two'}}),188 ]189 response = nova.Keypairs().get(request)190 self.assertStatusCode(response, 200)191 self.assertEqual({"items": [{"id": "one"}, {"id": "two"}]},192 response.json)193 self.mock_keypair_list.assert_called_once_with(request)194 @test.create_mocks({api.nova: ['keypair_create']})195 def test_keypair_create(self):196 request = self.mock_rest_request(body='''{"name": "Ni!",197 "key_type": "ssh"}''')198 new = self.mock_keypair_create.return_value199 new.to_dict.return_value = {'name': 'Ni!',200 'key_type': 'ssh',201 'public_key': 'sekrit'}202 new.name = 'Ni!'203 with mock.patch.object(settings, 'DEBUG', True):204 response = nova.Keypairs().post(request)205 self.assertStatusCode(response, 201)206 self.assertEqual({"name": "Ni!",207 "key_type": "ssh",208 "public_key": "sekrit"},209 response.json)210 self.assertEqual('/api/nova/keypairs/Ni%21', response['location'])211 self.mock_keypair_create.assert_called_once_with(request, 'Ni!', 'ssh')212 @test.create_mocks({api.nova: ['keypair_import']})213 def test_keypair_import(self):214 request = self.mock_rest_request(body='''215 {"name": "Ni!", "public_key": "hi", "key_type": "ssh"}216 ''')217 new = self.mock_keypair_import.return_value218 new.to_dict.return_value = {'name': 'Ni!',219 'public_key': 'hi',220 'key_type': 'ssh'}221 new.name = 'Ni!'222 with mock.patch.object(settings, 'DEBUG', True):223 response = nova.Keypairs().post(request)224 self.assertStatusCode(response, 201)225 self.assertEqual({"name": "Ni!",226 "public_key": "hi",227 "key_type": "ssh"},228 response.json)229 self.assertEqual('/api/nova/keypairs/Ni%21', response['location'])230 self.mock_keypair_import.assert_called_once_with(request,231 'Ni!',232 'hi',233 'ssh')234 @test.create_mocks({api.nova: ['keypair_get']})235 def test_keypair_get(self):236 request = self.mock_rest_request()237 self.mock_keypair_get.return_value.to_dict.return_value = {'name': '1'}238 response = nova.Keypair().get(request, '1')239 self.assertStatusCode(response, 200)240 self.assertEqual({"name": "1"},241 response.json)242 self.mock_keypair_get.assert_called_once_with(request, "1")243 @test.create_mocks({api.nova: ['keypair_delete']})244 def test_keypair_delete(self):245 self.mock_keypair_delete.return_value = None246 request = self.mock_rest_request()247 nova.Keypair().delete(request, "1")248 self.mock_keypair_delete.assert_called_once_with(request, "1")249 #250 # Availability Zones251 #252 def test_availzone_get_brief(self):253 self._test_availzone_get(False)254 def test_availzone_get_detailed(self):255 self._test_availzone_get(True)256 @test.create_mocks({api.nova: ['availability_zone_list']})257 def _test_availzone_get(self, detail):258 if detail:259 request = self.mock_rest_request(GET={'detailed': 'true'})260 else:261 request = self.mock_rest_request(GET={})262 self.mock_availability_zone_list.return_value = [263 mock.Mock(**{'to_dict.return_value': {'id': 'one'}}),264 mock.Mock(**{'to_dict.return_value': {'id': 'two'}}),265 ]266 response = nova.AvailabilityZones().get(request)267 self.assertStatusCode(response, 200)268 self.assertEqual({"items": [{"id": "one"}, {"id": "two"}]},269 response.json)270 self.mock_availability_zone_list.assert_called_once_with(request,271 detail)272 #273 # Limits274 #275 def test_limits_get_not_reserved(self):276 self._test_limits_get(False)277 def test_limits_get_reserved(self):278 self._test_limits_get(True)279 @test.create_mocks({api.nova: ['tenant_absolute_limits']})280 def _test_limits_get(self, reserved):281 if reserved:282 request = self.mock_rest_request(GET={'reserved': 'true'})283 else:284 request = self.mock_rest_request(GET={})285 self.mock_tenant_absolute_limits.return_value = {'id': 'one'}286 response = nova.Limits().get(request)287 self.assertStatusCode(response, 200)288 self.mock_tenant_absolute_limits.assert_called_once_with(request,289 reserved)290 self.assertEqual({"id": "one"}, response.json)291 #292 # Servers293 #294 def test_server_create_missing(self):295 request = self.mock_rest_request(body='''{"name": "hi"}''')296 response = nova.Servers().post(request)297 self.assertStatusCode(response, 400)298 self.assertEqual("missing required parameter 'source_id'",299 response.json)300 @test.create_mocks({api.nova: ['server_create']})301 def test_server_create_basic(self):302 request = self.mock_rest_request(body='''{"name": "Ni!",303 "source_id": "image123", "flavor_id": "flavor123",304 "key_name": "sekrit", "user_data": "base64 yes",305 "security_groups": [{"name": "root"}]}306 ''')307 new = self.mock_server_create.return_value308 new.to_dict.return_value = {'id': 'server123'}309 new.id = 'server123'310 response = nova.Servers().post(request)311 self.assertStatusCode(response, 201)312 self.assertEqual({"id": "server123"}, response.json)313 self.assertEqual('/api/nova/servers/server123', response['location'])314 self.mock_server_create.assert_called_once_with(315 request, 'Ni!', 'image123', 'flavor123', 'sekrit', 'base64 yes',316 [{'name': 'root'}]317 )318 @test.create_mocks({api.nova: ['server_create']})319 def test_server_create_with_leading_trailing_space(self):320 request = self.mock_rest_request(body='''{"name": " Ni! ",321 "source_id": "image123", "flavor_id": "flavor123",322 "key_name": "sekrit", "user_data": "base64 yes",323 "security_groups": [{"name": "root"}]}324 ''')325 new = self.mock_server_create.return_value326 new.to_dict.return_value = {'name': ' Ni! '.strip()}327 new.id = str(uuid.uuid4())328 response = nova.Servers().post(request)329 self.assertStatusCode(response, 201)330 self.assertEqual({"name": "Ni!"}, response.json)331 self.mock_server_create.assert_called_once_with(332 request, ' Ni! ', 'image123', 'flavor123', 'sekrit', 'base64 yes',333 [{'name': 'root'}])334 @test.create_mocks({api.nova: ['server_list']})335 def test_server_list(self):336 request = self.mock_rest_request()337 self.mock_server_list.return_value = ([338 mock.Mock(**{'to_dict.return_value': {'id': 'one'}}),339 mock.Mock(**{'to_dict.return_value': {'id': 'two'}}),340 ], False)341 response = nova.Servers().get(request)342 self.assertStatusCode(response, 200)343 self.assertEqual({'items': [{'id': 'one'}, {'id': 'two'}]},344 response.json)345 self.mock_server_list.assert_called_once_with(request)346 @test.create_mocks({api.nova: ['server_get']})347 def test_server_get_single(self):348 request = self.mock_rest_request()349 self.mock_server_get.return_value.to_dict.return_value = {'name': '1'}350 response = nova.Server().get(request, "1")351 self.assertStatusCode(response, 200)352 self.mock_server_get.assert_called_once_with(request, "1")353 #354 # Server Groups355 #356 @test.create_mocks({api.nova: ['server_group_list']})357 def test_server_group_list(self):358 request = self.mock_rest_request()359 self.mock_server_group_list.return_value = [360 mock.Mock(**{'to_dict.return_value': {'id': '1'}}),361 mock.Mock(**{'to_dict.return_value': {'id': '2'}}),362 ]363 response = nova.ServerGroups().get(request)364 self.assertStatusCode(response, 200)365 self.assertEqual({'items': [{'id': '1'}, {'id': '2'}]},366 response.json)367 self.mock_server_group_list.assert_called_once_with(request)368 @test.create_mocks({api.nova: ['server_group_create']})369 def test_server_group_create(self):370 req_data = json.dumps({371 'name': 'server_group', 'policies': ['affinity']})372 self.mock_server_group_create.return_value = mock.Mock(**{373 'id': '123',374 'to_dict.return_value': {'id': '123',375 'name': 'server_group',376 'policies': ['affinity']}377 })378 server_group_data = {'name': 'server_group',379 'policies': ['affinity']}380 request = self.mock_rest_request(body=req_data)381 response = nova.ServerGroups().post(request)382 self.assertStatusCode(response, 201)383 self.assertEqual('/api/nova/servergroups/123', response['location'])384 self.mock_server_group_create.assert_called_once_with(385 request, **server_group_data)386 @test.create_mocks({api.nova: ['server_group_delete']})387 def test_server_group_delete(self):388 request = self.mock_rest_request()389 self.mock_server_group_delete.return_value = None390 nova.ServerGroup().delete(request, "1")391 self.mock_server_group_delete.assert_called_once_with(request, "1")392 @test.create_mocks({api.nova: ['server_group_get']})393 def test_server_group_get_single(self):394 request = self.mock_rest_request()395 servergroup = self.server_groups.first()396 self.mock_server_group_get.return_value = servergroup397 response = nova.ServerGroup().get(request, "1")398 self.assertStatusCode(response, 200)399 self.assertEqual(servergroup.to_dict(), response.json)400 self.mock_server_group_get.assert_called_once_with(request, "1")401 #402 # Server Metadata403 #404 @test.create_mocks({api.nova: ['server_get']})405 def test_server_get_metadata(self):406 request = self.mock_rest_request()407 meta = {'foo': 'bar'}408 ret_val_server = self.mock_server_get.return_value409 ret_val_server.to_dict.return_value.get.return_value = meta410 response = nova.ServerMetadata().get(request, "1")411 self.assertStatusCode(response, 200)412 self.mock_server_get.assert_called_once_with(request, "1")413 @test.create_mocks({api.nova: ['server_metadata_delete',414 'server_metadata_update']})415 def test_server_edit_metadata(self):416 request = self.mock_rest_request(417 body='{"updated": {"a": "1", "b": "2"}, "removed": ["c", "d"]}'418 )419 self.mock_server_metadata_update.return_value = None420 self.mock_server_metadata_delete.return_value = None421 response = nova.ServerMetadata().patch(request, '1')422 self.assertStatusCode(response, 204)423 self.assertEqual(b'', response.content)424 self.mock_server_metadata_update.assert_called_once_with(425 request, '1', {'a': '1', 'b': '2'}426 )427 self.mock_server_metadata_delete.assert_called_once_with(428 request, '1', ['c', 'd']429 )430 #431 # Extensions432 #433 @test.create_mocks({api.nova: ['list_extensions']})434 def test_extension_list(self):435 request = self.mock_rest_request()436 self.mock_list_extensions.return_value = ['foo', 'bar']437 response = nova.Extensions().get(request)438 self.assertStatusCode(response, 200)439 self.assertEqual({"items": [{"name": "foo"}, {"name": "bar"}]},440 response.json)441 self.mock_list_extensions.assert_called_once_with(request)442 #443 # Flavors444 #445 @test.create_mocks({api.nova: ['flavor_get', 'flavor_access_list']})446 def test_flavor_get_single_with_access_list(self):447 request = self.mock_rest_request(GET={'get_access_list': 'tRuE'})448 self.mock_flavor_get.return_value.to_dict.return_value = {'name': '1'}449 self.mock_flavor_get.return_value.is_public = False450 self.mock_flavor_access_list.return_value = [451 mock.Mock(**{'tenant_id': '11'}),452 mock.Mock(**{'tenant_id': '22'}),453 ]454 response = nova.Flavor().get(request, "1")455 self.assertStatusCode(response, 200)456 self.assertEqual(to_json(response.content.decode('utf-8')),457 to_json('{"access-list": ["11", "22"], "name": "1"}'))458 self.mock_flavor_get.assert_called_once_with(request, "1",459 get_extras=False)460 self.mock_flavor_access_list.assert_called_once_with(request, "1")461 def test_get_extras_no(self):462 self._test_flavor_get_single(get_extras=False)463 def test_get_extras_yes(self):464 self._test_flavor_get_single(get_extras=True)465 def test_get_extras_default(self):466 self._test_flavor_get_single(get_extras=None)467 @test.create_mocks({api.nova: ['flavor_get']})468 def _test_flavor_get_single(self, get_extras):469 if get_extras:470 request = self.mock_rest_request(GET={'get_extras': 'tRuE'})471 elif get_extras is None:472 request = self.mock_rest_request()473 get_extras = False474 else:475 request = self.mock_rest_request(GET={'get_extras': 'fAlsE'})476 self.mock_flavor_get.return_value.to_dict.return_value = {'name': '1'}477 response = nova.Flavor().get(request, "1")478 self.assertStatusCode(response, 200)479 if get_extras:480 self.assertEqual(response.json, {"extras": {}, "name": "1"})481 else:482 self.assertEqual({"name": "1"}, response.json)483 self.mock_flavor_get.assert_called_once_with(request, "1",484 get_extras=get_extras)485 @test.create_mocks({api.nova: ['flavor_get']})486 def test_flavor_get_single_with_swap_set_to_empty(self):487 request = self.mock_rest_request()488 self.mock_flavor_get.return_value\489 .to_dict.return_value = {'name': '1', 'swap': ''}490 response = nova.Flavor().get(request, "1")491 self.assertStatusCode(response, 200)492 self.assertEqual(to_json(response.content.decode('utf-8')),493 to_json('{"name": "1", "swap": 0}'))494 self.mock_flavor_get.assert_called_once_with(request, '1',495 get_extras=False)496 @test.create_mocks({api.nova: ['flavor_delete']})497 def test_flavor_delete(self):498 self.mock_flavor_delete.return_value = None499 request = self.mock_rest_request()500 nova.Flavor().delete(request, "1")501 self.mock_flavor_delete.assert_called_once_with(request, "1")502 @test.create_mocks({api.nova: ['flavor_create']})503 def test_flavor_create(self):504 flavor_req_data = '{"name": "flavor", ' \505 '"ram": 12, ' \506 '"vcpus": 1, ' \507 '"disk": 2, ' \508 '"OS-FLV-EXT-DATA:ephemeral": 3, ' \509 '"swap": 4, ' \510 '"id": "123"' \511 '}'512 self.mock_flavor_create.return_value = mock.Mock(**{513 'id': '123',514 'to_dict.return_value': {'id': '123', 'name': 'flavor'}515 })516 flavor_data = {'name': 'flavor',517 'memory': 12,518 'vcpu': 1,519 'disk': 2,520 'ephemeral': 3,521 'swap': 4,522 'flavorid': '123',523 'is_public': True}524 request = self.mock_rest_request(body=flavor_req_data)525 response = nova.Flavors().post(request)526 self.assertStatusCode(response, 201)527 self.assertEqual('/api/nova/flavors/123', response['location'])528 self.mock_flavor_create.assert_called_once_with(request, **flavor_data)529 @test.create_mocks({api.nova: ['flavor_create',530 'add_tenant_to_flavor']})531 def test_flavor_create_with_access_list(self):532 flavor_req_data = '{"name": "flavor", ' \533 '"ram": 12, ' \534 '"vcpus": 1, ' \535 '"disk": 2, ' \536 '"OS-FLV-EXT-DATA:ephemeral": 3, ' \537 '"swap": 4, ' \538 '"id": "123", ' \539 '"flavor_access": [{"id":"1", "name":"test"}]' \540 '}'541 self.mock_flavor_create.return_value = mock.Mock(**{542 'id': '1234',543 'to_dict.return_value': {'id': '1234', 'name': 'flavor'}544 })545 # A list of FlavorAccess object is returned but it is actually unused.546 self.mock_add_tenant_to_flavor.return_value = [547 mock.sentinel.flavor_access1,548 ]549 flavor_data = {'name': 'flavor',550 'memory': 12,551 'vcpu': 1,552 'disk': 2,553 'ephemeral': 3,554 'swap': 4,555 'flavorid': '123',556 'is_public': False}557 request = self.mock_rest_request(body=flavor_req_data)558 response = nova.Flavors().post(request)559 self.assertStatusCode(response, 201)560 self.assertEqual('/api/nova/flavors/1234', response['location'])561 self.mock_flavor_create.assert_called_once_with(request, **flavor_data)562 self.mock_add_tenant_to_flavor.assert_called_once_with(563 request, '1234', '1')564 @test.create_mocks({api.nova: ['flavor_create',565 'flavor_delete',566 'flavor_get_extras']})567 def test_flavor_update(self):568 flavor_req_data = '{"name": "flavor", ' \569 '"ram": 12, ' \570 '"vcpus": 1, ' \571 '"disk": 2, ' \572 '"OS-FLV-EXT-DATA:ephemeral": 3, ' \573 '"swap": 4' \574 '}'575 self.mock_flavor_get_extras.return_value = {}576 self.mock_flavor_create.return_value = mock.Mock(**{577 'id': '123',578 'to_dict.return_value': {'id': '123', 'name': 'flavor'}579 })580 self.mock_flavor_delete.return_value = None581 flavor_data = {'name': 'flavor',582 'memory': 12,583 'vcpu': 1,584 'disk': 2,585 'ephemeral': 3,586 'swap': 4,587 'flavorid': '123',588 'is_public': True}589 request = self.mock_rest_request(body=flavor_req_data)590 response = nova.Flavor().patch(request, '123')591 self.assertStatusCode(response, 204)592 self.mock_flavor_get_extras.assert_called_once_with(593 request, '123', raw=True)594 self.mock_flavor_delete.assert_called_once_with(request, '123')595 self.mock_flavor_create.assert_called_once_with(request, **flavor_data)596 @test.create_mocks({api.nova: ['flavor_create', 'flavor_delete',597 'flavor_extra_set', 'flavor_get_extras']})598 def test_flavor_update_with_extras(self):599 flavor_req_data = '{"name": "flavor", ' \600 '"ram": 12, ' \601 '"vcpus": 1, ' \602 '"disk": 2, ' \603 '"OS-FLV-EXT-DATA:ephemeral": 3, ' \604 '"swap": 4' \605 '}'606 extra_dict = mock.Mock()607 self.mock_flavor_get_extras.return_value = extra_dict608 self.mock_flavor_create.return_value = mock.Mock(**{609 'id': '1234',610 'to_dict.return_value': {'id': '1234', 'name': 'flavor'}611 })612 self.mock_flavor_delete.return_value = None613 self.mock_flavor_extra_set.return_value = None614 flavor_data = {'name': 'flavor',615 'memory': 12,616 'vcpu': 1,617 'disk': 2,618 'ephemeral': 3,619 'swap': 4,620 'flavorid': '123',621 'is_public': True}622 request = self.mock_rest_request(body=flavor_req_data)623 response = nova.Flavor().patch(request, '123')624 self.assertStatusCode(response, 204)625 self.mock_flavor_delete.assert_called_once_with(request, '123')626 self.mock_flavor_create.assert_called_once_with(request, **flavor_data)627 self.mock_flavor_get_extras.assert_called_once_with(request, '123',628 raw=True)629 self.mock_flavor_extra_set.assert_called_once_with(request, '1234',630 extra_dict)631 @test.create_mocks({api.nova: ['flavor_create',632 'flavor_delete',633 'flavor_get_extras',634 'add_tenant_to_flavor']})635 def test_flavor_update_with_access_list(self):636 flavor_req_data = '{"name": "flavor", ' \637 '"ram": 12, ' \638 '"vcpus": 1, ' \639 '"disk": 2, ' \640 '"OS-FLV-EXT-DATA:ephemeral": 3, ' \641 '"swap": 4, ' \642 '"flavor_access": [{"id":"1", "name":"test"}]' \643 '}'644 self.mock_flavor_get_extras.return_value = {}645 self.mock_flavor_create.return_value = mock.Mock(**{646 'id': '1234',647 'to_dict.return_value': {'id': '1234', 'name': 'flavor'}648 })649 self.mock_flavor_delete.return_value = None650 # A list of FlavorAccess object is returned but it is actually unused.651 self.mock_add_tenant_to_flavor.return_value = [652 mock.sentinel.flavor_access1,653 ]654 flavor_data = {'name': 'flavor',655 'memory': 12,656 'vcpu': 1,657 'disk': 2,658 'ephemeral': 3,659 'swap': 4,660 'flavorid': '123',661 'is_public': False}662 request = self.mock_rest_request(body=flavor_req_data)663 response = nova.Flavor().patch(request, '123')664 self.assertStatusCode(response, 204)665 self.mock_flavor_get_extras.assert_called_once_with(666 request, '123', raw=True)667 self.mock_flavor_delete.assert_called_once_with(request, '123')668 self.mock_flavor_create.assert_called_once_with(request, **flavor_data)669 self.mock_add_tenant_to_flavor.assert_called_once_with(670 request, '1234', '1')671 @test.create_mocks({api.nova: ['flavor_list']})672 def _test_flavor_list_public(self, is_public=None):673 if is_public:674 request = self.mock_rest_request(GET={'is_public': 'tRuE'})675 elif is_public is None:676 request = self.mock_rest_request(GET={})677 else:678 request = self.mock_rest_request(GET={'is_public': 'fAlsE'})679 self.mock_flavor_list.return_value = [680 FakeFlavor("1"), FakeFlavor("2")681 ]682 response = nova.Flavors().get(request)683 self.assertStatusCode(response, 200)684 self.assertEqual({"items": [{"id": "1"}, {"id": "2"}]},685 response.json)686 self.mock_flavor_list.assert_called_once_with(request,687 is_public=is_public,688 get_extras=False)689 def test_flavor_list_private(self):690 self._test_flavor_list_public(is_public=False)691 def test_flavor_list_public(self):692 self._test_flavor_list_public(is_public=True)693 def test_flavor_list_public_none(self):694 self._test_flavor_list_public(is_public=None)695 @test.create_mocks({api.nova: ['flavor_list']})696 def _test_flavor_list_extras(self, get_extras=None):697 if get_extras:698 request = self.mock_rest_request(GET={'get_extras': 'tRuE'})699 elif get_extras is None:700 request = self.mock_rest_request(GET={})701 get_extras = False702 else:703 request = self.mock_rest_request(GET={'get_extras': 'fAlsE'})704 self.mock_flavor_list.return_value = [705 FakeFlavor("1"), FakeFlavor("2")706 ]707 response = nova.Flavors().get(request)708 self.assertStatusCode(response, 200)709 if get_extras:710 self.assertEqual({"items": [{"extras": {}, "id": "1"},711 {"extras": {}, "id": "2"}]},712 response.json)713 else:714 self.assertEqual({"items": [{"id": "1"}, {"id": "2"}]},715 response.json)716 self.mock_flavor_list.assert_called_once_with(request, is_public=None,717 get_extras=get_extras)718 def test_flavor_list_extras_no(self):719 self._test_flavor_list_extras(get_extras=False)720 def test_flavor_list_extras_yes(self):721 self._test_flavor_list_extras(get_extras=True)722 def test_flavor_list_extras_absent(self):723 self._test_flavor_list_extras(get_extras=None)724 @test.create_mocks({api.nova: ['flavor_get_extras']})725 def test_flavor_get_extra_specs(self):726 request = self.mock_rest_request()727 self.mock_flavor_get_extras.return_value.to_dict.return_value = \728 {'foo': '1'}729 response = nova.FlavorExtraSpecs().get(request, "1")730 self.assertStatusCode(response, 200)731 self.mock_flavor_get_extras.assert_called_once_with(request, "1",732 raw=True)733 @test.create_mocks({api.nova: ['flavor_extra_delete',734 'flavor_extra_set']})735 def test_flavor_edit_extra_specs(self):736 request = self.mock_rest_request(737 body='{"updated": {"a": "1", "b": "2"}, "removed": ["c", "d"]}'738 )739 self.mock_flavor_extra_delete.return_value = None740 self.mock_flavor_extra_set.return_value = {'a': '1', 'b': '2'}741 response = nova.FlavorExtraSpecs().patch(request, '1')742 self.assertStatusCode(response, 204)743 self.assertEqual(b'', response.content)744 self.mock_flavor_extra_set.assert_called_once_with(745 request, '1', {'a': '1', 'b': '2'}746 )747 self.mock_flavor_extra_delete.assert_called_once_with(748 request, '1', ['c', 'd']749 )750 @test.create_mocks({api.nova: ['aggregate_get']})751 def test_aggregate_get_extra_specs(self):752 request = self.mock_rest_request()753 self.mock_aggregate_get.return_value.metadata = {'a': '1', 'b': '2'}754 response = nova.AggregateExtraSpecs().get(request, "1")755 self.assertStatusCode(response, 200)756 self.assertEqual({"a": "1", "b": "2"}, response.json)757 self.mock_aggregate_get.assert_called_once_with(request, "1")758 @test.create_mocks({api.nova: ['aggregate_set_metadata']})759 def test_aggregate_edit_extra_specs(self):760 self.mock_aggregate_set_metadata.return_value = self.aggregates.first()761 request = self.mock_rest_request(762 body='{"updated": {"a": "1", "b": "2"}, "removed": ["c", "d"]}'763 )764 response = nova.AggregateExtraSpecs().patch(request, '1')765 self.assertStatusCode(response, 204)766 self.assertEqual(b'', response.content)767 self.mock_aggregate_set_metadata.assert_called_once_with(768 request, '1', {'a': '1', 'b': '2', 'c': None, 'd': None}769 )770 #771 # Services772 #773 @test.create_mocks({api.base: ['is_service_enabled'],774 api.nova: ['service_list',775 'extension_supported']})776 def test_services_get(self):777 request = self.mock_rest_request(GET={})778 self.mock_service_list.return_value = [779 mock.Mock(**{'to_dict.return_value': {'id': '1'}}),780 mock.Mock(**{'to_dict.return_value': {'id': '2'}})781 ]782 self.mock_is_service_enabled.return_value = True783 self.mock_extension_supported.return_value = True784 response = nova.Services().get(request)785 self.assertStatusCode(response, 200)786 self.assertEqual('{"items": [{"id": "1"}, {"id": "2"}]}',787 response.content.decode('utf-8'))788 self.mock_service_list.assert_called_once_with(request)789 self.mock_is_service_enabled.assert_called_once_with(request,790 'compute')791 self.mock_extension_supported.assert_called_once_with(792 'Services', request)793 @mock.patch.object(api.base, 'is_service_enabled')794 def test_services_get_disabled(self, mock_is_service_enabled):795 request = self.mock_rest_request(GET={})796 mock_is_service_enabled.return_value = False797 response = nova.Services().get(request)798 self.assertStatusCode(response, 501)799 mock_is_service_enabled.assert_called_once_with(request, 'compute')800 @test.create_mocks({api.base: ['is_service_enabled'],801 quotas: ['get_disabled_quotas'],802 api.nova: ['default_quota_get']})803 def test_quota_sets_defaults_get(self):804 filters = {'user': {'tenant_id': 'tenant'}}805 request = self.mock_rest_request(**{'GET': dict(filters)})806 self.mock_is_service_enabled.return_value = True807 self.mock_get_disabled_quotas.return_value = ['floating_ips']808 self.mock_default_quota_get.return_value = [809 Quota('metadata_items', 100),810 Quota('floating_ips', 1),811 Quota('q2', 101)812 ]813 response = nova.DefaultQuotaSets().get(request)814 self.assertStatusCode(response, 200)815 self.assertEqual(response.json,816 {"items": [817 {"limit": 100,818 "display_name": "Metadata Items",819 "name": "metadata_items"},820 {"limit": 101,821 "display_name": "Q2",822 "name": "q2"}823 ]})824 self.mock_is_service_enabled.assert_called_once_with(request,825 'compute')826 self.mock_get_disabled_quotas.assert_called_once_with(request)827 self.mock_default_quota_get.assert_called_once_with(828 request, request.user.tenant_id)829 @test.create_mocks({api.base: ['is_service_enabled']})830 def test_quota_sets_defaults_get_when_service_is_disabled(self):831 filters = {'user': {'tenant_id': 'tenant'}}832 request = self.mock_rest_request(**{'GET': dict(filters)})833 self.mock_is_service_enabled.return_value = False834 response = nova.DefaultQuotaSets().get(request)835 self.assertStatusCode(response, 501)836 self.assertEqual(response.content.decode('utf-8'),837 '"Service Nova is disabled."')838 self.mock_is_service_enabled.assert_called_once_with(request,839 'compute')840 @test.create_mocks({api.base: ['is_service_enabled'],841 quotas: ['get_disabled_quotas'],842 api.nova: ['default_quota_update']})843 def test_quota_sets_defaults_patch(self):844 request = self.mock_rest_request(body='''845 {"key_pairs": "15", "metadata_items": "5000",846 "cores": "10", "instances": "20", "floating_ips": 10,847 "injected_file_content_bytes": "15",848 "injected_file_path_bytes": "5000",849 "injected_files": "5", "ram": "10", "gigabytes": "5"}850 ''')851 self.mock_is_service_enabled.return_value = True852 self.mock_get_disabled_quotas.return_value = ['floating_ips']853 self.mock_default_quota_update.return_value = None854 response = nova.DefaultQuotaSets().patch(request)855 self.assertStatusCode(response, 204)856 self.assertEqual(response.content.decode('utf-8'), '')857 self.mock_is_service_enabled.assert_called_once_with(request,858 'compute')859 self.mock_get_disabled_quotas.assert_called_once_with(request)860 self.mock_default_quota_update.assert_called_once_with(861 request, key_pairs='15',862 metadata_items='5000', cores='10',863 instances='20', injected_file_content_bytes='15',864 injected_file_path_bytes='5000',865 injected_files='5', ram='10')866 @test.create_mocks({api.base: ['is_service_enabled']})867 def test_quota_sets_defaults_patch_when_service_is_disabled(self):868 request = self.mock_rest_request(body='''869 {"key_pairs": "15", "metadata_items": "5000",870 "cores": "10", "instances": "20", "floating_ips": 10,871 "injected_file_content_bytes": "15",872 "injected_file_path_bytes": "5000",873 "injected_files": "5", "ram": "10", "gigabytes": "5"}874 ''')875 self.mock_is_service_enabled.return_value = False876 response = nova.DefaultQuotaSets().patch(request)877 self.assertStatusCode(response, 501)878 self.assertEqual(response.content.decode('utf-8'),879 '"Service Nova is disabled."')880 self.mock_is_service_enabled.assert_called_once_with(request,881 'compute')882 @test.create_mocks({quotas: ['get_disabled_quotas']})883 def test_editable_quotas_get(self):884 disabled_quotas = {'floating_ips', 'fixed_ips',885 'security_groups', 'security_group_rules'}886 editable_quotas = {'cores', 'volumes', 'network', 'fixed_ips'}887 self.mock_get_disabled_quotas.return_value = disabled_quotas888 request = self.mock_rest_request()889 with mock.patch.object(quotas, 'QUOTA_FIELDS', editable_quotas):890 response = nova.EditableQuotaSets().get(request)891 self.assertStatusCode(response, 200)892 # NOTE(amotoki): assertItemsCollectionEqual cannot be used below893 # since the item list is generated from a set and the order of items894 # is unpredictable.895 self.assertEqual(set(response.json['items']),896 {'cores', 'volumes', 'network'})897 self.mock_get_disabled_quotas.assert_called_once_with(request)898 @test.create_mocks({api.base: ['is_service_enabled'],899 quotas: ['get_disabled_quotas'],900 api.nova: ['tenant_quota_update']})901 def test_quota_sets_patch(self):902 quota_data = dict(cores='15', instances='5',903 ram='50000', metadata_items='150',904 injected_files='5',905 injected_file_content_bytes='10240',906 floating_ips='50', fixed_ips='5',907 security_groups='10',908 security_group_rules='100')909 request = self.mock_rest_request(body='''910 {"cores": "15", "ram": "50000", "instances": "5",911 "metadata_items": "150", "injected_files": "5",912 "injected_file_content_bytes": "10240", "floating_ips": "50",913 "fixed_ips": "5", "security_groups": "10" ,914 "security_group_rules": "100", "volumes": "10"}915 ''')916 self.mock_get_disabled_quotas.return_value = set()917 self.mock_is_service_enabled.return_value = True918 self.mock_tenant_quota_update.return_value = None919 with mock.patch.object(quotas, 'NOVA_QUOTA_FIELDS',920 {n for n in quota_data}):921 response = nova.QuotaSets().patch(request, 'spam123')922 self.assertStatusCode(response, 204)923 self.assertEqual(response.content.decode('utf-8'), '')924 self.mock_is_service_enabled.assert_called_once_with(request,925 'compute')926 self.mock_get_disabled_quotas.assert_called_once_with(request)927 self.mock_tenant_quota_update.assert_called_once_with(928 request, 'spam123', **quota_data)929 @test.create_mocks({api.nova: ['tenant_quota_update'],930 api.base: ['is_service_enabled'],931 quotas: ['get_disabled_quotas']})932 def test_quota_sets_patch_when_service_is_disabled(self):933 quota_data = dict(cores='15', instances='5',934 ram='50000', metadata_items='150',935 injected_files='5',936 injected_file_content_bytes='10240',937 floating_ips='50', fixed_ips='5',938 security_groups='10',939 security_group_rules='100')940 request = self.mock_rest_request(body='''941 {"cores": "15", "ram": "50000", "instances": "5",942 "metadata_items": "150", "injected_files": "5",943 "injected_file_content_bytes": "10240", "floating_ips": "50",944 "fixed_ips": "5", "security_groups": "10" ,945 "security_group_rules": "100", "volumes": "10"}946 ''')947 self.mock_get_disabled_quotas.return_value = {}948 self.mock_is_service_enabled.return_value = False949 self.mock_tenant_quota_update.return_value = None950 with mock.patch.object(quotas, 'NOVA_QUOTA_FIELDS',951 {n for n in quota_data}):952 response = nova.QuotaSets().patch(request, 'spam123')953 self.assertStatusCode(response, 501)954 self.assertEqual(response.content.decode('utf-8'),955 '"Service Nova is disabled."')956 self.mock_get_disabled_quotas.assert_called_once_with(request)957 self.mock_is_service_enabled.assert_called_once_with(request,958 'compute')959 self.mock_tenant_quota_update.assert_not_called()960 @test.create_mocks({api.nova: ['is_feature_available']})961 def test_version_get(self):962 request = self.mock_rest_request()963 self.mock_is_feature_available.return_value = True964 response = nova.Features().get(request, 'fake')965 self.assertStatusCode(response, 200)966 self.assertEqual(response.content.decode('utf-8'), 'true')967 self.mock_is_feature_available.assert_called_once_with(request,...

Full Screen

Full Screen

test_keystone.py

Source:test_keystone.py Github

copy

Full Screen

1# Copyright 2014, Rackspace, US, Inc.2#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 at6#7# http://www.apache.org/licenses/LICENSE-2.08#9# Unless required by applicable law or agreed to in writing, software10# 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 and13# limitations under the License.14from django.conf import settings15import mock16from oslo_serialization import jsonutils17from openstack_dashboard import api18from openstack_dashboard.api.rest import keystone19from openstack_dashboard.test import helpers as test20class KeystoneRestTestCase(test.TestCase):21 #22 # Version23 #24 @test.create_mocks({api.keystone: ['get_version']})25 def test_version_get(self):26 request = self.mock_rest_request()27 self.mock_get_version.return_value = '3'28 response = keystone.Version().get(request)29 self.assertStatusCode(response, 200)30 self.assertEqual(response.json, {"version": "3"})31 self.mock_get_version.assert_called_once_with()32 #33 # Users34 #35 @test.create_mocks({api.keystone: ['user_get']})36 def test_user_get(self):37 request = self.mock_rest_request()38 self.mock_user_get.return_value.to_dict.return_value = {'name': 'Ni!'}39 response = keystone.User().get(request, 'the_id')40 self.assertStatusCode(response, 200)41 self.assertEqual(response.json, {"name": "Ni!"})42 self.mock_user_get.assert_called_once_with(43 request, 'the_id', admin=False)44 @test.create_mocks({api.keystone: ['user_get']})45 def test_user_get_current(self):46 request = self.mock_rest_request(**{'user.id': 'current_id'})47 self.mock_user_get.return_value.to_dict.return_value = {'name': 'Ni!'}48 response = keystone.User().get(request, 'current')49 self.assertStatusCode(response, 200)50 self.assertEqual(response.json, {"name": "Ni!"})51 self.mock_user_get.assert_called_once_with(52 request, 'current_id', admin=False)53 @test.create_mocks({api.keystone: ['user_list']})54 def test_user_get_list(self):55 request = self.mock_rest_request(**{56 'session.get': mock.Mock(return_value='the_domain'),57 'GET': {},58 })59 self.mock_user_list.return_value = [60 mock.Mock(**{'to_dict.return_value': {'name': 'Ni!'}}),61 mock.Mock(**{'to_dict.return_value': {'name': 'Ptang!'}})62 ]63 response = keystone.Users().get(request)64 self.assertStatusCode(response, 200)65 self.assertEqual(response.json,66 {"items": [{"name": "Ni!"}, {"name": "Ptang!"}]})67 self.mock_user_list.assert_called_once_with(request, project=None,68 domain='the_domain',69 group=None,70 filters=None)71 @test.create_mocks({api.keystone: ['user_list']})72 def test_user_get_list_with_filters(self):73 filters = {'enabled': True}74 request = self.mock_rest_request(**{75 'session.get': mock.Mock(return_value='the_domain'),76 'GET': dict(**filters),77 })78 self.mock_user_list.return_value = [79 mock.Mock(**{'to_dict.return_value': {'name': 'Ni!'}}),80 mock.Mock(**{'to_dict.return_value': {'name': 'Ptang!'}})81 ]82 response = keystone.Users().get(request)83 self.assertStatusCode(response, 200)84 self.assertEqual(response.json,85 {"items": [{"name": "Ni!"}, {"name": "Ptang!"}]})86 self.mock_user_list.assert_called_once_with(request, project=None,87 domain='the_domain',88 group=None,89 filters=filters)90 def test_user_create_full(self):91 self._test_user_create(92 '{"name": "bob", '93 '"password": "sekrit", "project": "123", '94 '"email": "spam@company.example", '95 '"description": "hello, puff"}',96 {97 'name': 'bob',98 'password': 'sekrit',99 'email': 'spam@company.example',100 'project': '123',101 'domain': 'the_domain',102 'enabled': True,103 'description': 'hello, puff'104 }105 )106 def test_user_create_existing_role(self):107 self._test_user_create(108 '{"name": "bob", '109 '"password": "sekrit", "project": "123", '110 '"email": "spam@company.example"}',111 {112 'name': 'bob',113 'password': 'sekrit',114 'email': 'spam@company.example',115 'project': '123',116 'domain': 'the_domain',117 'enabled': True,118 'description': None119 }120 )121 def test_user_create_no_project(self):122 self._test_user_create(123 '{"name": "bob", '124 '"password": "sekrit", "project": "", '125 '"email": "spam@company.example"}',126 {127 'name': 'bob',128 'password': 'sekrit',129 'email': 'spam@company.example',130 'project': None,131 'domain': 'the_domain',132 'enabled': True,133 'description': None134 }135 )136 def test_user_create_partial(self):137 self._test_user_create(138 '{"name": "bob", "project": ""}',139 {140 'name': 'bob',141 'password': None,142 'email': None,143 'project': None,144 'domain': 'the_domain',145 'enabled': True,146 'description': None147 }148 )149 @test.create_mocks({api.keystone: ['get_default_domain',150 'user_create']})151 def _test_user_create(self, supplied_body, add_user_call):152 request = self.mock_rest_request(body=supplied_body)153 self.mock_get_default_domain.return_value = \154 mock.Mock(**{'id': 'the_domain'})155 self.mock_user_create.return_value = mock.Mock(**{156 'id': 'user123',157 'to_dict.return_value': {'id': 'user123', 'name': 'bob'}158 })159 response = keystone.Users().post(request)160 self.assertStatusCode(response, 201)161 self.assertEqual(response['location'],162 '/api/keystone/users/user123')163 self.assertEqual(response.json,164 {"id": "user123", "name": "bob"})165 self.mock_user_create.assert_called_once_with(request, **add_user_call)166 self.mock_get_default_domain.assert_called_once_with(request)167 @test.create_mocks({api.keystone: ['user_delete']})168 def test_user_delete_many(self):169 request = self.mock_rest_request(body='''170 ["id1", "id2", "id3"]171 ''')172 self.mock_user_delete.return_value = None173 response = keystone.Users().delete(request)174 self.assertStatusCode(response, 204)175 self.assertEqual(response.content, b'')176 self.mock_user_delete.assert_has_calls([177 mock.call(request, 'id1'),178 mock.call(request, 'id2'),179 mock.call(request, 'id3'),180 ])181 @test.create_mocks({api.keystone: ['user_delete']})182 def test_user_delete(self):183 request = self.mock_rest_request()184 self.mock_user_delete.return_value = None185 response = keystone.User().delete(request, 'the_id')186 self.assertStatusCode(response, 204)187 self.assertEqual(response.content, b'')188 self.mock_user_delete.assert_called_once_with(request, 'the_id')189 @test.create_mocks({api.keystone: ['user_get',190 'user_update_password']})191 def test_user_patch_password(self):192 request = self.mock_rest_request(body='''193 {"password": "sekrit"}194 ''')195 user = keystone.User()196 self.mock_user_get.return_value = mock.sentinel.user197 self.mock_user_update_password.return_value = None198 response = user.patch(request, 'user123')199 self.assertStatusCode(response, 204)200 self.assertEqual(response.content, b'')201 self.mock_user_get.assert_called_once_with(request, 'user123')202 self.mock_user_update_password.assert_called_once_with(203 request, mock.sentinel.user, 'sekrit')204 @test.create_mocks({api.keystone: ['user_get',205 'user_update_enabled']})206 def test_user_patch_enabled(self):207 request = self.mock_rest_request(body='''208 {"enabled": false}209 ''')210 user = keystone.User()211 self.mock_user_get.return_value = mock.sentinel.user212 self.mock_user_update_enabled.return_value = None213 response = user.patch(request, 'user123')214 self.assertStatusCode(response, 204)215 self.assertEqual(response.content, b'')216 self.mock_user_get.assert_called_once_with(request, 'user123')217 self.mock_user_update_enabled.assert_called_once_with(218 request, mock.sentinel.user, False)219 @test.create_mocks({api.keystone: ['user_get',220 'user_update']})221 def test_user_patch_project(self):222 request = self.mock_rest_request(body='''223 {"project": "other123"}224 ''')225 user = keystone.User()226 self.mock_user_get.return_value = mock.sentinel.user227 self.mock_user_update.return_value = self.users.first()228 response = user.patch(request, 'user123')229 self.assertStatusCode(response, 204)230 self.assertEqual(response.content, b'')231 self.mock_user_get.assert_called_once_with(request, 'user123')232 self.mock_user_update.assert_called_once_with(233 request, mock.sentinel.user, project='other123')234 @test.create_mocks({api.keystone: ['user_get',235 'user_update']})236 def test_user_patch_multiple(self):237 request = self.mock_rest_request(body='''238 {"project": "other123", "name": "something"}239 ''')240 user = keystone.User()241 self.mock_user_get.return_value = mock.sentinel.user242 self.mock_user_update.return_value = self.users.first()243 response = user.patch(request, 'user123')244 self.assertStatusCode(response, 204)245 self.assertEqual(response.content, b'')246 self.mock_user_get.assert_called_once_with(request, 'user123')247 self.mock_user_update.assert_called_once_with(248 request, mock.sentinel.user, project='other123', name='something')249 #250 # Roles251 #252 @test.create_mocks({api.keystone: ['role_get']})253 def test_role_get(self):254 request = self.mock_rest_request()255 self.mock_role_get.return_value.to_dict.return_value = {'name': 'Ni!'}256 response = keystone.Role().get(request, 'the_id')257 self.assertStatusCode(response, 200)258 self.assertEqual(response.json, {"name": "Ni!"})259 self.mock_role_get.assert_called_once_with(request, 'the_id')260 @test.create_mocks({api.keystone: ['get_default_role']})261 def test_role_get_default(self):262 request = self.mock_rest_request()263 ret_val_role = self.mock_get_default_role.return_value264 ret_val_role.to_dict.return_value = {'name': 'Ni!'}265 response = keystone.Role().get(request, 'default')266 self.assertStatusCode(response, 200)267 self.assertEqual(response.json, {"name": "Ni!"})268 self.mock_get_default_role.assert_called_once_with(request)269 @test.create_mocks({api.keystone: ['role_list']})270 def test_role_get_list(self):271 request = self.mock_rest_request(**{'GET': {}})272 self.mock_role_list.return_value = [273 mock.Mock(**{'to_dict.return_value': {'name': 'Ni!'}}),274 mock.Mock(**{'to_dict.return_value': {'name': 'Ptang!'}})275 ]276 response = keystone.Roles().get(request)277 self.assertStatusCode(response, 200)278 self.assertEqual(response.json,279 {"items": [{"name": "Ni!"}, {"name": "Ptang!"}]})280 self.mock_role_list.assert_called_once_with(request)281 @test.create_mocks({api.keystone: ['roles_for_user']})282 def test_role_get_for_user(self):283 request = self.mock_rest_request(**{'GET': {'user_id': 'user123',284 'project_id': 'project123'}})285 self.mock_roles_for_user.return_value = [286 mock.Mock(**{'to_dict.return_value': {'name': 'Ni!'}}),287 mock.Mock(**{'to_dict.return_value': {'name': 'Ptang!'}})288 ]289 response = keystone.Roles().get(request)290 self.assertStatusCode(response, 200)291 self.assertEqual(response.json,292 {"items": [{"name": "Ni!"}, {"name": "Ptang!"}]})293 self.mock_roles_for_user.assert_called_once_with(request, 'user123',294 'project123')295 @test.create_mocks({api.keystone: ['role_create']})296 def test_role_create(self):297 request = self.mock_rest_request(body='''298 {"name": "bob"}299 ''')300 self.mock_role_create.return_value.id = 'role123'301 self.mock_role_create.return_value.to_dict.return_value = {302 'id': 'role123', 'name': 'bob'303 }304 response = keystone.Roles().post(request)305 self.assertStatusCode(response, 201)306 self.assertEqual(response['location'],307 '/api/keystone/roles/role123')308 self.assertEqual(response.json, {"id": "role123", "name": "bob"})309 self.mock_role_create.assert_called_once_with(request, 'bob')310 @test.create_mocks({api.keystone: ['add_tenant_user_role']})311 def test_role_grant(self):312 self.mock_add_tenant_user_role.return_value = None313 request = self.mock_rest_request(body='''314 {"action": "grant", "data": {"user_id": "user123",315 "role_id": "role123", "project_id": "project123"}}316 ''')317 response = keystone.ProjectRole().put(request, "project1", "role2",318 "user3")319 self.assertStatusCode(response, 204)320 self.assertEqual(response.content, b'')321 self.mock_add_tenant_user_role.assert_called_once_with(322 request, 'project1', 'user3', 'role2')323 @test.create_mocks({api.keystone: ['role_delete']})324 def test_role_delete_many(self):325 self.mock_role_delete.return_value = None326 request = self.mock_rest_request(body='''327 ["id1", "id2", "id3"]328 ''')329 response = keystone.Roles().delete(request)330 self.assertStatusCode(response, 204)331 self.assertEqual(response.content, b'')332 self.mock_role_delete.assert_has_calls([333 mock.call(request, 'id1'),334 mock.call(request, 'id2'),335 mock.call(request, 'id3'),336 ])337 @test.create_mocks({api.keystone: ['role_delete']})338 def test_role_delete(self):339 self.mock_role_delete.return_value = None340 request = self.mock_rest_request()341 response = keystone.Role().delete(request, 'the_id')342 self.assertStatusCode(response, 204)343 self.assertEqual(response.content, b'')344 self.mock_role_delete.assert_called_once_with(request, 'the_id')345 @test.create_mocks({api.keystone: ['role_update']})346 def test_role_patch(self):347 self.mock_role_update.return_value = self.roles.first()348 request = self.mock_rest_request(body='{"name": "spam"}')349 response = keystone.Role().patch(request, 'the_id')350 self.assertStatusCode(response, 204)351 self.assertEqual(response.content, b'')352 self.mock_role_update.assert_called_once_with(request,353 'the_id',354 'spam')355 #356 # Domains357 #358 @test.create_mocks({api.keystone: ['get_default_domain']})359 def test_default_domain_get(self):360 request = self.mock_rest_request()361 domain = api.base.APIDictWrapper({'id': 'the_id', 'name': 'the_name'})362 self.mock_get_default_domain.return_value = domain363 response = keystone.DefaultDomain().get(request)364 self.assertStatusCode(response, 200)365 self.assertEqual(response.json, domain.to_dict())366 self.mock_get_default_domain.assert_called_once_with(request)367 @test.create_mocks({api.keystone: ['domain_get']})368 def test_domain_get(self):369 request = self.mock_rest_request()370 ret_val_domain = self.mock_domain_get.return_value371 ret_val_domain.to_dict.return_value = {'name': 'Ni!'}372 response = keystone.Domain().get(request, 'the_id')373 self.assertStatusCode(response, 200)374 self.assertEqual(response.json, {"name": "Ni!"})375 self.mock_domain_get.assert_called_once_with(request, 'the_id')376 @test.create_mocks({api.keystone: ['get_default_domain']})377 def test_domain_get_default(self):378 request = self.mock_rest_request()379 self.mock_get_default_domain.return_value.to_dict.return_value = {380 'name': 'Ni!'381 }382 response = keystone.Domain().get(request, 'default')383 self.assertStatusCode(response, 200)384 self.assertEqual(response.json, {"name": "Ni!"})385 self.mock_get_default_domain.assert_called_once_with(request)386 @test.create_mocks({api.keystone: ['domain_list']})387 def test_domain_get_list(self):388 request = self.mock_rest_request()389 self.mock_domain_list.return_value = [390 mock.Mock(**{'to_dict.return_value': {'name': 'Ni!'}}),391 mock.Mock(**{'to_dict.return_value': {'name': 'Ptang!'}})392 ]393 response = keystone.Domains().get(request)394 self.assertStatusCode(response, 200)395 self.assertEqual(response.json,396 {"items": [{"name": "Ni!"}, {"name": "Ptang!"}]})397 self.mock_domain_list.assert_called_once_with(request)398 def test_domain_create_full(self):399 self._test_domain_create(400 '{"name": "bob", '401 '"description": "sekrit", "enabled": false}',402 {403 'description': 'sekrit',404 'enabled': False405 }406 )407 def test_domain_create_partial(self):408 self._test_domain_create(409 '{"name": "bob"}',410 {411 'description': None,412 'enabled': True413 }414 )415 @test.create_mocks({api.keystone: ['domain_create']})416 def _test_domain_create(self, supplied_body, expected_call):417 request = self.mock_rest_request(body=supplied_body)418 ret_val_domain = self.mock_domain_create.return_value419 ret_val_domain.id = 'domain123'420 ret_val_domain.to_dict.return_value = {421 'id': 'domain123', 'name': 'bob'422 }423 response = keystone.Domains().post(request)424 self.assertStatusCode(response, 201)425 self.assertEqual(response['location'],426 '/api/keystone/domains/domain123')427 self.assertEqual(response.json, {"id": "domain123", "name": "bob"})428 self.mock_domain_create.assert_called_once_with(request, 'bob',429 **expected_call)430 @test.create_mocks({api.keystone: ['domain_delete']})431 def test_domain_delete_many(self):432 self.mock_domain_delete.return_value = None433 request = self.mock_rest_request(body='''434 ["id1", "id2", "id3"]435 ''')436 response = keystone.Domains().delete(request)437 self.assertStatusCode(response, 204)438 self.assertEqual(response.content, b'')439 self.mock_domain_delete.assert_has_calls([440 mock.call(request, 'id1'),441 mock.call(request, 'id2'),442 mock.call(request, 'id3'),443 ])444 @test.create_mocks({api.keystone: ['domain_delete']})445 def test_domain_delete(self):446 self.mock_domain_delete.return_value = None447 request = self.mock_rest_request()448 response = keystone.Domain().delete(request, 'the_id')449 self.assertStatusCode(response, 204)450 self.assertEqual(response.content, b'')451 self.mock_domain_delete.assert_called_once_with(request, 'the_id')452 @test.create_mocks({api.keystone: ['domain_update']})453 def test_domain_patch(self):454 self.mock_domain_update.return_value = self.domains.first()455 request = self.mock_rest_request(body='{"name": "spam"}')456 response = keystone.Domain().patch(request, 'the_id')457 self.assertStatusCode(response, 204)458 self.assertEqual(response.content, b'')459 self.mock_domain_update.assert_called_once_with(request,460 'the_id',461 name='spam',462 description=None,463 enabled=None)464 #465 # Projects466 #467 @test.create_mocks({api.keystone: ['tenant_get']})468 def test_project_get(self):469 request = self.mock_rest_request()470 ret_val_tenant = self.mock_tenant_get.return_value471 ret_val_tenant.to_dict.return_value = {'name': 'Ni!'}472 response = keystone.Project().get(request, 'the_id')473 self.assertStatusCode(response, 200)474 self.assertEqual(response.json, {"name": "Ni!"})475 self.mock_tenant_get.assert_called_once_with(476 request, 'the_id', admin=False)477 def test_project_get_list(self):478 self._test_project_get_list(479 {},480 {481 'paginate': False,482 'marker': None,483 'domain': None,484 'user': None,485 'admin': True,486 'filters': None487 }488 )489 def test_project_get_list_with_params_true(self):490 self._test_project_get_list(491 {492 'paginate': 'true',493 'admin': 'true'494 },495 {496 'paginate': True,497 'marker': None,498 'domain': None,499 'user': None,500 'admin': True,501 'filters': None502 }503 )504 def test_project_get_list_with_params_false(self):505 self._test_project_get_list(506 {507 'paginate': 'false',508 'admin': 'false'509 },510 {511 'paginate': False,512 'marker': None,513 'domain': None,514 'user': None,515 'admin': False,516 'filters': None517 }518 )519 @test.create_mocks({api.keystone: ['tenant_list']})520 def _test_project_get_list(self, params, expected_call):521 request = self.mock_rest_request(**{'GET': dict(**params)})522 self.mock_tenant_list.return_value = ([523 mock.Mock(**{'to_dict.return_value': {'name': 'Ni!'}}),524 mock.Mock(**{'to_dict.return_value': {'name': 'Ptang!'}})525 ], False)526 with mock.patch.object(settings, 'DEBUG', True):527 response = keystone.Projects().get(request)528 self.assertStatusCode(response, 200)529 self.assertEqual(response.json,530 {"has_more": False,531 "items": [{"name": "Ni!"}, {"name": "Ptang!"}]})532 self.mock_tenant_list.assert_called_once_with(request, **expected_call)533 @test.create_mocks({api.keystone: ['tenant_list']})534 def test_project_get_list_with_filters(self):535 filters = {'name': 'Ni!'}536 request = self.mock_rest_request(**{'GET': dict(**filters)})537 self.mock_tenant_list.return_value = ([538 mock.Mock(**{'to_dict.return_value': {'name': 'Ni!'}}),539 mock.Mock(**{'to_dict.return_value': {'name': 'Ni!'}})540 ], False)541 with mock.patch.object(settings, 'DEBUG', True):542 response = keystone.Projects().get(request)543 self.assertStatusCode(response, 200)544 self.assertEqual(response.json,545 {"has_more": False,546 "items": [{"name": "Ni!"}, {"name": "Ni!"}]})547 self.mock_tenant_list.assert_called_once_with(request, paginate=False,548 marker=None, domain=None,549 user=None, admin=True,550 filters=filters)551 def test_project_create_full(self):552 self._test_project_create(553 '{"name": "bob", '554 '"domain_id": "domain123", "description": "sekrit", '555 '"enabled": false}',556 {557 'name': 'bob',558 'description': 'sekrit',559 'domain': 'domain123',560 'enabled': False561 }562 )563 def test_project_create_partial(self):564 self._test_project_create(565 '{"name": "bob"}',566 {567 'name': 'bob',568 'description': None,569 'domain': None,570 'enabled': True571 }572 )573 @test.create_mocks({api.keystone: ['tenant_create']})574 def _test_project_create(self, supplied_body, expected_args):575 request = self.mock_rest_request(body=supplied_body)576 self.mock_tenant_create.return_value.id = 'project123'577 self.mock_tenant_create.return_value.to_dict.return_value = {578 'id': 'project123', 'name': 'bob'579 }580 response = keystone.Projects().post(request)581 self.assertStatusCode(response, 201)582 self.assertEqual(response['location'],583 '/api/keystone/projects/project123')584 self.assertEqual(response.json,585 {"id": "project123", "name": "bob"})586 self.mock_tenant_create.assert_called_once_with(request,587 **expected_args)588 @test.create_mocks({api.keystone: ['tenant_delete']})589 def test_project_delete_many(self):590 self.mock_tenant_delete.return_value = None591 request = self.mock_rest_request(body='''592 ["id1", "id2", "id3"]593 ''')594 response = keystone.Projects().delete(request)595 self.assertStatusCode(response, 204)596 self.assertEqual(response.content, b'')597 self.mock_tenant_delete.assert_has_calls([598 mock.call(request, 'id1'),599 mock.call(request, 'id2'),600 mock.call(request, 'id3'),601 ])602 @test.create_mocks({api.keystone: ['tenant_delete']})603 def test_project_delete(self):604 self.mock_tenant_delete.return_value = None605 request = self.mock_rest_request()606 response = keystone.Project().delete(request, 'the_id')607 self.assertStatusCode(response, 204)608 self.assertEqual(response.content, b'')609 self.mock_tenant_delete.assert_called_once_with(request, 'the_id')610 @test.create_mocks({api.keystone: ['tenant_update']})611 def test_project_patch(self):612 # nothing in the Horizon code documents what additional parameters are613 # allowed, so we'll just assume GIGO614 self.mock_tenant_update.return_value = self.tenants.first()615 request = self.mock_rest_request(body='''616 {"name": "spam", "domain_id": "domain123", "foo": "bar"}617 ''')618 response = keystone.Project().patch(request, 'spam123')619 self.assertStatusCode(response, 204)620 self.assertEqual(response.content, b'')621 self.mock_tenant_update.assert_called_once_with(request,622 'spam123',623 name='spam', foo='bar',624 description=None,625 domain='domain123',626 enabled=None)627 #628 # Service Catalog629 #630 def test_service_catalog_get(self):631 request = self.mock_rest_request()632 request.user = mock.MagicMock(**{'service_catalog': [633 {'endpoints': [634 {'url': 'http://cool_url/image',635 'interface': 'admin',636 'region': 'RegionOne',637 'region_id': 'RegionOne',638 'id': 'test'},639 {'url': 'http://cool_url/image',640 'interface': 'public',641 'region': 'RegionOne',642 'region_id': 'RegionOne',643 'id': 'test'},644 {'url': 'http://cool_url/image',645 'interface': 'internal',646 'region': 'RegionOne',647 'region_id': 'RegionOne',648 'id': 'test'}],649 'type': 'image',650 'id': '2b5bc2e59b094f898a43f5e8ce446240',651 'name': 'glance'},652 {'endpoints': [653 {'url': 'http://cool_url/volume/v2/test',654 'interface': 'public',655 'region': 'RegionOne',656 'region_id': 'RegionOne',657 'id': '29a629afb80547ea9baa4266e97b4cb5'},658 {'url': 'http://cool_url/volume/v2/test',659 'interface': 'admin',660 'region': 'RegionOne',661 'region_id': 'RegionOne',662 'id': '29a629afb80547ea9baa4266e97b4cb5'}],663 'type': 'volumev2',664 'id': '55ef272cfa714e54b8f2046c157b027d',665 'name': 'cinderv2'},666 {'endpoints': [667 {'url': 'http://cool_url/compute/v2/check',668 'interface': 'internal',669 'region': 'RegionOne',670 'region_id': 'RegionOne',671 'id': 'e8c440e025d94355ab82c78cc2062129'}],672 'type': 'compute_legacy',673 'id': 'b7f1d3f4119643508d5ca2325eb8af87',674 'name': 'nova_legacy'}]})675 response = keystone.ServiceCatalog().get(request)676 self.assertStatusCode(response, 200)677 content = [{'endpoints': [678 {'url': 'http://cool_url/image',679 'interface': 'public',680 'region': 'RegionOne',681 'region_id': 'RegionOne',682 'id': 'test'}],683 'type': 'image',684 'id': '2b5bc2e59b094f898a43f5e8ce446240',685 'name': 'glance'},686 {'endpoints': [687 {'url': 'http://cool_url/volume/v2/test',688 'interface': 'public',689 'region': 'RegionOne',690 'region_id': 'RegionOne',691 'id': '29a629afb80547ea9baa4266e97b4cb5'}],692 'type': 'volumev2',693 'id': '55ef272cfa714e54b8f2046c157b027d',694 'name': 'cinderv2'}]695 self.assertEqual(content, jsonutils.loads(response.content))696 #697 # User Session698 #699 def test_user_session_get(self):700 request = self.mock_rest_request()701 request.user = mock.Mock(702 services_region='some region',703 super_secret_thing='not here',704 token=type('', (object,), {'id': 'token here'}),705 is_authenticated=lambda: True,706 spec=['services_region', 'super_secret_thing']707 )708 response = keystone.UserSession().get(request)709 self.assertStatusCode(response, 200)710 content = jsonutils.loads(response.content)711 self.assertEqual(content['services_region'], 'some region')712 self.assertEqual(content['token'], 'token here')713 self.assertNotIn('super_secret_thing', content)714 #715 # Groups716 #717 @test.create_mocks({api.keystone: ['group_list']})718 def test_group_get_list(self):719 request = self.mock_rest_request(**{720 'session.get': mock.Mock(return_value='the_domain'),721 'GET': {},722 })723 self.mock_group_list.return_value = [724 mock.Mock(**{'to_dict.return_value': {'name': 'uno!'}}),725 mock.Mock(**{'to_dict.return_value': {'name': 'dos!'}})726 ]727 response = keystone.Groups().get(request)728 self.assertStatusCode(response, 200)729 self.assertEqual(response.json,730 {"items": [{"name": "uno!"}, {"name": "dos!"}]})731 self.mock_group_list.assert_called_once_with(request,732 domain='the_domain')733 @test.create_mocks({api.keystone: ['group_create']})734 def test_group_create(self):735 request = self.mock_rest_request(**{736 'session.get': mock.Mock(return_value='the_domain'),737 'GET': {},738 'body': '{"name": "bug!", "description": "bugaboo!!"}',739 })740 self.mock_group_create.return_value.id = 'group789'741 self.mock_group_create.return_value.to_dict.return_value = {742 'id': 'group789', 'name': 'bug!', 'description': 'bugaboo!!'743 }744 response = keystone.Groups().post(request)745 self.assertStatusCode(response, 201)746 self.assertEqual(response['location'],747 '/api/keystone/groups/group789')748 self.assertEqual(response.json,749 {"id": "group789",750 "name": "bug!",751 "description": "bugaboo!!"})752 self.mock_group_create.assert_called_once_with(request, 'the_domain',753 'bug!', 'bugaboo!!')754 @test.create_mocks({api.keystone: ['group_create']})755 def test_group_create_without_description(self):756 request = self.mock_rest_request(**{757 'session.get': mock.Mock(return_value='the_domain'),758 'GET': {},759 'body': '{"name": "bug!"}',760 })761 self.mock_group_create.return_value.id = 'group789'762 self.mock_group_create.return_value.to_dict.return_value = {763 'id': 'group789', 'name': 'bug!'764 }765 response = keystone.Groups().post(request)766 self.assertStatusCode(response, 201)767 self.assertEqual(response['location'],768 '/api/keystone/groups/group789')769 self.assertEqual(response.json,770 {"id": "group789",771 "name": "bug!"})772 self.mock_group_create.assert_called_once_with(request, 'the_domain',773 'bug!', None)774 @test.create_mocks({api.keystone: ['group_get']})775 def test_group_get(self):776 request = self.mock_rest_request()777 self.mock_group_get.return_value.to_dict.return_value = {778 'name': 'bug!', 'description': 'bugaboo!!'}779 response = keystone.Group().get(request, 'the_id')780 self.assertStatusCode(response, 200)781 self.assertEqual(response.json, {"name": "bug!",782 "description": "bugaboo!!"})783 self.mock_group_get.assert_called_once_with(request, 'the_id')784 @test.create_mocks({api.keystone: ['group_delete']})785 def test_group_delete(self):786 self.mock_group_delete.return_value = None787 request = self.mock_rest_request()788 response = keystone.Group().delete(request, 'the_id')789 self.assertStatusCode(response, 204)790 self.assertEqual(response.content, b'')791 self.mock_group_delete.assert_called_once_with(request, 'the_id')792 @test.create_mocks({api.keystone: ['group_update']})793 def test_group_patch(self):794 self.mock_group_update.return_value = self.groups.first()795 request = self.mock_rest_request(796 body='{"name": "spam_i_am", "description": "Sir Spam"}')797 response = keystone.Group().patch(request, 'the_id')798 self.assertStatusCode(response, 204)799 self.assertEqual(response.content, b'')800 self.mock_group_update.assert_called_once_with(request,801 'the_id',802 'spam_i_am',803 'Sir Spam')804 @test.create_mocks({api.keystone: ['group_delete']})805 def test_group_delete_many(self):806 self.mock_group_delete.return_value = None807 request = self.mock_rest_request(body='''808 ["id1", "id2", "id3"]809 ''')810 response = keystone.Groups().delete(request)811 self.assertStatusCode(response, 204)812 self.assertEqual(response.content, b'')813 self.mock_group_delete.assert_has_calls([814 mock.call(request, 'id1'),815 mock.call(request, 'id2'),816 mock.call(request, 'id3'),817 ])818 #819 # Services820 #821 @test.create_mocks({api.keystone: ['Service']})822 def test_services_get(self):823 request = self.mock_rest_request()824 mock_service = {825 "name": "srv_name",826 "type": "srv_type",827 "host": "srv_host"828 }829 request.user = mock.Mock(830 service_catalog=[mock_service],831 services_region='some region'832 )833 self.mock_Service.return_value.to_dict.return_value = mock_service834 response = keystone.Services().get(request)835 self.assertStatusCode(response, 200)...

Full Screen

Full Screen

test_sense_pi.py

Source:test_sense_pi.py Github

copy

Full Screen

1from django.test import SimpleTestCase2from unittest.mock import patch, MagicMock3from testfixtures import TempDirectory4import os5import sys6sys.modules[7 "sense_hat"8] = MagicMock() # mock these modules so that they don't have to be installed9sys.modules["sense_emu"] = MagicMock()10from hardware.SensorPi.sense_pi import SensePi # noqa : E40211from hardware.Utils.logger import Logger # noqa : E40212@patch("hardware.SensorPi.sense_pi.SenseHat")13class SensePiTests(SimpleTestCase):14 def setUp(self):15 self.temp_dir = TempDirectory()16 def tearDown(self):17 self.temp_dir.cleanup()18 def test_init_no_logs_no_ids(self, mock_sense):19 mock_show_message = MagicMock()20 mock_clear = MagicMock()21 mock_sense.return_value.show_message = mock_show_message22 mock_sense.return_value.clear = mock_clear23 expected_sensor_ids = {24 "temperature": 1,25 "pressure": 2,26 "humidity": 3,27 "acceleration": 4,28 "orientation": 5,29 }30 expected_color = (87, 46, 140)31 with patch.dict(32 os.environ,33 {"SENSE_HAT_LOG_FILE": "logger.txt", "LOG_DIRECTORY": self.temp_dir.path},34 ):35 sense = SensePi()36 mock_show_message.assert_called_with(37 "MERCURY", text_colour=expected_color, scroll_speed=0.0438 )39 mock_clear.assert_called()40 self.assertTrue(sense.logging is not None)41 self.assertTrue(sense.logging.name == "SENSE_HAT_LOG_FILE")42 self.assertIsInstance(sense.logging, Logger)43 self.assertDictEqual(sense.sensor_ids, expected_sensor_ids)44 def test_init_logs_ids(self, mock_sense):45 mock_show_message = MagicMock()46 mock_clear = MagicMock()47 mock_sense.return_value.show_message = mock_show_message48 mock_sense.return_value.clear = mock_clear49 expected_sensor_ids = {50 "temperature": 5,51 "pressure": 4,52 "humidity": 3,53 "acceleration": 2,54 "orientation": 1,55 }56 expected_color = (87, 46, 140)57 with patch.dict(58 os.environ, {"SENSE_LOG": "logger.txt", "LOG_DIRECTORY": self.temp_dir.path}59 ):60 sense = SensePi(log_file_name="SENSE_LOG", sensor_ids=expected_sensor_ids)61 mock_show_message.assert_called_with(62 "MERCURY", text_colour=expected_color, scroll_speed=0.0463 )64 mock_clear.assert_called()65 self.assertTrue(sense.logging is not None)66 self.assertTrue(sense.logging.name == "SENSE_LOG")67 self.assertIsInstance(sense.logging, Logger)68 self.assertDictEqual(sense.sensor_ids, expected_sensor_ids)69 def test_init_no_logs_ids(self, mock_sense):70 mock_show_message = MagicMock()71 mock_clear = MagicMock()72 mock_sense.return_value.show_message = mock_show_message73 mock_sense.return_value.clear = mock_clear74 expected_sensor_ids = {75 "temperature": 5,76 "pressure": 4,77 "humidity": 3,78 "acceleration": 2,79 "orientation": 1,80 }81 expected_color = (87, 46, 140)82 with patch.dict(83 os.environ,84 {"SENSE_HAT_LOG_FILE": "logger.txt", "LOG_DIRECTORY": self.temp_dir.path},85 ):86 sense = SensePi(sensor_ids=expected_sensor_ids)87 mock_show_message.assert_called_with(88 "MERCURY", text_colour=expected_color, scroll_speed=0.0489 )90 mock_clear.assert_called()91 self.assertTrue(sense.logging is not None)92 self.assertTrue(sense.logging.name == "SENSE_HAT_LOG_FILE")93 self.assertIsInstance(sense.logging, Logger)94 self.assertDictEqual(sense.sensor_ids, expected_sensor_ids)95 def test_init_logs_no_ids(self, mock_sense):96 mock_show_message = MagicMock()97 mock_clear = MagicMock()98 mock_sense.return_value.show_message = mock_show_message99 mock_sense.return_value.clear = mock_clear100 expected_sensor_ids = {101 "temperature": 1,102 "pressure": 2,103 "humidity": 3,104 "acceleration": 4,105 "orientation": 5,106 }107 expected_color = (87, 46, 140)108 with patch.dict(109 os.environ, {"SENSE_LOG": "logger.txt", "LOG_DIRECTORY": self.temp_dir.path}110 ):111 sense = SensePi(log_file_name="SENSE_LOG")112 mock_show_message.assert_called_with(113 "MERCURY", text_colour=expected_color, scroll_speed=0.04114 )115 mock_clear.assert_called()116 self.assertTrue(sense.logging is not None)117 self.assertTrue(sense.logging.name == "SENSE_LOG")118 self.assertIsInstance(sense.logging, Logger)119 self.assertDictEqual(sense.sensor_ids, expected_sensor_ids)120 @patch("hardware.SensorPi.sense_pi.date_str_with_current_timezone")121 def test_factory_temp(self, mock_date, mock_sense):122 mock_show_message = MagicMock()123 mock_clear = MagicMock()124 mock_sense.return_value.show_message = mock_show_message125 mock_sense.return_value.clear = mock_clear126 mock_sense.return_value.get_temperature.return_value = "100"127 mock_sense.return_value.get_pressure.return_value = "50"128 mock_sense.return_value.get_humidity.return_value = "20"129 mock_sense.return_value.get_accelerometer_raw.return_value = "20"130 mock_sense.return_value.get_orientation.return_value = (1, 1, 1)131 date_str = "example_date"132 mock_date.return_value = date_str133 with patch.dict(134 os.environ,135 {"SENSE_HAT_LOG_FILE": "logger.txt", "LOG_DIRECTORY": self.temp_dir.path},136 ):137 sense = SensePi()138 data = sense.factory("TEMPERATURE")139 expected_data = {140 "sensor_id": 1,141 "values": {"temperature": "100"},142 "date": date_str,143 }144 self.assertDictEqual(expected_data, data)145 @patch("hardware.SensorPi.sense_pi.date_str_with_current_timezone")146 def test_factory_pressure(self, mock_date, mock_sense):147 mock_show_message = MagicMock()148 mock_clear = MagicMock()149 mock_sense.return_value.show_message = mock_show_message150 mock_sense.return_value.clear = mock_clear151 mock_sense.return_value.get_temperature.return_value = "100"152 mock_sense.return_value.get_pressure.return_value = "50"153 mock_sense.return_value.get_humidity.return_value = "20"154 mock_sense.return_value.get_accelerometer_raw.return_value = "20"155 mock_sense.return_value.get_orientation.return_value = (1, 1, 1)156 date_str = "example_date"157 mock_date.return_value = date_str158 with patch.dict(159 os.environ,160 {"SENSE_HAT_LOG_FILE": "logger.txt", "LOG_DIRECTORY": self.temp_dir.path},161 ):162 sense = SensePi()163 data = sense.factory("PRESSURE")164 expected_data = {165 "sensor_id": 2,166 "values": {"pressure": "50"},167 "date": date_str,168 }169 self.assertDictEqual(expected_data, data)170 @patch("hardware.SensorPi.sense_pi.date_str_with_current_timezone")171 def test_factory_humidity(self, mock_date, mock_sense):172 mock_show_message = MagicMock()173 mock_clear = MagicMock()174 mock_sense.return_value.show_message = mock_show_message175 mock_sense.return_value.clear = mock_clear176 mock_sense.return_value.get_temperature.return_value = "100"177 mock_sense.return_value.get_pressure.return_value = "50"178 mock_sense.return_value.get_humidity.return_value = "20"179 mock_sense.return_value.get_accelerometer_raw.return_value = "20"180 mock_sense.return_value.get_orientation.return_value = (1, 1, 1)181 date_str = "example_date"182 mock_date.return_value = date_str183 with patch.dict(184 os.environ,185 {"SENSE_HAT_LOG_FILE": "logger.txt", "LOG_DIRECTORY": self.temp_dir.path},186 ):187 sense = SensePi()188 data = sense.factory("HUMIDITY")189 expected_data = {190 "sensor_id": 3,191 "values": {"humidity": "20"},192 "date": date_str,193 }194 self.assertDictEqual(expected_data, data)195 @patch("hardware.SensorPi.sense_pi.date_str_with_current_timezone")196 def test_factory_accel(self, mock_date, mock_sense):197 mock_show_message = MagicMock()198 mock_clear = MagicMock()199 mock_sense.return_value.show_message = mock_show_message200 mock_sense.return_value.clear = mock_clear201 mock_sense.return_value.get_temperature.return_value = "100"202 mock_sense.return_value.get_pressure.return_value = "50"203 mock_sense.return_value.get_humidity.return_value = "20"204 mock_sense.return_value.get_accelerometer_raw.return_value = "20"205 mock_sense.return_value.get_orientation.return_value = (1, 1, 1)206 date_str = "example_date"207 mock_date.return_value = date_str208 with patch.dict(209 os.environ,210 {"SENSE_HAT_LOG_FILE": "logger.txt", "LOG_DIRECTORY": self.temp_dir.path},211 ):212 sense = SensePi()213 data = sense.factory("ACCELERATION")214 expected_data = {215 "sensor_id": 4,216 "values": {"acceleration": "20"},217 "date": date_str,218 }219 self.assertDictEqual(expected_data, data)220 @patch("hardware.SensorPi.sense_pi.date_str_with_current_timezone")221 def test_factory_orientation(self, mock_date, mock_sense):222 mock_show_message = MagicMock()223 mock_clear = MagicMock()224 mock_sense.return_value.show_message = mock_show_message225 mock_sense.return_value.clear = mock_clear226 mock_sense.return_value.get_temperature.return_value = "100"227 mock_sense.return_value.get_pressure.return_value = "50"228 mock_sense.return_value.get_humidity.return_value = "20"229 mock_sense.return_value.get_accelerometer_raw.return_value = "20"230 mock_sense.return_value.get_orientation.return_value = (1, 1, 1)231 date_str = "example_date"232 mock_date.return_value = date_str233 with patch.dict(234 os.environ,235 {"SENSE_HAT_LOG_FILE": "logger.txt", "LOG_DIRECTORY": self.temp_dir.path},236 ):237 sense = SensePi()238 data = sense.factory("ORIENTATION")239 expected_data = {240 "sensor_id": 5,241 "values": {"orientation": (1, 1, 1)},242 "date": date_str,243 }244 self.assertDictEqual(expected_data, data)245 @patch("hardware.SensorPi.sense_pi.date_str_with_current_timezone")246 def test_factory_invalid_key(self, mock_date, mock_sense):247 mock_show_message = MagicMock()248 mock_clear = MagicMock()249 mock_sense.return_value.show_message = mock_show_message250 mock_sense.return_value.clear = mock_clear251 date_str = "example_date"252 mock_date.return_value = date_str253 with patch.dict(254 os.environ,255 {"SENSE_HAT_LOG_FILE": "logger.txt", "LOG_DIRECTORY": self.temp_dir.path},256 ):257 sense = SensePi()258 data = sense.factory("SOME_KEY")259 expected_data = {}260 self.assertDictEqual(expected_data, data)261 @patch("hardware.SensorPi.sense_pi.date_str_with_current_timezone")262 def test_factory_all(self, mock_date, mock_sense):263 mock_show_message = MagicMock()264 mock_clear = MagicMock()265 mock_sense.return_value.show_message = mock_show_message266 mock_sense.return_value.clear = mock_clear267 mock_sense.return_value.get_temperature.return_value = "100"268 mock_sense.return_value.get_pressure.return_value = "50"269 mock_sense.return_value.get_humidity.return_value = "20"270 mock_sense.return_value.get_accelerometer_raw.return_value = "20"271 mock_sense.return_value.get_orientation.return_value = (1, 1, 1)272 date_str = "example_date"273 mock_date.return_value = date_str274 with patch.dict(275 os.environ,276 {"SENSE_HAT_LOG_FILE": "logger.txt", "LOG_DIRECTORY": self.temp_dir.path},277 ):278 sense = SensePi()279 data = sense.factory("ALL")280 expected_data = {281 "values": {282 "temperature": "100",283 "pressure": "50",284 "humidity": "20",285 "acceleration": "20",286 "orientation": (1, 1, 1),287 },288 "date": date_str,289 }290 self.assertDictEqual(expected_data, data)291 @patch("hardware.SensorPi.sense_pi.date_str_with_current_timezone")292 def test_sense_get_all(self, mock_date, mock_sense):293 mock_show_message = MagicMock()294 mock_clear = MagicMock()295 mock_sense.return_value.show_message = mock_show_message296 mock_sense.return_value.clear = mock_clear297 mock_sense.return_value.get_temperature.return_value = "100"298 mock_sense.return_value.get_pressure.return_value = "50"299 mock_sense.return_value.get_humidity.return_value = "20"300 mock_sense.return_value.get_accelerometer_raw.return_value = "20"301 mock_sense.return_value.get_orientation.return_value = (1, 1, 1)302 date_str = "example_date"303 mock_date.return_value = date_str304 with patch.dict(305 os.environ,306 {"SENSE_HAT_LOG_FILE": "logger.txt", "LOG_DIRECTORY": self.temp_dir.path},307 ):308 sense = SensePi()309 data = sense.get_all()310 expected_data = {311 "values": {312 "temperature": "100",313 "pressure": "50",314 "humidity": "20",315 "acceleration": "20",316 "orientation": (1, 1, 1),317 },318 "date": date_str,319 }320 self.assertDictEqual(expected_data, data)321 @patch("hardware.SensorPi.sense_pi.date_str_with_current_timezone")322 def test_sense_get_temp(self, mock_date, mock_sense):323 mock_show_message = MagicMock()324 mock_clear = MagicMock()325 mock_sense.return_value.show_message = mock_show_message326 mock_sense.return_value.clear = mock_clear327 mock_sense.return_value.get_temperature.return_value = "100"328 mock_sense.return_value.get_pressure.return_value = "50"329 mock_sense.return_value.get_humidity.return_value = "20"330 mock_sense.return_value.get_accelerometer_raw.return_value = "20"331 mock_sense.return_value.get_orientation.return_value = (1, 1, 1)332 date_str = "example_date"333 mock_date.return_value = date_str334 with patch.dict(335 os.environ,336 {"SENSE_HAT_LOG_FILE": "logger.txt", "LOG_DIRECTORY": self.temp_dir.path},337 ):338 sense = SensePi()339 data = sense.get_temperature()340 expected_data = {341 "sensor_id": 1,342 "values": {"temperature": "100"},343 "date": date_str,344 }345 self.assertDictEqual(expected_data, data)346 @patch("hardware.SensorPi.sense_pi.date_str_with_current_timezone")347 def test_sense_get_pressure(self, mock_date, mock_sense):348 mock_show_message = MagicMock()349 mock_clear = MagicMock()350 mock_sense.return_value.show_message = mock_show_message351 mock_sense.return_value.clear = mock_clear352 mock_sense.return_value.get_temperature.return_value = "100"353 mock_sense.return_value.get_pressure.return_value = "50"354 mock_sense.return_value.get_humidity.return_value = "20"355 mock_sense.return_value.get_accelerometer_raw.return_value = "20"356 mock_sense.return_value.get_orientation.return_value = (1, 1, 1)357 date_str = "example_date"358 mock_date.return_value = date_str359 with patch.dict(360 os.environ,361 {"SENSE_HAT_LOG_FILE": "logger.txt", "LOG_DIRECTORY": self.temp_dir.path},362 ):363 sense = SensePi()364 data = sense.get_pressure()365 expected_data = {366 "sensor_id": 2,367 "values": {"pressure": "50"},368 "date": date_str,369 }370 self.assertDictEqual(expected_data, data)371 @patch("hardware.SensorPi.sense_pi.date_str_with_current_timezone")372 def test_sense_get_humidity(self, mock_date, mock_sense):373 mock_show_message = MagicMock()374 mock_clear = MagicMock()375 mock_sense.return_value.show_message = mock_show_message376 mock_sense.return_value.clear = mock_clear377 mock_sense.return_value.get_temperature.return_value = "100"378 mock_sense.return_value.get_pressure.return_value = "50"379 mock_sense.return_value.get_humidity.return_value = "20"380 mock_sense.return_value.get_accelerometer_raw.return_value = "20"381 mock_sense.return_value.get_orientation.return_value = (1, 1, 1)382 date_str = "example_date"383 mock_date.return_value = date_str384 with patch.dict(385 os.environ,386 {"SENSE_HAT_LOG_FILE": "logger.txt", "LOG_DIRECTORY": self.temp_dir.path},387 ):388 sense = SensePi()389 data = sense.get_humidity()390 expected_data = {391 "sensor_id": 3,392 "values": {"humidity": "20"},393 "date": date_str,394 }395 self.assertDictEqual(expected_data, data)396 @patch("hardware.SensorPi.sense_pi.date_str_with_current_timezone")397 def test_sense_get_accel(self, mock_date, mock_sense):398 mock_show_message = MagicMock()399 mock_clear = MagicMock()400 mock_sense.return_value.show_message = mock_show_message401 mock_sense.return_value.clear = mock_clear402 mock_sense.return_value.get_temperature.return_value = "100"403 mock_sense.return_value.get_pressure.return_value = "50"404 mock_sense.return_value.get_humidity.return_value = "20"405 mock_sense.return_value.get_accelerometer_raw.return_value = "20"406 mock_sense.return_value.get_orientation.return_value = (1, 1, 1)407 date_str = "example_date"408 mock_date.return_value = date_str409 with patch.dict(410 os.environ,411 {"SENSE_HAT_LOG_FILE": "logger.txt", "LOG_DIRECTORY": self.temp_dir.path},412 ):413 sense = SensePi()414 data = sense.get_acceleration()415 expected_data = {416 "sensor_id": 4,417 "values": {"acceleration": "20"},418 "date": date_str,419 }420 self.assertDictEqual(expected_data, data)421 @patch("hardware.SensorPi.sense_pi.date_str_with_current_timezone")422 def test_sense_get_orientation(self, mock_date, mock_sense):423 mock_show_message = MagicMock()424 mock_clear = MagicMock()425 mock_sense.return_value.show_message = mock_show_message426 mock_sense.return_value.clear = mock_clear427 mock_sense.return_value.get_temperature.return_value = "100"428 mock_sense.return_value.get_pressure.return_value = "50"429 mock_sense.return_value.get_humidity.return_value = "20"430 mock_sense.return_value.get_accelerometer_raw.return_value = "20"431 mock_sense.return_value.get_orientation.return_value = (1, 1, 1)432 date_str = "example_date"433 mock_date.return_value = date_str434 with patch.dict(435 os.environ,436 {"SENSE_HAT_LOG_FILE": "logger.txt", "LOG_DIRECTORY": self.temp_dir.path},437 ):438 sense = SensePi()439 data = sense.get_orientation()440 expected_data = {441 "sensor_id": 5,442 "values": {"orientation": (1, 1, 1)},443 "date": date_str,444 }...

Full Screen

Full Screen

Playwright tutorial

LambdaTest’s Playwright tutorial will give you a broader idea about the Playwright automation framework, its unique features, and use cases with examples to exceed your understanding of Playwright testing. This tutorial will give A to Z guidance, from installing the Playwright framework to some best practices and advanced concepts.

Chapters:

  1. What is Playwright : Playwright is comparatively new but has gained good popularity. Get to know some history of the Playwright with some interesting facts connected with it.
  2. How To Install Playwright : Learn in detail about what basic configuration and dependencies are required for installing Playwright and run a test. Get a step-by-step direction for installing the Playwright automation framework.
  3. Playwright Futuristic Features: Launched in 2020, Playwright gained huge popularity quickly because of some obliging features such as Playwright Test Generator and Inspector, Playwright Reporter, Playwright auto-waiting mechanism and etc. Read up on those features to master Playwright testing.
  4. What is Component Testing: Component testing in Playwright is a unique feature that allows a tester to test a single component of a web application without integrating them with other elements. Learn how to perform Component testing on the Playwright automation framework.
  5. Inputs And Buttons In Playwright: Every website has Input boxes and buttons; learn about testing inputs and buttons with different scenarios and examples.
  6. Functions and Selectors in Playwright: Learn how to launch the Chromium browser with Playwright. Also, gain a better understanding of some important functions like “BrowserContext,” which allows you to run multiple browser sessions, and “newPage” which interacts with a page.
  7. Handling Alerts and Dropdowns in Playwright : Playwright interact with different types of alerts and pop-ups, such as simple, confirmation, and prompt, and different types of dropdowns, such as single selector and multi-selector get your hands-on with handling alerts and dropdown in Playright testing.
  8. Playwright vs Puppeteer: Get to know about the difference between two testing frameworks and how they are different than one another, which browsers they support, and what features they provide.
  9. Run Playwright Tests on LambdaTest: Playwright testing with LambdaTest leverages test performance to the utmost. You can run multiple Playwright tests in Parallel with the LammbdaTest test cloud. Get a step-by-step guide to run your Playwright test on the LambdaTest platform.
  10. Playwright Python Tutorial: Playwright automation framework support all major languages such as Python, JavaScript, TypeScript, .NET and etc. However, there are various advantages to Python end-to-end testing with Playwright because of its versatile utility. Get the hang of Playwright python testing with this chapter.
  11. Playwright End To End Testing Tutorial: Get your hands on with Playwright end-to-end testing and learn to use some exciting features such as TraceViewer, Debugging, Networking, Component testing, Visual testing, and many more.
  12. Playwright Video Tutorial: Watch the video tutorials on Playwright testing from experts and get a consecutive in-depth explanation of Playwright automation testing.

Run Playwright Python automation tests on LambdaTest cloud grid

Perform automation testing on 3000+ real desktop and mobile devices online.

Try LambdaTest Now !!

Get 100 minutes of automation test minutes FREE!!

Next-Gen App & Browser Testing Cloud

Was this article helpful?

Helpful

NotHelpful