mirror of
https://github.com/GNS3/gns3-server.git
synced 2024-12-27 00:11:07 +00:00
a2fdc92fcb
This create a directory by node to allow feature like save as to work when running on multiple compute. Benefits now dynamips work like other nodes. Old topologies are migrated. Ref https://github.com/GNS3/gns3-gui/issues/1761
133 lines
5.9 KiB
Python
133 lines
5.9 KiB
Python
#!/usr/bin/env python
|
|
#
|
|
# Copyright (C) 2016 GNS3 Technologies Inc.
|
|
#
|
|
# This program is free software: you can redistribute it and/or modify
|
|
# it under the terms of the GNU General Public License as published by
|
|
# the Free Software Foundation, either version 3 of the License, or
|
|
# (at your option) any later version.
|
|
#
|
|
# This program is distributed in the hope that it will be useful,
|
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
# GNU General Public License for more details.
|
|
#
|
|
# You should have received a copy of the GNU General Public License
|
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
|
|
#
|
|
# This will test the conversion from old topology format to the new
|
|
#
|
|
# Read tests/topologies/README.rst for documentation
|
|
|
|
import os
|
|
import json
|
|
import pytest
|
|
import shutil
|
|
|
|
|
|
from gns3server.controller.topology import load_topology, GNS3_FILE_FORMAT_REVISION
|
|
|
|
topologies_directory = os.path.join(os.path.dirname(os.path.realpath(__file__)), "topologies")
|
|
|
|
|
|
def topologies():
|
|
dirs = []
|
|
for directory in os.listdir(topologies_directory):
|
|
if os.path.isdir(os.path.join(topologies_directory, directory)):
|
|
dirs.append(directory)
|
|
return dirs
|
|
|
|
|
|
@pytest.mark.parametrize("directory", topologies())
|
|
def test_convert(directory, tmpdir):
|
|
before_directory = os.path.join(topologies_directory, directory, "before")
|
|
after_directory = os.path.join(topologies_directory, directory, "after")
|
|
|
|
assert os.path.exists(before_directory), "No before directory found file for {}".format(directory)
|
|
assert os.path.exists(after_directory), "No after directory found file for {}".format(directory)
|
|
|
|
gns3_file = None
|
|
for file in os.listdir(before_directory):
|
|
if file.endswith(".gns3"):
|
|
gns3_file = file
|
|
|
|
assert gns3_file, "No .gns3 found file for {}".format(before_directory)
|
|
|
|
with open(os.path.join(before_directory, gns3_file)) as f:
|
|
before_topology = json.load(f)
|
|
|
|
# We use a temporary directory for conversion operation to not corrupt our files
|
|
work_directory = str(tmpdir / "work")
|
|
shutil.copytree(before_directory, work_directory)
|
|
|
|
work_topology = load_topology(os.path.join(work_directory, gns3_file))
|
|
assert work_topology
|
|
|
|
if "revision" not in before_topology or before_topology["revision"] < GNS3_FILE_FORMAT_REVISION:
|
|
assert os.path.exists(os.path.join(work_directory, gns3_file + ".backup{}".format(before_topology.get("revision", 0))))
|
|
|
|
# We should have the same file in after directory and the work directory
|
|
for root, dirs, files in os.walk(after_directory):
|
|
for file in files:
|
|
directory = os.path.relpath(root, after_directory)
|
|
file_path = os.path.join(work_directory, directory, file)
|
|
assert os.path.exists(file_path), "{} is missing".format(os.path.join(directory, file))
|
|
|
|
# For gns3project we check if size are not too much differents
|
|
if file_path.endswith(".gns3project"):
|
|
size = os.stat(file_path).st_size
|
|
other_size = os.stat(os.path.join(os.path.join(root, file))).st_size
|
|
assert size in range(other_size - 100, other_size + 100), "File {} is different".format(os.path.join(directory, file))
|
|
# For non .gns3 file we check if the file are the same
|
|
elif not file_path.endswith(".gns3"):
|
|
assert os.stat(file_path).st_size == os.stat(os.path.join(os.path.join(root, file))).st_size, "File {} is different".format(os.path.join(directory, file))
|
|
|
|
# Check if we don't have unexpected file in work directory
|
|
for root, dirs, files in os.walk(work_directory):
|
|
for file in files:
|
|
directory = os.path.relpath(root, work_directory)
|
|
file_path = os.path.join(after_directory, directory, file)
|
|
# .backup are created by the conversion process
|
|
if ".backup" not in file_path:
|
|
assert os.path.exists(file_path), "{} should not be here".format(os.path.join(directory, file))
|
|
|
|
with open(os.path.join(after_directory, gns3_file)) as f:
|
|
after_topology = json.load(f)
|
|
compare_dict("/", work_topology, after_topology)
|
|
|
|
|
|
def compare_dict(path, source, reference):
|
|
"""
|
|
Compare two dictionnary of a topology
|
|
"""
|
|
assert isinstance(source, dict), "Source is not a dict in {}".format(path)
|
|
for key in source:
|
|
assert key in reference, "Unexcepted {} in {} it should be {}".format(key, source, reference)
|
|
for key in sorted(reference.keys()):
|
|
val = reference[key]
|
|
assert key in source, "{} is missing in {}".format(key, source)
|
|
if isinstance(val, str) or isinstance(val, float) or isinstance(val, int) or isinstance(val, bool) or val is None:
|
|
if val == "ANYSTR":
|
|
pass
|
|
elif val == "ANYUUID" and len(source[key]) == 36:
|
|
pass
|
|
# We test that the revision number has been bumpd to last version. This avoid modifying all the tests
|
|
# at each new revision bump.
|
|
elif key == "revision":
|
|
assert source[key] == GNS3_FILE_FORMAT_REVISION
|
|
else:
|
|
assert val == source[key], "Wrong value for {}: \n{}\nit should be\n{}".format(key, source[key], val)
|
|
elif isinstance(val, dict):
|
|
compare_dict(path + key + "/", source[key], val)
|
|
elif isinstance(val, list):
|
|
assert len(val) == len(source[key]), "Not enough value in {} ({}/{}) it shoud be {} not {}".format(key, len(val), len(source[key]), val, source[key])
|
|
for idx, element in enumerate(source[key]):
|
|
if isinstance(element, dict):
|
|
compare_dict(path + key + "/", element, val[idx])
|
|
else:
|
|
assert element == val[idx]
|
|
else:
|
|
assert False, "Value type for {} is not supported".format(key)
|