class TestChangeInitiatorsWizard(FRTestCase): def suiteSetup(self): self.username = ARGS.values.username self.password = ARGS.values.password self.locale = ARGS.values.locale self.webUIHostName = frutil.getFQDN( self.marscluster.getMasterNode().hostname) def testSetup(self): self.driver = self.getDriver() self.loginPage = LoginPage(driver=self.driver, url=self.webUIHostName) self.headerPage = HeaderPage(driver=self.driver) self.allStoragePage = AllStoragePage(driver=self.driver) self.initiatorGroupsPage = InitiatorGroupsPage(driver=self.driver) LOG.step('Cleaning out cluster content') LOG.info('Destroying LUNs...') luns = express.Luns(node=self.marscluster, cleanup=True) del luns self.assertFalse(self.marscluster.lun.show(json=True)) LOG.info('Done.') LOG.info('Destroying existing initiator groups...') self.marscluster.igroup.destroyAll() LOG.info('Done.') self.luns = express.Luns(node=self.marscluster) LOG.step('Signing in') self.loginPage.open() self.loginPage.waitUntilOpen() if self.locale is None: self.locale = self.loginPage.getRandomLocale() self.loginPage.signIn(username=self.username, password=self.password, locale=self.locale) LOG.info('Signed in with username: %s, password: %s, locale: %s.' % (self.username, self.password, self.locale)) LOG.info('Browser landed on header page.') LOG.info('Navigating to Initiator Groups page...') self.headerPage.btnManager.click() self.allStoragePage.tabInitiatorGroups.click() self.initiatorGroupsPage.waitUntilOpen() LOG.info('Browser landed on Initiator Groups page.') def test_verify_wwpns_not_assigned(self): """ Verify dialog shows WWPNs unselected in grid when they are not assigned to initiator group. """ initiatorGroupName = 'IG-1' LOG.step('Creating initiator group with no WWPNs assigned') self.marscluster.igroup.create(name=initiatorGroupName, ostype='vmware') initiatorGroups = self.marscluster.igroup.show(json=True) self.assertTrue(len(initiatorGroups) == 1) self.assertTrue(initiatorGroups[0]['name'] == initiatorGroupName) self.assertFalse(initiatorGroups[0]['initiators']) LOG.info('Initiator group created:\n', initiatorGroups[0]) self.initiatorGroupsPage.btnRefresh.click() self.initiatorGroupsPage.btnRefresh.waitUntilEnabled() LOG.step('Opening wizard') wizard = ChangeInitiatorsWizard(driver=self.driver) wizard.open(initiator_group=initiatorGroupName) LOG.info('Wizard open.') LOG.step('Verifying defaults') self.assertTrue(wizard.activePage.lblTitle.isVisible()) LOG.info('Title is visible:', wizard.activePage.lblTitle.getText()) self.assertTrue( wizard.activePage.lblSubtitle.getText() == initiatorGroupName) LOG.info('Initiator group name is visible:', wizard.activePage.lblSubtitle.getText()) LOG.step('Verifying no WWPNs assigned to initiator group') wwpns = wizard.activePage.gridInitiatorWWPNs.find(selected=True) selectedWWPNs = wizard.activePage.gridInitiatorWWPNs.find( selected=True) self.assertFalse(selectedWWPNs) LOG.info('Selected WWPNs:', selectedWWPNs) def test_verify_wwpns_assigned(self): """ Verify dialog shows WWPNs selected in grid when they are assigned to initiator group. """ initiatorGroupName = 'IG-1' LOG.step('Creating initiator group with WWPNs assigned') fictiveWWPNs = [] for _ in range(2): fictiveWWPNs.append(':'.join( re.findall( '..', format(random.randrange(sys.maxint), 'x').rjust(16, 'f')))) self.marscluster.igroup.create(name=initiatorGroupName, ostype='vmware', initiators=','.join(fictiveWWPNs)) initiatorGroups = self.marscluster.igroup.show(json=True) self.assertTrue(len(initiatorGroups) == 1) self.assertTrue(initiatorGroups[0]['name'] == initiatorGroupName) self.assertTrue(len(initiatorGroups[0]['initiators']) == 2) LOG.info('Initiator group created:\n', initiatorGroups[0]) self.initiatorGroupsPage.btnRefresh.click() self.initiatorGroupsPage.btnRefresh.waitUntilEnabled() LOG.step('Opening wizard') wizard = ChangeInitiatorsWizard(driver=self.driver) wizard.open(initiator_group=initiatorGroupName) LOG.info('Wizard open.') LOG.step('Verifying defaults') self.assertTrue(wizard.activePage.lblTitle.isVisible()) LOG.info('Title is visible:', wizard.activePage.lblTitle.getText()) self.assertTrue( wizard.activePage.lblSubtitle.getText() == initiatorGroupName) LOG.info('Initiator group name is visible:', wizard.activePage.lblSubtitle.getText()) LOG.step('Verifying WWPNs assigned to initiator group') selectedWWPNs = wizard.activePage.gridInitiatorWWPNs.find( selected=True) self.assertTrue(len(selectedWWPNs) == 2) for wwpn in selectedWWPNs: self.assertTrue(wwpn['initiator_group'] in fictiveWWPNs) LOG.info("WWPN assigned to initiator group '%s': %s" % (wwpn['initiator_group'], initiatorGroupName)) def test_add_wwpns(self): """ Verify adding new WWPNs and assigning them to initiator group. """ initiatorGroupName = 'IG-1' newWWPNsNumber = 3 LOG.step('Creating initiator group without WWPNs') self.marscluster.igroup.create(name=initiatorGroupName, ostype='vmware') initiatorGroups = self.marscluster.igroup.show(json=True) self.assertTrue(len(initiatorGroups) == 1) self.assertTrue(initiatorGroups[0]['name'] == initiatorGroupName) self.assertFalse(initiatorGroups[0]['initiators']) LOG.info('Initiator group created:\n', initiatorGroups[0]) self.initiatorGroupsPage.btnRefresh.click() self.initiatorGroupsPage.btnRefresh.waitUntilEnabled() LOG.step('Opening wizard') wizard = ChangeInitiatorsWizard(driver=self.driver) wizard.open(initiator_group=initiatorGroupName) LOG.info('Wizard open.') fictiveWWPNs = [] for _ in range(newWWPNsNumber): fictiveWWPNs.append(':'.join( re.findall( '..', format(random.randrange(sys.maxint), 'x').rjust(16, 'f')))) LOG.step('Adding new WWPNs to list: %s' % fictiveWWPNs) wizard.activePage.addWWPNs(wwpns=fictiveWWPNs) selectedWWPNs = [ wwpn for wwpn in wizard.activePage.getWWPNs() if wwpn['selected'] ] self.assertTrue(len(selectedWWPNs) == newWWPNsNumber) for wwpn in selectedWWPNs: self.assertTrue(wwpn['initiator_group'] in fictiveWWPNs) LOG.info('WWPN added and selected in list:', wwpn['initiator_group']) LOG.step('Verifying WWPNs have been assigned to initiator group') initiatorGroup = self.marscluster.igroup.show(json=True)[0] for wwpn in fictiveWWPNs: self.assertTrue(wwpn in initiatorGroup['initiators']) for wwpn in initiatorGroup['initiators']: self.assertTrue(wwpn in fictiveWWPNs) LOG.info("WWPN '%s' has beed assigned to initiator group." % wwpn) def test_reassign_wwpns(self): """ Verify changing initiator WWPNs in dialog. """ initiatorGroupName = 'IG-1' newWWPNsNumber = 7 LOG.step('Generating fictive WWPNs') fictiveWWPNs = [] for _ in range(newWWPNsNumber): fictiveWWPNs.append(':'.join( re.findall( '..', format(random.randrange(sys.maxint), 'x').rjust(16, 'f')))) LOG.info('Fictive WWPNs generated:', fictiveWWPNs) LOG.step('Creating initiator group with half of WWPNs assigned') # Assign half of WWPNs wwpns = ','.join(fictiveWWPNs[:newWWPNsNumber / 2]) self.marscluster.igroup.create(name=initiatorGroupName, ostype='vmware', initiators=wwpns) initiatorGroup = self.marscluster.igroup.show(json=True)[0] LOG.info('Initiator group created:\n', initiatorGroup) self.initiatorGroupsPage.btnRefresh.click() self.initiatorGroupsPage.btnRefresh.waitUntilEnabled() LOG.step('Opening wizard') wizard = ChangeInitiatorsWizard(driver=self.driver) wizard.open(initiator_group=initiatorGroupName) LOG.info('Wizard open.') LOG.step('Verifying assigned WWPNs are shown and selected in grid') selectedWWPNs = [ wwpn['initiator_group'] for wwpn in wizard.activePage.getWWPNs() if wwpn['selected'] ] for wwpn in fictiveWWPNs[:newWWPNsNumber / 2]: self.assertTrue(wwpn in selectedWWPNs) LOG.info("WWPN '%s' shown selected in grid." % wwpn) LOG.step('Reassigning of another half of WWPNs to initiator group') wizard.activePage.addWWPNs(wwpns=fictiveWWPNs[newWWPNsNumber / 2:]) wizard.activePage.setWWPNs(wwpns=fictiveWWPNs[newWWPNsNumber / 2:]) selectedWWPNs = [ wwpn['initiator_group'] for wwpn in wizard.activePage.getWWPNs() if wwpn['selected'] ] for wwpn in fictiveWWPNs[newWWPNsNumber / 2:]: self.assertTrue(wwpn in selectedWWPNs) LOG.info("WWPN '%s' shown selected in grid." % wwpn) LOG.step('Submitting dialog') wizard.close() LOG.info('Dialog submitted.') self.initiatorGroupsPage.btnRefresh.click() self.initiatorGroupsPage.btnRefresh.waitUntilEnabled() LOG.step('Verifying WWPN reassignment has been done.') initiatorGroup = self.marscluster.igroup.show(json=True)[0] for wwpn in fictiveWWPNs[newWWPNsNumber / 2:]: self.assertTrue(wwpn in initiatorGroup['initiators']) for wwpn in initiatorGroup['initiators']: self.assertTrue(wwpn in selectedWWPNs) LOG.info("WWPN '%s' has been assigned to initiator group." % wwpn) def test_dialog_not_available(self): """ Verify menu 'Edit' on Initiator Groups page is disabled when no initiator group selected. """ initiatorGroupPrefix = 'IG' initiatorGroupNumber = 3 self._createInitiatorGroups(prefix=initiatorGroupPrefix, number=initiatorGroupNumber) LOG.step('Navigating to Initiator Groups page') HeaderPage(driver=self.driver).btnManager.click() AllStoragePage(driver=self.driver).tabInitiatorGroups.click() self.assertTrue(self.initiatorGroupsPage.isOpen()) LOG.info('Initiator Groups page is open:', self.initiatorGroupsPage.isOpen()) self.initiatorGroupsPage.btnRefresh.click() self.initiatorGroupsPage.btnRefresh.waitUntilEnabled() LOG.step('Unselecting all initiator groups in grid') self.initiatorGroupsPage.gridInitiatorGroups.unselect() initiatorGroups = self.initiatorGroupsPage.gridInitiatorGroups.find( selected=True) self.assertFalse(initiatorGroups) LOG.info('Selected initiator groups:', initiatorGroups) LOG.step("Verifying menu 'Edit' is disabled") self.assertFalse(self.initiatorGroupsPage.menuEdit.isEnabled()) LOG.info("Menu 'Edit' is enabled:", self.initiatorGroupsPage.menuEdit.isEnabled()) def testTeardown(self): self.driver.close() def suiteTeardown(self): LOG.step('Closing browser') self.driver.quit() luns = express.Luns(node=self.marscluster, cleanup=True) del luns self.marscluster.igroup.destroyAll() LOG.info('LUNs & initiator groups destroyed.') def _createInitiatorGroups(self, prefix, number): LOG.step('Creating initiator group(s)') for groupNumber in range(number): fictiveWWPN = format(random.randrange(sys.maxint), 'x').rjust(16, 'f') self.marscluster.igroup.create(name=prefix + '-' + str(groupNumber), ostype='vmware', initiators=fictiveWWPN) groupNames = [ group['name'] for group in self.marscluster.igroup.show(json=True) ] LOG.info('Initiator group(s) created:', groupNames) return groupNames
class TestRenameLUNSnapshotWizard(FRTestCase): def suiteSetup(self): self.username = ARGS.values.username self.password = ARGS.values.password self.locale = ARGS.values.locale self.webUIHostName = getFQDN(self.marscluster.getMasterNode().hostname) def testSetup(self): self.driver = self.getDriver() self.loginPage = LoginPage(driver=self.driver, url=self.webUIHostName) self.headerPage = HeaderPage(driver=self.driver) self.allStoragePage = AllStoragePage(driver=self.driver) self.lunsPage = LUNsPage(driver=self.driver) self.lunDetailsPage = LUNDetailsPage(driver=self.driver) self.lunSnapshotsPage = LUNSnapshotsPage(driver=self.driver) LOG.step('Cleaning out cluster content') snapshots = self.marscluster.snapshot.show(json=True) for snapshot in snapshots: self.marscluster.snapshot.delete(name=snapshot['name'], lun=snapshot['object']) self.assertFalse(self.marscluster.snapshot.show(json=True)) LOG.info('Snapshots destroyed.') luns = express.Luns(node=self.marscluster, cleanup=True) del luns self.assertFalse(self.marscluster.lun.show(json=True)) LOG.info('LUNs destroyed.') self.luns = express.Luns(node=self.marscluster) LOG.step('Signing in') self.loginPage.open() self.loginPage.waitUntilOpen() if self.locale is None: self.locale = self.loginPage.getRandomLocale() self.loginPage.signIn(username=self.username, password=self.password, locale=self.locale) LOG.info('Signed in with username: %s, password: %s, locale: %s.' % (self.username, self.password, self.locale)) LOG.info('Browser landed on header page.') LOG.step('Navigating to LUNs page') self.headerPage.btnManager.click() self.allStoragePage.tabLUNs.click() self.lunsPage.waitUntilOpen() LOG.info('Browser landed on LUNs page.') def test_valid_name(self): """ Verify LUN snapshot renaming with valid name. """ lunNamePrefix = 'LuN' lunName = lunNamePrefix + '_1' snapshotName = lunName + '_snap_0' snapshotNewName = snapshotName + '.m' LOG.step('Creating LUN') self.luns.create(count=1, size='1g', prefix=lunNamePrefix) LOG.info('LUN created:\n', self.marscluster.lun.show(json=True)) LOG.step('Creating LUN snapshot') self.marscluster.snapshot.create(luns=lunName, name=snapshotName) snapshots = self.marscluster.snapshot.show(json=True) snapshot = [ snapshot for snapshot in snapshots if (snapshot['name'] == snapshotName and snapshot['object'] == lunName) ][0] snapshotUUID = snapshot['uuid'] LOG.info('Snapshot created:\n', snapshot) LOG.step("LUN '%s': Opening Snapshots page" % lunName) lunSnapshotsPage = LUNSnapshotsPage( driver=self.driver, url=self.webUIHostName + ('/#manager/storage/allstorage/luns/%s/snapshot' % lunName)) lunSnapshotsPage.open() lunSnapshotsPage.waitUntilOpen() LOG.info('LUN Snapshots page is open.') LOG.step('Renaming LUN snapshot in dialog') wizard = RenameLUNSnapshotWizard(driver=self.driver) wizard.open(name=snapshotName) LOG.info('Old snapshot name:', snapshotName) wizard.renameLUNSnapshotPage.renameLUNSnapshot(name=snapshotNewName) LOG.info('New snapshot name:', snapshotNewName) wizard.renameLUNSnapshotPage.submit() LOG.info('Rename submitted.') LOG.step('Verifying LUN snapshot name has been changed') snapshots = self.marscluster.snapshot.show(json=True) snapshot = [ snapshot for snapshot in snapshots if snapshot['uuid'] == snapshotUUID ][0] self.assertTrue(snapshot['name'] == snapshotNewName) LOG.info('LUN snapshot has been renamed:\n', snapshot) def test_invalid_name(self): """ Verify LUN snapshot renaming with invalid name. """ lunNamePrefix = 'LuN' lunName = lunNamePrefix + '_1' snapshotName = lunName + '_snap_0' snapshotNewName = snapshotName + '*&#@1A_^?,' LOG.step('Creating LUN') self.luns.create(count=1, size='1g', prefix=lunNamePrefix) LOG.info('LUN created:\n', self.marscluster.lun.show(json=True)) LOG.step('Creating LUN snapshot') self.marscluster.snapshot.create(luns=lunName, name=snapshotName) snapshots = self.marscluster.snapshot.show(json=True) snapshot = [ snapshot for snapshot in snapshots if (snapshot['name'] == snapshotName and snapshot['object'] == lunName) ][0] snapshotUUID = snapshot['uuid'] LOG.info('Snapshot created:\n', snapshot) LOG.step("LUN '%s': Opening Snapshots page" % lunName) lunSnapshotsPage = LUNSnapshotsPage( driver=self.driver, url=self.webUIHostName + ('/#manager/storage/allstorage/luns/%s/snapshot' % lunName)) lunSnapshotsPage.open() lunSnapshotsPage.waitUntilOpen() LOG.info('LUN Snapshots page is open.') LOG.step('Renaming LUN snapshot in dialog') wizard = RenameLUNSnapshotWizard(driver=self.driver) wizard.open(name=snapshotName) LOG.info('Old snapshot name:', snapshotName) wizard.renameLUNSnapshotPage.renameLUNSnapshot(name=snapshotNewName) LOG.info('New snapshot name:', snapshotNewName) LOG.step('Verifying LUN snapshot name error message') wizard.activePage.lblNameError.waitUntilPresent() LOG.info('Name error message:', wizard.activePage.lblNameError.getText()) self.assertFalse(wizard.activePage.btnOK.isEnabled()) LOG.info("Button 'OK' is enabled:", wizard.activePage.btnOK.isEnabled()) LOG.step('Verifying LUN snapshot has not been renamed') snapshots = self.marscluster.snapshot.show(json=True) snapshot = [ snapshot for snapshot in snapshots if snapshot['uuid'] == snapshotUUID ][0] self.assertTrue(snapshot['name'] == snapshotName) LOG.info('LUN snapshot has not been renamed:\n', snapshot) def test_unicode_name(self): """ Verify error message on setting LUN snapshot name containing Unicode characters. """ lunNamePrefix = 'LuN' lunName = lunNamePrefix + '_1' snapshotName = lunName + '_snap_0' snapshotNewName = snapshotName + u'Fran\u00e7ais' LOG.step('Creating LUN') self.luns.create(count=1, size='1g', prefix=lunNamePrefix) LOG.info('LUN created:\n', self.marscluster.lun.show(json=True)) LOG.step('Creating LUN snapshot') self.marscluster.snapshot.create(luns=lunName, name=snapshotName) snapshots = self.marscluster.snapshot.show(json=True) snapshot = [ snapshot for snapshot in snapshots if (snapshot['name'] == snapshotName and snapshot['object'] == lunName) ][0] snapshotUUID = snapshot['uuid'] LOG.info('Snapshot created:\n', snapshot) LOG.step("LUN '%s': Opening Snapshots page" % lunName) lunSnapshotsPage = LUNSnapshotsPage( driver=self.driver, url=self.webUIHostName + ('/#manager/storage/allstorage/luns/%s/snapshot' % lunName)) lunSnapshotsPage.open() lunSnapshotsPage.waitUntilOpen() LOG.info('LUN Snapshots page is open.') LOG.step('Renaming LUN snapshot in dialog') wizard = RenameLUNSnapshotWizard(driver=self.driver) wizard.open(name=snapshotName) LOG.info('Old snapshot name:', snapshotName) wizard.renameLUNSnapshotPage.renameLUNSnapshot(name=snapshotNewName) LOG.info('New snapshot name:', snapshotNewName) LOG.step('Verifying LUN snapshot name error message') wizard.activePage.lblNameError.waitUntilPresent() LOG.info('Name error message:', wizard.activePage.lblNameError.getText()) self.assertFalse(wizard.activePage.btnOK.isEnabled()) LOG.info("Button 'OK' is enabled:", wizard.activePage.btnOK.isEnabled()) LOG.step('Verifying LUN snapshot has not been renamed') snapshots = self.marscluster.snapshot.show(json=True) snapshot = [ snapshot for snapshot in snapshots if snapshot['uuid'] == snapshotUUID ][0] self.assertTrue(snapshot['name'] == snapshotName) LOG.info('LUN snapshot has not been renamed:\n', snapshot) def test_dialog_not_available(self): lunNamePrefix = 'LuN' lunName = lunNamePrefix + '_1' snapshotName = lunName + '_snap_0' LOG.step('Creating LUN') self.luns.create(count=1, size='1g', prefix=lunNamePrefix) LOG.info('LUN created:\n', self.marscluster.lun.show(json=True)) LOG.step('Creating LUN snapshot') self.marscluster.snapshot.create(luns=lunName, name=snapshotName) snapshots = self.marscluster.snapshot.show(json=True) snapshot = [ snapshot for snapshot in snapshots if (snapshot['name'] == snapshotName and snapshot['object'] == lunName) ][0] snapshotUUID = snapshot['uuid'] LOG.info('Snapshot created:\n', snapshot) LOG.step("LUN '%s': Opening Snapshots page" % lunName) lunSnapshotsPage = LUNSnapshotsPage( driver=self.driver, url=self.webUIHostName + ('/#manager/storage/allstorage/luns/%s/snapshot' % lunName)) lunSnapshotsPage.open() lunSnapshotsPage.waitUntilOpen() LOG.info('LUN Snapshots page is open.') LOG.step('Unselecting all LUN snapshots in grid') lunSnapshotsPage.gridSnapshots.unselect() selectedSnapshots = lunSnapshotsPage.gridSnapshots.find(selected=True) self.assertFalse(selectedSnapshots) LOG.info('LUN snapshots selected in grid:', selectedSnapshots) LOG.step("Verifying menu 'Edit' is unavailable") self.assertFalse(lunSnapshotsPage.menuEdit.isEnabled()) LOG.info("Menu 'Edit' is enabled:", lunSnapshotsPage.menuEdit.isEnabled()) def test_dialog_cancel(self): """ Verify LUN snapshot name remains intact on dialog cancel. """ lunNamePrefix = 'LuN' lunName = lunNamePrefix + '_1' snapshotName = lunName + '_snap_0' snapshotNewName = snapshotName + '.m' LOG.step('Creating LUN') self.luns.create(count=1, size='1g', prefix=lunNamePrefix) LOG.info('LUN created:\n', self.marscluster.lun.show(json=True)) LOG.step('Creating LUN snapshot') self.marscluster.snapshot.create(luns=lunName, name=snapshotName) snapshots = self.marscluster.snapshot.show(json=True) snapshot = [ snapshot for snapshot in snapshots if (snapshot['name'] == snapshotName and snapshot['object'] == lunName) ][0] snapshotUUID = snapshot['uuid'] LOG.info('Snapshot created:\n', snapshot) LOG.step("LUN '%s': Opening Snapshots page" % lunName) lunSnapshotsPage = LUNSnapshotsPage( driver=self.driver, url=self.webUIHostName + ('/#manager/storage/allstorage/luns/%s/snapshot' % lunName)) lunSnapshotsPage.open() lunSnapshotsPage.waitUntilOpen() LOG.info('LUN Snapshots page is open.') LOG.step('Renaming LUN snapshot in dialog') wizard = RenameLUNSnapshotWizard(driver=self.driver) wizard.open(name=snapshotName) LOG.info('Old snapshot name:', snapshotName) wizard.renameLUNSnapshotPage.renameLUNSnapshot(name=snapshotNewName) self.assertTrue(wizard.activePage.txtName.getText() == snapshotNewName) LOG.info('New snapshot name:', snapshotNewName) LOG.step('Canceling dialog without submission') wizard.cancel() LOG.info('Dialog cancelled.') LOG.step('Verifying LUN snapshot has not been renamed') snapshots = self.marscluster.snapshot.show(json=True) snapshot = [ snapshot for snapshot in snapshots if snapshot['uuid'] == snapshotUUID ][0] self.assertTrue(snapshot['name'] == snapshotName) LOG.info('LUN snapshot has not been renamed:\n', snapshot) def testTeardown(self): self.driver.close() LOG.info('Driver closed.') def suiteTeardown(self): self.driver.quit() LOG.info('Driver quit.') LOG.step('Deleting snapshots') snapshots = self.marscluster.snapshot.show(json=True) for snapshot in snapshots: self.marscluster.snapshot.delete(name=snapshot['name'], lun=snapshot['object']) self.assertFalse(self.marscluster.snapshot.show(json=True)) LOG.info('Snapshots deleted.') LOG.step('Destroying LUNs') luns = express.Luns(node=self.marscluster, cleanup=True) del luns LOG.info('LUNs destroyed.')
class TestComponentSearchBox(FRTestCase): def suiteSetup(self): self.locale = ARGS.values.locale self.username = ARGS.values.username self.password = ARGS.values.password self.webUIHostName = getFQDN(self.marscluster.hostname) self.luns = express.Luns(node=self.marscluster) def testSetup(self): self.driver = self.setupDriver() self.loginPage = LoginPage(driver=self.driver, url=self.webUIHostName) self.headerPage = HeaderPage(driver=self.driver) self.allStoragePage = AllStoragePage(driver=self.driver) self.lunsPage = LUNsPage(driver=self.driver) LOG.step('Signing in') self.loginPage.open() self.loginPage.waitUntilOpen() self.loginPage.signIn(username=self.username, password=self.password, locale=self.locale) LOG.info('Signed in with username: %s, password: %s, locale: %s.' % (self.username, self.password, self.locale)) LOG.info('Browser landed on header page.') LOG.step('Navigating to LUNs page') self.headerPage.btnManager.click() self.allStoragePage.tabLUNs.click() self.lunsPage.waitUntilOpen() LOG.info('Browser landed on LUNs page.') LOG.step('Creating LUNs') self.lunNamePrefix = 'LuN' self.lunCount = 20 self.luns.create(count=self.lunCount, size='1g', prefix=self.lunNamePrefix) luns = self.marscluster.lun.show(json=True) LOG.info('LUNs created:\n', [lun['name'] for lun in luns]) self.lunsPage.btnRefresh.click() self.lunsPage.btnRefresh.waitUntilEnabled() def test_search(self): """ Search for single/multiple row(s) in grid. Verify displayed rows satisfy search key. """ LOG.step('Searching for unique value: %s' % self.lunNamePrefix + '_' + str(self.lunCount)) self.lunsPage.sBoxSearch.setText(text=self.lunNamePrefix + '_' + str(self.lunCount)) luns = self.lunsPage.gridLUNs.find() self.assertTrue(len(luns) == 1) self.assertTrue(luns[0]['name'] == self.lunNamePrefix + '_' + str(self.lunCount)) LOG.info('LUNs displayed:', luns) LOG.step('Searching for multiple values: %s' % self.lunNamePrefix + '_1*') self.lunsPage.sBoxSearch.clear() self.lunsPage.sBoxSearch.setText(text=self.lunNamePrefix + '_1') luns = [lun['name'] for lun in self.lunsPage.gridLUNs.find()] # 'LuN_1', 'LuN_10' ... 'LuN_19' self.assertTrue(len(luns) == 11) for lun in luns: self.assertTrue(lun.startswith(self.lunNamePrefix + '_1')) LOG.info('LUNs displayed:', luns) def testTeardown(self): self.driver.close() luns = express.Luns(node=self.marscluster, cleanup=True) del luns LOG.info('LUNs destroyed.') def suiteTeardown(self): LOG.step('Closing browser') self.driver.quit()
class TestChangeInitiatorGroupOSTypeWizard(FRTestCase): def suiteSetup(self): self.username = ARGS.values.username self.password = ARGS.values.password self.locale = ARGS.values.locale self.webUIHostName = getFQDN(self.marscluster.getMasterNode().hostname) def testSetup(self): self.driver = self.getDriver() self.loginPage = LoginPage(driver=self.driver, url=self.webUIHostName) self.initiatorGroupsPage = InitiatorGroupsPage(driver=self.driver) LOG.info('Destroying existing LUNs...') self.marscluster.lun.unmapAll() self.marscluster.lun.destroyAll() self.assertFalse(self.marscluster.lun.show(json=True)) LOG.info('Done.') LOG.info('Destroying existing initiator groups...') self.marscluster.igroup.destroyAll() LOG.info('Done.') self.luns = express.Luns(node=self.marscluster) LOG.step('Signing in') self.loginPage.open() self.loginPage.waitUntilOpen() if self.locale is None: self.locale = self.loginPage.getRandomLocale() self.loginPage.signIn(username=self.username, password=self.password, locale=self.locale) LOG.info('Signed in with username: %s, password: %s, locale: %s.' % (self.username, self.password, self.locale)) LOG.info('Browser landed on header page.') def test_change_os_type(self): """ Verify changing of OS type for initiator group. """ initiatorGroupCount = 3 initiatorGroupPrefix = 'IG' osTypes = ['Windows', 'Linux', 'VMware', 'Xen'] initiatorGroups = self._createInitiatorGroups(prefix=initiatorGroupPrefix, number=initiatorGroupCount) initiatorGroupName = initiatorGroups[0] LOG.step('Changing OS type of initiator group in dialog') wizard = ChangeInitiatorGroupOSTypeWizard(driver=self.driver) for osType in osTypes: LOG.step('Opening dialog') wizard.open(initiator_groups=initiatorGroupName) LOG.info('Dialog open for initiator group:', initiatorGroupName) LOG.step('Setting OS type: %s' % osType) wizard.activePage.setOSType(osType=osType) wizard.submit() LOG.info('OS type set and dialog submitted') LOG.step('Verifying OS type has been changed') initiatorGroup = [initiatorGroup for initiatorGroup in self.marscluster.igroup.show(json=True) if initiatorGroup['name'] == initiatorGroupName][0] self.assertTrue(initiatorGroup['ostype'] == osType.lower()) LOG.info('OS type has been changed to:', initiatorGroup['ostype']) def test_change_os_type_related_groups(self): """ Verify dialog window 'Change related initiator groups' pops up when user change OS type for one of related (having same WWPN and OS type) initiator groups. """ initiatorGroupCount = 3 initiatorGroupPrefix = 'IG_' originalOSType = 'Windows' newOSType = 'Xen' LOG.step('Creating multiple related initiator groups') wwpn = format(random.randrange(sys.maxint), 'x').rjust(16, 'f') for count in range(initiatorGroupCount): self.marscluster.igroup.create(name=initiatorGroupPrefix + str(count), ostype=originalOSType, initiators=wwpn) initiatorGroups = self.marscluster.igroup.show(json=True) self.assertTrue(len(initiatorGroups) == initiatorGroupCount) initiatorGroupName = initiatorGroups[0]['name'] LOG.info('Initiator groups created:\n', initiatorGroups) LOG.step('Opening dialog') wizard = ChangeInitiatorGroupOSTypeWizard(driver=self.driver) wizard.open(initiator_groups=initiatorGroupName) LOG.info('Dialog open for initiator group:', initiatorGroupName) LOG.step('Setting initiator group OS type to: %s' % newOSType) wizard.activePage.setOSType(osType=newOSType) wizard.submit() LOG.info('Dialog submitted.') LOG.step('Verifying related groups are listed on confirmation page') wizard.changeRelatedInitiatorGroupsPage.waitUntilOpen() listedGroupsNames = wizard.activePage.lblInitiatorGroups.getText() relatedGroupsNames = [groupName['name'] for groupName in initiatorGroups[1:]] for groupName in relatedGroupsNames: self.assertTrue(groupName in listedGroupsNames) LOG.info('Initiator group listed on page:', groupName) LOG.step('Submitting changes of related initiator groups') wizard.activePage.submit() LOG.info('Dialog closed.') LOG.step('Verifying related initiator groups have been changed') initiatorGroups = self.marscluster.igroup.show(json=True) for initiatorGroup in initiatorGroups: self.assertTrue(initiatorGroup['ostype'] == newOSType.lower()) LOG.info("Initiator group '%s' has OS type: %s" % (initiatorGroup['name'], initiatorGroup['ostype'])) def test_change_os_type_multiple_groups(self): """ Verify OS type change for multiple initiator groups. """ initiatorGroupCount = 10 initiatorGroupPrefix = 'IG_' originalOSType = 'Windows' newOSType = 'Xen' LOG.step('Creating multiple related initiator groups') for count in range(initiatorGroupCount): wwpn = format(random.randrange(sys.maxint), 'x').rjust(16, 'f') self.marscluster.igroup.create(name=initiatorGroupPrefix + str(count), ostype=originalOSType, initiators=wwpn) initiatorGroups = self.marscluster.igroup.show(json=True) self.assertTrue(len(initiatorGroups) == initiatorGroupCount) initiatorGroupName = initiatorGroups[0]['name'] LOG.info('Initiator groups created:\n', initiatorGroups) selectedGroupNames = [initiatorGroup['name'] for initiatorGroup in initiatorGroups[:initiatorGroupCount / 2]] LOG.step('Opening dialog') wizard = ChangeInitiatorGroupOSTypeWizard(driver=self.driver) wizard.open(initiator_groups=selectedGroupNames) LOG.info('Dialog open for initiator groups:', selectedGroupNames) LOG.step('Setting initiator group OS type to: %s' % newOSType) wizard.activePage.setOSType(osType=newOSType) wizard.submit() LOG.info('Dialog submitted.') LOG.step('Verifying OS type has been changed for selected initiator groups only') initiatorGroups = self.marscluster.igroup.show(json=True) for initiatorGroup in initiatorGroups: if initiatorGroup['name'] in selectedGroupNames: self.assertTrue(initiatorGroup['ostype'] == newOSType.lower()) else: self.assertTrue(initiatorGroup['ostype'] == originalOSType.lower()) LOG.info("Initiator group '%s' has OS type: %s" % (initiatorGroup['name'], initiatorGroup['ostype'])) def test_change_os_type_multiple_related_groups(self): """ Verify OS type change for multiple related initiator groups. """ initiatorGroupCount = 10 initiatorGroupPrefix = 'IG_' originalOSType = 'Windows' newOSType = 'Xen' LOG.step('Creating multiple related initiator groups') wwpn = format(random.randrange(sys.maxint), 'x').rjust(16, 'f') for count in range(initiatorGroupCount): self.marscluster.igroup.create(name=initiatorGroupPrefix + str(count), ostype=originalOSType, initiators=wwpn) initiatorGroups = self.marscluster.igroup.show(json=True) self.assertTrue(len(initiatorGroups) == initiatorGroupCount) initiatorGroupName = initiatorGroups[0]['name'] LOG.info('Initiator groups created:\n', initiatorGroups) selectedGroupNames = [initiatorGroup['name'] for initiatorGroup in initiatorGroups[:initiatorGroupCount / 2]] LOG.step('Opening dialog') wizard = ChangeInitiatorGroupOSTypeWizard(driver=self.driver) wizard.open(initiator_groups=selectedGroupNames) LOG.info('Dialog open for initiator groups:', selectedGroupNames) LOG.step('Setting initiator group OS type to: %s' % newOSType) wizard.activePage.setOSType(osType=newOSType) wizard.submit() LOG.info('Dialog submitted.') LOG.step('Verifying related groups are listed on confirmation page') wizard.changeRelatedInitiatorGroupsPage.waitUntilOpen() listedGroupsNames = wizard.activePage.lblInitiatorGroups.getText() relatedGroupsNames = [groupName['name'] for groupName in initiatorGroups[initiatorGroupCount / 2:]] for groupName in relatedGroupsNames: self.assertTrue(groupName in listedGroupsNames) LOG.info('Initiator group listed on page:', groupName) LOG.step('Submitting changes of related initiator groups') wizard.activePage.submit() LOG.info('Dialog closed.') LOG.step('Verifying OS type has been changed for all related initiator groups') initiatorGroups = self.marscluster.igroup.show(json=True) for initiatorGroup in initiatorGroups: self.assertTrue(initiatorGroup['ostype'] == newOSType.lower()) LOG.info("Initiator group '%s' has OS type: %s" % (initiatorGroup['name'], initiatorGroup['ostype'])) def test_dialog_cancel(self): """ Verify OS type of initiator group remains intact on dialog cancel. """ initiatorGroupCount = 3 initiatorGroupPrefix = 'IG' originalOStype = 'Windows' newOSType = 'Xen' LOG.step('Creating initiator groups') initiatorGroups = self._createInitiatorGroups(prefix=initiatorGroupPrefix, number=initiatorGroupCount, osType=originalOStype) LOG.info('Initiator groups created:', initiatorGroups) LOG.step('Opening dialog') wizard = ChangeInitiatorGroupOSTypeWizard(driver=self.driver) wizard.open(initiator_groups=initiatorGroups[0]) LOG.info('Dialog open for initiator group:', initiatorGroups[0]) LOG.step('Setting initiator group OS type to: %s' % newOSType) wizard.activePage.setOSType(osType=newOSType) self.assertTrue(wizard.activePage.dLstOSType.getText() == newOSType) LOG.info('OS type set to:', wizard.activePage.dLstOSType.getText()) LOG.step('Canceling dialog without submission') wizard.cancel() LOG.info('Dialog closed.') LOG.step('Verifying initiator group OS type remains original') initiatorGroup = [group for group in self.marscluster.igroup.show(json=True) if group['name'] == initiatorGroups[0]][0] self.assertTrue(initiatorGroup['ostype'] == originalOStype.lower()) LOG.info('Initiator froup OS type has not been changed:', initiatorGroup['ostype']) def _createInitiatorGroups(self, prefix, number, osType='vmware'): LOG.step('Creating initiator group(s)') for groupNumber in range(number): fictiveWWPN = format(random.randrange(sys.maxint), 'x').rjust(16, 'f') self.marscluster.igroup.create(name=prefix + '-' + str(groupNumber), ostype=osType.lower(), initiators=fictiveWWPN) groupNames = [group['name'] for group in self.marscluster.igroup.show(json=True)] LOG.info('Initiator group(s) created:', groupNames) return groupNames def testTeardown(self): self.driver.close() LOG.info('Driver closed.') def suiteTeardown(self): LOG.step('Quitting browser') self.driver.quit() luns = express.Luns(node=self.marscluster, cleanup=True) del luns self.marscluster.igroup.destroyAll() LOG.info('LUNs & initiator groups destroyed.')
class TestDeleteLUNWizard(FRTestCase): def suiteSetup(self): self.username = ARGS.values.username self.password = ARGS.values.password self.locale = ARGS.values.locale self.webUIHostName = getFQDN(self.marscluster.getMasterNode().hostname) def testSetup(self): self.driver = self.getDriver() self.loginPage = LoginPage(driver=self.driver, url=self.webUIHostName) self.headerPage = HeaderPage(driver=self.driver) self.allStoragePage = AllStoragePage(driver=self.driver) self.lunsPage = LUNsPage(driver=self.driver) self.node = self.marscluster self.luns = express.Luns(node=self.marscluster) # self.luns.setCleanup(True) LOG.step('Signing in') self.loginPage.open() self.loginPage.waitUntilOpen() if self.locale is None: self.locale = self.loginPage.getRandomLocale() self.loginPage.signIn(username=self.username, password=self.password, locale=self.locale) LOG.info('Signed in with username: %s, password: %s, locale: %s.' % (self.username, self.password, self.locale)) LOG.info('Browser landed on header page.') LOG.info('Navigating to LUNs page...') self.headerPage.btnManager.click() self.allStoragePage.tabLUNs.click() self.lunsPage.waitUntilOpen() LOG.info('Browser landed on LUNs page.') def test_delete_single_lun(self): """ Verify single LUN's deletion. """ LOG.step('Creating LUNs') lunCount = 3 lunSize = 2 lunSizeUnit = 'G' lunNamePrefix = 'LuN' self.luns.create(count=lunCount, size=str(lunSize) + lunSizeUnit, prefix=lunNamePrefix) LOG.info('LUNs created:\n', pprint.pformat(self.marscluster.lun.show(json=True))) # Refresh LUN grid self.lunsPage.btnRefresh.click() self.lunsPage.btnRefresh.waitUntilEnabled() LOG.step("Deleting LUN '%s'" % (lunNamePrefix + '_1')) wizard = DeleteLUNWizard(driver=self.driver) wizard.open(name=lunNamePrefix + '_1') wizard.activePage.confirm() wizard.activePage.submit() LOG.info('LUN deletion submitted.') LOG.step('Verifying LUN has been deleted') luns = self.marscluster.lun.show(json=True) self.assertTrue(len(luns) == lunCount - 1) self.assertTrue((lunNamePrefix + '_1') not in [lun['name'] for lun in luns]) LOG.info('LUNs:\n%s' % pprint.pformat(luns)) LOG.info("LUN '%s' deleted." % (lunNamePrefix + '_1')) def test_delete_multiple_luns(self): """ Verify multiple LUNs' deletion. """ LOG.step('Creating LUNs') lunCount = 7 lunSize = 2 lunSizeUnit = 'G' lunNamePrefix = 'LuN' lunsToDelete = [ lunNamePrefix + '_1', lunNamePrefix + '_2', lunNamePrefix + '_3' ] self.luns.create(count=lunCount, size=str(lunSize) + lunSizeUnit, prefix=lunNamePrefix) LOG.info('LUNs created:\n', pprint.pformat(self.marscluster.lun.show(json=True))) # Refresh LUN grid self.lunsPage.btnRefresh.click() self.lunsPage.btnRefresh.waitUntilEnabled() LOG.step("Deleting LUNs: %s" % lunsToDelete) wizard = DeleteLUNWizard(driver=self.driver) wizard.open(name=lunsToDelete) wizard.activePage.confirm() wizard.activePage.submit() LOG.info('LUN deletion submitted.') LOG.step('Verifying LUNs have been deleted') luns = [lun['name'] for lun in self.marscluster.lun.show(json=True)] self.assertTrue(len(luns) == lunCount - len(lunsToDelete)) for lunName in lunsToDelete: self.assertFalse(lunName in luns) LOG.info('Existing LUNs:\n%s' % luns) def test_dialog_cancel(self): """ Verify 'Delete LUN -> Cancel' does cancel dialog gracefully, LUN not deleted. """ LOG.step('Creating LUNs') lunCount = 3 lunSize = 2 lunSizeUnit = 'G' lunNamePrefix = 'LuN' self.luns.create(count=lunCount, size=str(lunSize) + lunSizeUnit, prefix=lunNamePrefix) lunsOriginal = [ lun['name'] for lun in self.marscluster.lun.show(json=True) ] LOG.info('LUNs created:', lunsOriginal) # Refresh LUN grid self.lunsPage.btnRefresh.click() self.lunsPage.btnRefresh.waitUntilEnabled() LOG.step('Opening wizard') wizard = DeleteLUNWizard(driver=self.driver) wizard.open(name=lunNamePrefix + '_1') LOG.info('Wizard open.') LOG.step('Canceling wizard') wizard.activePage.confirm() wizard.cancel() LOG.info('Wizard closed without submission.') LOG.step('Verifying LUN has remain intact') luns = [lun['name'] for lun in self.marscluster.lun.show(json=True)] self.assertTrue(len(luns) == lunCount) for lunName in luns: self.assertTrue(lunName in lunsOriginal) LOG.info('LUNs original: %s' % lunsOriginal) LOG.info('LUNs existing: %s' % luns) def test_dialog_not_available(self): """ Verify that 'Delete LUN' is not available when no selected LUNs present. """ LOG.step('Creating LUNs') lunCount = 3 lunSize = 2 lunSizeUnit = 'G' lunNamePrefix = 'LuN' self.luns.create(count=lunCount, size=str(lunSize) + lunSizeUnit, prefix=lunNamePrefix) lunsOriginal = [ lun['name'] for lun in self.marscluster.lun.show(json=True) ] LOG.info('LUNs created:', lunsOriginal) # Refresh LUN grid self.lunsPage.btnRefresh.click() self.lunsPage.btnRefresh.waitUntilEnabled() LOG.step('Unselecting all LUNs in grid') self.lunsPage.gridLUNs.unselect() self.assertFalse(self.lunsPage.gridLUNs.find(selected=True)) LOG.info('No LUNs selected in grid.') LOG.step("Verifying button 'Delete' is disabled.") self.assertFalse(self.lunsPage.btnDelete.isEnabled()) LOG.info("Button 'Delete' is enabled:", self.lunsPage.btnDelete.isEnabled()) def testTeardown(self): self.driver.close() luns = express.Luns(node=self.marscluster, cleanup=True) del luns LOG.info('LUNs destroyed.') def suiteTeardown(self): LOG.step('Closing browser') self.driver.quit() LOG.info('Browser closed.')
class TestCloneLUNSnapshotWizard(FRTestCase): def suiteSetup(self): self.username = ARGS.values.username self.password = ARGS.values.password self.locale = ARGS.values.locale self.webUIHostName = getFQDN(self.marscluster.getMasterNode().hostname) def testSetup(self): self.driver = self.getDriver() self.loginPage = LoginPage(driver=self.driver, url=self.webUIHostName) self.headerPage = HeaderPage(driver=self.driver) self.allStoragePage = AllStoragePage(driver=self.driver) self.lunsPage = LUNsPage(driver=self.driver) self.lunDetailsPage = LUNDetailsPage(driver=self.driver) self.lunSnapshotsPage = LUNSnapshotsPage(driver=self.driver) LOG.step('Cleaning out cluster content') snapshots = self.marscluster.snapshot.show(json=True) for snapshot in snapshots: self.marscluster.snapshot.delete(name=snapshot['name'], lun=snapshot['object']) self.assertFalse(self.marscluster.snapshot.show(json=True)) LOG.info('Snapshots destroyed.') luns = express.Luns(node=self.marscluster, cleanup=True) del luns self.assertFalse(self.marscluster.lun.show(json=True)) LOG.info('LUNs destroyed.') self.marscluster.igroup.destroyAll() LOG.info('Initiator groups destroyed.') self._deleteDependentConsistencyGroups() LOG.info('Consistency groups destroyed.') self.luns = express.Luns(node=self.marscluster) LOG.step('Signing in') self.loginPage.open() self.loginPage.waitUntilOpen() if self.locale is None: self.locale = self.loginPage.getRandomLocale() self.loginPage.signIn(username=self.username, password=self.password, locale=self.locale) LOG.info('Signed in with username: %s, password: %s, locale: %s.' % (self.username, self.password, self.locale)) LOG.info('Browser landed on header page.') LOG.info('Navigating to LUNs page...') self.headerPage.btnManager.click() self.allStoragePage.tabLUNs.click() self.lunsPage.waitUntilOpen() LOG.info('Browser landed on LUNs page.') def test_clone_no_ig_cg(self): """ Verify LUN snapshot cloning when no initiator/consistency groups exist. """ lunNamePrefix = 'LuN' lunName = lunNamePrefix + '_1' snapshotName = lunName + '_snap' cloneName = lunName + '_clone_0' LOG.step('Creating LUN') self.luns.create(count=1, size='1g', prefix=lunNamePrefix) luns = self.marscluster.lun.show(json=True) LOG.info('LUNs created:\n', luns) LOG.step('Creating LUN snapshot') self.marscluster.snapshot.create(luns=lunName, name=snapshotName) snapshots = self.marscluster.snapshot.show(json=True) LOG.info('Snapshot created:\n', snapshots) self.lunsPage.btnRefresh.click() self.lunsPage.btnRefresh.waitUntilEnabled() self._navigateToLUNSnapshotsPage(lunName=lunName) LOG.step('Opening wizard') wizard = CloneLUNSnapshotWizard(driver=self.driver) wizard.open(lunName=lunName, lunSnapshotName=snapshotName) LOG.info('Wizard open.') LOG.step('Verifying default details of LUN snapshot clone') self.assertTrue( wizard.activePage.lblSubtitle.getText() == snapshotName) LOG.info('LUN snapshot name:', wizard.activePage.lblSubtitle.getText()) self.assertTrue(wizard.activePage.txtName.getText() == cloneName) LOG.info('LUN snapshot clone name:', wizard.activePage.txtName.getText()) self.assertFalse( wizard.activePage.cBoxParentConsistencyGroup.isEnabled()) LOG.info('Parent consistency group is enabled:', wizard.activePage.cBoxParentConsistencyGroup.isEnabled()) wizard.activePage.dLstMappedTo.expand() wizard.selectInitiatorGroupsPage.waitUntilOpen() initiatorGroups = wizard.selectInitiatorGroupsPage.gridInitiatorGroups.find( ) self.assertFalse(initiatorGroups) LOG.info('Initiator groups available:', initiatorGroups) wizard.activePage.dLstMappedTo.collapse() LOG.step('Cloning LUN snapshot') wizard.activePage.submit() self._verifyClone(snapshotName=snapshotName, cloneName=cloneName) def test_clone_not_mapped(self): """ Verify LUN snapshot cloning when initiator and consistency groups exist but not mapped. """ lunNamePrefix = 'LuN' lunName = lunNamePrefix + '_1' snapshotName = lunName + '_snap' cloneName = lunName + '_clone_0' initiatorGroupName = 'IG-' initiatorGroupsNumber = 5 parentConsistencyGroupName = 'Parent-CG' LOG.step('Creating LUN') self.luns.create(count=1, size='1g', prefix=lunNamePrefix) luns = self.marscluster.lun.show(json=True) self.assertTrue(len(luns) == 1) LOG.info('LUN created:\n', luns) LOG.step('Creating LUN snapshot') self.marscluster.snapshot.create(luns=lunName, name=snapshotName) snapshots = self.marscluster.snapshot.show(json=True) LOG.info('Snapshot created:\n', snapshots) LOG.step('Creating initiator groups') for initiatorIndex in range(initiatorGroupsNumber): fictiveWWPN = format(random.randrange(sys.maxint), 'x').rjust(16, 'f') self.marscluster.igroup.create(name=(initiatorGroupName + str(initiatorIndex)), ostype='vmware', initiators=fictiveWWPN) originalInitiatorGroups = self.marscluster.igroup.show(json=True) self.assertTrue(len(originalInitiatorGroups) == initiatorGroupsNumber) LOG.info('Initiator groups created:\n', originalInitiatorGroups) LOG.step('Creating consistency group') self.marscluster.cg.create(name=parentConsistencyGroupName) consistencyGroups = self.marscluster.cg.show(json=True) self.assertTrue(len(consistencyGroups) == 1) self.assertTrue( consistencyGroups[0]['name'] == parentConsistencyGroupName) LOG.info('Consistency group created:', parentConsistencyGroupName) self.lunsPage.btnRefresh.click() self.lunsPage.btnRefresh.waitUntilEnabled() self._navigateToLUNSnapshotsPage(lunName=lunName) LOG.step('Opening wizard') wizard = CloneLUNSnapshotWizard(driver=self.driver) wizard.open(lunName=lunName, lunSnapshotName=snapshotName) LOG.info('Wizard open.') LOG.step('Verifying default details of LUN snapshot clone') self.assertTrue(wizard.activePage.txtName.getText() == cloneName) LOG.info('Default LUN snapshot clone name:', wizard.activePage.txtName.getText()) wizard.activePage.dLstMappedTo.expand() wizard.selectInitiatorGroupsPage.waitUntilOpen() initiatorGroups = wizard.selectInitiatorGroupsPage.gridInitiatorGroups.find( ) self.assertTrue(len(initiatorGroups) == len(originalInitiatorGroups)) mappedInitiatorGroups = [ initiatorGroup for initiatorGroup in initiatorGroups if initiatorGroup['selected'] == True ] self.assertFalse(mappedInitiatorGroups) LOG.info('Mapped initiator groups:', mappedInitiatorGroups) wizard.activePage.dLstMappedTo.collapse() self.assertTrue( wizard.activePage.cBoxParentConsistencyGroup.isEnabled()) LOG.info('Parent consistency group is enabled:', wizard.activePage.cBoxParentConsistencyGroup.isEnabled()) consistencyGroups = wizard.activePage.cBoxParentConsistencyGroup.getItems( ) self.assertTrue(parentConsistencyGroupName in consistencyGroups) LOG.info('Consistency groups available:', consistencyGroups) LOG.step('Cloning LUN') wizard.activePage.submit() self._verifyClone(snapshotName=snapshotName, cloneName=cloneName) def test_clone_mapped(self): """ Verify LUN snapshot cloning when mapped to initiator and consistency groups. """ lunNamePrefix = 'LuN' lunName = lunNamePrefix + '_1' snapshotName = lunName + '_snap' cloneName = lunName + '_clone_0' initiatorGroupName = 'IG-' initiatorGroupsNumber = 5 parentConsistencyGroupName = 'Parent-CG' LOG.step('Creating LUN') self.luns.create(count=1, size='1g', prefix=lunNamePrefix) luns = self.marscluster.lun.show(json=True) self.assertTrue(len(luns) == 1) LOG.info('LUN created:\n', luns) LOG.step('Creating LUN snapshot') self.marscluster.snapshot.create(luns=lunName, name=snapshotName) snapshots = self.marscluster.snapshot.show(json=True) LOG.info('Snapshot created:\n', snapshots) LOG.step('Creating initiator groups') for initiatorIndex in range(initiatorGroupsNumber): fictiveWWPN = format(random.randrange(sys.maxint), 'x').rjust(16, 'f') self.marscluster.igroup.create(name=(initiatorGroupName + str(initiatorIndex)), ostype='vmware', initiators=fictiveWWPN) originalInitiatorGroups = self.marscluster.igroup.show(json=True) self.assertTrue(len(originalInitiatorGroups) == initiatorGroupsNumber) LOG.info('Initiator groups created:\n', originalInitiatorGroups) LOG.step('Mapping LUN snapshot to initiator groups') self.marscluster.lun.map({ 'name': lunName, 'igroup': originalInitiatorGroups[0]['name'] }) self.marscluster.lun.map({ 'name': lunName, 'igroup': originalInitiatorGroups[-1]['name'] }) LOG.info('LUN snapshot initiator group mapping:', self.marscluster.lun.mapped_show()) LOG.step('Creating consistency group') self.marscluster.cg.create({ 'name': parentConsistencyGroupName, 'members': lunName }) consistencyGroups = self.marscluster.cg.show(json=True) self.assertTrue(len(consistencyGroups) == 1) lun = [ lun for lun in self.marscluster.lun.show(json=True) if lun['name'] == parentConsistencyGroupName + '/' + lunNamePrefix + '_1' ][0] LOG.info('Consistency group created and mapped:', lun['maps']) self.lunsPage.btnRefresh.click() self.lunsPage.btnRefresh.waitUntilEnabled() self._navigateToLUNSnapshotsPage(lunName=lunName) LOG.step('Opening wizard') wizard = CloneLUNSnapshotWizard(driver=self.driver) wizard.open(lunName=lunName, lunSnapshotName=snapshotName) LOG.info('Wizard open.') LOG.step('Verifying default details of LUN snapshot clone') self.assertTrue(wizard.activePage.txtName.getText() == cloneName) LOG.info('Default LUN snapshot clone name:', wizard.activePage.txtName.getText()) wizard.activePage.dLstMappedTo.expand() wizard.selectInitiatorGroupsPage.waitUntilOpen() initiatorGroups = wizard.selectInitiatorGroupsPage.gridInitiatorGroups.find( ) self.assertTrue(len(initiatorGroups) == len(originalInitiatorGroups)) mappedInitiatorGroups = [ initiatorGroup for initiatorGroup in initiatorGroups if initiatorGroup['selected'] == True ] self.assertTrue(len(mappedInitiatorGroups) == 2) self.assertTrue(mappedInitiatorGroups[0]['initiator_group'] in [ originalInitiatorGroups[0]['name'], originalInitiatorGroups[-1] ['name'] ]) self.assertTrue(mappedInitiatorGroups[1]['initiator_group'] in [ originalInitiatorGroups[0]['name'], originalInitiatorGroups[-1] ['name'] ]) LOG.info('Mapped initiator groups:', mappedInitiatorGroups) wizard.activePage.dLstMappedTo.collapse() self.assertTrue( wizard.activePage.cBoxParentConsistencyGroup.isEnabled()) LOG.info('Parent consistency group is enabled:', wizard.activePage.cBoxParentConsistencyGroup.isEnabled()) consistencyGroups = wizard.activePage.cBoxParentConsistencyGroup.getItems( ) self.assertTrue(parentConsistencyGroupName in consistencyGroups) LOG.info('Consistency groups available:', consistencyGroups) LOG.step('Cloning LUN snapshot') wizard.activePage.submit() self._verifyClone(snapshotName=snapshotName, cloneName=cloneName) luns = self.marscluster.lun.show(json=True) clone = [lun for lun in luns if lun['name'] == cloneName][0] mappedInitiatorGroups = [ group['igroup-name'] for group in clone['maps'] ] self.assertTrue(len(mappedInitiatorGroups) == 2) self.assertTrue(mappedInitiatorGroups[0] in [ originalInitiatorGroups[0]['name'], originalInitiatorGroups[-1] ['name'] ]) self.assertTrue(mappedInitiatorGroups[1] in [ originalInitiatorGroups[0]['name'], originalInitiatorGroups[-1] ['name'] ]) LOG.info('Mapped initiator groups:', mappedInitiatorGroups) def test_clone_sequent(self): """ Verify auto-naming of clone when previous auto-named clone already exists. """ lunNamePrefix = 'LuN' lunName = lunNamePrefix + '_1' snapshotName = lunName + '_snap' cloneName = lunName + '_clone_0' sequentCloneName = lunName + '_clone_1' LOG.step('Creating LUN') self.luns.create(count=1, size='1g', prefix=lunNamePrefix) luns = self.marscluster.lun.show(json=True) self.assertTrue(len(luns) == 1) LOG.info('LUN created:\n', luns) LOG.step('Creating LUN snapshot') self.marscluster.snapshot.create(luns=lunName, name=snapshotName) snapshots = self.marscluster.snapshot.show(json=True) LOG.info('Snapshot created:\n', snapshots) self.lunsPage.btnRefresh.click() self.lunsPage.btnRefresh.waitUntilEnabled() self._navigateToLUNSnapshotsPage(lunName=lunName) LOG.step('Opening wizard') wizard = CloneLUNSnapshotWizard(driver=self.driver) wizard.open(lunName=lunName, lunSnapshotName=snapshotName) LOG.info('Wizard open.') LOG.step('Cloning LUN snapshot') wizard.activePage.submit() self._verifyClone(snapshotName=snapshotName, cloneName=cloneName) LOG.step('Opening wizard') wizard.open(lunName=lunName, lunSnapshotName=snapshotName) LOG.info('Wizard open.') LOG.step('Sequent cloning of LUN snapshot') wizard.activePage.submit() self._verifyClone(snapshotName=snapshotName, cloneName=sequentCloneName) def test_dialog_not_available(self): """ Verify dialog not available when no or >= 2 LUNs selected. """ lunNamePrefix = 'LuN' lunName = lunNamePrefix + '_1' lunSnapshotNamePrefix = lunName + '_snap_' lunSnapshotCount = 4 LOG.step('Creating LUN') self.luns.create(count=1, size='1g', prefix=lunNamePrefix) luns = self.marscluster.lun.show(json=True) LOG.info('LUN created:\n', luns) LOG.step('Creating LUN snapshots') for count in range(lunSnapshotCount): self.marscluster.snapshot.create(luns=lunName, name=lunSnapshotNamePrefix + str(count)) snapshots = self.marscluster.snapshot.show(json=True) LOG.info('Snapshot created:\n', snapshots) self.lunsPage.btnRefresh.click() self.lunsPage.btnRefresh.waitUntilEnabled() self._navigateToLUNSnapshotsPage(lunName=lunName) LOG.step('Unselecting all LUN snapshots in grid') self.lunSnapshotsPage.gridSnapshots.unselect() snapshots = self.lunSnapshotsPage.gridSnapshots.find(selected=True) self.assertFalse(snapshots) LOG.info('Selected LUN snapshots:', snapshots) LOG.step("Verifying button 'Clone' disabled") self.assertFalse(self.lunSnapshotsPage.btnClone.isEnabled()) LOG.info("Button 'Clone' is enabled:", self.lunSnapshotsPage.btnClone.isEnabled()) LOG.step('Selecting 1 LUN snapshot in grid') self.lunSnapshotsPage.gridSnapshots.unselect() self.lunSnapshotsPage.gridSnapshots.select(name=lunSnapshotNamePrefix + '1') snapshots = self.lunSnapshotsPage.gridSnapshots.find(selected=True) self.assertTrue(len(snapshots) == 1) LOG.info('Selected LUN snapshots:', snapshots) LOG.step("Verifying button 'Clone' enabled") self.assertTrue(self.lunSnapshotsPage.btnClone.isEnabled()) LOG.info("Button 'Clone' is enabled:", self.lunSnapshotsPage.btnClone.isEnabled()) LOG.step('Selecting 2 LUN snapshots in grid') self.lunSnapshotsPage.gridSnapshots.unselect() self.lunSnapshotsPage.gridSnapshots.select( name=[lunSnapshotNamePrefix + '1', lunSnapshotNamePrefix + '2']) snapshots = self.lunSnapshotsPage.gridSnapshots.find(selected=True) self.assertTrue(len(snapshots) == 2) LOG.info('Selected LUN snapshots:', snapshots) LOG.step("Verifying button 'Clone' disabled") self.assertFalse(self.lunSnapshotsPage.btnClone.isEnabled()) LOG.info("Button 'Clone' is enabled:", self.lunSnapshotsPage.btnClone.isEnabled()) def test_dialog_cancel(self): """ Verify closing wizard without submission does not affect LUN and its mappings. """ lunNamePrefix = 'LuN' lunName = lunNamePrefix + '_1' snapshotName = lunName + '_snap' LOG.step('Creating LUNs') self.luns.create(count=1, size='1g', prefix=lunNamePrefix) luns = self.marscluster.lun.show(json=True) lunCount = len(luns) LOG.info('LUN created:\n', luns) LOG.step('Creating LUN snapshot') self.marscluster.snapshot.create(luns=lunName, name=snapshotName) snapshots = self.marscluster.snapshot.show(json=True) LOG.info('Snapshot created:\n', snapshots) self.lunsPage.btnRefresh.click() self.lunsPage.btnRefresh.waitUntilEnabled() self._navigateToLUNSnapshotsPage(lunName=lunName) LOG.step('Opening wizard') wizard = CloneLUNSnapshotWizard(driver=self.driver) wizard.open(lunName=lunName, lunSnapshotName=snapshotName) LOG.info('Wizard open.') LOG.step('Closing wizard') wizard.cancel() LOG.info('Wizard closed.') LOG.step('Verifying no LUN snapshot clone has been created.') luns = self.marscluster.lun.show(json=True) self.assertTrue(len(luns) == lunCount) LOG.info('No clone has been created.') def testTeardown(self): self.driver.close() def suiteTeardown(self): LOG.step('Closing browser') self.driver.quit() LOG.step('Deleting snapshots') snapshots = self.marscluster.snapshot.show(json=True) for snapshot in snapshots: self.marscluster.snapshot.delete(name=snapshot['name'], lun=snapshot['object']) self.assertFalse(self.marscluster.snapshot.show(json=True)) LOG.info('Snapshots deleted.') LOG.step('Destroying LUNs') luns = express.Luns(node=self.marscluster, cleanup=True) del luns LOG.info('LUNs destroyed.') def _deleteDependentConsistencyGroups(self): while True: consistencyGroups = self.marscluster.cg.show(json=True) if not consistencyGroups: break else: for consistencyGroup in consistencyGroups: if 'cg' not in consistencyGroup: self.marscluster.cg.delete( name=consistencyGroup['name']) def _navigateToLUNSnapshotsPage(self, lunName): LOG.step('Navigating to LUN Snapshots page...') self.lunsPage.gridLUNs.clickLink(name=lunName, click={'name': lunName}) self.lunDetailsPage.waitUntilOpen() self.lunDetailsPage.tabSnapshots.click() self.lunSnapshotsPage.waitUntilOpen() LOG.info('Browser landed on LUN Snapshots page.') def _verifyClone(self, snapshotName, cloneName): luns = self.marscluster.lun.show(json=True) snapshots = self.marscluster.snapshot.show(json=True) snapshot = [ snapshot for snapshot in snapshots if snapshot['name'] == snapshotName ][0] clone = [ lun for lun in luns if (lun.get('parent-snapshot') == snapshotName and lun['name'] == cloneName) ][0] self.assertTrue(clone) self.assertTrue(clone['size'] == snapshot['lun-info']['size']) LOG.info("Clone size equal to snapshot size:", clone['size']) self.assertTrue(clone['parent'] == snapshot['object']) LOG.info("Cloned parent is original LUN:", clone['parent'])
class TestEditLUNStateWizard(FRTestCase): def suiteSetup(self): self.username = ARGS.values.username self.password = ARGS.values.password self.locale = ARGS.values.locale self.webUIHostName = getFQDN(self.marscluster.getMasterNode().hostname) def testSetup(self): self.driver = self.getDriver() self.loginPage = LoginPage(driver=self.driver, url=self.webUIHostName) self.headerPage = HeaderPage(driver=self.driver) self.allStoragePage = AllStoragePage(driver=self.driver) self.lunsPage = LUNsPage(driver=self.driver) self.node = self.marscluster self.luns = express.Luns(node=self.marscluster) LOG.step('Signing in') self.loginPage.open() self.loginPage.waitUntilOpen() if self.locale is None: self.locale = self.loginPage.getRandomLocale() self.loginPage.signIn(username=self.username, password=self.password, locale=self.locale) LOG.info('Signed in with username: %s, password: %s, locale: %s.' % (self.username, self.password, self.locale)) LOG.info('Browser landed on header page.') LOG.info('Navigating to LUNs page...') self.headerPage.btnManager.click() self.allStoragePage.tabLUNs.click() self.lunsPage.waitUntilOpen() LOG.info('Browser landed on LUNs page.') def test_single_lun_offline_online(self): """ Verify single LUN's state change from Online to Offline. """ LOG.step('Creating LUNs') lunCount = 3 lunSize = 2 lunSizeUnit = 'G' lunNamePrefix = 'LuN' self.luns.create(count=lunCount, size=str(lunSize) + lunSizeUnit, prefix=lunNamePrefix) LOG.info('LUNs created:\n', self.marscluster.lun.show(json=True)) # Refresh LUN grid self.lunsPage.btnRefresh.click() self.lunsPage.btnRefresh.waitUntilEnabled() LOG.step('Taking LUN offline') wizard = EditLUNStateWizard(driver=self.driver) wizard.openTakeOffline(name=lunNamePrefix + '_1') wizard.activePage.submit() LOG.info('Taking offline submitted.') LOG.step('Verifying LUN state') lunState = { lun['name']: lun['lun-state'] for lun in self.node.lun.show(json=True) }[lunNamePrefix + '_1'] self.assertTrue(lunState == 'offline') LOG.info('LUN state:', lunState) LOG.step('Taking LUN online') wizard.takeOnline(name=lunNamePrefix + '_1') LOG.info('Taking online submitted.') LOG.step('Verifying LUN state') lunState = { lun['name']: lun['lun-state'] for lun in self.node.lun.show(json=True) }[lunNamePrefix + '_1'] self.assertTrue(lunState == 'online') LOG.info('LUN state:', lunState) def test_multiple_luns_offline_online(self): """ Verify multiple LUNs' state change from Online to Offline. """ LOG.step('Creating LUNs') lunCount = 7 lunSize = 2 lunSizeUnit = 'G' lunNamePrefix = 'LuN' self.luns.create(count=lunCount, size=str(lunSize) + lunSizeUnit, prefix=lunNamePrefix) LOG.info('LUNs created:\n', self.marscluster.lun.show(json=True)) # Refresh LUN grid self.lunsPage.btnRefresh.click() self.lunsPage.btnRefresh.waitUntilEnabled() LOG.step('Taking all LUNs offline') wizard = EditLUNStateWizard(driver=self.driver) wizard.openTakeOffline(name=lunNamePrefix, matchPattern=True) wizard.activePage.submit() LOG.info('Taking offline submitted.') LOG.step("Verifying LUNs' state") luns = { lun['name']: lun['lun-state'] for lun in self.node.lun.show(json=True) } for lunName in luns: self.assertTrue(luns[lunName] == 'offline') LOG.info("LUN: %s, state: %s" % (lunName, luns[lunName])) LOG.step('Taking all LUNs online') wizard.takeOnline(name=lunNamePrefix, matchPattern=True) LOG.info('Taking online submitted.') # Let UI to communicate with the server and update LUNs. time.sleep(3) LOG.step("Verifying LUNs' state") luns = { lun['name']: lun['lun-state'] for lun in self.node.lun.show(json=True) } for lunName in luns: self.assertTrue(luns[lunName] == 'online') LOG.info("LUN: %s, state: %s" % (lunName, luns[lunName])) def test_offline_cancel(self): """ Verify 'Take Offline -> Cancel' does cancel dialog gracefully, state not affected. """ LOG.step('Creating LUNs') lunCount = 3 lunSize = 2 lunSizeUnit = 'G' lunNamePrefix = 'LuN' self.luns.create(count=lunCount, size=str(lunSize) + lunSizeUnit, prefix=lunNamePrefix) LOG.info('LUNs created:\n', self.marscluster.lun.show(json=True)) # Refresh LUN grid self.lunsPage.btnRefresh.click() self.lunsPage.btnRefresh.waitUntilEnabled() LOG.step('Taking LUN offline') wizard = EditLUNStateWizard(driver=self.driver) wizard.openTakeOffline(name=lunNamePrefix + '_1') LOG.info("'Take Offline' page is open.") LOG.step('Canceling dialog') wizard.cancel() LOG.info('Dialog cancelled.') LOG.step('Verifying LUN state has not been changed') lunState = { lun['name']: lun['lun-state'] for lun in self.node.lun.show(json=True) }[lunNamePrefix + '_1'] self.assertTrue(lunState == 'online') LOG.info('LUN state:', lunState) def test_online_not_available(self): """ Verify that 'Take Online' is not available for selected LUNs with status 'Online'. """ LOG.step('Creating LUNs') lunCount = 3 lunSize = 2 lunSizeUnit = 'G' lunNamePrefix = 'LuN' self.luns.create(count=lunCount, size=str(lunSize) + lunSizeUnit, prefix=lunNamePrefix) LOG.info('LUNs created:\n', self.marscluster.lun.show(json=True)) # Refresh LUN grid self.lunsPage.btnRefresh.click() self.lunsPage.btnRefresh.waitUntilEnabled() LOG.step("Selecting LUN '%s'" % lunNamePrefix + '_1') self.lunsPage.gridLUNs.select(name=lunNamePrefix + '_1') LOG.info('LUN selected.') LOG.step( "Verifying menu 'State -> Online' is disabled for LUN in online") isOnlineEnabled = self.lunsPage.menuEdit.isItemEnabled( item=['State', 'Online']) self.assertFalse(isOnlineEnabled) LOG.info("Menu 'Edit': Item 'State -> Online' is enabled:", isOnlineEnabled) LOG.step( "Verifying menu 'State -> Offline' is enabled for LUN in online") isOfflineEnabled = self.lunsPage.menuEdit.isItemEnabled( item=['State', 'Offline']) self.assertTrue(isOfflineEnabled) LOG.info("Menu 'Edit': Item 'State -> Offline' is enabled:", isOfflineEnabled) def test_offline_not_available(self): """ Verify that 'Take Offline' is not available for selected LUNs with status 'Offline'. """ LOG.step('Creating LUNs') lunCount = 3 lunSize = 2 lunSizeUnit = 'G' lunNamePrefix = 'LuN' self.luns.create(count=lunCount, size=str(lunSize) + lunSizeUnit, prefix=lunNamePrefix) LOG.info('LUNs created:\n', self.marscluster.lun.show(json=True)) # Refresh LUN grid self.lunsPage.btnRefresh.click() self.lunsPage.btnRefresh.waitUntilEnabled() LOG.step('Taking LUN offline') wizard = EditLUNStateWizard(driver=self.driver) wizard.openTakeOffline(name=lunNamePrefix + '_1') wizard.activePage.submit() LOG.info('Taking offline submitted.') LOG.step('Verifying LUN state') lunState = { lun['name']: lun['lun-state'] for lun in self.node.lun.show(json=True) }[lunNamePrefix + '_1'] self.assertTrue(lunState == 'offline') LOG.info('LUN state:', lunState) LOG.step("Selecting LUN '%s'" % lunNamePrefix + '_1') self.lunsPage.gridLUNs.select(name=lunNamePrefix + '_1') LOG.info('LUN selected.') LOG.step( "Verifying menu 'State -> Offline' is disabled for LUN in offline") isOfflineEnabled = self.lunsPage.menuEdit.isItemEnabled( item=['State', 'Offline']) self.assertFalse(isOfflineEnabled) LOG.info("Menu 'Edit': Item 'State -> Offline' is enabled:", isOfflineEnabled) LOG.step( "Verifying menu 'State -> Online' is enabled for LUN in offline") isOnlineEnabled = self.lunsPage.menuEdit.isItemEnabled( item=['State', 'Online']) self.assertTrue(isOnlineEnabled) LOG.info("Menu 'Edit': Item 'State -> Online' is enabled:", isOnlineEnabled) def testTeardown(self): self.driver.close() luns = express.Luns(node=self.marscluster, cleanup=True) del luns LOG.info('LUNs destroyed.') def suiteTeardown(self): LOG.step('Closing browser') self.driver.quit()
class TestRenameLUNWizard(FRTestCase): def suiteSetup(self): self.username = ARGS.values.username self.password = ARGS.values.password self.locale = ARGS.values.locale self.webUIHostName = getFQDN(self.marscluster.getMasterNode().hostname) def testSetup(self): self.driver = self.getDriver() self.loginPage = LoginPage(driver=self.driver, url=self.webUIHostName) self.headerPage = HeaderPage(driver=self.driver) self.allStoragePage = AllStoragePage(driver=self.driver) self.lunsPage = LUNsPage(driver=self.driver) self.node = self.marscluster self.luns = express.Luns(node=self.marscluster) LOG.step('Signing in') self.loginPage.open() self.loginPage.waitUntilOpen() if self.locale is None: self.locale = self.loginPage.getRandomLocale() self.loginPage.signIn(username=self.username, password=self.password, locale=self.locale) LOG.info('Signed in with username: %s, password: %s, locale: %s.' % (self.username, self.password, self.locale)) LOG.info('Browser landed on header page.') LOG.info('Navigating to LUNs page...') self.headerPage.btnManager.click() self.allStoragePage.tabLUNs.click() self.lunsPage.waitUntilOpen() LOG.info('Browser landed on LUNs page.') def test_valid_name(self): """ Verify LUN renaming with valid name. """ LOG.step('Creating LUNs') lunCount = 3 lunSize = '1g' lunNamePrefix = 'LuN' lunNewName = 'NewName' self.luns.create(count=lunCount, size=lunSize, prefix=lunNamePrefix) LOG.info('LUNs created:\n', self.node.lun.show(json=True)) self.lunsPage.btnRefresh.click() self.lunsPage.btnRefresh.waitUntilEnabled() LOG.step('Renaming LUN in dialog') wizard = RenameLUNWizard(driver=self.driver) wizard.open(name=lunNamePrefix + '_1') LOG.info('Old LUN name:', lunNamePrefix + '_1') wizard.renameLUNPage.renameLUN(name=lunNewName) LOG.info('New LUN name:', lunNewName) wizard.renameLUNPage.submit() LOG.info('Rename submitted.') LOG.step('Verifying LUN name has been changed') lun = self.lunsPage.gridLUNs.find(name=lunNewName) self.assertTrue(len(lun) == 1) self.assertTrue(lun[0]['name'] == lunNewName) LOG.info('LUN found:\n', lun) def test_invalid_name(self): """ Verify LUN renaming with invalid name. """ LOG.step('Creating LUNs') lunCount = 3 lunSize = '1g' lunNamePrefix = 'LuN' lunNewName = 'NewName*&#@1A_^?,' self.luns.create(count=lunCount, size=lunSize, prefix=lunNamePrefix) LOG.info('LUNs created:\n', self.node.lun.show(json=True)) self.lunsPage.btnRefresh.click() self.lunsPage.btnRefresh.waitUntilEnabled() LOG.step('Renaming LUN in dialog') wizard = RenameLUNWizard(driver=self.driver) wizard.open(name=lunNamePrefix + '_1') LOG.info('Old LUN name:', lunNamePrefix + '_1') wizard.renameLUNPage.renameLUN(name=lunNewName) LOG.info('New LUN name:', lunNewName) LOG.step('Verifying name error message') wizard.activePage.lblNameError.waitUntilPresent() LOG.info('Name error message:', wizard.activePage.lblNameError.getText()) self.assertFalse(wizard.activePage.btnOK.isEnabled()) LOG.info("Button 'OK' is enabled:", wizard.activePage.btnOK.isEnabled()) def test_unicode_name(self): """ Verify error message on setting LUN name containing Unicode characters. """ LOG.step('Creating LUNs') lunCount = 3 lunSize = '1g' lunNamePrefix = 'LuN' lunNewName = u'Fran\u00e7ais' self.luns.create(count=lunCount, size=lunSize, prefix=lunNamePrefix) LOG.info('LUNs created:\n', self.node.lun.show(json=True)) self.lunsPage.btnRefresh.click() self.lunsPage.btnRefresh.waitUntilEnabled() LOG.step('Renaming LUN in dialog') wizard = RenameLUNWizard(driver=self.driver) wizard.open(name=lunNamePrefix + '_1') LOG.info('Old LUN name:', lunNamePrefix + '_1') wizard.renameLUNPage.renameLUN(name=lunNewName) LOG.info('New LUN name:', lunNewName) LOG.step('Verifying LUN invalid name error message') wizard.activePage.lblNameError.waitUntilVisible() LOG.info('Error message:', wizard.activePage.lblNameError.getText()) def test_dialog_cancel(self): """ Verify LUN name remains intact on dialog cancel. """ LOG.step('Creating LUNs') lunCount = 3 lunSize = '1g' lunNamePrefix = 'LuN' lunNewName = 'NewName' self.luns.create(count=lunCount, size=lunSize, prefix=lunNamePrefix) LOG.info('LUNs created:\n', self.node.lun.show(json=True)) self.lunsPage.btnRefresh.click() self.lunsPage.btnRefresh.waitUntilEnabled() LOG.step('Assigning new LUN name in dialog') wizard = RenameLUNWizard(driver=self.driver) wizard.open(name=lunNamePrefix + '_1') LOG.info('Old LUN name:', lunNamePrefix + '_1') wizard.renameLUNPage.renameLUN(name=lunNewName) LOG.info('New LUN name:', lunNewName) LOG.step('Canceling dialog without submission') wizard.cancel() LOG.info('Dialog cancelled.') LOG.step('Verifying LUN name has not been changed') luns = self.lunsPage.gridLUNs.find(name=lunNamePrefix + '_1') self.assertTrue(len(luns) == 1) self.assertTrue(luns[0]['name'] == lunNamePrefix + '_1') LOG.info('LUNs with old name:\n', luns) luns = self.lunsPage.gridLUNs.find(name=lunNewName) self.assertTrue(len(luns) == 0) LOG.info('LUNs with new name:\n', luns) def testTeardown(self): self.driver.close() luns = express.Luns(node=self.marscluster, cleanup=True) del luns LOG.info('LUNs destroyed.') def suiteTeardown(self): LOG.step('Closing browser') self.driver.quit()
class TestEditLUNMappingsWizard(FRTestCase): def suiteSetup(self): self.username = ARGS.values.username self.password = ARGS.values.password self.locale = ARGS.values.locale self.webUIHostName = getFQDN(self.marscluster.getMasterNode().hostname) def testSetup(self): self.driver = self.getDriver() self.loginPage = LoginPage(driver=self.driver, url=self.webUIHostName) self.headerPage = HeaderPage(driver=self.driver) self.allStoragePage = AllStoragePage(driver=self.driver) self.lunsPage = LUNsPage(driver=self.driver) LOG.step('Cleaning out cluster content') LOG.info('Destroying LUNs...') luns = express.Luns(node=self.marscluster, cleanup=True) del luns self.assertFalse(self.marscluster.lun.show(json=True)) LOG.info('Done.') LOG.info('Destroying existing initiator groups...') self.marscluster.igroup.destroyAll() LOG.info('Done.') LOG.info('Destroying existing consistency groups...') self.deleteDependentConsistencyGroups() LOG.info('Done.') self.luns = express.Luns(node=self.marscluster) LOG.step('Signing in') self.loginPage.open() self.loginPage.waitUntilOpen() if self.locale is None: self.locale = self.loginPage.getRandomLocale() self.loginPage.signIn(username=self.username, password=self.password, locale=self.locale) LOG.info('Signed in with username: %s, password: %s, locale: %s.' % (self.username, self.password, self.locale)) LOG.info('Browser landed on header page.') LOG.info('Navigating to LUNs page...') self.headerPage.btnManager.click() self.allStoragePage.tabLUNs.click() self.lunsPage.waitUntilOpen() LOG.info('Browser landed on LUNs page.') def deleteDependentConsistencyGroups(self): while True: consistencyGroups = self.marscluster.cg.show(json=True) if not consistencyGroups: break else: for consistencyGroup in consistencyGroups: if 'cg' not in consistencyGroup: self.marscluster.cg.delete( name=consistencyGroup['name']) def test_no_ig(self): """ Verify wizard's grid is empty when no initiators groups exist. """ LOG.step('Creating LUNs') lunCount = 3 lunSize = 2 lunSizeUnit = 'G' lunNamePrefix = 'LuN' self.luns.create(count=lunCount, size=str(lunSize) + lunSizeUnit, prefix=lunNamePrefix) LOG.info('LUNs created:\n', self.marscluster.lun.show(json=True)) # Refresh LUN grid self.lunsPage.btnRefresh.click() self.lunsPage.btnRefresh.waitUntilEnabled() LOG.step('Opening wizard') wizard = EditLUNMappingsWizard(driver=self.driver) wizard.open(name=lunNamePrefix + '_1') LOG.info('Wizard open') LOG.step('Verifying no initiator groups are available') initiatorGroups = wizard.activePage.gridInitiatorGroups.find() self.assertFalse(initiatorGroups) LOG.info('Initiators groups available:', initiatorGroups) LOG.step("Verifying button 'OK' is disabled") self.assertFalse(wizard.activePage.btnOK.isEnabled()) LOG.info("Button 'OK' enabled:", wizard.activePage.btnOK.isEnabled()) def test_mapped(self): """ Verify proper LUN mapping on wizard's page. """ LOG.step('Creating LUNs') lunCount = 3 lunSize = 2 lunSizeUnit = 'G' lunNamePrefix = 'LuN' initiatorGroupName = 'IG-' initiatorGroupsNumber = 5 self.luns.create(count=lunCount, size=str(lunSize) + lunSizeUnit, prefix=lunNamePrefix) LOG.info('LUNs created:\n', self.marscluster.lun.show(json=True)) LOG.step('Creating initiator groups') for initiatorIndex in range(initiatorGroupsNumber): fictiveWWPN = format(random.randrange(sys.maxint), 'x').rjust(16, 'f') self.marscluster.igroup.create(name=(initiatorGroupName + str(initiatorIndex)), ostype='vmware', initiators=fictiveWWPN) initiatorGroups = self.marscluster.igroup.show(json=True) LOG.info('Initiator groups created:\n', initiatorGroups) LOG.step('Mapping LUN to initiator groups') self.marscluster.lun.map({ 'name': lunNamePrefix + '_1', 'igroup': initiatorGroups[0]['name'] }) self.marscluster.lun.map({ 'name': lunNamePrefix + '_1', 'igroup': initiatorGroups[-1]['name'] }) LOG.info('LUN mapped:\n', self.marscluster.lun.mapping_show(json=True)) # Refresh LUN grid self.lunsPage.btnRefresh.click() self.lunsPage.btnRefresh.waitUntilEnabled() LOG.step('Opening wizard') wizard = EditLUNMappingsWizard(driver=self.driver) wizard.open(name=lunNamePrefix + '_1') LOG.info('Wizard open') self.assertTrue(wizard.activePage.lblName.getText() == lunNamePrefix + '_1') LOG.step('Verifying LUN mapping') groups = wizard.activePage.gridInitiatorGroups.find() self.assertTrue(len(initiatorGroups) == len(groups)) for group in groups: if (group['initiator_groups'] == initiatorGroups[0]['name']) or \ (group['initiator_groups'] == initiatorGroups[-1]['name']): self.assertTrue(group['selected'] == True) LOG.info("LUN '%s' mapped to initiator group: %s" % (lunNamePrefix + '_1', group['initiator_groups'])) else: self.assertFalse(group['selected'] == True) def test_not_mapped(self): """ Verify no mapping on wizard's page when LUN not mapped. """ LOG.step('Creating LUNs') lunCount = 3 lunSize = 2 lunSizeUnit = 'G' lunNamePrefix = 'LuN' initiatorGroupName = 'IG-' initiatorGroupsNumber = 5 self.luns.create(count=lunCount, size=str(lunSize) + lunSizeUnit, prefix=lunNamePrefix) LOG.info('LUNs created:\n', self.marscluster.lun.show(json=True)) LOG.step('Creating initiator groups') for initiatorIndex in range(initiatorGroupsNumber): fictiveWWPN = format(random.randrange(sys.maxint), 'x').rjust(16, 'f') self.marscluster.igroup.create(name=(initiatorGroupName + str(initiatorIndex)), ostype='vmware', initiators=fictiveWWPN) initiatorGroups = self.marscluster.igroup.show(json=True) LOG.info('Initiator groups created:\n', initiatorGroups) # Refresh LUN grid self.lunsPage.btnRefresh.click() self.lunsPage.btnRefresh.waitUntilEnabled() LOG.step('Opening wizard') wizard = EditLUNMappingsWizard(driver=self.driver) wizard.open(name=lunNamePrefix + '_1') LOG.info('Wizard open') self.assertTrue(wizard.activePage.lblName.getText() == lunNamePrefix + '_1') LOG.step('Verifying LUN not mapped') groups = wizard.activePage.gridInitiatorGroups.find() self.assertTrue(len(initiatorGroups) == len(groups)) for group in groups: self.assertFalse(group['selected'] == True) LOG.info("LUN '%s' mapped to '%s': %s" % (lunNamePrefix + '_1', group['initiator_groups'], group['selected'])) def test_map(self): """ Verify LUN mapping made in wizard. """ LOG.step('Creating LUNs') lunCount = 3 lunSize = 2 lunSizeUnit = 'G' lunNamePrefix = 'LuN' initiatorGroupName = 'IG-' initiatorGroupsNumber = 5 self.luns.create(count=lunCount, size=str(lunSize) + lunSizeUnit, prefix=lunNamePrefix) LOG.info('LUNs created:\n', self.marscluster.lun.show(json=True)) LOG.step('Creating initiator groups') for initiatorIndex in range(initiatorGroupsNumber): fictiveWWPN = format(random.randrange(sys.maxint), 'x').rjust(16, 'f') self.marscluster.igroup.create(name=(initiatorGroupName + str(initiatorIndex)), ostype='vmware', initiators=fictiveWWPN) initiatorGroups = self.marscluster.igroup.show(json=True) LOG.info('Initiator groups created:\n', initiatorGroups) # Refresh LUN grid self.lunsPage.btnRefresh.click() self.lunsPage.btnRefresh.waitUntilEnabled() LOG.step('Opening wizard') wizard = EditLUNMappingsWizard(driver=self.driver) wizard.open(name=lunNamePrefix + '_1') LOG.info('Wizard open') self.assertTrue(wizard.activePage.lblName.getText() == lunNamePrefix + '_1') LOG.step('Mapping LUN to initiator groups') self.assertTrue( len(initiatorGroups) == len( wizard.activePage.gridInitiatorGroups.find())) # Select first and last initiator groups in grid wizard.activePage.gridInitiatorGroups.select(initiator_groups=[ initiatorGroups[0]['name'], initiatorGroups[-1]['name'] ]) LOG.info('Initiator groups selected:\n', wizard.activePage.gridInitiatorGroups.find(selected=True)) wizard.activePage.submit() LOG.info('Wizard submitted.') LOG.step('Verifying LUN mapping') mappedGroups = [ group['igroup-name'] for group in self.marscluster.lun.mapping_show(json=True) ] self.assertTrue(len(mappedGroups) == 2) self.assertTrue(initiatorGroups[0]['name'] in mappedGroups) LOG.info("LUN '%s' mapped to initiator group: %s" % (lunNamePrefix + '_1', initiatorGroups[0]['name'])) self.assertTrue(initiatorGroups[-1]['name'] in mappedGroups) LOG.info("LUN '%s' mapped to initiator group: %s" % (lunNamePrefix + '_1', initiatorGroups[-1]['name'])) def test_remap(self): """ Verify proper LUN re-mapping on wizard's page. """ LOG.step('Creating LUNs') lunCount = 3 lunSize = 2 lunSizeUnit = 'G' lunNamePrefix = 'LuN' initiatorGroupName = 'IG-' initiatorGroupsNumber = 5 self.luns.create(count=lunCount, size=str(lunSize) + lunSizeUnit, prefix=lunNamePrefix) LOG.info('LUNs created:\n', self.marscluster.lun.show(json=True)) LOG.step('Creating initiator groups') for initiatorIndex in range(initiatorGroupsNumber): fictiveWWPN = format(random.randrange(sys.maxint), 'x').rjust(16, 'f') self.marscluster.igroup.create(name=(initiatorGroupName + str(initiatorIndex)), ostype='vmware', initiators=fictiveWWPN) initiatorGroups = self.marscluster.igroup.show(json=True) LOG.info('Initiator groups created:\n', initiatorGroups) LOG.step('Mapping LUN to initiator groups') # Map to first and last initiator groups self.marscluster.lun.map({ 'name': lunNamePrefix + '_1', 'igroup': initiatorGroups[0]['name'] }) self.marscluster.lun.map({ 'name': lunNamePrefix + '_1', 'igroup': initiatorGroups[-1]['name'] }) LOG.info('LUN mapped:\n', self.marscluster.lun.mapping_show(json=True)) # Refresh LUN grid self.lunsPage.btnRefresh.click() self.lunsPage.btnRefresh.waitUntilEnabled() LOG.step('Opening wizard') wizard = EditLUNMappingsWizard(driver=self.driver) wizard.open(name=lunNamePrefix + '_1') LOG.info('Wizard open') LOG.step('Re-mapping LUN') # Map LUN to second initiator group instead of 1st and last ones wizard.activePage.selectInitiatorGroups( name=[initiatorGroups[1]['name']]) LOG.info('Mapping set to initiator group:', initiatorGroups[1]['name']) wizard.activePage.submit() LOG.info('Wizard submitted.') LOG.step('Verifying LUN mapping') lunMapping = self.marscluster.lun.mapping_show(json=True) self.assertTrue(len(lunMapping) == 1) self.assertTrue( lunMapping[0]['igroup-name'] == initiatorGroups[1]['name']) LOG.info("LUN '%s' mapped to initiator group: %s" % (lunNamePrefix + '_1', lunMapping[0]['igroup-name'])) def test_unmap(self): """ Verify LUN un-mapping on wizard's page. """ LOG.step('Creating LUNs') lunCount = 3 lunSize = 2 lunSizeUnit = 'G' lunNamePrefix = 'LuN' initiatorGroupName = 'IG-' initiatorGroupsNumber = 5 self.luns.create(count=lunCount, size=str(lunSize) + lunSizeUnit, prefix=lunNamePrefix) LOG.info('LUNs created:\n', self.marscluster.lun.show(json=True)) LOG.step('Creating initiator groups') for initiatorIndex in range(initiatorGroupsNumber): fictiveWWPN = format(random.randrange(sys.maxint), 'x').rjust(16, 'f') self.marscluster.igroup.create(name=(initiatorGroupName + str(initiatorIndex)), ostype='vmware', initiators=fictiveWWPN) initiatorGroups = self.marscluster.igroup.show(json=True) LOG.info('Initiator groups created:\n', initiatorGroups) LOG.step('Mapping LUN to initiator groups') # Map to first and last initiator groups self.marscluster.lun.map({ 'name': lunNamePrefix + '_1', 'igroup': initiatorGroups[0]['name'] }) self.marscluster.lun.map({ 'name': lunNamePrefix + '_1', 'igroup': initiatorGroups[-1]['name'] }) LOG.info('LUN mapped:\n', [ lun for lun in self.marscluster.lun.mapping_show(json=True) if lun['lun-name'] == lunNamePrefix + '_1' ][0]) # Refresh LUN grid self.lunsPage.btnRefresh.click() self.lunsPage.btnRefresh.waitUntilEnabled() LOG.step('Opening wizard') wizard = EditLUNMappingsWizard(driver=self.driver) wizard.open(name=lunNamePrefix + '_1') LOG.info('Wizard open.') LOG.step('Unselecting all initiator groups') wizard.activePage.selectInitiatorGroups() self.assertFalse( wizard.activePage.gridInitiatorGroups.find(selected=True)) LOG.info('Selected initiator groups:', wizard.activePage.gridInitiatorGroups.find(selected=True)) wizard.activePage.submit() LOG.info('Wizard submitted.') LOG.step('Verifying LUN has been um-mapped') lunMapping = [ lun for lun in self.marscluster.lun.mapping_show(json=True) if lun['lun-name'] == lunNamePrefix + '_1' ] self.assertFalse(lunMapping) LOG.info("LUN '%s' has no mappings." % (lunNamePrefix + '_1')) def test_dialog_cancel(self): """ Verify LUN mapping remains intact on wizard cancellation. """ LOG.step('Creating LUNs') lunCount = 3 lunSize = 2 lunSizeUnit = 'G' lunNamePrefix = 'LuN' initiatorGroupName = 'IG-' initiatorGroupsNumber = 5 self.luns.create(count=lunCount, size=str(lunSize) + lunSizeUnit, prefix=lunNamePrefix) LOG.info('LUNs created:\n', self.marscluster.lun.show(json=True)) LOG.step('Creating initiator groups') for initiatorIndex in range(initiatorGroupsNumber): fictiveWWPN = format(random.randrange(sys.maxint), 'x').rjust(16, 'f') self.marscluster.igroup.create(name=(initiatorGroupName + str(initiatorIndex)), ostype='vmware', initiators=fictiveWWPN) initiatorGroups = self.marscluster.igroup.show(json=True) LOG.info('Initiator groups created:\n', initiatorGroups) LOG.step('Mapping LUN to initiator groups') # Map to first and last initiator groups self.marscluster.lun.map({ 'name': lunNamePrefix + '_1', 'igroup': initiatorGroups[0]['name'] }) self.marscluster.lun.map({ 'name': lunNamePrefix + '_1', 'igroup': initiatorGroups[-1]['name'] }) originalMappings = [ lun for lun in self.marscluster.lun.mapping_show(json=True) if lun['lun-name'] == lunNamePrefix + '_1' ] LOG.info('LUN mapped:\n', originalMappings) # Refresh LUN grid self.lunsPage.btnRefresh.click() self.lunsPage.btnRefresh.waitUntilEnabled() LOG.step('Opening wizard') wizard = EditLUNMappingsWizard(driver=self.driver) wizard.open(name=lunNamePrefix + '_1') LOG.info('Wizard open.') LOG.step('Canceling wizard') wizard.cancel() LOG.info('Wizard closed without submission.') LOG.step('Verifying LUN mappings') mappings = [ lun['igroup-name'] for lun in self.marscluster.lun.mapping_show(json=True) if lun['lun-name'] == lunNamePrefix + '_1' ] self.assertTrue(len(originalMappings) == len(mappings)) for mapping in originalMappings: self.assertTrue(mapping['igroup-name'] in mappings) LOG.info("LUN '%s' mapped to initiator group: %s" % (lunNamePrefix + '_1', mapping['igroup-name'])) LOG.info('LUN mappings remain intact.') def test_dialog_not_available(self): """ Verify menu item 'Edit -> Mappings' not available when multiple LUNs selected in grid. """ LOG.step('Creating LUNs') lunCount = 3 lunSize = 2 lunSizeUnit = 'G' lunNamePrefix = 'LuN' initiatorGroupName = 'IG-' initiatorGroupsNumber = 5 self.luns.create(count=lunCount, size=str(lunSize) + lunSizeUnit, prefix=lunNamePrefix) LOG.info('LUNs created:\n', self.marscluster.lun.show(json=True)) LOG.step('Creating initiator groups') for initiatorIndex in range(initiatorGroupsNumber): fictiveWWPN = format(random.randrange(sys.maxint), 'x').rjust(16, 'f') self.marscluster.igroup.create(name=(initiatorGroupName + str(initiatorIndex)), ostype='vmware', initiators=fictiveWWPN) initiatorGroups = self.marscluster.igroup.show(json=True) LOG.info('Initiator groups created:\n', initiatorGroups) LOG.step('Mapping LUN to initiator groups') # Map to first and last initiator groups self.marscluster.lun.map({ 'name': lunNamePrefix + '_1', 'igroup': initiatorGroups[0]['name'] }) self.marscluster.lun.map({ 'name': lunNamePrefix + '_1', 'igroup': initiatorGroups[-1]['name'] }) originalMappings = [ lun for lun in self.marscluster.lun.mapping_show(json=True) if lun['lun-name'] == lunNamePrefix + '_1' ] LOG.info('LUN mapped:\n', originalMappings) # Refresh LUN grid self.lunsPage.btnRefresh.click() self.lunsPage.btnRefresh.waitUntilEnabled() LOG.step('Selecting multiple LUNs') self.lunsPage.gridLUNs.select() LOG.info('LUNs selected:\n', self.lunsPage.gridLUNs.find(selected=True)) LOG.step("Checking state of menu 'Edit'") self.assertFalse(self.lunsPage.menuEdit.isItemEnabled(item='Mappings')) LOG.info("Menu item 'Edit -> Mappings' is enabled:", self.lunsPage.menuEdit.isItemEnabled(item='Mappings')) def testTeardown(self): self.driver.close() luns = express.Luns(node=self.marscluster, cleanup=True) del luns LOG.info('LUNs destroyed.') def suiteTeardown(self): LOG.step('Closing browser') self.driver.quit()
class TestCreateInitiatorGroupWizard(FRTestCase): def suiteSetup(self): self.username = ARGS.values.username self.password = ARGS.values.password self.locale = ARGS.values.locale self.webUIHostName = getFQDN(self.marscluster.getMasterNode().hostname) def testSetup(self): self.driver = self.getDriver() self.loginPage = LoginPage(driver=self.driver, url=self.webUIHostName) self.headerPage = HeaderPage(driver=self.driver) self.allStoragePage = AllStoragePage(driver=self.driver) self.initiatorGroupsPage = InitiatorGroupsPage(driver=self.driver) LOG.step('Cleaning out cluster content') LOG.info('Destroying LUNs...') luns = express.Luns(node=self.marscluster, cleanup=True) del luns self.assertFalse(self.marscluster.lun.show(json=True)) LOG.info('Done.') LOG.info('Destroying existing initiator groups...') self.marscluster.igroup.destroyAll() LOG.info('Done.') self.luns = express.Luns(node=self.marscluster) LOG.step('Signing in') self.loginPage.open() self.loginPage.waitUntilOpen() if self.locale is None: self.locale = self.loginPage.getRandomLocale() self.loginPage.signIn(username=self.username, password=self.password, locale=self.locale) LOG.info('Signed in with username: %s, password: %s, locale: %s.' % (self.username, self.password, self.locale)) LOG.info('Browser landed on header page.') LOG.info('Navigating to Initiator Groups page...') self.headerPage.btnManager.click() self.allStoragePage.tabInitiatorGroups.click() self.initiatorGroupsPage.waitUntilOpen() LOG.info('Browser landed on Initiator Groups page.') def test_create_minimal(self): """ Verify initiator group creation when name specified explicitly, OS Type is as default. """ initiatorGroupName = 'IG-1' defaultOSType = 'Windows' LOG.step('Opening wizard') wizard = CreateInitiatorGroupWizard(driver=self.driver) wizard.open() LOG.info('Wizard open.') LOG.step('Verifying default parameters') self.assertFalse(wizard.activePage.txtName.getText()) LOG.info("Default name: %s" % wizard.activePage.txtName.getText()) self.assertTrue( wizard.activePage.dLstOSType.getText() == defaultOSType) LOG.info("Default OS Type: %s" % wizard.activePage.dLstOSType.getText()) selectedWWPNs = wizard.activePage.gridInitiatorWWPNs.find( selected=True) self.assertFalse(selectedWWPNs) LOG.info('Selected WWPNs:', selectedWWPNs) LOG.step('Setting initiator group name') wizard.activePage.setName(name=initiatorGroupName) name = wizard.activePage.txtName.getText() self.assertTrue(name == initiatorGroupName) LOG.info('Initiator group name set:', name) LOG.step('Submitting dialog') wizard.activePage.submit() LOG.info('Dialog submitted.') LOG.step('Verifying initiator group has been created') initiatorGroups = self.marscluster.igroup.show(json=True) self.assertTrue(len(initiatorGroups) == 1) self.assertTrue(initiatorGroups[0]['name'] == initiatorGroupName) LOG.info('Initiator group created:', initiatorGroups[0]['name']) def test_create_custom_os_type(self): """ Verify initiator group creation when name and OS type specified explicitly. """ initiatorGroupName = 'IG-1' osType = 'Xen' LOG.step('Opening wizard') wizard = CreateInitiatorGroupWizard(driver=self.driver) wizard.open() LOG.info('Wizard open.') LOG.step('Setting initiator group name') wizard.activePage.setName(name=initiatorGroupName) name = wizard.activePage.txtName.getText() self.assertTrue(name == initiatorGroupName) LOG.info('Initiator group name set:', name) LOG.step('Setting OS type: %s' % osType) wizard.activePage.setOSType(osType=osType) setOSType = wizard.activePage.dLstOSType.getText() self.assertTrue(setOSType == osType) LOG.info('OS type set:', setOSType) LOG.step('Submitting dialog') wizard.activePage.submit() LOG.info('Dialog submitted.') LOG.step('Verifying initiator group has been created') initiatorGroups = self.marscluster.igroup.show(json=True) self.assertTrue(len(initiatorGroups) == 1) self.assertTrue(initiatorGroups[0]['name'] == initiatorGroupName) LOG.info("Initiator group's name:", initiatorGroups[0]['name']) self.assertTrue(initiatorGroups[0]['ostype'] == osType.lower()) LOG.info("Initiator group's OS type:", initiatorGroups[0]['ostype']) def test_create_single_initiator(self): """ Verify initiator group creation when name and OS type specified explicitly, and single initiator selected. """ initiatorGroupName = 'IG-1' osType = 'Xen' LOG.step('Opening wizard') wizard = CreateInitiatorGroupWizard(driver=self.driver) wizard.open() LOG.info('Wizard open.') LOG.step('Setting initiator group name') wizard.activePage.setName(name=initiatorGroupName) name = wizard.activePage.txtName.getText() self.assertTrue(name == initiatorGroupName) LOG.info('Initiator group name set:', name) LOG.step('Setting OS type: %s' % osType) wizard.activePage.setOSType(osType=osType) setOSType = wizard.activePage.dLstOSType.getText() self.assertTrue(setOSType == osType) LOG.info('OS type set:', setOSType) LOG.step('Setting single initiator') wwpns = wizard.activePage.getWWPNs() if wwpns: wizard.activePage.setWWPNs(wwpns=wwpns[0]['initiator_group']) setWWPNs = wizard.activePage.gridInitiatorWWPNs.find(selected=True) self.assertTrue(len(setWWPNs) == 1) self.assertTrue( setWWPNs[0]['initiator_group'] == wwpns[0]['initiator_group']) LOG.info('Initiator WWPN set:', setWWPNs[0]['initiator_group']) LOG.step('Submitting dialog') wizard.activePage.submit() LOG.info('Dialog submitted.') LOG.step('Verifying initiator group has been created') initiatorGroups = self.marscluster.igroup.show(json=True) self.assertTrue(len(initiatorGroups) == 1) self.assertTrue(initiatorGroups[0]['name'] == initiatorGroupName) LOG.info("Initiator group's name:", initiatorGroups[0]['name']) self.assertTrue(initiatorGroups[0]['ostype'] == osType.lower()) LOG.info("Initiator group's OS type:", initiatorGroups[0]['ostype']) self.assertTrue(initiatorGroups[0]['initiators'][0] == wwpns[0] ['initiator_group']) LOG.info("Initiator group's WWPN:", wwpns[0]['initiator_group']) else: LOG.info('No initiators found. Test skipped.') def test_create_add_single_initiator(self): """ Verify initiator group creation when name and OS type specified explicitly, and single initiator added and selected. """ initiatorGroupName = 'IG-1' osType = 'Xen' LOG.step('Opening wizard') wizard = CreateInitiatorGroupWizard(driver=self.driver) wizard.open() LOG.info('Wizard open.') LOG.step('Setting initiator group name') wizard.activePage.setName(name=initiatorGroupName) name = wizard.activePage.txtName.getText() self.assertTrue(name == initiatorGroupName) LOG.info('Initiator group name set:', name) LOG.step('Setting OS type: %s' % osType) wizard.activePage.setOSType(osType=osType) setOSType = wizard.activePage.dLstOSType.getText() self.assertTrue(setOSType == osType) LOG.info('OS type set:', setOSType) fictiveWWPN = ':'.join( re.findall( '..', format(random.randrange(sys.maxint), 'x').rjust(16, 'f'))) LOG.step('Adding new initiator: %s' % fictiveWWPN) wizard.activePage.addWWPNs(wwpns=fictiveWWPN) wwpns = wizard.activePage.getWWPNs() foundWWPN = [ wwpn for wwpn in wwpns if wwpn['initiator_group'] == fictiveWWPN ] self.assertTrue(foundWWPN) LOG.info('Initiator added:', foundWWPN[0]['initiator_group']) LOG.step('Setting single initiator: %s' % fictiveWWPN) wizard.activePage.setWWPNs(wwpns=fictiveWWPN) setWWPNs = wizard.activePage.gridInitiatorWWPNs.find(selected=True) self.assertTrue(len(setWWPNs) == 1) self.assertTrue(setWWPNs[0]['initiator_group'] == fictiveWWPN) LOG.info('Initiator WWPN set:', setWWPNs[0]['initiator_group']) LOG.step('Submitting dialog') wizard.activePage.submit() LOG.info('Dialog submitted.') LOG.step('Verifying initiator group has been created') initiatorGroups = self.marscluster.igroup.show(json=True) self.assertTrue(len(initiatorGroups) == 1) self.assertTrue(initiatorGroups[0]['name'] == initiatorGroupName) LOG.info("Initiator group's name:", initiatorGroups[0]['name']) self.assertTrue(initiatorGroups[0]['ostype'] == osType.lower()) LOG.info("Initiator group's OS type:", initiatorGroups[0]['ostype']) self.assertTrue(initiatorGroups[0]['initiators'][0] == fictiveWWPN) LOG.info("Initiator group's WWPN:", wwpns[0]['initiator_group']) def test_create_multiple_initiators(self): """ Verify initiator group creation when name and OS type specified explicitly, and multiple initiators (either existing or fictive). """ initiatorGroupName = 'IG-1' osType = 'Xen' initiatorsNumber = 10 LOG.step('Opening wizard') wizard = CreateInitiatorGroupWizard(driver=self.driver) wizard.open() LOG.info('Wizard open.') LOG.step('Setting initiator group name') wizard.activePage.setName(name=initiatorGroupName) name = wizard.activePage.txtName.getText() self.assertTrue(name == initiatorGroupName) LOG.info('Initiator group name set:', name) LOG.step('Setting OS type: %s' % osType) wizard.activePage.setOSType(osType=osType) setOSType = wizard.activePage.dLstOSType.getText() self.assertTrue(setOSType == osType) LOG.info('OS type set:', setOSType) wwpns = wizard.activePage.getWWPNs() if len(wwpns) < initiatorsNumber: LOG.step('Adding fictive initiators') fictiveWWPNs = [] for wwpnNumber in range(len(wwpns), initiatorsNumber): wizard.activePage.addWWPNs(wwpns=fictiveWWPNs) fictiveWWPNs.append(':'.join( re.findall( '..', format(random.randrange(sys.maxint), 'x').rjust(16, 'f')))) wizard.activePage.addWWPNs(wwpns=fictiveWWPNs) wwpns = [ wwpn['initiator_group'] for wwpn in wizard.activePage.getWWPNs() ] for wwpn in fictiveWWPNs: self.assertTrue(wwpn in wwpns) else: wwpns = [ wwpn['initiator_group'] for wwpn in wizard.activePage.getWWPNs() ] LOG.info('Initiators available:', wwpns) LOG.step('Setting all initiators') wizard.activePage.setWWPNs(wwpns=wwpns) setWWPNs = wizard.activePage.gridInitiatorWWPNs.find(selected=True) self.assertTrue(len(setWWPNs) == initiatorsNumber) LOG.info('Initiator WWPNs set:\n', setWWPNs) LOG.step('Submitting dialog') wizard.activePage.submit() LOG.info('Dialog submitted.') LOG.step('Verifying initiator group has been created') initiatorGroups = self.marscluster.igroup.show(json=True) self.assertTrue(len(initiatorGroups) == 1) self.assertTrue(initiatorGroups[0]['name'] == initiatorGroupName) LOG.info("Initiator group's name:", initiatorGroups[0]['name']) self.assertTrue(initiatorGroups[0]['ostype'] == osType.lower()) LOG.info("Initiator group's OS type:", initiatorGroups[0]['ostype']) self.assertTrue( len(initiatorGroups[0]['initiators']) == initiatorsNumber) for initiator in initiatorGroups[0]['initiators']: self.assertTrue(initiator in wwpns) LOG.info("Initiator group's WWPN:", initiator) def test_dialog_cancel(self): """ Verify closing dialog without submission has no effect. """ LOG.step('Opening wizard') wizard = CreateInitiatorGroupWizard(driver=self.driver) wizard.open() LOG.info('Wizard open.') LOG.step('Closing dialog without submission') wizard.cancel() LOG.info('Dialog closed.') LOG.step('Verifying no initiator groups were created') initiatorGroups = self.marscluster.igroup.show(json=True) self.assertFalse(initiatorGroups) LOG.info('Initiator groups:', initiatorGroups) def testTeardown(self): self.driver.close() def suiteTeardown(self): LOG.step('Closing browser') self.driver.quit() luns = express.Luns(node=self.marscluster, cleanup=True) del luns self.marscluster.igroup.destroyAll() LOG.info('LUNs & initiator groups destroyed.')
class TestEditLUNIDsWizard(FRTestCase): def suiteSetup(self): self.username = ARGS.values.username self.password = ARGS.values.password self.locale = ARGS.values.locale self.webUIHostName = getFQDN(self.marscluster.getMasterNode().hostname) def testSetup(self): self.driver = self.getDriver() self.loginPage = LoginPage(driver=self.driver, url=self.webUIHostName) self.headerPage = HeaderPage(driver=self.driver) self.allStoragePage = AllStoragePage(driver=self.driver) self.lunsPage = LUNsPage(driver=self.driver) luns = express.Luns(node=self.marscluster, cleanup=True) del luns self.luns = express.Luns(node=self.marscluster) self.marscluster.igroup.destroyAll() LOG.step('Signing in') self.loginPage.open() self.loginPage.waitUntilOpen() if self.locale is None: self.locale = self.loginPage.getRandomLocale() self.loginPage.signIn(username=self.username, password=self.password, locale=self.locale) LOG.info('Signed in with username: %s, password: %s, locale: %s.' % (self.username, self.password, self.locale)) LOG.info('Browser landed on header page.') LOG.step('Navigating to LUNs page') self.headerPage.btnManager.click() self.allStoragePage.tabLUNs.click() self.lunsPage.waitUntilOpen() LOG.info('Browser landed on LUNs page.') def test_single_mapping(self): """ Verify setting ID for LUN with single initiator group mapping. """ newID = 173 LOG.step('Creating LUN') self.luns.create(count=1, size='1g', prefix='LuN') LOG.info('LUN created:\n', self.marscluster.lun.show(json=True)) groupNames = self.createInitiatorGroups(prefix='IG', number=1) LOG.step('Mapping LUN to initiator group') self.marscluster.lun.map({'name': 'LuN_1', 'igroup': groupNames[0]}) LOG.info('LUN mapped:\n', self.marscluster.lun.mapping_show(json=True)) # Refresh LUN grid self.lunsPage.btnRefresh.click() self.lunsPage.btnRefresh.waitUntilEnabled() LOG.step('Opening wizard') wizard = EditLUNIDsWizard(driver=self.driver) wizard.open(name='LuN_1') LOG.info('Wizard open.') LOG.step('Verifying default ID') ids = wizard.activePage.getIDs() self.assertTrue(len(ids) == 1) self.assertTrue(ids['IG-0'] == '0') LOG.info('Default ID set:', ids['IG-0']) LOG.step('Setting new ID: %s' % newID) wizard.activePage.setIDs(ids={'IG-0': newID}) wizard.activePage.submit() LOG.info('Dialog submitted.') LOG.step('Verifying new ID') lun = self.marscluster.lun.show(json=True)[0] self.assertTrue(lun['maps'][0]['lun-id'] == newID) LOG.info('LUN mapping ID set to:', lun['maps'][0]['lun-id']) def test_multiple_mappings(self): """ Verify setting IDs for LUN with multiple initiator group mappings. """ initiatorGroupsNumber = 5 maxID = 4095 LOG.step('Creating LUN') self.luns.create(count=1, size='1g', prefix='LuN') LOG.info('LUN created:\n', self.marscluster.lun.show(json=True)) # List of initiator group names with default IDs ids = { groupName: 0 for groupName in self.createInitiatorGroups( prefix='IG', number=initiatorGroupsNumber) } LOG.step('Mapping LUN to initiator groups') for groupName in ids: self.marscluster.lun.map({'name': 'LuN_1', 'igroup': groupName}) LOG.info('LUN mapped:\n', self.marscluster.lun.mapping_show(json=True)) # Refresh LUN grid self.lunsPage.btnRefresh.click() self.lunsPage.btnRefresh.waitUntilEnabled() LOG.step('Opening wizard') wizard = EditLUNIDsWizard(driver=self.driver) wizard.open(name='LuN_1') LOG.info('Wizard open.') LOG.step('Setting random IDs') uniqueIDs = [] for groupName in ids: # To avoid duplicated IDs. while True: id = random.randint(0, maxID) if id not in uniqueIDs: uniqueIDs.append(id) ids[groupName] = id LOG.info("Initiator group '%s': ID set to %s" % (groupName, id)) break wizard.activePage.setIDs(ids=ids) wizard.activePage.submit() LOG.info('Dialog submitted.') LOG.step('Verifying LUN mapping IDs') mappings = self.marscluster.lun.show(json=True)[0]['maps'] self.assertTrue(len(mappings) == len(ids)) for mapping in mappings: self.assertTrue(mapping['lun-name'] == 'LuN_1') self.assertTrue(mapping['lun-id'] == ids[mapping['igroup-name']]) LOG.info("Initiator group '%s': ID=%s" % (mapping['igroup-name'], ids[mapping['igroup-name']])) def test_fail_original_id(self): """ Verify button 'OK' is disabled when original ID was typed in. """ LOG.step('Creating LUN') self.luns.create(count=1, size='1g', prefix='LuN') LOG.info('LUN created:\n', self.marscluster.lun.show(json=True)) self.createInitiatorGroups(prefix='IG', number=1) LOG.step('Mapping LUN to initiator group') self.marscluster.lun.map({'name': 'LuN_1', 'igroup': 'IG-0'}) LOG.info('LUN mapped:\n', self.marscluster.lun.mapping_show(json=True)) # Refresh LUN grid self.lunsPage.btnRefresh.click() self.lunsPage.btnRefresh.waitUntilEnabled() LOG.step('Opening wizard') wizard = EditLUNIDsWizard(driver=self.driver) wizard.open(name='LuN_1') LOG.info('Wizard open.') LOG.step('Typing in original ID') ids = wizard.activePage.getIDs() self.assertTrue(len(ids) == 1) id = ids['IG-0'] LOG.info('Original ID:', id) wizard.activePage.setIDs(ids={'IG-0': id}) newID = wizard.activePage.getIDs()['IG-0'] LOG.info('Typed ID:', newID) self.assertFalse(wizard.activePage.btnOK.isEnabled()) LOG.info("Button 'OK' is enabled:", wizard.activePage.btnOK.isEnabled()) def test_fail_invalid_id(self): """ Verify typing invalid ID filters out non-numeric characters. """ validIDPart = '700' invalidIDPart = 'W-' LOG.step('Creating LUN') self.luns.create(count=1, size='1g', prefix='LuN') LOG.info('LUN created:\n', self.marscluster.lun.show(json=True)) self.createInitiatorGroups(prefix='IG', number=1) LOG.step('Mapping LUN to initiator group') self.marscluster.lun.map({'name': 'LuN_1', 'igroup': 'IG-0'}) LOG.info('LUN mapped:\n', self.marscluster.lun.mapping_show(json=True)) # Refresh LUN grid self.lunsPage.btnRefresh.click() self.lunsPage.btnRefresh.waitUntilEnabled() LOG.step('Opening wizard') wizard = EditLUNIDsWizard(driver=self.driver) wizard.open(name='LuN_1') LOG.info('Wizard open.') LOG.step('Typing in invalid ID: %s' % validIDPart + invalidIDPart) wizard.activePage.setIDs(ids={'IG-0': validIDPart + invalidIDPart}) typedText = wizard.activePage.getIDs()['IG-0'] self.assertTrue(typedText == validIDPart) LOG.info('Typed value:', typedText) def test_max_id(self): """ Verify error message appears when ID exceeds upper limit (4095). """ maxID = 4095 LOG.step('Creating LUN') self.luns.create(count=1, size='1g', prefix='LuN') LOG.info('LUN created:\n', self.marscluster.lun.show(json=True)) self.createInitiatorGroups(prefix='IG', number=1) LOG.step('Mapping LUN to initiator group') self.marscluster.lun.map({'name': 'LuN_1', 'igroup': 'IG-0'}) LOG.info('LUN mapped:\n', self.marscluster.lun.mapping_show(json=True)) # Refresh LUN grid self.lunsPage.btnRefresh.click() self.lunsPage.btnRefresh.waitUntilEnabled() LOG.step('Opening wizard') wizard = EditLUNIDsWizard(driver=self.driver) wizard.open(name='LuN_1') LOG.info('Wizard open.') LOG.step('Typing in maximal acceptable ID: %s' % maxID) wizard.activePage.setIDs(ids={'IG-0': maxID}) self.assertTrue(wizard.activePage.btnOK.isEnabled()) LOG.info("Button 'OK' is enabled:", wizard.activePage.btnOK.isEnabled()) LOG.step('Typing in ID exceeding maximal: %s' % (maxID + 1)) wizard.activePage.setIDs(ids={'IG-0': maxID + 1}) self.assertFalse(wizard.activePage.btnOK.isEnabled()) LOG.info("Button 'OK' is enabled:", wizard.activePage.btnOK.isEnabled()) def test_fail_nonunique_id(self): """ Verify error message when typed ID is used by another LUN mapped to the same initiator group. """ LOG.step('Creating 2 LUNs') self.luns.create(count=2, size='1g', prefix='LuN') LOG.info('LUNs created:\n', self.marscluster.lun.show(json=True)) self.createInitiatorGroups(prefix='IG', number=1) LOG.step('Mapping LUNs to the same initiator group') self.marscluster.lun.map({'name': 'LuN_1', 'igroup': 'IG-0'}) self.marscluster.lun.map({'name': 'LuN_2', 'igroup': 'IG-0'}) mappings = self.marscluster.lun.mapping_show(json=True) LOG.info('LUN mapped:\n', mappings) # Refresh LUN grid self.lunsPage.btnRefresh.click() self.lunsPage.btnRefresh.waitUntilEnabled() LOG.step('Opening wizard') wizard = EditLUNIDsWizard(driver=self.driver) wizard.open(name=mappings[0]['lun-name'].encode('utf-8')) LOG.info('Wizard open for LUN:', mappings[0]['lun-name']) LOG.step('Setting ID same as another LUN') wizard.activePage.setIDs(ids={mappings[1]['lun-id']}) self.assertFalse(wizard.activePage.btnOK.isEnabled()) LOG.info("Button 'OK' is enabled:", wizard.activePage.btnOK.isEnabled()) def test_dialog_cancel(self): """ Verify ID remains unchanged on canceling dialog without submission. """ LOG.step('Creating LUN') self.luns.create(count=1, size='1g', prefix='LuN') LOG.info('LUN created:\n', self.marscluster.lun.show(json=True)) self.createInitiatorGroups(prefix='IG', number=1) LOG.step('Mapping LUN to initiator group') self.marscluster.lun.map({'name': 'LuN_1', 'igroup': 'IG-0'}) originalMappings = self.marscluster.lun.mapping_show(json=True) LOG.info('LUN mapped:\n', originalMappings) # Refresh LUN grid self.lunsPage.btnRefresh.click() self.lunsPage.btnRefresh.waitUntilEnabled() LOG.step('Opening wizard') wizard = EditLUNIDsWizard(driver=self.driver) wizard.open(name='LuN_1') LOG.info('Wizard open.') newID = '305' LOG.step('Setting new ID: %s' % newID) wizard.activePage.setIDs(ids={'IG-0': newID}) ids = wizard.activePage.getIDs() self.assertTrue(ids['IG-0'] == newID) LOG.info('Typed ID:', ids['IG-0']) LOG.step('Canceling dialog without submission') wizard.cancel() LOG.info('Dialog closed.') LOG.step('Verifying mappings have not been changed') mappings = self.marscluster.lun.mapping_show(json=True) self.assertTrue(len(mappings) == len(originalMappings)) self.assertTrue( mappings[0]['igroup-name'] == originalMappings[0]['igroup-name']) LOG.info('Initiator group:', originalMappings[0]['igroup-name']) self.assertTrue( mappings[0]['lun-name'] == originalMappings[0]['lun-name']) LOG.info('LUN:', originalMappings[0]['lun-name']) self.assertTrue(mappings[0]['lun-id'] == originalMappings[0]['lun-id']) LOG.info('LUN ID:', originalMappings[0]['lun-id']) def createInitiatorGroups(self, prefix, number): LOG.step('Creating initiator group(s)') for groupNumber in range(number): fictiveWWPN = format(random.randrange(sys.maxint), 'x').rjust(16, 'f') self.marscluster.igroup.create(name=prefix + '-' + str(groupNumber), ostype='vmware', initiators=fictiveWWPN) groupNames = [ group['name'] for group in self.marscluster.igroup.show(json=True) ] LOG.info('Initiator group(s) created:', groupNames) return groupNames def testTeardown(self): self.driver.close() def suiteTeardown(self): LOG.step('Closing browser') self.driver.quit() LOG.info('Browser closed.') luns = express.Luns(node=self.marscluster, cleanup=True) del luns self.marscluster.igroup.destroyAll()
class TestRenameInitiatorWizard(FRTestCase): def suiteSetup(self): self.username = ARGS.values.username self.password = ARGS.values.password self.locale = ARGS.values.locale self.webUIHostName = getFQDN(self.marscluster.getMasterNode().hostname) def testSetup(self): self.driver = self.getDriver() self.loginPage = LoginPage(driver=self.driver, url=self.webUIHostName) self.headerPage = HeaderPage(driver=self.driver) self.allStoragePage = AllStoragePage(driver=self.driver) self.initiatorGroupsPage = InitiatorGroupsPage(driver=self.driver) LOG.info('Destroying existing LUNs...') self.marscluster.lun.unmapAll() self.marscluster.lun.destroyAll() self.assertFalse(self.marscluster.lun.show(json=True)) LOG.info('Done.') LOG.info('Destroying existing initiator groups...') self.marscluster.igroup.destroyAll() LOG.info('Done.') self.luns = express.Luns(node=self.marscluster) LOG.step('Signing in') self.loginPage.open() self.loginPage.waitUntilOpen() if self.locale is None: self.locale = self.loginPage.getRandomLocale() self.loginPage.signIn(username=self.username, password=self.password, locale=self.locale) LOG.info('Signed in with username: %s, password: %s, locale: %s.' % (self.username, self.password, self.locale)) LOG.info('Browser landed on header page.') LOG.info('Navigating to Initiator Groups page...') self.headerPage.btnManager.click() self.allStoragePage.tabInitiatorGroups.click() self.initiatorGroupsPage.waitUntilOpen() LOG.info('Browser landed on Initiator Groups page.') def test_valid_name(self): """ Verify initiator group renaming with new valid name. """ initiatorGroupCount = 3 initiatorGroupPrefix = 'IG' newName = 'IG-New' initiatorGroups = self.createInitiatorGroups( prefix=initiatorGroupPrefix, number=initiatorGroupCount) self.initiatorGroupsPage.btnRefresh.click() self.initiatorGroupsPage.btnRefresh.waitUntilEnabled() LOG.step('Renaming initiator group in dialog') wizard = RenameInitiatorGroupWizard(driver=self.driver) wizard.open(initiator_group=initiatorGroups[0]) LOG.info('Old name:', wizard.activePage.txtName.getText()) wizard.renameInitiatorGroupPage.renameInitiatorGroup(name=newName) LOG.info('New name:', wizard.activePage.txtName.getText()) wizard.renameInitiatorGroupPage.submit() LOG.info('Rename submitted.') LOG.step('Verifying initiator group name has been changed') initiatorGroups = [ group['name'] for group in self.marscluster.igroup.show(json=True) ] self.assertTrue(newName in initiatorGroups) LOG.info("Name '%s' found in initiator groups list:\n%s" % (newName, initiatorGroups)) def test_invalid_name(self): """ Verify error message when invalid name typed in. """ initiatorGroupCount = 3 initiatorGroupPrefix = 'IG' newName = 'IG*&#@1A_^?,' initiatorGroups = self.createInitiatorGroups( prefix=initiatorGroupPrefix, number=initiatorGroupCount) self.initiatorGroupsPage.btnRefresh.click() self.initiatorGroupsPage.btnRefresh.waitUntilEnabled() LOG.step("Changing initiator group name with: %s" % newName) wizard = RenameInitiatorGroupWizard(driver=self.driver) wizard.open(initiator_group=initiatorGroups[0]) LOG.info('Old name:', wizard.activePage.txtName.getText()) wizard.renameInitiatorGroupPage.renameInitiatorGroup(name=newName) LOG.info('New name:', wizard.activePage.txtName.getText()) LOG.step('Verifying name error message') wizard.activePage.lblNameError.waitUntilPresent() LOG.info('Name error message:', wizard.activePage.lblNameError.getText()) self.assertFalse(wizard.activePage.btnOK.isEnabled()) LOG.info("Button 'OK' is enabled:", wizard.activePage.btnOK.isEnabled()) def test_max_length_name(self): """ Verify error message when name length exceeds limit (96). """ initiatorGroupCount = 3 initiatorGroupPrefix = 'IG' newName = 'IGx' * 32 initiatorGroups = self.createInitiatorGroups( prefix=initiatorGroupPrefix, number=initiatorGroupCount) self.initiatorGroupsPage.btnRefresh.click() self.initiatorGroupsPage.btnRefresh.waitUntilEnabled() LOG.step("Setting initiator group name to maximal length: %s" % newName) wizard = RenameInitiatorGroupWizard(driver=self.driver) wizard.open(initiator_group=initiatorGroups[0]) LOG.info('Old name:', wizard.activePage.txtName.getText()) wizard.renameInitiatorGroupPage.renameInitiatorGroup(name=newName) LOG.info('New name:', wizard.activePage.txtName.getText()) LOG.step('Verifying no error messaging') wizard.activePage.lblNameError.waitUntilHidden() LOG.info('Error message is present:', wizard.activePage.lblNameError.isVisible()) self.assertTrue(wizard.activePage.btnOK.isEnabled()) LOG.info("Button 'OK' is enabled:", wizard.activePage.btnOK.isEnabled()) LOG.step('Setting initiator group name to maximal + 1 length: %s' % (newName + 'Y')) wizard.renameInitiatorGroupPage.renameInitiatorGroup(name=newName + 'Y') LOG.info('New name:', wizard.activePage.txtName.getText()) LOG.step('Verifying name error message') wizard.activePage.lblNameError.waitUntilVisible() LOG.info('Name error message:', wizard.activePage.lblNameError.getText()) self.assertFalse(wizard.activePage.btnOK.isEnabled()) LOG.info("Button 'OK' is enabled:", wizard.activePage.btnOK.isEnabled()) def test_unicode_name(self): """ Verify error message on setting initiator group name to contain Unicode characters. """ initiatorGroupCount = 3 initiatorGroupPrefix = 'IG' newName = u'Fran\u00e7ais' initiatorGroups = self.createInitiatorGroups( prefix=initiatorGroupPrefix, number=initiatorGroupCount) self.initiatorGroupsPage.btnRefresh.click() self.initiatorGroupsPage.btnRefresh.waitUntilEnabled() LOG.step("Changing initiator group name with: %s" % newName) wizard = RenameInitiatorGroupWizard(driver=self.driver) wizard.open(initiator_group=initiatorGroups[0]) LOG.info('Old name:', wizard.activePage.txtName.getText()) wizard.renameInitiatorGroupPage.renameInitiatorGroup(name=newName) LOG.info('New name:', wizard.activePage.txtName.getText()) LOG.step('Verifying name error message') wizard.activePage.lblNameError.waitUntilPresent() LOG.info('Name error message:', wizard.activePage.lblNameError.getText()) self.assertFalse(wizard.activePage.btnOK.isEnabled()) LOG.info("Button 'OK' is enabled:", wizard.activePage.btnOK.isEnabled()) def test_rename_mapped(self): """ Verify rename of initiator group which is mapped to LUN. """ lunName = 'LuN' lunSize = '1g' initiatorGroupCount = 3 initiatorGroupPrefix = 'IG' newName = 'IG-New' LOG.step('Creating and mapping LUN') self.luns.create(count=1, size=lunSize, prefix=lunName) initiatorGroup = self.createInitiatorGroups( prefix=initiatorGroupPrefix, number=initiatorGroupCount)[0] self.marscluster.lun.map({ 'name': lunName + '_1', 'igroup': initiatorGroup }) luns = self.marscluster.lun.show(json=True) self.assertTrue(len(luns) == 1) self.assertTrue(len(luns[0]['maps']) == 1) self.assertTrue(luns[0]['maps'][0]['igroup-name'] == initiatorGroup) LOG.info("LUN '%s' mapped: %s" % (luns[0]['name'], luns[0]['maps'])) self.initiatorGroupsPage.btnRefresh.click() self.initiatorGroupsPage.btnRefresh.waitUntilEnabled() LOG.step('Renaming initiator group in dialog') wizard = RenameInitiatorGroupWizard(driver=self.driver) wizard.open(initiator_group=initiatorGroup) LOG.info('Old name:', wizard.activePage.txtName.getText()) wizard.renameInitiatorGroupPage.renameInitiatorGroup(name=newName) LOG.info('New name:', wizard.activePage.txtName.getText()) wizard.renameInitiatorGroupPage.submit() LOG.info('Rename submitted.') LOG.step('Verifying initiator group name has been changed') initiatorGroups = [ group['name'] for group in self.marscluster.igroup.show(json=True) ] self.assertTrue(newName in initiatorGroups) LOG.info("Name '%s' found in initiator groups list:\n%s" % (newName, initiatorGroups)) def test_dialog_cancel(self): """ Verify initiator group name remains intact on dialog cancel. """ initiatorGroupCount = 3 initiatorGroupPrefix = 'IG' newName = 'IG-New' initiatorGroups = self.createInitiatorGroups( prefix=initiatorGroupPrefix, number=initiatorGroupCount) self.initiatorGroupsPage.btnRefresh.click() self.initiatorGroupsPage.btnRefresh.waitUntilEnabled() LOG.step('Renaming initiator group in dialog') wizard = RenameInitiatorGroupWizard(driver=self.driver) wizard.open(initiator_group=initiatorGroups[0]) LOG.info('Old name:', wizard.activePage.txtName.getText()) wizard.renameInitiatorGroupPage.renameInitiatorGroup(name=newName) LOG.info('New name:', wizard.activePage.txtName.getText()) LOG.step('Canceling dialog without submission') wizard.cancel() LOG.step('Verifying initiator group name has not been changed') initiatorGroups = [ group['name'] for group in self.marscluster.igroup.show(json=True) ] self.assertTrue(newName not in initiatorGroups) LOG.info("Name '%s' is not found in initiator groups list:\n%s" % (newName, initiatorGroups)) def createInitiatorGroups(self, prefix, number): LOG.step('Creating initiator group(s)') for groupNumber in range(number): fictiveWWPN = format(random.randrange(sys.maxint), 'x').rjust(16, 'f') self.marscluster.igroup.create(name=prefix + '-' + str(groupNumber), ostype='vmware', initiators=fictiveWWPN) groupNames = [ group['name'] for group in self.marscluster.igroup.show(json=True) ] LOG.info('Initiator group(s) created:', groupNames) return groupNames def testTeardown(self): self.driver.close() LOG.info('Driver closed.') def suiteTeardown(self): LOG.step('Quitting browser') self.driver.quit() luns = express.Luns(node=self.marscluster, cleanup=True) del luns self.marscluster.igroup.destroyAll() LOG.info('LUNs & initiator groups destroyed.')
class TestCreateConsistencyGroupWizard(FRTestCase): def suiteSetup(self): self.username = ARGS.values.username self.password = ARGS.values.password self.locale = ARGS.values.locale self.webUIHostName = getFQDN(self.marscluster.getMasterNode().hostname) def testSetup(self): self.driver = self.getDriver() self.loginPage = LoginPage(driver=self.driver, url=self.webUIHostName) self.headerPage = HeaderPage(driver=self.driver) self.allStoragePage = AllStoragePage(driver=self.driver) self.consistencyGroupsPage = ConsistencyGroupsPage(driver=self.driver) LOG.step('Cleaning out cluster content') LOG.info('Destroying LUNs...') luns = express.Luns(node=self.marscluster, cleanup=True) del luns self.assertFalse(self.marscluster.lun.show(json=True)) LOG.info('Done.') LOG.info('Deleting consistency groups...') while True: consistencyGroups = self.marscluster.cg.show(json=True) if consistencyGroups: self.marscluster.cg.delete(name=consistencyGroups[0]['name']) else: break self.assertFalse(self.marscluster.cg.show(json=True)) LOG.info('Done.') self.luns = express.Luns(node=self.marscluster) LOG.step('Signing in') self.loginPage.open() self.loginPage.waitUntilOpen() if self.locale is None: self.locale = self.loginPage.getRandomLocale() self.loginPage.signIn(username=self.username, password=self.password, locale=self.locale) LOG.info('Signed in with username: %s, password: %s, locale: %s.' % (self.username, self.password, self.locale)) LOG.info('Browser landed on header page.') LOG.info('Navigating to Consistency Groups page...') self.headerPage.btnManager.click() self.allStoragePage.tabConsistencyGroups.click() self.consistencyGroupsPage.waitUntilOpen() LOG.info('Browser landed on Consistency Groups page.') def test_create_minimal(self): """ Verify new consistency group creation when only name specified. """ consistencyGroupName = 'cg1' LOG.step('Opening wizard') wizard = CreateConsistencyGroupWizard(driver=self.driver) wizard.open() LOG.info('Wizard open.') LOG.step('Verifying default parameters') self.assertFalse(wizard.activePage.txtName.getText()) LOG.info("Default name: %s" % wizard.activePage.txtName.getText()) candidates = wizard.activePage.gridCandidates.find() self.assertFalse(candidates) LOG.info('Candidates:', candidates) LOG.step('Setting consistency group name') wizard.activePage.setName(name=consistencyGroupName) name = wizard.activePage.txtName.getText() self.assertTrue(name == consistencyGroupName) LOG.info('Consistency group name set:', name) LOG.step('Submitting dialog') wizard.submit() LOG.info('Dialog submitted.') LOG.step('Verifying consistency group has been created') consistencyGroups = self.marscluster.cg.show(json=True) self.assertTrue(len(consistencyGroups) == 1) self.assertTrue(consistencyGroups[0]['name'] == consistencyGroupName) self.assertFalse(consistencyGroups[0]['members']) LOG.info('Consistency group created:', consistencyGroups[0]['name']) def test_create_mapped_lun(self): """ Verify new consistency group creation with mapped LUNs. """ lunNamePrefix = 'lun' lunCount = 5 consistencyGroupName = 'cg1' LOG.step('Creating LUNs') for count in range(lunCount): self.marscluster.lun.create(name=lunNamePrefix + str(count), size='1g') luns = self.marscluster.lun.show(json=True) self.assertTrue(len(luns) == lunCount) LOG.info('LUNs created:', [lun['name'] for lun in luns]) LOG.step('Opening wizard') wizard = CreateConsistencyGroupWizard(driver=self.driver) wizard.open() LOG.info('Wizard open.') LOG.step('Verifying LUNs are present as candidates') candidates = [ candidate['candidates'] for candidate in wizard.activePage.getCandidates() ] self.assertTrue(len(candidates) == lunCount) for lun in luns: self.assertTrue(lun['name'] in candidates) LOG.info('Candidates:', candidates) LOG.step('Setting consistency group name') wizard.activePage.setName(name=consistencyGroupName) name = wizard.activePage.txtName.getText() self.assertTrue(name == consistencyGroupName) LOG.info('Consistency group name set:', name) LOG.step('Setting LUN as candidate to map') wizard.activePage.setCandidates(candidates=lunNamePrefix + '0') setCandidates = wizard.activePage.gridCandidates.find(selected=True) self.assertTrue(len(setCandidates) == 1) self.assertTrue(setCandidates[0]['candidates'] == lunNamePrefix + '0') LOG.info('Candidate set:', setCandidates[0]['candidates']) LOG.step('Submitting dialog') wizard.submit() LOG.info('Dialog submitted.') LOG.step('Verifying consistency group has been created') consistencyGroups = self.marscluster.cg.show(json=True) self.assertTrue(len(consistencyGroups) == 1) self.assertTrue(consistencyGroups[0]['name'] == consistencyGroupName) self.assertTrue(len(consistencyGroups[0]['members']) == 1) self.assertTrue(consistencyGroups[0]['members'][0]['name'] == consistencyGroupName + '/' + lunNamePrefix + '0') LOG.info('Consistency group has been created and mapped:', consistencyGroups[0]) def test_create_nested_cg(self): """ Verify new consistency group creation with under another consistency group. """ parentName = 'cgPr' childName = 'cgCh' LOG.step('Creating child consistency group') self.marscluster.cg.create(name=childName) consistencyGroups = self.marscluster.cg.show(json=True) self.assertTrue(len(consistencyGroups) == 1) self.assertTrue(consistencyGroups[0]['name'] == childName) LOG.info('Child consistency group created:', consistencyGroups[0]) self.consistencyGroupsPage.btnRefresh.click() self.consistencyGroupsPage.btnRefresh.waitUntilEnabled() LOG.step('Opening dialog with no consistency groups selected') self.consistencyGroupsPage.gridConsistencyGroups.unselect() self.assertFalse( self.consistencyGroupsPage.gridConsistencyGroups.find( selected=True)) wizard = CreateConsistencyGroupWizard(driver=self.driver) wizard.open() self.assertFalse(wizard.activePage.lblSubtitle.isVisible()) LOG.info('Wizard open.') LOG.step('Creating parent consistency group: %s' % parentName) wizard.activePage.setName(name=parentName) wizard.activePage.setCandidates(candidates=childName + '/') wizard.submit() LOG.info('Dialog closed.') LOG.step( 'Verifying child consistency group has been added to parent one') consistencyGroups = self.marscluster.cg.show(json=True) parentConsistencyGroup = [ consistencyGroup for consistencyGroup in consistencyGroups if consistencyGroup['name'] == parentName ][0] self.assertTrue(len(parentConsistencyGroup['members']) == 1) self.assertTrue( parentConsistencyGroup['members'][0]['name'] == parentName + '/' + childName) LOG.info('Parent consistency group has been created:', parentConsistencyGroup) def test_create_nested_cg_selected(self): """ Verify new consistency group creation under another consistency group selected in grid. """ parentName = 'cgPr' childName = 'cgCh' LOG.step('Creating parent consistency group') self.marscluster.cg.create(name=parentName) consistencyGroups = self.marscluster.cg.show(json=True) self.assertTrue(len(consistencyGroups) == 1) self.assertTrue(consistencyGroups[0]['name'] == parentName) LOG.info('Parent consistency group created:', consistencyGroups[0]) self.consistencyGroupsPage.btnRefresh.click() self.consistencyGroupsPage.btnRefresh.waitUntilEnabled() LOG.step('Opening dialog with parent consistency groups selected') wizard = CreateConsistencyGroupWizard(driver=self.driver) wizard.open(parentConsistencyGroup=parentName) self.assertTrue(wizard.activePage.lblSubtitle.getText() == parentName) LOG.info('Wizard open.') LOG.step('Creating child consistency group: %s' % childName) wizard.activePage.setName(name=childName) wizard.submit() LOG.info('Dialog closed.') LOG.step( 'Verifying child consistency group has been added to parent one') consistencyGroups = self.marscluster.cg.show(json=True) parentConsistencyGroup = [ consistencyGroup for consistencyGroup in consistencyGroups if consistencyGroup['name'] == parentName ][0] self.assertTrue(len(parentConsistencyGroup['members']) == 1) self.assertTrue( parentConsistencyGroup['members'][0]['name'] == parentName + '/' + childName) LOG.info('Parent consistency group has been created:', parentConsistencyGroup) def test_dialog_cancel(self): """ Verify closing dialog without submission has no effect. """ consistencyGroupName = 'cg1' LOG.step('Opening dialog') wizard = CreateConsistencyGroupWizard(driver=self.driver) wizard.open() LOG.info('Wizard open.') LOG.step('Setting name for new consistency group') wizard.activePage.setName(name=consistencyGroupName) self.assertTrue( wizard.activePage.txtName.getText() == consistencyGroupName) LOG.info('Consistency group name set:', wizard.activePage.txtName.getText()) LOG.step('Canceling dialog without submission') wizard.cancel() LOG.info('Dialog cancelled.') LOG.step('Verifying no consistency group has been created') consistencyGroups = self.marscluster.cg.show(json=True) self.assertFalse(consistencyGroups) LOG.info('Consistency groups:', consistencyGroups) def test_dialog_not_available(self): """ Verify dialog is not available when 2 or more consistency groups selected in grid. """ namePrefix = 'cg' consistencyGroupsNumber = 5 LOG.step('Creating multiple consistency groups') for count in range(consistencyGroupsNumber): self.marscluster.cg.create(name=namePrefix + str(count)) consistencyGroups = self.marscluster.cg.show(json=True) self.assertTrue(len(consistencyGroups) == consistencyGroupsNumber) LOG.info('Consistency groups created:', [ consistencyGroup['name'] for consistencyGroup in consistencyGroups ]) self.consistencyGroupsPage.btnRefresh.click() self.consistencyGroupsPage.btnRefresh.waitUntilEnabled() LOG.step('Selecting multiple consistency groups in grid') self.consistencyGroupsPage.gridConsistencyGroups.select( name=[namePrefix + '0', namePrefix + '3']) selectedConsistencyGroups = \ self.consistencyGroupsPage.gridConsistencyGroups.find(selected=True) self.assertTrue(len(selectedConsistencyGroups) == 2) LOG.info('Consistency groups selected in grid:', [ consistencyGroup['name'] for consistencyGroup in selectedConsistencyGroups ]) LOG.step('Verifying dialog is not available for given selection') self.assertFalse( self.consistencyGroupsPage.menuCreate.isItemEnabled( item='Consistency group')) LOG.info( 'Dialog is available:', self.consistencyGroupsPage.menuCreate.isItemEnabled( item='Consistency group')) def testTeardown(self): self.driver.close() def suiteTeardown(self): LOG.step('Closing browser') self.driver.quit() luns = express.Luns(node=self.marscluster, cleanup=True) del luns consistencyGroups = self.marscluster.cg.show(json=True) for consistencyGroup in consistencyGroups: self.marscluster.cg.delete(name=consistencyGroup['name']) self.assertFalse(self.marscluster.cg.show(json=True))
class TestResizeLUNWizard(FRTestCase): def suiteSetup(self): self.username = ARGS.values.username self.password = ARGS.values.password self.locale = ARGS.values.locale self.webUIHostName = getFQDN(self.marscluster.getMasterNode().hostname) def testSetup(self): self.driver = self.getDriver() self.loginPage = LoginPage(driver=self.driver, url=self.webUIHostName) self.headerPage = HeaderPage(driver=self.driver) self.allStoragePage = AllStoragePage(driver=self.driver) self.lunsPage = LUNsPage(driver=self.driver) self.luns = express.Luns(node=self.marscluster) LOG.step('Signing in') self.loginPage.open() self.loginPage.waitUntilOpen() if self.locale is None: self.locale = self.loginPage.getRandomLocale() self.loginPage.signIn(username=self.username, password=self.password, locale=self.locale) LOG.info('Signed in with username: %s, password: %s, locale: %s.' % (self.username, self.password, self.locale)) LOG.info('Browser landed on header page.') LOG.info('Navigating to LUNs page...') self.headerPage.btnManager.click() self.allStoragePage.tabLUNs.click() self.lunsPage.waitUntilOpen() LOG.info('Browser landed on LUNs page.') def test_valid_size(self): """ Verify LUN resizing with valid size. """ LOG.step('Creating LUNs') lunCount = 3 lunOldSize = 2 lunNewSize = 10 lunSizeUnit = 'G' lunNamePrefix = 'LuN' self.luns.create(count=lunCount, size=str(lunOldSize) + lunSizeUnit, prefix=lunNamePrefix) LOG.info('LUNs created:\n', self.marscluster.lun.show(json=True)) # Refresh LUN grid self.lunsPage.btnRefresh.click() self.lunsPage.btnRefresh.waitUntilEnabled() LOG.step('Resizing LUN in dialog') wizard = ResizeLUNWizard(driver=self.driver, locale=self.locale) wizard.open(name=lunNamePrefix + '_1') LOG.info('Old LUN size:', str(lunOldSize) + lunSizeUnit) wizard.resizeLUNPage.resizeLUN(size=str(lunNewSize) + lunSizeUnit) LOG.info('New LUN size:', wizard.resizeLUNPage.txtSize.getText() + wizard.resizeLUNPage.dLstSizeUnit.getText()) wizard.resizeLUNPage.submit() LOG.info('Resize submitted.') LOG.step('Verifying LUN size has been changed as specified') luns = self.lunsPage.gridLUNs.find(name=lunNamePrefix + '_1') self.assertTrue(len(luns) == 1) resultSize = float(Utility.getSizeValue(size=luns[0]['size']).replace(',', '.')) resultSizeUnit = Utility.getSizeUnit(size=luns[0]['size']) self.assertTrue(resultSize == lunNewSize) self.assertTrue(resultSizeUnit == lunSizeUnit) LOG.info('LUN found: name=%s, size=%s.' % (luns[0]['name'], luns[0]['size'])) def test_invalid_size(self): """ Verify error message on LUN resizing with invalid size. Verify LUN size remains intact. """ LOG.step('Creating LUNs') lunCount = 3 lunOldSize = 104857600 lunNamePrefix = 'LuN' lunNewSize = '65t' self.luns.create(count=lunCount, size=lunOldSize, prefix=lunNamePrefix) LOG.info('LUNs created:\n', self.marscluster.lun.show(json=True)) # Refresh LUN grid self.lunsPage.btnRefresh.click() self.lunsPage.btnRefresh.waitUntilEnabled() LOG.step('Setting new LUN size in dialog') wizard = ResizeLUNWizard(driver=self.driver, locale=self.locale) wizard.open(name=lunNamePrefix + '_1') wizard.resizeLUNPage.resizeLUN(size=lunNewSize) LOG.info('New LUN size:', wizard.resizeLUNPage.txtSize.getText() + wizard.resizeLUNPage.dLstSizeUnit.getText()) self.assertTrue(wizard.activePage.lblSizeError.isVisible()) LOG.info('Error message displayed:', wizard.activePage.lblSizeError.getText()) self.assertFalse(wizard.activePage.btnOK.isEnabled()) LOG.info("Button 'OK' is enabled:", wizard.activePage.btnOK.isEnabled()) LOG.step('Canceling dialog') wizard.cancel() LOG.info('Dialog closed.') LOG.step('Verifying no changes have been made for LUNs sizes') self.lunsPage.btnRefresh.click() self.lunsPage.btnRefresh.waitUntilEnabled() for lun in self.marscluster.lun.show(json=True): self.assertTrue(lun['size'] == lunOldSize) LOG.info("LUN '%s': size %s is intact." % (lun['name'], lun['size'])) def test_terminal_size(self): """ Test verifies LUN resizing to minimum and maximum sizes respecting given size unit. """ sizes = { 'B': { 'low': 512, 'high': long(64) * pow(1024, 4), 'multiplier': 1 }, 'K': { 'low': 0.5, 'high': long(64) * pow(1024, 3), 'multiplier': 1024 }, 'M': { 'low': 0.001, 'high': long(64) * pow(1024, 2), 'multiplier': 1024 ** 2 }, 'G': { 'low': 0.001, 'high': long(64) * 1024, 'multiplier': 1024 ** 3 }, 'T': { 'low': 0.001, 'high': 64, 'multiplier': 1024 ** 4 } } lunsToCreate = {} for sizeUnit in sizes: nameLow = 'LuN_' + sizeUnit + '_low' sizeLow = str(sizes[sizeUnit]['low']) + sizeUnit nameHigh = 'LuN_' + sizeUnit + '_high' sizeHigh = str(sizes[sizeUnit]['high']) + sizeUnit LOG.step("Creating LUNs with size unit '%s'" % sizeUnit) if sizeUnit not in ['B', 'K']: self.marscluster.lun.create(name=nameLow, size='0.5k') self.marscluster.lun.create(name=nameHigh, size='0.5k') luns = self.marscluster.lun.show(json=True) LOG.info('LUNs created:\n', luns) # Refresh LUN grid self.lunsPage.btnRefresh.click() self.lunsPage.btnRefresh.waitUntilEnabled() # Skip assigning the same size with low size units. Reducing LUN size is not available. if sizeUnit not in ['B', 'K']: LOG.step("Opening wizard for LUN '%s'" % nameLow) wizard = ResizeLUNWizard(driver=self.driver, locale=self.locale) wizard.open(name=nameLow) LOG.info('Wizard opened.') LOG.step("Modifying LUN size to be minimal: size='%s'" % sizeLow) wizard.activePage.resizeLUN(size=sizeLow) wizard.activePage.submit() LOG.info('Resize submitted.') sizeToCreate = sizes[sizeUnit]['low'] * sizes[sizeUnit]['multiplier'] # Sizes of LUNs are rounded up to 512-byte bound if sizeToCreate % 512 > 0: sizeToCreate = int(sizeToCreate / 512) * 512 + 512 lunsToCreate[nameLow] = sizeToCreate LOG.step("Opening wizard for LUN '%s'" % nameHigh) wizard = ResizeLUNWizard(driver=self.driver, locale=self.locale) wizard.open(name=nameHigh) LOG.info('Wizard opened.') LOG.step("Modifying LUN size to be maximal: size='%s'" % sizeHigh) wizard.activePage.resizeLUN(size=sizeHigh) wizard.activePage.submit() LOG.info('Resize submitted.') lunsToCreate[nameHigh] = sizes[sizeUnit]['high'] * sizes[sizeUnit]['multiplier'] createdLUNs = self.marscluster.lun.show(json=True) LOG.step('Verifying modified LUN size is as specified') for lun in createdLUNs: self.assertTrue(lun['size'] == lunsToCreate[lun['name']]) LOG.info("Size of LUN '%s' (bytes): %s" % (lun['name'], lun['size'])) LOG.step('Cleaning up LUNs') luns = express.Luns(node=self.marscluster, cleanup=True) del luns LOG.info('LUNs destroyed.') def test_same_size(self): """ Verify error message on LUN resizing with the same (initial) size. Verify LUN size remain intact. """ LOG.step('Creating LUN') lunName = 'LuN' lunSize = 104857600 self.marscluster.lun.create(name=lunName, size=lunSize) LOG.info('LUNs created:\n', self.marscluster.lun.show(json=True)) # Refresh LUN grid self.lunsPage.btnRefresh.click() self.lunsPage.btnRefresh.waitUntilEnabled() LOG.step('Setting same LUN size in dialog') wizard = ResizeLUNWizard(driver=self.driver, locale=self.locale) wizard.open(name=lunName) wizard.resizeLUNPage.resizeLUN(size=str(lunSize) + 'B') LOG.info('New LUN size:', wizard.resizeLUNPage.txtSize.getText() + wizard.resizeLUNPage.dLstSizeUnit.getText()) wizard.activePage.btnOK.click() LOG.info('Dialog title notifies failure:', wizard.activePage.lblTitle.getText()) self.assertTrue(wizard.activePage.lblSameSizeError.isVisible()) LOG.info('Error message displayed:', wizard.activePage.lblSameSizeError.getText()) self.assertFalse(wizard.activePage.btnOK.isEnabled()) LOG.info("Button 'OK' is enabled:", wizard.activePage.btnOK.isEnabled()) LOG.step('Canceling dialog') wizard.cancel() LOG.info('Dialog closed.') LOG.step('Verifying no change have been made for LUN size') luns = self.marscluster.lun.show(json=True) self.assertTrue(len(luns) == 1) self.assertTrue(luns[0]['size'] == lunSize) LOG.info("LUN '%s': size %s is intact." % (luns[0]['name'], luns[0]['size'])) def test_dialog_cancel(self): """ Verify LUN size remains intact on dialog canceling. """ LOG.step('Creating LUNs') lunCount = 3 lunOldSize = 104857600 lunNamePrefix = 'LuN' lunNewSize = '1t' self.luns.create(count=lunCount, size=lunOldSize, prefix=lunNamePrefix) LOG.info('LUNs created:\n', self.marscluster.lun.show(json=True)) # Refresh LUN grid self.lunsPage.btnRefresh.click() self.lunsPage.btnRefresh.waitUntilEnabled() LOG.step('Setting new LUN size in dialog') wizard = ResizeLUNWizard(driver=self.driver, locale=self.locale) wizard.open(name=lunNamePrefix + '_1') wizard.resizeLUNPage.resizeLUN(size=lunNewSize) LOG.info('New LUN size:', wizard.resizeLUNPage.txtSize.getText() + wizard.resizeLUNPage.dLstSizeUnit.getText()) LOG.step('Canceling dialog') wizard.cancel() LOG.info('Dialog closed.') LOG.step('Verifying no changes have been made for LUNs sizes') self.lunsPage.btnRefresh.click() self.lunsPage.btnRefresh.waitUntilEnabled() for lun in self.marscluster.lun.show(json=True): self.assertTrue(lun['size'] == lunOldSize) LOG.info("LUN '%s': size %s is intact." % (lun['name'], lun['size'])) def testTeardown(self): self.driver.close() luns = express.Luns(node=self.marscluster, cleanup=True) del luns LOG.info('LUNs destroyed.') def suiteTeardown(self): LOG.step('Closing browser') self.driver.quit()
class TestDeleteInitiatorGroupWizard(FRTestCase): """ In fact, there is no such a wizard as 'Delete Initiator Group', this is just function on clicking button 'Delete'. """ def suiteSetup(self): self.username = ARGS.values.username self.password = ARGS.values.password self.locale = ARGS.values.locale self.webUIHostName = getFQDN(self.marscluster.getMasterNode().hostname) def testSetup(self): self.driver = self.getDriver() self.loginPage = LoginPage(driver=self.driver, url=self.webUIHostName) self.headerPage = HeaderPage(driver=self.driver) self.allStoragePage = AllStoragePage(driver=self.driver) self.initiatorGroupsPage = InitiatorGroupsPage(driver=self.driver) LOG.step('Cleaning out cluster content') LOG.info('Destroying LUNs...') luns = express.Luns(node=self.marscluster, cleanup=True) del luns self.assertFalse(self.marscluster.lun.show(json=True)) LOG.info('Done.') LOG.info('Destroying existing initiator groups...') self.marscluster.igroup.destroyAll() LOG.info('Done.') self.luns = express.Luns(node=self.marscluster) LOG.step('Signing in') self.loginPage.open() self.loginPage.waitUntilOpen() if self.locale is None: self.locale = self.loginPage.getRandomLocale() self.loginPage.signIn(username=self.username, password=self.password, locale=self.locale) LOG.info('Signed in with username: %s, password: %s, locale: %s.' % (self.username, self.password, self.locale)) LOG.info('Browser landed on header page.') LOG.info('Navigating to Initiator Groups page...') self.headerPage.btnManager.click() self.allStoragePage.tabInitiatorGroups.click() self.initiatorGroupsPage.waitUntilOpen() LOG.info('Browser landed on Initiator Groups page.') def test_delete_single(self): """ Verify deletion of single unmapped initiator group. """ initiatorGroupPrefix = 'IG' initiatorGroupNumber = 5 initiatorGroupNames = self._createInitiatorGroups( prefix=initiatorGroupPrefix, number=initiatorGroupNumber) self.initiatorGroupsPage.btnRefresh.click() self.initiatorGroupsPage.btnRefresh.waitUntilEnabled() LOG.step('Selecting initiator group in grid') self.initiatorGroupsPage.gridInitiatorGroups.select( initiator_group=initiatorGroupNames[0]) selectedGroups = self.initiatorGroupsPage.gridInitiatorGroups.find( selected=True) self.assertTrue(len(selectedGroups) == 1) self.assertTrue( selectedGroups[0]['initiator_group'] == initiatorGroupNames[0]) LOG.info('Initiator group selected:', initiatorGroupNames[0]) LOG.step('Deleting and verifying initiator group has been deleted') self.initiatorGroupsPage.btnDelete.click() initiatorGroups = self.marscluster.igroup.show(json=True) self.assertTrue(len(initiatorGroups) == initiatorGroupNumber - 1) self.assertFalse(initiatorGroupNames[0] in [group['name'] for group in initiatorGroups]) LOG.info( "Initiator group '%s' is not present:\n" % initiatorGroupNames[0].encode('utf-8'), initiatorGroups) def test_delete_multi(self): """ Verify deletion of multiple unmapped initiator groups. """ initiatorGroupPrefix = 'IG' initiatorGroupNumber = 9 initiatorGroupNames = self._createInitiatorGroups( prefix=initiatorGroupPrefix, number=initiatorGroupNumber) self.initiatorGroupsPage.btnRefresh.click() self.initiatorGroupsPage.btnRefresh.waitUntilEnabled() LOG.step('Selecting initiator groups in grid') self.initiatorGroupsPage.gridInitiatorGroups.select( initiator_group=initiatorGroupNames[:initiatorGroupNumber / 2]) selectedGroups = self.initiatorGroupsPage.gridInitiatorGroups.find( selected=True) self.assertTrue(len(selectedGroups) == initiatorGroupNumber / 2) LOG.info('Initiator group selected:', selectedGroups) LOG.step('Deleting and verifying initiator group has been deleted') self.initiatorGroupsPage.btnDelete.click() # Give some time to perform operation time.sleep(2) initiatorGroupNames = [ group['name'] for group in self.marscluster.igroup.show(json=True) ] self.assertTrue( len(initiatorGroupNames) == initiatorGroupNumber - (initiatorGroupNumber / 2)) for group in selectedGroups: self.assertFalse(group['initiator_group'] in initiatorGroupNames) LOG.info('Initiator group is not present:', group['initiator_group']) def test_delete_mapped(self): """ Verify warning when initiator group with mapped LUN is getting deleted. """ lunName = 'lun1' initiatorGroupName = 'ig1' LOG.step('Creating initiator group') fictiveWWPN = format(random.randrange(sys.maxint), 'x').rjust(16, 'f') self.marscluster.igroup.create(name=initiatorGroupName, ostype='windows', initiators=fictiveWWPN) initiatorGroups = self.marscluster.igroup.show(json=True) self.assertTrue(len(initiatorGroups) == 1) LOG.info('Initiator group created:\n', initiatorGroups[0]) LOG.step('Creating and mapping LUN') self.marscluster.lun.create(name=lunName, size='1g') self.marscluster.lun.map(name=lunName, igroup=initiatorGroups[0]['name']) luns = self.marscluster.lun.show(json=True) self.assertTrue(len(luns) == 1) self.assertTrue(len(luns[0]['maps']) == 1) self.assertTrue( luns[0]['maps'][0]['igroup-name'] == initiatorGroupName) LOG.info('LUN created:\n', luns[0]) self.initiatorGroupsPage.btnRefresh.click() self.initiatorGroupsPage.btnRefresh.waitUntilEnabled() LOG.step('Deleting initiator group: %s' % initiatorGroupName) self.initiatorGroupsPage.gridInitiatorGroups.select( initiator_group=initiatorGroupName) self.initiatorGroupsPage.btnDelete.click() deleteMappedInitiatorGroupPage = DeleteMappedInitiatorGroupPage( driver=self.driver) deleteMappedInitiatorGroupPage.waitUntilOpen() LOG.info('Warning message window open:', deleteMappedInitiatorGroupPage.lblTitle.getText()) deleteMappedInitiatorGroupPage.btnClose.click() LOG.step('Verifying initiator group has not been deleted') initiatorGroups = self.marscluster.igroup.show(json=True) self.assertTrue(len(initiatorGroups) == 1) self.assertTrue(initiatorGroups[0]['name'] == initiatorGroupName) LOG.info('Initiator group exists:', initiatorGroups[0]['name']) def test_delete_multi_mapped(self): """ Verify warning when multiple initiator groups with mapped LUNs are getting deleted. """ initiatorGroupPrefix = 'ig' initiatorGroupNumber = 3 lunsPrefix = 'lun' initiatorGroupNames = self._createInitiatorGroups( prefix=initiatorGroupPrefix, number=initiatorGroupNumber) LOG.step('Creating and mapping LUNs') self.luns.create(count=initiatorGroupNumber, size='1g', prefix=lunsPrefix) luns = self.marscluster.lun.show(json=True) self.assertTrue(len(luns) == initiatorGroupNumber) LOG.info('LUNs created:\n', luns) for count in range(len(luns)): self.marscluster.lun.map(name=luns[count]['name'], igroup=initiatorGroupNames[count]) luns = self.marscluster.lun.show(json=True) for count in range(len(luns)): self.assertTrue(len(luns[count]['maps']) == 1) self.assertTrue(luns[count]['maps'][0]['igroup-name'] == initiatorGroupNames[count]) LOG.info('LUNs mapped to initiator groups:\n', [(lun['name'], lun['maps']) for lun in luns]) self.initiatorGroupsPage.btnRefresh.click() self.initiatorGroupsPage.btnRefresh.waitUntilEnabled() LOG.step('Deleting all initiator groups at once: %s' % initiatorGroupNames) self.initiatorGroupsPage.gridInitiatorGroups.select( initiator_group=initiatorGroupNames) self.initiatorGroupsPage.btnDelete.click() deleteMappedInitiatorGroupPage = DeleteMappedInitiatorGroupPage( driver=self.driver) deleteMappedInitiatorGroupPage.waitUntilOpen() LOG.info('Warning message window open:', deleteMappedInitiatorGroupPage.lblTitle.getText()) deleteMappedInitiatorGroupPage.btnClose.click() LOG.step('Verifying initiator groups have not been deleted') initiatorGroups = self.marscluster.igroup.show(json=True) self.assertTrue(len(initiatorGroups) == initiatorGroupNumber) LOG.info('Initiator groups exist:', initiatorGroups) def test_delete_multi_mixed(self): """ Verify warning when at least one of multiple selected initiator groups has mapping with LUN. """ initiatorGroupPrefix = 'ig' initiatorGroupNumber = 3 lunName = 'lun1' initiatorGroupNames = self._createInitiatorGroups( prefix=initiatorGroupPrefix, number=initiatorGroupNumber) LOG.step('Creating LUN') self.marscluster.lun.create(name=lunName, size='1g') luns = self.marscluster.lun.show(json=True) self.assertTrue(len(luns) == 1) LOG.info('LUN created:\n', luns[0]) LOG.step('Mapping LUN to one of initiator groups') self.marscluster.lun.map(name=lunName, igroup=initiatorGroupNames[0]) lun = self.marscluster.lun.show(json=True)[0] self.assertTrue(len(lun['maps']) == 1) self.assertTrue( lun['maps'][0]['igroup-name'] == initiatorGroupNames[0]) LOG.info("LUN '%s' mapped to initiator group: %s" % (lun['name'], lun['maps'][0]['igroup-name'])) self.initiatorGroupsPage.btnRefresh.click() self.initiatorGroupsPage.btnRefresh.waitUntilEnabled() LOG.step('Deleting all initiator groups at once: %s' % initiatorGroupNames) self.initiatorGroupsPage.gridInitiatorGroups.select( initiator_group=initiatorGroupNames) self.initiatorGroupsPage.btnDelete.click() deleteMappedInitiatorGroupPage = DeleteMappedInitiatorGroupPage( driver=self.driver) deleteMappedInitiatorGroupPage.waitUntilOpen() LOG.info('Warning message window open:', deleteMappedInitiatorGroupPage.lblTitle.getText()) deleteMappedInitiatorGroupPage.btnClose.click() LOG.step('Verifying initiator groups have not been deleted') initiatorGroups = self.marscluster.igroup.show(json=True) self.assertTrue(len(initiatorGroups) == initiatorGroupNumber) LOG.info('Initiator groups exist:', initiatorGroups) def test_delete_not_available(self): """ Verify deletion is not available when no initiator groups selected in grid. """ initiatorGroupPrefix = 'ig' initiatorGroupNumber = 3 initiatorGroupNames = self._createInitiatorGroups( prefix=initiatorGroupPrefix, number=initiatorGroupNumber) self.initiatorGroupsPage.btnRefresh.click() self.initiatorGroupsPage.btnRefresh.waitUntilEnabled() LOG.step('Deselecting all initiator groups in grid') self.initiatorGroupsPage.gridInitiatorGroups.unselect( initiator_group=initiatorGroupNames) selectedGroups = self.initiatorGroupsPage.gridInitiatorGroups.find( selected=True) self.assertFalse(selectedGroups) LOG.info('Selected initiator groups:', selectedGroups) LOG.step("Verifying button 'Delete' is disabled in tool bar") self.assertFalse(self.initiatorGroupsPage.btnDelete.isEnabled()) LOG.info("Button 'Delete' is enabled:", self.initiatorGroupsPage.btnDelete.isEnabled()) def testTeardown(self): self.driver.close() def suiteTeardown(self): LOG.step('Closing browser') self.driver.quit() luns = express.Luns(node=self.marscluster, cleanup=True) del luns self.marscluster.igroup.destroyAll() LOG.info('LUNs & initiator groups destroyed.') def _createInitiatorGroups(self, prefix, number, osType='vmware'): LOG.step('Creating initiator group(s)') for groupNumber in range(number): fictiveWWPN = format(random.randrange(sys.maxint), 'x').rjust(16, 'f') self.marscluster.igroup.create(name=prefix + '-' + str(groupNumber), ostype=osType.lower(), initiators=fictiveWWPN) groupNames = [ group['name'] for group in self.marscluster.igroup.show(json=True) ] LOG.info('Initiator group(s) created:', groupNames) return groupNames