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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    def suiteTeardown(self):
        LOG.step('Closing browser')
        self.driver.quit()
        self.marscluster.snapshot.deleteAll()
        luns = express.Luns(node=self.marscluster, cleanup=True)
        del luns
        LOG.info('LUNs & snapshots cleaned up.')
class 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()
Exemple #3
0
class TestComponentDropDownList(FRTestCase):
    def suiteSetup(self):
        self.username = ARGS.values.username
        self.password = ARGS.values.password
        self.webUIHostName = getFQDN(self.mars[0].hostname)

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    def testTeardown(self):
        self.driver.quit()
class 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.')
Exemple #5
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 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
Exemple #7
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()
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 TestComponentMenu(FRTestCase):
    def suiteSetup(self):
        self.username = ARGS.values.username
        self.password = ARGS.values.password
        self.webUIHostName = getFQDN(self.mars[0].hostname)

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

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

        LOG.step("Getting item list of menu 'Locale'")
        LOG.info('Menu items:\n', self.loginPage.menuLocale.getItems())

        LOG.step('Selecting locale menu item')
        self.loginPage.selectLocale(locale=ARGS.values.locale)
        LOG.info('Locale hypertext reference:',
            self.loginPage.menuLocale.getAttribute(attributeName='href'))

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

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

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

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

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

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

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

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

    def testTeardown(self):
        self.driver.quit()
class 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()
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()
Exemple #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.')
Exemple #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))
Exemple #14
0
class TestComponentBasic(FRTestCase):
    def suiteSetup(self):
        self.username = ARGS.values.username
        self.password = ARGS.values.password
        self.webUIHostName = getFQDN(self.mars[0].hostname)

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

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

        LOG.step("Getting text of label 'Product Name'")
        LOG.info('Product name:', self.loginPage.lblProductName.getText())

        LOG.step("Getting text of label 'Product Version'")
        LOG.info('Product version:', self.loginPage.lblProductVersion.getText())

        LOG.step('Typing username')
        self.loginPage.txtUsername.setText(self.username)
        self.assertTrue(self.loginPage.txtUsername.getText() == self.username)
        LOG.info('Username:'******'Typing password')
        self.loginPage.txtPassword.waitUntilPresent()
        self.loginPage.txtPassword.setText(self.password)
        self.assertTrue(self.loginPage.txtPassword.getText() == self.password)
        LOG.info('Password:'******'Sign In'")
        self.loginPage.btnSignIn.waitUntilPresent()
        self.loginPage.btnSignIn.waitUntilEnabled()
        LOG.info('Button is present:', self.loginPage.btnSignIn.isPresent())
        LOG.info('Button is enabled:', self.loginPage.btnSignIn.isEnabled())
        LOG.info('Button is visible:', self.loginPage.btnSignIn.isVisible())

        LOG.step("Getting text of button 'Sign In'")
        LOG.info('Button text:', self.loginPage.btnSignIn.getText())

        LOG.step("Clicking on button 'Sign In'")
        self.loginPage.btnSignIn.click()

        LOG.step("Expecting button 'Manager' on header page")
        self.headerPage.btnManager.waitUntilPresent()
        LOG.info('Button is present:', self.headerPage.btnManager.isPresent())
        self.headerPage.btnManager.waitUntilEnabled()
        LOG.info('Button is enabled:', self.headerPage.btnManager.isEnabled())
        LOG.info('Button is visible:', self.headerPage.btnManager.isVisible())

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

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

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

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

        LOG.step("Getting state of check box 'Add to a consistency group'")
        checkBoxState = self.defineLUNsPage.chkAddToConsistencyGroup.isSelected()
        LOG.info('Check box is selected:', checkBoxState)

        LOG.step('Inverting state of check box')
        self.defineLUNsPage.chkAddToConsistencyGroup.setState(select=(not checkBoxState))
        self.assertTrue(self.defineLUNsPage.chkAddToConsistencyGroup.isSelected() == (not checkBoxState))
        LOG.info('Check box is selected:', self.defineLUNsPage.chkAddToConsistencyGroup.isSelected())

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

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

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

    def testTeardown(self):
        self.driver.quit()
class TestLoginPage(FRTestCase):
    def suiteSetup(self):
        self.username = ARGS.values.username
        self.invalidUsername = ARGS.values.invalidusername
        self.password = ARGS.values.password
        self.invalidPassword = ARGS.values.invalidpassword
        self.locale = ARGS.values.locale
        self.webUIHostName = getFQDN(self.marscluster.getMasterNode().hostname)

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

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

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

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

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

        LOG.step('Validating help links availability')

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

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

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

        LOG.step('Validating company branding availability')

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

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

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

        LOG.step('Validating input controls availability')

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

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

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

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

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

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

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

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

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

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

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

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

        LOG.step('Logging out web page')

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

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

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

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

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

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

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

    def test_blank_inputs(self):
        self._testInvalidInputs()

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

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

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

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

        self.loginPage.txtPassword.clear()

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

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

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

            LOG.step("Expecting login failed dialog")

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

            LOG.step('Closing login failed dialog')

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

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

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

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

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

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

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

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

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

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

        LOG.step('Verifying LUN state')

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    def suiteTeardown(self):
        LOG.step('Closing browser')
        self.driver.quit()
class 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.')
Exemple #18
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 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.')
Exemple #20
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