Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • silecs/opensilecs
  • k.fugiel/opensilecs
  • s.kupiecki/opensilecs
3 results
Show changes
Commits on Source (3)
Showing
with 730 additions and 627 deletions
lxml
xmlschema
\ No newline at end of file
import os
from setuptools import setup, find_packages from setuptools import setup, find_packages
__version__ = "0.1.0" __version__ = "0.1.0"
__description__ = "Script in order to model PLC devices in FESA by using the Silecs framework" __description__ = "Script in order to model PLC devices in FESA by using the Silecs framework"
with open('requirements.txt') as f:
required = f.read().splitlines()
setup( setup(
name="opensilecs", name="opensilecs",
version=__version__, version=__version__,
description=__description__, description=__description__,
url="https://git.gsi.de/silecs/opensilecs/-/tree/master/silecs-cli", url="https://git.gsi.de/silecs/opensilecs",
author="GSI", author="GSI",
license="GPLv3", license="GPLv3",
packages=find_packages(), packages=find_packages(),
install_requires=[ install_requires=required
'lxml',
],
entry_points={"console_scripts": ['silecs = silecs_cli.silecs:run']},
) )
\ No newline at end of file
...@@ -374,6 +374,11 @@ ...@@ -374,6 +374,11 @@
</xs:appinfo> </xs:appinfo>
</xs:annotation> </xs:annotation>
</xs:attribute> </xs:attribute>
<xs:assert test="if (@model != 'M340')
then true()
else if(@base-address mod 2 = 0)
then true()
else false()" />
</xs:extension> </xs:extension>
</xs:complexContent> </xs:complexContent>
</xs:complexType> </xs:complexType>
...@@ -432,6 +437,11 @@ ...@@ -432,6 +437,11 @@
</xs:appinfo> </xs:appinfo>
</xs:annotation> </xs:annotation>
</xs:attribute> </xs:attribute>
<xs:assert test="if (@model != 'CX9020')
then true()
else if(@base-address mod 2 = 0)
then true()
else false()" />
</xs:extension> </xs:extension>
</xs:complexContent> </xs:complexContent>
</xs:complexType> </xs:complexType>
......
...@@ -2,4 +2,15 @@ ...@@ -2,4 +2,15 @@
Command line tool for silecs project creation, xml validation, code generation, etc. Command line tool for silecs project creation, xml validation, code generation, etc.
Component of the opensilecs PLC-framework. Component of the opensilecs PLC-framework.
\ No newline at end of file
## Tests
In [tests](tests) directory there is a file [tests_silecs.py](tests/tests_silecs.py) containg unit tests written using `unittest` framework.
Directory [testClasses](tests/testClasses) contain example classes uses for tests and some extra example files used for tests are provided in directory [examples](tests/examples).
Tests can be run using following command:
```
python3 -m unittest
```
...@@ -6,8 +6,10 @@ import datetime ...@@ -6,8 +6,10 @@ import datetime
import shutil import shutil
import subprocess import subprocess
import lxml.etree from xml.dom import minidom
from packaging import version
import xmlschema
SILECS_VERSION = "2.3.0" SILECS_VERSION = "2.3.0"
SILECSDESIGN = "silecsdesign" SILECSDESIGN = "silecsdesign"
...@@ -22,16 +24,14 @@ FESA_BASE=f"/opt/fesa/fesa-fwk/{FESA_VERSION}" ...@@ -22,16 +24,14 @@ FESA_BASE=f"/opt/fesa/fesa-fwk/{FESA_VERSION}"
FESA_XSD=f"{FESA_BASE}/fesa-model-gsi/xml/deployment/deployment-gsi.xsd" FESA_XSD=f"{FESA_BASE}/fesa-model-gsi/xml/deployment/deployment-gsi.xsd"
FESA_GSI_TEMPLATE=f"{FESA_BASE}/fesa-model-gsi/xml/design/templates/GSIClassTemplate.xml" FESA_GSI_TEMPLATE=f"{FESA_BASE}/fesa-model-gsi/xml/design/templates/GSIClassTemplate.xml"
# silecs specific variables # silecs specific variables
try: try:
SILECS_BASE=(os.environ['SILECS_BASE']) SILECS_BASE=(os.environ['SILECS_BASE'])
except KeyError: except KeyError:
SILECS_BASE=f"/common/usr/cscofe/silecs/{SILECS_VERSION}" SILECS_BASE=f"/common/usr/cscofe/silecs/{SILECS_VERSION}"
SILECS_BASE = f".." DESIGN_SHEMA_PATH = f"{SILECS_BASE}/silecs-model/xml/DesignSchema.xsd"
DESIGN_SHEMA_PATH = f"{SILECS_BASE}/silecs-model/src/xml/DesignSchema.xsd" DEPLOY_SHEMA_PATH = f"{SILECS_BASE}/silecs-model/xml/DeploySchema.xsd"
DEPLOY_SHEMA_PATH = f"{SILECS_BASE}/silecs-model/src/xml/DeploySchema.xsd"
SILECS_CODEGEN_BASE=f"{SILECS_BASE}/silecs-codegen/xml/" SILECS_CODEGEN_BASE=f"{SILECS_BASE}/silecs-codegen/xml/"
SILECS_CODEGEN_MIGRATION=f"{SILECS_BASE}/silecs-codegen/xml/migration" SILECS_CODEGEN_MIGRATION=f"{SILECS_BASE}/silecs-codegen/xml/migration"
...@@ -39,6 +39,12 @@ SILECS_CODEGEN_MIGRATION=f"{SILECS_BASE}/silecs-codegen/xml/migration" ...@@ -39,6 +39,12 @@ SILECS_CODEGEN_MIGRATION=f"{SILECS_BASE}/silecs-codegen/xml/migration"
# See here for details: https://gitlab.com/al.schwinn/silecs-cli/-/issues/4 # See here for details: https://gitlab.com/al.schwinn/silecs-cli/-/issues/4
SILECS_CODEGEN_FESA=f"{SILECS_BASE}/silecs-codegen/xml/fesa/fesa_7_3_0/" SILECS_CODEGEN_FESA=f"{SILECS_BASE}/silecs-codegen/xml/fesa/fesa_7_3_0/"
try:
RELEASE_PARAM_DIR=(os.environ['RELEASE_PARAM_DIR'])
except KeyError:
RELEASE_PARAM_DIR="/common/export/fesa/local"
# import files for generating sources # import files for generating sources
sys.path.append(SILECS_CODEGEN_BASE) sys.path.append(SILECS_CODEGEN_BASE)
sys.path.append(SILECS_CODEGEN_MIGRATION) sys.path.append(SILECS_CODEGEN_MIGRATION)
...@@ -72,6 +78,8 @@ class SilecsArgumentParser(argparse.ArgumentParser): ...@@ -72,6 +78,8 @@ class SilecsArgumentParser(argparse.ArgumentParser):
"\t To add missing properties and value-items specified in 'MyClass.silecsdesign' into the FESA document 'MyClass.design'.\n" \ "\t To add missing properties and value-items specified in 'MyClass.silecsdesign' into the FESA document 'MyClass.design'.\n" \
"\t This will as well ate C++ code.\n" \ "\t This will as well ate C++ code.\n" \
"\t\t silces -g ~/workspace/MyClass/src/MyClass.silecsdesign\n\n" \ "\t\t silces -g ~/workspace/MyClass/src/MyClass.silecsdesign\n\n" \
"\t To release silecs deploy param to FEC specific FESA release directory.\n" \
"\t\t silces -r ~/workspace/MyClass_DU/src/MyClass_DU.silecsdeploy\n\n" \
"\nCheck the Silecs Wiki for more info: https://www-acc.gsi.de/wiki/Frontend/SILECS\n" \ "\nCheck the Silecs Wiki for more info: https://www-acc.gsi.de/wiki/Frontend/SILECS\n" \
print(examples) print(examples)
...@@ -92,6 +100,12 @@ def get_project_name(filepath): ...@@ -92,6 +100,12 @@ def get_project_name(filepath):
""" """
return os.path.splitext(os.path.basename(filepath))[0] return os.path.splitext(os.path.basename(filepath))[0]
def get_filename(filepath):
"""Get filename from path
eg. workspace/TestClass/src/TestClass.silecsdesign -> TestClass.silecsdesign
"""
_, filename = os.path.split(filepath)
return filename
def get_project_dir(filepath): def get_project_dir(filepath):
"""Get project dir """Get project dir
...@@ -141,21 +155,26 @@ def create_backup_file(filepath): ...@@ -141,21 +155,26 @@ def create_backup_file(filepath):
def validate(silecs_design_deploy_path, xsd_path): def validate(silecs_design_deploy_path, xsd_path):
"""Validate silecs design deploy""" """Validate silecs design deploy"""
validation_result = True
try: try:
print(f"validating {silecs_design_deploy_path}") print(f"validating {silecs_design_deploy_path}")
xmlschema_doc = lxml.etree.parse(xsd_path)
xmlschema = lxml.etree.XMLSchema(xmlschema_doc) schema = xmlschema.XMLSchema11(xsd_path)
xml_doc = lxml.etree.parse(silecs_design_deploy_path) try:
result = xmlschema.validate(xml_doc) schema.validate(silecs_design_deploy_path)
return result except xmlschema.validators.exceptions.XMLSchemaValidationError as e:
print(e)
validation_result = False
return validation_result
except OSError as e: except OSError as e:
print(e) print(e)
return False return False
except Exception as e: except (lxml.etree.DocumentInvalid, OSError, Exception) as e:
print(e) print(e)
return False return False
# TODO: Implement jave-rules - See here for details: https://gitlab.com/al.schwinn/silecs-cli/-/issues/3
def silecs_validate(file_paths): def silecs_validate(file_paths):
for path in file_paths: for path in file_paths:
...@@ -163,9 +182,9 @@ def silecs_validate(file_paths): ...@@ -163,9 +182,9 @@ def silecs_validate(file_paths):
xsd_path = get_schema_path(path) xsd_path = get_schema_path(path)
val_result = validate(path, xsd_path) val_result = validate(path, xsd_path)
if val_result: if val_result:
print("File is valid") print("\nFile is valid")
else: else:
print("File is not valid. Check errors above.") print("\nFile is not valid. Check errors above.")
except Exception as e: except Exception as e:
print(e) print(e)
...@@ -349,10 +368,86 @@ def silecs_diagnostic_tool(filepath): ...@@ -349,10 +368,86 @@ def silecs_diagnostic_tool(filepath):
##### Release parameter file ###### ##### Release parameter file ######
def copy_param_file(fesa_fec_name, param_file_src, project_name):
"""Copy file from param_file_src to the default, FEC specific FESA release directory (RELEASE_PARAM_DIR/fesa_fec_name/project_name)
and development directory (RELEASE_PARAM_DIR/fesa_fec_name/project_name-d) .
"""
fesa_fec_dst_folder = os.path.join(RELEASE_PARAM_DIR, fesa_fec_name, f"{project_name}")
fesa_fec_dst_folder_dev = fesa_fec_dst_folder + "-d"
fesa_fec_dst_folders = [fesa_fec_dst_folder_dev, fesa_fec_dst_folder]
for fesa_fec_dst in fesa_fec_dst_folders:
if not os.path.isdir(fesa_fec_dst):
print(f"Generating folder-structures for FEC: {os.path.abspath(fesa_fec_dst)}")
os.makedirs(fesa_fec_dst)
print("Folder generated")
param_file_name = get_filename(param_file_src)
fesa_fec_dst_file = os.path.join(fesa_fec_dst, param_file_name)
print(f"Installing parameter-file {param_file_name} to {fesa_fec_dst}.")
with open(fesa_fec_dst_file, 'w+'):
shutil.copyfile(src=param_file_src, dst=fesa_fec_dst_file)
def release(filepath):
"""Copy generated silecs deploy parameter files to directory"""
filepath = os.path.abspath(filepath)
project_path = get_project_path(filepath)
project_name = get_project_name(filepath)
param_dir = os.path.join(project_path, "generated-silecs", "client")
extension = get_extension(filepath)
if extension != SILECSDEPLOY:
print(f"Error: you need to provide {SILECSDEPLOY} file")
return False
try:
silecs_deploy_document = minidom.parse(filepath)
controller_nodes = silecs_deploy_document.getElementsByTagName("Controller")
for controller in controller_nodes:
host_name = controller.getAttribute("host-name")
plc_nodes = controller.childNodes
plc_element = None
for plc in plc_nodes:
if plc.nodeType == minidom.Node.ELEMENT_NODE:
plc_element = plc
break
if not plc_element:
raise Exception(f"No concrete plc defined for controller: {host_name}")
device_nodes = plc_element.getElementsByTagName("Device")
fesa_fec_name = None
for device in device_nodes:
fesa_fec_name = device.getAttribute("fesa-fec-name")
device_label = device.getAttribute("silecs-device-label")
if not fesa_fec_name:
print(f"Skipping controller: {host_name} Reason:")
print(f"For silecs-device {device_label} the attribute @fesa-fec-name is not define")
continue
param_file_name = f"{host_name}.silecsparam"
param_file_path = os.path.abspath(os.path.join(param_dir, param_file_name))
if not os.path.isfile(param_file_path):
print(f"Skipping controller: {host_name} Reason:")
print(f"No parameter file found for this controller. Did you run the code-generation ?")
continue
copy_param_file(fesa_fec_name, param_file_path, project_name)
return True
except Exception as e:
print(e)
return False
def silecs_release(file_paths): def silecs_release(file_paths):
# TODO - See here for details: https://gitlab.com/al.schwinn/silecs-cli/-/issues/5 for filepath in file_paths:
print("Not implemented yet .. please copy the param file by hand for now") release_result = release(filepath)
if release_result:
print("Release successfull")
else:
print("Error during release. Check errors above.")
##### Migrate file to new silecs version ###### ##### Migrate file to new silecs version ######
...@@ -411,8 +506,9 @@ def _parse_arguments(): ...@@ -411,8 +506,9 @@ def _parse_arguments():
parser.add_argument( parser.add_argument(
"-r", "-r",
"--release", "--release",
metavar="file", nargs="+",
help="release parameter file fo FEC (TODO)" metavar="silecsdeploy",
help="release parameter file fo FEC for silecsdeploy file"
) )
parser.add_argument( parser.add_argument(
......
#!/bin/sh
# File/Project has to be the last argument
FILE=${@:$#}
PROJECT_NAME=$(echo "${FILE##*/}" | sed 's/\.[^.]*$//')
SCRIPT=$(readlink -f "$0")
SILECS_VERSION=2.3.0
# Prefill $SILECS_BASE with a local path, if you want to test a local installation
if [ -z $SILECS_BASE ]; then
SILECS_BASE=/common/usr/cscofe/silecs/${SILECS_VERSION}
fi
echo "using sileces base path: $SILECS_BASE"
FESA_VERSION=7.4.0
FESA_BASE=/opt/fesa/fesa-fwk/$FESA_VERSION
N_ARGUMENTS=$#
function help {
echo -e ""
echo -e "Usage: silecs [OPTION] [FILE]"
echo -e ""
echo -e "Script in order to model PLC devices in FESA by using the Silecs framework."
echo -e ""
echo -e "\t -c \t create new .silecsdesign/.silecsdeploy file for the specified FESA .design/.deploy file"
echo -e "\t -v \t validate silecs xml file"
echo -e "\t -g \t generate source code for silecs xml file"
echo -e "\t -d \t start diagnostic tool for silecs xml file"
echo -e "\t -r \t release parameter file to FEC (TODO)"
echo -e "\t -m \t migrate silecs design/deploy file to new silecs version (TODO)"
echo -e "\t -h \t show this help"
echo -e ""
echo -e "Examples:"
echo -e ""
echo -e "\t To create a new file 'MyClass.silecsdesign' for the FESA class."
echo -e "\t\t silces -c ~/workspace/MyClass/src/MyClass.design"
echo -e ""
echo -e "\t To validate 'MyClass.silecsdesign'."
echo -e "\t\t silces -v ~/workspace/MyClass/src/MyClass.silecsdesign"
echo -e ""
echo -e "\t To add missing properties and value-items specified in 'MyClass.silecsdesign' into the FESA document 'MyClass.design'."
echo -e "\t This will as well ate C++ code."
echo -e "\t\t silces -g ~/workspace/MyClass/src/MyClass.silecsdesign"
echo -e ""
echo -e "Check the Silecs Wiki for more info: https://www-acc.gsi.de/wiki/Frontend/SILECS"
echo -e ""
exit 1;
}
if [ $N_ARGUMENTS -lt 1 ]
then
echo "Error: Wrong number of arguments supplied."
help
fi
function assert_n_arguments {
if [ $N_ARGUMENTS -lt $1 ]
then
echo "Error: Wrong number of arguments supplied."
help
fi
}
function silecs_validate {
assert_n_arguments 2
EXTENSION=$(echo "$FILE" | sed 's/^.*\.//')
# Resolve possible relative path
FILE=$(realpath "$FILE" )
case $EXTENSION in
silecsdesign)
SCHEMA=$SILECS_BASE/silecs-model/xml/DesignSchema.xsd
;;
silecsdeploy)
SCHEMA=$SILECS_BASE/silecs-model/xml/DeploySchema.xsd
;;
*)
echo "Error: Passed file for validation needs to have the extension '.silecsdesign' or '.silecsdeploy'"
exit 1
;;
esac
echo "validating $FILE"
echo ""
xmllint --schema $SCHEMA $FILE --noout
RESULT=$?
echo ""
if [ $RESULT -eq 0 ]
then
echo "File is valid"
else
echo "File is not valid. Check errors above."
fi
return $RESULT
# TODO: Implement jave-rules - See here for details: https://gitlab.com/al.schwinn/silecs-cli/-/issues/3
}
function execute_python {
PYTHON_FILE=$1
PYTHON_METHOD=$2
SILECS_CODEGEN_BASE=$SILECS_BASE/silecs-codegen/xml/
SILECS_CODEGEN_MIGRATION=$SILECS_BASE/silecs-codegen/xml/migration
# TODO: Check for concrete fesa version - See here for details: https://gitlab.com/al.schwinn/silecs-cli/-/issues/4
SILECS_CODEGEN_FESA=$SILECS_BASE/silecs-codegen/xml/fesa/fesa_7_3_0/
ARGUMENTS=""
for ((i=3; i<=$#; i++))
do
ARGUMENTS+="'"
ARGUMENTS+=${!i}
ARGUMENTS+="'"
if [ $i -ne $# ]
then
ARGUMENTS+=","
fi
done
#echo $ARGUMENTS
python3 -c "import sys;\
sys.path.append('$SILECS_CODEGEN_BASE');\
sys.path.append('$SILECS_CODEGEN_MIGRATION');\
sys.path.append('$SILECS_CODEGEN_FESA');\
import $PYTHON_FILE;\
$PYTHON_FILE.$PYTHON_METHOD($ARGUMENTS);"
return $?
}
function silecs_generate {
assert_n_arguments 2
silecs_validate
if [ $? -ne 0 ]; then
echo ""
echo "Error: $FILE is not valid. Please fix all xml errors before generating code !"
exit 1
fi
# Resolve possible relative path
FILE=$(realpath "$FILE" )
EXTENSION=$(echo "$FILE" | sed 's/^.*\.//')
case $EXTENSION in
silecsdesign)
silecs_generate_silecsdesign
;;
silecsdeploy)
silecs_generate_silecsdeploy
;;
*)
echo "Error: Passed file for code generation needs to have the exctension '.silecsdesign' or '.silecsdeploy'"
exit 1
;;
esac
}
function silecs_generate_silecsdesign {
SILECS_DESIGN_FILE=$FILE
PROJECT_PATH=$(dirname "$(dirname "$FILE")")
WORKSPACE_PATH=$(dirname "$PROJECT_PATH")
SILECS_LIBRARY_BASE=$SILECS_BASE/silecs-communication-cpp
FESA_DESIGN_FILE=$PROJECT_PATH/src/$PROJECT_NAME.design
FESA_XSD=$FESA_BASE/fesa-model-gsi/xml/design/design-gsi.xsd
echo "generating code for $PROJECT_NAME ..."
echo ""
if [ -f $FESA_DESIGN_FILE ];
then
echo "Please note that old, obsolete xml-elements are not deleted automatically! Sometimes this can lead to an invalid FESA Design document!"
echo "If this is the case, please remove the obsolete elements by hand."
echo "Creating a backup of the existing FESA file at: $FESA_DESIGN_FILE.backup"
echo ""
cp $FESA_DESIGN_FILE $FESA_DESIGN_FILE.backup
fi
execute_python generateFesaDesign fillDesignFile $FESA_VERSION $PROJECT_NAME $WORKSPACE_PATH $FESA_XSD
execute_python generateSourceCode genCppFiles $PROJECT_NAME $WORKSPACE_PATH $SILECS_DESIGN_FILE
echo ""
echo "Please not that you need to add the dependency to the silecs library to your Makefile."
echo "Here an example: https://www-acc.gsi.de/wiki/Frontend/Silecs_1_0_0_CodeSnippets#Dependency_in_Makefile.specific !"
echo ""
echo "Code generation finished"
}
function silecs_generate_silecsdeploy {
SILECS_DEPLOY_FILE=$FILE
PROJECT_PATH=$(dirname "$(dirname "$FILE")")
WORKSPACE_PATH=$(dirname "$PROJECT_PATH")
SILECS_LIBRARY_BASE=$SILECS_BASE/silecs-communication-cpp
FESA_DEPLOY_FILE=$PROJECT_PATH/src/$PROJECT_NAME.deploy
FESA_XSD=$FESA_BASE/fesa-model-gsi/xml/deployment/deployment-gsi.xsd
FESA_GSI_TEMPLATE=$FESA_BASE/fesa-model-gsi/xml/design/templates/GSIClassTemplate.xml
SILECS_DEPLOY_VERSION="unused_parameter"
echo "generating code for $PROJECT_NAME ..."
echo ""
if [ -f $FESA_DESIGN_FILE ];
then
echo "Please note that old, obsolete xml-elements are not deleted automatically! Sometimes this can lead to an invalid FESA document!"
echo "If this is the case, please remove the obsolete elements by hand."
echo "Creating a backup of the existing FESA file at: $FESA_DEPLOY_FILE.backup"
echo ""
cp $FESA_DEPLOY_FILE $FESA_DEPLOY_FILE.backup
fi
execute_python genparam genParam $WORKSPACE_PATH $PROJECT_NAME $SILECS_DEPLOY_VERSION $SILECS_VERSION
execute_python genplcsrc genPlcSrc $WORKSPACE_PATH $PROJECT_NAME $SILECS_VERSION
execute_python genduwrapper genDuWrapper $WORKSPACE_PATH $PROJECT_NAME $SILECS_DEPLOY_VERSION
execute_python fillFESADeployUnit fillDeployUnit $WORKSPACE_PATH $PROJECT_NAME $FESA_XSD $FESA_VERSION
echo ""
echo "Please not that you need to add the dependency to the silecs library to your Makefile."
echo "Here an example: https://www-acc.gsi.de/wiki/Frontend/Silecs_1_0_0_CodeSnippets#Dependency_in_Makefile.specific !"
echo ""
echo "Code generation finished"
}
function silecs_create_design {
NEWFILEPATH=$1
DATE=$(date +%x)
SCHEMA_PATH=$SILECS_BASE/silecs-model/xml/DesignSchema.xsd
DESIGN_TEMPLATE='<?xml version="1.0" encoding="UTF-8"?>
<SILECS-Design silecs-version="'$SILECS_VERSION'" created="'$DATE'" updated="'$DATE'"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="'$SCHEMA_PATH'">
<Information>
<Owner user-login="'$USER'"/>
<Editor user-login="'$USER'"/>
</Information>
<SILECS-Class name="'$PROJECT_NAME'" version="0.1.0" domain="OPERATIONAL" >
<Acquisition-Block name="MyBlock" generateFesaProperty="true">
<Acquisition-Register name="myRegister" generateFesaValueItem="true">
<scalar format="int32"/>
</Acquisition-Register>
</Acquisition-Block>
</SILECS-Class>
</SILECS-Design>'
if [ -f $NEWFILEPATH ]; then
echo "Error: There is already a .silecsdesign file available: $NEWFILEPATH"
exit 1
fi
echo $DESIGN_TEMPLATE | xmllint --format - > $NEWFILEPATH
echo ""
echo "created new silecsdesign: $NEW_FILE"
}
function silecs_create_deploy {
NEWFILEPATH=$1
DATE=$(date +%x)
SCHEMA_PATH=$SILECS_BASE/silecs-model/xml/DeploySchema.xsd
DEPLOY_TEMPLATE='<?xml version="1.0" encoding="UTF-8"?>
<SILECS-Deploy silecs-version="'$SILECS_VERSION'" created="'$DATE'" updated="'$DATE'"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="'$SCHEMA_PATH'">
<Information>
<Owner user-login="'$USER'"/>
<Editor user-login="'$USER'"/>
</Information>
<Deploy-Unit name="'$PROJECT_NAME'" version="0.1.0"/>
<SilecsDesign silecs-design-name="" silecs-design-version=""/>
<Controller host-name="">
<Siemens-PLC system="TIA-PORTAL" model="SIMATIC_S7-300" protocol="DEVICE_MODE" base-DB-number="1">
<Device silecs-device-label="dev0" silecs-design-ref="" fesa-device-name="" fesa-fec-name=""/>
</Siemens-PLC>
</Controller>
</SILECS-Deploy>'
if [ -f $NEWFILEPATH ]; then
echo "Error: There is already a .silecsdeploy file available: $NEWFILEPATH"
exit 1
fi
echo $DEPLOY_TEMPLATE | xmllint --format - > $NEWFILEPATH
echo ""
echo "created new silecsdeploy: $NEW_FILE"
}
function silecs_create {
assert_n_arguments 2
# Resolve possible relative path
FILE=$(realpath "$FILE" )
EXTENSION=$(echo "$FILE" | sed 's/^.*\.//')
FILE_PATH=$(dirname "$FILE")
case $EXTENSION in
design)
NEW_FILE=$FILE_PATH/$PROJECT_NAME.silecsdesign
silecs_create_design $NEW_FILE
;;
deploy)
NEW_FILE=$FILE_PATH/$PROJECT_NAME.silecsdeploy
silecs_create_deploy $NEW_FILE
;;
*)
echo "Error: Passed FESA file needs to have the extension '.design' or '.deploy'"
exit 1
;;
esac
}
function silecs_open_diag {
assert_n_arguments 2
# Resolve possible relative path
FILE=$(realpath "$FILE" )
EXTENSION=$(echo "$FILE" | sed 's/^.*\.//')
if [ $EXTENSION -ne "silecsdeploy" ]; then
echo "Error: diag tool only can be opened for a -silecsdeploy file"
fi
SILECS_DIAG_TOOL=$SILECS_BASE/silecs-diagnostic-cpp/bin/x86_64/silecs-diagnostic
$SILECS_DIAG_TOOL -d $FILE
}
function silecs_release_param {
# TODO - See here for details: https://gitlab.com/al.schwinn/silecs-cli/-/issues/5
echo "Not implemented yet .. please copy the param file by hand for now"
}
function silecs_migrate {
# TODO - See here for details: https://gitlab.com/al.schwinn/silecs-cli/-/issues/7
echo "Not implemented yet .. please update/migrate by hand for now"
}
while getopts c:v:g:d:r:m:h flag
do
case "${flag}" in
c ) silecs_create;;
v ) silecs_validate;;
g ) silecs_generate;;
d ) silecs_open_diag;;
r ) silecs_release_param;;
m ) silecs_migrate;;
h ) help;;
esac
done
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
<SILECS-Deploy <SILECS-Deploy
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
silecs-version="2.3.0" created="08/16/2022" updated="08/16/2022" silecs-version="2.3.0" created="08/16/2022" updated="08/16/2022"
xsi:noNamespaceSchemaLocation="/common/usr/cscofe/silecs/2.3.0/silecs-model/xml/DeploySchema.xsd"> xsi:noNamespaceSchemaLocation="../silecs-model/src/xml/DeploySchema.xsd">
<Information> <Information>
<Owner user-login="mnabywan" /> <Owner user-login="mnabywan" />
<Editor user-login="mnabywan" /> <Editor user-login="mnabywan" />
...@@ -11,11 +11,11 @@ ...@@ -11,11 +11,11 @@
<SilecsDesign silecs-design-name="SilecsTestClass" <SilecsDesign silecs-design-name="SilecsTestClass"
silecs-design-version="0.1.0" /> silecs-design-version="0.1.0" />
<Controller host-name="tsts7001"> <Controller host-name="tsts7001">
<Siemens-PLC system="TIA-PORTAL" model="SIMATIC_S7-1500" <Schneider-PLC system="UNITY Pro" model="M340"
protocol="DEVICE_MODE" base-DB-number="1"> protocol="BLOCK_MODE" base-address="1">
<Device silecs-device-label="dev0" <Device silecs-device-label="dev0"
silecs-design-ref="SilecsTestClass" fesa-device-name="mySilecsTest" silecs-design-ref="SilecsTestClass" fesa-device-name="mySilecsTest"
fesa-fec-name="asl751"></Device> fesa-fec-name="asl751"></Device>
</Siemens-PLC> </Schneider-PLC>
</Controller> </Controller>
</SILECS-Deploy> </SILECS-Deploy>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<SILECS-Design silecs-version="2.3.0" created="08/22/2022" updated="08/22/2022"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="../silecs-model/src/xml/DesignSchema.xsd">
<Information>
<Owner user-login="localadmin_mnabywan"/>
<Editor user-login="localadmin_mnabywan"/>
</Information>
<SILECS-Class name="SilecsTestDesign" version="0.1.0" domain="OPERATIONAL" >
<Acquisition-Block name="MyBlock" generateFesaProperty="true">
<Acquisition-Register name="myRegister" generateFesaValueItem="true">
<scalar format="int32"/>
</Acquisition-Register>
</Acquisition-Block>
</SILECS-Class>
</SILECS-Design>
\ No newline at end of file
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
<SILECS-Deploy <SILECS-Deploy
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
silecs-version="2.3.0" created="08/16/2022" updated="08/16/2022" silecs-version="2.3.0" created="08/16/2022" updated="08/16/2022"
xsi:noNamespaceSchemaLocation="/common/usr/cscofe/silecs/2.3.0/silecs-model/xml/DeploySchema.xsd"> xsi:noNamespaceSchemaLocation="../silecs-model/src/xml/DeploySchema.xsd">
<Information> <Information>
<Owner user-login="mnabywan" /> <Owner user-login="mnabywan" />
<Editor user-login="mnabywan" /> <Editor user-login="mnabywan" />
...@@ -16,6 +16,7 @@ ...@@ -16,6 +16,7 @@
<Device silecs-device-label="dev0" <Device silecs-device-label="dev0"
silecs-design-ref="SilecsTestClass" fesa-device-name="mySilecsTest" silecs-design-ref="SilecsTestClass" fesa-device-name="mySilecsTest"
fesa-fec-name="asl751"></Device> fesa-fec-name="asl751"></Device>
</Siemens-PLCerror> </Siemens-PLC>
<unknown>test123</unknown>
</Controller> </Controller>
</SILECS-Deploy> </SILECS-Deploy>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?><deploy-unit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="file:/opt/fesa/fesa-model-gsi/7.4.0/xml/deployment/deployment-gsi.xsd">
<information>
<deploy-unit-name>SilecsTestClass2_DU</deploy-unit-name>
<deploy-unit-major-version>0</deploy-unit-major-version>
<deploy-unit-minor-version>1</deploy-unit-minor-version>
<deploy-unit-tiny-version>0</deploy-unit-tiny-version>
<description>Empty Template description</description>
<fesa-version>7.4.0</fesa-version>
</information>
<ownership>
<responsible name="Undefined"/>
<creator login="mnabywan"/>
</ownership>
<class>
<class-name>class-name</class-name>
<class-major-version>0</class-major-version>
<class-minor-version>1</class-minor-version>
<class-tiny-version>0</class-tiny-version>
<device-instance>required</device-instance>
</class>
<executable>
<server extension="_S"/>
</executable>
</deploy-unit>
<?xml version="1.0"?>
<SILECS-Param silecs-version="2.3.0">
<Mapping-Info>
<Owner user-login="mnabywan"/>
<Generation date="2022-08-30 11:14:17.910098"/>
<Deployment checksum="570584630"/>
</Mapping-Info>
<SILECS-Mapping plc-name="tsts7001" plc-brand="SIEMENS" plc-system="TIA-PORTAL" plc-model="SIMATIC_S7-1500" protocol="DEVICE_MODE" address="1" DI-address="-1" DO-address="-1" AI-address="-1" AO-address="-1" domain="" used-mem="TODO">
<SILECS-Class name="SilecsHeader" version="1.0.0" address="1" DI-address="-1" DO-address="-1" AI-address="-1" AO-address="-1" used-mem="DB1..DB1/48 bytes" used-DI="0 byte" used-DO="0 byte" used-AI="0 byte" used-AO="0 byte">
<Acquisition-Block name="hdrBlk" size="14" address="0" mem-size="48">
<Acquisition-Register name="_version" size="1" address="0" mem-size="18">
<string string-length="16" format="string"/>
</Acquisition-Register>
<Acquisition-Register name="_checksum" size="4" address="18" mem-size="4">
<scalar format="uint32"/>
</Acquisition-Register>
<Acquisition-Register name="_user" size="1" address="22" mem-size="18">
<string string-length="16" format="string"/>
</Acquisition-Register>
<Acquisition-Register name="_date" size="8" address="40" mem-size="8">
<scalar format="dt"/>
</Acquisition-Register>
</Acquisition-Block>
<Instance label="SilecsHeader" address="1" DI-address="-1" DO-address="-1" AI-address="-1" AO-address="-1"/>
</SILECS-Class>
<SILECS-Class name="SilecsTestClass" version="0.1.0" address="2" DI-address="-1" DO-address="-1" AI-address="-1" AO-address="-1" used-mem="DB2..DB2/8 bytes" used-DI="0 byte" used-DO="0 byte" used-AI="0 byte" used-AO="0 byte">
<Acquisition-Block name="MyBlock" size="4" address="0" mem-size="4">
<Acquisition-Register name="myRegister" generateFesaValueItem="true" size="4" address="0" mem-size="4">
<scalar format="int32"/>
</Acquisition-Register>
</Acquisition-Block>
<Setting-Block name="MySetting" size="4" address="4" mem-size="4">
<Setting-Register name="mySettingRegister" generateFesaValueItem="true" size="4" address="0" mem-size="4">
<scalar format="int32"/>
</Setting-Register>
</Setting-Block>
<Instance label="dev0" address="2" DI-address="-1" DO-address="-1" AI-address="-1" AO-address="-1"/>
</SILECS-Class>
</SILECS-Mapping>
</SILECS-Param>
(* ---------------------------------------------------------------------
* SilecsHeader/ v1.0.0
* BLOCK Type definition
* ---------------------------------------------------------------------
*)
TYPE _SilecsHeader_hdrBlk
AUTHOR: mnabywan
FAMILY: SILECS
NAME: UDTB
STRUCT
_version: STRING[16] := 'SILECS_2.3.0';
_checksum: DWORD := DW#16#22026e36;
_user: STRING[16] := 'mnabywan';
_date: DT := DT#2022-8-30-11:14:18;
END_STRUCT;
END_TYPE
(* ---------------------------------------------------------------------
* SilecsHeader/ v1.0.0
* BLOCK instance definition
* ---------------------------------------------------------------------
*)
DATA_BLOCK SilecsHeader_SilecsHeader
{ S7_Optimized_Access := 'FALSE' }
AUTHOR: mnabywan
FAMILY: SILECS
NAME: DEV_MODE
STRUCT
hdrBlk: _SilecsHeader_hdrBlk;
END_STRUCT;
BEGIN
END_DATA_BLOCK
(* ---------------------------------------------------------------------
* SilecsTestClass/ v0.1.0
* BLOCK Type definition
* ---------------------------------------------------------------------
*)
TYPE _SilecsTestClass_MyBlock
AUTHOR: mnabywan
FAMILY: SILECS
NAME: UDTB
STRUCT
myRegister: DINT;
END_STRUCT;
END_TYPE
TYPE _SilecsTestClass_MySetting
AUTHOR: mnabywan
FAMILY: SILECS
NAME: UDTB
STRUCT
mySettingRegister: DINT;
END_STRUCT;
END_TYPE
(* ---------------------------------------------------------------------
* SilecsTestClass/ v0.1.0
* BLOCK instance definition
* ---------------------------------------------------------------------
*)
DATA_BLOCK SilecsTestClass_dev0
{ S7_Optimized_Access := 'FALSE' }
AUTHOR: mnabywan
FAMILY: SILECS
NAME: DEV_MODE
STRUCT
MyBlock: _SilecsTestClass_MyBlock;
MySetting: _SilecsTestClass_MySetting;
END_STRUCT;
BEGIN
END_DATA_BLOCK
"_SilecsHeader_hdrBlk","UDT 1","UDT 1","[SilecsHeader/1.0.0] UDT symbol: _<class-name>_<block-name>"
"SilecsHeader_SilecsHeader","DB 1","DB 1","[SilecsHeader/1.0.0] DB symbol: <class-name>_<device-label | device-id>"
"_SilecsTestClass_MyBlock","UDT 2","UDT 2","[SilecsTestClass/0.1.0] UDT symbol: _<class-name>_<block-name>"
"_SilecsTestClass_MySetting","UDT 3","UDT 3",""
"SilecsTestClass_dev0","DB 2","DB 2","[SilecsTestClass/0.1.0] DB symbol: <class-name>_<device-label | device-id>"
/* Copyright CERN 2015
*
* WARNING: This code is automatically generated from your SILECS deploy unit document.
* You should never modify the content of this file as it would break consistency.
* Furthermore, any changes will be overwritten in the next code generation.
* Any modification shall be done using the SILECS development environment
* and regenerating this source code.
*/
#ifndef SILECSHEADER_H_
#define SILECSHEADER_H_
#include <silecs-communication/wrapper/Block.h>
#include <silecs-communication/wrapper/DeployUnit.h>
#include <silecs-communication/wrapper/Design.h>
#include <silecs-communication/wrapper/Device.h>
namespace SilecsHeader
{
class Design : public SilecsWrapper::Design
{
public:
Design(SilecsWrapper::DeployUnit *deployUnit) :
SilecsWrapper::Design("SilecsHeader", "1.0.0", deployUnit)
{
}
~Design()
{
}
};
} /* namespace SilecsHeader */
#endif /* SILECSHEADER_H_ */
/* Copyright CERN 2015
*
* WARNING: This code is automatically generated from your SILECS deploy unit document.
* You should never modify the content of this file as it would break consistency.
* Furthermore, any changes will be overwritten in the next code generation.
* Any modification shall be done using the SILECS development environment
* and regenerating this source code.
*/
#ifndef SILECSTESTCLASS_H_
#define SILECSTESTCLASS_H_
#include <silecs-communication/wrapper/Block.h>
#include <silecs-communication/wrapper/DeployUnit.h>
#include <silecs-communication/wrapper/Design.h>
#include <silecs-communication/wrapper/Device.h>
namespace SilecsTestClass
{
class Design : public SilecsWrapper::Design
{
public:
Design(SilecsWrapper::DeployUnit *deployUnit) :
SilecsWrapper::Design("SilecsTestClass", "0.1.0", deployUnit)
{
}
~Design()
{
}
};
} /* namespace SilecsTestClass */
#endif /* SILECSTESTCLASS_H_ */
/* Copyright CERN 2015
*
* WARNING: This code is automatically generated from your SILECS deploy unit document.
* You should never modify the content of this file as it would break consistency.
* Furthermore, any changes will be overwritten in the next code generation.
* Any modification shall be done using the SILECS development environment
* and regenerating this source code.
*/
#ifndef SILECSTESTCLASS_DU_H_
#define SILECSTESTCLASS_DU_H_
#include <silecs-communication/interface/equipment/SilecsCluster.h>
#include <silecs-communication/wrapper/DeployUnit.h>
#include <silecs-communication/wrapper/Design.h>
#include "SilecsHeader.h"
#include "SilecsTestClass.h"
namespace SilecsTestClass_DU
{
typedef SilecsWrapper::DeployConfig DeployConfig;
typedef SilecsWrapper::DesignConfig DesignConfig;
class DeployUnit : public SilecsWrapper::DeployUnit
{
public:
/*!
* \brief Use this method to create/get the unique instance of the Deploy Unit.
*
* \param logTopics This parameter can be used to enable/disable log topics
* valid topics are ERROR[,INFO,DEBUG,SETUP,ALLOC,RECV,SEND,COMM,DATA,LOCK].
*
* \param globalConfig This parameter can be used to pass different parameters to
* the library. I.e. enabling automatic connection.
*/
static DeployUnit* getInstance(const std::string& logTopics = "",
const SilecsWrapper::DeployConfig& globalConfig = SilecsWrapper::DeployConfig())
{
if (_instance == NULL)
{
_instance = new DeployUnit(logTopics, globalConfig);
}
else
{
if (logTopics.empty() == false)
{
_instance->getService()->setLogTopics(logTopics);
}
}
return dynamic_cast<DeployUnit*>(_instance);
}
/*!
* \brief Use this method to create/get the unique instance of the Deploy Unit.
*
* \param globalConfig This parameter can be used to pass different parameters to
* the library. I.e. enabling automatic connection.
*/
static DeployUnit* getInstance(const SilecsWrapper::DeployConfig& globalConfig)
{
return getInstance("", globalConfig);
}
/*!
* \brief Return pointer to the deployed design SilecsHeader.
*/
SilecsHeader::Design* getSilecsHeader()
{
return _SilecsHeader;
}
/*!
* \brief Return pointer to the deployed design SilecsTestClass.
*/
SilecsTestClass::Design* getSilecsTestClass()
{
return _SilecsTestClass;
}
private:
SilecsHeader::Design* _SilecsHeader;
SilecsTestClass::Design* _SilecsTestClass;
DeployUnit(const std::string& logTopics, const SilecsWrapper::DeployConfig& globalConfig) :
SilecsWrapper::DeployUnit("SilecsTestClass_DU", "0.1.0", logTopics, globalConfig)
{
// Construct Design SilecsHeader
_SilecsHeader = new SilecsHeader::Design((SilecsWrapper::DeployUnit*) this);
// Construct Design SilecsTestClass
_SilecsTestClass = new SilecsTestClass::Design((SilecsWrapper::DeployUnit*) this);
}
~DeployUnit()
{
delete _SilecsHeader;
delete _SilecsTestClass;
}
};
class Controller : public SilecsWrapper::Controller
{
public:
Controller(SilecsWrapper::Design *design, const std::string parameterFile) :
SilecsWrapper::Controller("tsts7001", "", design, parameterFile)
{
_deviceMap.insert(std::pair<std::string, SilecsWrapper::Device*>("SilecsHeader", new SilecsWrapper::Device("SilecsHeader", this)));
_deviceMap.insert(std::pair<std::string, SilecsWrapper::Device*>("dev0", new SilecsWrapper::Device("dev0", this)));
}
~Controller()
{
map<std::string, SilecsWrapper::Device*>::iterator it;
for (it = _deviceMap.begin(); it != _deviceMap.end(); it++)
{
delete it->second;
}
}
/*!
* \brief Return pointer to the requested device.
* \param label Device label.
*/
SilecsWrapper::Device* getDevice(const std::string& label)
{
if (_deviceMap.find(label) != _deviceMap.end())
{
return _deviceMap[label];
}
throw Silecs::SilecsException(__FILE__, __LINE__, Silecs::PARAM_UNKNOWN_DEVICE_NAME, label);
}
std::map<std::string, SilecsWrapper::Device*>& getDeviceMap()
{
return _deviceMap;
}
/*!
* \brief Get pointer to device SilecsHeader.
*/
SilecsWrapper::Device* getSilecsHeader()
{
return _deviceMap["SilecsHeader"];
}
/*!
* \brief Get pointer to device dev0.
*/
SilecsWrapper::Device* getDev0()
{
return _deviceMap["dev0"];
}
private:
std::map<std::string, SilecsWrapper::Device*> _deviceMap;
};
} /* namespace SilecsTestClass_DU */
#endif /* SILECSTESTCLASS_DU_H_ */
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<deploy-unit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="/opt/fesa/fesa-fwk/7.4.0/fesa-model-gsi/xml/deployment/deployment-gsi.xsd"> <deploy-unit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="file:/opt/fesa/fesa-model-gsi/7.4.0/xml/deployment/deployment-gsi.xsd"><include><xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="/home/bel/mnabywan/lnx/workspace-silecs-test/SilecsTestClass/generated/xml/SilecsTestClassSchedulingView.xml"/></include>
<include><xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="/home/bel/mnabywan/lnx/workspace-silecs-course/SilecsTestClass/generated/xml/SilecsTestClassSchedulingView.xml"/></include>
<information> <information>
<deploy-unit-name>SilecsTestClassDU</deploy-unit-name> <deploy-unit-name>SilecsTestClass_DU</deploy-unit-name>
<deploy-unit-major-version>0</deploy-unit-major-version> <deploy-unit-major-version>0</deploy-unit-major-version>
<deploy-unit-minor-version>1</deploy-unit-minor-version> <deploy-unit-minor-version>1</deploy-unit-minor-version>
<deploy-unit-tiny-version>0</deploy-unit-tiny-version> <deploy-unit-tiny-version>0</deploy-unit-tiny-version>
...@@ -19,14 +18,12 @@ ...@@ -19,14 +18,12 @@
<class-minor-version>1</class-minor-version> <class-minor-version>1</class-minor-version>
<class-tiny-version>0</class-tiny-version> <class-tiny-version>0</class-tiny-version>
<device-instance>required</device-instance> <device-instance>required</device-instance>
<path>/home/bel/mnabywan/lnx/workspace-silecs-course/SilecsTestClass</path> <path>/home/bel/mnabywan/lnx/workspace-silecs-test/SilecsTestClass</path></class>
</class>
<scheduler> <scheduler>
<concurrency-layer name="default" threading-policy="single" id="_220816150343_0"> <concurrency-layer name="default" threading-policy="single" id="_220830122259_0">
<scheduling-unit scheduling-unit-name-ref="SilecsTestClass::StatusUpdateSchedulingUnit"/> <scheduling-unit scheduling-unit-name-ref="SilecsTestClass::StatusUpdateSchedulingUnit" />
</concurrency-layer> </concurrency-layer>
</scheduler> </scheduler>
<executable> <executable><mixed extension="_M" />
<mixed extension="_M"/>
</executable> </executable>
</deploy-unit> </deploy-unit>
<?xml version="1.0" encoding="UTF-8"?>
<SILECS-Deploy xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" silecs-version="2.3.0" created="08/30/2022" updated="08/30/2022" xsi:noNamespaceSchemaLocation="/common/usr/cscofe/silecs/2.3.0/silecs-model/xml/DeploySchema.xsd">
<Information>
<Owner user-login="mnabywan"/>
<Editor user-login="mnabywan"/>
</Information>
<Deploy-Unit name="SilecsTestClass_DU" version="0.1.0"/>
<SilecsDesign silecs-design-name="SilecsTestClass" silecs-design-version="0.1.0"/>
<Controller host-name="tsts7001">
<Siemens-PLC system="TIA-PORTAL" model="SIMATIC_S7-1500" protocol="DEVICE_MODE" base-DB-number="1">
<Device silecs-device-label="dev0" silecs-design-ref="SilecsTestClass" fesa-device-name="testDeviceSilecs1" fesa-fec-name="SilecsTestClass"/>
</Siemens-PLC>
</Controller>
</SILECS-Deploy>
import os import os
import sys import sys
import unittest import unittest
import filecmp
import shutil
from mock import patch
RELEASE_PARAM_DIR_PATH = os.path.join("tests", "releaseParamDir")
os.environ["RELEASE_PARAM_DIR"] = RELEASE_PARAM_DIR_PATH
sys.path.append('../') sys.path.append('../')
from silecs_cli import silecs import silecs
BASE_FOR_BACKUP = os.path.join("tests", "examples", "SilecsTestClass.design")
BACKUP = BASE_FOR_BACKUP + ".backup"
DESIGN_PATH = os.path.join("tests", "examples", "SilecsTestClass2.design") DESIGN_PATH = os.path.join("tests", "testClasses", "SilecsTestClass", "src", "SilecsTestClass.design")
DEPLOY_PATH = os.path.join("tests", "examples", "SilecsTestClass_2_DU.deploy") DEPLOY_PATH = os.path.join("tests", "testClasses", "SilecsTestClass_DU", "src", "SilecsTestClass_DU.deploy")
BACKUP = DESIGN_PATH + ".backup"
SILECS_DESIGN_PATH = DESIGN_PATH.split(".")[0] + ".silecsdesign" SILECS_DESIGN_PATH = DESIGN_PATH.split(".")[0] + ".silecsdesign"
SILECS_DEPLOY_PATH = DEPLOY_PATH.split(".")[0] + ".silecsdeploy" SILECS_DEPLOY_PATH = DEPLOY_PATH.split(".")[0] + ".silecsdeploy"
RELEASE_PARAM_FILEPATH = os.path.join(RELEASE_PARAM_DIR_PATH, "SilecsTestClass", "SilecsTestClass_DU", "tsts7001.silecsparam")
RELEASE_PARAM_FILEPATH_DEV = os.path.join(RELEASE_PARAM_DIR_PATH, "SilecsTestClass", "SilecsTestClass_DU-d", "tsts7001.silecsparam")
design_schema_path_mock = "../silecs-model/src/xml/DesignSchema.xsd"
deploy_schema_path_mock = "../silecs-model/src/xml/DeploySchema.xsd"
@patch('silecs.DESIGN_SHEMA_PATH', design_schema_path_mock)
@patch('silecs.DEPLOY_SHEMA_PATH', deploy_schema_path_mock)
class SilecsTest(unittest.TestCase): class SilecsTest(unittest.TestCase):
"""Class to test silecs.py script""" """Class to test silecs.py script"""
@classmethod @classmethod
...@@ -26,8 +39,11 @@ class SilecsTest(unittest.TestCase): ...@@ -26,8 +39,11 @@ class SilecsTest(unittest.TestCase):
if os.path.isfile(SILECS_DESIGN_PATH): if os.path.isfile(SILECS_DESIGN_PATH):
os.remove(SILECS_DESIGN_PATH) os.remove(SILECS_DESIGN_PATH)
if os.path.isfile(SILECS_DEPLOY_PATH): if os.path.isfile(RELEASE_PARAM_FILEPATH):
os.remove(SILECS_DEPLOY_PATH) shutil.rmtree(RELEASE_PARAM_DIR_PATH)
if os.path.isfile(RELEASE_PARAM_FILEPATH_DEV):
shutil.rmtree(RELEASE_PARAM_DIR_PATH_DEV)
def test_get_extension(self): def test_get_extension(self):
"""Test getting extension from file""" """Test getting extension from file"""
...@@ -92,22 +108,34 @@ class SilecsTest(unittest.TestCase): ...@@ -92,22 +108,34 @@ class SilecsTest(unittest.TestCase):
def test_create_backup_file(self): def test_create_backup_file(self):
"""Test creating backup file""" """Test creating backup file"""
silecs.create_backup_file(BASE_FOR_BACKUP) silecs.create_backup_file(DESIGN_PATH)
self.assertNotEqual(os.stat(BACKUP).st_size, 0) self.assertNotEqual(os.stat(BACKUP).st_size, 0)
def test_silecs_validate(self): def test_silecs_validate(self):
"""Test validating silecs design/deploy files""" """Test validating silecs design/deploy files"""
silecs_design_deploy_paths = [os.path.join("tests", "examples", "SilecsTestClass.silecsdesign"), \ silecs_design_deploy_paths_result = [
os.path.join("tests", "examples", "SilecsTestClassDU.silecsdeploy")] (os.path.join("tests", "testClasses", "SilecsTestClass_DU", "src", "SilecsTestClass_DU.silecsdeploy"), True), \
for path in silecs_design_deploy_paths: (os.path.join("tests", "examples", "SchneiderM340TestDU_invalid.silecsdeploy"), False), \
(os.path.join("tests", "examples", "SilecsTestClassDU_invalid.silecsdeploy"), False)
]
for path, expected_result in silecs_design_deploy_paths_result:
xsd_path = silecs.get_schema_path(path) xsd_path = silecs.get_schema_path(path)
self.assertEqual(silecs.validate(path, xsd_path), True) self.assertEqual(silecs.validate(path, xsd_path), expected_result)
def test_create_validate(self):
"""Test creating silecs design file and then validate it"""
try:
new_file_path = silecs.get_silecs_file_path_from_fesa(DESIGN_PATH)
silecs.create(new_file_path)
except Exception as e:
print(e)
xsd_path = silecs.get_schema_path(new_file_path)
self.assertEqual(silecs.validate(new_file_path, xsd_path), True)
def test_silecs_validate_invalid(self): if os.path.isfile(new_file_path):
"""Test validating invalid silecs file""" os.remove(new_file_path)
invalid_silecs_deploy_path = os.path.join("tests", "examples", "SilecsTestClassDU_invalid.silecsdeploy")
xsd_path = silecs.get_schema_path(invalid_silecs_deploy_path)
self.assertEqual(silecs.validate(invalid_silecs_deploy_path, xsd_path), False)
def test_create_silecs_design(self): def test_create_silecs_design(self):
"""Test creating silecs design files from design file""" """Test creating silecs design files from design file"""
...@@ -129,10 +157,6 @@ class SilecsTest(unittest.TestCase): ...@@ -129,10 +157,6 @@ class SilecsTest(unittest.TestCase):
path = os.path.abspath(DEPLOY_PATH) path = os.path.abspath(DEPLOY_PATH)
new_file_path = silecs.get_silecs_file_path_from_fesa(path) new_file_path = silecs.get_silecs_file_path_from_fesa(path)
silecs.create(new_file_path)
print(new_file_path)
self.assertEqual(os.path.exists(new_file_path), True)
self.assertNotEqual(os.stat(new_file_path).st_size, 0)
try: try:
silecs.create(new_file_path) silecs.create(new_file_path)
...@@ -140,6 +164,16 @@ class SilecsTest(unittest.TestCase): ...@@ -140,6 +164,16 @@ class SilecsTest(unittest.TestCase):
print(str(e)) print(str(e))
self.assertIn("There is already a .silecsdeploy file available:", str(e)) self.assertIn("There is already a .silecsdeploy file available:", str(e))
def test_release_param(self):
"""Test release param file"""
result = silecs.release(SILECS_DEPLOY_PATH)
self.assertEqual(result, True)
self.assertEqual(os.path.isfile(RELEASE_PARAM_FILEPATH), True)
self.assertEqual(filecmp.cmp(RELEASE_PARAM_FILEPATH,
os.path.join("tests", "testClasses", "SilecsTestClass_DU", "generated-silecs", "client", "tsts7001.silecsparam")),
True)
if __name__ == "_main__": if __name__ == "_main__":
unittest.main() unittest.main()