示例#1
0
def test_this_is_really_our_pid():
    process = mock.Mock(spec=psutil.Process, username=USER1, pid=PID, create_time=CREATE_TIME)
    assert TRH.this_is_really_our_pid(process, process.username, process.create_time)
    assert TRH.this_is_really_our_pid(
        process, process.username, process.create_time + TRH.MAX_START_TIME_DRIFT.as_(Time.SECONDS) - 1
    )
    assert not TRH.this_is_really_our_pid(process, "user2", process.create_time)
    assert not TRH.this_is_really_our_pid(
        process, process.username, process.create_time + TRH.MAX_START_TIME_DRIFT.as_(Time.SECONDS) + 1
    )
    assert not TRH.this_is_really_our_pid(
        process, process.username, process.create_time - (TRH.MAX_START_TIME_DRIFT.as_(Time.SECONDS) + 1)
    )
def write_header(root, sandbox, task_id):
    log_dir = os.path.join(sandbox, '.logs')
    path = TaskPath(root=root, task_id=task_id, log_dir=log_dir)
    header = RunnerHeader(task_id=task_id, sandbox=sandbox, log_dir=log_dir)
    ckpt = TaskRunnerHelper.open_checkpoint(path.getpath('runner_checkpoint'))
    ckpt.write(RunnerCkpt(runner_header=header))
    ckpt.close()
def write_header(root, sandbox, task_id):
  log_dir = os.path.join(sandbox, '.logs')
  path = TaskPath(root=root, task_id=task_id, log_dir=log_dir)
  header = RunnerHeader(task_id=task_id, sandbox=sandbox, log_dir=log_dir)
  ckpt = TaskRunnerHelper.open_checkpoint(path.getpath('runner_checkpoint'))
  ckpt.write(RunnerCkpt(runner_header=header))
  ckpt.close()
示例#4
0
def test_scan_process():
  # TODO(jon): add more tests for successful cases; this really just looks for errors.

  assert TRH.scan_process(
      make_runner_state(cpid=None, pid=None), PROCESS_NAME) == (None, None, set())

  with mock.patch(PSUTIL_PATH) as p_mock:
    class WrappedNoSuchProcess(psutil.NoSuchProcess):
      # psutil.NoSuchProcess exception requires an argument, but mock doesn't support that.
      def __init__(self): pass
    p_mock.side_effect = WrappedNoSuchProcess
    assert TRH.scan_process(
        make_runner_state(cpid=None), PROCESS_NAME) == (None, None, set())
    assert TRH.scan_process(
        make_runner_state(pid=None), PROCESS_NAME) == (None, None, set())

  with mock.patch(PSUTIL_PATH) as p_mock:
    p_mock.side_effect = psutil.Error
    assert TRH.scan_process(
        make_runner_state(cpid=None), PROCESS_NAME) == (None, None, set())
    assert TRH.scan_process(
        make_runner_state(pid=None), PROCESS_NAME) == (None, None, set())

  with mock.patch(TRH_PATH) as trh_mock:
    trh_mock.this_is_really_our_pid.returns = False
    assert TRH.scan_process(
        make_runner_state(), PROCESS_NAME) == (None, None, set())

  with mock.patch(TRH_PATH) as trh_mock:
    trh_mock.this_is_really_our_pid.sideffect = psutil.Error
    assert TRH.scan_process(
        make_runner_state(), PROCESS_NAME) == (None, None, set())
示例#5
0
    def test_pg_is_killed(self):
        runner = self.start_runner()
        tm = TaskMonitor(runner.tempdir, runner.task_id)
        self.wait_until_running(tm)
        process_state, run_number = tm.get_active_processes()[0]
        assert process_state.process == 'process'
        assert run_number == 0

        child_pidfile = os.path.join(runner.sandbox, runner.task_id,
                                     'child.txt')
        while not os.path.exists(child_pidfile):
            time.sleep(0.1)
        parent_pidfile = os.path.join(runner.sandbox, runner.task_id,
                                      'parent.txt')
        while not os.path.exists(parent_pidfile):
            time.sleep(0.1)
        with open(child_pidfile) as fp:
            child_pid = int(fp.read().rstrip())
        with open(parent_pidfile) as fp:
            parent_pid = int(fp.read().rstrip())

        ps = ProcessProviderFactory.get()
        ps.collect_all()
        assert parent_pid in ps.pids()
        assert child_pid in ps.pids()
        assert child_pid in ps.children_of(parent_pid)

        with open(os.path.join(runner.sandbox, runner.task_id, 'exit.txt'),
                  'w') as fp:
            fp.write('go away!')

        while tm.task_state() is not TaskState.SUCCESS:
            time.sleep(0.1)

        state = tm.get_state()
        assert state.processes['process'][0].state == ProcessState.SUCCESS

        # Another test case may have called setup_child_subreaping(). We therefore have to reap any
        # terminated re-parented child processes to ensure that we don't list already terminated
        # processes (i.e. zombies) in ps.pids() below.
        TaskRunnerHelper.reap_children()

        ps.collect_all()
        assert parent_pid not in ps.pids()
        assert child_pid not in ps.pids()
示例#6
0
def test_this_is_really_our_pid():
    process = mock.Mock(spec=psutil.Process, pid=PID)
    process.username.return_value = USER1
    process.create_time.return_value = CREATE_TIME
    assert TRH.this_is_really_our_pid(process, process.username(),
                                      process.create_time())
    assert TRH.this_is_really_our_pid(
        process, process.username(),
        process.create_time() + TRH.MAX_START_TIME_DRIFT.as_(Time.SECONDS) - 1)
    assert not TRH.this_is_really_our_pid(process, 'user2',
                                          process.create_time())
    assert not TRH.this_is_really_our_pid(
        process, process.username(),
        process.create_time() + TRH.MAX_START_TIME_DRIFT.as_(Time.SECONDS) + 1)
    assert not TRH.this_is_really_our_pid(
        process, process.username(),
        process.create_time() -
        (TRH.MAX_START_TIME_DRIFT.as_(Time.SECONDS) + 1))
示例#7
0
def kill(args, options):
  """Kill task(s)

  Usage: thermos kill task_id1 [task_id2 ...]

  Regular expressions may be used to match multiple tasks.
  """
  if not args:
    print('Must specify tasks!', file=sys.stderr)
    return

  matched_tasks = tasks_from_re(args, options.root, state='active')

  if not matched_tasks:
    print('No active tasks matched.')
    return

  for task_id in matched_tasks:
    print('Killing %s...' % task_id, end='')
    TaskRunnerHelper.kill(task_id, options.root, force=True)
    print('done.')
示例#8
0
def test_garbage_collector(safe_rmtree, safe_delete):
    with temporary_dir() as sandbox, temporary_dir(
    ) as checkpoint_root, temporary_dir() as log_dir:

        path = TaskPath(root=checkpoint_root, task_id='test', log_dir=log_dir)

        touch(os.path.join(sandbox, 'test_file1'))
        touch(os.path.join(sandbox, 'test_file2'))
        safe_mkdir(
            os.path.dirname(path.given(state='finished').getpath('task_path')))
        safe_mkdir(os.path.dirname(path.getpath('runner_checkpoint')))
        touch(path.given(state='finished').getpath('task_path'))

        header = RunnerHeader(task_id='test', sandbox=sandbox, log_dir=log_dir)
        ckpt = TaskRunnerHelper.open_checkpoint(
            path.getpath('runner_checkpoint'))
        ckpt.write(RunnerCkpt(runner_header=header))
        ckpt.close()

        gc = TaskGarbageCollector(checkpoint_root, task_id='test')
        assert gc._state.header.log_dir == log_dir
        assert gc._state.header.sandbox == sandbox

        # erase metadata
        gc.erase_metadata()
        safe_delete.assert_has_calls([
            call(path.given(state='finished').getpath('task_path')),
            call(path.getpath('runner_checkpoint'))
        ],
                                     any_order=True)
        safe_rmtree.assert_has_calls([call(path.getpath('checkpoint_path'))])

        safe_delete.reset_mock()
        safe_rmtree.reset_mock()

        # erase logs
        gc.erase_logs()
        safe_rmtree.assert_has_calls([call(log_dir)])

        safe_delete.reset_mock()
        safe_rmtree.reset_mock()

        # erase sandbox
        gc.erase_data()

        safe_delete.assert_has_calls([
            call(os.path.join(sandbox, 'test_file1')),
            call(os.path.join(sandbox, 'test_file2'))
        ],
                                     any_order=True)
        safe_rmtree.assert_has_calls([call(sandbox)])
示例#9
0
def test_this_is_really_our_pid():
  process = mock.Mock(spec=psutil.Process, pid=PID)
  process.username.return_value = USER1
  process.create_time.return_value = CREATE_TIME
  assert TRH.this_is_really_our_pid(
      process,
      process.username(),
      process.create_time())
  assert TRH.this_is_really_our_pid(
      process,
      process.username(),
      process.create_time() + TRH.MAX_START_TIME_DRIFT.as_(Time.SECONDS) - 1)
  assert not TRH.this_is_really_our_pid(
      process,
      'user2',
      process.create_time())
  assert not TRH.this_is_really_our_pid(
      process,
      process.username(),
      process.create_time() + TRH.MAX_START_TIME_DRIFT.as_(Time.SECONDS) + 1)
  assert not TRH.this_is_really_our_pid(
      process,
      process.username(),
      process.create_time() - (TRH.MAX_START_TIME_DRIFT.as_(Time.SECONDS) + 1))
示例#10
0
def test_garbage_collector(safe_rmtree, safe_delete):
  with temporary_dir() as sandbox, temporary_dir() as checkpoint_root, temporary_dir() as log_dir:

    path = TaskPath(root=checkpoint_root, task_id='test', log_dir=log_dir)

    touch(os.path.join(sandbox, 'test_file1'))
    touch(os.path.join(sandbox, 'test_file2'))
    safe_mkdir(os.path.dirname(path.given(state='finished').getpath('task_path')))
    safe_mkdir(os.path.dirname(path.getpath('runner_checkpoint')))
    touch(path.given(state='finished').getpath('task_path'))

    header = RunnerHeader(task_id='test', sandbox=sandbox, log_dir=log_dir)
    ckpt = TaskRunnerHelper.open_checkpoint(path.getpath('runner_checkpoint'))
    ckpt.write(RunnerCkpt(runner_header=header))
    ckpt.close()

    gc = TaskGarbageCollector(checkpoint_root, task_id='test')
    assert gc._state.header.log_dir == log_dir
    assert gc._state.header.sandbox == sandbox

    # erase metadata
    gc.erase_metadata()
    safe_delete.assert_has_calls([
        call(path.given(state='finished').getpath('task_path')),
        call(path.getpath('runner_checkpoint'))], any_order=True)
    safe_rmtree.assert_has_calls([call(path.getpath('checkpoint_path'))])

    safe_delete.reset_mock()
    safe_rmtree.reset_mock()

    # erase logs
    gc.erase_logs()
    safe_rmtree.assert_has_calls([call(log_dir)])

    safe_delete.reset_mock()
    safe_rmtree.reset_mock()

    # erase sandbox
    gc.erase_data()

    safe_delete.assert_has_calls([
        call(os.path.join(sandbox, 'test_file1')),
        call(os.path.join(sandbox, 'test_file2'))], any_order=True)
    safe_rmtree.assert_has_calls([call(sandbox)])
示例#11
0
def test_scan_process():
    # TODO(jon): add more tests for successful cases; this really just looks for errors.

    assert TRH.scan_process(make_runner_state(cpid=None, pid=None),
                            PROCESS_NAME) == (None, None, set())

    with mock.patch(PSUTIL_PATH) as p_mock:

        class WrappedNoSuchProcess(psutil.NoSuchProcess):
            # psutil.NoSuchProcess exception requires an argument, but mock doesn't support that.

            def __init__(self):
                pass

        p_mock.side_effect = WrappedNoSuchProcess
        assert TRH.scan_process(make_runner_state(cpid=None),
                                PROCESS_NAME) == (None, None, set())
        assert TRH.scan_process(make_runner_state(pid=None),
                                PROCESS_NAME) == (None, None, set())

    with mock.patch(PSUTIL_PATH) as p_mock:
        p_mock.side_effect = psutil.Error
        assert TRH.scan_process(make_runner_state(cpid=None),
                                PROCESS_NAME) == (None, None, set())
        assert TRH.scan_process(make_runner_state(pid=None),
                                PROCESS_NAME) == (None, None, set())

    with mock.patch(TRH_PATH) as trh_mock:
        trh_mock.this_is_really_our_pid.returns = False
        assert TRH.scan_process(make_runner_state(),
                                PROCESS_NAME) == (None, None, set())

    with mock.patch(TRH_PATH) as trh_mock:
        trh_mock.this_is_really_our_pid.sideffect = psutil.Error
        assert TRH.scan_process(make_runner_state(),
                                PROCESS_NAME) == (None, None, set())
示例#12
0
def test_this_is_really_our_pid():
    process = mock_process(PID, USER1, uid=UID)
    assert TRH.this_is_really_our_pid(process, UID, USER1,
                                      process.create_time())
    assert TRH.this_is_really_our_pid(
        process, UID, USER1,
        process.create_time() + TRH.MAX_START_TIME_DRIFT.as_(Time.SECONDS) - 1)
    assert TRH.this_is_really_our_pid(
        process, UID, 'user2', process.create_time()), (
            'An equivalent UID is considered the same user.')
    assert not TRH.this_is_really_our_pid(
        process, UID + 1, USER1,
        process.create_time()), ('UIDs should not match.')
    assert not TRH.this_is_really_our_pid(
        process, UID, USER1,
        process.create_time() + TRH.MAX_START_TIME_DRIFT.as_(Time.SECONDS) +
        1), ('Process is outside of start time drift.')
    assert not TRH.this_is_really_our_pid(
        process, UID, USER1,
        process.create_time() -
        (TRH.MAX_START_TIME_DRIFT.as_(Time.SECONDS) + 1)), (
            'Process is outside of start time drift.')
    assert not TRH.this_is_really_our_pid(
        process, None, 'user2', process.create_time()
    ), ("If no uid is checkpointed but the username is different, we can't know it's ours."
        )

    process = mock_process(PID, USER1)
    assert not TRH.this_is_really_our_pid(
        process, UID, USER1, process.create_time()
    ), ('We cannot validate whether this is our process without a process UID.'
        )
    assert TRH.this_is_really_our_pid(
        process, None, USER1,
        process.create_time()), ('Previous behavior is preserved.')

    process = mock_process(PID, username=KeyError('Unknown user'), uid=UID)
    assert TRH.this_is_really_our_pid(process, UID, USER1,
                                      process.create_time())
    assert not TRH.this_is_really_our_pid(process, None, USER1,
                                          process.create_time())
    assert TRH.this_is_really_our_pid(
        process, UID, 'user2', process.create_time()
    ), ('If the user has been renamed but the UID is the same, this is still our process.'
        )
示例#13
0
def test_this_is_really_our_pid_root():
    # Test the case where a process has a non root uid but the uid in the header
    # was root (meaning that it `setuid` itself)
    process = mock_process(PID, USER1, uid=UID)
    assert TRH.this_is_really_our_pid(process, ROOT_UID, USER1,
                                      process.create_time())
示例#14
0
def test_this_is_really_our_pid():
  process = mock_process(PID, USER1, uid=UID)
  assert TRH.this_is_really_our_pid(process, UID, USER1, process.create_time())
  assert TRH.this_is_really_our_pid(process, UID, USER1,
      process.create_time() + TRH.MAX_START_TIME_DRIFT.as_(Time.SECONDS) - 1)
  assert TRH.this_is_really_our_pid(process, UID, 'user2', process.create_time()), (
      'An equivalent UID is considered the same user.')
  assert not TRH.this_is_really_our_pid(process, UID + 1, USER1, process.create_time()), (
      'UIDs should not match.')
  assert not TRH.this_is_really_our_pid(process, UID, USER1,
      process.create_time() + TRH.MAX_START_TIME_DRIFT.as_(Time.SECONDS) + 1), (
          'Process is outside of start time drift.')
  assert not TRH.this_is_really_our_pid(process, UID, USER1,
      process.create_time() - (TRH.MAX_START_TIME_DRIFT.as_(Time.SECONDS) + 1)), (
          'Process is outside of start time drift.')
  assert not TRH.this_is_really_our_pid(process, None, 'user2', process.create_time()), (
      "If no uid is checkpointed but the username is different, we can't know it's ours.")

  process = mock_process(PID, USER1)
  assert not TRH.this_is_really_our_pid(process, UID, USER1, process.create_time()), (
      'We cannot validate whether this is our process without a process UID.')
  assert TRH.this_is_really_our_pid(process, None, USER1, process.create_time()), (
      'Previous behavior is preserved.')

  process = mock_process(PID, username=KeyError('Unknown user'), uid=UID)
  assert TRH.this_is_really_our_pid(process, UID, USER1, process.create_time())
  assert not TRH.this_is_really_our_pid(process, None, USER1, process.create_time())
  assert TRH.this_is_really_our_pid(process, UID, 'user2', process.create_time()), (
      'If the user has been renamed but the UID is the same, this is still our process.')
示例#15
0
def test_this_is_really_our_pid_root():
  # Test the case where a process has a non root uid but the uid in the header
  # was root (meaning that it `setuid` itself)
  process = mock_process(PID, USER1, uid=UID)
  assert TRH.this_is_really_our_pid(process, ROOT_UID, USER1, process.create_time())