Files
VisualSapfor/src/SapforTestingSystem/PerformSapforTask.java

354 lines
14 KiB
Java
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
package SapforTestingSystem;
import Common.Constants;
import Common.Global;
import Common.Utils.Utils;
import GlobalData.Tasks.TaskState;
import ProjectData.Files.DBProjectFile;
import ProjectData.LanguageName;
import ProjectData.Messages.Errors.MessageError;
import ProjectData.Project.db_project_info;
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<SapforTask> {
@Override
public String getDescription() {
return "Запуск задачи SAPFOR";
}
@Override
protected boolean needsAnimation() {
return false;
}
//--
File sapfor_drv;
SapforConfiguration_json sapforConfiguration_json;
//-----
File parentTask;
File task;
//-----
Process process = null;
int exit_code = Constants.Nan;
//----
File outputFile = null;
File errorsFile = null;
//--
Vector<String> outputLines;
Vector<String> errorsLines;
//---
@Override
protected boolean canStart(Object... args) throws Exception {
sapfor_drv = (File) args[0];
sapforConfiguration_json = (SapforConfiguration_json) args[1];
String testDescription = (String) args[2];
target = (SapforTask) args[3];
//--->>
parentTask = Paths.get(Global.Home, sapforConfiguration_json.id, testDescription).toFile();
task = null;
//--->>
target.sapfor_configuration_id = sapforConfiguration_json.id;
target.test_description = testDescription;
target.root = parentTask.getAbsolutePath();
return true;
}
protected static boolean checkLines(Vector<String> 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())
+ (sapforConfiguration_json.flags.isEmpty() ? "" : (" " + sapforConfiguration_json.flags))
+ " -noLogo"
+ " " + command +
" 1>" +
Utils.DQuotes(outputFile.getAbsolutePath()) +
" 2>" +
Utils.DQuotes(errorsFile.getAbsolutePath()),
Charset.defaultCharset());
if (!file.setExecutable(true))
throw new Exception("Не удалось сделать файл скрипта " + name + " исполняемым!");
//--
ProcessBuilder procBuilder = new ProcessBuilder(file.getAbsolutePath());
procBuilder.directory(workspace);
process = procBuilder.start();
exit_code = process.waitFor();
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(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<File> 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(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("<s=" + s + ">");
// 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<MessageError> messages) throws Exception {
//Образец запакованного сообщения
//ERROR - [#1020: red43.fdv: line 988]: Active DVM directives are not supported (turn on DVM-directive support option)
Vector<String> 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<MessageError> 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();
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.root, "исходная"));
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);
}
}