package _VisualDVM.TestingSystem.DVM; import Common.Utils.Utils_; import _VisualDVM.Constants; import _VisualDVM.Global; import _VisualDVM.GlobalData.RemoteFile.RemoteFile; import _VisualDVM.GlobalData.Tasks.TaskState; import _VisualDVM.Passes.All.UnzipFolderPass; import _VisualDVM.TestingSystem.Common.TasksPackageState; import _VisualDVM.TestingSystem.DVM.DVMTasks.DVMCompilationTask; import _VisualDVM.TestingSystem.DVM.DVMTasks.DVMRunTask; import _VisualDVM.Utils; 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 { testingPackage.readJson(); LinkedHashMap tests = getTestsFromJson(); //синхронизировать их. for (int test_id : tests.keySet()) { 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); } } @Override protected boolean checkIfPaused() throws Exception { RemoteFile pausedFile = new RemoteFile(packageRemoteWorkspace, Constants.pause); return user.connection.Exists(pausedFile); } @Override protected void PackageWorkspaceCreation() throws Exception { if (!CheckModules()) { return; } //-- testingPackage.readJson(); //-- LinkedHashMap tests = getTestsFromJson(); //создать папку для пакета. user.connection.RMDIR(packageRemoteWorkspace.full_name); 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.checkFinishState(); UpdatePackageState(); //теперь удалить распакованную папку с результатами. для скачки нужен только архив. File unpacked_results = new File(packageLocalWorkspace.getAbsolutePath(), "results"); try { Utils_.forceDeleteWithCheck(unpacked_results); } catch (Exception ex) { ex.printStackTrace(); } } @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(); } //-- if (state_changed) switch (testingPackage.state) { case CompilationExecution: case RunningExecution: case Aborted: EmailPackage(); break; } //-- return progress_changed || state_changed; } @Override protected void DownloadResults() throws Exception { Utils_.CheckDirectory(packageLocalWorkspace); RemoteFile killedFile = new RemoteFile(packageRemoteWorkspace,"kill"); if (user.connection.Exists(killedFile)){ UpdatePackageState(TasksPackageState.Aborted); }else { 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); } UpdatePackageState(TasksPackageState.Analysis); } //--- if (testingPackage.eraseWorkspace!=0 && 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()) { RemoteFile killFile = new RemoteFile(packageRemoteWorkspace, "kill"); user.connection.writeToFile("fatality", killFile); } } @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"; } }