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
Showing
with 571 additions and 450 deletions
......@@ -18,6 +18,8 @@ import sys
import time
import zlib
import libxml2
import datetime
import string
import iecommon
import iefiles
......@@ -62,7 +64,8 @@ whichUnityFormat = {
'int' : 'INT',
'dint' : 'DINT',
'real' : 'REAL',
'dt' : 'DT'
'dt' : 'DT',
'dtl' : 'DTL'
}
whichTwincatFormat = {
......@@ -89,8 +92,8 @@ whichTwincatFormat = {
'string' : 'STRING'
}
schneiderRegArray = """ARRAY[0..%d] OF %s"""
schneiderRegArray2d = """ARRAY[0..%d, 0..%d] OF %s"""
schneiderRegArray = string.Template("""ARRAY[0..${value}] OF ${len}""")
schneiderRegArray2d = string.Template("""ARRAY[0..${value1}, 0..${value2}] OF ${len}""")
# Beckhoff templates (using newlines \r\n because TwinCAT compiler complains with line feed character)
beckhoffReg = """ %s_%04x_%s AT %%MW%s: %s;\r\n\r\n"""
......@@ -112,42 +115,35 @@ def xsyRegister(register):
if register.isString():
return strLen
elif register.isStringArray():
return schneiderRegArray %(register.dim1-1, strLen)
return schneiderRegArray.substitute(value=register.dim1-1, len=strLen)
else: #2D-Array
return schneiderRegArray2d %(register.dim1-1, register.dim2-1, strLen)
return schneiderRegArray2d.substitute(value1=register.dim1-1, value2=register.dim2-1, len=strLen)
else:
if register.isScalar():
return whichUnityFormat[register.format]
elif register.isArray():
return schneiderRegArray %(register.dim1-1, whichUnityFormat[register.format])
return schneiderRegArray.substitute(value=register.dim1-1, len=whichUnityFormat[register.format])
else: #2D-Array
return schneiderRegArray2d %(register.dim1-1, register.dim2-1, whichUnityFormat[register.format])
return schneiderRegArray2d.substitute(value1=register.dim1-1, value2=register.dim2-1, len=whichUnityFormat[register.format])
def decimalToBCD(value):
return ((value//10)*16)+(value%10)
# convert date to DATE_AND_TIME string format (Siemens SIMATIC PLC)
# convert date to DATE_TIME_LONG or DATE_AND_TIME string format (Siemens SIMATIC PLC)
def getDateTime(controller):
dt = time.localtime(time.time())
if controller.model == 'SIMATIC_S7-1200':
# convert date to BCD byte-array (SIMATIC S7-12xx CPU does not support DATE_AND_TIME type)
return "%s,%s,%s,%s,%s,%s" %(decimalToBCD(dt[0]-2000),
decimalToBCD(dt[1]),
decimalToBCD(dt[2]),
decimalToBCD(dt[3]),
decimalToBCD(dt[4]),
decimalToBCD(dt[5]))
else:
return "DT#%s-%s-%s-%s:%s:%s" %(dt[0],dt[1],dt[2],dt[3],dt[4],dt[5])
dt = datetime.datetime.now()
if iecommon.supportsDateTimeLong(controller):
return "DTL#%s-%s-%s-%s:%s:%s.%03d" %(dt.year, dt.month, dt.day, dt.hour, dt.minute, dt.second, dt.microsecond // 1000)
else:
return "DT#%s-%s-%s-%s:%s:%s" % (dt.year, dt.month, dt.day, dt.hour, dt.minute, dt.second)
#-------------------------------------------------------------------------
# SIEMENS PLC code generation
#-------------------------------------------------------------------------
def generateSiemensSources(param, sourceFolderPath ,logTopics):
stlString = ''
stlString = s7template.head.substitute()
symString = '' # for .sdf Symbol file
# Prepare the Simatic Symbols (<.sdf> file)
......@@ -187,7 +183,8 @@ def generateSiemensSources(param, sourceFolderPath ,logTopics):
for block in paramClass.getParamMemoryBlocks():
blockList += s7template.stlBlock(paramClass.name, block.name)
deviceLabel = deviceDOM.prop('label')
stlString += s7template.generateBlock(param.owner, paramClass.name, paramClass.version, param.controller.system, DBnumber, deviceLabel, blockList, (deviceIndex == 0),param.controller.protocol)
fesaLabel = deviceDOM.prop('fesa-label')
stlString += s7template.generateBlock(param.owner, paramClass.name, paramClass.version, param.controller.system, DBnumber, deviceLabel, blockList, (deviceIndex == 0), param.controller.protocol, fesaLabel)
symString += s7template.symDeviceDB(paramClass.name, paramClass.version, deviceLabel, DBnumber, (deviceIndex == 0))
DBnumber += 1
......@@ -197,9 +194,10 @@ def generateSiemensSources(param, sourceFolderPath ,logTopics):
deviceList = ''
for deviceDOM in deviceDOMList:
deviceLabel = deviceDOM.prop('label')
deviceList += s7template.stlDevice(deviceLabel, paramClass.name, block.name)
fesaLabel = deviceDOM.prop('fesa-label')
deviceList += s7template.stlDevice(deviceLabel, paramClass.name, block.name, fesaLabel)
stlString += s7template.generateBlock(param.owner, paramClass.name, paramClass.version, param.controller.system, DBnumber, block.name, deviceList, (blockIndex == 0),param.controller.protocol)
stlString += s7template.generateBlock(param.owner, paramClass.name, paramClass.version, param.controller.system, DBnumber, block.name, deviceList, (blockIndex == 0),param.controller.protocol, "")
symString += s7template.symBlockDB(paramClass.name, paramClass.version, block.name, DBnumber, (blockIndex == 0))
DBnumber += 1
......@@ -525,6 +523,8 @@ def generateBeckhoffSources(param, sourceFolderPath, logTopics):
source += """* | C.E.R.N Geneva, Switzerland\r\n"""
source += """* | SILECS - BE/CO-FE\r\n"""
source += """* | April 2015\r\n"""
source += """* | This file is auto generated by the SILECS framework tools.\r\n"""
source += """* | Code regeneration will overwrite it.\r\n"""
source += """* +-------------------------------------------------------------------\r\n"""
source += """*\r\n"""
source += """* Release : SILECS_%s\r\n"""%(param.silecsVersion)
......@@ -543,7 +543,7 @@ def generateBeckhoffSources(param, sourceFolderPath, logTopics):
source += 'END_VAR'
# Write the source into the EXP source file
generateControllerFiles(sourceFolderPath,param.controller.hostName,".exp",source,logTopics);
generateControllerFiles(sourceFolderPath,param.controller.hostName,".exp",source,logTopics)
#-------------------------------------------------------------------------
# NI code generation
......@@ -556,7 +556,7 @@ def generateControllerFiles(sourceFolderPath,hostName,fileExtention,source,logTo
fileName = hostName + fileExtention
fullFilePath = os.path.normpath(sourceFolderPath + "/" + fileName )
iecommon.logInfo("Generate PLC sources: %s" %fullFilePath,logTopics);
iecommon.logInfo("Generate PLC sources: %s" %fullFilePath,logTopics)
fdesc = open(fullFilePath, "w")
fdesc.write(source)
fdesc.close()
......
......@@ -172,4 +172,9 @@ def getPatchSilecsVersion(silecsVersionString):
secondDot = silecsVersionString.find('.',firstDot)
return silecsVersionString[secondDot:]
def supportsDateTimeLong(controller):
if controller.brand != "SIEMENS":
return False
if controller.model in ['SIMATIC_S7-300', 'SIMATIC_S7-400']:
return False
return True
......@@ -26,9 +26,9 @@ designFormat = '.silecsdesign'
deployFormat = '.silecsdeploy'
paramFormat = '.silecsparam'
def loadSilecsDesignDOM(workspacePath, silecsDesign, silecsVersion, funcGetSilecsDesignFilePath):
def loadSilecsDesignDOM(workspacePath, silecsDesign, silecsVersion, funcGetSilecsDesignFilePath, datetime_format=xmltemplate.DATE_AND_TIME):
if silecsDesign.name == "SilecsHeader":
silecsHeader = xmltemplate.getSilecsHeader(silecsVersion)
silecsHeader = xmltemplate.getSilecsHeader(silecsVersion, datetime_format)
return libxml2.parseDoc(silecsHeader)
else:
designPath = funcGetSilecsDesignFilePath(workspacePath, silecsDesign.name)
......
......@@ -16,6 +16,7 @@
import os
import sys
import ParseMigrationArgs
from migrationBase import MigrationBase
from migration0_10_0to1_0_0.migrators import *
......@@ -26,8 +27,8 @@ import FileUtils
import shutil
class Migration(MigrationBase):
def __init__(self, arguments):
super(Migration, self).__init__()
def __init__(self, silecsDocument, xmlSchema, versionOld, versionNew, createBackup):
super(Migration, self).__init__(silecsDocument, xmlSchema, versionOld, versionNew, createBackup)
def migrateClass(self, context, projectDir ):
modified = designGenerateFesaPropValueItemMigrator(context)
......@@ -42,9 +43,7 @@ class Migration(MigrationBase):
return modified
def migrateFESAInstanceFile(self):
results = self.parser.parse_args()
silecsDocument = results.silecsDocument
projectDir = FileUtils.getProjectDir(silecsDocument)
projectDir = FileUtils.getProjectDir(self.silecsDocument)
testFolder = projectDir + "/src/test"
if not os.path.isdir(testFolder):
return
......@@ -60,7 +59,18 @@ class Migration(MigrationBase):
if fesaInstanceFileMigrator(context):
self._saveAndBackupFile(context,instanceFile)
if __name__ == "__main__":
migration = Migration(sys.argv)
def main_parse():
arguments = ParseMigrationArgs.parse_arguments()
run_migrate(arguments.silecsDocument,
arguments.xmlSchema,
arguments.versionOld,
arguments.versionNew,
arguments.createBackup)
def run_migrate(silecsDocument, xmlSchema, versionOld, versionNew, createBackup):
migration = Migration(silecsDocument, xmlSchema, versionOld, versionNew, createBackup)
migration.migrate()
migration.backupOldFESAMakeSpecific()
if __name__ == "__main__":
main_parse()
......@@ -16,6 +16,7 @@
import os
import sys
import ParseMigrationArgs
from migrationBase import MigrationBase
from migration_0_9_0to0_10_0.migrateDeployDeviceNumber import DeployDeviceNumberMigrator
......@@ -25,8 +26,8 @@ import libxml2
import sys
class Migration(MigrationBase):
def __init__(self, arguments):
super(Migration, self).__init__()
def __init__(self, silecsDocument, xmlSchema, versionOld, versionNew, createBackup):
super(Migration, self).__init__(silecsDocument, xmlSchema, versionOld, versionNew, createBackup)
self._deployDomainMigrator = DeployDomainMigrator()
self._migrateDeployDeviceNumber = DeployDeviceNumberMigrator()
......@@ -39,6 +40,17 @@ class Migration(MigrationBase):
modified = self._migrateDeployDeviceNumber.migrate(context)
return modified
if __name__ == "__main__":
migration = Migration(sys.argv)
def main_parse():
arguments = ParseMigrationArgs.parse_arguments()
run_migrate(arguments.silecsDocument,
arguments.xmlSchema,
arguments.versionOld,
arguments.versionNew,
arguments.createBackup)
def run_migrate(silecsDocument, xmlSchema, versionOld, versionNew, createBackup):
migration = Migration(silecsDocument, xmlSchema, versionOld, versionNew, createBackup)
migration.migrate()
if __name__ == "__main__":
main_parse()
......@@ -16,6 +16,7 @@
import os
import sys
import ParseMigrationArgs
from migrationBase import MigrationBase
from migration1_0_Xto2_0_0.migrators import *
......@@ -26,16 +27,26 @@ import FileUtils
import shutil
class Migration(MigrationBase):
def __init__(self, arguments):
super(Migration, self).__init__()
def __init__(self, silecsDocument, xmlSchema, versionOld, versionNew, createBackup):
super(Migration, self).__init__(silecsDocument, xmlSchema, versionOld, versionNew, createBackup)
def migrateClass(self, context, projectDir ):
def migrateClass(self, context, projectDir):
modified = designValueTypeMigrator(context)
modified |= designBlockRegisterMigrator(context)
return modified
def main_parse():
arguments = ParseMigrationArgs.parse_arguments()
run_migrate(arguments.silecsDocument,
arguments.xmlSchema,
arguments.versionOld,
arguments.versionNew,
arguments.createBackup)
if __name__ == "__main__":
migration = Migration(sys.argv)
def run_migrate(silecsDocument, xmlSchema, versionOld, versionNew, createBackup):
migration = Migration(silecsDocument, xmlSchema, versionOld, versionNew, createBackup)
migration.migrate()
migration.backupOldFESAMakeSpecific()
if __name__ == "__main__":
main_parse()
......@@ -16,6 +16,7 @@
import os
import sys
import ParseMigrationArgs
from migrationBase import MigrationBase
from migration2_0_Xto2_1_X.migrators import *
......@@ -26,8 +27,8 @@ import FileUtils
import shutil
class Migration(MigrationBase):
def __init__(self, arguments):
super(Migration, self).__init__()
def __init__(self, silecsDocument, xmlSchema, versionOld, versionNew, createBackup):
super(Migration, self).__init__(silecsDocument, xmlSchema, versionOld, versionNew, createBackup)
def migrateClass(self, context, projectDir ):
modified = False
......@@ -52,8 +53,17 @@ class Migration(MigrationBase):
self.updateFESAMakeSpecific()
return modified
def main_parse():
arguments = ParseMigrationArgs.parse_arguments()
run_migrate(arguments.silecsDocument,
arguments.xmlSchema,
arguments.versionOld,
arguments.versionNew,
arguments.createBackup)
if __name__ == "__main__":
migration = Migration(sys.argv)
def run_migrate(silecsDocument, xmlSchema, versionOld, versionNew, createBackup):
migration = Migration(silecsDocument, xmlSchema, versionOld, versionNew, createBackup)
migration.migrate()
if __name__ == "__main__":
main_parse()
......@@ -53,10 +53,3 @@ def getFesaSourceFiles(fesaClassName, projectDir):
print(os.path.join(root,file))
sourceFiles.append(os.path.join(root,file))
return sourceFiles
def replaceInFile(filePath,searchString,replaceWithString):
with open(filePath, 'r') as file :
filedata = file.read()
filedata = filedata.replace(searchString, replaceWithString)
with open(filePath, 'w') as file:
file.write(filedata)
\ No newline at end of file
from argparse import ArgumentParser
def parse_arguments():
parser = ArgumentParser(description='Migration script')
parser.add_argument("silecsDocument", action="store", help="The SILECS document to migrate")
parser.add_argument("xmlSchema", action="store", help="Path to the new schema")
parser.add_argument("versionOld", action="store", help="old silecs version")
parser.add_argument("versionNew", action="store", help="new silecs version")
parser.add_argument('--backup', dest='createBackup', action='store_true')
parser.add_argument('--no-backup', dest='createBackup', action='store_false')
parser.set_defaults(createBackup=False)
arguments = parser.parse_args()
return arguments
......@@ -14,12 +14,10 @@
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
from test.testBase import *
import unittest
import libxml2
#from migration.0_10_0to1_0_0 import *
from migration.migration0_10_0to1_0_0.migrators import *
import inspect #get caller name
SilecsDesignOld = '''<?xml version="1.0" encoding="UTF-8"?>
<SILECS-Design xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
......@@ -90,59 +88,50 @@ SilecsDeployOldParsed = libxml2.parseDoc(SilecsDeployOld)
fesaInstanceOldParsed = libxml2.parseFile("migration/migration0_10_0to1_0_0/DeviceData_PneuDriveDU.instance")
def testdeployRemoveSilecsHeaderMigrator(deployDoc):
deployRemoveSilecsHeaderMigrator(deployDoc)
silecsHeaders = deployDoc.xpathEval('/SILECS-Deploy/Deploy-Classes/Class/name[text()="SilecsHeader"]')
assertEqual(len(silecsHeaders),0)
class TestMigration0_10_0to1_0_0(unittest.TestCase):
def testdeployReOrderControllerAndClassesMigrator(deployDoc):
deployReOrderControllerAndClassesMigrator(deployDoc)
print(deployDoc)
oldClasses = deployDoc.xpathEval('/SILECS-Deploy/Deploy-Classes/Class')
assertEqual(len(oldClasses),0)
oldDeployInstances = deployDoc.xpathEval('/SILECS-Deploy/Deploy-Instances')
assertEqual(len(oldDeployInstances),0)
oldPLCNode = deployDoc.xpathEval('/SILECS-Deploy/Deploy-Unit/Siemens-PLC')
assertEqual(len(oldPLCNode),0)
def test_deploySwapStep7TiaMigrator(self):
deploySwapStep7TiaMigrator(SilecsDeployOldParsed)
plcEntries = SilecsDeployOldParsed.xpathEval("/SILECS-Deploy/Deploy-Unit/Siemens-PLC[@system='TIA-PORTAL']")
self.assertEqual(len(plcEntries),1)
newContollers = deployDoc.xpathEval('/SILECS-Deploy/Controller')
assertEqual(len(newContollers),2)
for newController in newContollers:
assertTrue(newController.hasProp("host-name"))
plcNodes = newController.xpathEval('Siemens-PLC')
assertEqual(len(plcNodes),1)
classNodes = newController.xpathEval('SilecsDesign')
assertEqual(len(classNodes),2)
pneuDrive = newController.xpathEval("SilecsDesign[@silecs-design-name='PneuDrive']")[0]
pneuDriveDevices = pneuDrive.xpathEval('Device')
assertEqual(len(pneuDriveDevices),6)
whatever = newController.xpathEval('SilecsDesign[@silecs-design-name="Whatever"]')[0]
whateverDevices = whatever.xpathEval('Device')
assertEqual(len(whateverDevices),1)
deployRemoveSilecsHeaderMigrator(SilecsDeployOldParsed)
silecsHeaders = SilecsDeployOldParsed.xpathEval('/SILECS-Deploy/Deploy-Classes/Class/name[text()="SilecsHeader"]')
self.assertEqual(len(silecsHeaders), 0)
def testdeploySwapStep7TiaMigrator(deployDoc):
deploySwapStep7TiaMigrator(deployDoc)
plcEntries = deployDoc.xpathEval("/SILECS-Deploy/Deploy-Unit/Siemens-PLC[@system='TIA-PORTAL']")
assertEqual(len(plcEntries),1)
deployReOrderControllerAndClassesMigrator(SilecsDeployOldParsed)
oldClasses = SilecsDeployOldParsed.xpathEval('/SILECS-Deploy/Deploy-Classes/Class')
self.assertEqual(len(oldClasses),0)
oldDeployInstances = SilecsDeployOldParsed.xpathEval('/SILECS-Deploy/Deploy-Instances')
self.assertEqual(len(oldDeployInstances),0)
oldPLCNode = SilecsDeployOldParsed.xpathEval('/SILECS-Deploy/Deploy-Unit/Siemens-PLC')
self.assertEqual(len(oldPLCNode),0)
def testdesignGenerateFesaPropValueItemMigrator(context):
designGenerateFesaPropValueItemMigrator(context)
updatedBlocks = context.xpathEval("//Block[@generateFesaProperty='true']")
updatedRegisters = context.xpathEval("//Register[@generateFesaValueItem='true']")
assertEqual(len(updatedBlocks),2)
assertEqual(len(updatedRegisters),12)
newContollers = SilecsDeployOldParsed.xpathEval('/SILECS-Deploy/Controller')
self.assertEqual(len(newContollers),2)
for newController in newContollers:
self.assertTrue(newController.hasProp("host-name"))
plcNodes = newController.xpathEval('Siemens-PLC')
self.assertEqual(len(plcNodes),1)
classNodes = newController.xpathEval('SilecsDesign')
self.assertEqual(len(classNodes),2)
pneuDrive = newController.xpathEval("SilecsDesign[@silecs-design-name='PneuDrive']")[0]
pneuDriveDevices = pneuDrive.xpathEval('Device')
self.assertEqual(len(pneuDriveDevices),6)
whatever = newController.xpathEval('SilecsDesign[@silecs-design-name="Whatever"]')[0]
whateverDevices = whatever.xpathEval('Device')
self.assertEqual(len(whateverDevices),1)
def testfesaInstanceFileMigrator(context):
fesaInstanceFileMigrator(context)
newValues = context.xpathEval("//device-instance[@name='YR11DF3']/configuration/parameterFile/value")
assertEqual(len(newValues),1)
assertEqual(newValues[0].getContent(),"../../../generated/client/sdaplc003.silecsparam")
def runTests():
testdeploySwapStep7TiaMigrator(SilecsDeployOldParsed)
testdeployRemoveSilecsHeaderMigrator(SilecsDeployOldParsed)
testdeployReOrderControllerAndClassesMigrator(SilecsDeployOldParsed)
testdesignGenerateFesaPropValueItemMigrator(SilecsDesignOldParsed)
testfesaInstanceFileMigrator(fesaInstanceOldParsed)
def test_designGenerateFesaPropValueItemMigrator(self):
designGenerateFesaPropValueItemMigrator(SilecsDesignOldParsed)
updatedBlocks = SilecsDesignOldParsed.xpathEval("//Block[@generateFesaProperty='true']")
updatedRegisters = SilecsDesignOldParsed.xpathEval("//Register[@generateFesaValueItem='true']")
self.assertEqual(len(updatedBlocks),2)
self.assertEqual(len(updatedRegisters),12)
# print deployDoc # for debugging
def test_fesaInstanceFileMigrator(self):
fesaInstanceFileMigrator(fesaInstanceOldParsed)
newValues = fesaInstanceOldParsed.xpathEval("//device-instance[@name='YR11DF3']/configuration/parameterFile/value")
self.assertEqual(len(newValues),1)
self.assertEqual(newValues[0].getContent(),"../../../generated/client/sdaplc003.silecsparam")
#!/usr/bin/python
# Copyright 2016 CERN and GSI
#
# 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/>.
from test.testBase import *
import libxml2
from migration.migration1_0_Xto2_0_0.migrators import *
import inspect #get caller name
def testdesignValueTypeMigrator():
SilecsDesignOld = '''<?xml version="1.0" encoding="UTF-8"?>
<SILECS-Design xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
silecs-version="0.10.0" created="03/21/16" updated="03/21/16"
xsi:noNamespaceSchemaLocation="/common/usr/cscofe/silecs/0.10.0/silecs-model/src/xml/DesignSchema.xsd">
<Information>
<Owner user-login="schwinn" />
<Editor user-login="schwinn" />
</Information>
<SILECS-Class name="PneuDrive" version="0.1.0" domain="TEST">
<Block name="Acq" mode="READ-ONLY">
<Register name="string1" synchro="MASTER" format="string" />
<Register name="string2" synchro="MASTER" format="string" string-len="65"/>
<Register name="string1D" synchro="MASTER" format="string" array-dim1="2" />
<Register name="string2D" synchro="MASTER" format="string" array-dim1="2" array-dim2="4"/>
<Register name="scalar" synchro="MASTER" format="int8" />
<Register name="scalar1D" synchro="MASTER" format="int8" array-dim1="2" />
<Register name="scalar2D" synchro="MASTER" format="int8" array-dim1="2" array-dim2="4"/>
</Block>
</SILECS-Class>
</SILECS-Design>'''
context = libxml2.parseDoc(SilecsDesignOld)
designValueTypeMigrator(context)
#context.shellPrintNode() #for debug
scalar = context.xpathEval("//Register[not(@format)]/scalar[@format='int8']")
array = context.xpathEval("//Register[not(@array-dim1)]/array[@dim='2' and @format='int8']")
array2D = context.xpathEval("//Register[not(@array-dim2)]/array2D[@dim1='2' and @dim2='4' and @format='int8']")
string1 = context.xpathEval("//Register/string[@format='string' and @string-length='64']")
string2 = context.xpathEval("//Register[not(@string-len)]/string[@format='string' and @string-length='65']")
stringArray = context.xpathEval("//Register/stringArray[@dim='2' and @format='string' and @string-length='64']")
stringArray2D = context.xpathEval("//Register/stringArray2D[@dim1='2' and @dim2='4' and @format='string' and @string-length='64']")
assertEqual(len(scalar),1)
assertEqual(len(array),1)
assertEqual(len(array2D),1)
assertEqual(len(string1),1)
assertEqual(len(string2),1)
assertEqual(len(stringArray),1)
assertEqual(len(stringArray2D),1)
def testdesignBlockRegisterMigrator():
SilecsDesignOld = '''<?xml version="1.0" encoding="UTF-8"?>
<SILECS-Design xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
silecs-version="0.10.0" created="03/21/16" updated="03/21/16"
xsi:noNamespaceSchemaLocation="/common/usr/cscofe/silecs/0.10.0/silecs-model/src/xml/DesignSchema.xsd">
<Information>
<Owner user-login="schwinn" />
<Editor user-login="schwinn" />
</Information>
<SILECS-Class name="PneuDrive" version="0.1.0" domain="TEST">
<Block name="block1" mode="READ-ONLY">
<Register name="b1r1" synchro="MASTER" format="string" />
<Register name="b1r2" synchro="NONE" format="string" array-dim1="2" />
</Block>
<Block name="block2" mode="READ-WRITE">
<Register name="b2r1" synchro="MASTER" format="string" />
<Register name="b2r2" synchro="SLAVE" format="string" />
<Register name="b2r3" synchro="NONE" format="string" array-dim1="2" />
</Block>
<Block name="block3" mode="WRITE-ONLY">
<Register name="b3r1" synchro="SLAVE" format="string" />
<Register name="b3r2" synchro="NONE" format="string" array-dim1="2" />
</Block>
</SILECS-Class>
</SILECS-Design>'''
context = libxml2.parseDoc(SilecsDesignOld)
designBlockRegisterMigrator(context)
context.shellPrintNode() #for debug
oldBlocks = context.xpathEval("//Block")
oldRegisters = context.xpathEval("//Register")
assertEqual(len(oldBlocks),0)
assertEqual(len(oldRegisters),0)
block1 = context.xpathEval("/SILECS-Design/SILECS-Class/Acquisition-Block")
block2 = context.xpathEval("/SILECS-Design/SILECS-Class/Setting-Block")
block3 = context.xpathEval("/SILECS-Design/SILECS-Class/Command-Block")
assertEqual(len(block1),1)
assertEqual(len(block2),1)
assertEqual(len(block3),1)
b1r1 = context.xpathEval("/SILECS-Design/SILECS-Class/Acquisition-Block/Acquisition-Register[@name='b1r1']")
b1r2 = context.xpathEval("/SILECS-Design/SILECS-Class/Acquisition-Block/Acquisition-Register[@name='b1r2']")
b2r1 = context.xpathEval("/SILECS-Design/SILECS-Class/Setting-Block/Volatile-Register[@name='b2r1']")
b2r2 = context.xpathEval("/SILECS-Design/SILECS-Class/Setting-Block/Setting-Register[@name='b2r2']") # synchro = master ? --> Missconfiguration --> We should have this reg in an acquisition-block
b2r3 = context.xpathEval("/SILECS-Design/SILECS-Class/Setting-Block/Volatile-Register[@name='b2r3']")
b3r2 = context.xpathEval("/SILECS-Design/SILECS-Class/Command-Block/Setting-Register[@name='b3r1']")
b3r2 = context.xpathEval("/SILECS-Design/SILECS-Class/Command-Block/Setting-Register[@name='b3r2']")
def runTests():
testdesignValueTypeMigrator()
testdesignBlockRegisterMigrator()
# print deployDoc # for debugging
#!/usr/bin/python
# Copyright 2016 CERN and GSI
#
# 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/>.
import unittest
import libxml2
from migration.migration1_0_Xto2_0_0.migrators import *
class TestMigration1_0_Xto2_0_0(unittest.TestCase):
def test_designValueTypeMigrator(self):
SilecsDesignOld = '''<?xml version="1.0" encoding="UTF-8"?>
<SILECS-Design xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
silecs-version="0.10.0" created="03/21/16" updated="03/21/16"
xsi:noNamespaceSchemaLocation="/common/usr/cscofe/silecs/0.10.0/silecs-model/src/xml/DesignSchema.xsd">
<Information>
<Owner user-login="schwinn" />
<Editor user-login="schwinn" />
</Information>
<SILECS-Class name="PneuDrive" version="0.1.0" domain="TEST">
<Block name="Acq" mode="READ-ONLY">
<Register name="string1" synchro="MASTER" format="string" />
<Register name="string2" synchro="MASTER" format="string" string-len="65"/>
<Register name="string1D" synchro="MASTER" format="string" array-dim1="2" />
<Register name="string2D" synchro="MASTER" format="string" array-dim1="2" array-dim2="4"/>
<Register name="scalar" synchro="MASTER" format="int8" />
<Register name="scalar1D" synchro="MASTER" format="int8" array-dim1="2" />
<Register name="scalar2D" synchro="MASTER" format="int8" array-dim1="2" array-dim2="4"/>
</Block>
</SILECS-Class>
</SILECS-Design>'''
context = libxml2.parseDoc(SilecsDesignOld)
designValueTypeMigrator(context)
#context.shellPrintNode() #for debug
scalar = context.xpathEval("//Register[not(@format)]/scalar[@format='int8']")
array = context.xpathEval("//Register[not(@array-dim1)]/array[@dim='2' and @format='int8']")
array2D = context.xpathEval("//Register[not(@array-dim2)]/array2D[@dim1='2' and @dim2='4' and @format='int8']")
string1 = context.xpathEval("//Register/string[@format='string' and @string-length='64']")
string2 = context.xpathEval("//Register[not(@string-len)]/string[@format='string' and @string-length='65']")
stringArray = context.xpathEval("//Register/stringArray[@dim='2' and @format='string' and @string-length='64']")
stringArray2D = context.xpathEval("//Register/stringArray2D[@dim1='2' and @dim2='4' and @format='string' and @string-length='64']")
self.assertEqual(len(scalar), 1)
self.assertEqual(len(array), 1)
self.assertEqual(len(array2D), 1)
self.assertEqual(len(string1), 1)
self.assertEqual(len(string2), 1)
self.assertEqual(len(stringArray), 1)
self.assertEqual(len(stringArray2D), 1)
def test_designBlockRegisterMigrator(self):
SilecsDesignOld = '''<?xml version="1.0" encoding="UTF-8"?>
<SILECS-Design xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
silecs-version="0.10.0" created="03/21/16" updated="03/21/16"
xsi:noNamespaceSchemaLocation="/common/usr/cscofe/silecs/0.10.0/silecs-model/src/xml/DesignSchema.xsd">
<Information>
<Owner user-login="schwinn" />
<Editor user-login="schwinn" />
</Information>
<SILECS-Class name="PneuDrive" version="0.1.0" domain="TEST">
<Block name="block1" mode="READ-ONLY">
<Register name="b1r1" synchro="MASTER" format="string" />
<Register name="b1r2" synchro="NONE" format="string" array-dim1="2" />
</Block>
<Block name="block2" mode="READ-WRITE">
<Register name="b2r1" synchro="MASTER" format="string" />
<Register name="b2r2" synchro="SLAVE" format="string" />
<Register name="b2r3" synchro="NONE" format="string" array-dim1="2" />
</Block>
<Block name="block3" mode="WRITE-ONLY">
<Register name="b3r1" synchro="SLAVE" format="string" />
<Register name="b3r2" synchro="NONE" format="string" array-dim1="2" />
</Block>
</SILECS-Class>
</SILECS-Design>'''
context = libxml2.parseDoc(SilecsDesignOld)
designBlockRegisterMigrator(context)
context.shellPrintNode() #for debug
oldBlocks = context.xpathEval("//Block")
oldRegisters = context.xpathEval("//Register")
self.assertEqual(len(oldBlocks),0)
self.assertEqual(len(oldRegisters),0)
block1 = context.xpathEval("/SILECS-Design/SILECS-Class/Acquisition-Block")
block2 = context.xpathEval("/SILECS-Design/SILECS-Class/Setting-Block")
block3 = context.xpathEval("/SILECS-Design/SILECS-Class/Command-Block")
self.assertEqual(len(block1),1)
self.assertEqual(len(block2),1)
self.assertEqual(len(block3),1)
b1r1 = context.xpathEval("/SILECS-Design/SILECS-Class/Acquisition-Block/Acquisition-Register[@name='b1r1']")
b1r2 = context.xpathEval("/SILECS-Design/SILECS-Class/Acquisition-Block/Acquisition-Register[@name='b1r2']")
b2r1 = context.xpathEval("/SILECS-Design/SILECS-Class/Setting-Block/Volatile-Register[@name='b2r1']")
b2r2 = context.xpathEval("/SILECS-Design/SILECS-Class/Setting-Block/Setting-Register[@name='b2r2']") # synchro = master ? --> Missconfiguration --> We should have this reg in an acquisition-block
b2r3 = context.xpathEval("/SILECS-Design/SILECS-Class/Setting-Block/Volatile-Register[@name='b2r3']")
b3r2 = context.xpathEval("/SILECS-Design/SILECS-Class/Command-Block/Setting-Register[@name='b3r1']")
b3r2 = context.xpathEval("/SILECS-Design/SILECS-Class/Command-Block/Setting-Register[@name='b3r2']")
#!/usr/bin/python
# Copyright 2016 CERN and GSI
#
# 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/>.
from test.testBase import *
import libxml2
from migration.migration2_0_Xto2_1_X.migrators import *
import inspect # get caller name
from shutil import copyfile
import os
#-------------------------------------- def testFesaClassMakeSpecificMigrator():
#------------- currentDirectory = os.path.dirname(os.path.abspath(__file__))
# makefileSpecific = os.path.join(currentDirectory, "myProject", "Makefile.specific")
# makefileSpecificOriginal = os.path.join(currentDirectory, "myProject", "Makefile.specific.original")
# makefileSpecificCorrect = os.path.join(currentDirectory, "myProject", "Makefile.specific.correct")
#-------------------------------------- if os.path.isfile(makefileSpecific):
#------------------------------------------- os.remove(makefileSpecific)
#---------------------- copyfile(makefileSpecificOriginal, makefileSpecific)
#--------------------------- fesaClassMakeSpecificMigrator(makefileSpecific)
#----------------- assertFileEqual(makefileSpecific,makefileSpecificCorrect)
def testSilecsDeployMigrator():
silecsDeployDocOld = '''<?xml version="1.0" encoding="UTF-8"?>
<SILECS-Deploy silecs-version="1.0.1" created="05/03/17" updated="05/03/17" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="/common/usr/cscofe/silecs/silecs-model/1.0.1/xml/DeploySchema.xsd">
<Information>
<Owner user-login="schwinn" />
<Editor user-login="schwinn" />
</Information>
<Deploy-Unit name="AlexTestDU" version="0.1.0" />
<Controller host-name="asl733">
<Siemens-PLC system="TIA-PORTAL" model="SIMATIC_S7-300" protocol="DEVICE_MODE" base-DB-number="1" />
<SilecsDesign silecs-design-version="0.1.0" silecs-design-name="AlexTest1">
<Device device-name="myDev1" />
<Device device-name="myDev2" />
</SilecsDesign>
<SilecsDesign silecs-design-version="0.1.0" silecs-design-name="AlexTest2">
<Device device-name="myDev3" />
<Device device-name="myDev4" />
</SilecsDesign>
</Controller>
<Controller host-name="asl744">
<Siemens-PLC system="TIA-PORTAL" model="SIMATIC_S7-300" protocol="DEVICE_MODE" base-DB-number="1" />
<SilecsDesign silecs-design-version="0.1.0" silecs-design-name="AlexTest1">
<Device device-name="myDev1" />
<Device device-name="myDev2" />
</SilecsDesign>
<SilecsDesign silecs-design-version="0.1.0" silecs-design-name="AlexTest2">
<Device device-name="myDev3" />
<Device device-name="myDev4" />
</SilecsDesign>
</Controller>
</SILECS-Deploy>'''
context = libxml2.parseDoc(silecsDeployDocOld)
silecsDeployMigrator(context)
print(context)
silecsDesigns = context.xpathEval("/SILECS-Deploy/SilecsDesign")
assertEqual(len(silecsDesigns),2)
devices = context.xpathEval("/SILECS-Deploy/Controller[@host-name='asl733']/*/Device")
assertEqual(len(devices),4)
assertEqual(devices[0].prop("silecs-design-ref"),"AlexTest1")
assertEqual(devices[0].prop("silecs-device-label"),"myDev1")
def testremoveFesaConfigurationFieldParameterFile():
FesaDocOld = '''<?xml version="1.0" encoding="UTF-8"?>
<equipment-model xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="file:/opt/fesa/fesa-model-gsi/4.2.0/xml/design/design-gsi.xsd">
<data>
<device-data>
<configuration>
<field name="parameterFile" id="_170711152634_36"><description>ParameterFile of the PLC (*.silecsparam)</description><array type="char"><dim>512</dim></array><default>../../../generated/client/MyControllerName.silecsparam</default></field><field name="plcDeviceLabel" id="_170711152634_37"><description>Name of the related SILECS instance within the PLC mapping</description><array type="char"><dim>128</dim></array></field><field name="plcHostName" id="_170711152634_38"><description>Hostname of the PLC that contains the related SILECS class device</description><array type="char"><dim>128</dim></array></field><GSI-detailed-status-labels-field name="detailedStatus_labels" id="_170503152015_8">
<array2D type="char">
<custom-constant-dim1 constant-name-ref="DETAILED_STATUS_SIZE"/>
<custom-constant-dim2 constant-name-ref="MAX_DETAILED_STATUS_LABEL_LENGTH"/>
</array2D>
<default>{myStatusLabel1,myStatusLabel2}</default>
</GSI-detailed-status-labels-field>
<GSI-detailed-status-severity-field name="detailedStatus_severity" id="_170503152015_9">
<custom-type-array data-type-name-ref="DETAILED_STATUS_SEVERITY">
<custom-constant-dim constant-name-ref="DETAILED_STATUS_SIZE"/>
</custom-type-array>
<default>{INFO,INFO}</default>
</GSI-detailed-status-severity-field>
<GSI-module-status-labels-field name="moduleStatus_labels" id="_170503152015_10">
<array2D type="char">
<custom-constant-dim1 constant-name-ref="MODULE_STATUS_SIZE"/>
<custom-constant-dim2 constant-name-ref="MAX_MODULE_STATUS_LABEL_LENGTH"/>
</array2D>
<default>{myModule1,myModule2}</default>
</GSI-module-status-labels-field>
</configuration>
</device-data>
</data>
</equipment-model>
'''
context = libxml2.parseDoc(FesaDocOld)
removeFesaConfigurationFieldParameterFile(context)
paramFields = context.xpathEval("//field[@name='parameterFile']")
assertEqual(len(paramFields),0)
def runTests():
#testFesaClassMakeSpecificMigrator()
testremoveFesaConfigurationFieldParameterFile()
testSilecsDeployMigrator()
# print deployDoc # for debugging
#!/usr/bin/python
# Copyright 2016 CERN and GSI
#
# 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/>.
import unittest
import libxml2
from migration.migration2_0_Xto2_1_X.migrators import *
class TestMigration2_0_Xto2_1_X(unittest.TestCase):
def test_silecsDeployMigrator(self):
silecsDeployDocOld = '''<?xml version="1.0" encoding="UTF-8"?>
<SILECS-Deploy silecs-version="1.0.1" created="05/03/17" updated="05/03/17" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="/common/usr/cscofe/silecs/silecs-model/1.0.1/xml/DeploySchema.xsd">
<Information>
<Owner user-login="schwinn" />
<Editor user-login="schwinn" />
</Information>
<Deploy-Unit name="AlexTestDU" version="0.1.0" />
<Controller host-name="asl733">
<Siemens-PLC system="TIA-PORTAL" model="SIMATIC_S7-300" protocol="DEVICE_MODE" base-DB-number="1" />
<SilecsDesign silecs-design-version="0.1.0" silecs-design-name="AlexTest1">
<Device device-name="myDev1" />
<Device device-name="myDev2" />
</SilecsDesign>
<SilecsDesign silecs-design-version="0.1.0" silecs-design-name="AlexTest2">
<Device device-name="myDev3" />
<Device device-name="myDev4" />
</SilecsDesign>
</Controller>
<Controller host-name="asl744">
<Siemens-PLC system="TIA-PORTAL" model="SIMATIC_S7-300" protocol="DEVICE_MODE" base-DB-number="1" />
<SilecsDesign silecs-design-version="0.1.0" silecs-design-name="AlexTest1">
<Device device-name="myDev1" />
<Device device-name="myDev2" />
</SilecsDesign>
<SilecsDesign silecs-design-version="0.1.0" silecs-design-name="AlexTest2">
<Device device-name="myDev3" />
<Device device-name="myDev4" />
</SilecsDesign>
</Controller>
</SILECS-Deploy>'''
context = libxml2.parseDoc(silecsDeployDocOld)
silecsDeployMigrator(context)
print(context)
silecsDesigns = context.xpathEval("/SILECS-Deploy/SilecsDesign")
self.assertEqual(len(silecsDesigns), 2)
devices = context.xpathEval("/SILECS-Deploy/Controller[@host-name='asl733']/*/Device")
self.assertEqual(len(devices),4)
self.assertEqual(devices[0].prop("silecs-design-ref"), "AlexTest1")
self.assertEqual(devices[0].prop("silecs-device-label"), "myDev1")
def test_removeFesaConfigurationFieldParameterFile(self):
FesaDocOld = '''<?xml version="1.0" encoding="UTF-8"?>
<equipment-model xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="file:/opt/fesa/fesa-model-gsi/4.2.0/xml/design/design-gsi.xsd">
<data>
<device-data>
<configuration>
<field name="parameterFile" id="_170711152634_36"><description>ParameterFile of the PLC (*.silecsparam)</description><array type="char"><dim>512</dim></array><default>../../../generated/client/MyControllerName.silecsparam</default></field><field name="plcDeviceLabel" id="_170711152634_37"><description>Name of the related SILECS instance within the PLC mapping</description><array type="char"><dim>128</dim></array></field><field name="plcHostName" id="_170711152634_38"><description>Hostname of the PLC that contains the related SILECS class device</description><array type="char"><dim>128</dim></array></field><GSI-detailed-status-labels-field name="detailedStatus_labels" id="_170503152015_8">
<array2D type="char">
<custom-constant-dim1 constant-name-ref="DETAILED_STATUS_SIZE"/>
<custom-constant-dim2 constant-name-ref="MAX_DETAILED_STATUS_LABEL_LENGTH"/>
</array2D>
<default>{myStatusLabel1,myStatusLabel2}</default>
</GSI-detailed-status-labels-field>
<GSI-detailed-status-severity-field name="detailedStatus_severity" id="_170503152015_9">
<custom-type-array data-type-name-ref="DETAILED_STATUS_SEVERITY">
<custom-constant-dim constant-name-ref="DETAILED_STATUS_SIZE"/>
</custom-type-array>
<default>{INFO,INFO}</default>
</GSI-detailed-status-severity-field>
<GSI-module-status-labels-field name="moduleStatus_labels" id="_170503152015_10">
<array2D type="char">
<custom-constant-dim1 constant-name-ref="MODULE_STATUS_SIZE"/>
<custom-constant-dim2 constant-name-ref="MAX_MODULE_STATUS_LABEL_LENGTH"/>
</array2D>
<default>{myModule1,myModule2}</default>
</GSI-module-status-labels-field>
</configuration>
</device-data>
</data>
</equipment-model>
'''
context = libxml2.parseDoc(FesaDocOld)
removeFesaConfigurationFieldParameterFile(context)
paramFields = context.xpathEval("//field[@name='parameterFile']")
self.assertEqual(len(paramFields), 0)
\ No newline at end of file
......@@ -18,22 +18,17 @@ import fnmatch
import os
import sys
import libxml2
from argparse import ArgumentParser
import FileUtils
import ParseMigrationArgs
class MigrationBase(object):
def __init__(self):
self.parser = ArgumentParser(description='Migration script')
self.parser.add_argument("silecsDocument", action="store", help="The SILECS document to migrate")
self.parser.add_argument("xmlSchema", action="store", help="Path to the new schema")
self.parser.add_argument("versionOld", action="store", help="old silecs version")
self.parser.add_argument("versionNew", action="store", help="new silecs version")
results = self.parser.parse_args()
self.versionOld = results.versionOld
self.versionNew = results.versionNew
self.silecsDocument = results.silecsDocument
self.xmlSchema = results.xmlSchema
def __init__(self, silecsDocument, xmlSchema, versionOld, versionNew, createBackup=False):
self.versionOld = versionOld
self.versionNew = versionNew
self.silecsDocument = silecsDocument
self.xmlSchema = xmlSchema
self.createBackup = createBackup
def fixSilecsVersion(self, context):
root = context.xpathEval("/*")[0]
if root.prop("silecs-version") != self.versionOld:
......@@ -50,18 +45,33 @@ class MigrationBase(object):
projectDir = FileUtils.getProjectDir(self.silecsDocument)
makeSpecific = os.path.join(projectDir,"Makefile.specific")
FileUtils.backupFile(makeSpecific)
def updateFESAMakeSpecific(self):
projectDir = FileUtils.getProjectDir(self.silecsDocument)
makeSpecific = os.path.join(projectDir,"Makefile.specific")
print("Migration-Info: Old Version-Strings in '" + makeSpecific + "' will be replaced\n")
if os.path.isfile(makeSpecific):
oldComm = "silecs-communication-cpp/" + self.versionOld
newComm = "silecs-communication-cpp/" + self.versionNew
FileUtils.replaceInFile(makeSpecific,oldComm,newComm)
oldSnap7 = "snap7/" + self.versionOld
newSnap7 = "snap7/" + self.versionNew
FileUtils.replaceInFile(makeSpecific,oldSnap7,newSnap7)
print(f"Migration-Info: {makeSpecific} will be updated.\n")
if FileUtils.fileExists(makeSpecific):
included = False
with open(makeSpecific, 'r') as file:
filedata = file.read()
if "include Makefile.silecs" in filedata:
# Correct include already in file, we have nothing to do.
included = True
if not included:
lines = []
for line in filedata.split('\n'):
if ("SILECS" in line) or ("snap7" in line) or ("SNAP7" in line):
print(f"Removing line '{line}'")
else:
lines.append(line + '\n')
lines.insert(0, "include Makefile.silecs\n")
lines.insert(0, "# Include SILECS makefile\n")
with open(makeSpecific, 'w') as file:
for line in lines:
file.write(line)
def removeGenCode(self):
projectDir = FileUtils.getProjectDir(self.silecsDocument)
......@@ -100,11 +110,13 @@ class MigrationBase(object):
# Unknown
else:
raise IOError("Document type unknown: %r" % extension)
# only chaning the version or the schema does not count as modification --> no backup needed
self.fixSilecsVersion(context)
self.fixXMLScheman(context,self.xmlSchema)
if modified:
self.updateFESAMakeSpecific()
if modified and self.createBackup:
self._saveAndBackupFile(context, self.silecsDocument)
else:
self._saveFile(context, self.silecsDocument)
......@@ -134,14 +146,18 @@ class MigrationBase(object):
context.saveTo(fd)
class MigrationAny(MigrationBase):
def __init__(self, arguments):
super(MigrationAny, self).__init__()
def run_migrate(silecsDocument, xmlSchema, versionOld, versionNew, createBackup):
migration = MigrationBase(silecsDocument, xmlSchema, versionOld, versionNew, createBackup)
migration.migrate()
def main_parse():
arguments = ParseMigrationArgs.parse_arguments()
def dummy(self):
#doNothing
print("dummy")
run_migrate(arguments.silecsDocument,
arguments.xmlSchema,
arguments.versionOld,
arguments.versionNew,
arguments.createBackup)
if __name__ == "__main__":
migration = MigrationAny(sys.argv)
migration.migrate()
\ No newline at end of file
main_parse()
......@@ -14,13 +14,12 @@
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
from test.testBase import *
import unittest
import libxml2
from migration.migration_0_9_0to0_10_0.migrateDeployDomain import *
from migration.migration_0_9_0to0_10_0.migrateDeployDeviceNumber import *
import inspect #get caller name
SilecsDeployOld = '''<?xml version="1.0" encoding="UTF-8"?>
<SILECS-Deploy silecs-version="0.9.0" created="03/04/16" updated="03/04/16"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
......@@ -59,33 +58,32 @@ SilecsDeployOld = '''<?xml version="1.0" encoding="UTF-8"?>
</SILECS-Deploy>
'''
def testMigrateDeployDeviceNumber(deployDoc):
migrator = DeployDeviceNumberMigrator()
migrator.migrate(deployDoc)
deviceNumbers = deployDoc.xpathEval("/SILECS-Deploy/Deploy-Classes/Class/device-number")
assertEqual(len(deviceNumbers),0)
deviceLists = deployDoc.xpathEval("/SILECS-Deploy/Deploy-Classes/Class/device-list")
assertEqual(len(deviceLists),3)
newHeader = deployDoc.xpathEval('/SILECS-Deploy/Deploy-Classes/Class/device-list/Device[@label="SilecsHeader"]')
assertEqual(len(newHeader),1)
test123 = deployDoc.xpathEval('/SILECS-Deploy/Deploy-Classes/Class/name[text()="Test123"]')
assertEqual(len(test123),1)
class TestMigration0_9_0to0_10_0(unittest.TestCase):
deviceListOnFirstPosition = test123[0].xpathEval('../*')[0]
assertTrue(deviceListOnFirstPosition.get_name() == 'device-list')
def setUp(self):
self.deployDoc = libxml2.parseDoc(SilecsDeployOld)
genericDevices = test123[0].xpathEval('../device-list/Device')
assertEqual(len(genericDevices),5)
def test_migrateDeployDeviceNumber(self):
migrator = DeployDeviceNumberMigrator()
migrator.migrate(self.deployDoc)
deviceNumbers = self.deployDoc.xpathEval("/SILECS-Deploy/Deploy-Classes/Class/device-number")
self.assertEqual(len(deviceNumbers),0)
deviceLists = self.deployDoc.xpathEval("/SILECS-Deploy/Deploy-Classes/Class/device-list")
self.assertEqual(len(deviceLists),3)
newHeader = self.deployDoc.xpathEval('/SILECS-Deploy/Deploy-Classes/Class/device-list/Device[@label="SilecsHeader"]')
self.assertEqual(len(newHeader),1)
test123 = self.deployDoc.xpathEval('/SILECS-Deploy/Deploy-Classes/Class/name[text()="Test123"]')
self.assertEqual(len(test123),1)
def testMigrateDeployDomain(deployDoc):
migrator = DeployDomainMigrator()
migrator.migrate(deployDoc)
controllers = deployDoc.xpathEval("/SILECS-Deploy/Deploy-Instances/Controller")
for controller in controllers:
assertFalse(controller.hasProp('domain'))
deviceListOnFirstPosition = test123[0].xpathEval('../*')[0]
self.assertTrue(deviceListOnFirstPosition.get_name() == 'device-list')
def runTests():
deployDoc = libxml2.parseDoc(SilecsDeployOld)
testMigrateDeployDomain(deployDoc)
testMigrateDeployDeviceNumber(deployDoc)
# print deployDoc # for debugging
genericDevices = test123[0].xpathEval('../device-list/Device')
self.assertEqual(len(genericDevices),5)
def test_MigrateDeployDomain(self):
migrator = DeployDomainMigrator()
migrator.migrate(self.deployDoc)
controllers = self.deployDoc.xpathEval("/SILECS-Deploy/Deploy-Instances/Controller")
for controller in controllers:
self.assertFalse(controller.hasProp('domain'))
class EnumItem(object):
def __init__(self, xmlNode) -> None:
self.xmlNode = xmlNode
self.access = xmlNode.prop("access")
self.symbol = xmlNode.prop("symbol")
self.value = xmlNode.prop("value")
def __str__(self) -> str:
return f"EnumItem: {self.access}, {self.symbol}, {self.value}"
class Enum(object):
def __init__(self, xmlNode) -> None:
self.xmlNode = xmlNode
self.name: str = xmlNode.prop("name")
self.items: EnumItem = []
items = xmlNode.xpathEval("item")
for item in items:
self.items.append(EnumItem(item))
def __str__(self) -> str:
items = ""
for item in self.items:
items += "\t"+ str(item) + "\n"
return f"Enum {self.name}.\nItems:\n {items}"
\ No newline at end of file