промежуточный. пилотный вариант планировщика в качестве отдельного процесса
This commit is contained in:
8
.idea/workspace.xml
generated
8
.idea/workspace.xml
generated
@@ -7,18 +7,14 @@
|
|||||||
</component>
|
</component>
|
||||||
<component name="ChangeListManager">
|
<component name="ChangeListManager">
|
||||||
<list default="true" id="e42177c3-2328-4b27-8a01-35779b2beb99" name="Default Changelist" comment="">
|
<list default="true" id="e42177c3-2328-4b27-8a01-35779b2beb99" name="Default Changelist" comment="">
|
||||||
<change afterPath="$PROJECT_DIR$/src/TestingSystem/DVM/MachineQueueSupervisor.java" afterDir="false" />
|
|
||||||
<change beforePath="$PROJECT_DIR$/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/workspace.xml" afterDir="false" />
|
<change beforePath="$PROJECT_DIR$/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/workspace.xml" afterDir="false" />
|
||||||
<change beforePath="$PROJECT_DIR$/properties" beforeDir="false" afterPath="$PROJECT_DIR$/properties" afterDir="false" />
|
<change beforePath="$PROJECT_DIR$/properties" beforeDir="false" afterPath="$PROJECT_DIR$/properties" afterDir="false" />
|
||||||
<change beforePath="$PROJECT_DIR$/src/Common/Current.java" beforeDir="false" afterPath="$PROJECT_DIR$/src/Common/Current.java" afterDir="false" />
|
|
||||||
<change beforePath="$PROJECT_DIR$/src/Common/Global.java" beforeDir="false" afterPath="$PROJECT_DIR$/src/Common/Global.java" afterDir="false" />
|
<change beforePath="$PROJECT_DIR$/src/Common/Global.java" beforeDir="false" afterPath="$PROJECT_DIR$/src/Common/Global.java" afterDir="false" />
|
||||||
<change beforePath="$PROJECT_DIR$/src/Common/UI/Menus_2023/MainMenuBar/MainMenuBar.java" beforeDir="false" afterPath="$PROJECT_DIR$/src/Common/UI/Menus_2023/MainMenuBar/MainMenuBar.java" afterDir="false" />
|
<change beforePath="$PROJECT_DIR$/src/Common/UI/Menus_2023/MainMenuBar/MainMenuBar.java" beforeDir="false" afterPath="$PROJECT_DIR$/src/Common/UI/Menus_2023/MainMenuBar/MainMenuBar.java" afterDir="false" />
|
||||||
<change beforePath="$PROJECT_DIR$/src/GlobalData/Tasks/Supervisor/Remote/ServerRunSupervisor.java" beforeDir="false" afterPath="$PROJECT_DIR$/src/GlobalData/Tasks/Supervisor/Remote/ServerRunSupervisor.java" afterDir="false" />
|
<change beforePath="$PROJECT_DIR$/src/Common/Utils/Utils.java" beforeDir="false" afterPath="$PROJECT_DIR$/src/Common/Utils/Utils.java" afterDir="false" />
|
||||||
<change beforePath="$PROJECT_DIR$/src/ProjectData/Messages/Message.java" beforeDir="false" afterPath="$PROJECT_DIR$/src/ProjectData/Messages/Message.java" afterDir="false" />
|
|
||||||
<change beforePath="$PROJECT_DIR$/src/Repository/Component/Visualiser.java" beforeDir="false" afterPath="$PROJECT_DIR$/src/Repository/Component/Visualiser.java" afterDir="false" />
|
|
||||||
<change beforePath="$PROJECT_DIR$/src/Repository/Server/ServerCode.java" beforeDir="false" afterPath="$PROJECT_DIR$/src/Repository/Server/ServerCode.java" afterDir="false" />
|
|
||||||
<change beforePath="$PROJECT_DIR$/src/TestingSystem/Common/TestingServer.java" beforeDir="false" afterPath="$PROJECT_DIR$/src/TestingSystem/Common/TestingServer.java" afterDir="false" />
|
<change beforePath="$PROJECT_DIR$/src/TestingSystem/Common/TestingServer.java" beforeDir="false" afterPath="$PROJECT_DIR$/src/TestingSystem/Common/TestingServer.java" afterDir="false" />
|
||||||
<change beforePath="$PROJECT_DIR$/src/TestingSystem/Common/TestsDatabase.java" beforeDir="false" afterPath="$PROJECT_DIR$/src/TestingSystem/Common/TestsDatabase.java" afterDir="false" />
|
<change beforePath="$PROJECT_DIR$/src/TestingSystem/Common/TestsDatabase.java" beforeDir="false" afterPath="$PROJECT_DIR$/src/TestingSystem/Common/TestsDatabase.java" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/src/TestingSystem/DVM/MachineQueueSupervisor.java" beforeDir="false" afterPath="$PROJECT_DIR$/src/TestingSystem/DVM/MachineQueueSupervisor.java" afterDir="false" />
|
||||||
<change beforePath="$PROJECT_DIR$/src/Visual_DVM_2021/Passes/All/TestPass.java" beforeDir="false" afterPath="$PROJECT_DIR$/src/Visual_DVM_2021/Passes/All/TestPass.java" afterDir="false" />
|
<change beforePath="$PROJECT_DIR$/src/Visual_DVM_2021/Passes/All/TestPass.java" beforeDir="false" afterPath="$PROJECT_DIR$/src/Visual_DVM_2021/Passes/All/TestPass.java" afterDir="false" />
|
||||||
</list>
|
</list>
|
||||||
<option name="SHOW_DIALOG" value="false" />
|
<option name="SHOW_DIALOG" value="false" />
|
||||||
|
|||||||
@@ -2,9 +2,9 @@
|
|||||||
"Mode": "Normal",
|
"Mode": "Normal",
|
||||||
"ServerAddress": "alex-freenas.ddns.net",
|
"ServerAddress": "alex-freenas.ddns.net",
|
||||||
"ServerUserName": "testuser",
|
"ServerUserName": "testuser",
|
||||||
"ServerUserSHHPort": 2000,
|
"ServerUserSHHPort": 23,
|
||||||
"ComponentsServerPort": 7995,
|
"ComponentsServerPort": 7995,
|
||||||
"TestingServerPort": 7998,
|
"TestingServerPort": 7996,
|
||||||
"SocketTimeout": 5000,
|
"SocketTimeout": 5000,
|
||||||
"OldServer": false,
|
"OldServer": false,
|
||||||
"SMTPHost": "smtp.mail.ru",
|
"SMTPHost": "smtp.mail.ru",
|
||||||
|
|||||||
@@ -405,10 +405,10 @@ public class Global {
|
|||||||
PackageMode();
|
PackageMode();
|
||||||
break;
|
break;
|
||||||
case MachineQueue:
|
case MachineQueue:
|
||||||
CreateLogAtHome();
|
|
||||||
MachineQueueSupervisor supervisor = new MachineQueueSupervisor(args);
|
MachineQueueSupervisor supervisor = new MachineQueueSupervisor(args);
|
||||||
supervisor.Start();
|
while (true){
|
||||||
break;
|
supervisor.Perform();
|
||||||
|
}
|
||||||
case Undefined:
|
case Undefined:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -55,7 +55,6 @@ public class MainMenuBar extends VisualiserMenuBar {
|
|||||||
//-
|
//-
|
||||||
setPreferredSize(new Dimension(0, 30));
|
setPreferredSize(new Dimension(0, 30));
|
||||||
//---
|
//---
|
||||||
/*
|
|
||||||
add(new MenuBarButton() {
|
add(new MenuBarButton() {
|
||||||
{
|
{
|
||||||
setIcon("/icons/Apply.png");
|
setIcon("/icons/Apply.png");
|
||||||
@@ -65,7 +64,6 @@ public class MainMenuBar extends VisualiserMenuBar {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
*/
|
|
||||||
ShowProject(false);
|
ShowProject(false);
|
||||||
}
|
}
|
||||||
public void ShowUpdatesIcon() {
|
public void ShowUpdatesIcon() {
|
||||||
|
|||||||
@@ -22,10 +22,7 @@ import java.awt.datatransfer.DataFlavor;
|
|||||||
import java.awt.datatransfer.StringSelection;
|
import java.awt.datatransfer.StringSelection;
|
||||||
import java.io.*;
|
import java.io.*;
|
||||||
import java.math.BigInteger;
|
import java.math.BigInteger;
|
||||||
import java.net.InetAddress;
|
import java.net.*;
|
||||||
import java.net.InetSocketAddress;
|
|
||||||
import java.net.Socket;
|
|
||||||
import java.net.URL;
|
|
||||||
import java.nio.charset.Charset;
|
import java.nio.charset.Charset;
|
||||||
import java.nio.file.*;
|
import java.nio.file.*;
|
||||||
import java.security.MessageDigest;
|
import java.security.MessageDigest;
|
||||||
|
|||||||
@@ -161,6 +161,7 @@ public abstract class TestingPlanner<P extends TestingPackage> {
|
|||||||
}
|
}
|
||||||
} catch (Exception ex) {
|
} catch (Exception ex) {
|
||||||
Print("Ошибка сеанса. Соединение будет разорвано.");
|
Print("Ошибка сеанса. Соединение будет разорвано.");
|
||||||
|
ex.printStackTrace();
|
||||||
Print(ex.getMessage());
|
Print(ex.getMessage());
|
||||||
//
|
//
|
||||||
testingPackage.connectionErrosCount++;
|
testingPackage.connectionErrosCount++;
|
||||||
|
|||||||
@@ -309,11 +309,8 @@ public class TestingServer extends RepositoryServer<TestsDatabase> {
|
|||||||
}
|
}
|
||||||
private void GetFirstActiveDVMPackagesByMachines() {
|
private void GetFirstActiveDVMPackagesByMachines() {
|
||||||
response = new ServerExchangeUnit_2021(ServerCode.OK);
|
response = new ServerExchangeUnit_2021(ServerCode.OK);
|
||||||
response.object = db.getFirstActiveDVMPackagesCopies();
|
response.object = new Vector<>();
|
||||||
}
|
// db.getFirstActiveDVMPackagesCopies(); //ЗАГЛУШКА. ЗА ПАКЕТЫ ДВМ ОТВЕЧАЕТ ОТДЕЛЬНЫЙ ПРОЦЕСС НА КАЖДУЮ МАШИНУ
|
||||||
private void GetFirstActiveDVMPackageForMachineURL() {
|
|
||||||
response = new ServerExchangeUnit_2021(ServerCode.OK);
|
|
||||||
response.object = db.getFirstActiveDVMPackagesCopiesForMachineURL(request.arg);
|
|
||||||
}
|
}
|
||||||
private void GetFirstActiveSapforPackages() throws Exception {
|
private void GetFirstActiveSapforPackages() throws Exception {
|
||||||
response = new ServerExchangeUnit_2021(ServerCode.OK);
|
response = new ServerExchangeUnit_2021(ServerCode.OK);
|
||||||
@@ -573,5 +570,10 @@ public class TestingServer extends RepositoryServer<TestsDatabase> {
|
|||||||
response = new ServerExchangeUnit_2021(ServerCode.OK);
|
response = new ServerExchangeUnit_2021(ServerCode.OK);
|
||||||
response.object = jsons;
|
response.object = jsons;
|
||||||
}
|
}
|
||||||
|
//--
|
||||||
|
private void GetFirstActiveDVMPackageForMachineURL() {
|
||||||
|
response = new ServerExchangeUnit_2021(ServerCode.OK);
|
||||||
|
response.object = db.getFirstActiveDVMPackageCopyForMachineURL(request.arg);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -27,7 +27,6 @@ import javafx.util.Pair;
|
|||||||
import org.apache.commons.io.FileUtils;
|
import org.apache.commons.io.FileUtils;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.Serializable;
|
|
||||||
import java.nio.file.Paths;
|
import java.nio.file.Paths;
|
||||||
import java.util.Comparator;
|
import java.util.Comparator;
|
||||||
import java.util.LinkedHashMap;
|
import java.util.LinkedHashMap;
|
||||||
@@ -210,13 +209,13 @@ public class TestsDatabase extends SQLiteDatabase {
|
|||||||
Group group = groupData.getKey();
|
Group group = groupData.getKey();
|
||||||
Vector<File> files = groupData.getValue();
|
Vector<File> files = groupData.getValue();
|
||||||
//--
|
//--
|
||||||
Group oldGroup = groups.getGroupByDescription(group.language,group.description);
|
Group oldGroup = groups.getGroupByDescription(group.language, group.description);
|
||||||
if (oldGroup == null) {
|
if (oldGroup == null) {
|
||||||
System.out.println("group "+Utils.Brackets(group.description)+" not found. create.");
|
System.out.println("group " + Utils.Brackets(group.description) + " not found. create.");
|
||||||
Insert(group);
|
Insert(group);
|
||||||
for (File file : files) {
|
for (File file : files) {
|
||||||
String testDescription = Utils.getNameWithoutExtension(file.getName()) + "_" + group.language.getDVMCompile();
|
String testDescription = Utils.getNameWithoutExtension(file.getName()) + "_" + group.language.getDVMCompile();
|
||||||
System.out.println("test "+Utils.Brackets(testDescription) + " create"); //добавить тест.
|
System.out.println("test " + Utils.Brackets(testDescription) + " create"); //добавить тест.
|
||||||
CreateTestFromSingleFile(account, sapfor, group, file, testDescription);
|
CreateTestFromSingleFile(account, sapfor, group, file, testDescription);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -224,7 +223,7 @@ public class TestsDatabase extends SQLiteDatabase {
|
|||||||
String testDescription = Utils.getNameWithoutExtension(file.getName()) + "_" + group.language.getDVMCompile();
|
String testDescription = Utils.getNameWithoutExtension(file.getName()) + "_" + group.language.getDVMCompile();
|
||||||
Test oldTest = tests.getTestByDescription(oldGroup.id, testDescription);
|
Test oldTest = tests.getTestByDescription(oldGroup.id, testDescription);
|
||||||
if (oldTest == null) {
|
if (oldTest == null) {
|
||||||
System.out.println("test "+Utils.Brackets(testDescription) + " not found. create"); //добавить тест.
|
System.out.println("test " + Utils.Brackets(testDescription) + " not found. create"); //добавить тест.
|
||||||
CreateTestFromSingleFile(account, sapfor, oldGroup, file, testDescription);
|
CreateTestFromSingleFile(account, sapfor, oldGroup, file, testDescription);
|
||||||
} else {
|
} else {
|
||||||
System.out.println(Utils.Brackets(testDescription) + " found. rewrite"); //добавить тест.
|
System.out.println(Utils.Brackets(testDescription) + " found. rewrite"); //добавить тест.
|
||||||
@@ -233,7 +232,43 @@ public class TestsDatabase extends SQLiteDatabase {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
public DVMPackage getFirstActiveDVMPackagesCopiesForMachineURL(String arg) {
|
public Vector<DVMPackage> getFirstActiveDVMPackageCopyForMachineURL(String arg) {
|
||||||
return null;
|
Vector<DVMPackage> res = new Vector<>();
|
||||||
|
Vector<DVMPackage> machinePackages = new Vector<>();
|
||||||
|
//--
|
||||||
|
//1. Получить список активных пакетов для машины.
|
||||||
|
for (DVMPackage dvmPackage : dvmPackages.Data.values()) {
|
||||||
|
switch (dvmPackage.state) {
|
||||||
|
case Done:
|
||||||
|
case Aborted:
|
||||||
|
case Draft:
|
||||||
|
case ConnectionError:
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
if (dvmPackage.getMachine().getURL().equals(arg))
|
||||||
|
machinePackages.add(dvmPackage);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!machinePackages.isEmpty()) {
|
||||||
|
machinePackages.sort(new Comparator<DVMPackage>() {
|
||||||
|
@Override
|
||||||
|
public int compare(DVMPackage o1, DVMPackage o2) {
|
||||||
|
return Integer.compare(o1.state.ordinal(), o2.state.ordinal());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
//-
|
||||||
|
DVMPackage activePackage = machinePackages.lastElement();
|
||||||
|
if (activePackage.state.equals(TasksPackageState.Queued)) {
|
||||||
|
activePackage.state = TasksPackageState.TestsSynchronize;
|
||||||
|
try {
|
||||||
|
Update(activePackage);
|
||||||
|
} catch (Exception ex) {
|
||||||
|
ex.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
res.add(activePackage);
|
||||||
|
}
|
||||||
|
return res;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,27 +1,473 @@
|
|||||||
package TestingSystem.DVM;
|
package TestingSystem.DVM;
|
||||||
|
import Common.Constants;
|
||||||
|
import Common.Current;
|
||||||
import Common.Global;
|
import Common.Global;
|
||||||
import Common.Utils.Utils;
|
import Common.Utils.Utils;
|
||||||
import GlobalData.Machine.Machine;
|
import GlobalData.Machine.Machine;
|
||||||
import GlobalData.Machine.MachineType;
|
import GlobalData.Machine.MachineType;
|
||||||
|
import GlobalData.RemoteFile.RemoteFile;
|
||||||
|
import GlobalData.Tasks.TaskState;
|
||||||
import GlobalData.User.User;
|
import GlobalData.User.User;
|
||||||
|
import ProjectData.Files.ProjectFile;
|
||||||
|
import ProjectData.LanguageName;
|
||||||
import Repository.Server.ServerCode;
|
import Repository.Server.ServerCode;
|
||||||
import Repository.Server.ServerExchangeUnit_2021;
|
import TestingSystem.Common.TasksPackageState;
|
||||||
|
import TestingSystem.Common.TestingPlanner;
|
||||||
import TestingSystem.DVM.DVMPackage.DVMPackage;
|
import TestingSystem.DVM.DVMPackage.DVMPackage;
|
||||||
import Visual_DVM_2021.Passes.PassException;
|
import TestingSystem.DVM.DVMTasks.DVMCompilationTask;
|
||||||
import Visual_DVM_2021.Passes.Server.TestingSystemPass;
|
import TestingSystem.DVM.DVMTasks.DVMRunTask;
|
||||||
|
import TestingSystem.DVM.DVMTasks.DVMTask;
|
||||||
|
import Visual_DVM_2021.Passes.All.UnzipFolderPass;
|
||||||
|
import Visual_DVM_2021.UI.Interface.Loggable;
|
||||||
|
import javafx.util.Pair;
|
||||||
|
import org.apache.commons.io.FileUtils;
|
||||||
|
|
||||||
import java.io.Serializable;
|
import java.io.File;
|
||||||
import java.util.Vector;
|
import java.io.FileFilter;
|
||||||
public class MachineQueueSupervisor {
|
import java.net.InetAddress;
|
||||||
//--
|
import java.nio.charset.Charset;
|
||||||
|
import java.nio.file.Paths;
|
||||||
|
import java.util.*;
|
||||||
|
public class MachineQueueSupervisor extends TestingPlanner<DVMPackage> {
|
||||||
Machine machine = null;
|
Machine machine = null;
|
||||||
User user = null;
|
User user = null;
|
||||||
|
boolean local;
|
||||||
|
RemoteFile packageRemoteWorkspace = null;
|
||||||
|
File packageLocalWorkspace = null;
|
||||||
|
//----
|
||||||
|
public MachineQueueSupervisor(String... args) {
|
||||||
|
Global.isWindows = System.getProperty("os.name").startsWith("Windows");
|
||||||
|
//---
|
||||||
|
String machineAddress = args[0];
|
||||||
|
int machinePort = Integer.parseInt(args[1]);
|
||||||
|
String userName = args[2];
|
||||||
|
String userPassword = args[3];
|
||||||
|
String userWorkspace = args[4];
|
||||||
|
String testingSystemRoot = args[5];
|
||||||
|
String supervisorHome = Global.Home; //при инициализации это текущая папка.
|
||||||
|
//---
|
||||||
|
Global.Log = new Loggable() {
|
||||||
|
@Override
|
||||||
|
public String getLogHomePath() {
|
||||||
|
return supervisorHome;
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public String getLogName() {
|
||||||
|
return Current.mode.toString();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
Global.Log.ClearLog();
|
||||||
|
//--
|
||||||
|
Global.Home = testingSystemRoot;
|
||||||
|
Global.CheckTestingSystemDirectories();
|
||||||
|
System.out.println(Global.TestsDirectory.getAbsolutePath());
|
||||||
|
//---
|
||||||
|
machine = new Machine(machineAddress, machineAddress, machinePort, MachineType.Server);
|
||||||
|
user = new User(userName, userPassword, userWorkspace);
|
||||||
|
CheckLocal();
|
||||||
|
//---
|
||||||
|
Print("machineAddress=" + Utils.Brackets(machineAddress));
|
||||||
|
Print("machinePort=" + Utils.Brackets(String.valueOf(machinePort)));
|
||||||
|
Print("userName=" + Utils.Brackets(userName));
|
||||||
|
Print("userPassword=" + Utils.Brackets(userPassword));
|
||||||
|
Print("userWorkspace=" + Utils.Brackets(userWorkspace));
|
||||||
|
Print("root=" + Utils.Brackets(Global.Home));
|
||||||
|
Print("local=" + local);
|
||||||
|
Print("=====");
|
||||||
|
//----
|
||||||
|
}
|
||||||
|
void CheckLocal() {
|
||||||
|
local = false;
|
||||||
|
try {
|
||||||
|
InetAddress address = InetAddress.getByName(machine.address);
|
||||||
|
InetAddress localAddress = InetAddress.getByName("alex-freenas.ddns.net");
|
||||||
|
Print("machine ip=" + Utils.Brackets(address.getHostAddress()));
|
||||||
|
Print("server ip=" + Utils.Brackets(localAddress.getHostAddress()));
|
||||||
|
local = localAddress.getHostAddress().equals(address.getHostAddress());
|
||||||
|
//todo в этом случае отдельный режим без ssh
|
||||||
|
} catch (Exception ex) {
|
||||||
|
Global.Log.PrintException(ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public String getPlanner() {
|
||||||
|
return String.join("/", user.workspace, "modules", "planner");
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
protected boolean Connect() {
|
||||||
|
if (user.connection == null) {
|
||||||
|
try {
|
||||||
|
user.connection = new UserConnection(machine, user);
|
||||||
|
Print("Соединение c " + machine.getURL() + " " + user.login + " успешно установлено.");
|
||||||
|
} 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 + " сброшено.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//--
|
||||||
|
//Получить ид тестов и их папки на сервере.
|
||||||
|
LinkedHashMap<Integer, File> getTestsFromJson() {
|
||||||
|
LinkedHashMap<Integer, File> res = new LinkedHashMap<>();
|
||||||
|
for (DVMCompilationTask task : testingPackage.package_json.compilationTasks) {
|
||||||
|
if (!res.containsKey(task.test_id)) {
|
||||||
|
res.put(task.test_id, Paths.get(Global.TestsDirectory.getAbsolutePath(), String.valueOf(task.test_id)).toFile());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
static LinkedHashMap<LanguageName, Vector<ProjectFile>> getTestPrograms(File test) {
|
||||||
|
LinkedHashMap<LanguageName, Vector<ProjectFile>> res = new LinkedHashMap<>();
|
||||||
|
//--
|
||||||
|
res.put(LanguageName.fortran, new Vector<>());
|
||||||
|
res.put(LanguageName.c, new Vector<>());
|
||||||
|
res.put(LanguageName.cpp, new Vector<>());
|
||||||
|
//--
|
||||||
|
File[] files = test.listFiles(new FileFilter() {
|
||||||
|
@Override
|
||||||
|
public boolean accept(File pathname) {
|
||||||
|
return pathname.isFile();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
if (files != null) {
|
||||||
|
for (File file : files) {
|
||||||
|
ProjectFile projectFile = new ProjectFile(new File(file.getName()));
|
||||||
|
if (projectFile.isNotExcludedProgram()) res.get(projectFile.languageName).add(projectFile);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
static void generateForLanguage(String dvm_drv, LanguageName language, Vector<ProjectFile> language_programs, Vector<String> titles, Vector<String> objects, Vector<String> bodies, String flags) {
|
||||||
|
if (!language_programs.isEmpty()) {
|
||||||
|
String LANG_ = language.toString().toUpperCase() + "_";
|
||||||
|
Vector<String> module_objects = new Vector<>();
|
||||||
|
String module_body = "";
|
||||||
|
int i = 1;
|
||||||
|
for (ProjectFile program : language_programs) {
|
||||||
|
//--
|
||||||
|
String object = Utils.DQuotes(language + "_" + i + ".o");
|
||||||
|
module_objects.add(object);
|
||||||
|
module_body += object + ":\n" + "\t" + String.join(" ", Utils.MFVar(LANG_ + "COMMAND"), Utils.MFVar(LANG_ + "FLAGS"), program.getStyleOptions(), "-c", program.getQSourceName(), "-o", object + "\n\n");
|
||||||
|
++i;
|
||||||
|
}
|
||||||
|
titles.add(String.join("\n", LANG_ + "COMMAND=" + Utils.DQuotes(dvm_drv) + " " + language.getDVMCompile(), LANG_ + "FLAGS=" + flags, LANG_ + "OBJECTS=" + String.join(" ", module_objects), ""));
|
||||||
|
objects.add(Utils.MFVar(LANG_ + "OBJECTS"));
|
||||||
|
bodies.add(module_body);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
static String generateMakefile(File test, LanguageName test_language, String dvm_drv, String flags) {
|
||||||
|
//----->>
|
||||||
|
LinkedHashMap<LanguageName, Vector<ProjectFile>> programs = getTestPrograms(test);
|
||||||
|
Vector<String> titles = new Vector<>();
|
||||||
|
Vector<String> objects = new Vector<>();
|
||||||
|
Vector<String> bodies = new Vector<>();
|
||||||
|
String binary = Utils.DQuotes("0");
|
||||||
|
//----->>
|
||||||
|
for (LanguageName languageName : programs.keySet()) {
|
||||||
|
generateForLanguage(dvm_drv, languageName, programs.get(languageName), titles, objects, bodies, flags);
|
||||||
|
}
|
||||||
|
//----->>
|
||||||
|
return String.join("\n", "LINK_COMMAND=" + Utils.DQuotes(dvm_drv) + " " + test_language.getDVMLink(), "LINK_FLAGS=" + flags + "\n", String.join("\n", titles), "all: " + binary, binary + " : " + String.join(" ", objects), "\t" + Utils.MFVar("LINK_COMMAND") + " " + Utils.MFVar("LINK_FLAGS") + " " + String.join(" ", objects) + " -o " + binary, String.join(" ", bodies));
|
||||||
|
}
|
||||||
|
public void getTasksInfo(List<? extends DVMTask> tasks, String file_name) throws Exception {
|
||||||
|
LinkedHashMap<Integer, DVMTask> sorted_tasks = new LinkedHashMap<>();
|
||||||
|
for (DVMTask task : tasks)
|
||||||
|
sorted_tasks.put(task.id, task);
|
||||||
|
//--
|
||||||
|
File info_file = Paths.get(packageLocalWorkspace.getAbsolutePath(), "results", file_name).toFile();
|
||||||
|
List<String> lines = FileUtils.readLines(info_file, Charset.defaultCharset());
|
||||||
|
for (String packed : lines) {
|
||||||
|
if (!packed.isEmpty()) {
|
||||||
|
String[] data = packed.split(" ");
|
||||||
|
int id = Integer.parseInt(data[0]);
|
||||||
|
TaskState state = TaskState.valueOf(data[1]);
|
||||||
|
double time = Double.parseDouble(data[2]);
|
||||||
|
//--
|
||||||
|
DVMTask task = sorted_tasks.get(id);
|
||||||
|
task.state = state;
|
||||||
|
task.Time = state.equals(TaskState.AbortedByTimeout) ? (task.maxtime + 1) : time;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
protected boolean CheckModules() throws Exception {
|
||||||
|
RemoteFile modulesDirectory = new RemoteFile(user.workspace, "modules");
|
||||||
|
RemoteFile version = new RemoteFile(modulesDirectory, "version.h");
|
||||||
|
int current_version = Constants.Nan;
|
||||||
|
int actual_version = Constants.planner_version;
|
||||||
|
if (user.connection.Exists(version)) {
|
||||||
|
try {
|
||||||
|
current_version = Integer.parseInt(user.connection.readFromFile(version));
|
||||||
|
} catch (Exception ex) {
|
||||||
|
ex.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (current_version < actual_version) {
|
||||||
|
Print("Закачка кода модулей...");
|
||||||
|
for (String resource_name : Constants.resourses_names) {
|
||||||
|
Print(resource_name);
|
||||||
|
user.connection.putResource(modulesDirectory, resource_name);
|
||||||
|
}
|
||||||
|
//--
|
||||||
|
Print("Сборка модулей...");
|
||||||
|
String modules_log = user.connection.compileModules(modulesDirectory);
|
||||||
|
if (!modules_log.isEmpty()) {
|
||||||
|
testingPackage.description = modules_log;
|
||||||
|
testingPackage.state = TasksPackageState.Aborted;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
//----
|
||||||
|
@Override
|
||||||
|
protected ServerCode getActivePackagesCode() {
|
||||||
|
return ServerCode.GetFirstActiveDVMPackageForMachineURL;
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
protected ServerCode getCheckIfNeedsKillCode() {
|
||||||
|
return ServerCode.DVMPackageNeedsKill;
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
protected TasksPackageState getStateAfterStart() {
|
||||||
|
return TasksPackageState.CompilationWorkspacesCreation;
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
protected void TestsSynchronize() throws Exception {
|
||||||
|
testingPackage.readJson();
|
||||||
|
LinkedHashMap<Integer, File> tests = getTestsFromJson();
|
||||||
|
//синхронизировать их.
|
||||||
|
for (int test_id : tests.keySet()) {
|
||||||
|
// Print("testId="+test_id);
|
||||||
|
File test = tests.get(test_id);
|
||||||
|
RemoteFile test_dst = new RemoteFile(testingPackage.user_workspace + "/projects/" + test_id, true);
|
||||||
|
// Print("src="+test.getAbsolutePath());
|
||||||
|
// Print("dst="+test_dst.full_name);
|
||||||
|
user.connection.MKDIR(test_dst);
|
||||||
|
user.connection.SynchronizeSubDirsR(test, test_dst);
|
||||||
|
// Print("done");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
protected void PackageWorkspaceCreation() throws Exception {
|
||||||
|
if (!CheckModules()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
//--
|
||||||
|
testingPackage.readJson();
|
||||||
|
//--
|
||||||
|
LinkedHashMap<Integer, File> tests = getTestsFromJson();
|
||||||
|
//создать папку для пакета.
|
||||||
|
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 {
|
||||||
|
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;
|
||||||
|
//--
|
||||||
|
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<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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
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));
|
||||||
|
testingPackage.PID = user.connection.startShellProcess(packageRemoteWorkspace, "PID",
|
||||||
|
"ulimit -s unlimited", plannerStartCommand);
|
||||||
|
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 Kill() throws Exception {
|
||||||
|
if (!testingPackage.PID.isEmpty()) {
|
||||||
|
user.connection.Command("kill -9 " + testingPackage.PID);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public void Perform() {
|
||||||
|
try {
|
||||||
|
testingPackage = null;
|
||||||
|
Vector<DVMPackage> activePackages = (Vector<DVMPackage>) ServerCommand(getActivePackagesCode(), machine.getURL(), null);
|
||||||
|
// System.out.println(this.getClass().getSimpleName()+": found "+activePackages.size()+" active packages");
|
||||||
|
for (DVMPackage activePackage : activePackages)
|
||||||
|
PerformPackage(activePackage);
|
||||||
|
} catch (Exception ex) {
|
||||||
|
ex.printStackTrace();
|
||||||
|
} finally {
|
||||||
|
Utils.sleep(getSleepMillis());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
protected void InitSessionCredentials() {
|
||||||
|
packageRemoteWorkspace = new RemoteFile(user.workspace + "/tests", String.valueOf(testingPackage.id), true);
|
||||||
|
packageLocalWorkspace = new File(Global.DVMPackagesDirectory, String.valueOf(testingPackage.id));
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
|
||||||
//--
|
//--
|
||||||
DVMPackage testingPackage = null; //текущий пакет.
|
DVMPackage testingPackage = null; //текущий пакет.
|
||||||
|
RemoteFile packageRemoteWorkspace = null;
|
||||||
|
File packageLocalWorkspace = null;
|
||||||
//--
|
//--
|
||||||
protected int getSleepMillis() {
|
protected int getSleepMillis() {
|
||||||
return 2000;
|
return 5000;
|
||||||
}
|
}
|
||||||
|
//--
|
||||||
|
protected boolean isPrintOn() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
protected void Print(String message) {
|
||||||
|
try {
|
||||||
|
if (isPrintOn()) {
|
||||||
|
System.out.println(message);
|
||||||
|
Global.Log.Print(message);
|
||||||
|
}
|
||||||
|
} catch (Exception ex) {
|
||||||
|
ex.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//--
|
||||||
protected Object ServerCommand(ServerCode code_in, String arg, Serializable object_in) throws Exception {
|
protected Object ServerCommand(ServerCode code_in, String arg, Serializable object_in) throws Exception {
|
||||||
TestingSystemPass<Object> pass = new TestingSystemPass<Object>() {
|
TestingSystemPass<Object> pass = new TestingSystemPass<Object>() {
|
||||||
@Override
|
@Override
|
||||||
@@ -44,28 +490,447 @@ public class MachineQueueSupervisor {
|
|||||||
return ServerCommand(code_in, "", null);
|
return ServerCommand(code_in, "", null);
|
||||||
}
|
}
|
||||||
//--
|
//--
|
||||||
public MachineQueueSupervisor(String... args) {
|
void UpdatePackageState(TasksPackageState state_in) throws Exception {
|
||||||
Global.isWindows = System.getProperty("os.name").startsWith("Windows");
|
testingPackage.state = state_in;
|
||||||
//---
|
testingPackage.ChangeDate = new Date().getTime();
|
||||||
String machineAddress = args[0];
|
ServerCommand(ServerCode.EditObject, testingPackage);
|
||||||
int machinePort = Integer.parseInt(args[1]);
|
switch (testingPackage.state) {
|
||||||
String userName = args[2];
|
case Done:
|
||||||
String userPassword = args[3];
|
case Aborted:
|
||||||
String userWorkspace = args[4];
|
case CompilationExecution:
|
||||||
//---
|
case RunningExecution:
|
||||||
machine = new Machine(machineAddress, machineAddress, machinePort, MachineType.Server);
|
EmailPackage();
|
||||||
user = new User(userName, userPassword, userWorkspace);
|
break;
|
||||||
//---
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
void UpdatePackage() throws Exception {
|
||||||
|
testingPackage.ChangeDate = new Date().getTime();
|
||||||
|
ServerCommand(ServerCode.EditObject, testingPackage);
|
||||||
|
}
|
||||||
|
void EmailPackage() throws Exception {
|
||||||
|
if (testingPackage.needsEmail == 1) {
|
||||||
|
EmailMessage message = new EmailMessage();
|
||||||
|
message.subject = "Состояние пакета задач " + Utils.Brackets(testingPackage) + " изменилось на " + Utils.Brackets(testingPackage.state.getDescription());
|
||||||
|
message.text = testingPackage.description;
|
||||||
|
message.targets.add(testingPackage.sender_address);
|
||||||
|
ServerCommand(ServerCode.Email, message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//--
|
||||||
|
boolean Connect() {
|
||||||
|
if (user.connection == null) {
|
||||||
|
try {
|
||||||
|
user.connection = new UserConnection(machine, user);
|
||||||
|
Print("Соединение c " + machine.getURL() + " " + user.login + " успешно установлено.");
|
||||||
|
} catch (Exception ex) {
|
||||||
|
Print(ex.toString());
|
||||||
|
user.connection = null;
|
||||||
|
Print("Не удалось установить соединение.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return user.connection != null;
|
||||||
|
}
|
||||||
|
void Disconnect() {
|
||||||
|
if (user.connection != null) {
|
||||||
|
user.connection.Disconnect();
|
||||||
|
user.connection = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
boolean CheckModules() throws Exception {
|
||||||
|
RemoteFile modulesDirectory = new RemoteFile(user.workspace, "modules");
|
||||||
|
RemoteFile version = new RemoteFile(modulesDirectory, "version.h");
|
||||||
|
int current_version = Constants.Nan;
|
||||||
|
int actual_version = Constants.planner_version;
|
||||||
|
if (user.connection.Exists(version)) {
|
||||||
|
try {
|
||||||
|
current_version = Integer.parseInt(user.connection.readFromFile(version));
|
||||||
|
} catch (Exception ex) {
|
||||||
|
ex.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (current_version < actual_version) {
|
||||||
|
Print("Закачка кода модулей...");
|
||||||
|
for (String resource_name : Constants.resourses_names) {
|
||||||
|
Print(resource_name);
|
||||||
|
user.connection.putResource(modulesDirectory, resource_name);
|
||||||
|
}
|
||||||
|
//--
|
||||||
|
Print("Сборка модулей...");
|
||||||
|
String modules_log = user.connection.compileModules(modulesDirectory);
|
||||||
|
if (!modules_log.isEmpty()) {
|
||||||
|
testingPackage.description = modules_log;
|
||||||
|
testingPackage.state = TasksPackageState.Aborted;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
String getPlanner() {
|
||||||
|
return String.join("/", user.workspace, "modules", "planner");
|
||||||
|
}
|
||||||
|
//--
|
||||||
|
//проверка, не является ли заданная машина сервером тестирования. в этом случае, при соединении не использовать ssh.
|
||||||
|
void CheckLocal() {
|
||||||
|
local = false;
|
||||||
|
try {
|
||||||
|
InetAddress address = InetAddress.getByName(machine.address);
|
||||||
|
InetAddress localAddress = InetAddress.getByName("alex-freenas.ddns.net");
|
||||||
|
Print("machine ip=" + Utils.Brackets(address.getHostAddress()));
|
||||||
|
Print("server ip=" + Utils.Brackets(localAddress.getHostAddress()));
|
||||||
|
local = localAddress.getHostAddress().equals(address.getHostAddress());
|
||||||
|
//todo в этом случае отдельный режим без ssh
|
||||||
|
} catch (Exception ex) {
|
||||||
|
Global.Log.PrintException(ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//--
|
||||||
|
|
||||||
public void Start() {
|
public void Start() {
|
||||||
|
while (true) {
|
||||||
try {
|
try {
|
||||||
testingPackage = null;
|
testingPackage = null;
|
||||||
testingPackage = (DVMPackage) ServerCommand(ServerCode.GetFirstActiveDVMPackageForMachineURL, machine.getURL(), null);
|
testingPackage = (DVMPackage) ServerCommand(ServerCode.GetFirstActiveDVMPackageForMachineURL, machine.getURL(), null);
|
||||||
|
if (testingPackage != null) {
|
||||||
|
//---
|
||||||
|
Print(testingPackage.id + ":" + testingPackage.state.getDescription());
|
||||||
|
packageRemoteWorkspace = new RemoteFile(user.workspace + "/tests", String.valueOf(testingPackage.id), true);
|
||||||
|
packageLocalWorkspace = new File(Global.DVMPackagesDirectory, String.valueOf(testingPackage.id));
|
||||||
|
PerformPackage();
|
||||||
|
testingPackage.destructor();
|
||||||
|
testingPackage = null;
|
||||||
|
System.gc();
|
||||||
|
} else
|
||||||
|
Print("Не найдено активных пакетов для машины " + machine.getURL());
|
||||||
} catch (Exception ex) {
|
} catch (Exception ex) {
|
||||||
ex.printStackTrace();
|
ex.printStackTrace();
|
||||||
} finally {
|
} finally {
|
||||||
|
Print("sleep");
|
||||||
Utils.sleep(getSleepMillis());
|
Utils.sleep(getSleepMillis());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
//-------------------------------------------------------------------------------
|
||||||
|
void TestsSynchronize() throws Exception {
|
||||||
|
testingPackage.readJson();
|
||||||
|
LinkedHashMap<Integer, File> 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void PackageWorkspaceCreation() throws Exception {
|
||||||
|
if (!CheckModules()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
//--
|
||||||
|
testingPackage.readJson();
|
||||||
|
//--
|
||||||
|
LinkedHashMap<Integer, File> tests = getTestsFromJson();
|
||||||
|
//создать папку для пакета.
|
||||||
|
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"));
|
||||||
|
}
|
||||||
|
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));
|
||||||
|
|
||||||
|
testingPackage.PID = user.connection.startShellProcess(packageRemoteWorkspace,"PID",
|
||||||
|
"ulimit -s unlimited", plannerStartCommand);
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
///------------------------------------------
|
||||||
|
//жизненный цикл планировщика
|
||||||
|
void Session() throws Exception {
|
||||||
|
switch (testingPackage.state) {
|
||||||
|
case TestsSynchronize:
|
||||||
|
TestsSynchronize();
|
||||||
|
UpdatePackageState(TasksPackageState.PackageWorkspaceCreation);
|
||||||
|
break;
|
||||||
|
case PackageWorkspaceCreation:
|
||||||
|
PackageWorkspaceCreation();
|
||||||
|
UpdatePackageState(TasksPackageState.PackageStart);
|
||||||
|
break;
|
||||||
|
case PackageStart:
|
||||||
|
PackageStart();
|
||||||
|
testingPackage.StartDate = new Date().getTime();
|
||||||
|
UpdatePackageState(TasksPackageState.CompilationWorkspacesCreation);
|
||||||
|
break;
|
||||||
|
case RunningEnd:
|
||||||
|
DownloadResults();
|
||||||
|
UpdatePackageState(TasksPackageState.Analysis);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
if (CheckNextState()) UpdatePackage();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//--
|
||||||
|
void getTasksInfo(List<? extends DVMTask> tasks, String file_name) throws Exception {
|
||||||
|
LinkedHashMap<Integer, DVMTask> sorted_tasks = new LinkedHashMap<>();
|
||||||
|
for (DVMTask task : tasks)
|
||||||
|
sorted_tasks.put(task.id, task);
|
||||||
|
//--
|
||||||
|
File info_file = Paths.get(packageLocalWorkspace.getAbsolutePath(), "results", file_name).toFile();
|
||||||
|
List<String> lines = FileUtils.readLines(info_file, Charset.defaultCharset());
|
||||||
|
for (String packed : lines) {
|
||||||
|
if (!packed.isEmpty()) {
|
||||||
|
String[] data = packed.split(" ");
|
||||||
|
int id = Integer.parseInt(data[0]);
|
||||||
|
TaskState state = TaskState.valueOf(data[1]);
|
||||||
|
double time = Double.parseDouble(data[2]);
|
||||||
|
//--
|
||||||
|
DVMTask task = sorted_tasks.get(id);
|
||||||
|
task.state = state;
|
||||||
|
task.Time = state.equals(TaskState.AbortedByTimeout) ? (task.maxtime + 1) : time;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
LinkedHashMap<Integer, File> getTestsFromJson() {
|
||||||
|
LinkedHashMap<Integer, File> res = new LinkedHashMap<>();
|
||||||
|
for (DVMCompilationTask task : testingPackage.package_json.compilationTasks) {
|
||||||
|
if (!res.containsKey(task.test_id)) {
|
||||||
|
res.put(task.test_id, Paths.get(Global.TestsDirectory.getAbsolutePath(), String.valueOf(task.test_id)).toFile());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
static LinkedHashMap<LanguageName, Vector<ProjectFile>> getTestPrograms(File test) {
|
||||||
|
LinkedHashMap<LanguageName, Vector<ProjectFile>> res = new LinkedHashMap<>();
|
||||||
|
//--
|
||||||
|
res.put(LanguageName.fortran, new Vector<>());
|
||||||
|
res.put(LanguageName.c, new Vector<>());
|
||||||
|
res.put(LanguageName.cpp, new Vector<>());
|
||||||
|
//--
|
||||||
|
File[] files = test.listFiles(new FileFilter() {
|
||||||
|
@Override
|
||||||
|
public boolean accept(File pathname) {
|
||||||
|
return pathname.isFile();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
if (files != null) {
|
||||||
|
for (File file : files) {
|
||||||
|
ProjectFile projectFile = new ProjectFile(new File(file.getName()));
|
||||||
|
if (projectFile.isNotExcludedProgram()) res.get(projectFile.languageName).add(projectFile);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
static void generateForLanguage(String dvm_drv, LanguageName language, Vector<ProjectFile> language_programs, Vector<String> titles, Vector<String> objects, Vector<String> bodies, String flags) {
|
||||||
|
if (!language_programs.isEmpty()) {
|
||||||
|
String LANG_ = language.toString().toUpperCase() + "_";
|
||||||
|
Vector<String> module_objects = new Vector<>();
|
||||||
|
String module_body = "";
|
||||||
|
int i = 1;
|
||||||
|
for (ProjectFile program : language_programs) {
|
||||||
|
//--
|
||||||
|
String object = Utils.DQuotes(language + "_" + i + ".o");
|
||||||
|
module_objects.add(object);
|
||||||
|
module_body += object + ":\n" + "\t" + String.join(" ", Utils.MFVar(LANG_ + "COMMAND"), Utils.MFVar(LANG_ + "FLAGS"), program.getStyleOptions(), "-c", program.getQSourceName(), "-o", object + "\n\n");
|
||||||
|
++i;
|
||||||
|
}
|
||||||
|
titles.add(String.join("\n", LANG_ + "COMMAND=" + Utils.DQuotes(dvm_drv) + " " + language.getDVMCompile(), LANG_ + "FLAGS=" + flags, LANG_ + "OBJECTS=" + String.join(" ", module_objects), ""));
|
||||||
|
objects.add(Utils.MFVar(LANG_ + "OBJECTS"));
|
||||||
|
bodies.add(module_body);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
static String generateMakefile(File test, LanguageName test_language, String dvm_drv, String flags) {
|
||||||
|
//----->>
|
||||||
|
LinkedHashMap<LanguageName, Vector<ProjectFile>> programs = getTestPrograms(test);
|
||||||
|
Vector<String> titles = new Vector<>();
|
||||||
|
Vector<String> objects = new Vector<>();
|
||||||
|
Vector<String> bodies = new Vector<>();
|
||||||
|
String binary = Utils.DQuotes("0");
|
||||||
|
//----->>
|
||||||
|
for (LanguageName languageName : programs.keySet()) {
|
||||||
|
generateForLanguage(dvm_drv, languageName, programs.get(languageName), titles, objects, bodies, flags);
|
||||||
|
}
|
||||||
|
//----->>
|
||||||
|
return String.join("\n", "LINK_COMMAND=" + Utils.DQuotes(dvm_drv) + " " + test_language.getDVMLink(), "LINK_FLAGS=" + flags + "\n", String.join("\n", titles), "all: " + binary, binary + " : " + String.join(" ", objects), "\t" + Utils.MFVar("LINK_COMMAND") + " " + Utils.MFVar("LINK_FLAGS") + " " + String.join(" ", objects) + " -o " + binary, String.join(" ", bodies));
|
||||||
|
}
|
||||||
|
//---
|
||||||
|
void Kill() throws Exception {
|
||||||
|
if (!testingPackage.PID.isEmpty())
|
||||||
|
user.connection.Command("kill -9 " + testingPackage.PID);
|
||||||
|
}
|
||||||
|
void AnalyseResults() throws Exception {
|
||||||
|
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;
|
||||||
|
//--
|
||||||
|
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<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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
testingPackage.progress = 100;
|
||||||
|
testingPackage.saveJson(); //запись обновленных результатов пакета в json!
|
||||||
|
Print("analysis done, ct_count=" + ct_count + " rt count=" + rt_count);
|
||||||
|
}
|
||||||
|
//--
|
||||||
|
void PerformPackage() throws Exception {
|
||||||
|
//--
|
||||||
|
if (testingPackage.connectionErrosCount>=10){
|
||||||
|
Print(testingPackage.id+" had 10 connection errors. stop");
|
||||||
|
UpdatePackageState(TasksPackageState.ConnectionError);
|
||||||
|
//todo тут надо будет завершать нить ибо испорчена и давать увед серверу?
|
||||||
|
}else {
|
||||||
|
//--
|
||||||
|
if (testingPackage.state.equals(TasksPackageState.Analysis)) {
|
||||||
|
AnalyseResults();
|
||||||
|
UpdatePackageState(TasksPackageState.Done);
|
||||||
|
} else {
|
||||||
|
try {
|
||||||
|
if (Connect()) {
|
||||||
|
int ptk_id = (int) ServerCommand(ServerCode.DVMPackageNeedsKill, testingPackage.id);
|
||||||
|
if (ptk_id != Constants.Nan) {
|
||||||
|
Print("package " + testingPackage.id + " NEEDS TO KILL");
|
||||||
|
Kill();
|
||||||
|
UpdatePackageState(TasksPackageState.Aborted);
|
||||||
|
ServerCommand(ServerCode.DeleteObjectByPK, new Pair(TestingPackageToKill.class, ptk_id));
|
||||||
|
} else {
|
||||||
|
Session();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
testingPackage.connectionErrosCount++;
|
||||||
|
UpdatePackage();
|
||||||
|
}
|
||||||
|
} catch (Exception ex) {
|
||||||
|
Print("Ошибка сеанса. Соединение будет разорвано.");
|
||||||
|
Print(ex.getMessage());
|
||||||
|
//
|
||||||
|
testingPackage.connectionErrosCount++;
|
||||||
|
UpdatePackage();
|
||||||
|
} finally {
|
||||||
|
Disconnect();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -40,6 +40,8 @@ public class TestPass extends Pass_2021 {
|
|||||||
byte[] localIp = InetAddress.getLocalHost().getAddress();
|
byte[] localIp = InetAddress.getLocalHost().getAddress();
|
||||||
InetAddress address = InetAddress.getByName("alex-freenas.ddns.net");
|
InetAddress address = InetAddress.getByName("alex-freenas.ddns.net");
|
||||||
System.out.println(address);
|
System.out.println(address);
|
||||||
|
|
||||||
|
|
||||||
//java определить по адресу сервера совпадает ли он с локальным
|
//java определить по адресу сервера совпадает ли он с локальным
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user