feisty meow concerns codebase  2.140
t_file_transfer.cpp
Go to the documentation of this file.
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>
22 #include <loggers/console_logger.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 
#define DEFINE_CLASS_NAME(objname)
Defines the name of a class by providing a couple standard methods.
Definition: enhance_cpp.h:45
#define FUNCDEF(func_in)
FUNCDEF sets the name of a function (and plugs it into the callstack).
Definition: enhance_cpp.h:57
#define HOOPLE_MAIN(obj_name, obj_args)
options that should work for most unix and linux apps.
Definition: hoople_main.h:61
string_array(1, math_list))) const char *addr_list[]
#define static_class_name()