Permalink
Browse files

Fixes a race condition

Also, fixes a couple of errant frameworks who were
not cleaning exiting their start shells.
  • Loading branch information...
msmith-techempower committed Dec 6, 2016
1 parent c7a5e42 commit 9531785f3e222953237855fddd3c44eeb0eac63b
@@ -1,5 +1,5 @@
{
"framework": "Revenj",
"framework": "revenj",
"tests": [{
"windows": {
"setup_file": "setup",
@@ -32,5 +32,4 @@ echo "Copying the configuration template"
cat $TROOT/Revenj.Http.exe.config | sed 's|\(ConnectionString.*server=\)localhost|\1'"${DBHOST}"'|' > $TROOT/exe/Revenj.Http.exe.config
echo "Running the Revenj instance"
mono $TROOT/exe/Revenj.Http.exe
sleep 5
mono $TROOT/exe/Revenj.Http.exe &
@@ -1,5 +1,5 @@
{
"framework": "Revenj.JVM",
"framework": "revenj",
"tests": [{
"default": {
"setup_file": "setup",
@@ -546,7 +546,6 @@ def exit_with_code(code):
p.communicate("""
sudo restart mysql
sudo restart mongod
sudo service redis-server restart
sudo service postgresql restart
sudo service cassandra restart
/opt/elasticsearch/elasticsearch restart
@@ -556,7 +555,6 @@ def exit_with_code(code):
st = verify_database_connections([
("mysql", self.database_host, 3306),
("mongodb", self.database_host, 27017),
("redis", self.database_host, 6379),
("postgresql", self.database_host, 5432),
("cassandra", self.database_host, 9160),
("elasticsearch", self.database_host, 9200)
@@ -573,9 +571,9 @@ def exit_with_code(code):
print "Error: Unable to recover port, cannot start test"
return exit_with_code(1)
result = test.start(out)
result, process = test.start(out)
if result != 0:
self.__stop_test(out)
self.__stop_test(out, process)
time.sleep(5)
out.write( "ERROR: Problem starting {name}\n".format(name=test.name) )
out.flush()
@@ -613,13 +611,13 @@ def exit_with_code(code):
##########################
out.write(header("Stopping %s" % test.name))
out.flush()
self.__stop_test(out)
self.__stop_test(out, process)
out.flush()
time.sleep(15)
if self.__is_port_bound(test.port):
# This can happen sometimes - let's try again
self.__stop_test(out)
self.__stop_test(out, process)
out.flush()
time.sleep(15)
if self.__is_port_bound(test.port):
@@ -664,7 +662,7 @@ def exit_with_code(code):
traceback.print_exc(file=out)
out.flush()
try:
self.__stop_test(out)
self.__stop_test(out, process)
except (subprocess.CalledProcessError) as e:
self.__write_intermediate_results(test.name,"<setup.py>#stop() raised an error")
out.write(header("Subprocess Error: Test .stop() raised exception %s" % test.name))
@@ -675,7 +673,7 @@ def exit_with_code(code):
# TODO - subprocess should not catch this exception!
# Parent process should catch it and cleanup/exit
except (KeyboardInterrupt) as e:
self.__stop_test(out)
self.__stop_test(out, process)
out.write(header("Cleaning up..."))
out.flush()
self.__finish()
@@ -692,13 +690,12 @@ def exit_with_code(code):
# __stop_test(benchmarker)
# Stops all running tests
############################################################
def __stop_test(self, out):
# Find the PID of the daemon (and remove trailing newline)
pid = subprocess.check_output(['pgrep','TFBReaper']).strip()
# Kill the children
subprocess.call(['pkill', '-P', pid], stderr=out, stdout=out)
# Kill the parent
subprocess.call(['kill', pid], stderr=out, stdout=out)
def __stop_test(self, out, process):
if process is not None:
# Kill the children
subprocess.call(['pkill', '-P', process.pid], stderr=out, stdout=out)
# Kill the parent
process.terminate()
############################################################
# End __stop_test
@@ -347,7 +347,7 @@ def watch_child_pipes(nbsr, prefix):
logging.info("Executed %s.sh, returning %s", self.setup_file, retcode)
os.chdir(previousDir)
return retcode
return retcode, p
############################################################
# End start
############################################################
@@ -1,28 +1,13 @@
#define _DEFAULT_SOURCE
#include <stdlib.h>
#include <unistd.h>
#include <sys/prctl.h>
#include <sys/syscall.h>
#include <asm/unistd.h>
#include <string.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/wait.h>
int main(int argc, char *argv[])
{
pid_t process_id = 0;
pid_t sid = 0;
// Create child process
process_id = fork();
// PARENT PROCESS. Need to kill it.
if (process_id > 0)
{
// Parent returns success in exit status
exit(0);
}
// Here we are as the child with no parent.
// Gather the command line arguments for the pass-through.
int count = argc - 1;
int *sizes = malloc(sizeof(int) * count);
@@ -55,13 +40,19 @@ int main(int argc, char *argv[])
// See: http://man7.org/linux/man-pages/man2/prctl.2.html
prctl(PR_SET_CHILD_SUBREAPER,1);
// Sets the process group id to that of the process id of
// this process. All child processes should inherit this
// group id unless setpgrp is called directly (which some
// will do).
setpgrp();
// This invokes whatever was passed as arguments to TFBReaper
// on the system. This program is merely a pass-through to
// a shell with the subreaper stuff enabled.
int ret = system(result);
free(result);
// We need to wait forever; the suite will clean this child
// We need to wait forever; the suite will clean this
// process up later.
for(;;){}

0 comments on commit 9531785

Please sign in to comment.