test/src/EngineTestSuite.cc
author Krista Bennett <krista@pep-project.org>
Wed, 01 Aug 2018 16:34:38 +0200
branchENGINE-451
changeset 2798 e0abb44b8098
parent 2795 4bd160717c54
child 2811 4bb07fc31b93
permissions -rw-r--r--
ENGINE-451: old files now backed up appropriately, new file now created in a separate file before rename clobbers confs.
     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 #import <string>
    14 #import <vector>
    15 #include <utility>
    16 
    17 #include "platform_unix.h"
    18 
    19 #include "test_util.h"
    20 #include "EngineTestSuite.h"
    21 using namespace std;
    22 
    23 // Constructor
    24 EngineTestSuite::EngineTestSuite(string suitename, string test_home_dir) {
    25     // FIXME: deal with base
    26     test_home = test_home_dir;
    27             
    28     number_of_tests = 0;
    29     on_test_number = 0;
    30     real_home = getenv("HOME");
    31 }
    32 
    33 EngineTestSuite::~EngineTestSuite() {}
    34 
    35 void EngineTestSuite::add_test_to_suite(std::pair<std::string, void (Test::Suite::*)()> test_func) {
    36     test_map.insert(test_func);
    37     register_test(test_func.second, test_func.first);
    38     number_of_tests++;
    39 }
    40 
    41 void EngineTestSuite::copy_conf_file_to_test_dir(const char* dest_path, const char* conf_orig_path, const char* conf_dest_name) {
    42     string conf_dest_path = dest_path;
    43     
    44     struct stat pathinfo;
    45 
    46     if(stat(conf_dest_path.c_str(), &pathinfo) != 0) {
    47         int errchk = mkdir(conf_dest_path.c_str(), S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH);
    48         if (errchk != 0)
    49             throw std::runtime_error("Error accessing conf file directory.");
    50     }
    51     
    52     conf_dest_path += "/";
    53     conf_dest_path += conf_dest_name;
    54     
    55     ifstream src(conf_orig_path);
    56     ofstream dst(conf_dest_path.c_str(), ios::trunc);
    57     
    58     assert(src);
    59     assert(dst);
    60     
    61     dst << src.rdbuf();
    62      
    63     src.close();
    64     dst.close();
    65 }
    66 
    67 void EngineTestSuite::add_file_to_gpg_dir_queue(string copy_from, string dst_fname) {    
    68     gpgdir_fileadd_queue.push_back(make_pair(copy_from, dst_fname));
    69 }
    70 
    71 void EngineTestSuite::add_file_to_home_dir_queue(string copy_from, string dst_fname) {
    72     homedir_fileadd_queue.push_back(make_pair(copy_from, dst_fname));
    73 }
    74 
    75 void EngineTestSuite::process_file_queue(string dirname, vector<pair<string, string>> file_queue) {
    76     if (file_queue.empty())
    77         return;
    78         
    79     vector<pair<string, string>>::iterator it;
    80     
    81     for (it = file_queue.begin(); it != file_queue.end(); it++) {
    82         copy_conf_file_to_test_dir(dirname.c_str(), it->first.c_str(), it->second.c_str());
    83     }
    84     
    85     file_queue.clear();
    86 }
    87 
    88 void EngineTestSuite::set_full_env() {
    89     set_full_env(NULL, NULL, NULL);
    90 }
    91 
    92 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) {
    93     int success = 0;
    94     struct stat dirchk;
    95     
    96     set_my_name();
    97 
    98     success = system("gpgconf --kill all");
    99     if (success != 0)
   100         throw std::runtime_error("SETUP: Error when executing 'gpgconf --kill all'.");
   101  //   sleep(1); // hopefully enough time for the system to recognise that it is dead. *sigh*    
   102 
   103     if (stat(test_home.c_str(), &dirchk) == 0) {
   104         if (!S_ISDIR(dirchk.st_mode))
   105             throw std::runtime_error(("The test directory, " + test_home + "exists, but is not a directory.").c_str()); 
   106                     
   107         struct stat buf;
   108 
   109         if (stat(test_home.c_str(), &buf) == 0) {
   110             cout << test_home << " exists. We'll recursively delete. We hope we're not horking your whole system..." << endl;
   111             int success = nftw((test_home + "/.").c_str(), util_delete_filepath, 100, FTW_DEPTH);
   112         }
   113     }
   114     else {
   115         int errchk = mkdir(test_home.c_str(), S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH);
   116         cout << errchk << endl;
   117         if (errchk != 0)
   118             throw std::runtime_error("Error creating a test directory.");
   119     }
   120 
   121     temp_test_home = test_home + "/" + my_name;
   122     
   123     int errchk = mkdir(temp_test_home.c_str(), S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH);
   124     if (errchk != 0)
   125         throw std::runtime_error("Error creating a test directory.");
   126 
   127     temp_test_home += "/" + to_string(on_test_number);
   128 
   129     errchk = mkdir(temp_test_home.c_str(), S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH);
   130     if (errchk != 0)
   131         throw std::runtime_error("Error creating a test directory.");
   132 
   133     // TODO: This is *nix specific, which the current testing env is anyway,
   134     // but it needn't remain so forever and always
   135     char* tmp = getenv("GNUPGHOME");
   136     if (tmp)
   137         prev_gpg_home = tmp;
   138         
   139     if (temp_test_home.empty())
   140         throw std::runtime_error("SETUP: BAD INITIALISATION. No test home.");
   141 
   142     
   143     string home = getenv("HOME");
   144     cout << "home is " << home << endl;
   145     assert(temp_test_home.compare(home) != 0);
   146     assert(temp_test_home.compare(home + "/") != 0);
   147     assert(temp_test_home.compare(home + "") != 0);
   148     assert(temp_test_home.compare(home + ".gnupg") != 0);
   149     assert(temp_test_home.compare(prev_gpg_home) != 0);
   150     assert(temp_test_home.compare(prev_gpg_home + "/.gnupg") != 0);
   151     assert(temp_test_home.compare(prev_gpg_home + ".gnupg") != 0);
   152 
   153     if (temp_test_home.compare(home) == 0 || temp_test_home.compare(home + "/") == 0 ||
   154         temp_test_home.compare(home + "/.gnupg") == 0 || temp_test_home.compare(home + ".gnupg") == 0 ||
   155         temp_test_home.compare(prev_gpg_home) == 0 || temp_test_home.compare(prev_gpg_home + "/.gnupg") == 0 ||
   156         temp_test_home.compare(prev_gpg_home + ".gnupg") == 0)
   157         throw std::runtime_error("SETUP: new GNUPGHOME threatens to mess up user GNUPGHOME (and delete all their keys). NO DICE.");
   158     
   159 //    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;
   160     
   161     struct stat buf;
   162     
   163     success = setenv("GNUPGHOME", (temp_test_home + "/.gnupg").c_str(), 1);
   164     if (success != 0)
   165         throw std::runtime_error("SETUP: Error when setting GNUPGHOME.");
   166 
   167     cout << "New GNUPGHOME is " << getenv("GNUPGHOME") << endl;
   168     
   169     success = setenv("HOME", temp_test_home.c_str(), 1);
   170     if (success != 0)
   171         throw std::runtime_error("SETUP: Cannot set test_home for init.");
   172 
   173     string tmp_gpg_dir = temp_test_home + "/.gnupg";
   174 
   175     process_file_queue(tmp_gpg_dir, gpgdir_fileadd_queue);
   176     process_file_queue(temp_test_home, homedir_fileadd_queue);
   177 
   178     if (gpg_conf_copy_path)
   179         copy_conf_file_to_test_dir(tmp_gpg_dir.c_str(), gpg_conf_copy_path, "gpg.conf");
   180     if (gpg_agent_conf_file_copy_path)        
   181         copy_conf_file_to_test_dir(tmp_gpg_dir.c_str(), gpg_agent_conf_file_copy_path, "gpg-agent.conf");
   182     if (db_conf_file_copy_path)
   183         copy_conf_file_to_test_dir(temp_test_home.c_str(), db_conf_file_copy_path, ".pEp_management.db");
   184         
   185     unix_local_db(true);
   186     gpg_conf(true);
   187     gpg_agent_conf(true);
   188     
   189 //    cout << "calling init()\n";
   190     PEP_STATUS status = init(&session);
   191     assert(status == PEP_STATUS_OK);
   192     assert(session);
   193 //    cout << "init() completed.\n";
   194 
   195 }
   196 
   197 void EngineTestSuite::restore_full_env() {
   198     release(session);
   199     session = NULL;
   200         
   201     int success = system("gpgconf --kill all");
   202     if (success != 0)
   203         throw std::runtime_error("RESTORE: Error when executing 'gpgconf --kill all'.");
   204 
   205     success = setenv("GNUPGHOME", prev_gpg_home.c_str(), 1);
   206     if (success != 0)
   207         throw std::runtime_error("RESTORE: Warning - cannot restore GNUPGHOME. Either set environment variable manually back to your home, or quit this session!");
   208                 
   209     success = nftw((test_home + "/.").c_str(), util_delete_filepath, 100, FTW_DEPTH);
   210     
   211     success = setenv("HOME", real_home.c_str(), 1);
   212     if (success != 0)
   213         throw std::runtime_error("RESTORE: Cannot reset home directory! Either set environment variable manually back to your home, or quit this session!");
   214     else
   215         cout << "RESTORE: HOME is now " << getenv("HOME") << endl;
   216     unix_local_db(true);
   217     gpg_conf(true);
   218     gpg_agent_conf(true);
   219     
   220 }
   221 
   222 void EngineTestSuite::setup() {
   223     on_test_number++;
   224 }
   225 
   226 void EngineTestSuite::tear_down() {
   227 }
   228 
   229 void EngineTestSuite::set_my_name() {
   230     my_name = typeid(*this).name();
   231 }