Statistics
| Branch: | Tag: | Revision:

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

History | View | Annotate | Download (8.8 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 d11c80c0 Ilias Tsitsimpis
from synnefo_tools.burnin.common import BurninTests, Proper
46 f772699c Ilias Tsitsimpis
47 f772699c Ilias Tsitsimpis
48 f772699c Ilias Tsitsimpis
# Too many public methods. pylint: disable-msg=R0904
49 d11c80c0 Ilias Tsitsimpis
class FlavorsTestSuite(BurninTests):
50 f772699c Ilias Tsitsimpis
    """Test flavor lists for consistency"""
51 d11c80c0 Ilias Tsitsimpis
    simple_flavors = Proper(value=None)
52 d11c80c0 Ilias Tsitsimpis
    detailed_flavors = Proper(value=None)
53 d11c80c0 Ilias Tsitsimpis
    simple_names = Proper(value=None)
54 f772699c Ilias Tsitsimpis
55 f772699c Ilias Tsitsimpis
    def test_001_simple_flavors(self):
56 f772699c Ilias Tsitsimpis
        """Test flavor list actually returns flavors"""
57 d11c80c0 Ilias Tsitsimpis
        self.simple_flavors = self._get_list_of_flavors(detail=False)
58 f772699c Ilias Tsitsimpis
        self.assertGreater(len(self.simple_flavors), 0)
59 f772699c Ilias Tsitsimpis
60 f772699c Ilias Tsitsimpis
    def test_002_get_detailed_flavors(self):
61 f772699c Ilias Tsitsimpis
        """Test detailed flavor list is the same length as list"""
62 d11c80c0 Ilias Tsitsimpis
        self.detailed_flavors = self._get_list_of_flavors(detail=True)
63 f772699c Ilias Tsitsimpis
        self.assertEquals(len(self.simple_flavors), len(self.detailed_flavors))
64 f772699c Ilias Tsitsimpis
65 f772699c Ilias Tsitsimpis
    def test_003_same_flavor_names(self):
66 f772699c Ilias Tsitsimpis
        """Test detailed and simple flavor list contain same names"""
67 d11c80c0 Ilias Tsitsimpis
        names = sorted([flv['name'] for flv in self.simple_flavors])
68 d11c80c0 Ilias Tsitsimpis
        self.simple_names = names
69 f772699c Ilias Tsitsimpis
        detailed_names = sorted([flv['name'] for flv in self.detailed_flavors])
70 d11c80c0 Ilias Tsitsimpis
        self.assertEqual(self.simple_names, detailed_names)
71 f772699c Ilias Tsitsimpis
72 f772699c Ilias Tsitsimpis
    def test_004_unique_flavor_names(self):
73 f772699c Ilias Tsitsimpis
        """Test flavors have unique names"""
74 f772699c Ilias Tsitsimpis
        self.assertEqual(sorted(list(set(self.simple_names))),
75 f772699c Ilias Tsitsimpis
                         self.simple_names)
76 f772699c Ilias Tsitsimpis
77 f772699c Ilias Tsitsimpis
    def test_005_well_formed_names(self):
78 f772699c Ilias Tsitsimpis
        """Test flavors have well formed names
79 f772699c Ilias Tsitsimpis

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

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