def cliExecuteAlgorithmFromExtendedMultiModel(): testutils.printSection("CLI execute algorithm from multi model") temporary = tempfile.mkdtemp() print(f"Temporary directory: {temporary}") resourcesPath = os.path.join(SCR_path, "execute_algorithm") multiModelPath = os.path.join(temporary, "multimodel.json") executionParametersPath = os.path.join(resourcesPath, "executionParameters.json") with open(os.path.join(resourcesPath, "extendedmultimodel.json"), "r") as jsonFile: multimodel = json.load(jsonFile) multimodel["fmus"]["{FMU}"] = pathlib.Path( os.path.abspath( os.path.join(SCR_path, "generate_from_multi_model", "rollback-test.fmu"))).as_uri() multimodel["fmus"]["{Controller}"] = pathlib.Path( os.path.abspath( os.path.join(SCR_path, "generate_from_multi_model", "rollback-end.fmu"))).as_uri() with open(multiModelPath, "w+") as jsonFile: json.dump(multimodel, jsonFile) cmd = "java -jar {0} sigver execute-algorithm -mm {1} -ep {2} -output {3} -di -vim FMI2".format( path, multiModelPath, executionParametersPath, temporary) func = lambda: validateAlgorithmExecution( os.path.join(temporary, "outputs.csv"), os.path.join(resourcesPath, "expectedoutputs.csv")) testutils.testCliCommandWithFunc(cmd, func)
def legacyCliSimConfig(): testutils.printSection("Legacy CLI with Simulation Configuration") temporary = testutils.createAndPrepareTempDirectory() cmd1 = "java -jar {0} -o -c {1} -sc {2} -r {3}".format( path, temporary.initializationPath, testutils.simulationConfigurationPath, temporary.resultPath) cliTest(temporary, cmd1)
def cliGenerateAlgorithmFromMultiModel(): testutils.printSection("CLI generate algorithm from multi model") temporary = tempfile.mkdtemp() print(f"Temporary directory: {temporary}") resourcesPath = os.path.join(SCR_path, "generate_from_multi_model") multiModelPath = os.path.join(temporary, "multimodel.json") with open(os.path.join(resourcesPath, "multimodel.json"), "r") as jsonFile: multiModel = json.load(jsonFile) multiModel["fmus"]["{FMU}"] = pathlib.Path( os.path.abspath(os.path.join(resourcesPath, "rollback-test.fmu"))).as_uri() multiModel["fmus"]["{Controller}"] = pathlib.Path( os.path.abspath(os.path.join(resourcesPath, "rollback-end.fmu"))).as_uri() with open(multiModelPath, "w+") as jsonFile: json.dump(multiModel, jsonFile) cmd = "java -jar {0} sigver generate-algorithm {1} -output {2}".format( path, multiModelPath, temporary) func = lambda: print( "Succesfully generated algorithm from multi model") if (os.path.exists( os.path.join(temporary, "algorithm.conf"))) else lambda: ( Exception("Algorithm was not returned")) testutils.testCliCommandWithFunc(cmd, func)
def simulate(sessionID): testutils.printSection("SIMULATE") r = requests.post(basicUrl + "/simulate/" + sessionID, json=json.load(open("wt/start_message.json"))) if not r.status_code == 200: raise Exception(f"Could not simulate: {r.text}") print("Simulate response code '%d, data=%s'" % (r.status_code, r.text))
def testVisualizationEntryPoint(basicUrl, baseResourcePath): testutils.printSection("WEB API visualize traces") tempDirectory = tempfile.mkdtemp() print("Temporary directory: " + tempDirectory) resourcesPath = os.path.join(baseResourcePath, "visualize_traces") with open(os.path.join(resourcesPath, "masterModel.conf")) as f: payloadString = f.read() response = requests.post(f"{basicUrl}/visualizeTrace", data=payloadString, headers={'Content-Type': 'text/plain'}) testutils.ensureResponseOk(response) videoFilePath = os.path.join(tempDirectory, "traces.mp4") with open(videoFilePath, 'wb') as wfile: wfile.write(response.content) print("Video file is located at: " + videoFilePath) fileSize = Path(videoFilePath).stat().st_size if fileSize < 100: raise Exception( "The size of the returned file seems too small to contain any video." ) else: print("SUCCESS: Trace visualization of the algorithm has been tested.")
def cliExpansion(): testutils.printSection("CLI Expansion") temporary = testutils.createAndPrepareTempDirectory() outputs = os.path.join(temporary.dirPath, outputsFileName) cmd = "java -jar {0} interpret -output {1} --dump-intermediate {1} {2} -vi FMI2".format( path, temporary.dirPath, testutils.mablExample) testutils.testCliCommandWithFunc( cmd, lambda: validateCliSpecResult(outputs, temporary))
def legacyCliStarttimeEndtime(): testutils.printSection("Legacy CLI with starttime and endtime") temporary = testutils.createAndPrepareTempDirectory() simConfigParsed = testutils.retrieveSimulationConfiguration() cmd2 = "java -jar {0} -o -c {1} -s {2} -e {3} -r {4}".format( path, temporary.initializationPath, simConfigParsed['startTime'], simConfigParsed['endTime'], temporary.resultPath) cliTest(temporary, cmd2)
def cliSpecGen(): testutils.printSection("CLI with Specification Generation") temporary = testutils.createAndPrepareTempDirectory() outputs = os.path.join(temporary.dirPath, outputsFileName) cmd = "java -jar {0} import -output {1} --dump-intermediate sg1 {2} {3} -i -vi FMI2".format( path, temporary.dirPath, temporary.initializationPath, testutils.simulationConfigurationPath) testutils.testCliCommandWithFunc( cmd, lambda: validateCliSpecResult(outputs, temporary))
def verifyAlgorithmTest(SCR_path, jarPath): testutils.printSection("CLI verify algorithm") temporary = tempfile.mkdtemp() print(f"Temporary directory: {temporary}") masterModelPath = os.path.join(SCR_path, "verify_algorithm", "masterModel.conf") cmd = "java -jar {0} scenario-verifier verify-algorithm {1} -output {2}".format( jarPath, masterModelPath, temporary) func = lambda: True testutils.testCliCommandWithFunc(cmd, func)
def visualizeTracesTest(SCR_path, jarPath): testutils.printSection("CLI visualize traces") temporary = tempfile.mkdtemp() print(f"Temporary directory: {temporary}") masterModelPath = os.path.join(SCR_path, "visualize_traces", "masterModel.conf") cmd = "java -jar {0} scenario-verifier visualize-traces {1} -output {2}".format( jarPath, masterModelPath, temporary) func = lambda: True testutils.testCliCommandWithFunc(cmd, func)
def cliGenerateAlgorithmFromScenario(): testutils.printSection("CLI generate algorithm from scenario") temporary = tempfile.mkdtemp() print(f"Temporary directory: {temporary}") scenarioPath = os.path.join(SCR_path, "generate_from_scenario", "scenario.conf") cmd = "java -jar {0} sigver generate-algorithm {1} -output {2}".format( path, scenarioPath, temporary) func = lambda: print("Succesfully generated algorithm from scenario") if ( os.path.exists(os.path.join(temporary, "algorithm.conf")) ) else lambda: (Exception("Algorithm was not returned")) testutils.testCliCommandWithFunc(cmd, func)
def cliExportCpp(runTest): testutils.printSection("CLI export cpp") if not runTest: print("Skipping CLI export cpp test...") return temporary = testutils.createAndPrepareTempDirectory() outputs = os.path.join(temporary.dirPath, outputsFileName) cmd = "java -jar {0} export -output {1} -vi FMI2 cpp {2}".format( path, temporary.dirPath, testutils.mablExample) print("Cmd: " + cmd) p = subprocess.run(cmd, shell=True, check=True) cmd = "cmake" if os.name == 'nt' or 'Windows' in platform.system( ) or 'CYGWIN' in platform.system(): cmd = cmd + " -G\"MSYS Makefiles\"" cmd = cmd + " -B{0} -S{1}".format( Path(temporary.dirPath) / 'build', temporary.dirPath) print("Cmd: " + cmd) p = subprocess.run(cmd, shell=True, check=True) cmd = "make -j8 -C {0}".format(Path(temporary.dirPath) / 'build') print("Cmd: " + cmd) p = subprocess.run(cmd, shell=True, check=True) output_csv_path = Path(temporary.dirPath) / 'build' / 'output.csv' runtime = { "DataWriter": [{ "filename": str(output_csv_path), "type": "CSV" }] } runtime_path = Path(temporary.dirPath) / 'build' / 'runtime.json' with open(runtime_path, 'w') as f: f.write(json.dumps(runtime)) cmd = "{0} -runtime {1}".format( Path(temporary.dirPath) / 'build' / 'sim', runtime_path) print("Cmd: " + cmd) p = subprocess.run(cmd, shell=True) if p.returncode != 0: raise Exception(f"Error executing {cmd}")
def testVerificationEntryPoint(basicUrl, baseResourcePath): testutils.printSection("WEB API verify algorithm") tempDirectory = tempfile.mkdtemp() print("Temporary directory: " + tempDirectory) resourcesPath = os.path.join(baseResourcePath, "verify_algorithm") with open(os.path.join(resourcesPath, "masterModel.conf")) as f: payloadString = f.read() response = requests.post(f"{basicUrl}/verifyAlgorithm", data=payloadString, headers={'Content-Type': 'text/plain'}) testutils.ensureResponseOk(response) actualResultJson = response.json() if (actualResultJson["verifiedSuccessfully"]): raise Exception( "The algorithm should not have been verified successfully.") else: print("SUCCESS: Verification of the algorithm has been tested.")
def testSimulationController(basicUrl): tempDirectory = tempfile.mkdtemp() print("Temporary directory: " + tempDirectory) # Update paths to FMUs config = testutils.retrieveConfiguration() print("CONFIG: %s" % json.dumps(config)) testutils.printSection("CREATE SESSION") r = requests.get(basicUrl + "/createSession") if not r.status_code == 200: raise Exception("Could not create session") status = json.loads(r.text) print("Session '%s', data=%s'" % (status["sessionId"], status)) # Initialize testutils.printSection("INITIALIZE") r = requests.post(basicUrl + "/initialize/" + status["sessionId"], json=config) if not r.status_code == 200: raise Exception("Could not initialize") print("Initialize response code '%d, data=%s'" % (r.status_code, r.text)) sessionID = status["sessionId"] # Weboscket support testutils.printSection("WEBSOCKET") wsurl = "ws://localhost:{port}/attachSession/{session}".format( port=port, session=sessionID) print("Connecting to websocket with url: " + wsurl) wsResult = os.path.join(tempDirectory, "wsActualResult.txt") socketFile = open(wsResult, "w") print("Writing websocket output to: " + wsResult) wsOnMessage = lambda ws, msg: socketFile.write(msg) wsThread = threading.Thread(target=ws_thread, args=( wsurl, wsOnMessage, )) wsThread.start() webSocketWaitAttempts = 0 while not websocketopen and webSocketWaitAttempts < 5: webSocketWaitAttempts += 1 print("WS: Awaiting websocket opening") time.sleep(0.5) if (not websocketopen): raise Exception("Unable to open socket connection") # Simulate simulate(sessionID) wsThread.join() socketFile.close() # Compare results testutils.printSection("WS OUTPUT COMPARE") if (not testutils.compare("WS", "wt/wsexpected.txt", wsResult)): raise Exception("Output files do not match.") # Get plain results testutils.printSection("PLAIN RESULT") r = requests.get(basicUrl + "/result/" + sessionID + "/plain") if not r.status_code == 200: raise Exception(f"Could not get plain results: {r.text}") print("Result response code '%d" % (r.status_code)) result_csv_path = "actual_result.csv" csv = r.text csvFilePath = os.path.join(tempDirectory, result_csv_path) with open(csvFilePath, "w+") as f: f.write(csv.replace("\r\n", "\n")) print("Wrote csv file to: " + csvFilePath) if not testutils.compareCSV("wt/result.csv", csvFilePath): raise Exception("CSV files did not match!") # Get zip results testutils.printSection("ZIP RESULT") r = requests.get(basicUrl + "/result/" + sessionID + "/zip", stream=True) if not r.status_code == 200: raise Exception(f"Could not get zip results: {r.text}") print("Result response code '%d" % (r.status_code)) result_zip_path = "actual_zip_result.zip" zipFilePath = os.path.join(tempDirectory, result_zip_path) chunk_size = 128 with open(zipFilePath, 'wb') as fd: for chunk in r.iter_content(chunk_size=chunk_size): fd.write(chunk) print("Wrote zip file to: " + zipFilePath) with closing(ZipFile(zipFilePath)) as archive: filesInZipCount = len(archive.infolist()) if filesInZipCount < 2: raise Exception( f"Wrong number of files in zip. Actually: {str(filesInZipCount)}") else: print("2 or more files in result zip. Actually: " + str(filesInZipCount)) # Execute via CLI testutils.printSection("EXECUTE VIA CLI") r = requests.post(basicUrl + "/executeViaCLI/" + sessionID, json={'executeViaCLI': True}) print("Result response code '%d" % (r.status_code)) if not r.status_code == 200: raise Exception(f"Could not execute via cli: {r.text}") simulate(sessionID) # Destroy testutils.printSection("DESTROY") r = requests.get(basicUrl + "/destroy/" + sessionID) print("Result response code '%d" % (r.status_code)) if not r.status_code == 200: raise Exception(f"Could not destroy: {r.text}")
def testScenarioController(basicUrl): baseResourcePath = "scenario_controller_resources" tempDirectory = tempfile.mkdtemp() print("Temporary directory: " + tempDirectory) #Test generate algorithm from scenario testutils.printSection("GENERATE ALGORITHM FROM SCENARIO") gas_resourcesPath = os.path.join(baseResourcePath, "generate_from_scenario") with open(os.path.join(gas_resourcesPath, "scenario.conf")) as f: payloadString = f.read() response = requests.post(f"{basicUrl}/generateAlgorithmFromScenario", data=payloadString, headers={'Content-Type': 'text/plain'}) testutils.ensureResponseOk(response) actualResult = os.path.join(tempDirectory, "actualResultFromScenario.txt") expectedResult = os.path.join(gas_resourcesPath, "expectedResult.txt") with open(actualResult, "w") as f: f.write(response.text) if (not testutils.compare("Generate from scenario", expectedResult, actualResult)): raise Exception( "Expected algorithm does not match the actual algorithm.") #Test generate algorithm from multi model testutils.printSection("GENERATE ALGORITHM FROM MULTI MODEL") gamm_resourcesPath = os.path.join(baseResourcePath, "generate_from_multi_model") # Set FMU path to be a relative path multiModel = json.load( open(os.path.join(gamm_resourcesPath, "multimodel.json"))) relativeFMUPathUri = pathlib.Path( os.path.abspath(os.path.join(gamm_resourcesPath, "rollback-test.fmu"))).as_uri() relativeControllerPathUri = pathlib.Path( os.path.abspath(os.path.join(gamm_resourcesPath, "rollback-end.fmu"))).as_uri() multiModel["fmus"]["{FMU}"] = relativeFMUPathUri multiModel["fmus"]["{Controller}"] = relativeControllerPathUri response = requests.post(f"{basicUrl}/generateAlgorithmFromMultiModel", json=multiModel) testutils.ensureResponseOk(response) actualMasterModel = response.content.decode('utf-8') with open(os.path.join(gamm_resourcesPath, "expectedMasterModel.txt")) as f: expectedMasterModel = f.read() expectedMasterModel = bytes(expectedMasterModel, "utf-8").decode("unicode_escape") if (not actualMasterModel == expectedMasterModel): print("ERROR: actual and expected master model do not match") print("Actual:") print(json.dumps(actualMasterModel, indent=2)) print("Expected:") print(json.dumps(expectedMasterModel, indent=2)) raise Exception( "Returned master model does not match the expected master model") else: print("Actual master model matches the expected master model") #Test execute algorithm testutils.printSection("EXECUTE ALGORITHM") ea_resourcesPath = os.path.join(baseResourcePath, "execute_algorithm") executableModel = json.load( open(os.path.join(ea_resourcesPath, "executableModel.json"))) executableModel["multiModel"]["fmus"]["{FMU}"] = relativeFMUPathUri executableModel["multiModel"]["fmus"][ "{Controller}"] = relativeControllerPathUri response = requests.post(f"{basicUrl}/executeAlgorithm", json=executableModel) testutils.ensureResponseOk(response) zipFilePath = os.path.join(tempDirectory, "actual_zip_result.zip") chunk_size = 128 with open(zipFilePath, 'wb') as fd: for chunk in response.iter_content(chunk_size=chunk_size): fd.write(chunk) print("Wrote zip file to: " + zipFilePath) actualCSVFilePath = os.path.join(tempDirectory, "actual_result.csv") expectedCSVFilePath = os.path.join(ea_resourcesPath, "expectedoutputs.csv") with ZipFile(zipFilePath, 'r') as z: with open(actualCSVFilePath, 'wb') as f: f.write(z.read('outputs.csv')) if not testutils.compareCSV(expectedCSVFilePath, actualCSVFilePath): raise Exception("CSV files did not match!")