Example #1
0
def main():

    deps = testdata.DEPS_MODERATE
    versions_by_package = depdata.generate_dict_versions_by_package(deps)

    (edeps, packs_wout_avail_version_info, dists_w_missing_dependencies) = depdata.elaborate_dependencies(
        deps, versions_by_package
    )

    assert depdata.are_deps_valid(testdata.DEPS_MODERATE) and depdata.are_deps_valid(
        testdata.DEPS_SIMPLE
    ), "The test dependencies are coming up as invalid for some reason...."

    # Clear any pre-existing test database.
    sqli.initialize(db_fname="data/test_dependencies.db")
    sqli.delete_all_tables()

    sqli.populate_sql_with_full_dependency_info(
        edeps,
        versions_by_package,
        packs_wout_avail_version_info,
        dists_w_missing_dependencies,
        db_fname="data/test_dependencies.db",
    )

    print("All tests in main() OK.")
Example #2
0
def test_depdata():
    """
  """
    assert 41 == len(testdata.DEPS_MODERATE), \
        "Set changed: should be len 41 but is len " + \
        str(len(testdata.DEPS_MODERATE)) + " - reconfigure tests"

    json.dump(testdata.DEPS_MODERATE, open('data/test_deps_set.json', 'w'))

    deps = depdata.load_json_db('data/test_deps_set.json')

    assert testdata.DEPS_MODERATE == deps, \
        "JSON write and load via load_json_db is breaking!"

    versions_by_package = depdata.generate_dict_versions_by_package(deps)

    assert 10 == len(versions_by_package)  # different package names

    total_package_versions = \
        sum([len(versions_by_package[p]) for p in versions_by_package])

    assert 41 == total_package_versions, \
        "Wrong number of versions: " + str(total_package_versions) + "instead" \
        + "of 41."

    (edeps, packs_wout_avail_version_info, dists_w_missing_dependencies) = \
        depdata.elaborate_dependencies(deps, versions_by_package)

    # 1 entry in the edeps dict
    assert 41 == len(edeps), \
        "Wrong number of dists in elaborate_dependencies output. " + \
        str(len(edeps)) + "instead of 41."

    # 1 version listed for every possible satisfying dependency
    n_dependencies_elaborated = 0
    for distkey in edeps:
        for satisfying_package_entry in edeps[distkey]:
            list_of_satisfying_versions = satisfying_package_entry[1]
            n_dependencies_elaborated += len(list_of_satisfying_versions)
            #print(distkey + " -> " + str(list_of_satisfying_versions))

    assert 34 == n_dependencies_elaborated, \
        "Expecting 34 satisfying versions (1 for every [depending dist]" + \
        ",[satisfying_version] pair. Instead, got " + \
        str(n_dependencies_elaborated)

    assert depdata.are_deps_valid(testdata.DEPS_MODERATE) and \
        depdata.are_deps_valid(testdata.DEPS_SIMPLE), \
        'The test dependencies are coming up as invalid for some reason....'

    print("test_depdata(): All tests OK.")
Example #3
0
def test_depdata():
    """
  """
    assert 41 == len(testdata.DEPS_MODERATE), (
        "Set changed: should be len 41 but is len " + str(len(testdata.DEPS_MODERATE)) + " - reconfigure tests"
    )

    json.dump(testdata.DEPS_MODERATE, open("data/test_deps_set.json", "w"))

    deps = depdata.load_json_db("data/test_deps_set.json")

    assert testdata.DEPS_MODERATE == deps, "JSON write and load via load_json_db is breaking!"

    versions_by_package = depdata.generate_dict_versions_by_package(deps)

    assert 10 == len(versions_by_package)  # different package names

    total_package_versions = sum([len(versions_by_package[p]) for p in versions_by_package])

    assert 41 == total_package_versions, (
        "Wrong number of versions: " + str(total_package_versions) + "instead" + "of 41."
    )

    (edeps, packs_wout_avail_version_info, dists_w_missing_dependencies) = depdata.elaborate_dependencies(
        deps, versions_by_package
    )

    # 1 entry in the edeps dict
    assert 41 == len(edeps), (
        "Wrong number of dists in elaborate_dependencies output. " + str(len(edeps)) + "instead of 41."
    )

    # 1 version listed for every possible satisfying dependency
    n_dependencies_elaborated = 0
    for distkey in edeps:
        for satisfying_package_entry in edeps[distkey]:
            list_of_satisfying_versions = satisfying_package_entry[1]
            n_dependencies_elaborated += len(list_of_satisfying_versions)
            # print(distkey + " -> " + str(list_of_satisfying_versions))

    assert 34 == n_dependencies_elaborated, (
        "Expecting 34 satisfying versions (1 for every [depending dist]"
        + ",[satisfying_version] pair. Instead, got "
        + str(n_dependencies_elaborated)
    )

    assert depdata.are_deps_valid(testdata.DEPS_MODERATE) and depdata.are_deps_valid(
        testdata.DEPS_SIMPLE
    ), "The test dependencies are coming up as invalid for some reason...."

    print("test_depdata(): All tests OK.")
Example #4
0
def test_detect_model_2_conflicts():
    """TEST 3: Detection of model 2 conflicts."""
    deps = testdata.DEPS_MODEL2
    versions_by_package = depdata.generate_dict_versions_by_package(deps)
    (edeps, packs_wout_avail_version_info, dists_w_missing_dependencies) = \
        depdata.elaborate_dependencies(deps, versions_by_package)

    success = ry.detect_model_2_conflict_from_distkey('motorengine(0.7.4)',
                                                      edeps,
                                                      versions_by_package)

    if not success:
        logger.error(
            'Did not detect model 2 conflict for motorengine(0.7.4). ):')
    else:
        logger.info("test_resolver(): Test 3 OK.")

    return success
Example #5
0
def main():

    deps = testdata.DEPS_MODERATE
    versions_by_package = depdata.generate_dict_versions_by_package(deps)

    (edeps, packs_wout_avail_version_info, dists_w_missing_dependencies) = \
        depdata.elaborate_dependencies(deps, versions_by_package)

    assert depdata.are_deps_valid(testdata.DEPS_MODERATE) and \
        depdata.are_deps_valid(testdata.DEPS_SIMPLE), \
        'The test dependencies are coming up as invalid for some reason....'

    # Clear any pre-existing test database.
    sqli.initialize(db_fname='data/test_dependencies.db')
    sqli.delete_all_tables()

    sqli.populate_sql_with_full_dependency_info(
        edeps,
        versions_by_package,
        packs_wout_avail_version_info,
        dists_w_missing_dependencies,
        db_fname='data/test_dependencies.db')

    print('All tests in main() OK.')
Example #6
0
def test_resolver(resolver_func,
                  expected_result,
                  distkey,
                  deps,
                  versions_by_package=None,
                  edeps=None,
                  expected_exception=None,
                  use_raw_deps=False):
    """
  Returns True if the given resolver function returns the expected result on
  the given data, else False. More modes described in args notes below.

  Solutions are compared with intelligent version parsing outsourced partly to
  pip's pip._vendor.packaging.version classes. For example, 2.0 and 2 and 2.0.0
  are all treated as equivalent.


  Arguments:

    resolver_func
      Argument resolver_func should be a function that accepts 3 arguments and
      returns a solution list:
        - Arg 1:  distkey to generate an install set for, whose installation
                  results in a fully satisfied set of dependencies
        - Arg 2:  dependency data (either deps or edeps, per depdata.py)
        - Arg 3:  versions_by_package, a dict mapping package names to all
                  versions of that package available
        - Return: a list containing the distkeys for dists to install

    expected_result
      This should be a list of distkeys. If the list given matches the solution
      generated by calling resolver_func with the appropriate arguments, we
      return True.
      If this is None, then we don't care what solution is returned by the call
      to resolver_func, only that no unexpected exceptions were raised and
      any expected exception was raised.

    distkey
      The distkey of the distribution to solve for (find install set that
      fully satisfies).
    
    deps
      Dependency data to be used in resolution.


  Optional Arguments:
    
    versions_by_package
      As described elsewhere, the dictionary mapping package names to available
      versions of those packages. If not provided, this is generated from deps.

    use_raw_deps
      If True, we do not try to elaborate dependencies (or use provided
      elaborated dependencies), instead passing the deps provided on in our
      call to resolver_func. Some resolvers do not use elaborated dependencies.

    edeps
      If provided, we don't elaborate the deps argument, but instead use these.

    expected_exception
      The type() of an exception that we expect to receive. If provided, we
      disregard expected_result and instead expect to catch an exception of the
      indicated type, returning True if we catch one and False otherwise.


  Raises:

    - UnresolvableConflictError (reraise) if unable to resolve and we were not
      told to expect UnresolvableConflictError. (Same goes for any other
      exceptions generated by call to resolver_func.)

  Side Effects:
    (NO:
     Used to also write dependency graph to resolver/output/test_resolver_* in
     graphviz .dot format, but have turned this off for now.)

  """

    if versions_by_package is None:
        versions_by_package = depdata.generate_dict_versions_by_package(deps)

    if use_raw_deps:
        edeps = deps

    elif edeps is None:
        (edeps, packs_wout_avail_version_info, dists_w_missing_dependencies) = \
          depdata.elaborate_dependencies(deps, versions_by_package)

    solution = None

    try:
        #(solution, _junk_, dotstrings) = \
        solution = \
            resolver_func(distkey, edeps, versions_by_package)

    except Exception as e:
        if expected_exception is None or type(e) is not expected_exception:
            logger.exception('Test Failure: Unexpectedly unable to resolve ' +
                             distkey)

            # Compromise traceback style so as not to give up python2 compatibility.
            six.reraise(
                UnexpectedException,
                UnexpectedException('Unexpectedly '
                                    'unable to resolve ' + distkey),
                sys.exc_info()[2])

            # Python 3 style (by far the nicest):
            #raise UnexpectedException('Unexpectedly unable to resolve ' + distkey) \
            #    from e

            # Original (2 or 3 compatible but not great on either, especially not 2)
            #raise

            #return False

        else:
            # We expected this error.
            logger.info('As expected, unable to resolve ' + distkey +
                        ' due to ' + str(type(e)) + '.')
            logger.info('  Exception caught: ' + e.args[0])
            return True

    else:
        logger.info('Resolved ' + distkey + '. Solution: ' + str(solution))
        #if dotstrings is not None: # If the func provides dotstrings
        #  fobj = open('data/resolver/test_resolver_' + resolver_func.__name__ +
        #      '_' + distkey + '.dot', 'w')
        #  fobj.write('digraph G {\n' + dotstrings + '}\n')
        #  fobj.close()

        # Were we expecting an exception? (We didn't get one if we're here.)
        if expected_exception is not None:
            logger.info('Expecting exception (' + str(expected_exception) +
                        ') but '
                        'none were raised. Was solving for ' + distkey +
                        ' using ' + resolver_func.__name__)
            return False

        # If expected_result is None, then we didn't care what the result was as
        # long as there was no unexpected exception / as long as whatever exception
        # is expected was raised.
        elif expected_result is None:
            logger.info(
                'No particular solution expected and resolver call did not '
                'raise an exception, therefore result is acceptable. Was solving '
                'for ' + distkey + ' using ' + resolver_func.__name__)
            return True

        # Is the solution set as expected?
        elif ry.dist_lists_are_equal(solution, expected_result):
            logger.info('Solution is as expected.')
            return True

        else:
            logger.info('Solution does not match while solving for ' +
                        distkey + ' using ' + resolver_func.__name__ + ':')
            logger.info('    Expected: ' + str(sorted(expected_result)))
            logger.info('    Produced: ' + str(sorted(solution)))
            return False