Beispiel #1
0
def test_upwards_relocation_with_one_level_must_return_expected_result(
        basic_trees, basic_types):
    root, new_root = basic_trees

    new_element = entities.Element(name='Employee',
                                   element_type=basic_types['token_type'])

    # New element was moved from network upwards
    new_root.add_child(new_element)
    root.get_child_by_name('Network').add_child(new_element)

    recalculate_hashes(new_root)
    recalculate_hashes(root)

    # Now, they must be different
    assert root != new_root

    result = compare(root, new_root)

    expected_relocations = [('/Root/Network/Employee', '/Root/Employee')]

    expected_removals = ['/Root/Network/Employee']

    assert result['relocations'] == expected_relocations
    assert result['removals'] == expected_removals

    others_empty(result, 'relocations', 'removals')
Beispiel #2
0
def test_relocation_with_one_level_must_return_expected_result(
        basic_trees, basic_types):
    root, new_root = basic_trees

    service = new_root.children[3]

    # Moving Root->Service to Root->Network->Service
    new_root.children[0].add_child(service)
    new_root.remove_child(service)

    recalculate_hashes(new_root)
    recalculate_hashes(root)

    # Now, they must be different
    assert root != new_root

    result = compare(root, new_root)

    expected_relocations = [('/Root/Service', '/Root/Network/Service')]

    expected_removals = ['/Root/Service']

    assert result['relocations'] == expected_relocations
    assert result['removals'] == expected_removals

    others_empty(result, 'relocations', 'removals')
Beispiel #3
0
def test_simple_mdl_versions_must_return_expected_compare_result(
        simple_mdl_versions):
    v17_tree, v19_tree = simple_mdl_versions

    result = diff.compare(v17_tree, v19_tree)

    expected_result = {
        'additions': [
            '/MDLRoot/NetworkDomains/Network/NetworkNode/InternalStructure',
            '/MDLRoot/NetworkDomains/Domain', '/MDLRoot/IPV4'
        ],
        'relocations':
        [('/MDLRoot/NetworkDomains/Network/NetworkNode/Routes',
          '/MDLRoot/NetworkDomains/Network/NetworkNode/InternalStructure/Module/Routes'
          ), ('/MDLRoot/DatabaseID', '/MDLRoot/NetworkDomains/DatabaseID')],
        'removals':
        sorted([
            '/MDLRoot/NetworkDomains/Network/NetworkNode/NetworkName',
            '/MDLRoot/NetworkDomains/Network/NetworkNode/Routes',
            '/MDLRoot/DatabaseID',
        ]),
        'renames':
        [('/MDLRoot/ConfigurationVersion', '/MDLRoot/ConfigVersion')],
        'reorders': [
            '/MDLRoot/NetworkDomains',
            '/MDLRoot/NetworkDomains/Network/Description'
        ]
    }

    result['removals'].sort()

    assert result == expected_result
Beispiel #4
0
def test_rename_in_two_different_levels_must_return_expected_operation(
        basic_trees):
    root, new_root = basic_trees

    # Let's remove Root->Network->Person
    new_root.children[0].children[0].name = 'Person'

    # Change name of Root->ReadOnly
    new_root.children[2].name = 'DisableChanges'

    recalculate_hashes(new_root)
    recalculate_hashes(root)

    # Now, they must be different
    assert root != new_root

    result = compare(root, new_root)

    expected_renames = [
        ('/Root/Network/Owner', '/Root/Network/Person'),
        ('/Root/ReadOnly', '/Root/DisableChanges'),
    ]

    # As we are using sets, we need to sort our result to compare it.
    result['renames'].sort(key=lambda x: x[0])

    assert result['renames'] == expected_renames

    others_empty(result, 'renames')
Beispiel #5
0
def test_rename_and_sub_tree_changes_must_return_expected_renames(
        basic_trees, basic_types):
    root, new_root = basic_trees

    # Renaming Network to another name
    assert new_root.children[0].name == 'Network'
    new_root.children[0].name = 'NewNetwork'

    # Inside network, lets change Owner to Person
    assert new_root.children[0].children[0].name == 'Owner'
    new_root.children[0].children[0].name = 'Person'

    recalculate_hashes(new_root)
    recalculate_hashes(root)

    # Now, they must be different
    assert root != new_root

    result = compare(root, new_root)

    expected_renames = [
        ('/Root/Network', '/Root/NewNetwork'),
        ('/Root/Network/Owner', '/Root/Network/Person'),
    ]

    # As we are using sets, we need to sort our result to compare it.
    result['renames'].sort(key=lambda x: x[0])

    assert result['renames'] == expected_renames

    others_empty(result, 'renames')
Beispiel #6
0
def test_removal_with_no_changes_must_return_empty(basic_trees):
    root, new_root = basic_trees

    result = compare(root, new_root)

    assert result['removals'] == []

    others_empty(result, 'removals')
Beispiel #7
0
def test_rename_with_similiar_name_must_return_expected_association(
        basic_trees, basic_types):
    root, new_root = basic_trees

    # Renaming other fields
    new_root.children[1].name = 'NewOwner'
    new_root.children[3].name = 'ServiceNew'

    # Two new fields with same type but different names to be used in renames
    root_name = entities.Element(name='Name',
                                 element_type=basic_types['token_type'])
    root_foo = entities.Element(name='Foo',
                                element_type=basic_types['token_type'])
    root_operation = entities.Element(name='Operation',
                                      element_type=basic_types['token_type'])

    new_root_name = entities.Element(name='NewName',
                                     element_type=basic_types['token_type'])
    new_root_foo = entities.Element(name='Bar',
                                    element_type=basic_types['token_type'])
    new_root_operation = entities.Element(
        name='OperationNew', element_type=basic_types['token_type'])

    root.add_child(root_name)
    root.add_child(root_foo)
    root.add_child(root_operation)

    new_root.add_child(new_root_name)
    new_root.add_child(new_root_foo)
    new_root.add_child(new_root_operation)

    recalculate_hashes(new_root)
    recalculate_hashes(root)

    # Now, they must be different
    assert root != new_root

    result = compare(root, new_root)

    expected_renames = [
        ('/Root/Foo', '/Root/Bar'),
        ('/Root/Name', '/Root/NewName'),
        ('/Root/Operation', '/Root/OperationNew'),
        ('/Root/Owner', '/Root/NewOwner'),
        ('/Root/Service', '/Root/ServiceNew'),
    ]

    # As we are using sets, we need to sort our result to compare it.
    result['renames'].sort(key=lambda x: x[0])

    assert result['renames'] == expected_renames

    others_empty(result, 'renames')
Beispiel #8
0
def test_full_mdl_versions_must_has_no_intersections_between_additions_and_removals(
        full_mdl_versions):
    v17_tree, v19_tree = full_mdl_versions

    result = diff.compare(v17_tree, v19_tree)

    # Checking if we have some item in more than one operation
    additions_set = set(result['additions'])
    removals_set = set(result['removals'])

    intersect = additions_set & removals_set

    assert len(intersect) == 0
Beispiel #9
0
def test_generate_xslt_with_simple_example_must_add_a_new_target_namespace(simple_versions, shared_datadir):
    first_result, second_result = simple_versions

    first_tree = first_result['element']
    second_tree = second_result['element']

    compare_result = compare(first_tree, second_tree)

    xslt = generate_xslt(first_tree, second_tree, compare_result, first_result['namespaces'], 'MDL19.xsd')

    assert '<xsl:template match="/mdl:MDLRoot/@xsi:schemaLocation">' in xslt

    relocation = ('<xsl:attribute name="xsi:schemaLocation">'
                  'http://inetprogram.org/projects/MDL MDL19.xsd</xsl:attribute>')
    assert relocation in xslt
Beispiel #10
0
def test_reorder_with_only_order_changes(basic_trees, basic_types):
    root, new_root = basic_trees

    network = new_root.get_child_by_name('Network')
    network.element_type.children = list(reversed(network.children))

    recalculate_hashes(new_root)
    recalculate_hashes(root)

    result = compare(root, new_root)

    expected_reorder = ['/Root/Network']

    assert result['reorders'] == expected_reorder

    others_empty(result, 'reorders')
Beispiel #11
0
def test_generate_xslt_with_full_example(full_versions, shared_datadir):
    first_result, second_result = full_versions

    first_tree = first_result['element']
    second_tree = second_result['element']

    compare_result = compare(first_tree, second_tree)

    xslt = generate_xslt(first_tree, second_tree, compare_result, first_result['namespaces'], 'MDL19.xsd')

    with open(shared_datadir / 'MDL_17_x_19_result.xslt', 'r') as mdl_result:
        xslt_expected = mdl_result.read()

    xslt = xslt.strip()
    xslt_expected = xslt_expected.strip()

    assert xslt == xslt_expected
Beispiel #12
0
def test_imediate_circular_dependency_rename_must_return_expected_result(
        basic_trees, basic_types):
    root, new_root = basic_trees

    # Circular dependency of network just inside network
    root_network = root.get_child_by_name('Network')
    root_network.add_child(root_network)

    # Add a new module node inside network of our ORIGINAL tree
    root_module_type = entities.ElementType(
        name='ModuleType',
        children=[
            entities.Element(name='Owner',
                             element_type=basic_types['token_type']),
        ])

    root_network.add_child(
        entities.Element(name='Module', element_type=root_module_type))

    # Add a new module node inside network of our NEW tree
    module_type = entities.ElementType(
        name='ModuleType',
        children=[
            entities.Element(name='Name',
                             element_type=basic_types['token_type']),
        ])

    network = new_root.get_child_by_name('Network')

    # Adding a circular dependency
    network.add_child(network)

    network.add_child(entities.Element(name='Module',
                                       element_type=module_type))

    recalculate_hashes(new_root)
    recalculate_hashes(root)

    result = compare(root, new_root)

    expected_renames = [('/Root/Network/Module/Owner',
                         '/Root/Network/Module/Name')]

    assert result['renames'] == expected_renames
    others_empty(result, 'renames')
Beispiel #13
0
def test_full_mdl_versions_must_return_expected_compare_result(
        full_mdl_versions):
    v17_tree, v19_tree = full_mdl_versions

    result = diff.compare(v17_tree, v19_tree)

    expected_keys = {
        'renames', 'additions', 'relocations', 'removals', 'reorders'
    }
    current_keys = set(result.keys())

    assert current_keys == expected_keys

    assert len(result['additions']) == 59
    assert len(result['removals']) == 68
    assert len(result['relocations']) == 59
    assert len(result['renames']) == 4
    assert len(result['reorders']) == 0
Beispiel #14
0
def test_additions_in_two_levels_must_return_expected_operation(
        basic_trees, basic_types):
    root, new_root = basic_trees

    enabled = entities.Element(name='Enabled',
                               element_type=basic_types['boolean_type'])
    new_root.children[0].add_child(enabled)

    recalculate_hashes(new_root)
    recalculate_hashes(root)

    # Now, they must be different
    assert root != new_root

    result = compare(root, new_root)

    expected_additions = ['/Root/Network/Enabled']

    assert result['additions'] == expected_additions

    others_empty(result, 'additions')
Beispiel #15
0
def test_rename_with_one_level_must_return_expected_operation(basic_trees):
    root, new_root = basic_trees

    # Change name of network node to Net
    new_root.children[0].name = 'Net'

    recalculate_hashes(new_root)
    recalculate_hashes(root)

    # Now, they must be different
    assert root != new_root

    result = compare(root, new_root)

    expected_renames = [
        ('/Root/Network', '/Root/Net'),
    ]

    assert result['renames'] == expected_renames

    others_empty(result, 'renames')
Beispiel #16
0
def test_rename_with_two_levels_must_return_expected_operation(basic_trees):
    root, new_root = basic_trees

    # Let's remove Root->Network->Person
    new_root.children[0].children[0].name = 'Person'

    recalculate_hashes(new_root)
    recalculate_hashes(root)

    # Now, they must be different
    assert root != new_root

    result = compare(root, new_root)

    expected_renames = [
        ('/Root/Network/Owner', '/Root/Network/Person'),
    ]

    assert result['renames'] == expected_renames

    others_empty(result, 'renames')
Beispiel #17
0
def test_relocation_with_new_sub_element_must_return_expected_result(
        basic_trees, basic_types):
    root, new_root = basic_trees

    # Moving Root->Service to new node Root->Module->Service
    service = new_root.children[3]
    new_root.remove_child(service)

    module_children = [
        entities.Element(name='Owner', element_type=basic_types['token_type']),
        service
    ]

    module_type = entities.ElementType(name='ModuleType',
                                       children=module_children)

    module = entities.Element(name='Module', element_type=module_type)

    new_root.add_child(module)

    recalculate_hashes(new_root)
    recalculate_hashes(root)

    # Now, they must be different
    assert root != new_root

    result = compare(root, new_root)

    expected_relocations = [('/Root/Service', '/Root/Module/Service')]

    expected_additions = ['/Root/Module']

    expected_removals = ['/Root/Service']

    assert result['relocations'] == expected_relocations
    assert result['additions'] == expected_additions
    assert result['removals'] == expected_removals

    others_empty(result, 'relocations', 'additions', 'removals')
Beispiel #18
0
def test_removal_with_one_level(basic_trees):
    root, new_root = basic_trees

    # Let's remove RootType->Owner
    children = new_root.element_type.children
    del children[1]
    new_root.element_type.children = children

    recalculate_hashes(new_root)
    recalculate_hashes(root)

    # Now, they must be different
    assert root != new_root

    result = compare(root, new_root)

    expected_removals = [
        '/Root/Owner',
    ]

    assert result['removals'] == expected_removals

    others_empty(result, 'removals')
Beispiel #19
0
def test_removal_two_levels(basic_trees):
    root, new_root = basic_trees

    # Let's remove RootType->Network->Owner
    network = new_root.get_child_by_name('Network')
    del network.children[0]
    network.element_type.children = network.children

    recalculate_hashes(new_root)
    recalculate_hashes(root)

    # Now, they must be different
    assert root != new_root

    result = compare(root, new_root)

    expected_removals = [
        '/Root/Network/Owner',
    ]

    assert result['removals'] == expected_removals

    others_empty(result, 'removals')
Beispiel #20
0
def test_circular_dependency_rename_tag_must_return_expected_result(
        basic_trees, basic_types):
    root, new_root = basic_trees
    network = new_root.children[0]

    # Rename Root->Network->ReadOnly attr
    network.children[1].name = 'OnlyRead'

    module_children = [
        entities.Element(name='Owner', element_type=basic_types['token_type']),
        network  # Adding a ciclic dependency here
    ]

    module_type = entities.ElementType(name='ModuleType',
                                       children=module_children)

    module = entities.Element(name='Module', element_type=module_type)

    network.add_child(module)

    recalculate_hashes(new_root)
    recalculate_hashes(root)

    expected_renames = [
        ('/Root/Network/ReadOnly', '/Root/Network/OnlyRead'),
    ]

    expected_additions = [
        '/Root/Network/Module',
    ]

    result = compare(root, new_root)

    assert result['renames'] == expected_renames
    assert result['additions'] == expected_additions

    others_empty(result, 'renames', 'additions')
Beispiel #21
0
def get_xslt():
    if not request.is_json:
        return jsonify({
            'error': 'Bad Request, json expected',
            'xslt': ''
        }), 400

    data = request.get_json()

    if 'srcSchema' not in data:
        return jsonify({
            'error': 'Bad Request, "srcSchema" expected',
            'xslt': ''
        }), 400

    if 'dstSchema' not in data:
        return jsonify({
            'error': 'Bad Request, "dstSchema" expected',
            'xslt': ''
        }), 400

    if 'documents' not in data['srcSchema']:
        return jsonify({
            'error': 'Bad Request, "srcSchema/documents" expected',
            'xslt': ''
        }), 400

    if 'documents' not in data['dstSchema']:
        return jsonify({
            'error': 'Bad Request, "dstSchema/documents" expected',
            'xslt': ''
        }), 400

    if len(data['srcSchema']['documents']) == 0:
        return jsonify({
            'error': 'Bad Request, expected at least one document',
            'xslt': ''
        }), 400

    if len(data['dstSchema']['documents']) == 0:
        return jsonify({
            'error': 'Bad Request, expected at least one document',
            'xslt': ''
        }), 400

    repo_src = _build_repository(data['srcSchema']['documents'])
    repo_dst = _build_repository(data['dstSchema']['documents'])

    src_result = repo_src.get_main_element()
    dst_result = repo_dst.get_main_element()

    if not src_result:
        return jsonify({
            'error':
            'Bad Request, expected at least one document as primary in "srcSchema"',
            'xslt': ''
        }), 400

    if not dst_result:
        return jsonify({
            'error':
            'Bad Request, expected at least one document as primary in "dstSchema"',
            'xslt': ''
        }), 400

    src_element = src_result['element']
    dst_element = dst_result['element']

    recalculate_hashes(src_element)
    recalculate_hashes(dst_element)

    compare_result = compare(src_element, dst_element)

    xslt = generate_xslt(src_element, dst_element, compare_result,
                         src_result['namespaces'], dst_result['location'])

    # TODO
    old_field_count = None
    new_field_count = None
    unchanged_count = None
    typerenamed_count = None
    graph_similar = None
    add_graph_similar = None
    similar_doc = None

    # TODO (handle nodes in additions and removals)
    removed_count = len(compare_result['removals'])
    added_count = len(compare_result['additions'])
    relocations = len(compare_result['relocations'])
    reorders = len(compare_result['reorders'])

    renamed_count = len(compare_result['renames'])

    return jsonify({
        'xslt': xslt,
        'translationMetrics': {
            'oldFieldCount': old_field_count,
            'newFieldCount': new_field_count,
            'removedFields': removed_count,
            'addedFields': added_count,
            'reorders': reorders,
            'renamedFields': renamed_count,
            'relocatedFields': relocations,
            'renamedTypes': typerenamed_count,
            'percentMapped': None  # TODO
        }
    })