[Openais] [PATCH] Add mem leak check for cpg_initialize() with no corosync

Angus Salkeld asalkeld at redhat.com
Mon Mar 8 12:11:15 PST 2010


Add a new test case to check that an application that
is attempting to conect to corosync via cpg_initialze()
does not leak memory if corosync is not running.

-Angus

Signed-off-by: Angus Salkeld <asalkeld at redhat.com>
---
 cts/agents/cpg_test_agent.c |    6 +++++
 cts/corosync.py             |   51 +++++++++++++++++++++++++++++++++++++-----
 cts/corotests.py            |   39 ++++++++++++++++++++++++++++++++
 3 files changed, 90 insertions(+), 6 deletions(-)

diff --git a/cts/agents/cpg_test_agent.c b/cts/agents/cpg_test_agent.c
index 593aadc..c7cc6a0 100644
--- a/cts/agents/cpg_test_agent.c
+++ b/cts/agents/cpg_test_agent.c
@@ -371,6 +371,11 @@ static void do_command (int sock, char* func, char*args[], int num_args)
 	} else if (strcmp ("cpg_initialize",func) == 0) {
 		int retry_count = 0;
 
+		if (strcmp (args[0], "retry") != 0) {
+			cpg_initialize (&cpg_handle, &callbacks);
+			return;
+		}
+
 		result = cpg_initialize (&cpg_handle, &callbacks);
 		while (result != CS_OK) {
 			syslog (LOG_ERR,
@@ -602,6 +607,7 @@ int main (int argc, char *argv[])
 
 	openlog (NULL, LOG_CONS|LOG_PID, LOG_DAEMON);
 
+	syslog (LOG_INFO, "starting...\n");
 	list_init (&msg_log_head);
 	list_init (&config_chg_log_head);
 
diff --git a/cts/corosync.py b/cts/corosync.py
index 21cb5b5..43bbaa2 100644
--- a/cts/corosync.py
+++ b/cts/corosync.py
@@ -352,12 +352,47 @@ class TestAgent(object):
         except RuntimeError, msg:
             return False
     
-    def start(self):
+    def memory_used(self):
+        cmd = 'grep VmRSS /proc/$(pidof '
+        if self.with_valgrind:
+            cmd = cmd + 'valgrind'
+        else:
+            cmd = cmd + self.binary
+        cmd = cmd  + ')/status | sed "s/VmRSS:[ \t]\+\([0-9]\+\) kB/\\1/"'
+
+        rc = self.rsh(self.node, cmd, stdout=1)
+        print 'TestAgent mem used: ' + rc
+        return int(rc)
+
+    def dump_mem_info(self):
+        fname = '/tmp/mem_check_test_agent.txt'
+        self.rsh.cp("%s:%s" % (self.node, fname), fname)
+
+        f = file(fname)
+        while True:
+            line = f.readline()
+            if len(line) == 0:
+                break
+            print line.strip()
+        f.close()
+
+
+    def start(self, with_valgrind=False):
         '''Set up the given ScenarioComponent'''
+
+        self.with_valgrind = with_valgrind
         self.env.debug('test agent: start (' + self.node + ')')
         self.sock = socket.socket (socket.AF_INET, socket.SOCK_STREAM)
         ip = socket.gethostbyname(self.node)
-        self.rsh(self.node, self.binary, blocking=0)
+        val = 'valgrind  '
+        val += '--leak-check=full '
+        val += '--show-reachable=yes '
+        val += '--log-file=/tmp/mem_check_test_agent.txt '
+        if with_valgrind:
+            self.rsh(self.node, val + self.binary, blocking=0)
+        else:
+            self.rsh(self.node, self.binary, blocking=0)
+
         is_connected = False
         retries = 0
         while not is_connected:
@@ -376,7 +411,10 @@ class TestAgent(object):
         '''Tear down (undo) the given ScenarioComponent'''
         self.env.debug('test agent: stop (' + self.node + ')')
         self.sock.close ()
-        self.rsh(self.node, "killall " + self.binary + " 2>/dev/null")
+        if self.with_valgrind:
+            self.rsh(self.node, "killall valgrind 2>/dev/null")
+        else:
+            self.rsh(self.node, "killall " + self.binary + " 2>/dev/null")
         self.started = False
 
     def send (self, args):
@@ -463,9 +501,10 @@ class CpgTestAgent(TestAgent):
         self.initialized = False
         self.nodeid = None
 
-    def start(self):
-        TestAgent.start(self)
-        self.send(["cpg_initialize"])
+    def start(self, with_valgrind=False):
+        TestAgent.start(self, with_valgrind)
+        if not with_valgrind:
+            self.send(["cpg_initialize", "retry"])
         self.used = False
 
     def stop(self):
diff --git a/cts/corotests.py b/cts/corotests.py
index d950d5c..187c0c4 100644
--- a/cts/corotests.py
+++ b/cts/corotests.py
@@ -357,6 +357,44 @@ class MemLeakSession(CoroTest):
             return self.failure(str(mem_leaked) + 'kB memory leaked.')
 

+###################################################################
+class CoroIpcMemLeak(CoroTest):
+    '''
+    Reproduce a memory leak in coroipc when corosync is not
+    running.
+    '''
+    def __init__(self, cm):
+        CoroTest.__init__(self,cm)
+        self.name="CoroIpcMemLeak"
+
+    def setup(self, node):
+        ret = CoroTest.setup(self, node)
+        self.CM.rsh(node, "killall -9 corosync")
+        self.CM.rsh(node, "rm -f /var/run/corosync.pid")
+        time.sleep(3)
+        self.CM.agent[node].stop()
+        self.CM.agent[node].start(with_valgrind=True)
+        return ret
+        
+    def __call__(self, node):
+        self.incr("calls")
+        # get & record the mem used by cpg_test_agent
+
+        self.CM.agent[node].send(["cpg_initialize", "let_fail"])
+        mem1 = self.CM.agent[node].memory_used()
+        for c in range(0, 100):
+            self.CM.agent[node].send(["cpg_initialize", "let_fail"])
+
+        mem2 = self.CM.agent[node].memory_used()
+        diff = mem2 - mem1
+        if mem2 > mem1:
+            self.CM.agent[node].stop()
+            time.sleep(3)
+            self.CM.agent[node].dump_mem_info()
+            return self.failure('memory leaked by: ' + str(diff))
+        else:
+            return self.success()
+
 
 AllTestClasses = []
 AllTestClasses.append(MemLeakObject)
@@ -367,6 +405,7 @@ AllTestClasses.append(CpgCfgChgOnNodeLeave_v1)
 AllTestClasses.append(CpgCfgChgOnNodeLeave_v2)
 AllTestClasses.append(CpgCfgChgOnExecCrash)
 AllTestClasses.append(CpgMsgOrderBasic)
+AllTestClasses.append(CoroIpcMemLeak)
 
 AllTestClasses.append(FlipTest)
 AllTestClasses.append(RestartTest)
-- 
1.6.6.1




More information about the Openais mailing list