http://git-wip-us.apache.org/repos/asf/hbase-site/blob/323b17d9/testdevapidocs/src-html/org/apache/hadoop/hbase/master/assignment/TestSplitTableRegionProcedure.html ---------------------------------------------------------------------- diff --git a/testdevapidocs/src-html/org/apache/hadoop/hbase/master/assignment/TestSplitTableRegionProcedure.html b/testdevapidocs/src-html/org/apache/hadoop/hbase/master/assignment/TestSplitTableRegionProcedure.html index 34e3682..da13fee 100644 --- a/testdevapidocs/src-html/org/apache/hadoop/hbase/master/assignment/TestSplitTableRegionProcedure.html +++ b/testdevapidocs/src-html/org/apache/hadoop/hbase/master/assignment/TestSplitTableRegionProcedure.html @@ -356,7 +356,7 @@ <span class="sourceLineNo">348</span> final TableName tableName = TableName.valueOf(name.getMethodName());<a name="line.348"></a> <span class="sourceLineNo">349</span> final ProcedureExecutor<MasterProcedureEnv> procExec = getMasterProcedureExecutor();<a name="line.349"></a> <span class="sourceLineNo">350</span><a name="line.350"></a> -<span class="sourceLineNo">351</span> RegionInfo [] regions = MasterProcedureTestingUtility.createTable(<a name="line.351"></a> +<span class="sourceLineNo">351</span> RegionInfo[] regions = MasterProcedureTestingUtility.createTable(<a name="line.351"></a> <span class="sourceLineNo">352</span> procExec, tableName, null, ColumnFamilyName1, ColumnFamilyName2);<a name="line.352"></a> <span class="sourceLineNo">353</span> insertData(tableName);<a name="line.353"></a> <span class="sourceLineNo">354</span> int splitRowNum = startRowNum + rowCount / 2;<a name="line.354"></a> @@ -374,181 +374,182 @@ <span class="sourceLineNo">366</span> long procId = procExec.submitProcedure(<a name="line.366"></a> <span class="sourceLineNo">367</span> new SplitTableRegionProcedure(procExec.getEnvironment(), regions[0], splitKey));<a name="line.367"></a> <span class="sourceLineNo">368</span><a name="line.368"></a> -<span class="sourceLineNo">369</span> // Failing before SPLIT_TABLE_REGION_CREATE_DAUGHTER_REGIONS we should trigger the<a name="line.369"></a> +<span class="sourceLineNo">369</span> // Failing before SPLIT_TABLE_REGION_UPDATE_META we should trigger the<a name="line.369"></a> <span class="sourceLineNo">370</span> // rollback<a name="line.370"></a> -<span class="sourceLineNo">371</span> // NOTE: the 3 (number before SPLIT_TABLE_REGION_CREATE_DAUGHTER_REGIONS step) is<a name="line.371"></a> +<span class="sourceLineNo">371</span> // NOTE: the 7 (number of SPLIT_TABLE_REGION_UPDATE_META step) is<a name="line.371"></a> <span class="sourceLineNo">372</span> // hardcoded, so you have to look at this test at least once when you add a new step.<a name="line.372"></a> -<span class="sourceLineNo">373</span> int numberOfSteps = 3;<a name="line.373"></a> -<span class="sourceLineNo">374</span> MasterProcedureTestingUtility.testRollbackAndDoubleExecution(procExec, procId, numberOfSteps,<a name="line.374"></a> +<span class="sourceLineNo">373</span> int lastStep = 7;<a name="line.373"></a> +<span class="sourceLineNo">374</span> MasterProcedureTestingUtility.testRollbackAndDoubleExecution(procExec, procId, lastStep,<a name="line.374"></a> <span class="sourceLineNo">375</span> true);<a name="line.375"></a> <span class="sourceLineNo">376</span> // check that we have only 1 region<a name="line.376"></a> <span class="sourceLineNo">377</span> assertEquals(1, UTIL.getAdmin().getRegions(tableName).size());<a name="line.377"></a> -<span class="sourceLineNo">378</span> List<HRegion> daughters = UTIL.getMiniHBaseCluster().getRegions(tableName);<a name="line.378"></a> -<span class="sourceLineNo">379</span> assertEquals(1, daughters.size());<a name="line.379"></a> -<span class="sourceLineNo">380</span> verifyData(daughters.get(0), startRowNum, rowCount,<a name="line.380"></a> -<span class="sourceLineNo">381</span> Bytes.toBytes(ColumnFamilyName1), Bytes.toBytes(ColumnFamilyName2));<a name="line.381"></a> -<span class="sourceLineNo">382</span><a name="line.382"></a> -<span class="sourceLineNo">383</span> assertEquals(splitSubmittedCount + 1, splitProcMetrics.getSubmittedCounter().getCount());<a name="line.383"></a> -<span class="sourceLineNo">384</span> assertEquals(splitFailedCount + 1, splitProcMetrics.getFailedCounter().getCount());<a name="line.384"></a> -<span class="sourceLineNo">385</span> }<a name="line.385"></a> -<span class="sourceLineNo">386</span><a name="line.386"></a> -<span class="sourceLineNo">387</span> @Test<a name="line.387"></a> -<span class="sourceLineNo">388</span> public void testRecoveryAndDoubleExecution() throws Exception {<a name="line.388"></a> -<span class="sourceLineNo">389</span> final TableName tableName = TableName.valueOf(name.getMethodName());<a name="line.389"></a> -<span class="sourceLineNo">390</span> final ProcedureExecutor<MasterProcedureEnv> procExec = getMasterProcedureExecutor();<a name="line.390"></a> -<span class="sourceLineNo">391</span><a name="line.391"></a> -<span class="sourceLineNo">392</span> RegionInfo [] regions = MasterProcedureTestingUtility.createTable(<a name="line.392"></a> -<span class="sourceLineNo">393</span> procExec, tableName, null, ColumnFamilyName1, ColumnFamilyName2);<a name="line.393"></a> -<span class="sourceLineNo">394</span> insertData(tableName);<a name="line.394"></a> -<span class="sourceLineNo">395</span> int splitRowNum = startRowNum + rowCount / 2;<a name="line.395"></a> -<span class="sourceLineNo">396</span> byte[] splitKey = Bytes.toBytes("" + splitRowNum);<a name="line.396"></a> -<span class="sourceLineNo">397</span><a name="line.397"></a> -<span class="sourceLineNo">398</span> assertTrue("not able to find a splittable region", regions != null);<a name="line.398"></a> -<span class="sourceLineNo">399</span> assertTrue("not able to find a splittable region", regions.length == 1);<a name="line.399"></a> -<span class="sourceLineNo">400</span> ProcedureTestingUtility.waitNoProcedureRunning(procExec);<a name="line.400"></a> -<span class="sourceLineNo">401</span> ProcedureTestingUtility.setKillIfHasParent(procExec, false);<a name="line.401"></a> -<span class="sourceLineNo">402</span> ProcedureTestingUtility.setKillAndToggleBeforeStoreUpdate(procExec, true);<a name="line.402"></a> -<span class="sourceLineNo">403</span><a name="line.403"></a> -<span class="sourceLineNo">404</span> // collect AM metrics before test<a name="line.404"></a> -<span class="sourceLineNo">405</span> collectAssignmentManagerMetrics();<a name="line.405"></a> -<span class="sourceLineNo">406</span><a name="line.406"></a> -<span class="sourceLineNo">407</span> // Split region of the table<a name="line.407"></a> -<span class="sourceLineNo">408</span> long procId = procExec.submitProcedure(<a name="line.408"></a> -<span class="sourceLineNo">409</span> new SplitTableRegionProcedure(procExec.getEnvironment(), regions[0], splitKey));<a name="line.409"></a> -<span class="sourceLineNo">410</span><a name="line.410"></a> -<span class="sourceLineNo">411</span> // Restart the executor and execute the step twice<a name="line.411"></a> -<span class="sourceLineNo">412</span> MasterProcedureTestingUtility.testRecoveryAndDoubleExecution(procExec, procId);<a name="line.412"></a> -<span class="sourceLineNo">413</span> ProcedureTestingUtility.assertProcNotFailed(procExec, procId);<a name="line.413"></a> -<span class="sourceLineNo">414</span><a name="line.414"></a> -<span class="sourceLineNo">415</span> verify(tableName, splitRowNum);<a name="line.415"></a> -<span class="sourceLineNo">416</span><a name="line.416"></a> -<span class="sourceLineNo">417</span> assertEquals(splitSubmittedCount + 1, splitProcMetrics.getSubmittedCounter().getCount());<a name="line.417"></a> -<span class="sourceLineNo">418</span> assertEquals(splitFailedCount, splitProcMetrics.getFailedCounter().getCount());<a name="line.418"></a> -<span class="sourceLineNo">419</span> }<a name="line.419"></a> -<span class="sourceLineNo">420</span><a name="line.420"></a> -<span class="sourceLineNo">421</span> @Test<a name="line.421"></a> -<span class="sourceLineNo">422</span> public void testSplitWithoutPONR() throws Exception {<a name="line.422"></a> -<span class="sourceLineNo">423</span> final TableName tableName = TableName.valueOf(name.getMethodName());<a name="line.423"></a> -<span class="sourceLineNo">424</span> final ProcedureExecutor<MasterProcedureEnv> procExec = getMasterProcedureExecutor();<a name="line.424"></a> -<span class="sourceLineNo">425</span><a name="line.425"></a> -<span class="sourceLineNo">426</span> RegionInfo [] regions = MasterProcedureTestingUtility.createTable(<a name="line.426"></a> -<span class="sourceLineNo">427</span> procExec, tableName, null, ColumnFamilyName1, ColumnFamilyName2);<a name="line.427"></a> -<span class="sourceLineNo">428</span> insertData(tableName);<a name="line.428"></a> -<span class="sourceLineNo">429</span> int splitRowNum = startRowNum + rowCount / 2;<a name="line.429"></a> -<span class="sourceLineNo">430</span> byte[] splitKey = Bytes.toBytes("" + splitRowNum);<a name="line.430"></a> -<span class="sourceLineNo">431</span><a name="line.431"></a> -<span class="sourceLineNo">432</span> assertTrue("not able to find a splittable region", regions != null);<a name="line.432"></a> -<span class="sourceLineNo">433</span> assertTrue("not able to find a splittable region", regions.length == 1);<a name="line.433"></a> -<span class="sourceLineNo">434</span> ProcedureTestingUtility.waitNoProcedureRunning(procExec);<a name="line.434"></a> -<span class="sourceLineNo">435</span> ProcedureTestingUtility.setKillAndToggleBeforeStoreUpdate(procExec, true);<a name="line.435"></a> -<span class="sourceLineNo">436</span><a name="line.436"></a> -<span class="sourceLineNo">437</span> // Split region of the table<a name="line.437"></a> -<span class="sourceLineNo">438</span> long procId = procExec.submitProcedure(<a name="line.438"></a> -<span class="sourceLineNo">439</span> new SplitTableRegionProcedure(procExec.getEnvironment(), regions[0], splitKey));<a name="line.439"></a> -<span class="sourceLineNo">440</span><a name="line.440"></a> -<span class="sourceLineNo">441</span> // Execute until step 7 of split procedure<a name="line.441"></a> -<span class="sourceLineNo">442</span> // NOTE: the 7 (number after SPLIT_TABLE_REGION_UPDATE_META step)<a name="line.442"></a> -<span class="sourceLineNo">443</span> MasterProcedureTestingUtility.testRecoveryAndDoubleExecution(procExec, procId, 7, false);<a name="line.443"></a> -<span class="sourceLineNo">444</span><a name="line.444"></a> -<span class="sourceLineNo">445</span> // Unset Toggle Kill and make ProcExec work correctly<a name="line.445"></a> -<span class="sourceLineNo">446</span> ProcedureTestingUtility.setKillAndToggleBeforeStoreUpdate(procExec, false);<a name="line.446"></a> -<span class="sourceLineNo">447</span> MasterProcedureTestingUtility.restartMasterProcedureExecutor(procExec);<a name="line.447"></a> -<span class="sourceLineNo">448</span> ProcedureTestingUtility.waitProcedure(procExec, procId);<a name="line.448"></a> -<span class="sourceLineNo">449</span><a name="line.449"></a> -<span class="sourceLineNo">450</span> // Even split failed after step 4, it should still works fine<a name="line.450"></a> -<span class="sourceLineNo">451</span> verify(tableName, splitRowNum);<a name="line.451"></a> -<span class="sourceLineNo">452</span> }<a name="line.452"></a> -<span class="sourceLineNo">453</span><a name="line.453"></a> -<span class="sourceLineNo">454</span> private void insertData(final TableName tableName) throws IOException, InterruptedException {<a name="line.454"></a> -<span class="sourceLineNo">455</span> Table t = UTIL.getConnection().getTable(tableName);<a name="line.455"></a> -<span class="sourceLineNo">456</span> Put p;<a name="line.456"></a> -<span class="sourceLineNo">457</span> for (int i= 0; i < rowCount / 2; i++) {<a name="line.457"></a> -<span class="sourceLineNo">458</span> p = new Put(Bytes.toBytes("" + (startRowNum + i)));<a name="line.458"></a> -<span class="sourceLineNo">459</span> p.addColumn(Bytes.toBytes(ColumnFamilyName1), Bytes.toBytes("q1"), Bytes.toBytes(i));<a name="line.459"></a> -<span class="sourceLineNo">460</span> p.addColumn(Bytes.toBytes(ColumnFamilyName2), Bytes.toBytes("q2"), Bytes.toBytes(i));<a name="line.460"></a> -<span class="sourceLineNo">461</span> t.put(p);<a name="line.461"></a> -<span class="sourceLineNo">462</span> p = new Put(Bytes.toBytes("" + (startRowNum + rowCount - i - 1)));<a name="line.462"></a> -<span class="sourceLineNo">463</span> p.addColumn(Bytes.toBytes(ColumnFamilyName1), Bytes.toBytes("q1"), Bytes.toBytes(i));<a name="line.463"></a> -<span class="sourceLineNo">464</span> p.addColumn(Bytes.toBytes(ColumnFamilyName2), Bytes.toBytes("q2"), Bytes.toBytes(i));<a name="line.464"></a> -<span class="sourceLineNo">465</span> t.put(p);<a name="line.465"></a> -<span class="sourceLineNo">466</span> if (i % 5 == 0) {<a name="line.466"></a> -<span class="sourceLineNo">467</span> UTIL.getAdmin().flush(tableName);<a name="line.467"></a> -<span class="sourceLineNo">468</span> }<a name="line.468"></a> -<span class="sourceLineNo">469</span> }<a name="line.469"></a> -<span class="sourceLineNo">470</span> }<a name="line.470"></a> -<span class="sourceLineNo">471</span><a name="line.471"></a> -<span class="sourceLineNo">472</span> private void deleteData(<a name="line.472"></a> -<span class="sourceLineNo">473</span> final TableName tableName,<a name="line.473"></a> -<span class="sourceLineNo">474</span> final int startDeleteRowNum) throws IOException, InterruptedException {<a name="line.474"></a> -<span class="sourceLineNo">475</span> Table t = UTIL.getConnection().getTable(tableName);<a name="line.475"></a> -<span class="sourceLineNo">476</span> final int numRows = rowCount + startRowNum - startDeleteRowNum;<a name="line.476"></a> -<span class="sourceLineNo">477</span> Delete d;<a name="line.477"></a> -<span class="sourceLineNo">478</span> for (int i= startDeleteRowNum; i <= numRows + startDeleteRowNum; i++) {<a name="line.478"></a> -<span class="sourceLineNo">479</span> d = new Delete(Bytes.toBytes("" + i));<a name="line.479"></a> -<span class="sourceLineNo">480</span> t.delete(d);<a name="line.480"></a> -<span class="sourceLineNo">481</span> if (i % 5 == 0) {<a name="line.481"></a> -<span class="sourceLineNo">482</span> UTIL.getAdmin().flush(tableName);<a name="line.482"></a> -<span class="sourceLineNo">483</span> }<a name="line.483"></a> -<span class="sourceLineNo">484</span> }<a name="line.484"></a> -<span class="sourceLineNo">485</span> }<a name="line.485"></a> -<span class="sourceLineNo">486</span><a name="line.486"></a> -<span class="sourceLineNo">487</span> private void verify(final TableName tableName, final int splitRowNum) throws IOException {<a name="line.487"></a> -<span class="sourceLineNo">488</span> List<HRegion> daughters = UTIL.getMiniHBaseCluster().getRegions(tableName);<a name="line.488"></a> -<span class="sourceLineNo">489</span> assertTrue(daughters.size() == 2);<a name="line.489"></a> -<span class="sourceLineNo">490</span> LOG.info("Row Count = " + UTIL.countRows(tableName));<a name="line.490"></a> -<span class="sourceLineNo">491</span> assertTrue(UTIL.countRows(tableName) == rowCount);<a name="line.491"></a> -<span class="sourceLineNo">492</span> int startRow;<a name="line.492"></a> -<span class="sourceLineNo">493</span> int numRows;<a name="line.493"></a> -<span class="sourceLineNo">494</span> for (int i = 0; i < daughters.size(); i++) {<a name="line.494"></a> -<span class="sourceLineNo">495</span> if (Bytes.compareTo(<a name="line.495"></a> -<span class="sourceLineNo">496</span> daughters.get(i).getRegionInfo().getStartKey(), HConstants.EMPTY_BYTE_ARRAY) == 0) {<a name="line.496"></a> -<span class="sourceLineNo">497</span> startRow = startRowNum; // first region<a name="line.497"></a> -<span class="sourceLineNo">498</span> numRows = splitRowNum - startRowNum;<a name="line.498"></a> -<span class="sourceLineNo">499</span> } else {<a name="line.499"></a> -<span class="sourceLineNo">500</span> startRow = splitRowNum;<a name="line.500"></a> -<span class="sourceLineNo">501</span> numRows = rowCount + startRowNum - splitRowNum;<a name="line.501"></a> -<span class="sourceLineNo">502</span> }<a name="line.502"></a> -<span class="sourceLineNo">503</span> verifyData(<a name="line.503"></a> -<span class="sourceLineNo">504</span> daughters.get(i),<a name="line.504"></a> -<span class="sourceLineNo">505</span> startRow,<a name="line.505"></a> -<span class="sourceLineNo">506</span> numRows,<a name="line.506"></a> -<span class="sourceLineNo">507</span> Bytes.toBytes(ColumnFamilyName1),<a name="line.507"></a> -<span class="sourceLineNo">508</span> Bytes.toBytes(ColumnFamilyName2));<a name="line.508"></a> -<span class="sourceLineNo">509</span> }<a name="line.509"></a> -<span class="sourceLineNo">510</span> }<a name="line.510"></a> -<span class="sourceLineNo">511</span><a name="line.511"></a> -<span class="sourceLineNo">512</span> private void verifyData(<a name="line.512"></a> -<span class="sourceLineNo">513</span> final HRegion newReg,<a name="line.513"></a> -<span class="sourceLineNo">514</span> final int startRow,<a name="line.514"></a> -<span class="sourceLineNo">515</span> final int numRows,<a name="line.515"></a> -<span class="sourceLineNo">516</span> final byte[]... families)<a name="line.516"></a> -<span class="sourceLineNo">517</span> throws IOException {<a name="line.517"></a> -<span class="sourceLineNo">518</span> for (int i = startRow; i < startRow + numRows; i++) {<a name="line.518"></a> -<span class="sourceLineNo">519</span> byte[] row = Bytes.toBytes("" + i);<a name="line.519"></a> -<span class="sourceLineNo">520</span> Get get = new Get(row);<a name="line.520"></a> -<span class="sourceLineNo">521</span> Result result = newReg.get(get);<a name="line.521"></a> -<span class="sourceLineNo">522</span> Cell[] raw = result.rawCells();<a name="line.522"></a> -<span class="sourceLineNo">523</span> assertEquals(families.length, result.size());<a name="line.523"></a> -<span class="sourceLineNo">524</span> for (int j = 0; j < families.length; j++) {<a name="line.524"></a> -<span class="sourceLineNo">525</span> assertTrue(CellUtil.matchingRows(raw[j], row));<a name="line.525"></a> -<span class="sourceLineNo">526</span> assertTrue(CellUtil.matchingFamily(raw[j], families[j]));<a name="line.526"></a> -<span class="sourceLineNo">527</span> }<a name="line.527"></a> -<span class="sourceLineNo">528</span> }<a name="line.528"></a> -<span class="sourceLineNo">529</span> }<a name="line.529"></a> -<span class="sourceLineNo">530</span><a name="line.530"></a> -<span class="sourceLineNo">531</span> private ProcedureExecutor<MasterProcedureEnv> getMasterProcedureExecutor() {<a name="line.531"></a> -<span class="sourceLineNo">532</span> return UTIL.getHBaseCluster().getMaster().getMasterProcedureExecutor();<a name="line.532"></a> -<span class="sourceLineNo">533</span> }<a name="line.533"></a> -<span class="sourceLineNo">534</span><a name="line.534"></a> -<span class="sourceLineNo">535</span> private void collectAssignmentManagerMetrics() {<a name="line.535"></a> -<span class="sourceLineNo">536</span> splitSubmittedCount = splitProcMetrics.getSubmittedCounter().getCount();<a name="line.536"></a> -<span class="sourceLineNo">537</span> splitFailedCount = splitProcMetrics.getFailedCounter().getCount();<a name="line.537"></a> -<span class="sourceLineNo">538</span> assignSubmittedCount = assignProcMetrics.getSubmittedCounter().getCount();<a name="line.538"></a> -<span class="sourceLineNo">539</span> assignFailedCount = assignProcMetrics.getFailedCounter().getCount();<a name="line.539"></a> -<span class="sourceLineNo">540</span> unassignSubmittedCount = unassignProcMetrics.getSubmittedCounter().getCount();<a name="line.540"></a> -<span class="sourceLineNo">541</span> unassignFailedCount = unassignProcMetrics.getFailedCounter().getCount();<a name="line.541"></a> -<span class="sourceLineNo">542</span> }<a name="line.542"></a> -<span class="sourceLineNo">543</span>}<a name="line.543"></a> +<span class="sourceLineNo">378</span> UTIL.waitUntilAllRegionsAssigned(tableName);<a name="line.378"></a> +<span class="sourceLineNo">379</span> List<HRegion> newRegions = UTIL.getMiniHBaseCluster().getRegions(tableName);<a name="line.379"></a> +<span class="sourceLineNo">380</span> assertEquals(1, newRegions.size());<a name="line.380"></a> +<span class="sourceLineNo">381</span> verifyData(newRegions.get(0), startRowNum, rowCount,<a name="line.381"></a> +<span class="sourceLineNo">382</span> Bytes.toBytes(ColumnFamilyName1), Bytes.toBytes(ColumnFamilyName2));<a name="line.382"></a> +<span class="sourceLineNo">383</span><a name="line.383"></a> +<span class="sourceLineNo">384</span> assertEquals(splitSubmittedCount + 1, splitProcMetrics.getSubmittedCounter().getCount());<a name="line.384"></a> +<span class="sourceLineNo">385</span> assertEquals(splitFailedCount + 1, splitProcMetrics.getFailedCounter().getCount());<a name="line.385"></a> +<span class="sourceLineNo">386</span> }<a name="line.386"></a> +<span class="sourceLineNo">387</span><a name="line.387"></a> +<span class="sourceLineNo">388</span> @Test<a name="line.388"></a> +<span class="sourceLineNo">389</span> public void testRecoveryAndDoubleExecution() throws Exception {<a name="line.389"></a> +<span class="sourceLineNo">390</span> final TableName tableName = TableName.valueOf(name.getMethodName());<a name="line.390"></a> +<span class="sourceLineNo">391</span> final ProcedureExecutor<MasterProcedureEnv> procExec = getMasterProcedureExecutor();<a name="line.391"></a> +<span class="sourceLineNo">392</span><a name="line.392"></a> +<span class="sourceLineNo">393</span> RegionInfo [] regions = MasterProcedureTestingUtility.createTable(<a name="line.393"></a> +<span class="sourceLineNo">394</span> procExec, tableName, null, ColumnFamilyName1, ColumnFamilyName2);<a name="line.394"></a> +<span class="sourceLineNo">395</span> insertData(tableName);<a name="line.395"></a> +<span class="sourceLineNo">396</span> int splitRowNum = startRowNum + rowCount / 2;<a name="line.396"></a> +<span class="sourceLineNo">397</span> byte[] splitKey = Bytes.toBytes("" + splitRowNum);<a name="line.397"></a> +<span class="sourceLineNo">398</span><a name="line.398"></a> +<span class="sourceLineNo">399</span> assertTrue("not able to find a splittable region", regions != null);<a name="line.399"></a> +<span class="sourceLineNo">400</span> assertTrue("not able to find a splittable region", regions.length == 1);<a name="line.400"></a> +<span class="sourceLineNo">401</span> ProcedureTestingUtility.waitNoProcedureRunning(procExec);<a name="line.401"></a> +<span class="sourceLineNo">402</span> ProcedureTestingUtility.setKillIfHasParent(procExec, false);<a name="line.402"></a> +<span class="sourceLineNo">403</span> ProcedureTestingUtility.setKillAndToggleBeforeStoreUpdate(procExec, true);<a name="line.403"></a> +<span class="sourceLineNo">404</span><a name="line.404"></a> +<span class="sourceLineNo">405</span> // collect AM metrics before test<a name="line.405"></a> +<span class="sourceLineNo">406</span> collectAssignmentManagerMetrics();<a name="line.406"></a> +<span class="sourceLineNo">407</span><a name="line.407"></a> +<span class="sourceLineNo">408</span> // Split region of the table<a name="line.408"></a> +<span class="sourceLineNo">409</span> long procId = procExec.submitProcedure(<a name="line.409"></a> +<span class="sourceLineNo">410</span> new SplitTableRegionProcedure(procExec.getEnvironment(), regions[0], splitKey));<a name="line.410"></a> +<span class="sourceLineNo">411</span><a name="line.411"></a> +<span class="sourceLineNo">412</span> // Restart the executor and execute the step twice<a name="line.412"></a> +<span class="sourceLineNo">413</span> MasterProcedureTestingUtility.testRecoveryAndDoubleExecution(procExec, procId);<a name="line.413"></a> +<span class="sourceLineNo">414</span> ProcedureTestingUtility.assertProcNotFailed(procExec, procId);<a name="line.414"></a> +<span class="sourceLineNo">415</span><a name="line.415"></a> +<span class="sourceLineNo">416</span> verify(tableName, splitRowNum);<a name="line.416"></a> +<span class="sourceLineNo">417</span><a name="line.417"></a> +<span class="sourceLineNo">418</span> assertEquals(splitSubmittedCount + 1, splitProcMetrics.getSubmittedCounter().getCount());<a name="line.418"></a> +<span class="sourceLineNo">419</span> assertEquals(splitFailedCount, splitProcMetrics.getFailedCounter().getCount());<a name="line.419"></a> +<span class="sourceLineNo">420</span> }<a name="line.420"></a> +<span class="sourceLineNo">421</span><a name="line.421"></a> +<span class="sourceLineNo">422</span> @Test<a name="line.422"></a> +<span class="sourceLineNo">423</span> public void testSplitWithoutPONR() throws Exception {<a name="line.423"></a> +<span class="sourceLineNo">424</span> final TableName tableName = TableName.valueOf(name.getMethodName());<a name="line.424"></a> +<span class="sourceLineNo">425</span> final ProcedureExecutor<MasterProcedureEnv> procExec = getMasterProcedureExecutor();<a name="line.425"></a> +<span class="sourceLineNo">426</span><a name="line.426"></a> +<span class="sourceLineNo">427</span> RegionInfo [] regions = MasterProcedureTestingUtility.createTable(<a name="line.427"></a> +<span class="sourceLineNo">428</span> procExec, tableName, null, ColumnFamilyName1, ColumnFamilyName2);<a name="line.428"></a> +<span class="sourceLineNo">429</span> insertData(tableName);<a name="line.429"></a> +<span class="sourceLineNo">430</span> int splitRowNum = startRowNum + rowCount / 2;<a name="line.430"></a> +<span class="sourceLineNo">431</span> byte[] splitKey = Bytes.toBytes("" + splitRowNum);<a name="line.431"></a> +<span class="sourceLineNo">432</span><a name="line.432"></a> +<span class="sourceLineNo">433</span> assertTrue("not able to find a splittable region", regions != null);<a name="line.433"></a> +<span class="sourceLineNo">434</span> assertTrue("not able to find a splittable region", regions.length == 1);<a name="line.434"></a> +<span class="sourceLineNo">435</span> ProcedureTestingUtility.waitNoProcedureRunning(procExec);<a name="line.435"></a> +<span class="sourceLineNo">436</span> ProcedureTestingUtility.setKillAndToggleBeforeStoreUpdate(procExec, true);<a name="line.436"></a> +<span class="sourceLineNo">437</span><a name="line.437"></a> +<span class="sourceLineNo">438</span> // Split region of the table<a name="line.438"></a> +<span class="sourceLineNo">439</span> long procId = procExec.submitProcedure(<a name="line.439"></a> +<span class="sourceLineNo">440</span> new SplitTableRegionProcedure(procExec.getEnvironment(), regions[0], splitKey));<a name="line.440"></a> +<span class="sourceLineNo">441</span><a name="line.441"></a> +<span class="sourceLineNo">442</span> // Execute until step 7 of split procedure<a name="line.442"></a> +<span class="sourceLineNo">443</span> // NOTE: the 7 (number after SPLIT_TABLE_REGION_UPDATE_META step)<a name="line.443"></a> +<span class="sourceLineNo">444</span> MasterProcedureTestingUtility.testRecoveryAndDoubleExecution(procExec, procId, 7, false);<a name="line.444"></a> +<span class="sourceLineNo">445</span><a name="line.445"></a> +<span class="sourceLineNo">446</span> // Unset Toggle Kill and make ProcExec work correctly<a name="line.446"></a> +<span class="sourceLineNo">447</span> ProcedureTestingUtility.setKillAndToggleBeforeStoreUpdate(procExec, false);<a name="line.447"></a> +<span class="sourceLineNo">448</span> MasterProcedureTestingUtility.restartMasterProcedureExecutor(procExec);<a name="line.448"></a> +<span class="sourceLineNo">449</span> ProcedureTestingUtility.waitProcedure(procExec, procId);<a name="line.449"></a> +<span class="sourceLineNo">450</span><a name="line.450"></a> +<span class="sourceLineNo">451</span> // Even split failed after step 4, it should still works fine<a name="line.451"></a> +<span class="sourceLineNo">452</span> verify(tableName, splitRowNum);<a name="line.452"></a> +<span class="sourceLineNo">453</span> }<a name="line.453"></a> +<span class="sourceLineNo">454</span><a name="line.454"></a> +<span class="sourceLineNo">455</span> private void insertData(final TableName tableName) throws IOException, InterruptedException {<a name="line.455"></a> +<span class="sourceLineNo">456</span> Table t = UTIL.getConnection().getTable(tableName);<a name="line.456"></a> +<span class="sourceLineNo">457</span> Put p;<a name="line.457"></a> +<span class="sourceLineNo">458</span> for (int i= 0; i < rowCount / 2; i++) {<a name="line.458"></a> +<span class="sourceLineNo">459</span> p = new Put(Bytes.toBytes("" + (startRowNum + i)));<a name="line.459"></a> +<span class="sourceLineNo">460</span> p.addColumn(Bytes.toBytes(ColumnFamilyName1), Bytes.toBytes("q1"), Bytes.toBytes(i));<a name="line.460"></a> +<span class="sourceLineNo">461</span> p.addColumn(Bytes.toBytes(ColumnFamilyName2), Bytes.toBytes("q2"), Bytes.toBytes(i));<a name="line.461"></a> +<span class="sourceLineNo">462</span> t.put(p);<a name="line.462"></a> +<span class="sourceLineNo">463</span> p = new Put(Bytes.toBytes("" + (startRowNum + rowCount - i - 1)));<a name="line.463"></a> +<span class="sourceLineNo">464</span> p.addColumn(Bytes.toBytes(ColumnFamilyName1), Bytes.toBytes("q1"), Bytes.toBytes(i));<a name="line.464"></a> +<span class="sourceLineNo">465</span> p.addColumn(Bytes.toBytes(ColumnFamilyName2), Bytes.toBytes("q2"), Bytes.toBytes(i));<a name="line.465"></a> +<span class="sourceLineNo">466</span> t.put(p);<a name="line.466"></a> +<span class="sourceLineNo">467</span> if (i % 5 == 0) {<a name="line.467"></a> +<span class="sourceLineNo">468</span> UTIL.getAdmin().flush(tableName);<a name="line.468"></a> +<span class="sourceLineNo">469</span> }<a name="line.469"></a> +<span class="sourceLineNo">470</span> }<a name="line.470"></a> +<span class="sourceLineNo">471</span> }<a name="line.471"></a> +<span class="sourceLineNo">472</span><a name="line.472"></a> +<span class="sourceLineNo">473</span> private void deleteData(<a name="line.473"></a> +<span class="sourceLineNo">474</span> final TableName tableName,<a name="line.474"></a> +<span class="sourceLineNo">475</span> final int startDeleteRowNum) throws IOException, InterruptedException {<a name="line.475"></a> +<span class="sourceLineNo">476</span> Table t = UTIL.getConnection().getTable(tableName);<a name="line.476"></a> +<span class="sourceLineNo">477</span> final int numRows = rowCount + startRowNum - startDeleteRowNum;<a name="line.477"></a> +<span class="sourceLineNo">478</span> Delete d;<a name="line.478"></a> +<span class="sourceLineNo">479</span> for (int i= startDeleteRowNum; i <= numRows + startDeleteRowNum; i++) {<a name="line.479"></a> +<span class="sourceLineNo">480</span> d = new Delete(Bytes.toBytes("" + i));<a name="line.480"></a> +<span class="sourceLineNo">481</span> t.delete(d);<a name="line.481"></a> +<span class="sourceLineNo">482</span> if (i % 5 == 0) {<a name="line.482"></a> +<span class="sourceLineNo">483</span> UTIL.getAdmin().flush(tableName);<a name="line.483"></a> +<span class="sourceLineNo">484</span> }<a name="line.484"></a> +<span class="sourceLineNo">485</span> }<a name="line.485"></a> +<span class="sourceLineNo">486</span> }<a name="line.486"></a> +<span class="sourceLineNo">487</span><a name="line.487"></a> +<span class="sourceLineNo">488</span> private void verify(final TableName tableName, final int splitRowNum) throws IOException {<a name="line.488"></a> +<span class="sourceLineNo">489</span> List<HRegion> daughters = UTIL.getMiniHBaseCluster().getRegions(tableName);<a name="line.489"></a> +<span class="sourceLineNo">490</span> assertTrue(daughters.size() == 2);<a name="line.490"></a> +<span class="sourceLineNo">491</span> LOG.info("Row Count = " + UTIL.countRows(tableName));<a name="line.491"></a> +<span class="sourceLineNo">492</span> assertTrue(UTIL.countRows(tableName) == rowCount);<a name="line.492"></a> +<span class="sourceLineNo">493</span> int startRow;<a name="line.493"></a> +<span class="sourceLineNo">494</span> int numRows;<a name="line.494"></a> +<span class="sourceLineNo">495</span> for (int i = 0; i < daughters.size(); i++) {<a name="line.495"></a> +<span class="sourceLineNo">496</span> if (Bytes.compareTo(<a name="line.496"></a> +<span class="sourceLineNo">497</span> daughters.get(i).getRegionInfo().getStartKey(), HConstants.EMPTY_BYTE_ARRAY) == 0) {<a name="line.497"></a> +<span class="sourceLineNo">498</span> startRow = startRowNum; // first region<a name="line.498"></a> +<span class="sourceLineNo">499</span> numRows = splitRowNum - startRowNum;<a name="line.499"></a> +<span class="sourceLineNo">500</span> } else {<a name="line.500"></a> +<span class="sourceLineNo">501</span> startRow = splitRowNum;<a name="line.501"></a> +<span class="sourceLineNo">502</span> numRows = rowCount + startRowNum - splitRowNum;<a name="line.502"></a> +<span class="sourceLineNo">503</span> }<a name="line.503"></a> +<span class="sourceLineNo">504</span> verifyData(<a name="line.504"></a> +<span class="sourceLineNo">505</span> daughters.get(i),<a name="line.505"></a> +<span class="sourceLineNo">506</span> startRow,<a name="line.506"></a> +<span class="sourceLineNo">507</span> numRows,<a name="line.507"></a> +<span class="sourceLineNo">508</span> Bytes.toBytes(ColumnFamilyName1),<a name="line.508"></a> +<span class="sourceLineNo">509</span> Bytes.toBytes(ColumnFamilyName2));<a name="line.509"></a> +<span class="sourceLineNo">510</span> }<a name="line.510"></a> +<span class="sourceLineNo">511</span> }<a name="line.511"></a> +<span class="sourceLineNo">512</span><a name="line.512"></a> +<span class="sourceLineNo">513</span> private void verifyData(<a name="line.513"></a> +<span class="sourceLineNo">514</span> final HRegion newReg,<a name="line.514"></a> +<span class="sourceLineNo">515</span> final int startRow,<a name="line.515"></a> +<span class="sourceLineNo">516</span> final int numRows,<a name="line.516"></a> +<span class="sourceLineNo">517</span> final byte[]... families)<a name="line.517"></a> +<span class="sourceLineNo">518</span> throws IOException {<a name="line.518"></a> +<span class="sourceLineNo">519</span> for (int i = startRow; i < startRow + numRows; i++) {<a name="line.519"></a> +<span class="sourceLineNo">520</span> byte[] row = Bytes.toBytes("" + i);<a name="line.520"></a> +<span class="sourceLineNo">521</span> Get get = new Get(row);<a name="line.521"></a> +<span class="sourceLineNo">522</span> Result result = newReg.get(get);<a name="line.522"></a> +<span class="sourceLineNo">523</span> Cell[] raw = result.rawCells();<a name="line.523"></a> +<span class="sourceLineNo">524</span> assertEquals(families.length, result.size());<a name="line.524"></a> +<span class="sourceLineNo">525</span> for (int j = 0; j < families.length; j++) {<a name="line.525"></a> +<span class="sourceLineNo">526</span> assertTrue(CellUtil.matchingRows(raw[j], row));<a name="line.526"></a> +<span class="sourceLineNo">527</span> assertTrue(CellUtil.matchingFamily(raw[j], families[j]));<a name="line.527"></a> +<span class="sourceLineNo">528</span> }<a name="line.528"></a> +<span class="sourceLineNo">529</span> }<a name="line.529"></a> +<span class="sourceLineNo">530</span> }<a name="line.530"></a> +<span class="sourceLineNo">531</span><a name="line.531"></a> +<span class="sourceLineNo">532</span> private ProcedureExecutor<MasterProcedureEnv> getMasterProcedureExecutor() {<a name="line.532"></a> +<span class="sourceLineNo">533</span> return UTIL.getHBaseCluster().getMaster().getMasterProcedureExecutor();<a name="line.533"></a> +<span class="sourceLineNo">534</span> }<a name="line.534"></a> +<span class="sourceLineNo">535</span><a name="line.535"></a> +<span class="sourceLineNo">536</span> private void collectAssignmentManagerMetrics() {<a name="line.536"></a> +<span class="sourceLineNo">537</span> splitSubmittedCount = splitProcMetrics.getSubmittedCounter().getCount();<a name="line.537"></a> +<span class="sourceLineNo">538</span> splitFailedCount = splitProcMetrics.getFailedCounter().getCount();<a name="line.538"></a> +<span class="sourceLineNo">539</span> assignSubmittedCount = assignProcMetrics.getSubmittedCounter().getCount();<a name="line.539"></a> +<span class="sourceLineNo">540</span> assignFailedCount = assignProcMetrics.getFailedCounter().getCount();<a name="line.540"></a> +<span class="sourceLineNo">541</span> unassignSubmittedCount = unassignProcMetrics.getSubmittedCounter().getCount();<a name="line.541"></a> +<span class="sourceLineNo">542</span> unassignFailedCount = unassignProcMetrics.getFailedCounter().getCount();<a name="line.542"></a> +<span class="sourceLineNo">543</span> }<a name="line.543"></a> +<span class="sourceLineNo">544</span>}<a name="line.544"></a>
http://git-wip-us.apache.org/repos/asf/hbase-site/blob/323b17d9/testdevapidocs/src-html/org/apache/hadoop/hbase/master/procedure/MasterProcedureTestingUtility.InjectAbortOnLoadListener.html ---------------------------------------------------------------------- diff --git a/testdevapidocs/src-html/org/apache/hadoop/hbase/master/procedure/MasterProcedureTestingUtility.InjectAbortOnLoadListener.html b/testdevapidocs/src-html/org/apache/hadoop/hbase/master/procedure/MasterProcedureTestingUtility.InjectAbortOnLoadListener.html index 8c7d5c9..0c87f49 100644 --- a/testdevapidocs/src-html/org/apache/hadoop/hbase/master/procedure/MasterProcedureTestingUtility.InjectAbortOnLoadListener.html +++ b/testdevapidocs/src-html/org/apache/hadoop/hbase/master/procedure/MasterProcedureTestingUtility.InjectAbortOnLoadListener.html @@ -387,7 +387,7 @@ <span class="sourceLineNo">379</span> */<a name="line.379"></a> <span class="sourceLineNo">380</span> public static void testRecoveryAndDoubleExecution(<a name="line.380"></a> <span class="sourceLineNo">381</span> final ProcedureExecutor<MasterProcedureEnv> procExec, final long procId,<a name="line.381"></a> -<span class="sourceLineNo">382</span> final int numSteps, final boolean expectExecRunning) throws Exception {<a name="line.382"></a> +<span class="sourceLineNo">382</span> final int lastStep, final boolean expectExecRunning) throws Exception {<a name="line.382"></a> <span class="sourceLineNo">383</span> ProcedureTestingUtility.waitProcedure(procExec, procId);<a name="line.383"></a> <span class="sourceLineNo">384</span> assertEquals(false, procExec.isRunning());<a name="line.384"></a> <span class="sourceLineNo">385</span><a name="line.385"></a> @@ -405,201 +405,204 @@ <span class="sourceLineNo">397</span> // fix would be get all visited states by the procedure and then check if user speccified<a name="line.397"></a> <span class="sourceLineNo">398</span> // state is in that list. Current assumption of sequential proregression of steps/ states is<a name="line.398"></a> <span class="sourceLineNo">399</span> // made at multiple places so we can keep while condition below for simplicity.<a name="line.399"></a> -<span class="sourceLineNo">400</span> Procedure proc = procExec.getProcedure(procId);<a name="line.400"></a> +<span class="sourceLineNo">400</span> Procedure<?> proc = procExec.getProcedure(procId);<a name="line.400"></a> <span class="sourceLineNo">401</span> int stepNum = proc instanceof StateMachineProcedure ?<a name="line.401"></a> <span class="sourceLineNo">402</span> ((StateMachineProcedure) proc).getCurrentStateId() : 0;<a name="line.402"></a> -<span class="sourceLineNo">403</span> while (stepNum < numSteps) {<a name="line.403"></a> -<span class="sourceLineNo">404</span> LOG.info("Restart " + stepNum + " exec state=" + proc);<a name="line.404"></a> -<span class="sourceLineNo">405</span> ProcedureTestingUtility.assertProcNotYetCompleted(procExec, procId);<a name="line.405"></a> -<span class="sourceLineNo">406</span> restartMasterProcedureExecutor(procExec);<a name="line.406"></a> -<span class="sourceLineNo">407</span> ProcedureTestingUtility.waitProcedure(procExec, procId);<a name="line.407"></a> -<span class="sourceLineNo">408</span> // Old proc object is stale, need to get the new one after ProcedureExecutor restart<a name="line.408"></a> -<span class="sourceLineNo">409</span> proc = procExec.getProcedure(procId);<a name="line.409"></a> -<span class="sourceLineNo">410</span> stepNum = proc instanceof StateMachineProcedure ?<a name="line.410"></a> -<span class="sourceLineNo">411</span> ((StateMachineProcedure) proc).getCurrentStateId() : stepNum + 1;<a name="line.411"></a> -<span class="sourceLineNo">412</span> }<a name="line.412"></a> -<span class="sourceLineNo">413</span><a name="line.413"></a> -<span class="sourceLineNo">414</span> assertEquals(expectExecRunning, procExec.isRunning());<a name="line.414"></a> -<span class="sourceLineNo">415</span> }<a name="line.415"></a> +<span class="sourceLineNo">403</span> for (;;) {<a name="line.403"></a> +<span class="sourceLineNo">404</span> if (stepNum == lastStep) {<a name="line.404"></a> +<span class="sourceLineNo">405</span> break;<a name="line.405"></a> +<span class="sourceLineNo">406</span> }<a name="line.406"></a> +<span class="sourceLineNo">407</span> LOG.info("Restart " + stepNum + " exec state=" + proc);<a name="line.407"></a> +<span class="sourceLineNo">408</span> ProcedureTestingUtility.assertProcNotYetCompleted(procExec, procId);<a name="line.408"></a> +<span class="sourceLineNo">409</span> restartMasterProcedureExecutor(procExec);<a name="line.409"></a> +<span class="sourceLineNo">410</span> ProcedureTestingUtility.waitProcedure(procExec, procId);<a name="line.410"></a> +<span class="sourceLineNo">411</span> // Old proc object is stale, need to get the new one after ProcedureExecutor restart<a name="line.411"></a> +<span class="sourceLineNo">412</span> proc = procExec.getProcedure(procId);<a name="line.412"></a> +<span class="sourceLineNo">413</span> stepNum = proc instanceof StateMachineProcedure ?<a name="line.413"></a> +<span class="sourceLineNo">414</span> ((StateMachineProcedure) proc).getCurrentStateId() : stepNum + 1;<a name="line.414"></a> +<span class="sourceLineNo">415</span> }<a name="line.415"></a> <span class="sourceLineNo">416</span><a name="line.416"></a> -<span class="sourceLineNo">417</span> /**<a name="line.417"></a> -<span class="sourceLineNo">418</span> * Run through all procedure flow states TWICE while also restarting<a name="line.418"></a> -<span class="sourceLineNo">419</span> * procedure executor at each step; i.e force a reread of procedure store.<a name="line.419"></a> -<span class="sourceLineNo">420</span> *<a name="line.420"></a> -<span class="sourceLineNo">421</span> *<p>It does<a name="line.421"></a> -<span class="sourceLineNo">422</span> * <ol><li>Execute step N - kill the executor before store update<a name="line.422"></a> -<span class="sourceLineNo">423</span> * <li>Restart executor/store<a name="line.423"></a> -<span class="sourceLineNo">424</span> * <li>Executes hook for each step twice<a name="line.424"></a> -<span class="sourceLineNo">425</span> * <li>Execute step N - and then save to store<a name="line.425"></a> -<span class="sourceLineNo">426</span> * </ol><a name="line.426"></a> -<span class="sourceLineNo">427</span> *<a name="line.427"></a> -<span class="sourceLineNo">428</span> *<p>This is a good test for finding state that needs persisting and steps that are not<a name="line.428"></a> -<span class="sourceLineNo">429</span> * idempotent. Use this version of the test when the order in which flow steps are executed is<a name="line.429"></a> -<span class="sourceLineNo">430</span> * not start to finish; where the procedure may vary the flow steps dependent on circumstance<a name="line.430"></a> -<span class="sourceLineNo">431</span> * found.<a name="line.431"></a> -<span class="sourceLineNo">432</span> * @see #testRecoveryAndDoubleExecution(ProcedureExecutor, long, int, boolean)<a name="line.432"></a> -<span class="sourceLineNo">433</span> */<a name="line.433"></a> -<span class="sourceLineNo">434</span> public static void testRecoveryAndDoubleExecution(<a name="line.434"></a> -<span class="sourceLineNo">435</span> final ProcedureExecutor<MasterProcedureEnv> procExec, final long procId, final StepHook hook)<a name="line.435"></a> -<span class="sourceLineNo">436</span> throws Exception {<a name="line.436"></a> -<span class="sourceLineNo">437</span> ProcedureTestingUtility.waitProcedure(procExec, procId);<a name="line.437"></a> -<span class="sourceLineNo">438</span> assertEquals(false, procExec.isRunning());<a name="line.438"></a> -<span class="sourceLineNo">439</span> for (int i = 0; !procExec.isFinished(procId); ++i) {<a name="line.439"></a> -<span class="sourceLineNo">440</span> LOG.info("Restart " + i + " exec state=" + procExec.getProcedure(procId));<a name="line.440"></a> -<span class="sourceLineNo">441</span> if (hook != null) {<a name="line.441"></a> -<span class="sourceLineNo">442</span> assertTrue(hook.execute(i));<a name="line.442"></a> -<span class="sourceLineNo">443</span> }<a name="line.443"></a> -<span class="sourceLineNo">444</span> restartMasterProcedureExecutor(procExec);<a name="line.444"></a> -<span class="sourceLineNo">445</span> ProcedureTestingUtility.waitProcedure(procExec, procId);<a name="line.445"></a> -<span class="sourceLineNo">446</span> }<a name="line.446"></a> -<span class="sourceLineNo">447</span> assertEquals(true, procExec.isRunning());<a name="line.447"></a> -<span class="sourceLineNo">448</span> ProcedureTestingUtility.assertProcNotFailed(procExec, procId);<a name="line.448"></a> -<span class="sourceLineNo">449</span> }<a name="line.449"></a> -<span class="sourceLineNo">450</span><a name="line.450"></a> -<span class="sourceLineNo">451</span> public static void testRecoveryAndDoubleExecution(<a name="line.451"></a> -<span class="sourceLineNo">452</span> final ProcedureExecutor<MasterProcedureEnv> procExec, final long procId) throws Exception {<a name="line.452"></a> -<span class="sourceLineNo">453</span> testRecoveryAndDoubleExecution(procExec, procId, null);<a name="line.453"></a> -<span class="sourceLineNo">454</span> }<a name="line.454"></a> -<span class="sourceLineNo">455</span><a name="line.455"></a> -<span class="sourceLineNo">456</span> /**<a name="line.456"></a> -<span class="sourceLineNo">457</span> * Hook which will be executed on each step<a name="line.457"></a> -<span class="sourceLineNo">458</span> */<a name="line.458"></a> -<span class="sourceLineNo">459</span> public interface StepHook{<a name="line.459"></a> -<span class="sourceLineNo">460</span> /**<a name="line.460"></a> -<span class="sourceLineNo">461</span> * @param step Step no. at which this will be executed<a name="line.461"></a> -<span class="sourceLineNo">462</span> * @return false if test should fail otherwise true<a name="line.462"></a> -<span class="sourceLineNo">463</span> * @throws IOException<a name="line.463"></a> -<span class="sourceLineNo">464</span> */<a name="line.464"></a> -<span class="sourceLineNo">465</span> boolean execute(int step) throws IOException;<a name="line.465"></a> -<span class="sourceLineNo">466</span> }<a name="line.466"></a> -<span class="sourceLineNo">467</span><a name="line.467"></a> -<span class="sourceLineNo">468</span> /**<a name="line.468"></a> -<span class="sourceLineNo">469</span> * Execute the procedure up to "lastStep" and then the ProcedureExecutor<a name="line.469"></a> -<span class="sourceLineNo">470</span> * is restarted and an abort() is injected.<a name="line.470"></a> -<span class="sourceLineNo">471</span> * If the procedure implement abort() this should result in rollback being triggered.<a name="line.471"></a> -<span class="sourceLineNo">472</span> * Each rollback step is called twice, by restarting the executor after every step.<a name="line.472"></a> -<span class="sourceLineNo">473</span> * At the end of this call the procedure should be finished and rolledback.<a name="line.473"></a> -<span class="sourceLineNo">474</span> * This method assert on the procedure being terminated with an AbortException.<a name="line.474"></a> -<span class="sourceLineNo">475</span> */<a name="line.475"></a> -<span class="sourceLineNo">476</span> public static void testRollbackAndDoubleExecution(<a name="line.476"></a> -<span class="sourceLineNo">477</span> final ProcedureExecutor<MasterProcedureEnv> procExec, final long procId,<a name="line.477"></a> -<span class="sourceLineNo">478</span> final int lastStep) throws Exception {<a name="line.478"></a> -<span class="sourceLineNo">479</span> testRollbackAndDoubleExecution(procExec, procId, lastStep, false);<a name="line.479"></a> -<span class="sourceLineNo">480</span> }<a name="line.480"></a> -<span class="sourceLineNo">481</span><a name="line.481"></a> -<span class="sourceLineNo">482</span> public static void testRollbackAndDoubleExecution(<a name="line.482"></a> -<span class="sourceLineNo">483</span> final ProcedureExecutor<MasterProcedureEnv> procExec, final long procId,<a name="line.483"></a> -<span class="sourceLineNo">484</span> final int lastStep, boolean waitForAsyncProcs) throws Exception {<a name="line.484"></a> -<span class="sourceLineNo">485</span> // Execute up to last step<a name="line.485"></a> -<span class="sourceLineNo">486</span> testRecoveryAndDoubleExecution(procExec, procId, lastStep, false);<a name="line.486"></a> -<span class="sourceLineNo">487</span><a name="line.487"></a> -<span class="sourceLineNo">488</span> // Restart the executor and rollback the step twice<a name="line.488"></a> -<span class="sourceLineNo">489</span> // rollback step N - kill before store update<a name="line.489"></a> -<span class="sourceLineNo">490</span> // restart executor/store<a name="line.490"></a> -<span class="sourceLineNo">491</span> // rollback step N - save on store<a name="line.491"></a> -<span class="sourceLineNo">492</span> InjectAbortOnLoadListener abortListener = new InjectAbortOnLoadListener(procExec);<a name="line.492"></a> -<span class="sourceLineNo">493</span> abortListener.addProcId(procId);<a name="line.493"></a> -<span class="sourceLineNo">494</span> procExec.registerListener(abortListener);<a name="line.494"></a> -<span class="sourceLineNo">495</span> try {<a name="line.495"></a> -<span class="sourceLineNo">496</span> for (int i = 0; !procExec.isFinished(procId); ++i) {<a name="line.496"></a> -<span class="sourceLineNo">497</span> LOG.info("Restart " + i + " rollback state: " + procExec.getProcedure(procId));<a name="line.497"></a> -<span class="sourceLineNo">498</span> ProcedureTestingUtility.assertProcNotYetCompleted(procExec, procId);<a name="line.498"></a> -<span class="sourceLineNo">499</span> restartMasterProcedureExecutor(procExec);<a name="line.499"></a> -<span class="sourceLineNo">500</span> ProcedureTestingUtility.waitProcedure(procExec, procId);<a name="line.500"></a> -<span class="sourceLineNo">501</span> }<a name="line.501"></a> -<span class="sourceLineNo">502</span> } finally {<a name="line.502"></a> -<span class="sourceLineNo">503</span> assertTrue(procExec.unregisterListener(abortListener));<a name="line.503"></a> -<span class="sourceLineNo">504</span> }<a name="line.504"></a> -<span class="sourceLineNo">505</span><a name="line.505"></a> -<span class="sourceLineNo">506</span> if (waitForAsyncProcs) {<a name="line.506"></a> -<span class="sourceLineNo">507</span> // Sometimes there are other procedures still executing (including asynchronously spawned by<a name="line.507"></a> -<span class="sourceLineNo">508</span> // procId) and due to KillAndToggleBeforeStoreUpdate flag ProcedureExecutor is stopped before<a name="line.508"></a> -<span class="sourceLineNo">509</span> // store update. Let all pending procedures finish normally.<a name="line.509"></a> -<span class="sourceLineNo">510</span> if (!procExec.isRunning()) {<a name="line.510"></a> -<span class="sourceLineNo">511</span> LOG.warn("ProcedureExecutor not running, may have been stopped by pending procedure due to"<a name="line.511"></a> -<span class="sourceLineNo">512</span> + " KillAndToggleBeforeStoreUpdate flag.");<a name="line.512"></a> -<span class="sourceLineNo">513</span> ProcedureTestingUtility.setKillAndToggleBeforeStoreUpdate(procExec, false);<a name="line.513"></a> -<span class="sourceLineNo">514</span> restartMasterProcedureExecutor(procExec);<a name="line.514"></a> -<span class="sourceLineNo">515</span> ProcedureTestingUtility.waitNoProcedureRunning(procExec);<a name="line.515"></a> -<span class="sourceLineNo">516</span> }<a name="line.516"></a> -<span class="sourceLineNo">517</span> }<a name="line.517"></a> -<span class="sourceLineNo">518</span><a name="line.518"></a> -<span class="sourceLineNo">519</span> assertEquals(true, procExec.isRunning());<a name="line.519"></a> -<span class="sourceLineNo">520</span> ProcedureTestingUtility.assertIsAbortException(procExec.getResult(procId));<a name="line.520"></a> -<span class="sourceLineNo">521</span> }<a name="line.521"></a> -<span class="sourceLineNo">522</span><a name="line.522"></a> -<span class="sourceLineNo">523</span> /**<a name="line.523"></a> -<span class="sourceLineNo">524</span> * Execute the procedure up to "lastStep" and then the ProcedureExecutor<a name="line.524"></a> -<span class="sourceLineNo">525</span> * is restarted and an abort() is injected.<a name="line.525"></a> -<span class="sourceLineNo">526</span> * If the procedure implement abort() this should result in rollback being triggered.<a name="line.526"></a> -<span class="sourceLineNo">527</span> * At the end of this call the procedure should be finished and rolledback.<a name="line.527"></a> -<span class="sourceLineNo">528</span> * This method assert on the procedure being terminated with an AbortException.<a name="line.528"></a> -<span class="sourceLineNo">529</span> */<a name="line.529"></a> -<span class="sourceLineNo">530</span> public static void testRollbackRetriableFailure(<a name="line.530"></a> -<span class="sourceLineNo">531</span> final ProcedureExecutor<MasterProcedureEnv> procExec, final long procId,<a name="line.531"></a> -<span class="sourceLineNo">532</span> final int lastStep) throws Exception {<a name="line.532"></a> -<span class="sourceLineNo">533</span> // Execute up to last step<a name="line.533"></a> -<span class="sourceLineNo">534</span> testRecoveryAndDoubleExecution(procExec, procId, lastStep, false);<a name="line.534"></a> -<span class="sourceLineNo">535</span><a name="line.535"></a> -<span class="sourceLineNo">536</span> // execute the rollback<a name="line.536"></a> -<span class="sourceLineNo">537</span> testRestartWithAbort(procExec, procId);<a name="line.537"></a> +<span class="sourceLineNo">417</span> assertEquals(expectExecRunning, procExec.isRunning());<a name="line.417"></a> +<span class="sourceLineNo">418</span> }<a name="line.418"></a> +<span class="sourceLineNo">419</span><a name="line.419"></a> +<span class="sourceLineNo">420</span> /**<a name="line.420"></a> +<span class="sourceLineNo">421</span> * Run through all procedure flow states TWICE while also restarting<a name="line.421"></a> +<span class="sourceLineNo">422</span> * procedure executor at each step; i.e force a reread of procedure store.<a name="line.422"></a> +<span class="sourceLineNo">423</span> *<a name="line.423"></a> +<span class="sourceLineNo">424</span> *<p>It does<a name="line.424"></a> +<span class="sourceLineNo">425</span> * <ol><li>Execute step N - kill the executor before store update<a name="line.425"></a> +<span class="sourceLineNo">426</span> * <li>Restart executor/store<a name="line.426"></a> +<span class="sourceLineNo">427</span> * <li>Executes hook for each step twice<a name="line.427"></a> +<span class="sourceLineNo">428</span> * <li>Execute step N - and then save to store<a name="line.428"></a> +<span class="sourceLineNo">429</span> * </ol><a name="line.429"></a> +<span class="sourceLineNo">430</span> *<a name="line.430"></a> +<span class="sourceLineNo">431</span> *<p>This is a good test for finding state that needs persisting and steps that are not<a name="line.431"></a> +<span class="sourceLineNo">432</span> * idempotent. Use this version of the test when the order in which flow steps are executed is<a name="line.432"></a> +<span class="sourceLineNo">433</span> * not start to finish; where the procedure may vary the flow steps dependent on circumstance<a name="line.433"></a> +<span class="sourceLineNo">434</span> * found.<a name="line.434"></a> +<span class="sourceLineNo">435</span> * @see #testRecoveryAndDoubleExecution(ProcedureExecutor, long, int, boolean)<a name="line.435"></a> +<span class="sourceLineNo">436</span> */<a name="line.436"></a> +<span class="sourceLineNo">437</span> public static void testRecoveryAndDoubleExecution(<a name="line.437"></a> +<span class="sourceLineNo">438</span> final ProcedureExecutor<MasterProcedureEnv> procExec, final long procId, final StepHook hook)<a name="line.438"></a> +<span class="sourceLineNo">439</span> throws Exception {<a name="line.439"></a> +<span class="sourceLineNo">440</span> ProcedureTestingUtility.waitProcedure(procExec, procId);<a name="line.440"></a> +<span class="sourceLineNo">441</span> assertEquals(false, procExec.isRunning());<a name="line.441"></a> +<span class="sourceLineNo">442</span> for (int i = 0; !procExec.isFinished(procId); ++i) {<a name="line.442"></a> +<span class="sourceLineNo">443</span> LOG.info("Restart " + i + " exec state=" + procExec.getProcedure(procId));<a name="line.443"></a> +<span class="sourceLineNo">444</span> if (hook != null) {<a name="line.444"></a> +<span class="sourceLineNo">445</span> assertTrue(hook.execute(i));<a name="line.445"></a> +<span class="sourceLineNo">446</span> }<a name="line.446"></a> +<span class="sourceLineNo">447</span> restartMasterProcedureExecutor(procExec);<a name="line.447"></a> +<span class="sourceLineNo">448</span> ProcedureTestingUtility.waitProcedure(procExec, procId);<a name="line.448"></a> +<span class="sourceLineNo">449</span> }<a name="line.449"></a> +<span class="sourceLineNo">450</span> assertEquals(true, procExec.isRunning());<a name="line.450"></a> +<span class="sourceLineNo">451</span> ProcedureTestingUtility.assertProcNotFailed(procExec, procId);<a name="line.451"></a> +<span class="sourceLineNo">452</span> }<a name="line.452"></a> +<span class="sourceLineNo">453</span><a name="line.453"></a> +<span class="sourceLineNo">454</span> public static void testRecoveryAndDoubleExecution(<a name="line.454"></a> +<span class="sourceLineNo">455</span> final ProcedureExecutor<MasterProcedureEnv> procExec, final long procId) throws Exception {<a name="line.455"></a> +<span class="sourceLineNo">456</span> testRecoveryAndDoubleExecution(procExec, procId, null);<a name="line.456"></a> +<span class="sourceLineNo">457</span> }<a name="line.457"></a> +<span class="sourceLineNo">458</span><a name="line.458"></a> +<span class="sourceLineNo">459</span> /**<a name="line.459"></a> +<span class="sourceLineNo">460</span> * Hook which will be executed on each step<a name="line.460"></a> +<span class="sourceLineNo">461</span> */<a name="line.461"></a> +<span class="sourceLineNo">462</span> public interface StepHook{<a name="line.462"></a> +<span class="sourceLineNo">463</span> /**<a name="line.463"></a> +<span class="sourceLineNo">464</span> * @param step Step no. at which this will be executed<a name="line.464"></a> +<span class="sourceLineNo">465</span> * @return false if test should fail otherwise true<a name="line.465"></a> +<span class="sourceLineNo">466</span> * @throws IOException<a name="line.466"></a> +<span class="sourceLineNo">467</span> */<a name="line.467"></a> +<span class="sourceLineNo">468</span> boolean execute(int step) throws IOException;<a name="line.468"></a> +<span class="sourceLineNo">469</span> }<a name="line.469"></a> +<span class="sourceLineNo">470</span><a name="line.470"></a> +<span class="sourceLineNo">471</span> /**<a name="line.471"></a> +<span class="sourceLineNo">472</span> * Execute the procedure up to "lastStep" and then the ProcedureExecutor<a name="line.472"></a> +<span class="sourceLineNo">473</span> * is restarted and an abort() is injected.<a name="line.473"></a> +<span class="sourceLineNo">474</span> * If the procedure implement abort() this should result in rollback being triggered.<a name="line.474"></a> +<span class="sourceLineNo">475</span> * Each rollback step is called twice, by restarting the executor after every step.<a name="line.475"></a> +<span class="sourceLineNo">476</span> * At the end of this call the procedure should be finished and rolledback.<a name="line.476"></a> +<span class="sourceLineNo">477</span> * This method assert on the procedure being terminated with an AbortException.<a name="line.477"></a> +<span class="sourceLineNo">478</span> */<a name="line.478"></a> +<span class="sourceLineNo">479</span> public static void testRollbackAndDoubleExecution(<a name="line.479"></a> +<span class="sourceLineNo">480</span> final ProcedureExecutor<MasterProcedureEnv> procExec, final long procId,<a name="line.480"></a> +<span class="sourceLineNo">481</span> final int lastStep) throws Exception {<a name="line.481"></a> +<span class="sourceLineNo">482</span> testRollbackAndDoubleExecution(procExec, procId, lastStep, false);<a name="line.482"></a> +<span class="sourceLineNo">483</span> }<a name="line.483"></a> +<span class="sourceLineNo">484</span><a name="line.484"></a> +<span class="sourceLineNo">485</span> public static void testRollbackAndDoubleExecution(<a name="line.485"></a> +<span class="sourceLineNo">486</span> final ProcedureExecutor<MasterProcedureEnv> procExec, final long procId,<a name="line.486"></a> +<span class="sourceLineNo">487</span> final int lastStep, boolean waitForAsyncProcs) throws Exception {<a name="line.487"></a> +<span class="sourceLineNo">488</span> // Execute up to last step<a name="line.488"></a> +<span class="sourceLineNo">489</span> testRecoveryAndDoubleExecution(procExec, procId, lastStep, false);<a name="line.489"></a> +<span class="sourceLineNo">490</span><a name="line.490"></a> +<span class="sourceLineNo">491</span> // Restart the executor and rollback the step twice<a name="line.491"></a> +<span class="sourceLineNo">492</span> // rollback step N - kill before store update<a name="line.492"></a> +<span class="sourceLineNo">493</span> // restart executor/store<a name="line.493"></a> +<span class="sourceLineNo">494</span> // rollback step N - save on store<a name="line.494"></a> +<span class="sourceLineNo">495</span> InjectAbortOnLoadListener abortListener = new InjectAbortOnLoadListener(procExec);<a name="line.495"></a> +<span class="sourceLineNo">496</span> abortListener.addProcId(procId);<a name="line.496"></a> +<span class="sourceLineNo">497</span> procExec.registerListener(abortListener);<a name="line.497"></a> +<span class="sourceLineNo">498</span> try {<a name="line.498"></a> +<span class="sourceLineNo">499</span> for (int i = 0; !procExec.isFinished(procId); ++i) {<a name="line.499"></a> +<span class="sourceLineNo">500</span> LOG.info("Restart " + i + " rollback state: " + procExec.getProcedure(procId));<a name="line.500"></a> +<span class="sourceLineNo">501</span> ProcedureTestingUtility.assertProcNotYetCompleted(procExec, procId);<a name="line.501"></a> +<span class="sourceLineNo">502</span> restartMasterProcedureExecutor(procExec);<a name="line.502"></a> +<span class="sourceLineNo">503</span> ProcedureTestingUtility.waitProcedure(procExec, procId);<a name="line.503"></a> +<span class="sourceLineNo">504</span> }<a name="line.504"></a> +<span class="sourceLineNo">505</span> } finally {<a name="line.505"></a> +<span class="sourceLineNo">506</span> assertTrue(procExec.unregisterListener(abortListener));<a name="line.506"></a> +<span class="sourceLineNo">507</span> }<a name="line.507"></a> +<span class="sourceLineNo">508</span><a name="line.508"></a> +<span class="sourceLineNo">509</span> if (waitForAsyncProcs) {<a name="line.509"></a> +<span class="sourceLineNo">510</span> // Sometimes there are other procedures still executing (including asynchronously spawned by<a name="line.510"></a> +<span class="sourceLineNo">511</span> // procId) and due to KillAndToggleBeforeStoreUpdate flag ProcedureExecutor is stopped before<a name="line.511"></a> +<span class="sourceLineNo">512</span> // store update. Let all pending procedures finish normally.<a name="line.512"></a> +<span class="sourceLineNo">513</span> if (!procExec.isRunning()) {<a name="line.513"></a> +<span class="sourceLineNo">514</span> LOG.warn("ProcedureExecutor not running, may have been stopped by pending procedure due to"<a name="line.514"></a> +<span class="sourceLineNo">515</span> + " KillAndToggleBeforeStoreUpdate flag.");<a name="line.515"></a> +<span class="sourceLineNo">516</span> ProcedureTestingUtility.setKillAndToggleBeforeStoreUpdate(procExec, false);<a name="line.516"></a> +<span class="sourceLineNo">517</span> restartMasterProcedureExecutor(procExec);<a name="line.517"></a> +<span class="sourceLineNo">518</span> ProcedureTestingUtility.waitNoProcedureRunning(procExec);<a name="line.518"></a> +<span class="sourceLineNo">519</span> }<a name="line.519"></a> +<span class="sourceLineNo">520</span> }<a name="line.520"></a> +<span class="sourceLineNo">521</span><a name="line.521"></a> +<span class="sourceLineNo">522</span> assertEquals(true, procExec.isRunning());<a name="line.522"></a> +<span class="sourceLineNo">523</span> ProcedureTestingUtility.assertIsAbortException(procExec.getResult(procId));<a name="line.523"></a> +<span class="sourceLineNo">524</span> }<a name="line.524"></a> +<span class="sourceLineNo">525</span><a name="line.525"></a> +<span class="sourceLineNo">526</span> /**<a name="line.526"></a> +<span class="sourceLineNo">527</span> * Execute the procedure up to "lastStep" and then the ProcedureExecutor<a name="line.527"></a> +<span class="sourceLineNo">528</span> * is restarted and an abort() is injected.<a name="line.528"></a> +<span class="sourceLineNo">529</span> * If the procedure implement abort() this should result in rollback being triggered.<a name="line.529"></a> +<span class="sourceLineNo">530</span> * At the end of this call the procedure should be finished and rolledback.<a name="line.530"></a> +<span class="sourceLineNo">531</span> * This method assert on the procedure being terminated with an AbortException.<a name="line.531"></a> +<span class="sourceLineNo">532</span> */<a name="line.532"></a> +<span class="sourceLineNo">533</span> public static void testRollbackRetriableFailure(<a name="line.533"></a> +<span class="sourceLineNo">534</span> final ProcedureExecutor<MasterProcedureEnv> procExec, final long procId,<a name="line.534"></a> +<span class="sourceLineNo">535</span> final int lastStep) throws Exception {<a name="line.535"></a> +<span class="sourceLineNo">536</span> // Execute up to last step<a name="line.536"></a> +<span class="sourceLineNo">537</span> testRecoveryAndDoubleExecution(procExec, procId, lastStep, false);<a name="line.537"></a> <span class="sourceLineNo">538</span><a name="line.538"></a> -<span class="sourceLineNo">539</span> assertEquals(true, procExec.isRunning());<a name="line.539"></a> -<span class="sourceLineNo">540</span> ProcedureTestingUtility.assertIsAbortException(procExec.getResult(procId));<a name="line.540"></a> -<span class="sourceLineNo">541</span> }<a name="line.541"></a> -<span class="sourceLineNo">542</span><a name="line.542"></a> -<span class="sourceLineNo">543</span> /**<a name="line.543"></a> -<span class="sourceLineNo">544</span> * Restart the ProcedureExecutor and inject an abort to the specified procedure.<a name="line.544"></a> -<span class="sourceLineNo">545</span> * If the procedure implement abort() this should result in rollback being triggered.<a name="line.545"></a> -<span class="sourceLineNo">546</span> * At the end of this call the procedure should be finished and rolledback, if abort is implemnted<a name="line.546"></a> -<span class="sourceLineNo">547</span> */<a name="line.547"></a> -<span class="sourceLineNo">548</span> public static void testRestartWithAbort(ProcedureExecutor<MasterProcedureEnv> procExec,<a name="line.548"></a> -<span class="sourceLineNo">549</span> long procId) throws Exception {<a name="line.549"></a> -<span class="sourceLineNo">550</span> ProcedureTestingUtility.setKillAndToggleBeforeStoreUpdate(procExec, false);<a name="line.550"></a> -<span class="sourceLineNo">551</span> InjectAbortOnLoadListener abortListener = new InjectAbortOnLoadListener(procExec);<a name="line.551"></a> -<span class="sourceLineNo">552</span> abortListener.addProcId(procId);<a name="line.552"></a> -<span class="sourceLineNo">553</span> procExec.registerListener(abortListener);<a name="line.553"></a> -<span class="sourceLineNo">554</span> try {<a name="line.554"></a> -<span class="sourceLineNo">555</span> ProcedureTestingUtility.assertProcNotYetCompleted(procExec, procId);<a name="line.555"></a> -<span class="sourceLineNo">556</span> LOG.info("Restart and rollback procId=" + procId);<a name="line.556"></a> -<span class="sourceLineNo">557</span> restartMasterProcedureExecutor(procExec);<a name="line.557"></a> -<span class="sourceLineNo">558</span> ProcedureTestingUtility.waitProcedure(procExec, procId);<a name="line.558"></a> -<span class="sourceLineNo">559</span> } finally {<a name="line.559"></a> -<span class="sourceLineNo">560</span> assertTrue(procExec.unregisterListener(abortListener));<a name="line.560"></a> -<span class="sourceLineNo">561</span> }<a name="line.561"></a> -<span class="sourceLineNo">562</span> }<a name="line.562"></a> -<span class="sourceLineNo">563</span><a name="line.563"></a> -<span class="sourceLineNo">564</span> public static class InjectAbortOnLoadListener<a name="line.564"></a> -<span class="sourceLineNo">565</span> implements ProcedureExecutor.ProcedureExecutorListener {<a name="line.565"></a> -<span class="sourceLineNo">566</span> private final ProcedureExecutor<MasterProcedureEnv> procExec;<a name="line.566"></a> -<span class="sourceLineNo">567</span> private TreeSet<Long> procsToAbort = null;<a name="line.567"></a> -<span class="sourceLineNo">568</span><a name="line.568"></a> -<span class="sourceLineNo">569</span> public InjectAbortOnLoadListener(final ProcedureExecutor<MasterProcedureEnv> procExec) {<a name="line.569"></a> -<span class="sourceLineNo">570</span> this.procExec = procExec;<a name="line.570"></a> -<span class="sourceLineNo">571</span> }<a name="line.571"></a> -<span class="sourceLineNo">572</span><a name="line.572"></a> -<span class="sourceLineNo">573</span> public void addProcId(long procId) {<a name="line.573"></a> -<span class="sourceLineNo">574</span> if (procsToAbort == null) {<a name="line.574"></a> -<span class="sourceLineNo">575</span> procsToAbort = new TreeSet<>();<a name="line.575"></a> -<span class="sourceLineNo">576</span> }<a name="line.576"></a> -<span class="sourceLineNo">577</span> procsToAbort.add(procId);<a name="line.577"></a> -<span class="sourceLineNo">578</span> }<a name="line.578"></a> -<span class="sourceLineNo">579</span><a name="line.579"></a> -<span class="sourceLineNo">580</span> @Override<a name="line.580"></a> -<span class="sourceLineNo">581</span> public void procedureLoaded(long procId) {<a name="line.581"></a> -<span class="sourceLineNo">582</span> if (procsToAbort != null && !procsToAbort.contains(procId)) {<a name="line.582"></a> -<span class="sourceLineNo">583</span> return;<a name="line.583"></a> -<span class="sourceLineNo">584</span> }<a name="line.584"></a> -<span class="sourceLineNo">585</span> procExec.abort(procId);<a name="line.585"></a> -<span class="sourceLineNo">586</span> }<a name="line.586"></a> -<span class="sourceLineNo">587</span><a name="line.587"></a> -<span class="sourceLineNo">588</span> @Override<a name="line.588"></a> -<span class="sourceLineNo">589</span> public void procedureAdded(long procId) { /* no-op */ }<a name="line.589"></a> +<span class="sourceLineNo">539</span> // execute the rollback<a name="line.539"></a> +<span class="sourceLineNo">540</span> testRestartWithAbort(procExec, procId);<a name="line.540"></a> +<span class="sourceLineNo">541</span><a name="line.541"></a> +<span class="sourceLineNo">542</span> assertEquals(true, procExec.isRunning());<a name="line.542"></a> +<span class="sourceLineNo">543</span> ProcedureTestingUtility.assertIsAbortException(procExec.getResult(procId));<a name="line.543"></a> +<span class="sourceLineNo">544</span> }<a name="line.544"></a> +<span class="sourceLineNo">545</span><a name="line.545"></a> +<span class="sourceLineNo">546</span> /**<a name="line.546"></a> +<span class="sourceLineNo">547</span> * Restart the ProcedureExecutor and inject an abort to the specified procedure.<a name="line.547"></a> +<span class="sourceLineNo">548</span> * If the procedure implement abort() this should result in rollback being triggered.<a name="line.548"></a> +<span class="sourceLineNo">549</span> * At the end of this call the procedure should be finished and rolledback, if abort is implemnted<a name="line.549"></a> +<span class="sourceLineNo">550</span> */<a name="line.550"></a> +<span class="sourceLineNo">551</span> public static void testRestartWithAbort(ProcedureExecutor<MasterProcedureEnv> procExec,<a name="line.551"></a> +<span class="sourceLineNo">552</span> long procId) throws Exception {<a name="line.552"></a> +<span class="sourceLineNo">553</span> ProcedureTestingUtility.setKillAndToggleBeforeStoreUpdate(procExec, false);<a name="line.553"></a> +<span class="sourceLineNo">554</span> InjectAbortOnLoadListener abortListener = new InjectAbortOnLoadListener(procExec);<a name="line.554"></a> +<span class="sourceLineNo">555</span> abortListener.addProcId(procId);<a name="line.555"></a> +<span class="sourceLineNo">556</span> procExec.registerListener(abortListener);<a name="line.556"></a> +<span class="sourceLineNo">557</span> try {<a name="line.557"></a> +<span class="sourceLineNo">558</span> ProcedureTestingUtility.assertProcNotYetCompleted(procExec, procId);<a name="line.558"></a> +<span class="sourceLineNo">559</span> LOG.info("Restart and rollback procId=" + procId);<a name="line.559"></a> +<span class="sourceLineNo">560</span> restartMasterProcedureExecutor(procExec);<a name="line.560"></a> +<span class="sourceLineNo">561</span> ProcedureTestingUtility.waitProcedure(procExec, procId);<a name="line.561"></a> +<span class="sourceLineNo">562</span> } finally {<a name="line.562"></a> +<span class="sourceLineNo">563</span> assertTrue(procExec.unregisterListener(abortListener));<a name="line.563"></a> +<span class="sourceLineNo">564</span> }<a name="line.564"></a> +<span class="sourceLineNo">565</span> }<a name="line.565"></a> +<span class="sourceLineNo">566</span><a name="line.566"></a> +<span class="sourceLineNo">567</span> public static class InjectAbortOnLoadListener<a name="line.567"></a> +<span class="sourceLineNo">568</span> implements ProcedureExecutor.ProcedureExecutorListener {<a name="line.568"></a> +<span class="sourceLineNo">569</span> private final ProcedureExecutor<MasterProcedureEnv> procExec;<a name="line.569"></a> +<span class="sourceLineNo">570</span> private TreeSet<Long> procsToAbort = null;<a name="line.570"></a> +<span class="sourceLineNo">571</span><a name="line.571"></a> +<span class="sourceLineNo">572</span> public InjectAbortOnLoadListener(final ProcedureExecutor<MasterProcedureEnv> procExec) {<a name="line.572"></a> +<span class="sourceLineNo">573</span> this.procExec = procExec;<a name="line.573"></a> +<span class="sourceLineNo">574</span> }<a name="line.574"></a> +<span class="sourceLineNo">575</span><a name="line.575"></a> +<span class="sourceLineNo">576</span> public void addProcId(long procId) {<a name="line.576"></a> +<span class="sourceLineNo">577</span> if (procsToAbort == null) {<a name="line.577"></a> +<span class="sourceLineNo">578</span> procsToAbort = new TreeSet<>();<a name="line.578"></a> +<span class="sourceLineNo">579</span> }<a name="line.579"></a> +<span class="sourceLineNo">580</span> procsToAbort.add(procId);<a name="line.580"></a> +<span class="sourceLineNo">581</span> }<a name="line.581"></a> +<span class="sourceLineNo">582</span><a name="line.582"></a> +<span class="sourceLineNo">583</span> @Override<a name="line.583"></a> +<span class="sourceLineNo">584</span> public void procedureLoaded(long procId) {<a name="line.584"></a> +<span class="sourceLineNo">585</span> if (procsToAbort != null && !procsToAbort.contains(procId)) {<a name="line.585"></a> +<span class="sourceLineNo">586</span> return;<a name="line.586"></a> +<span class="sourceLineNo">587</span> }<a name="line.587"></a> +<span class="sourceLineNo">588</span> procExec.abort(procId);<a name="line.588"></a> +<span class="sourceLineNo">589</span> }<a name="line.589"></a> <span class="sourceLineNo">590</span><a name="line.590"></a> <span class="sourceLineNo">591</span> @Override<a name="line.591"></a> -<span class="sourceLineNo">592</span> public void procedureFinished(long procId) { /* no-op */ }<a name="line.592"></a> -<span class="sourceLineNo">593</span> }<a name="line.593"></a> -<span class="sourceLineNo">594</span>}<a name="line.594"></a> +<span class="sourceLineNo">592</span> public void procedureAdded(long procId) { /* no-op */ }<a name="line.592"></a> +<span class="sourceLineNo">593</span><a name="line.593"></a> +<span class="sourceLineNo">594</span> @Override<a name="line.594"></a> +<span class="sourceLineNo">595</span> public void procedureFinished(long procId) { /* no-op */ }<a name="line.595"></a> +<span class="sourceLineNo">596</span> }<a name="line.596"></a> +<span class="sourceLineNo">597</span>}<a name="line.597"></a>