def test_update(update_field, shared_client, cleanup, scan_type):
    """Create scan, then update it and assert the values are changed.

    :id: c40a64c1-346e-4fce-ad18-4090066050a1
    :description: Create a scan and assert that it completes
    :steps:
        1) Create a network credential
        2) Create a network source with the credential
        3) Create a scan with the network source
        4) Assert that the scan is created and all fields match the request.
        5) Update a field and assert that changes are made
    :expectedresults: A scan is created with all options set as requested.
    """
    source_ids = []
    for _ in range(random.randint(1, 10)):
        src_type = random.choice(QPC_SOURCE_TYPES)
        src = gen_valid_source(cleanup, src_type, "localhost")
        source_ids.append(src._id)
    scan = Scan(source_ids=source_ids, scan_type=scan_type, client=shared_client)
    scan.create()
    cleanup.append(scan)
    remote_scn = scan.read().json()
    assert scan.equivalent(remote_scn)
    if update_field == "source":
        src_type = random.choice(QPC_SOURCE_TYPES)
        src = gen_valid_source(cleanup, src_type, "localhost")
        scan.sources.append(src._id)
    if update_field == "max_concurrency":
        scan.options.update({"max_concurrecny": random.randint(1, 49)})
    if update_field == "name":
        scan.name = uuid4()
    scan.update()
    remote_scn = scan.read().json()
    assert scan.equivalent(remote_scn)
Beispiel #2
0
def test_create_exclude_hosts(shared_client, cleanup, scan_host):
    """Create a source with the excluded hosts option.

    :id: 40365ec0-a8b5-4dc9-b7b4-dad826602d66
    :description: Create a network source with some excluded host IPs.
    :steps:
        1) Create host credential
        2) Send POST with data to create the source using the credential to
           the source endpoint, with the exclude hosts option.
    :expectedresults: A new source entry is created with the data.
    """
    gen_valid_source(cleanup, "network", hosts="1.1.1.1", exclude_hosts=scan_host)
Beispiel #3
0
def test_type_mismatch(src_type, cleanup, shared_client):
    """Attempt to create sources with credentials of the wrong type.

    For example, if we create a 'network' typed credential, we can not create a
    'vcenter' typed source using this credential.

    :id: 89bc1bb5-127b-48da-b106-82cd1ef7e00a
    :description: Test that we cannot create a source with the wrong type
        of credential.
    :steps:
        1) Create a credential of one type
        2) Attempt to create a source with that credential of a different type
    :expectedresults: An error is thrown and no new source is created.
    :caseautomation: notautomated
    """
    src = gen_valid_source(cleanup, src_type, "localhost", create=False)
    other_types = set(QPC_SOURCE_TYPES).difference(set((src_type,)))
    other_cred = Credential(
        password=uuid4(), cred_type=random.choice(list(other_types))
    )
    other_cred.create()
    cleanup.append(other_cred)
    src.credentials = [other_cred._id]
    src.client = api.Client(api.echo_handler)
    create_response = src.create()
    assert create_response.status_code == 400
    if create_response.status_code in [200, 201]:
        cleanup.append(src)
    assert "source_type" in create_response.json().keys()
Beispiel #4
0
def test_delete(src_type, cleanup, shared_client):
    """After creating several {network, vcenter} sources, delete one.

    :id: 24d811b1-655d-4278-ab9f-64ca46a7121b
    :description: Test that we can delete an individual {network, vcenter}
        source by id
    :steps:
        1) Create collection of {network, vcenter} sources, saving the
           information.
        2) Send a DELETE request to destroy individual source
        3) Confirm that all sources are on the server except the deleted one.
        4) Repeat until all sources are deleted.
    :expectedresults: All sources are present on the server except the
        deleted source.
    """
    created_srcs = []
    num_srcs = random.randint(2, 20)
    echo_client = api.Client(response_handler=api.echo_handler)
    for i in range(num_srcs):
        # gen_valid_srcs will take care of cleanup
        created_srcs.append(gen_valid_source(cleanup, src_type, "localhost"))
    for i in range(num_srcs):
        delete_src = created_srcs.pop()
        delete_src.delete()
        delete_src.client = echo_client
        delete_response = delete_src.read()
        assert delete_response.status_code == 404
        for p in created_srcs:
            assert_matches_server(p)
def test_scan_with_optional_products(scan_type, shared_client, cleanup):
    """Create a scan with disabled optional products.

    :id: 366604ed-e423-4140-b0d8-38626e264688
    :description: Perform a scan and disable an optional product.
    :steps:
        1) Create a network credential
        2) Create network source using the network credential.
        3) Create a scan using the network source. When creating the scan
           disable the optional products.
    :expectedresults: The scan is created.
    """
    num_products = random.randint(0, len(QPC_OPTIONAL_PRODUCTS))
    product_combinations = combinations(QPC_OPTIONAL_PRODUCTS, num_products)
    for combo in product_combinations:
        source_ids = []
        for _ in range(random.randint(1, 10)):
            src_type = random.choice(QPC_SOURCE_TYPES)
            src = gen_valid_source(cleanup, src_type, "localhost")
            source_ids.append(src._id)
        scan = Scan(source_ids=source_ids, scan_type=scan_type, client=shared_client)
        products = {p: True for p in QPC_OPTIONAL_PRODUCTS if p not in combo}
        products.update({p: False for p in combo})
        scan.options.update({OPTIONAL_PROD: products})
        scan.create()
        cleanup.append(scan)
        assert scan.equivalent(scan.read().json())
Beispiel #6
0
def test_update_with_invalid_src_type(src_type, scan_host, cleanup):
    """Attempt to update exclude_hosts with a non-network source type.

    :id: 66467eb5-79ab-4430-9957-b49fca4cd9ef
    :description: Create valid non-network source, and then attempt to
        update it with an excluded hostname option.
    :steps:
        1) Create valid credential and source that isn't a network type
        2) Update the source with an excluded host
    :expectedresults: Error codes are returned and the source is not updated.
    """
    src = gen_valid_source(cleanup, src_type, scan_host)
    original_data = copy.deepcopy(src.fields())
    src.exclude_hosts = ["10.10.10.10"]
    assert_source_update_fails(original_data, src)
Beispiel #7
0
def test_delete_with_dependencies(src_type, cleanup, shared_client):
    """Test that cannot delete sources if other objects depend on them.

    :id: 76d79090-a3f7-4750-a8b8-eaf6c2ed4b89
    :description: Test that sources cannot be deleted if they are members
        of a scan.
    :steps:
        1) Create a valid source and one or more scans that use it.
        2) Attempt to delete the source, this should fail
        3) Delete the scan(s)
        4) Assert that we can now delete the source
    :expectedresults: The source is not created
    :caseautomation: notautomated
    """
    src1 = gen_valid_source(cleanup, src_type, "localhost")
    src2 = gen_valid_source(cleanup, src_type, "localhost")
    scns = []
    for i in range(random.randint(2, 6)):
        if i % 2 == 0:
            scn = Scan(source_ids=[src1._id])
        else:
            scn = Scan(source_ids=[src1._id, src2._id])
        scns.append(scn)
        scn.create()
        cleanup.append(scn)
    src1.client = api.Client(api.echo_handler)
    # this should fail
    del_response = src1.delete()
    assert del_response.status_code == 400
    # now delete scan, and then we should be allowed to delete source
    for scn in scns:
        scn.delete()
        cleanup.remove(scn)
    src1.client = shared_client
    src1.delete()
    cleanup.remove(src1)
Beispiel #8
0
def test_update_remove_field(src_type, cleanup, field):
    """Attempt to update valid source with either no hosts or no credentials.

    :id: 49feb858-319f-4f77-b330-65426dfd1734
    :description: Create valid {network, vcenter} source, and then attempt to
        update it to have either no credentials or no hosts.
    :steps:
        1) Create valid credential and source
        2) Update the source with no credentials or no hosts
    :expectedresults: Error codes are returned and the source is not updated.
    """
    src = gen_valid_source(cleanup, src_type, "localhost")
    # we have to use deep copy because these are nested dictionaries
    original_data = copy.deepcopy(src.fields())
    setattr(src, field, [])
    assert_source_update_fails(original_data, src)
Beispiel #9
0
def test_update_with_bad_exclude_host(src_type, scan_host, cleanup):
    """Attempt to update valid source with an invalid excluded host.

    :id: 62cc08ad-1149-4c2b-a4ad-0e4c07d10ff6
    :description: Create valid {network, vcenter} source, and then attempt to
        update it with an invalid excluded hostname option.
    :steps:
        1) Create valid credential and source
        2) Update the source with an invalid excluded host
    :expectedresults: Error codes are returned and the source is not updated.
    """
    src = gen_valid_source(cleanup, src_type, scan_host)
    original_data = src.fields()
    # Test updating source with bad excluded host
    src.exclude_hosts = ["*invalid!!host&*"]
    assert_source_update_fails(original_data, src)
Beispiel #10
0
def test_update_with_bad_host(src_type, scan_host, cleanup):
    """Attempt to update valid source with an invalid host.

    :id: 26176135-b147-46bc-b0b5-57d5bc515b72
    :description: Create valid {network, vcenter} source, and then attempt to
        update it with invalid hostname.
    :steps:
        1) Create valid credential and source
        2) Update the source with an invalid host
    :expectedresults: Error codes are returned and the source is not updated.
    """
    src = gen_valid_source(cleanup, src_type, scan_host)
    original_data = copy.deepcopy(src.fields())
    # Test updating source with bad host
    src.hosts = ["*invalid!!host&*"]
    assert_source_update_fails(original_data, src)
Beispiel #11
0
def test_create_with_port(src_type, cleanup, shared_client):
    """Test that we may create with a custom port specified.

    :id: 9e83e1ed-e229-4822-a9c3-cbb8a7e4282e
    :description: Test that sources can be created with custom ports.
    :steps:
        1) Create a credential
        2) Create a source of the same type and specify a custom port.
    :expectedresults: A source is created with user specified data.
    :caseautomation: notautomated
    """
    src = gen_valid_source(cleanup, src_type, "localhost", create=False)
    src.port = random.randint(20, 9000)
    src.create()
    cleanup.append(src)
    server_src = src.read().json()
    assert src.equivalent(server_src)
Beispiel #12
0
def test_update_bad_credential(src_type, scan_host, cleanup):
    """Attempt to update valid source with invalid data.

    :id: 79954c63-608c-46b3-81eb-e2a1e984473e
    :description: Create valid {network, vcenter} source, and then attempt to
        update it with an invalid credential.
    :steps:
        1) Create valid credential and source
        2) Update the source with invalid credentials
    :expectedresults: Error codes are returned and the source is not updated.
    """
    src = gen_valid_source(cleanup, src_type, scan_host)
    original_data = copy.deepcopy(src.fields())

    # Case "a" add credential that doesnt exist
    # The server never assigns negative values
    src.credentials = [-1]
    assert_source_update_fails(original_data, src)
Beispiel #13
0
def test_read_all(src_type, cleanup, shared_client):
    """After created, retrieve all network sources with GET to api.

    :id: e708362c-a289-46f1-ad05-724e3e4383d5
    :description: The API should return list with all sources created
        when a GET request is sent to the {network, vcenter} sources endpoint.
    :steps:
        1) Create collection of sources, saving the information.
        2) Send GET request to {network, vcenter} source endpoint to get list
           of created {network, vcenter} sources
        3) Confirm that all sources are in the list.
    :expectedresults: All sources are present in data returned by API.
    """
    created_src_ids = set()
    # having a list of the sources locally will be helpful
    # for understanding failures as pytest will display the
    # data
    created_srcs = []
    for _ in range(random.randint(2, 10)):
        # gen_valid_srcs will take care of cleanup
        src = gen_valid_source(cleanup, src_type, "localhost")
        created_srcs.append(src)
        created_src_ids.add(src._id)
    this_page = Source().list().json()
    while this_page:
        for source in this_page["results"]:
            if source["id"] in created_src_ids:
                created_src_ids.remove(source["id"])
        next_page = this_page.get("next")
        if next_page:
            # must strip url of host information
            next_page = re.sub(r".*/api", "/api", next_page)
            this_page = shared_client.get(next_page).json()
        else:
            break

    # if we found everything we created, then the list should be empty
    if created_src_ids:
        raise AssertionError(
            "Expected to find all sources with correct data on server,\n"
            "but the following sources did not match expected or were"
            "missing from the server: \n"
            "{}".format(" ".join(created_src_ids))
        )
Beispiel #14
0
def test_port_default(src_type, cleanup, shared_client):
    """Test that the correct default port is provided if it is not specified.

    :id: 22af9909-887a-4bea-811c-6ef438a53fdb
    :description: Test that the correct default port is chosen for each type.
    :steps:
        1) Create a credential
        2) Create a source of the same type and do not specify the port
        3) Test that the correct default port is provided based on type.
    :expectedresults: A source is created with sensible default port.
    :caseautomation: notautomated
    """
    src = gen_valid_source(cleanup, src_type, "localhost", create=False)
    src.port = None
    src.create()
    cleanup.append(src)
    server_src = src.read().json()
    assert server_src.get("port") == DEFAULT_PORT[src_type]
    assert src.equivalent(server_src)
Beispiel #15
0
def test_negative_disable_optional_products(scan_type, shared_client, cleanup):
    """Attempt to disable optional products with non-acceptable booleans.

    :id: 2adb483c-578d-4131-b426-9f772c1803de
    :description: Create a scan with bad input for optional products
    :steps:
        1) Create a network credential
        2) Create network source using the network credential.
        3) Create a scan using the network source. When creating the scan
           disable the optional products with bad values.
    :expectedresults: The scan is not created.
    """
    num_products = random.randint(1, len(QPC_OPTIONAL_PRODUCTS))
    product_combinations = combinations(QPC_OPTIONAL_PRODUCTS, num_products)
    for combo in product_combinations:
        source_ids = []
        for _ in range(random.randint(1, 10)):
            src_type = random.choice(QPC_SOURCE_TYPES)
            src = gen_valid_source(cleanup, src_type, "localhost")
            source_ids.append(src._id)
        scan = Scan(source_ids=source_ids, scan_type=scan_type, client=shared_client)
        products = {p: True for p in QPC_OPTIONAL_PRODUCTS if p not in combo}
        bad_choice = random.choice(["hamburger", "87", 42, "*"])
        products.update({p: bad_choice for p in combo})
        scan.options.update({OPTIONAL_PROD: products})
        echo_client = api.Client(response_handler=api.echo_handler)
        scan.client = echo_client
        create_response = scan.create()
        if create_response.status_code == 201:
            cleanup.append(scan)
            raise AssertionError(
                "Optional products should be disabled and\n"
                "enabled with booleans. If invalid input is given, the user\n"
                "should be alerted."
                "The following data was provided: {}".format(products)
            )
        assert create_response.status_code == 400
        message = create_response.json().get("options", {})
        assert message.get(OPTIONAL_PROD) is not None
Beispiel #16
0
def test_create(shared_client, cleanup, scan_type):
    """Create scan and assert it has correct values.

    :id: ee3b0bc8-1489-443e-86bb-e2a2349e9c98
    :description: Create a scan and assert that it completes
    :steps:
        1) Create a network credential
        2) Create a network source with the credential
        3) Create a scan with the network source
        4) Assert that the scan is created and all fields match the request.
    :expectedresults: A scan is created with all options set as requested.
    """
    source_ids = []
    for _ in range(random.randint(1, 10)):
        src_type = random.choice(QPC_SOURCE_TYPES)
        src = gen_valid_source(cleanup, src_type, "localhost")
        source_ids.append(src._id)
    scan = Scan(source_ids=source_ids, scan_type=scan_type, client=shared_client)
    scan.create()
    cleanup.append(scan)
    remote_scn = scan.read().json()
    assert scan.equivalent(remote_scn)
Beispiel #17
0
def test_negative_invalid_port(src_type, bad_port, cleanup, shared_client):
    """Test that we are prevented from using a nonsense value for the port.

    :id: e64df701-5819-4e80-a5d2-d26cbc6f71a7
    :description: Test that sources cannot be created with bad values for the
        port.
    :steps:
        1) Create a credential
        2) Attempt to create a source of the same type and specify a custom
           port with various nonsense values like 'foo**' or -1 or a Boolean
    :expectedresults: The source is not created
    :caseautomation: notautomated
    """
    src = gen_valid_source(cleanup, src_type, "localhost", create=False)
    src.port = bad_port
    src.client = api.Client(api.echo_handler)
    create_response = src.create()
    assert create_response.status_code == 400
    if create_response.status_code in [200, 201]:
        cleanup.append(src)
    # assert that the server tells us what we did wrong
    assert "port" in create_response.json().keys()