test/src/EngineTestSuite.cc
author Krista 'DarthMama' Bennett <krista@pep.foundation>
Mon, 25 Feb 2019 16:36:16 +0100
branchsync_test_refactor
changeset 3315 4d8f93b6cdcb
parent 3299 f15bf275c50f
child 3333 189b5a5eca19
child 3335 09af2cf0ac74
permissions -rw-r--r--
*hiss* NULL is important.
     1 #include <stdlib.h>
     2 #include <sys/stat.h>
     3 #include <errno.h>
     4 #include <stdlib.h>
     5 #include <unistd.h>
     6 #include <ftw.h>
     7 #include <assert.h>
     8 #include <fstream>
     9 #include <iostream>
    10 #include <sys/types.h>
    11 #include <sys/stat.h>
    12 
    13 #include <string>
    14 #include <vector>
    15 #include <utility>
    16 #include <cpptest.h>
    17 
    18 #include "platform_unix.h"
    19 
    20 #include "TestUtils.h"
    21 #include "EngineTestSuite.h"
    22 #include "pEpTestStatic.h"
    23 #include <algorithm>
    24 #include "TestConstants.h"
    25 
    26 using namespace std;
    27 
    28 // Constructor
    29 EngineTestSuite::EngineTestSuite(string suitename, 
    30                                  string test_home_dir,
    31                                  bool make_default_device) {
    32     // FIXME: deal with base
    33     test_home = test_home_dir;
    34             
    35     number_of_tests = 0;
    36     on_test_number = 0;
    37     real_home = getenv("HOME");
    38     session = NULL;
    39     device = NULL;
    40     make_device = make_default_device;
    41 }
    42 
    43 EngineTestSuite::~EngineTestSuite() {}
    44 
    45 void EngineTestSuite::add_test_to_suite(std::pair<std::string, void (Test::Suite::*)()> test_func) {
    46     test_map.insert(test_func);
    47     register_test(test_func.second, test_func.first);
    48     number_of_tests++;
    49 }
    50 
    51 void EngineTestSuite::copy_conf_file_to_test_dir(const char* dest_path, const char* conf_orig_path, const char* conf_dest_name) {
    52     string conf_dest_path = dest_path;
    53     
    54     struct stat pathinfo;
    55 
    56     if(stat(conf_dest_path.c_str(), &pathinfo) != 0) {
    57         int errchk = mkdir(conf_dest_path.c_str(), S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH);
    58         if (errchk != 0)
    59             throw std::runtime_error("Error accessing conf file directory.");
    60     }
    61     
    62     conf_dest_path += "/";
    63     conf_dest_path += conf_dest_name;
    64     
    65     ifstream src(conf_orig_path);
    66     ofstream dst(conf_dest_path.c_str(), ios::trunc);
    67     
    68     assert(src);
    69     assert(dst);
    70     
    71     dst << src.rdbuf();
    72      
    73     src.close();
    74     dst.close();
    75 }
    76 
    77 void EngineTestSuite::add_file_to_gpg_dir_queue(string copy_from, string dst_fname) {    
    78     gpgdir_fileadd_queue.push_back(make_pair(copy_from, dst_fname));
    79 }
    80 
    81 void EngineTestSuite::add_file_to_home_dir_queue(string copy_from, string dst_fname) {
    82     homedir_fileadd_queue.push_back(make_pair(copy_from, dst_fname));
    83 }
    84 
    85 void EngineTestSuite::process_file_queue(string dirname, vector<pair<string, string>> file_queue) {
    86     if (file_queue.empty())
    87         return;
    88         
    89     vector<pair<string, string>>::iterator it;
    90     
    91     for (it = file_queue.begin(); it != file_queue.end(); it++) {
    92         copy_conf_file_to_test_dir(dirname.c_str(), it->first.c_str(), it->second.c_str());
    93     }
    94     
    95     file_queue.clear();
    96 }
    97 
    98 void EngineTestSuite::set_full_env() {
    99     set_full_env(NULL, NULL, NULL);
   100 }
   101 
   102 void EngineTestSuite::set_full_env(const char* gpg_conf_copy_path, const char* gpg_agent_conf_file_copy_path, const char* db_conf_file_copy_path) {
   103     int success = 0;
   104     struct stat dirchk;
   105     
   106     set_my_name();
   107 
   108 // // FIXME
   109 // #ifndef USE_NETPGP
   110 //     success = system("gpgconf --kill all");
   111 //     if (success != 0)
   112 //         throw std::runtime_error("SETUP: Error when executing 'gpgconf --kill all'.");    
   113 // #endif
   114 
   115     if (stat(test_home.c_str(), &dirchk) == 0) {
   116         if (!S_ISDIR(dirchk.st_mode))
   117             throw std::runtime_error(("The test directory, " + test_home + "exists, but is not a directory.").c_str()); 
   118                     
   119         struct stat buf;
   120 
   121         if (stat(test_home.c_str(), &buf) == 0) {
   122             int success = nftw((test_home + "/.").c_str(), util_delete_filepath, 100, FTW_DEPTH);
   123         }
   124     }
   125     else {
   126         int errchk = mkdir(test_home.c_str(), S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH);
   127         cout << errchk << endl;
   128         if (errchk != 0)
   129             throw std::runtime_error("Error creating a test directory.");
   130     }
   131 
   132     if (my_name.size() > pEpTestStatic::classname_chars)
   133         my_name.resize(pEpTestStatic::classname_chars);
   134 
   135     if (on_test_number > pEpTestStatic::max_test_num) {
   136         cerr << "Warning - there are at least " << pEpTestStatic::max_test_num << " tests in this suite. While this probably won't cause "
   137              << endl << "problems, there is an obscure possibility that if your test path is REALLY REALLY LONG, tests will fail because gpg-agent "
   138              << endl << "won't start with huge paths. In general, however, we stop well before these limits, and pEpTestStatic::testnum_path_chars "
   139              << endl << "is overly conservative, so you probably don't need to worry." << endl;
   140     }    
   141 
   142     temp_test_home = test_home + "/" + my_name;
   143     
   144     int errchk = mkdir(temp_test_home.c_str(), S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH);
   145     if (errchk != 0 && errno != EEXIST)
   146         throw std::runtime_error("Error creating a test directory.");
   147 
   148     temp_test_home += "/" + to_string(on_test_number);
   149 
   150     errchk = mkdir(temp_test_home.c_str(), S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH);
   151     if (errchk != 0)
   152         throw std::runtime_error("Error creating a test directory.");
   153 
   154     // TODO: This is *nix specific, which the current testing env is anyway,
   155     // but it needn't remain so forever and always
   156 
   157     string home = getenv("HOME");
   158 
   159     char* tmp = NULL;
   160     
   161     tmp = getenv("GNUPGHOME");
   162 
   163     prev_pgp_home.clear();
   164     
   165     if (tmp)
   166         prev_pgp_home = tmp;
   167         
   168     if (temp_test_home.empty())
   169         throw std::runtime_error("SETUP: BAD INITIALISATION. No test home.");
   170     
   171     assert(temp_test_home.compare(home) != 0);
   172     assert(temp_test_home.compare(home + "/") != 0);
   173     // assert(temp_test_home.compare(home + "/.gnupg") != 0); // This is an EXCLUSION test, so we leave this.
   174     // assert(temp_test_home.compare(home + ".gnupg") != 0);
   175     // assert(temp_test_home.compare(home + "/gnupg") != 0);
   176     // assert(temp_test_home.compare(home + "gnupg") != 0);
   177     // assert(temp_test_home.compare(prev_pgp_home) != 0);
   178     // assert(temp_test_home.compare(prev_pgp_home + "/gnupg") != 0);
   179     // assert(temp_test_home.compare(prev_pgp_home + "gnupg") != 0);
   180     // assert(temp_test_home.compare(prev_pgp_home + "/.gnupg") != 0);
   181     // assert(temp_test_home.compare(prev_pgp_home + ".gnupg") != 0);
   182 
   183     if (temp_test_home.compare(home) == 0 || temp_test_home.compare(home + "/") == 0 ||
   184         temp_test_home.compare(home + "/gnupg") == 0 || temp_test_home.compare(home + "gnupg") == 0 ||
   185         temp_test_home.compare(home + "/.gnupg") == 0 || temp_test_home.compare(home + ".gnupg") == 0)
   186         // temp_test_home.compare(prev_pgp_home) == 0 || temp_test_home.compare(prev_pgp_home + "/gnupg") == 0 ||
   187         // temp_test_home.compare(prev_pgp_home + "gnupg") == 0 || temp_test_home.compare(prev_pgp_home + "/.gnupg") == 0 ||
   188         // temp_test_home.compare(prev_pgp_home + ".gnupg") == 0)
   189         throw std::runtime_error("SETUP: new pgp homedir threatens to mess up user pgp homedir (and delete all their keys). NO DICE.");
   190     
   191 //    cout << "Ok - checked if new test home will be safe. We'll try and make the directory, deleting it if it has already exists." << endl;
   192     cout << "Test home directory is " << temp_test_home << endl;
   193     
   194     struct stat buf;
   195     // 
   196     // success = setenv("GNUPGHOME", (temp_test_home + "/gnupg").c_str(), 1);
   197     // if (success != 0)
   198     //     throw std::runtime_error("SETUP: Error when setting GNUPGHOME.");
   199     // 
   200     // cout << "New GNUPGHOME is " << getenv("GNUPGHOME") << endl << endl;
   201     
   202     success = setenv("HOME", temp_test_home.c_str(), 1);
   203     if (success != 0)
   204         throw std::runtime_error("SETUP: Cannot set test_home for init.");
   205 
   206     // string tmp_gpg_dir = temp_test_home + "/.gnupg";
   207 
   208     // process_file_queue(tmp_gpg_dir, gpgdir_fileadd_queue);
   209     // process_file_queue(temp_test_home, homedir_fileadd_queue);
   210 
   211     // if (gpg_conf_copy_path)
   212     //     copy_conf_file_to_test_dir((temp_test_home + "/gnupg").c_str(), gpg_conf_copy_path, "gpg.conf");
   213     // if (gpg_agent_conf_file_copy_path)        
   214     //     copy_conf_file_to_test_dir((temp_test_home + "/gnupg").c_str(), gpg_agent_conf_file_copy_path, "gpg-agent.conf");
   215     // if (db_conf_file_copy_path)
   216     //     copy_conf_file_to_test_dir(temp_test_home.c_str(), db_conf_file_copy_path, ".pEp_management.db");
   217         
   218     // unix_local_db(true);
   219     // gpg_conf(true);
   220     // gpg_agent_conf(true);
   221     
   222 //    cout << "calling init()\n";
   223 //     PEP_STATUS status = init(&session, cached_messageToSend, cached_inject_sync_event);
   224 // #ifndef USE_NETPGP            
   225 //     success = system("gpgconf --create-socketdir");
   226 //     if (success != 0)
   227 //         throw std::runtime_error("RESTORE: Error when executing 'gpgconf --create-socketdir'.");        
   228 //     system("gpg-connect-agent /bye");   // Just in case - otherwise, we die on MacOS sometimes. Is this enough??
   229 // #endif
   230 
   231 //    assert(status == PEP_STATUS_OK);
   232 //    assert(session);
   233 //    cout << "init() completed.\n";
   234     if (make_device) {
   235         device = new pEpTestDevice(temp_test_home, "DefaultDevice");
   236         session = device->session;
   237     }
   238 }
   239 
   240 void EngineTestSuite::restore_full_env() {
   241 //    release(session);
   242 //    session = NULL;
   243     if (make_device) {
   244         delete(device);
   245         device = NULL;
   246         session = NULL;
   247     }
   248         
   249     int success = 0;    
   250 
   251 // #ifndef USE_NETPGP        
   252 //     success = system("gpgconf --kill all");
   253 //     if (success != 0)
   254 //         throw std::runtime_error("RESTORE: Error when executing 'gpgconf --kill all'.");
   255 //     success = system("gpgconf --remove-socketdir");            
   256 //     if (success != 0)
   257 //         throw std::runtime_error("RESTORE: Error when executing 'gpgconf --remove-socketdir'.");    
   258 // #endif
   259 
   260     success = setenv("GNUPGHOME", prev_pgp_home.c_str(), 1);
   261     if (success != 0)
   262         throw std::runtime_error("RESTORE: Warning - cannot restore GNUPGHOME. Either set environment variable manually back to your home, or quit this session!");
   263                 
   264     success = nftw((test_home + "/.").c_str(), util_delete_filepath, 100, FTW_DEPTH);
   265     
   266     success = setenv("HOME", real_home.c_str(), 1);
   267     if (success != 0)
   268         throw std::runtime_error("RESTORE: Cannot reset home directory! Either set environment variable manually back to your home, or quit this session!");
   269     // else
   270     //     cout << "RESTORE: HOME is now " << getenv("HOME") << endl;
   271     // unix_local_db(true);
   272     // gpg_conf(true);
   273     // gpg_agent_conf(true);
   274 
   275 }
   276 
   277 void EngineTestSuite::setup() {
   278     on_test_number++;
   279 }
   280 
   281 void EngineTestSuite::tear_down() {}
   282 
   283 void EngineTestSuite::set_my_name() {
   284     my_name = typeid(*this).name();
   285 }