Mercurial > hg > ThermostatQA
view src/org/thermostat/qa/framework/ThermostatUtilities.java @ 167:7baba5d67a16
Fixes of gui tests and web storage tests, making tests more independent
* Makefile: added possibility to change backend for making screenshots
* Makefile: fixed problem with web storage (content of thermostat webapp
direcory is copied in /webaps/thermostat instead of *.war)
* Makefile: add coping configuration files to thermostat user directory,
which fixed problem of some tests relying on leftower configuration and
make it possible run them independently
* README.md: new informations about screenshot backends included
* src/org/thermostat/qa/framework/Patterns.java: new possible patterns for
some tabs added (versions of tabs highlighted under cursor)
* src/org/thermostat/qa/framework/ThermostatUtilities.java: thermostats jaas
configruation file is now passed to tomcat
* src/org/thermostat/qa/testsuites/GuiClientSmokeTest.java: adding 1 second
delay fixed problem, when test sometimes failed
* src/org/thermostat/qa/testsuites/GuiHostViewSmokeTest.java: window is now
not resized more than necessary (caused problem where part of the window
did not fit in lower resolution (1024x768) displays/vncs and test failed)
* patterns/1.1.0/noAA/ClientPreferencesDialog/connection_info_label.png:
added/updated pattern
* patterns/1.1.0/noAA/HostView/memory_tab_chsen.png: same as previous
* patterns/1.1.0/noAA/HostView/notes_tab.png: same as previous
* patterns/1.1.0/noAA/HostView/notes_tab_chosen.png: same as previous
* patterns/1.1.0/noAA/HostView/memory_tab_chosen2.png: same as previous
* patterns/1.1.0/noAA/HostView/numa_tab_chosen2.png: same as previous
* patterns/1.1.0/noAA/HostView/processor_tab_chosen2.png: same as previous
author | Zdenek Zambersky <zzambers@redhat.com> |
---|---|
date | Fri, 21 Nov 2014 10:50:09 +0100 |
parents | e8ad3e5e4893 |
children |
line wrap: on
line source
/* ThermostatQA - test framework for Thermostat Monitoring Tool Copyright 2013 Red Hat, Inc. This file is part of ThermostatQA ThermostatQA is distributed under the GNU General Public License, version 2 or any later version (with a special exception described below, commonly known as the "Classpath Exception"). A copy of GNU General Public License (GPL) is included in this distribution, in the file COPYING. Linking ThermostatQA code with other modules is making a combined work based on ThermostatQA. Thus, the terms and conditions of the GPL cover the whole combination. As a special exception, the copyright holders of ThermostatQA give you permission to link this code with independent modules to produce an executable, regardless of the license terms of these independent modules, and to copy and distribute the resulting executable under terms of your choice, provided that you also meet, for each linked independent module, the terms and conditions of the license of that module. An independent module is a module which is not derived from or based on ThermostatQA code. If you modify ThermostatQA, you may extend this exception to your version of the software, but you are not obligated to do so. If you do not wish to do so, delete this exception statement from your version. */ package org.thermostat.qa.framework; import java.awt.event.KeyEvent; import java.io.BufferedReader; import java.io.File; import java.io.IOException; import java.io.InputStreamReader; import java.util.ArrayList; import java.util.LinkedList; import java.util.List; import org.thermostat.qa.common.Configuration; import org.thermostat.qa.reporter.FileUtils; /** * Class ThermostatUtilities * contains the helper methods for running thermostat commands in processes, * running auxiliary scripts, and getting output from the processes. * */ public abstract class ThermostatUtilities { private static final String tomcatHome = System.getProperty("tomcat.home"); /** * Expected exit value of all thermostat processes. */ protected static final int EXPECTED_EXIT_VALUE = 0; protected static final int ONE_SEC = 1000; protected static final int FIVE_SEC = 5 * ONE_SEC; protected String mongoPortString = null; /** * Current configuration of thermostat tests. */ protected Configuration configuration = null; public void setConfigurationFromProperties(String[] args) { this.configuration = new Configuration(args); } public class ServiceStarter implements Runnable { @Override public void run() { Process process; try { process = runThermostatInNewProcess("service", ""); List<String> processOutput = readProcessOutput(process); for (String s : processOutput) { logInfo("run", "Service starter: " + s); } Assert.assertNotNull(processOutput, "error getting standard output"); } catch (IOException e) { e.printStackTrace(); } } } public class StorageStarter implements Runnable { @Override public void run() { Process process; try { process = runThermostatInNewProcess("storage", "--start"); List<String> processOutput = readProcessOutput(process); for (String s : processOutput) { logInfo("run", "Storage starter: " + s); } Assert.assertNotNull(processOutput, "error getting standard output"); } catch (IOException e) { e.printStackTrace(); } } } public class GuiThread extends Thread { @Override public void run() { Process process; try { process = runThermostatInNewProcess("gui"); List<String> processOutput = readProcessOutput(process); sleep(ONE_SEC); Assert.assertNotNull(processOutput, "no output from process"); int exitValue = process.exitValue(); Assert.assertEquals(exitValue, EXPECTED_EXIT_VALUE, "Bad thermostat exit value " + exitValue); } catch (IOException e) { e.printStackTrace(); } catch (InterruptedException e) { e.printStackTrace(); } } } public class AgentThread extends Thread { @Override public void run() { Process process; try { process = runThermostatInNewProcess("agent"); List<String> processOutput = readProcessOutput(process); sleep(ONE_SEC); Assert.assertNotNull(processOutput, "no output from process"); // int exitValue = process.exitValue(); // Assert.assertEquals(exitValue, EXPECTED_EXIT_VALUE, "Bad thermostat exit value " + exitValue); } catch (IOException e) { e.printStackTrace(); } catch (InterruptedException e) { e.printStackTrace(); } } } /** * Log into a standard output. * * @param prefix * string printed before class name. * @param delimiter * delimiter between prefix and the class name. * @param methodName * name of method implementing the test. */ protected void log(String prefix, char delimiter, String methodName) { System.out.println(prefix + ": " + this.getClass().getName() + delimiter + methodName); } protected void logInfo(String methodName, String message) { log("INFO", '.', methodName + ": " + message); } /** * Log into a standard output. * * @param prefix * string printed before class name. * @param delimiter * delimiter between prefix and the class name. * @param methodName * name of method implementing the test. * @param exception * message generated from exception */ protected void log(String prefix, char delimiter, String methodName, String exception) { System.out.println(prefix + ": " + this.getClass().getName() + delimiter + methodName + " " + exception); } /** * Returns version of Java. The input could have the following form: "1.7.0_06" * and we are interested only in "7" in this case. * * @return Java version */ protected int getJavaVersion() { String javaVersionStr = System.getProperty("java.version"); String[] parts = javaVersionStr.split("\\."); return Integer.parseInt(parts[1]); } /** * * @param process * @throws IOException */ protected void waitForExternalProcess(Process process) throws IOException { InputStreamReader processStdOut = new InputStreamReader(process.getInputStream()); while (processStdOut.read() != -1) { // should be empty ;-) } processStdOut.close(); } /** * * @param process * @return * @throws IOException */ public static List<String> readProcessOutput(Process process) throws IOException { List<String> out = new ArrayList<String>(); BufferedReader bufferedReader = new BufferedReader( new InputStreamReader(process.getInputStream())); String line; while ((line = bufferedReader.readLine()) != null) { out.add(line); } bufferedReader.close(); return out; } /** * * @param cmd * @return * @throws IOException */ protected static Process runProcess(String... cmd) throws IOException { return Runtime.getRuntime().exec(cmd); } /** * * @return * @throws IOException */ protected Process runThermostatInNewProcess() throws IOException { return Runtime.getRuntime().exec(this.configuration.getThermostatExecutable()); } /** * * @param flags * @return * @throws IOException */ public Process runThermostatInNewProcess(String... flags) throws IOException { if (!useFlags(flags)) { return runThermostatInNewProcess(); } String[] cmdArray = new String[flags.length + 1]; cmdArray[0] = this.configuration.getThermostatExecutable(); System.arraycopy(flags, 0, cmdArray, 1, flags.length); return Runtime.getRuntime().exec(cmdArray); } /** * * @param flags * @return */ private static boolean useFlags(String... flags) { return !(flags == null || flags.length == 0 || flags[0] == null); } /** * * @param scriptName * @return * @throws IOException */ public static List<String> runHelperBashScript(String scriptName, String... params) throws IOException { String readScriptName = "./scripts/" + scriptName; if (!useFlags(params)) { Process process = runProcess("bash", readScriptName); return readProcessOutput(process); } String[] cmdArray = new String[params.length + 2]; cmdArray[0] = "bash"; cmdArray[1] = readScriptName; System.arraycopy(params, 0, cmdArray, 2, params.length); Process process = runProcess(cmdArray); return readProcessOutput(process); } /** * Method makeScriptExecutable * takes a name of a file in ./scripts and performs chmod +x * * @param scriptName * @throws IOException */ protected static void makeScriptExecutable(String scriptName) throws IOException { String[] cmdArray = new String[]{"chmod","+x","./scripts/"+scriptName}; Runtime.getRuntime().exec(cmdArray); } /** * Method runBashScriptWithContent * gets list of strings which it writes as a content of a script with * given name, makes this script executable and runs it. * * @param scriptName * * @param content * @param params * @return * @throws IOException */ public static List<String> runBashScriptWithContent(String scriptName, List<String> content, String... params) throws IOException { //write content into a file in ./scripts FileUtils.writeTextFile("./scripts/"+scriptName, content); makeScriptExecutable(scriptName); return runHelperBashScript(scriptName, params); } /** * Method thermostatPingHost * calls thermostat ping hostId, usable when the db does not require * login and password. * * @param hostId * @return * @throws IOException */ protected List<String> thermostatPingHost(String hostId) throws IOException{ String scriptname="thermostatPingHost.sh"; List<String> content = new LinkedList<String>(); content.add(this.configuration.getThermostatExecutable() + " ping "+hostId); return runBashScriptWithContent(scriptname, content); } /** * Method thermostatPingHost * calls thermostat ping hostId, usable when the db requires * login and password (possibly empty). * * @param hostId * @param login * @param passwd * @return * @throws IOException */ protected List<String> thermostatPingHost(String hostId, String login, String passwd) throws IOException{ String scriptname="thermostatPingHost.sh"; List<String> dblogin = new LinkedList<String>(); dblogin.add(login); dblogin.add(passwd); FileUtils.writeTextFile("./scripts/dblogin.txt", dblogin); List<String> content = new LinkedList<String>(); content.add(this.configuration.getThermostatExecutable() + " ping "+hostId+" < ./scripts/dblogin.txt"); return runBashScriptWithContent(scriptname, content); } protected List<String> thermostatListVms(String login, String passwd) throws IOException{ String scriptname="thermostatListVms.sh"; createDBLoginTextFile(login, passwd); List<String> content = new LinkedList<String>(); content.add(this.configuration.getThermostatExecutable() + " list-vms < ./scripts/dblogin.txt"); return runBashScriptWithContent(scriptname, content); } protected List<String> thermostatDumpHeap(String hostId, String vmId, String login, String passwd) throws IOException{ String scriptname="thermostatDumpHeap.sh"; createDBLoginTextFile(login, passwd); List<String> content = new LinkedList<String>(); content.add(this.configuration.getThermostatExecutable() + " dump-heap -a " + hostId + " -v " + vmId + " < ./scripts/dblogin.txt" ); return runBashScriptWithContent(scriptname, content); } protected void createDBLoginTextFile(String login, String passwd){ List<String> dblogin = new LinkedList<String>(); dblogin.add(login); dblogin.add(passwd); FileUtils.writeTextFile("./scripts/dblogin.txt", dblogin); } protected void sleep(int ms) { try { Thread.sleep(ms); } catch (InterruptedException e) { e.printStackTrace(); } } protected void printOutput(List<String> out) { for (String s : out) { System.out.println(s); } } protected void startStorage() { new Thread(new StorageStarter()).start(); // let the storage to setup and warm-up sleep(2 * ONE_SEC); } protected void stopStorage() throws IOException { Process process = runThermostatInNewProcess("storage", "--stop"); List<String> processOutput = readProcessOutput(process); for (String s : processOutput) { logInfo("run", "Storage stopper: " + s); } Assert.assertNotNull(processOutput, "error getting standard output"); } public List<String> runCommandsInThermostatShell(String commandsFileName) throws IOException { String scriptFileName = "run_thermostat_shell_with_commands.sh"; //write the script specific to our test.properties //thermostat bin shell + commands for thermostat shell List<String> lines = new LinkedList<String>(); lines.add(this.configuration.getThermostatExecutable() + " shell < ./scripts/" + commandsFileName); FileUtils.writeTextFile("./scripts/"+scriptFileName, lines); //chmod - make the script executable makeScriptExecutable(scriptFileName); //run the new script return runHelperBashScript(scriptFileName); } public List<String> runCommandsInMongoShell(String commandsFileName) throws IOException { String scriptFileName = "run_mongo_shell_with_commands.sh"; //write the script specific to our test.properties //thermostat bin shell + commands for thermostat shell List<String> lines = new LinkedList<String>(); lines.add("mongo 127.0.01:27518 " + commandsFileName); FileUtils.writeTextFile("./scripts/"+scriptFileName, lines); //chmod - make the script executable makeScriptExecutable(scriptFileName); //run the new script return runHelperBashScript(scriptFileName); } protected void stopGUI(GuiRobot robot) { robot.pressCtrlPlusSmallLetter('q'); } protected void startWebStorage() throws IOException { // whereas the storage would be started/stopped many times startStorage(); startTomcat(); } protected void stopWebStorage() throws IOException { stopTomcat(); stopStorage(); } /** * Method prepareWebStorageConfigFiles * copies thermostat configuration files for agent and client logins * and thermostat-roles, thermostat-users from * /storageconfig/web-tomcat. * The method does it by creating a script * webStorage_prepareWebConfig.sh * and running this script. * * @throws IOException */ protected void prepareWebStorageConfigFiles() throws IOException { List<String> lines = new LinkedList<String>(); lines.add("cp ./storageconfig/"+this.configuration.getThermostatVersion()+"/web-tomcat/agent.auth "+this.configuration.getThermostatUserHome() + "etc/"); lines.add("cp ./storageconfig/"+this.configuration.getThermostatVersion()+"/web-tomcat/agent.properties "+this.configuration.getThermostatUserHome() + "etc/"); lines.add("cp ./storageconfig/"+this.configuration.getThermostatVersion()+"/web-tomcat/client.properties "+this.configuration.getThermostatUserHome() + "etc/"); lines.add("cp ./storageconfig/"+this.configuration.getThermostatVersion()+"/web-tomcat/thermostat-roles.properties "+this.configuration.getThermostatHome() + "etc/"); lines.add("cp ./storageconfig/"+this.configuration.getThermostatVersion()+"/web-tomcat/thermostat-users.properties "+this.configuration.getThermostatHome() + "etc/"); runBashScriptWithContent("webStorage_prepareWebConfig.sh", lines); } /** * Method prepareWebStorageBadClientLoginFile * copies a thermostat configuration file for client logins that would not * work, because the login and password will be different from the ones * given in the thermostat configuration. * * The method does it by creating a script * webStorage_prepareBadClientAuth.sh * and running this script. * * @throws IOException */ protected void prepareWebStorageBadClientLoginFile() throws IOException { List<String> lines = new LinkedList<String>(); lines.add("cp ./storageconfig/"+this.configuration.getThermostatVersion()+"/web-tomcat/client.badauth "+this.configuration.getThermostatUserHome() + "etc/client.properties"); runBashScriptWithContent("webStorage_prepareBadClientAuth.sh", lines); } /** * Method prepareWebStorageBadAgentLoginFile * copies a thermostat configuration file for agent logins that would not * work, because the login and password will be different from the ones * given in the thermostat configuration. * * The method does it by creating a script * webStorage_prepareBadAgentAuth.sh * and running this script. * * @throws IOException */ protected void prepareWebStorageBadAgentLoginFile() throws IOException { List<String> lines = new LinkedList<String>(); lines.add("cp ./storageconfig/"+this.configuration.getThermostatVersion()+"/web-tomcat/agent.badauth "+this.configuration.getThermostatUserHome() + "etc/agent.auth"); runBashScriptWithContent("webStorage_prepareBadAgentAuth.sh", lines); } /** * Method restoreNormalStorageConfigFiles * copies the configuration files for agent and client logins * and thermostat-roles, thermostat-users from * /storageconfig/db-mongodb. * The method does it by creating a script * webStorage_restoreNormalConfig.sh * and running this script. * * @throws IOException */ protected void restoreNormalStorageConfigFiles() throws IOException { //move back the original versions of the configuration files //web storage -> mongodb List<String> lines = new LinkedList<String>(); lines.add("cp ./storageconfig/"+this.configuration.getThermostatVersion()+"/db-mongodb/agent.auth "+this.configuration.getThermostatUserHome() + "etc/"); lines.add("cp ./storageconfig/"+this.configuration.getThermostatVersion()+"/db-mongodb/agent.properties "+this.configuration.getThermostatUserHome() + "etc/"); lines.add("cp ./storageconfig/"+this.configuration.getThermostatVersion()+"/db-mongodb/client.properties "+this.configuration.getThermostatUserHome() + "etc/"); lines.add("cp ./storageconfig/"+this.configuration.getThermostatVersion()+"/db-mongodb/thermostat-roles.properties "+this.configuration.getThermostatHome() + "etc/"); lines.add("cp ./storageconfig/"+this.configuration.getThermostatVersion()+"/db-mongodb/thermostat-users.properties "+this.configuration.getThermostatHome() + "etc/"); runBashScriptWithContent("webStorage_restoreNormalConfig.sh", lines); } protected void startTomcat() throws IOException { //startup.sh from the apache-tomcat dir List<String> lines = new LinkedList<String>(); lines.add("JAVA_OPTS=\"-Djava.security.auth.login.config=" + configuration.getThermostatHome() + "etc/thermostat_jaas.conf\" " + tomcatHome + File.separator + "bin/startup.sh"); runBashScriptWithContent("webStorage_startTomcat.sh", lines); } protected void stopTomcat() throws IOException { //shutdown.sh from the apache-tomcat dir List<String> lines = new LinkedList<String>(); lines.add(tomcatHome + File.separator + "bin/shutdown.sh"); runBashScriptWithContent("webStorage_stopTomcat.sh", lines); } protected List<String> getTomcatOutputs(String filename) { List<String> result = new LinkedList<String>(); //for now only the catalina.out file String catalinaOutFile = tomcatHome + File.separator + "logs/" + filename; result = FileUtils.readTextFile(catalinaOutFile); return result; } protected void createTomcatThermostatOutputFiles() throws IOException { //cat all files of thermostat-web-storage-* into one text file //called thermostat-web-storage-logs.txt //similarly for catalina* files //and localhost_access_log_* files List<String> lines = new LinkedList<String>(); lines.add("cat " + tomcatHome + File.separator + "logs/thermostat-web-storage.* > " + tomcatHome + File.separator + "logs/thermostat-web-storage-logs.txt"); lines.add("cat " + tomcatHome + File.separator + "logs/localhost_access_log_* > " + tomcatHome + File.separator + "logs/localhost_access_logs.txt"); lines.add("cat " + tomcatHome + File.separator + "logs/catalina* > " + tomcatHome + File.separator + "logs/catalina-logs.txt"); runBashScriptWithContent("webStorage_allThermostatLogsInOne.sh", lines); } protected void eraseTomcatOutputFiles() throws IOException { //rm all log files List<String> lines = new LinkedList<String>(); lines.add("rm "+ tomcatHome + File.separator + "logs/catalina*"); lines.add("rm "+ tomcatHome + File.separator + "logs/thermostat-web-storage*"); lines.add("rm "+ tomcatHome + File.separator + "logs/localhost_access_log*"); runBashScriptWithContent("webStorage_removeAllThermostatLogsFromTomcat.sh", lines); } protected String getMongoPortString() throws IOException { if(this.mongoPortString == null) { startStorage(); runHelperBashScript("find_mongo_port.sh"); List<String> lines = FileUtils.readTextFile("./scripts/mongoPortNumber.txt"); this.mongoPortString = lines.get(0); stopStorage(); } return this.mongoPortString; } }