普通文本  |  137行  |  4.47 KB

#! /usr/bin/python

"""A simple heartbeat client.

Executes heartbeats against a simple_heartbeat_server running on the give
--server address and deserializes records into an in memory sqlite database.

Usage:
1. heartbeat_client.py
    --server http://localhost:8080
    --board lumpy

    Perform a heartbeat against the given server for the given board,
    and deserialize records into a sqlite database.

2. heartbeat_client.py
    --server http://localhost:8080
    --board lumpy
    --host_limit 1 --job_limit 100

    Do the same as 1, but instruct the server to limit the hosts to 1
    and jobs to 100. This is useful for debugging issues with only jobs/hosts.
"""


from json import decoder
import argparse
import sys
import urllib2

import common

from autotest_lib.scheduler.shard import simple_heartbeat_server
from autotest_lib.frontend import setup_django_environment
from autotest_lib.frontend.afe import frontend_test_utils
from autotest_lib.frontend.afe import models

json_decoder = decoder.JSONDecoder()


class HeartbeatHandler(frontend_test_utils.FrontendTestMixin):
    """Performs heartbeats and deserializes into an in memory database."""

    _config_section = 'AUTOTEST_WEB'


    def __init__(self, server):
        """Initialize a heartbeat server.

        @param server: The address of a simple_heartbeat_server.
        """
        self.server = server
        self._frontend_common_setup(setup_tables=True, fill_data=False)


    @staticmethod
    @simple_heartbeat_server.time_call
    def get_heartbeat_packet(server, board, host_limit, job_limit):
        """Perform the heartbeat.

        Constructs a url like: http://localhost:8080/lumpy?raw&host_limit=3
        and does a urlopen.

        @param server: The address of a simple_heartbeat_server.
        @param host_limit: The number of hosts to include in the heartbeat.
        @param job_limit: The number of jobs to include in the heartbeat.

        @return: A string containing the heartbeat packet.
        """
        url = '%s/%s?raw' % (server, board)
        if job_limit:
            url = '%s&job_limit=%s' % (url, job_limit)
        if host_limit:
            url = '%s&host_limit=%s' % (url, host_limit)
        print 'Performing heartbeat against %s' % url
        return urllib2.urlopen(url).read()


    @staticmethod
    @simple_heartbeat_server.time_call
    def deserialize_heartbeat(packet):
        """Deserialize the given heartbeat packet into an in memory database.

        @param packet: A string representing the heartbeat packet containing
                jobs and hosts.

        @return: The json decoded heartbeat.
        """
        response = json_decoder.decode(packet)
        [models.Host.deserialize(h) for h in response['hosts']]
        [models.Job.deserialize(j) for j in response['jobs']]
        return response


    def perform_heartbeat(self, board, host_limit, job_limit):
        """Perform a heartbeat against the given server, for the given board.

        @param board: Boardname, eg: lumpy.
        @param host_limit: Limit number of hosts retrieved.
        @param job_limit: Limit number of jobs retrieved.
        """
        timing, packet = self.get_heartbeat_packet(
                self.server, board, host_limit, job_limit)
        print 'Time to perform heartbeat %s' % timing
        timing, response = self.deserialize_heartbeat(packet)
        print 'Time to deserialize hearbeat %s' % timing
        print ('Jobs: %s, Hosts: %s' %
                (len(response['jobs']), len(response['hosts'])))


def _parse_args(args):
    parser = argparse.ArgumentParser(
            description='Start up a simple heartbeat client.')
    parser.add_argument(
            '--server', default='http://localhost:8080',
            help='Address of a simple_heartbeat_server to heartbeat against.')
    parser.add_argument(
            '--board', default='lumpy',
            help='Heartbeats can only be performed '
                 'against a specific board, eg: lumpy.')
    parser.add_argument(
            '--host_limit', default='',
            help='Limit hosts in the heartbeat.')
    parser.add_argument(
            '--job_limit', default='',
            help='Limit jobs in the heartbeat.')
    args = parser.parse_args(args)
    args.board = args.board.lstrip(
            simple_heartbeat_server.BoardHandler.board_prefix)
    return args


if __name__ == '__main__':
    args = _parse_args(sys.argv[1:])
    HeartbeatHandler(args.server).perform_heartbeat(
            args.board, args.host_limit, args.job_limit)