def testSetup(self):
        self.driver = self.getDriver()
        self.loginPage = LoginPage(driver=self.driver, url=self.webUIHostName)
        self.headerPage = HeaderPage(driver=self.driver)
        self.allStoragePage = AllStoragePage(driver=self.driver)
        self.lunsPage = LUNsPage(driver=self.driver)

        self.marscluster.snapshot.deleteAll()
        luns = express.Luns(node=self.marscluster, cleanup=True)
        del luns
        self.luns = express.Luns(node=self.marscluster)

        LOG.step('Signing in')
        self.loginPage.open()
        if self.locale is None:
            self.locale = self.loginPage.getRandomLocale()
        self.loginPage.signIn(username=self.username,
                              password=self.password,
                              locale=self.locale)
        LOG.info('Signed in with username: %s, password: %s, locale: %s.' %
                 (self.username, self.password, self.locale))
        LOG.info('Browser landed on header page.')

        LOG.info('Navigating to LUNs page...')
        self.headerPage.btnManager.click()
        self.allStoragePage.tabLUNs.click()
        self.lunsPage.waitUntilOpen()
        LOG.info('Browser landed on LUNs page.')
Esempio n. 2
0
 def testSetup(self):
     self.driver = self.setupDriver()
     self.loginPage = LoginPage(driver=self.driver, url=self.webUIHostName)
     self.headerPage = HeaderPage(driver=self.driver)
     self.allStoragePage = AllStoragePage(driver=self.driver)
     self.lunsPage = LUNsPage(driver=self.driver)
     self.defineLUNsPage = DefineLUNsPage(driver=self.driver)
Esempio n. 3
0
    def testSetup(self):
        self.driver = self.getDriver()
        self.driver.timeout = self.timeout
        self.loginPage = LoginPage(driver=self.driver, url=self.webUIHostName)
        self.headerPage = HeaderPage(driver=self.driver)
        self.allStoragePage = AllStoragePage(driver=self.driver)
        self.lunsPage = LUNsPage(driver=self.driver)

        LOG.info('Destroying existing LUNs...')
        self.marscluster.lun.unmapAll()
        self.marscluster.lun.destroyAll()
        self.assertFalse(self.marscluster.lun.show(json=True))
        LOG.info('Done.')
        LOG.info('Destroying existing initiator groups...')
        self.marscluster.igroup.destroyAll()
        LOG.info('Done.')
        LOG.info('Destroying existing consistency groups...')
        self.deleteDependentConsistencyGroups()
        LOG.info('Done.')

        if self.locale is None:
            self.locale = self.loginPage.getRandomLocale()
        self.loginPage.signIn(username=self.username,
                              password=self.password,
                              locale=self.locale)
    def testSetup(self):
        self.driver = self.getDriver()
        self.loginPage = LoginPage(driver=self.driver, url=self.webUIHostName)
        self.initiatorGroupsPage = InitiatorGroupsPage(driver=self.driver)

        LOG.info('Destroying existing LUNs...')
        self.marscluster.lun.unmapAll()
        self.marscluster.lun.destroyAll()
        self.assertFalse(self.marscluster.lun.show(json=True))
        LOG.info('Done.')
        LOG.info('Destroying existing initiator groups...')
        self.marscluster.igroup.destroyAll()
        LOG.info('Done.')

        self.luns = express.Luns(node=self.marscluster)

        LOG.step('Signing in')
        self.loginPage.open()
        self.loginPage.waitUntilOpen()
        if self.locale is None:
            self.locale = self.loginPage.getRandomLocale()
        self.loginPage.signIn(username=self.username, password=self.password, locale=self.locale)
        LOG.info('Signed in with username: %s, password: %s, locale: %s.' % (self.username,
            self.password, self.locale))
        LOG.info('Browser landed on header page.')
    def testSetup(self):
        self.driver = self.setupDriver()
        self.loginPage = LoginPage(driver=self.driver, url=self.webUIHostName)
        self.headerPage = HeaderPage(driver=self.driver)
        self.allStoragePage = AllStoragePage(driver=self.driver)
        self.lunsPage = LUNsPage(driver=self.driver)

        LOG.step('Signing in')
        self.loginPage.open()
        self.loginPage.waitUntilOpen()
        self.loginPage.signIn(username=self.username,
                              password=self.password,
                              locale=self.locale)
        LOG.info('Signed in with username: %s, password: %s, locale: %s.' %
                 (self.username, self.password, self.locale))
        LOG.info('Browser landed on header page.')

        LOG.step('Navigating to LUNs page')
        self.headerPage.btnManager.click()
        self.allStoragePage.tabLUNs.click()
        self.lunsPage.waitUntilOpen()
        LOG.info('Browser landed on LUNs page.')

        LOG.step('Creating LUNs')
        self.lunNamePrefix = 'LuN'
        self.lunCount = 20
        self.luns.create(count=self.lunCount,
                         size='1g',
                         prefix=self.lunNamePrefix)
        luns = self.marscluster.lun.show(json=True)
        LOG.info('LUNs created:\n', [lun['name'] for lun in luns])

        self.lunsPage.btnRefresh.click()
        self.lunsPage.btnRefresh.waitUntilEnabled()
Esempio n. 6
0
    def testSetup(self):
        self.driver = self.getDriver()
        self.loginPage = LoginPage(driver=self.driver, url=self.webUIHostName)
        self.headerPage = HeaderPage(driver=self.driver)
        self.allStoragePage = AllStoragePage(driver=self.driver)
        self.lunsPage = LUNsPage(driver=self.driver)

        self.loginPage.signIn(username=self.username, password=self.password)
    def testSetup(self):
        self.driver = self.getDriver()
        self.loginPage = LoginPage(driver=self.driver, url=self.webUIHostName)
        self.headerPage = HeaderPage(driver=self.driver)
        self.loginFailedPage = LoginFailedPage(driver=self.driver)

        LOG.step('Opening login page')
        self.loginPage.open()

        if self.locale is None:
            self.locale = self.loginPage.getRandomLocale()

        LOG.step('Selecting locale: %s' % self.locale)
        self.loginPage.selectLocale(locale=self.locale)
        LOG.info('Selected locale: %s' % self.locale)
Esempio n. 8
0
    def testSetup(self):
        self.driver = self.getDriver()
        self.loginPage = LoginPage(driver=self.driver, url=self.webUIHostName)
        self.headerPage = HeaderPage(driver=self.driver)
        self.allStoragePage = AllStoragePage(driver=self.driver)
        self.lunsPage = LUNsPage(driver=self.driver)
        self.lunDetailsPage = LUNDetailsPage(driver=self.driver)
        self.lunSnapshotsPage = LUNSnapshotsPage(driver=self.driver)

        LOG.step('Cleaning out cluster content')
        snapshots = self.marscluster.snapshot.show(json=True)
        for snapshot in snapshots:
            self.marscluster.snapshot.delete(name=snapshot['name'],
                                             lun=snapshot['object'])
        self.assertFalse(self.marscluster.snapshot.show(json=True))
        LOG.info('Snapshots destroyed.')

        luns = express.Luns(node=self.marscluster, cleanup=True)
        del luns
        self.assertFalse(self.marscluster.lun.show(json=True))
        LOG.info('LUNs destroyed.')

        self.marscluster.igroup.destroyAll()
        LOG.info('Initiator groups destroyed.')

        self._deleteDependentConsistencyGroups()
        LOG.info('Consistency groups destroyed.')

        self.luns = express.Luns(node=self.marscluster)

        LOG.step('Signing in')
        self.loginPage.open()
        self.loginPage.waitUntilOpen()
        if self.locale is None:
            self.locale = self.loginPage.getRandomLocale()
        self.loginPage.signIn(username=self.username,
                              password=self.password,
                              locale=self.locale)
        LOG.info('Signed in with username: %s, password: %s, locale: %s.' %
                 (self.username, self.password, self.locale))
        LOG.info('Browser landed on header page.')

        LOG.info('Navigating to LUNs page...')
        self.headerPage.btnManager.click()
        self.allStoragePage.tabLUNs.click()
        self.lunsPage.waitUntilOpen()
        LOG.info('Browser landed on LUNs page.')
Esempio n. 9
0
    def testSetup(self):
        self.driver = self.getDriver()
        self.loginPage = LoginPage(driver=self.driver, url=self.webUIHostName)
        self.headerPage = HeaderPage(driver=self.driver)
        self.allStoragePage = AllStoragePage(driver=self.driver)
        self.consistencyGroupsPage = ConsistencyGroupsPage(driver=self.driver)

        LOG.step('Cleaning out cluster content')
        LOG.info('Destroying LUNs...')
        luns = express.Luns(node=self.marscluster, cleanup=True)
        del luns
        self.assertFalse(self.marscluster.lun.show(json=True))
        LOG.info('Done.')
        LOG.info('Deleting consistency groups...')
        while True:
            consistencyGroups = self.marscluster.cg.show(json=True)
            if consistencyGroups:
                self.marscluster.cg.delete(name=consistencyGroups[0]['name'])
            else:
                break
        self.assertFalse(self.marscluster.cg.show(json=True))
        LOG.info('Done.')

        self.luns = express.Luns(node=self.marscluster)

        LOG.step('Signing in')
        self.loginPage.open()
        self.loginPage.waitUntilOpen()
        if self.locale is None:
            self.locale = self.loginPage.getRandomLocale()
        self.loginPage.signIn(username=self.username,
                              password=self.password,
                              locale=self.locale)
        LOG.info('Signed in with username: %s, password: %s, locale: %s.' %
                 (self.username, self.password, self.locale))
        LOG.info('Browser landed on header page.')

        LOG.info('Navigating to Consistency Groups page...')
        self.headerPage.btnManager.click()
        self.allStoragePage.tabConsistencyGroups.click()
        self.consistencyGroupsPage.waitUntilOpen()
        LOG.info('Browser landed on Consistency Groups page.')
    def testSetup(self):
        self.driver = self.getDriver()
        self.loginPage = LoginPage(driver=self.driver, url=self.webUIHostName)
        self.headerPage = HeaderPage(driver=self.driver)
        self.allStoragePage = AllStoragePage(driver=self.driver)
        self.lunsPage = LUNsPage(driver=self.driver)

        self.mars[0].lun.unmapAll()
        self.mars[0].lun.destroyAll()
        self.luns = express.Luns(node=self.node, cleanup=True)

        self.loginPage.signIn(username=self.username,
                              password=self.password,
                              locale=self.locale)

        LOG.step('Navigating to All Storage -> LUNs page')
        self.headerPage.btnManager.waitUntilPresent()
        self.headerPage.btnManager.click()
        self.allStoragePage.tabLUNs.waitUntilPresent()
        self.allStoragePage.tabLUNs.click()
        self.lunsPage.gridLUNs.waitUntilPresent()
        LOG.info("Grid is present on web page.")
    def testSetup(self):
        self.driver = self.getDriver()
        self.loginPage = LoginPage(driver=self.driver, url=self.webUIHostName)

        LOG.info('Destroying existing LUNs...')
        self.marscluster.lun.unmapAll()
        self.marscluster.lun.destroyAll()
        self.assertFalse(self.marscluster.lun.show(json=True))
        LOG.info('Done.')
        LOG.info('Destroying existing initiator groups...')
        self.marscluster.igroup.destroyAll()
        LOG.info('Done.')
        LOG.info('Destroying existing consistency groups...')
        self._deleteDependentConsistencyGroups()
        LOG.info('Done.')

        if self.locale is None:
            self.locale = self.loginPage.getRandomLocale()
        self.loginPage.signIn(username=self.username,
                              password=self.password,
                              locale=self.locale)
        LOG.info('Signed in with username: %s, password: %s, locale: %s.' %
                 (self.username, self.password, self.locale))
    def testSetup(self):
        self.driver = self.getDriver()
        self.loginPage = LoginPage(driver=self.driver, url=self.webUIHostName)
        self.headerPage = HeaderPage(driver=self.driver)
        self.allStoragePage = AllStoragePage(driver=self.driver)
        self.initiatorGroupsPage = InitiatorGroupsPage(driver=self.driver)

        LOG.step('Cleaning out cluster content')
        LOG.info('Destroying LUNs...')
        luns = express.Luns(node=self.marscluster, cleanup=True)
        del luns
        self.assertFalse(self.marscluster.lun.show(json=True))
        LOG.info('Done.')
        LOG.info('Destroying existing initiator groups...')
        self.marscluster.igroup.destroyAll()
        LOG.info('Done.')

        self.luns = express.Luns(node=self.marscluster)

        LOG.step('Signing in')
        self.loginPage.open()
        self.loginPage.waitUntilOpen()
        if self.locale is None:
            self.locale = self.loginPage.getRandomLocale()
        self.loginPage.signIn(username=self.username,
                              password=self.password,
                              locale=self.locale)
        LOG.info('Signed in with username: %s, password: %s, locale: %s.' %
                 (self.username, self.password, self.locale))
        LOG.info('Browser landed on header page.')

        LOG.info('Navigating to Initiator Groups page...')
        self.headerPage.btnManager.click()
        self.allStoragePage.tabInitiatorGroups.click()
        self.initiatorGroupsPage.waitUntilOpen()
        LOG.info('Browser landed on Initiator Groups page.')
class TestLoginPage(FRTestCase):
    def suiteSetup(self):
        self.username = ARGS.values.username
        self.invalidUsername = ARGS.values.invalidusername
        self.password = ARGS.values.password
        self.invalidPassword = ARGS.values.invalidpassword
        self.locale = ARGS.values.locale
        self.webUIHostName = getFQDN(self.marscluster.getMasterNode().hostname)

    def testSetup(self):
        self.driver = self.getDriver()
        self.loginPage = LoginPage(driver=self.driver, url=self.webUIHostName)
        self.headerPage = HeaderPage(driver=self.driver)
        self.loginFailedPage = LoginFailedPage(driver=self.driver)

        LOG.step('Opening login page')
        self.loginPage.open()

        if self.locale is None:
            self.locale = self.loginPage.getRandomLocale()

        LOG.step('Selecting locale: %s' % self.locale)
        self.loginPage.selectLocale(locale=self.locale)
        LOG.info('Selected locale: %s' % self.locale)

    def test_validate_components(self):
        """
            This validates availability of components on login page.
        """
        supportLinkHRef = 'http://support.netapp.com/'
        productName = 'FlashRay System Manager'

        LOG.step('Validating help links availability')

        self.loginPage.linkHelp.waitUntilPresent()
        self.assertTrue(self.loginPage.linkHelp.isPresent())
        self.assertTrue(self.loginPage.linkHelp.isVisible())
        LOG.info('Help link available.')

        self.assertTrue(self.loginPage.linkSupport.isPresent())
        self.assertTrue(self.loginPage.linkSupport.isVisible())
        self.assertTrue(
            self.loginPage.linkSupport.getHref() == supportLinkHRef)
        LOG.info('Support link available.')

        self.assertTrue(self.loginPage.linkNetApp.isPresent())
        self.assertTrue(self.loginPage.linkNetApp.isVisible())
        LOG.info('Company page link available.')

        LOG.step('Validating company branding availability')

        self.assertTrue(self.loginPage.imgCompanyLogo.isPresent())
        self.assertTrue(self.loginPage.imgCompanyLogo.isVisible())
        LOG.info('Company logo available.')

        self.assertTrue(self.loginPage.lblProductName.isPresent())
        self.assertTrue(self.loginPage.lblProductName.isVisible())
        self.assertTrue(productName in self.loginPage.lblProductName.getText())
        LOG.info('Product name label available.')

        self.assertTrue(self.loginPage.lblProductVersion.isPresent())
        self.assertTrue(self.loginPage.lblProductVersion.isVisible())
        LOG.info('Product version label available.')

        LOG.step('Validating input controls availability')

        self.assertTrue(self.loginPage.lblUsername.isPresent())
        self.assertTrue(self.loginPage.lblUsername.isVisible())
        LOG.info('Username label available.')

        self.assertTrue(self.loginPage.lblPassword.isPresent())
        self.assertTrue(self.loginPage.lblPassword.isVisible())
        LOG.info('Password label available.')

        self.assertTrue(self.loginPage.txtUsername.isPresent())
        self.assertTrue(self.loginPage.txtUsername.isVisible())
        LOG.info('Username input box available.')

        self.assertTrue(self.loginPage.txtPassword.isPresent())
        self.assertTrue(self.loginPage.txtPassword.isVisible())
        LOG.info('Password input box available.')

        self.assertTrue(self.loginPage.btnSignIn.isPresent())
        self.assertTrue(self.loginPage.btnSignIn.isVisible())
        LOG.info('Sign-in button available.')

        self.assertTrue(self.loginPage.menuLocale.isPresent())
        self.assertTrue(self.loginPage.menuLocale.isVisible())
        self.assertTrue(self.loginPage.menuLocale.isEnabled())
        LOG.info('Locale selection menu available.')

    def test_valid_login(self):
        LOG.step('Typing username')

        self.loginPage.txtUsername.setText(self.username)
        self.assertTrue(self.loginPage.txtUsername.getText() == self.username)
        LOG.info('Username:'******'Typing password')

        self.loginPage.txtPassword.waitUntilPresent()
        self.loginPage.txtPassword.setText(self.password)
        self.assertTrue(self.loginPage.txtPassword.getText() == self.password)
        LOG.info('Password:'******'Sign In'")

        self.loginPage.btnSignIn.waitUntilEnabled()
        self.loginPage.btnSignIn.click()

        LOG.step("Expecting button 'Manager' on header page")

        self.headerPage.btnManager.waitUntilPresent()
        self.assertTrue(self.headerPage.btnManager.isPresent())
        self.assertTrue(self.headerPage.btnManager.isEnabled())
        self.assertTrue(self.headerPage.btnManager.isVisible())
        LOG.info("Button 'Manager' is present on web page.")

        LOG.step('Logging out web page')

        self.headerPage.menuUser.select(item='Sign Out')
        self.loginPage.waitUntilLoaded()

        LOG.step('Verifying login page is open')
        self.loginPage.lblProductName.waitUntilPresent()
        self.assertTrue(self.loginPage.lblProductName.isPresent())
        self.assertTrue(self.loginPage.lblProductName.isVisible())
        LOG.info('Product name label is present on login page.')

    def test_invalid_username(self):
        self._testInvalidInputs(username=self.invalidUsername,
                                password=self.password)

    def test_invalid_password(self):
        self._testInvalidInputs(username=self.username,
                                password=self.invalidPassword)

    def test_invalid_inputs(self):
        self._testInvalidInputs(username=self.invalidUsername,
                                password=self.invalidPassword)

    def test_blank_username(self):
        self._testInvalidInputs(password=self.password)

    def test_blank_password(self):
        self._testInvalidInputs(username=self.username)

    def test_blank_inputs(self):
        self._testInvalidInputs()

    def _testInvalidInputs(self, username='', password=''):
        LOG.step('Clearing username input box')

        self.loginPage.txtUsername.waitUntilPresent()
        self.loginPage.txtUsername.clear()

        if username:
            LOG.step('Typing username')

            self.loginPage.txtUsername.setText(username)
            self.assertTrue(self.loginPage.txtUsername.getText() == username)
        LOG.info('Username:'******'Clearing password input box')

        self.loginPage.txtPassword.clear()

        if password:
            LOG.step('Typing password')

            self.loginPage.txtPassword.setText(password)
            self.assertTrue(self.loginPage.txtPassword.getText() == password)
        LOG.info('Password:'******'Sign-in button disabled')
        # One or both credentials are invalid
        else:
            LOG.step("Clicking on button 'Sign In'")

            self.loginPage.btnSignIn.waitUntilPresent()
            self.loginPage.btnSignIn.waitUntilEnabled()
            self.loginPage.btnSignIn.click()

            LOG.step("Expecting login failed dialog")

            self.loginFailedPage.lblTitle.waitUntilPresent()
            LOG.info('Title label is present on login failed page')

            LOG.step('Closing login failed dialog')

            self.loginFailedPage.btnOK.click()
            self.loginPage.waitUntilLoaded()
            self.loginPage.lblProductName.waitUntilPresent()
            LOG.info('Product name label is present on login page')

    def testTeardown(self):
        self.driver.close()

    def suiteTeardown(self):
        LOG.step('suiteTeardown: Closing browser')
        self.driver.quit()
class TestEditLUNMappingsWizard(FRTestCase):
    def suiteSetup(self):
        self.username = ARGS.values.username
        self.password = ARGS.values.password
        self.locale = ARGS.values.locale
        self.webUIHostName = getFQDN(self.marscluster.getMasterNode().hostname)

    def testSetup(self):
        self.driver = self.getDriver()
        self.loginPage = LoginPage(driver=self.driver, url=self.webUIHostName)
        self.headerPage = HeaderPage(driver=self.driver)
        self.allStoragePage = AllStoragePage(driver=self.driver)
        self.lunsPage = LUNsPage(driver=self.driver)

        LOG.step('Cleaning out cluster content')
        LOG.info('Destroying LUNs...')
        luns = express.Luns(node=self.marscluster, cleanup=True)
        del luns
        self.assertFalse(self.marscluster.lun.show(json=True))
        LOG.info('Done.')
        LOG.info('Destroying existing initiator groups...')
        self.marscluster.igroup.destroyAll()
        LOG.info('Done.')
        LOG.info('Destroying existing consistency groups...')
        self.deleteDependentConsistencyGroups()
        LOG.info('Done.')

        self.luns = express.Luns(node=self.marscluster)

        LOG.step('Signing in')
        self.loginPage.open()
        self.loginPage.waitUntilOpen()
        if self.locale is None:
            self.locale = self.loginPage.getRandomLocale()
        self.loginPage.signIn(username=self.username,
                              password=self.password,
                              locale=self.locale)
        LOG.info('Signed in with username: %s, password: %s, locale: %s.' %
                 (self.username, self.password, self.locale))
        LOG.info('Browser landed on header page.')

        LOG.info('Navigating to LUNs page...')
        self.headerPage.btnManager.click()
        self.allStoragePage.tabLUNs.click()
        self.lunsPage.waitUntilOpen()
        LOG.info('Browser landed on LUNs page.')

    def deleteDependentConsistencyGroups(self):
        while True:
            consistencyGroups = self.marscluster.cg.show(json=True)
            if not consistencyGroups:
                break
            else:
                for consistencyGroup in consistencyGroups:
                    if 'cg' not in consistencyGroup:
                        self.marscluster.cg.delete(
                            name=consistencyGroup['name'])

    def test_no_ig(self):
        """
            Verify wizard's grid is empty when no initiators groups exist.
        """
        LOG.step('Creating LUNs')
        lunCount = 3
        lunSize = 2
        lunSizeUnit = 'G'
        lunNamePrefix = 'LuN'
        self.luns.create(count=lunCount,
                         size=str(lunSize) + lunSizeUnit,
                         prefix=lunNamePrefix)
        LOG.info('LUNs created:\n', self.marscluster.lun.show(json=True))

        # Refresh LUN grid
        self.lunsPage.btnRefresh.click()
        self.lunsPage.btnRefresh.waitUntilEnabled()

        LOG.step('Opening wizard')
        wizard = EditLUNMappingsWizard(driver=self.driver)
        wizard.open(name=lunNamePrefix + '_1')
        LOG.info('Wizard open')

        LOG.step('Verifying no initiator groups are available')
        initiatorGroups = wizard.activePage.gridInitiatorGroups.find()
        self.assertFalse(initiatorGroups)
        LOG.info('Initiators groups available:', initiatorGroups)

        LOG.step("Verifying button 'OK' is disabled")
        self.assertFalse(wizard.activePage.btnOK.isEnabled())
        LOG.info("Button 'OK' enabled:", wizard.activePage.btnOK.isEnabled())

    def test_mapped(self):
        """
            Verify proper LUN mapping on wizard's page.
        """
        LOG.step('Creating LUNs')
        lunCount = 3
        lunSize = 2
        lunSizeUnit = 'G'
        lunNamePrefix = 'LuN'
        initiatorGroupName = 'IG-'
        initiatorGroupsNumber = 5
        self.luns.create(count=lunCount,
                         size=str(lunSize) + lunSizeUnit,
                         prefix=lunNamePrefix)
        LOG.info('LUNs created:\n', self.marscluster.lun.show(json=True))

        LOG.step('Creating initiator groups')
        for initiatorIndex in range(initiatorGroupsNumber):
            fictiveWWPN = format(random.randrange(sys.maxint),
                                 'x').rjust(16, 'f')
            self.marscluster.igroup.create(name=(initiatorGroupName +
                                                 str(initiatorIndex)),
                                           ostype='vmware',
                                           initiators=fictiveWWPN)
        initiatorGroups = self.marscluster.igroup.show(json=True)
        LOG.info('Initiator groups created:\n', initiatorGroups)

        LOG.step('Mapping LUN to initiator groups')
        self.marscluster.lun.map({
            'name': lunNamePrefix + '_1',
            'igroup': initiatorGroups[0]['name']
        })
        self.marscluster.lun.map({
            'name': lunNamePrefix + '_1',
            'igroup': initiatorGroups[-1]['name']
        })
        LOG.info('LUN mapped:\n', self.marscluster.lun.mapping_show(json=True))

        # Refresh LUN grid
        self.lunsPage.btnRefresh.click()
        self.lunsPage.btnRefresh.waitUntilEnabled()

        LOG.step('Opening wizard')
        wizard = EditLUNMappingsWizard(driver=self.driver)
        wizard.open(name=lunNamePrefix + '_1')
        LOG.info('Wizard open')

        self.assertTrue(wizard.activePage.lblName.getText() == lunNamePrefix +
                        '_1')

        LOG.step('Verifying LUN mapping')
        groups = wizard.activePage.gridInitiatorGroups.find()
        self.assertTrue(len(initiatorGroups) == len(groups))
        for group in groups:
            if (group['initiator_groups'] == initiatorGroups[0]['name']) or \
            (group['initiator_groups'] == initiatorGroups[-1]['name']):
                self.assertTrue(group['selected'] == True)
                LOG.info("LUN '%s' mapped to initiator group: %s" %
                         (lunNamePrefix + '_1', group['initiator_groups']))
            else:
                self.assertFalse(group['selected'] == True)

    def test_not_mapped(self):
        """
            Verify no mapping on wizard's page when LUN not mapped.
        """
        LOG.step('Creating LUNs')
        lunCount = 3
        lunSize = 2
        lunSizeUnit = 'G'
        lunNamePrefix = 'LuN'
        initiatorGroupName = 'IG-'
        initiatorGroupsNumber = 5
        self.luns.create(count=lunCount,
                         size=str(lunSize) + lunSizeUnit,
                         prefix=lunNamePrefix)
        LOG.info('LUNs created:\n', self.marscluster.lun.show(json=True))

        LOG.step('Creating initiator groups')
        for initiatorIndex in range(initiatorGroupsNumber):
            fictiveWWPN = format(random.randrange(sys.maxint),
                                 'x').rjust(16, 'f')
            self.marscluster.igroup.create(name=(initiatorGroupName +
                                                 str(initiatorIndex)),
                                           ostype='vmware',
                                           initiators=fictiveWWPN)
        initiatorGroups = self.marscluster.igroup.show(json=True)
        LOG.info('Initiator groups created:\n', initiatorGroups)

        # Refresh LUN grid
        self.lunsPage.btnRefresh.click()
        self.lunsPage.btnRefresh.waitUntilEnabled()

        LOG.step('Opening wizard')
        wizard = EditLUNMappingsWizard(driver=self.driver)
        wizard.open(name=lunNamePrefix + '_1')
        LOG.info('Wizard open')

        self.assertTrue(wizard.activePage.lblName.getText() == lunNamePrefix +
                        '_1')

        LOG.step('Verifying LUN not mapped')
        groups = wizard.activePage.gridInitiatorGroups.find()
        self.assertTrue(len(initiatorGroups) == len(groups))
        for group in groups:
            self.assertFalse(group['selected'] == True)
            LOG.info("LUN '%s' mapped to '%s': %s" %
                     (lunNamePrefix + '_1', group['initiator_groups'],
                      group['selected']))

    def test_map(self):
        """
            Verify LUN mapping made in wizard.
        """
        LOG.step('Creating LUNs')
        lunCount = 3
        lunSize = 2
        lunSizeUnit = 'G'
        lunNamePrefix = 'LuN'
        initiatorGroupName = 'IG-'
        initiatorGroupsNumber = 5
        self.luns.create(count=lunCount,
                         size=str(lunSize) + lunSizeUnit,
                         prefix=lunNamePrefix)
        LOG.info('LUNs created:\n', self.marscluster.lun.show(json=True))

        LOG.step('Creating initiator groups')
        for initiatorIndex in range(initiatorGroupsNumber):
            fictiveWWPN = format(random.randrange(sys.maxint),
                                 'x').rjust(16, 'f')
            self.marscluster.igroup.create(name=(initiatorGroupName +
                                                 str(initiatorIndex)),
                                           ostype='vmware',
                                           initiators=fictiveWWPN)
        initiatorGroups = self.marscluster.igroup.show(json=True)
        LOG.info('Initiator groups created:\n', initiatorGroups)

        # Refresh LUN grid
        self.lunsPage.btnRefresh.click()
        self.lunsPage.btnRefresh.waitUntilEnabled()

        LOG.step('Opening wizard')
        wizard = EditLUNMappingsWizard(driver=self.driver)
        wizard.open(name=lunNamePrefix + '_1')
        LOG.info('Wizard open')

        self.assertTrue(wizard.activePage.lblName.getText() == lunNamePrefix +
                        '_1')

        LOG.step('Mapping LUN to initiator groups')
        self.assertTrue(
            len(initiatorGroups) == len(
                wizard.activePage.gridInitiatorGroups.find()))
        # Select first and last initiator groups in grid
        wizard.activePage.gridInitiatorGroups.select(initiator_groups=[
            initiatorGroups[0]['name'], initiatorGroups[-1]['name']
        ])
        LOG.info('Initiator groups selected:\n',
                 wizard.activePage.gridInitiatorGroups.find(selected=True))
        wizard.activePage.submit()
        LOG.info('Wizard submitted.')

        LOG.step('Verifying LUN mapping')
        mappedGroups = [
            group['igroup-name']
            for group in self.marscluster.lun.mapping_show(json=True)
        ]
        self.assertTrue(len(mappedGroups) == 2)
        self.assertTrue(initiatorGroups[0]['name'] in mappedGroups)
        LOG.info("LUN '%s' mapped to initiator group: %s" %
                 (lunNamePrefix + '_1', initiatorGroups[0]['name']))
        self.assertTrue(initiatorGroups[-1]['name'] in mappedGroups)
        LOG.info("LUN '%s' mapped to initiator group: %s" %
                 (lunNamePrefix + '_1', initiatorGroups[-1]['name']))

    def test_remap(self):
        """
            Verify proper LUN re-mapping on wizard's page.
        """
        LOG.step('Creating LUNs')
        lunCount = 3
        lunSize = 2
        lunSizeUnit = 'G'
        lunNamePrefix = 'LuN'
        initiatorGroupName = 'IG-'
        initiatorGroupsNumber = 5
        self.luns.create(count=lunCount,
                         size=str(lunSize) + lunSizeUnit,
                         prefix=lunNamePrefix)
        LOG.info('LUNs created:\n', self.marscluster.lun.show(json=True))

        LOG.step('Creating initiator groups')
        for initiatorIndex in range(initiatorGroupsNumber):
            fictiveWWPN = format(random.randrange(sys.maxint),
                                 'x').rjust(16, 'f')
            self.marscluster.igroup.create(name=(initiatorGroupName +
                                                 str(initiatorIndex)),
                                           ostype='vmware',
                                           initiators=fictiveWWPN)
        initiatorGroups = self.marscluster.igroup.show(json=True)
        LOG.info('Initiator groups created:\n', initiatorGroups)

        LOG.step('Mapping LUN to initiator groups')
        # Map to first and last initiator groups
        self.marscluster.lun.map({
            'name': lunNamePrefix + '_1',
            'igroup': initiatorGroups[0]['name']
        })
        self.marscluster.lun.map({
            'name': lunNamePrefix + '_1',
            'igroup': initiatorGroups[-1]['name']
        })
        LOG.info('LUN mapped:\n', self.marscluster.lun.mapping_show(json=True))

        # Refresh LUN grid
        self.lunsPage.btnRefresh.click()
        self.lunsPage.btnRefresh.waitUntilEnabled()

        LOG.step('Opening wizard')
        wizard = EditLUNMappingsWizard(driver=self.driver)
        wizard.open(name=lunNamePrefix + '_1')
        LOG.info('Wizard open')

        LOG.step('Re-mapping LUN')
        # Map LUN to second initiator group instead of 1st and last ones
        wizard.activePage.selectInitiatorGroups(
            name=[initiatorGroups[1]['name']])
        LOG.info('Mapping set to initiator group:', initiatorGroups[1]['name'])
        wizard.activePage.submit()
        LOG.info('Wizard submitted.')

        LOG.step('Verifying LUN mapping')
        lunMapping = self.marscluster.lun.mapping_show(json=True)
        self.assertTrue(len(lunMapping) == 1)
        self.assertTrue(
            lunMapping[0]['igroup-name'] == initiatorGroups[1]['name'])
        LOG.info("LUN '%s' mapped to initiator group: %s" %
                 (lunNamePrefix + '_1', lunMapping[0]['igroup-name']))

    def test_unmap(self):
        """
            Verify LUN un-mapping on wizard's page.
        """
        LOG.step('Creating LUNs')
        lunCount = 3
        lunSize = 2
        lunSizeUnit = 'G'
        lunNamePrefix = 'LuN'
        initiatorGroupName = 'IG-'
        initiatorGroupsNumber = 5
        self.luns.create(count=lunCount,
                         size=str(lunSize) + lunSizeUnit,
                         prefix=lunNamePrefix)
        LOG.info('LUNs created:\n', self.marscluster.lun.show(json=True))

        LOG.step('Creating initiator groups')
        for initiatorIndex in range(initiatorGroupsNumber):
            fictiveWWPN = format(random.randrange(sys.maxint),
                                 'x').rjust(16, 'f')
            self.marscluster.igroup.create(name=(initiatorGroupName +
                                                 str(initiatorIndex)),
                                           ostype='vmware',
                                           initiators=fictiveWWPN)
        initiatorGroups = self.marscluster.igroup.show(json=True)
        LOG.info('Initiator groups created:\n', initiatorGroups)

        LOG.step('Mapping LUN to initiator groups')
        # Map to first and last initiator groups
        self.marscluster.lun.map({
            'name': lunNamePrefix + '_1',
            'igroup': initiatorGroups[0]['name']
        })
        self.marscluster.lun.map({
            'name': lunNamePrefix + '_1',
            'igroup': initiatorGroups[-1]['name']
        })
        LOG.info('LUN mapped:\n', [
            lun for lun in self.marscluster.lun.mapping_show(json=True)
            if lun['lun-name'] == lunNamePrefix + '_1'
        ][0])

        # Refresh LUN grid
        self.lunsPage.btnRefresh.click()
        self.lunsPage.btnRefresh.waitUntilEnabled()

        LOG.step('Opening wizard')
        wizard = EditLUNMappingsWizard(driver=self.driver)
        wizard.open(name=lunNamePrefix + '_1')
        LOG.info('Wizard open.')

        LOG.step('Unselecting all initiator groups')
        wizard.activePage.selectInitiatorGroups()
        self.assertFalse(
            wizard.activePage.gridInitiatorGroups.find(selected=True))
        LOG.info('Selected initiator groups:',
                 wizard.activePage.gridInitiatorGroups.find(selected=True))
        wizard.activePage.submit()
        LOG.info('Wizard submitted.')

        LOG.step('Verifying LUN has been um-mapped')
        lunMapping = [
            lun for lun in self.marscluster.lun.mapping_show(json=True)
            if lun['lun-name'] == lunNamePrefix + '_1'
        ]
        self.assertFalse(lunMapping)
        LOG.info("LUN '%s' has no mappings." % (lunNamePrefix + '_1'))

    def test_dialog_cancel(self):
        """
            Verify LUN mapping remains intact on wizard cancellation.
        """
        LOG.step('Creating LUNs')
        lunCount = 3
        lunSize = 2
        lunSizeUnit = 'G'
        lunNamePrefix = 'LuN'
        initiatorGroupName = 'IG-'
        initiatorGroupsNumber = 5
        self.luns.create(count=lunCount,
                         size=str(lunSize) + lunSizeUnit,
                         prefix=lunNamePrefix)
        LOG.info('LUNs created:\n', self.marscluster.lun.show(json=True))

        LOG.step('Creating initiator groups')
        for initiatorIndex in range(initiatorGroupsNumber):
            fictiveWWPN = format(random.randrange(sys.maxint),
                                 'x').rjust(16, 'f')
            self.marscluster.igroup.create(name=(initiatorGroupName +
                                                 str(initiatorIndex)),
                                           ostype='vmware',
                                           initiators=fictiveWWPN)
        initiatorGroups = self.marscluster.igroup.show(json=True)
        LOG.info('Initiator groups created:\n', initiatorGroups)

        LOG.step('Mapping LUN to initiator groups')
        # Map to first and last initiator groups
        self.marscluster.lun.map({
            'name': lunNamePrefix + '_1',
            'igroup': initiatorGroups[0]['name']
        })
        self.marscluster.lun.map({
            'name': lunNamePrefix + '_1',
            'igroup': initiatorGroups[-1]['name']
        })
        originalMappings = [
            lun for lun in self.marscluster.lun.mapping_show(json=True)
            if lun['lun-name'] == lunNamePrefix + '_1'
        ]
        LOG.info('LUN mapped:\n', originalMappings)

        # Refresh LUN grid
        self.lunsPage.btnRefresh.click()
        self.lunsPage.btnRefresh.waitUntilEnabled()

        LOG.step('Opening wizard')
        wizard = EditLUNMappingsWizard(driver=self.driver)
        wizard.open(name=lunNamePrefix + '_1')
        LOG.info('Wizard open.')

        LOG.step('Canceling wizard')
        wizard.cancel()
        LOG.info('Wizard closed without submission.')

        LOG.step('Verifying LUN mappings')
        mappings = [
            lun['igroup-name']
            for lun in self.marscluster.lun.mapping_show(json=True)
            if lun['lun-name'] == lunNamePrefix + '_1'
        ]
        self.assertTrue(len(originalMappings) == len(mappings))
        for mapping in originalMappings:
            self.assertTrue(mapping['igroup-name'] in mappings)
            LOG.info("LUN '%s' mapped to initiator group: %s" %
                     (lunNamePrefix + '_1', mapping['igroup-name']))
        LOG.info('LUN mappings remain intact.')

    def test_dialog_not_available(self):
        """
            Verify menu item 'Edit -> Mappings' not available when multiple LUNs selected in grid.
        """
        LOG.step('Creating LUNs')
        lunCount = 3
        lunSize = 2
        lunSizeUnit = 'G'
        lunNamePrefix = 'LuN'
        initiatorGroupName = 'IG-'
        initiatorGroupsNumber = 5
        self.luns.create(count=lunCount,
                         size=str(lunSize) + lunSizeUnit,
                         prefix=lunNamePrefix)
        LOG.info('LUNs created:\n', self.marscluster.lun.show(json=True))

        LOG.step('Creating initiator groups')
        for initiatorIndex in range(initiatorGroupsNumber):
            fictiveWWPN = format(random.randrange(sys.maxint),
                                 'x').rjust(16, 'f')
            self.marscluster.igroup.create(name=(initiatorGroupName +
                                                 str(initiatorIndex)),
                                           ostype='vmware',
                                           initiators=fictiveWWPN)
        initiatorGroups = self.marscluster.igroup.show(json=True)
        LOG.info('Initiator groups created:\n', initiatorGroups)

        LOG.step('Mapping LUN to initiator groups')
        # Map to first and last initiator groups
        self.marscluster.lun.map({
            'name': lunNamePrefix + '_1',
            'igroup': initiatorGroups[0]['name']
        })
        self.marscluster.lun.map({
            'name': lunNamePrefix + '_1',
            'igroup': initiatorGroups[-1]['name']
        })
        originalMappings = [
            lun for lun in self.marscluster.lun.mapping_show(json=True)
            if lun['lun-name'] == lunNamePrefix + '_1'
        ]
        LOG.info('LUN mapped:\n', originalMappings)

        # Refresh LUN grid
        self.lunsPage.btnRefresh.click()
        self.lunsPage.btnRefresh.waitUntilEnabled()

        LOG.step('Selecting multiple LUNs')
        self.lunsPage.gridLUNs.select()
        LOG.info('LUNs selected:\n',
                 self.lunsPage.gridLUNs.find(selected=True))

        LOG.step("Checking state of menu 'Edit'")
        self.assertFalse(self.lunsPage.menuEdit.isItemEnabled(item='Mappings'))
        LOG.info("Menu item 'Edit -> Mappings' is enabled:",
                 self.lunsPage.menuEdit.isItemEnabled(item='Mappings'))

    def testTeardown(self):
        self.driver.close()
        luns = express.Luns(node=self.marscluster, cleanup=True)
        del luns
        LOG.info('LUNs destroyed.')

    def suiteTeardown(self):
        LOG.step('Closing browser')
        self.driver.quit()
class TestCreateLUNSnapshotWizard(FRTestCase):
    def suiteSetup(self):
        self.username = ARGS.values.username
        self.password = ARGS.values.password
        self.locale = ARGS.values.locale
        self.webUIHostName = getFQDN(self.marscluster.getMasterNode().hostname)

    def testSetup(self):
        self.driver = self.getDriver()
        self.loginPage = LoginPage(driver=self.driver, url=self.webUIHostName)
        self.headerPage = HeaderPage(driver=self.driver)
        self.allStoragePage = AllStoragePage(driver=self.driver)
        self.lunsPage = LUNsPage(driver=self.driver)

        self.marscluster.snapshot.deleteAll()
        luns = express.Luns(node=self.marscluster, cleanup=True)
        del luns
        self.luns = express.Luns(node=self.marscluster)

        LOG.step('Signing in')
        self.loginPage.open()
        if self.locale is None:
            self.locale = self.loginPage.getRandomLocale()
        self.loginPage.signIn(username=self.username,
                              password=self.password,
                              locale=self.locale)
        LOG.info('Signed in with username: %s, password: %s, locale: %s.' %
                 (self.username, self.password, self.locale))
        LOG.info('Browser landed on header page.')

        LOG.info('Navigating to LUNs page...')
        self.headerPage.btnManager.click()
        self.allStoragePage.tabLUNs.click()
        self.lunsPage.waitUntilOpen()
        LOG.info('Browser landed on LUNs page.')

    def test_create_default_name(self):
        """
            Verify snapshot creation with default snapshot name.
        """
        LOG.step('Creating LUNs')
        lunCount = 3
        lunSize = 1
        lunSizeUnit = 'G'
        lunNamePrefix = 'LuN'
        self.luns.create(count=lunCount,
                         size=str(lunSize) + lunSizeUnit,
                         prefix=lunNamePrefix)
        LOG.info('LUNs created:\n', self.marscluster.lun.show(json=True))

        # Refresh LUN grid
        self.lunsPage.btnRefresh.click()
        self.lunsPage.btnRefresh.waitUntilEnabled()

        LOG.step('Opening dialog')
        wizard = CreateLUNSnapshotWizard(driver=self.driver)
        wizard.open(name=lunNamePrefix + '_1')
        LOG.info('Dialog is open.')

        LOG.step('Verifying snapshot default name')
        self.assertTrue(wizard.activePage.txtName.getText() == lunNamePrefix +
                        '_1_snap_0')
        LOG.info('Snapshot name:', wizard.activePage.txtName.getText())

        LOG.step('Creating snapshot copy')
        wizard.activePage.submit()
        LOG.info('Dialog submitted.')

        LOG.step('Verifying snapshot has been created')
        snapshots = self.marscluster.snapshot.show(json=True)
        self.assertTrue(len(snapshots) == 1)
        self.assertTrue(snapshots[0]['create-time-object'] == lunNamePrefix +
                        '_1')
        LOG.info('LUN name:', snapshots[0]['create-time-object'])
        self.assertTrue(snapshots[0]['name'] == lunNamePrefix + '_1_snap_0')
        LOG.info('Snapshot name:', snapshots[0]['name'])

    def test_create_custom_name(self):
        """
            Verify snapshot creation with customized name.
        """
        LOG.step('Creating LUNs')
        lunCount = 3
        lunSize = 1
        lunSizeUnit = 'G'
        lunNamePrefix = 'LuN'
        snapshotName = 'Snapshot-100'
        self.luns.create(count=lunCount,
                         size=str(lunSize) + lunSizeUnit,
                         prefix=lunNamePrefix)
        LOG.info('LUNs created:\n', self.marscluster.lun.show(json=True))

        # Refresh LUN grid
        self.lunsPage.btnRefresh.click()
        self.lunsPage.btnRefresh.waitUntilEnabled()

        LOG.step('Opening dialog')
        wizard = CreateLUNSnapshotWizard(driver=self.driver)
        wizard.open(name=lunNamePrefix + '_1')
        LOG.info('Dialog is open.')

        LOG.step('Creating snapshot copy')
        LOG.info('Setting snapshot name')
        wizard.activePage.setName(name=snapshotName)
        self.assertTrue(wizard.activePage.txtName.getText() == snapshotName)
        LOG.info('Snapshot name set:', wizard.activePage.txtName.getText())
        wizard.activePage.submit()
        LOG.info('Dialog submitted.')

        LOG.step('Verifying snapshot has been created')
        snapshots = self.marscluster.snapshot.show(json=True)
        self.assertTrue(len(snapshots) == 1)
        self.assertTrue(snapshots[0]['create-time-object'] == lunNamePrefix +
                        '_1')
        LOG.info('LUN name:', snapshots[0]['create-time-object'])
        self.assertTrue(snapshots[0]['name'] == snapshotName)
        LOG.info('Snapshot name:', snapshots[0]['name'])

    def test_fail_invalid_name(self):
        """
            Verify error message when snapshot name is invalid.
        """
        LOG.step('Creating LUNs')
        lunCount = 3
        lunSize = 1
        lunSizeUnit = 'G'
        lunNamePrefix = 'LuN'
        snapshotName = 'Snap$hot'
        self.luns.create(count=lunCount,
                         size=str(lunSize) + lunSizeUnit,
                         prefix=lunNamePrefix)
        LOG.info('LUNs created:\n', self.marscluster.lun.show(json=True))

        # Refresh LUN grid
        self.lunsPage.btnRefresh.click()
        self.lunsPage.btnRefresh.waitUntilEnabled()

        LOG.step('Opening dialog')
        wizard = CreateLUNSnapshotWizard(driver=self.driver)
        wizard.open(name=lunNamePrefix + '_1')
        LOG.info('Dialog is open.')

        LOG.step('Verifying error message on invalid snapshot name')
        wizard.activePage.setName(name=snapshotName)
        self.assertTrue(wizard.activePage.txtName.getText() == snapshotName)
        LOG.info('Snapshot name set:', wizard.activePage.txtName.getText())
        self.assertTrue(wizard.activePage.lblNameError.isVisible())
        LOG.info('Error message displayed:',
                 wizard.activePage.lblNameError.getText())
        self.assertFalse(wizard.activePage.btnOK.isEnabled())
        LOG.info("Button 'OK' is enabled:",
                 wizard.activePage.btnOK.isEnabled())

    def test_create_sequent(self):
        """
            Verify default name has increased number when snapshot with default name exists.
        """
        LOG.step('Creating LUNs')
        lunCount = 3
        lunSize = 1
        lunSizeUnit = 'G'
        lunNamePrefix = 'LuN'
        self.luns.create(count=lunCount,
                         size=str(lunSize) + lunSizeUnit,
                         prefix=lunNamePrefix)
        LOG.info('LUNs created:\n', self.marscluster.lun.show(json=True))

        # Refresh LUN grid
        self.lunsPage.btnRefresh.click()
        self.lunsPage.btnRefresh.waitUntilEnabled()

        LOG.step('Opening dialog')
        wizard = CreateLUNSnapshotWizard(driver=self.driver)
        wizard.open(name=lunNamePrefix + '_1')
        LOG.info('Dialog is open.')

        LOG.step('Creating snapshot with default name')
        self.assertTrue(wizard.activePage.txtName.getText() == lunNamePrefix +
                        '_1_snap_0')
        LOG.info('Default snapshot name set:',
                 wizard.activePage.txtName.getText())
        wizard.activePage.submit()
        LOG.info('Dialog submitted.')

        LOG.step('Subsequent creation of snapshot with default name')
        wizard.open(name=lunNamePrefix + '_1')
        self.assertTrue(wizard.activePage.txtName.getText() == lunNamePrefix +
                        '_1_snap_1')
        LOG.info('Default snapshot name set:',
                 wizard.activePage.txtName.getText())
        wizard.activePage.submit()
        LOG.info('Dialog submitted.')

        LOG.step("Verifying snapshots' names")
        snapshotNames = [
            snapshot['name']
            for snapshot in self.marscluster.snapshot.show(json=True)
        ]
        self.assertTrue(len(snapshotNames) == 2)
        self.assertTrue((lunNamePrefix + '_1_snap_0') in snapshotNames)
        LOG.info('Snapshot found:', lunNamePrefix + '_1_snap_0')
        self.assertTrue((lunNamePrefix + '_1_snap_1') in snapshotNames)
        LOG.info('Snapshot found:', lunNamePrefix + '_1_snap_1')

    def test_dialog_not_available(self):
        """
            Verify the dialog is not available when 0 or > 2 LUNs selected in grid.
        """
        LOG.step('Creating LUNs')
        lunCount = 3
        lunSize = 1
        lunSizeUnit = 'G'
        lunNamePrefix = 'LuN'
        self.luns.create(count=lunCount,
                         size=str(lunSize) + lunSizeUnit,
                         prefix=lunNamePrefix)
        LOG.info('LUNs created:\n', self.marscluster.lun.show(json=True))

        # Refresh LUN grid
        self.lunsPage.btnRefresh.click()
        self.lunsPage.btnRefresh.waitUntilEnabled()

        LOG.step('Verifying dialog is unavailable when no LUNs selected')
        self.lunsPage.gridLUNs.unselect()
        selectedLUNs = self.lunsPage.gridLUNs.find(selected=True)
        self.assertFalse(selectedLUNs)
        LOG.info('Selected LUNs:', selectedLUNs)
        self.assertFalse(
            self.lunsPage.menuCreate.isItemEnabled(item='Snapshot copy'))
        LOG.info("Menu item 'Snapshot copy' enabled:",
                 self.lunsPage.menuCreate.isItemEnabled(item='Snapshot copy'))

        LOG.step('Verifying dialog is unavailable when multiple LUNs selected')
        self.lunsPage.gridLUNs.unselect()
        self.lunsPage.gridLUNs.select(
            name=[lunNamePrefix + '_1', lunNamePrefix + '_2'])
        selectedLUNs = [
            lun['name'] for lun in self.lunsPage.gridLUNs.find(selected=True)
        ]
        self.assertTrue(len(selectedLUNs) == 2)
        LOG.info('Selected LUNs:', selectedLUNs)
        self.assertFalse(
            self.lunsPage.menuCreate.isItemEnabled(item='Snapshot copy'))
        LOG.info("Menu item 'Snapshot copy' enabled:",
                 self.lunsPage.menuCreate.isItemEnabled(item='Snapshot copy'))

    def test_dialog_cancel(self):
        """
            Verify canceling dialog without submission leaves LUNs and snapshots intact.
        """
        LOG.step('Creating LUNs')
        lunCount = 3
        lunSize = 1
        lunSizeUnit = 'G'
        lunNamePrefix = 'LuN'
        self.luns.create(count=lunCount,
                         size=str(lunSize) + lunSizeUnit,
                         prefix=lunNamePrefix)
        LOG.info('LUNs created:\n', self.marscluster.lun.show(json=True))

        # Refresh LUN grid
        self.lunsPage.btnRefresh.click()
        self.lunsPage.btnRefresh.waitUntilEnabled()

        LOG.step('Opening dialog')
        wizard = CreateLUNSnapshotWizard(driver=self.driver)
        wizard.open(name=lunNamePrefix + '_1')
        LOG.info('Dialog is open.')

        LOG.step('Canceling dialog without submission')
        wizard.cancel()
        LOG.info('Dialog closed.')

        LOG.step('Verifying no snapshots have been created')
        snapshots = self.marscluster.snapshot.show(json=True)
        self.assertFalse(snapshots)
        LOG.info('Created snapshots:', snapshots)

    def testTeardown(self):
        self.driver.close()

    def suiteTeardown(self):
        LOG.step('Closing browser')
        self.driver.quit()
        self.marscluster.snapshot.deleteAll()
        luns = express.Luns(node=self.marscluster, cleanup=True)
        del luns
        LOG.info('LUNs & snapshots cleaned up.')
class TestCreateLUNsIGPageWizard(FRTestCase):
    def suiteSetup(self):
        self.username = ARGS.values.username
        self.password = ARGS.values.password
        self.locale = ARGS.values.locale
        self.webUIHostName = frutil.getFQDN(
            self.marscluster.getMasterNode().hostname)

    def testSetup(self):
        self.driver = self.getDriver()
        self.loginPage = LoginPage(driver=self.driver, url=self.webUIHostName)

        LOG.info('Destroying existing LUNs...')
        self.marscluster.lun.unmapAll()
        self.marscluster.lun.destroyAll()
        self.assertFalse(self.marscluster.lun.show(json=True))
        LOG.info('Done.')
        LOG.info('Destroying existing initiator groups...')
        self.marscluster.igroup.destroyAll()
        LOG.info('Done.')
        LOG.info('Destroying existing consistency groups...')
        self._deleteDependentConsistencyGroups()
        LOG.info('Done.')

        if self.locale is None:
            self.locale = self.loginPage.getRandomLocale()
        self.loginPage.signIn(username=self.username,
                              password=self.password,
                              locale=self.locale)
        LOG.info('Signed in with username: %s, password: %s, locale: %s.' %
                 (self.username, self.password, self.locale))

    def test_single_lun_invalid_name(self):
        """
            Test verifies inability of creation of single LUN with invalid name.
        """
        name = 'LuN:$1001'
        numberOfLUNs = '1'
        size = '3g'
        initiatorGroupPrefix = 'IG'
        initiatorGroupNumber = 5

        initiatorGroups = self._createInitiatorGroups(
            prefix=initiatorGroupPrefix, number=initiatorGroupNumber)

        LOG.step('Creating wizard')
        wizard = CreateLUNsIGPageWizard(driver=self.driver, locale=self.locale)

        LOG.step('Opening dialog')
        wizard.open(initiator_group=initiatorGroups[0])
        self.assertTrue(wizard.defineLUNsPage.isOpen())
        LOG.info('Front page is open:', wizard.defineLUNsPage.isOpen())

        LOG.step("Calling: defineSingleLUN(name='%s', size='%s')" %
                 (name, size))
        wizard.activePage.defineSingleLUN(name=name, size=size)

        LOG.step('Verifying error message as name is invalid')
        self.assertTrue(wizard.activePage.lblNameError.isPresent())
        LOG.info('Error message is present:',
                 wizard.activePage.lblNameError.isPresent())
        wizard.activePage.lblNameError.isVisible()
        LOG.info('Error message is visible:',
                 wizard.activePage.lblNameError.isVisible())
        LOG.info('Error message:', wizard.activePage.lblNameError.isPresent())

        LOG.step("Verifying button 'OK' is disabled.")
        self.assertFalse(wizard.activePage.btnOK.isEnabled())
        LOG.info("Button 'OK' is enabled:",
                 wizard.activePage.btnOK.isEnabled())

        LOG.step("Closing the dialog by clicking button 'Cancel'")
        wizard.activePage.btnCancel.click()

        LOG.step("Verifying the dialog has been closed")
        self.assertFalse(wizard.activePage.isOpen())
        LOG.info('Front page is open:', wizard.activePage.isOpen())

        LOG.step('Verifying no LUNs have been created')
        luns = self.marscluster.lun.show(json=True)
        self.assertFalse(luns)
        LOG.info('LUNs:', luns)

    def test_single_lun_max_length_name(self):
        """
            Test verifies creation of single LUNs with maximum length of name (255).
        """
        name = 'LuN__' + ('0' * 250)
        size = '3g'
        initiatorGroupPrefix = 'IG'
        initiatorGroupNumber = 5

        initiatorGroups = self._createInitiatorGroups(
            prefix=initiatorGroupPrefix, number=initiatorGroupNumber)

        LOG.step('Creating wizard')
        wizard = CreateLUNsIGPageWizard(driver=self.driver, locale=self.locale)

        LOG.step('Opening dialog')
        wizard.open(initiator_group=initiatorGroups[0])
        self.assertTrue(wizard.defineLUNsPage.isOpen())
        LOG.info('Front page is open:', wizard.defineLUNsPage.isOpen())

        LOG.step("Calling method: defineSingleLUN(name='%s', size='%s')" %
                 (name, size))
        wizard.activePage.defineSingleLUN(name=name, size=size)

        LOG.step('Verifying no name error message present on page.')
        self.assertFalse(wizard.activePage.lblNameError.isPresent())
        LOG.info('Name error message is present:',
                 wizard.activePage.lblNameError.isPresent())

        LOG.step('Finishing wizard')
        wizard.activePage.submit()
        wizard.activePage.waitUntilClosed()
        LOG.info('Wizard closed.')

        LOG.step('Verifying created LUN has provided name')
        luns = self.marscluster.lun.show(json=True)
        self.assertTrue(len(luns) == 1)
        self.assertTrue(luns[0]['name'] == name)
        LOG.info('LUN name:', luns[0]['name'])

        LOG.step('Verifying LUN has specified mapping')
        self.assertTrue(len(luns[0]['maps']) == 1)
        self.assertTrue(
            luns[0]['maps'][0]['igroup-name'] == initiatorGroups[0])
        LOG.info('LUN mapping:', luns[0]['maps'])

    def test_single_lun_terminal_size(self):
        """
            Test verifies creation of single LUN with minimum and maximum sizes respecting given size unit.
        """
        initiatorGroupPrefix = 'IG'
        initiatorGroupNumber = 3
        sizes = {
            'B': {
                'low': 512,
                'high': long(64) * pow(1024, 4),
                'multiplier': 1
            },
            'K': {
                'low': 0.5,
                'high': long(64) * pow(1024, 3),
                'multiplier': 1024
            },
            'M': {
                'low': 0.001,
                'high': long(64) * pow(1024, 2),
                'multiplier': 1024**2
            },
            'G': {
                'low': 0.001,
                'high': long(64) * 1024,
                'multiplier': 1024**3
            },
            'T': {
                'low': 0.001,
                'high': 64,
                'multiplier': 1024**4
            }
        }

        initiatorGroups = self._createInitiatorGroups(
            prefix=initiatorGroupPrefix, number=initiatorGroupNumber)
        lunsToCreate = {}

        for sizeUnit in sizes:
            nameLow = 'LuN_' + sizeUnit + '_low'
            sizeLow = str(sizes[sizeUnit]['low']) + sizeUnit
            nameHigh = 'LuN_' + sizeUnit + '_high'
            sizeHigh = str(sizes[sizeUnit]['high']) + sizeUnit

            LOG.step('Opening wizard')
            wizard = CreateLUNsIGPageWizard(driver=self.driver,
                                            locale=self.locale)
            wizard.open(initiator_group=initiatorGroups[0])
            self.assertTrue(wizard.defineLUNsPage.isOpen())
            LOG.info('Wizard open.')

            LOG.step("Creating LUN with minimal size: name='%s', size='%s')" %
                     (nameLow, sizeLow))
            wizard.activePage.defineSingleLUN(name=nameLow, size=sizeLow)
            wizard.defineLUNsPage.submit()
            LOG.info('Wizard submitted.')

            sizeToCreate = sizes[sizeUnit]['low'] * sizes[sizeUnit][
                'multiplier']
            # Sizes of LUNs are rounded up to 512-byte bound
            if sizeToCreate % 512 > 0:
                sizeToCreate = int(sizeToCreate / 512) * 512 + 512
            lunsToCreate[nameLow] = sizeToCreate

            LOG.step('Opening wizard')
            wizard = CreateLUNsIGPageWizard(driver=self.driver,
                                            locale=self.locale)
            wizard.open(initiator_group=initiatorGroups[0])
            self.assertTrue(wizard.defineLUNsPage.isOpen())
            LOG.info('Wizard open.')

            LOG.step("Creating LUN with minimal size: name='%s', size='%s')" %
                     (nameHigh, sizeHigh))
            wizard.activePage.defineSingleLUN(name=nameHigh, size=sizeHigh)
            wizard.defineLUNsPage.submit()
            LOG.info('Wizard submitted.')

            lunsToCreate[nameHigh] = sizes[sizeUnit]['high'] * sizes[sizeUnit][
                'multiplier']

            createdLUNs = self.marscluster.lun.show(json=True)
            self.assertTrue(len(createdLUNs) == 2)

            LOG.step(
                'Verifying sizes and mappings of created LUNs are as specified'
            )
            for lun in createdLUNs:
                self.assertTrue(lun['size'] == lunsToCreate[lun['name']])
                LOG.info("Size of LUN '%s' (bytes): %s" %
                         (lun['name'], lun['size']))
                self.assertTrue(len(lun['maps']) == 1)
                self.assertTrue(
                    lun['maps'][0]['igroup-name'] == initiatorGroups[0])
                LOG.info("LUN '%s' mapping: %s" %
                         (lun['name'], lun['maps'][0]))

            LOG.step('Destroying LUNs')
            self.marscluster.lun.unmapAll()
            self.marscluster.lun.destroyAll()
            self.assertFalse(self.marscluster.lun.show(json=True))
            LOG.info('All LUNs destroyed.')

    def test_single_lun_map_new_parent_cg(self):
        """
            Test verifies creation of single LUN mapped to newly created parent consistency group.
        """
        lunName = 'LuN'
        lunSize = '1g'
        consistencyGroupName = 'New-CG'
        initiatorGroupPrefix = 'IG'
        initiatorGroupNumber = 3

        initiatorGroups = self._createInitiatorGroups(
            prefix=initiatorGroupPrefix, number=initiatorGroupNumber)

        LOG.step('Creating wizard')
        wizard = CreateLUNsIGPageWizard(driver=self.driver, locale=self.locale)
        wizard.open(initiator_group=initiatorGroups[0])
        LOG.info('Wizard created.')

        LOG.step('Defining single LUN')
        wizard.activePage.defineSingleLUN(name=lunName, size=lunSize)
        LOG.info('LUN name:', lunName)
        LOG.info('LUN size:', lunSize)
        wizard.activePage.addToConsistencyGroup(
            newConsistencyGroup=consistencyGroupName)
        LOG.info("LUN's consistency group:", consistencyGroupName)
        wizard.activePage.submit()
        LOG.info('Wizard submitted.')

        LOG.step(
            'Verifying LUN has been created and mapped to consistency group')
        lun = self.marscluster.lun.show(json=True)[0]
        self.assertTrue(lunName in lun['name'])
        self.assertTrue(lun['cg'] == consistencyGroupName)
        LOG.info('LUN name: %s; consistency group: %s' %
                 (lun['name'], lun['cg']))

        LOG.step('Verifying LUN has specified mapping')
        self.assertTrue(len(lun['maps']) == 1)
        self.assertTrue(lun['maps'][0]['igroup-name'] == initiatorGroups[0])
        LOG.info('LUN mapping:', lun['maps'])

    def test_single_lun_map_exist_parent_cg(self):
        """
            Test verifies creation of single LUN mapped to existing parent consistency group.
        """
        lunName = 'LuN'
        lunSize = '1g'
        parentConsistencyGroupName = 'Parent-CG'
        initiatorGroupPrefix = 'IG'
        initiatorGroupNumber = 3

        initiatorGroups = self._createInitiatorGroups(
            prefix=initiatorGroupPrefix, number=initiatorGroupNumber)

        LOG.step('Creating consistency group')
        self.marscluster.cg.create(name=parentConsistencyGroupName)
        consistencyGroups = self.marscluster.cg.show(json=True)
        self.assertTrue(len(consistencyGroups) == 1)
        self.assertTrue(
            consistencyGroups[0]['name'] == parentConsistencyGroupName)
        LOG.info('Consistency group created:', parentConsistencyGroupName)

        LOG.step('Creating wizard')
        wizard = CreateLUNsIGPageWizard(driver=self.driver, locale=self.locale)
        wizard.open(initiator_group=initiatorGroups[0])
        LOG.info('Wizard created.')

        LOG.step('Defining single LUN')
        wizard.activePage.defineSingleLUN(name=lunName, size=lunSize)
        LOG.info('LUN name:', lunName)
        LOG.info('LUN size:', lunSize)
        wizard.activePage.addToConsistencyGroup(
            parentConsistencyGroup=parentConsistencyGroupName)
        LOG.info("LUN's consistency group:", parentConsistencyGroupName)
        wizard.activePage.submit()
        LOG.info('Wizard submitted.')

        LOG.step(
            'Verifying LUN has been created and mapped to existing consistency group'
        )
        lun = self.marscluster.lun.show(json=True)[0]
        self.assertTrue(lunName in lun['name'])
        self.assertTrue(lun['cg'] == parentConsistencyGroupName)
        LOG.info('LUN name: %s; consistency group: %s' %
                 (lun['name'], lun['cg']))

        LOG.step('Verifying LUN has specified mapping')
        self.assertTrue(len(lun['maps']) == 1)
        self.assertTrue(lun['maps'][0]['igroup-name'] == initiatorGroups[0])
        LOG.info('LUN mapping:', lun['maps'])

    def test_single_lun_map_exist_new_parent_cg(self):
        """
            Test verifies creation of single LUN mapped to existing parent and new consistency groups.
        """
        lunName = 'LuN'
        lunSize = '1g'
        parentConsistencyGroupName = 'Parent-CG'
        newConsistencyGroupName = 'New-CG'
        initiatorGroupPrefix = 'IG'
        initiatorGroupNumber = 3

        initiatorGroups = self._createInitiatorGroups(
            prefix=initiatorGroupPrefix, number=initiatorGroupNumber)

        LOG.step('Creating consistency group')
        self.marscluster.cg.create(name=parentConsistencyGroupName)
        consistencyGroups = self.marscluster.cg.show(json=True)
        self.assertTrue(len(consistencyGroups) == 1)
        self.assertTrue(
            consistencyGroups[0]['name'] == parentConsistencyGroupName)
        LOG.info('Consistency group created:', parentConsistencyGroupName)

        LOG.step('Creating wizard')
        wizard = CreateLUNsIGPageWizard(driver=self.driver, locale=self.locale)
        wizard.open(initiator_group=initiatorGroups[0])
        LOG.info('Wizard created.')

        LOG.step('Defining single LUN')
        wizard.activePage.defineSingleLUN(name=lunName, size=lunSize)
        LOG.info('LUN name:', lunName)
        LOG.info('LUN size:', lunSize)
        wizard.activePage.addToConsistencyGroup(
            parentConsistencyGroup=parentConsistencyGroupName,
            newConsistencyGroup=newConsistencyGroupName)
        LOG.info("LUN's consistency group:", parentConsistencyGroupName)
        wizard.activePage.submit()
        LOG.info('Wizard submitted.')

        LOG.step('Verifying mapped LUN has been created')
        luns = self.marscluster.lun.show(json=True)
        self.assertTrue(len(luns) == 1)
        self.assertTrue(luns[0]['name'] == (parentConsistencyGroupName + '/' +
                                            newConsistencyGroupName + '/' +
                                            lunName))
        self.assertTrue(luns[0]['cg'] == (parentConsistencyGroupName + '/' +
                                          newConsistencyGroupName))
        LOG.info("LUN created: 'name': '%s'; 'cg': '%s'" %
                 (luns[0]['name'], luns[0]['cg']))
        mappingFound = False
        for consistencyGroup in self.marscluster.cg.show(json=True):
            if consistencyGroup['name'] == luns[0]['cg']:
                mappingFound = True
        self.assertTrue(mappingFound)
        LOG.info('Mapped consistency group found.')

        LOG.step('Verifying LUN has specified mapping')
        self.assertTrue(len(luns[0]['maps']) == 1)
        self.assertTrue(
            luns[0]['maps'][0]['igroup-name'] == initiatorGroups[0])
        LOG.info('LUN mapping:', luns[0]['maps'])

    def test_multi_lun_auto_start_low(self):
        """
            Test verifies creation of multiple LUNs with values of 'Start At' shorter than suffix (ex. 2 digits in
            'start at' = 55 is shorter than 4 pounds in suffix '####') are justified to number of pounds (i.e. prefix
            'LuN_' and 'start at' 55' gets translated to 'LuN_0055').
        """
        numberOfLUNs = 10
        lunNamePrefix = 'LuN_'
        lunSize = '1g'
        startAt = 99
        initiatorGroupPrefix = 'IG'
        initiatorGroupNumber = 3

        initiatorGroups = self._createInitiatorGroups(
            prefix=initiatorGroupPrefix, number=initiatorGroupNumber)

        for suffixIndex in range(4):
            suffix = '#' * (suffixIndex + 1)
            LOG.step("Creating LUNs with suffix '%s' and starting at %s" %
                     (suffix, str(startAt)))
            LOG.step('Creating wizard')
            wizard = CreateLUNsIGPageWizard(driver=self.driver,
                                            locale=self.locale)
            wizard.open(initiator_group=initiatorGroups[0])
            LOG.info('Wizard created.')

            LOG.step('Defining multiple LUNs')
            wizard.activePage.defineMultipleLUNsAuto(number=numberOfLUNs,
                                                     size=lunSize,
                                                     prefix=lunNamePrefix,
                                                     suffix=(suffix + ' '),
                                                     startAt=startAt)
            LOG.info(
                "LUN properties defined: number: %s; size: %s, prefix: '%s'; suffix: '%s'; start at: %s"
                % (numberOfLUNs, lunSize, lunNamePrefix,
                   (suffix + ' '), startAt))
            wizard.activePage.submit()
            LOG.info('Wizard submitted.')

            LOG.step('Verifying LUN names')
            luns = self.marscluster.lun.show(json=True)
            lunNames = [lun['name'] for lun in luns]
            for lunIndex in range(startAt, (startAt + numberOfLUNs)):
                lunName = lunNamePrefix + str(lunIndex).rjust(
                    suffixIndex + 1, '0')
                self.assertTrue(lunName in lunNames)
                LOG.info('LUN found:', lunName)

            LOG.step('Verifying mapping of all LUNs')
            for lun in luns:
                self.assertTrue(len(lun['maps']) == 1)
                self.assertTrue(
                    lun['maps'][0]['igroup-name'] == initiatorGroups[0])
                LOG.info("LUN '%s' mapping: %s" %
                         (lun['name'], lun['maps'][0]))

                LOG.step('Destroying LUNs')
                self.marscluster.lun.unmapAll()
                self.marscluster.lun.destroyAll()
                self.assertFalse(self.marscluster.lun.show(json=True))
                LOG.info('All LUNs destroyed.')

    def test_multi_lun_auto_start_high(self):
        """
            Test verifies creation of multiple LUNs with values of 'Start At' longer than suffix (ex. 5 digits in
            'start at' = 55555 is longer than 4 pounds in suffix '####') are not truncated to number of pounds (i.e.
            'LuN_55555' is not becoming 'LuN_5555').
        """
        numberOfLUNs = 10
        lunNamePrefix = 'LuN_'
        lunSize = '1G'
        startAt = 55555
        initiatorGroupPrefix = 'IG'
        initiatorGroupNumber = 3

        initiatorGroups = self._createInitiatorGroups(
            prefix=initiatorGroupPrefix, number=initiatorGroupNumber)

        for suffixIndex in range(4):
            suffix = '#' * (suffixIndex + 1)
            LOG.step("Creating LUNs with suffix '%s' and starting at %s" %
                     (suffix, str(startAt)))
            LOG.step('Creating wizard')
            wizard = CreateLUNsIGPageWizard(driver=self.driver,
                                            locale=self.locale)
            wizard.open(initiator_group=initiatorGroups[0])
            LOG.info('Wizard created.')

            LOG.step('Defining multiple LUNs')
            wizard.activePage.defineMultipleLUNsAuto(number=numberOfLUNs,
                                                     size=lunSize,
                                                     prefix=lunNamePrefix,
                                                     suffix=(suffix + ' '),
                                                     startAt=startAt)
            LOG.info(
                "LUN properties defined: number: %s; size: %s, prefix: '%s'; suffix: '%s'; start at: %s"
                % (numberOfLUNs, lunSize, lunNamePrefix,
                   (suffix + ' '), startAt))
            wizard.activePage.submit()
            LOG.info('Wizard submitted.')

            LOG.step('Verifying LUN names')
            luns = self.marscluster.lun.show(json=True)
            lunNames = [
                lun['name'] for lun in self.marscluster.lun.show(json=True)
            ]
            for lunIndex in range(startAt, (startAt + numberOfLUNs)):
                self.assertTrue((lunNamePrefix + str(lunIndex)) in lunNames)
                LOG.info('LUN found:', lunNamePrefix + str(lunIndex))

            LOG.step('Verifying mapping of all LUNs')
            for lun in luns:
                self.assertTrue(len(lun['maps']) == 1)
                self.assertTrue(
                    lun['maps'][0]['igroup-name'] == initiatorGroups[0])
                LOG.info("LUN '%s' mapping: %s" %
                         (lun['name'], lun['maps'][0]))

                LOG.step('Destroying LUNs')
                self.marscluster.lun.unmapAll()
                self.marscluster.lun.destroyAll()
                self.assertFalse(self.marscluster.lun.show(json=True))
                LOG.info('All LUNs destroyed.')

    def test_multi_lun_terminal_size(self):
        """
            Test verifies creation of multiple LUNs with minimum and maximum sizes respecting given size unit.
        """
        initiatorGroupPrefix = 'IG'
        initiatorGroupNumber = 3
        # Could be increased with bigger capacity storage. Now is supports 2 LUNs at 64 TB.
        sizes = {
            'B': {
                'low': 512,
                'high': long(64) * pow(1024, 4),
                'multiplier': 1
            },
            'K': {
                'low': 0.5,
                'high': long(64) * pow(1024, 3),
                'multiplier': 1024
            },
            'M': {
                'low': 0.001,
                'high': long(64) * pow(1024, 2),
                'multiplier': 1024**2
            },
            'G': {
                'low': 0.001,
                'high': long(64) * 1024,
                'multiplier': 1024**3
            },
            'T': {
                'low': 0.001,
                'high': 64,
                'multiplier': 1024**4
            }
        }

        initiatorGroups = self._createInitiatorGroups(
            prefix=initiatorGroupPrefix, number=initiatorGroupNumber)
        lunsToCreate = {}

        for sizeUnit in sizes:
            nameLow = 'LuN_' + sizeUnit + '_low'
            sizeLow = str(sizes[sizeUnit]['low']) + sizeUnit
            nameHigh = 'LuN_' + sizeUnit + '_high'
            sizeHigh = str(sizes[sizeUnit]['high']) + sizeUnit

            LOG.step('Opening wizard')
            wizard = CreateLUNsIGPageWizard(driver=self.driver,
                                            locale=self.locale)
            wizard.open(initiator_group=initiatorGroups[0])
            self.assertTrue(wizard.defineLUNsPage.isOpen())
            LOG.info('Wizard open.')

            LOG.step(
                "Creating 2 LUNs with minimal and maximal sizes: name=['%s', '%s'], size=['%s', '%s'])"
                % (nameLow, nameHigh, sizeLow, sizeHigh))
            lunsProperties = [{
                'name': nameLow,
                'size': sizeLow
            }, {
                'name': nameHigh,
                'size': sizeHigh
            }]
            wizard.activePage.defineMultipleLUNsManually(
                lunsProperties=lunsProperties)
            wizard.defineLUNsPage.submit()
            LOG.info('Wizard submitted.')

            sizeToCreate = sizes[sizeUnit]['low'] * sizes[sizeUnit][
                'multiplier']
            # Sizes of LUNs are rounded up to 512-byte bound
            if sizeToCreate % 512 > 0:
                sizeToCreate = int(sizeToCreate / 512) * 512 + 512
            lunsToCreate[nameLow] = sizeToCreate

            lunsToCreate[nameHigh] = sizes[sizeUnit]['high'] * sizes[sizeUnit][
                'multiplier']

            createdLUNs = self.marscluster.lun.show(json=True)

            LOG.step(
                'Verifying sizes and mappings of created LUNs are as specified'
            )
            for lun in createdLUNs:
                self.assertTrue(lun['size'] == lunsToCreate[lun['name']])
                LOG.info("Size of LUN '%s' (bytes): %s" %
                         (lun['name'], lun['size']))
                self.assertTrue(len(lun['maps']) == 1)
                self.assertTrue(
                    lun['maps'][0]['igroup-name'] == initiatorGroups[0])
                LOG.info("LUN '%s' mapping: %s" %
                         (lun['name'], lun['maps'][0]))

            LOG.step('Destroying LUNs')
            self.marscluster.lun.unmapAll()
            self.marscluster.lun.destroyAll()
            self.assertFalse(self.marscluster.lun.show(json=True))
            LOG.info('All LUNs destroyed.')

    def test_multi_lun_map_exist_new_parent_cg(self):
        """
            Test verifies creation of multiple LUNs mapped to existing parent and new consistency groups.
        """
        parentConsistencyGroupName = 'Parent-CG'
        newConsistencyGroupName = 'New-CG'
        lunsProperties = [{
            'name': 'LuN-1',
            'size': '1G'
        }, {
            'name': 'LuN-2',
            'size': '1G'
        }, {
            'name': 'LuN-3',
            'size': '1G'
        }, {
            'name': 'LuN-4',
            'size': '1G'
        }, {
            'name': 'LuN-5',
            'size': '1G'
        }, {
            'name': 'LuN-6',
            'size': '1G'
        }, {
            'name': 'LuN-7',
            'size': '1G'
        }, {
            'name': 'LuN-8',
            'size': '1G'
        }, {
            'name': 'LuN-9',
            'size': '1G'
        }, {
            'name': 'LuN-10',
            'size': '1G'
        }]
        initiatorGroupPrefix = 'IG'
        initiatorGroupNumber = 3

        initiatorGroups = self._createInitiatorGroups(
            prefix=initiatorGroupPrefix, number=initiatorGroupNumber)

        LOG.step('Creating consistency group')
        self.marscluster.cg.create(name=parentConsistencyGroupName)
        consistencyGroups = self.marscluster.cg.show(json=True)
        self.assertTrue(len(consistencyGroups) == 1)
        self.assertTrue(
            consistencyGroups[0]['name'] == parentConsistencyGroupName)
        LOG.info('Consistency group created:', parentConsistencyGroupName)

        LOG.step('Opening wizard')
        wizard = CreateLUNsIGPageWizard(driver=self.driver, locale=self.locale)
        wizard.open(initiator_group=initiatorGroups[0])
        LOG.info('Wizard open.')

        LOG.step(
            'Creating %s LUNs mapped to existing parent and new consistency groups'
            % len(lunsProperties))
        wizard.activePage.defineMultipleLUNsManually(
            lunsProperties=lunsProperties)
        wizard.activePage.addToConsistencyGroup(
            parentConsistencyGroup=parentConsistencyGroupName,
            newConsistencyGroup=newConsistencyGroupName)
        wizard.activePage.submit()
        LOG.info('Wizard submitted.')

        LOG.step('Verifying LUNs have been created and mapped')
        lunNames = [lunProperties['name'] for lunProperties in lunsProperties]
        luns = self.marscluster.lun.show(json=True)
        for lun in luns:
            self.assertTrue(lun['name'].split('/')[-1] in lunNames)
            self.assertTrue(lun['cg'] == parentConsistencyGroupName + '/' +
                            newConsistencyGroupName)
            LOG.info("LUN found: name: '%s'; cg: '%s'" %
                     (lun['name'], lun['cg']))
            self.assertTrue(len(lun['maps']) == 1)
            self.assertTrue(
                lun['maps'][0]['igroup-name'] == initiatorGroups[0])
            LOG.info("LUN '%s' mapping: %s" % (lun['name'], lun['maps'][0]))

    def test_invalid_inputs(self):
        """
            Verify wizard cannot proceed (button 'OK' is disabled) when inputs are not fully
            populated.
        """
        lunName = 'LuN'
        lunSize = '10'
        initiatorGroupPrefix = 'IG'
        initiatorGroupNumber = 3

        initiatorGroups = self._createInitiatorGroups(
            prefix=initiatorGroupPrefix, number=initiatorGroupNumber)

        LOG.step('Opening wizard')
        wizard = CreateLUNsIGPageWizard(driver=self.driver, locale=self.locale)
        wizard.open(initiator_group=initiatorGroups[0])
        LOG.info('Wizard open.')

        LOG.step('Verifying proceed is disabled')
        self.assertFalse(wizard.activePage.txtName.getText())
        LOG.info("Name: '%s'" % wizard.activePage.txtName.getText())
        self.assertFalse(wizard.activePage.txtSize.getText())
        LOG.info("Size: '%s'" % wizard.activePage.txtSize.getText())
        wizard.activePage.btnOK.waitUntilDisabled()
        LOG.info("Button 'OK' is enabled:",
                 wizard.activePage.btnOK.isEnabled())

        LOG.step('Setting only LUN name')
        wizard.activePage.txtName.setText(text=lunName)
        self.assertTrue(wizard.activePage.txtName.getText() == lunName)
        LOG.info('LUN name:', wizard.activePage.txtName.getText())
        LOG.info('LUN size:', wizard.activePage.txtSize.getText())
        wizard.activePage.btnOK.waitUntilDisabled()
        LOG.info("Button 'OK' is enabled:",
                 wizard.activePage.btnOK.isEnabled())

        LOG.step('Setting only LUN size')
        wizard.activePage.txtName.clear()
        wizard.activePage.txtSize.setText(text=lunSize)
        self.assertTrue(wizard.activePage.txtSize.getText() == lunSize)
        LOG.info('LUN name:', wizard.activePage.txtName.getText())
        LOG.info('LUN size:', wizard.activePage.txtSize.getText())
        wizard.activePage.btnOK.waitUntilDisabled()
        LOG.info("Button 'OK' is enabled:",
                 wizard.activePage.btnOK.isEnabled())

        LOG.step('Setting LUN name & size')
        wizard.activePage.txtName.setText(text=lunName)
        LOG.info('LUN name:', wizard.activePage.txtName.getText())
        LOG.info('LUN size:', wizard.activePage.txtSize.getText())
        wizard.activePage.btnOK.waitUntilEnabled()
        LOG.info("Button 'OK' is enabled:",
                 wizard.activePage.btnOK.isEnabled())

    def test_dialog_cancel(self):
        """
            Verify no LUNs created when dialog closed without submission.
        """
        lunName = 'LuN'
        lunSize = '1g'
        initiatorGroupPrefix = 'IG'
        initiatorGroupNumber = 3

        initiatorGroups = self._createInitiatorGroups(
            prefix=initiatorGroupPrefix, number=initiatorGroupNumber)

        LOG.step('Opening wizard')
        wizard = CreateLUNsIGPageWizard(driver=self.driver, locale=self.locale)
        wizard.open(initiator_group=initiatorGroups[0])
        LOG.info('Wizard open.')

        LOG.step('Defining single LUN')
        wizard.activePage.defineSingleLUN(name=lunName, size=lunSize)
        LOG.info('LUN name:', lunName)
        LOG.info('LUN size:', lunSize)

        LOG.step('Closing wizard without submission')
        wizard.cancel()
        LOG.info('Wizard cancelled.')

        LOG.step('Verifying LUN has not been created')
        luns = self.marscluster.lun.show(json=True)
        self.assertFalse(luns)
        LOG.info('LUNs:', luns)

    def test_dialog_not_available(self):
        """
            Verify item 'LUNs' of menu 'Create' on Initiator Groups page is disabled when no
              initiator group selected.
        """
        initiatorGroupPrefix = 'IG'
        initiatorGroupNumber = 3

        initiatorGroups = self._createInitiatorGroups(
            prefix=initiatorGroupPrefix, number=initiatorGroupNumber)

        LOG.step('Navigating to Initiator Groups page')
        HeaderPage(driver=self.driver).btnManager.click()
        AllStoragePage(driver=self.driver).tabInitiatorGroups.click()
        initiatorGroupsPage = InitiatorGroupsPage(driver=self.driver)
        self.assertTrue(initiatorGroupsPage.isOpen())
        LOG.info('Initiator Groups page is open:',
                 initiatorGroupsPage.isOpen())

        LOG.step('Unselecting all initiator groups in grid')
        initiatorGroupsPage.gridInitiatorGroups.unselect()
        initiatorGroups = initiatorGroupsPage.gridInitiatorGroups.find(
            selected=True)
        self.assertFalse(initiatorGroups)
        LOG.info('Selected initiator groups:', initiatorGroups)

        LOG.step("Verifying menu item 'Create -> LUNs' is disabled")
        menuCreate = initiatorGroupsPage.menuCreate
        self.assertFalse(menuCreate.isItemEnabled(item='LUNs'))
        LOG.info("Menu item 'Create -> LUNs' is enabled:",
                 menuCreate.isItemEnabled(item='LUNs'))

    def testTeardown(self):
        self.driver.quit()
        luns = express.Luns(node=self.marscluster, cleanup=True)
        del luns
        self.marscluster.igroup.destroyAll()
        LOG.info('LUNs & initiator groups destroyed.')

    def _createInitiatorGroups(self, prefix, number):
        LOG.step('Creating initiator group(s)')
        for groupNumber in range(number):
            fictiveWWPN = format(random.randrange(sys.maxint),
                                 'x').rjust(16, 'f')
            self.marscluster.igroup.create(name=prefix + '-' +
                                           str(groupNumber),
                                           ostype='vmware',
                                           initiators=fictiveWWPN)
        groupNames = [
            group['name'] for group in self.marscluster.igroup.show(json=True)
        ]
        LOG.info('Initiator group(s) created:', groupNames)
        return groupNames

    def _deleteDependentConsistencyGroups(self):
        while True:
            consistencyGroups = self.marscluster.cg.show(json=True)
            if not consistencyGroups:
                break
            else:
                for consistencyGroup in consistencyGroups:
                    if 'cg' not in consistencyGroup:
                        self.marscluster.cg.delete(
                            name=consistencyGroup['name'])
Esempio n. 17
0
class TestComponentDropDownList(FRTestCase):
    def suiteSetup(self):
        self.username = ARGS.values.username
        self.password = ARGS.values.password
        self.webUIHostName = getFQDN(self.mars[0].hostname)

    def testSetup(self):
        self.driver = self.setupDriver()
        self.loginPage = LoginPage(driver=self.driver, url=self.webUIHostName)
        self.headerPage = HeaderPage(driver=self.driver)
        self.allStoragePage = AllStoragePage(driver=self.driver)
        self.lunsPage = LUNsPage(driver=self.driver)
        self.defineLUNsPage = DefineLUNsPage(driver=self.driver)

    def test_component_drop_down_list(self):
        LOG.step('Opening login page')
        self.loginPage.open()

        LOG.step('Typing username')
        self.loginPage.txtUsername.setText(self.username)
        self.assertTrue(self.loginPage.txtUsername.getText() == self.username)
        LOG.info('Username:'******'Typing password')
        self.loginPage.txtPassword.waitUntilPresent()
        self.loginPage.txtPassword.setText(self.password)
        self.assertTrue(self.loginPage.txtPassword.getText() == self.password)
        LOG.info('Password:'******'Sign In'")
        self.loginPage.btnSignIn.waitUntilPresent()
        self.loginPage.btnSignIn.waitUntilEnabled()
        self.loginPage.btnSignIn.click()

        LOG.step("Clicking on button 'Manager'")
        self.headerPage.btnManager.waitUntilPresent()
        self.headerPage.btnManager.click()

        LOG.step("Clicking on tab 'LUNs'")
        self.allStoragePage.tabLUNs.click()

        LOG.step("Selecting item 'LUNs' in menu 'Create'")
        self.lunsPage.menuCreate.waitUntilPresent()
        self.lunsPage.menuCreate.select(item='LUNs')

        LOG.step("Confirming dialog 'Create LUNs' popped up")
        self.defineLUNsPage.lblTitle.waitUntilPresent()
        LOG.info('Dialog title is present:',
                 self.defineLUNsPage.lblTitle.isPresent())

        LOG.step("Getting value of drop-down list 'Size Unit'")
        LOG.info('Size unit:', self.defineLUNsPage.dLstSizeUnit.getText())

        LOG.step("Getting items of drop-down list 'Size Unit'")
        LOG.info("Items of drop-down list 'Size Unit':\n %s" %
                 self.defineLUNsPage.dLstSizeUnit.getItems())

        sizeUnitIndex = 0
        LOG.step("Selecting item of drop-down list 'Size Unit' by index %s" %
                 str(sizeUnitIndex))
        self.defineLUNsPage.dLstSizeUnit.select(item=sizeUnitIndex)
        LOG.info('Size unit:', self.defineLUNsPage.dLstSizeUnit.getText())

        sizeUnit = 'TiB'
        LOG.step("Setting value of drop-down list 'Size Unit' to '%s'" %
                 sizeUnit)
        self.defineLUNsPage.dLstSizeUnit.select(item=sizeUnit)
        self.assertTrue(self.defineLUNsPage.dLstSizeUnit.getText() == sizeUnit)
        LOG.info('Size unit:', self.defineLUNsPage.dLstSizeUnit.getText())

        LOG.step("Closing dialog by clicking on button 'Cancel'")
        self.defineLUNsPage.btnCancel.click()

        LOG.step("Selecting item 'Sign Out' from user menu")
        self.headerPage.menuUser.waitUntilPresent()
        self.headerPage.menuUser.select(item='Sign Out')

        LOG.step('Verifying browser comes back to login page')
        self.loginPage.imgCompanyLogo.waitUntilPresent()
        LOG.info('Company logo is present on page:',
                 self.loginPage.imgCompanyLogo.isPresent())

    def testTeardown(self):
        self.driver.quit()
class TestEditLUNStateWizard(FRTestCase):
    def suiteSetup(self):
        self.username = ARGS.values.username
        self.password = ARGS.values.password
        self.locale = ARGS.values.locale
        self.webUIHostName = getFQDN(self.marscluster.getMasterNode().hostname)

    def testSetup(self):
        self.driver = self.getDriver()
        self.loginPage = LoginPage(driver=self.driver, url=self.webUIHostName)
        self.headerPage = HeaderPage(driver=self.driver)
        self.allStoragePage = AllStoragePage(driver=self.driver)
        self.lunsPage = LUNsPage(driver=self.driver)

        self.node = self.marscluster
        self.luns = express.Luns(node=self.marscluster)

        LOG.step('Signing in')
        self.loginPage.open()
        self.loginPage.waitUntilOpen()
        if self.locale is None:
            self.locale = self.loginPage.getRandomLocale()
        self.loginPage.signIn(username=self.username,
                              password=self.password,
                              locale=self.locale)
        LOG.info('Signed in with username: %s, password: %s, locale: %s.' %
                 (self.username, self.password, self.locale))
        LOG.info('Browser landed on header page.')

        LOG.info('Navigating to LUNs page...')
        self.headerPage.btnManager.click()
        self.allStoragePage.tabLUNs.click()
        self.lunsPage.waitUntilOpen()
        LOG.info('Browser landed on LUNs page.')

    def test_single_lun_offline_online(self):
        """
            Verify single LUN's state change from Online to Offline.
        """
        LOG.step('Creating LUNs')
        lunCount = 3
        lunSize = 2
        lunSizeUnit = 'G'
        lunNamePrefix = 'LuN'
        self.luns.create(count=lunCount,
                         size=str(lunSize) + lunSizeUnit,
                         prefix=lunNamePrefix)
        LOG.info('LUNs created:\n', self.marscluster.lun.show(json=True))

        # Refresh LUN grid
        self.lunsPage.btnRefresh.click()
        self.lunsPage.btnRefresh.waitUntilEnabled()

        LOG.step('Taking LUN offline')
        wizard = EditLUNStateWizard(driver=self.driver)
        wizard.openTakeOffline(name=lunNamePrefix + '_1')
        wizard.activePage.submit()
        LOG.info('Taking offline submitted.')

        LOG.step('Verifying LUN state')

        lunState = {
            lun['name']: lun['lun-state']
            for lun in self.node.lun.show(json=True)
        }[lunNamePrefix + '_1']
        self.assertTrue(lunState == 'offline')
        LOG.info('LUN state:', lunState)

        LOG.step('Taking LUN online')
        wizard.takeOnline(name=lunNamePrefix + '_1')
        LOG.info('Taking online submitted.')

        LOG.step('Verifying LUN state')
        lunState = {
            lun['name']: lun['lun-state']
            for lun in self.node.lun.show(json=True)
        }[lunNamePrefix + '_1']
        self.assertTrue(lunState == 'online')
        LOG.info('LUN state:', lunState)

    def test_multiple_luns_offline_online(self):
        """
            Verify multiple LUNs' state change from Online to Offline.
        """
        LOG.step('Creating LUNs')
        lunCount = 7
        lunSize = 2
        lunSizeUnit = 'G'
        lunNamePrefix = 'LuN'
        self.luns.create(count=lunCount,
                         size=str(lunSize) + lunSizeUnit,
                         prefix=lunNamePrefix)
        LOG.info('LUNs created:\n', self.marscluster.lun.show(json=True))

        # Refresh LUN grid
        self.lunsPage.btnRefresh.click()
        self.lunsPage.btnRefresh.waitUntilEnabled()

        LOG.step('Taking all LUNs offline')
        wizard = EditLUNStateWizard(driver=self.driver)
        wizard.openTakeOffline(name=lunNamePrefix, matchPattern=True)
        wizard.activePage.submit()
        LOG.info('Taking offline submitted.')

        LOG.step("Verifying LUNs' state")
        luns = {
            lun['name']: lun['lun-state']
            for lun in self.node.lun.show(json=True)
        }
        for lunName in luns:
            self.assertTrue(luns[lunName] == 'offline')
            LOG.info("LUN: %s, state: %s" % (lunName, luns[lunName]))

        LOG.step('Taking all LUNs online')
        wizard.takeOnline(name=lunNamePrefix, matchPattern=True)
        LOG.info('Taking online submitted.')

        # Let UI to communicate with the server and update LUNs.
        time.sleep(3)

        LOG.step("Verifying LUNs' state")
        luns = {
            lun['name']: lun['lun-state']
            for lun in self.node.lun.show(json=True)
        }
        for lunName in luns:
            self.assertTrue(luns[lunName] == 'online')
            LOG.info("LUN: %s, state: %s" % (lunName, luns[lunName]))

    def test_offline_cancel(self):
        """
            Verify 'Take Offline -> Cancel' does cancel dialog gracefully, state not affected.
        """
        LOG.step('Creating LUNs')
        lunCount = 3
        lunSize = 2
        lunSizeUnit = 'G'
        lunNamePrefix = 'LuN'
        self.luns.create(count=lunCount,
                         size=str(lunSize) + lunSizeUnit,
                         prefix=lunNamePrefix)
        LOG.info('LUNs created:\n', self.marscluster.lun.show(json=True))

        # Refresh LUN grid
        self.lunsPage.btnRefresh.click()
        self.lunsPage.btnRefresh.waitUntilEnabled()

        LOG.step('Taking LUN offline')
        wizard = EditLUNStateWizard(driver=self.driver)
        wizard.openTakeOffline(name=lunNamePrefix + '_1')
        LOG.info("'Take Offline' page is open.")

        LOG.step('Canceling dialog')
        wizard.cancel()
        LOG.info('Dialog cancelled.')

        LOG.step('Verifying LUN state has not been changed')
        lunState = {
            lun['name']: lun['lun-state']
            for lun in self.node.lun.show(json=True)
        }[lunNamePrefix + '_1']
        self.assertTrue(lunState == 'online')
        LOG.info('LUN state:', lunState)

    def test_online_not_available(self):
        """
            Verify that 'Take Online' is not available for selected LUNs with status 'Online'.
        """
        LOG.step('Creating LUNs')
        lunCount = 3
        lunSize = 2
        lunSizeUnit = 'G'
        lunNamePrefix = 'LuN'
        self.luns.create(count=lunCount,
                         size=str(lunSize) + lunSizeUnit,
                         prefix=lunNamePrefix)
        LOG.info('LUNs created:\n', self.marscluster.lun.show(json=True))

        # Refresh LUN grid
        self.lunsPage.btnRefresh.click()
        self.lunsPage.btnRefresh.waitUntilEnabled()

        LOG.step("Selecting LUN '%s'" % lunNamePrefix + '_1')
        self.lunsPage.gridLUNs.select(name=lunNamePrefix + '_1')
        LOG.info('LUN selected.')

        LOG.step(
            "Verifying menu 'State -> Online' is disabled for LUN in online")
        isOnlineEnabled = self.lunsPage.menuEdit.isItemEnabled(
            item=['State', 'Online'])
        self.assertFalse(isOnlineEnabled)
        LOG.info("Menu 'Edit': Item 'State -> Online' is enabled:",
                 isOnlineEnabled)

        LOG.step(
            "Verifying menu 'State -> Offline' is enabled for LUN in online")
        isOfflineEnabled = self.lunsPage.menuEdit.isItemEnabled(
            item=['State', 'Offline'])
        self.assertTrue(isOfflineEnabled)
        LOG.info("Menu 'Edit': Item 'State -> Offline' is enabled:",
                 isOfflineEnabled)

    def test_offline_not_available(self):
        """
            Verify that 'Take Offline' is not available for selected LUNs with status 'Offline'.
        """
        LOG.step('Creating LUNs')
        lunCount = 3
        lunSize = 2
        lunSizeUnit = 'G'
        lunNamePrefix = 'LuN'
        self.luns.create(count=lunCount,
                         size=str(lunSize) + lunSizeUnit,
                         prefix=lunNamePrefix)
        LOG.info('LUNs created:\n', self.marscluster.lun.show(json=True))

        # Refresh LUN grid
        self.lunsPage.btnRefresh.click()
        self.lunsPage.btnRefresh.waitUntilEnabled()

        LOG.step('Taking LUN offline')
        wizard = EditLUNStateWizard(driver=self.driver)
        wizard.openTakeOffline(name=lunNamePrefix + '_1')
        wizard.activePage.submit()
        LOG.info('Taking offline submitted.')

        LOG.step('Verifying LUN state')
        lunState = {
            lun['name']: lun['lun-state']
            for lun in self.node.lun.show(json=True)
        }[lunNamePrefix + '_1']
        self.assertTrue(lunState == 'offline')
        LOG.info('LUN state:', lunState)

        LOG.step("Selecting LUN '%s'" % lunNamePrefix + '_1')
        self.lunsPage.gridLUNs.select(name=lunNamePrefix + '_1')
        LOG.info('LUN selected.')

        LOG.step(
            "Verifying menu 'State -> Offline' is disabled for LUN in offline")
        isOfflineEnabled = self.lunsPage.menuEdit.isItemEnabled(
            item=['State', 'Offline'])
        self.assertFalse(isOfflineEnabled)
        LOG.info("Menu 'Edit': Item 'State -> Offline' is enabled:",
                 isOfflineEnabled)

        LOG.step(
            "Verifying menu 'State -> Online' is enabled for LUN in offline")
        isOnlineEnabled = self.lunsPage.menuEdit.isItemEnabled(
            item=['State', 'Online'])
        self.assertTrue(isOnlineEnabled)
        LOG.info("Menu 'Edit': Item 'State -> Online' is enabled:",
                 isOnlineEnabled)

    def testTeardown(self):
        self.driver.close()
        luns = express.Luns(node=self.marscluster, cleanup=True)
        del luns
        LOG.info('LUNs destroyed.')

    def suiteTeardown(self):
        LOG.step('Closing browser')
        self.driver.quit()
class TestCreateInitiatorGroupWizard(FRTestCase):
    def suiteSetup(self):
        self.username = ARGS.values.username
        self.password = ARGS.values.password
        self.locale = ARGS.values.locale
        self.webUIHostName = getFQDN(self.marscluster.getMasterNode().hostname)

    def testSetup(self):
        self.driver = self.getDriver()
        self.loginPage = LoginPage(driver=self.driver, url=self.webUIHostName)
        self.headerPage = HeaderPage(driver=self.driver)
        self.allStoragePage = AllStoragePage(driver=self.driver)
        self.initiatorGroupsPage = InitiatorGroupsPage(driver=self.driver)

        LOG.step('Cleaning out cluster content')
        LOG.info('Destroying LUNs...')
        luns = express.Luns(node=self.marscluster, cleanup=True)
        del luns
        self.assertFalse(self.marscluster.lun.show(json=True))
        LOG.info('Done.')
        LOG.info('Destroying existing initiator groups...')
        self.marscluster.igroup.destroyAll()
        LOG.info('Done.')

        self.luns = express.Luns(node=self.marscluster)

        LOG.step('Signing in')
        self.loginPage.open()
        self.loginPage.waitUntilOpen()
        if self.locale is None:
            self.locale = self.loginPage.getRandomLocale()
        self.loginPage.signIn(username=self.username,
                              password=self.password,
                              locale=self.locale)
        LOG.info('Signed in with username: %s, password: %s, locale: %s.' %
                 (self.username, self.password, self.locale))
        LOG.info('Browser landed on header page.')

        LOG.info('Navigating to Initiator Groups page...')
        self.headerPage.btnManager.click()
        self.allStoragePage.tabInitiatorGroups.click()
        self.initiatorGroupsPage.waitUntilOpen()
        LOG.info('Browser landed on Initiator Groups page.')

    def test_create_minimal(self):
        """
            Verify initiator group creation when name specified explicitly, OS Type is as default.
        """
        initiatorGroupName = 'IG-1'
        defaultOSType = 'Windows'

        LOG.step('Opening wizard')
        wizard = CreateInitiatorGroupWizard(driver=self.driver)
        wizard.open()
        LOG.info('Wizard open.')

        LOG.step('Verifying default parameters')
        self.assertFalse(wizard.activePage.txtName.getText())
        LOG.info("Default name: %s" % wizard.activePage.txtName.getText())
        self.assertTrue(
            wizard.activePage.dLstOSType.getText() == defaultOSType)
        LOG.info("Default OS Type: %s" %
                 wizard.activePage.dLstOSType.getText())
        selectedWWPNs = wizard.activePage.gridInitiatorWWPNs.find(
            selected=True)
        self.assertFalse(selectedWWPNs)
        LOG.info('Selected WWPNs:', selectedWWPNs)

        LOG.step('Setting initiator group name')
        wizard.activePage.setName(name=initiatorGroupName)
        name = wizard.activePage.txtName.getText()
        self.assertTrue(name == initiatorGroupName)
        LOG.info('Initiator group name set:', name)

        LOG.step('Submitting dialog')
        wizard.activePage.submit()
        LOG.info('Dialog submitted.')

        LOG.step('Verifying initiator group has been created')
        initiatorGroups = self.marscluster.igroup.show(json=True)
        self.assertTrue(len(initiatorGroups) == 1)
        self.assertTrue(initiatorGroups[0]['name'] == initiatorGroupName)
        LOG.info('Initiator group created:', initiatorGroups[0]['name'])

    def test_create_custom_os_type(self):
        """
            Verify initiator group creation when name and OS type specified explicitly.
        """
        initiatorGroupName = 'IG-1'
        osType = 'Xen'

        LOG.step('Opening wizard')
        wizard = CreateInitiatorGroupWizard(driver=self.driver)
        wizard.open()
        LOG.info('Wizard open.')

        LOG.step('Setting initiator group name')
        wizard.activePage.setName(name=initiatorGroupName)
        name = wizard.activePage.txtName.getText()
        self.assertTrue(name == initiatorGroupName)
        LOG.info('Initiator group name set:', name)

        LOG.step('Setting OS type: %s' % osType)
        wizard.activePage.setOSType(osType=osType)
        setOSType = wizard.activePage.dLstOSType.getText()
        self.assertTrue(setOSType == osType)
        LOG.info('OS type set:', setOSType)

        LOG.step('Submitting dialog')
        wizard.activePage.submit()
        LOG.info('Dialog submitted.')

        LOG.step('Verifying initiator group has been created')
        initiatorGroups = self.marscluster.igroup.show(json=True)
        self.assertTrue(len(initiatorGroups) == 1)
        self.assertTrue(initiatorGroups[0]['name'] == initiatorGroupName)
        LOG.info("Initiator group's name:", initiatorGroups[0]['name'])
        self.assertTrue(initiatorGroups[0]['ostype'] == osType.lower())
        LOG.info("Initiator group's OS type:", initiatorGroups[0]['ostype'])

    def test_create_single_initiator(self):
        """
            Verify initiator group creation when name and OS type specified explicitly, and single
              initiator selected.
        """
        initiatorGroupName = 'IG-1'
        osType = 'Xen'

        LOG.step('Opening wizard')
        wizard = CreateInitiatorGroupWizard(driver=self.driver)
        wizard.open()
        LOG.info('Wizard open.')

        LOG.step('Setting initiator group name')
        wizard.activePage.setName(name=initiatorGroupName)
        name = wizard.activePage.txtName.getText()
        self.assertTrue(name == initiatorGroupName)
        LOG.info('Initiator group name set:', name)

        LOG.step('Setting OS type: %s' % osType)
        wizard.activePage.setOSType(osType=osType)
        setOSType = wizard.activePage.dLstOSType.getText()
        self.assertTrue(setOSType == osType)
        LOG.info('OS type set:', setOSType)

        LOG.step('Setting single initiator')
        wwpns = wizard.activePage.getWWPNs()
        if wwpns:
            wizard.activePage.setWWPNs(wwpns=wwpns[0]['initiator_group'])
            setWWPNs = wizard.activePage.gridInitiatorWWPNs.find(selected=True)

            self.assertTrue(len(setWWPNs) == 1)
            self.assertTrue(
                setWWPNs[0]['initiator_group'] == wwpns[0]['initiator_group'])
            LOG.info('Initiator WWPN set:', setWWPNs[0]['initiator_group'])

            LOG.step('Submitting dialog')
            wizard.activePage.submit()
            LOG.info('Dialog submitted.')

            LOG.step('Verifying initiator group has been created')
            initiatorGroups = self.marscluster.igroup.show(json=True)
            self.assertTrue(len(initiatorGroups) == 1)
            self.assertTrue(initiatorGroups[0]['name'] == initiatorGroupName)
            LOG.info("Initiator group's name:", initiatorGroups[0]['name'])
            self.assertTrue(initiatorGroups[0]['ostype'] == osType.lower())
            LOG.info("Initiator group's OS type:",
                     initiatorGroups[0]['ostype'])
            self.assertTrue(initiatorGroups[0]['initiators'][0] == wwpns[0]
                            ['initiator_group'])
            LOG.info("Initiator group's WWPN:", wwpns[0]['initiator_group'])
        else:
            LOG.info('No initiators found. Test skipped.')

    def test_create_add_single_initiator(self):
        """
            Verify initiator group creation when name and OS type specified explicitly, and single
              initiator added and selected.
        """
        initiatorGroupName = 'IG-1'
        osType = 'Xen'

        LOG.step('Opening wizard')
        wizard = CreateInitiatorGroupWizard(driver=self.driver)
        wizard.open()
        LOG.info('Wizard open.')

        LOG.step('Setting initiator group name')
        wizard.activePage.setName(name=initiatorGroupName)
        name = wizard.activePage.txtName.getText()
        self.assertTrue(name == initiatorGroupName)
        LOG.info('Initiator group name set:', name)

        LOG.step('Setting OS type: %s' % osType)
        wizard.activePage.setOSType(osType=osType)
        setOSType = wizard.activePage.dLstOSType.getText()
        self.assertTrue(setOSType == osType)
        LOG.info('OS type set:', setOSType)

        fictiveWWPN = ':'.join(
            re.findall(
                '..',
                format(random.randrange(sys.maxint), 'x').rjust(16, 'f')))
        LOG.step('Adding new initiator: %s' % fictiveWWPN)
        wizard.activePage.addWWPNs(wwpns=fictiveWWPN)
        wwpns = wizard.activePage.getWWPNs()
        foundWWPN = [
            wwpn for wwpn in wwpns if wwpn['initiator_group'] == fictiveWWPN
        ]
        self.assertTrue(foundWWPN)
        LOG.info('Initiator added:', foundWWPN[0]['initiator_group'])

        LOG.step('Setting single initiator: %s' % fictiveWWPN)
        wizard.activePage.setWWPNs(wwpns=fictiveWWPN)
        setWWPNs = wizard.activePage.gridInitiatorWWPNs.find(selected=True)
        self.assertTrue(len(setWWPNs) == 1)
        self.assertTrue(setWWPNs[0]['initiator_group'] == fictiveWWPN)
        LOG.info('Initiator WWPN set:', setWWPNs[0]['initiator_group'])

        LOG.step('Submitting dialog')
        wizard.activePage.submit()
        LOG.info('Dialog submitted.')

        LOG.step('Verifying initiator group has been created')
        initiatorGroups = self.marscluster.igroup.show(json=True)
        self.assertTrue(len(initiatorGroups) == 1)
        self.assertTrue(initiatorGroups[0]['name'] == initiatorGroupName)
        LOG.info("Initiator group's name:", initiatorGroups[0]['name'])
        self.assertTrue(initiatorGroups[0]['ostype'] == osType.lower())
        LOG.info("Initiator group's OS type:", initiatorGroups[0]['ostype'])
        self.assertTrue(initiatorGroups[0]['initiators'][0] == fictiveWWPN)
        LOG.info("Initiator group's WWPN:", wwpns[0]['initiator_group'])

    def test_create_multiple_initiators(self):
        """
            Verify initiator group creation when name and OS type specified explicitly, and multiple
              initiators (either existing or fictive).
        """
        initiatorGroupName = 'IG-1'
        osType = 'Xen'
        initiatorsNumber = 10

        LOG.step('Opening wizard')
        wizard = CreateInitiatorGroupWizard(driver=self.driver)
        wizard.open()
        LOG.info('Wizard open.')

        LOG.step('Setting initiator group name')
        wizard.activePage.setName(name=initiatorGroupName)
        name = wizard.activePage.txtName.getText()
        self.assertTrue(name == initiatorGroupName)
        LOG.info('Initiator group name set:', name)

        LOG.step('Setting OS type: %s' % osType)
        wizard.activePage.setOSType(osType=osType)
        setOSType = wizard.activePage.dLstOSType.getText()
        self.assertTrue(setOSType == osType)
        LOG.info('OS type set:', setOSType)

        wwpns = wizard.activePage.getWWPNs()
        if len(wwpns) < initiatorsNumber:
            LOG.step('Adding fictive initiators')
            fictiveWWPNs = []
            for wwpnNumber in range(len(wwpns), initiatorsNumber):
                wizard.activePage.addWWPNs(wwpns=fictiveWWPNs)
                fictiveWWPNs.append(':'.join(
                    re.findall(
                        '..',
                        format(random.randrange(sys.maxint),
                               'x').rjust(16, 'f'))))
            wizard.activePage.addWWPNs(wwpns=fictiveWWPNs)
            wwpns = [
                wwpn['initiator_group']
                for wwpn in wizard.activePage.getWWPNs()
            ]
            for wwpn in fictiveWWPNs:
                self.assertTrue(wwpn in wwpns)
        else:
            wwpns = [
                wwpn['initiator_group']
                for wwpn in wizard.activePage.getWWPNs()
            ]
        LOG.info('Initiators available:', wwpns)

        LOG.step('Setting all initiators')
        wizard.activePage.setWWPNs(wwpns=wwpns)
        setWWPNs = wizard.activePage.gridInitiatorWWPNs.find(selected=True)
        self.assertTrue(len(setWWPNs) == initiatorsNumber)
        LOG.info('Initiator WWPNs set:\n', setWWPNs)

        LOG.step('Submitting dialog')
        wizard.activePage.submit()
        LOG.info('Dialog submitted.')

        LOG.step('Verifying initiator group has been created')
        initiatorGroups = self.marscluster.igroup.show(json=True)
        self.assertTrue(len(initiatorGroups) == 1)
        self.assertTrue(initiatorGroups[0]['name'] == initiatorGroupName)
        LOG.info("Initiator group's name:", initiatorGroups[0]['name'])
        self.assertTrue(initiatorGroups[0]['ostype'] == osType.lower())
        LOG.info("Initiator group's OS type:", initiatorGroups[0]['ostype'])
        self.assertTrue(
            len(initiatorGroups[0]['initiators']) == initiatorsNumber)
        for initiator in initiatorGroups[0]['initiators']:
            self.assertTrue(initiator in wwpns)
            LOG.info("Initiator group's WWPN:", initiator)

    def test_dialog_cancel(self):
        """
            Verify closing dialog without submission has no effect.
        """
        LOG.step('Opening wizard')
        wizard = CreateInitiatorGroupWizard(driver=self.driver)
        wizard.open()
        LOG.info('Wizard open.')

        LOG.step('Closing dialog without submission')
        wizard.cancel()
        LOG.info('Dialog closed.')

        LOG.step('Verifying no initiator groups were created')
        initiatorGroups = self.marscluster.igroup.show(json=True)
        self.assertFalse(initiatorGroups)
        LOG.info('Initiator groups:', initiatorGroups)

    def testTeardown(self):
        self.driver.close()

    def suiteTeardown(self):
        LOG.step('Closing browser')
        self.driver.quit()
        luns = express.Luns(node=self.marscluster, cleanup=True)
        del luns
        self.marscluster.igroup.destroyAll()
        LOG.info('LUNs & initiator groups destroyed.')
class TestComponentGrid(FRTestCase):
    def suiteSetup(self):
        self.username = ARGS.values.username
        self.password = ARGS.values.password
        self.locale = ARGS.values.locale
        self.lunSize = ARGS.values.lunsize
        self.node = self.mars[0]
        self.webUIHostName = getFQDN(self.mars[0].hostname)

    def testSetup(self):
        self.driver = self.getDriver()
        self.loginPage = LoginPage(driver=self.driver, url=self.webUIHostName)
        self.headerPage = HeaderPage(driver=self.driver)
        self.allStoragePage = AllStoragePage(driver=self.driver)
        self.lunsPage = LUNsPage(driver=self.driver)

        self.mars[0].lun.unmapAll()
        self.mars[0].lun.destroyAll()
        self.luns = express.Luns(node=self.node, cleanup=True)

        self.loginPage.signIn(username=self.username,
                              password=self.password,
                              locale=self.locale)

        LOG.step('Navigating to All Storage -> LUNs page')
        self.headerPage.btnManager.waitUntilPresent()
        self.headerPage.btnManager.click()
        self.allStoragePage.tabLUNs.waitUntilPresent()
        self.allStoragePage.tabLUNs.click()
        self.lunsPage.gridLUNs.waitUntilPresent()
        LOG.info("Grid is present on web page.")

    def test_component_grid_sort(self):
        prefixLower = 'EARTH'
        prefixMiddle = 'MARS'
        prefixUpper = 'VENUS'
        lunCount = 3

        LOG.step("Creating %s LUNs with name prefix '%s'" %
                 (lunCount, prefixLower))
        self.luns.create(count=lunCount, size=self.lunSize, prefix=prefixLower)

        LOG.step("Creating %s LUNs with name prefix '%s'" %
                 (lunCount, prefixMiddle))
        self.luns.create(count=lunCount,
                         size=self.lunSize,
                         prefix=prefixMiddle)

        LOG.step("Creating %s LUNs with name prefix '%s'" %
                 (lunCount, prefixUpper))
        self.luns.create(count=lunCount, size=self.lunSize, prefix=prefixUpper)

        self.lunsPage.btnRefresh.click()

        LOG.step('Creating LUNs grid object')
        gridLUNs = self.lunsPage.gridLUNs

        LOG.step('Getting grid initial sorting')
        LOG.info('Grid sorted by:\n', gridLUNs.sortedBy())

        for columnName in gridLUNs.columnNames:
            if columnName != 'selected':
                LOG.step("Sorting grid by column '%s' in ascending order" %
                         columnName)
                gridLUNs.sort(column=columnName, ascend=True)
                sortedBy = gridLUNs.sortedBy()
                self.assertTrue(sortedBy['column'] == columnName)
                self.assertTrue(sortedBy['ascend'])
                LOG.info('Grid sorted by:\n', sortedBy)

                LOG.step("Sorting grid by column '%s' in descending order" %
                         columnName)
                gridLUNs.sort(column=columnName, ascend=False)
                sortedBy = gridLUNs.sortedBy()
                self.assertTrue(sortedBy['column'] == columnName)
                self.assertFalse(sortedBy['ascend'])
                LOG.info('Grid sorted by:\n', sortedBy)

        LOG.step(
            "Sorting grid by column name 'Serial Number' (non-normalized)")
        gridLUNs.sort(column='Serial Number', ascend=True)
        sortedBy = gridLUNs.sortedBy()
        self.assertTrue(sortedBy['column'] == 'serial_number')
        LOG.info('Grid sorted by:\n', sortedBy)

        LOG.step("Sorting grid by column 'Name' in ascending order")
        gridLUNs.sort(column='name', ascend=True)
        rows = gridLUNs.find()
        self.assertTrue(rows[0]['name'] == prefixLower + '_1')
        LOG.info('First row:', rows[0]['name'])
        self.assertTrue(rows[-1]['name'] == prefixUpper + '_' + str(lunCount))
        LOG.info('Last row:', rows[-1]['name'])

        LOG.step("Sorting grid by column 'Name' in descending order")
        gridLUNs.sort(column='name', ascend=False)
        rows = gridLUNs.find()
        self.assertTrue(rows[0]['name'] == prefixUpper + '_' + str(lunCount))
        LOG.info('First row:', rows[0]['name'])
        self.assertTrue(rows[-1]['name'] == prefixLower + '_1')
        LOG.info('Last row:', rows[-1]['name'])

        LOG.step('Attempting to sort grid by selectable column (checkbox)')
        try:
            gridLUNs.sort(column='selected')
        except AttributeError:
            LOG.info("Unable to sort by selectable column.")

    def test_component_grid_select(self):
        prefixLower = 'ERIS'
        prefixMiddle = 'PLUTO'
        prefixUpper = 'SEDNA'
        lunCount = 3

        LOG.step("Creating %s LUNs with name prefix '%s'" %
                 (lunCount, prefixLower))
        self.luns.create(count=lunCount, size=self.lunSize, prefix=prefixLower)

        LOG.step("Creating %s LUNs with name prefix '%s'" %
                 (lunCount, prefixMiddle))
        self.luns.create(count=lunCount,
                         size=self.lunSize,
                         prefix=prefixMiddle)

        LOG.step("Creating %s LUNs with name prefix '%s'" %
                 (lunCount, prefixUpper))
        self.luns.create(count=lunCount, size=self.lunSize, prefix=prefixUpper)

        self.lunsPage.btnRefresh.click()

        LOG.step('Creating LUNs grid object')
        gridLUNs = self.lunsPage.gridLUNs

        LOG.step('Selecting rows by name')
        gridLUNs.select(name=prefixLower + '_1')
        for row in gridLUNs.find(selected=True):
            self.assertTrue(row['name'].startswith(prefixLower))
        LOG.info('Selected rows:\n', gridLUNs.find(selected=True))

        LOG.step('Unselecting all rows')
        gridLUNs.unselect()

        LOG.step("Selecting rows by name pattern '%s' (leading)" %
                 prefixMiddle)
        gridLUNs.select(name=prefixMiddle, matchPattern=True)
        for row in gridLUNs.find(selected=True):
            self.assertTrue(row['name'].startswith(prefixMiddle))
        LOG.info('Selected rows:\n', gridLUNs.find(selected=True))

        LOG.step('Unselecting all rows')
        gridLUNs.unselect()

        LOG.step("Selecting rows by name pattern '_1' (trailing)")
        gridLUNs.select(name='_1', matchPattern=True)
        for row in gridLUNs.find(selected=True):
            self.assertTrue('_1' in row['name'])
        LOG.info('Selected rows:\n', gridLUNs.find(selected=True))

        LOG.step('Unselecting all rows')
        gridLUNs.unselect()
        self.assertFalse(gridLUNs.find(selected=True))
        LOG.info('Selected rows:\n', gridLUNs.find(selected=True))

    def test_component_grid_select_complex_filter(self):
        prefixLower = 'CARPO'
        prefixMiddle = 'DIA'
        prefixUpper = 'LEDA'
        lunCount = 3

        LOG.step("Creating %s LUNs with name prefix '%s'" %
                 (lunCount, prefixLower))
        self.luns.create(count=lunCount, size=self.lunSize, prefix=prefixLower)

        LOG.step("Creating %s LUNs with name prefix '%s'" %
                 (lunCount, prefixMiddle))
        self.luns.create(count=lunCount,
                         size=self.lunSize,
                         prefix=prefixMiddle)

        LOG.step("Creating %s LUNs with name prefix '%s'" %
                 (lunCount, prefixUpper))
        self.luns.create(count=lunCount, size=self.lunSize, prefix=prefixUpper)

        self.lunsPage.btnRefresh.click()

        LOG.step('Creating LUNs grid object')
        gridLUNs = self.lunsPage.gridLUNs

        LOG.step(
            "Selecting rows by complex filter: name contains '%s' or '%s'" %
            (prefixLower, prefixUpper))
        gridLUNs.select(name=[prefixLower, prefixUpper],
                        matchPattern=True,
                        valuesCondition='OR')
        selectedRows = gridLUNs.find(selected=True)
        for row in selectedRows:
            self.assertTrue((prefixLower in row['name'])
                            or (prefixUpper in row['name']))
        LOG.info('Selected rows:\n', selectedRows)

        LOG.step('Unselecting all rows')
        gridLUNs.unselect()

        LOG.step('Selecting all rows')
        gridLUNs.select()
        totalRows = len(gridLUNs.find())
        selectedRows = len(gridLUNs.find(selected=True))
        self.assertTrue(totalRows == selectedRows)
        LOG.info('Total rows:', totalRows)
        LOG.info('Selected rows:', selectedRows)

        LOG.step('Unselecting all rows')
        gridLUNs.unselect()

        LOG.step(
            "Selecting all rows then unselecting them by complex filter: name contains '%s' or '%s'"
            % (prefixLower, prefixUpper))
        gridLUNs.select()
        gridLUNs.unselect(name=[prefixLower, prefixUpper],
                          matchPattern=True,
                          valuesCondition='OR')
        unselectedRows = gridLUNs.find(selected=False)
        for row in unselectedRows:
            self.assertTrue((prefixLower in row['name'])
                            or (prefixUpper in row['name']))
        LOG.info('Unselected rows:\n', unselectedRows)

        LOG.step('Unselecting all rows')
        gridLUNs.unselect()

        LOG.step(
            'Attempting to select rows by false filter condition (non-existing value)'
        )
        gridLUNs.select(name=['NIX', 'STYX'],
                        matchPattern=True,
                        valuesCondition='OR')
        selectedRows = gridLUNs.find(selected=True)
        self.assertFalse(selectedRows)
        LOG.info('Selected rows:\n', selectedRows)

    def test_component_grid_select_repeat(self):
        """
            Test cases applying (un)selection to rows being already in target state
        """
        prefixLower = 'LARISSA'
        prefixMiddle = 'PROTEUS'
        prefixUpper = 'TRITON'
        lunCount = 3

        LOG.step("Creating %s LUNs with name prefix '%s'" %
                 (lunCount, prefixLower))
        self.luns.create(count=lunCount, size=self.lunSize, prefix=prefixLower)

        LOG.step("Creating %s LUNs with name prefix '%s'" %
                 (lunCount, prefixMiddle))
        self.luns.create(count=lunCount,
                         size=self.lunSize,
                         prefix=prefixMiddle)

        LOG.step("Creating %s LUNs with name prefix '%s'" %
                 (lunCount, prefixUpper))
        self.luns.create(count=lunCount, size=self.lunSize, prefix=prefixUpper)

        self.lunsPage.btnRefresh.click()

        LOG.step('Creating LUNs grid object')
        gridLUNs = self.lunsPage.gridLUNs
        LOG.step('Attempting to select already selected rows (row by row)')
        gridLUNs.select(name=prefixLower, matchPattern=True)
        selectedRows1Pass = gridLUNs.find(selected=True)
        LOG.info('Selected rows (first pass):\n', len(selectedRows1Pass))
        gridLUNs.select(name=prefixLower, matchPattern=True)
        selectedRows2Pass = gridLUNs.find(selected=True)
        self.assertTrue(len(selectedRows1Pass) == len(selectedRows2Pass))
        for row1Pass in selectedRows1Pass:
            self.assertTrue(
                row1Pass['name'] in
                [row2Pass['name'] for row2Pass in selectedRows2Pass])
        LOG.info('Selected rows (second pass):\n', len(selectedRows2Pass))

        LOG.step('Unselecting all rows')
        gridLUNs.unselect()

        LOG.step('Attempting to select already selected rows (head selector)')
        gridLUNs.select()
        selectedRows1Pass = gridLUNs.find(selected=True)
        LOG.info('Selected rows (initial state):\n', len(selectedRows1Pass))
        gridLUNs.select()
        selectedRows2Pass = gridLUNs.find(selected=True)
        self.assertTrue(len(selectedRows1Pass) == len(selectedRows2Pass))
        LOG.info('Selected rows (repeated selection with head selector):\n',
                 len(selectedRows2Pass))

        LOG.step('Unselecting all rows')
        gridLUNs.unselect()

        LOG.step('Attempting to unselect already unselected rows (row by row)')
        unselectedRows = gridLUNs.find(selected=False)
        gridLUNs.unselect(name=prefixLower, matchPattern=True)
        unselectedRows2Pass = gridLUNs.find(selected=False)
        self.assertTrue(len(unselectedRows) == len(unselectedRows2Pass))
        LOG.info('Unselected rows number (initial state):',
                 len(unselectedRows))
        LOG.info('Unselected rows number (repeated unselection):',
                 len(unselectedRows2Pass))

        LOG.step(
            'Attempting to unselect already unselected rows (head selector)')
        gridLUNs.unselect()
        unselectedRowsHeadSelector = gridLUNs.find(selected=False)
        self.assertTrue(len(unselectedRows) == len(unselectedRowsHeadSelector))
        LOG.info('Unselected rows number (initial state):',
                 len(unselectedRows))
        LOG.info(
            'Unselected rows number (repeated unselection with head selector):',
            len(unselectedRowsHeadSelector))

    def test_component_grid_find(self):
        prefixLower = 'JUPITER'
        prefixMiddle = 'NEPTUNE'
        prefixUpper = 'URANUS'
        lunCount = 3

        LOG.step("Creating %s LUNs with name prefix '%s'" %
                 (lunCount, prefixLower))
        self.luns.create(count=lunCount, size=self.lunSize, prefix=prefixLower)

        self.lunsPage.btnRefresh.click()

        LOG.step("Creating %s LUNs with name prefix '%s'" %
                 (lunCount, prefixMiddle))
        self.luns.create(count=lunCount,
                         size=self.lunSize,
                         prefix=prefixMiddle)

        self.lunsPage.btnRefresh.click()

        LOG.step("Creating %s LUNs with name prefix '%s'" %
                 (lunCount, prefixUpper))
        self.luns.create(count=lunCount, size=self.lunSize, prefix=prefixUpper)

        self.lunsPage.btnRefresh.click()

        LOG.step('Creating LUNs grid object')
        gridLUNs = self.lunsPage.gridLUNs

        LOG.step("Finding rows by name '%s'" % prefixMiddle)
        foundRows = gridLUNs.find(name=prefixMiddle, matchPattern=True)
        for row in foundRows:
            self.assertTrue(prefixMiddle in row['name'])
        LOG.info('Found rows:\n', foundRows)

        LOG.step('Unselecting all rows')
        gridLUNs.unselect()
        selectedRows = gridLUNs.find(selected=True)
        self.assertFalse(selectedRows)
        LOG.info('Selected rows:\n', selectedRows)

        LOG.step(
            "Finding rows by multiple names '%s' and '%s' (pattern matching)" %
            (prefixLower, prefixUpper))
        foundRows = gridLUNs.find(name=[prefixLower, prefixUpper],
                                  matchPattern=True)
        for row in foundRows:
            self.assertTrue((prefixLower in row['name'])
                            or (prefixUpper in row['name']))
        LOG.info('Found rows:\n', foundRows)

        LOG.step('Unselecting all rows')
        gridLUNs.unselect()
        selectedRows = gridLUNs.find(selected=True)
        self.assertFalse(selectedRows)
        LOG.info('Selected rows:\n', selectedRows)

        LOG.step(
            "Finding rows by multiple names '%s_1' and '%s_3' (exact matching)"
            % (prefixLower, prefixUpper))
        foundRows = gridLUNs.find(
            name=[prefixLower + '_1', prefixUpper + '_3'])
        for row in foundRows:
            self.assertTrue((prefixLower + '_1' in row['name'])
                            or (prefixUpper + '_3' in row['name']))
        LOG.info('Found rows:\n', foundRows)

        LOG.step('Unselecting all rows')
        gridLUNs.unselect()
        selectedRows = gridLUNs.find(selected=True)
        self.assertFalse(selectedRows)
        LOG.info('Selected rows:\n', selectedRows)

        LOG.step('Finding all rows')
        foundRows = gridLUNs.find()
        LOG.info('Found rows:\n', len(foundRows))
        gridLUNs.unselect()
        unselectedRows = gridLUNs.find(selected=False)
        self.assertTrue(len(foundRows) == len(unselectedRows))
        LOG.info('Unselected rows:\n', len(unselectedRows))

    def test_component_grid_multi_page(self):
        prefix = 'IO'
        lunCount = 135

        LOG.step("Creating %s LUNs with name prefix '%s'" % (lunCount, prefix))
        self.luns.create(count=lunCount, size=self.lunSize, prefix=prefix)

        LOG.step('Creating LUNs grid object')
        gridLUNs = self.lunsPage.gridLUNs

        LOG.info('Pages:', gridLUNs.pages)

        LOG.step('Navigating to page 1')
        gridLUNs.goToPage(number=1)
        self.assertTrue(gridLUNs.page == 1)
        LOG.info('Page:', gridLUNs.page)
        self.assertFalse(gridLUNs.hasFirstPage)
        LOG.info('Has first page:', gridLUNs.hasFirstPage)
        self.assertFalse(gridLUNs.hasPreviousPage)
        LOG.info('Has previous page:', gridLUNs.hasPreviousPage)
        if gridLUNs.pages > 1:
            self.assertTrue(gridLUNs.hasNextPage)
            self.assertTrue(gridLUNs.hasLastPage)
        else:
            self.assertFalse(gridLUNs.hasNextPage)
            self.assertFalse(gridLUNs.hasLastPage)
        LOG.info('Has next page:', gridLUNs.hasNextPage)
        LOG.info('Has last page:', gridLUNs.hasLastPage)

        LOG.step('Navigating to next page')
        gridLUNs.goNextPage()
        self.assertTrue(gridLUNs.page == 2)
        LOG.info('Page:', gridLUNs.page)
        self.assertTrue(gridLUNs.hasFirstPage)
        LOG.info('Has first page:', gridLUNs.hasFirstPage)
        self.assertTrue(gridLUNs.hasPreviousPage)
        LOG.info('Has previous page:', gridLUNs.hasPreviousPage)
        if gridLUNs.pages > 2:
            self.assertTrue(gridLUNs.hasNextPage)
            self.assertTrue(gridLUNs.hasLastPage)
        else:
            self.assertFalse(gridLUNs.hasNextPage)
            self.assertFalse(gridLUNs.hasLastPage)
        LOG.info('Has next page:', gridLUNs.hasNextPage)
        LOG.info('Has last page:', gridLUNs.hasLastPage)

        LOG.step(
            'Navigating through all pages: first, next until last, previous until first, last'
        )
        gridLUNs.goFirstPage()
        LOG.info('Page:', gridLUNs.page)
        while gridLUNs.page < gridLUNs.pages:
            gridLUNs.goNextPage()
            LOG.info('Page:', gridLUNs.page)
        if gridLUNs.pages > 1:
            self.assertTrue(gridLUNs.hasFirstPage)
            self.assertTrue(gridLUNs.hasPreviousPage)
            self.assertTrue(gridLUNs.page == gridLUNs.pages)
            self.assertFalse(gridLUNs.hasNextPage)
            self.assertFalse(gridLUNs.hasLastPage)
        while gridLUNs.page > 1:
            gridLUNs.goPreviousPage()
            LOG.info('Page:', gridLUNs.page)
        self.assertTrue(gridLUNs.page == 1)

        LOG.step("Navigating to non-existing page")
        try:
            gridLUNs.goToPage(number=(gridLUNs.pages + 1))
        except LookupError as e:
            LOG.info(e.message)

    def test_component_grid_click_link(self):
        prefix = 'SATURN'
        lunCount = 3

        LOG.step("Creating %s LUNs with name prefix '%s'" % (lunCount, prefix))
        self.luns.create(count=lunCount, size=self.lunSize, prefix=prefix)

        self.lunsPage.btnRefresh.click()

        LOG.step('Creating LUNs grid object')
        gridLUNs = self.lunsPage.gridLUNs

        for rowCount in range(1, lunCount + 1):
            LOG.step(
                "Clicking on link '%s' in cell name='%s'" %
                (prefix + '_' + str(rowCount), prefix + '_' + str(rowCount)))
            gridLUNs.clickLink(name=prefix + '_' + str(rowCount),
                               click={'name': prefix + '_' + str(rowCount)})
            self.driver.back()
            LOG.info('Navigated back in browser history')

    def testTeardown(self):
        try:
            LOG.info("Destroying existing LUNs...")
            del self.luns
        except Exception as e:
            raise FailedProductException(e)
        self.driver.quit()
Esempio n. 21
0
class TestCloneLUNSnapshotWizard(FRTestCase):
    def suiteSetup(self):
        self.username = ARGS.values.username
        self.password = ARGS.values.password
        self.locale = ARGS.values.locale
        self.webUIHostName = getFQDN(self.marscluster.getMasterNode().hostname)

    def testSetup(self):
        self.driver = self.getDriver()
        self.loginPage = LoginPage(driver=self.driver, url=self.webUIHostName)
        self.headerPage = HeaderPage(driver=self.driver)
        self.allStoragePage = AllStoragePage(driver=self.driver)
        self.lunsPage = LUNsPage(driver=self.driver)
        self.lunDetailsPage = LUNDetailsPage(driver=self.driver)
        self.lunSnapshotsPage = LUNSnapshotsPage(driver=self.driver)

        LOG.step('Cleaning out cluster content')
        snapshots = self.marscluster.snapshot.show(json=True)
        for snapshot in snapshots:
            self.marscluster.snapshot.delete(name=snapshot['name'],
                                             lun=snapshot['object'])
        self.assertFalse(self.marscluster.snapshot.show(json=True))
        LOG.info('Snapshots destroyed.')

        luns = express.Luns(node=self.marscluster, cleanup=True)
        del luns
        self.assertFalse(self.marscluster.lun.show(json=True))
        LOG.info('LUNs destroyed.')

        self.marscluster.igroup.destroyAll()
        LOG.info('Initiator groups destroyed.')

        self._deleteDependentConsistencyGroups()
        LOG.info('Consistency groups destroyed.')

        self.luns = express.Luns(node=self.marscluster)

        LOG.step('Signing in')
        self.loginPage.open()
        self.loginPage.waitUntilOpen()
        if self.locale is None:
            self.locale = self.loginPage.getRandomLocale()
        self.loginPage.signIn(username=self.username,
                              password=self.password,
                              locale=self.locale)
        LOG.info('Signed in with username: %s, password: %s, locale: %s.' %
                 (self.username, self.password, self.locale))
        LOG.info('Browser landed on header page.')

        LOG.info('Navigating to LUNs page...')
        self.headerPage.btnManager.click()
        self.allStoragePage.tabLUNs.click()
        self.lunsPage.waitUntilOpen()
        LOG.info('Browser landed on LUNs page.')

    def test_clone_no_ig_cg(self):
        """
            Verify LUN snapshot cloning when no initiator/consistency groups exist.
        """
        lunNamePrefix = 'LuN'
        lunName = lunNamePrefix + '_1'
        snapshotName = lunName + '_snap'
        cloneName = lunName + '_clone_0'

        LOG.step('Creating LUN')
        self.luns.create(count=1, size='1g', prefix=lunNamePrefix)
        luns = self.marscluster.lun.show(json=True)
        LOG.info('LUNs created:\n', luns)

        LOG.step('Creating LUN snapshot')
        self.marscluster.snapshot.create(luns=lunName, name=snapshotName)
        snapshots = self.marscluster.snapshot.show(json=True)
        LOG.info('Snapshot created:\n', snapshots)

        self.lunsPage.btnRefresh.click()
        self.lunsPage.btnRefresh.waitUntilEnabled()
        self._navigateToLUNSnapshotsPage(lunName=lunName)

        LOG.step('Opening wizard')
        wizard = CloneLUNSnapshotWizard(driver=self.driver)
        wizard.open(lunName=lunName, lunSnapshotName=snapshotName)
        LOG.info('Wizard open.')

        LOG.step('Verifying default details of LUN snapshot clone')
        self.assertTrue(
            wizard.activePage.lblSubtitle.getText() == snapshotName)
        LOG.info('LUN snapshot name:', wizard.activePage.lblSubtitle.getText())

        self.assertTrue(wizard.activePage.txtName.getText() == cloneName)
        LOG.info('LUN snapshot clone name:',
                 wizard.activePage.txtName.getText())
        self.assertFalse(
            wizard.activePage.cBoxParentConsistencyGroup.isEnabled())
        LOG.info('Parent consistency group is enabled:',
                 wizard.activePage.cBoxParentConsistencyGroup.isEnabled())
        wizard.activePage.dLstMappedTo.expand()
        wizard.selectInitiatorGroupsPage.waitUntilOpen()
        initiatorGroups = wizard.selectInitiatorGroupsPage.gridInitiatorGroups.find(
        )
        self.assertFalse(initiatorGroups)
        LOG.info('Initiator groups available:', initiatorGroups)
        wizard.activePage.dLstMappedTo.collapse()

        LOG.step('Cloning LUN snapshot')
        wizard.activePage.submit()
        self._verifyClone(snapshotName=snapshotName, cloneName=cloneName)

    def test_clone_not_mapped(self):
        """
            Verify LUN snapshot cloning when initiator and consistency groups exist but not mapped.
        """
        lunNamePrefix = 'LuN'
        lunName = lunNamePrefix + '_1'
        snapshotName = lunName + '_snap'
        cloneName = lunName + '_clone_0'
        initiatorGroupName = 'IG-'
        initiatorGroupsNumber = 5
        parentConsistencyGroupName = 'Parent-CG'

        LOG.step('Creating LUN')
        self.luns.create(count=1, size='1g', prefix=lunNamePrefix)
        luns = self.marscluster.lun.show(json=True)
        self.assertTrue(len(luns) == 1)
        LOG.info('LUN created:\n', luns)

        LOG.step('Creating LUN snapshot')
        self.marscluster.snapshot.create(luns=lunName, name=snapshotName)
        snapshots = self.marscluster.snapshot.show(json=True)
        LOG.info('Snapshot created:\n', snapshots)

        LOG.step('Creating initiator groups')
        for initiatorIndex in range(initiatorGroupsNumber):
            fictiveWWPN = format(random.randrange(sys.maxint),
                                 'x').rjust(16, 'f')
            self.marscluster.igroup.create(name=(initiatorGroupName +
                                                 str(initiatorIndex)),
                                           ostype='vmware',
                                           initiators=fictiveWWPN)
        originalInitiatorGroups = self.marscluster.igroup.show(json=True)
        self.assertTrue(len(originalInitiatorGroups) == initiatorGroupsNumber)
        LOG.info('Initiator groups created:\n', originalInitiatorGroups)

        LOG.step('Creating consistency group')
        self.marscluster.cg.create(name=parentConsistencyGroupName)
        consistencyGroups = self.marscluster.cg.show(json=True)
        self.assertTrue(len(consistencyGroups) == 1)
        self.assertTrue(
            consistencyGroups[0]['name'] == parentConsistencyGroupName)
        LOG.info('Consistency group created:', parentConsistencyGroupName)

        self.lunsPage.btnRefresh.click()
        self.lunsPage.btnRefresh.waitUntilEnabled()
        self._navigateToLUNSnapshotsPage(lunName=lunName)

        LOG.step('Opening wizard')
        wizard = CloneLUNSnapshotWizard(driver=self.driver)
        wizard.open(lunName=lunName, lunSnapshotName=snapshotName)
        LOG.info('Wizard open.')

        LOG.step('Verifying default details of LUN snapshot clone')
        self.assertTrue(wizard.activePage.txtName.getText() == cloneName)
        LOG.info('Default LUN snapshot clone name:',
                 wizard.activePage.txtName.getText())
        wizard.activePage.dLstMappedTo.expand()
        wizard.selectInitiatorGroupsPage.waitUntilOpen()
        initiatorGroups = wizard.selectInitiatorGroupsPage.gridInitiatorGroups.find(
        )
        self.assertTrue(len(initiatorGroups) == len(originalInitiatorGroups))
        mappedInitiatorGroups = [
            initiatorGroup for initiatorGroup in initiatorGroups
            if initiatorGroup['selected'] == True
        ]
        self.assertFalse(mappedInitiatorGroups)
        LOG.info('Mapped initiator groups:', mappedInitiatorGroups)
        wizard.activePage.dLstMappedTo.collapse()
        self.assertTrue(
            wizard.activePage.cBoxParentConsistencyGroup.isEnabled())
        LOG.info('Parent consistency group is enabled:',
                 wizard.activePage.cBoxParentConsistencyGroup.isEnabled())
        consistencyGroups = wizard.activePage.cBoxParentConsistencyGroup.getItems(
        )
        self.assertTrue(parentConsistencyGroupName in consistencyGroups)
        LOG.info('Consistency groups available:', consistencyGroups)

        LOG.step('Cloning LUN')
        wizard.activePage.submit()
        self._verifyClone(snapshotName=snapshotName, cloneName=cloneName)

    def test_clone_mapped(self):
        """
            Verify LUN snapshot cloning when mapped to initiator and consistency groups.
        """
        lunNamePrefix = 'LuN'
        lunName = lunNamePrefix + '_1'
        snapshotName = lunName + '_snap'
        cloneName = lunName + '_clone_0'
        initiatorGroupName = 'IG-'
        initiatorGroupsNumber = 5
        parentConsistencyGroupName = 'Parent-CG'

        LOG.step('Creating LUN')
        self.luns.create(count=1, size='1g', prefix=lunNamePrefix)
        luns = self.marscluster.lun.show(json=True)
        self.assertTrue(len(luns) == 1)
        LOG.info('LUN created:\n', luns)

        LOG.step('Creating LUN snapshot')
        self.marscluster.snapshot.create(luns=lunName, name=snapshotName)
        snapshots = self.marscluster.snapshot.show(json=True)
        LOG.info('Snapshot created:\n', snapshots)

        LOG.step('Creating initiator groups')
        for initiatorIndex in range(initiatorGroupsNumber):
            fictiveWWPN = format(random.randrange(sys.maxint),
                                 'x').rjust(16, 'f')
            self.marscluster.igroup.create(name=(initiatorGroupName +
                                                 str(initiatorIndex)),
                                           ostype='vmware',
                                           initiators=fictiveWWPN)
        originalInitiatorGroups = self.marscluster.igroup.show(json=True)
        self.assertTrue(len(originalInitiatorGroups) == initiatorGroupsNumber)
        LOG.info('Initiator groups created:\n', originalInitiatorGroups)

        LOG.step('Mapping LUN snapshot to initiator groups')
        self.marscluster.lun.map({
            'name': lunName,
            'igroup': originalInitiatorGroups[0]['name']
        })
        self.marscluster.lun.map({
            'name': lunName,
            'igroup': originalInitiatorGroups[-1]['name']
        })
        LOG.info('LUN snapshot initiator group mapping:',
                 self.marscluster.lun.mapped_show())

        LOG.step('Creating consistency group')
        self.marscluster.cg.create({
            'name': parentConsistencyGroupName,
            'members': lunName
        })
        consistencyGroups = self.marscluster.cg.show(json=True)
        self.assertTrue(len(consistencyGroups) == 1)
        lun = [
            lun for lun in self.marscluster.lun.show(json=True)
            if lun['name'] == parentConsistencyGroupName + '/' +
            lunNamePrefix + '_1'
        ][0]
        LOG.info('Consistency group created and mapped:', lun['maps'])

        self.lunsPage.btnRefresh.click()
        self.lunsPage.btnRefresh.waitUntilEnabled()
        self._navigateToLUNSnapshotsPage(lunName=lunName)

        LOG.step('Opening wizard')
        wizard = CloneLUNSnapshotWizard(driver=self.driver)
        wizard.open(lunName=lunName, lunSnapshotName=snapshotName)
        LOG.info('Wizard open.')

        LOG.step('Verifying default details of LUN snapshot clone')
        self.assertTrue(wizard.activePage.txtName.getText() == cloneName)
        LOG.info('Default LUN snapshot clone name:',
                 wizard.activePage.txtName.getText())
        wizard.activePage.dLstMappedTo.expand()
        wizard.selectInitiatorGroupsPage.waitUntilOpen()
        initiatorGroups = wizard.selectInitiatorGroupsPage.gridInitiatorGroups.find(
        )
        self.assertTrue(len(initiatorGroups) == len(originalInitiatorGroups))
        mappedInitiatorGroups = [
            initiatorGroup for initiatorGroup in initiatorGroups
            if initiatorGroup['selected'] == True
        ]
        self.assertTrue(len(mappedInitiatorGroups) == 2)
        self.assertTrue(mappedInitiatorGroups[0]['initiator_group'] in [
            originalInitiatorGroups[0]['name'], originalInitiatorGroups[-1]
            ['name']
        ])
        self.assertTrue(mappedInitiatorGroups[1]['initiator_group'] in [
            originalInitiatorGroups[0]['name'], originalInitiatorGroups[-1]
            ['name']
        ])
        LOG.info('Mapped initiator groups:', mappedInitiatorGroups)
        wizard.activePage.dLstMappedTo.collapse()
        self.assertTrue(
            wizard.activePage.cBoxParentConsistencyGroup.isEnabled())
        LOG.info('Parent consistency group is enabled:',
                 wizard.activePage.cBoxParentConsistencyGroup.isEnabled())
        consistencyGroups = wizard.activePage.cBoxParentConsistencyGroup.getItems(
        )
        self.assertTrue(parentConsistencyGroupName in consistencyGroups)
        LOG.info('Consistency groups available:', consistencyGroups)

        LOG.step('Cloning LUN snapshot')
        wizard.activePage.submit()
        self._verifyClone(snapshotName=snapshotName, cloneName=cloneName)

        luns = self.marscluster.lun.show(json=True)
        clone = [lun for lun in luns if lun['name'] == cloneName][0]
        mappedInitiatorGroups = [
            group['igroup-name'] for group in clone['maps']
        ]
        self.assertTrue(len(mappedInitiatorGroups) == 2)
        self.assertTrue(mappedInitiatorGroups[0] in [
            originalInitiatorGroups[0]['name'], originalInitiatorGroups[-1]
            ['name']
        ])
        self.assertTrue(mappedInitiatorGroups[1] in [
            originalInitiatorGroups[0]['name'], originalInitiatorGroups[-1]
            ['name']
        ])
        LOG.info('Mapped initiator groups:', mappedInitiatorGroups)

    def test_clone_sequent(self):
        """
            Verify auto-naming of clone when previous auto-named clone already exists.
        """
        lunNamePrefix = 'LuN'
        lunName = lunNamePrefix + '_1'
        snapshotName = lunName + '_snap'
        cloneName = lunName + '_clone_0'
        sequentCloneName = lunName + '_clone_1'

        LOG.step('Creating LUN')
        self.luns.create(count=1, size='1g', prefix=lunNamePrefix)
        luns = self.marscluster.lun.show(json=True)
        self.assertTrue(len(luns) == 1)
        LOG.info('LUN created:\n', luns)

        LOG.step('Creating LUN snapshot')
        self.marscluster.snapshot.create(luns=lunName, name=snapshotName)
        snapshots = self.marscluster.snapshot.show(json=True)
        LOG.info('Snapshot created:\n', snapshots)

        self.lunsPage.btnRefresh.click()
        self.lunsPage.btnRefresh.waitUntilEnabled()
        self._navigateToLUNSnapshotsPage(lunName=lunName)

        LOG.step('Opening wizard')
        wizard = CloneLUNSnapshotWizard(driver=self.driver)
        wizard.open(lunName=lunName, lunSnapshotName=snapshotName)
        LOG.info('Wizard open.')

        LOG.step('Cloning LUN snapshot')
        wizard.activePage.submit()
        self._verifyClone(snapshotName=snapshotName, cloneName=cloneName)

        LOG.step('Opening wizard')
        wizard.open(lunName=lunName, lunSnapshotName=snapshotName)
        LOG.info('Wizard open.')

        LOG.step('Sequent cloning of LUN snapshot')
        wizard.activePage.submit()
        self._verifyClone(snapshotName=snapshotName,
                          cloneName=sequentCloneName)

    def test_dialog_not_available(self):
        """
            Verify dialog not available when no or >= 2 LUNs selected.
        """
        lunNamePrefix = 'LuN'
        lunName = lunNamePrefix + '_1'
        lunSnapshotNamePrefix = lunName + '_snap_'
        lunSnapshotCount = 4

        LOG.step('Creating LUN')
        self.luns.create(count=1, size='1g', prefix=lunNamePrefix)
        luns = self.marscluster.lun.show(json=True)
        LOG.info('LUN created:\n', luns)

        LOG.step('Creating LUN snapshots')
        for count in range(lunSnapshotCount):
            self.marscluster.snapshot.create(luns=lunName,
                                             name=lunSnapshotNamePrefix +
                                             str(count))
        snapshots = self.marscluster.snapshot.show(json=True)
        LOG.info('Snapshot created:\n', snapshots)

        self.lunsPage.btnRefresh.click()
        self.lunsPage.btnRefresh.waitUntilEnabled()
        self._navigateToLUNSnapshotsPage(lunName=lunName)

        LOG.step('Unselecting all LUN snapshots in grid')
        self.lunSnapshotsPage.gridSnapshots.unselect()
        snapshots = self.lunSnapshotsPage.gridSnapshots.find(selected=True)
        self.assertFalse(snapshots)
        LOG.info('Selected LUN snapshots:', snapshots)

        LOG.step("Verifying button 'Clone' disabled")
        self.assertFalse(self.lunSnapshotsPage.btnClone.isEnabled())
        LOG.info("Button 'Clone' is enabled:",
                 self.lunSnapshotsPage.btnClone.isEnabled())

        LOG.step('Selecting 1 LUN snapshot in grid')
        self.lunSnapshotsPage.gridSnapshots.unselect()
        self.lunSnapshotsPage.gridSnapshots.select(name=lunSnapshotNamePrefix +
                                                   '1')
        snapshots = self.lunSnapshotsPage.gridSnapshots.find(selected=True)
        self.assertTrue(len(snapshots) == 1)
        LOG.info('Selected LUN snapshots:', snapshots)

        LOG.step("Verifying button 'Clone' enabled")
        self.assertTrue(self.lunSnapshotsPage.btnClone.isEnabled())
        LOG.info("Button 'Clone' is enabled:",
                 self.lunSnapshotsPage.btnClone.isEnabled())

        LOG.step('Selecting 2 LUN snapshots in grid')
        self.lunSnapshotsPage.gridSnapshots.unselect()
        self.lunSnapshotsPage.gridSnapshots.select(
            name=[lunSnapshotNamePrefix + '1', lunSnapshotNamePrefix + '2'])
        snapshots = self.lunSnapshotsPage.gridSnapshots.find(selected=True)
        self.assertTrue(len(snapshots) == 2)
        LOG.info('Selected LUN snapshots:', snapshots)

        LOG.step("Verifying button 'Clone' disabled")
        self.assertFalse(self.lunSnapshotsPage.btnClone.isEnabled())
        LOG.info("Button 'Clone' is enabled:",
                 self.lunSnapshotsPage.btnClone.isEnabled())

    def test_dialog_cancel(self):
        """
            Verify closing wizard without submission does not affect LUN and its mappings.
        """
        lunNamePrefix = 'LuN'
        lunName = lunNamePrefix + '_1'
        snapshotName = lunName + '_snap'

        LOG.step('Creating LUNs')
        self.luns.create(count=1, size='1g', prefix=lunNamePrefix)
        luns = self.marscluster.lun.show(json=True)
        lunCount = len(luns)
        LOG.info('LUN created:\n', luns)

        LOG.step('Creating LUN snapshot')
        self.marscluster.snapshot.create(luns=lunName, name=snapshotName)
        snapshots = self.marscluster.snapshot.show(json=True)
        LOG.info('Snapshot created:\n', snapshots)

        self.lunsPage.btnRefresh.click()
        self.lunsPage.btnRefresh.waitUntilEnabled()
        self._navigateToLUNSnapshotsPage(lunName=lunName)

        LOG.step('Opening wizard')
        wizard = CloneLUNSnapshotWizard(driver=self.driver)
        wizard.open(lunName=lunName, lunSnapshotName=snapshotName)
        LOG.info('Wizard open.')

        LOG.step('Closing wizard')
        wizard.cancel()
        LOG.info('Wizard closed.')

        LOG.step('Verifying no LUN snapshot clone has been created.')
        luns = self.marscluster.lun.show(json=True)
        self.assertTrue(len(luns) == lunCount)
        LOG.info('No clone has been created.')

    def testTeardown(self):
        self.driver.close()

    def suiteTeardown(self):
        LOG.step('Closing browser')
        self.driver.quit()

        LOG.step('Deleting snapshots')
        snapshots = self.marscluster.snapshot.show(json=True)
        for snapshot in snapshots:
            self.marscluster.snapshot.delete(name=snapshot['name'],
                                             lun=snapshot['object'])
        self.assertFalse(self.marscluster.snapshot.show(json=True))
        LOG.info('Snapshots deleted.')

        LOG.step('Destroying LUNs')
        luns = express.Luns(node=self.marscluster, cleanup=True)
        del luns
        LOG.info('LUNs destroyed.')

    def _deleteDependentConsistencyGroups(self):
        while True:
            consistencyGroups = self.marscluster.cg.show(json=True)
            if not consistencyGroups:
                break
            else:
                for consistencyGroup in consistencyGroups:
                    if 'cg' not in consistencyGroup:
                        self.marscluster.cg.delete(
                            name=consistencyGroup['name'])

    def _navigateToLUNSnapshotsPage(self, lunName):
        LOG.step('Navigating to LUN Snapshots page...')
        self.lunsPage.gridLUNs.clickLink(name=lunName, click={'name': lunName})
        self.lunDetailsPage.waitUntilOpen()
        self.lunDetailsPage.tabSnapshots.click()
        self.lunSnapshotsPage.waitUntilOpen()
        LOG.info('Browser landed on LUN Snapshots page.')

    def _verifyClone(self, snapshotName, cloneName):
        luns = self.marscluster.lun.show(json=True)
        snapshots = self.marscluster.snapshot.show(json=True)
        snapshot = [
            snapshot for snapshot in snapshots
            if snapshot['name'] == snapshotName
        ][0]
        clone = [
            lun for lun in luns if (lun.get('parent-snapshot') == snapshotName
                                    and lun['name'] == cloneName)
        ][0]
        self.assertTrue(clone)
        self.assertTrue(clone['size'] == snapshot['lun-info']['size'])
        LOG.info("Clone size equal to snapshot size:", clone['size'])
        self.assertTrue(clone['parent'] == snapshot['object'])
        LOG.info("Cloned parent is original LUN:", clone['parent'])
class TestDeleteLUNWizard(FRTestCase):
    def suiteSetup(self):
        self.username = ARGS.values.username
        self.password = ARGS.values.password
        self.locale = ARGS.values.locale
        self.webUIHostName = getFQDN(self.marscluster.getMasterNode().hostname)

    def testSetup(self):
        self.driver = self.getDriver()
        self.loginPage = LoginPage(driver=self.driver, url=self.webUIHostName)
        self.headerPage = HeaderPage(driver=self.driver)
        self.allStoragePage = AllStoragePage(driver=self.driver)
        self.lunsPage = LUNsPage(driver=self.driver)

        self.node = self.marscluster
        self.luns = express.Luns(node=self.marscluster)
        # self.luns.setCleanup(True)

        LOG.step('Signing in')
        self.loginPage.open()
        self.loginPage.waitUntilOpen()
        if self.locale is None:
            self.locale = self.loginPage.getRandomLocale()
        self.loginPage.signIn(username=self.username,
                              password=self.password,
                              locale=self.locale)
        LOG.info('Signed in with username: %s, password: %s, locale: %s.' %
                 (self.username, self.password, self.locale))
        LOG.info('Browser landed on header page.')

        LOG.info('Navigating to LUNs page...')
        self.headerPage.btnManager.click()
        self.allStoragePage.tabLUNs.click()
        self.lunsPage.waitUntilOpen()
        LOG.info('Browser landed on LUNs page.')

    def test_delete_single_lun(self):
        """
            Verify single LUN's deletion.
        """
        LOG.step('Creating LUNs')
        lunCount = 3
        lunSize = 2
        lunSizeUnit = 'G'
        lunNamePrefix = 'LuN'
        self.luns.create(count=lunCount,
                         size=str(lunSize) + lunSizeUnit,
                         prefix=lunNamePrefix)
        LOG.info('LUNs created:\n',
                 pprint.pformat(self.marscluster.lun.show(json=True)))

        # Refresh LUN grid
        self.lunsPage.btnRefresh.click()
        self.lunsPage.btnRefresh.waitUntilEnabled()

        LOG.step("Deleting LUN '%s'" % (lunNamePrefix + '_1'))
        wizard = DeleteLUNWizard(driver=self.driver)
        wizard.open(name=lunNamePrefix + '_1')
        wizard.activePage.confirm()
        wizard.activePage.submit()
        LOG.info('LUN deletion submitted.')

        LOG.step('Verifying LUN has been deleted')
        luns = self.marscluster.lun.show(json=True)
        self.assertTrue(len(luns) == lunCount - 1)
        self.assertTrue((lunNamePrefix +
                         '_1') not in [lun['name'] for lun in luns])
        LOG.info('LUNs:\n%s' % pprint.pformat(luns))
        LOG.info("LUN '%s' deleted." % (lunNamePrefix + '_1'))

    def test_delete_multiple_luns(self):
        """
            Verify multiple LUNs' deletion.
        """
        LOG.step('Creating LUNs')
        lunCount = 7
        lunSize = 2
        lunSizeUnit = 'G'
        lunNamePrefix = 'LuN'
        lunsToDelete = [
            lunNamePrefix + '_1', lunNamePrefix + '_2', lunNamePrefix + '_3'
        ]
        self.luns.create(count=lunCount,
                         size=str(lunSize) + lunSizeUnit,
                         prefix=lunNamePrefix)
        LOG.info('LUNs created:\n',
                 pprint.pformat(self.marscluster.lun.show(json=True)))

        # Refresh LUN grid
        self.lunsPage.btnRefresh.click()
        self.lunsPage.btnRefresh.waitUntilEnabled()

        LOG.step("Deleting LUNs: %s" % lunsToDelete)
        wizard = DeleteLUNWizard(driver=self.driver)
        wizard.open(name=lunsToDelete)
        wizard.activePage.confirm()
        wizard.activePage.submit()
        LOG.info('LUN deletion submitted.')

        LOG.step('Verifying LUNs have been deleted')
        luns = [lun['name'] for lun in self.marscluster.lun.show(json=True)]
        self.assertTrue(len(luns) == lunCount - len(lunsToDelete))
        for lunName in lunsToDelete:
            self.assertFalse(lunName in luns)
        LOG.info('Existing LUNs:\n%s' % luns)

    def test_dialog_cancel(self):
        """
            Verify 'Delete LUN -> Cancel' does cancel dialog gracefully, LUN not deleted.
        """
        LOG.step('Creating LUNs')
        lunCount = 3
        lunSize = 2
        lunSizeUnit = 'G'
        lunNamePrefix = 'LuN'
        self.luns.create(count=lunCount,
                         size=str(lunSize) + lunSizeUnit,
                         prefix=lunNamePrefix)
        lunsOriginal = [
            lun['name'] for lun in self.marscluster.lun.show(json=True)
        ]
        LOG.info('LUNs created:', lunsOriginal)

        # Refresh LUN grid
        self.lunsPage.btnRefresh.click()
        self.lunsPage.btnRefresh.waitUntilEnabled()

        LOG.step('Opening wizard')
        wizard = DeleteLUNWizard(driver=self.driver)
        wizard.open(name=lunNamePrefix + '_1')
        LOG.info('Wizard open.')

        LOG.step('Canceling wizard')
        wizard.activePage.confirm()
        wizard.cancel()
        LOG.info('Wizard closed without submission.')

        LOG.step('Verifying LUN has remain intact')
        luns = [lun['name'] for lun in self.marscluster.lun.show(json=True)]
        self.assertTrue(len(luns) == lunCount)
        for lunName in luns:
            self.assertTrue(lunName in lunsOriginal)
        LOG.info('LUNs original: %s' % lunsOriginal)
        LOG.info('LUNs existing: %s' % luns)

    def test_dialog_not_available(self):
        """
            Verify that 'Delete LUN' is not available when no selected LUNs present.
        """
        LOG.step('Creating LUNs')
        lunCount = 3
        lunSize = 2
        lunSizeUnit = 'G'
        lunNamePrefix = 'LuN'
        self.luns.create(count=lunCount,
                         size=str(lunSize) + lunSizeUnit,
                         prefix=lunNamePrefix)
        lunsOriginal = [
            lun['name'] for lun in self.marscluster.lun.show(json=True)
        ]
        LOG.info('LUNs created:', lunsOriginal)

        # Refresh LUN grid
        self.lunsPage.btnRefresh.click()
        self.lunsPage.btnRefresh.waitUntilEnabled()

        LOG.step('Unselecting all LUNs in grid')
        self.lunsPage.gridLUNs.unselect()
        self.assertFalse(self.lunsPage.gridLUNs.find(selected=True))
        LOG.info('No LUNs selected in grid.')

        LOG.step("Verifying button 'Delete' is disabled.")
        self.assertFalse(self.lunsPage.btnDelete.isEnabled())
        LOG.info("Button 'Delete' is enabled:",
                 self.lunsPage.btnDelete.isEnabled())

    def testTeardown(self):
        self.driver.close()
        luns = express.Luns(node=self.marscluster, cleanup=True)
        del luns
        LOG.info('LUNs destroyed.')

    def suiteTeardown(self):
        LOG.step('Closing browser')
        self.driver.quit()
        LOG.info('Browser closed.')
Esempio n. 23
0
class TestRenameLUNWizard(FRTestCase):
    def suiteSetup(self):
        self.username = ARGS.values.username
        self.password = ARGS.values.password
        self.locale = ARGS.values.locale
        self.webUIHostName = getFQDN(self.marscluster.getMasterNode().hostname)

    def testSetup(self):
        self.driver = self.getDriver()
        self.loginPage = LoginPage(driver=self.driver, url=self.webUIHostName)
        self.headerPage = HeaderPage(driver=self.driver)
        self.allStoragePage = AllStoragePage(driver=self.driver)
        self.lunsPage = LUNsPage(driver=self.driver)

        self.node = self.marscluster
        self.luns = express.Luns(node=self.marscluster)

        LOG.step('Signing in')
        self.loginPage.open()
        self.loginPage.waitUntilOpen()
        if self.locale is None:
            self.locale = self.loginPage.getRandomLocale()
        self.loginPage.signIn(username=self.username, password=self.password, locale=self.locale)
        LOG.info('Signed in with username: %s, password: %s, locale: %s.' % (self.username,
            self.password, self.locale))
        LOG.info('Browser landed on header page.')

        LOG.info('Navigating to LUNs page...')
        self.headerPage.btnManager.click()
        self.allStoragePage.tabLUNs.click()
        self.lunsPage.waitUntilOpen()
        LOG.info('Browser landed on LUNs page.')

    def test_valid_name(self):
        """
            Verify LUN renaming with valid name.
        """
        LOG.step('Creating LUNs')
        lunCount = 3
        lunSize = '1g'
        lunNamePrefix = 'LuN'
        lunNewName = 'NewName'
        self.luns.create(count=lunCount, size=lunSize, prefix=lunNamePrefix)
        LOG.info('LUNs created:\n', self.node.lun.show(json=True))

        self.lunsPage.btnRefresh.click()
        self.lunsPage.btnRefresh.waitUntilEnabled()

        LOG.step('Renaming LUN in dialog')
        wizard = RenameLUNWizard(driver=self.driver)
        wizard.open(name=lunNamePrefix + '_1')
        LOG.info('Old LUN name:', lunNamePrefix + '_1')
        wizard.renameLUNPage.renameLUN(name=lunNewName)
        LOG.info('New LUN name:', lunNewName)
        wizard.renameLUNPage.submit()
        LOG.info('Rename submitted.')

        LOG.step('Verifying LUN name has been changed')
        lun = self.lunsPage.gridLUNs.find(name=lunNewName)
        self.assertTrue(len(lun) == 1)
        self.assertTrue(lun[0]['name'] == lunNewName)
        LOG.info('LUN found:\n', lun)

    def test_invalid_name(self):
        """
            Verify LUN renaming with invalid name.
        """
        LOG.step('Creating LUNs')
        lunCount = 3
        lunSize = '1g'
        lunNamePrefix = 'LuN'
        lunNewName = 'NewName*&#@1A_^?,'
        self.luns.create(count=lunCount, size=lunSize, prefix=lunNamePrefix)
        LOG.info('LUNs created:\n', self.node.lun.show(json=True))

        self.lunsPage.btnRefresh.click()
        self.lunsPage.btnRefresh.waitUntilEnabled()

        LOG.step('Renaming LUN in dialog')
        wizard = RenameLUNWizard(driver=self.driver)
        wizard.open(name=lunNamePrefix + '_1')
        LOG.info('Old LUN name:', lunNamePrefix + '_1')
        wizard.renameLUNPage.renameLUN(name=lunNewName)
        LOG.info('New LUN name:', lunNewName)

        LOG.step('Verifying name error message')
        wizard.activePage.lblNameError.waitUntilPresent()
        LOG.info('Name error message:', wizard.activePage.lblNameError.getText())
        self.assertFalse(wizard.activePage.btnOK.isEnabled())
        LOG.info("Button 'OK' is enabled:", wizard.activePage.btnOK.isEnabled())

    def test_unicode_name(self):
        """
            Verify error message on setting LUN name containing Unicode characters.
        """
        LOG.step('Creating LUNs')
        lunCount = 3
        lunSize = '1g'
        lunNamePrefix = 'LuN'
        lunNewName = u'Fran\u00e7ais'
        self.luns.create(count=lunCount, size=lunSize, prefix=lunNamePrefix)
        LOG.info('LUNs created:\n', self.node.lun.show(json=True))

        self.lunsPage.btnRefresh.click()
        self.lunsPage.btnRefresh.waitUntilEnabled()

        LOG.step('Renaming LUN in dialog')
        wizard = RenameLUNWizard(driver=self.driver)
        wizard.open(name=lunNamePrefix + '_1')
        LOG.info('Old LUN name:', lunNamePrefix + '_1')
        wizard.renameLUNPage.renameLUN(name=lunNewName)
        LOG.info('New LUN name:', lunNewName)

        LOG.step('Verifying LUN invalid name error message')
        wizard.activePage.lblNameError.waitUntilVisible()
        LOG.info('Error message:', wizard.activePage.lblNameError.getText())

    def test_dialog_cancel(self):
        """
            Verify LUN name remains intact on dialog cancel.
        """
        LOG.step('Creating LUNs')
        lunCount = 3
        lunSize = '1g'
        lunNamePrefix = 'LuN'
        lunNewName = 'NewName'
        self.luns.create(count=lunCount, size=lunSize, prefix=lunNamePrefix)
        LOG.info('LUNs created:\n', self.node.lun.show(json=True))

        self.lunsPage.btnRefresh.click()
        self.lunsPage.btnRefresh.waitUntilEnabled()

        LOG.step('Assigning new LUN name in dialog')
        wizard = RenameLUNWizard(driver=self.driver)
        wizard.open(name=lunNamePrefix + '_1')
        LOG.info('Old LUN name:', lunNamePrefix + '_1')
        wizard.renameLUNPage.renameLUN(name=lunNewName)
        LOG.info('New LUN name:', lunNewName)

        LOG.step('Canceling dialog without submission')
        wizard.cancel()
        LOG.info('Dialog cancelled.')

        LOG.step('Verifying LUN name has not been changed')
        luns = self.lunsPage.gridLUNs.find(name=lunNamePrefix + '_1')
        self.assertTrue(len(luns) == 1)
        self.assertTrue(luns[0]['name'] == lunNamePrefix + '_1')
        LOG.info('LUNs with old name:\n', luns)
        luns = self.lunsPage.gridLUNs.find(name=lunNewName)
        self.assertTrue(len(luns) == 0)
        LOG.info('LUNs with new name:\n', luns)

    def testTeardown(self):
        self.driver.close()
        luns = express.Luns(node=self.marscluster, cleanup=True)
        del luns
        LOG.info('LUNs destroyed.')

    def suiteTeardown(self):
        LOG.step('Closing browser')
        self.driver.quit()
Esempio n. 24
0
class TestCreateLUNsWizard(FRTestCase):
    def suiteSetup(self):
        self.username = ARGS.values.username
        self.password = ARGS.values.password
        self.locale = ARGS.values.locale
        self.timeout = ARGS.values.timeout
        self.webUIHostName = getFQDN(self.marscluster.getMasterNode().hostname)

    def testSetup(self):
        self.driver = self.getDriver()
        self.driver.timeout = self.timeout
        self.loginPage = LoginPage(driver=self.driver, url=self.webUIHostName)
        self.headerPage = HeaderPage(driver=self.driver)
        self.allStoragePage = AllStoragePage(driver=self.driver)
        self.lunsPage = LUNsPage(driver=self.driver)

        LOG.info('Destroying existing LUNs...')
        self.marscluster.lun.unmapAll()
        self.marscluster.lun.destroyAll()
        self.assertFalse(self.marscluster.lun.show(json=True))
        LOG.info('Done.')
        LOG.info('Destroying existing initiator groups...')
        self.marscluster.igroup.destroyAll()
        LOG.info('Done.')
        LOG.info('Destroying existing consistency groups...')
        self.deleteDependentConsistencyGroups()
        LOG.info('Done.')

        if self.locale is None:
            self.locale = self.loginPage.getRandomLocale()
        self.loginPage.signIn(username=self.username,
                              password=self.password,
                              locale=self.locale)

    def test_single_lun_invalid_name(self):
        """
            Test verifies inability of creation of single LUN with invalid name.
        """
        name = 'LuN:$1001'
        numberOfLUNs = '1'
        size = '3g'

        LOG.step('Creating wizard')
        wizard = CreateLUNsWizard(driver=self.driver, locale=self.locale)

        LOG.step('Opening front page of dialog')
        wizard.open()
        self.assertTrue(wizard.defineLUNsPage.isOpen())
        LOG.info('Front page is open:', wizard.defineLUNsPage.isOpen())

        LOG.step("Calling method: defineSingleLUN(name='%s', size='%s')" %
                 (name, size))
        wizard.activePage.defineSingleLUN(name=name, size=size)

        LOG.step('Verifying error message as name is invalid')
        self.assertTrue(wizard.activePage.lblNameError.isPresent())
        LOG.info('Error message is present:',
                 wizard.activePage.lblNameError.isPresent())
        wizard.activePage.lblNameError.isVisible()
        LOG.info('Error message is visible:',
                 wizard.activePage.lblNameError.isVisible())
        LOG.info('Error message:', wizard.activePage.lblNameError.isPresent())

        LOG.step("Verifying button 'Next' is disabled.")
        self.assertFalse(wizard.activePage.btnNext.isEnabled())
        LOG.info("Button 'Next' is enabled:",
                 wizard.activePage.btnNext.isEnabled())

        LOG.step("Closing the dialog by clicking button 'Cancel'")
        wizard.activePage.btnCancel.click()

        LOG.step("Verifying the dialog has been closed")
        self.assertFalse(wizard.activePage.isOpen())
        LOG.info('Front page is open:', wizard.activePage.isOpen())

    def test_single_lun_max_length_name(self):
        """
            Test verifies creation of single LUNs with maximum length of name (255).
        """
        name = 'LuN__' + ('0' * 250)
        size = '3g'

        LOG.step('Creating wizard')
        wizard = CreateLUNsWizard(driver=self.driver, locale=self.locale)

        LOG.step('Opening front page of dialog')
        wizard.open()
        self.assertTrue(wizard.defineLUNsPage.isOpen())
        LOG.info('Front page is open:', wizard.defineLUNsPage.isOpen())

        LOG.step("Calling method: defineSingleLUN(name='%s', size='%s')" %
                 (name, size))
        wizard.activePage.defineSingleLUN(name=name, size=size)

        LOG.step('Verifying no name error message present on page.')
        self.assertFalse(wizard.activePage.lblNameError.isPresent())
        LOG.info('Name error message is present:',
                 wizard.activePage.lblNameError.isPresent())

        LOG.step('Finishing wizard')
        wizard.goNext()
        wizard.selectInitiatorGroupsPage.waitUntilOpen()
        LOG.info('Proceeded to page', wizard.selectInitiatorGroupsPage.name)
        wizard.goNext()
        wizard.confirmPage.waitUntilOpen()
        LOG.info('Proceeded to page', wizard.confirmPage.name)
        wizard.goNext()
        wizard.closePage.waitUntilOpen()
        LOG.info('Proceeded to page', wizard.closePage.name)
        wizard.closePage.close()
        wizard.closePage.waitUntilClosed()
        LOG.info('Wizard closed.')

        LOG.step('Verifying created LUNs have provided name')
        self.assertTrue(
            self.marscluster.lun.show(json=True)[0]['name'] == name)
        LOG.info('LUN name:', self.marscluster.lun.show(json=True)[0]['name'])

    def test_single_lun_terminal_size(self):
        """
            Test verifies creation of single LUN with minimum and maximum sizes respecting given size unit.
        """
        sizes = {
            'B': {
                'low': 512,
                'high': long(64) * pow(1024, 4),
                'multiplier': 1
            },
            'K': {
                'low': 0.5,
                'high': long(64) * pow(1024, 3),
                'multiplier': 1024
            },
            'M': {
                'low': 0.001,
                'high': long(64) * pow(1024, 2),
                'multiplier': 1024**2
            },
            'G': {
                'low': 0.001,
                'high': long(64) * 1024,
                'multiplier': 1024**3
            },
            'T': {
                'low': 0.001,
                'high': 64,
                'multiplier': 1024**4
            }
        }
        lunsToCreate = {}

        for sizeUnit in sizes:
            nameLow = 'LuN_' + sizeUnit + '_low'
            sizeLow = str(sizes[sizeUnit]['low']) + sizeUnit
            nameHigh = 'LuN_' + sizeUnit + '_high'
            sizeHigh = str(sizes[sizeUnit]['high']) + sizeUnit

            LOG.step('Creating wizard')
            wizard = CreateLUNsWizard(driver=self.driver, locale=self.locale)
            wizard.open()
            self.assertTrue(wizard.defineLUNsPage.isOpen())
            LOG.info('Wizard created.')

            LOG.step("Creating LUN with minimal size: name='%s', size='%s')" %
                     (nameLow, sizeLow))
            wizard.activePage.defineSingleLUN(name=nameLow, size=sizeLow)
            wizard.goNext()
            wizard.goNext()
            wizard.goNext()
            wizard.closePage.close()
            LOG.info('Wizard closed.')

            sizeToCreate = sizes[sizeUnit]['low'] * sizes[sizeUnit][
                'multiplier']
            # Sizes of LUNs are rounded up to 512-byte bound
            if sizeToCreate % 512 > 0:
                sizeToCreate = int(sizeToCreate / 512) * 512 + 512
            lunsToCreate[nameLow] = sizeToCreate

            LOG.step('Creating wizard')
            wizard = CreateLUNsWizard(driver=self.driver, locale=self.locale)
            wizard.open()
            self.assertTrue(wizard.defineLUNsPage.isOpen())
            LOG.info('Wizard created.')

            LOG.step("Creating LUN with minimal size: name='%s', size='%s')" %
                     (nameHigh, sizeHigh))
            wizard.activePage.defineSingleLUN(name=nameHigh, size=sizeHigh)
            wizard.goNext()
            wizard.goNext()
            wizard.goNext()
            wizard.closePage.close()
            LOG.info('Wizard closed.')

            lunsToCreate[nameHigh] = sizes[sizeUnit]['high'] * sizes[sizeUnit][
                'multiplier']

            createdLUNs = self.marscluster.lun.show(json=True)
            self.assertTrue(len(createdLUNs) == 2)

            LOG.step('Verifying size of created LUNs is as specified')
            for lun in createdLUNs:
                self.assertTrue(lun['size'] == lunsToCreate[lun['name']])
                LOG.info("Size of LUN '%s' (bytes): %s" %
                         (lun['name'], lun['size']))

            LOG.step('Destroying LUNs')
            self.marscluster.lun.destroyAll()
            self.assertFalse(self.marscluster.lun.show(json=True))
            LOG.info('All LUNs destroyed.')

    def test_single_lun_map_new_parent_cg(self):
        """
            Test verifies creation of single LUN mapped to newly created parent consistency group.
        """
        lunName = 'LuN'
        consistencyGroupName = 'New-CG'

        LOG.step('Creating wizard')
        wizard = CreateLUNsWizard(driver=self.driver, locale=self.locale)
        wizard.open()
        LOG.info('Wizard created.')

        LOG.step('Defining single LUN')
        wizard.activePage.defineSingleLUN(name=lunName, size='1G')
        wizard.activePage.addToConsistencyGroup(
            newConsistencyGroup=consistencyGroupName)
        LOG.step("Navigating to 'Select Initiator Groups' page")
        wizard.goNext()
        wizard.selectInitiatorGroupsPage.waitUntilOpen()
        LOG.info("Browser landed on 'Select Initiator Groups' page")

        LOG.step("Navigating to 'Confirm' page")
        wizard.goNext()
        wizard.confirmPage.waitUntilOpen()
        LOG.info("Browser landed on 'Confirm' page")

        LOG.step('Navigating back to front page')
        wizard.goBack()
        wizard.activePage.waitUntilOpen()
        wizard.goBack()
        wizard.activePage.waitUntilOpen()
        LOG.info("Browser landed on 'Define LUNs' page")

        LOG.step('Verifying LUN definitions')
        self.assertTrue(wizard.activePage.dLstNumberOfLUNs.getText() == '1')
        LOG.info('Number of LUNs:',
                 wizard.activePage.dLstNumberOfLUNs.getText())
        self.assertTrue(wizard.activePage.txtName.getText() == lunName)
        LOG.info('LUN name:', wizard.activePage.txtName.getText())
        self.assertTrue(wizard.activePage.txtSize.getText() == '1')
        LOG.info('LUN size:', wizard.activePage.txtSize.getText())
        self.assertTrue(
            wizard.activePage.chkAddToConsistencyGroup.isSelected())
        LOG.info('Add to consistency group:',
                 wizard.activePage.chkAddToConsistencyGroup.isSelected())
        self.assertTrue(wizard.activePage.txtNewConsistencyGroup.getText() ==
                        consistencyGroupName)
        LOG.info('Consistency group name:',
                 wizard.activePage.txtNewConsistencyGroup.getText())

        LOG.step('Navigating to confirmation page')
        wizard.goNext()
        wizard.activePage.waitUntilOpen()
        wizard.goNext()
        wizard.confirmPage.waitUntilOpen()
        LOG.info('Browser landed on confirmation page')

        LOG.step('Verifying LUNs to create')
        luns = wizard.activePage.gridLUNs.find()
        self.assertTrue(len(luns) == 1)
        self.assertTrue(luns[0]['name'] == lunName)
        LOG.info('LUNs to create:\n', luns)

        LOG.step("Navigating to 'Close' page")
        wizard.goNext()
        wizard.closePage.waitUntilOpen()
        LOG.info("Browser landed on 'Close' page")

        wizard.closePage.close()
        LOG.info('Wizard closed.')

        LOG.step(
            'Verifying LUN has been created and mapped to consistency group')
        lun = self.marscluster.lun.show(json=True)[0]
        self.assertTrue(lunName in lun['name'])
        self.assertTrue(lun['cg'] == consistencyGroupName)
        LOG.info('LUN name: %s; consistency group: %s' %
                 (lun['name'], lun['cg']))

    def test_single_lun_map_exist_parent_cg(self):
        """
            Test verifies creation of single LUN mapped to existing parent consistency group.
        """
        lunName = 'LuN'
        parentConsistencyGroupName = 'Parent-CG'

        LOG.step('Creating consistency group')
        self.marscluster.cg.create(name=parentConsistencyGroupName)
        consistencyGroups = self.marscluster.cg.show(json=True)
        self.assertTrue(len(consistencyGroups) == 1)
        self.assertTrue(
            consistencyGroups[0]['name'] == parentConsistencyGroupName)
        LOG.info('Consistency group created:', parentConsistencyGroupName)

        LOG.step('Creating wizard')
        wizard = CreateLUNsWizard(driver=self.driver, locale=self.locale)
        wizard.open()
        LOG.info('Wizard created.')

        LOG.step('Defining single LUN')
        wizard.activePage.defineSingleLUN(name=lunName, size='1G')
        wizard.activePage.addToConsistencyGroup(
            parentConsistencyGroup=parentConsistencyGroupName)
        wizard.goNext()
        wizard.goNext()
        wizard.goNext()
        wizard.closePage.close()
        LOG.info('Wizard closed.')

        LOG.step(
            'Verifying LUN has been created and mapped to existing consistency group'
        )
        lun = self.marscluster.lun.show(json=True)[0]
        self.assertTrue(lunName in lun['name'])
        self.assertTrue(lun['cg'] == parentConsistencyGroupName)
        LOG.info('LUN name: %s; consistency group: %s' %
                 (lun['name'], lun['cg']))

    def test_single_lun_map_exist_new_parent_cg(self):
        """
            Test verifies creation of single LUN mapped to existing parent and new consistency groups.
        """
        lunName = 'LuN'
        parentConsistencyGroupName = 'Parent-CG'
        newConsistencyGroupName = 'New-CG'

        LOG.step('Creating consistency group')
        self.marscluster.cg.create(name=parentConsistencyGroupName)
        consistencyGroups = self.marscluster.cg.show(json=True)
        self.assertTrue(len(consistencyGroups) == 1)
        self.assertTrue(
            consistencyGroups[0]['name'] == parentConsistencyGroupName)
        LOG.info('Consistency group created:', parentConsistencyGroupName)

        LOG.step('Creating wizard')
        wizard = CreateLUNsWizard(driver=self.driver, locale=self.locale)
        wizard.open()
        LOG.info('Wizard created.')

        LOG.step('Defining single LUN')
        wizard.activePage.defineSingleLUN(name=lunName, size='1G')
        wizard.activePage.addToConsistencyGroup(
            parentConsistencyGroup=parentConsistencyGroupName,
            newConsistencyGroup=newConsistencyGroupName)
        wizard.goNext()
        wizard.goNext()
        wizard.goNext()
        wizard.closePage.close()
        LOG.info('Wizard closed.')

        LOG.step('Verifying mapped LUN has been created')
        luns = self.marscluster.lun.show(json=True)
        self.assertTrue(len(luns) == 1)
        self.assertTrue(luns[0]['name'] == (parentConsistencyGroupName + '/' +
                                            newConsistencyGroupName + '/' +
                                            lunName))
        self.assertTrue(luns[0]['cg'] == (parentConsistencyGroupName + '/' +
                                          newConsistencyGroupName))
        LOG.info("LUN created: 'name': '%s'; 'cg': '%s'" %
                 (luns[0]['name'], luns[0]['cg']))
        mappingFound = False
        for consistencyGroup in self.marscluster.cg.show(json=True):
            if consistencyGroup['name'] == luns[0]['cg']:
                mappingFound = True
        self.assertTrue(mappingFound)
        LOG.info('Mapped consistency group found.')

    def test_single_lun_map_single_ig(self):
        """
            Test verifies creation of single LUN mapped to single initiator group with single WWPN.
        """
        lunName = 'LuN'
        lunSize = '1G'
        initiatorGroupName = 'IG-1'

        LOG.step('Creating initiator group')
        wwpn = self.marscluster.fcp.initiator_show(json=True)[0]['wwpn']
        self.marscluster.igroup.create(name=initiatorGroupName,
                                       ostype='vmware',
                                       initiators=wwpn)
        initiatorGroups = self.marscluster.igroup.show(json=True)
        self.assertTrue(len(initiatorGroups) == 1)
        self.assertTrue((initiatorGroups[0]['name'] == initiatorGroupName)
                        and (initiatorGroups[0]['initiators'][0] == wwpn))
        LOG.info(
            "Initiator group created: name: '%s'; initiators: '%s'" %
            (initiatorGroups[0]['name'], initiatorGroups[0]['initiators']))

        LOG.step('Creating wizard')
        wizard = CreateLUNsWizard(driver=self.driver, locale=self.locale)
        wizard.open()
        LOG.info('Wizard created.')

        LOG.step('Defining single LUN')
        wizard.activePage.defineSingleLUN(name=lunName, size=lunSize)
        LOG.info("Properties defined: name: '%s'; size: '%s'" %
                 (lunName, lunSize))
        wizard.goNext()
        wizard.selectInitiatorGroupsPage.selectInitiatorGroups(
            initiatorGroups=initiatorGroupName)
        LOG.info("Initiator groups selected: '%s'" % initiatorGroupName)
        wizard.goNext()
        wizard.goNext()
        wizard.closePage.close()
        LOG.info('Wizard closed.')

        LOG.step(
            'Verifying LUN has been created and mapped to initiator group')
        luns = self.marscluster.lun.show(json=True)
        self.assertTrue(len(luns) == 1)
        self.assertTrue(luns[0]['name'] == lunName)
        self.assertTrue(
            luns[0]['maps'][0]['igroup-name'] == initiatorGroupName)
        self.assertTrue(luns[0]['maps'][0]['lun-name'] == lunName)
        self.assertTrue(luns[0]['igroups'][0] == initiatorGroupName)
        LOG.info("LUN created: name: '%s'; igroup-name: '%s'" %
                 (lunName, initiatorGroupName))

    def test_single_lun_map_multi_ig_different_wwpn(self):
        """
            Test verifies creation of single LUN mapped to multiple initiator groups with different
              WWPNs (one initiator per group).
        """
        lunName = 'LuN'
        lunSize = '1G'
        initiatorGroupName = 'IG-'
        initiatorGroupsNumber = 5
        initiatorGroupNames = []

        LOG.step('Creating initiator groups')
        for initiatorIndex in range(initiatorGroupsNumber):
            fictiveWWPN = format(random.randrange(sys.maxint),
                                 'x').rjust(16, 'f')
            self.marscluster.igroup.create(name=(initiatorGroupName +
                                                 str(initiatorIndex)),
                                           ostype='vmware',
                                           initiators=fictiveWWPN)
            initiatorGroupNames.append(initiatorGroupName +
                                       str(initiatorIndex))
        initiatorGroups = self.marscluster.igroup.show(json=True)
        self.assertTrue(len(initiatorGroups) == initiatorGroupsNumber)
        # Verify all created IGs are in list of IGs were to be created
        for initiatorGroupIndex in range(len(initiatorGroups)):
            del initiatorGroupNames[initiatorGroupNames.index(
                initiatorGroups[initiatorGroupIndex]['name'])]
        self.assertFalse(initiatorGroupNames)
        LOG.info('Initiator groups created:\n', initiatorGroups)

        LOG.step('Creating wizard')
        wizard = CreateLUNsWizard(driver=self.driver, locale=self.locale)
        wizard.open()
        LOG.info('Wizard created.')

        LOG.step('Defining single LUN')
        wizard.activePage.defineSingleLUN(name=lunName, size=lunSize)
        LOG.info("LUN properties defined: name: '%s'; size: '%s'" %
                 (lunName, lunSize))
        wizard.goNext()
        # Select all created IGs
        initiatorGroupNames = [
            initiatorGroup['name'] for initiatorGroup in initiatorGroups
        ]
        wizard.selectInitiatorGroupsPage.selectInitiatorGroups(
            initiatorGroups=initiatorGroupNames)
        LOG.info('Initiator groups selected:\n', initiatorGroupNames)
        wizard.goNext()
        wizard.goNext()
        wizard.closePage.close()
        LOG.info('Wizard closed.')

        LOG.step(
            'Verifying LUN has been created and mapped to initiator groups')
        initiatorGroups = self.marscluster.igroup.show(json=True)
        for initiatorGroup in initiatorGroups:
            self.assertTrue(
                initiatorGroup['lun-maps'][0]['lun-name'] == lunName)
        luns = self.marscluster.lun.show(json=True)
        self.assertTrue(len(luns) == 1)
        for initiatorGroupName in [
                initiatorGroup['name'] for initiatorGroup in initiatorGroups
        ]:
            self.assertTrue(initiatorGroupName in luns[0]['igroups'])
        LOG.info("LUN created: name: '%s'; lun-maps:\n'%s'" %
                 (lunName, luns[0]['igroups']))

    def test_multi_lun_auto_start_low(self):
        """
            Test verifies creation of multiple LUNs with values of 'Start At' shorter than suffix (ex. 2 digits in
            'start at' = 55 is shorter than 4 pounds in suffix '####') are justified to number of pounds (i.e. prefix
            'LuN_' and 'start at' 55' gets translated to 'LuN_0055').
        """
        numberOfLUNs = 10
        lunNamePrefix = 'LuN_'
        lunSize = '1G'
        startAt = 99

        for suffixIndex in range(4):
            suffix = '#' * (suffixIndex + 1)
            LOG.step("Creating LUNs with suffix '%s' and starting at %s" %
                     (suffix, str(startAt)))
            LOG.step('Creating wizard')
            wizard = CreateLUNsWizard(driver=self.driver, locale=self.locale)
            wizard.open()
            LOG.info('Wizard created.')

            LOG.step('Defining multiple LUNs')
            wizard.activePage.defineMultipleLUNsAuto(number=numberOfLUNs,
                                                     size=lunSize,
                                                     prefix=lunNamePrefix,
                                                     suffix=(suffix + ' '),
                                                     startAt=startAt)
            LOG.info(
                "LUN properties defined: number: %s; size: %s, prefix: '%s'; suffix: '%s'; start at: %s"
                % (numberOfLUNs, lunSize, lunNamePrefix,
                   (suffix + ' '), startAt))
            wizard.goNext()
            wizard.goNext()
            wizard.goNext()
            wizard.closePage.close()
            LOG.info('Wizard closed.')

            LOG.step('Verifying LUN names')
            lunNames = [
                lun['name'] for lun in self.marscluster.lun.show(json=True)
            ]
            for lunIndex in range(startAt, (startAt + numberOfLUNs)):
                lunName = lunNamePrefix + str(lunIndex).rjust(
                    suffixIndex + 1, '0')
                self.assertTrue(lunName in lunNames)
                LOG.info('LUN found:', lunName)

            LOG.step('Destroying LUNs')
            self.marscluster.lun.destroyAll()
            self.assertFalse(self.marscluster.lun.show(json=True))
            LOG.info('All LUNs destroyed.')

    def test_multi_lun_auto_start_high(self):
        """
            Test verifies creation of multiple LUNs with values of 'Start At' longer than suffix (ex. 5 digits in
            'start at' = 55555 is longer than 4 pounds in suffix '####') are not truncated to number of pounds (i.e.
            'LuN_55555' is not becoming 'LuN_5555').
        """
        numberOfLUNs = 10
        lunNamePrefix = 'LuN_'
        lunSize = '1G'
        startAt = 55555

        for suffixIndex in range(4):
            suffix = '#' * (suffixIndex + 1)
            LOG.step("Creating LUNs with suffix '%s' and starting at %s" %
                     (suffix, str(startAt)))
            LOG.step('Creating wizard')
            wizard = CreateLUNsWizard(driver=self.driver, locale=self.locale)
            wizard.open()
            LOG.info('Wizard created.')

            LOG.step('Defining multiple LUNs')
            wizard.activePage.defineMultipleLUNsAuto(number=numberOfLUNs,
                                                     size=lunSize,
                                                     prefix=lunNamePrefix,
                                                     suffix=(suffix + ' '),
                                                     startAt=startAt)
            LOG.info(
                "LUN properties defined: number: %s; size: %s, prefix: '%s'; suffix: '%s'; start at: %s"
                % (numberOfLUNs, lunSize, lunNamePrefix,
                   (suffix + ' '), startAt))
            wizard.goNext()
            wizard.goNext()
            wizard.goNext()
            wizard.closePage.close()
            LOG.info('Wizard closed.')

            LOG.step('Verifying LUN names')
            lunNames = [
                lun['name'] for lun in self.marscluster.lun.show(json=True)
            ]
            for lunIndex in range(startAt, (startAt + numberOfLUNs)):
                self.assertTrue((lunNamePrefix + str(lunIndex)) in lunNames)
                LOG.info('LUN found:', lunNamePrefix + str(lunIndex))

            LOG.step('Destroying LUNs')
            self.marscluster.lun.destroyAll()
            self.assertFalse(self.marscluster.lun.show(json=True))
            LOG.info('All LUNs destroyed.')

    def test_multi_lun_terminal_size(self):
        """
            Test verifies creation of multiple LUNs with minimum and maximum sizes respecting given size unit.
        """
        # Could be increased with bigger capacity storage. Now is supports 2 LUNs at 64 TB.
        sizes = {
            'B': {
                'low': 512,
                'high': long(64) * pow(1024, 4),
                'multiplier': 1
            },
            'K': {
                'low': 0.5,
                'high': long(64) * pow(1024, 3),
                'multiplier': 1024
            },
            'M': {
                'low': 0.001,
                'high': long(64) * pow(1024, 2),
                'multiplier': 1024**2
            },
            'G': {
                'low': 0.001,
                'high': long(64) * 1024,
                'multiplier': 1024**3
            },
            'T': {
                'low': 0.001,
                'high': 64,
                'multiplier': 1024**4
            }
        }
        lunsToCreate = {}

        for sizeUnit in sizes:
            nameLow = 'LuN_' + sizeUnit + '_low'
            sizeLow = str(sizes[sizeUnit]['low']) + sizeUnit
            nameHigh = 'LuN_' + sizeUnit + '_high'
            sizeHigh = str(sizes[sizeUnit]['high']) + sizeUnit

            LOG.step('Creating wizard')
            wizard = CreateLUNsWizard(driver=self.driver, locale=self.locale)
            wizard.open()
            self.assertTrue(wizard.defineLUNsPage.isOpen())
            LOG.info('Wizard created.')

            LOG.step(
                "Creating 2 LUNs with minimal and maximal sizes: name=['%s', '%s'], size=['%s', '%s'])"
                % (nameLow, nameHigh, sizeLow, sizeHigh))
            lunsProperties = [{
                'name': nameLow,
                'size': sizeLow
            }, {
                'name': nameHigh,
                'size': sizeHigh
            }]
            wizard.activePage.defineMultipleLUNsManually(
                lunsProperties=lunsProperties)
            wizard.goNext()
            wizard.goNext()
            wizard.goNext()
            wizard.closePage.close()
            LOG.info('Wizard closed.')

            sizeToCreate = sizes[sizeUnit]['low'] * sizes[sizeUnit][
                'multiplier']
            # Sizes of LUNs are rounded up to 512-byte bound
            if sizeToCreate % 512 > 0:
                sizeToCreate = int(sizeToCreate / 512) * 512 + 512
            lunsToCreate[nameLow] = sizeToCreate

            lunsToCreate[nameHigh] = sizes[sizeUnit]['high'] * sizes[sizeUnit][
                'multiplier']

            createdLUNs = self.marscluster.lun.show(json=True)

            LOG.step('Verifying size of created LUNs is as specified')
            for lun in createdLUNs:
                self.assertTrue(lun['size'] == lunsToCreate[lun['name']])
                LOG.info("Size of LUN '%s' (bytes): %s" %
                         (lun['name'], lun['size']))

            LOG.step('Destroying LUNs')
            self.marscluster.lun.destroyAll()
            self.assertFalse(self.marscluster.lun.show(json=True))
            LOG.info('All LUNs destroyed.')

    def test_multi_lun_map_exist_new_parent_cg(self):
        """
            Test verifies creation of multiple LUNs mapped to existing parent and new consistency groups.
        """
        parentConsistencyGroupName = 'Parent-CG'
        newConsistencyGroupName = 'New-CG'
        lunsProperties = [{
            'name': 'LuN-1',
            'size': '1G'
        }, {
            'name': 'LuN-2',
            'size': '1G'
        }, {
            'name': 'LuN-3',
            'size': '1G'
        }, {
            'name': 'LuN-4',
            'size': '1G'
        }, {
            'name': 'LuN-5',
            'size': '1G'
        }, {
            'name': 'LuN-6',
            'size': '1G'
        }, {
            'name': 'LuN-7',
            'size': '1G'
        }, {
            'name': 'LuN-8',
            'size': '1G'
        }, {
            'name': 'LuN-9',
            'size': '1G'
        }, {
            'name': 'LuN-10',
            'size': '1G'
        }]

        LOG.step('Creating consistency group')
        self.marscluster.cg.create(name=parentConsistencyGroupName)
        consistencyGroups = self.marscluster.cg.show(json=True)
        self.assertTrue(len(consistencyGroups) == 1)
        self.assertTrue(
            consistencyGroups[0]['name'] == parentConsistencyGroupName)
        LOG.info('Consistency group created:', parentConsistencyGroupName)

        LOG.step('Creating wizard')
        wizard = CreateLUNsWizard(driver=self.driver, locale=self.locale)
        wizard.open()
        LOG.info('Wizard created.')

        LOG.step(
            'Creating %s LUNs mapped to existing parent and new consistency groups'
            % len(lunsProperties))
        wizard.activePage.defineMultipleLUNsManually(
            lunsProperties=lunsProperties)
        wizard.activePage.addToConsistencyGroup(
            parentConsistencyGroup=parentConsistencyGroupName,
            newConsistencyGroup=newConsistencyGroupName)
        wizard.goNext()
        wizard.goNext()
        wizard.goNext()
        wizard.closePage.close()
        LOG.info('Wizard closed.')

        LOG.step(
            'Verifying LUNs have been created and mapped to consistency groups'
        )
        lunNames = [lunProperties['name'] for lunProperties in lunsProperties]
        luns = self.marscluster.lun.show(json=True)
        for lun in luns:
            self.assertTrue(lun['name'].split('/')[-1] in lunNames)
            self.assertTrue(lun['cg'] == parentConsistencyGroupName + '/' +
                            newConsistencyGroupName)
            LOG.info("LUN found: name: '%s'; cg: '%s'" %
                     (lun['name'], lun['cg']))

    def test_multi_lun_map_multi_ig_different_wwpn(self):
        """
            Test verifies creation of multiple LUNs defined manually and mapped to multiple initiator groups with
            different WWPNs.
        """
        initiatorGroupName = 'IG-'
        initiatorGroupsNumber = 5
        initiatorGroupNames = []

        lunsProperties = [{
            'name': 'LuN-1',
            'size': '1G'
        }, {
            'name': 'LuN-2',
            'size': '1G'
        }, {
            'name': 'LuN-3',
            'size': '1G'
        }, {
            'name': 'LuN-4',
            'size': '1G'
        }, {
            'name': 'LuN-5',
            'size': '1G'
        }, {
            'name': 'LuN-6',
            'size': '1G'
        }, {
            'name': 'LuN-7',
            'size': '1G'
        }, {
            'name': 'LuN-8',
            'size': '1G'
        }, {
            'name': 'LuN-9',
            'size': '1G'
        }, {
            'name': 'LuN-10',
            'size': '1G'
        }]

        LOG.step('Creating initiator groups')
        for initiatorIndex in range(initiatorGroupsNumber):
            fictiveWWPN = format(random.randrange(sys.maxint),
                                 'x').rjust(16, 'f')
            self.marscluster.igroup.create(name=(initiatorGroupName +
                                                 str(initiatorIndex)),
                                           ostype='vmware',
                                           initiators=fictiveWWPN)
            initiatorGroupNames.append(initiatorGroupName +
                                       str(initiatorIndex))
        initiatorGroups = self.marscluster.igroup.show(json=True)
        self.assertTrue(len(initiatorGroups) == initiatorGroupsNumber)
        # Verify all created IGs are in list of IGs were to be created
        for initiatorGroupIndex in range(len(initiatorGroups)):
            del initiatorGroupNames[initiatorGroupNames.index(
                initiatorGroups[initiatorGroupIndex]['name'])]
        self.assertFalse(initiatorGroupNames)
        LOG.info('Initiator groups created:\n', initiatorGroups)

        LOG.step('Creating wizard')
        wizard = CreateLUNsWizard(driver=self.driver, locale=self.locale)
        wizard.open()
        LOG.info('Wizard created.')

        LOG.step(
            'Creating %s LUNs mapped to multiple initiator groups with different WWPNs'
            % len(lunsProperties))
        wizard.activePage.defineMultipleLUNsManually(
            lunsProperties=lunsProperties)
        LOG.info('LUNs properties defined:\n', lunsProperties)
        wizard.goNext()
        # Select all created IGs
        initiatorGroupNames = [
            initiatorGroup['name'] for initiatorGroup in initiatorGroups
        ]
        wizard.selectInitiatorGroupsPage.selectInitiatorGroups(
            initiatorGroups=initiatorGroupNames)
        LOG.info('Initiator groups selected:\n', initiatorGroupNames)
        wizard.goNext()
        wizard.goNext()
        # Give some time to complete operation
        time.sleep(2)
        wizard.closePage.close()
        LOG.info('Wizard closed.')

        LOG.step(
            'Verifying LUNs have been created and mapped to initiator groups')
        lunNames = [lunProperties['name'] for lunProperties in lunsProperties]
        luns = self.marscluster.lun.show(json=True)
        initiatorGroupNames = [
            initiatorGroup['name']
            for initiatorGroup in self.marscluster.igroup.show(json=True)
        ]
        for lun in luns:
            self.assertTrue(lun['name'] in lunNames)
            del lunNames[lunNames.index(lun['name'])]
            lunMapNames = [map['igroup-name'] for map in lun['maps']]
            for initiatorGroupName in initiatorGroupNames:
                self.assertTrue(initiatorGroupName in lunMapNames)
            LOG.info("LUN found: name: '%s''; maps:\n%s" %
                     (lun['name'], lunMapNames))

    def test_dialog_not_available(self):
        """
            Verify wizard cannot proceed (button 'Next' is disabled) when inputs are not fully
            populated.
        """
        lunName = 'LuN'
        lunSize = '10'
        LOG.step('Creating wizard')
        wizard = CreateLUNsWizard(driver=self.driver, locale=self.locale)
        wizard.open()
        LOG.info('Wizard created.')

        LOG.step('Verifying proceed is disabled')
        self.assertFalse(wizard.activePage.txtName.getText())
        LOG.info("Name: '%s'" % wizard.activePage.txtName.getText())
        self.assertFalse(wizard.activePage.txtSize.getText())
        LOG.info("Size: '%s'" % wizard.activePage.txtSize.getText())
        wizard.activePage.btnNext.waitUntilDisabled()
        LOG.info("Button 'Next' is enabled:",
                 wizard.activePage.btnNext.isEnabled())

        LOG.step('Setting only LUN name')
        wizard.activePage.txtName.setText(text=lunName)
        self.assertTrue(wizard.activePage.txtName.getText() == lunName)
        LOG.info('LUN name:', wizard.activePage.txtName.getText())
        LOG.info('LUN size:', wizard.activePage.txtSize.getText())
        wizard.activePage.btnNext.waitUntilDisabled()
        LOG.info("Button 'Next' is enabled:",
                 wizard.activePage.btnNext.isEnabled())

        LOG.step('Setting only LUN size')
        wizard.activePage.txtName.clear()
        wizard.activePage.txtSize.setText(text=lunSize)
        self.assertTrue(wizard.activePage.txtSize.getText() == lunSize)
        LOG.info('LUN name:', wizard.activePage.txtName.getText())
        LOG.info('LUN size:', wizard.activePage.txtSize.getText())
        wizard.activePage.btnNext.waitUntilDisabled()
        LOG.info("Button 'Next' is enabled:",
                 wizard.activePage.btnNext.isEnabled())

        LOG.step('Setting LUN name & size')
        wizard.activePage.txtName.setText(text=lunName)
        LOG.info('LUN name:', wizard.activePage.txtName.getText())
        LOG.info('LUN size:', wizard.activePage.txtSize.getText())
        wizard.activePage.btnNext.waitUntilEnabled()
        LOG.info("Button 'Next' is enabled:",
                 wizard.activePage.btnNext.isEnabled())

    def deleteDependentConsistencyGroups(self):
        while True:
            consistencyGroups = self.marscluster.cg.show(json=True)
            if not consistencyGroups:
                break
            else:
                for consistencyGroup in consistencyGroups:
                    if 'cg' not in consistencyGroup:
                        self.marscluster.cg.delete(
                            name=consistencyGroup['name'])

    def testTeardown(self):
        self.driver.quit()
        luns = express.Luns(node=self.marscluster, cleanup=True)
        del luns
        LOG.info('LUNs destroyed.')
class TestChangeInitiatorGroupOSTypeWizard(FRTestCase):
    def suiteSetup(self):
        self.username = ARGS.values.username
        self.password = ARGS.values.password
        self.locale = ARGS.values.locale
        self.webUIHostName = getFQDN(self.marscluster.getMasterNode().hostname)

    def testSetup(self):
        self.driver = self.getDriver()
        self.loginPage = LoginPage(driver=self.driver, url=self.webUIHostName)
        self.initiatorGroupsPage = InitiatorGroupsPage(driver=self.driver)

        LOG.info('Destroying existing LUNs...')
        self.marscluster.lun.unmapAll()
        self.marscluster.lun.destroyAll()
        self.assertFalse(self.marscluster.lun.show(json=True))
        LOG.info('Done.')
        LOG.info('Destroying existing initiator groups...')
        self.marscluster.igroup.destroyAll()
        LOG.info('Done.')

        self.luns = express.Luns(node=self.marscluster)

        LOG.step('Signing in')
        self.loginPage.open()
        self.loginPage.waitUntilOpen()
        if self.locale is None:
            self.locale = self.loginPage.getRandomLocale()
        self.loginPage.signIn(username=self.username, password=self.password, locale=self.locale)
        LOG.info('Signed in with username: %s, password: %s, locale: %s.' % (self.username,
            self.password, self.locale))
        LOG.info('Browser landed on header page.')

    def test_change_os_type(self):
        """
            Verify changing of OS type for initiator group.
        """
        initiatorGroupCount = 3
        initiatorGroupPrefix = 'IG'
        osTypes = ['Windows', 'Linux', 'VMware', 'Xen']

        initiatorGroups = self._createInitiatorGroups(prefix=initiatorGroupPrefix,
            number=initiatorGroupCount)
        initiatorGroupName = initiatorGroups[0]

        LOG.step('Changing OS type of initiator group in dialog')
        wizard = ChangeInitiatorGroupOSTypeWizard(driver=self.driver)
        for osType in osTypes:
            LOG.step('Opening dialog')
            wizard.open(initiator_groups=initiatorGroupName)
            LOG.info('Dialog open for initiator group:', initiatorGroupName)

            LOG.step('Setting OS type: %s' % osType)
            wizard.activePage.setOSType(osType=osType)
            wizard.submit()
            LOG.info('OS type set and dialog submitted')

            LOG.step('Verifying OS type has been changed')
            initiatorGroup = [initiatorGroup for initiatorGroup in
                self.marscluster.igroup.show(json=True) if initiatorGroup['name'] ==
                initiatorGroupName][0]
            self.assertTrue(initiatorGroup['ostype'] == osType.lower())
            LOG.info('OS type has been changed to:', initiatorGroup['ostype'])

    def test_change_os_type_related_groups(self):
        """
            Verify dialog window 'Change related initiator groups' pops up when user change OS type
              for one of related (having same WWPN and OS type) initiator groups.
        """
        initiatorGroupCount = 3
        initiatorGroupPrefix = 'IG_'
        originalOSType = 'Windows'
        newOSType = 'Xen'

        LOG.step('Creating multiple related initiator groups')
        wwpn = format(random.randrange(sys.maxint), 'x').rjust(16, 'f')
        for count in range(initiatorGroupCount):
            self.marscluster.igroup.create(name=initiatorGroupPrefix + str(count),
                ostype=originalOSType, initiators=wwpn)
        initiatorGroups = self.marscluster.igroup.show(json=True)
        self.assertTrue(len(initiatorGroups) == initiatorGroupCount)
        initiatorGroupName = initiatorGroups[0]['name']
        LOG.info('Initiator groups created:\n', initiatorGroups)

        LOG.step('Opening dialog')
        wizard = ChangeInitiatorGroupOSTypeWizard(driver=self.driver)
        wizard.open(initiator_groups=initiatorGroupName)
        LOG.info('Dialog open for initiator group:', initiatorGroupName)

        LOG.step('Setting initiator group OS type to: %s' % newOSType)
        wizard.activePage.setOSType(osType=newOSType)
        wizard.submit()
        LOG.info('Dialog submitted.')

        LOG.step('Verifying related groups are listed on confirmation page')
        wizard.changeRelatedInitiatorGroupsPage.waitUntilOpen()
        listedGroupsNames = wizard.activePage.lblInitiatorGroups.getText()
        relatedGroupsNames = [groupName['name'] for groupName in initiatorGroups[1:]]
        for groupName in relatedGroupsNames:
            self.assertTrue(groupName in listedGroupsNames)
            LOG.info('Initiator group listed on page:', groupName)

        LOG.step('Submitting changes of related initiator groups')
        wizard.activePage.submit()
        LOG.info('Dialog closed.')

        LOG.step('Verifying related initiator groups have been changed')
        initiatorGroups = self.marscluster.igroup.show(json=True)
        for initiatorGroup in initiatorGroups:
            self.assertTrue(initiatorGroup['ostype'] == newOSType.lower())
            LOG.info("Initiator group '%s' has OS type: %s" % (initiatorGroup['name'],
                initiatorGroup['ostype']))

    def test_change_os_type_multiple_groups(self):
        """
            Verify OS type change for multiple initiator groups.
        """
        initiatorGroupCount = 10
        initiatorGroupPrefix = 'IG_'
        originalOSType = 'Windows'
        newOSType = 'Xen'

        LOG.step('Creating multiple related initiator groups')
        for count in range(initiatorGroupCount):
            wwpn = format(random.randrange(sys.maxint), 'x').rjust(16, 'f')
            self.marscluster.igroup.create(name=initiatorGroupPrefix + str(count),
                ostype=originalOSType, initiators=wwpn)
        initiatorGroups = self.marscluster.igroup.show(json=True)
        self.assertTrue(len(initiatorGroups) == initiatorGroupCount)
        initiatorGroupName = initiatorGroups[0]['name']
        LOG.info('Initiator groups created:\n', initiatorGroups)

        selectedGroupNames = [initiatorGroup['name'] for initiatorGroup in
            initiatorGroups[:initiatorGroupCount / 2]]
        LOG.step('Opening dialog')
        wizard = ChangeInitiatorGroupOSTypeWizard(driver=self.driver)
        wizard.open(initiator_groups=selectedGroupNames)
        LOG.info('Dialog open for initiator groups:', selectedGroupNames)

        LOG.step('Setting initiator group OS type to: %s' % newOSType)
        wizard.activePage.setOSType(osType=newOSType)
        wizard.submit()
        LOG.info('Dialog submitted.')

        LOG.step('Verifying OS type has been changed for selected initiator groups only')
        initiatorGroups = self.marscluster.igroup.show(json=True)
        for initiatorGroup in initiatorGroups:
            if initiatorGroup['name'] in selectedGroupNames:
                self.assertTrue(initiatorGroup['ostype'] == newOSType.lower())
            else:
                self.assertTrue(initiatorGroup['ostype'] == originalOSType.lower())
            LOG.info("Initiator group '%s' has OS type: %s" % (initiatorGroup['name'],
                initiatorGroup['ostype']))

    def test_change_os_type_multiple_related_groups(self):
        """
            Verify OS type change for multiple related initiator groups.
        """
        initiatorGroupCount = 10
        initiatorGroupPrefix = 'IG_'
        originalOSType = 'Windows'
        newOSType = 'Xen'

        LOG.step('Creating multiple related initiator groups')
        wwpn = format(random.randrange(sys.maxint), 'x').rjust(16, 'f')
        for count in range(initiatorGroupCount):
            self.marscluster.igroup.create(name=initiatorGroupPrefix + str(count),
                ostype=originalOSType, initiators=wwpn)
        initiatorGroups = self.marscluster.igroup.show(json=True)
        self.assertTrue(len(initiatorGroups) == initiatorGroupCount)
        initiatorGroupName = initiatorGroups[0]['name']
        LOG.info('Initiator groups created:\n', initiatorGroups)

        selectedGroupNames = [initiatorGroup['name'] for initiatorGroup in
            initiatorGroups[:initiatorGroupCount / 2]]
        LOG.step('Opening dialog')
        wizard = ChangeInitiatorGroupOSTypeWizard(driver=self.driver)
        wizard.open(initiator_groups=selectedGroupNames)
        LOG.info('Dialog open for initiator groups:', selectedGroupNames)

        LOG.step('Setting initiator group OS type to: %s' % newOSType)
        wizard.activePage.setOSType(osType=newOSType)
        wizard.submit()
        LOG.info('Dialog submitted.')

        LOG.step('Verifying related groups are listed on confirmation page')
        wizard.changeRelatedInitiatorGroupsPage.waitUntilOpen()
        listedGroupsNames = wizard.activePage.lblInitiatorGroups.getText()
        relatedGroupsNames = [groupName['name'] for groupName in initiatorGroups[initiatorGroupCount
            / 2:]]
        for groupName in relatedGroupsNames:
            self.assertTrue(groupName in listedGroupsNames)
            LOG.info('Initiator group listed on page:', groupName)

        LOG.step('Submitting changes of related initiator groups')
        wizard.activePage.submit()
        LOG.info('Dialog closed.')

        LOG.step('Verifying OS type has been changed for all related initiator groups')
        initiatorGroups = self.marscluster.igroup.show(json=True)
        for initiatorGroup in initiatorGroups:
            self.assertTrue(initiatorGroup['ostype'] == newOSType.lower())
            LOG.info("Initiator group '%s' has OS type: %s" % (initiatorGroup['name'],
                initiatorGroup['ostype']))

    def test_dialog_cancel(self):
        """
            Verify OS type of initiator group remains intact on dialog cancel.
        """
        initiatorGroupCount = 3
        initiatorGroupPrefix = 'IG'
        originalOStype = 'Windows'
        newOSType = 'Xen'

        LOG.step('Creating initiator groups')
        initiatorGroups = self._createInitiatorGroups(prefix=initiatorGroupPrefix,
            number=initiatorGroupCount, osType=originalOStype)
        LOG.info('Initiator groups created:', initiatorGroups)

        LOG.step('Opening dialog')
        wizard = ChangeInitiatorGroupOSTypeWizard(driver=self.driver)
        wizard.open(initiator_groups=initiatorGroups[0])
        LOG.info('Dialog open for initiator group:', initiatorGroups[0])

        LOG.step('Setting initiator group OS type to: %s' % newOSType)
        wizard.activePage.setOSType(osType=newOSType)
        self.assertTrue(wizard.activePage.dLstOSType.getText() == newOSType)
        LOG.info('OS type set to:', wizard.activePage.dLstOSType.getText())

        LOG.step('Canceling dialog without submission')
        wizard.cancel()
        LOG.info('Dialog closed.')

        LOG.step('Verifying initiator group OS type remains original')
        initiatorGroup = [group for group in self.marscluster.igroup.show(json=True) if
            group['name'] == initiatorGroups[0]][0]
        self.assertTrue(initiatorGroup['ostype'] == originalOStype.lower())
        LOG.info('Initiator froup OS type has not been changed:', initiatorGroup['ostype'])

    def _createInitiatorGroups(self, prefix, number, osType='vmware'):
        LOG.step('Creating initiator group(s)')
        for groupNumber in range(number):
            fictiveWWPN = format(random.randrange(sys.maxint), 'x').rjust(16, 'f')
            self.marscluster.igroup.create(name=prefix + '-' + str(groupNumber),
                ostype=osType.lower(), initiators=fictiveWWPN)
        groupNames = [group['name'] for group in self.marscluster.igroup.show(json=True)]
        LOG.info('Initiator group(s) created:', groupNames)
        return groupNames

    def testTeardown(self):
        self.driver.close()
        LOG.info('Driver closed.')

    def suiteTeardown(self):
        LOG.step('Quitting browser')
        self.driver.quit()
        luns = express.Luns(node=self.marscluster, cleanup=True)
        del luns
        self.marscluster.igroup.destroyAll()
        LOG.info('LUNs & initiator groups destroyed.')
Esempio n. 26
0
class TestCreateLUNsWizard(FRTestCase):
    def suiteSetup(self):
        self.username = ARGS.values.username
        self.password = ARGS.values.password
        self.webUIHostName = getFQDN(self.mars[0].hostname)

    def testSetup(self):
        self.driver = self.getDriver()
        self.loginPage = LoginPage(driver=self.driver, url=self.webUIHostName)
        self.headerPage = HeaderPage(driver=self.driver)
        self.allStoragePage = AllStoragePage(driver=self.driver)
        self.lunsPage = LUNsPage(driver=self.driver)

        self.loginPage.signIn(username=self.username, password=self.password)

    def test_wizard_create_luns_define_single_lun_no_input(self):
        title = 'Create LUNs'
        stepDescription = 'Step 1 of 2: Define LUN properties'
        numberOfLUNs = '1'
        namePlaceholder = 'Enter LUN Name'
        sizePlaceholder = 'Enter LUN Size'
        sizeUnit = 'GiB'
        consistencyGroupDescription = 'A consistency group allows you to back up and clone multiple LUNs as a group.'

        LOG.step('Creating wizard')
        wizard = CreateLUNsWizard(driver=self.driver)

        LOG.step('Opening front page of dialog')
        wizard.open()

        LOG.step('Verifying title of front page')
        self.assertTrue(wizard.activePage.lblTitle.getText() == title)
        LOG.info('Title:', wizard.activePage.lblTitle.getText())

        LOG.step('Verifying step description of front page')
        self.assertTrue(wizard.activePage.lblStepDescription.getText() == stepDescription)
        LOG.info('Step description:', wizard.activePage.lblStepDescription.getText())

        LOG.step('Verifying default number of LUNs')
        self.assertTrue(wizard.activePage.dLstNumberOfLUNs.getText() == numberOfLUNs)
        LOG.info('Number of LUNs:', wizard.activePage.dLstNumberOfLUNs.getText())

        LOG.step('Verifying default LUN name (blank)')
        self.assertTrue(wizard.activePage.txtName.getText() == '')
        self.assertTrue(wizard.activePage.txtName.getAttribute(attributeName='placeholder') ==
            namePlaceholder)
        LOG.info('LUN name:', "'", wizard.activePage.txtName.getText(), "'")
        LOG.info('LUN name placeholder:',
            wizard.activePage.txtName.getAttribute(attributeName='placeholder'))

        LOG.step('Verifying default LUN size (blank)')
        self.assertTrue(wizard.activePage.txtSize.getText() == '')
        self.assertTrue(wizard.activePage.txtSize.getAttribute(attributeName='placeholder') ==
            sizePlaceholder)
        LOG.info('LUN size:', "'", wizard.activePage.txtSize.getText(), "'")
        LOG.info('LUN size placeholder:',
            wizard.activePage.txtSize.getAttribute(attributeName='placeholder'))

        LOG.step('Verifying default LUN size unit')
        self.assertTrue(wizard.activePage.dLstSizeUnit.getText() == sizeUnit)
        LOG.info('LUN size unit:', wizard.activePage.dLstSizeUnit.getText())

        LOG.step("Verifying default state of check box 'Add to a consistency group'")
        self.assertFalse(wizard.activePage.chkAddToConsistencyGroup.isSelected())
        LOG.info('Check box is selected:', wizard.activePage.chkAddToConsistencyGroup.isSelected())

        LOG.step('Verifying consistency group description')
        self.assertTrue(wizard.activePage.lblConsistencyGroupDescription.getText() ==
        consistencyGroupDescription)
        LOG.info('Description:', wizard.activePage.lblConsistencyGroupDescription.getText())

        LOG.step("Verifying button 'Next' state")
        self.assertFalse(wizard.activePage.btnNext.isEnabled())
        LOG.info("Button 'Next' is enabled:", wizard.activePage.btnNext.isEnabled())

        LOG.step("Verifying button 'Cancel' state")
        self.assertTrue(wizard.activePage.btnCancel.isEnabled())
        LOG.info("Button 'Cancel' is enabled:", wizard.activePage.btnNext.isEnabled())

        LOG.step("Closing the dialog by clicking button 'Cancel'")
        wizard.activePage.btnCancel.click()

        LOG.step("Verifying the dialog has been closed")
        self.assertFalse(wizard.activePage.isOpen())
        LOG.info('Front page is open:', wizard.activePage.isOpen())

    def test_wizard_create_luns_define_single_lun_input_check(self):
        # TODO: File a bug 'This field is required' -> 'Name: This field is required'
        nameErrorBlank = 'This field is required'
        sizeErrorBlank = 'Size: This field is required'
        # TODO: File a bug error message has end point while other messages do not.
        sizeErrorLimit = 'Size: LUN size must be between 512 bytes and 64 TiB.'
        lowerInvalidBoundarySize = '511'
        lowerValidBoundarySize = '512'
        higherValidBoundarySize = pow(1024, 4) * 64
        higherInvalidBoundarySize = pow(1024, 4) * 64 + 1

        LOG.step('Creating wizard')
        wizard = CreateLUNsWizard(driver=self.driver)

        LOG.step('Opening front page of dialog')
        wizard.open()
        self.assertTrue(wizard.defineLUNsPage.isOpen())
        LOG.info('Wizard landed on front page.')

        LOG.step('Verifying no error messages on page by default.')
        self.assertFalse(wizard.activePage.lblNameError.isPresent() and wizard.activePage.lblNameError.isVisible())
        LOG.info('LUN name error message is not visible on page.')
        self.assertFalse(wizard.activePage.lblSizeError.isPresent() and wizard.activePage.lblSizeError.isVisible())
        LOG.info('LUN size error message is not visible on page.')

        LOG.step('Verifying error message on moving focus off LUN name text box')
        wizard.activePage.txtName.setFocus()
        wizard.activePage.txtSize.setFocus()
        wizard.activePage.lblNameError.waitUntilPresent()
        self.assertTrue(wizard.activePage.lblNameError.isVisible())
        LOG.info('LUN name error message is visible on page.')
        wizard.activePage.lblSizeError.waitUntilAbsent()
        LOG.info('LUN size error message is not visible on page.')

        LOG.step('Verifying error message on moving focus off LUN size text box')
        wizard.activePage.txtName.setFocus()
        wizard.activePage.lblNameError.waitUntilPresent()
        self.assertTrue(wizard.activePage.lblNameError.isVisible())
        LOG.info('LUN name error message is visible on page.')
        wizard.activePage.lblSizeError.waitUntilPresent()
        self.assertTrue(wizard.activePage.lblSizeError.isVisible())
        LOG.info('LUN size error message is visible on page.')

        LOG.step('Verifying LUN size error message on size not in between %s B and %s TiB' % (lowerValidBoundarySize,
        higherValidBoundarySize / pow(1024, 4)))
        wizard.activePage.dLstSizeUnit.select(item='B')
        wizard.activePage.txtSize.setText(text=lowerInvalidBoundarySize)
        wizard.activePage.lblSizeError.waitUntilPresent()
        wizard.activePage.lblSizeError.waitUntilText(text=sizeErrorLimit)
        LOG.info("Size: %s B: '%s'" % (lowerInvalidBoundarySize, wizard.activePage.lblSizeError.getText()))

        wizard.activePage.txtSize.clear()
        wizard.activePage.txtSize.setText(text=lowerValidBoundarySize)
        wizard.activePage.lblSizeError.waitUntilAbsent()
        LOG.info('Size: %s B: No error.' % lowerValidBoundarySize)

        wizard.activePage.txtSize.clear()
        wizard.activePage.txtSize.setText(text=higherValidBoundarySize)
        wizard.activePage.lblSizeError.waitUntilAbsent()
        LOG.info('Size: %s B: No error.' % higherValidBoundarySize)

        wizard.activePage.txtSize.clear()
        wizard.activePage.txtSize.setText(text=higherInvalidBoundarySize)
        wizard.activePage.lblSizeError.waitUntilPresent()
        self.assertTrue(wizard.activePage.lblSizeError.isVisible() and wizard.activePage.lblSizeError.getText() ==
        sizeErrorLimit)
        LOG.info("Size: %s B: '%s'" % (higherInvalidBoundarySize, wizard.activePage.lblSizeError.getText()))

        LOG.step("Closing the dialog by clicking button 'Cancel'")
        wizard.activePage.btnCancel.click()

        LOG.step("Verifying the dialog has been closed")
        self.assertFalse(wizard.activePage.isOpen())
        LOG.info('Front page is open:', wizard.activePage.isOpen())

    def test_wizard_create_luns_define_multiple_luns_auto_no_input(self):
        numberOfLUNs = '3'
        prefixPlaceholder = 'Enter Prefix'
        suffix = '## (01, 02, ...)'
        startAt = '1'
        # TODO: File a bug 'Enter size' -> 'Enter Size'
        sizePlaceholder = 'Enter size'
        sizeUnit = 'GiB'

        LOG.step('Creating wizard')
        wizard = CreateLUNsWizard(driver=self.driver)

        LOG.step('Opening front page of dialog')
        wizard.open()

        LOG.step('Selecting multiple LUNs')
        wizard.activePage.dLstNumberOfLUNs.select(item=numberOfLUNs)
        self.assertTrue(wizard.activePage.dLstNumberOfLUNs.getText() == str(numberOfLUNs))
        LOG.info('Number of LUNs:', wizard.activePage.dLstNumberOfLUNs.getText())

        LOG.step('Verifying LUN name and size auto-definition is selected by default')
        self.assertTrue(wizard.activePage.rBtnAutoNameAndSize.isSelected())
        LOG.info('LUN name and size auto-definition is selected:', wizard.activePage.rBtnAutoNameAndSize.isSelected())

        LOG.step('Verifying LUN name and size manual definition is unselected by default')
        self.assertFalse(wizard.activePage.rBtnManuallyNameAndSize.isSelected())
        LOG.info('LUN name and size manual definition is selected:',
        wizard.activePage.rBtnManuallyNameAndSize.isSelected())

        LOG.step('Verifying default LUN name prefix (blank)')
        self.assertTrue(wizard.activePage.txtPrefix.getText() == '')
        self.assertTrue(wizard.activePage.txtPrefix.getAttribute(attributeName='placeholder') ==
            prefixPlaceholder)
        LOG.info('LUN name prefix:', wizard.activePage.txtPrefix.getText())
        LOG.info('LUN name prefix placeholder:',
            wizard.activePage.txtPrefix.getAttribute(attributeName='placeholder'))

        LOG.step("Verifying default LUN name suffix ('%s')" % suffix)
        self.assertTrue(wizard.activePage.dLstSuffix.getText() == suffix)
        LOG.info('LUN name suffix:', wizard.activePage.dLstSuffix.getText())

        LOG.step('Verifying LUN name suffix start')
        self.assertTrue(wizard.activePage.txtStartAt.getText() == startAt)
        LOG.info('LUN name suffix starts at:', wizard.activePage.txtStartAt.getText())

        LOG.step('Verifying default LUN size (blank)')
        self.assertTrue(wizard.activePage.txtAutoSize.getText() == '')
        self.assertTrue(wizard.activePage.txtAutoSize.getAttribute(attributeName='placeholder') ==
            sizePlaceholder)
        LOG.info('LUN size:', "'", wizard.activePage.txtAutoSize.getText(), "'")
        LOG.info('LUN size placeholder:',
            wizard.activePage.txtAutoSize.getAttribute(attributeName='placeholder'))

        LOG.step("Verifying default LUN size unit ('%s')" % sizeUnit)
        self.assertTrue(wizard.activePage.dLstAutoSizeUnit.getText() == sizeUnit)
        LOG.info('LUN size unit:', wizard.activePage.dLstAutoSizeUnit.getText())

        LOG.step("Verifying button 'Next' state")
        self.assertFalse(wizard.activePage.btnNext.isEnabled())
        LOG.info("Button 'Next' is enabled:", wizard.activePage.btnNext.isEnabled())

        LOG.step("Verifying button 'Cancel' state")
        self.assertTrue(wizard.activePage.btnCancel.isEnabled())
        LOG.info("Button 'Cancel' is enabled:", wizard.activePage.btnNext.isEnabled())

        LOG.step("Closing the dialog by clicking button 'Cancel'")
        wizard.activePage.btnCancel.click()

        LOG.step("Verifying the dialog has been closed")
        self.assertFalse(wizard.activePage.isOpen())
        LOG.info('Front page is open:', wizard.activePage.isOpen())

    def test_wizard_create_luns_define_multiple_luns_auto_input_check(self):
        numberOfLUNs = '3'
        prefix = 'LUN'
        sizeErrorBlank = 'Size: This field is required'
        sizeErrorLimit = 'Size: LUN size must be between 512 bytes and 64 TiB.'
        lowerInvalidBoundarySize = '511'
        lowerValidBoundarySize = '512'
        higherValidBoundarySize = pow(1024, 4) * 64
        higherInvalidBoundarySize = pow(1024, 4) * 64 + 1
        # TODO: File a bug to remove space before colon
        defaultPreview = 'Preview : 01'
        customPrefix = 'LuN'
        customSuffix = '####'
        customStartAt = 50

        LOG.step('Creating wizard')
        wizard = CreateLUNsWizard(driver=self.driver)

        LOG.step('Opening front page of dialog')
        wizard.open()
        self.assertTrue(wizard.defineLUNsPage.isOpen())
        LOG.info('Wizard landed on LUN definition page.')

        LOG.step('Selecting multiple LUNs')
        wizard.activePage.dLstNumberOfLUNs.select(item=numberOfLUNs)
        self.assertTrue(wizard.activePage.dLstNumberOfLUNs.getText() == str(numberOfLUNs))
        LOG.info('Number of LUNs:', wizard.activePage.dLstNumberOfLUNs.getText())

        LOG.step('Selecting LUN name and size auto-definition')
        wizard.activePage.rBtnAutoNameAndSize.select()
        self.assertTrue(wizard.activePage.rBtnAutoNameAndSize.isSelected())
        LOG.info('LUN name and size auto-definition is selected:', wizard.activePage.rBtnAutoNameAndSize.isSelected())

        LOG.step('Verifying no LUN size error message by default')
        self.assertFalse(wizard.activePage.lblAutoSizeError.isPresent())
        LOG.info('LUN size error message is not visible.')

        LOG.step('Verifying LUN size error message show up on text box clearance')
        wizard.activePage.txtAutoSize.sendKeys('1')
        time.sleep(.5)
        wizard.activePage.txtAutoSize.sendKeys(Keys.BACK_SPACE)
        wizard.activePage.lblAutoSizeError.waitUntilPresent()
        wizard.activePage.lblAutoSizeError.waitUntilText(text=sizeErrorBlank)
        LOG.info('LUN size error message is visible.')

        LOG.step('Verifying LUN size error message on size not in between %s B and %s TiB' % (lowerValidBoundarySize,
        higherValidBoundarySize / pow(1024, 4)))
        wizard.activePage.dLstAutoSizeUnit.select(item='B')
        wizard.activePage.txtAutoSize.setText(text=lowerInvalidBoundarySize)
        wizard.activePage.lblAutoSizeError.waitUntilPresent()
        wizard.activePage.lblAutoSizeError.waitUntilText(text=sizeErrorLimit)
        LOG.info("Size: %s B: '%s'" % (lowerInvalidBoundarySize, wizard.activePage.lblAutoSizeError.getText()))

        wizard.activePage.txtAutoSize.clear()
        wizard.activePage.txtAutoSize.setText(text=lowerValidBoundarySize)
        wizard.activePage.lblAutoSizeError.waitUntilAbsent()
        LOG.info('Size: %s B: No error.' % lowerValidBoundarySize)

        wizard.activePage.txtAutoSize.clear()
        wizard.activePage.txtAutoSize.setText(text=higherValidBoundarySize)
        wizard.activePage.lblAutoSizeError.waitUntilAbsent()
        LOG.info('Size: %s B: No error.' % higherValidBoundarySize)

        wizard.activePage.txtAutoSize.clear()
        wizard.activePage.txtAutoSize.setText(text=higherInvalidBoundarySize)
        wizard.activePage.lblAutoSizeError.waitUntilPresent()
        LOG.info("Size: %s B: '%s'" % (wizard.activePage.txtAutoSize.getText(),
        wizard.activePage.lblAutoSizeError.getText()))
        self.assertTrue(wizard.activePage.lblAutoSizeError.isVisible() and
        wizard.activePage.lblAutoSizeError.getText() == sizeErrorLimit)
        LOG.info("Size: %s B: '%s'" % (higherInvalidBoundarySize, wizard.activePage.lblAutoSizeError.getText()))

        LOG.step('Verifying auto-name default preview')
        self.assertTrue(wizard.activePage.lblPreview.getText() == defaultPreview)
        LOG.info('Auto-name default preview:', wizard.activePage.lblPreview.getText())

        LOG.step('Verifying auto-name custom preview')
        wizard.activePage.txtPrefix.setText(text=customPrefix)
        LOG.info('Custom prefix:', customPrefix)
        wizard.activePage.dLstSuffix.select(item=customSuffix, exact=False)
        LOG.info('Custom suffix:', customSuffix)
        wizard.activePage.txtStartAt.clear()
        wizard.activePage.txtStartAt.setText(text=customStartAt)
        LOG.info('Custom number starts at:', customStartAt)
        customName = customPrefix + str(customStartAt).rjust(len(customSuffix), '0')
        wizard.activePage.lblPreview.waitUntilText(text=customName)
        self.assertTrue(wizard.activePage.lblPreview.getText() == ('Preview : ' + customName))
        LOG.info('Auto-name custom preview:', wizard.activePage.lblPreview.getText())

        LOG.step("Closing the dialog by clicking button 'Cancel'")
        wizard.activePage.btnCancel.click()

        LOG.step("Verifying the dialog has been closed")
        self.assertFalse(wizard.activePage.isOpen())
        LOG.info('Front page is open:', wizard.activePage.isOpen())

    def test_wizard_create_luns_define_multiple_luns_manually_no_input(self):
        numberOfLUNs = 2
        namePlaceholder = 'Enter LUN Name'
        sizePlaceholder = 'Enter LUN Size'

        LOG.step('Creating wizard')
        wizard = CreateLUNsWizard(driver=self.driver)

        LOG.step('Opening front page of dialog')
        wizard.open()
        self.assertTrue(wizard.defineLUNsPage.isOpen())
        LOG.info('Wizard landed on LUN definition page.')

        LOG.step('Selecting multiple LUNs')
        wizard.activePage.dLstNumberOfLUNs.select(item=str(numberOfLUNs))
        self.assertTrue(wizard.activePage.dLstNumberOfLUNs.getText() == str(numberOfLUNs))
        LOG.info('Number of LUNs:', wizard.activePage.dLstNumberOfLUNs.getText())

        LOG.step('Selecting LUN name and size manual definition')
        wizard.activePage.rBtnManuallyNameAndSize.select()

        LOG.step('Verifying LUN name and size default values')
        for lunIndex in range(1, numberOfLUNs + 1):
            LOG.info('LUN index:', lunIndex)

            txtName = textbox.TextBox(driver=self.driver,
            selector=wizard.activePage.selectors.txtManuallyName(index=lunIndex))
            self.assertFalse(txtName.getText())
            LOG.info("Name: '%s'" % txtName.getText())
            self.assertTrue(txtName.getAttribute(attributeName='placeholder') == namePlaceholder)
            LOG.info('Name placeholder:', txtName.getAttribute(attributeName='placeholder'))

            txtSize = textbox.TextBox(driver=self.driver,
            selector=wizard.activePage.selectors.txtManuallySize(index=lunIndex))
            self.assertFalse(txtSize.getText())
            LOG.info("Size: '%s'" % txtSize.getText())
            self.assertTrue(txtSize.getAttribute(attributeName='placeholder') == sizePlaceholder)
            LOG.info('Size placeholder:', txtSize.getAttribute(attributeName='placeholder'))

        LOG.step("Closing the dialog by clicking button 'Cancel'")
        wizard.activePage.btnCancel.click()

        LOG.step("Verifying the dialog has been closed")
        self.assertFalse(wizard.activePage.isOpen())
        LOG.info('Front page is open:', wizard.activePage.isOpen())

    def test_wizard_create_luns_define_multiple_luns_manually_input_check(self):
        numberOfLUNs = 2
        nameErrorBlank = 'This field is required'
        sizeErrorBlank = 'Size: This field is required'

        LOG.step('Creating wizard')
        wizard = CreateLUNsWizard(driver=self.driver)

        LOG.step('Opening front page of dialog')
        wizard.open()
        self.assertTrue(wizard.defineLUNsPage.isOpen())
        LOG.info('Wizard landed on LUN definition page.')

        LOG.step('Selecting multiple LUNs')
        wizard.activePage.dLstNumberOfLUNs.select(item=str(numberOfLUNs))
        self.assertTrue(wizard.activePage.dLstNumberOfLUNs.getText() == str(numberOfLUNs))
        LOG.info('Number of LUNs:', wizard.activePage.dLstNumberOfLUNs.getText())

        LOG.step('Selecting LUN name and size manual definition')
        wizard.activePage.rBtnManuallyNameAndSize.select()

        LOG.step('Verifying error messages on moving off LUN name and size text boxes')
        for lunIndex in range(1, numberOfLUNs + 1):
            LOG.info('LUN index:', lunIndex)

            lblNameError = label.Label(driver=self.driver,
            selector=wizard.activePage.selectors.lblManuallyNameError(index=lunIndex))
            lblSizeError = label.Label(driver=self.driver,
            selector=wizard.activePage.selectors.lblManuallySizeError(index=lunIndex))
            self.assertFalse(lblNameError.isPresent() and lblNameError.isVisible())
            LOG.info('LUN name error message is not visible.')
            self.assertFalse(lblSizeError.isPresent() and lblSizeError.isVisible())
            LOG.info('LUN size error message is not visible.')

            txtName = textbox.TextBox(driver=self.driver,
            selector=wizard.activePage.selectors.txtManuallyName(index=lunIndex))
            txtSize = textbox.TextBox(driver=self.driver,
            selector=wizard.activePage.selectors.txtManuallySize(index=lunIndex))

            txtName.setFocus()
            txtSize.setFocus()
            txtName.setFocus()

            LOG.info('Error messages triggered.')
            lblNameError.waitUntilText(text=nameErrorBlank)
            LOG.info('LUN name error message:', lblNameError.getText())
            lblSizeError.waitUntilText(text=sizeErrorBlank)
            LOG.info('LUN size error message:', lblSizeError.getText())

        LOG.step("Verifying button 'Next' is disabled when LUN properties undefined")
        self.assertFalse(wizard.activePage.btnNext.isEnabled())
        LOG.info("Button 'Cancel' is enabled:", wizard.activePage.btnNext.isEnabled())

        LOG.step('Verifying error messages disappear when LUN properties defined')
        for lunIndex in range(1, numberOfLUNs + 1):
            LOG.info('LUN index:', lunIndex)

            txtName = textbox.TextBox(driver=self.driver,
            selector=wizard.activePage.selectors.txtManuallyName(index=lunIndex))
            txtSize = textbox.TextBox(driver=self.driver,
            selector=wizard.activePage.selectors.txtManuallySize(index=lunIndex))

            txtName.setText(text=('LuN-' + str(lunIndex)))
            LOG.info('LUN name:', txtName.getText())
            txtSize.setText(text=lunIndex)
            LOG.info('LUN size:', txtSize.getText())

            lblNameError = label.Label(driver=self.driver,
            selector=wizard.activePage.selectors.lblManuallyNameError(index=lunIndex))
            lblSizeError = label.Label(driver=self.driver,
            selector=wizard.activePage.selectors.lblManuallySizeError(index=lunIndex))

            lblNameError.waitUntilAbsent()
            LOG.info('LUN name error message is not visible.')
            lblSizeError.waitUntilAbsent()
            LOG.info('LUN size error message is not visible.')

        LOG.step("Verifying button 'Next' is enabled")
        self.assertTrue(wizard.activePage.btnNext.isEnabled())
        LOG.info("Button 'Next' is enabled:", wizard.activePage.btnNext.isEnabled())

        LOG.step("Closing the dialog by clicking button 'Cancel'")
        wizard.activePage.btnCancel.click()

        LOG.step("Verifying the dialog has been closed")
        self.assertFalse(wizard.activePage.isOpen())
        LOG.info('Front page is open:', wizard.activePage.isOpen())

    def test_wizard_create_luns_define_single_lun_manually_add_to_consistency_group_no_input(self):
        lunName = 'LuN-1'
        lunSize = 1
        newConsistencyGroup = 'Enter consistency group name'
        consistencyGroupError = 'Select parent consistency group or enter new consistency group or provide both of them.'
        newConsistencyGroupName = 'CG-New'
        newConsistencyGroupConfirmation = 'New consistency group: '

        self.deleteConsistencyGroups()

        LOG.step('Creating wizard')
        wizard = CreateLUNsWizard(driver=self.driver)

        LOG.step('Opening front page of dialog')
        wizard.open()
        self.assertTrue(wizard.defineLUNsPage.isOpen())
        LOG.info('Wizard landed on LUN definition page.')

        LOG.step('Defining LUN properties')
        wizard.activePage.txtName.setText(text=lunName)
        LOG.info('LUN name:', wizard.activePage.txtName.getText())
        wizard.activePage.txtSize.setText(text=lunSize)
        LOG.info('LUN size:', wizard.activePage.txtSize.getText())

        LOG.step('Enabling CG mapping')
        wizard.activePage.chkAddToConsistencyGroup.select()
        self.assertTrue(wizard.activePage.chkAddToConsistencyGroup.isSelected())
        LOG.info("Check box 'Add to a consistency group' is selected.")

        LOG.step('Verifying parent group is None')
        self.assertTrue(wizard.activePage.cBoxParentConsistencyGroup.getText() == 'None')
        LOG.info('Parent consistency group:', wizard.activePage.cBoxParentConsistencyGroup.getText())

        LOG.step('Verifying consistency group default settings')
        self.assertFalse(wizard.activePage.txtNewConsistencyGroup.getText())
        LOG.info("New consistency group text box value: '%s'",
            wizard.activePage.txtNewConsistencyGroup.getText())
        self.assertTrue(wizard.activePage.txtNewConsistencyGroup.getAttribute(attributeName='placeholder')
            == newConsistencyGroup)
        LOG.info('New consistency group text box placeholder:',
        wizard.activePage.txtNewConsistencyGroup.getAttribute(attributeName='placeholder'))

        LOG.step('Verifying consistency group error message when text box in dirty state')
        wizard.activePage.txtNewConsistencyGroup.setFocus()
        wizard.activePage.cBoxParentConsistencyGroup.element.click()
        self.assertTrue(wizard.activePage.lblConsistencyGroupError.isPresent() and
        wizard.activePage.lblConsistencyGroupError.isVisible() and
        wizard.activePage.lblConsistencyGroupError.getText() == consistencyGroupError)
        LOG.info('Consistency group error message is present:', wizard.activePage.lblConsistencyGroupError.isPresent())
        LOG.info('Consistency group error message is visible:',
        wizard.activePage.lblConsistencyGroupError.isVisible())
        LOG.info('Consistency group error message:', wizard.activePage.lblConsistencyGroupError.getText())

        LOG.step("Verifying button 'Next' availability")
        self.assertFalse(wizard.activePage.btnNext.isEnabled())
        LOG.info("Button 'Next' is enabled:", wizard.activePage.btnNext.isEnabled())

        LOG.step('Specifying new consistency group')
        wizard.activePage.txtNewConsistencyGroup.setText(text=newConsistencyGroupName)
        LOG.info('New consistency group:', wizard.activePage.txtNewConsistencyGroup.getText())

        LOG.step("Verifying error message disappeared and button 'Next' enabled")
        time.sleep(.5)
        self.assertFalse(wizard.activePage.lblConsistencyGroupError.isPresent())
        LOG.info('Consistency group error message is present:', wizard.activePage.lblConsistencyGroupError.isPresent())
        self.assertTrue(wizard.activePage.btnNext.isEnabled())
        LOG.info("Button 'Next' is enabled:", wizard.activePage.btnNext.isEnabled())

        LOG.step('Navigating to confirmation page')
        wizard.goNext()
        wizard.goNext()
        self.assertTrue(wizard.confirmPage.isOpen())
        LOG.info('Confirmation page is open:', wizard.confirmPage.isOpen())

        LOG.step('Verifying new consistency group is presented on confirmation page')
        self.assertTrue(wizard.activePage.lblNewConsistencyGroup.isPresent())
        LOG.info('New consistency group is present:', wizard.activePage.lblNewConsistencyGroup.isPresent())
        self.assertTrue(wizard.activePage.lblNewConsistencyGroup.isVisible())
        LOG.info('New consistency group is visible:', wizard.activePage.lblNewConsistencyGroup.isVisible())
        self.assertTrue(wizard.activePage.lblNewConsistencyGroup.getText() == (newConsistencyGroupConfirmation +
        newConsistencyGroupName))
        LOG.info('New consistency group confirmation text:', wizard.activePage.lblNewConsistencyGroup.getText())

        LOG.step("Closing the dialog by clicking button 'Cancel'")
        self.assertTrue(wizard.activePage.btnCancel.isEnabled())
        LOG.info("Button 'Cancel' is enabled:", wizard.activePage.btnCancel.isEnabled())
        wizard.activePage.btnCancel.click()

        LOG.step("Verifying the dialog has been closed")
        self.assertFalse(wizard.confirmPage.isOpen())
        LOG.info('Confirmation page is open:', wizard.confirmPage.isOpen())

        LOG.step('Deleting Consistency groups')
        self.deleteConsistencyGroups()
        LOG.info('Consistency groups deleted.')

    def test_wizard_create_luns_define_multiple_luns_auto_map_to_initiator_group(self):
        numberOfLUNs = 5
        prefix = 'LuN'
        lunSize = 3
        initiatorGroupNames = ['IG-1', 'IG-2', 'IG-3', 'IG-4', 'IG-5', 'IG-6', 'IG-7']
        numberOfFilteredGroups = 5

        LOG.step('Deleting initiator groups')
        self.mars[0].lun.unmapAll()
        self.mars[0].igroup.destroyAll()
        self.assertFalse(self.mars[0].igroup.show(json=True))
        LOG.info('Initiator groups:\n', self.mars[0].igroup.show(json=True))

        LOG.step('Creating new initiator groups')
        initiators = self.mars[0].fcp.initiator_show(json=True)
        for groupName in initiatorGroupNames:
            self.mars[0].igroup.create(name=groupName, ostype='linux', initiators=initiators[0]['wwpn'])
        LOG.info('Initiator groups:\n', self.mars[0].igroup.show(json=True))

        LOG.step('Creating wizard')
        wizard = CreateLUNsWizard(driver=self.driver)

        LOG.step('Opening front page of dialog')
        wizard.open()
        self.assertTrue(wizard.defineLUNsPage.isOpen())
        LOG.info('Wizard landed on LUN definition page.')

        LOG.step('Selecting multiple LUNs')
        wizard.activePage.dLstNumberOfLUNs.select(item=str(numberOfLUNs))
        self.assertTrue(wizard.activePage.dLstNumberOfLUNs.getText() == str(numberOfLUNs))
        LOG.info('Number of LUNs:', wizard.activePage.dLstNumberOfLUNs.getText())

        LOG.step('Selecting LUN name and size auto-definition')
        wizard.activePage.rBtnAutoNameAndSize.select()
        self.assertTrue(wizard.activePage.rBtnAutoNameAndSize.isSelected())
        LOG.info('LUN name and size auto-definition is selected:', wizard.activePage.rBtnAutoNameAndSize.isSelected())

        LOG.step('Setting LUN properties')
        wizard.activePage.txtPrefix.setText(text=prefix)
        LOG.info('Custom prefix:', prefix)
        wizard.activePage.txtAutoSize.setText(text=lunSize)
        LOG.info('LUN size:', lunSize)

        LOG.step('Navigating to initiator group selection page')
        wizard.goNext()
        self.assertTrue(wizard.selectInitiatorGroupsPage.isOpen())
        LOG.info('Initiator group selection page is open:', wizard.selectInitiatorGroupsPage.isOpen())

        LOG.step('Verifying initiator groups in grid')
        gridRows = wizard.activePage.gridInitiatorGroups.find()
        LOG.info('Grid rows:\n', gridRows)
        self.assertTrue(len(gridRows) == len(initiatorGroupNames))
        LOG.info('Number of resulting rows (%s) == number of provided group names (%s)' % (len(gridRows),
        len(initiatorGroupNames)))
        for row in gridRows:
            self.assertTrue(row['initiator_groups'] in initiatorGroupNames)
            LOG.info("Grid: Initiator group '%s' found in provided group names." % row['initiator_groups'])

        LOG.step('Selecting 2 first rows')
        wizard.activePage.gridInitiatorGroups.select(initiator_groups=initiatorGroupNames[:numberOfFilteredGroups])
        selectedRows = wizard.activePage.gridInitiatorGroups.find(selected=True)
        LOG.info('Selected rows:\n', selectedRows)

        LOG.step('Verifying only selected rows are visible')
        wizard.activePage.chkShowOnlySelectedInitiatorGroups.select()
        self.assertTrue(wizard.activePage.chkShowOnlySelectedInitiatorGroups.isSelected())
        LOG.info('Filtering check box is selected:', wizard.activePage.chkShowOnlySelectedInitiatorGroups.isSelected())
        visibleRows = wizard.activePage.gridInitiatorGroups.find()
        LOG.info('Visible grid rows (groups):\n', visibleRows)
        self.assertTrue(len(visibleRows) == numberOfFilteredGroups)
        LOG.info('Number of visible rows (%s) == provided one (%s)' % (len(visibleRows), numberOfFilteredGroups))

        LOG.step('Navigating to confirmation page')
        wizard.goNext()
        self.assertTrue(wizard.confirmPage.isOpen())
        LOG.info('Confirmation page is open:', wizard.confirmPage.isOpen())

        LOG.step('Verifying LUN mapping in grid on confirmation page')
        lunRows = wizard.activePage.gridLUNs.find()
        LOG.info('Rows to confirm:\n', lunRows)
        self.assertTrue(len(lunRows) == numberOfLUNs)
        LOG.info('Number of LUN rows in grid (%s) == provided number of LUNs (%s)' % (len(lunRows), numberOfLUNs))
        selectedGroups = [row['initiator_groups'] for row in selectedRows]
        lunNames = [prefix + str(lunIndex).rjust(2, '0') for lunIndex in range(1, numberOfLUNs + 1)]
        for lunIndex in range(numberOfLUNs):
            self.assertTrue(lunRows[lunIndex]['name'] in lunNames)
            LOG.info("LUN '%s' is found in grid." % lunRows[lunIndex]['name'])
            for groupName in selectedGroups:
                self.assertTrue(groupName in lunRows[lunIndex]['mapped_to'])
                LOG.info('LUN mapping found in row:', groupName)

        LOG.step("Closing the dialog by clicking button 'Cancel'")
        wizard.activePage.btnCancel.click()

        LOG.step("Verifying the dialog has been closed")
        self.assertFalse(wizard.confirmPage.isOpen())
        LOG.info('Confirmation page is open:', wizard.activePage.isOpen())

        LOG.step('Deleting initiator groups')
        self.mars[0].lun.unmapAll()
        self.mars[0].igroup.destroyAll()
        self.assertFalse(self.mars[0].igroup.show(json=True))
        LOG.info('Initiator groups:\n', self.mars[0].igroup.show(json=True))

    def deleteConsistencyGroups(self):
        groups = self.mars[0].cg.show(json=True)
        for group in groups:
            self.mars[0].cg.delete(name=group['name'])

    def testTeardown(self):
        self.driver.quit()
class TestChangeInitiatorsWizard(FRTestCase):
    def suiteSetup(self):
        self.username = ARGS.values.username
        self.password = ARGS.values.password
        self.locale = ARGS.values.locale
        self.webUIHostName = frutil.getFQDN(
            self.marscluster.getMasterNode().hostname)

    def testSetup(self):
        self.driver = self.getDriver()
        self.loginPage = LoginPage(driver=self.driver, url=self.webUIHostName)
        self.headerPage = HeaderPage(driver=self.driver)
        self.allStoragePage = AllStoragePage(driver=self.driver)
        self.initiatorGroupsPage = InitiatorGroupsPage(driver=self.driver)

        LOG.step('Cleaning out cluster content')
        LOG.info('Destroying LUNs...')
        luns = express.Luns(node=self.marscluster, cleanup=True)
        del luns
        self.assertFalse(self.marscluster.lun.show(json=True))
        LOG.info('Done.')
        LOG.info('Destroying existing initiator groups...')
        self.marscluster.igroup.destroyAll()
        LOG.info('Done.')

        self.luns = express.Luns(node=self.marscluster)

        LOG.step('Signing in')
        self.loginPage.open()
        self.loginPage.waitUntilOpen()
        if self.locale is None:
            self.locale = self.loginPage.getRandomLocale()
        self.loginPage.signIn(username=self.username,
                              password=self.password,
                              locale=self.locale)
        LOG.info('Signed in with username: %s, password: %s, locale: %s.' %
                 (self.username, self.password, self.locale))
        LOG.info('Browser landed on header page.')

        LOG.info('Navigating to Initiator Groups page...')
        self.headerPage.btnManager.click()
        self.allStoragePage.tabInitiatorGroups.click()
        self.initiatorGroupsPage.waitUntilOpen()
        LOG.info('Browser landed on Initiator Groups page.')

    def test_verify_wwpns_not_assigned(self):
        """
            Verify dialog shows WWPNs unselected in grid when they are not assigned to initiator
              group.
        """
        initiatorGroupName = 'IG-1'

        LOG.step('Creating initiator group with no WWPNs assigned')
        self.marscluster.igroup.create(name=initiatorGroupName,
                                       ostype='vmware')
        initiatorGroups = self.marscluster.igroup.show(json=True)
        self.assertTrue(len(initiatorGroups) == 1)
        self.assertTrue(initiatorGroups[0]['name'] == initiatorGroupName)
        self.assertFalse(initiatorGroups[0]['initiators'])
        LOG.info('Initiator group created:\n', initiatorGroups[0])

        self.initiatorGroupsPage.btnRefresh.click()
        self.initiatorGroupsPage.btnRefresh.waitUntilEnabled()

        LOG.step('Opening wizard')
        wizard = ChangeInitiatorsWizard(driver=self.driver)
        wizard.open(initiator_group=initiatorGroupName)
        LOG.info('Wizard open.')

        LOG.step('Verifying defaults')
        self.assertTrue(wizard.activePage.lblTitle.isVisible())
        LOG.info('Title is visible:', wizard.activePage.lblTitle.getText())
        self.assertTrue(
            wizard.activePage.lblSubtitle.getText() == initiatorGroupName)
        LOG.info('Initiator group name is visible:',
                 wizard.activePage.lblSubtitle.getText())

        LOG.step('Verifying no WWPNs assigned to initiator group')
        wwpns = wizard.activePage.gridInitiatorWWPNs.find(selected=True)
        selectedWWPNs = wizard.activePage.gridInitiatorWWPNs.find(
            selected=True)
        self.assertFalse(selectedWWPNs)
        LOG.info('Selected WWPNs:', selectedWWPNs)

    def test_verify_wwpns_assigned(self):
        """
            Verify dialog shows WWPNs selected in grid when they are assigned to initiator group.
        """
        initiatorGroupName = 'IG-1'

        LOG.step('Creating initiator group with WWPNs assigned')
        fictiveWWPNs = []
        for _ in range(2):
            fictiveWWPNs.append(':'.join(
                re.findall(
                    '..',
                    format(random.randrange(sys.maxint), 'x').rjust(16, 'f'))))
        self.marscluster.igroup.create(name=initiatorGroupName,
                                       ostype='vmware',
                                       initiators=','.join(fictiveWWPNs))
        initiatorGroups = self.marscluster.igroup.show(json=True)
        self.assertTrue(len(initiatorGroups) == 1)
        self.assertTrue(initiatorGroups[0]['name'] == initiatorGroupName)
        self.assertTrue(len(initiatorGroups[0]['initiators']) == 2)
        LOG.info('Initiator group created:\n', initiatorGroups[0])

        self.initiatorGroupsPage.btnRefresh.click()
        self.initiatorGroupsPage.btnRefresh.waitUntilEnabled()

        LOG.step('Opening wizard')
        wizard = ChangeInitiatorsWizard(driver=self.driver)
        wizard.open(initiator_group=initiatorGroupName)
        LOG.info('Wizard open.')

        LOG.step('Verifying defaults')
        self.assertTrue(wizard.activePage.lblTitle.isVisible())
        LOG.info('Title is visible:', wizard.activePage.lblTitle.getText())
        self.assertTrue(
            wizard.activePage.lblSubtitle.getText() == initiatorGroupName)
        LOG.info('Initiator group name is visible:',
                 wizard.activePage.lblSubtitle.getText())

        LOG.step('Verifying WWPNs assigned to initiator group')
        selectedWWPNs = wizard.activePage.gridInitiatorWWPNs.find(
            selected=True)
        self.assertTrue(len(selectedWWPNs) == 2)
        for wwpn in selectedWWPNs:
            self.assertTrue(wwpn['initiator_group'] in fictiveWWPNs)
            LOG.info("WWPN assigned to initiator group '%s': %s" %
                     (wwpn['initiator_group'], initiatorGroupName))

    def test_add_wwpns(self):
        """
            Verify adding new WWPNs and assigning them to initiator group.
        """
        initiatorGroupName = 'IG-1'
        newWWPNsNumber = 3

        LOG.step('Creating initiator group without WWPNs')
        self.marscluster.igroup.create(name=initiatorGroupName,
                                       ostype='vmware')
        initiatorGroups = self.marscluster.igroup.show(json=True)
        self.assertTrue(len(initiatorGroups) == 1)
        self.assertTrue(initiatorGroups[0]['name'] == initiatorGroupName)
        self.assertFalse(initiatorGroups[0]['initiators'])
        LOG.info('Initiator group created:\n', initiatorGroups[0])

        self.initiatorGroupsPage.btnRefresh.click()
        self.initiatorGroupsPage.btnRefresh.waitUntilEnabled()

        LOG.step('Opening wizard')
        wizard = ChangeInitiatorsWizard(driver=self.driver)
        wizard.open(initiator_group=initiatorGroupName)
        LOG.info('Wizard open.')

        fictiveWWPNs = []
        for _ in range(newWWPNsNumber):
            fictiveWWPNs.append(':'.join(
                re.findall(
                    '..',
                    format(random.randrange(sys.maxint), 'x').rjust(16, 'f'))))
        LOG.step('Adding new WWPNs to list: %s' % fictiveWWPNs)
        wizard.activePage.addWWPNs(wwpns=fictiveWWPNs)
        selectedWWPNs = [
            wwpn for wwpn in wizard.activePage.getWWPNs() if wwpn['selected']
        ]
        self.assertTrue(len(selectedWWPNs) == newWWPNsNumber)
        for wwpn in selectedWWPNs:
            self.assertTrue(wwpn['initiator_group'] in fictiveWWPNs)
            LOG.info('WWPN added and selected in list:',
                     wwpn['initiator_group'])

        LOG.step('Verifying WWPNs have been assigned to initiator group')
        initiatorGroup = self.marscluster.igroup.show(json=True)[0]
        for wwpn in fictiveWWPNs:
            self.assertTrue(wwpn in initiatorGroup['initiators'])
        for wwpn in initiatorGroup['initiators']:
            self.assertTrue(wwpn in fictiveWWPNs)
            LOG.info("WWPN '%s' has beed assigned to initiator group." % wwpn)

    def test_reassign_wwpns(self):
        """
            Verify changing initiator WWPNs in dialog.
        """
        initiatorGroupName = 'IG-1'
        newWWPNsNumber = 7

        LOG.step('Generating fictive WWPNs')
        fictiveWWPNs = []
        for _ in range(newWWPNsNumber):
            fictiveWWPNs.append(':'.join(
                re.findall(
                    '..',
                    format(random.randrange(sys.maxint), 'x').rjust(16, 'f'))))
        LOG.info('Fictive WWPNs generated:', fictiveWWPNs)

        LOG.step('Creating initiator group with half of WWPNs assigned')
        # Assign half of WWPNs
        wwpns = ','.join(fictiveWWPNs[:newWWPNsNumber / 2])
        self.marscluster.igroup.create(name=initiatorGroupName,
                                       ostype='vmware',
                                       initiators=wwpns)
        initiatorGroup = self.marscluster.igroup.show(json=True)[0]
        LOG.info('Initiator group created:\n', initiatorGroup)

        self.initiatorGroupsPage.btnRefresh.click()
        self.initiatorGroupsPage.btnRefresh.waitUntilEnabled()

        LOG.step('Opening wizard')
        wizard = ChangeInitiatorsWizard(driver=self.driver)
        wizard.open(initiator_group=initiatorGroupName)
        LOG.info('Wizard open.')

        LOG.step('Verifying assigned WWPNs are shown and selected in grid')
        selectedWWPNs = [
            wwpn['initiator_group'] for wwpn in wizard.activePage.getWWPNs()
            if wwpn['selected']
        ]
        for wwpn in fictiveWWPNs[:newWWPNsNumber / 2]:
            self.assertTrue(wwpn in selectedWWPNs)
            LOG.info("WWPN '%s' shown selected in grid." % wwpn)

        LOG.step('Reassigning of another half of WWPNs to initiator group')
        wizard.activePage.addWWPNs(wwpns=fictiveWWPNs[newWWPNsNumber / 2:])
        wizard.activePage.setWWPNs(wwpns=fictiveWWPNs[newWWPNsNumber / 2:])
        selectedWWPNs = [
            wwpn['initiator_group'] for wwpn in wizard.activePage.getWWPNs()
            if wwpn['selected']
        ]
        for wwpn in fictiveWWPNs[newWWPNsNumber / 2:]:
            self.assertTrue(wwpn in selectedWWPNs)
            LOG.info("WWPN '%s' shown selected in grid." % wwpn)

        LOG.step('Submitting dialog')
        wizard.close()
        LOG.info('Dialog submitted.')

        self.initiatorGroupsPage.btnRefresh.click()
        self.initiatorGroupsPage.btnRefresh.waitUntilEnabled()

        LOG.step('Verifying WWPN reassignment has been done.')
        initiatorGroup = self.marscluster.igroup.show(json=True)[0]
        for wwpn in fictiveWWPNs[newWWPNsNumber / 2:]:
            self.assertTrue(wwpn in initiatorGroup['initiators'])
        for wwpn in initiatorGroup['initiators']:
            self.assertTrue(wwpn in selectedWWPNs)
            LOG.info("WWPN '%s' has been assigned to initiator group." % wwpn)

    def test_dialog_not_available(self):
        """
            Verify menu 'Edit' on Initiator Groups page is disabled when no initiator group
              selected.
        """
        initiatorGroupPrefix = 'IG'
        initiatorGroupNumber = 3

        self._createInitiatorGroups(prefix=initiatorGroupPrefix,
                                    number=initiatorGroupNumber)

        LOG.step('Navigating to Initiator Groups page')
        HeaderPage(driver=self.driver).btnManager.click()
        AllStoragePage(driver=self.driver).tabInitiatorGroups.click()
        self.assertTrue(self.initiatorGroupsPage.isOpen())
        LOG.info('Initiator Groups page is open:',
                 self.initiatorGroupsPage.isOpen())

        self.initiatorGroupsPage.btnRefresh.click()
        self.initiatorGroupsPage.btnRefresh.waitUntilEnabled()

        LOG.step('Unselecting all initiator groups in grid')
        self.initiatorGroupsPage.gridInitiatorGroups.unselect()
        initiatorGroups = self.initiatorGroupsPage.gridInitiatorGroups.find(
            selected=True)
        self.assertFalse(initiatorGroups)
        LOG.info('Selected initiator groups:', initiatorGroups)

        LOG.step("Verifying menu 'Edit' is disabled")
        self.assertFalse(self.initiatorGroupsPage.menuEdit.isEnabled())
        LOG.info("Menu 'Edit' is enabled:",
                 self.initiatorGroupsPage.menuEdit.isEnabled())

    def testTeardown(self):
        self.driver.close()

    def suiteTeardown(self):
        LOG.step('Closing browser')
        self.driver.quit()
        luns = express.Luns(node=self.marscluster, cleanup=True)
        del luns
        self.marscluster.igroup.destroyAll()
        LOG.info('LUNs & initiator groups destroyed.')

    def _createInitiatorGroups(self, prefix, number):
        LOG.step('Creating initiator group(s)')
        for groupNumber in range(number):
            fictiveWWPN = format(random.randrange(sys.maxint),
                                 'x').rjust(16, 'f')
            self.marscluster.igroup.create(name=prefix + '-' +
                                           str(groupNumber),
                                           ostype='vmware',
                                           initiators=fictiveWWPN)
        groupNames = [
            group['name'] for group in self.marscluster.igroup.show(json=True)
        ]
        LOG.info('Initiator group(s) created:', groupNames)
        return groupNames
class TestComponentMenu(FRTestCase):
    def suiteSetup(self):
        self.username = ARGS.values.username
        self.password = ARGS.values.password
        self.webUIHostName = getFQDN(self.mars[0].hostname)

    def testSetup(self):
        self.driver = self.setupDriver()
        self.loginPage = LoginPage(driver=self.driver, url=self.webUIHostName)
        self.headerPage = HeaderPage(driver=self.driver)
        self.allStoragePage = AllStoragePage(driver=self.driver)
        self.lunsPage = LUNsPage(driver=self.driver)
        self.defineLUNsPage = DefineLUNsPage(driver=self.driver)

    def test_component_menu(self):
        LOG.step('Opening login page')
        self.loginPage.open()

        LOG.step("Getting item list of menu 'Locale'")
        LOG.info('Menu items:\n', self.loginPage.menuLocale.getItems())

        LOG.step('Selecting locale menu item')
        self.loginPage.selectLocale(locale=ARGS.values.locale)
        LOG.info('Locale hypertext reference:',
            self.loginPage.menuLocale.getAttribute(attributeName='href'))

        LOG.step('Typing username')
        self.loginPage.txtUsername.setText(self.username)
        self.assertTrue(self.loginPage.txtUsername.getText() == self.username)
        LOG.info('Username:'******'Typing password')
        self.loginPage.txtPassword.waitUntilPresent()
        self.loginPage.txtPassword.setText(self.password)
        self.assertTrue(self.loginPage.txtPassword.getText() == self.password)
        LOG.info('Password:'******'Sign In'")
        self.loginPage.btnSignIn.waitUntilPresent()
        self.loginPage.btnSignIn.waitUntilEnabled()
        self.loginPage.btnSignIn.click()

        LOG.step("Clicking on button 'Manager'")
        self.headerPage.btnManager.waitUntilPresent()
        self.headerPage.btnManager.click()

        LOG.step("Clicking on tab 'LUNs'")
        self.allStoragePage.tabLUNs.click()

        LOG.step("Selecting item 'LUNs' in menu 'Create'")
        self.lunsPage.menuCreate.waitUntilPresent()
        self.lunsPage.menuCreate.select(item='LUNs')

        LOG.step("Confirming dialog 'Create LUNs' popped up")
        self.defineLUNsPage.lblTitle.waitUntilPresent()
        LOG.info('Dialog title is present:', self.defineLUNsPage.lblTitle.isPresent())

        LOG.step("Closing dialog by clicking on button 'Cancel'")
        self.defineLUNsPage.btnCancel.click()

        LOG.step("Selecting item 'Sign Out' from user menu")
        self.headerPage.menuUser.waitUntilPresent()
        self.headerPage.menuUser.select(item='Sign Out')

        LOG.step('Verifying browser comes back to login page')
        self.loginPage.imgCompanyLogo.waitUntilPresent()
        LOG.info('Company logo is present on page:', self.loginPage.imgCompanyLogo.isPresent())

    def testTeardown(self):
        self.driver.quit()
class TestRenameLUNSnapshotWizard(FRTestCase):
    def suiteSetup(self):
        self.username = ARGS.values.username
        self.password = ARGS.values.password
        self.locale = ARGS.values.locale
        self.webUIHostName = getFQDN(self.marscluster.getMasterNode().hostname)

    def testSetup(self):
        self.driver = self.getDriver()
        self.loginPage = LoginPage(driver=self.driver, url=self.webUIHostName)
        self.headerPage = HeaderPage(driver=self.driver)
        self.allStoragePage = AllStoragePage(driver=self.driver)
        self.lunsPage = LUNsPage(driver=self.driver)
        self.lunDetailsPage = LUNDetailsPage(driver=self.driver)
        self.lunSnapshotsPage = LUNSnapshotsPage(driver=self.driver)

        LOG.step('Cleaning out cluster content')
        snapshots = self.marscluster.snapshot.show(json=True)
        for snapshot in snapshots:
            self.marscluster.snapshot.delete(name=snapshot['name'],
                                             lun=snapshot['object'])
        self.assertFalse(self.marscluster.snapshot.show(json=True))
        LOG.info('Snapshots destroyed.')

        luns = express.Luns(node=self.marscluster, cleanup=True)
        del luns
        self.assertFalse(self.marscluster.lun.show(json=True))
        LOG.info('LUNs destroyed.')

        self.luns = express.Luns(node=self.marscluster)

        LOG.step('Signing in')
        self.loginPage.open()
        self.loginPage.waitUntilOpen()
        if self.locale is None:
            self.locale = self.loginPage.getRandomLocale()
        self.loginPage.signIn(username=self.username,
                              password=self.password,
                              locale=self.locale)
        LOG.info('Signed in with username: %s, password: %s, locale: %s.' %
                 (self.username, self.password, self.locale))
        LOG.info('Browser landed on header page.')

        LOG.step('Navigating to LUNs page')
        self.headerPage.btnManager.click()
        self.allStoragePage.tabLUNs.click()
        self.lunsPage.waitUntilOpen()
        LOG.info('Browser landed on LUNs page.')

    def test_valid_name(self):
        """
            Verify LUN snapshot renaming with valid name.
        """
        lunNamePrefix = 'LuN'
        lunName = lunNamePrefix + '_1'
        snapshotName = lunName + '_snap_0'
        snapshotNewName = snapshotName + '.m'

        LOG.step('Creating LUN')
        self.luns.create(count=1, size='1g', prefix=lunNamePrefix)
        LOG.info('LUN created:\n', self.marscluster.lun.show(json=True))

        LOG.step('Creating LUN snapshot')
        self.marscluster.snapshot.create(luns=lunName, name=snapshotName)
        snapshots = self.marscluster.snapshot.show(json=True)
        snapshot = [
            snapshot for snapshot in snapshots
            if (snapshot['name'] == snapshotName
                and snapshot['object'] == lunName)
        ][0]
        snapshotUUID = snapshot['uuid']
        LOG.info('Snapshot created:\n', snapshot)

        LOG.step("LUN '%s': Opening Snapshots page" % lunName)
        lunSnapshotsPage = LUNSnapshotsPage(
            driver=self.driver,
            url=self.webUIHostName +
            ('/#manager/storage/allstorage/luns/%s/snapshot' % lunName))
        lunSnapshotsPage.open()
        lunSnapshotsPage.waitUntilOpen()
        LOG.info('LUN Snapshots page is open.')

        LOG.step('Renaming LUN snapshot in dialog')
        wizard = RenameLUNSnapshotWizard(driver=self.driver)
        wizard.open(name=snapshotName)
        LOG.info('Old snapshot name:', snapshotName)
        wizard.renameLUNSnapshotPage.renameLUNSnapshot(name=snapshotNewName)
        LOG.info('New snapshot name:', snapshotNewName)
        wizard.renameLUNSnapshotPage.submit()
        LOG.info('Rename submitted.')

        LOG.step('Verifying LUN snapshot name has been changed')
        snapshots = self.marscluster.snapshot.show(json=True)
        snapshot = [
            snapshot for snapshot in snapshots
            if snapshot['uuid'] == snapshotUUID
        ][0]
        self.assertTrue(snapshot['name'] == snapshotNewName)
        LOG.info('LUN snapshot has been renamed:\n', snapshot)

    def test_invalid_name(self):
        """
            Verify LUN snapshot renaming with invalid name.
        """
        lunNamePrefix = 'LuN'
        lunName = lunNamePrefix + '_1'
        snapshotName = lunName + '_snap_0'
        snapshotNewName = snapshotName + '*&#@1A_^?,'

        LOG.step('Creating LUN')
        self.luns.create(count=1, size='1g', prefix=lunNamePrefix)
        LOG.info('LUN created:\n', self.marscluster.lun.show(json=True))

        LOG.step('Creating LUN snapshot')
        self.marscluster.snapshot.create(luns=lunName, name=snapshotName)
        snapshots = self.marscluster.snapshot.show(json=True)
        snapshot = [
            snapshot for snapshot in snapshots
            if (snapshot['name'] == snapshotName
                and snapshot['object'] == lunName)
        ][0]
        snapshotUUID = snapshot['uuid']
        LOG.info('Snapshot created:\n', snapshot)

        LOG.step("LUN '%s': Opening Snapshots page" % lunName)
        lunSnapshotsPage = LUNSnapshotsPage(
            driver=self.driver,
            url=self.webUIHostName +
            ('/#manager/storage/allstorage/luns/%s/snapshot' % lunName))
        lunSnapshotsPage.open()
        lunSnapshotsPage.waitUntilOpen()
        LOG.info('LUN Snapshots page is open.')

        LOG.step('Renaming LUN snapshot in dialog')
        wizard = RenameLUNSnapshotWizard(driver=self.driver)
        wizard.open(name=snapshotName)
        LOG.info('Old snapshot name:', snapshotName)
        wizard.renameLUNSnapshotPage.renameLUNSnapshot(name=snapshotNewName)
        LOG.info('New snapshot name:', snapshotNewName)

        LOG.step('Verifying LUN snapshot name error message')
        wizard.activePage.lblNameError.waitUntilPresent()
        LOG.info('Name error message:',
                 wizard.activePage.lblNameError.getText())
        self.assertFalse(wizard.activePage.btnOK.isEnabled())
        LOG.info("Button 'OK' is enabled:",
                 wizard.activePage.btnOK.isEnabled())

        LOG.step('Verifying LUN snapshot has not been renamed')
        snapshots = self.marscluster.snapshot.show(json=True)
        snapshot = [
            snapshot for snapshot in snapshots
            if snapshot['uuid'] == snapshotUUID
        ][0]
        self.assertTrue(snapshot['name'] == snapshotName)
        LOG.info('LUN snapshot has not been renamed:\n', snapshot)

    def test_unicode_name(self):
        """
            Verify error message on setting LUN snapshot name containing Unicode characters.
        """
        lunNamePrefix = 'LuN'
        lunName = lunNamePrefix + '_1'
        snapshotName = lunName + '_snap_0'
        snapshotNewName = snapshotName + u'Fran\u00e7ais'

        LOG.step('Creating LUN')
        self.luns.create(count=1, size='1g', prefix=lunNamePrefix)
        LOG.info('LUN created:\n', self.marscluster.lun.show(json=True))

        LOG.step('Creating LUN snapshot')
        self.marscluster.snapshot.create(luns=lunName, name=snapshotName)
        snapshots = self.marscluster.snapshot.show(json=True)
        snapshot = [
            snapshot for snapshot in snapshots
            if (snapshot['name'] == snapshotName
                and snapshot['object'] == lunName)
        ][0]
        snapshotUUID = snapshot['uuid']
        LOG.info('Snapshot created:\n', snapshot)

        LOG.step("LUN '%s': Opening Snapshots page" % lunName)
        lunSnapshotsPage = LUNSnapshotsPage(
            driver=self.driver,
            url=self.webUIHostName +
            ('/#manager/storage/allstorage/luns/%s/snapshot' % lunName))
        lunSnapshotsPage.open()
        lunSnapshotsPage.waitUntilOpen()
        LOG.info('LUN Snapshots page is open.')

        LOG.step('Renaming LUN snapshot in dialog')
        wizard = RenameLUNSnapshotWizard(driver=self.driver)
        wizard.open(name=snapshotName)
        LOG.info('Old snapshot name:', snapshotName)
        wizard.renameLUNSnapshotPage.renameLUNSnapshot(name=snapshotNewName)
        LOG.info('New snapshot name:', snapshotNewName)

        LOG.step('Verifying LUN snapshot name error message')
        wizard.activePage.lblNameError.waitUntilPresent()
        LOG.info('Name error message:',
                 wizard.activePage.lblNameError.getText())
        self.assertFalse(wizard.activePage.btnOK.isEnabled())
        LOG.info("Button 'OK' is enabled:",
                 wizard.activePage.btnOK.isEnabled())

        LOG.step('Verifying LUN snapshot has not been renamed')
        snapshots = self.marscluster.snapshot.show(json=True)
        snapshot = [
            snapshot for snapshot in snapshots
            if snapshot['uuid'] == snapshotUUID
        ][0]
        self.assertTrue(snapshot['name'] == snapshotName)
        LOG.info('LUN snapshot has not been renamed:\n', snapshot)

    def test_dialog_not_available(self):
        lunNamePrefix = 'LuN'
        lunName = lunNamePrefix + '_1'
        snapshotName = lunName + '_snap_0'

        LOG.step('Creating LUN')
        self.luns.create(count=1, size='1g', prefix=lunNamePrefix)
        LOG.info('LUN created:\n', self.marscluster.lun.show(json=True))

        LOG.step('Creating LUN snapshot')
        self.marscluster.snapshot.create(luns=lunName, name=snapshotName)
        snapshots = self.marscluster.snapshot.show(json=True)
        snapshot = [
            snapshot for snapshot in snapshots
            if (snapshot['name'] == snapshotName
                and snapshot['object'] == lunName)
        ][0]
        snapshotUUID = snapshot['uuid']
        LOG.info('Snapshot created:\n', snapshot)

        LOG.step("LUN '%s': Opening Snapshots page" % lunName)
        lunSnapshotsPage = LUNSnapshotsPage(
            driver=self.driver,
            url=self.webUIHostName +
            ('/#manager/storage/allstorage/luns/%s/snapshot' % lunName))
        lunSnapshotsPage.open()
        lunSnapshotsPage.waitUntilOpen()
        LOG.info('LUN Snapshots page is open.')

        LOG.step('Unselecting all LUN snapshots in grid')
        lunSnapshotsPage.gridSnapshots.unselect()
        selectedSnapshots = lunSnapshotsPage.gridSnapshots.find(selected=True)
        self.assertFalse(selectedSnapshots)
        LOG.info('LUN snapshots selected in grid:', selectedSnapshots)

        LOG.step("Verifying menu 'Edit' is unavailable")
        self.assertFalse(lunSnapshotsPage.menuEdit.isEnabled())
        LOG.info("Menu 'Edit' is enabled:",
                 lunSnapshotsPage.menuEdit.isEnabled())

    def test_dialog_cancel(self):
        """
            Verify LUN snapshot name remains intact on dialog cancel.
        """
        lunNamePrefix = 'LuN'
        lunName = lunNamePrefix + '_1'
        snapshotName = lunName + '_snap_0'
        snapshotNewName = snapshotName + '.m'

        LOG.step('Creating LUN')
        self.luns.create(count=1, size='1g', prefix=lunNamePrefix)
        LOG.info('LUN created:\n', self.marscluster.lun.show(json=True))

        LOG.step('Creating LUN snapshot')
        self.marscluster.snapshot.create(luns=lunName, name=snapshotName)
        snapshots = self.marscluster.snapshot.show(json=True)
        snapshot = [
            snapshot for snapshot in snapshots
            if (snapshot['name'] == snapshotName
                and snapshot['object'] == lunName)
        ][0]
        snapshotUUID = snapshot['uuid']
        LOG.info('Snapshot created:\n', snapshot)

        LOG.step("LUN '%s': Opening Snapshots page" % lunName)
        lunSnapshotsPage = LUNSnapshotsPage(
            driver=self.driver,
            url=self.webUIHostName +
            ('/#manager/storage/allstorage/luns/%s/snapshot' % lunName))
        lunSnapshotsPage.open()
        lunSnapshotsPage.waitUntilOpen()
        LOG.info('LUN Snapshots page is open.')

        LOG.step('Renaming LUN snapshot in dialog')
        wizard = RenameLUNSnapshotWizard(driver=self.driver)
        wizard.open(name=snapshotName)
        LOG.info('Old snapshot name:', snapshotName)
        wizard.renameLUNSnapshotPage.renameLUNSnapshot(name=snapshotNewName)
        self.assertTrue(wizard.activePage.txtName.getText() == snapshotNewName)
        LOG.info('New snapshot name:', snapshotNewName)

        LOG.step('Canceling dialog without submission')
        wizard.cancel()
        LOG.info('Dialog cancelled.')

        LOG.step('Verifying LUN snapshot has not been renamed')
        snapshots = self.marscluster.snapshot.show(json=True)
        snapshot = [
            snapshot for snapshot in snapshots
            if snapshot['uuid'] == snapshotUUID
        ][0]
        self.assertTrue(snapshot['name'] == snapshotName)
        LOG.info('LUN snapshot has not been renamed:\n', snapshot)

    def testTeardown(self):
        self.driver.close()
        LOG.info('Driver closed.')

    def suiteTeardown(self):
        self.driver.quit()
        LOG.info('Driver quit.')

        LOG.step('Deleting snapshots')
        snapshots = self.marscluster.snapshot.show(json=True)
        for snapshot in snapshots:
            self.marscluster.snapshot.delete(name=snapshot['name'],
                                             lun=snapshot['object'])
        self.assertFalse(self.marscluster.snapshot.show(json=True))
        LOG.info('Snapshots deleted.')

        LOG.step('Destroying LUNs')
        luns = express.Luns(node=self.marscluster, cleanup=True)
        del luns
        LOG.info('LUNs destroyed.')
class TestComponentSearchBox(FRTestCase):
    def suiteSetup(self):
        self.locale = ARGS.values.locale
        self.username = ARGS.values.username
        self.password = ARGS.values.password
        self.webUIHostName = getFQDN(self.marscluster.hostname)

        self.luns = express.Luns(node=self.marscluster)

    def testSetup(self):
        self.driver = self.setupDriver()
        self.loginPage = LoginPage(driver=self.driver, url=self.webUIHostName)
        self.headerPage = HeaderPage(driver=self.driver)
        self.allStoragePage = AllStoragePage(driver=self.driver)
        self.lunsPage = LUNsPage(driver=self.driver)

        LOG.step('Signing in')
        self.loginPage.open()
        self.loginPage.waitUntilOpen()
        self.loginPage.signIn(username=self.username,
                              password=self.password,
                              locale=self.locale)
        LOG.info('Signed in with username: %s, password: %s, locale: %s.' %
                 (self.username, self.password, self.locale))
        LOG.info('Browser landed on header page.')

        LOG.step('Navigating to LUNs page')
        self.headerPage.btnManager.click()
        self.allStoragePage.tabLUNs.click()
        self.lunsPage.waitUntilOpen()
        LOG.info('Browser landed on LUNs page.')

        LOG.step('Creating LUNs')
        self.lunNamePrefix = 'LuN'
        self.lunCount = 20
        self.luns.create(count=self.lunCount,
                         size='1g',
                         prefix=self.lunNamePrefix)
        luns = self.marscluster.lun.show(json=True)
        LOG.info('LUNs created:\n', [lun['name'] for lun in luns])

        self.lunsPage.btnRefresh.click()
        self.lunsPage.btnRefresh.waitUntilEnabled()

    def test_search(self):
        """
            Search for single/multiple row(s) in grid. Verify displayed rows satisfy search key.
        """
        LOG.step('Searching for unique value: %s' % self.lunNamePrefix + '_' +
                 str(self.lunCount))
        self.lunsPage.sBoxSearch.setText(text=self.lunNamePrefix + '_' +
                                         str(self.lunCount))
        luns = self.lunsPage.gridLUNs.find()
        self.assertTrue(len(luns) == 1)
        self.assertTrue(luns[0]['name'] == self.lunNamePrefix + '_' +
                        str(self.lunCount))
        LOG.info('LUNs displayed:', luns)

        LOG.step('Searching for multiple values: %s' % self.lunNamePrefix +
                 '_1*')
        self.lunsPage.sBoxSearch.clear()
        self.lunsPage.sBoxSearch.setText(text=self.lunNamePrefix + '_1')
        luns = [lun['name'] for lun in self.lunsPage.gridLUNs.find()]
        # 'LuN_1', 'LuN_10' ... 'LuN_19'
        self.assertTrue(len(luns) == 11)
        for lun in luns:
            self.assertTrue(lun.startswith(self.lunNamePrefix + '_1'))
        LOG.info('LUNs displayed:', luns)

    def testTeardown(self):
        self.driver.close()
        luns = express.Luns(node=self.marscluster, cleanup=True)
        del luns
        LOG.info('LUNs destroyed.')

    def suiteTeardown(self):
        LOG.step('Closing browser')
        self.driver.quit()