Skip to content

Commit

Permalink
Merge pull request #5791 from BOINC/dpa_wsl_wrapper
Browse files Browse the repository at this point in the history
Add wsl_wrapper
  • Loading branch information
AenBleidd authored Sep 5, 2024
2 parents 4463029 + 2157d4f commit 152dd86
Show file tree
Hide file tree
Showing 21 changed files with 485 additions and 161 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/linux.yml
Original file line number Diff line number Diff line change
Expand Up @@ -246,7 +246,7 @@ jobs:
if: success() && matrix.type == 'apps'
run: |
export CFLAGS="-O3"
export CXXFLAGS="-O3"
export CXXFLAGS="-O3 -std=c++11"
export LDFLAGS="-static-libstdc++ -s"
export RELEASE_ARCH=x86_64
./configure --enable-apps --enable-apps-vbox --disable-server --disable-client --disable-manager
Expand All @@ -256,7 +256,7 @@ jobs:
if: success() && matrix.type == 'apps-x86'
run: |
export CFLAGS="-O3 -m32"
export CXXFLAGS="-O3 -m32"
export CXXFLAGS="-O3 -m32 -std=c++11"
export LDFLAGS="-static-libstdc++ -s -m32"
export RELEASE_ARCH=i686
./configure --enable-apps --enable-apps-vbox --disable-server --disable-client --disable-manager --host=i686-linux-gnu
Expand Down
6 changes: 0 additions & 6 deletions client/app_start.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -697,12 +697,6 @@ int ACTIVE_TASK::start(bool test) {
exit(0);
}

// use special exec path for test app
//
if (wup->project->app_test) {
strcpy(exec_path, gstate.app_test_file.c_str());
}

#ifdef _WIN32
PROCESS_INFORMATION process_info;
STARTUPINFO startup_info;
Expand Down
107 changes: 60 additions & 47 deletions client/app_test.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// This file is part of BOINC.
// http://boinc.berkeley.edu
// Copyright (C) 2023 University of California
// https://boinc.berkeley.edu
// Copyright (C) 2024 University of California
//
// BOINC is free software; you can redistribute it and/or modify it
// under the terms of the GNU Lesser General Public License
Expand All @@ -17,77 +17,81 @@

// A framework that lets you run jobs under a BOINC client
// without a project, and without fake XML files
// Lets you debug client/app interactions.
// This lets you debug client/app interactions.
//
// To use this framework:
// edit this file to describe your application:
// - edit this file to describe your application:
// input/output files, attributes, etc.
// NOTE: currently it's set up for an app that:
// - is a native BOINC app (i.e. uses the BOINC library)
// - has 1 input file:
// logical name 'in' and physical name 'infile'
// - has 1 output file:
// logical name 'out' and physical name 'outfile'
// - has the command line 'in out' (i.e. the logical file names)
// To change these, edit app_test_init() below
// NOTE: currently it's set up for an app that uses the WSL wrapper
//
// build the BOINC client with these changes
// make a BOINC data directory, say 'test'
// - build the BOINC client with these changes
// - make a BOINC data directory, say 'test'
// (or you can use an existing BOINC data directory,
// in which case the client will also run jobs that are there)
// make a directory test/slots/app_test
// - make a directory test/slots/app_test
// The client will run the test job there.
// Clean it out between runs.
// the test directory acts as the project directory. In it, put
// - make a dir test/projects/app_test
// - In the project directory, put:
// - the executable file
// - the input file(s) with physical names
// in the test directory, run boinc --app_test exec_filename
// - run boinc (in the data directory if you created one)
// when the job is done, the client won't clean out the slot dir.
// You can examine the contents of the slot dir,
// and examine the output files in the test dir.
// and examine the output files in the project dir.
// Clean out the slot dir between tests.

#include "project.h"
#include "client_types.h"
#include "result.h"
#include "client_state.h"

// set to 0 to enable app test

#if 1
void CLIENT_STATE::app_test_init() {}
#else
#include "client_types.h"
#include "log_flags.h"
#include "project.h"
#include "result.h"
// The following functions create client data structures
// (PROJECT, APP, APP_VERSION, WORKUNIT, RESULT, FILE_REF, FILE_INFO)
// for the test app and job.
// The names and version numbers must match up.
static PROJECT* make_project() {
PROJECT *proj = new PROJECT;
strcpy(proj->project_name, "test project");
strcpy(proj->master_url, "test_project_url");
strcpy(proj->_project_dir, ".");
strcpy(proj->project_name, "app_test project");
strcpy(proj->master_url, "https://app.test/");
strcpy(proj->_project_dir, "projects/app_test");
proj->app_test = true;
proj->non_cpu_intensive = false;
// tell the client to use the slots/app_test slot dir for this project
gstate.projects.push_back(proj);
return proj;
}
static APP* make_app(PROJECT* proj) {
APP *app = new APP;
strcpy(app->name, "test app");
strcpy(app->user_friendly_name, "test app");
strcpy(app->name, "test_app");
strcpy(app->user_friendly_name, "test_app");
app->project = proj;
gstate.apps.push_back(app);
return app;
}
#define INPUT_FILE 0
#define OUTPUT_FILE 1
#define EXEC_FILE 2
#define MAIN_PROG 2
static FILE_REF* make_file(
PROJECT *proj, const char* phys_name, const char* log_name, int ftype
PROJECT *proj, const char* phys_name, const char* log_name,
int ftype, bool copy_file
) {
FILE_INFO *fip = new FILE_INFO;
strcpy(fip->name, phys_name);
fip->project = proj;
fip->status = (ftype == OUTPUT_FILE)?FILE_NOT_PRESENT:FILE_PRESENT;
if (ftype == EXEC_FILE) fip->executable = true;
if (ftype == MAIN_PROG) fip->executable = true;
if (ftype == OUTPUT_FILE) {
fip->max_nbytes = 1e9;
fip->upload_urls.add(string("foobar"));
Expand All @@ -98,46 +102,44 @@ static FILE_REF* make_file(
strcpy(fref->open_name, log_name);
}
fref->file_info = fip;
if (ftype == EXEC_FILE) fref->main_program = true;
if (ftype == MAIN_PROG) fref->main_program = true;
fref->copy_file = copy_file;
return fref;
}
static APP_VERSION* make_app_version(APP *app, const char* exec_name) {
if (!boinc_file_exists(exec_name)) {
fprintf(stderr, "%s doesn't exist\n", exec_name);
exit(1);
}
static APP_VERSION* make_app_version(APP *app) {
APP_VERSION *av = new APP_VERSION;
strcpy(av->app_name, "test_av");
strcpy(av->app_name, app->name);
strcpy(av->api_version, "8.0");
av->app = app;
av->project = app->project;
av->avg_ncpus = 1;
av->version_num = 1;
av->flops = 1e9;
FILE_REF *fref = make_file(app->project, exec_name, NULL, EXEC_FILE);
av->app_files.push_back(*fref);
gstate.app_versions.push_back(av);
return av;
}
static WORKUNIT* make_workunit(APP* app) {
static WORKUNIT* make_workunit(APP_VERSION *av) {
WORKUNIT *wu = new WORKUNIT;
APP* app = av->app;
strcpy(wu->name, "test_wu");
strcpy(wu->app_name, "test_app");
strcpy(wu->app_name, app->name);
wu->app = app;
wu->project = app->project;
wu->rsc_fpops_est = 1e9;
wu->rsc_fpops_bound = 1e12;
wu->rsc_memory_bound = 1e9;
wu->rsc_disk_bound = 1e9;
wu->version_num = av->version_num;
gstate.workunits.push_back(wu);
return wu;
}
static RESULT* make_result(APP_VERSION *av, WORKUNIT* wu) {
RESULT *res = new RESULT;
strcpy(res->name, "test_result");
strcpy(res->wu_name, "test_wu");
strcpy(res->wu_name, wu->name);
res->project = av->project;
res->avp = av;
res->wup = wu;
Expand All @@ -160,26 +162,36 @@ void CLIENT_STATE::app_test_init() {
have_sporadic_app = true;
#endif
APP_VERSION *av = make_app_version(app, app_test_file.c_str());
APP_VERSION *av = make_app_version(app);
av->app_files.push_back(
*make_file(app->project, "wsl_wrapper.exe", NULL, MAIN_PROG, false)
);
av->app_files.push_back(
*make_file(app->project, "main", NULL, INPUT_FILE, true)
);
av->app_files.push_back(
*make_file(app->project, "worker", NULL, INPUT_FILE, false)
);
// can put other stuff here like
#if 0
av->gpu_ram = 1e7;
av->gpu_usage.rsc_type = PROC_TYPE_NVIDIA_GPU;
av->gpu_usage.usage = 1;
#endif
WORKUNIT *wu = make_workunit(app);
WORKUNIT *wu = make_workunit(av);
#if 1
wu->command_line = "in out";
//wu->command_line = "--nsecs 60";
wu->input_files.push_back(
*make_file(proj, "infile", "in", INPUT_FILE)
*make_file(proj, "infile", "in", INPUT_FILE, false)
);
#endif
RESULT *result = make_result(av, wu);
#if 1
result->output_files.push_back(
*make_file(proj, "outfile", "out", OUTPUT_FILE)
*make_file(proj, "outfile", "out", OUTPUT_FILE, false)
);
#endif
Expand All @@ -188,3 +200,4 @@ void CLIENT_STATE::app_test_init() {
cc_config.unsigned_apps_ok = true;
cc_config.skip_cpu_benchmarks = true;
}
#endif
4 changes: 1 addition & 3 deletions client/client_state.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -644,9 +644,7 @@ int CLIENT_STATE::init() {
//
parse_state_file();

if (app_test) {
app_test_init();
}
app_test_init();

bool new_client = is_new_client();

Expand Down
4 changes: 2 additions & 2 deletions client/client_state.h
Original file line number Diff line number Diff line change
Expand Up @@ -245,8 +245,8 @@ struct CLIENT_STATE {
void process_autologin(bool first);

// --------------- app_test.cpp:
bool app_test;
string app_test_file;
bool app_test; // this and the follow are not used,
string app_test_file; // but if I remove them the client crashes on exit. WTF???
void app_test_init();

// --------------- current_version.cpp:
Expand Down
8 changes: 0 additions & 8 deletions client/cs_cmdline.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,6 @@ static void print_options(char* prog) {
" --abort_jobs_on_exit when client exits, abort and report jobs\n"
" --allow_remote_gui_rpc allow remote GUI RPC connections\n"
" --allow_multiple_clients allow >1 instances per host\n"
" --app_test F run a simulated job with the given app\n"
" --attach_project <URL> <key> attach to a project\n"
" --check_all_logins for idle detection, check remote logins too\n"
" --daemon run as daemon (Unix)\n"
Expand Down Expand Up @@ -128,13 +127,6 @@ void CLIENT_STATE::parse_cmdline(int argc, char** argv) {
cc_config.allow_multiple_clients = true;
} else if (ARG(allow_remote_gui_rpc)) {
cc_config.allow_remote_gui_rpc = true;
} else if (ARG(app_test)) {
if (i+1 >= argc) {
fprintf(stderr, "usage: boinc --app_test exec-file\n");
exit(1);
}
app_test = true;
app_test_file = argv[++i];
} else if (ARG(attach_project)) {
if (i >= argc-2) {
show_options = true;
Expand Down
3 changes: 2 additions & 1 deletion client/cs_files.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -103,8 +103,9 @@ int CLIENT_STATE::make_project_dirs() {

string name;
char path[MAXPATHLEN];
DirScanner dir("projects");
DirScanner dir(PROJECTS_DIR);
while (dir.scan(name)) {
if (name == "app_test") continue;
snprintf(path, sizeof(path), "projects/%s", name.c_str());
if (std::find(pds.begin(), pds.end(), path) != pds.end()) {
continue;
Expand Down
1 change: 1 addition & 0 deletions client/cs_statefile.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -755,6 +755,7 @@ int CLIENT_STATE::write_state(MIOFILE& f) {
if (retval) return retval;
for (j=0; j<projects.size(); j++) {
PROJECT* p = projects[j];
if (p->app_test) continue; // don't write app_test project
retval = p->write_state(f);
if (retval) return retval;
for (i=0; i<apps.size(); i++) {
Expand Down
2 changes: 1 addition & 1 deletion client/file_names.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -227,7 +227,7 @@ void delete_old_slot_dirs() {
safe_strcpy(filename, "");
retval = dir_scan(filename, dirp, sizeof(filename));
if (retval) break;
if (!strcmp(filename, "app_test")) {
if (strstr(filename, "test")) {
continue;
}
snprintf(path, sizeof(path), "%s/%s", SLOTS_DIR, filename);
Expand Down
Loading

0 comments on commit 152dd86

Please sign in to comment.