def main(default=None, commands=None, config_spec="", tests=None, description=None): """Parses command line arguments and configuration, then runs the appropriate command. """ start_time = datetime.now() log.debug("Start: '%s'", " ".join(sys.argv)) log.debug("Time: '%s'", start_time) commands = collect_commands(default, commands or []) # Configure the application from the command line and get the # command to be run run_command, arguments, interactive = configure( default, commands, config_spec, "Thanks for using %(prog)s." if description is None else description) # Store the commands and tests globally # I believe global is justified here for simplicity if tests is not None: global TESTS # pylint:disable=W0603 TESTS = tests global COMMANDS # pylint:disable=W0603 COMMANDS = commands # Initialize the main logger based on the configuration # and handle the state safely with logging_context(), \ StateHandler(filename=conf['pyexperiment.state_filename'], load=conf['pyexperiment.load_state'], save=conf['pyexperiment.save_state'], rotate_n_files=conf[ 'pyexperiment.rotate_n_state_files']): # Run the command with the supplied arguments if run_command is not None: result = run_command(*arguments) if result is not None: print(result) # Drop to the interactive console if necessary, passing the result if interactive: embed_interactive(result=result) # After everything is done, print timings if necessary if (((isinstance(conf['pyexperiment.print_timings'], bool) and conf['pyexperiment.print_timings']) or conf['pyexperiment.print_timings'] == 'True')): log.print_timings() end_time = datetime.now() log.debug("End: '%s'", " ".join(sys.argv)) log.debug("Time: '%s'", end_time) log.debug("Took: %.3fs", (end_time - start_time).total_seconds())
def test_with_block_load_fail(self): """Test with-block of the StateHandler does not destroy when failing """ state['a'] = 123 with tempfile.NamedTemporaryFile() as temp: state.reset_instance() state['a'] = 12 with StateHandler(temp.name, load=True): self.assertEqual(len(state), 1) self.assertEqual(state['a'], 12)
def test_with_block_does_load(self): """Test the with-block of the StateHandler loads if required """ state['a'] = 123 with tempfile.NamedTemporaryFile() as temp: state.save(temp.name) state.reset_instance() with StateHandler(temp.name, load=True): self.assertEqual(len(state), 1) self.assertEqual(state['a'], 123)
def test_with_block_does_not_load(self): """Test the basic with-block of the StateHandler does not load anything """ state['a'] = 1 self.assertEqual(len(state), 1) with tempfile.NamedTemporaryFile() as temp: state.save(temp.name) state.reset_instance() with StateHandler(temp.name): self.assertEqual(len(state), 0)
def test_with_block_does_save(self): """Test the with-block of the StateHandler saves if required """ state['a'] = 1 with tempfile.NamedTemporaryFile() as temp: state.save(temp.name) state.reset_instance() with StateHandler(temp.name, save=True): state['a'] = 42 state.reset_instance() state.load(temp.name) self.assertEqual(state['a'], 42)
def test_with_block_show(self): """Test with-block of the StateHandler does not cause show to fail """ with tempfile.NamedTemporaryFile() as temp: state.reset_instance() state['a'] = 12 with StateHandler(temp.name, load=True): self.assertEqual(len(state), 1) self.assertEqual(state['a'], 12) buf = io.StringIO() with stdout_redirector(buf): state.show() self.assertNotEqual(len(buf.getvalue()), 0) self.assertRegexpMatches(buf.getvalue(), r"a:12")
def test_with_block_locks(self): """Test the with-block of the StateHandler locks the state """ state['a'] = 123 with tempfile.NamedTemporaryFile() as temp: def other_op(): """Function to run in another process""" StateHandler.STATE_LOCK_TIMEOUT = 0.001 other_handler = StateHandler(temp.name, load=True) self.assertRaises(RuntimeError, other_handler.__enter__) state.save(temp.name) state.reset_instance() with StateHandler(temp.name, load=True): process = multiprocessing.Process(target=other_op) process.start() process.join()
def test_other_process_locks(self): """Test locking the state in another process locks """ with tempfile.NamedTemporaryFile() as temp: def other_op(queue): """Lock the lockfile, then wait for poison pill """ lockfile.FileLock(temp.name).acquire() while queue.empty(): sleep(0.01) lockfile.FileLock(temp.name).release() queue = multiprocessing.Queue() process = multiprocessing.Process(target=other_op, args=(queue, )) process.start() while not lockfile.FileLock(temp.name).is_locked(): sleep(0.01) StateHandler.STATE_LOCK_TIMEOUT = 0.001 handler = StateHandler(temp.name, load=False) self.assertRaises(RuntimeError, handler.lock) queue.put(None) process.join()
def other_op(): """Function to run in another process""" StateHandler.STATE_LOCK_TIMEOUT = 0.001 other_handler = StateHandler(temp.name, load=True) self.assertRaises(RuntimeError, other_handler.__enter__)