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