feisty meow concerns codebase  2.140
test_dirtree_fcopy.cpp
Go to the documentation of this file.
1 /*****************************************************************************\
2 * *
3 * Name : test_fcopy_file_transfer *
4 * Author : Chris Koeritz *
5 * *
6 * Purpose: *
7 * *
8 * Tests the directory_tree object as a file copy prompter. *
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 <basis/guards.h>
23 #include <loggers/console_logger.h>
24 #include <filesystem/directory.h>
26 #include <filesystem/filename.h>
31 #include <unit_test/unit_base.h>
32 
33 using namespace application;
34 using namespace basis;
35 using namespace loggers;
36 using namespace filesystem;
37 using namespace unit_test;
38 
39 #define LOG(s) CLASS_EMERGENCY_LOG(program_wide_logger::get(), s)
40 
41 class test_fcopy : virtual public unit_base, virtual public application_shell
42 {
43 public:
44  test_fcopy() : application_shell() {}
45  DEFINE_CLASS_NAME("test_dirtree_fcopy");
46  int execute();
47 };
48 
49 int test_fcopy::execute()
50 {
51  FUNCDEF("execute");
52 //old: if (application::_global_argc < 3)
53 //old: non_continuable_error(class_name(), "command line", "this program needs two "
54 //old: "parameters:\na directory for the source and one for the target.");
55 
56  astring source_dir;
57  astring target_dir;
58  if (application::_global_argc < 3) {
59  // special default for testing--just use part of our own hierarchy to compare.
60  source_dir = environment::get("FEISTY_MEOW_SCRIPTS");
61  target_dir = environment::get("FEISTY_MEOW_SCRIPTS");
62  } else {
63  source_dir = application::_global_argv[1];
64  target_dir = application::_global_argv[2];
65  }
66 
67  // read the source location.
68  log(astring("Scanning source tree at \"") + source_dir + "\"");
69  directory_tree source(source_dir, "*");
70  if (!source.good())
71  non_continuable_error(class_name(), "directory_tree construction",
72  "the source directory could not be read");
73 
74  // read the stuff that exists at the target.
75  log(astring("Scanning target tree at \"") + target_dir + "\"");
76  directory_tree target(target_dir, "*");
77  if (!target.good())
78  non_continuable_error(class_name(), "directory_tree construction",
79  "the target directory could not be read");
80 
81  LOG("calculating checksums for source.");
82  if (!source.calculate(true))
83  non_continuable_error(class_name(), "directory_tree calculation",
84  "the source tree could not be calculated");
85 
86  LOG("calculating checksums for target.");
87  if (!target.calculate(true))
88  non_continuable_error(class_name(), "directory_tree calculation",
89  "the target tree could not be calculated");
90 
91  astring source_start;
92  astring target_start;
94  source_start = application::_global_argv[3];
96  target_start = application::_global_argv[4];
97 
98  LOG("comparing the two trees.");
99  filename_list diffs;
100  directory_tree::compare_trees(source, source_start, target, target_start,
101  diffs, file_info::EQUAL_CHECKSUM_TIMESTAMP_FILESIZE);
102 //LOG("missing files:");
103 //LOG(diffs.text_form());
104 
105  byte_array packed_form;
106  diffs.pack(packed_form);
107  filename_list regen;
108  if (!regen.unpack(packed_form))
109  non_continuable_error(class_name(), "filename_list packing",
110  "could not unpack the list of differences");
111 
112 //LOG("after packing and restoring:");
113 //LOG(regen.text_form());
114 
115  if (regen.elements() != diffs.elements())
116  non_continuable_error(class_name(), "filename_list packing",
117  "there were a different number of elements in unpacked form");
118  for (int i = 0; i < diffs.elements(); i++) {
119  if (!regen.member(*diffs[i])) {
120  astring name = diffs[i]->raw();
121  non_continuable_error(class_name(), "filename_list packing",
122  astring("name from original set was missing in regenerated: ")
123  + name);
124  }
125  }
126 
127  for (int i = 0; i < diffs.elements(); i++) {
128  file_info *curr = diffs[i];
129  filename source_file = source.path() + filename::default_separator()
130  + curr->raw();
131  filename target_file = target.path() + filename::default_separator()
132  + curr->secondary();
133 //LOG(astring("cp source: ") + source_file.raw());
134 //LOG(astring("-> target: ") + target_file.raw());
135  filename targ_dir = target_file.dirname();
136  if (!targ_dir.is_directory()) {
137  bool worked = directory::recursive_create(targ_dir);
138  if (!worked)
139  non_continuable_error(class_name(), "recursive mkdir",
140  astring("failed to create the target directory ") + targ_dir);
141  }
142 
143  outcome ret = heavy_file_operations::copy_file(source_file, target_file);
144  if (ret != heavy_file_operations::OKAY)
145  non_continuable_error(class_name(), "copying file", astring("there was an error ")
146  + heavy_file_operations::outcome_name(ret)
147  + " when copying the file.");
148  }
149 
150 //do the copy by going across the entire set of files and making sure
151 //they get copied to target.
152 //
153 //reread the target location.
154 //
155 //compare with source tree read before.
156 
157  critical_events::alert_message("directory_tree file transfer:: works for those functions tested.");
158  return 0;
159 }
160 
161 HOOPLE_MAIN(test_fcopy, )
162 
The application_shell is a base object for console programs.
Provides a dynamically resizable ASCII character string.
Definition: astring.h:35
A very common template for a dynamic array of bytes.
Definition: byte_array.h:36
Outcomes describe the state of completion for an operation.
Definition: outcome.h:31
An object that traverses directory trees and provides a view of all files.
Encapsulates some measures and calculations based on a file's contents.
Definition: file_info.h:29
const basis::astring & secondary() const
observes the alternate form of the name.
Definition: file_info.cpp:74
bool member(const filename &to_check) const
finds the index for "to_find" or returns a negative number.
virtual void pack(basis::byte_array &packed_form) const
Creates a packed form of the packable object in "packed_form".
virtual bool unpack(basis::byte_array &packed_form)
Restores the packable from the "packed_form".
Provides operations commonly needed on file names.
Definition: filename.h:64
bool is_directory() const
Definition: filename.cpp:325
const basis::astring & raw() const
returns the astring that we're holding onto for the path.
Definition: filename.cpp:97
filename dirname() const
returns the directory for the filename.
Definition: filename.cpp:393
int elements() const
the maximum number of elements currently allowed in this amorph.
Definition: amorph.h:66
#define non_continuable_error(c, f, i)
an extra piece of information used, if available, in bounds_halt below.
#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
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.
Useful support functions for unit testing, especially within hoople.
Definition: unit_base.cpp:35
#define LOG(s)