367 lines
14 KiB
Java
367 lines
14 KiB
Java
package TestingSystem.SAPFOR;
|
||
import Common.Constants;
|
||
import Common.Global;
|
||
import Common.Utils.Utils;
|
||
import GlobalData.Tasks.TaskState;
|
||
import ProjectData.Messages.Errors.MessageError;
|
||
import TestingSystem.SAPFOR.Json.SapforConfiguration_json;
|
||
import TestingSystem.SAPFOR.Json.SapforVersion_json;
|
||
import TestingSystem.SAPFOR.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.Date;
|
||
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 root;
|
||
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];
|
||
target = (SapforTask) args[2];
|
||
//--->>
|
||
parentTask = Paths.get(Global.Home, String.valueOf(sapforConfiguration_json.id), target.test_description).toFile();
|
||
root = new File(Global.Home, String.valueOf(sapforConfiguration_json.id));
|
||
task = null;
|
||
//--->>
|
||
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())
|
||
+ (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<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(
|
||
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("<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(); //нельзя!!! сначала надо определиться с версиями. И только потом, получать файлы.
|
||
//а так же, убрать 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.StartDate = new Date().getTime();
|
||
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;
|
||
}
|
||
target.ChangeDate = new Date().getTime();
|
||
}
|
||
}
|