예제 #1
0
    def open(self, name):
        """
            Select LUN in grid by given name, then set name of new snapshot.
            @param name: Name of LUN which to select in grid.
        """
        lunsPage = LUNsPage(driver=self.driver)
        lunsPage.waitUntilOpen()
        # In LUNs grid, select row with given LUN name by checking row check box.
        lunsPage.gridLUNs.unselect()
        lunsPage.gridLUNs.select(name=name)

        # In menu 'Create', select item 'Snapshot copy'.
        lunsPage.menuCreate.select(item='Snapshot copy')
        self.createSnapshotPage.waitUntilOpen()

        self.activePageNumber = 0
        self.activePage = self._pages[self._pages.keys()[self.activePageNumber]]
        LOG.l4('%s.open()' % self.name)
    def open(self, name):
        """
            Select LUN in grid by given name, then open 'Clone a LUN' dialog.
            @param name: Name of LUN which to select in grid.
        """
        lunsPage = LUNsPage(driver=self.driver)
        lunsPage.waitUntilOpen()
        # In LUNs grid, select row with given LUN name by checking row check box.
        lunsPage.gridLUNs.unselect()
        lunsPage.gridLUNs.select(name=name)
        lunsPage.btnClone.click()

        self.cloneLUNPage.waitUntilOpen()

        self.activePageNumber = 0
        self.activePage = self._pages[self._pages.keys()[
            self.activePageNumber]]
        LOG.l4("%s.open(name='%s')" % (self.name, name))
    def open(self, name):
        """
            Select LUN in grid by given name, then open rename dialog.
            @param name: Name of LUN which to select in grid.
        """
        lunsPage = LUNsPage(driver=self.driver)
        lunsPage.waitUntilOpen()
        # In LUNs grid, select row with given LUN name by checking row check box.
        lunsPage.gridLUNs.unselect()
        lunsPage.gridLUNs.select(name=name)
        # In menu 'Edit', select item 'Name'.
        lunsPage.menuEdit.select(item='Name')

        self.renameLUNPage.waitUntilOpen()

        self.activePageNumber = 0
        self.activePage = self._pages[self._pages.keys()[
            self.activePageNumber]]
        LOG.l4("%s.open(name='%s')" % (self.name, name))
class TestRenameLUNSnapshotWizard(FRTestCase):
    def suiteSetup(self):
        self.username = ARGS.values.username
        self.password = ARGS.values.password
        self.locale = ARGS.values.locale
        self.webUIHostName = getFQDN(self.marscluster.getMasterNode().hostname)

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

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

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

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

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

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

    def test_valid_name(self):
        """
            Verify LUN snapshot renaming with valid name.
        """
        lunNamePrefix = 'LuN'
        lunName = lunNamePrefix + '_1'
        snapshotName = lunName + '_snap_0'
        snapshotNewName = snapshotName + '.m'

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

        LOG.step('Creating LUN snapshot')
        self.marscluster.snapshot.create(luns=lunName, name=snapshotName)
        snapshots = self.marscluster.snapshot.show(json=True)
        snapshot = [
            snapshot for snapshot in snapshots
            if (snapshot['name'] == snapshotName
                and snapshot['object'] == lunName)
        ][0]
        snapshotUUID = snapshot['uuid']
        LOG.info('Snapshot created:\n', snapshot)

        LOG.step("LUN '%s': Opening Snapshots page" % lunName)
        lunSnapshotsPage = LUNSnapshotsPage(
            driver=self.driver,
            url=self.webUIHostName +
            ('/#manager/storage/allstorage/luns/%s/snapshot' % lunName))
        lunSnapshotsPage.open()
        lunSnapshotsPage.waitUntilOpen()
        LOG.info('LUN Snapshots page is open.')

        LOG.step('Renaming LUN snapshot in dialog')
        wizard = RenameLUNSnapshotWizard(driver=self.driver)
        wizard.open(name=snapshotName)
        LOG.info('Old snapshot name:', snapshotName)
        wizard.renameLUNSnapshotPage.renameLUNSnapshot(name=snapshotNewName)
        LOG.info('New snapshot name:', snapshotNewName)
        wizard.renameLUNSnapshotPage.submit()
        LOG.info('Rename submitted.')

        LOG.step('Verifying LUN snapshot name has been changed')
        snapshots = self.marscluster.snapshot.show(json=True)
        snapshot = [
            snapshot for snapshot in snapshots
            if snapshot['uuid'] == snapshotUUID
        ][0]
        self.assertTrue(snapshot['name'] == snapshotNewName)
        LOG.info('LUN snapshot has been renamed:\n', snapshot)

    def test_invalid_name(self):
        """
            Verify LUN snapshot renaming with invalid name.
        """
        lunNamePrefix = 'LuN'
        lunName = lunNamePrefix + '_1'
        snapshotName = lunName + '_snap_0'
        snapshotNewName = snapshotName + '*&#@1A_^?,'

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

        LOG.step('Creating LUN snapshot')
        self.marscluster.snapshot.create(luns=lunName, name=snapshotName)
        snapshots = self.marscluster.snapshot.show(json=True)
        snapshot = [
            snapshot for snapshot in snapshots
            if (snapshot['name'] == snapshotName
                and snapshot['object'] == lunName)
        ][0]
        snapshotUUID = snapshot['uuid']
        LOG.info('Snapshot created:\n', snapshot)

        LOG.step("LUN '%s': Opening Snapshots page" % lunName)
        lunSnapshotsPage = LUNSnapshotsPage(
            driver=self.driver,
            url=self.webUIHostName +
            ('/#manager/storage/allstorage/luns/%s/snapshot' % lunName))
        lunSnapshotsPage.open()
        lunSnapshotsPage.waitUntilOpen()
        LOG.info('LUN Snapshots page is open.')

        LOG.step('Renaming LUN snapshot in dialog')
        wizard = RenameLUNSnapshotWizard(driver=self.driver)
        wizard.open(name=snapshotName)
        LOG.info('Old snapshot name:', snapshotName)
        wizard.renameLUNSnapshotPage.renameLUNSnapshot(name=snapshotNewName)
        LOG.info('New snapshot name:', snapshotNewName)

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

        LOG.step('Verifying LUN snapshot has not been renamed')
        snapshots = self.marscluster.snapshot.show(json=True)
        snapshot = [
            snapshot for snapshot in snapshots
            if snapshot['uuid'] == snapshotUUID
        ][0]
        self.assertTrue(snapshot['name'] == snapshotName)
        LOG.info('LUN snapshot has not been renamed:\n', snapshot)

    def test_unicode_name(self):
        """
            Verify error message on setting LUN snapshot name containing Unicode characters.
        """
        lunNamePrefix = 'LuN'
        lunName = lunNamePrefix + '_1'
        snapshotName = lunName + '_snap_0'
        snapshotNewName = snapshotName + u'Fran\u00e7ais'

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

        LOG.step('Creating LUN snapshot')
        self.marscluster.snapshot.create(luns=lunName, name=snapshotName)
        snapshots = self.marscluster.snapshot.show(json=True)
        snapshot = [
            snapshot for snapshot in snapshots
            if (snapshot['name'] == snapshotName
                and snapshot['object'] == lunName)
        ][0]
        snapshotUUID = snapshot['uuid']
        LOG.info('Snapshot created:\n', snapshot)

        LOG.step("LUN '%s': Opening Snapshots page" % lunName)
        lunSnapshotsPage = LUNSnapshotsPage(
            driver=self.driver,
            url=self.webUIHostName +
            ('/#manager/storage/allstorage/luns/%s/snapshot' % lunName))
        lunSnapshotsPage.open()
        lunSnapshotsPage.waitUntilOpen()
        LOG.info('LUN Snapshots page is open.')

        LOG.step('Renaming LUN snapshot in dialog')
        wizard = RenameLUNSnapshotWizard(driver=self.driver)
        wizard.open(name=snapshotName)
        LOG.info('Old snapshot name:', snapshotName)
        wizard.renameLUNSnapshotPage.renameLUNSnapshot(name=snapshotNewName)
        LOG.info('New snapshot name:', snapshotNewName)

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

        LOG.step('Verifying LUN snapshot has not been renamed')
        snapshots = self.marscluster.snapshot.show(json=True)
        snapshot = [
            snapshot for snapshot in snapshots
            if snapshot['uuid'] == snapshotUUID
        ][0]
        self.assertTrue(snapshot['name'] == snapshotName)
        LOG.info('LUN snapshot has not been renamed:\n', snapshot)

    def test_dialog_not_available(self):
        lunNamePrefix = 'LuN'
        lunName = lunNamePrefix + '_1'
        snapshotName = lunName + '_snap_0'

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

        LOG.step('Creating LUN snapshot')
        self.marscluster.snapshot.create(luns=lunName, name=snapshotName)
        snapshots = self.marscluster.snapshot.show(json=True)
        snapshot = [
            snapshot for snapshot in snapshots
            if (snapshot['name'] == snapshotName
                and snapshot['object'] == lunName)
        ][0]
        snapshotUUID = snapshot['uuid']
        LOG.info('Snapshot created:\n', snapshot)

        LOG.step("LUN '%s': Opening Snapshots page" % lunName)
        lunSnapshotsPage = LUNSnapshotsPage(
            driver=self.driver,
            url=self.webUIHostName +
            ('/#manager/storage/allstorage/luns/%s/snapshot' % lunName))
        lunSnapshotsPage.open()
        lunSnapshotsPage.waitUntilOpen()
        LOG.info('LUN Snapshots page is open.')

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

        LOG.step("Verifying menu 'Edit' is unavailable")
        self.assertFalse(lunSnapshotsPage.menuEdit.isEnabled())
        LOG.info("Menu 'Edit' is enabled:",
                 lunSnapshotsPage.menuEdit.isEnabled())

    def test_dialog_cancel(self):
        """
            Verify LUN snapshot name remains intact on dialog cancel.
        """
        lunNamePrefix = 'LuN'
        lunName = lunNamePrefix + '_1'
        snapshotName = lunName + '_snap_0'
        snapshotNewName = snapshotName + '.m'

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

        LOG.step('Creating LUN snapshot')
        self.marscluster.snapshot.create(luns=lunName, name=snapshotName)
        snapshots = self.marscluster.snapshot.show(json=True)
        snapshot = [
            snapshot for snapshot in snapshots
            if (snapshot['name'] == snapshotName
                and snapshot['object'] == lunName)
        ][0]
        snapshotUUID = snapshot['uuid']
        LOG.info('Snapshot created:\n', snapshot)

        LOG.step("LUN '%s': Opening Snapshots page" % lunName)
        lunSnapshotsPage = LUNSnapshotsPage(
            driver=self.driver,
            url=self.webUIHostName +
            ('/#manager/storage/allstorage/luns/%s/snapshot' % lunName))
        lunSnapshotsPage.open()
        lunSnapshotsPage.waitUntilOpen()
        LOG.info('LUN Snapshots page is open.')

        LOG.step('Renaming LUN snapshot in dialog')
        wizard = RenameLUNSnapshotWizard(driver=self.driver)
        wizard.open(name=snapshotName)
        LOG.info('Old snapshot name:', snapshotName)
        wizard.renameLUNSnapshotPage.renameLUNSnapshot(name=snapshotNewName)
        self.assertTrue(wizard.activePage.txtName.getText() == snapshotNewName)
        LOG.info('New snapshot name:', snapshotNewName)

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

        LOG.step('Verifying LUN snapshot has not been renamed')
        snapshots = self.marscluster.snapshot.show(json=True)
        snapshot = [
            snapshot for snapshot in snapshots
            if snapshot['uuid'] == snapshotUUID
        ][0]
        self.assertTrue(snapshot['name'] == snapshotName)
        LOG.info('LUN snapshot has not been renamed:\n', snapshot)

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

    def suiteTeardown(self):
        self.driver.quit()
        LOG.info('Driver quit.')

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

        LOG.step('Destroying LUNs')
        luns = express.Luns(node=self.marscluster, cleanup=True)
        del luns
        LOG.info('LUNs destroyed.')
class 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()
예제 #7
0
class TestCloneLUNSnapshotWizard(FRTestCase):
    def suiteSetup(self):
        self.username = ARGS.values.username
        self.password = ARGS.values.password
        self.locale = ARGS.values.locale
        self.webUIHostName = getFQDN(self.marscluster.getMasterNode().hostname)

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    def suiteTeardown(self):
        LOG.step('Closing browser')
        self.driver.quit()
        LOG.info('Browser closed.')
예제 #9
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 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 TestEditLUNMappingsWizard(FRTestCase):
    def suiteSetup(self):
        self.username = ARGS.values.username
        self.password = ARGS.values.password
        self.locale = ARGS.values.locale
        self.webUIHostName = getFQDN(self.marscluster.getMasterNode().hostname)

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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