blob: a7c6c6ddb92648ada923f62b241d8f8e9556e35e [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.phoenix.end2end;
import org.apache.phoenix.end2end.index.IndexTestUtil;
import org.apache.phoenix.thirdparty.com.google.common.collect.Maps;
import org.apache.commons.lang3.StringUtils;
import org.apache.hadoop.hbase.TableName;
import org.apache.hadoop.hbase.client.Admin;
import org.apache.hadoop.hbase.client.TableDescriptor;
import org.apache.phoenix.end2end.index.IndexCoprocIT;
import org.apache.phoenix.hbase.index.IndexRegionObserver;
import org.apache.phoenix.hbase.index.Indexer;
import org.apache.phoenix.index.GlobalIndexChecker;
import org.apache.phoenix.jdbc.PhoenixConnection;
import org.apache.phoenix.mapreduce.index.IndexTool;
import org.apache.phoenix.mapreduce.index.IndexUpgradeTool;
import org.apache.phoenix.query.BaseTest;
import org.apache.phoenix.query.ConnectionQueryServices;
import org.apache.phoenix.query.QueryServices;
import org.apache.phoenix.util.MetaDataUtil;
import org.apache.phoenix.util.PhoenixRuntime;
import org.apache.phoenix.util.PropertiesUtil;
import org.apache.phoenix.util.ReadOnlyProps;
import org.apache.phoenix.util.SchemaUtil;
import org.junit.Assert;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import org.junit.experimental.categories.Category;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized.Parameters;
import org.junit.runners.Parameterized;
import org.mockito.ArgumentCaptor;
import org.mockito.Captor;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.MockitoAnnotations;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.Arrays;
import java.util.Collection;
import java.util.Map;
import java.util.Properties;
import java.util.UUID;
import static org.apache.phoenix.mapreduce.index.IndexUpgradeTool.ROLLBACK_OP;
import static org.apache.phoenix.mapreduce.index.IndexUpgradeTool.UPGRADE_OP;
import static org.apache.phoenix.query.QueryServices.DROP_METADATA_ATTRIB;
import static org.apache.phoenix.util.TestUtil.TEST_PROPERTIES;
import static org.mockito.Mockito.times;
@RunWith(Parameterized.class)
@Category(NeedsOwnMiniClusterTest.class)
public class ParameterizedIndexUpgradeToolIT extends BaseTest {
private static final String [] INDEXES_LIST = new String[8];
private static final String [] INDEXES_LIST_NAMESPACE = new String[8];
private static final String [] INDEXES_LIST_SIMPLIFIED = new String[1];
private static final String [] INDEXES_LIST_NAMESPACE_SIMPLIFIED = new String[1];
private static final String [] TRANSACTIONAL_INDEXES_LIST = new String[2];
private static final String [] TABLE_LIST = new String[4];
private static final String [] TABLE_LIST_NAMESPACE = new String[4];
private static final String [] TABLE_LIST_SIMPLIFIED = new String[1];
private static final String [] TABLE_LIST_NAMESPACE_SIMPLIFIED = new String[1];
private static final String [] TRANSACTIONAL_TABLE_LIST = new String[1];
private static String INPUT_LIST = "";
private static final String INPUT_FILE = "/tmp/input_file_index_upgrade.csv";
private static Map<String, String> serverProps = Maps.newHashMapWithExpectedSize(1),
clientProps = Maps.newHashMapWithExpectedSize(1);
private final boolean mutable;
private final boolean upgrade;
private final boolean isNamespaceEnabled;
private final boolean rebuild;
private StringBuilder optionsBuilder;
private String tableDDLOptions;
private Connection conn;
private Connection connTenant;
private Admin admin;
private IndexUpgradeTool iut;
private static String tmpDir = System.getProperty("java.io.tmpdir");;
@Mock
private IndexTool indexToolMock;
@Captor
private ArgumentCaptor<String []> argCapture;
@BeforeClass
public static synchronized void saveTmp () throws Exception {
tmpDir = System.getProperty("java.io.tmpdir");
}
@Before
public void setup () throws Exception {
MockitoAnnotations.initMocks(this);
optionsBuilder = new StringBuilder();
setClusterProperties();
setUpTestDriver(new ReadOnlyProps(serverProps.entrySet().iterator()),
new ReadOnlyProps(clientProps.entrySet().iterator()));
conn = DriverManager.getConnection(getUrl(), new Properties());
conn.setAutoCommit(true);
String tenantId = generateUniqueName();
Properties props = PropertiesUtil.deepCopy(TEST_PROPERTIES);
props.setProperty(PhoenixRuntime.TENANT_ID_ATTRIB, tenantId);
connTenant = DriverManager.getConnection(getUrl(), props);
ConnectionQueryServices queryServices = conn.unwrap(PhoenixConnection.class)
.getQueryServices();
admin = queryServices.getAdmin();
if (!mutable) {
optionsBuilder.append(" IMMUTABLE_ROWS=true");
}
tableDDLOptions = optionsBuilder.toString();
}
private void setClusterProperties() {
// we need to destroy the cluster if it was initiated using property as true
if (Boolean.toString(upgrade).equals(clientProps
.get(QueryServices.INDEX_REGION_OBSERVER_ENABLED_ATTRIB))
|| Boolean.toString(!isNamespaceEnabled).equals(serverProps
.get(QueryServices.IS_NAMESPACE_MAPPING_ENABLED))) {
tearDownMiniCluster(1);
System.setProperty("java.io.tmpdir", tmpDir);
}
//setting up properties for namespace
clientProps.put(QueryServices.IS_NAMESPACE_MAPPING_ENABLED,
Boolean.toString(isNamespaceEnabled));
clientProps.put(QueryServices.IS_SYSTEM_TABLE_MAPPED_TO_NAMESPACE,
Boolean.toString(isNamespaceEnabled));
clientProps.put(DROP_METADATA_ATTRIB, Boolean.toString(true));
serverProps.putAll(clientProps);
//To mimic the upgrade/rollback scenario, so that table creation uses old/new design
clientProps.put(QueryServices.INDEX_REGION_OBSERVER_ENABLED_ATTRIB,
Boolean.toString(!upgrade));
}
private void prepareFullSetup() throws SQLException {
clearOldTableNames();
String mockTableOne = "TEST." + generateUniqueName();
TABLE_LIST[0] = mockTableOne;
String mockTableTwo = "TEST1." + generateUniqueName();
TABLE_LIST[1] = mockTableTwo;
String mockTableThree = "TEST." + generateUniqueName();
TABLE_LIST[2] = mockTableThree;
String multiTenantTable = "TEST." + generateUniqueName();
TABLE_LIST[3] = multiTenantTable;
INPUT_LIST = StringUtils.join(TABLE_LIST, ",");
if (isNamespaceEnabled) {
TABLE_LIST_NAMESPACE[0] = mockTableOne.replace(".", ":");
TABLE_LIST_NAMESPACE[1] = mockTableTwo.replace(".", ":");
TABLE_LIST_NAMESPACE[2] = mockTableThree.replace(".", ":");
TABLE_LIST_NAMESPACE[3] = multiTenantTable.replace(".", ":");
conn.createStatement().execute("CREATE SCHEMA IF NOT EXISTS TEST");
conn.createStatement().execute("CREATE SCHEMA IF NOT EXISTS TEST1");
}
conn.createStatement().execute("CREATE TABLE " + mockTableOne + " (id bigint NOT NULL "
+ "PRIMARY KEY, a.name varchar, sal bigint, address varchar)" + tableDDLOptions);
conn.createStatement().execute("CREATE TABLE "+ mockTableTwo + " (id bigint NOT NULL "
+ "PRIMARY KEY, name varchar, city varchar, phone bigint)" + tableDDLOptions);
conn.createStatement().execute("CREATE TABLE " + mockTableThree + " (id bigint NOT NULL "
+ "PRIMARY KEY, name varchar, age bigint)" + tableDDLOptions);
String
createTblStr =
"CREATE TABLE " + multiTenantTable + " (TENANT_ID VARCHAR(15) NOT NULL,ID INTEGER NOT NULL"
+ ", NAME VARCHAR, CONSTRAINT PK_1 PRIMARY KEY (TENANT_ID, ID)) MULTI_TENANT=true";
conn.createStatement().execute(createTblStr);
String transactTable = generateUniqueName();
TRANSACTIONAL_TABLE_LIST[0] = transactTable;
conn.createStatement().execute("CREATE TABLE " + transactTable + " (id bigint NOT NULL "
+ "PRIMARY KEY, a.name varchar, sal bigint, address varchar) "
+ " TRANSACTIONAL=true, TRANSACTION_PROVIDER='OMID' "
+ ((tableDDLOptions.trim().length() > 0) ? "," : "") + tableDDLOptions);
String mockOneViewOne = "TEST." + generateUniqueName();
String mockOneViewTwo = "TEST." + generateUniqueName();
String mockTwoViewOne = "TEST1." + generateUniqueName();
String transactView = generateUniqueName();
//views
conn.createStatement().execute("CREATE VIEW " + mockOneViewOne + " (view_column varchar) "
+ "AS SELECT * FROM " + mockTableOne + " WHERE a.name = 'a'");
conn.createStatement().execute("CREATE VIEW " + mockOneViewTwo + " (view_column varchar,"
+ " zip varchar) AS SELECT * FROM " + mockTableOne + " WHERE a.name = 'a'");
conn.createStatement().execute("CREATE VIEW " + mockTwoViewOne + " (view_column varchar,"
+ " state varchar) AS SELECT * FROM " + mockTableTwo + " WHERE name = 'c'");
conn.createStatement().execute("CREATE VIEW " + transactView + " (view_column varchar,"
+ " state varchar) AS SELECT * FROM " + transactTable + " WHERE name = 'c'");
//view-indexes
String indexOneMockOneViewOne = generateUniqueName();
String indexTwoMockOneViewTwo = generateUniqueName();
String indexOneMockTwoViewTwo = generateUniqueName();
String indexThreeMockOneViewOne = generateUniqueName();
String transactViewIndex = generateUniqueName();
INDEXES_LIST[6] = MetaDataUtil.getViewIndexPhysicalName(mockTableOne);
INDEXES_LIST[7] = MetaDataUtil.getViewIndexPhysicalName(mockTableTwo);
if (isNamespaceEnabled) {
INDEXES_LIST_NAMESPACE[6] =
MetaDataUtil.getViewIndexPhysicalName(TABLE_LIST_NAMESPACE[0]);
INDEXES_LIST_NAMESPACE[7] =
MetaDataUtil.getViewIndexPhysicalName(TABLE_LIST_NAMESPACE[1]);
}
conn.createStatement().execute("CREATE INDEX " + indexOneMockOneViewOne + " ON "
+ mockOneViewOne + " (view_column)");
conn.createStatement().execute("CREATE INDEX " + indexTwoMockOneViewTwo + " ON "
+ mockOneViewTwo + " (zip)");
conn.createStatement().execute("CREATE INDEX " + indexOneMockTwoViewTwo + " ON "
+ mockTwoViewOne + " (state, city)");
conn.createStatement().execute("CREATE INDEX " + indexThreeMockOneViewOne
+ " ON " + mockOneViewOne + " (view_column)");
conn.createStatement().execute("CREATE INDEX " + transactViewIndex + " ON " +
transactView + " (view_column)");
//indexes
String indexOneMockOne = generateUniqueName();
String indexTwoMockOne = generateUniqueName();
String indexOneMockTwo = generateUniqueName();
String indexTwoMockTwo = generateUniqueName();
String indexThreeMockTwo = generateUniqueName();
String indexThreeMockThree = generateUniqueName();
String transactIndex = generateUniqueName();
TRANSACTIONAL_INDEXES_LIST[0] = transactIndex;
TRANSACTIONAL_INDEXES_LIST[1] = MetaDataUtil.getViewIndexPhysicalName(transactTable);
if (isNamespaceEnabled) {
INDEXES_LIST_NAMESPACE[0] = "TEST:" + indexOneMockOne;
INDEXES_LIST_NAMESPACE[1] = "TEST:" + indexTwoMockOne;
INDEXES_LIST_NAMESPACE[2] = "TEST1:" + indexOneMockTwo;
INDEXES_LIST_NAMESPACE[3] = "TEST1:" + indexTwoMockTwo;
INDEXES_LIST_NAMESPACE[4] = "TEST1:" + indexThreeMockTwo;
INDEXES_LIST_NAMESPACE[5] = "TEST:" + indexThreeMockThree;
} else {
INDEXES_LIST[0] = "TEST." + indexOneMockOne;
INDEXES_LIST[1] = "TEST." + indexTwoMockOne;
INDEXES_LIST[2] = "TEST1." + indexOneMockTwo;
INDEXES_LIST[3] = "TEST1." + indexTwoMockTwo;
INDEXES_LIST[4] = "TEST1." + indexThreeMockTwo;
INDEXES_LIST[5] = "TEST." + indexThreeMockThree;
}
conn.createStatement().execute("CREATE INDEX " + indexOneMockOne + " ON " + mockTableOne +
" (sal, a.name)");
conn.createStatement().execute("CREATE INDEX " + indexTwoMockOne + " ON " + mockTableOne
+ " (a.name)");
conn.createStatement().execute("CREATE INDEX " + indexOneMockTwo + " ON " + mockTableTwo
+ " (city)");
conn.createStatement().execute("CREATE INDEX " + indexTwoMockTwo + " ON " + mockTableTwo
+ " (phone)");
conn.createStatement().execute("CREATE INDEX " + indexThreeMockTwo + " ON " +
"" + mockTableTwo + " (name)");
conn.createStatement().execute("CREATE INDEX " + indexThreeMockThree + " ON " +
mockTableThree + " (age, name)");
conn.createStatement().execute("CREATE INDEX " + transactIndex + " ON " + transactTable +
" (sal)");
// Tenant ones
String tenantView = "TEST." + generateUniqueName();
String tenantViewIndex = generateUniqueName();
connTenant.createStatement().execute(
"CREATE VIEW " + tenantView + " AS SELECT * FROM " + multiTenantTable);
connTenant.createStatement().execute("CREATE INDEX " + tenantViewIndex + " ON "
+ tenantView + " (NAME)");
conn.createStatement().execute("ALTER INDEX " + indexTwoMockOneViewTwo + " ON "
+ mockOneViewOne + " DISABLE");
connTenant.createStatement().execute("ALTER INDEX " + tenantViewIndex + " ON " +
tenantView + " DISABLE");
conn.createStatement().execute("ALTER INDEX " + indexTwoMockOne + " ON " + mockTableOne +
" DISABLE");
iut = new IndexUpgradeTool(upgrade ? UPGRADE_OP : ROLLBACK_OP, INPUT_LIST,
null, "/tmp/index_upgrade_" + UUID.randomUUID().toString(),
true, indexToolMock, rebuild);
iut.setConf(getUtility().getConfiguration());
iut.setTest(true);
}
private void clearOldTableNames() {
Arrays.fill(TABLE_LIST, null);
Arrays.fill(TABLE_LIST_NAMESPACE, null);
Arrays.fill(TABLE_LIST_SIMPLIFIED, null);
Arrays.fill(TABLE_LIST_NAMESPACE_SIMPLIFIED, null);
Arrays.fill(INDEXES_LIST, null);
Arrays.fill(INDEXES_LIST_NAMESPACE, null);
Arrays.fill(INDEXES_LIST_SIMPLIFIED, null);
Arrays.fill(INDEXES_LIST_NAMESPACE_SIMPLIFIED, null);
Arrays.fill(TRANSACTIONAL_INDEXES_LIST, null);
Arrays.fill(TRANSACTIONAL_TABLE_LIST, null);
}
private void prepareSimplifiedSetup() throws SQLException {
clearOldTableNames();
String mockTableOne = "TEST." + generateUniqueName();
INPUT_LIST = mockTableOne;
if (isNamespaceEnabled) {
conn.createStatement().execute("CREATE SCHEMA IF NOT EXISTS TEST");
conn.createStatement().execute("CREATE SCHEMA IF NOT EXISTS TEST1");
TABLE_LIST_NAMESPACE_SIMPLIFIED[0] = mockTableOne.replace(".", ":");
} else {
TABLE_LIST_SIMPLIFIED[0] = mockTableOne;
}
conn.createStatement().execute("CREATE TABLE " + mockTableOne + " (id bigint NOT NULL "
+ "PRIMARY KEY, a.name varchar, sal bigint, address varchar)" + tableDDLOptions);
conn.commit();
String indexOneMockOne = generateUniqueName();
if (isNamespaceEnabled) {
INDEXES_LIST_NAMESPACE_SIMPLIFIED[0] = "TEST:" + indexOneMockOne;
} else {
INDEXES_LIST_SIMPLIFIED[0] = "TEST." + indexOneMockOne;
}
conn.createStatement().execute("CREATE INDEX " + indexOneMockOne + " ON " + mockTableOne +
" (sal, a.name)");
conn.commit();
iut = new IndexUpgradeTool(upgrade ? UPGRADE_OP : ROLLBACK_OP, INPUT_LIST,
null, "/tmp/index_upgrade_" + UUID.randomUUID().toString(),
true, indexToolMock, rebuild);
iut.setConf(getUtility().getConfiguration());
iut.setTest(true);
}
private void validate(boolean pre, boolean isSimplified) throws IOException {
String [] indexList;
String [] tableList;
if (isSimplified) {
if (isNamespaceEnabled) {
indexList = INDEXES_LIST_NAMESPACE_SIMPLIFIED;
tableList = TABLE_LIST_NAMESPACE_SIMPLIFIED;
} else {
indexList = INDEXES_LIST_SIMPLIFIED;
tableList = TABLE_LIST_SIMPLIFIED;
}
} else {
if (isNamespaceEnabled) {
indexList = INDEXES_LIST_NAMESPACE;
tableList = TABLE_LIST_NAMESPACE;
} else {
indexList = INDEXES_LIST;
tableList = TABLE_LIST;
}
}
if (pre) {
if (upgrade) {
checkOldIndexingCoprocessors(indexList,tableList);
} else {
checkNewIndexingCoprocessors(indexList,tableList);
}
} else {
if (upgrade) {
checkNewIndexingCoprocessors(indexList,tableList);
} else {
checkOldIndexingCoprocessors(indexList,tableList);
}
}
}
private void checkNewIndexingCoprocessors(String [] indexList, String [] tableList)
throws IOException {
if (mutable) {
for (String table : tableList) {
if (table != null) {
TableDescriptor indexDesc = admin.getDescriptor(TableName.valueOf(table));
Assert.assertTrue("Can't find IndexRegionObserver for " + table,
indexDesc.hasCoprocessor(IndexRegionObserver.class.getName()));
Assert.assertFalse("Found Indexer on " + table,
indexDesc.hasCoprocessor(Indexer.class.getName()));
IndexTestUtil.assertCoprocConfig(indexDesc, IndexRegionObserver.class.getName(),
IndexCoprocIT.INDEX_REGION_OBSERVER_CONFIG);
}
}
}
for (String index : indexList) {
if (index != null) {
TableDescriptor indexDesc = admin.getDescriptor(TableName.valueOf(index));
Assert.assertTrue("Couldn't find GlobalIndexChecker on " + index,
indexDesc.hasCoprocessor(GlobalIndexChecker.class.getName()));
IndexTestUtil.assertCoprocConfig(indexDesc, GlobalIndexChecker.class.getName(),
IndexCoprocIT.GLOBAL_INDEX_CHECKER_CONFIG);
}
}
// Transactional indexes should not have new coprocessors
for (String index : TRANSACTIONAL_INDEXES_LIST) {
if (index != null) {
Assert.assertFalse("Found GlobalIndexChecker on transactional index " + index,
admin.getDescriptor(TableName.valueOf(index))
.hasCoprocessor(GlobalIndexChecker.class.getName()));
}
}
for (String table : TRANSACTIONAL_TABLE_LIST) {
if (table != null) {
Assert.assertFalse("Found IndexRegionObserver on transactional table",
admin.getDescriptor(TableName.valueOf(table))
.hasCoprocessor(IndexRegionObserver.class.getName()));
}
}
}
private void checkOldIndexingCoprocessors(String [] indexList, String [] tableList)
throws IOException {
if (mutable) {
for (String table : tableList) {
TableDescriptor indexDesc = admin.getDescriptor(TableName.valueOf(table));
Assert.assertTrue("Can't find Indexer for " + table,
indexDesc.hasCoprocessor(Indexer.class.getName()));
Assert.assertFalse("Found IndexRegionObserver on " + table,
indexDesc.hasCoprocessor(IndexRegionObserver.class.getName()));
IndexTestUtil.assertCoprocConfig(indexDesc, Indexer.class.getName(),
IndexCoprocIT.INDEXER_CONFIG);
}
}
for (String index : indexList) {
Assert.assertFalse("Found GlobalIndexChecker on " + index,
admin.getDescriptor(TableName.valueOf(index))
.hasCoprocessor(GlobalIndexChecker.class.getName()));
}
}
@Parameters(name ="IndexUpgradeToolIT_mutable={0},upgrade={1},isNamespaceEnabled={2}, rebuild={3}")
public static synchronized Collection<Object[]> data() {
return Arrays.asList(new Object[][] {
{false, false, true, false},
{true, false, false, true},
{false, true, false, false},
{true, true, true, true}
});
}
public ParameterizedIndexUpgradeToolIT(boolean mutable, boolean upgrade,
boolean isNamespaceEnabled, boolean rebuild) {
this.mutable = mutable;
this.upgrade = upgrade;
this.isNamespaceEnabled = isNamespaceEnabled;
this.rebuild = rebuild;
}
@Test
public void testNonDryRunToolWithMultiTables() throws Exception {
prepareFullSetup(); //test with all tables
validate(true, false);
iut.setDryRun(false);
iut.setLogFile(null);
iut.prepareToolSetup();
iut.executeTool();
//testing actual run
validate(false, false);
// testing if tool waited in case of immutable tables
if (!mutable) {
Assert.assertEquals("Index upgrade tool didn't wait for client cache to expire "
+ "for immutable tables", true, iut.getIsWaitComplete());
} else {
Assert.assertEquals("Index upgrade tool waited for client cache to expire "
+ "for mutable tables", false, iut.getIsWaitComplete());
}
if(upgrade && rebuild) {
//verifying if index tool was started
Mockito.verify(indexToolMock,
times(11)) // for every index/view-index except index on transaction table
.run(argCapture.capture());
} else {
Mockito.verifyZeroInteractions(indexToolMock);
}
}
@Test
public void testDryRunAndFailures() throws Exception {
prepareFullSetup(); //test with all tables
validate(true, false);
// test with incorrect table
iut.setInputTables("TEST3.TABLE_NOT_PRESENT");
iut.prepareToolSetup();
int status = iut.executeTool();
Assert.assertEquals(-1, status);
validate(true, false);
// test with input file parameter
BufferedWriter writer = new BufferedWriter(new FileWriter(new File(INPUT_FILE)));
writer.write(INPUT_LIST);
writer.close();
iut.setInputTables(null);
iut.setInputFile(INPUT_FILE);
iut.prepareToolSetup();
status = iut.executeTool();
Assert.assertEquals(0, status);
validate(true, false);
// test table without index
if (upgrade && !isNamespaceEnabled) {
conn.createStatement().execute("CREATE TABLE TEST.NEW_TABLE (id bigint NOT NULL "
+ "PRIMARY KEY, a.name varchar, sal bigint, address varchar)" + tableDDLOptions);
iut.setInputTables("TEST.NEW_TABLE");
iut.prepareToolSetup();
status = iut.executeTool();
Assert.assertEquals(0, status);
conn.createStatement().execute("DROP TABLE TEST.NEW_TABLE");
}
}
@Test
public void testRollbackAfterFailure() throws Exception {
prepareSimplifiedSetup(); //only need one table and index to verify rollback
validate(true, true);
if (upgrade) {
iut.setFailUpgradeTask(true);
} else {
iut.setFailDowngradeTask(true);
}
iut.prepareToolSetup();
int status = iut.executeTool();
Assert.assertEquals(-1, status);
//should have rolled back and be in the same status we started with
validate(true, true);
}
@Test
public void testTableReenableAfterDoubleFailure() throws Exception {
prepareSimplifiedSetup(); //only need one table and index to verify re-enabling
validate(true, true);
//this will force the upgrade/downgrade to fail, and then the rollback to fail too
//we want to make sure that even then, we'll try to re-enable the HBase tables
iut.setFailUpgradeTask(true);
iut.setFailDowngradeTask(true);
iut.prepareToolSetup();
try {
iut.executeTool();
} catch (RuntimeException e) {
//double failures throw an exception so that the tool stops immediately
validateTablesEnabled(INPUT_LIST);
return;
}
Assert.fail("Should have thrown an exception!");
}
private void validateTablesEnabled(String inputList) throws IOException, SQLException {
Admin admin = conn.unwrap(PhoenixConnection.class).getQueryServices().getAdmin();
String[] tableNames = inputList.split(",");
Assert.assertNotNull(tableNames);
Assert.assertTrue(tableNames.length > 0);
for (String tableName : tableNames) {
String physicalTableName =
SchemaUtil.getPhysicalHBaseTableName(SchemaUtil.getSchemaNameFromFullName(tableName),
SchemaUtil.getTableNameFromFullName(tableName), isNamespaceEnabled).getString();
Assert.assertTrue(admin.isTableEnabled(TableName.valueOf(physicalTableName)));
}
}
}