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

Steven Dake sdake at redhat.com
Tue Mar 9 11:42:27 PST 2010


good for merge

On Tue, 2010-03-09 at 07:11 +1100, Angus Salkeld wrote:
> 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)



More information about the Openais mailing list