package SapforTestingSystem; import Common.Constants; import Common.Global; import Common.Utils.Utils; import GlobalData.Tasks.TaskState; import ProjectData.Messages.Errors.MessageError; import SapforTestingSystem.Json.SapforConfiguration_json; import SapforTestingSystem.Json.SapforVersion_json; import SapforTestingSystem.SapforTask.SapforTask; import Visual_DVM_2021.Passes.PassCode_2021; import Visual_DVM_2021.Passes.Pass_2021; import org.apache.commons.io.FileUtils; import java.io.File; import java.nio.charset.Charset; import java.nio.file.Paths; import java.util.Arrays; import java.util.Comparator; import java.util.Vector; import static java.lang.Character.isDigit; public class PerformSapforTask extends Pass_2021 { @Override public String getDescription() { return "Запуск задачи SAPFOR"; } @Override protected boolean needsAnimation() { return false; } //-- File sapfor_drv; SapforConfiguration_json sapforConfiguration_json; //----- File root; File parentTask; File task; //----- Process process = null; int exit_code = Constants.Nan; //---- File outputFile = null; File errorsFile = null; //-- Vector outputLines; Vector errorsLines; //--- @Override protected boolean canStart(Object... args) throws Exception { sapfor_drv = (File) args[0]; sapforConfiguration_json = (SapforConfiguration_json) args[1]; target = (SapforTask) args[2]; //--->> parentTask = Paths.get(Global.Home, sapforConfiguration_json.id, target.test_description).toFile(); root = new File(Global.Home, sapforConfiguration_json.id); task = null; //--->> return true; } protected static boolean checkLines(Vector lines) { for (String line : lines) { if (line.toLowerCase().contains("internal error")) { return false; } if (line.toLowerCase().contains("exception")) { return false; } if (line.contains("[ERROR]")) { return false; } if (line.toLowerCase().contains("segmentation fault")) { return false; } } return true; } protected boolean performSapforScript(String name, File workspace, String command, String outName, String errName) throws Exception { process = null; exit_code = Constants.Nan; //--- File data_workspace = new File(workspace, Constants.data); Utils.CheckDirectory(data_workspace); outputFile = new File(data_workspace, outName); errorsFile = new File(data_workspace, errName); Utils.delete_with_check(outputFile); Utils.delete_with_check(errorsFile); //--- File file = new File(data_workspace, name + (Global.isWindows ? ".bat" : ".sh")); FileUtils.write(file, Utils.DQuotes(sapfor_drv.getAbsolutePath()) + (target.flags.isEmpty() ? "" : (" " + target.flags)) + " -noLogo" + " " + command + " 1>" + Utils.DQuotes(outputFile.getAbsolutePath()) + " 2>" + Utils.DQuotes(errorsFile.getAbsolutePath()), Charset.defaultCharset()); if (!file.setExecutable(true)) throw new Exception("Не удалось сделать файл скрипта " + name + " исполняемым!"); //-- boolean flag = false; do { try { ProcessBuilder procBuilder = new ProcessBuilder(file.getAbsolutePath()); procBuilder.directory(workspace); process = procBuilder.start(); exit_code = process.waitFor(); flag = true; } catch (Exception ex) { Global.Log.PrintException(ex); Utils.sleep(1000); } } while (!flag); process = null; //--- outputLines = new Vector<>(FileUtils.readLines(outputFile)); errorsLines = new Vector<>(FileUtils.readLines(errorsFile)); return (exit_code == 0) && checkLines(outputLines) && checkLines(errorsLines); } protected boolean parse() throws Exception { if (performSapforScript("parse", parentTask, "-parse *.f *.for *.fdv *.f90 *.f77", Constants.parse_out_file, Constants.parse_err_file) && (new File(parentTask, "dvm.proj")).exists()) { return true; } else { target.state = TaskState.DoneWithErrors; return false; } } //слегка изменить подход. protected boolean transformation(PassCode_2021 code) throws Exception { task = new File(parentTask, "v1"); Utils.CheckAndCleanDirectory(task); //папка для преобразования. //если версия пустая, это тоже результат тестирования. Поэтому должна учитываться в древе. target.versions.add(new SapforVersion_json( root.getAbsolutePath(), task.getAbsolutePath(), code.getDescription())); //--- if (performSapforScript("transformation", parentTask, code.getTestingCommand() + " -F " + Utils.DQuotes(task.getAbsolutePath()), Constants.out_file, Constants.err_file )) { target.state = TaskState.Done; parentTask = task; return true; } target.state = TaskState.DoneWithErrors; return false; } protected void variants() throws Exception { //папки вариантов создается самим сапфором. target.state = performSapforScript("create_variants", parentTask, " -t 13 -allVars" + " -tinfo" , Constants.out_file, Constants.err_file ) ? TaskState.Done : TaskState.DoneWithErrors; //найти папки с вариантами. File[] files_ = parentTask.listFiles((dir, name) -> dir.isDirectory() && Utils.isParallelVersionName(name)); if ((files_ != null) && (files_.length > 0)) { Vector files = new Vector<>(Arrays.asList(files_)); files.sort(Comparator.comparingInt(o -> Integer.parseInt(o.getName().substring(1)))); for (File file : files) target.variants.add( new SapforVersion_json( root.getAbsolutePath(), file.getAbsolutePath(), PassCode_2021.SPF_CreateParallelVariant.getDescription())); } } //-------------------------------------------------->> public MessageError unpackMessage(String line_in) throws Exception { MessageError res = new MessageError(); res.file = ""; res.line = Constants.Nan; res.value = ""; String line = line_in.substring(9); //System.out.println(line); int i = 0; int s = 0; String lexeme = ""; //#1020: red43.fdv: line 988]: Active DVM directives are not supported (turn on DVM-directive support option) for (char c : line.toCharArray()) { // System.out.print(""); // System.out.println(c); switch (s) { case 0: //поиск groups_s if (c == '#') { s = 1; lexeme = ""; } else return null; break; case 1: //group_s if (isDigit(c)) { res.group_s += c; lexeme += c; } else if (c == ':') { s = 2; res.group = Integer.parseInt(lexeme); } else return null; break; case 2: //поиск filename if (c == ' ') { s = 3; } else return null; break; case 3: //filename if (c == ':') { s = 4; } else { res.file += c; } break; case 4: //поиск line if (c == ' ') { s = 5; lexeme = ""; } else return null; break; case 5: //line if (c == ' ') { if (!lexeme.equals("line")) return null; else { s = 6; lexeme = ""; } } else { lexeme += c; } break; case 6: //line number if (isDigit(c)) { lexeme += c; } else if (c == ']') { res.line = Integer.parseInt(lexeme); s = 7; } else return null; break; case 7: //Поиск value if (c == ':') { s = 8; } else return null; break; case 8: if (c == ' ') { s = 9; } else return null; break; case 9: //value res.value += c; break; } ; ++i; } //-- if (s != 9) return null; //-- return res; } public void readMessagesFromFileDump(File file, Vector messages) throws Exception { //Образец запакованного сообщения //ERROR - [#1020: red43.fdv: line 988]: Active DVM directives are not supported (turn on DVM-directive support option) Vector lines = new Vector<>(FileUtils.readLines(file)); if (!lines.isEmpty()) { for (int i = lines.size() - 1; i >= 0; --i) { String line = lines.get(i); if (line.startsWith("ERROR - ")) { MessageError message = unpackMessage(line); if (message != null) messages.add(message); //-- } else break; } } } //-- /* protected void createVersionProjectData(SapforVersion_json version, boolean isTransformation) throws Exception { db_project_info project = new db_project_info(); project.Home = new File(version.version); project.name = project.Home.getName(); project.description = version.description; project.languageName = LanguageName.fortran; project.creationDate = Utils.getDateNumber(); //-- Vector messages = new Vector<>(); //-- if (isTransformation) { File p_out = Paths.get(project.Home.getAbsolutePath(), Constants.data, Constants.parse_out_file).toFile(); File p_err = Paths.get(project.Home.getAbsolutePath(), Constants.data, Constants.parse_err_file).toFile(); File out = Paths.get(project.Home.getAbsolutePath(), Constants.data, Constants.out_file).toFile(); File err = Paths.get(project.Home.getAbsolutePath(), Constants.data, Constants.err_file).toFile(); //-- if (p_out.exists()) { project.Log += (FileUtils.readFileToString(p_out)); readMessagesFromFileDump(p_out, messages); } if (out.exists()) { project.Log += "\n" + FileUtils.readFileToString(out); readMessagesFromFileDump(out, messages); } //в потоки ошибок идет информация от операционной системы. сообщений там быть не должно. if (p_err.exists()) project.Log += (FileUtils.readFileToString(p_err)); if (err.exists()) project.Log += "\n" + FileUtils.readFileToString(err); //-- } project.CreateVisualiserData(); //--- if (isTransformation && !messages.isEmpty()) { project.Open(); //нельзя!!! сначала надо определиться с версиями. И только потом, получать файлы. //а так же, убрать dep и txt project.db.BeginTransaction(); for (MessageError m : messages) { if (project.db.files.containsKey(m.file)) { DBProjectFile file = project.db.files.Data.get(m.file); file.CreateAndAddNewMessage(1, m.value, m.line, m.group); //update file project.db.Update(file); } } project.db.Commit(); project.db.Disconnect(); } } */ //-------------------------------------------------->> @Override protected void body() throws Exception { target.versions.add(new SapforVersion_json(target.test_description, "исходная")); for (PassCode_2021 code : sapforConfiguration_json.codes) { if (parse()) { if (code.equals(PassCode_2021.CreateParallelVariants)) variants(); else if (!transformation(code)) break; } else break; } } @Override protected void performFinish() throws Exception { /* //теперь строим деревья версий. нельзя делать в body. так как могут быть исключения например неверный код процесса. for (SapforVersion_json version : target.versions) createVersionProjectData(version, true); for (SapforVersion_json version : target.variants) createVersionProjectData(version, false); */ } }