[asterisk-commits] sgriepentrog: branch sgriepentrog/testsuite-valgrind r4353 - in /asterisk/tea...
SVN commits to the Asterisk project
asterisk-commits at lists.digium.com
Wed Nov 20 15:15:15 CST 2013
Author: sgriepentrog
Date: Wed Nov 20 15:15:14 2013
New Revision: 4353
URL: http://svnview.digium.com/svn/testsuite?view=rev&rev=4353
Log:
functional but working version of valgrind
Modified:
asterisk/team/sgriepentrog/testsuite-valgrind/lib/python/asterisk/TestCase.py
asterisk/team/sgriepentrog/testsuite-valgrind/lib/python/asterisk/TestConfig.py
asterisk/team/sgriepentrog/testsuite-valgrind/lib/python/asterisk/asterisk.py
asterisk/team/sgriepentrog/testsuite-valgrind/runtests.py
Modified: asterisk/team/sgriepentrog/testsuite-valgrind/lib/python/asterisk/TestCase.py
URL: http://svnview.digium.com/svn/testsuite/asterisk/team/sgriepentrog/testsuite-valgrind/lib/python/asterisk/TestCase.py?view=diff&rev=4353&r1=4352&r2=4353
==============================================================================
--- asterisk/team/sgriepentrog/testsuite-valgrind/lib/python/asterisk/TestCase.py (original)
+++ asterisk/team/sgriepentrog/testsuite-valgrind/lib/python/asterisk/TestCase.py Wed Nov 20 15:15:14 2013
@@ -15,6 +15,7 @@
import time
import traceback
import uuid
+import TestSuiteUtils
from hashlib import md5
from twisted.internet import reactor, defer
from twisted.python import failure, log
@@ -181,10 +182,24 @@
by individual tests, however.
"""
+
+ valgrind = False
+ if None != self.test_config.valgrind:
+ valgrind = self.test_config.valgrind
+ elif os.getenv("VALGRIND") == "true":
+ valgrind = True
+ if True == valgrind:
+ if TestSuiteUtils.which('valgrind') is None:
+ # this would be better done elsewhere and stop
+ logger.error("Valgrind is not installed")
+ valgrind = False
+
for c in range(count):
logger.info("Creating Asterisk instance %d" % (c + 1))
host = "127.0.0.%d" % (c + 1)
self.ast.append(Asterisk(base=self.base, host=host))
+ self.ast[c].valgrind = valgrind
+
""" If a base configuration for this Asterisk instance has been
provided, install it first"""
if base_configs_path:
Modified: asterisk/team/sgriepentrog/testsuite-valgrind/lib/python/asterisk/TestConfig.py
URL: http://svnview.digium.com/svn/testsuite/asterisk/team/sgriepentrog/testsuite-valgrind/lib/python/asterisk/TestConfig.py?view=diff&rev=4353&r1=4352&r2=4353
==============================================================================
--- asterisk/team/sgriepentrog/testsuite-valgrind/lib/python/asterisk/TestConfig.py (original)
+++ asterisk/team/sgriepentrog/testsuite-valgrind/lib/python/asterisk/TestConfig.py Wed Nov 20 15:15:14 2013
@@ -252,6 +252,7 @@
self.feature_check = {}
self.test_configuration = "(none)"
self.condition_definitions = []
+ self.valgrind = None
self.global_test_config = global_test_config
self.__parse_config()
@@ -339,6 +340,15 @@
self.can_run = False
print "ERROR: '%s' is not a valid Asterisk version" % \
properties["forced-version"]
+ if "valgrind" in properties:
+ try:
+ if properties["valgrind"].upper().strip() == "YES":
+ self.valgrind = True
+ if properties["valgrind"].upper().strip() == "NO":
+ self.valgrind = False
+ except:
+ print "ERROR: '%s' is not a valid value for valgrind" %\
+ properties["valgrind"]
def __parse_config(self):
test_config = "%s/test-config.yaml" % self.test_name
Modified: asterisk/team/sgriepentrog/testsuite-valgrind/lib/python/asterisk/asterisk.py
URL: http://svnview.digium.com/svn/testsuite/asterisk/team/sgriepentrog/testsuite-valgrind/lib/python/asterisk/asterisk.py?view=diff&rev=4353&r1=4352&r2=4353
==============================================================================
--- asterisk/team/sgriepentrog/testsuite-valgrind/lib/python/asterisk/asterisk.py (original)
+++ asterisk/team/sgriepentrog/testsuite-valgrind/lib/python/asterisk/asterisk.py Wed Nov 20 15:15:14 2013
@@ -206,6 +206,10 @@
self.directories = {}
self.ast_version = AsteriskVersion()
self.base = Asterisk.test_suite_root
+ self.valgrind = False
+ self.valgrind_supp_filename = ""
+ self.valgrind_log_filename = ""
+ self.valgrind_xml_filename = ""
if base is not None:
self.base = "%s/%s" % (self.base, base)
if self.localtest_root:
@@ -261,6 +265,8 @@
"""
def __start_asterisk_callback():
+ if self.valgrind:
+ logger.info("Running Asterisk under valgrind")
self.processProtocol = AsteriskProtocol(self.host, self.__stop_deferred)
self.process = reactor.spawnProcess(self.processProtocol,
self.cmd[0],
@@ -294,6 +300,21 @@
"-f", "-g", "-q", "-m", "-n",
"-C", "%s" % os.path.join(self.astetcdir, "asterisk.conf")
]
+
+ if self.valgrind:
+ self.valgrind_log_filename = os.path.join(self.base, "valgrind.txt")
+ self.valgrind_xml_filename = os.path.join(self.base, "valgrind.xml")
+ self.valgrind_supp_filename = os.path.join(self.base, "etc/asterisk/valgrind.supp")
+ if os.path.exists(self.valgrind_supp_filename):
+ logger.info("Using the valgrind suppression file %s" % (self.valgrind_supp_filename))
+ self.cmd = ["valgrind", "--log-file=%s" % (self.valgrind_log_filename), "--xml=yes",
+ "--xml-file=%s" % (self.valgrind_xml_filename), "--suppressions=%s" % (
+ self.valgrind_supp_filename), "--leak-check=full"] + self.cmd
+ else:
+ logger.info("Valgrind Suppression file does not exist %s" % (os.path.dirname(self.valgrind_supp_filename)))
+ self.cmd = ["valgrind", "--log-file=%s" % (self.valgrind_log_filename), "--xml=yes",
+ "--xml-file=%s" % (self.valgrind_xml_filename), "--leak-check=full"] + self.cmd
+ print "Asterisk binary command [%s]" % (self.cmd)
# Make the start/stop deferreds - this method will return
# the start deferred, and pass the stop deferred to the AsteriskProtocol
Modified: asterisk/team/sgriepentrog/testsuite-valgrind/runtests.py
URL: http://svnview.digium.com/svn/testsuite/asterisk/team/sgriepentrog/testsuite-valgrind/runtests.py?view=diff&rev=4353&r1=4352&r2=4353
==============================================================================
--- asterisk/team/sgriepentrog/testsuite-valgrind/runtests.py (original)
+++ asterisk/team/sgriepentrog/testsuite-valgrind/runtests.py Wed Nov 20 15:15:14 2013
@@ -18,6 +18,7 @@
import socket
import shutil
import xml.dom
+import xml.dom.minidom
import random
sys.path.append("lib/python")
@@ -38,6 +39,7 @@
self.time = 0.0
self.test_name = test_name
self.ast_version = ast_version
+ self.existing_ast_instances = 0
self.options = options
self.test_config = TestConfig(test_name, global_config)
self.failure_message = ""
@@ -60,6 +62,14 @@
print msg
self.stdout += msg + "\n"
cmd.append(str(self.ast_version).rstrip())
+ #Before running the test case, check if there exists
+ #any asterisk directories for this test case
+ ast_directories = "%s/%s" % (Asterisk.test_suite_root, self.test_name.lstrip("tests/"))
+ while True:
+ if os.path.isdir("%s/ast%d" % (ast_directories, self.existing_ast_instances+1)):
+ self.existing_ast_instances += 1
+ else:
+ break
p = subprocess.Popen(cmd, stdout=subprocess.PIPE,
stderr=subprocess.STDOUT)
self.pid = p.pid
@@ -79,8 +89,11 @@
print "Core dumps detected; failing test"
self.passed = False
self.__archive_core_dumps(core_dumps)
+ self.__parse_valgrind_xml()
+ self.__parse_run_output(self.stdout)
if not self.passed:
self.__archive_ast_logs()
+ self.__archive_ast_valgrind_logs()
self.__archive_pcap_dump()
print 'Test %s %s\n' % (cmd, 'passed' if self.passed else 'failed')
@@ -128,7 +141,7 @@
def __archive_ast_logs(self):
ast_directories = "%s/%s" % (Asterisk.test_suite_root, self.test_name.lstrip("tests/"))
- i = 1
+ i = self.existing_ast_instances + 1
while True:
if os.path.isdir("%s/ast%d" % (ast_directories, i)):
ast_dir = "%s/ast%d/var/log/asterisk" % (ast_directories, i)
@@ -137,9 +150,9 @@
if not os.path.exists(dest_dir):
try:
hardlink_or_copy(ast_dir + "/messages.txt",
- dest_dir + "/messages.txt")
+ dest_dir + "/messages.txt")
hardlink_or_copy(ast_dir + "/full.txt",
- dest_dir + "/full.txt")
+ dest_dir + "/full.txt")
if os.path.exists(ast_dir + "/mmlog"):
hardlink_or_copy(ast_dir + "/mmlog",
dest_dir + "/mmlog")
@@ -147,6 +160,120 @@
print "Exception occurred while archiving logs from %s to %s: %s" % (
ast_dir, dest_dir, e
)
+ else:
+ break
+ i += 1
+
+ def __archive_ast_valgrind_logs(self):
+ ast_directories = "%s/%s" % (Asterisk.test_suite_root,
+ self.test_name.lstrip("tests/"))
+ i = self.existing_ast_instances + 1
+ while True:
+ if os.path.isdir("%s/ast%d" % (ast_directories, i)):
+ src_dir = "%s/ast%d/" % (ast_directories, i)
+ dest_dir = "./logs/%s/ast%d/" % (self.test_name.lstrip(
+ "tests/"), i)
+ if os.path.exists(dest_dir):
+ try:
+ if os.path.exists(src_dir+"/valgrind.txt"):
+ hardlink_or_copy(src_dir + "/valgrind.txt", dest_dir +
+ "/valgrind.txt")
+ if os.path.exists(src_dir+"/valgrind.xml"):
+ hardlink_or_copy(src_dir + "/valgrind.xml", dest_dir +
+ "/valgrind.xml")
+ print "Examine errors in %s/valgrind.xml" % dest_dir
+ except Exception, e:
+ print "Exception occurred valgrind logs from %s to %s: %s" % (
+ src_dir, dest_dir, e
+ )
+ else:
+ break
+ i += 1
+
+ def __parse_valgrind_xml(self):
+ #Parse valgrind XML and calculate number of bytes definately lost
+ ast_directories = "%s/%s" % (Asterisk.test_suite_root, self.test_name.lstrip("tests/"))
+ i = self.existing_ast_instances+1
+ while True:
+ if os.path.isdir("%s/ast%d" % (ast_directories, i)):
+ ast_dir = "%s/ast%d/" % (ast_directories, i)
+ if os.path.exists(ast_dir+"/valgrind.xml"):
+ print "Found the valgrind XML in %s " % ast_dir
+ count_bytes_leaked = 0
+ count_errors_found = 0
+ count_error_kinds = {}
+ try:
+ xmldoc = xml.dom.minidom.parse(ast_dir+"/valgrind.xml")
+ except Exception, e:
+ # valgrind may have left off the closing tag
+ with open(ast_dir+"/valgrind.xml", "a") as xmlfile:
+ xmlfile.write("</valgrindoutput>")
+ try:
+ xmldoc = xml.dom.minidom.parse(ast_dir+"/valgrind.xml")
+ except Exception, e:
+ msg = "Exception while parsing %s/valgrind.xml: %s" % (ast_dir, e)
+ self.stdout += msg + "\n"
+ print msg
+ self.passed = False
+ i += 1
+ continue
+
+ try:
+ error_list = xmldoc.getElementsByTagName('error')
+ count_errors_found = len(error_list)
+
+ def getText(nodelist):
+ text = []
+ for node in nodelist:
+ if node.nodeType == node.ELEMENT_NODE:
+ text.append(getText(node.childNodes))
+ if node.nodeType == node.TEXT_NODE:
+ text.append(str(node.data))
+ return ''.join(text)
+
+ for error in error_list:
+ kind = getText(error.getElementsByTagName('kind'))
+
+ stack = error.getElementsByTagName('stack')[0]
+ frame = stack.getElementsByTagName('frame')[0]
+ fn = getText(frame.getElementsByTagName('fn'))
+ file = getText(frame.getElementsByTagName('file'))
+ line = getText(frame.getElementsByTagName('line'))
+
+ msg = "%s() %s:%s" % (fn, file, line)
+
+ if not kind in count_error_kinds:
+ count_error_kinds[kind] = []
+ count_error_kinds[kind].append(msg)
+
+ if kind == "Leak_DefinitelyLost":
+ leaked_bytes = error.getElementsByTagName('leakedbytes')
+ if len(leaked_bytes) == 1:
+ dom_element = leaked_bytes[0]
+ count_bytes_leaked += int(dom_element.childNodes[0].nodeValue)
+
+ except Exception, e:
+ print "Exception checking elements valgrind XML: %s" % (e)
+ self.passed = False
+
+ for kind, list in count_error_kinds.iteritems():
+ msg = "Valgrind found %d errors of type %s" % (len(list), kind)
+ self.stdout += msg + "\n"
+ print msg
+ for details in list:
+ print " %s" % details
+
+ if count_bytes_leaked > 0:
+ msg = "Valgrind detected %s bytes definitely leaked" % (count_bytes_leaked)
+ self.stdout += msg + "\n"
+ print msg
+ self.passed = False
+ if count_errors_found > 0:
+ msg = "Valgrind detected %s total errors" % (count_errors_found)
+ self.stdout += msg + "\n"
+ print msg
+ self.passed = False
+
else:
break
i += 1
@@ -404,6 +531,9 @@
parser.add_option("-L", "--list-tags", action="store_true",
dest="list_tags", default=False,
help="List available tags")
+ parser.add_option("--valgrind", action="store_true",
+ dest="valgrind", default=False,
+ help="Run Asterisk under valgrind")
(options, args) = parser.parse_args(argv)
ast_version = AsteriskVersion(options.version)
@@ -423,6 +553,8 @@
test_suite.list_tags()
return 0
+ if options.valgrind:
+ os.environ["VALGRIND"] = "true"
print "Running tests for Asterisk %s ...\n" % str(ast_version)
test_suite.run()
@@ -473,6 +605,6 @@
# Try a copy instead
shutil.copyfile(source, destination)
-
if __name__ == "__main__":
sys.exit(main() or 0)
+# vim:sw=4:ts=4:expandtab:textwidth=79
More information about the asterisk-commits
mailing list