linux done
This commit is contained in:
parent
989c44891d
commit
8dfd101ae9
155
src/main.cpp
155
src/main.cpp
@ -5,13 +5,14 @@
|
|||||||
#include <filesystem>
|
#include <filesystem>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <functional>
|
#include <functional>
|
||||||
|
#include <future>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include<json/json.h>
|
#include<json/json.h>
|
||||||
#include <ostream>
|
#include <ostream>
|
||||||
#include <queue>
|
#include <queue>
|
||||||
#include <sstream>
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <thread>
|
#include <thread>
|
||||||
|
#include <utility>
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
#include<windows.h>
|
#include<windows.h>
|
||||||
@ -59,21 +60,30 @@ struct Test{
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifdef _WIN32
|
struct ProgramRet{
|
||||||
struct ProgramRet{
|
time_point<system_clock> start;
|
||||||
time_point<steady_clock> start;
|
time_point<system_clock> end;
|
||||||
time_point<steady_clock> end;
|
};
|
||||||
};
|
|
||||||
void executeCommandWithRedirect(const std::string &command, const std::string &inputFile, const std::string &outputFile);
|
|
||||||
#else
|
|
||||||
struct ProgramRet{
|
|
||||||
time_point<system_clock> start;
|
|
||||||
time_point<system_clock> end;
|
|
||||||
};
|
|
||||||
#endif
|
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
T getValueOrPanic(T value);
|
T getValueOrPanic(T value);
|
||||||
|
int compareFiles(const std::string& path1, const std::string& path2);
|
||||||
|
|
||||||
|
struct Statu{
|
||||||
|
bool isTLE = false;
|
||||||
|
int cmp;
|
||||||
|
int id;
|
||||||
|
friend std::ostream& operator<<(std::ostream &os,Statu &s){
|
||||||
|
if(s.isTLE){
|
||||||
|
os<<"tests "<<s.id<<" TLE";
|
||||||
|
}else if(s.cmp==0){
|
||||||
|
os<<"tests "<<s.id<<" AC";
|
||||||
|
}else{
|
||||||
|
os<<"tests "<<s.id<<" WA line:"<<s.cmp;
|
||||||
|
}
|
||||||
|
return os;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
int main(int argc, char* argv[]) {
|
int main(int argc, char* argv[]) {
|
||||||
LOG("Zengtudor OI test tools . loading files .. please add a json file in arg");
|
LOG("Zengtudor OI test tools . loading files .. please add a json file in arg");
|
||||||
@ -119,6 +129,12 @@ int main(int argc, char* argv[]) {
|
|||||||
LOG("creating building dir")
|
LOG("creating building dir")
|
||||||
std::filesystem::create_directory(buildDir);
|
std::filesystem::create_directory(buildDir);
|
||||||
}
|
}
|
||||||
|
LOG("getting run time out")
|
||||||
|
int runtimeout = 0;
|
||||||
|
if(jsonValue["runtimeout"]!=Json::nullValue){
|
||||||
|
runtimeout = jsonValue["runtimeout"].asInt();
|
||||||
|
printValue(runtimeout)
|
||||||
|
}
|
||||||
LOG("compiling")
|
LOG("compiling")
|
||||||
string compileCommands;
|
string compileCommands;
|
||||||
const path exePath = (buildDir/"main").string()+(isWindows==true?".exe":"");
|
const path exePath = (buildDir/"main").string()+(isWindows==true?".exe":"");
|
||||||
@ -130,16 +146,19 @@ int main(int argc, char* argv[]) {
|
|||||||
auto cpuNums = getCpuNums();
|
auto cpuNums = getCpuNums();
|
||||||
printValue(cpuNums)
|
printValue(cpuNums)
|
||||||
|
|
||||||
if(jsonValue["tests"].size()==0)LOG("cannot find tests");
|
if(jsonValue["tests"].size()==0){
|
||||||
|
LOG("cannot find tests")
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
LOG("parsing tests")
|
LOG("parsing tests")
|
||||||
vector<Test> tests;
|
vector<Test> tests(jsonValue["tests"].size()+1);
|
||||||
auto &jsonTests = jsonValue["tests"];
|
auto &jsonTests = jsonValue["tests"];
|
||||||
for(unsigned int i=1;i<=jsonTests.size();i++){
|
for(unsigned int i=1;i<=jsonTests.size();i++){
|
||||||
tests.push_back({
|
tests[i]={
|
||||||
.id = i,
|
.id = i,
|
||||||
.in=getAbsolutePath(projectPath, getValueOrPanic(jsonTests[i-1]["in"]).asString()),
|
.in=getAbsolutePath(projectPath, getValueOrPanic(jsonTests[i-1]["in"]).asString()),
|
||||||
.ans=getAbsolutePath(projectPath,getValueOrPanic(jsonTests[i-1]["ans"]).asString()),
|
.ans=getAbsolutePath(projectPath,getValueOrPanic(jsonTests[i-1]["ans"]).asString()),
|
||||||
});
|
};
|
||||||
}
|
}
|
||||||
queue<std::function<ProgramRet()>> tasks;
|
queue<std::function<ProgramRet()>> tasks;
|
||||||
const auto testsPath = projectPath/"tests";
|
const auto testsPath = projectPath/"tests";
|
||||||
@ -149,42 +168,92 @@ int main(int argc, char* argv[]) {
|
|||||||
}
|
}
|
||||||
printValue(testsPath)
|
printValue(testsPath)
|
||||||
const string exePathStr = getProtectPath(exePath);
|
const string exePathStr = getProtectPath(exePath);
|
||||||
for (auto i : tests) {
|
for(auto i:tests){
|
||||||
tasks.push([i, &exePathStr, &testsPath]() -> ProgramRet {
|
tasks.push([i,&exePathStr,&testsPath]()->ProgramRet{
|
||||||
string id_str = std::to_string(i.id);
|
string commands;
|
||||||
path outPath = testsPath / (id_str + ".out");
|
std::stringstream ss;
|
||||||
|
ss<<i.id;
|
||||||
// 构建命令
|
string id_str;
|
||||||
string commands = exePathStr + " < " + getProtectPath(i.in) + " > " + getProtectPath(outPath);
|
ss>>id_str;
|
||||||
|
path outPath = testsPath/(id_str+".out") ;
|
||||||
// 输出构建的命令进行调试
|
commands = commands+exePathStr+" < "+getProtectPath(i.in)+" > "+getProtectPath(outPath);
|
||||||
LOG(commands);
|
LOG(commands)
|
||||||
|
|
||||||
// 执行命令
|
|
||||||
auto start = high_resolution_clock::now();
|
auto start = high_resolution_clock::now();
|
||||||
#ifdef _WIN32
|
system(commands.c_str());
|
||||||
executeCommandWithRedirect(commands, getProtectPath(i.in), getProtectPath(outPath));
|
auto end=high_resolution_clock::now();
|
||||||
#else
|
|
||||||
system(commands.c_str())
|
|
||||||
#endif
|
|
||||||
auto end = high_resolution_clock::now();
|
|
||||||
|
|
||||||
// AS_EM(result, 0,"error in exec commands")
|
|
||||||
|
|
||||||
return ProgramRet{
|
return ProgramRet{
|
||||||
.start = start,
|
.start=start,
|
||||||
.end = end
|
.end = end
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
while(tasks.size()>0){
|
while(tasks.size()>0){
|
||||||
auto i = tasks.front();
|
auto i = tasks.front();
|
||||||
tasks.pop();
|
tasks.pop();
|
||||||
thread newThread(i);
|
futures.push_back(std::async(std::launch::async,i));
|
||||||
AS_EQ(newThread.joinable(),true);
|
|
||||||
newThread.join();
|
|
||||||
}
|
}
|
||||||
|
vector<ProgramRet> results(jsonTests.size()+1);
|
||||||
|
for(auto &i:futures){
|
||||||
|
if(runtimeout>0){
|
||||||
|
if(i.wait_for(std::chrono::milliseconds(runtimeout))==std::future_status::ready){
|
||||||
|
auto ret = i.get();
|
||||||
|
results[ret.id]=ret;
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
i.wait();
|
||||||
|
auto ret = i.get();
|
||||||
|
results[ret.id]=ret;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
LOG("get results done")
|
||||||
|
for(int i=1;i<=jsonTests.size();i++){
|
||||||
|
LOG(results[i])
|
||||||
|
}
|
||||||
|
|
||||||
|
vector<Statu> status(jsonTests.size()+1);
|
||||||
|
for(int i=1;i<=jsonTests.size();i++){
|
||||||
|
printValue(tests[i].ans)
|
||||||
|
status[i]={
|
||||||
|
.isTLE=(results[i].id==0?true:false),
|
||||||
|
.cmp=compareFiles(results[i].outPath,tests[i].ans),
|
||||||
|
.id=i
|
||||||
|
};
|
||||||
|
}
|
||||||
|
for(int i=1;i<=jsonTests.size();i++){
|
||||||
|
cout<<status[i]<<endl;
|
||||||
|
}
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
int compareFiles(const std::string& path1, const std::string& path2) {
|
||||||
|
std::ifstream file1(path1);
|
||||||
|
std::ifstream file2(path2);
|
||||||
|
|
||||||
|
if (!file1.is_open()) {
|
||||||
|
std::cerr << "无法打开文件: " << path1 << std::endl;
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
if (!file2.is_open()) {
|
||||||
|
std::cerr << "无法打开文件: " << path2 << std::endl;
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string line1, line2;
|
||||||
|
int lineNumber = 1;
|
||||||
|
|
||||||
|
while (std::getline(file1, line1) && std::getline(file2, line2)) {
|
||||||
|
if (line1 != line2) {
|
||||||
|
return lineNumber; // 返回第一个不同的行号
|
||||||
|
}
|
||||||
|
++lineNumber;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 如果一个文件还没读完
|
||||||
|
if (std::getline(file1, line1) || std::getline(file2, line2)) {
|
||||||
|
return lineNumber;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0; // 文件内容完全一致
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
|
@ -1,8 +1,11 @@
|
|||||||
#include<bits/stdc++.h>
|
#include<bits/stdc++.h>
|
||||||
|
#include <chrono>
|
||||||
|
#include <thread>
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
|
|
||||||
int main(){
|
int main(){
|
||||||
|
// this_thread::sleep_for(chrono::seconds(2));
|
||||||
string s;
|
string s;
|
||||||
cin>>s;
|
cin>>s;
|
||||||
cout<<s<<endl;
|
cout<<s<<endl;
|
||||||
|
@ -5,10 +5,5 @@
|
|||||||
"args":[
|
"args":[
|
||||||
"-O3"
|
"-O3"
|
||||||
],
|
],
|
||||||
"tests":[
|
"runtimeout":100
|
||||||
{
|
|
||||||
"in":"a.in",
|
|
||||||
"ans":"1.ans"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
}
|
Loading…
Reference in New Issue
Block a user