getting these octopus tests updated. not quite there yet.
[feisty_meow.git] / octopi / library / tests_octopus / t_file_transfer.cpp
1 /*****************************************************************************\
2 *                                                                             *
3 *  Name   : test_file_transfer_tentacle                                       *
4 *  Author : Chris Koeritz                                                     *
5 *                                                                             *
6 *  Purpose:                                                                   *
7 *                                                                             *
8 *    Tests the file_transfer_tentacle without any networking involved.        *
9 *                                                                             *
10 *******************************************************************************
11 * Copyright (c) 2005-$now By Author.  This program is free software; you can  *
12 * redistribute it and/or modify it under the terms of the GNU General Public  *
13 * License as published by the Free Software Foundation; either version 2 of   *
14 * the License or (at your option) any later version.  This is online at:      *
15 *     http://www.fsf.org/copyleft/gpl.html                                    *
16 * Please send any updates to: fred@gruntose.com                               *
17 \*****************************************************************************/
18
19 #include <basis/functions.h>
20 #include <structures/string_array.h>
21 #include <structures/static_memory_gremlin.h>
22 #include <loggers/console_logger.h>
23 #include <application/application_shell.h>
24 #include <tentacles/file_transfer_tentacle.h>
25 #include <tentacles/recursive_file_copy.h>
26
27 #define LOG(s) CLASS_EMERGENCY_LOG(program_wide_logger::get(), s)
28
29 class test_file_transfer_tentacle : public application_shell
30 {
31 public:
32   test_file_transfer_tentacle() : application_shell(static_class_name()) {}
33   DEFINE_CLASS_NAME("test_dirtree_fcopy");
34   int execute();
35 };
36
37 int test_file_transfer_tentacle::execute()
38 {
39   FUNCDEF("execute");
40
41   if (__argc < 3) {
42     log("\
43 This program needs two parameters:\n\
44 a directory for the source root and one for the target root.\n\
45 Optionally, a third parameter may specify a starting point within the\n\
46 source root.\n\
47 Further, if fourth or more parameters are found, they are taken to be\n\
48 files to include; only they will be transferred.\n");
49     return 23;
50   }
51
52   astring source_dir = __argv[1];
53   astring target_dir = __argv[2];
54
55   astring source_start = "";
56   if (__argc >= 4) {
57     source_start = __argv[3];
58   }
59
60   string_array includes;
61   if (__argc >= 5) {
62     for (int i = 4; i < __argc; i++) {
63       includes += __argv[i];
64     }
65   }
66
67
68   outcome returned = recursive_file_copy::copy_hierarchy
69       (file_transfer_tentacle::COMPARE_SIZE_AND_TIME, source_dir,
70       target_dir, includes, source_start);
71
72 /*
73   astring source_root = "snootums";
74   if (source_start.t()) {
75     source_root += filename::default_separator() + source_start;
76   }
77
78   tcpip_stack stack;
79   octopus ring_leader(stack.hostname(), 10 * MEGABYTE);
80   file_transfer_tentacle *tran = new file_transfer_tentacle(MAX_CHUNK, false);
81   ring_leader.add_tentacle(tran);
82
83   outcome add_ret = tran->add_correspondence("snootums", source_dir,
84       10 * MINUTE_ms);
85   if (add_ret != tentacle::OKAY)
86     deadly_error(class_name(), func, "failed to add the correspondence");
87
88   file_transfer_infoton *initiate = new file_transfer_infoton;
89   initiate->_request = true;
90   initiate->_command = file_transfer_infoton::TREE_COMPARISON;
91   initiate->_src_root = source_root;
92   initiate->_dest_root = target_dir;
93   directory_tree target_area(target_dir);
94   target_area.calculate();
95   initiate->package_tree_info(target_area, includes);
96
97   octopus_entity ent = ring_leader.issue_identity();
98   octopus_request_id req_id(ent, 1);
99   outcome start_ret = ring_leader.evaluate(initiate, req_id);
100   if (start_ret != tentacle::OKAY)
101     deadly_error(class_name(), func, "failed to start the comparison");
102
103   file_transfer_infoton *reply_from_init
104       = (file_transfer_infoton *)ring_leader.acquire_specific_result(req_id);
105   if (!reply_from_init)
106     deadly_error(class_name(), func, "no response to tree compare start");
107
108   filename_list diffs;
109   byte_array pack_copy = reply_from_init->_packed_data;
110   if (!diffs.unpack(pack_copy))
111     deadly_error(class_name(), func, "could not unpack filename list!");
112 //  LOG(astring("got list of diffs:\n") + diffs.text_form());
113
114   octopus client_spider(stack.hostname(), 10 * MEGABYTE);
115   file_transfer_tentacle *tran2 = new file_transfer_tentacle(MAX_CHUNK, false);
116   tran2->register_file_transfer(ent, source_root, target_dir, includes);
117   client_spider.add_tentacle(tran2);
118
119   octopus_request_id resp_id(ent, 2);
120   outcome ini_resp_ret = client_spider.evaluate(reply_from_init, resp_id);
121   if (ini_resp_ret != tentacle::OKAY)
122     deadly_error(class_name(), func, "failed to process the start response!");
123
124   infoton *junk = client_spider.acquire_specific_result(resp_id);
125   if (junk)
126     deadly_error(class_name(), func, "got a response we shouldn't have!");
127
128   int iter = 0;
129   while (true) {
130 LOG(a_sprintf("ongoing chunk %d", ++iter));
131
132     // keep going until we find a broken reply.
133     file_transfer_infoton *ongoing = new file_transfer_infoton;
134     ongoing->_request = true;
135     ongoing->_command = file_transfer_infoton::PLACE_FILE_CHUNKS;
136     ongoing->_src_root = source_root;
137     ongoing->_dest_root = target_dir;
138
139     octopus_request_id chunk_id(ent, iter + 10);
140     outcome place_ret = ring_leader.evaluate(ongoing, chunk_id);
141     if (place_ret != tentacle::OKAY)
142       deadly_error(class_name(), func, "failed to run ongoing transfer");
143   
144     file_transfer_infoton *reply = (file_transfer_infoton *)ring_leader
145          .acquire_specific_result(chunk_id);
146     if (!reply)
147       deadly_error(class_name(), func, "failed to get ongoing transfer reply");
148
149     if (!reply->_packed_data.length()) {
150       LOG("hit termination condition: no data packed in for file chunks.");
151       break;
152     }
153
154     byte_array copy = reply->_packed_data;
155     while (copy.length()) {
156       file_transfer_header head;
157       if (!head.unpack(copy)) 
158         deadly_error(class_name(), func, "failed to unpack header");
159 LOG(astring("header: ") + head.text_form());
160 LOG(a_sprintf("size in array: %d", copy.length()));
161       if (copy.length() < head._length)
162         deadly_error(class_name(), func, "not enough length in array");
163       copy.zap(0, head._length - 1);
164 LOG(a_sprintf("size in array now: %d", copy.length()));
165     }
166     if (copy.length())
167       deadly_error(class_name(), func, "still had data in array");
168
169     octopus_request_id resp_id(ent, iter + 11);
170     outcome resp_ret = client_spider.evaluate(reply, resp_id);
171     if (resp_ret != tentacle::OKAY)
172       deadly_error(class_name(), func, "failed to process the transfer reply!");
173   
174   }
175 */
176
177   if (returned == common::OKAY)
178     guards::alert_message("file_transfer_tentacle:: works for those "
179         "functions tested.");
180   else
181     guards::alert_message(astring("file_transfer_tentacle:: failed with "
182         "outcome=") + recursive_file_copy::outcome_name(returned));
183   return 0;
184 }
185
186 HOOPLE_MAIN(test_file_transfer_tentacle, )
187