mirror of
https://github.com/Telecominfraproject/oopt-gnpy.git
synced 2025-10-29 01:02:32 +00:00
fix: use loaded json instead of Path for extra configs
In order to be used by API. Co-authored-by: Renato Ambrosone <renato.ambrosone@polito.it> Signed-off-by: EstherLerouzic <esther.lerouzic@orange.com> Change-Id: I12111427c8a90b85b3158cdd95f4ee771cb39316
This commit is contained in:
72
gnpy/tools/default_edfa_config.py
Normal file
72
gnpy/tools/default_edfa_config.py
Normal file
@@ -0,0 +1,72 @@
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# SPDX-License-Identifier: BSD-3-Clause
|
||||
# gnpy.tools.default_edfa_configs: loads JSON configuration files at module initialization time
|
||||
# Copyright (C) 2025 Telecom Infra Project and GNPy contributors
|
||||
# see AUTHORS.rst for a list of contributors
|
||||
|
||||
"""
|
||||
gnpy.tools.default_edfa_config
|
||||
==============================
|
||||
|
||||
Default configs for pre defined amplifiers:
|
||||
- Juniper-BoosterHG.json,
|
||||
- std_medium_gain_advanced_config.json
|
||||
"""
|
||||
|
||||
from logging import getLogger
|
||||
from typing import Dict, Optional
|
||||
from json import JSONDecodeError, load
|
||||
from pathlib import Path
|
||||
|
||||
from gnpy.core.exceptions import ConfigurationError
|
||||
from gnpy.tools.convert_legacy_yang import yang_to_legacy
|
||||
|
||||
|
||||
_logger = getLogger(__name__)
|
||||
_examples_dir = Path(__file__).parent.parent / 'example-data'
|
||||
|
||||
|
||||
def _load_json_file(file_path: Path) -> Optional[Dict]:
|
||||
"""Load and parse a JSON file.
|
||||
:param file_path: Path to the JSON file to load
|
||||
:type file_path: Path
|
||||
:return: Dict containing the parsed JSON data or None if loading fails
|
||||
:rtype: Optional[Dict]
|
||||
"""
|
||||
try:
|
||||
with open(file_path, 'r', encoding='utf-8') as file:
|
||||
return yang_to_legacy(load(file))
|
||||
except FileNotFoundError:
|
||||
msg = f"Configuration file not found: {file_path}"
|
||||
_logger.error(msg)
|
||||
return None
|
||||
except JSONDecodeError as e:
|
||||
msg = f"Invalid JSON in configuration file {file_path}: {e}"
|
||||
_logger.error(msg)
|
||||
return None
|
||||
|
||||
|
||||
# Default files to load
|
||||
_files_to_load = {
|
||||
"std_medium_gain_advanced_config.json": _examples_dir / "std_medium_gain_advanced_config.json",
|
||||
"Juniper-BoosterHG.json": _examples_dir / "Juniper-BoosterHG.json"
|
||||
}
|
||||
|
||||
# Load configurations
|
||||
_configs: Dict = {}
|
||||
|
||||
for key, filepath in _files_to_load.items():
|
||||
config_data = _load_json_file(filepath)
|
||||
if config_data is not None:
|
||||
_configs[key] = config_data
|
||||
else:
|
||||
_msg = f"Failed to load configuration: {key}. Using empty dict as fallback."
|
||||
_logger.error(_msg)
|
||||
raise ConfigurationError
|
||||
|
||||
# Expose the constant
|
||||
DEFAULT_EXTRA_CONFIG: Dict[str, Dict] = _configs
|
||||
|
||||
DEFAULT_EQPT_CONFIG: Path = _examples_dir / "eqpt_config.json"
|
||||
@@ -18,7 +18,7 @@ from pathlib import Path
|
||||
import json
|
||||
from collections import namedtuple
|
||||
from copy import deepcopy
|
||||
from typing import Union, Dict, List, Tuple
|
||||
from typing import Union, Dict, List, Tuple, Optional
|
||||
from networkx import DiGraph
|
||||
from numpy import arange
|
||||
|
||||
@@ -35,6 +35,7 @@ from gnpy.topology.spectrum_assignment import mvalue_to_slots
|
||||
from gnpy.tools.convert import xls_to_json_data
|
||||
from gnpy.tools.service_sheet import read_service_sheet
|
||||
from gnpy.tools.convert_legacy_yang import yang_to_legacy, legacy_to_yang
|
||||
from gnpy.tools.default_edfa_config import DEFAULT_EXTRA_CONFIG, DEFAULT_EQPT_CONFIG
|
||||
|
||||
|
||||
_logger = getLogger(__name__)
|
||||
@@ -45,10 +46,6 @@ Model_fg = namedtuple('Model_fg', 'nf0')
|
||||
Model_openroadm_ila = namedtuple('Model_openroadm_ila', 'nf_coef')
|
||||
Model_hybrid = namedtuple('Model_hybrid', 'nf_ram gain_ram edfa_variety')
|
||||
Model_dual_stage = namedtuple('Model_dual_stage', 'preamp_variety booster_variety')
|
||||
_examples_dir = Path(__file__).parent.parent / 'example-data'
|
||||
DEFAULT_EXTRA_CONFIG = {"std_medium_gain_advanced_config.json": _examples_dir / "std_medium_gain_advanced_config.json",
|
||||
"Juniper-BoosterHG.json": _examples_dir / "Juniper-BoosterHG.json"}
|
||||
DEFAULT_EQPT_CONFIG = _examples_dir / "eqpt_config.json"
|
||||
|
||||
|
||||
class Model_openroadm_preamp:
|
||||
@@ -245,8 +242,8 @@ class Amp(_JsonThing):
|
||||
if type_def == 'fixed_gain':
|
||||
if 'default_config_from_json' in kwargs:
|
||||
# use user defined default instead of DEFAULT_EDFA_CONFIG
|
||||
config_filename = extra_configs[kwargs.pop('default_config_from_json')]
|
||||
config = load_json(config_filename)
|
||||
config_filename = kwargs.pop('default_config_from_json')
|
||||
config = deepcopy(extra_configs[config_filename])
|
||||
try:
|
||||
nf0 = kwargs.pop('nf0')
|
||||
except KeyError as exc: # nf0 is expected for a fixed gain amp
|
||||
@@ -260,13 +257,13 @@ class Amp(_JsonThing):
|
||||
nf_def = Model_fg(nf0)
|
||||
elif type_def == 'advanced_model':
|
||||
# use the user file name define in library instead of default config
|
||||
config_filename = extra_configs[kwargs.pop('advanced_config_from_json')]
|
||||
config = load_json(config_filename)
|
||||
config_filename = kwargs.pop('advanced_config_from_json')
|
||||
config = deepcopy(extra_configs[config_filename])
|
||||
elif type_def == 'variable_gain':
|
||||
if 'default_config_from_json' in kwargs:
|
||||
# use user defined default instead of DEFAULT_EDFA_CONFIG
|
||||
config_filename = extra_configs[kwargs.pop('default_config_from_json')]
|
||||
config = load_json(config_filename)
|
||||
config_filename = kwargs.pop('default_config_from_json')
|
||||
config = deepcopy(extra_configs[config_filename])
|
||||
gain_min, gain_max = kwargs['gain_min'], kwargs['gain_flatmax']
|
||||
try: # nf_min and nf_max are expected for a variable gain amp
|
||||
nf_min = kwargs.pop('nf_min')
|
||||
@@ -389,36 +386,37 @@ def _spectrum_from_json(json_data: dict):
|
||||
return spectrum
|
||||
|
||||
|
||||
def merge_equipment(equipment: dict, additional_filenames: List[Path], extra_configs: Dict[str, Path]):
|
||||
def merge_equipment(equipment: Dict, extra_equipments: Dict[str, Dict], extra_configs: Dict[str, Dict]):
|
||||
"""Merge additional equipment libraries into the base equipment dictionary.
|
||||
Typical case is the use of third party transceivers which are not part of a the supplier library.
|
||||
|
||||
raise warnings if the same reference is used on two different libraries
|
||||
"""
|
||||
for filename in additional_filenames:
|
||||
extra_eqpt = load_equipment(filename, extra_configs)
|
||||
for filename, json_data in extra_equipments.items():
|
||||
extra_eqpt = _equipment_from_json(json_data, extra_configs)
|
||||
# populate with default eqpt to streamline loading
|
||||
for eqpt_type, extra_items in extra_eqpt.items():
|
||||
for type_variety, item in extra_items.items():
|
||||
if type_variety not in equipment[eqpt_type]:
|
||||
equipment[eqpt_type][type_variety] = item
|
||||
else:
|
||||
msg = f'\n\tEquipment file {filename.name}: duplicate equipment entry found: {eqpt_type}-{type_variety}\n'
|
||||
msg = f'\n\tEquipment file {filename}: duplicate equipment entry found: {eqpt_type}-{type_variety}\n'
|
||||
_logger.warning(msg)
|
||||
|
||||
|
||||
def load_equipments_and_configs(equipment_filename: Path,
|
||||
extra_equipment_filenames: List[Path],
|
||||
extra_config_filenames: List[Path]) -> dict:
|
||||
extra_config_filenames: List[Path]) -> Dict:
|
||||
"""Loads equipment configurations and merge with additional equipment and configuration files.
|
||||
|
||||
Args:
|
||||
equipment_filename (Path): The path to the primary equipment configuration file.
|
||||
extra_equipment_filenames (List[Path]): A list of paths to additional equipment configuration files to merge.
|
||||
extra_config_filenames (List[Path]): A list of paths to additional configuration files to include.
|
||||
|
||||
Returns:
|
||||
dict: A dictionary containing the loaded equipment configurations.
|
||||
:param equipment_filename: The path to the primary equipment configuration file.
|
||||
:type equipment_filename: Path
|
||||
:param extra_equipment_filenames: A list of paths to additional equipment configuration files to merge.
|
||||
:type extra_equipment_filenames: List[Path]
|
||||
:param extra_config_filenames: A list of paths to additional configuration files to include.
|
||||
:type extra_config_filenames: List[Path]
|
||||
:return: A dictionary containing the loaded equipment configurations.
|
||||
:rtype: Dict
|
||||
|
||||
Notes:
|
||||
If no equipment filename is provided, a default equipment configuration will be used.
|
||||
@@ -429,16 +427,24 @@ def load_equipments_and_configs(equipment_filename: Path,
|
||||
if not equipment_filename:
|
||||
equipment_filename = DEFAULT_EQPT_CONFIG
|
||||
if extra_config_filenames:
|
||||
extra_configs = {f.name: f for f in extra_config_filenames}
|
||||
# All files must have different filenames (as filename is used as the key in the library)
|
||||
filename_list = [f.name for f in extra_config_filenames]
|
||||
if len(set(filename_list)) != len(extra_config_filenames):
|
||||
msg = f'Identical filenames for extra-config {filename_list}'
|
||||
_logger.error(msg)
|
||||
raise ConfigurationError(msg)
|
||||
extra_configs = {f.name: load_json(f) for f in extra_config_filenames}
|
||||
for k, v in DEFAULT_EXTRA_CONFIG.items():
|
||||
extra_configs[k] = v
|
||||
equipment = load_equipment(equipment_filename, extra_configs)
|
||||
if extra_equipment_filenames:
|
||||
merge_equipment(equipment, extra_equipment_filenames, extra_configs)
|
||||
# use the string representation of the path to support identical filenames but placed in different folders.
|
||||
extra_equipments = {f.as_posix(): load_json(f) for f in extra_equipment_filenames}
|
||||
merge_equipment(equipment, extra_equipments, extra_configs)
|
||||
return equipment
|
||||
|
||||
|
||||
def load_equipment(filename: Path, extra_configs: Dict[str, Path] = DEFAULT_EXTRA_CONFIG) -> dict:
|
||||
def load_equipment(filename: Path, extra_configs: Dict[str, Dict] = DEFAULT_EXTRA_CONFIG) -> Dict:
|
||||
"""Load equipment, returns equipment dict
|
||||
"""
|
||||
json_data = load_gnpy_json(filename)
|
||||
@@ -544,7 +550,7 @@ def _si_sanity_check(equipment):
|
||||
del equipment['SI'][possible_SI[0]]
|
||||
|
||||
|
||||
def _equipment_from_json(json_data: dict, extra_configs: Dict[str, Path]) -> dict:
|
||||
def _equipment_from_json(json_data: dict, extra_configs: Dict[str, Dict]) -> Dict:
|
||||
"""build global dictionnary eqpt_library that stores all eqpt characteristics:
|
||||
edfa type type_variety, fiber type_variety
|
||||
from the eqpt_config.json (filename parameter)
|
||||
@@ -1022,13 +1028,21 @@ def results_to_json(pathresults: List[ResultElement]):
|
||||
return {'response': [n.json for n in pathresults]}
|
||||
|
||||
|
||||
def load_eqpt_topo_from_json(eqpt: dict, topology: dict) -> Tuple[dict, DiGraph]:
|
||||
def load_eqpt_topo_from_json(eqpt: dict, topology: dict, extra_equipments: Optional[Dict[str, Dict]] = None,
|
||||
extra_configs: Dict[str, Dict] = DEFAULT_EXTRA_CONFIG) -> Tuple[dict, DiGraph]:
|
||||
"""Loads equipment configuration and network topology from JSON data.
|
||||
|
||||
:param eqpt: Dictionary containing the equipment configuration in JSON format.
|
||||
It includes details about the devices to be processed and structured.
|
||||
:type eqpt: dict
|
||||
:param topology: Dictionary representing the network topology in JSON format,
|
||||
defining the structure of the network and its connections.
|
||||
:type topology: dict
|
||||
:param extra_equipments: dictionary containing additional libraries (eg for pluggables). Key can be
|
||||
the file Path or any other string.
|
||||
:type extra_equipments: Optional[Dict[str, Dict]]
|
||||
:param extra_configs: Additional configurations for amplifiers in the library
|
||||
:type extra_configs: Dict[str, Dict]
|
||||
|
||||
:return: A tuple containing:
|
||||
|
||||
@@ -1036,7 +1050,8 @@ def load_eqpt_topo_from_json(eqpt: dict, topology: dict) -> Tuple[dict, DiGraph]
|
||||
- A directed graph (DiGraph) representing the network topology, where nodes
|
||||
correspond to equipment and edges define their connections.
|
||||
"""
|
||||
equipment = _equipment_from_json(eqpt, DEFAULT_EXTRA_CONFIG)
|
||||
equipment = _equipment_from_json(eqpt, extra_configs)
|
||||
if extra_equipments:
|
||||
merge_equipment(equipment, extra_equipments, extra_configs)
|
||||
network = network_from_json(topology, equipment)
|
||||
return equipment, network
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@ WARNING gnpy.tools.json_io:json_io.py
|
||||
default value is type_variety = default
|
||||
|
||||
WARNING gnpy.tools.json_io:json_io.py
|
||||
Equipment file extra_eqpt_config.json: duplicate equipment entry found: Transceiver-ZR400G
|
||||
Equipment file tests/data/extra_eqpt_config.json: duplicate equipment entry found: Transceiver-ZR400G
|
||||
|
||||
INFO gnpy.core.network:network.py
|
||||
Reference used for design: (Input optical power reference in span = 0.00dBm
|
||||
|
||||
@@ -6,23 +6,25 @@
|
||||
# Copyright (C) 2025 Telecom Infra Project and GNPy contributors
|
||||
# see AUTHORS.rst for a list of contributors
|
||||
|
||||
from pathlib import Path
|
||||
import pytest
|
||||
|
||||
from numpy import zeros, array
|
||||
from numpy.testing import assert_allclose
|
||||
|
||||
from gnpy.core.elements import Transceiver, Edfa, Fiber
|
||||
from gnpy.core.utils import automatic_fmax, lin2db, db2lin, merge_amplifier_restrictions, dbm2watt, watt2dbm
|
||||
from gnpy.core.info import create_input_spectral_information, create_arbitrary_spectral_information
|
||||
from gnpy.core.network import build_network, set_amplifier_voa
|
||||
from gnpy.tools.json_io import load_network, load_equipment, load_json, _equipment_from_json, network_from_json
|
||||
from gnpy.topology.request import PathRequest
|
||||
from pathlib import Path
|
||||
import pytest
|
||||
|
||||
|
||||
TEST_DIR = Path(__file__).parent
|
||||
DATA_DIR = TEST_DIR / 'data'
|
||||
test_network = DATA_DIR / 'test_network.json'
|
||||
eqpt_library = DATA_DIR / 'eqpt_config.json'
|
||||
extra_configs = {"std_medium_gain_advanced_config.json": DATA_DIR / "std_medium_gain_advanced_config.json",
|
||||
"Juniper-BoosterHG.json": DATA_DIR / "Juniper-BoosterHG.json"}
|
||||
extra_configs = {"std_medium_gain_advanced_config.json": load_json(DATA_DIR / "std_medium_gain_advanced_config.json")}
|
||||
|
||||
# TODO in elements.py code: pytests doesn't pass with 1 channel: interpolate fail
|
||||
|
||||
@@ -551,7 +553,7 @@ def test_multiband():
|
||||
def test_user_defined_config():
|
||||
"""Checks that a user defined config is correctly used instead of DEFAULT_EDFA_CONFIG
|
||||
"""
|
||||
extra_configs['user_edfa_config.json'] = DATA_DIR / 'user_edfa_config.json'
|
||||
extra_configs['user_edfa_config.json'] = load_json(DATA_DIR / 'user_edfa_config.json')
|
||||
user_edfa = {
|
||||
"type_variety": "user_defined",
|
||||
"type_def": "variable_gain",
|
||||
@@ -596,7 +598,7 @@ def test_default_config():
|
||||
"""Checks that a config using a file gives the exact same result as the default config if values are identical
|
||||
to DEFAULT_EDFA_CONFIG
|
||||
"""
|
||||
extra_configs['copy_default_edfa_config.json'] = DATA_DIR / 'copy_default_edfa_config.json'
|
||||
extra_configs['copy_default_edfa_config.json'] = load_json(DATA_DIR / 'copy_default_edfa_config.json')
|
||||
user_edfa = {
|
||||
"type_variety": "user_defined",
|
||||
"type_def": "variable_gain",
|
||||
@@ -680,7 +682,7 @@ def test_frequency_range(file):
|
||||
}
|
||||
if file:
|
||||
user_edfa["default_config_from_json"] = file['name']
|
||||
extra_configs[file['name']] = file['path']
|
||||
extra_configs[file['name']] = load_json(file['path'])
|
||||
# add the reference to
|
||||
json_data = load_json(eqpt_library)
|
||||
json_data['Edfa'].append(user_edfa)
|
||||
|
||||
@@ -33,8 +33,7 @@ network_file_name = data_dir / 'testTopology_expected.json'
|
||||
service_file_name = data_dir / 'testTopology_testservices.json'
|
||||
result_file_name = data_dir / 'testTopology_testresults.json'
|
||||
eqpt_library_name = data_dir / 'eqpt_config.json'
|
||||
extra_configs = {"std_medium_gain_advanced_config.json": data_dir / "std_medium_gain_advanced_config.json",
|
||||
"Juniper-BoosterHG.json": data_dir / "Juniper-BoosterHG.json"}
|
||||
extra_configs = {"std_medium_gain_advanced_config.json": load_json(data_dir / "std_medium_gain_advanced_config.json")}
|
||||
|
||||
|
||||
def pathrequest(pch_dbm: float, p_tot_dbm: float = None, nb_channels: int = None):
|
||||
|
||||
@@ -22,7 +22,8 @@ from gnpy.core.elements import Roadm
|
||||
from gnpy.topology.request import (compute_path_dsjctn, isdisjoint, find_reversed_path, PathRequest,
|
||||
correct_json_route_list, requests_aggregation, Disjunction)
|
||||
from gnpy.topology.spectrum_assignment import build_oms_list
|
||||
from gnpy.tools.json_io import requests_from_json, load_requests, load_network, load_equipment, disjunctions_from_json
|
||||
from gnpy.tools.json_io import requests_from_json, load_requests, load_network, load_equipment, \
|
||||
disjunctions_from_json, load_json
|
||||
|
||||
|
||||
DATA_DIR = Path(__file__).parent.parent / 'tests/data'
|
||||
@@ -30,8 +31,7 @@ NETWORK_FILE_NAME = DATA_DIR / 'testTopology_expected.json'
|
||||
SERVICE_FILE_NAME = DATA_DIR / 'testTopology_testservices.json'
|
||||
RESULT_FILE_NAME = DATA_DIR / 'testTopology_testresults.json'
|
||||
EQPT_LIBRARY_NAME = DATA_DIR / 'eqpt_config.json'
|
||||
EXTRA_CONFIGS = {"std_medium_gain_advanced_config.json": DATA_DIR / "std_medium_gain_advanced_config.json",
|
||||
"Juniper-BoosterHG.json": DATA_DIR / "Juniper-BoosterHG.json"}
|
||||
EXTRA_CONFIGS = {"std_medium_gain_advanced_config.json": load_json(DATA_DIR / "std_medium_gain_advanced_config.json")}
|
||||
|
||||
|
||||
@pytest.fixture()
|
||||
|
||||
@@ -34,8 +34,7 @@ TEST_DIR = Path(__file__).parent
|
||||
DATA_DIR = TEST_DIR / 'data'
|
||||
EQPT_FILENAME = DATA_DIR / 'eqpt_config.json'
|
||||
NETWORK_FILENAME = DATA_DIR / 'testTopology_expected.json'
|
||||
EXTRA_CONFIGS = {"std_medium_gain_advanced_config.json": DATA_DIR / "std_medium_gain_advanced_config.json",
|
||||
"Juniper-BoosterHG.json": DATA_DIR / "Juniper-BoosterHG.json"}
|
||||
EXTRA_CONFIGS = {"std_medium_gain_advanced_config.json": load_json(DATA_DIR / "std_medium_gain_advanced_config.json")}
|
||||
|
||||
|
||||
@pytest.mark.parametrize('degree, equalization_type, target, expected_pch_out_dbm, expected_si',
|
||||
|
||||
@@ -19,7 +19,7 @@ from numpy.testing import assert_array_equal, assert_allclose
|
||||
import pytest
|
||||
from gnpy.core.utils import automatic_nch, dbm2watt
|
||||
from gnpy.core.network import build_network
|
||||
from gnpy.tools.json_io import load_equipment, load_network
|
||||
from gnpy.tools.json_io import load_equipment, load_network, load_json
|
||||
from gnpy.core.equipment import trx_mode_params
|
||||
from gnpy.topology.request import PathRequest, compute_constrained_path, propagate
|
||||
|
||||
@@ -28,8 +28,7 @@ TEST_DIR = Path(__file__).parent
|
||||
DATA_DIR = TEST_DIR / 'data'
|
||||
EQPT_FILENAME = DATA_DIR / 'eqpt_config.json'
|
||||
NETWORK_FILENAME = DATA_DIR / 'perdegreemeshTopologyExampleV2_auto_design_expected.json'
|
||||
EXTRA_CONFIGS = {"std_medium_gain_advanced_config.json": DATA_DIR / "std_medium_gain_advanced_config.json",
|
||||
"Juniper-BoosterHG.json": DATA_DIR / "Juniper-BoosterHG.json"}
|
||||
EXTRA_CONFIGS = {"std_medium_gain_advanced_config.json": load_json(DATA_DIR / "std_medium_gain_advanced_config.json")}
|
||||
|
||||
|
||||
def pathrequest(pch_dbm, nb_channels):
|
||||
|
||||
56
tests/test_json_io.py
Normal file
56
tests/test_json_io.py
Normal file
@@ -0,0 +1,56 @@
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# SPDX-License-Identifier: BSD-3-Clause
|
||||
# test_gain_mode
|
||||
# Copyright (C) 2025 Telecom Infra Project and GNPy contributors
|
||||
# see AUTHORS.rst for a list of contributors
|
||||
|
||||
"""
|
||||
checks behaviour of gain mode
|
||||
- if all amps have their gains set, check that these gains are used, even if power_dbm or req_power change
|
||||
- check that saturation is correct in gain mode
|
||||
|
||||
"""
|
||||
|
||||
from pathlib import Path
|
||||
|
||||
from gnpy.tools.json_io import load_json, load_eqpt_topo_from_json
|
||||
import networkx as nx
|
||||
|
||||
|
||||
TEST_DIR = Path(__file__).parent
|
||||
DATA_DIR = TEST_DIR / 'data'
|
||||
EQPT_FILENAME = DATA_DIR / 'eqpt_config.json'
|
||||
NETWORK_FILENAME = DATA_DIR / 'LinkforTest.json'
|
||||
EXTRA_CONFIGS = {"std_medium_gain_advanced_config.json": load_json(DATA_DIR / "std_medium_gain_advanced_config.json")}
|
||||
|
||||
|
||||
def test_load_eqpt_topo_from_json():
|
||||
eqpt = load_json(EQPT_FILENAME)
|
||||
topology = load_json(NETWORK_FILENAME)
|
||||
extra_equipments = None
|
||||
extra_configs = EXTRA_CONFIGS
|
||||
|
||||
equipment, network = load_eqpt_topo_from_json(eqpt, topology, extra_equipments, extra_configs)
|
||||
|
||||
assert isinstance(equipment, dict)
|
||||
assert isinstance(network, nx.DiGraph)
|
||||
|
||||
assert len(network.nodes) > 0
|
||||
assert len(network.edges) > 0
|
||||
|
||||
|
||||
def test_load_eqpt_topo_from_json_default_extra():
|
||||
eqpt = load_json(EQPT_FILENAME)
|
||||
topology = load_json(NETWORK_FILENAME)
|
||||
|
||||
equipment, network = load_eqpt_topo_from_json(eqpt, topology)
|
||||
|
||||
assert isinstance(equipment, dict)
|
||||
assert isinstance(network, nx.DiGraph)
|
||||
# Check that some expected nodes exist (example: 'A', 'B')
|
||||
assert len(network.nodes) > 0
|
||||
assert len(network.edges) > 0
|
||||
|
||||
|
||||
@@ -17,15 +17,14 @@ import pytest
|
||||
from gnpy.core.exceptions import ConfigurationError, ServiceError, EquipmentConfigError, ParametersError, \
|
||||
NetworkTopologyError
|
||||
from gnpy.tools.json_io import SI, Roadm, Amp, load_equipment, requests_from_json, network_from_json, \
|
||||
load_network, load_requests
|
||||
load_network, load_requests, load_json
|
||||
from gnpy.tools.convert import xls_to_json_data
|
||||
|
||||
TEST_DIR = Path(__file__).parent
|
||||
EQPT_FILENAME = TEST_DIR / 'data/eqpt_config.json'
|
||||
MULTIBAND_EQPT_FILENAME = TEST_DIR / 'data/eqpt_config_multiband.json'
|
||||
DATA_DIR = TEST_DIR / 'data'
|
||||
EXTRA_CONFIGS = {"std_medium_gain_advanced_config.json": DATA_DIR / "std_medium_gain_advanced_config.json",
|
||||
"Juniper-BoosterHG.json": DATA_DIR / "Juniper-BoosterHG.json"}
|
||||
EXTRA_CONFIGS = {"std_medium_gain_advanced_config.json": load_json(DATA_DIR / "std_medium_gain_advanced_config.json")}
|
||||
|
||||
|
||||
def test_jsonthing(caplog):
|
||||
|
||||
@@ -31,8 +31,7 @@ DATA_DIR = TEST_DIR / 'data'
|
||||
EQPT_FILENAME = DATA_DIR / 'eqpt_config.json'
|
||||
EQPT_MULTBAND_FILENAME = DATA_DIR / 'eqpt_config_multiband.json'
|
||||
NETWORK_FILENAME = DATA_DIR / 'bugfixiteratortopo.json'
|
||||
EXTRA_CONFIGS = {"std_medium_gain_advanced_config.json": DATA_DIR / "std_medium_gain_advanced_config.json",
|
||||
"Juniper-BoosterHG.json": DATA_DIR / "Juniper-BoosterHG.json"}
|
||||
EXTRA_CONFIGS = {"std_medium_gain_advanced_config.json": load_json(DATA_DIR / "std_medium_gain_advanced_config.json")}
|
||||
|
||||
|
||||
@pytest.mark.parametrize("node, attenuation", [
|
||||
|
||||
@@ -36,13 +36,12 @@ from gnpy.tools.convert import convert_file
|
||||
from gnpy.tools.json_io import (load_json, load_network, save_network, load_equipment, requests_from_json,
|
||||
disjunctions_from_json, network_to_json, network_from_json)
|
||||
from gnpy.tools.service_sheet import read_service_sheet, correct_xls_route_list, Request_element, Request
|
||||
from gnpy.tools.default_edfa_config import DEFAULT_EXTRA_CONFIG
|
||||
|
||||
TEST_DIR = Path(__file__).parent
|
||||
DATA_DIR = TEST_DIR / 'data'
|
||||
EQPT_FILENAME = DATA_DIR / 'eqpt_config.json'
|
||||
EXTRA_CONFIGS = {"std_medium_gain_advanced_config.json": DATA_DIR / "std_medium_gain_advanced_config.json",
|
||||
"Juniper-BoosterHG.json": DATA_DIR / "Juniper-BoosterHG.json"}
|
||||
equipment = load_equipment(EQPT_FILENAME, EXTRA_CONFIGS)
|
||||
equipment = load_equipment(EQPT_FILENAME, DEFAULT_EXTRA_CONFIG)
|
||||
|
||||
|
||||
def pathrequest(pch_dbm: float, p_tot_dbm: float = None, nb_channels: int = None):
|
||||
@@ -108,7 +107,7 @@ def test_excel_json_generation(tmpdir, xls_input, expected_json_output):
|
||||
}.items())
|
||||
def test_auto_design_generation_fromxlsgainmode(tmpdir, xls_input, expected_json_output):
|
||||
"""tests generation of topology json and that the build network gives correct results in gain mode"""
|
||||
equipment = load_equipment(EQPT_FILENAME, EXTRA_CONFIGS)
|
||||
equipment = load_equipment(EQPT_FILENAME, DEFAULT_EXTRA_CONFIG)
|
||||
network = load_network(xls_input, equipment)
|
||||
add_missing_elements_in_network(network, equipment)
|
||||
# in order to test the Eqpt sheet and load gain target,
|
||||
@@ -139,7 +138,7 @@ def test_auto_design_generation_fromxlsgainmode(tmpdir, xls_input, expected_json
|
||||
}.items())
|
||||
def test_auto_design_generation_fromjson(tmpdir, json_input, power_mode):
|
||||
"""test that autodesign creates same file as an input file already autodesigned"""
|
||||
equipment = load_equipment(EQPT_FILENAME, EXTRA_CONFIGS)
|
||||
equipment = load_equipment(EQPT_FILENAME, DEFAULT_EXTRA_CONFIG)
|
||||
network = load_network(json_input, equipment)
|
||||
# in order to test the Eqpt sheet and load gain target,
|
||||
# change the power-mode to False (to be in gain mode)
|
||||
@@ -166,7 +165,7 @@ def test_auto_design_generation_fromjson(tmpdir, json_input, power_mode):
|
||||
}.items())
|
||||
def test_excel_service_json_generation(xls_input, expected_json_output):
|
||||
"""test services creation"""
|
||||
equipment = load_equipment(EQPT_FILENAME, EXTRA_CONFIGS)
|
||||
equipment = load_equipment(EQPT_FILENAME, DEFAULT_EXTRA_CONFIG)
|
||||
network = load_network(DATA_DIR / 'testTopology.xls', equipment)
|
||||
# Build the network once using the default power defined in SI in eqpt config
|
||||
p_db = equipment['SI']['default'].power_dbm
|
||||
@@ -187,7 +186,7 @@ def test_excel_service_json_generation(xls_input, expected_json_output):
|
||||
def test_csv_response_generation(tmpdir, json_input):
|
||||
"""tests if generated csv is consistant with expected generation same columns (order not important)"""
|
||||
json_data = load_json(json_input)
|
||||
equipment = load_equipment(EQPT_FILENAME, EXTRA_CONFIGS)
|
||||
equipment = load_equipment(EQPT_FILENAME, DEFAULT_EXTRA_CONFIG)
|
||||
csv_filename = Path(tmpdir / json_input.name).with_suffix('.csv')
|
||||
with open(csv_filename, 'w', encoding='utf-8') as fcsv:
|
||||
jsontocsv(json_data, equipment, fcsv)
|
||||
@@ -252,7 +251,7 @@ def test_csv_response_generation(tmpdir, json_input):
|
||||
def test_json_response_generation(xls_input, expected_response_file):
|
||||
"""tests if json response is correctly generated for all combinations of requests"""
|
||||
|
||||
equipment = load_equipment(EQPT_FILENAME, EXTRA_CONFIGS)
|
||||
equipment = load_equipment(EQPT_FILENAME, DEFAULT_EXTRA_CONFIG)
|
||||
network = load_network(xls_input, equipment)
|
||||
p_db = equipment['SI']['default'].power_dbm
|
||||
|
||||
@@ -669,7 +668,7 @@ def test_roadm_type_variety(type_variety, target_pch_out_db, correct_variety):
|
||||
# Do not add type variety in json_data to test that it creates a 'default' type_variety
|
||||
expected_roadm['type_variety'] = 'default'
|
||||
expected_roadm['params']['target_pch_out_db'] = target_pch_out_db
|
||||
equipment = load_equipment(EQPT_FILENAME, EXTRA_CONFIGS)
|
||||
equipment = load_equipment(EQPT_FILENAME, DEFAULT_EXTRA_CONFIG)
|
||||
if correct_variety:
|
||||
network = network_from_json(json_data, equipment)
|
||||
roadm = [n for n in network.nodes()][0]
|
||||
|
||||
@@ -20,6 +20,7 @@ from gnpy.core.utils import automatic_nch, dbm2watt
|
||||
from gnpy.topology.request import explicit_path, PathRequest
|
||||
from gnpy.topology.spectrum_assignment import build_oms_list
|
||||
from gnpy.tools.json_io import load_equipment, load_network, requests_from_json
|
||||
from gnpy.tools.default_edfa_config import DEFAULT_EXTRA_CONFIG
|
||||
|
||||
|
||||
TEST_DIR = Path(__file__).parent
|
||||
@@ -27,9 +28,8 @@ DATA_DIR = TEST_DIR / 'data'
|
||||
EQPT_FILENAME = DATA_DIR / 'eqpt_config.json'
|
||||
NETWORK_FILENAME = DATA_DIR / 'testTopology_auto_design_expected.json'
|
||||
SERVICE_FILENAME = DATA_DIR / 'testTopology_services_expected.json'
|
||||
EXTRA_CONFIGS = {"std_medium_gain_advanced_config.json": DATA_DIR / "std_medium_gain_advanced_config.json",
|
||||
"Juniper-BoosterHG.json": DATA_DIR / "Juniper-BoosterHG.json"}
|
||||
equipment = load_equipment(EQPT_FILENAME, EXTRA_CONFIGS)
|
||||
|
||||
equipment = load_equipment(EQPT_FILENAME, DEFAULT_EXTRA_CONFIG)
|
||||
|
||||
|
||||
def pathrequest(pch_dbm, nb_channels):
|
||||
|
||||
@@ -22,15 +22,14 @@ from gnpy.core.elements import Transceiver, Fiber, Edfa, Roadm
|
||||
from gnpy.core.utils import db2lin, dbm2watt
|
||||
from gnpy.core.info import create_input_spectral_information
|
||||
from gnpy.core.network import build_network
|
||||
from gnpy.tools.json_io import load_network, load_equipment, network_from_json
|
||||
from gnpy.tools.json_io import load_network, load_equipment, network_from_json, load_json
|
||||
from gnpy.topology.request import PathRequest
|
||||
|
||||
TEST_DIR = Path(__file__).parent
|
||||
DATA_DIR = TEST_DIR / 'data'
|
||||
network_file_name = DATA_DIR / 'LinkforTest.json'
|
||||
eqpt_library_name = DATA_DIR / 'eqpt_config.json'
|
||||
EXTRA_CONFIGS = {"std_medium_gain_advanced_config.json": DATA_DIR / "std_medium_gain_advanced_config.json",
|
||||
"Juniper-BoosterHG.json": DATA_DIR / "Juniper-BoosterHG.json"}
|
||||
EXTRA_CONFIGS = {"std_medium_gain_advanced_config.json": load_json(DATA_DIR / "std_medium_gain_advanced_config.json")}
|
||||
|
||||
|
||||
@pytest.fixture(params=[(96, 0.05e12), (60, 0.075e12), (45, 0.1e12), (2, 0.1e12)],
|
||||
|
||||
@@ -35,8 +35,7 @@ TEST_DIR = Path(__file__).parent
|
||||
DATA_DIR = TEST_DIR / 'data'
|
||||
EQPT_FILENAME = DATA_DIR / 'eqpt_config.json'
|
||||
NETWORK_FILE_NAME = DATA_DIR / 'testTopology_expected.json'
|
||||
EXTRA_CONFIGS = {"std_medium_gain_advanced_config.json": DATA_DIR / "std_medium_gain_advanced_config.json",
|
||||
"Juniper-BoosterHG.json": DATA_DIR / "Juniper-BoosterHG.json"}
|
||||
EXTRA_CONFIGS = {"std_medium_gain_advanced_config.json": load_json(DATA_DIR / "std_medium_gain_advanced_config.json")}
|
||||
|
||||
|
||||
def pathrequest(pch_dbm: float, p_tot_dbm: float = None, nb_channels: int = None):
|
||||
|
||||
@@ -24,17 +24,16 @@ from gnpy.topology.spectrum_assignment import (build_oms_list, align_grids, nval
|
||||
bitmap_sum, Bitmap, spectrum_selection, pth_assign_spectrum,
|
||||
build_path_oms_id_list, aggregate_oms_bitmap)
|
||||
from gnpy.tools.json_io import (load_equipment, load_network, requests_from_json, disjunctions_from_json,
|
||||
_check_one_request)
|
||||
_check_one_request, load_json)
|
||||
|
||||
TEST_DIR = Path(__file__).parent
|
||||
DATA_DIR = TEST_DIR / 'data'
|
||||
EQPT_FILENAME = DATA_DIR / 'eqpt_config.json'
|
||||
NETWORK_FILENAME = DATA_DIR / 'testTopology_auto_design_expected.json'
|
||||
SERVICE_FILENAME = DATA_DIR / 'testTopology_services_expected.json'
|
||||
EXTRA_CONFIGS = {"std_medium_gain_advanced_config.json": DATA_DIR / "std_medium_gain_advanced_config.json",
|
||||
"Juniper-BoosterHG.json": DATA_DIR / "Juniper-BoosterHG.json"}
|
||||
EXTRA_CONFIGS = {"std_medium_gain_advanced_config.json": load_json(DATA_DIR / "std_medium_gain_advanced_config.json")}
|
||||
|
||||
grid = 0.00625e12
|
||||
grid = 0.00625e12
|
||||
slot = 0.0125e12
|
||||
guardband = 25.0e9
|
||||
cband_freq_min = 191.3e12
|
||||
|
||||
@@ -16,14 +16,13 @@ import pytest
|
||||
from gnpy.core.equipment import trx_mode_params
|
||||
from gnpy.core.exceptions import EquipmentConfigError
|
||||
from gnpy.tools.json_io import load_equipment, load_json, _equipment_from_json
|
||||
from gnpy.tools.default_edfa_config import DEFAULT_EXTRA_CONFIG
|
||||
|
||||
|
||||
TEST_DIR = Path(__file__).parent
|
||||
DATA_DIR = TEST_DIR / 'data'
|
||||
EQPT_LIBRARY_NAME = DATA_DIR / 'eqpt_config.json'
|
||||
NETWORK_FILE_NAME = DATA_DIR / 'testTopology_expected.json'
|
||||
EXTRA_CONFIGS = {"std_medium_gain_advanced_config.json": DATA_DIR / "std_medium_gain_advanced_config.json",
|
||||
"Juniper-BoosterHG.json": DATA_DIR / "Juniper-BoosterHG.json"}
|
||||
|
||||
|
||||
@pytest.mark.parametrize('trx_type, trx_mode, error_message, no_error, expected_result',
|
||||
@@ -96,7 +95,7 @@ def test_trx_mode_params(trx_type, trx_mode, error_message, no_error, expected_r
|
||||
'penalties': None,
|
||||
'cost': None
|
||||
}
|
||||
equipment = load_equipment(EQPT_LIBRARY_NAME, EXTRA_CONFIGS)
|
||||
equipment = load_equipment(EQPT_LIBRARY_NAME, DEFAULT_EXTRA_CONFIG)
|
||||
if no_error:
|
||||
trx_params = trx_mode_params(equipment, trx_type, trx_mode, error_message)
|
||||
print(trx_params)
|
||||
@@ -155,7 +154,7 @@ def test_wrong_baudrate_spacing(baudrate, spacing, error_message):
|
||||
'equalization_offset_db': 0}]
|
||||
}
|
||||
json_data['Transceiver'].append(wrong_transceiver)
|
||||
equipment = _equipment_from_json(json_data, EXTRA_CONFIGS)
|
||||
equipment = _equipment_from_json(json_data, DEFAULT_EXTRA_CONFIG)
|
||||
|
||||
with pytest.raises(EquipmentConfigError, match=error_message):
|
||||
_ = trx_mode_params(equipment, 'vendorB_trx-type1', 'wrong mode', error_message=False)
|
||||
|
||||
Reference in New Issue
Block a user