From 60f97b1e47e34219c946fa720d66002a2d1fb661 Mon Sep 17 00:00:00 2001 From: David Anderson Date: Mon, 18 Sep 2023 11:20:35 -0700 Subject: [PATCH 1/5] client: add '--app_test fname' option. The client will run and communicate with that app. You don't need to make any XML files. --- client/Makefile.am | 1 + client/Makefile.linux | 6 ++++-- client/app_start.cpp | 20 ++++++++++++++------ client/client_state.cpp | 34 ++++++++++++++++++++++------------ client/client_state.h | 5 +++++ client/cs_cmdline.cpp | 3 +++ lib/msg_queue.cpp | 1 + 7 files changed, 50 insertions(+), 20 deletions(-) diff --git a/client/Makefile.am b/client/Makefile.am index bceb548022a..e583aa24ad1 100644 --- a/client/Makefile.am +++ b/client/Makefile.am @@ -40,6 +40,7 @@ boinc_client_SOURCES = \ app_config.cpp \ app_control.cpp \ app_start.cpp \ + app_test.cpp \ async_file.cpp \ check_state.cpp \ client_msgs.cpp \ diff --git a/client/Makefile.linux b/client/Makefile.linux index acbc24ba64b..7f0461d74e6 100644 --- a/client/Makefile.linux +++ b/client/Makefile.linux @@ -6,7 +6,8 @@ # make -f Makefile.linux clean all # 3) do the same in this dir -CC = g++ -O4 -Wall -I ../ -I ../lib/ +//CC = g++ -O4 -Wall -I ../ -I ../lib/ +CC = g++ -g -Wall -I ../ -I ../lib/ PROGS = boinc boinccmd @@ -19,6 +20,7 @@ BOINC_OBJ = \ app_config.o \ app_control.o \ app_start.o \ + app_test.o \ async_file.o \ check_state.o \ client_msgs.o \ @@ -133,7 +135,7 @@ SRC = \ clean: rm -f $(PROGS) $(BOINC_OBJ) dependencies -LIBS = ../lib/lib.a \ +LIBS = ../lib/boinc.a \ -L /usr/local/lib/ \ -lpthread \ -lX11 -lXss \ diff --git a/client/app_start.cpp b/client/app_start.cpp index 6144ba0b70d..127c4e7b59e 100644 --- a/client/app_start.cpp +++ b/client/app_start.cpp @@ -691,6 +691,12 @@ int ACTIVE_TASK::start(bool test) { exit(0); } + if (gstate.app_test) { + strcpy(slot_dir, "slots/app_test"); + strcpy(exec_path, gstate.app_test_file.c_str()); + } + + #ifdef _WIN32 PROCESS_INFORMATION process_info; STARTUPINFO startup_info; @@ -897,7 +903,7 @@ int ACTIVE_TASK::start(bool test) { if (log_flags.task_debug) { msg_printf(wup->project, MSG_INFO, - "[task] ACTIVE_TASK::start(): forked process: pid %d\n", pid + "[task_debug] ACTIVE_TASK::start(): forked process: pid %d\n", pid ); } @@ -1131,7 +1137,7 @@ int ACTIVE_TASK::start(bool test) { // if (log_flags.task_debug) { msg_printf(wup->project, MSG_INFO, - "[task] ACTIVE_TASK::start(): forked process: pid %d\n", pid + "[task_debug] ACTIVE_TASK::start(): forked process: pid %d\n", pid ); } @@ -1154,14 +1160,16 @@ int ACTIVE_TASK::start(bool test) { gstate.verify_app_version_files(result); } - char err_msg[4096]; - snprintf(err_msg, sizeof(err_msg), "couldn't start app: %.256s", buf); - gstate.report_result_error(*result, err_msg); if (log_flags.task_debug) { msg_printf(wup->project, MSG_INFO, - "[task] couldn't start app: %s", buf + "[task_debug] couldn't start app: %s", buf ); } + + char err_msg[4096]; + snprintf(err_msg, sizeof(err_msg), "couldn't start app: %.256s", buf); + gstate.report_result_error(*result, err_msg); + set_task_state(PROCESS_COULDNT_START, "start"); return retval; } diff --git a/client/client_state.cpp b/client/client_state.cpp index 3d27daf8016..00f2c410599 100644 --- a/client/client_state.cpp +++ b/client/client_state.cpp @@ -521,8 +521,10 @@ int CLIENT_STATE::init() { #endif } - parse_account_files(); - parse_statistics_files(); + if (!app_test) { + parse_account_files(); + parse_statistics_files(); + } // check for GPUs. // @@ -609,7 +611,11 @@ int CLIENT_STATE::init() { // ignoring any tags (and associated stuff) // for projects with no account file // - parse_state_file(); + if (app_test) { + app_test_init(); + } else { + parse_state_file(); + } bool new_client = is_new_client(); @@ -731,8 +737,10 @@ int CLIENT_STATE::init() { // do CPU scheduler and work fetch // request_schedule_cpus("Startup"); - request_work_fetch("Startup"); - work_fetch.init(); + if (!app_test) { + request_work_fetch("Startup"); + work_fetch.init(); + } rec_interval_start = now; // set up the project and slot directories @@ -1155,15 +1163,17 @@ bool CLIENT_STATE::poll_slow_events() { POLL_ACTION(schedule_cpus, schedule_cpus ); tasks_restarted = true; } - if (!network_suspended) { + if (!network_suspended && !app_test) { POLL_ACTION(scheduler_rpc , scheduler_rpc_poll ); } - retval = write_state_file_if_needed(); - if (retval) { - msg_printf(NULL, MSG_INTERNAL_ERROR, - "Couldn't write state file: %s; giving up", boincerror(retval) - ); - exit(EXIT_STATEFILE_WRITE); + if (!app_test) { + retval = write_state_file_if_needed(); + if (retval) { + msg_printf(NULL, MSG_INTERNAL_ERROR, + "Couldn't write state file: %s; giving up", boincerror(retval) + ); + exit(EXIT_STATEFILE_WRITE); + } } if (log_flags.poll_debug) { msg_printf(0, MSG_INFO, diff --git a/client/client_state.h b/client/client_state.h index bce4b7650f6..44f62df8d75 100644 --- a/client/client_state.h +++ b/client/client_state.h @@ -244,6 +244,11 @@ struct CLIENT_STATE { PROJECT_LIST project_list; void process_autologin(bool first); +// --------------- app_test.cpp: + bool app_test; + string app_test_file; + void app_test_init(); + // --------------- current_version.cpp: string newer_version; string client_version_check_url; diff --git a/client/cs_cmdline.cpp b/client/cs_cmdline.cpp index 1d14ec7b8b7..e7a624d6141 100644 --- a/client/cs_cmdline.cpp +++ b/client/cs_cmdline.cpp @@ -127,6 +127,9 @@ 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)) { + app_test = true; + app_test_file = argv[++i]; } else if (ARG(attach_project)) { if (i >= argc-2) { show_options = true; diff --git a/lib/msg_queue.cpp b/lib/msg_queue.cpp index 18860ef754c..4d65470f118 100644 --- a/lib/msg_queue.cpp +++ b/lib/msg_queue.cpp @@ -25,6 +25,7 @@ #include #endif +#include "boinc_stdio.h" #include "msg_queue.h" int create_message_queue(key_t key) { From ec78ce84d83712f7bd0ccfb7a2ef7bad13972f64 Mon Sep 17 00:00:00 2001 From: David Anderson Date: Mon, 18 Sep 2023 16:36:52 -0700 Subject: [PATCH 2/5] Change --app_test so that the test job runs alongside whatever jobs are already there. --- client/app_control.cpp | 4 +++- client/app_start.cpp | 4 +++- client/client_state.cpp | 32 +++++++++++++------------------- client/file_names.cpp | 3 +++ client/project.cpp | 1 + client/project.h | 2 ++ client/work_fetch.cpp | 10 ++++++---- 7 files changed, 31 insertions(+), 25 deletions(-) diff --git a/client/app_control.cpp b/client/app_control.cpp index 8612add3b50..6d6d6861796 100644 --- a/client/app_control.cpp +++ b/client/app_control.cpp @@ -609,7 +609,9 @@ void ACTIVE_TASK::handle_exited_app(int stat) { "read_stderr_file(): %s", boincerror(retval) ); } - client_clean_out_dir(slot_dir, "handle_exited_app()"); + if (!wup->project->app_test) { + client_clean_out_dir(slot_dir, "handle_exited_app()"); + } clear_schedule_backoffs(this); // clear scheduling backoffs of jobs waiting for GPU } diff --git a/client/app_start.cpp b/client/app_start.cpp index 127c4e7b59e..b0c34a601ee 100644 --- a/client/app_start.cpp +++ b/client/app_start.cpp @@ -691,7 +691,9 @@ int ACTIVE_TASK::start(bool test) { exit(0); } - if (gstate.app_test) { + // use special slot and exec path for test app + // + if (wup->project->app_test) { strcpy(slot_dir, "slots/app_test"); strcpy(exec_path, gstate.app_test_file.c_str()); } diff --git a/client/client_state.cpp b/client/client_state.cpp index 00f2c410599..0a32d53941e 100644 --- a/client/client_state.cpp +++ b/client/client_state.cpp @@ -521,10 +521,8 @@ int CLIENT_STATE::init() { #endif } - if (!app_test) { - parse_account_files(); - parse_statistics_files(); - } + parse_account_files(); + parse_statistics_files(); // check for GPUs. // @@ -611,10 +609,10 @@ int CLIENT_STATE::init() { // ignoring any tags (and associated stuff) // for projects with no account file // + parse_state_file(); + if (app_test) { app_test_init(); - } else { - parse_state_file(); } bool new_client = is_new_client(); @@ -737,10 +735,8 @@ int CLIENT_STATE::init() { // do CPU scheduler and work fetch // request_schedule_cpus("Startup"); - if (!app_test) { - request_work_fetch("Startup"); - work_fetch.init(); - } + request_work_fetch("Startup"); + work_fetch.init(); rec_interval_start = now; // set up the project and slot directories @@ -1163,17 +1159,15 @@ bool CLIENT_STATE::poll_slow_events() { POLL_ACTION(schedule_cpus, schedule_cpus ); tasks_restarted = true; } - if (!network_suspended && !app_test) { + if (!network_suspended) { POLL_ACTION(scheduler_rpc , scheduler_rpc_poll ); } - if (!app_test) { - retval = write_state_file_if_needed(); - if (retval) { - msg_printf(NULL, MSG_INTERNAL_ERROR, - "Couldn't write state file: %s; giving up", boincerror(retval) - ); - exit(EXIT_STATEFILE_WRITE); - } + retval = write_state_file_if_needed(); + if (retval) { + msg_printf(NULL, MSG_INTERNAL_ERROR, + "Couldn't write state file: %s; giving up", boincerror(retval) + ); + exit(EXIT_STATEFILE_WRITE); } if (log_flags.poll_debug) { msg_printf(0, MSG_INFO, diff --git a/client/file_names.cpp b/client/file_names.cpp index f8dea15a88c..bb55398fa69 100644 --- a/client/file_names.cpp +++ b/client/file_names.cpp @@ -227,6 +227,9 @@ void delete_old_slot_dirs() { safe_strcpy(filename, ""); retval = dir_scan(filename, dirp, sizeof(filename)); if (retval) break; + if (!strcmp(filename, "app_test")) { + continue; + } snprintf(path, sizeof(path), "%s/%s", SLOTS_DIR, filename); if (is_dir(path)) { #ifndef _WIN32 diff --git a/client/project.cpp b/client/project.cpp index 468ba3b3081..e83727e77de 100644 --- a/client/project.cpp +++ b/client/project.cpp @@ -126,6 +126,7 @@ void PROJECT::init() { app_configs.clear(); upload_backoff.is_upload = true; download_backoff.is_upload = false; + app_test = false; #ifdef SIM idle_time = 0; diff --git a/client/project.h b/client/project.h index 56b6d0ca427..9b8bc3c5503 100644 --- a/client/project.h +++ b/client/project.h @@ -202,6 +202,8 @@ struct PROJECT : PROJ_AM { std::vector user_files; std::vector project_files; // files not specific to apps or work - e.g. icons + bool app_test; + // this is the project created by --app_test ///////////////// member functions ///////////////// diff --git a/client/work_fetch.cpp b/client/work_fetch.cpp index e54cb0ab3d2..ae67a6538f0 100644 --- a/client/work_fetch.cpp +++ b/client/work_fetch.cpp @@ -736,11 +736,13 @@ void WORK_FETCH::setup() { PROJECT* WORK_FETCH::choose_project() { PROJECT* p; - if (log_flags.work_fetch_debug) { - msg_printf(0, MSG_INFO, "choose_project(): %f", gstate.now); - } p = non_cpu_intensive_project_needing_work(); - if (p) return p; + if (p) { + if (log_flags.work_fetch_debug) { + msg_printf(p, MSG_INFO, "[work_fetch] fetching work for NCI project"); + } + return p; + } setup(); From aa18db4890f9c24a1d5eda2bef87fac2e04f89f9 Mon Sep 17 00:00:00 2001 From: David Anderson Date: Mon, 18 Sep 2023 18:03:32 -0700 Subject: [PATCH 3/5] Oops! Forgot to add the key file --- client/app_test.cpp | 84 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 84 insertions(+) create mode 100644 client/app_test.cpp diff --git a/client/app_test.cpp b/client/app_test.cpp new file mode 100644 index 00000000000..5c899ee6cb8 --- /dev/null +++ b/client/app_test.cpp @@ -0,0 +1,84 @@ +// This file is part of BOINC. +// http://boinc.berkeley.edu +// Copyright (C) 2023 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 . + +// Set up data structures (project, app, app version, WU, result etc.) +// so that the client runs the given executable. +// Lets you debug client/app interactions with no server or fake XML files + +#include "project.h" +#include "client_types.h" +#include "result.h" +#include "client_state.h" +#include "log_flags.h" + +void CLIENT_STATE::app_test_init() { + PROJECT *proj = new PROJECT; + strcpy(proj->project_name, "test project"); + strcpy(proj->master_url, "test_project_url"); + strcpy(proj->_project_dir, "."); + proj->app_test = true; + projects.push_back(proj); + + APP *app = new APP; + strcpy(app->name, "test app"); + strcpy(app->user_friendly_name, "test app"); + app->project = proj; + apps.push_back(app); + + FILE_INFO *fip = new FILE_INFO; + strcpy(fip->name, app_test_file.c_str()); + fip->status = FILE_PRESENT; + fip->executable = true; + file_infos.push_back(fip); + + FILE_REF * fref = new FILE_REF; + fref->file_info = fip; + strcpy(fip->name, app_test_file.c_str()); + fref->main_program = true; + + APP_VERSION *av = new APP_VERSION; + strcpy(av->app_name, "test_av"); + strcpy(av->api_version, "8.0"); + av->app = app; + av->project = proj; + av->app_files.push_back(*fref); + app_versions.push_back(av); + + WORKUNIT *wu = new WORKUNIT; + strcpy(wu->name, "test_wu"); + strcpy(wu->app_name, "test_app"); + wu->project = proj; + wu->app = app; + wu->rsc_fpops_est = 1e9; + wu->rsc_fpops_bound = 1e12; + wu->rsc_memory_bound = 1e9; + wu->rsc_disk_bound = 1e9; + workunits.push_back(wu); + + RESULT *res = new RESULT; + strcpy(res->name, "test_result"); + strcpy(res->wu_name, "test_wu"); + res->project = proj; + res->avp = av; + res->wup = wu; + res->app = app; + res->report_deadline = dtime()+86400; + results.push_back(res); + + network_suspended = true; + cc_config.skip_cpu_benchmarks = true; +} From 13873bfb26b2d10894b20554aa6aab1642bcef03 Mon Sep 17 00:00:00 2001 From: davidpanderson Date: Mon, 18 Sep 2023 18:08:02 -0700 Subject: [PATCH 4/5] Add new file to Win solution --- win_build/boinc_cli.vcxproj | 1 + 1 file changed, 1 insertion(+) diff --git a/win_build/boinc_cli.vcxproj b/win_build/boinc_cli.vcxproj index fd84a615118..4c22ebf11d5 100644 --- a/win_build/boinc_cli.vcxproj +++ b/win_build/boinc_cli.vcxproj @@ -311,6 +311,7 @@ + From 8ea2aba1d89b9060370a2eee8f7477bdcdc999fe Mon Sep 17 00:00:00 2001 From: David Anderson Date: Mon, 18 Sep 2023 21:40:46 -0700 Subject: [PATCH 5/5] Add new file to Mac project file --- mac_build/boinc.xcodeproj/project.pbxproj | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/mac_build/boinc.xcodeproj/project.pbxproj b/mac_build/boinc.xcodeproj/project.pbxproj index 5e3dd53534a..edaecae0614 100644 --- a/mac_build/boinc.xcodeproj/project.pbxproj +++ b/mac_build/boinc.xcodeproj/project.pbxproj @@ -40,6 +40,8 @@ /* End PBXAggregateTarget section */ /* Begin PBXBuildFile section */ + 81FD378F2AB95D4A00E29818 /* app_test.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 81FD378E2AB95D4A00E29818 /* app_test.cpp */; }; + 81FD37902AB95D4A00E29818 /* app_test.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 81FD378E2AB95D4A00E29818 /* app_test.cpp */; }; B13E2D172655655000D5C977 /* detect_rosetta_cpu.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B13E2D162655655000D5C977 /* detect_rosetta_cpu.cpp */; }; DD000D6A24D0208E0083DE77 /* OpenGL.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DD89165E0F3B1BC200DE5B1C /* OpenGL.framework */; }; DD000D6B24D020940083DE77 /* OpenGL.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DD89165E0F3B1BC200DE5B1C /* OpenGL.framework */; }; @@ -887,6 +889,7 @@ /* Begin PBXFileReference section */ 20286C33FDCF999611CA2CEA /* Carbon.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Carbon.framework; path = /System/Library/Frameworks/Carbon.framework; sourceTree = ""; }; + 81FD378E2AB95D4A00E29818 /* app_test.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = app_test.cpp; sourceTree = ""; }; AA8B6B1B046C364400A80164 /* app_ipc.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = app_ipc.cpp; sourceTree = ""; }; AA8B6B1C046C364400A80164 /* app_ipc.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = app_ipc.h; path = ../lib/app_ipc.h; sourceTree = SOURCE_ROOT; }; AAA31C97042157A800A80164 /* shmem.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = shmem.cpp; sourceTree = ""; }; @@ -2075,6 +2078,7 @@ F54B8FBE02AC0A0C01FB7237 /* client */ = { isa = PBXGroup; children = ( + 81FD378E2AB95D4A00E29818 /* app_test.cpp */, DD344B3D07C5ABF40043025C /* acct_mgr.cpp */, DD344B3E07C5ABF40043025C /* acct_mgr.h */, DD33C6F608B5BB4500768630 /* acct_setup.h */, @@ -3959,6 +3963,7 @@ DD99172A1E69A92A00555337 /* mac_spawn.cpp in Sources */, DDE586B310FC8E9B00DFA887 /* mfile.cpp in Sources */, DD3741D610FC948C001257EB /* filesys.cpp in Sources */, + 81FD37902AB95D4A00E29818 /* app_test.cpp in Sources */, DD3741D910FC94BA001257EB /* url.cpp in Sources */, DD76BF9717CB465C0075936D /* opencl_boinc.cpp in Sources */, ); @@ -4073,6 +4078,7 @@ DD76BF9517CB45D20075936D /* opencl_boinc.cpp in Sources */, DD82D83C1F831E0500EEC6AD /* keyword.cpp in Sources */, DD6A829C181103990037172D /* thread.cpp in Sources */, + 81FD378F2AB95D4A00E29818 /* app_test.cpp in Sources */, DDDC2055183B560B00CB5845 /* mac_address.cpp in Sources */, DD55AF6D1916248200259439 /* coproc_sched.cpp in Sources */, );