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 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()
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.')
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.')
Example #6
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 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()
Example #8
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()
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 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 TestEditLUNIDsWizard(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)

        luns = express.Luns(node=self.marscluster, cleanup=True)
        del luns
        self.luns = express.Luns(node=self.marscluster)
        self.marscluster.igroup.destroyAll()

        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_single_mapping(self):
        """
            Verify setting ID for LUN with single initiator group mapping.
        """
        newID = 173

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

        groupNames = self.createInitiatorGroups(prefix='IG', number=1)

        LOG.step('Mapping LUN to initiator group')
        self.marscluster.lun.map({'name': 'LuN_1', 'igroup': groupNames[0]})
        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 = EditLUNIDsWizard(driver=self.driver)
        wizard.open(name='LuN_1')
        LOG.info('Wizard open.')

        LOG.step('Verifying default ID')
        ids = wizard.activePage.getIDs()
        self.assertTrue(len(ids) == 1)
        self.assertTrue(ids['IG-0'] == '0')
        LOG.info('Default ID set:', ids['IG-0'])

        LOG.step('Setting new ID: %s' % newID)
        wizard.activePage.setIDs(ids={'IG-0': newID})
        wizard.activePage.submit()
        LOG.info('Dialog submitted.')

        LOG.step('Verifying new ID')
        lun = self.marscluster.lun.show(json=True)[0]
        self.assertTrue(lun['maps'][0]['lun-id'] == newID)
        LOG.info('LUN mapping ID set to:', lun['maps'][0]['lun-id'])

    def test_multiple_mappings(self):
        """
            Verify setting IDs for LUN with multiple initiator group mappings.
        """
        initiatorGroupsNumber = 5
        maxID = 4095

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

        # List of initiator group names with default IDs
        ids = {
            groupName: 0
            for groupName in self.createInitiatorGroups(
                prefix='IG', number=initiatorGroupsNumber)
        }

        LOG.step('Mapping LUN to initiator groups')
        for groupName in ids:
            self.marscluster.lun.map({'name': 'LuN_1', 'igroup': groupName})
        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 = EditLUNIDsWizard(driver=self.driver)
        wizard.open(name='LuN_1')
        LOG.info('Wizard open.')

        LOG.step('Setting random IDs')
        uniqueIDs = []
        for groupName in ids:
            # To avoid duplicated IDs.
            while True:
                id = random.randint(0, maxID)
                if id not in uniqueIDs:
                    uniqueIDs.append(id)
                    ids[groupName] = id
                    LOG.info("Initiator group '%s': ID set to %s" %
                             (groupName, id))
                    break
        wizard.activePage.setIDs(ids=ids)
        wizard.activePage.submit()
        LOG.info('Dialog submitted.')

        LOG.step('Verifying LUN mapping IDs')
        mappings = self.marscluster.lun.show(json=True)[0]['maps']
        self.assertTrue(len(mappings) == len(ids))
        for mapping in mappings:
            self.assertTrue(mapping['lun-name'] == 'LuN_1')
            self.assertTrue(mapping['lun-id'] == ids[mapping['igroup-name']])
            LOG.info("Initiator group '%s': ID=%s" %
                     (mapping['igroup-name'], ids[mapping['igroup-name']]))

    def test_fail_original_id(self):
        """
            Verify button 'OK' is disabled when original ID was typed in.
        """
        LOG.step('Creating LUN')
        self.luns.create(count=1, size='1g', prefix='LuN')
        LOG.info('LUN created:\n', self.marscluster.lun.show(json=True))

        self.createInitiatorGroups(prefix='IG', number=1)

        LOG.step('Mapping LUN to initiator group')
        self.marscluster.lun.map({'name': 'LuN_1', 'igroup': 'IG-0'})
        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 = EditLUNIDsWizard(driver=self.driver)
        wizard.open(name='LuN_1')
        LOG.info('Wizard open.')

        LOG.step('Typing in original ID')
        ids = wizard.activePage.getIDs()
        self.assertTrue(len(ids) == 1)
        id = ids['IG-0']
        LOG.info('Original ID:', id)
        wizard.activePage.setIDs(ids={'IG-0': id})
        newID = wizard.activePage.getIDs()['IG-0']
        LOG.info('Typed ID:', newID)
        self.assertFalse(wizard.activePage.btnOK.isEnabled())
        LOG.info("Button 'OK' is enabled:",
                 wizard.activePage.btnOK.isEnabled())

    def test_fail_invalid_id(self):
        """
            Verify typing invalid ID filters out non-numeric characters.
        """
        validIDPart = '700'
        invalidIDPart = 'W-'

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

        self.createInitiatorGroups(prefix='IG', number=1)

        LOG.step('Mapping LUN to initiator group')
        self.marscluster.lun.map({'name': 'LuN_1', 'igroup': 'IG-0'})
        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 = EditLUNIDsWizard(driver=self.driver)
        wizard.open(name='LuN_1')
        LOG.info('Wizard open.')

        LOG.step('Typing in invalid ID: %s' % validIDPart + invalidIDPart)
        wizard.activePage.setIDs(ids={'IG-0': validIDPart + invalidIDPart})
        typedText = wizard.activePage.getIDs()['IG-0']
        self.assertTrue(typedText == validIDPart)
        LOG.info('Typed value:', typedText)

    def test_max_id(self):
        """
            Verify error message appears when ID exceeds upper limit (4095).
        """
        maxID = 4095

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

        self.createInitiatorGroups(prefix='IG', number=1)

        LOG.step('Mapping LUN to initiator group')
        self.marscluster.lun.map({'name': 'LuN_1', 'igroup': 'IG-0'})
        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 = EditLUNIDsWizard(driver=self.driver)
        wizard.open(name='LuN_1')
        LOG.info('Wizard open.')

        LOG.step('Typing in maximal acceptable ID: %s' % maxID)
        wizard.activePage.setIDs(ids={'IG-0': maxID})
        self.assertTrue(wizard.activePage.btnOK.isEnabled())
        LOG.info("Button 'OK' is enabled:",
                 wizard.activePage.btnOK.isEnabled())

        LOG.step('Typing in ID exceeding maximal: %s' % (maxID + 1))
        wizard.activePage.setIDs(ids={'IG-0': maxID + 1})
        self.assertFalse(wizard.activePage.btnOK.isEnabled())
        LOG.info("Button 'OK' is enabled:",
                 wizard.activePage.btnOK.isEnabled())

    def test_fail_nonunique_id(self):
        """
            Verify error message when typed ID is used by another LUN mapped to the same initiator
              group.
        """
        LOG.step('Creating 2 LUNs')
        self.luns.create(count=2, size='1g', prefix='LuN')
        LOG.info('LUNs created:\n', self.marscluster.lun.show(json=True))

        self.createInitiatorGroups(prefix='IG', number=1)

        LOG.step('Mapping LUNs to the same initiator group')
        self.marscluster.lun.map({'name': 'LuN_1', 'igroup': 'IG-0'})
        self.marscluster.lun.map({'name': 'LuN_2', 'igroup': 'IG-0'})
        mappings = self.marscluster.lun.mapping_show(json=True)
        LOG.info('LUN mapped:\n', mappings)

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

        LOG.step('Opening wizard')
        wizard = EditLUNIDsWizard(driver=self.driver)
        wizard.open(name=mappings[0]['lun-name'].encode('utf-8'))
        LOG.info('Wizard open for LUN:', mappings[0]['lun-name'])

        LOG.step('Setting ID same as another LUN')
        wizard.activePage.setIDs(ids={mappings[1]['lun-id']})
        self.assertFalse(wizard.activePage.btnOK.isEnabled())
        LOG.info("Button 'OK' is enabled:",
                 wizard.activePage.btnOK.isEnabled())

    def test_dialog_cancel(self):
        """
            Verify ID remains unchanged on canceling dialog without submission.
        """
        LOG.step('Creating LUN')
        self.luns.create(count=1, size='1g', prefix='LuN')
        LOG.info('LUN created:\n', self.marscluster.lun.show(json=True))

        self.createInitiatorGroups(prefix='IG', number=1)

        LOG.step('Mapping LUN to initiator group')
        self.marscluster.lun.map({'name': 'LuN_1', 'igroup': 'IG-0'})
        originalMappings = self.marscluster.lun.mapping_show(json=True)
        LOG.info('LUN mapped:\n', originalMappings)

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

        LOG.step('Opening wizard')
        wizard = EditLUNIDsWizard(driver=self.driver)
        wizard.open(name='LuN_1')
        LOG.info('Wizard open.')

        newID = '305'
        LOG.step('Setting new ID: %s' % newID)
        wizard.activePage.setIDs(ids={'IG-0': newID})
        ids = wizard.activePage.getIDs()
        self.assertTrue(ids['IG-0'] == newID)
        LOG.info('Typed ID:', ids['IG-0'])

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

        LOG.step('Verifying mappings have not been changed')
        mappings = self.marscluster.lun.mapping_show(json=True)
        self.assertTrue(len(mappings) == len(originalMappings))
        self.assertTrue(
            mappings[0]['igroup-name'] == originalMappings[0]['igroup-name'])
        LOG.info('Initiator group:', originalMappings[0]['igroup-name'])
        self.assertTrue(
            mappings[0]['lun-name'] == originalMappings[0]['lun-name'])
        LOG.info('LUN:', originalMappings[0]['lun-name'])
        self.assertTrue(mappings[0]['lun-id'] == originalMappings[0]['lun-id'])
        LOG.info('LUN ID:', originalMappings[0]['lun-id'])

    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 testTeardown(self):
        self.driver.close()

    def suiteTeardown(self):
        LOG.step('Closing browser')
        self.driver.quit()
        LOG.info('Browser closed.')
        luns = express.Luns(node=self.marscluster, cleanup=True)
        del luns
        self.marscluster.igroup.destroyAll()
Example #12
0
class TestRenameInitiatorWizard(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.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.')

        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_valid_name(self):
        """
            Verify initiator group renaming with new valid name.
        """
        initiatorGroupCount = 3
        initiatorGroupPrefix = 'IG'
        newName = 'IG-New'
        initiatorGroups = self.createInitiatorGroups(
            prefix=initiatorGroupPrefix, number=initiatorGroupCount)

        self.initiatorGroupsPage.btnRefresh.click()
        self.initiatorGroupsPage.btnRefresh.waitUntilEnabled()

        LOG.step('Renaming initiator group in dialog')
        wizard = RenameInitiatorGroupWizard(driver=self.driver)
        wizard.open(initiator_group=initiatorGroups[0])
        LOG.info('Old name:', wizard.activePage.txtName.getText())
        wizard.renameInitiatorGroupPage.renameInitiatorGroup(name=newName)
        LOG.info('New name:', wizard.activePage.txtName.getText())
        wizard.renameInitiatorGroupPage.submit()
        LOG.info('Rename submitted.')

        LOG.step('Verifying initiator group name has been changed')
        initiatorGroups = [
            group['name'] for group in self.marscluster.igroup.show(json=True)
        ]
        self.assertTrue(newName in initiatorGroups)
        LOG.info("Name '%s' found in initiator groups list:\n%s" %
                 (newName, initiatorGroups))

    def test_invalid_name(self):
        """
            Verify error message when invalid name typed in.
        """
        initiatorGroupCount = 3
        initiatorGroupPrefix = 'IG'
        newName = 'IG*&#@1A_^?,'
        initiatorGroups = self.createInitiatorGroups(
            prefix=initiatorGroupPrefix, number=initiatorGroupCount)

        self.initiatorGroupsPage.btnRefresh.click()
        self.initiatorGroupsPage.btnRefresh.waitUntilEnabled()

        LOG.step("Changing initiator group name with: %s" % newName)
        wizard = RenameInitiatorGroupWizard(driver=self.driver)
        wizard.open(initiator_group=initiatorGroups[0])
        LOG.info('Old name:', wizard.activePage.txtName.getText())
        wizard.renameInitiatorGroupPage.renameInitiatorGroup(name=newName)
        LOG.info('New name:', wizard.activePage.txtName.getText())

        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_max_length_name(self):
        """
            Verify error message when name length exceeds limit (96).
        """
        initiatorGroupCount = 3
        initiatorGroupPrefix = 'IG'
        newName = 'IGx' * 32
        initiatorGroups = self.createInitiatorGroups(
            prefix=initiatorGroupPrefix, number=initiatorGroupCount)

        self.initiatorGroupsPage.btnRefresh.click()
        self.initiatorGroupsPage.btnRefresh.waitUntilEnabled()

        LOG.step("Setting initiator group name to maximal length: %s" %
                 newName)
        wizard = RenameInitiatorGroupWizard(driver=self.driver)
        wizard.open(initiator_group=initiatorGroups[0])
        LOG.info('Old name:', wizard.activePage.txtName.getText())
        wizard.renameInitiatorGroupPage.renameInitiatorGroup(name=newName)
        LOG.info('New name:', wizard.activePage.txtName.getText())

        LOG.step('Verifying no error messaging')
        wizard.activePage.lblNameError.waitUntilHidden()
        LOG.info('Error message is present:',
                 wizard.activePage.lblNameError.isVisible())
        self.assertTrue(wizard.activePage.btnOK.isEnabled())
        LOG.info("Button 'OK' is enabled:",
                 wizard.activePage.btnOK.isEnabled())

        LOG.step('Setting initiator group name to maximal + 1 length: %s' %
                 (newName + 'Y'))
        wizard.renameInitiatorGroupPage.renameInitiatorGroup(name=newName +
                                                             'Y')
        LOG.info('New name:', wizard.activePage.txtName.getText())

        LOG.step('Verifying name error message')
        wizard.activePage.lblNameError.waitUntilVisible()
        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 initiator group name to contain Unicode characters.
        """
        initiatorGroupCount = 3
        initiatorGroupPrefix = 'IG'
        newName = u'Fran\u00e7ais'
        initiatorGroups = self.createInitiatorGroups(
            prefix=initiatorGroupPrefix, number=initiatorGroupCount)

        self.initiatorGroupsPage.btnRefresh.click()
        self.initiatorGroupsPage.btnRefresh.waitUntilEnabled()

        LOG.step("Changing initiator group name with: %s" % newName)
        wizard = RenameInitiatorGroupWizard(driver=self.driver)
        wizard.open(initiator_group=initiatorGroups[0])
        LOG.info('Old name:', wizard.activePage.txtName.getText())
        wizard.renameInitiatorGroupPage.renameInitiatorGroup(name=newName)
        LOG.info('New name:', wizard.activePage.txtName.getText())

        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_rename_mapped(self):
        """
            Verify rename of initiator group which is mapped to LUN.
        """
        lunName = 'LuN'
        lunSize = '1g'
        initiatorGroupCount = 3
        initiatorGroupPrefix = 'IG'
        newName = 'IG-New'

        LOG.step('Creating and mapping LUN')
        self.luns.create(count=1, size=lunSize, prefix=lunName)
        initiatorGroup = self.createInitiatorGroups(
            prefix=initiatorGroupPrefix, number=initiatorGroupCount)[0]
        self.marscluster.lun.map({
            'name': lunName + '_1',
            'igroup': initiatorGroup
        })
        luns = self.marscluster.lun.show(json=True)
        self.assertTrue(len(luns) == 1)
        self.assertTrue(len(luns[0]['maps']) == 1)
        self.assertTrue(luns[0]['maps'][0]['igroup-name'] == initiatorGroup)
        LOG.info("LUN '%s' mapped: %s" % (luns[0]['name'], luns[0]['maps']))

        self.initiatorGroupsPage.btnRefresh.click()
        self.initiatorGroupsPage.btnRefresh.waitUntilEnabled()

        LOG.step('Renaming initiator group in dialog')
        wizard = RenameInitiatorGroupWizard(driver=self.driver)
        wizard.open(initiator_group=initiatorGroup)
        LOG.info('Old name:', wizard.activePage.txtName.getText())
        wizard.renameInitiatorGroupPage.renameInitiatorGroup(name=newName)
        LOG.info('New name:', wizard.activePage.txtName.getText())
        wizard.renameInitiatorGroupPage.submit()
        LOG.info('Rename submitted.')

        LOG.step('Verifying initiator group name has been changed')
        initiatorGroups = [
            group['name'] for group in self.marscluster.igroup.show(json=True)
        ]
        self.assertTrue(newName in initiatorGroups)
        LOG.info("Name '%s' found in initiator groups list:\n%s" %
                 (newName, initiatorGroups))

    def test_dialog_cancel(self):
        """
            Verify initiator group name remains intact on dialog cancel.
        """
        initiatorGroupCount = 3
        initiatorGroupPrefix = 'IG'
        newName = 'IG-New'
        initiatorGroups = self.createInitiatorGroups(
            prefix=initiatorGroupPrefix, number=initiatorGroupCount)

        self.initiatorGroupsPage.btnRefresh.click()
        self.initiatorGroupsPage.btnRefresh.waitUntilEnabled()

        LOG.step('Renaming initiator group in dialog')
        wizard = RenameInitiatorGroupWizard(driver=self.driver)
        wizard.open(initiator_group=initiatorGroups[0])
        LOG.info('Old name:', wizard.activePage.txtName.getText())
        wizard.renameInitiatorGroupPage.renameInitiatorGroup(name=newName)
        LOG.info('New name:', wizard.activePage.txtName.getText())

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

        LOG.step('Verifying initiator group name has not been changed')
        initiatorGroups = [
            group['name'] for group in self.marscluster.igroup.show(json=True)
        ]
        self.assertTrue(newName not in initiatorGroups)
        LOG.info("Name '%s' is not found in initiator groups list:\n%s" %
                 (newName, initiatorGroups))

    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 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.')
Example #13
0
class TestCreateConsistencyGroupWizard(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.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 test_create_minimal(self):
        """
            Verify new consistency group creation when only name specified.
        """
        consistencyGroupName = 'cg1'

        LOG.step('Opening wizard')
        wizard = CreateConsistencyGroupWizard(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())
        candidates = wizard.activePage.gridCandidates.find()
        self.assertFalse(candidates)
        LOG.info('Candidates:', candidates)

        LOG.step('Setting consistency group name')
        wizard.activePage.setName(name=consistencyGroupName)
        name = wizard.activePage.txtName.getText()
        self.assertTrue(name == consistencyGroupName)
        LOG.info('Consistency group name set:', name)

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

        LOG.step('Verifying consistency group has been created')
        consistencyGroups = self.marscluster.cg.show(json=True)
        self.assertTrue(len(consistencyGroups) == 1)
        self.assertTrue(consistencyGroups[0]['name'] == consistencyGroupName)
        self.assertFalse(consistencyGroups[0]['members'])
        LOG.info('Consistency group created:', consistencyGroups[0]['name'])

    def test_create_mapped_lun(self):
        """
            Verify new consistency group creation with mapped LUNs.
        """
        lunNamePrefix = 'lun'
        lunCount = 5
        consistencyGroupName = 'cg1'

        LOG.step('Creating LUNs')
        for count in range(lunCount):
            self.marscluster.lun.create(name=lunNamePrefix + str(count),
                                        size='1g')
        luns = self.marscluster.lun.show(json=True)
        self.assertTrue(len(luns) == lunCount)
        LOG.info('LUNs created:', [lun['name'] for lun in luns])

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

        LOG.step('Verifying LUNs are present as candidates')
        candidates = [
            candidate['candidates']
            for candidate in wizard.activePage.getCandidates()
        ]
        self.assertTrue(len(candidates) == lunCount)
        for lun in luns:
            self.assertTrue(lun['name'] in candidates)
        LOG.info('Candidates:', candidates)

        LOG.step('Setting consistency group name')
        wizard.activePage.setName(name=consistencyGroupName)
        name = wizard.activePage.txtName.getText()
        self.assertTrue(name == consistencyGroupName)
        LOG.info('Consistency group name set:', name)

        LOG.step('Setting LUN as candidate to map')
        wizard.activePage.setCandidates(candidates=lunNamePrefix + '0')
        setCandidates = wizard.activePage.gridCandidates.find(selected=True)
        self.assertTrue(len(setCandidates) == 1)
        self.assertTrue(setCandidates[0]['candidates'] == lunNamePrefix + '0')
        LOG.info('Candidate set:', setCandidates[0]['candidates'])

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

        LOG.step('Verifying consistency group has been created')
        consistencyGroups = self.marscluster.cg.show(json=True)
        self.assertTrue(len(consistencyGroups) == 1)
        self.assertTrue(consistencyGroups[0]['name'] == consistencyGroupName)
        self.assertTrue(len(consistencyGroups[0]['members']) == 1)
        self.assertTrue(consistencyGroups[0]['members'][0]['name'] ==
                        consistencyGroupName + '/' + lunNamePrefix + '0')
        LOG.info('Consistency group has been created and mapped:',
                 consistencyGroups[0])

    def test_create_nested_cg(self):
        """
            Verify new consistency group creation with under another consistency group.
        """
        parentName = 'cgPr'
        childName = 'cgCh'

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

        self.consistencyGroupsPage.btnRefresh.click()
        self.consistencyGroupsPage.btnRefresh.waitUntilEnabled()

        LOG.step('Opening dialog with no consistency groups selected')
        self.consistencyGroupsPage.gridConsistencyGroups.unselect()
        self.assertFalse(
            self.consistencyGroupsPage.gridConsistencyGroups.find(
                selected=True))
        wizard = CreateConsistencyGroupWizard(driver=self.driver)
        wizard.open()
        self.assertFalse(wizard.activePage.lblSubtitle.isVisible())
        LOG.info('Wizard open.')

        LOG.step('Creating parent consistency group: %s' % parentName)
        wizard.activePage.setName(name=parentName)
        wizard.activePage.setCandidates(candidates=childName + '/')
        wizard.submit()
        LOG.info('Dialog closed.')

        LOG.step(
            'Verifying child consistency group has been added to parent one')
        consistencyGroups = self.marscluster.cg.show(json=True)
        parentConsistencyGroup = [
            consistencyGroup for consistencyGroup in consistencyGroups
            if consistencyGroup['name'] == parentName
        ][0]
        self.assertTrue(len(parentConsistencyGroup['members']) == 1)
        self.assertTrue(
            parentConsistencyGroup['members'][0]['name'] == parentName + '/' +
            childName)
        LOG.info('Parent consistency group has been created:',
                 parentConsistencyGroup)

    def test_create_nested_cg_selected(self):
        """
            Verify new consistency group creation under another consistency group selected in grid.
        """
        parentName = 'cgPr'
        childName = 'cgCh'

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

        self.consistencyGroupsPage.btnRefresh.click()
        self.consistencyGroupsPage.btnRefresh.waitUntilEnabled()

        LOG.step('Opening dialog with parent consistency groups selected')
        wizard = CreateConsistencyGroupWizard(driver=self.driver)
        wizard.open(parentConsistencyGroup=parentName)
        self.assertTrue(wizard.activePage.lblSubtitle.getText() == parentName)
        LOG.info('Wizard open.')

        LOG.step('Creating child consistency group: %s' % childName)
        wizard.activePage.setName(name=childName)
        wizard.submit()
        LOG.info('Dialog closed.')

        LOG.step(
            'Verifying child consistency group has been added to parent one')
        consistencyGroups = self.marscluster.cg.show(json=True)
        parentConsistencyGroup = [
            consistencyGroup for consistencyGroup in consistencyGroups
            if consistencyGroup['name'] == parentName
        ][0]
        self.assertTrue(len(parentConsistencyGroup['members']) == 1)
        self.assertTrue(
            parentConsistencyGroup['members'][0]['name'] == parentName + '/' +
            childName)
        LOG.info('Parent consistency group has been created:',
                 parentConsistencyGroup)

    def test_dialog_cancel(self):
        """
            Verify closing dialog without submission has no effect.
        """
        consistencyGroupName = 'cg1'

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

        LOG.step('Setting name for new consistency group')
        wizard.activePage.setName(name=consistencyGroupName)
        self.assertTrue(
            wizard.activePage.txtName.getText() == consistencyGroupName)
        LOG.info('Consistency group name set:',
                 wizard.activePage.txtName.getText())

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

        LOG.step('Verifying no consistency group has been created')
        consistencyGroups = self.marscluster.cg.show(json=True)
        self.assertFalse(consistencyGroups)
        LOG.info('Consistency groups:', consistencyGroups)

    def test_dialog_not_available(self):
        """
            Verify dialog is not available when 2 or more consistency groups selected in grid.
        """
        namePrefix = 'cg'
        consistencyGroupsNumber = 5

        LOG.step('Creating multiple consistency groups')
        for count in range(consistencyGroupsNumber):
            self.marscluster.cg.create(name=namePrefix + str(count))
        consistencyGroups = self.marscluster.cg.show(json=True)
        self.assertTrue(len(consistencyGroups) == consistencyGroupsNumber)
        LOG.info('Consistency groups created:', [
            consistencyGroup['name'] for consistencyGroup in consistencyGroups
        ])

        self.consistencyGroupsPage.btnRefresh.click()
        self.consistencyGroupsPage.btnRefresh.waitUntilEnabled()

        LOG.step('Selecting multiple consistency groups in grid')
        self.consistencyGroupsPage.gridConsistencyGroups.select(
            name=[namePrefix + '0', namePrefix + '3'])
        selectedConsistencyGroups = \
            self.consistencyGroupsPage.gridConsistencyGroups.find(selected=True)
        self.assertTrue(len(selectedConsistencyGroups) == 2)
        LOG.info('Consistency groups selected in grid:', [
            consistencyGroup['name']
            for consistencyGroup in selectedConsistencyGroups
        ])

        LOG.step('Verifying dialog is not available for given selection')
        self.assertFalse(
            self.consistencyGroupsPage.menuCreate.isItemEnabled(
                item='Consistency group'))
        LOG.info(
            'Dialog is available:',
            self.consistencyGroupsPage.menuCreate.isItemEnabled(
                item='Consistency group'))

    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
        consistencyGroups = self.marscluster.cg.show(json=True)
        for consistencyGroup in consistencyGroups:
            self.marscluster.cg.delete(name=consistencyGroup['name'])
        self.assertFalse(self.marscluster.cg.show(json=True))
Example #14
0
class TestResizeLUNWizard(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.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_size(self):
        """
            Verify LUN resizing with valid size.
        """
        LOG.step('Creating LUNs')
        lunCount = 3
        lunOldSize = 2
        lunNewSize = 10
        lunSizeUnit = 'G'
        lunNamePrefix = 'LuN'
        self.luns.create(count=lunCount, size=str(lunOldSize) + 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('Resizing LUN in dialog')
        wizard = ResizeLUNWizard(driver=self.driver, locale=self.locale)
        wizard.open(name=lunNamePrefix + '_1')

        LOG.info('Old LUN size:', str(lunOldSize) + lunSizeUnit)
        wizard.resizeLUNPage.resizeLUN(size=str(lunNewSize) + lunSizeUnit)
        LOG.info('New LUN size:', wizard.resizeLUNPage.txtSize.getText() +
            wizard.resizeLUNPage.dLstSizeUnit.getText())
        wizard.resizeLUNPage.submit()
        LOG.info('Resize submitted.')

        LOG.step('Verifying LUN size has been changed as specified')
        luns = self.lunsPage.gridLUNs.find(name=lunNamePrefix + '_1')
        self.assertTrue(len(luns) == 1)
        resultSize = float(Utility.getSizeValue(size=luns[0]['size']).replace(',', '.'))
        resultSizeUnit = Utility.getSizeUnit(size=luns[0]['size'])
        self.assertTrue(resultSize == lunNewSize)
        self.assertTrue(resultSizeUnit == lunSizeUnit)
        LOG.info('LUN found: name=%s, size=%s.' % (luns[0]['name'], luns[0]['size']))

    def test_invalid_size(self):
        """
            Verify error message on LUN resizing with invalid size.
            Verify LUN size remains intact.
        """
        LOG.step('Creating LUNs')
        lunCount = 3
        lunOldSize = 104857600
        lunNamePrefix = 'LuN'
        lunNewSize = '65t'
        self.luns.create(count=lunCount, size=lunOldSize, 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('Setting new LUN size in dialog')
        wizard = ResizeLUNWizard(driver=self.driver, locale=self.locale)
        wizard.open(name=lunNamePrefix + '_1')
        wizard.resizeLUNPage.resizeLUN(size=lunNewSize)
        LOG.info('New LUN size:', wizard.resizeLUNPage.txtSize.getText() +
            wizard.resizeLUNPage.dLstSizeUnit.getText())
        self.assertTrue(wizard.activePage.lblSizeError.isVisible())
        LOG.info('Error message displayed:',
            wizard.activePage.lblSizeError.getText())
        self.assertFalse(wizard.activePage.btnOK.isEnabled())
        LOG.info("Button 'OK' is enabled:", wizard.activePage.btnOK.isEnabled())

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

        LOG.step('Verifying no changes have been made for LUNs sizes')
        self.lunsPage.btnRefresh.click()
        self.lunsPage.btnRefresh.waitUntilEnabled()
        for lun in self.marscluster.lun.show(json=True):
            self.assertTrue(lun['size'] == lunOldSize)
            LOG.info("LUN '%s': size %s is intact." % (lun['name'], lun['size']))

    def test_terminal_size(self):
        """
            Test verifies LUN resizing to 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 LUNs with size unit '%s'" % sizeUnit)
            if sizeUnit not in ['B', 'K']:
                self.marscluster.lun.create(name=nameLow, size='0.5k')
            self.marscluster.lun.create(name=nameHigh, size='0.5k')
            luns = self.marscluster.lun.show(json=True)
            LOG.info('LUNs created:\n', luns)

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

            # Skip assigning the same size with low size units. Reducing LUN size is not available.
            if sizeUnit not in ['B', 'K']:
                LOG.step("Opening wizard for LUN '%s'" % nameLow)
                wizard = ResizeLUNWizard(driver=self.driver, locale=self.locale)
                wizard.open(name=nameLow)
                LOG.info('Wizard opened.')

                LOG.step("Modifying LUN size to be minimal: size='%s'" % sizeLow)
                wizard.activePage.resizeLUN(size=sizeLow)
                wizard.activePage.submit()
                LOG.info('Resize 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 for LUN '%s'" % nameHigh)
            wizard = ResizeLUNWizard(driver=self.driver, locale=self.locale)
            wizard.open(name=nameHigh)
            LOG.info('Wizard opened.')

            LOG.step("Modifying LUN size to be maximal: size='%s'" % sizeHigh)
            wizard.activePage.resizeLUN(size=sizeHigh)
            wizard.activePage.submit()
            LOG.info('Resize submitted.')

            lunsToCreate[nameHigh] = sizes[sizeUnit]['high'] * sizes[sizeUnit]['multiplier']
            createdLUNs = self.marscluster.lun.show(json=True)

            LOG.step('Verifying modified LUN size 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('Cleaning up LUNs')
            luns = express.Luns(node=self.marscluster, cleanup=True)
            del luns
            LOG.info('LUNs destroyed.')

    def test_same_size(self):
        """
            Verify error message on LUN resizing with the same (initial) size.
            Verify LUN size remain intact.
        """
        LOG.step('Creating LUN')
        lunName = 'LuN'
        lunSize = 104857600
        self.marscluster.lun.create(name=lunName, size=lunSize)
        LOG.info('LUNs created:\n', self.marscluster.lun.show(json=True))

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

        LOG.step('Setting same LUN size in dialog')
        wizard = ResizeLUNWizard(driver=self.driver, locale=self.locale)
        wizard.open(name=lunName)
        wizard.resizeLUNPage.resizeLUN(size=str(lunSize) + 'B')
        LOG.info('New LUN size:', wizard.resizeLUNPage.txtSize.getText() +
            wizard.resizeLUNPage.dLstSizeUnit.getText())
        wizard.activePage.btnOK.click()

        LOG.info('Dialog title notifies failure:', wizard.activePage.lblTitle.getText())
        self.assertTrue(wizard.activePage.lblSameSizeError.isVisible())
        LOG.info('Error message displayed:', wizard.activePage.lblSameSizeError.getText())
        self.assertFalse(wizard.activePage.btnOK.isEnabled())
        LOG.info("Button 'OK' is enabled:", wizard.activePage.btnOK.isEnabled())

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

        LOG.step('Verifying no change have been made for LUN size')
        luns = self.marscluster.lun.show(json=True)
        self.assertTrue(len(luns) == 1)
        self.assertTrue(luns[0]['size'] == lunSize)
        LOG.info("LUN '%s': size %s is intact." % (luns[0]['name'], luns[0]['size']))

    def test_dialog_cancel(self):
        """
            Verify LUN size remains intact on dialog canceling.
        """
        LOG.step('Creating LUNs')
        lunCount = 3
        lunOldSize = 104857600
        lunNamePrefix = 'LuN'
        lunNewSize = '1t'
        self.luns.create(count=lunCount, size=lunOldSize, 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('Setting new LUN size in dialog')
        wizard = ResizeLUNWizard(driver=self.driver, locale=self.locale)
        wizard.open(name=lunNamePrefix + '_1')
        wizard.resizeLUNPage.resizeLUN(size=lunNewSize)
        LOG.info('New LUN size:', wizard.resizeLUNPage.txtSize.getText() +
            wizard.resizeLUNPage.dLstSizeUnit.getText())

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

        LOG.step('Verifying no changes have been made for LUNs sizes')
        self.lunsPage.btnRefresh.click()
        self.lunsPage.btnRefresh.waitUntilEnabled()
        for lun in self.marscluster.lun.show(json=True):
            self.assertTrue(lun['size'] == lunOldSize)
            LOG.info("LUN '%s': size %s is intact." % (lun['name'], lun['size']))

    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()
Example #15
0
class TestDeleteInitiatorGroupWizard(FRTestCase):
    """
        In fact, there is no such a wizard as 'Delete Initiator Group', this is just function on
          clicking button 'Delete'.
    """
    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_delete_single(self):
        """
            Verify deletion of single unmapped initiator group.
        """
        initiatorGroupPrefix = 'IG'
        initiatorGroupNumber = 5

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

        self.initiatorGroupsPage.btnRefresh.click()
        self.initiatorGroupsPage.btnRefresh.waitUntilEnabled()

        LOG.step('Selecting initiator group in grid')
        self.initiatorGroupsPage.gridInitiatorGroups.select(
            initiator_group=initiatorGroupNames[0])
        selectedGroups = self.initiatorGroupsPage.gridInitiatorGroups.find(
            selected=True)
        self.assertTrue(len(selectedGroups) == 1)
        self.assertTrue(
            selectedGroups[0]['initiator_group'] == initiatorGroupNames[0])
        LOG.info('Initiator group selected:', initiatorGroupNames[0])

        LOG.step('Deleting and verifying initiator group has been deleted')
        self.initiatorGroupsPage.btnDelete.click()
        initiatorGroups = self.marscluster.igroup.show(json=True)
        self.assertTrue(len(initiatorGroups) == initiatorGroupNumber - 1)
        self.assertFalse(initiatorGroupNames[0] in
                         [group['name'] for group in initiatorGroups])
        LOG.info(
            "Initiator group '%s' is not present:\n" %
            initiatorGroupNames[0].encode('utf-8'), initiatorGroups)

    def test_delete_multi(self):
        """
            Verify deletion of multiple unmapped initiator groups.
        """
        initiatorGroupPrefix = 'IG'
        initiatorGroupNumber = 9

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

        self.initiatorGroupsPage.btnRefresh.click()
        self.initiatorGroupsPage.btnRefresh.waitUntilEnabled()

        LOG.step('Selecting initiator groups in grid')
        self.initiatorGroupsPage.gridInitiatorGroups.select(
            initiator_group=initiatorGroupNames[:initiatorGroupNumber / 2])
        selectedGroups = self.initiatorGroupsPage.gridInitiatorGroups.find(
            selected=True)
        self.assertTrue(len(selectedGroups) == initiatorGroupNumber / 2)
        LOG.info('Initiator group selected:', selectedGroups)

        LOG.step('Deleting and verifying initiator group has been deleted')
        self.initiatorGroupsPage.btnDelete.click()
        # Give some time to perform operation
        time.sleep(2)
        initiatorGroupNames = [
            group['name'] for group in self.marscluster.igroup.show(json=True)
        ]
        self.assertTrue(
            len(initiatorGroupNames) == initiatorGroupNumber -
            (initiatorGroupNumber / 2))
        for group in selectedGroups:
            self.assertFalse(group['initiator_group'] in initiatorGroupNames)
            LOG.info('Initiator group is not present:',
                     group['initiator_group'])

    def test_delete_mapped(self):
        """
            Verify warning when initiator group with mapped LUN is getting deleted.
        """
        lunName = 'lun1'
        initiatorGroupName = 'ig1'

        LOG.step('Creating initiator group')
        fictiveWWPN = format(random.randrange(sys.maxint), 'x').rjust(16, 'f')
        self.marscluster.igroup.create(name=initiatorGroupName,
                                       ostype='windows',
                                       initiators=fictiveWWPN)
        initiatorGroups = self.marscluster.igroup.show(json=True)
        self.assertTrue(len(initiatorGroups) == 1)
        LOG.info('Initiator group created:\n', initiatorGroups[0])

        LOG.step('Creating and mapping LUN')
        self.marscluster.lun.create(name=lunName, size='1g')
        self.marscluster.lun.map(name=lunName,
                                 igroup=initiatorGroups[0]['name'])
        luns = self.marscluster.lun.show(json=True)
        self.assertTrue(len(luns) == 1)
        self.assertTrue(len(luns[0]['maps']) == 1)
        self.assertTrue(
            luns[0]['maps'][0]['igroup-name'] == initiatorGroupName)
        LOG.info('LUN created:\n', luns[0])

        self.initiatorGroupsPage.btnRefresh.click()
        self.initiatorGroupsPage.btnRefresh.waitUntilEnabled()

        LOG.step('Deleting initiator group: %s' % initiatorGroupName)
        self.initiatorGroupsPage.gridInitiatorGroups.select(
            initiator_group=initiatorGroupName)
        self.initiatorGroupsPage.btnDelete.click()
        deleteMappedInitiatorGroupPage = DeleteMappedInitiatorGroupPage(
            driver=self.driver)
        deleteMappedInitiatorGroupPage.waitUntilOpen()
        LOG.info('Warning message window open:',
                 deleteMappedInitiatorGroupPage.lblTitle.getText())
        deleteMappedInitiatorGroupPage.btnClose.click()

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

    def test_delete_multi_mapped(self):
        """
            Verify warning when multiple initiator groups with mapped LUNs are getting deleted.
        """
        initiatorGroupPrefix = 'ig'
        initiatorGroupNumber = 3
        lunsPrefix = 'lun'

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

        LOG.step('Creating and mapping LUNs')
        self.luns.create(count=initiatorGroupNumber,
                         size='1g',
                         prefix=lunsPrefix)
        luns = self.marscluster.lun.show(json=True)
        self.assertTrue(len(luns) == initiatorGroupNumber)
        LOG.info('LUNs created:\n', luns)
        for count in range(len(luns)):
            self.marscluster.lun.map(name=luns[count]['name'],
                                     igroup=initiatorGroupNames[count])
        luns = self.marscluster.lun.show(json=True)
        for count in range(len(luns)):
            self.assertTrue(len(luns[count]['maps']) == 1)
            self.assertTrue(luns[count]['maps'][0]['igroup-name'] ==
                            initiatorGroupNames[count])
        LOG.info('LUNs mapped to initiator groups:\n',
                 [(lun['name'], lun['maps']) for lun in luns])

        self.initiatorGroupsPage.btnRefresh.click()
        self.initiatorGroupsPage.btnRefresh.waitUntilEnabled()

        LOG.step('Deleting all initiator groups at once: %s' %
                 initiatorGroupNames)
        self.initiatorGroupsPage.gridInitiatorGroups.select(
            initiator_group=initiatorGroupNames)
        self.initiatorGroupsPage.btnDelete.click()
        deleteMappedInitiatorGroupPage = DeleteMappedInitiatorGroupPage(
            driver=self.driver)
        deleteMappedInitiatorGroupPage.waitUntilOpen()
        LOG.info('Warning message window open:',
                 deleteMappedInitiatorGroupPage.lblTitle.getText())
        deleteMappedInitiatorGroupPage.btnClose.click()

        LOG.step('Verifying initiator groups have not been deleted')
        initiatorGroups = self.marscluster.igroup.show(json=True)
        self.assertTrue(len(initiatorGroups) == initiatorGroupNumber)
        LOG.info('Initiator groups exist:', initiatorGroups)

    def test_delete_multi_mixed(self):
        """
            Verify warning when at least one of multiple selected initiator groups has mapping with
              LUN.
        """
        initiatorGroupPrefix = 'ig'
        initiatorGroupNumber = 3
        lunName = 'lun1'

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

        LOG.step('Creating LUN')
        self.marscluster.lun.create(name=lunName, size='1g')
        luns = self.marscluster.lun.show(json=True)
        self.assertTrue(len(luns) == 1)
        LOG.info('LUN created:\n', luns[0])

        LOG.step('Mapping LUN to one of initiator groups')
        self.marscluster.lun.map(name=lunName, igroup=initiatorGroupNames[0])
        lun = self.marscluster.lun.show(json=True)[0]
        self.assertTrue(len(lun['maps']) == 1)
        self.assertTrue(
            lun['maps'][0]['igroup-name'] == initiatorGroupNames[0])
        LOG.info("LUN '%s' mapped to initiator group: %s" %
                 (lun['name'], lun['maps'][0]['igroup-name']))

        self.initiatorGroupsPage.btnRefresh.click()
        self.initiatorGroupsPage.btnRefresh.waitUntilEnabled()

        LOG.step('Deleting all initiator groups at once: %s' %
                 initiatorGroupNames)
        self.initiatorGroupsPage.gridInitiatorGroups.select(
            initiator_group=initiatorGroupNames)
        self.initiatorGroupsPage.btnDelete.click()
        deleteMappedInitiatorGroupPage = DeleteMappedInitiatorGroupPage(
            driver=self.driver)
        deleteMappedInitiatorGroupPage.waitUntilOpen()
        LOG.info('Warning message window open:',
                 deleteMappedInitiatorGroupPage.lblTitle.getText())
        deleteMappedInitiatorGroupPage.btnClose.click()

        LOG.step('Verifying initiator groups have not been deleted')
        initiatorGroups = self.marscluster.igroup.show(json=True)
        self.assertTrue(len(initiatorGroups) == initiatorGroupNumber)
        LOG.info('Initiator groups exist:', initiatorGroups)

    def test_delete_not_available(self):
        """
            Verify deletion is not available when no initiator groups selected in grid.
        """
        initiatorGroupPrefix = 'ig'
        initiatorGroupNumber = 3

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

        self.initiatorGroupsPage.btnRefresh.click()
        self.initiatorGroupsPage.btnRefresh.waitUntilEnabled()

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

        LOG.step("Verifying button 'Delete' is disabled in tool bar")
        self.assertFalse(self.initiatorGroupsPage.btnDelete.isEnabled())
        LOG.info("Button 'Delete' is enabled:",
                 self.initiatorGroupsPage.btnDelete.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, 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