Example #1
0
def test_future_instances(param):
    """Test instance events generate usage summary results for correct tags.

    :id: f3c84697-a40c-40d9-846d-117e2647e9d3
    :description: Test combinations of image tags, start/end events, and the
        resulting counts from the summary report API.
    :steps:
        1) Add a cloud account
        2) Insert instance, image, and event data
        3) GET from the account report endpoint
    :expectedresults:
        - The instance, image, RHEL, and Openshift counts match the expectation
    """
    user = utils.create_user_account()
    auth = utils.get_auth(user)
    acct = inject_aws_cloud_account(user['id'], acct_age=param.acct_age)
    start, end = 0, None

    client = api.Client(authenticate=False)

    events = [start]
    if end:
        events.append(end)
    inject_instance_data(acct['id'], '', events)

    # Set date range for 30 days in the past
    start, end = utils.get_time_range(-30)
    params = {
        'start': start,
        'end': end,
    }
    response = client.get(urls.REPORT_ACCOUNTS, params=params, auth=auth)

    account = response.json()['cloud_account_overviews'][0]
    acct_creation = datetime.today() - timedelta(days=param.acct_age)

    start, end = utils.get_time_range(-30, formatted=False)
    if acct_creation < start:
        info = 'Account created before start of window'
    elif acct_creation > end:
        info = 'Account newer than window'
    else:
        info = 'Account created during window'

    assert account['cloud_account_id'] == acct['aws_account_id']

    if param.unknown:
        exp = None
    else:
        exp = 0
    assert account['images'] == exp, info
    assert account['instances'] == exp, info
    assert account['rhel_instances'] == exp, info
    assert account['openshift_instances'] == exp, info
Example #2
0
def test_image_report_empty():
    """Test accounts without any instance or image report has empty summary.

    :id: 2a152ef6-fcd8-491c-b3cc-bda81699453a
    :description: Test that an account without any instances or images shows up
        in the results with 0 counts.
    :steps:
        1) Add a cloud account
        2) GET from the image report endpoint
    :expectedresults:
        - An empty list is returned
    """
    user = utils.create_user_account()
    auth = utils.get_auth(user)
    acct = inject_aws_cloud_account(user['id'])
    client = api.Client(authenticate=False)

    report_start, report_end = utils.get_time_range()
    params = {
        'start': report_start,
        'end': report_end,
        'account_id': acct['id'],
    }
    response = client.get(urls.REPORT_IMAGES, params=params, auth=auth)

    images = response.json()['images']

    assert images == [], repr(images)
Example #3
0
def test_list_accounts_empty(create_user_account):
    """Test accounts without any instance or image history have empty summaries.

    :id: 2a152ef6-fcd8-491c-b3cc-bda81699453a
    :description: Test that an account without any instances or images shows up
        in the results with 0 counts.
    :steps:
        1) Add a cloud account
        2) GET from the account report endpoint
    :expectedresults:
        - The account is in the response and matches the created account
        - Instances, images, RHEL, and Openshift all have 0 counts
    """
    user = create_user_account()
    auth = utils.get_auth(user)
    acct = inject_aws_cloud_account(user['id'])
    client = api.Client(authenticate=False)

    start, end = utils.get_time_range()
    params = {
        'start': start,
        'end': end,
    }
    response = client.get(urls.REPORT_ACCOUNTS, params=params, auth=auth)

    account = response.json()['cloud_account_overviews'][0]

    assert account['cloud_account_id'] == acct['aws_account_id']
    assert account['images'] == 0, repr(account)
    assert account['instances'] == 0, repr(account)
    assert account['rhel_instances'] == 0, repr(account)
    assert account['openshift_instances'] == 0, repr(account)
Example #4
0
def test_runtime_requests_from_future():
    """Test future start and end times for empty set result.

    :id: 133A04EE-55C3-4948-B2F9-D89A6A84C9FC
    :description: Test events that start/end in the future ensuring
        that results are empty [].
    :steps:
        1) Add a cloud account
        2) Insert past instance, image, and event data
        3) Insert future instance, image, and event data
        4) GET from the image report endpoint
    :expectedresults:
        - When start/end times are in the future OR when start>end
            expect runtine_seconds to be empty.
    """
    user = utils.create_user_account()
    auth = utils.get_auth(user)
    acct = inject_aws_cloud_account(user['id'])
    image_type = 'openshift'
    instance_start = 2
    instance_end = 1
    client = api.Client(authenticate=False, response_handler=api.echo_handler)
    events = [instance_start]
    if instance_end:
        events.append(instance_end)
    inject_instance_data(acct['id'], image_type, events)

    report_start, report_end = utils.get_time_range(180)
    params = {
        'start': report_start,
        'end': report_end,
        'account_id': acct['id'],
    }
    response = client.get(urls.REPORT_ACCOUNTS, params=params, auth=auth)
    response_data = response.json()['cloud_account_overviews'][0]
    rhel_instances = response_data['rhel_instances']
    openshift_instances = response_data['openshift_instances']
    rhel_runtime_seconds = response_data['rhel_runtime_seconds']
    openshift_runtime_seconds = response_data['openshift_runtime_seconds']

    assert rhel_instances is None
    assert openshift_instances is None
    assert rhel_runtime_seconds is None
    assert openshift_runtime_seconds is None
    past_date = datetime.datetime.now() + datetime.timedelta(-30)
    backwards_params = {
        'start': report_start,
        'end': past_date,
        'account_id': acct['id'],
    }
    response = client.get(
        urls.REPORT_ACCOUNTS,
        params=backwards_params,
        auth=auth,
    )
    response_error = response.json()['non_field_errors'][0]
    assert response_error == 'End date must be after start date.'
Example #5
0
def test_filter_by_account_id_and_name(accounts_report_data, superuser):
    """Test that cloud accounts report can be filtered by account ID and name.

    :id: edacb611-dfec-4d8b-b480-b0c0d901c08e
    :description: Test that regular users and superusers can filter cloud
        accounts by account ID and name. This is not useful since the account
        ID will restrict the list to a single account but, since this is a
        possibility, ensure that an and operation will be done to match both
        account ID and name.
    :steps:
        1) Add three cloud accounts
        2) Insert some instance events for all accounts.
        3) Filter the cloud accounts by providing the account_id and a name
           pattern that does not match the account's name.
        4) Ensure an emptly list is returned since it won't match anything.
        5) Now update the account ID and the name pattern to match both the
           account ID and the name.
        4) Ensure a single account is returned and assert that their instance
           events are correct.
    :expectedresults:
        No result should be returned if both account ID and name pattern don't
        match any account. One result is returned when both account ID and name
        pattern match an account. All instance events should match for the
        matched account.
    """
    auth, first_account, second_account, third_account = accounts_report_data
    client = api.Client(authenticate=superuser)
    start, end = utils.get_time_range()
    params = {
        'end': end,
        'account_id': second_account['id'],
        'name_pattern': 'EaT sOme ToFu',
        'start': start,
    }
    if superuser:
        params['user_id'] = first_account['user_id']

    # No result will be returned since it will try to mach the account ID and
    # the name pattern
    response = client.get(urls.REPORT_ACCOUNTS, params=params, auth=auth)
    cloud_account_overviews = response.json()['cloud_account_overviews']
    assert len(cloud_account_overviews) == 0, cloud_account_overviews

    # Now update the account ID to point to an account that the name pattern
    # will match, it should return a single result.
    params['account_id'] = first_account['id']
    response = client.get(urls.REPORT_ACCOUNTS, params=params, auth=auth)
    cloud_account_overviews = response.json()['cloud_account_overviews']
    assert len(cloud_account_overviews) == 1, cloud_account_overviews
    account = cloud_account_overviews[0]
    assert first_account['aws_account_id'] == account['cloud_account_id']
    assert account['images'] == 1, repr(account)
    assert account['instances'] == 1, repr(account)
    assert account['rhel_instances'] == 1, repr(account)
    assert account['openshift_instances'] == 0, repr(account)
Example #6
0
def test_list_specific_image(images_data):
    """Test if a specific image can be fetched.

    :id: 99aaec58-6053-476d-9674-ee650ffa33a9
    :description: Check if a regular user can fetch one of its images. Check if
        a superuser can fetch all images. Check if a regular user can't fetch
        an image that belongs to another user.
    :steps:
        1. Fetch all images
        2. For each image, check if its owner and a superuser can fetch each.
           Also check if another user can't fetch it.
    :expectedresults:
        A regular user can only fetch its images and a superuser can fetch all
        images.
    """
    user1, user2, auth1, auth2, images1, images2 = images_data
    cfg = config.get_config()
    superuser_auth = api.TokenAuth(cfg.get('superuser_token'))
    client = api.Client(authenticate=False)
    start, end = utils.get_time_range()

    response = client.get(urls.IMAGE, auth=superuser_auth).json()
    assert response['count'] == len(images1) + len(images2), response
    all_images = response['results']
    ec2_ami_ids1 = [image['ec2_ami_id'] for image in images1]
    ec2_ami_ids2 = [image['ec2_ami_id'] for image in images2]

    for image in all_images:
        if image['ec2_ami_id'] in ec2_ami_ids1:
            auth = auth1
            other_auth = auth2
        elif image['ec2_ami_id'] in ec2_ami_ids2:
            auth = auth2
            other_auth = auth1
        else:
            raise ValueError(
                f'{image} not in {ec2_ami_ids1} or {ec2_ami_ids2}')
        image_url = urljoin(urls.IMAGE, str(image['id']))

        # Ensure superuser can fetch it
        response = client.get(image_url, auth=superuser_auth).json()
        assert response == image

        # Ensure the image owner can fetch it
        response = client.get(image_url, auth=auth).json()
        assert response == image

        # Ensure any other user can't fetch it
        old_handler = client.response_handler
        client.response_handler = api.echo_handler
        response = client.get(image_url, auth=other_auth)
        client.response_handler = old_handler
        assert response.status_code == 404
        assert response.json()['detail'] == 'Not found.'
Example #7
0
def test_list_account_while_impersonating(impersonate):
    """Test account data fetched via impersonating a user as a superuser.

    :id: 5f99c7ec-a4d3-4040-868f-9340015e4c9c
    :description: Test that the same assertions can be made for fetching data
        as a regular user and fetching data impersonating that same user
    :steps:
        1) Add a cloud account
        2) Insert instance, image, and event data
        3) GET from the account report endpoint as regular user
        3) GET from the account report endpoint as super user impersonating
    :expectedresults:
        - The instance, image, RHEL, and Openshift counts match the expectation
    """
    user = utils.create_user_account()
    auth = utils.get_auth(user)
    acct = inject_aws_cloud_account(user['id'])
    image_type = 'rhel'
    exp_inst = 1
    exp_images = 1
    exp_rhel = 1
    exp_openshift = 0
    start = 0
    end = None
    offset = 0

    # authenticate (as superuser) if we are impersonating
    client = api.Client(authenticate=impersonate)

    events = [start]
    if end:
        events.append(end)
    inject_instance_data(acct['id'], image_type, events)

    start, end = utils.get_time_range(offset)
    params = {
        'start': start,
        'end': end,
    }
    if impersonate:
        params['user_id'] = user['id']
    response = client.get(urls.REPORT_ACCOUNTS, params=params, auth=auth)

    account = response.json()['cloud_account_overviews'][0]

    assert account['cloud_account_id'] == acct['aws_account_id']
    assert account['images'] == exp_images, repr(account)
    assert account['instances'] == exp_inst, repr(account)
    assert account['rhel_instances'] == exp_rhel, repr(account)
    assert account['openshift_instances'] == exp_openshift, repr(account)
Example #8
0
def test_multiple_runs_counted_once():
    """Test instances being run a different times in the same period count once.

    :id: 0e8d0475-54d9-43af-9c2b-23f84865c6b4
    :description: Within any single period of reporting an instance which has
        been started and stopped multiple times still counts just once.
    :steps:
        1) Add a cloud account
        2) Insert event data with more than one start and stop in the last 30
           day period
        3) GET from the account report endpoint
    :expectedresults:
        - The instance and image should only be counted once
    """
    user = utils.create_user_account()
    auth = utils.get_auth(user)
    acct = inject_aws_cloud_account(user['id'])
    image_type = ''
    exp_inst = 1
    exp_images = 1
    exp_rhel = 0
    exp_openshift = 0

    client = api.Client(authenticate=False)

    start, end = utils.get_time_range()
    params = {
        'start': start,
        'end': end,
    }

    events = [
        20,
        15,
        10,
        5,
    ]
    inject_instance_data(acct['id'], image_type, events)

    response = client.get(urls.REPORT_ACCOUNTS, params=params, auth=auth)

    account = response.json()['cloud_account_overviews'][0]

    assert account['cloud_account_id'] == acct['aws_account_id']
    assert account['images'] == exp_images, repr(account)
    assert account['instances'] == exp_inst, repr(account)
    assert account['rhel_instances'] == exp_rhel, repr(account)
    assert account['openshift_instances'] == exp_openshift, repr(account)
Example #9
0
def test_list_images_while_impersonating(impersonate):
    """Test account data fetched via impersonating a user as a superuser.

    :id: 5f99c7ec-a4d3-4040-868f-9340015e4c9c
    :description: Test that the same assertions can be made for fetching data
        as a regular user and fetching data impersonating that same user
    :steps:
        1) Add a cloud account
        2) Insert instance, image, and event data
        3) GET from the image report endpoint as regular user
        3) GET from the image report endpoint as super user impersonating
    :expectedresults:
        - The images are returned for the user and a super user, but
            no one else.
    """
    user = utils.create_user_account()
    auth = utils.get_auth(user)
    acct = inject_aws_cloud_account(user['id'])
    image_type = 'rhel'
    exp_rhel = True
    exp_openshift = False
    start = 12
    end = 10
    offset = 0
    # start and end values indicate number of days in the past
    # so their difference is the whole number of days of runtime
    expected_runtime = (start - end) * 24 * 60 * 60

    # authenticate (as superuser) if we are impersonating
    client = api.Client(authenticate=impersonate)

    events = [start]
    if end:
        events.append(end)
    inject_instance_data(acct['id'], image_type, events)

    report_start, report_end = utils.get_time_range(offset)
    params = {
        'start': report_start,
        'end': report_end,
        'account_id': acct['id'],
    }
    response = client.get(urls.REPORT_IMAGES, params=params, auth=auth)

    image = response.json()['images'][0]
    assert image['rhel'] == exp_rhel, repr(image)
    assert image['openshift'] == exp_openshift, repr(image)
    assert int(image['runtime_seconds']) == int(expected_runtime), repr(image)
Example #10
0
def test_list_account_with_multiple():
    """Test that a user with multiple accounts can list all.

    :id: 1f16a664-a4ea-410e-9ff8-0a6e42cb4df2
    :description: Test that the same assertions can be made for fetching data
        with just one account works with multiple.
    :steps:
        1) Add a cloud account
        2) Insert instance, image, and event data
        3) GET from the account report endpoint as regular user
    :expectedresults:
        - The instance, image, RHEL, and Openshift counts match the expectation
    """
    user = utils.create_user_account()
    auth = utils.get_auth(user)
    acct = inject_aws_cloud_account(user['id'])
    image_type = 'rhel'
    exp_inst = 1
    exp_images = 1
    exp_rhel = 1
    exp_openshift = 0
    time = 0
    offset = 0

    acct2 = inject_aws_cloud_account(user['id'])

    client = api.Client(authenticate=False)

    inject_instance_data(acct['id'], image_type, [time])

    start, end = utils.get_time_range(offset)
    params = {
        'start': start,
        'end': end,
    }
    response = client.get(urls.REPORT_ACCOUNTS, params=params, auth=auth)

    accounts = response.json()['cloud_account_overviews']
    account = accounts[0]
    account2 = accounts[1]

    assert account['cloud_account_id'] == acct['aws_account_id']
    assert account2['cloud_account_id'] == acct2['aws_account_id']
    assert account['images'] == exp_images, repr(account)
    assert account['instances'] == exp_inst, repr(account)
    assert account['rhel_instances'] == exp_rhel, repr(account)
    assert account['openshift_instances'] == exp_openshift, repr(account)
Example #11
0
def test_past_without_instances():
    """Test accounts with instances only after the filter period.

    :id: 72aaa6e2-2c60-4e71-bb47-3644bd6beb71
    :description: Test that an account with instances that were created prior
        to the current report end date.
    :steps:
        1) Add a cloud account
        2) Inject instance data for today
        3) GET from the account report endpoint for 30 days ago
    :expectedresults:
        - The account is in the response and matches the created account
        - Instances, images, RHEL, and Openshift all have None counts
    """
    user = utils.create_user_account()
    auth = utils.get_auth(user)
    # TODO: refactor inject_aws_cloud_account to use seed data
    acct = ''  # inject_aws_cloud_account(user['id'])
    client = api.Client(authenticate=False)

    # ask for last 30 days
    report_start, report_end = utils.get_time_range()
    params = {
        'start': report_start,
        'end': report_end,
        'account_id': acct['id'],
    }

    response = client.get(urls.REPORT_IMAGES, params=params, auth=auth)
    images = response.json()['images']

    assert images == [], repr(images)

    # No tagged images, started 60 days ago and stopped 45 days ago
    # image_type = ''
    instance_start = 60
    instance_end = 45
    events = [instance_start, instance_end]
    print(events)
    # inject_instance_data(acct['id'], image_type, events)

    # test that still have no images in report
    response = client.get(urls.REPORT_IMAGES, params=params, auth=auth)
    images = response.json()['images']

    assert images == [], repr(images)
Example #12
0
def test_filter_by_name(accounts_report_data, superuser):
    """Test that cloud accounts can be filtered by name.

    :id: 5abbfb8d-c447-464a-a980-4c7e8d2fcc80
    :description: Test that regular users and superusers can filter cloud
        accounts by name. Cloudigrade takes the search pattern, split its words
        and then for each word is matched as a substring in the name, any
        account that is matched is returned.
    :steps:
        1) Add three cloud accounts
        2) Insert some instance events for all accounts.
        3) Filter the cloud accounts using a two words pattern. Each pattern's
           word should match a single account.
        4) Ensure two accounts are returned and assert that their instance
           events are correct.
    :expectedresults:
        Two accounts are returned, one matched by the first word and the other
        by the second word. All instance events should match.
    """
    auth, first_account, second_account, third_account = accounts_report_data
    client = api.Client(authenticate=superuser)
    start, end = utils.get_time_range()
    params = {
        'end': end,
        'name_pattern': 'EaT sOme ToFu',
        'start': start,
    }
    if superuser:
        params['user_id'] = first_account['user_id']
    response = client.get(urls.REPORT_ACCOUNTS, params=params, auth=auth)

    results = sorted(response.json()['cloud_account_overviews'],
                     key=operator.itemgetter('name'))
    assert len(results) == 2, results
    for expected, account in zip((first_account, third_account), results):
        assert expected['aws_account_id'] == account['cloud_account_id']
        assert account['images'] == 1, repr(account)
        assert account['instances'] == 1, repr(account)
        if expected is first_account:
            assert account['rhel_instances'] == 1, repr(account)
            assert account['openshift_instances'] == 0, repr(account)
        else:
            assert account['rhel_instances'] == 0, repr(account)
            assert account['openshift_instances'] == 1, repr(account)
Example #13
0
def test_image_tagging(conf):
    """Test instance events generate image usage results with correct tags.

    :id: f3c84697-a40c-40d9-846d-117e2647e9d3
    :description: Test combinations of image tags, start/end events, and the
        resulting counts from the summary report API.
    :steps:
        1) Add a cloud account
        2) Insert instance, image, and event data
        3) GET from the image report endpoint
    :expectedresults:
        - The images have correct tags and usage amounts
    """
    user = utils.create_user_account()
    auth = utils.get_auth(user)
    acct = inject_aws_cloud_account(user['id'])
    image_type, exp_inst, exp_images, exp_rhel, exp_openshift, \
        instance_start, instance_end, offset = conf
    # start and end values indicate number of days in the past
    # so their difference is the whole number of days of runtime
    expected_runtime = (instance_start - instance_end) * 24 * 60 * 60
    client = api.Client(authenticate=False)

    events = [instance_start]
    if instance_end:
        events.append(instance_end)
    inject_instance_data(acct['id'], image_type, events)

    report_start, report_end = utils.get_time_range(offset)
    params = {
        'start': report_start,
        'end': report_end,
        'account_id': acct['id'],
    }
    response = client.get(urls.REPORT_IMAGES, params=params, auth=auth)

    image = response.json()['images'][0]
    assert image['rhel'] == exp_rhel, repr(image)
    assert image['openshift'] == exp_openshift, repr(image)
    assert int(image['runtime_seconds']) == int(expected_runtime), repr(image)
Example #14
0
def test_list_account_tagging(conf):
    """Test instance events generate usage summary results for correct tags.

    :id: f3c84697-a40c-40d9-846d-117e2647e9d3
    :description: Test combinations of image tags, start/end events, and the
        resulting counts from the summary report API.
    :steps:
        1) Add a cloud account
        2) Insert instance, image, and event data
        3) GET from the account report endpoint
    :expectedresults:
        - The instance, image, RHEL, and Openshift counts match the expectation
    """
    user = utils.create_user_account()
    auth = utils.get_auth(user)
    acct = inject_aws_cloud_account(user['id'])
    image_type, exp_inst, exp_images, exp_rhel, exp_openshift, \
        start, end, offset = conf[1:]

    client = api.Client(authenticate=False)

    events = [start]
    if end:
        events.append(end)
    inject_instance_data(acct['id'], image_type, events)

    start, end = utils.get_time_range(offset)
    params = {
        'start': start,
        'end': end,
    }
    response = client.get(urls.REPORT_ACCOUNTS, params=params, auth=auth)

    account = response.json()['cloud_account_overviews'][0]

    assert account['cloud_account_id'] == acct['aws_account_id']
    assert account['images'] == exp_images, repr(account)
    assert account['instances'] == exp_inst, repr(account)
    assert account['rhel_instances'] == exp_rhel, repr(account)
    assert account['openshift_instances'] == exp_openshift, repr(account)
Example #15
0
def test_list_all_images(images_data, superuser):
    """Test if images can be listed.

    :id: 9b103387-4868-4f30-ab61-47fc54e2f41f
    :description: Check if a regular user can fetch all of its images and if a
        superuser can fetch all images on the system or filter the images by
        any user.
    :steps:
        1. List all images using a regular user. Check if the returned images
           are only the ones that belong to the user.
        2. List all images on the system using a superuser. Also check if a
           superuser can filter the list of images by user.
    :expectedresults:
        A regular user can only list its images and a superuser can fetch all
        images or filter by user.
    """
    user1, user2, auth1, auth2, images1, images2 = images_data
    client = api.Client(authenticate=superuser)
    start, end = utils.get_time_range()
    params = None
    if superuser:
        # fisrt check if superuser is able to fetch all images
        response = client.get(urls.IMAGE).json()
        assert response['count'] == len(images1) + len(images2), response
        images = response['results']
        for image, expected in zip(images, images1 + images2):
            for key, value in expected.items():
                assert image[key] == value, images

        # Now restrict the results to an specific user
        params = {'user_id': user1['id']}
    response = client.get(urls.IMAGE, auth=auth1, params=params).json()

    assert len(images1) == response['count']
    images = response['results']

    for image, expected in zip(images, images1):
        for key, value in expected.items():
            assert image[key] == value, images
Example #16
0
def test_filter_by_account_id(accounts_report_data, superuser):
    """Test that cloud accounts report can be filtered by account ID.

    :id: 8de488c4-2550-4d51-9d25-a7c4355fe6f4
    :description: Test that regular users and superusers can filter cloud
        accounts by account ID.
    :steps:
        1) Add three cloud accounts
        2) Insert some instance events for all accounts.
        3) Filter the cloud accounts by providing the account_id of one of the
           three accounts ID
        4) Ensure a single account is returned and assert that their instance
           events are correct.
    :expectedresults:
        One account matched by its account ID is returned. All instance events
        should match.
    """
    auth, first_account, second_account, third_account = accounts_report_data
    client = api.Client(authenticate=superuser)
    start, end = utils.get_time_range()
    params = {
        'account_id': second_account['id'],
        'end': end,
        'start': start,
    }
    if superuser:
        params['user_id'] = first_account['user_id']
    response = client.get(urls.REPORT_ACCOUNTS, params=params, auth=auth)

    cloud_account_overviews = response.json()['cloud_account_overviews']
    assert len(cloud_account_overviews) == 1, cloud_account_overviews
    account = cloud_account_overviews[0]
    assert second_account['aws_account_id'] == account['cloud_account_id']
    assert account['images'] == 1, repr(account)
    assert account['instances'] == 1, repr(account)
    assert account['rhel_instances'] == 1, repr(account)
    assert account['openshift_instances'] == 1, repr(account)
Example #17
0
def test_flagged_account_numbers():
    """Test the number of flagged images in accounts.

    :id: BBD687F5-0B78-4E86-8368-C5C8EEBD9263
    :description: Test that the number of images reported as flagged matches
    the flagged/challenged images in accounts.

    :steps:
        1) Add a cloud account
        2) Insert RHEL and RHOCP image
        3) Check number of challenged/flagged RHEL/RHOCP images
        4) Challenge images
        5) Check number of challenged/flagged RHEL/RHOCP images
    :expectedresults:
        - Challenged RHEL images = 0 when none are challenged
        - Challenged RHEL images > 0 when one or more are challenged
        - Challenged RHOCP images = 0 when none are challenged
        - Challenged RHOCP images > 0 when one or more are challenged
    """
    user = utils.create_user_account()
    auth = utils.get_auth(user)
    acct = inject_aws_cloud_account(user['id'])

    images = {}
    for tag in ('rhel', 'openshift'):
        image_type = tag
        events = [1, 2]
        client = api.Client(authenticate=False,
                            response_handler=api.echo_handler)
        images[tag] = inject_instance_data(
            acct['id'],
            image_type,
            events,
        )

        report_start, report_end = utils.get_time_range()
        params = {
            'start': report_start,
            'end': report_end,
            'account_id': acct['id'],
        }
    response = client.get(urls.REPORT_ACCOUNTS, params=params,
                          auth=auth).json()['cloud_account_overviews'][0]
    assert response['rhel_instances'] == 1
    assert response['openshift_instances'] == 1
    assert response['rhel_images_challenged'] == 0
    assert response['openshift_images_challenged'] == 0

    rhel_image = images.get('rhel')
    openshift_image = images.get('openshift')
    images = [rhel_image, openshift_image]
    # Shuffle images to be sure that each is called first, to ensure that
    # order doesn't matter
    shuffle(images)
    first_image_url = urljoin(urls.IMAGE, str(images[0]['image_id'])) + '/'
    second_image_url = urljoin(urls.IMAGE, str(images[1]['image_id'])) + '/'
    first_image_response = client.get(first_image_url, auth=auth).json()
    second_image = ''
    challenged_image = ''
    unchallenged_image = ''

    # Challenge first image
    if first_image_response['rhel']:
        first_image_response['rhel_challenged'] = True
        client.put(first_image_url, first_image_response, auth=auth)
        first_image = 'rhel'
        second_image = 'openshift'
        challenged_image = 'rhel_images_challenged'
        unchallenged_image = 'openshift_images_challenged'
    else:
        first_image_response['openshift_challenged'] = True
        client.put(first_image_url, first_image_response, auth=auth)
        first_image = 'openshift'
        second_image = 'rhel'
        challenged_image = 'openshift_images_challenged'
        unchallenged_image = 'rhel_images_challenged'
    first_response = client.get(urls.REPORT_ACCOUNTS, params=params,
                                auth=auth).json()['cloud_account_overviews'][0]

    assert first_response[challenged_image] == 1
    assert first_response[unchallenged_image] == 0
    assert first_response[f'{second_image}_instances'] == 1
    assert first_response[f'{first_image}_instances'] == 0

    # Challenge second image
    second_image_response = client.get(second_image_url, auth=auth).json()
    second_image_response[f'{second_image}_challenged'] = True

    client.put(second_image_url, second_image_response, auth=auth)
    second_response = client.get(
        urls.REPORT_ACCOUNTS, params=params,
        auth=auth).json()['cloud_account_overviews'][0]

    assert second_response[challenged_image] == 1
    assert second_response[unchallenged_image] == 1
    assert second_response[f'{second_image}_instances'] == 0
    assert second_response[f'{first_image}_instances'] == 0