From 4e8f82d19cde5c33e64115fad171a7a88bec6726 Mon Sep 17 00:00:00 2001 From: Karl Chen Date: Sat, 28 Jun 2003 00:56:45 +0000 Subject: [PATCH] test_exit, test_signal svn path=/trunk/boinc/; revision=1612 --- checkin_notes | 25 ++++++++++++++++++++++++- test/Makefile.am | 2 ++ test/Makefile.in | 2 ++ test/boinc.py | 12 ++++++++++++ test/test_abort.py | 14 ++++---------- test/test_exit.py | 28 ++++++++++++++++++++++++++++ test/test_signal.py | 29 +++++++++++++++++++++++++++++ test/test_uc.py | 25 ++++++++++++++++++++----- 8 files changed, 121 insertions(+), 16 deletions(-) create mode 100755 test/test_exit.py create mode 100755 test/test_signal.py diff --git a/checkin_notes b/checkin_notes index 6a1c666f3f..71f7343785 100755 --- a/checkin_notes +++ b/checkin_notes @@ -5047,7 +5047,7 @@ Karl 2003/06/25 - if application exceeds disk space limit, output message "Exceeded size limit" instead of "Couldn't upload files" - test that an aborted result due to file limit causes client_state = - RESULT_RESULT_OUTCOME_CLIENT_ERROR (currently this test FAILS!) + RESULT_OUTCOME_CLIENT_ERROR (currently this test FAILS!) - test resource limits in python db/ @@ -5089,3 +5089,26 @@ Karl 2003/06/26 test_sanity.py boinc.py test_masterurl_failure.py (new) + +Karl 2003/06/26 + - working on master url fetch failure retry policy + - test_signal.py. currently FAILS! + - test_exit.py. currently FAILS! + There is another bug similar to the one found by test_abort where the + client goes into FILES_UPLOADED even the application exited with an error. + + client/ + client_state.C + scheduler_op.C + + lib/ + util.C + util.h + + test/ + boinc.py + test_masterurl_failure.py + test_uc.py + testproxy + test_exit.py (added) + test_signal.py (added) diff --git a/test/Makefile.am b/test/Makefile.am index 60e82a3235..a71688542b 100644 --- a/test/Makefile.am +++ b/test/Makefile.am @@ -8,6 +8,8 @@ TESTS = test_sanity.py \ test_1sec.py \ test_abort.py \ test_rsc.py \ + test_exit.py \ + test_signal.py \ test_backend.py EXTRA_DIST = \ diff --git a/test/Makefile.in b/test/Makefile.in index c8a9a91774..5c10dece62 100644 --- a/test/Makefile.in +++ b/test/Makefile.in @@ -175,6 +175,8 @@ TESTS = test_sanity.py \ test_1sec.py \ test_abort.py \ test_rsc.py \ + test_exit.py \ + test_signal.py \ test_backend.py diff --git a/test/boinc.py b/test/boinc.py index 8cccc85705..e5311b640d 100644 --- a/test/boinc.py +++ b/test/boinc.py @@ -216,6 +216,16 @@ def _check_vars(dict, **names): class STARTS_WITH(str): pass +class MATCH_REGEXPS(list): + def match(self, text): + '''Returns True iff each regexp in self is in text''' + for r in self: + R = re.compile(r) + if not R.search(text): + return False + return True + pass + def dict_match(dic, resultdic): '''match values in DIC against RESULTDIC''' if not isinstance(dic, dict): @@ -229,6 +239,8 @@ def dict_match(dic, resultdic): continue if isinstance(expected,STARTS_WITH): match = found.startswith(expected) + elif isinstance(expected,MATCH_REGEXPS): + match = expected.match(found) else: match = found == expected if not match: diff --git a/test/test_abort.py b/test/test_abort.py index b9bf0a910a..8304942423 100755 --- a/test/test_abort.py +++ b/test/test_abort.py @@ -12,22 +12,16 @@ class WorkAbort(WorkUC): WorkUC.__init__(self) self.result_template = "abort_result" -class ResultAbort(ResultUC): +class ResultAbort(ResultUCError): def __init__(self): - ResultUC.__init__(self) - self.client_state = RESULT_OUTCOME_CLIENT_ERROR + ResultUCError.__init__(self) + self.stderr_out.append('Output file exceeded size limit') class ProjectAbort(ProjectUC): def __init__(self): ProjectUC.__init__(self, short_name='test_abort', works=[WorkAbort()]) - def check(self): - # no results should have been uploaded - self.check_deleted("upload/uc_wu_%d_0", count=self.redundancy) - self.sched_run('validate_test') - self.check_results(ResultAbort()) - self.sched_run('assimilator') - self.sched_run('file_deleter') + self.check_client_error(ResultAbort()) if __name__ == '__main__': test_msg("result abort mechanism (disk space limit)") diff --git a/test/test_exit.py b/test/test_exit.py new file mode 100755 index 0000000000..c0ffd1b831 --- /dev/null +++ b/test/test_exit.py @@ -0,0 +1,28 @@ +#!/usr/bin/env python + +## $Id$ + +# Make sure server hears that client exited with nonzero status. + +from test_uc import * + +class WorkExit(WorkUC): + def __init__(self): + WorkUC.__init__(self) + self.wu_template = "uc_exit_wu" + +class ResultExit(ResultUCError): + def __init__(self): + ResultUCError.__init__(self) + self.stderr_out.append('process exited with a nonzero exit code') + +class ProjectExit(ProjectUC): + def __init__(self): + ProjectUC.__init__(self, short_name='test_exit', works=[WorkExit()]) + def check(self): + self.check_client_error(ResultExit()) + +if __name__ == '__main__': + test_msg("application exit report mechanism") + ProjectExit() + run_check_all() diff --git a/test/test_signal.py b/test/test_signal.py new file mode 100755 index 0000000000..de35ebd293 --- /dev/null +++ b/test/test_signal.py @@ -0,0 +1,29 @@ +#!/usr/bin/env python + +## $Id$ + +# Make sure server hears that client died by a signal. + +from test_uc import * + +class WorkSignal(WorkUC): + def __init__(self): + WorkUC.__init__(self) + self.wu_template = "uc_sig_wu" + +class ResultSignal(ResultUCError): + def __init__(self): + ResultUCError.__init__(self) + self.stderr_out.append('SIGHUP: terminal line hangup') + self.stderr_out.append('process exited with a nonzero exit code') + +class ProjectSignal(ProjectUC): + def __init__(self): + ProjectUC.__init__(self, short_name='test_signal', works=[WorkSignal()]) + def check(self): + self.check_client_error(ResultSignal()) + +if __name__ == '__main__': + test_msg("application signal report mechanism") + ProjectSignal() + run_check_all() diff --git a/test/test_uc.py b/test/test_uc.py index f0f098e3f0..99b4dd3e87 100755 --- a/test/test_uc.py +++ b/test/test_uc.py @@ -39,11 +39,17 @@ class WorkUC(Work): class ResultUC: def __init__(self): self.server_state = RESULT_SERVER_STATE_OVER - self.stderr_out = STARTS_WITH("""APP: upper_case: starting, argc 1 -APP: upper_case: argv[0] is upper_case -APP: upper_case ending, wrote """) + self.stderr_out = MATCH_REGEXPS([ """ +APP: upper_case: starting, argc \\d+ +APP: upper_case: argv[[]0[]] is upper_case +APP: upper_case ending, wrote \\d+ chars"""]) # self.exit_status = 0 +class ResultUCError: + def __init__(self): + self.client_state = 3 # TODO: get this from lib/result_state.h + self.stderr_out = MATCH_REGEXPS([ """ +APP: upper_case: starting, argc \\d+"""]) class ProjectUC(Project): def __init__(self, works=None, users=None, hosts=None, @@ -58,15 +64,24 @@ class ProjectUC(Project): redundancy=redundancy, resource_share=resource_share ) - def check(self): + def check(self, result=ResultUC()): + '''Check results uploaded correctly''' self.sched_run('validate_test') - self.check_results(ResultUC()) + self.check_results(result) self.check_files_match("upload/uc_wu_%d_0", "uc_correct_output", count=self.redundancy) self.sched_run('assimilator') self.sched_run('file_deleter') self.check_deleted("download/input") self.check_deleted("upload/uc_wu_%d_0", count=self.redundancy) + def check_client_error(self, result=ResultUCError()): + '''Check no results uploaded''' + self.check_deleted("upload/uc_wu_%d_0", count=self.redundancy) + self.sched_run('validate_test') + self.check_results(result) + self.sched_run('assimilator') + self.sched_run('file_deleter') + def run(self): self.install() self.sched_install('feeder')