From c517c5d22b63297c58e6613ea50a754b1b2ee8c6 Mon Sep 17 00:00:00 2001 From: David Anderson Date: Mon, 26 Aug 2002 22:57:17 +0000 Subject: [PATCH] bug fixes svn path=/trunk/boinc/; revision=383 --- checkin_notes | 48 ++++++++++ client/app.C | 28 +++--- client/client_state.C | 42 ++++----- client/client_state.h | 36 ++++---- client/client_types.C | 12 ++- client/client_types.h | 2 + client/cs_scheduler.C | 2 +- client/file_xfer.C | 4 +- client/http.C | 10 +-- client/http.h | 10 ++- client/pers_file_xfer.C | 8 +- client/scheduler_op.C | 4 +- client/scheduler_op.h | 3 + db/db.h | 139 +++++++++++++++-------------- html/ops/db.inc | 172 ++++++++++++++++++++++++++++++++++++ html/ops/util.inc | 111 +++++++++++++++++++++++ lib/crypt_prog.C | 2 +- sched/file_upload_handler.C | 25 +++--- sched/handle_request.C | 89 +++++++++---------- sched/server_types.C | 10 ++- sched/server_types.h | 1 + test/init.inc | 53 ++++++++--- test/master.html | 19 +++- test/test_uc.php | 13 ++- 24 files changed, 623 insertions(+), 220 deletions(-) create mode 100644 html/ops/db.inc create mode 100644 html/ops/util.inc diff --git a/checkin_notes b/checkin_notes index 96b792ed6c..467b24e3f7 100755 --- a/checkin_notes +++ b/checkin_notes @@ -1710,3 +1710,51 @@ Eric August 26, 2002 app.h cs_apps.C +David August 26, 2002 + - adding missing clause to SCHEDULER_OP::poll(); was failing to + return state to IDLE, caused reply to get processed twice + - return user name, total credit, avg credit in scheduler RPC reply + - save/restore these in client state file + - client was trying to delete "checkpoint CPU file" in wrong directory + - change CLIENT_STATE field from "version" to "core_client_version" + - got rid of CLIENT_STATE::update_net_stats(), insert_file_xfer() + (made some stuff public) + - disable host performance measurement (temp! turn back on later) + - removed comments of the form + read_config_file(); // read config file + - in HTTP op of type POST2, it's not an error if htp->file is zero + - replaced hardwired HTTP_STATUS constants + - made separate db.inc, util.inc in html_ops + - key creation prints message before delay, not after + - file upload handler prints user name in error log lines + - scheduling server: make USER, HOST part of SCHEDULER_REPLY + so don't have to pass around as separate args + - in test/init.inc, don't use the init_db() from html_user/. + define it separately here. + - in test/init.inc, split up clear_data_dirs() into + client, server parts + - change test_uc.php to not create keys by default + + client/ + app.C + client_state.C,h + cs_scheduler.C + file_xfer.C + http.C,h + pers_file_xfer.C + scheduler_op.C,h + db/ + db.h + html_ops/ + db.inc (new) + util.inc (new) + lib/ + crypt_prog.C + sched/ + file_upload_handler.C + handle_request.C + server_types.C,h + test/ + init.inc + master.html + test_uc.php diff --git a/client/app.C b/client/app.C index 336053beb0..2ac8e6d1f6 100644 --- a/client/app.C +++ b/client/app.C @@ -446,12 +446,12 @@ bool ACTIVE_TASK_SET::poll() { atp->state = PROCESS_EXITED; atp->exit_status = WEXITSTATUS(stat); atp->result->exit_status = atp->exit_status; - if (log_flags.task_debug) printf("process exited status%d\n", atp->exit_status); + if (log_flags.task_debug) printf("process exited: status %d\n", atp->exit_status); } else if (WIFSIGNALED(stat)) { atp->state = PROCESS_WAS_SIGNALED; atp->signal = WTERMSIG(stat); atp->result->exit_status = atp->signal; - if (log_flags.task_debug) printf("process was signaled %d\n", atp->signal); + if (log_flags.task_debug) printf("process was signaled: %d\n", atp->signal); } else { atp->state = PROCESS_EXIT_UNKNOWN; atp->result->exit_status = -1; @@ -600,33 +600,39 @@ int ACTIVE_TASK_SET::restart_tasks() { // bool ACTIVE_TASK::check_app_status_files() { FILE* f; - char app_path[256]; + char path[256]; bool found = false; int retval; - sprintf(app_path, "%s/%s", slot_dir, CHECKPOINT_CPU_FILE); - f = fopen(app_path, "r"); + sprintf(path, "%s/%s", slot_dir, CHECKPOINT_CPU_FILE); + f = fopen(path, "r"); if (f) { found = true; parse_checkpoint_cpu_file(f, checkpoint_cpu_time); fclose(f); - retval = file_delete(CHECKPOINT_CPU_FILE); + retval = file_delete(path); if (retval) { - fprintf(stderr, "error: ACTIVE_TASK.check_app_status_files: could not delete file %s\n", CHECKPOINT_CPU_FILE); + fprintf(stderr, + "ACTIVE_TASK.check_app_status_files: could not delete %s: %d\n", + path, retval + ); } } - sprintf(app_path, "%s/%s", slot_dir, FRACTION_DONE_FILE); - f = fopen(app_path, "r"); + sprintf(path, "%s/%s", slot_dir, FRACTION_DONE_FILE); + f = fopen(path, "r"); if (f) { found = true; parse_fraction_done_file( f, current_cpu_time, fraction_done ); fclose(f); - retval = file_delete(app_path); + retval = file_delete(path); if (retval) { - fprintf(stderr, "error: ACTIVE_TASK.check_app_status_files: could not delete file %s\n", FRACTION_DONE_FILE); + fprintf(stderr, + "ACTIVE_TASK.check_app_status_files: could not delete %s: %d\n", + path, retval + ); } } return found; diff --git a/client/client_state.C b/client/client_state.C index 84fe19eb8d..667b7d583a 100644 --- a/client/client_state.C +++ b/client/client_state.C @@ -34,7 +34,6 @@ #define SECONDS_IN_MONTH 2592000 -// Global CLIENT_STATE object CLIENT_STATE gstate; CLIENT_STATE::CLIENT_STATE() { @@ -49,7 +48,7 @@ CLIENT_STATE::CLIENT_STATE() { giveup_after = PERS_GIVEUP; contacted_sched_server = false; activities_suspended = false; - version = VERSION; + core_client_version = VERSION; platform_name = HOST; exit_after = -1; app_started = 0; @@ -61,8 +60,8 @@ int CLIENT_STATE::init() { nslots = 1; - // Read the user preferences file, if it exists. If it doesn't, - // prompt user for project URL via initialize_prefs() + // Read the user preferences file, if it exists. + // If it doesn't, prompt user for project URL via initialize_prefs() // prefs = new PREFS; retval = prefs->parse_file(); @@ -79,7 +78,6 @@ int CLIENT_STATE::init() { } } - // Initialize the random number generator srand(clock()); // copy all PROJECTs from the prefs to the client state. @@ -126,31 +124,27 @@ bool CLIENT_STATE::run_time_tests() { )); } -// Updates computer statistics (roughly once a month) +// gets info about the host +// NOTE: this locks up the process for 10-20 seconds, +// so it should be called very seldom // int CLIENT_STATE::time_tests() { get_host_info(host_info); // this is platform dependent +#if 0 host_info.p_fpops = run_double_prec_test(4); //these are not host_info.p_iops = run_int_test(4); - //host_info.p_membw = run_mem_bandwidth_test(4); - host_info.p_membw = 100000; + host_info.p_membw = run_mem_bandwidth_test(4); + host_info.m_cache = check_cache_size(CACHE_MAX); +#else + host_info.p_fpops = 1000000000; + host_info.p_iops = 1000000000; + host_info.p_membw = 1000000000; + host_info.m_cache = 1000000; +#endif host_info.p_calculated = (double)time(0); //set time calculated - //host_info.m_cache = check_cache_size(CACHE_MAX); return 0; } -// Update the net_stats object, since it's private -// -void CLIENT_STATE::update_net_stats(bool is_upload, double nbytes, double nsecs) { - net_stats.update( is_upload, nbytes, nsecs ); -} - -// Insert an object into the file_xfers object, since it's private -// -int CLIENT_STATE::insert_file_xfer( FILE_XFER *fxp ) { - return file_xfers->insert(fxp); -} - // Return the maximum allowed disk usage as determined by user preferences. // Since there are three different settings in the prefs, it returns the least // of the three. @@ -275,7 +269,7 @@ int CLIENT_STATE::parse_state_file() { } // Init PERS_FILE_XFER and push it onto pers_file_xfer stack if (fip->pers_file_xfer) { - fip->pers_file_xfer->init( fip, fip->upload_when_present ); + fip->pers_file_xfer->init(fip, fip->upload_when_present); pers_xfers->insert( fip->pers_file_xfer ); } } else { @@ -373,9 +367,9 @@ int CLIENT_STATE::write_state_file() { active_tasks.write(f); fprintf(f, "%s\n" - "%d\n", + "%d\n", platform_name, - version + core_client_version ); fprintf(f, "\n"); fclose(f); diff --git a/client/client_state.h b/client/client_state.h index eaa660c340..eb37af24e7 100644 --- a/client/client_state.h +++ b/client/client_state.h @@ -35,23 +35,11 @@ #include "scheduler_op.h" #include "time_stats.h" +// CLIENT_STATE is the global variables of the core client +// Most of the state is saved to and restored from "client_state.xml" +// class CLIENT_STATE { public: - CLIENT_STATE(); - int init(); - int restart_tasks(); - int exit(); - bool do_something(); - void parse_cmdline(int argc, char** argv); - bool time_to_exit(); - bool run_time_tests(); - int time_tests(); - double current_disk_usage(); - double allowed_disk_usage(); - void update_net_stats(bool is_upload, double nbytes, double nsecs); - int insert_file_xfer( FILE_XFER *fxp ); - unsigned int giveup_after; - vector projects; vector apps; vector file_infos; @@ -66,11 +54,25 @@ public: ACTIVE_TASK_SET active_tasks; HOST_INFO host_info; PREFS* prefs; + NET_STATS net_stats; + + CLIENT_STATE(); + int init(); + int restart_tasks(); + int exit(); + bool do_something(); + void parse_cmdline(int argc, char** argv); + bool time_to_exit(); + bool run_time_tests(); + int time_tests(); + double current_disk_usage(); + double allowed_disk_usage(); + unsigned int giveup_after; + private: bool client_state_dirty; TIME_STATS time_stats; - NET_STATS net_stats; - int version; + int core_client_version; char* platform_name; unsigned int nslots; bool exit_when_idle; diff --git a/client/client_types.C b/client/client_types.C index 3f6539db1b..92a67201db 100644 --- a/client/client_types.C +++ b/client/client_types.C @@ -37,6 +37,8 @@ PROJECT::PROJECT() { resource_share = 0; strcpy(project_name,""); strcpy(user_name,""); + total_credit = 0; + expavg_credit = 0; rpc_seqno = 0; hostid = 0; exp_avg_cpu = 0; @@ -100,6 +102,8 @@ int PROJECT::parse_state(FILE* in) { else if (parse_str(buf, "", master_url)) continue; else if (parse_str(buf, "", project_name)) continue; else if (parse_str(buf, "", user_name)) continue; + else if (parse_double(buf, "", total_credit)) continue; + else if (parse_double(buf, "", expavg_credit)) continue; else if (parse_int(buf, "", rpc_seqno)) continue; else if (parse_int(buf, "", hostid)) continue; else if (parse_double(buf, "", exp_avg_cpu)) continue; @@ -115,7 +119,7 @@ int PROJECT::parse_state(FILE* in) { return ERR_XML_PARSE; } -// Write the project information to prefs.xml +// Write the project information to client state file // int PROJECT::write_state(FILE* out) { unsigned int i; @@ -133,6 +137,8 @@ int PROJECT::write_state(FILE* out) { " %s\n" " %s\n" " %s\n" + " %f\n" + " %f\n" " %d\n" " %d\n" " %f\n" @@ -142,6 +148,8 @@ int PROJECT::write_state(FILE* out) { master_url, project_name, user_name, + total_credit, + expavg_credit, rpc_seqno, hostid, exp_avg_cpu, @@ -166,6 +174,8 @@ void PROJECT::copy_state_fields(PROJECT& p) { scheduler_urls = p.scheduler_urls; strcpy( project_name, p.project_name ); strcpy( user_name, p.user_name ); + total_credit = p.total_credit; + expavg_credit = p.expavg_credit; rpc_seqno = p.rpc_seqno; hostid = p.hostid; exp_avg_cpu = p.exp_avg_cpu; diff --git a/client/client_types.h b/client/client_types.h index a354af467f..1a19d37487 100644 --- a/client/client_types.h +++ b/client/client_types.h @@ -61,6 +61,8 @@ public: vector scheduler_urls; // where to find scheduling servers char project_name[256]; // descriptive. not unique char user_name[256]; + double total_credit; // as reported by server + double expavg_credit; // as reported by server int rpc_seqno; int hostid; double exp_avg_cpu; // exponentially weighted CPU time diff --git a/client/cs_scheduler.C b/client/cs_scheduler.C index 0dab488d4b..5cc0a9a95d 100644 --- a/client/cs_scheduler.C +++ b/client/cs_scheduler.C @@ -183,7 +183,7 @@ int CLIENT_STATE::make_scheduler_request(PROJECT* p, double work_req) { p->hostid, p->rpc_seqno, platform_name, - version, + core_client_version, work_req ); if (p->code_sign_key) { diff --git a/client/file_xfer.C b/client/file_xfer.C index 310045b463..377eebabd3 100644 --- a/client/file_xfer.C +++ b/client/file_xfer.C @@ -106,7 +106,9 @@ int FILE_XFER::init_upload(FILE_INFO& file_info) { file_info.upload_offset ); file_size_query = false; - return HTTP_OP::init_post2(fip->get_url(), header, pathname, fip->upload_offset); + return HTTP_OP::init_post2( + fip->get_url(), header, pathname, fip->upload_offset + ); } } diff --git a/client/http.C b/client/http.C index 7ca0e03f8f..22e92cb931 100644 --- a/client/http.C +++ b/client/http.C @@ -434,10 +434,8 @@ bool HTTP_OP_SET::poll() { htp->http_op_state = HTTP_STATE_REPLY_HEADER; if (htp->file) { fclose(htp->file); - } else { - printf("HTTP_OP_SET::poll(): unexpected NULL file\n"); - } - htp->file = 0; + htp->file = 0; + } htp->do_file_io = false; htp->want_upload = false; htp->want_download = true; @@ -449,7 +447,7 @@ bool HTTP_OP_SET::poll() { if (log_flags.http_debug) printf("got reply header\n"); read_http_reply_header(htp->socket, htp->hrh); // TODO: handle all kinds of redirects here - if (htp->hrh.status == 301 || htp->hrh.status == 302) { + if (htp->hrh.status == HTTP_STATUS_MOVED_PERM || htp->hrh.status == HTTP_STATUS_MOVED_TEMP) { // Close the old socket htp->close_socket(); switch (htp->http_op_type) { @@ -472,7 +470,7 @@ bool HTTP_OP_SET::poll() { htp->open_server(); break; } - if (htp->hrh.status/100 != 2) { + if ((htp->hrh.status/100)*100 != HTTP_STATUS_OK) { htp->http_op_state = HTTP_STATE_DONE; htp->http_op_retval = htp->hrh.status; break; diff --git a/client/http.h b/client/http.h index d28b3e1658..426d144ce8 100644 --- a/client/http.h +++ b/client/http.h @@ -26,6 +26,12 @@ #include "net_xfer.h" +// official HTTP status codes +#define HTTP_STATUS_OK 200 +#define HTTP_STATUS_RANGE_REQUEST_ERROR 416 +#define HTTP_STATUS_MOVED_PERM 301 +#define HTTP_STATUS_MOVED_TEMP 302 + struct HTTP_REPLY_HEADER { int status; int content_length; @@ -87,14 +93,12 @@ public: #define HTTP_STATE_CONNECTING 1 #define HTTP_STATE_REQUEST_HEADER 2 #define HTTP_STATE_REQUEST_BODY1 3 + // sending the string part of a POST2 operation #define HTTP_STATE_REQUEST_BODY 4 #define HTTP_STATE_REPLY_HEADER 5 #define HTTP_STATE_REPLY_BODY 6 #define HTTP_STATE_DONE 7 -#define HTTP_OK 200 -#define HTTP_RANGE_REQUEST_ERROR 416 - extern int read_http_reply_header(int socket, HTTP_REPLY_HEADER&); #endif diff --git a/client/pers_file_xfer.C b/client/pers_file_xfer.C index daf2e77771..36453913e0 100644 --- a/client/pers_file_xfer.C +++ b/client/pers_file_xfer.C @@ -81,7 +81,7 @@ bool PERS_FILE_XFER::start_xfer() { (is_upload ? "upload" : "download"), fip->get_url(), retval ); } else { - retval = gstate.insert_file_xfer(file_xfer); + retval = gstate.file_xfers->insert(file_xfer); if (retval) return false; fxp = file_xfer; if (log_flags.file_xfer) { @@ -128,7 +128,7 @@ bool PERS_FILE_XFER::poll(unsigned int now) { if (fip->generated_locally) { // If the file was generated locally (for upload), update stats // and delete the local copy of the file if needed - gstate.update_net_stats(true, fip->nbytes, fxp->elapsed_time()); + gstate.net_stats.update(true, fip->nbytes, fxp->elapsed_time()); // file has been uploaded - delete if not sticky if (!fip->sticky) { @@ -139,7 +139,7 @@ bool PERS_FILE_XFER::poll(unsigned int now) { } else { // Otherwise we downloaded the file. Update stats, verify // the file with RSA or MD5, and change permissions - gstate.update_net_stats(false, fip->nbytes, fxp->elapsed_time()); + gstate.net_stats.update(false, fip->nbytes, fxp->elapsed_time()); get_pathname(fip, pathname); retval = verify_downloaded_file(pathname, *fip); if (retval) { @@ -175,7 +175,7 @@ bool PERS_FILE_XFER::poll(unsigned int now) { // void PERS_FILE_XFER::handle_xfer_failure(unsigned int cur_time) { // If it was a bad range request, delete the file and start over - if (fxp->file_xfer_retval == HTTP_RANGE_REQUEST_ERROR) { + if (fxp->file_xfer_retval == HTTP_STATUS_RANGE_REQUEST_ERROR) { fip->delete_file(); } diff --git a/client/scheduler_op.C b/client/scheduler_op.C index 7010f7d24e..7bad50c6c8 100644 --- a/client/scheduler_op.C +++ b/client/scheduler_op.C @@ -315,7 +315,9 @@ bool SCHEDULER_OP::poll() { } else { scheduler_op_done = true; } - } + } else { + scheduler_op_done = true; + } } } if (scheduler_op_done) { diff --git a/client/scheduler_op.h b/client/scheduler_op.h index 8010928f4c..9019739786 100644 --- a/client/scheduler_op.h +++ b/client/scheduler_op.h @@ -78,6 +78,9 @@ struct SCHEDULER_REPLY { char project_name[256]; int prefs_mod_time; char* prefs_xml; + char user_name[256]; + double total_credit; + double expavg_credit; vector apps; vector file_infos; vector app_versions; diff --git a/db/db.h b/db/db.h index 8a14eed487..d8d43727da 100644 --- a/db/db.h +++ b/db/db.h @@ -46,7 +46,7 @@ struct PROJECT { // struct PLATFORM { int id; - unsigned int create_time; // UNIX time of record creation + unsigned int create_time; char name[256]; // Platform name (i.e. "sparc-sun-solaris2.7") }; @@ -55,8 +55,8 @@ struct PLATFORM { // struct APP { int id; - unsigned int create_time; // UNIX time of record creation - char name[256]; // application name (i.e. "setiathome_4.0"), preferably short + unsigned int create_time; + char name[256]; // application name, preferably short int min_version; // don't use versions before this char result_xml_template[MAX_BLOB_SIZE]; // if any workunits have dynamic results, @@ -71,20 +71,20 @@ struct APP { // struct APP_VERSION { int id; - unsigned int create_time; // UNIX time of record creation - int appid; // id of APP record associated with this APP_VERSION - int version_num; // Version number - int platformid; // id of PLATFORM record associated with this APP_VERSION + unsigned int create_time; + int appid; + int version_num; + int platformid; - // describes app files. format: - // ... - // ... - // - // ... - // ... - // - // char xml_doc[MAX_BLOB_SIZE]; + // describes app files. format: + // ... + // ... + // + // ... + // ... + // + // // The following defined for apps other than core client. // They let you handle backwards-incompatible changes to @@ -105,50 +105,49 @@ struct APP_VERSION { struct USER { int id; - unsigned int create_time; // UNIX time of record creation - char email_addr[256]; // User email address - char name[256]; // User name - char web_password[256]; // User specifiable web password - char authenticator[256]; // Authenticator string, used to confirm email - // address when signing up for a project - char country[256]; // User country (selected from a list in countries.C) - char postal_code[256]; // User postal code + unsigned int create_time; + char email_addr[256]; + char name[256]; + char web_password[256]; + char authenticator[256]; + char country[256]; + char postal_code[256]; double total_credit; - double expavg_credit; // exponenially averaged credit - int expavg_time; // last time the above was computed - char prefs[MAX_BLOB_SIZE]; // Raw XML preferences data + double expavg_credit; // exponentially averaged credit + int expavg_time; // last time the above was computed + char prefs[MAX_BLOB_SIZE]; // XML preferences unsigned int prefs_mod_time; // When the preferences were last updated - int teamid; //if the user is part of a team + int teamid; // if the user is part of a team }; -#define TEAM_TYPE_COMPANY_SMALL 1 -#define TEAM_TYPE_COMPANY_MEDIUM 2 -#define TEAM_TYPE_COMPANY_LARGE 3 -#define TEAM_TYPE_CLUB 4 -#define TEAM_TYPE_PRIMARY 5 -#define TEAM_TYPE_SECONDARY 6 -#define TEAM_TYPE_UNIVERSITY 7 -#define TEAM_TYPE_JUNIOR_COLLEGE 8 -#define TEAM_TYPE_GOVERNMENT 9 +#define TEAM_TYPE_COMPANY_SMALL 1 +#define TEAM_TYPE_COMPANY_MEDIUM 2 +#define TEAM_TYPE_COMPANY_LARGE 3 +#define TEAM_TYPE_CLUB 4 +#define TEAM_TYPE_PRIMARY 5 +#define TEAM_TYPE_SECONDARY 6 +#define TEAM_TYPE_UNIVERSITY 7 +#define TEAM_TYPE_JUNIOR_COLLEGE 8 +#define TEAM_TYPE_GOVERNMENT 9 struct TEAM { int id; int userid; // User ID of team founder - char name[256]; // Team name + char name[256]; char name_lc[256]; // Team name in lowercase (used for searching) - char url[256]; // URL of team - int type; // Team type (company, club, etc, see above definitions) - char name_html[256]; // + char url[256]; + int type; // Team type (see above) + char name_html[256]; char description[256]; int nusers; }; struct HOST { int id; - unsigned int create_time; // UNIX time of record creation + unsigned int create_time; int userid; // ID of user running this host int rpc_seqno; // last seqno received from client - unsigned int rpc_time; // UNIX time of last scheduler RPC + unsigned int rpc_time; // time of last scheduler RPC // all remaining items are assigned by the client int timezone; @@ -159,28 +158,28 @@ struct HOST { double on_frac; // Fraction of the time (0-1) that the host is on double connected_frac; // Fraction of time that host is connected - double active_frac; // Fraction of time that host is actively doing tasks + double active_frac; // Fraction of time that host is enabled to work int p_ncpus; // Number of CPUs on host - char p_vendor[256]; // Vendor name of host CPU - char p_model[256]; // Model of host CPU - double p_fpops; // Approximate flop speed of host CPU - double p_iops; // Approximate integer op/sec speed of host CPU - double p_membw; // Approximate memory bandwidth of host + char p_vendor[256]; // Vendor name of CPU + char p_model[256]; // Model of CPU + double p_fpops; // Approximate floating point speed of CPU + double p_iops; // Approximate integer op/sec speed of CPU + double p_membw; // Approximate memory bandwidth of CPU double p_calculated; - char os_name[256]; // Name of host operating system - char os_version[256]; // Version of host operating system + char os_name[256]; // Name of operating system + char os_version[256]; // Version of operating system - double m_nbytes; // Size of host memory in bytes + double m_nbytes; // Size of memory in bytes double m_cache; // Size of CPU cache in bytes (L1 or L2?) - double m_swap; // Size of host swap space in bytes + double m_swap; // Size of swap space in bytes double d_total; // Total disk space double d_free; - double n_bwup; // Average upload bandwidth for host - double n_bwdown; // Average download bandwidth for host + double n_bwup; // Average upload bandwidth + double n_bwdown; // Average download bandwidth int parse(FILE*); int parse_time_stats(FILE*); @@ -189,20 +188,20 @@ struct HOST { struct WORKUNIT { int id; - unsigned int create_time; // UNIX time of record creation + unsigned int create_time; // time of record creation int appid; // ID of APP record tied to this workunit int previous_wuid; bool has_successor; char name[256]; // Name of the workunit char xml_doc[MAX_BLOB_SIZE]; int batch; - double rsc_fpops; // estimated # of FP operations - double rsc_iops; // estimated # of integer operations - double rsc_memory; // estimated size of RAM working set (bytes) - double rsc_disk; // estimated amount of disk needed (bytes) + double rsc_fpops; // estimated # of FP operations + double rsc_iops; // estimated # of integer operations + double rsc_memory; // estimated size of RAM working set (bytes) + double rsc_disk; // estimated amount of disk needed (bytes) bool dynamic_results; // whether to create new results on demand - int max_results; // 0 if no limit + int max_results; // 0 if no limit int nresults; int nresults_unsent; int nresults_done; @@ -221,16 +220,16 @@ struct WORKUNIT { struct RESULT { int id; - unsigned int create_time; // UNIX time of record creation - int workunitid; // ID of the workunit tied to this result - int state; // Current state of the processing for this result - int hostid; // ID of host currently processing this result - unsigned int report_deadline; // UNIX time deadline for receiving result - unsigned int sent_time; // UNIX time that result request was sent to host - unsigned int received_time; // UNIX time that result data was received from host - char name[256]; // Name of result - int exit_status; // Final exit status of application that processed result - double cpu_time; // Total CPU time required to complete result + unsigned int create_time; + int workunitid; + int state; // state (see above) + int hostid; // host processing this result + unsigned int report_deadline; // deadline for receiving result + unsigned int sent_time; // when result was sent to host + unsigned int received_time; // when result was received from host + char name[256]; + int exit_status; + double cpu_time; // CPU time used to complete result char xml_doc_in[MAX_BLOB_SIZE]; // descriptions of output files char xml_doc_out[MAX_BLOB_SIZE]; // MD5s of output files char stderr_out[MAX_BLOB_SIZE]; // stderr output, if any diff --git a/html/ops/db.inc b/html/ops/db.inc new file mode 100644 index 0000000000..6992f9a1b2 --- /dev/null +++ b/html/ops/db.inc @@ -0,0 +1,172 @@ +id); + row("created", time_str($platform->create_time)); + row("name", $platform->name); + echo ""; +} + +function show_app($app) { + start_table(); + row("ID", $app->id); + row("created", time_str($app->create_time)); + row("name", $app->name); + row("result template", "
".htmlspecialchars($app->result_xml_template)."
"); + echo ""; +} + +function show_app_version($app_version) { + start_table(); + row("ID", $app_version->id); + row("created", time_str($app_version->create_time)); + row("app ID", $app_version->appid); + row("version num", $app_version->version_num); + row("platform ID", $app_version->platformid); + row("XML doc", "
".htmlspecialchars($app_version->xml_doc)."
"); + row("min_core_version", $app_version->min_core_version); + row("max_core_version", $app_version->max_core_version); + row("message", $app_version->message); + row("deprecated", $app_version->deprecated); + echo ""; +} + +function show_host($host) { + + echo TABLE2."\n"; + echo "Below is information on all the hosts you have running the BOINC core client."; + echo "

"; + echo "".TD2.LG_FONT."Host Information:\n"; + row("IP address: ", "$host->last_ip_addr
(same the last $host->nsame_ip_addr times)"); + row("Domain name: ", $host->domain_name); + $x = $host->timezone/3600; + row("Time zone: ", "UTC - $x hours"); + row("Created: ", time_str($host->create_time)); + row("CPU: ", "$host->p_vendor $host->p_model"); + row("Number of CPUs: ", $host->p_ncpus); + row("Operating System: ", "$host->os_name $host->os_version"); + $x = $host->m_nbytes/(1024*1024); + $y = round($x, 2); + row("Memory: ", "$y MB"); + $x = $host->m_cache/1024; + $y = round($x, 2); + row("Cache: ", "$y KB"); + $x = $host->m_swap/(1024*1024); + $y = round($x, 2); + row("Swap Space: ", "$y MB"); + $x = $host->d_total/(1024*1024*1024); + $y = round($x, 2); + row("Total Disk Space: ", "$y GB"); + $x = $host->d_free/(1024*1024*1024); + $y = round($x, 2); + row("Free Disk Space: ", "$y GB"); + row("Avg network bandwidth:
(upstream)
", "$host->n_bwup bytes/sec"); + row("Avg network bandwidth:
(downstream)
", "$host->n_bwdown bytes/sec"); + row("Number of times client has contacted server: ", $host->rpc_seqno); + row("Last time contacted server: ", time_str($host->rpc_time)); + row("% of time client on: ", 100*$host->on_frac." %"); + row("% of time host connected: ", 100*$host->connected_frac." %"); + row("% of time user active: ", 100*$host->active_frac." %"); + echo "\n"; + +} + +function show_workunit($wu) { + start_table(); + row("created", time_str($wu->create_time)); + row("name", $wu->name); + row("XML doc", "

".htmlspecialchars($wu->xml_doc)."
"); + row("app ID", $wu->appid); + row("batch", $wu->batch); + row("FP operations", $wu->rsc_fpops); + row("integer operations", $wu->rsc_iops); + row("memory requirement", $wu->rsc_memory); + row("disk requirement", $wu->rsc_disk); + row("dynamic results", $wu->dynamic_results?"yes":"no"); + row("max_results", $wu->max_results); + row("nresults", $wu->nresults); + row("nresults_unsent", $wu->nresults_unsent); + row("nresults_done", $wu->nresults_done); + row("nresults_fail", $wu->nresults_fail); + echo ""; +} + +function res_state_string($s) { + switch($s) { + case 1: return "inactive"; + case 2: return "unsent"; + case 3: return "in progress"; + case 4: return "done"; + case 5: return "timeout"; + case 6: return "error"; + } +} + +function show_result($result) { + start_table(); + row("created", time_str($result->create_time)); + row("name", $result->name); + row("workunit ID", $result->workunitid); + row("state", res_state_string($result->state)); + row("host ID", $result->hostid); + row("sent", time_str($result->sent_time)); + row("received", time_str($result->received_time)); + row("exit status", $result->exit_status); + row("CPU time", $result->cpu_time); + row("XML doc in", "
".htmlspecialchars($result->xml_doc_in)."
"); + row("XML doc out", "
".htmlspecialchars($result->xml_doc_out)."
"); + row("stderr out", "
".htmlspecialchars($result->stderr_out)."
"); + row("batch", $result->batch); + row("validated", $result->validated); + echo ""; +} + +function show_user($user) { + start_table(); + row("created", time_str($user->create_time)); + row("total credit", $user->total_credit); + row("recent averaged credit:", $user->expavg_credit); + row("name", $user->name); + row("email address", $user->email_addr); + row("country", $user->country); + row("postal code", $user->postal_code); + echo "\n"; +} + +function show_team($team) { + start_table(); + row("ID", $team->id); + row("founder", $team->userid); + row("name", $team->name); + row("url", $team->url); + row("type", $team->type); + row("name_html", $team->name_html); + row("description", $team->description); +} + +?> diff --git a/html/ops/util.inc b/html/ops/util.inc new file mode 100644 index 0000000000..aa299bab58 --- /dev/null +++ b/html/ops/util.inc @@ -0,0 +1,111 @@ +"); +define("SM_FONT", ""); + +define("TD", ""); +define("TD2", ""); +define("TD3", ""); + +define("TABLE", ""); +define("TABLE2", "
"); + +define("BG_COLOR", " bgcolor=cccccc "); +define("TITLE_COLOR", " bgcolor=000000 "); +define("TITLE_FONT", " "); +define("BODY_COLOR", " bgcolor=ffffff "); +define("NOLOGIN", "Not logged in. Click here to login.\n"); +define("BADPASS", "The password you entered is incorrect. Click the Back button on your browser to re-enter your password or try again later."); +define("DIFFPASS", "You've typed two different passwords. Click the Back button on your browser to edit your information, making sure you type the same password in both password fields."); + +function get_project_name() { + $fp = fopen(db_name, "r"); + $db_name = fgets($fp, 1024); + $db_name = rtrim($db_name); + return $db_name; +} + +function get_user_from_cookie() { + $auth = ""; + $c = getenv("HTTP_COOKIE"); + $d = str_replace("; ", "&", $c); + parse_str($d); + if ($auth) return lookup_user_auth($auth); + return NULL; +} + +function show_login($user) { + if ($user) { + printf("Logged in as %s.\n", $user->name); + printf("
Log in as someone else.\n"); + $project = get_project_name(); + printf("
My %s\n", $project); + } else { + echo NOLOGIN; + } +} + +function page_head($title) { + echo "$title\n"; + $project = get_project_name(); + echo TABLE . "
" . TITLE_FONT . "".$project.": $title
\n"; +} + +function page_tail() { + echo "
| Create New Account | Login \n"; + echo "| User Page | Teams | Main Project Page |
\n"; +} + +function date_str($when) { + return date("g:i A, l M j", $when); +} + +function time_str($x) { + if ($x == 0) return "---"; + return strftime("%T %b %e, %Y", $x); +} + +function start_table() { + echo ""; +} + +function row($x, $y) { + echo "\n"; +} + +function row2($x, $y) { + echo "\n"; +} + +function row3($x, $y, $z) { + echo "\n"; +} + +function random_string() { + return md5(uniqid(rand())); +} + +function print_country_select() { + PassThru("/disks/milkyway/a/users/anderson/boinc/tools/country_select"); +} + +function print_page_header($title) { + echo "\n"; + echo "\n"; + echo "$title\n"; + echo "\n"; + echo "\n"; + echo "

\n"; +} + +function print_page_end() { + echo ""; +} + +?> diff --git a/lib/crypt_prog.C b/lib/crypt_prog.C index 449639efbe..da19404b12 100644 --- a/lib/crypt_prog.C +++ b/lib/crypt_prog.C @@ -39,6 +39,7 @@ main(int argc, char** argv) { exit(1); } if (!strcmp(argv[1], "-genkey")) { + printf("creating keys in %s and %s\n", argv[3], argv[4]); n = atoi(argv[2]); R_RandomCreate(&randomStruct); @@ -50,7 +51,6 @@ main(int argc, char** argv) { ); if (retval) die("R_GeneratePEMKeys\n"); - printf("creating keys in %s and %s\n", argv[3], argv[4]); fpriv = fopen(argv[3], "w"); if (!fpriv) die("fopen"); fpub = fopen(argv[4], "w"); diff --git a/sched/file_upload_handler.C b/sched/file_upload_handler.C index 5e6ce88376..a17e4a0349 100644 --- a/sched/file_upload_handler.C +++ b/sched/file_upload_handler.C @@ -71,7 +71,7 @@ int FILE_INFO::parse(FILE* in) { strcatdup(signed_xml, buf); if (parse_str(buf, "", name)) continue; if (parse_double(buf, "", max_nbytes)) continue; - //fprintf(stderr, "file_upload_handler: FILE_INFO::parse: unrecognized: %s \n", buf); + //fprintf(stderr, "file_upload_handler (%s): FILE_INFO::parse: unrecognized: %s \n", BOINC_USER, buf); } return 1; } @@ -79,10 +79,10 @@ int FILE_INFO::parse(FILE* in) { int print_status(int status, char* message) { printf("Content-type: text/plain\n\n%d\n", status); if (message) printf("%s\n", message); -#if 0 - fprintf(stderr, "Content-type: text/plain\n\n%d\n", status); - if (message) fprintf(stderr, "%s\n", message); -#endif + fprintf(stderr, + "file_upload_handler (%s): status %d: %s>\n", + BOINC_USER, status, message + ); return 0; } @@ -145,14 +145,16 @@ int handle_request(FILE* in, R_RSA_PUBLIC_KEY& key) { if (match_tag(buf, "")) { retval = file_info.parse(in); if (retval) { - fprintf(stderr, "file_upload_handler: FILE_INFO.parse\n"); + fprintf(stderr, + "file_upload_handler (%s): FILE_INFO.parse\n", + BOINC_USER + ); return retval; } retval = verify_string( file_info.signed_xml, file_info.xml_signature, key, is_valid ); if (retval || !is_valid) { - fprintf(stderr, "invalid XML signature\n"); print_status(-1, "invalid XML signature"); return -1; } @@ -175,14 +177,12 @@ int handle_request(FILE* in, R_RSA_PUBLIC_KEY& key) { else if (parse_double(buf, "", nbytes)) continue; else if (match_tag(buf, "")) { if (nbytes == 0) { - fprintf(stderr, "nbytes missing\n"); print_status(-1, "nbytes missing"); return -1; } // enforce limits in signed XML if (nbytes > file_info.max_nbytes) { - fprintf(stderr, "nbytes too large\n"); sprintf(buf, "nbytes too large: %f > %f", nbytes, file_info.max_nbytes @@ -193,8 +193,11 @@ int handle_request(FILE* in, R_RSA_PUBLIC_KEY& key) { sprintf(path, "%s/%s", BOINC_UPLOAD_DIR, file_info.name); retval = copy_socket_to_file(in, path, offset, nbytes); - if(retval) { - fprintf(stderr, "file_upload_handler: copy_socket_to_file\n"); + if (retval) { + fprintf(stderr, + "file_upload_handler (%s): copy_socket_to_file %d %s\n", + BOINC_USER, retval, path + ); } break; } diff --git a/sched/handle_request.C b/sched/handle_request.C index 6a98b4f282..e8fa357814 100644 --- a/sched/handle_request.C +++ b/sched/handle_request.C @@ -97,25 +97,23 @@ int add_wu_to_reply( // If no host ID is supplied, or if RPC seqno mismatch, // create a new host record and return its ID // -int authenticate_user( - SCHEDULER_REQUEST& sreq, SCHEDULER_REPLY& reply, USER& user, HOST& host -) { +int authenticate_user(SCHEDULER_REQUEST& sreq, SCHEDULER_REPLY& reply) { int retval; if (sreq.hostid) { - retval = db_host(sreq.hostid, host); + retval = db_host(sreq.hostid, reply.host); if (retval) { strcpy(reply.message, "Can't find host record"); strcpy(reply.message_priority, "low"); return -1; } - retval = db_user(host.userid, user); + retval = db_user(reply.host.userid, reply.user); if (retval) { strcpy(reply.message, "Can't find user record"); strcpy(reply.message_priority, "low"); return -1; } - if (strcmp(sreq.authenticator, user.authenticator)) { + if (strcmp(sreq.authenticator, reply.user.authenticator)) { strcpy(reply.message, "Invalid or missing authenticator. " "Visit this project's web site to get an authenticator." @@ -127,36 +125,39 @@ int authenticate_user( // If the seqno from the host is less than what we expect, // the user must have copied the state file to a different host. // Make a new host record. - if (sreq.rpc_seqno < host.rpc_seqno) { + if (sreq.rpc_seqno < reply.host.rpc_seqno) { sreq.hostid = 0; goto new_host; } - host.rpc_seqno = sreq.rpc_seqno; - host.rpc_time = time(0); + reply.host.rpc_seqno = sreq.rpc_seqno; + reply.host.rpc_time = time(0); } else { - strcpy(user.authenticator, sreq.authenticator); - retval = db_user_lookup_auth(user); + strcpy(reply.user.authenticator, sreq.authenticator); + retval = db_user_lookup_auth(reply.user); if (retval) { strcpy(reply.message, "Invalid or missing authenticator"); strcpy(reply.message_priority, "low"); return -1; } new_host: - host = sreq.host; - host.id = 0; - host.create_time = time(0); - host.userid = user.id; - host.rpc_seqno = 0; - host.rpc_time = time(0); - retval = db_host_new(host); + // reply.user is filled in and valid at this point + // + reply.host = sreq.host; + reply.host.id = 0; + reply.host.create_time = time(0); + reply.host.userid = reply.user.id; + reply.host.rpc_seqno = 0; + reply.host.rpc_time = time(0); + retval = db_host_new(reply.host); if (retval) { strcpy(reply.message, "server database error"); strcpy(reply.message_priority, "low"); db_print_error("db_host_new"); return -1; } - host.id = db_insert_id(); - reply.hostid = host.id; + reply.host.id = db_insert_id(); + reply.hostid = reply.host.id; + // this tells client to updates its host ID } return 0; } @@ -205,16 +206,16 @@ int update_host_record(SCHEDULER_REQUEST& sreq, HOST& host) { // update user record in DB. // If we our DB has more recent prefs than client's, send them. // -int handle_prefs(SCHEDULER_REQUEST& sreq, SCHEDULER_REPLY& reply, USER& user) { - if (sreq.prefs_mod_time > user.prefs_mod_time && strlen(sreq.prefs_xml)) { - strcpy(user.prefs, sreq.prefs_xml); - user.prefs_mod_time = sreq.prefs_mod_time; - if (user.prefs_mod_time > (unsigned)time(0)) { - user.prefs_mod_time = (unsigned)time(0); +int handle_prefs(SCHEDULER_REQUEST& sreq, SCHEDULER_REPLY& reply) { + if (sreq.prefs_mod_time > reply.user.prefs_mod_time && strlen(sreq.prefs_xml)) { + strcpy(reply.user.prefs, sreq.prefs_xml); + reply.user.prefs_mod_time = sreq.prefs_mod_time; + if (reply.user.prefs_mod_time > (unsigned)time(0)) { + reply.user.prefs_mod_time = (unsigned)time(0); } - db_user_update(user); + db_user_update(reply.user); } - if (user.prefs_mod_time > sreq.prefs_mod_time) { + if (reply.user.prefs_mod_time > sreq.prefs_mod_time) { reply.send_prefs = true; } return 0; @@ -222,9 +223,7 @@ int handle_prefs(SCHEDULER_REQUEST& sreq, SCHEDULER_REPLY& reply, USER& user) { // handle completed results // -int handle_results( - SCHEDULER_REQUEST& sreq, SCHEDULER_REPLY& reply, HOST& host -) { +int handle_results(SCHEDULER_REQUEST& sreq, SCHEDULER_REPLY& reply) { unsigned int i; int retval; RESULT result, *rp; @@ -244,7 +243,7 @@ int handle_results( // TODO: handle error returns // - result.hostid = host.id; + result.hostid = reply.host.id; result.received_time = time(0); result.exit_status = rp->exit_status; result.cpu_time = rp->cpu_time; @@ -276,7 +275,7 @@ int handle_results( int send_work( SCHEDULER_REQUEST& sreq, SCHEDULER_REPLY& reply, PLATFORM& platform, - HOST& host, SCHED_SHMEM& ss + SCHED_SHMEM& ss ) { int i, retval, nresults = 0, seconds_to_fill; WORKUNIT wu; @@ -299,7 +298,7 @@ int send_work( // the following should be a critical section // if (!ss.wu_results[i].present || - !wu_is_feasible(ss.wu_results[i].workunit, host) + !wu_is_feasible(ss.wu_results[i].workunit, reply.host) ) { continue; } @@ -308,15 +307,15 @@ int send_work( ss.wu_results[i].present = false; retval = add_wu_to_reply(wu, reply, platform, ss, - estimate_duration(wu, host) + estimate_duration(wu, reply.host) ); if (retval) continue; reply.insert_result(result); - seconds_to_fill -= (int)estimate_duration(wu, host); + seconds_to_fill -= (int)estimate_duration(wu, reply.host); nresults++; result.state = RESULT_STATE_IN_PROGRESS; - result.hostid = host.id; + result.hostid = reply.host.id; result.sent_time = time(0); db_result_update(result); @@ -337,7 +336,7 @@ int send_work( result.create_time = time(0); result.workunitid = wu.id; result.state = RESULT_STATE_IN_PROGRESS; - result.hostid = host.id; + result.hostid = reply.host.id; result.sent_time = time(0); sprintf(result.name, "result_%d", result.id); app = db.lookup_app(wu.appid); @@ -415,16 +414,14 @@ void process_request( SCHEDULER_REQUEST& sreq, SCHEDULER_REPLY& reply, SCHED_SHMEM& ss, char* code_sign_key ) { - HOST host; - USER user; PLATFORM* platform; int retval; char buf[256]; - retval = authenticate_user(sreq, reply, user, host); + retval = authenticate_user(sreq, reply); if (retval) return; - retval = update_host_record(sreq, host); + retval = update_host_record(sreq, reply.host); // look up the client's platform in the DB // @@ -436,13 +433,11 @@ void process_request( return; } - reply.user = user; + handle_prefs(sreq, reply); - handle_prefs(sreq, reply, user); + handle_results(sreq, reply); - handle_results(sreq, reply, host); - - send_work(sreq, reply, *platform, host, ss); + send_work(sreq, reply, *platform, ss); send_code_sign_key(sreq, reply, code_sign_key); } diff --git a/sched/server_types.C b/sched/server_types.C index 6f03e6275b..b3aeecbb2f 100644 --- a/sched/server_types.C +++ b/sched/server_types.C @@ -114,7 +114,15 @@ int SCHEDULER_REPLY::write(FILE* fout) { gproject.name ); - + fprintf(fout, + "%s\n" + "%f\n" + "%f\n", + user.name, + user.total_credit, + user.expavg_credit + ); + if (request_delay) { fprintf(fout, "%d\n", request_delay); } diff --git a/sched/server_types.h b/sched/server_types.h index 8b772d5fb9..bee9a1b2ca 100644 --- a/sched/server_types.h +++ b/sched/server_types.h @@ -52,6 +52,7 @@ struct SCHEDULER_REPLY { // this tells client to reset rpc_seqno bool send_prefs; // whether to send preferences USER user; + HOST host; vector apps; vector app_versions; vectorwus; diff --git a/test/init.inc b/test/init.inc index 44f6717ba4..28c2725d17 100644 --- a/test/init.inc +++ b/test/init.inc @@ -4,7 +4,6 @@ define("VERSION", "1"); define("CORE_CLIENT", "boinc_".VERSION."_$BOINC_PLATFORM"); define("PROJECTS", "localhost.localdomain zoot"); -include_once("../html_user/db.inc"); function clear_db() { PassThru("cd ../db; init_db"); @@ -17,6 +16,22 @@ $BOINC_EMAIL = null; $BOINC_DOWNLOAD_URL = null; $BOINC_KEY_DIR = null; $BOINC_MASTER_URL = null; +$BOINC_DB_NAME = null; + +function open_db() { + global $BOINC_DB_NAME; + + $retval = mysql_connect(); + if (!$retval) { + echo "mysql_connect() failed\n"; + exit(); + } + $retval = mysql_select_db($BOINC_DB_NAME); + if (!$retval) { + echo "mysql_select_db() failed\n"; + exit(); + } +} function check_env_vars() { global $BOINC_DOWNLOAD_DIR; @@ -26,6 +41,7 @@ function check_env_vars() { global $BOINC_DOWNLOAD_URL; global $BOINC_KEY_DIR; global $BOINC_MASTER_URL; + global $BOINC_DB_NAME; $bad = false; $BOINC_DOWNLOAD_DIR = getenv("BOINC_DOWNLOAD_DIR"); @@ -63,38 +79,47 @@ function check_env_vars() { echo "Must define BOINC_MASTER_URL\n"; $bad = true; } + $BOINC_DB_NAME = getenv("BOINC_DB_NAME"); + if ($BOINC_DB_NAME == null) { + echo "Must define BOINC_DB_NAME\n"; + $bad = true; + } if ($bad) exit(); } -function clear_data_dirs() { +function clear_server_dirs($clear_key_dir) { global $BOINC_DOWNLOAD_DIR; global $BOINC_UPLOAD_DIR; + global $BOINC_KEY_DIR; - $BOINC_DOWNLOAD_DIR = getenv("BOINC_DOWNLOAD_DIR"); if ($BOINC_DOWNLOAD_DIR == null) { echo "Must define BOINC_DOWNLOAD_DIR\n"; $bad = true; } - $BOINC_UPLOAD_DIR = getenv("BOINC_UPLOAD_DIR"); if ($BOINC_UPLOAD_DIR == null) { echo "Must define BOINC_UPLOAD_DIR\n"; $bad = true; } - $BOINC_KEY_DIR = getenv("BOINC_KEY_DIR"); if ($BOINC_KEY_DIR == null) { echo "Must define BOINC_KEY_DIR\n"; $bad = true; } - $MASTER_URL = urlencode(stripslashes(stripslashes(getenv("BOINC_MASTER_URL")))); - if ($MASTER_URL == null) { - echo "Must define BOINC_MASTER_URL\n"; - $bad = true; - } if ($bad) exit(); PassThru("rm -f $BOINC_DOWNLOAD_DIR/*"); PassThru("rm -f $BOINC_UPLOAD_DIR/*"); - PassThru("rm -f $BOINC_KEY_DIR/*"); + if ($clear_key_dir) { + PassThru("rm -f $BOINC_KEY_DIR/*"); + } +} + +function clear_client_dirs() { + $MASTER_URL = urlencode(stripslashes(stripslashes(getenv("BOINC_MASTER_URL")))); + if ($MASTER_URL == null) { + echo "Must define BOINC_MASTER_URL\n"; + $bad = true; + } + if ($bad) exit(); PassThru("rm -f $MASTER_URL/*" ); } @@ -230,7 +255,7 @@ function compare_file($out, $correct) { } function check_results_done() { - db_init(); + open_db(); $result = mysql_query("select * from result where state<>4"); while ($x = mysql_fetch_object($result)) { echo "result $x->id is not done\n"; @@ -238,7 +263,7 @@ function check_results_done() { } function num_wus_left() { - db_init(); + open_db(); $numwus = mysql_query("select count(*) as nres from result where state<>4"); $result = mysql_fetch_object($numwus); return $result->nres; @@ -271,7 +296,7 @@ function get_time($file_name) { function compare_time($app_time) { $epsilon = 0.0001; - db_init(); + open_db(); $data = mysql_query("select cpu_time from result where name = 'uccpu_wu_0'"); $result = mysql_fetch_object($data); $db_time = $result->cpu_time; diff --git a/test/master.html b/test/master.html index 60044e2e7a..2f57a59f15 100644 --- a/test/master.html +++ b/test/master.html @@ -1,3 +1,16 @@ -

Test BOINC Project

- -http://localhost/boinc-cgi/cgi + +BOINC Test Project + + +

BOINC Test Project

+

+

+ + diff --git a/test/test_uc.php b/test/test_uc.php index fe6fb34218..9bd5528719 100644 --- a/test/test_uc.php +++ b/test/test_uc.php @@ -8,8 +8,13 @@ check_env_vars(); clear_db(); - clear_data_dirs(); - create_keys(); + if (true) { + clear_server_dirs(false); + } else { + clear_server_dirs(true); + create_keys(); + } + clear_client_dirs(); init_client_dirs("prefs1.xml"); copy_to_download_dir("input"); add_project("Test Project"); @@ -18,8 +23,8 @@ add_app("upper_case", null, null); create_work("-appname upper_case -rsc_iops 180000000000.0 -rsc_fpops 0.0 -wu_name uc_wu -wu_template uc_wu -result_template uc_result -nresults 2 input input input input input"); start_feeder(); - //run_client("-exit_after 10"); - run_client("-exit_when_idle"); + run_client("-exit_after 10"); + //run_client("-exit_when_idle"); stop_feeder(); check_results_done(); compare_file("uc_wu_0_0", "uc_correct_output");
$x$y
$x$y
$x$y$z