| /* |
| * 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.tool; |
| |
| import com.google.gson.Gson; |
| |
| import org.apache.phoenix.end2end.NeedsOwnMiniClusterTest; |
| import org.apache.phoenix.query.BaseTest; |
| import org.apache.phoenix.query.QueryServices; |
| import org.apache.phoenix.util.ReadOnlyProps; |
| import org.junit.After; |
| import org.junit.Before; |
| import org.junit.Test; |
| import org.junit.experimental.categories.Category; |
| import org.junit.runner.RunWith; |
| import org.junit.runners.Parameterized; |
| import org.slf4j.Logger; |
| import org.slf4j.LoggerFactory; |
| |
| import java.io.ByteArrayOutputStream; |
| import java.io.File; |
| import java.io.FileReader; |
| import java.io.FilenameFilter; |
| import java.io.IOException; |
| import java.io.InputStream; |
| import java.sql.Connection; |
| import java.sql.DriverManager; |
| import java.sql.SQLException; |
| import java.util.ArrayList; |
| import java.util.Arrays; |
| import java.util.Collection; |
| import java.util.HashMap; |
| import java.util.List; |
| import java.util.Map; |
| import java.util.Properties; |
| |
| import static org.apache.phoenix.tool.PhoenixCanaryTool.propFileName; |
| import static org.junit.Assert.assertFalse; |
| import static org.junit.Assert.assertTrue; |
| |
| @RunWith(Parameterized.class) |
| @Category(NeedsOwnMiniClusterTest.class) |
| public class ParameterizedPhoenixCanaryToolIT extends BaseTest { |
| |
| private static final Logger LOGGER = |
| LoggerFactory.getLogger(ParameterizedPhoenixCanaryToolIT.class); |
| private static final String stdOutSink |
| = "org.apache.phoenix.tool.PhoenixCanaryTool$StdOutSink"; |
| private static final String fileOutSink |
| = "org.apache.phoenix.tool.PhoenixCanaryTool$FileOutSink"; |
| |
| private static Map<String, String> serverProps = new HashMap<>(2); |
| private static Map<String, String> clientProps = new HashMap<>(2); |
| private static String connString = ""; |
| private static Properties canaryProp = new Properties(); |
| private static Connection connection = null; |
| private boolean isNamespaceEnabled; |
| private boolean isPositiveTestType; |
| private List<String> cmd = new ArrayList<>(); |
| private String resultSinkOption; |
| private ByteArrayOutputStream out = new ByteArrayOutputStream(); |
| private String tmpDir = System.getProperty("java.io.tmpdir"); |
| |
| public ParameterizedPhoenixCanaryToolIT(boolean isPositiveTestType, |
| boolean isNamespaceEnabled, String resultSinkOption) { |
| this.isPositiveTestType = isPositiveTestType; |
| this.isNamespaceEnabled = isNamespaceEnabled; |
| this.resultSinkOption = resultSinkOption; |
| } |
| |
| @Parameterized.Parameters(name = "ParameterizedPhoenixCanaryToolIT_isPositiveTestType={0}," + |
| "isNamespaceEnabled={1},resultSinkOption={2}") |
| public static Collection parametersList() { |
| return Arrays.asList(new Object[][] { |
| {true, true, stdOutSink}, |
| {true, true, fileOutSink}, |
| {false, true, stdOutSink}, |
| {false, true, fileOutSink}, |
| {true, false, stdOutSink}, |
| {true, false, fileOutSink}, |
| {false, false, stdOutSink}, |
| {false, false, fileOutSink} |
| }); |
| } |
| |
| @Before |
| public void setup() throws Exception { |
| String createSchema; |
| String createTable; |
| |
| if(needsNewCluster()) { |
| setClientSideNamespaceProperties(); |
| setServerSideNamespaceProperties(); |
| tearDownMiniCluster(NUM_SLAVES_BASE); |
| System.setProperty("java.io.tmpdir", tmpDir); |
| // FIXME no idea why java.io.tmpdir gets deleted. We don't see this behaviour in |
| // the main phoenix repo with same versions |
| File tempDir = new File(tmpDir); |
| tempDir.mkdirs(); |
| setUpTestDriver(new ReadOnlyProps(serverProps.entrySet().iterator()), |
| new ReadOnlyProps(clientProps.entrySet().iterator())); |
| LOGGER.info("New cluster is spinned up with test parameters " + |
| "isPositiveTestType" + this.isPositiveTestType + |
| "isNamespaceEnabled" + this.isNamespaceEnabled + |
| "resultSinkOption" + this.resultSinkOption); |
| connString = BaseTest.getUrl(); |
| connection = getConnection(); |
| } |
| |
| if (this.isNamespaceEnabled) { |
| createSchema = "CREATE SCHEMA IF NOT EXISTS TEST"; |
| connection.createStatement().execute(createSchema); |
| } |
| createTable = "CREATE TABLE IF NOT EXISTS TEST.PQSTEST " + |
| "(mykey INTEGER NOT NULL PRIMARY KEY, mycolumn VARCHAR," + |
| " insert_date TIMESTAMP)"; |
| connection.createStatement().execute(createTable); |
| cmd.add("--constring"); |
| cmd.add(connString); |
| cmd.add("--logsinkclass"); |
| cmd.add(this.resultSinkOption); |
| if (this.resultSinkOption.contains(stdOutSink)) { |
| System.setOut(new java.io.PrintStream(out)); |
| } else { |
| loadCanaryPropertiesFile(canaryProp); |
| } |
| } |
| |
| private boolean needsNewCluster() { |
| if (connection == null) { |
| return true; |
| } |
| if (!clientProps.get(QueryServices.IS_SYSTEM_TABLE_MAPPED_TO_NAMESPACE) |
| .equalsIgnoreCase(String.valueOf(this.isNamespaceEnabled))) { |
| return true; |
| } |
| return false; |
| } |
| |
| private void setClientSideNamespaceProperties() { |
| |
| clientProps.put(QueryServices.IS_SYSTEM_TABLE_MAPPED_TO_NAMESPACE, |
| String.valueOf(this.isNamespaceEnabled)); |
| |
| clientProps.put(QueryServices.IS_NAMESPACE_MAPPING_ENABLED, |
| String.valueOf(this.isNamespaceEnabled)); |
| } |
| |
| private Connection getConnection() throws SQLException { |
| Properties props = new Properties(); |
| props.setProperty(QueryServices.IS_SYSTEM_TABLE_MAPPED_TO_NAMESPACE, |
| String.valueOf(this.isNamespaceEnabled)); |
| |
| props.setProperty(QueryServices.IS_NAMESPACE_MAPPING_ENABLED, |
| String.valueOf(this.isNamespaceEnabled)); |
| return DriverManager.getConnection(connString, props); |
| } |
| |
| void setServerSideNamespaceProperties() { |
| serverProps.put(QueryServices.IS_NAMESPACE_MAPPING_ENABLED, |
| String.valueOf(this.isNamespaceEnabled)); |
| serverProps.put(QueryServices.IS_SYSTEM_TABLE_MAPPED_TO_NAMESPACE, |
| String.valueOf(this.isNamespaceEnabled)); |
| } |
| |
| /* |
| * This test runs in the test suit with |
| * combination of parameters provided. |
| * It tests the tool in positive type where test expects to pass |
| * and negative type where test expects to fail. |
| */ |
| @Test |
| public void phoenixCanaryToolTest() throws SQLException, IOException { |
| if (!isPositiveTestType) { |
| dropTestTable(); |
| } |
| PhoenixCanaryTool.main(cmd.toArray(new String[cmd.size()])); |
| Boolean result = getAggregatedResult(); |
| if (isPositiveTestType) { |
| assertTrue(result); |
| } else { |
| assertFalse(result); |
| } |
| } |
| |
| private Boolean getAggregatedResult() throws IOException { |
| HashMap<String, Boolean> resultsMap; |
| Boolean result = true; |
| resultsMap = parsePublishedResults(); |
| for (Boolean b : resultsMap.values()) { |
| result = result && b; |
| } |
| return result; |
| } |
| |
| private HashMap<String, Boolean> parsePublishedResults() throws IOException { |
| Gson parser = new Gson(); |
| CanaryTestResult[] results; |
| HashMap<String, Boolean> resultsMap = new HashMap<>(); |
| |
| if (this.resultSinkOption.contains(fileOutSink)) { |
| File resultFile = getTestResultsFile(); |
| results = parser.fromJson(new FileReader(resultFile), |
| CanaryTestResult[].class); |
| } else { |
| String result = out.toString(); |
| results = parser.fromJson(result, CanaryTestResult[].class); |
| } |
| for (CanaryTestResult r : results) { |
| resultsMap.put(r.getTestName(), r.isSuccessful()); |
| } |
| return resultsMap; |
| } |
| |
| private File getTestResultsFile() { |
| File[] files = getLogFileList(); |
| return files[0]; |
| } |
| |
| @After |
| public void teardown() throws SQLException { |
| if (this.isNamespaceEnabled) { |
| dropTestTableAndSchema(); |
| } else { |
| dropTestTable(); |
| } |
| if (this.resultSinkOption.contains(fileOutSink)) { |
| deleteResultSinkFile(); |
| } |
| } |
| |
| private void deleteResultSinkFile() { |
| File[] files = getLogFileList(); |
| for (final File file : files) { |
| if (!file.delete()) { |
| System.err.println("Can't remove " + file.getAbsolutePath()); |
| } |
| } |
| } |
| |
| private File[] getLogFileList() { |
| File dir = new File(canaryProp.getProperty("file.location")); |
| return dir.listFiles(new FilenameFilter() { |
| @Override |
| public boolean accept(File dir, String name) { |
| return name.endsWith(".log"); |
| } |
| }); |
| } |
| |
| private void loadCanaryPropertiesFile(Properties prop) { |
| InputStream input = ClassLoader.getSystemResourceAsStream(propFileName); |
| try { |
| prop.load(input); |
| } catch (IOException e) { |
| e.printStackTrace(); |
| } |
| } |
| |
| private void dropTestTable() throws SQLException { |
| String dropTable = "DROP TABLE IF EXISTS TEST.PQSTEST"; |
| connection.createStatement().execute(dropTable); |
| } |
| |
| private void dropTestTableAndSchema() throws SQLException { |
| dropTestTable(); |
| String dropSchema = "DROP SCHEMA IF EXISTS TEST"; |
| connection.createStatement().execute(dropSchema); |
| } |
| |
| } |