Mercurial > hg > ThermostatQA
changeset 145:aa71f19bba98
adding DBHeapDumpTest testsuite
author | Jana Fabrikova <jfabriko@redhat.com> |
---|---|
date | Wed, 19 Feb 2014 14:23:56 +0100 |
parents | 59cc22faeb48 |
children | 28a547a9cfb4 |
files | ChangeLog Makefile patterns/1.1.0/AA/VMView/heap_analyzer_tab.png scripts/check-collections-heap-dump.js src/org/thermostat/qa/framework/Patterns.java src/org/thermostat/qa/framework/ThermostatUtilities.java src/org/thermostat/qa/testsuites/DBHeapDumpTest.java |
diffstat | 7 files changed, 581 insertions(+), 7 deletions(-) [+] |
line wrap: on
line diff
--- a/ChangeLog Tue Feb 18 11:58:17 2014 +0100 +++ b/ChangeLog Wed Feb 19 14:23:56 2014 +0100 @@ -1,3 +1,19 @@ +2014-02-19 Jana Fabrikova <jfabriko@redhat.com> + + * src/org/thermostat/qa/testsuites/DBHeapDumpTest.java: + adding testsuite with 16 testcases for testing the db scheme with running + storage, agent and gui where heap dump was performed via the gui + * scripts/check-collections-heap-dump.js: + auxiliary javascript file, commands to be run in the mongo shell + * src/org/thermostat/qa/framework/Patterns.java: + updating the used patterns + * src/org/thermostat/qa/framework/ThermostatUtilities.java: + adding method (runCommandsInMongoShell) used by the DBHeapDumpTest testsuite + * patterns/AA: + updating the pattern files + * Makefile: + adding DBHeapDumpTest to the list of tests + 2014-02-18 Jana Fabrikova <jfabriko@redhat.com> * src/org/thermostat/qa/testsuites/DBSchemeSmokeTest.java:
--- a/Makefile Tue Feb 18 11:58:17 2014 +0100 +++ b/Makefile Wed Feb 19 14:23:56 2014 +0100 @@ -48,7 +48,8 @@ GuiHostViewSmokeTest \ CommandChannelSmokeTest \ CommandChannelWebStorageTest \ - DBSchemeSmokeTest + DBSchemeSmokeTest \ + DBHeapDumpTest ALL_CLASSES = \ $(BUILD_DIR)/$(ANNOTATIONS_PACKAGE)/TestTypes.class \ @@ -97,7 +98,8 @@ $(BUILD_DIR)/$(TEST_PACKAGE)/GuiHostViewSmokeTest.class \ $(BUILD_DIR)/$(TEST_PACKAGE)/CommandChannelSmokeTest.class \ $(BUILD_DIR)/$(TEST_PACKAGE)/CommandChannelWebStorageTest.class \ - $(BUILD_DIR)/$(TEST_PACKAGE)/DBSchemeSmokeTest.class + $(BUILD_DIR)/$(TEST_PACKAGE)/DBSchemeSmokeTest.class \ + $(BUILD_DIR)/$(TEST_PACKAGE)/DBHeapDumpTest.class all: build runtests
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/scripts/check-collections-heap-dump.js Wed Feb 19 14:23:56 2014 +0100 @@ -0,0 +1,258 @@ +debug = false; +verbose = true; + +//function for running the tests +var runTests = function() +{ + // get the thermostat db + db = db.getMongo().getDB( "thermostat" ); + + // initialize the arrays of collection field names + types + fity = { + "agent-config" : [ + ["agentId","string"], + ["startTime","NumberLong"], + ["stopTime","NumberLong"], + ["alive","boolean"], + ["configListenAddress","string"] + ], + "backend-info" : [ + ["agentId","string"], + ["name","string"], + ["description","string"], + ["observeNewJvm","boolean"], + ["pids","empty array"], + ["active","boolean"], + ["orderValue","number"] + ], + "cpu-stats" : [ + ["agentId","string"], + ["perProcessorUsage","array of number"], + ["timeStamp","NumberLong"] + ], + "fs.chunks" : [ + ["files_id","ObjectId"], + ["n","number"], + ["data","BinData"] + ], + "fs.files" : [ + ["chunkSize","NumberLong"], + ["length","NumberLong"], + ["md5","string"], + ["filename","string"], + ["contentType","object null"], + ["uploadDate","ISODate"], + ["aliases","object null"] + ], + "host-info" : [ + ["agentId","string"], + ["hostname","string"], + ["osName","string"], + ["osKernel","string"], + ["cpuModel","string"], + ["cpuCount","number"], + ["totalMemory","NumberLong"] + ], + "memory-stats" : [ + ["agentId","string"], + ["timeStamp","NumberLong"], + ["total","NumberLong"], + ["free","NumberLong"], + ["buffers","NumberLong"], + ["cached","NumberLong"], + ["swapTotal","NumberLong"], + ["swapFree","NumberLong"], + ["commitLimit","NumberLong"] + ], + "network-info" : [ + ["agentId","string"], + ["interfaceName","string"], + ["ip4Addr","string"], + ["ip6Addr","object null"] + ], + "numa-host-info" : [ + ["agentId","string"], + ["numNumaNodes","number"] + ], + "numa-stat" : [ + ["agentId","string"], + ["timeStamp","NumberLong"], + ["nodeStats","array of object"] + ], + "vm-class-stats" : [ + ["agentId","string"], + ["vmId","string"], + ["timeStamp","NumberLong"], + ["loadedClasses","NumberLong"] + ], + "vm-cpu-stats" : [ + ["agentId","string"], + ["vmId","string"], + ["timeStamp","NumberLong"], + ["cpuLoad","number"] + ], + "vm-gc-stats" : [ + ["agentId","string"], + ["vmId","string"], + ["timeStamp","NumberLong"], + ["collectorName","string"], + ["runCount","NumberLong"], + ["wallTime","NumberLong"] + ], + "vm-heap-info" : [ + ["agentId","string"], + ["vmId","string"], + ["timeStamp","NumberLong"], + ["heapId","string"], + ["heapDumpId","string"], + ["histogramId","string"] + ], + "vm-info" : [ + ["agentId","string"], + ["vmId","string"], + ["vmPid","number"], + ["startTimeStamp","NumberLong"], + ["stopTimeStamp","NumberLong"], + ["javaVersion","string"], + ["javaHome","string"], + ["mainClass","string"], + ["javaCommandLine","string"], + ["vmName","string"], + ["vmArguments","string"], + ["vmInfo","string"], + ["vmVersion","string"], + ["propertiesAsArray","empty array"], + ["environmentAsArray","array of object"], + ["loadedNativeLibraries","empty array"], + ["uid","NumberLong"], + ["username","string"] + ], + "vm-memory-stats" : [ + ["agentId","string"], + ["vmId","string"], + ["timeStamp","NumberLong"], + ["generations","array of object"] + ], + "vm-thread-capabilities" : [ + ["agentId","string"], + ["vmId","string"], + ["supportedFeaturesList","array of string"] + ], + "vm-thread-harvesting" : [ + ["agentId","string"], + ["vmId","string"], + ["timeStamp","NumberLong"], + ["harvesting","boolean"] + ] + } + + //check the schemes of all collections + c = db.getCollectionNames(); + c.forEach(getSchemaAnalysis); +} + +// get collection from db +var mappedCollection = function(x) { return db[x]; } + +// function for inspecting the types in each collection +var getSchemaAnalysis = function(y) { + if(debug || verbose) + print("---------------------------------------------------------------"); + if( fity[y] != null && fity[y].length >0) + { + var wholeSchemaPass = true; + var schemaPass; + if(debug || verbose) + { + print("checking collection: " + y); + } + // deal with agent config schema + // it is expected to have agentId, alive, configListenAddress + // startTime, etc. keys + // Ideally it would analyze the type of the field as well. + // + // example: + // record.startTime.tojson() == 'NumberLong("1391084711073")' + var record = mappedCollection(y).findOne(); + var fieldsTypes = fity[y]; + if(debug) printjson(fieldsTypes); + for(var i=0; i<fieldsTypes.length; i++) + { + //checking not null + the right type of one field + schemaPass = true; + schemaPass = checkOneField(record, fieldsTypes[i][0], fieldsTypes[i][1]); + wholeSchemaPass = wholeSchemaPass && schemaPass; + } + + var isPass = wholeSchemaPass ? "OK" : "BAD"; + print("schema for " + y + " is " + isPass ); + return wholeSchemaPass; + }else{ + print("schema for "+ y + " is UNKNOWN by this test script"); + return false; + } +} + +// special type=arrays, +// for objects (not arrays) the realType will be parsed from json representation: +var typeOrObjectTypeOf = function(x) +{ + if(x == null) + { + if(Array.isArray(x)) + return "array null" + else if(typeof x == "object") + return "object null" + else return "null"; + } + var type = typeof x; + if( Array.isArray(x) ) + { + if(x.length > 0) + { + type = "array of "+typeOrObjectTypeOf(x[0]); + }else{ + type = "empty array"; + } + } + if( type == "object" ) + { + if("tojson" in x) + { + var jsonRep = x.tojson(); + var endOfObjName = jsonRep.indexOf('('); + type = jsonRep.substring(0,endOfObjName); + } + } + return type; +} + +// returns boolean if the given field is ok in given record +var checkOneField = function(record,field,expectedType) +{ + if(debug || verbose) + { + print("-checking field "+field+":"); + } + var notNull = (record[field] != null); + var realType = typeOrObjectTypeOf(record[field]); + var ofExpectedType = false; + if((typeof expectedType) == "string")//one expected type + { + ofExpectedType = (realType == expectedType) + }else{ //more admissible expected types = an array of them + for(var i=0; i<expectedType.length; i++) + { + ofExpectedType = ofExpectedType || (expectedType[i] == realType); + } + } + var OKString = (notNull && ofExpectedType)? "OK":"BAD" + if(debug || verbose) + { + print(" not-null?"+notNull+", type="+realType+" (expected="+expectedType+") ... "+OKString); + } + return notNull && ofExpectedType +} + +/******************RUN******************/ +runTests();
--- a/src/org/thermostat/qa/framework/Patterns.java Tue Feb 18 11:58:17 2014 +0100 +++ b/src/org/thermostat/qa/framework/Patterns.java Wed Feb 19 14:23:56 2014 +0100 @@ -50,8 +50,9 @@ public static final String MAIN_MENU = "MainWindow/main_menu"; public static final String[] HOST_VIEW_ICON = {"MainWindow/host_icon_grey", "MainWindow/host_icon_white", "MainWindow/host_icon_whiteblue"}; public static final String[] HOST_VIEW_ICON_ACTIVE = {"MainWindow/host_icon_blue", "MainWindow/host_icon_blue2"}; - public static final String VM_VIEW_ICON = "MainWindow/vm_icon_grey"; - public static final String VM_VIEW_ICON_ACTIVE = "MainWindow/vm_icon_blue"; + public static final String HOST_ICON_WITH_ARROW = "MainWindow/host_icon_with_arrow"; + public static final String[] VM_VIEW_ICON = {"MainWindow/vm_icon_grey", "MainWindow/vm_icon_whiteblue"}; + public static final String[] VM_VIEW_ICON_ACTIVE = {"MainWindow/vm_icon_blue","MainWindow/vm_icon_blue2"}; public static final String RESIZABLE = "MainWindow/resizable"; } @@ -92,7 +93,7 @@ public static final String THERMOSTAT_LOGO = "AboutDialog/thermostat_logo"; public static final String THERMOSTAT_TITLE = "AboutDialog/thermostat_title"; public static final String UPPER_TEXT = "AboutDialog/about_text_upper_part"; - public static final String LOWER_TEXT = "AboutDialog/about_text_lower_part"; + public static final String[] LOWER_TEXT = {"AboutDialog/about_text_lower_part3", "AboutDialog/about_text_lower_part","AboutDialog/about_text_lower_part2"}; } public static class SummaryTab @@ -116,7 +117,7 @@ public static final String BAD_LOGIN_USER_NAME = "ClientPreferencesDialog/bad_login_user_name"; public static final String SAVE_ENTITLEMENTS_CHECKED = "ClientPreferencesDialog/save_entitlements_checked"; public static final String PASSWORD_EDIT_AND_LABEL = "ClientPreferencesDialog/password_edit_and_label"; - public static final String[] WEB_STORAGE_CONNECTION_INFO = { "ClientPreferencesDialog/web_storage_connection_info", "ClientPreferencesDialog/web_storage_connection_info2"}; + public static final String[] WEB_STORAGE_CONNECTION_INFO = { "ClientPreferencesDialog/web_storage_connection_info", "ClientPreferencesDialog/web_storage_connection_info2","ClientPreferencesDialog/web_storage_connection_info3" }; } @@ -209,7 +210,7 @@ public static final String CPU_TAB_CHOSEN = "VMView/cpu_tab_chosen"; public static final String GC_TAB = "VMView/gc_tab"; public static final String GC_TAB_CHOSEN = "VMView/gc_tab_chosen"; - public static final String HEAP_ANALYZER_TAB = "VMView/heap_analyzer_tab"; + public static final String[] HEAP_ANALYZER_TAB = {"VMView/heap_analyzer_tab","VMView/heap_analyzer_tab2"}; public static final String HEAP_ANALYZER_TAB_CHOSEN = "VMView/heap_analyzer_tab_chosen"; public static final String MEMORY_TAB = "VMView/memory_tab"; public static final String MEMORY_TAB_CHOSEN = "VMView/memory_tab_chosen";
--- a/src/org/thermostat/qa/framework/ThermostatUtilities.java Tue Feb 18 11:58:17 2014 +0100 +++ b/src/org/thermostat/qa/framework/ThermostatUtilities.java Wed Feb 19 14:23:56 2014 +0100 @@ -459,6 +459,22 @@ 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.pressCtrlPlusKey(KeyEvent.VK_Q);
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/org/thermostat/qa/testsuites/DBHeapDumpTest.java Wed Feb 19 14:23:56 2014 +0100 @@ -0,0 +1,281 @@ +/* + + ThermostatQA - test framework for Thermostat Monitoring Tool + + Copyright 2014 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.testsuites; + +import java.awt.AWTException; +import java.awt.Rectangle; +import java.io.IOException; +import java.util.List; + + + + + + +import org.thermostat.qa.annotations.StorageType; +import org.thermostat.qa.annotations.StorageTypes; +import org.thermostat.qa.annotations.TestType; +import org.thermostat.qa.annotations.TestTypes; +import org.thermostat.qa.framework.Assert; +import org.thermostat.qa.framework.GuiRobot; +import org.thermostat.qa.framework.Patterns; +import org.thermostat.qa.framework.ThermostatGuiTest; + +/** + * Class DBSchemeSmokeTest + * contains basic smoke tests for checking the db scheme for thermostat mongodb + * storage. The test starts storage and one agent. Then all the collections + * that should not be empty after these steps are checked - there should be + * a non-null record in each (findOne() in the js script for mongo shell), and + * its elements should be of the right types. + * + */ +@TestType(TestTypes.GUI_TEST) +@StorageType(StorageTypes.MONGODB_STORAGE) +public class DBHeapDumpTest extends ThermostatGuiTest +{ + + private List<String> scriptOutput; + private GuiRobot robot; + + private GuiRobot clickOnVMView() throws IOException, AWTException{ + //start storage + GuiRobot robot = startStorageOnly(); + //start agent + new AgentThread().start(); + logInfo("runAgentThread", "Thermostat Agent started"); + + if (this.configuration.useDummyGfxTests()) + { + robot.loadScreenshot("GuiStarted1"); + } + else + { + //start gui + runThermostatGuiInANewThread(); + sleep(15000); + robot.createScreenCapture(); + robot.saveScreenshot("GuiStarted1"); + } + + //if only host icon is visible, click the '>' icon to see all its vms + Rectangle r = findPattern(robot, Patterns.MainWindow.HOST_ICON_WITH_ARROW, "host view icon with arrow"); + if(r != null) + { + r.width = 6; + robot.clickToRectangle(r); + sleep(ONE_SEC); + robot.createScreenCapture(); + robot.saveScreenshot("GuiStarted2"); + } + + r = checkForPattern(robot, Patterns.MainWindow.VM_VIEW_ICON, "vm view icon"); + robot.clickToRectangle(r); + + if (this.configuration.useDummyGfxTests()) + { + robot.loadScreenshot("VMViewActive1"); + } + else + { + sleep(2000); + robot.createScreenCapture(); + robot.saveScreenshot("VMViewActive1"); + } + + checkForPattern(robot, Patterns.MainWindow.VM_VIEW_ICON_ACTIVE, "vm view active icon"); + robot.saveScreenshot("VMViewActive2"); + + return robot; + } + + private GuiRobot dumpAHeap() throws IOException, AWTException { + + robot = clickOnVMView(); + + //click on Heap Analyzer tab + Rectangle r = checkForPattern(robot, Patterns.VMView.HEAP_ANALYZER_TAB, "heap analyzer tab"); + robot.clickToRectangle(r); + + if (this.configuration.useDummyGfxTests()) + { + robot.loadScreenshot("VMViewHeapAnalyzer1"); + } + else + { + sleep(2000); + robot.createScreenCapture(); + robot.saveScreenshot("VMViewHeapAnalyzer1"); + } + + checkForPattern(robot, Patterns.VMView.HEAP_ANALYZER_TAB_CHOSEN, "heap analyzer tab chosen"); + robot.saveScreenshot("VMViewHeapAnalyzer2"); + + //click on Heap Dump button + r = checkForPattern(robot, Patterns.VMViewHeapAnalyzerTab.HEAP_DUMP_LABEL, "vm view icon"); + robot.clickToRectangle(r); + + return robot; + } + + @Override + protected void tearDown() + { + + } + + @Override + protected void setUp() + { + // TODO + //start storage and agent + try + { + this.robot = dumpAHeap(); + } + catch (IOException e1) + { + // TODO Auto-generated catch block + e1.printStackTrace(); + } + catch (AWTException e1) + { + // TODO Auto-generated catch block + e1.printStackTrace(); + } + + + + //run js test script, get output + try + { + scriptOutput = runCommandsInMongoShell("check-collection-heap-dump.js"); + } + catch (IOException e) + { + e.printStackTrace(); + } + + //stop the agent and storage + try + { + //ADD END OF THE SITUATION HERE + stopGUI(robot); + runHelperBashScript("stop_all_therm_agents.sh"); + stopStorage(); + } + catch (IOException e) + { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } + + public void testAgentConfig(){ + Assert.assertNotNull(scriptOutput, "problems running auxiliary script"); + checkPresenceOfPatternInTexts(scriptOutput, "schema for agent-config is OK"); + } + public void testBackendInfo(){ + Assert.assertNotNull(scriptOutput, "problems running auxiliary script"); + checkPresenceOfPatternInTexts(scriptOutput, "schema for backend-info is OK"); + } + public void testCpuStats(){ + Assert.assertNotNull(scriptOutput, "problems running auxiliary script"); + checkPresenceOfPatternInTexts(scriptOutput, "schema for cpu-stats is OK"); + } + /*public void testFs.chunks(){ + Assert.assertNotNull(scriptOutput, "problems running auxiliary script"); + checkPresenceOfPatternInTexts(scriptOutput, "schema for fs.chunks is OK"); + } + public void testFs.files(){ + Assert.assertNotNull(scriptOutput, "problems running auxiliary script"); + checkPresenceOfPatternInTexts(scriptOutput, "schema for fs.files is OK"); + }*/ + public void testHostInfo(){ + Assert.assertNotNull(scriptOutput, "problems running auxiliary script"); + checkPresenceOfPatternInTexts(scriptOutput, "schema for host-info is OK"); + } + public void testMemoryStats(){ + Assert.assertNotNull(scriptOutput, "problems running auxiliary script"); + checkPresenceOfPatternInTexts(scriptOutput, "schema for memory-stats is OK"); + } + public void testNetworkInfo(){ + Assert.assertNotNull(scriptOutput, "problems running auxiliary script"); + checkPresenceOfPatternInTexts(scriptOutput, "schema for network-info is OK"); + } + public void testNumaHostInfo(){ + Assert.assertNotNull(scriptOutput, "problems running auxiliary script"); + checkPresenceOfPatternInTexts(scriptOutput, "schema for numa-host-info is OK"); + } + public void testNumaStat(){ + Assert.assertNotNull(scriptOutput, "problems running auxiliary script"); + checkPresenceOfPatternInTexts(scriptOutput, "schema for numa-stat is OK"); + } + public void testVmClassStats(){ + Assert.assertNotNull(scriptOutput, "problems running auxiliary script"); + checkPresenceOfPatternInTexts(scriptOutput, "schema for vm-class-stats is OK"); + } + public void testVmCpuStats(){ + Assert.assertNotNull(scriptOutput, "problems running auxiliary script"); + checkPresenceOfPatternInTexts(scriptOutput, "schema for vm-cpu-stats is OK"); + } + public void testVmGcStats(){ + Assert.assertNotNull(scriptOutput, "problems running auxiliary script"); + checkPresenceOfPatternInTexts(scriptOutput, "schema for vm-gc-stats is OK"); + } + public void testVmHeapInfo(){ + Assert.assertNotNull(scriptOutput, "problems running auxiliary script"); + checkPresenceOfPatternInTexts(scriptOutput, "schema for vm-heap-info is OK"); + } + public void testVmInfo(){ + Assert.assertNotNull(scriptOutput, "problems running auxiliary script"); + checkPresenceOfPatternInTexts(scriptOutput, "schema for vm-info is OK"); + } + public void testVmMemoryStats(){ + Assert.assertNotNull(scriptOutput, "problems running auxiliary script"); + checkPresenceOfPatternInTexts(scriptOutput, "schema for vm-memory-stats is OK"); + } + public void testVmThreadCapabilities(){ + Assert.assertNotNull(scriptOutput, "problems running auxiliary script"); + checkPresenceOfPatternInTexts(scriptOutput, "schema for vm-thread-capabilities is OK"); + } + public void testVmThreadHarvesting(){ + Assert.assertNotNull(scriptOutput, "problems running auxiliary script"); + checkPresenceOfPatternInTexts(scriptOutput, "schema for vm-thread-harvesting is OK"); + } + + public static void main(String[] args) { + new DBHeapDumpTest().doTests(args); + } + +}