예제 #1
0
    def __init__(self, feedback_queue, file_name):
        self._feedback_queue = feedback_queue

        with open(file_name, 'r') as f:
            config_string = f.read()

        new_config = config.string_to_python(config_string)
        available_tasks = api.get_tasks(False)

        for task in new_config:
            if task['type'] not in available_tasks:
                self._feedback_queue.put(
                    (common.api_exception_status,
                     'task ' + task['type'] + ' does not exist in '
                     'this build'))
                continue

            try:
                api.new_task(task)
            except KeyError as e:
                self._feedback_queue.put(
                    (common.api_exception_status,
                     'task ' + task['type'] + ' missing required key '
                     '%s from its configuration' % str(e)))
            except ValueError as e:
                self._feedback_queue.put(
                    (common.api_exception_status,
                     'task ' + task['type'] + ' has at least one '
                     'bad value for a config option:\n%s' % str(e)))

        thread = threading.Thread(target=self._handle_communication)
        thread.daemon = True
        thread.start()
예제 #2
0
    def __call__(self):
        now = time.time()
        slept = now - self._last_check
        self._last_check = now

        trigger_probability = slept / self._time_per_trigger
        if random.random() < trigger_probability:
            self._triggered += 1
            api.new_task(self._task)
예제 #3
0
    def _check_regexes(self, body):
        """ Check if any of the configured regexes match against an email.

        Args:
            body (str): The string of an email body.
        """
        for regex in self._regexes:
            if regex.search(body):
                api.new_task(self._regexes[regex])
예제 #4
0
def test_good_cases(task, good_cases):
    """ Used to test properly formatted configs. Prints feedback from the task.

    Args:
        task: A task dictionary mapping 'type' to the task name (e.g. 'ssh')
        good_cases: A list of tuples of the form ('config_name', config). config should be properly formatted.
    """
    sim = usersim.UserSim(True)
    for config_name, config in good_cases:
        task['config'] = config
        api.new_task(task)
        print('Correctly accepted %s' % config_name)
예제 #5
0
    def _check_links(self, body):
        """ Check if a link exists in an email, and if so checks if we should open it.

        Args:
            body (str): The string of an email body.
        """
        # As useful as they are, regular expressions are ugly. If the name doesn't give it away, this matches a URL.
        url_regex = '([0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}|(((news|telnet|nttp|file|http|ftp|https)://)' \
                    '|(www|ftp)[-A-Za-z0-9]*\\.)[-A-Za-z0-9/\\.]+)(:[0-9]*)?'
        match = re.search(url_regex, body)

        if match and random.randint(1, 100) <= self._config['open_links']:
            # There was a link in the email and we chose to click it.
            link_config = {'type': 'firefox', 'config': {'sites': [match.group()]}}
            api.new_task(link_config)
예제 #6
0
def run_test():
    test_1 = {'type': 'test', 'config': {}}
    test_2 = {'type': 'testfeedback', 'config': {}}
    config = {'type': 'sequence', 'config': {'tasks': [test_1, test_2]}}

    sim = usersim.UserSim(True)

    task_id = api.new_task(config)

    print('Cycle 1')
    sim.cycle()

    print(api.status_task(task_id))

    print('Cycle 2')
    sim.cycle()

    print(api.status_task(task_id))

    print('Cycle 3')
    sim.cycle()

    # The sequence task may be stopped here, if it goes after the testfeedback task.
    print(api.status_task(task_id))

    print('Cycle 4')
    sim.cycle()

    # Otherwise it would be stopped here.
    print(api.status_task(task_id))
예제 #7
0
def test_bad_value_cases(task, bad_value_cases):
    """ Test configs with invalid values.

    Args:
        task (dict): A task config dict. task['config'] will be overwritten.
        bad_value_cases (list(tuple)): List of tuples of the form ('config_name', config), where config
            contains a key:value pair with an invalid value.
    """
    for config_name, config in bad_value_cases:
        task['config'] = config
        try:
            api.new_task(task)
        except ValueError:
            print('Correctly rejected %s' % config_name)
        else:
            raise AssertionError('Incorrectly accepted %s' % config_name)
예제 #8
0
def run_test():
    # Calculate the trigger time to be 10 seconds from now.
    trigger_time = datetime.datetime.now() + datetime.timedelta(seconds=5)
    trigger_time = trigger_time.time()
    time = '{}{}'.format(str(trigger_time.hour), str(trigger_time.minute))
    seconds = float(trigger_time.second)
    print('Trigger time is {}'.format(str(trigger_time)))

    config = {'type': 'attime',
              'config': {'time': str(time),
                         'seconds': seconds,
                         'task': {'type': 'test',
                                  'config': {}}}}

    sim = usersim.UserSim(True)

    task_id = api.new_task(config)

    result = sim.cycle()
    print(sim.status_task(task_id)['status'])

    while True:
        result = sim.cycle()

        if len(result) > 1:
            print(result)

        # Only break once we see the nested task has been stopped.
        if api.status_task(2)['state'] == api.States.STOPPED:
            break
예제 #9
0
def run_test():
    test_1 = {'type': 'test',
              'config': {}}
    test_2 = {'type': 'testfeedback',
              'config': {}}
    config = {'type': 'all',
              'config': {'tasks': [test_1, test_2]}}

    sim = usersim.UserSim(True)

    task_id = api.new_task(config)

    print('Cycle 1')
    sim.cycle()

    print(api.status_task(task_id))

    print('Cycle 2')
    sim.cycle()

    # If both tasks go before the all task, it will be stopped here.
    print(api.status_task(task_id))

    print('Cycle 3')
    sim.cycle()

    # Otherwise, it will be stopped here.
    print(api.status_task(task_id))
예제 #10
0
def run_test():
    reps = 10
    config = {
        'type': 'frequency',
        'config': {
            'frequency': 2000,
            'repetitions': reps,
            'task': {
                'type': 'test',
                'config': {}
            }
        }
    }

    sim = usersim.UserSim(True)

    task_id = api.new_task(config)

    while True:
        result = sim.cycle()

        if len(result) > 1:
            print(result)

        # Break once the final task has been stopped.
        if api.status_task(task_id + reps)['state'] == api.States.STOPPED:
            break
예제 #11
0
def test_good_cases(task, good_cases):
    """ Test properly formatted configs.

    Args:
        task (dict): A task config dict. task['config'] will be overwritten.
        good_cases (list(tuple)): List of tuples of the form ('config_name', config), where config
            is a valid config for the task.
    """
    for config_name, config in good_cases:
        task['config'] = config
        sim = usersim.UserSim(True)
        api.new_task(task)
        # Running this one is way too annoying.
        #result = sim.cycle()
        #for item in result:
        #    print(item)
        print('Correctly accepted %s' % config_name)
예제 #12
0
 def __call__(self):
     if not self._waiting and self._index < len(self._tasks):
         # Start the next task and wait for it.
         self._current = api.new_task(self._tasks[self._index])
         self._waiting = True
         self._index += 1
     if api.status_task(self._current)['state'] == api.States.STOPPED:
         self._waiting = False
예제 #13
0
def test_bad_key_cases(task, bad_key_cases):
    """ Used to test configs with missing keys. This function will raise an assertion error if validate incorrectly
    accepts a bad config dictionary.

    Args:
        task: A task dictionary mapping 'type' to the task name (e.g. 'ssh')
        bad_key_cases: A list of tuples of the form ('config_name', config). config should be missing at least one key.

    Raises:
        AssertionError: If api.new_task does not raise a KeyError
    """
    for config_name, config in bad_key_cases:
        task['config'] = config
        try:
            api.new_task(task)
            raise AssertionError('Incorrectly accepted %s' % config_name)
        except KeyError:
            print('Correctly rejected %s' % config_name)
예제 #14
0
    def _handle_communication(self):
        """ Periodically check if there are any new config files available or if there is any feedback that should be
        forwarded.
        """
        while True:
            new_config = self._receive()
            if new_config:
                available_tasks = api.get_tasks(False)

                for task in new_config:
                    # As in the _receive method, it's okay for the feedback messages in here to stay in case feedback is
                    # used with boost in later versions.
                    if task['type'] not in available_tasks:
                        self._feedback_queue.put(
                            (common.api_exception_status,
                             'task ' + task['type'] + ' does not '
                             'exist in the current build'))
                        continue

                    try:
                        api.new_task(task)
                    except KeyError as e:
                        self._feedback_queue.put(
                            (common.api_exception_status,
                             'task ' + task['type'] + ' missing '
                             'required key %s from its configuration' %
                             e.message))
                    except ValueError as e:
                        self._feedback_queue.put(
                            (common.api_exception_status,
                             'task ' + task['type'] + ' has at least '
                             'one bad value for a config option:\n%s' %
                             e.message))

            self._send()

            # So the CPU isn't running at 100%.
            time.sleep(5)
예제 #15
0
def run_test():
    seconds = 10
    task = {'type': 'test', 'config': {}}

    config = {'type': 'delay', 'config': {'task': task, 'seconds': seconds}}

    sim = usersim.UserSim(True)

    task_id = api.new_task(config)

    while True:
        sim.cycle()
        if api.status_task(2)['state'] == api.States.STOPPED:
            print('Nested delay task complete.')
            break
예제 #16
0
    def __call__(self):
        if not self._started:
            for task in self._tasks:
                task_id = api.new_task(task)
                self._task_ids.add(task_id)
            self._started = True

        self._stopped_task_ids = set()
        for task_id in self._task_ids:
            # Check that all nested tasks have stopped.
            if api.status_task(task_id)['state'] == api.States.STOPPED:
                # Would do self._task_ids.remove here, but we can't modify the data structure while iterating over it.
                self._stopped_task_ids.add(task_id)
            else:
                break
        else:
            # Since they are uncommon, the else part of a for-else executes when the for loop completes without a break.
            self._done = True

        # No point repeating work that's already been completed.
        self._task_ids = self._task_ids - self._stopped_task_ids
예제 #17
0
def test_new_task():
    task = {'type': 'test', 'config': {}}
    assert api.new_task(task, reset=True) == 1
예제 #18
0
 def __call__(self):
     if datetime.datetime.now() >= self._trigger_time:
         self._triggered = True
         api.new_task(self._task)