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>
26#include <filesystem/filename.h>
31#include <unit_test/unit_base.h>
32
33using namespace application;
34using namespace basis;
35using namespace loggers;
36using namespace filesystem;
37using namespace unit_test;
38
39#define LOG(s) CLASS_EMERGENCY_LOG(program_wide_logger::get(), s)
40
41class test_fcopy : virtual public unit_base, virtual public application_shell
42{
43public:
44 test_fcopy() : application_shell() {}
45 DEFINE_CLASS_NAME("test_dirtree_fcopy");
46 int execute();
47};
48
49int 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;
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,
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);
145 non_continuable_error(class_name(), "copying file", astring("there was an error ")
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
161HOOPLE_MAIN(test_fcopy, )
162
The application_shell is a base object for console programs.
virtual int execute()=0
< retrieves the command line from the /proc hierarchy on linux.
application_shell()
constructs an application_shell to serve as the root of the program.
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
static astring get(const astring &variable_name)
looks up the "variable_name" in the current environment variables.
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.
static bool compare_trees(const directory_tree &source, const directory_tree &target, filename_list &differences, file_info::file_similarity how_to_compare)
compares the tree in "source" with the tree in "target".
static bool recursive_create(const basis::astring &directory_name)
returns true if the "directory_name" can be created or already exists.
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
static basis::astring default_separator()
returns the default separator character for this OS.
Definition filename.cpp:93
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
static basis::outcome copy_file(const basis::astring &source, const basis::astring &destination, int copy_chunk_factor=heavy_file_operations::copy_chunk_factor())
copies a file from the "source" location to the "destination".
static const char * outcome_name(const basis::outcome &to_name)
static void alert_message(const char *info, const char *title="Alert Message")
shows the message in "info", with an optional "title" on the message.
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.
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)