mirror of https://github.com/BOINC/boinc.git
204 lines
6.0 KiB
C++
204 lines
6.0 KiB
C++
// This file is part of BOINC.
|
|
// 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
|
|
// as published by the Free Software Foundation,
|
|
// either version 3 of the License, or (at your option) any later version.
|
|
//
|
|
// BOINC is distributed in the hope that it will be useful,
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
|
// See the GNU Lesser General Public License for more details.
|
|
//
|
|
// You should have received a copy of the GNU Lesser General Public License
|
|
// along with BOINC. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
// A framework that lets you run jobs under a BOINC client
|
|
// without a project, and without fake XML files
|
|
// This lets you debug client/app interactions.
|
|
//
|
|
// To use this framework:
|
|
// - edit this file to describe your application:
|
|
// input/output files, attributes, etc.
|
|
// 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'
|
|
// (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
|
|
// The client will run the test job there.
|
|
// Clean it out between runs.
|
|
// - make a dir test/projects/app_test
|
|
// - In the project directory, put:
|
|
// - the executable file
|
|
// - the input file(s) with physical names
|
|
// - 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 project dir.
|
|
// Clean out the slot dir between tests.
|
|
|
|
#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, "app_test project");
|
|
strcpy(proj->master_url, "https://app.test/");
|
|
strcpy(proj->_project_dir, "projects/app_test");
|
|
proj->app_test = true;
|
|
// 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");
|
|
app->project = proj;
|
|
gstate.apps.push_back(app);
|
|
return app;
|
|
}
|
|
|
|
#define INPUT_FILE 0
|
|
#define OUTPUT_FILE 1
|
|
#define MAIN_PROG 2
|
|
|
|
static FILE_REF* make_file(
|
|
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 == MAIN_PROG) fip->executable = true;
|
|
if (ftype == OUTPUT_FILE) {
|
|
fip->max_nbytes = 1e9;
|
|
fip->upload_urls.add(string("foobar"));
|
|
}
|
|
gstate.file_infos.push_back(fip);
|
|
FILE_REF * fref = new FILE_REF;
|
|
if (log_name) {
|
|
strcpy(fref->open_name, log_name);
|
|
}
|
|
fref->file_info = fip;
|
|
if (ftype == MAIN_PROG) fref->main_program = true;
|
|
fref->copy_file = copy_file;
|
|
return fref;
|
|
}
|
|
|
|
static APP_VERSION* make_app_version(APP *app) {
|
|
APP_VERSION *av = new APP_VERSION;
|
|
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;
|
|
gstate.app_versions.push_back(av);
|
|
return av;
|
|
}
|
|
|
|
static WORKUNIT* make_workunit(APP_VERSION *av) {
|
|
WORKUNIT *wu = new WORKUNIT;
|
|
APP* app = av->app;
|
|
strcpy(wu->name, "test_wu");
|
|
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, wu->name);
|
|
res->project = av->project;
|
|
res->avp = av;
|
|
res->wup = wu;
|
|
res->app = av->app;
|
|
res->report_deadline = dtime()+86400;
|
|
gstate.results.push_back(res);
|
|
return res;
|
|
}
|
|
|
|
// app_test_init() sets up above data structures
|
|
// so that the client runs a test job.
|
|
//
|
|
void CLIENT_STATE::app_test_init() {
|
|
PROJECT *proj = make_project();
|
|
|
|
APP *app = make_app(proj);
|
|
// can put other stuff here like
|
|
#if 0
|
|
app->sporadic = true;
|
|
have_sporadic_app = true;
|
|
#endif
|
|
|
|
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(av);
|
|
#if 1
|
|
//wu->command_line = "--nsecs 60";
|
|
wu->input_files.push_back(
|
|
*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, false)
|
|
);
|
|
#endif
|
|
|
|
// tell the client not to get work or run benchmarks
|
|
//
|
|
cc_config.unsigned_apps_ok = true;
|
|
cc_config.skip_cpu_benchmarks = true;
|
|
}
|
|
#endif
|