Пример #1
0
    def get(self, hostname_status, hostname):
        """GET request for information about hostname

    Args:
        hostname_status: binary representation of a retired system.
        hostname: string name of system hostname passed through url.

    Returns:
        Hostname data as represented in the hostnames table.

        Success:
            Status Code: 200 OK
                * return hostnames table entry.
        Failure:
            Status Code: 404 Not Found
                * hostname does not exist or invalid hostname_status.
    """
        validate(hostname=hostname,
                 hostname_status=hostname_status,
                 http_error_code=404)
        # query for hostname information
        hostnames_list = get_table('hostnames',
                                   hostname=hostname,
                                   hostname_status=hostname_status)

        return {'hostnames': hostnames_list}, 200
Пример #2
0
    def get(self, tests_runs_id, tests_logs_id):
        """Download test log file."""
        validate(tests_runs_id=tests_runs_id, tests_logs_id=tests_logs_id)
        tests_log = get_data_by_id('tests_logs', tests_logs_id)

        if tests_runs_id != tests_log['tests_runs_id']:
            # invalid url - no log with under given tests_runs id
            error_msg = 'tests_runs_id=\'{}\' with tests_logs_id=\'{}\' Not Found.'
            abort(404, message=error_msg.format(tests_runs_id, tests_logs_id))

        # absolute path to file log
        filepath = tests_log['location']
        # unique name of file for log in disk
        uuid_filename = filepath.split('/')[-1]
        # path to folder that hold the log file in disk
        upload_folder = filepath.replace(uuid_filename, '')
        # user friendly name of test log
        friendly_filename = tests_log['files_name']

        file_attachment = send_from_directory(
            upload_folder,
            uuid_filename,
            as_attachment=True,
            attachment_filename=friendly_filename)
        return file_attachment
Пример #3
0
    def get(self, hostname_status, hostname):
        """GET request for all info on tests_runs associated with the hostname.

    Args:
        hostname: string name of system hostname passed through url.

    Returns:
        Table dictionary of tests_runs with applied query paramters for filtering.

        Success:
            Status Code: 200 OK
                * return tests runs information
        Failure:
            Status Code: 404 Not Found
                * Invalid url - invalid hostname_status or hostname
    """
        validate(hostname_status=hostname_status,
                 hostname=hostname,
                 http_error_code=404)
        parser = reqparse.RequestParser()

        add_filter_query_parameters(parser, 'tests_runs')
        args = parser.parse_args()
        filter = parse_filter_query_parameters(args, 'tests_runs')

        # overwrite filter with static info from uri
        static_params = zip_params(hostname=hostname,
                                   hostname_status=hostname_status)
        filter.update(static_params)

        # query for filtered test-history
        tests_runs = get_table('tests_runs', constraints=filter)

        return {'tests_runs': tests_runs}, 200
    def post(self, hostname_status):
        """POST request to add a hostname to the database.
    
    Args:
        hostname_status: string annotation of a system for a binary representation of an 'active' 

    Returns:
        Dictionary of inserted hostname with keys coinciding column names of the table hostnames.

        Success: 
            Status Code: 201 Created
                * hostname inserted into the database.
        Failure: 
            Status Code: 404 Not Found
                * status provided does not exist.
                * required arguments not supplied in request.
            Status Code: 405 Method Not Allowed
                * attempt to add a non-active hostname not allowed.
            Status Code: 409 Conflict
                * duplicate insertion for active hostname not allowed.
    """
        validate(hostname_status=hostname_status, http_error_code=404)

        # require 'hostname' parameter from request.
        parser = reqparse.RequestParser()
        parser.add_argument('hostname', type=str, required=True)
        args = parser.parse_args()

        if is_retired(hostname_status):
            # Hostnames added to the database must be active, return status code 405 Method Not Allowed
            return {
                'message': 'The method is not allowed for the requested URL.'
            }, 405

        # check if working hostname already exists in db.
        existing_hostname = get_table('hostnames',
                                      hostname=args['hostname'],
                                      hostname_status=hostname_status)

        if existing_hostname:
            # active hostname already exists, returning conflict status code 409.
            return {
                'message':
                '{} hostname, {}, already exists. Insertion not allowed.'.
                format(hostname_status, args['hostname'])
            }, 409

        # otherwise, insert hostname into db.
        inserted_hostname = insert_hostname(args['hostname'])

        return inserted_hostname
    def post(self):
        """POST request to begin testrun on active 'hostname' with 'test'.

    Returns:
        Success:
            Status Code: 201 Created
                * inserted tests_runs dictionary row
        Failure:
            Status Code: 409 Conflict
                * hostname or test name supplied not found.
                * attempt to run a test on a retired hostname.
    """
        parser = reqparse.RequestParser()

        parser.add_argument('hostname', type=str, required=True)
        parser.add_argument('tests_name', type=str, required=True)
        args = parser.parse_args()

        # validate that hostname and tests name exist in the db
        validate(hostname=args['hostname'],
                 tests_name=args['tests_name'],
                 http_error_code=409)

        # validate active hostname
        active_hostname = get_table('hostnames',
                                    hostname=args['hostname'],
                                    retiredflag=HOSTNAME_ACTIVE)
        if not active_hostname:
            # throw 409 Conflict error for attempt to run a test on a retired system
            error_msg = 'System \'{}\' must be active.'.format(
                args['hostname'])
            abort(409, message={'hostname': error_msg})

        # if hostname has no running tests, directly execute test on hostname else queue test
        running_tests = get_running_tests(hostname=args['hostname'])
        # assume hostname is busy and queue test
        statuses_id = STATUS_QUEUED
        if not running_tests:
            # hostname server ready to directly host a test_run
            statuses_id = STATUS_STARTED

        inserted_tests_run = insert_tests_run(hostname=args['hostname'],
                                              tests_name=args['tests_name'],
                                              statuses_id=statuses_id)

        if statuses_id == STATUS_QUEUED:
            # insert to queue
            insert_tests_runs_queue(inserted_tests_run['id'])

        return inserted_tests_run, 201
Пример #6
0
  def post(self, tests_runs_id):
    """POST request to upload a log associated with a testsrun.

    Args: 
        tests_runs_id: integer representation of a unique testsrun passed thorugh url.
    """ 
    validate(tests_runs_id=tests_runs_id, http_error_code=404)

    inserted_tests_logs = []
    for a_file in request.files.getlist('file'):
      if a_file.filename:
        # insert file log to database and disk
        tests_logs_id = insert_tests_log(tests_runs_id, a_file)
        data = get_data_by_id('tests_logs', tests_logs_id, raw=True)
        inserted_tests_logs.append(data)        
    return {'tests_logs' : inserted_tests_logs}, 201
Пример #7
0
  def put(self, tests_runs_id):
    """Updates testsruns table row data.
    
    Returns:
        Dictionary of updated tests_runs row.

        Success:
            Status Code: 200 OK
                * tests_runs row is updated.
        Failure:
            Status Code: 404 Not Found
                * invalid url - tests_runs_id not found.
                * 
    """
    validate(tests_runs_id=tests_runs_id, http_error_code=404)

    # require status name parameter from request.
    parser = reqparse.RequestParser()
    parser.add_argument('statuses_name', type=str)
    parser.add_argument('config', type=str)
    parser.add_argument('notes', type=str)
    parser.add_argument('scratch', type=str)
    args = parser.parse_args()

    statuses = {}
    if args['statuses_name']:
      # get statuses full profile (id, name)
      validate(statuses_name=args['statuses_name'], http_error_code=409)
      data = get_table('statuses', statuses_name=args['statuses_name'])
      statuses = data[0]

    values = {}
    for field in get_table_fields('tests_runs'):
      # set up tests_runs fields to be updated with args
      if field in args and args[field]:
        values.update({field : args[field]})
      elif field == 'statuses_id' and statuses:
        values.update({field : statuses['id']})

    if not values:
      # no data to updated
      abort(400, message='At least one parameter is required: {}'.format(args.keys()))

    updated_tests_runs = update('tests_runs', tests_runs_id, values)
    return updated_tests_runs, 200
    def get(self, tests_runs_id):
        """GET request for (hostname, tests name, start time, end time, notes, config, scratch)
    on testsrun with url passed 'id'

    Args:
        tests_runs_id : Integer identification of a specific testsrun in interest passed 
                        through url.
    Returns:
        Success:
            Status Code: 200 OK
                * table row dictionary from 'tests_runs' with row id = 'id'.
        Failure:
            Status Code: 404 Not Found
                * testsruns row 'id' does not exists in database.
    """
        validate(tests_runs_id=tests_runs_id, http_error_code=404)
        tests_run = get_table('tests_runs', tests_runs_id=tests_runs_id)
        return tests_run
Пример #9
0
  def delete(self, tests_runs_id):
    """Delete tests_log file from disk and db."""
    validate(tests_runs_id=tests_runs_id, http_error_code=404)
    # require tests_logs_id paramter in POST body 
    parser = reqparse.RequestParser()
    parser.add_argument('tests_logs_id', type=int, required=True)
    args = parser.parse_args()
    # validate tests logs id exists
    validate(tests_logs_id=args['tests_logs_id'], http_error_code=404)

    tests_log = get_data_by_id('tests_logs', args['tests_logs_id'])
    if tests_runs_id != tests_log['tests_runs_id']:
      # log id does not belong to tests_run - conflict
      error_msg = 'tests_runs_id=\'{}\' with tests_logs_id=\'{}\' Not Found.'
      abort(409, message=error_msg.format(tests_runs_id, args['tests_logs_id']))

    # delete log from disk and db
    deleted_log = delete_tests_log(args['tests_logs_id'])
    return deleted_log
Пример #10
0
    def get(self, hostname_status):
        """GET request for all systems labeled as given by the 'hostname_status' 
    
    Args:
        hostname_status: string annotation of a system for a binary representation of an 'active' 
                         or 'retired' hostname.
    
    Returns:
        Dictoinary of the hostnames table with a filtered hostname_status.

        Success:
            Status Code: 200 OK
                * valid hostname_status provided.
        Failure:
            Status Code: 404 Not Found 
                * hostname_status provided unknown - not {active, retired} - invalid url.
    """
        validate(hostname_status=hostname_status, http_error_code=404)
        # Get all hostnames with given retired hostname status
        hostnames_table = get_table('hostnames',
                                    hostname_status=hostname_status)

        return {'hostnames': hostnames_table}, 200
Пример #11
0
 def get(self, tests_runs_id):
   """GET request for tests_logs_ids that contain the fileblobs associated with testsruns_id""" 
   validate(tests_runs_id=tests_runs_id, http_error_code=404)
   tests_logs = get_table('tests_logs', tests_runs_id=tests_runs_id, raw=True)
   return {'tests_logs' : tests_logs}, 200
Пример #12
0
    def delete(self, hostname_status):
        """DELETE the hostname by setting the retired flag to True.

    Args:
        hostname_status: string annotation of a system to show retired status. 

    Returns:
        Dictionary of deleted hostname with keys coinciding the column names of table hostnames.

        Success:
            Status Code: 200 OK
                * hostname deleted.
        Failure: 
            Status Code: 404 Not Found
                * invalid url - hostname_status is not valid.
            Status Code: 400  Bad Request
                * no parameters were passed in the JSON body to the request.
            Status Code: 405 Method Not Allowed
                * attempt to do a DELETE request on invalid hostname_status in url
            Status Code: 409 Conflict
                * hostname did not exist in the database.
                * hostname is marked as retired in the database.
                * active hostname is busy with running tests.
    """
        validate(hostname_status=hostname_status, http_error_code=404)

        if is_retired(hostname_status):
            # only remove active hostnames; return 405 Method Not Allowed
            return {
                'message': 'The method is not allowed for the requested URL.'
            }, 405

        # require 'hostname' parameter from request.
        parser = reqparse.RequestParser()
        parser.add_argument('hostname', type=str)
        parser.add_argument('hostnames_id', type=int)
        args = parser.parse_args()

        if args['hostname'] is None and args['hostnames_id'] is None:
            # at least one argument is required otherwise throw 400 Bad Request.
            errors = {
                'hostname': 'Missing parameter in JSON body',
                'hostnames_id': 'Missing parameter in JSON body',
                'message': 'At least one paramter is required',
            }
            abort(400, message=errors)

        # validate that hostname info exists in the db
        validate(hostname=args['hostname'],
                 hostnames_id=args['hostnames_id'],
                 http_error_code=409)

        # validate that the hostname is active
        active_hostname = get_table('hostnames',
                                    hostname=args['hostname'],
                                    hostnames_id=args['hostnames_id'],
                                    hostname_status=hostname_status)

        if not active_hostname:
            # hostname is not active - validation check failed.
            supplied_args = {
                key: value
                for key, value in args.items() if value is not None
            }
            error_msg = 'No active hostname found with supplied args: {}'.format(
                supplied_args)
            abort(409, message=error_msg)

        # if hostname is running tests - abort DELETE request
        running_tests = get_running_tests(hostname=args['hostname'],
                                          hostnames_id=args['hostnames_id'])

        if running_tests:
            # system currently running tests - throw 409 Conflict
            error_msg = 'System is Busy. Currently processing {} tests.'.format(
                len(running_tests))
            errors = {args['hostname']: error_msg}
            abort(409, message=errors)

        # internally hostnames_id takes precedence over hostname string
        hostnames_deleted = delete_hostname(hostnames_id=args['hostnames_id'],
                                            hostname=args['hostname'])

        return {'hostnames': hostnames_deleted}, 200