00001 /*****************************************************************************\ 00002 * * 00003 * Name : test_file_transfer_tentacle * 00004 * Author : Chris Koeritz * 00005 * * 00006 * Purpose: * 00007 * * 00008 * Tests the file_transfer_tentacle without any networking involved. * 00009 * * 00010 ******************************************************************************* 00011 * Copyright (c) 2005-$now By Author. This program is free software; you can * 00012 * redistribute it and/or modify it under the terms of the GNU General Public * 00013 * License as published by the Free Software Foundation; either version 2 of * 00014 * the License or (at your option) any later version. This is online at: * 00015 * http://www.fsf.org/copyleft/gpl.html * 00016 * Please send any updates to: fred@gruntose.com * 00017 \*****************************************************************************/ 00018 00019 #include <basis/function.h> 00020 #include <basis/string_array.h> 00021 #include <opsystem/application_shell.h> 00022 #include <loggers/console_logger.h> 00023 #include <data_struct/static_memory_gremlin.h> 00024 #include <tentacles/recursive_file_copy.h> 00025 00026 #define LOG(s) CLASS_EMERGENCY_LOG(program_wide_logger(), s) 00027 00028 class test_file_transfer_tentacle : public application_shell 00029 { 00030 public: 00031 test_file_transfer_tentacle() : application_shell(static_class_name()) {} 00032 IMPLEMENT_CLASS_NAME("test_dirtree_fcopy"); 00033 int execute(); 00034 }; 00035 00036 int test_file_transfer_tentacle::execute() 00037 { 00038 FUNCDEF("execute"); 00039 00040 if (__argc < 3) { 00041 log("\ 00042 This program needs two parameters:\n\ 00043 a directory for the source root and one for the target root.\n\ 00044 Optionally, a third parameter may specify a starting point within the\n\ 00045 source root.\n\ 00046 Further, if fourth or more parameters are found, they are taken to be\n\ 00047 files to include; only they will be transferred.\n"); 00048 return 23; 00049 } 00050 00051 istring source_dir = __argv[1]; 00052 istring target_dir = __argv[2]; 00053 00054 istring source_start = ""; 00055 if (__argc >= 4) { 00056 source_start = __argv[3]; 00057 } 00058 00059 string_array includes; 00060 if (__argc >= 5) { 00061 for (int i = 4; i < __argc; i++) { 00062 includes += __argv[i]; 00063 } 00064 } 00065 00066 outcome returned = recursive_file_copy::copy_hierarchy(source_dir, 00067 target_dir, includes, source_start); 00068 00069 /* 00070 istring source_root = "snootums"; 00071 if (source_start.t()) { 00072 source_root += filename::default_separator() + source_start; 00073 } 00074 00075 tcpip_stack stack; 00076 octopus ring_leader(stack.hostname(), 10 * MEGABYTE); 00077 file_transfer_tentacle *tran = new file_transfer_tentacle(MAX_CHUNK, false); 00078 ring_leader.add_tentacle(tran); 00079 00080 outcome add_ret = tran->add_correspondence("snootums", source_dir, 00081 10 * MINUTE_ms); 00082 if (add_ret != tentacle::OKAY) 00083 deadly_error(class_name(), func, "failed to add the correspondence"); 00084 00085 file_transfer_infoton *initiate = new file_transfer_infoton; 00086 initiate->_request = true; 00087 initiate->_command = file_transfer_infoton::TREE_COMPARISON; 00088 initiate->_src_root = source_root; 00089 initiate->_dest_root = target_dir; 00090 directory_tree target_area(target_dir); 00091 target_area.calculate(); 00092 initiate->package_tree_info(target_area, includes); 00093 00094 octopus_entity ent = ring_leader.issue_identity(); 00095 octopus_request_id req_id(ent, 1); 00096 outcome start_ret = ring_leader.evaluate(initiate, req_id); 00097 if (start_ret != tentacle::OKAY) 00098 deadly_error(class_name(), func, "failed to start the comparison"); 00099 00100 file_transfer_infoton *reply_from_init 00101 = (file_transfer_infoton *)ring_leader.acquire_specific_result(req_id); 00102 if (!reply_from_init) 00103 deadly_error(class_name(), func, "no response to tree compare start"); 00104 00105 filename_list diffs; 00106 byte_array pack_copy = reply_from_init->_packed_data; 00107 if (!diffs.unpack(pack_copy)) 00108 deadly_error(class_name(), func, "could not unpack filename list!"); 00109 // LOG(istring("got list of diffs:\n") + diffs.text_form()); 00110 00111 octopus client_spider(stack.hostname(), 10 * MEGABYTE); 00112 file_transfer_tentacle *tran2 = new file_transfer_tentacle(MAX_CHUNK, false); 00113 tran2->register_file_transfer(ent, source_root, target_dir, includes); 00114 client_spider.add_tentacle(tran2); 00115 00116 octopus_request_id resp_id(ent, 2); 00117 outcome ini_resp_ret = client_spider.evaluate(reply_from_init, resp_id); 00118 if (ini_resp_ret != tentacle::OKAY) 00119 deadly_error(class_name(), func, "failed to process the start response!"); 00120 00121 infoton *junk = client_spider.acquire_specific_result(resp_id); 00122 if (junk) 00123 deadly_error(class_name(), func, "got a response we shouldn't have!"); 00124 00125 int iter = 0; 00126 while (true) { 00127 LOG(isprintf("ongoing chunk %d", ++iter)); 00128 00129 // keep going until we find a broken reply. 00130 file_transfer_infoton *ongoing = new file_transfer_infoton; 00131 ongoing->_request = true; 00132 ongoing->_command = file_transfer_infoton::PLACE_FILE_CHUNKS; 00133 ongoing->_src_root = source_root; 00134 ongoing->_dest_root = target_dir; 00135 00136 octopus_request_id chunk_id(ent, iter + 10); 00137 outcome place_ret = ring_leader.evaluate(ongoing, chunk_id); 00138 if (place_ret != tentacle::OKAY) 00139 deadly_error(class_name(), func, "failed to run ongoing transfer"); 00140 00141 file_transfer_infoton *reply = (file_transfer_infoton *)ring_leader 00142 .acquire_specific_result(chunk_id); 00143 if (!reply) 00144 deadly_error(class_name(), func, "failed to get ongoing transfer reply"); 00145 00146 if (!reply->_packed_data.length()) { 00147 LOG("hit termination condition: no data packed in for file chunks."); 00148 break; 00149 } 00150 00151 byte_array copy = reply->_packed_data; 00152 while (copy.length()) { 00153 file_transfer_header head; 00154 if (!head.unpack(copy)) 00155 deadly_error(class_name(), func, "failed to unpack header"); 00156 LOG(istring("header: ") + head.text_form()); 00157 LOG(isprintf("size in array: %d", copy.length())); 00158 if (copy.length() < head._length) 00159 deadly_error(class_name(), func, "not enough length in array"); 00160 copy.zap(0, head._length - 1); 00161 LOG(isprintf("size in array now: %d", copy.length())); 00162 } 00163 if (copy.length()) 00164 deadly_error(class_name(), func, "still had data in array"); 00165 00166 octopus_request_id resp_id(ent, iter + 11); 00167 outcome resp_ret = client_spider.evaluate(reply, resp_id); 00168 if (resp_ret != tentacle::OKAY) 00169 deadly_error(class_name(), func, "failed to process the transfer reply!"); 00170 00171 } 00172 */ 00173 00174 if (returned == common::OKAY) 00175 guards::alert_message("file_transfer_tentacle:: works for those " 00176 "functions tested."); 00177 else 00178 guards::alert_message(istring("file_transfer_tentacle:: failed with " 00179 "outcome=") + recursive_file_copy::outcome_name(returned)); 00180 return 0; 00181 } 00182 00183 HOOPLE_MAIN(test_file_transfer_tentacle, ) 00184
1.5.1