test_vm_controlls.py 9.53 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
# Copyright 2014 Budapest University of Technology and Economics (BME IK)
#
# This file is part of CIRCLE Cloud.
#
# CIRCLE is free software: you can redistribute it and/or modify it under
# the terms of the GNU General Public License as published by the Free
# Software Foundation, either version 3 of the License, or (at your option)
# any later version.
#
# CIRCLE is distributed in the hope that it will be useful, but WITHOUT ANY
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
# FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
# details.
#
# You should have received a copy of the GNU General Public License along
# with CIRCLE.  If not, see <http://www.gnu.org/licenses/>.
from selenose.cases import SeleniumTestCase
18 19 20 21 22 23 24
from django.contrib.auth.models import User
import random
import urlparse
import re
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
Csók Tamás committed
25 26 27
random_pass = "".join([random.choice(
    '0123456789abcdefghijklmnopqrstvwxyz') for n in xrange(10)])
wait_max_sec = 10
28 29 30
host = 'https:127.0.0.1'


31
class UtilityMixin(object):
32 33 34 35 36
    def login(self, username, password='password'):
        driver = self.driver
        driver.get('%s/accounts/login/' % host)
        try:
            name_input = driver.find_element_by_id("id_username")
37 38
            password_input = driver.find_element_by_id("id_password")
            submit_input = driver.find_element_by_id("submit-id-submit")
39
        except:
40 41 42 43 44 45 46 47 48
            inputs = driver.find_elements_by_tag_name("input")
            for current_input in inputs:
                input_type = current_input.get_attribute("type")
                if input_type == "text":
                    name_input = current_input
                if input_type == "password":
                    password_input = current_input
                if input_type == "submit":
                    submit_input = current_input
49
        try:
50 51 52 53 54 55 56 57 58
            name_input.clear()
            name_input.send_keys(username)
            password_input.clear()
            password_input.send_keys(password)
            submit_input.click()
            try:  # If selenium runs only in a small (virtual) screen
                driver.find_element_by_class_name('navbar-toggle').click()
            except:
                pass
Csók Tamás committed
59
            WebDriverWait(self.driver, wait_max_sec).until(
60 61
                EC.element_to_be_clickable((
                    By.CSS_SELECTOR, "a[href*='/dashboard/profile/']")))
62
        except:
63 64 65
            raise Exception('Selenium cannot find the form controls')

    def get_link_by_href(self, target_href, attributes=None):
66
        try:
67 68 69 70 71 72 73 74 75 76 77 78 79 80
            links = self.driver.find_elements_by_tag_name('a')
            for link in links:
                href = link.get_attribute('href')
                if href is not None:
                    if target_href in href:
                        perfect_fit = True
                        if isinstance(attributes, dict):
                            for key, target_value in attributes.iteritems():
                                attr_check = link.get_attribute(key)
                                if attr_check is not None:
                                    if target_value not in attr_check:
                                        perfect_fit = False
                        if perfect_fit:
                            return link
81
        except:
82 83
            raise Exception(
                'Selenium cannot find the href=%s link' % target_href)
84

85 86 87 88 89 90 91
    def create_random_vm(self):
        try:
            self.driver.get('%s/dashboard/vm/create/' % host)
            vm_list = []
            pk = None
            vm_list = self.driver.find_elements_by_class_name(
                'vm-create-template-summary')
Csók Tamás committed
92
            self.driver.save_screenshot('screenie.png')
93 94
            choice = random.randint(0, len(vm_list) - 1)
            vm_list[choice].click()
Csók Tamás committed
95
            create = WebDriverWait(self.driver, wait_max_sec).until(
96 97 98
                EC.element_to_be_clickable((
                    By.CLASS_NAME, 'vm-create-start')))
            create.click()
Csók Tamás committed
99
            WebDriverWait(self.driver, wait_max_sec).until(
100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139
                EC.visibility_of_element_located((
                    By.CLASS_NAME, 'alert-success')))
            url = urlparse.urlparse(self.driver.current_url)
            pk = re.search(r'\d+', url.path).group()
            return pk
        except:
            raise Exception('Selenium cannot start any VM')

    def viewChange(self, target_box):
        driver = self.driver
        driver.get('%s/dashboard/' % host)
        list_view = driver.find_element_by_id('%s-list-view' % target_box)
        graph_view = driver.find_element_by_id('%s-graph-view' % target_box)
        js_script = 'return arguments[0].style.display;'
        required_attributes = {'data-index-box': target_box}
        graph_view_link = self.get_link_by_href(
            '#index-graph-view',
            required_attributes).find_element_by_tag_name('i')
        list_view_link = self.get_link_by_href(
            '#index-list-view',
            required_attributes).find_element_by_tag_name('i')
        list_view_link.click()
        states = [driver.execute_script("%s" % js_script, list_view),
                  driver.execute_script("%s" % js_script, graph_view)]
        graph_view_link.click()
        states.extend([driver.execute_script("%s" % js_script, list_view),
                       driver.execute_script("%s" % js_script, graph_view)])
        list_view_link.click()
        states.extend([driver.execute_script("%s" % js_script, list_view),
                       driver.execute_script("%s" % js_script, graph_view)])
        return states

    def delete_vm(self, pk):
        try:
            driver = self.driver
            driver.get('%s/dashboard/vm/%s/' % (host, pk))
            status_span = driver.find_element_by_id('vm-details-state')
            destroy_link = self.get_link_by_href(
                "/dashboard/vm/%s/op/destroy/" % pk)
            destroy_link.click()
Csók Tamás committed
140
            destroy = WebDriverWait(self.driver, wait_max_sec).until(
141 142
                EC.element_to_be_clickable((By.ID, 'op-form-send')))
            destroy.click()
Csók Tamás committed
143
            WebDriverWait(status_span, wait_max_sec).until(
144 145 146 147 148 149 150 151
                EC.visibility_of_element_located((
                    By.CLASS_NAME, 'fa-trash-o')))
            return True
        except:
            raise Exception("Selenium can not destroy a VM")


class VmDetailTest(UtilityMixin, SeleniumTestCase):
152
    def setUp(self):
Csók Tamás committed
153
        self.u1 = User.objects.create(username='test_%s' % random_pass,
154
                                      is_superuser=True)
Csók Tamás committed
155
        self.u1.set_password(random_pass)
156
        self.u1.save()
157
        self.addCleanup(self.u1.delete)
158

159 160 161
    def test_01_login(self):
        title = 'Dashboard | CIRCLE'
        location = '/dashboard/'
Csók Tamás committed
162
        self.login('test_%s' % random_pass, random_pass)
163
        self.driver.get('%s/dashboard/' % host)
164 165
        url = urlparse.urlparse(self.driver.current_url)
        (self.assertIn('%s' % title, self.driver.title,
Csók Tamás committed
166
                       '%s is not found in the title' % title) or
167 168 169 170
            self.assertEqual(url.path, '%s' % location,
                             'URL path is not equal with %s' % location))

    def test_02_able_to_create_vm(self):
Csók Tamás committed
171
        self.login('test_%s' % random_pass, random_pass)
172 173 174
        vm_list = None
        create_vm_link = self.get_link_by_href('/dashboard/vm/create/')
        create_vm_link.click()
Csók Tamás committed
175 176 177
        WebDriverWait(self.driver, wait_max_sec).until(
            EC.visibility_of_element_located((
                By.ID, 'create-modal')))
178 179
        vm_list = self.driver.find_elements_by_class_name(
            'vm-create-template-summary')
Csók Tamás committed
180
        print 'Selenium found %s template possibilities' % len(vm_list)
181
        (self.assertIsNotNone(
Csók Tamás committed
182
            vm_list, "Selenium can not find the VM list") or
183 184 185
            self.assertGreater(len(vm_list), 0, "The create VM list is empty"))

    def test_03_create_vm(self):
Csók Tamás committed
186
        self.login('test_%s' % random_pass, random_pass)
187 188 189 190
        pk = self.create_random_vm()
        self.assertIsNotNone(pk, "Can not create a VM")

    def test_04_vm_view_change(self):
Csók Tamás committed
191
        self.login('test_%s' % random_pass, random_pass)
192 193 194 195 196 197 198 199 200 201
        expected_states = ["", "none",
                           "none", "",
                           "block", "none"]
        states = self.viewChange("vm")
        print 'states: [%s]' % ', '.join(map(str, states))
        print 'expected: [%s]' % ', '.join(map(str, expected_states))
        self.assertListEqual(states, expected_states,
                             "The view mode does not change for VM listing")

    def test_05_node_view_change(self):
Csók Tamás committed
202
        self.login('test_%s' % random_pass, random_pass)
203 204 205 206 207 208 209 210 211 212
        expected_states = ["", "none",
                           "none", "",
                           "block", "none"]
        states = self.viewChange("node")
        print 'states: [%s]' % ', '.join(map(str, states))
        print 'expected: [%s]' % ', '.join(map(str, expected_states))
        self.assertListEqual(states, expected_states,
                             "The view mode does not change for NODE listing")

    def test_06_delete_vm(self):
Csók Tamás committed
213
        self.login('test_%s' % random_pass, random_pass)
214 215
        pk = self.create_random_vm()
        self.assertTrue(self.delete_vm(pk), "Can not delete a VM")