Example #1
0
File: core.py Project: shakhat/act
def apply_action_filter(action_filter):
    if not action_filter:
        for a in registry.get_actions():
            yield a
    else:
        for action in registry.get_actions():
            if re.match(action_filter, str(action)):
                yield action
Example #2
0
File: core.py Project: shakhat/act
def process(scenario, interval):
    # the entry-point to engine
    registry.init()
    metrics.clear()

    # initialize the world
    default_items = [item_pkg.Item('root')]

    world = world_pkg.World()
    for item in default_items:
        world.put(item)

    # global section
    globals = scenario.get('global') or {}
    global_limits = globals['limits'] if 'limits' in globals else {}

    for action in registry.get_actions():
        limit = action.get_limit()
        if limit:
            global_limits[str(action)] = limit

    # play!
    play = scenario['play']

    LOG.info('Playing scenario "%s"', scenario['title'])

    # add tear down
    play.append(dict(concurrency=0, duration=1000, title='tear down'))

    task_results = []
    task_queue = rq.Queue(consts.TASK_QUEUE_NAME)
    failed_queue = rq.Queue(consts.FAILURE_QUEUE_NAME)
    failed_queue.empty()
    metrics.set_metric(metrics.METRIC_TYPE_SUMMARY, 'failures', 0,
                       mood=metrics.MOOD_HAPPY)

    failures = 0
    counter = 0
    actions_counter = collections.defaultdict(int)

    for idx, stage in enumerate(play):
        title = stage.get('title') or ('stage #%s' % idx)
        duration = stage['duration']
        concurrency = stage['concurrency']

        LOG.info('Playing stage "%s" duration: %s, concurrency: %s',
                 title, duration, concurrency)

        limits = stage.get('limits') or {}
        limits.update(global_limits)

        watch = timeutils.StopWatch(duration=duration)
        watch.start()

        while not watch.expired():

            pending = []
            for task_result in task_results:
                operation = task_result.return_value

                if operation is None:
                    pending.append(task_result)
                else:
                    handle_operation(operation, world)

                    counter += 1
                    metrics.set_metric(metrics.METRIC_TYPE_SUMMARY,
                                       'operation', counter)

            addition = concurrency - len(pending)
            if addition > 0:  # need to add more tasks
                for i in range(addition):
                    actions = apply_action_filter(stage.get('filter'))
                    actions = apply_limits_filter(limits, actions,
                                                  actions_counter)
                    next_task = produce_task(world, actions)
                    if not next_task:
                        break  # no more actions possible
                    pending.append(task_queue.enqueue(do_action, next_task))
                    actions_counter[str(next_task.action)] += 1

            task_results = pending

            if len(failed_queue) > failures:
                failures = len(failed_queue)
                metrics.set_metric(metrics.METRIC_TYPE_SUMMARY, 'failures',
                                   failures, mood=metrics.MOOD_SAD)

            metrics.set_metric(metrics.METRIC_TYPE_SUMMARY, 'backlog',
                               len(task_results))

            for action, counter in actions_counter.items():
                metrics.set_metric(metrics.METRIC_TYPE_ACTIONS, action,
                                   counter)

            for item_type, counter in world.get_counters().items():
                metrics.set_metric(metrics.METRIC_TYPE_OBJECTS, item_type,
                                   counter)

            if len(task_results) == 0:  # no existing tasks and no to add
                break  # tear down finished

            time.sleep(interval)

    LOG.info('World: %s', world)