summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexandraAllakhverdieva <aallakhverdieva@mirantis.com>2016-01-28 06:19:18 -0500
committerAlexandra Allakhverdieva <aallakhverdieva@mirantis.com>2016-02-16 12:02:09 +0000
commita2baaf118211f15f19687132611bf9df2edb0ecd (patch)
tree9790f11270c39ec255be956c2f1714304fc5af98
parent227db914bbaeeb9f34f072cd56fe2bd880ac2af6 (diff)
Test for images (create volume/launch instance from image)
Added test_create_volume_from_image() Added test_launch_instance_from_image() Implements blueprint: horizon-integration-tests-coverage Change-Id: Ib127e8516596c0bcf0259f9cc6054d6171a26ee2
Notes
Notes (review): Code-Review+2: Timur Sufiev <tsufiev@mirantis.com> Code-Review+2: Richard Jones <r1chardj0n3s@gmail.com> Workflow+1: Richard Jones <r1chardj0n3s@gmail.com> Code-Review+1: zhurong <aaronzhu1121@gmail.com> Verified+2: Jenkins Submitted-by: Jenkins Submitted-at: Wed, 24 Feb 2016 03:31:41 +0000 Reviewed-on: https://review.openstack.org/273467 Project: openstack/horizon Branch: refs/heads/master
-rw-r--r--openstack_dashboard/test/integration_tests/config.py3
-rw-r--r--openstack_dashboard/test/integration_tests/horizon.conf2
-rw-r--r--openstack_dashboard/test/integration_tests/pages/project/compute/imagespage.py64
-rw-r--r--openstack_dashboard/test/integration_tests/pages/project/compute/instancespage.py5
-rw-r--r--openstack_dashboard/test/integration_tests/tests/test_images.py83
5 files changed, 148 insertions, 9 deletions
diff --git a/openstack_dashboard/test/integration_tests/config.py b/openstack_dashboard/test/integration_tests/config.py
index c4b0c28..c4acee3 100644
--- a/openstack_dashboard/test/integration_tests/config.py
+++ b/openstack_dashboard/test/integration_tests/config.py
@@ -103,6 +103,9 @@ InstancesGroup = [
103 cfg.StrOpt('image_name', 103 cfg.StrOpt('image_name',
104 default='cirros-0.3.4-x86_64-uec (24.0 MB)', 104 default='cirros-0.3.4-x86_64-uec (24.0 MB)',
105 help="Boot Source to be selected for launch Instances"), 105 help="Boot Source to be selected for launch Instances"),
106 cfg.StrOpt('flavor',
107 default='m1.tiny',
108 help="Flavor to be selected for launch Instances"),
106] 109]
107 110
108VolumeGroup = [ 111VolumeGroup = [
diff --git a/openstack_dashboard/test/integration_tests/horizon.conf b/openstack_dashboard/test/integration_tests/horizon.conf
index fbfa378..2707381 100644
--- a/openstack_dashboard/test/integration_tests/horizon.conf
+++ b/openstack_dashboard/test/integration_tests/horizon.conf
@@ -77,6 +77,8 @@ ssh_user=cirros
77available_zone=nova 77available_zone=nova
78#image_name to launch instances 78#image_name to launch instances
79image_name=cirros-0.3.4-x86_64-uec (24.0 MB) 79image_name=cirros-0.3.4-x86_64-uec (24.0 MB)
80#flavor to launch instances
81flavor=m1.tiny
80 82
81[volume] 83[volume]
82volume_type=lvmdriver-1 84volume_type=lvmdriver-1
diff --git a/openstack_dashboard/test/integration_tests/pages/project/compute/imagespage.py b/openstack_dashboard/test/integration_tests/pages/project/compute/imagespage.py
index 0b79bec..e7a4009 100644
--- a/openstack_dashboard/test/integration_tests/pages/project/compute/imagespage.py
+++ b/openstack_dashboard/test/integration_tests/pages/project/compute/imagespage.py
@@ -16,6 +16,11 @@ from openstack_dashboard.test.integration_tests.pages import basepage
16from openstack_dashboard.test.integration_tests.regions import forms 16from openstack_dashboard.test.integration_tests.regions import forms
17from openstack_dashboard.test.integration_tests.regions import tables 17from openstack_dashboard.test.integration_tests.regions import tables
18 18
19from openstack_dashboard.test.integration_tests.pages.project.compute.\
20 instancespage import InstancesPage
21from openstack_dashboard.test.integration_tests.pages.project.compute.\
22 volumes.volumespage import VolumesPage
23
19 24
20class ImagesTable(tables.TableRegion): 25class ImagesTable(tables.TableRegion):
21 name = "images" 26 name = "images"
@@ -27,6 +32,20 @@ class ImagesTable(tables.TableRegion):
27 "minimum_ram", "is_public", "protected" 32 "minimum_ram", "is_public", "protected"
28 ) 33 )
29 34
35 CREATE_VOLUME_FROM_IMAGE_FORM_FIELDS = (
36 "name", "description", "image_source",
37 "type", "size", "availability_zone")
38
39 LAUNCH_INSTANCE_FROM_FIELDS = ((
40 "availability_zone", "name", "flavor",
41 "count", "source_type", "instance_snapshot_id",
42 "volume_id", "volume_snapshot_id", "image_id", "volume_size",
43 "vol_delete_on_instance_delete"),
44 ("keypair", "groups"),
45 ("script_source", "script_upload", "script_data"),
46 ("disk_config", "config_drive")
47 )
48
30 @tables.bind_table_action('create') 49 @tables.bind_table_action('create')
31 def create_image(self, create_button): 50 def create_image(self, create_button):
32 create_button.click() 51 create_button.click()
@@ -38,6 +57,20 @@ class ImagesTable(tables.TableRegion):
38 delete_button.click() 57 delete_button.click()
39 return forms.BaseFormRegion(self.driver, self.conf) 58 return forms.BaseFormRegion(self.driver, self.conf)
40 59
60 @tables.bind_row_action('create_volume_from_image')
61 def create_volume(self, create_volume, row):
62 create_volume.click()
63 return forms.FormRegion(
64 self.driver, self.conf,
65 field_mappings=self.CREATE_VOLUME_FROM_IMAGE_FORM_FIELDS)
66
67 @tables.bind_row_action('launch_image', primary=True)
68 def launch_instance(self, launch_instance, row):
69 launch_instance.click()
70 return forms.TabbedFormRegion(
71 self.driver, self.conf,
72 field_mappings=self.LAUNCH_INSTANCE_FROM_FIELDS)
73
41 74
42class ImagesPage(basepage.BaseNavigationPage): 75class ImagesPage(basepage.BaseNavigationPage):
43 76
@@ -107,3 +140,34 @@ class ImagesPage(basepage.BaseNavigationPage):
107 140
108 def wait_until_image_active(self, name): 141 def wait_until_image_active(self, name):
109 self._wait_until(lambda x: self.is_image_active(name)) 142 self._wait_until(lambda x: self.is_image_active(name))
143
144 def create_volume_from_image(self, name, volume_name=None,
145 description=None,
146 volume_size=None):
147 row = self._get_row_with_image_name(name)
148 create_volume_form = self.images_table.create_volume(row)
149 if volume_name is not None:
150 create_volume_form.name.text = volume_name
151 if description is not None:
152 create_volume_form.description.text = description
153 create_volume_form.image_source = name
154 create_volume_form.size.value = volume_size if volume_size \
155 else self.conf.volume.volume_size
156 create_volume_form.availability_zone.value = \
157 self.conf.launch_instances.available_zone
158 create_volume_form.submit()
159 return VolumesPage(self.driver, self.conf)
160
161 def launch_instance_from_image(self, name, instance_name,
162 instance_count=1, flavor=None):
163 row = self._get_row_with_image_name(name)
164 launch_instance = self.images_table.launch_instance(row)
165 launch_instance.availability_zone.value = \
166 self.conf.launch_instances.available_zone
167 launch_instance.name.text = instance_name
168 if flavor is None:
169 flavor = self.conf.launch_instances.flavor
170 launch_instance.flavor.text = flavor
171 launch_instance.count.value = instance_count
172 launch_instance.submit()
173 return InstancesPage(self.driver, self.conf)
diff --git a/openstack_dashboard/test/integration_tests/pages/project/compute/instancespage.py b/openstack_dashboard/test/integration_tests/pages/project/compute/instancespage.py
index 96eb3ec..183549f 100644
--- a/openstack_dashboard/test/integration_tests/pages/project/compute/instancespage.py
+++ b/openstack_dashboard/test/integration_tests/pages/project/compute/instancespage.py
@@ -54,6 +54,7 @@ class InstancesPage(basepage.BaseNavigationPage):
54 54
55 INSTANCES_TABLE_NAME_COLUMN = 'name' 55 INSTANCES_TABLE_NAME_COLUMN = 'name'
56 INSTANCES_TABLE_STATUS_COLUMN = 'status' 56 INSTANCES_TABLE_STATUS_COLUMN = 'status'
57 INSTANCES_TABLE_IMAGE_NAME_COLUMN = 'image_name'
57 58
58 def __init__(self, driver, conf): 59 def __init__(self, driver, conf):
59 super(InstancesPage, self).__init__(driver, conf) 60 super(InstancesPage, self).__init__(driver, conf)
@@ -135,3 +136,7 @@ class InstancesPage(basepage.BaseNavigationPage):
135 elif 'volume snapshot (creates a new volume)' in boot_source: 136 elif 'volume snapshot (creates a new volume)' in boot_source:
136 return (instance.volume_snapshot_id, 137 return (instance.volume_snapshot_id,
137 self.DEFAULT_VOLUME_SNAPSHOT_NAME) 138 self.DEFAULT_VOLUME_SNAPSHOT_NAME)
139
140 def get_image_name(self, instance_name):
141 row = self._get_row_with_instance_name(instance_name)
142 return row.cells[self.INSTANCES_TABLE_IMAGE_NAME_COLUMN].text
diff --git a/openstack_dashboard/test/integration_tests/tests/test_images.py b/openstack_dashboard/test/integration_tests/tests/test_images.py
index d73375a..11735e8 100644
--- a/openstack_dashboard/test/integration_tests/tests/test_images.py
+++ b/openstack_dashboard/test/integration_tests/tests/test_images.py
@@ -13,10 +13,10 @@
13from openstack_dashboard.test.integration_tests import helpers 13from openstack_dashboard.test.integration_tests import helpers
14from openstack_dashboard.test.integration_tests.regions import messages 14from openstack_dashboard.test.integration_tests.regions import messages
15 15
16IMAGE_NAME = helpers.gen_random_resource_name("image")
16 17
17class TestImages(helpers.TestCase): 18
18 """Login as demo user""" 19class TestImagesBasic(helpers.TestCase):
19 IMAGE_NAME = helpers.gen_random_resource_name("image")
20 20
21 @property 21 @property
22 def images_page(self): 22 def images_page(self):
@@ -31,16 +31,16 @@ class TestImages(helpers.TestCase):
31 """ 31 """
32 images_page = self.images_page 32 images_page = self.images_page
33 33
34 images_page.create_image(self.IMAGE_NAME) 34 images_page.create_image(IMAGE_NAME)
35 self.assertTrue(images_page.find_message_and_dismiss(messages.SUCCESS)) 35 self.assertTrue(images_page.find_message_and_dismiss(messages.SUCCESS))
36 self.assertFalse(images_page.find_message_and_dismiss(messages.ERROR)) 36 self.assertFalse(images_page.find_message_and_dismiss(messages.ERROR))
37 self.assertTrue(images_page.is_image_present(self.IMAGE_NAME)) 37 self.assertTrue(images_page.is_image_present(IMAGE_NAME))
38 self.assertTrue(images_page.is_image_active(self.IMAGE_NAME)) 38 self.assertTrue(images_page.is_image_active(IMAGE_NAME))
39 39
40 images_page.delete_image(self.IMAGE_NAME) 40 images_page.delete_image(IMAGE_NAME)
41 self.assertTrue(images_page.find_message_and_dismiss(messages.SUCCESS)) 41 self.assertTrue(images_page.find_message_and_dismiss(messages.SUCCESS))
42 self.assertFalse(images_page.find_message_and_dismiss(messages.ERROR)) 42 self.assertFalse(images_page.find_message_and_dismiss(messages.ERROR))
43 self.assertFalse(images_page.is_image_present(self.IMAGE_NAME)) 43 self.assertFalse(images_page.is_image_present(IMAGE_NAME))
44 44
45 def test_images_pagination(self): 45 def test_images_pagination(self):
46 """This test checks images pagination 46 """This test checks images pagination
@@ -95,7 +95,72 @@ class TestImages(helpers.TestCase):
95 settings_page.find_message_and_dismiss(messages.SUCCESS) 95 settings_page.find_message_and_dismiss(messages.SUCCESS)
96 96
97 97
98class TestImagesAdmin(helpers.AdminTestCase, TestImages): 98class TestImagesAdvanced(helpers.TestCase):
99 """Login as demo user"""
100
101 @property
102 def images_page(self):
103 return self.home_pg.go_to_compute_imagespage()
104
105 def test_create_volume_from_image(self):
106 """This test case checks create volume from image functionality:
107 Steps:
108 1. Login to Horizon Dashboard as regular user
109 2. Navigate to Project -> Compute -> Images
110 3. Create new volume from image
111 4. Check that volume is created with expected name
112 5. Check that volume status is Available
113 """
114 images_page = self.images_page
115 source_image = self.CONFIG.image.images_list[0]
116 target_volume = "created_from_{0}".format(source_image)
117
118 volumes_page = images_page.create_volume_from_image(
119 source_image, volume_name=target_volume)
120 self.assertTrue(
121 volumes_page.find_message_and_dismiss(messages.INFO))
122 self.assertFalse(
123 volumes_page.find_message_and_dismiss(messages.ERROR))
124 self.assertTrue(volumes_page.is_volume_present(target_volume))
125 self.assertTrue(volumes_page.is_volume_status(target_volume,
126 'Available'))
127 volumes_page.delete_volume(target_volume)
128 volumes_page.find_message_and_dismiss(messages.SUCCESS)
129 volumes_page.find_message_and_dismiss(messages.ERROR)
130 self.assertTrue(volumes_page.is_volume_deleted(target_volume))
131
132 def test_launch_instance_from_image(self):
133 """This test case checks launch instance from image functionality:
134 Steps:
135 1. Login to Horizon Dashboard as regular user
136 2. Navigate to Project -> Compute -> Images
137 3. Launch new instance from image
138 4. Check that instance is create
139 5. Check that status of newly created instance is Active
140 6. Check that image_name in correct in instances table
141 """
142 images_page = self.images_page
143 source_image = self.CONFIG.image.images_list[0]
144 target_instance = "created_from_{0}".format(source_image)
145 instances_page = images_page.launch_instance_from_image(
146 source_image, target_instance)
147 self.assertTrue(
148 instances_page.find_message_and_dismiss(messages.SUCCESS))
149 self.assertFalse(
150 instances_page.find_message_and_dismiss(messages.ERROR))
151 self.assertTrue(instances_page.is_instance_active(target_instance))
152 actual_image_name = instances_page.get_image_name(target_instance)
153 self.assertEqual(source_image, actual_image_name)
154
155 instances_page.delete_instance(target_instance)
156 self.assertTrue(
157 instances_page.find_message_and_dismiss(messages.SUCCESS))
158 self.assertFalse(
159 instances_page.find_message_and_dismiss(messages.ERROR))
160 self.assertTrue(instances_page.is_instance_deleted(target_instance))
161
162
163class TestImagesAdmin(helpers.AdminTestCase, TestImagesBasic):
99 """Login as admin user""" 164 """Login as admin user"""
100 IMAGE_NAME = helpers.gen_random_resource_name("image") 165 IMAGE_NAME = helpers.gen_random_resource_name("image")
101 166