changeset 142:80e28ec6a244

adding DBSchemeSmokeTest testsuite
author Jana Fabrikova <jfabriko@redhat.com>
date Mon, 17 Feb 2014 13:14:15 +0100
parents 658e54ab4ab3
children a3ea3e268e5e
files ChangeLog scripts/check-collections-smoke.js scripts/check-collections-smoke.sh src/org/thermostat/qa/testsuites/DBSchemeSmokeTest.java
diffstat 4 files changed, 451 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- a/ChangeLog	Wed Dec 04 17:27:28 2013 +0100
+++ b/ChangeLog	Mon Feb 17 13:14:15 2014 +0100
@@ -1,3 +1,15 @@
+2014-02-17  Jana Fabrikova  <jfabriko@redhat.com>
+
+	* src/org/thermostat/qa/testsuites/DBSchemeSmokeTest.java:
+	adding testsuite with 15 testcases for testing the db scheme with running
+	storage and one agent
+	* scripts/check-collections-smoke.js:
+	* scripts/check-collections-smoke.sh:
+	script and javascript auxiliary files for performing the tests via running
+	javascript code in the mongo shell
+	* Makefile:
+	adding DBSchemeSmokeTest to the list of tests
+
 2013-12-04  Jana Fabrikova  <jfabriko@redhat.com>
 
 	* storageconfig/1.1.0:
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/scripts/check-collections-smoke.js	Mon Feb 17 13:14:15 2014 +0100
@@ -0,0 +1,247 @@
+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"], 
+                         ["alive","boolean"],
+                         ["configListenAddress","string"],
+                         ["startTime","NumberLong"],
+                         ["stopTime","NumberLong"] 
+                       ],
+                 "backend-info" :
+                       [ ["agentId","string"],
+                         ["name","string"],
+                         ["description","string"],
+                         ["observeNewJvm","boolean"],
+                         ["pids",["empty array","array of number"]],
+                         ["active","boolean"],
+                         ["orderValue","number"]
+                       ],
+                 "cpu-stats" :
+                       [ ["agentId","string"],
+                         ["perProcessorUsage","array of number"],
+                         ["timeStamp","NumberLong"]
+                       ],
+                 "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","string"]
+                       ],
+                 "numa-host-info" :
+                       [ ["agentId","string"],
+                         ["numNumaNodes","number"]
+                       ],
+                 "numa-stat" :
+                       [ ["agentId","string"],
+                         ["timeStamp", "NumberLong"],
+                         ["nodeStats","array of object"]
+	               ],
+                 "system.indexes" :
+                       [ ["v","number"],
+                         ["key","object"],
+                         ["ns","string"],
+                         ["name","string"]
+                       ],
+                 "vm-class-stats" :
+                       [ ["agentId","string"],
+                         ["vmId","string"],
+                         ["timeStamp","NumberLong"],
+                         ["loadedClasses","NumberLong"]
+                       ],
+                 "vm-cpu-stats" :
+                       [ ["agentId","string"],
+                         ["vmId","string"],
+                         ["timeStamp","NumberLong"],
+                         ["cpuLoad","number"]
+                       ],
+                 "vm-deadlock-data" :
+                       [],
+                 "vm-gc-stats" :
+                       [ ["agentId","string"],
+                         ["vmId","string"],
+                         ["timeStamp","NumberLong"],
+                         ["collectorName","string"],
+                         ["runCount","NumberLong"],
+                         ["wallTime","NumberLong"]
+                       ],
+                 "vm-heap-info" : [],
+                 "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","array of object"]], //???TODO what type?
+                         ["environmentAsArray","array of object"],
+                         ["loadedNativeLibraries",["empty array","array of object"]],//???TODO what type?
+                         ["uid","NumberLong"],
+                         ["username","string"]
+                       ],
+                 "vm-jmx-notification" : [],
+                 "vm-jmx-notification-status" : [],
+                 "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"]
+                       ],
+                 "vm-thread-info" : [],
+                 "vm-thread-summary": []
+           }
+
+    //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( fity[y] != null && fity[y].length >0)
+    {
+        var wholeSchemaPass = true;
+        var schemaPass;
+        if(debug || verbose) 
+        {
+            print("---------------------------------------------------------------");
+            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();
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/scripts/check-collections-smoke.sh	Mon Feb 17 13:14:15 2014 +0100
@@ -0,0 +1,2 @@
+mongo 127.0.0.1:27518 check-collections-smoke.js
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/org/thermostat/qa/testsuites/DBSchemeSmokeTest.java	Mon Feb 17 13:14:15 2014 +0100
@@ -0,0 +1,190 @@
+/*
+
+    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.testsuites;
+
+import java.io.IOException;
+import java.util.List;
+
+
+import org.thermostat.qa.framework.Assert;
+import org.thermostat.qa.framework.ThermostatTest;
+
+/**
+ * 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.
+ *
+ */
+public class DBSchemeSmokeTest extends ThermostatTest
+{
+    
+    private List<String> scriptOutput;
+    
+    @Override
+    protected void tearDown()
+    {
+
+    }
+
+    @Override
+    protected void setUp()
+    {
+        // TODO
+        //start storage
+        startStorage();
+        //start agent
+        new AgentThread().start();
+
+        //run js test script, get output
+        try
+        {
+            scriptOutput = runHelperBashScript("check-collections-smoke.sh");
+        }
+        catch (IOException e)
+        {
+            e.printStackTrace();
+        }
+        
+        //stop the agent and storage
+        try
+        {
+            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 js script in mongo shell");
+        //find a line in scriptOutput containing "schema for agent-config is OK"
+        checkPresenceOfPatternInTexts(scriptOutput, "schema for agent-config is OK");
+    }
+    public void testBackendInfo(){
+        Assert.assertNotNull(scriptOutput, "problems running auxiliary js script in mongo shell");
+        checkPresenceOfPatternInTexts(scriptOutput, "schema for backend-info is OK");
+    }
+    public void testCpuStats(){
+        Assert.assertNotNull(scriptOutput, "problems running auxiliary js script in mongo shell");
+        checkPresenceOfPatternInTexts(scriptOutput, "schema for cpu-stats is OK");
+    }
+    public void testHostInfo(){
+        Assert.assertNotNull(scriptOutput, "problems running auxiliary js script in mongo shell");
+        checkPresenceOfPatternInTexts(scriptOutput, "schema for host-info is OK");
+    }
+    public void testMemoryStats(){
+        Assert.assertNotNull(scriptOutput, "problems running auxiliary js script in mongo shell");
+        checkPresenceOfPatternInTexts(scriptOutput, "schema for memory-stats is OK");
+    }
+    /* this test fails on fedora 20 (ipv6 address is null is it ok or not? on rhel6 it passes)
+    public void testNetworkInfo(){
+        Assert.assertNotNull(scriptOutput, "problems running auxiliary js script in mongo shell");
+        checkPresenceOfPatternInTexts(scriptOutput, "schema for network-info is OK");
+    }*/
+    public void testNumaHostInfo(){
+        Assert.assertNotNull(scriptOutput, "problems running auxiliary js script in mongo shell");
+        checkPresenceOfPatternInTexts(scriptOutput, "schema for numa-host-info is OK");
+    }
+    public void testNumaStat(){
+        Assert.assertNotNull(scriptOutput, "problems running auxiliary js script in mongo shell");
+        checkPresenceOfPatternInTexts(scriptOutput, "schema for numa-stat is OK");
+    }
+    public void testSystemIndexes(){
+        Assert.assertNotNull(scriptOutput, "problems running auxiliary js script in mongo shell");
+        checkPresenceOfPatternInTexts(scriptOutput, "schema for system.indexes is OK");
+    }
+    public void testVmClassStats(){
+        Assert.assertNotNull(scriptOutput, "problems running auxiliary js script in mongo shell");
+        checkPresenceOfPatternInTexts(scriptOutput, "schema for vm-class-stats is OK");
+    }
+    public void testVmCpuStats(){
+        Assert.assertNotNull(scriptOutput, "problems running auxiliary js script in mongo shell");
+        checkPresenceOfPatternInTexts(scriptOutput, "schema for vm-cpu-stats is OK");
+    }
+    /*public void testVmDeadlockData(){
+        Assert.assertNotNull(scriptOutput, "problems running auxiliary js script in mongo shell");
+        checkPresenceOfPatternInTexts(scriptOutput, "schema for vm-deadlock-data is UNKNOWN");
+    }*/
+    public void testVmGcStats(){
+        Assert.assertNotNull(scriptOutput, "problems running auxiliary js script in mongo shell");
+        checkPresenceOfPatternInTexts(scriptOutput, "schema for vm-gc-stats is OK");
+    }
+    /*public void testVmHeapInfo(){
+        Assert.assertNotNull(scriptOutput, "problems running auxiliary js script in mongo shell");
+        checkPresenceOfPatternInTexts(scriptOutput, "schema for heap-info is UNKNOWN");
+    }*/
+    public void testVmInfo(){
+        Assert.assertNotNull(scriptOutput, "problems running auxiliary js script in mongo shell");
+        checkPresenceOfPatternInTexts(scriptOutput, "schema for vm-info is OK");
+    }
+    /*public void testVmJmxNotification(){
+        Assert.assertNotNull(scriptOutput, "problems running auxiliary js script in mongo shell");
+        checkPresenceOfPatternInTexts(scriptOutput, "schema for vm-jmx-notification is UNKNOWN");
+    }
+    public void testVmJmxNotificationStatus(){
+        Assert.assertNotNull(scriptOutput, "problems running auxiliary js script in mongo shell");
+        checkPresenceOfPatternInTexts(scriptOutput, "schema for vm-jmx-notification-status is UNKNOWN");
+    }*/
+    public void testVmMemoryStats(){
+        Assert.assertNotNull(scriptOutput, "problems running auxiliary js script in mongo shell");
+        checkPresenceOfPatternInTexts(scriptOutput, "schema for vm-memory-stats is OK");
+    }
+    public void testVmThreadCapabilities(){
+        Assert.assertNotNull(scriptOutput, "problems running auxiliary js script in mongo shell");
+        checkPresenceOfPatternInTexts(scriptOutput, "schema for vm-thread-capabilities is OK");
+    }
+    public void testVmThreadHarvesting(){
+        Assert.assertNotNull(scriptOutput, "problems running auxiliary js script in mongo shell");
+        checkPresenceOfPatternInTexts(scriptOutput, "schema for vm-thread-harvesting is OK");
+    }
+    /*public void testVmThreadInfo(){
+        Assert.assertNotNull(scriptOutput, "problems running auxiliary js script in mongo shell");
+        checkPresenceOfPatternInTexts(scriptOutput, "schema for vm-thread-info is UNKNOWN");
+    }
+    public void testVmThreadSummary(){
+        Assert.assertNotNull(scriptOutput, "problems running auxiliary js script in mongo shell");
+        checkPresenceOfPatternInTexts(scriptOutput, "schema for vm-thread-summary is UNKNOWN");
+    }*/
+
+    
+    public static void main(String[] args) {
+        new DBSchemeSmokeTest().doTests(args);
+    }
+
+}