package TestingSystem.DVM; import Common.Constants; import Common.Global; import Common.Utils.Utils; import GlobalData.RemoteFile.RemoteFile; import GlobalData.Tasks.TaskState; import TestingSystem.Common.TasksPackageState; import TestingSystem.DVM.DVMTasks.DVMCompilationTask; import TestingSystem.DVM.DVMTasks.DVMRunTask; import Visual_DVM_2021.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 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 tests = getTestsFromJson(); //создать папку для пакета. user.connection.sftpChannel.mkdir(packageRemoteWorkspace.full_name); //положить туда запакованные тексты задач. Vector compilationLines = new Vector<>(); Vector 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 { testingPackage.readJson(); Print("analysing results"); Vector 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; //-- for (DVMCompilationTask compilationTask : testingPackage.package_json.compilationTasks) { compilationTask.dvm_package_id = testingPackage.id; 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 output_lines = Arrays.asList(output.split("\n")); List errors_lines = Arrays.asList(errors.split("\n")); //--- if (Utils.isCrushed(output_lines, errors_lines)) { runTask.state = TaskState.Crushed; } else { Pair 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); } } } } } } testingPackage.progress = 100; testingPackage.saveJson(); //запись обновленных результатов пакета в json! Print("analysis done, ct_count=" + ct_count + " rt count=" + rt_count); } @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 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; } }