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