Statistics
| Branch: | Tag: | Revision:

root / snf-tools / synnefo_tools / burnin / images_tests.py @ c2f037ff

History | View | Annotate | Download (9 kB)

1 f772699c Ilias Tsitsimpis
2 f772699c Ilias Tsitsimpis
# Copyright 2013 GRNET S.A. All rights reserved.
3 f772699c Ilias Tsitsimpis
#
4 f772699c Ilias Tsitsimpis
# Redistribution and use in source and binary forms, with or
5 f772699c Ilias Tsitsimpis
# without modification, are permitted provided that the following
6 f772699c Ilias Tsitsimpis
# conditions are met:
7 f772699c Ilias Tsitsimpis
#
8 f772699c Ilias Tsitsimpis
#   1. Redistributions of source code must retain the above
9 f772699c Ilias Tsitsimpis
#      copyright notice, this list of conditions and the following
10 f772699c Ilias Tsitsimpis
#      disclaimer.
11 f772699c Ilias Tsitsimpis
#
12 f772699c Ilias Tsitsimpis
#   2. Redistributions in binary form must reproduce the above
13 f772699c Ilias Tsitsimpis
#      copyright notice, this list of conditions and the following
14 f772699c Ilias Tsitsimpis
#      disclaimer in the documentation and/or other materials
15 f772699c Ilias Tsitsimpis
#      provided with the distribution.
16 f772699c Ilias Tsitsimpis
#
17 f772699c Ilias Tsitsimpis
# THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS
18 f772699c Ilias Tsitsimpis
# OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
19 f772699c Ilias Tsitsimpis
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
20 f772699c Ilias Tsitsimpis
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR
21 f772699c Ilias Tsitsimpis
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
22 f772699c Ilias Tsitsimpis
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
23 f772699c Ilias Tsitsimpis
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
24 f772699c Ilias Tsitsimpis
# USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
25 f772699c Ilias Tsitsimpis
# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26 f772699c Ilias Tsitsimpis
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
27 f772699c Ilias Tsitsimpis
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28 f772699c Ilias Tsitsimpis
# POSSIBILITY OF SUCH DAMAGE.
29 f772699c Ilias Tsitsimpis
#
30 f772699c Ilias Tsitsimpis
# The views and conclusions contained in the software and
31 f772699c Ilias Tsitsimpis
# documentation are those of the authors and should not be
32 f772699c Ilias Tsitsimpis
# interpreted as representing official policies, either expressed
33 f772699c Ilias Tsitsimpis
# or implied, of GRNET S.A.
34 f772699c Ilias Tsitsimpis
35 f772699c Ilias Tsitsimpis
"""
36 f772699c Ilias Tsitsimpis
This is the burnin class that tests the Flavors/Images functionality
37 f772699c Ilias Tsitsimpis

38 f772699c Ilias Tsitsimpis
"""
39 f772699c Ilias Tsitsimpis
40 f772699c Ilias Tsitsimpis
import os
41 f772699c Ilias Tsitsimpis
import shutil
42 f772699c Ilias Tsitsimpis
43 f772699c Ilias Tsitsimpis
from kamaki.clients import ClientError
44 f772699c Ilias Tsitsimpis
45 c2f037ff Ilias Tsitsimpis
from synnefo_tools.burnin.common import BurninTests, Proper, \
46 c2f037ff Ilias Tsitsimpis
    QPITHOS, QADD, QREMOVE
47 f772699c Ilias Tsitsimpis
48 f772699c Ilias Tsitsimpis
49 9355a604 Ilias Tsitsimpis
# pylint: disable=too-many-public-methods
50 d11c80c0 Ilias Tsitsimpis
class FlavorsTestSuite(BurninTests):
51 f772699c Ilias Tsitsimpis
    """Test flavor lists for consistency"""
52 d11c80c0 Ilias Tsitsimpis
    simple_flavors = Proper(value=None)
53 d11c80c0 Ilias Tsitsimpis
    detailed_flavors = Proper(value=None)
54 d11c80c0 Ilias Tsitsimpis
    simple_names = Proper(value=None)
55 f772699c Ilias Tsitsimpis
56 f772699c Ilias Tsitsimpis
    def test_001_simple_flavors(self):
57 f772699c Ilias Tsitsimpis
        """Test flavor list actually returns flavors"""
58 d11c80c0 Ilias Tsitsimpis
        self.simple_flavors = self._get_list_of_flavors(detail=False)
59 f772699c Ilias Tsitsimpis
        self.assertGreater(len(self.simple_flavors), 0)
60 f772699c Ilias Tsitsimpis
61 f772699c Ilias Tsitsimpis
    def test_002_get_detailed_flavors(self):
62 f772699c Ilias Tsitsimpis
        """Test detailed flavor list is the same length as list"""
63 d11c80c0 Ilias Tsitsimpis
        self.detailed_flavors = self._get_list_of_flavors(detail=True)
64 f772699c Ilias Tsitsimpis
        self.assertEquals(len(self.simple_flavors), len(self.detailed_flavors))
65 f772699c Ilias Tsitsimpis
66 f772699c Ilias Tsitsimpis
    def test_003_same_flavor_names(self):
67 f772699c Ilias Tsitsimpis
        """Test detailed and simple flavor list contain same names"""
68 d11c80c0 Ilias Tsitsimpis
        names = sorted([flv['name'] for flv in self.simple_flavors])
69 d11c80c0 Ilias Tsitsimpis
        self.simple_names = names
70 f772699c Ilias Tsitsimpis
        detailed_names = sorted([flv['name'] for flv in self.detailed_flavors])
71 d11c80c0 Ilias Tsitsimpis
        self.assertEqual(self.simple_names, detailed_names)
72 f772699c Ilias Tsitsimpis
73 f772699c Ilias Tsitsimpis
    def test_004_unique_flavor_names(self):
74 f772699c Ilias Tsitsimpis
        """Test flavors have unique names"""
75 f772699c Ilias Tsitsimpis
        self.assertEqual(sorted(list(set(self.simple_names))),
76 f772699c Ilias Tsitsimpis
                         self.simple_names)
77 f772699c Ilias Tsitsimpis
78 f772699c Ilias Tsitsimpis
    def test_005_well_formed_names(self):
79 f772699c Ilias Tsitsimpis
        """Test flavors have well formed names
80 f772699c Ilias Tsitsimpis

81 f772699c Ilias Tsitsimpis
        Test flavors have names of the form CxxRyyDzz, where xx is vCPU count,
82 f772699c Ilias Tsitsimpis
        yy is RAM in MiB, zz is Disk in GiB
83 f772699c Ilias Tsitsimpis

84 f772699c Ilias Tsitsimpis
        """
85 f772699c Ilias Tsitsimpis
        for flv in self.detailed_flavors:
86 f772699c Ilias Tsitsimpis
            flavor = (flv['vcpus'], flv['ram'], flv['disk'],
87 f772699c Ilias Tsitsimpis
                      flv['SNF:disk_template'])
88 f772699c Ilias Tsitsimpis
            self.assertEqual("C%dR%dD%d%s" % flavor, flv['name'],
89 f772699c Ilias Tsitsimpis
                             "Flavor %s doesn't match its specs" % flv['name'])
90 f772699c Ilias Tsitsimpis
91 f772699c Ilias Tsitsimpis
92 f772699c Ilias Tsitsimpis
# --------------------------------------------------------------------
93 9355a604 Ilias Tsitsimpis
# pylint: disable=too-many-public-methods
94 d11c80c0 Ilias Tsitsimpis
class ImagesTestSuite(BurninTests):
95 f772699c Ilias Tsitsimpis
    """Test image lists for consistency"""
96 d11c80c0 Ilias Tsitsimpis
    simple_images = Proper(value=None)
97 d11c80c0 Ilias Tsitsimpis
    detailed_images = Proper(value=None)
98 d11c80c0 Ilias Tsitsimpis
    system_images = Proper(value=None)
99 d11c80c0 Ilias Tsitsimpis
    temp_dir = Proper(value=None)
100 d11c80c0 Ilias Tsitsimpis
    temp_image_name = Proper(value=None)
101 d11c80c0 Ilias Tsitsimpis
    temp_image_file = Proper(value=None)
102 f772699c Ilias Tsitsimpis
103 f772699c Ilias Tsitsimpis
    def test_001_list_images(self):
104 f772699c Ilias Tsitsimpis
        """Test simple image list actually returns images"""
105 d11c80c0 Ilias Tsitsimpis
        self.simple_images = self._get_list_of_images(detail=False)
106 d11c80c0 Ilias Tsitsimpis
        self.assertGreater(len(self.simple_images), 0)
107 f772699c Ilias Tsitsimpis
108 f772699c Ilias Tsitsimpis
    def test_002_list_images_detailed(self):
109 f772699c Ilias Tsitsimpis
        """Test detailed image list is the same length as simple list"""
110 d11c80c0 Ilias Tsitsimpis
        self.detailed_images = self._get_list_of_images(detail=True)
111 d11c80c0 Ilias Tsitsimpis
        self.assertEqual(len(self.simple_images), len(self.detailed_images))
112 f772699c Ilias Tsitsimpis
113 f772699c Ilias Tsitsimpis
    def test_003_same_image_names(self):
114 f772699c Ilias Tsitsimpis
        """Test detailed and simple image list contain the same names"""
115 f772699c Ilias Tsitsimpis
        snames = sorted([i['name'] for i in self.simple_images])
116 f772699c Ilias Tsitsimpis
        dnames = sorted([i['name'] for i in self.detailed_images])
117 f772699c Ilias Tsitsimpis
        self.assertEqual(snames, dnames)
118 f772699c Ilias Tsitsimpis
119 f772699c Ilias Tsitsimpis
    def test_004_system_images(self):
120 f772699c Ilias Tsitsimpis
        """Test that there are system images registered"""
121 f772699c Ilias Tsitsimpis
        images = self._get_list_of_sys_images(images=self.detailed_images)
122 d11c80c0 Ilias Tsitsimpis
        self.system_images = images
123 f772699c Ilias Tsitsimpis
        self.assertGreater(len(images), 0)
124 f772699c Ilias Tsitsimpis
125 f772699c Ilias Tsitsimpis
    def test_005_unique_image_names(self):
126 f772699c Ilias Tsitsimpis
        """Test system images have unique names"""
127 f772699c Ilias Tsitsimpis
        names = sorted([i['name'] for i in self.system_images])
128 f772699c Ilias Tsitsimpis
        self.assertEqual(sorted(list(set(names))), names)
129 f772699c Ilias Tsitsimpis
130 f772699c Ilias Tsitsimpis
    def test_006_image_metadata(self):
131 f772699c Ilias Tsitsimpis
        """Test every system image has specific metadata defined"""
132 f772699c Ilias Tsitsimpis
        keys = frozenset(["osfamily", "root_partition"])
133 f772699c Ilias Tsitsimpis
        for i in self.system_images:
134 f772699c Ilias Tsitsimpis
            self.assertTrue(keys.issubset(i['properties'].keys()))
135 f772699c Ilias Tsitsimpis
136 f772699c Ilias Tsitsimpis
    def test_007_download_image(self):
137 f772699c Ilias Tsitsimpis
        """Download image from Pithos"""
138 f772699c Ilias Tsitsimpis
        # Find the 'Debian Base' image
139 6c78720b Ilias Tsitsimpis
        images = self._find_images(["name:^Debian Base$"],
140 6c78720b Ilias Tsitsimpis
                                   images=self.system_images)
141 6c78720b Ilias Tsitsimpis
        image = images[0]
142 6c78720b Ilias Tsitsimpis
        self.info("Will use %s with id %s", image['name'], image['id'])
143 f772699c Ilias Tsitsimpis
        image_location = \
144 f772699c Ilias Tsitsimpis
            image['location'].replace("://", " ").replace("/", " ").split()
145 f772699c Ilias Tsitsimpis
        image_owner = image_location[1]
146 f772699c Ilias Tsitsimpis
        self.info("Image's owner is %s", image_owner)
147 f772699c Ilias Tsitsimpis
        image_container = image_location[2]
148 f772699c Ilias Tsitsimpis
        self.info("Image's container is %s", image_container)
149 f772699c Ilias Tsitsimpis
        image_name = image_location[3]
150 f772699c Ilias Tsitsimpis
        self.info("Image's name is %s", image_name)
151 d11c80c0 Ilias Tsitsimpis
        self.temp_image_name = image_name
152 f772699c Ilias Tsitsimpis
153 f772699c Ilias Tsitsimpis
        self._set_pithos_account(image_owner)
154 f772699c Ilias Tsitsimpis
        self._set_pithos_container(image_container)
155 f772699c Ilias Tsitsimpis
156 f772699c Ilias Tsitsimpis
        # Create temp directory
157 d11c80c0 Ilias Tsitsimpis
        self.temp_dir = self._create_tmp_directory()
158 d11c80c0 Ilias Tsitsimpis
        self.temp_image_file = \
159 d11c80c0 Ilias Tsitsimpis
            os.path.join(self.temp_dir, self.temp_image_name)
160 f772699c Ilias Tsitsimpis
161 f772699c Ilias Tsitsimpis
        # Write to file
162 cee3ee9b Ilias Tsitsimpis
        self.info("Downloading image to %s", self.temp_image_file)
163 f772699c Ilias Tsitsimpis
        with open(self.temp_image_file, "w+b") as fout:
164 f772699c Ilias Tsitsimpis
            self.clients.pithos.download_object(image_name, fout)
165 f772699c Ilias Tsitsimpis
166 f772699c Ilias Tsitsimpis
    def test_008_upload_image(self):
167 f772699c Ilias Tsitsimpis
        """Upload the image to Pithos"""
168 f772699c Ilias Tsitsimpis
        self._set_pithos_account(self._get_uuid())
169 f772699c Ilias Tsitsimpis
        self._create_pithos_container("burnin-images")
170 3e5bbd85 Ilias Tsitsimpis
        file_size = os.path.getsize(self.temp_image_file)
171 f772699c Ilias Tsitsimpis
        with open(self.temp_image_file, "r+b") as fin:
172 f772699c Ilias Tsitsimpis
            self.clients.pithos.upload_object(self.temp_image_name, fin)
173 f772699c Ilias Tsitsimpis
174 3e5bbd85 Ilias Tsitsimpis
        # Verify quotas
175 c2f037ff Ilias Tsitsimpis
        changes = \
176 c2f037ff Ilias Tsitsimpis
            {self._get_uuid(): [(QPITHOS, QADD, file_size, None)]}
177 c2f037ff Ilias Tsitsimpis
        self._check_quotas(changes)
178 3e5bbd85 Ilias Tsitsimpis
179 f772699c Ilias Tsitsimpis
    def test_009_register_image(self):
180 f772699c Ilias Tsitsimpis
        """Register image to Plankton"""
181 f772699c Ilias Tsitsimpis
        location = "pithos://" + self._get_uuid() + \
182 f772699c Ilias Tsitsimpis
            "/burnin-images/" + self.temp_image_name
183 f772699c Ilias Tsitsimpis
        self.info("Registering image %s", location)
184 f772699c Ilias Tsitsimpis
185 f772699c Ilias Tsitsimpis
        params = {'is_public': False}
186 f772699c Ilias Tsitsimpis
        properties = {'OSFAMILY': "linux", 'ROOT_PARTITION': 1}
187 f772699c Ilias Tsitsimpis
        self.clients.image.register(self.temp_image_name, location,
188 f772699c Ilias Tsitsimpis
                                    params, properties)
189 f772699c Ilias Tsitsimpis
190 f772699c Ilias Tsitsimpis
        # Check that image is registered
191 f772699c Ilias Tsitsimpis
        self.info("Checking that image has been registered")
192 f772699c Ilias Tsitsimpis
        images = self._get_list_of_images(detail=True)
193 f772699c Ilias Tsitsimpis
        images = [i for i in images if i['location'] == location]
194 f772699c Ilias Tsitsimpis
        self.assertEqual(len(images), 1)
195 f772699c Ilias Tsitsimpis
        self.info("Image registered with id %s", images[0]['id'])
196 f772699c Ilias Tsitsimpis
197 f772699c Ilias Tsitsimpis
    def test_010_cleanup_image(self):
198 f772699c Ilias Tsitsimpis
        """Remove uploaded image from Pithos"""
199 f772699c Ilias Tsitsimpis
        # Remove uploaded image
200 f772699c Ilias Tsitsimpis
        self.info("Deleting uploaded image %s", self.temp_image_name)
201 f772699c Ilias Tsitsimpis
        self.clients.pithos.del_object(self.temp_image_name)
202 3e5bbd85 Ilias Tsitsimpis
        # Verify quotas
203 3e5bbd85 Ilias Tsitsimpis
        file_size = os.path.getsize(self.temp_image_file)
204 c2f037ff Ilias Tsitsimpis
        changes = \
205 c2f037ff Ilias Tsitsimpis
            {self._get_uuid(): [(QPITHOS, QREMOVE, file_size, None)]}
206 c2f037ff Ilias Tsitsimpis
        self._check_quotas(changes)
207 d11c80c0 Ilias Tsitsimpis
        self.temp_image_name = None
208 f772699c Ilias Tsitsimpis
        # Remove temp directory
209 f772699c Ilias Tsitsimpis
        self.info("Deleting temp directory %s", self.temp_dir)
210 f772699c Ilias Tsitsimpis
        self._remove_tmp_directory(self.temp_dir)
211 d11c80c0 Ilias Tsitsimpis
        self.temp_dir = None
212 f772699c Ilias Tsitsimpis
213 f772699c Ilias Tsitsimpis
    @classmethod
214 f772699c Ilias Tsitsimpis
    def tearDownClass(cls):  # noqa
215 f772699c Ilias Tsitsimpis
        """Clean up"""
216 f772699c Ilias Tsitsimpis
        if cls.temp_image_name is not None:
217 f772699c Ilias Tsitsimpis
            try:
218 f772699c Ilias Tsitsimpis
                cls.clients.pithos.del_object(cls.temp_image_name)
219 f772699c Ilias Tsitsimpis
            except ClientError:
220 f772699c Ilias Tsitsimpis
                pass
221 f772699c Ilias Tsitsimpis
222 f772699c Ilias Tsitsimpis
        if cls.temp_dir is not None:
223 f772699c Ilias Tsitsimpis
            try:
224 f772699c Ilias Tsitsimpis
                shutil.rmtree(cls.temp_dir)
225 f772699c Ilias Tsitsimpis
            except OSError:
226 f772699c Ilias Tsitsimpis
                pass