feisty meow concerns codebase  2.140
test_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 
21 #include <basis/functions.h>
22 #include <filesystem/directory.h>
23 #include <filesystem/filename.h>
24 #include <loggers/console_logger.h>
26 #include <mathematics/chaos.h>
32 #include <unit_test/unit_base.h>
33 
34 using namespace application;
35 using namespace basis;
36 using namespace filesystem;
37 using namespace loggers;
38 using namespace mathematics;
39 using namespace octopi;
40 using namespace processes;
41 using namespace structures;
42 using namespace textual;
43 using namespace unit_test;
44 
45 #define LOG(s) CLASS_EMERGENCY_LOG(program_wide_logger::get(), astring(s))
46 
47 class test_file_transfer_tentacle : virtual public unit_base, virtual public application_shell
48 {
49 public:
50  test_file_transfer_tentacle() : application_shell() {
51  DEFAULT_SOURCE_DIRECTORY = environment::get("FEISTY_MEOW_SCRIPTS");
52  DEFAULT_TARGET_DIRECTORY = environment::get("HOME") + a_sprintf("/tftt_junkdir_%d", randomizer().inclusive(1, 65535));
53  }
54  DEFINE_CLASS_NAME("test_dirtree_fcopy");
55  int execute();
56  void print_instructions();
57 
58 private:
59  astring DEFAULT_SOURCE_DIRECTORY;
60  astring DEFAULT_TARGET_DIRECTORY;
61 };
62 
64 {
65  FUNCDEF("print_instructions");
66  LOG("\
67 This program needs two parameters:\n\
68 a directory for the source root and one for the target root.\n\
69 Optionally, a third parameter may specify a starting point within the\n\
70 source root.\n\
71 Further, if fourth or more parameters are found, they are taken to be\n\
72 files to include; only they will be transferred.\n");
73 
74 }
75 
76 int test_file_transfer_tentacle::execute()
77 {
78  FUNCDEF("execute");
79 
84 
85  astring source_dir = "";
87  if (source_dir.empty()) {
88  LOG(astring("using default source directory: ") + DEFAULT_SOURCE_DIRECTORY);
89  source_dir = DEFAULT_SOURCE_DIRECTORY;
90  }
91  astring target_dir = "";
93  if (target_dir.empty()) {
94  LOG(astring("using default target directory: ") + DEFAULT_TARGET_DIRECTORY);
95  target_dir = DEFAULT_TARGET_DIRECTORY;
96  bool made_it = directory::make_directory(target_dir);
97  if (!made_it) {
98  deadly_error(class_name(), func, astring("failed to create target directory for copying: ") + target_dir);
99  }
100  }
101 
102  // do some verification of what we were handed as directories.
103  filename source(source_dir);
104  if (!source.exists() || !source.is_directory()) {
106  return 23;
107  }
108  filename target(target_dir);
109  if (!target.exists() || !target.is_directory()) {
111  return 23;
112  }
113 
114  astring source_start = "";
115  if (application::_global_argc >= 4) {
116  source_start = application::_global_argv[3];
117  }
118 
119  string_array includes;
120  if (application::_global_argc >= 5) {
121  for (int i = 4; i < application::_global_argc; i++) {
122  includes += application::_global_argv[i];
123  }
124  }
125 
126  outcome returned = recursive_file_copy::copy_hierarchy
127  (file_transfer_tentacle::COMPARE_SIZE_AND_TIME, source_dir,
128  target_dir, includes, source_start);
129 
130 
131  int retval = 0; // dress for success (then re-clothe after wardrobe malfunctions).
132 
133  if (returned == common::OKAY) {
134 //hmmm: now check the contents with differ or something independent of our code.
135 //returned = more results from that
136  }
137 
138  // delete the temporary directory.
139  launch_process launcher;
140  un_int kid_id = 0;
141  un_int rm_result = launcher.run("rm", astring("-rf ") + target_dir, launch_process::AWAIT_APP_EXIT, kid_id);
142  if (rm_result != 0) {
143  critical_events::alert_message(astring(class_name()) + ":: failed to remove temporary directory '" + target_dir + a_sprintf("' with OS exit value of %d", rm_result));
144  // this is just a guess at what failure occurred in terms of our outcomes; the log should show more details.
145  returned = common::ACCESS_DENIED;
146  }
147 
148  if (returned == common::OKAY)
149  critical_events::alert_message(astring(class_name()) + ":: works for those "
150  "functions tested.");
151  else
152  critical_events::alert_message(astring(class_name()) + "file_transfer_tentacle:: failed with "
153  "outcome=" + recursive_file_copy::outcome_name(returned));
154 
155  return 0;
156 }
157 
158 HOOPLE_MAIN(test_file_transfer_tentacle, )
159 
int print_instructions(bool good, const astring &program_name)
Definition: checker.cpp:45
The application_shell is a base object for console programs.
a_sprintf is a specialization of astring that provides printf style support.
Definition: astring.h:440
Provides a dynamically resizable ASCII character string.
Definition: astring.h:35
bool empty() const
empty() reports if the string is empty, that is, of zero length().
Definition: astring.h:90
Outcomes describe the state of completion for an operation.
Definition: outcome.h:31
Provides operations commonly needed on file names.
Definition: filename.h:64
Provides the capability to start processes in a variety of ways to run other applications.
static basis::un_int run(const basis::astring &app_name, const basis::astring &command_line, int flag, basis::un_int &child_id)
starts an application using the "app_name" as the executable to run.
An array of strings with some additional helpful methods.
Definition: string_array.h:32
#define deadly_error(c, f, i)
#define DEFINE_CLASS_NAME(objname)
Defines the name of a class by providing a couple standard methods.
Definition: enhance_cpp.h:42
#define FUNCDEF(func_in)
FUNCDEF sets the name of a function (and plugs it into the callstack).
Definition: enhance_cpp.h:54
Provides macros that implement the 'main' program of an application.
#define HOOPLE_MAIN(obj_name, obj_args)
options that should work for most unix and linux apps.
Definition: hoople_main.h:61
Implements an application lock to ensure only one is running at once.
char ** _global_argv
The guards collection helps in testing preconditions and reporting errors.
Definition: array.h:30
unsigned int un_int
Abbreviated name for unsigned integers.
Definition: definitions.h:62
A platform independent way to obtain the timestamp of a file.
Definition: byte_filer.cpp:37
A logger that sends to the console screen using the standard output device.
An extension to floating point primitives providing approximate equality.
Definition: averager.h:21
A dynamic container class that holds any kind of object via pointers.
Definition: amorph.h:55
Useful support functions for unit testing, especially within hoople.
Definition: unit_base.cpp:35
#define randomizer()
#define LOG(s)