Files
VisualSapfor/src/_VisualDVM/TestingSystem/DVM/RemoteDVMTestingPlanner.java
2024-10-14 12:54:52 +03:00

278 lines
13 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 _VisualDVM.TestingSystem.DVM;
import Common.Utils.Utils_;
import _VisualDVM.Constants;
import _VisualDVM.Global;
import _VisualDVM.Utils;
import _VisualDVM.GlobalData.RemoteFile.RemoteFile;
import _VisualDVM.GlobalData.Tasks.TaskState;
import _VisualDVM.TestingSystem.Common.TasksPackageState;
import _VisualDVM.TestingSystem.DVM.DVMTasks.DVMCompilationTask;
import _VisualDVM.TestingSystem.DVM.DVMTasks.DVMRunTask;
import _VisualDVM.Passes.All.UnzipFolderPass;
import javafx.util.Pair;
import org.apache.commons.io.FileUtils;
import java.io.File;
import java.nio.file.Paths;
import java.util.*;
public class RemoteDVMTestingPlanner extends DVMTestingPlanner {
RemoteFile packageRemoteWorkspace = null;
public RemoteDVMTestingPlanner(String... args) {
super(args);
}
@Override
protected boolean Connect() {
if (user.connection == null) {
try {
user.connection = new UserConnection(machine, user);
Print("Соединение c " + machine.getURL() + " " + user.login + " успешно установлено.");
Print("Проверка инициализации..");
user.connection.CheckUserInitialization(testingPackage.sender_address);
} catch (Exception ex) {
Print(ex.toString());
user.connection = null;
Print("Не удалось установить соединение.");
}
}
return user.connection != null;
}
@Override
protected void Disconnect() {
if (user.connection != null) {
user.connection.Disconnect();
user.connection = null;
Print("Соединение c " + machine.getURL() + " " + user.login + " сброшено.");
}
}
//----
@Override
protected void TestsSynchronize() throws Exception {
System.out.println("--");
testingPackage.readJson();
System.out.println("+");
LinkedHashMap<Integer, File> tests = getTestsFromJson();
//синхронизировать их.
for (int test_id : tests.keySet()) {
System.out.println("test=" + test_id);
File test = tests.get(test_id);
RemoteFile test_dst = new RemoteFile(testingPackage.user_workspace + "/projects/" + test_id, true);
user.connection.MKDIR(test_dst);
user.connection.SynchronizeSubDirsR(test, test_dst);
}
System.out.println("++");
}
@Override
protected void PackageWorkspaceCreation() throws Exception {
System.out.println("package workspace creation");
if (!CheckModules()) {
return;
}
System.out.println("modules checked");
//--
testingPackage.readJson();
//--
LinkedHashMap<Integer, File> tests = getTestsFromJson();
//создать папку для пакета.
user.connection.RMDIR(packageRemoteWorkspace.full_name);
user.connection.sftpChannel.mkdir(packageRemoteWorkspace.full_name);
//положить туда запакованные тексты задач.
Vector<String> compilationLines = new Vector<>();
Vector<String> runLines = new Vector<>();
for (DVMCompilationTask compilationTask : testingPackage.package_json.compilationTasks) {
String makefileText = generateMakefile(tests.get(compilationTask.test_id), compilationTask.language, testingPackage.drv, compilationTask.flags);
compilationLines.addAll(compilationTask.pack(makefileText));
for (DVMRunTask runTask : compilationTask.runTasks)
runLines.addAll(runTask.pack(null));
}
RemoteFile compilationPackage = new RemoteFile(packageRemoteWorkspace, "compilationTasks");
RemoteFile runPackage = new RemoteFile(packageRemoteWorkspace, "runTasks");
user.connection.writeToFile(String.join("\n", compilationLines) + "\n", compilationPackage);
user.connection.writeToFile(String.join("\n", runLines) + "\n", runPackage);
// --
user.connection.MKDIR(new RemoteFile(packageRemoteWorkspace, "state"));
}
@Override
protected void AnalyseResults() throws Exception {
boolean hasErrors = false;
testingPackage.readJson();
Print("analysing results");
Vector<DVMRunTask> runTasks = new Vector<>();
for (DVMCompilationTask compilationTask : testingPackage.package_json.compilationTasks)
runTasks.addAll(compilationTask.runTasks);
//----
getTasksInfo(testingPackage.package_json.compilationTasks, "CompilationInfo.txt");
getTasksInfo(runTasks, "RunningInfo.txt");
//--
int ct_count = 0;
int rt_count = 0;
int good=0;
//--
for (DVMCompilationTask compilationTask : testingPackage.package_json.compilationTasks) {
compilationTask.dvm_package_id = testingPackage.id;
if (!compilationTask.state.equals(TaskState.Done))
hasErrors = true;
ct_count++;
File ct_workspace = Paths.get(packageLocalWorkspace.getAbsolutePath(), "results", String.valueOf(compilationTask.id)).toFile();
if (ct_workspace.exists()) {
for (DVMRunTask runTask : compilationTask.runTasks) {
runTask.dvm_package_id = testingPackage.id;
rt_count++;
runTask.compilation_state = compilationTask.state;
runTask.compilation_time = compilationTask.Time;
if (compilationTask.state == TaskState.DoneWithErrors) {
runTask.state = TaskState.Canceled;
} else {
File rt_workspace = Paths.get(packageLocalWorkspace.getAbsolutePath(), "results", String.valueOf(runTask.id)).toFile();
if (rt_workspace.exists() && runTask.state.equals(TaskState.Finished)) {
//анализ задачи на запуск.
File outFile = new File(rt_workspace, Constants.out_file);
File errFile = new File(rt_workspace.getAbsolutePath(), Constants.err_file);
//--
String output = FileUtils.readFileToString(outFile);
String errors = FileUtils.readFileToString(errFile);
//--
List<String> output_lines = Arrays.asList(output.split("\n"));
List<String> errors_lines = Arrays.asList(errors.split("\n"));
//---
if (Utils.isCrushed(output_lines, errors_lines)) {
runTask.state = TaskState.Crushed;
} else {
Pair<TaskState, Integer> results = new Pair<>(TaskState.Done, 100);
switch (runTask.test_type) {
case Correctness:
results = Utils.analyzeCorrectness(output_lines);
break;
case Performance:
results = Utils.analyzePerformance(output_lines);
break;
default:
break;
}
runTask.state = results.getKey();
runTask.progress = results.getValue();
runTask.CleanTime = Utils.parseCleanTime(output);
}
}
}
if (!runTask.state.equals(TaskState.Done))
hasErrors = true;
else good++;
}
}
}
testingPackage.progress = 100;
testingPackage.saveJson(); //запись обновленных результатов пакета в json!
Print("analysis done, ct_count=" + ct_count + " rt count=" + rt_count);
testingPackage.state = hasErrors ? TasksPackageState.DoneWithErrors : TasksPackageState.Done;
double percent = ( ((double)(good))/testingPackage.tasksCount)*100.0;
testingPackage.description = "Выполнено на "+((int)percent)+"%\n"+
"Всего задач: "+testingPackage.tasksCount+", из них с ошибками "+(testingPackage.tasksCount-good);
UpdatePackageState();
}
@Override
protected void PackageStart() throws Exception {
String plannerStartCommand = String.join(" ",
Utils_.DQuotes(getPlanner()),
Utils_.DQuotes(user.workspace),
Utils_.DQuotes(packageRemoteWorkspace.full_name),
Utils_.DQuotes(testingPackage.kernels),
Utils_.DQuotes(testingPackage.drv));
user.connection.startShellProcess(packageRemoteWorkspace, "planner_output",
"ulimit -s unlimited", plannerStartCommand);
//---
RemoteFile PID = new RemoteFile(packageRemoteWorkspace, "PID");
while (!user.connection.Exists(PID)) {
Print("PID not found");
Utils_.sleep(1000);
}
testingPackage.PID = user.connection.readFromFile(PID).replace("\n", "").replace("\r", "");
//---
System.out.println("PID=" + Utils_.Brackets(testingPackage.PID));
RemoteFile STARTED = new RemoteFile(packageRemoteWorkspace, "STARTED");
while (!user.connection.Exists(STARTED)) {
Print("waiting for package start...");
Utils_.sleep(1000);
}
}
@Override
protected boolean CheckNextState() throws Exception {
boolean progress_changed = false;
boolean state_changed = false;
RemoteFile progress = new RemoteFile(packageRemoteWorkspace, "progress");
if (user.connection.Exists(progress)) {
String s = user.connection.readFromFile(progress);
int current_progress = Integer.parseInt(s);
if (current_progress != testingPackage.progress) {
Print("progress changed: " + current_progress);
testingPackage.progress = current_progress;
progress_changed = true;
}
}
RemoteFile stateDir = new RemoteFile(packageRemoteWorkspace, "state");
//состояния пакета могут меняться только по возрастанию. ищем, появилось ли такое.
Vector<TasksPackageState> higherStates = testingPackage.state.getHigherStates();
Collections.reverse(higherStates); //берем в обратном порядке, чтобы быстрее найти высшее.
for (TasksPackageState state : higherStates) {
RemoteFile file = new RemoteFile(stateDir, state.toString());
if (user.connection.Exists(file)) {
Print("found new state: " + file.name);
testingPackage.state = state;
state_changed = true;
break;
}
}
//--
user.connection.iterations++;
if (user.connection.iterations == 100) {
Disconnect();
}
//--
return progress_changed || state_changed;
}
@Override
protected void DownloadResults() throws Exception {
Utils_.CheckDirectory(packageLocalWorkspace);
RemoteFile remote_results_archive = new RemoteFile(packageRemoteWorkspace, "results.zip");
File results_archive = new File(packageLocalWorkspace, "results.zip");
user.connection.performScript(packageRemoteWorkspace, "zip -r " + Utils_.DQuotes("results.zip") + " " + Utils_.DQuotes("results"));
//---
if (user.connection.Exists(remote_results_archive)) {
user.connection.getSingleFile(remote_results_archive.full_name, results_archive.getAbsolutePath());
UnzipFolderPass unzipFolderPass = new UnzipFolderPass();
unzipFolderPass.Do(results_archive.getAbsolutePath(), packageLocalWorkspace.getAbsolutePath(), false);
}
//---
if (Global.properties.eraseTestingWorkspaces && user.connection.Exists(packageRemoteWorkspace))
user.connection.RMDIR(packageRemoteWorkspace.full_name);
}
@Override
protected void MachineConnectionError() {
Finalize("Количество безуспешных попыток соединения с машиной " + machine.getURL() + " превысило 10");
}
@Override
protected void Kill() throws Exception {
if (!testingPackage.PID.isEmpty()) {
user.connection.Command("kill -9 " + testingPackage.PID);
}
}
@Override
protected void InitSessionCredentials() {
packageRemoteWorkspace = new RemoteFile(user.workspace + "/tests", String.valueOf(testingPackage.id), true);
packageLocalWorkspace = new File(Global.DVMPackagesDirectory, String.valueOf(testingPackage.id));
}
@Override
protected boolean CheckModules() throws Exception {
String log = user.connection.CheckModulesVersion();
if (!log.isEmpty()) {
testingPackage.description = log;
testingPackage.state = TasksPackageState.Aborted;
return false;
}
return true;
}
@Override
public String packageDescription() {
return "DVM";
}
}