test/src/engine_tests/SyncTests.cc
author Volker Birk <vb@pep-project.org>
Thu, 06 Jun 2019 22:20:55 +0200
branchsync
changeset 3817 c2cb0ab6040a
parent 3540 8b1730bcb3e0
child 3818 0b34a967ab39
permissions -rw-r--r--
subtype "pEp.sync" invalid, switching to "pEp-sync"
vb@3251
     1
// This file is under GNU General Public License 3.0
vb@3251
     2
// see LICENSE.txt
vb@3251
     3
vb@3251
     4
#include <stdlib.h>
vb@3251
     5
#include <string>
krista@3429
     6
#include <assert.h>
krista@3431
     7
#include <cpptest.h>
krista@3431
     8
#include "test_util.h"
vb@3251
     9
vb@3251
    10
#include "pEpEngine.h"
vb@3251
    11
vb@3251
    12
#include "pEp_internal.h"
vb@3251
    13
#include "KeySync_fsm.h"
vb@3251
    14
#include "sync_codec.h"
vb@3251
    15
vb@3251
    16
#include "EngineTestSessionSuite.h"
vb@3251
    17
#include "SyncTests.h"
vb@3251
    18
vb@3251
    19
using namespace std;
vb@3251
    20
vb@3251
    21
void Sync_Adapter::processing()
vb@3251
    22
{
vb@3251
    23
    cout << "waiting for processing\n";
vb@3251
    24
    while (!q.empty()) {
vb@3251
    25
        nanosleep((const struct timespec[]){{0, 100000000L}}, NULL);
vb@3251
    26
    }
vb@3251
    27
}
vb@3251
    28
vb@3251
    29
PEP_STATUS Sync_Adapter::notifyHandshake(
vb@3251
    30
        pEp_identity *me,
vb@3251
    31
        pEp_identity *partner,
vb@3251
    32
        sync_handshake_signal signal
vb@3251
    33
    )
vb@3251
    34
{
vb@3251
    35
    return PEP_STATUS_OK;
vb@3251
    36
}
vb@3251
    37
vb@3251
    38
int Sync_Adapter::inject_sync_event(SYNC_EVENT ev, void *management)
vb@3251
    39
{
vb@3251
    40
    Sync_event_t *_ev = ev;
vb@3251
    41
    switch (_ev->fsm) {
vb@3251
    42
        case Sync_PR_keysync:
vb@3251
    43
            cout << "injecting event " << KeySync_event_name(_ev->event) << "\n";
vb@3251
    44
            break;
vb@3251
    45
        default:
vb@3251
    46
            cout << "unknown state machine: " << _ev->fsm << "\n";
vb@3251
    47
            assert(0);
vb@3251
    48
    }
vb@3251
    49
    auto adapter = static_cast< Sync_Adapter *>(management);
vb@3251
    50
    adapter->q.push_front(ev);
vb@3251
    51
    return 0;
vb@3251
    52
}
vb@3251
    53
vb@3251
    54
Sync_event_t *Sync_Adapter::retrieve_next_sync_event(void *management, unsigned threshold)
vb@3251
    55
{
vb@3251
    56
    auto adapter = static_cast< Sync_Adapter *>(management);
vb@3251
    57
    time_t started = time(nullptr);
vb@3251
    58
    bool timeout = false;
vb@3251
    59
vb@3251
    60
    while (adapter->q.empty()) {
vb@3251
    61
        int i = 0;
vb@3251
    62
        ++i;
vb@3251
    63
        if (i > 10) {
vb@3251
    64
            if (time(nullptr) > started + threshold) {
vb@3251
    65
                timeout = true;
vb@3251
    66
                break;
vb@3251
    67
            }
vb@3251
    68
            i = 0;
vb@3251
    69
        }
vb@3251
    70
        nanosleep((const struct timespec[]){{0, 100000000L}}, NULL);
vb@3251
    71
    }
vb@3251
    72
vb@3251
    73
    if (timeout)
vb@3251
    74
        return SYNC_TIMEOUT_EVENT;
vb@3251
    75
vb@3251
    76
    Sync_event_t *ev = adapter->q.pop_front();
vb@3251
    77
    if (ev) {
vb@3251
    78
        switch (ev->fsm) {
vb@3251
    79
            case Sync_PR_keysync:
vb@3251
    80
                cout << "sync thread: retrieving event " << KeySync_event_name(ev->event) << "\n";
vb@3251
    81
                break;
vb@3251
    82
            default:
vb@3251
    83
                cout << "sync thread: unknown state machine: " << ev->fsm << "\n";
vb@3251
    84
                assert(0);
vb@3251
    85
        }
vb@3251
    86
    }
vb@3251
    87
    else {
vb@3251
    88
        cout << "sync thread: retrieving shutdown\n";
vb@3251
    89
    }
vb@3251
    90
vb@3251
    91
    return ev;
vb@3251
    92
}
vb@3251
    93
vb@3251
    94
PEP_STATUS Sync_Adapter::messageToSend(struct _message *msg)
vb@3251
    95
{
vb@3251
    96
    assert(msg && msg->attachments);
vb@3251
    97
    
vb@3251
    98
    cout << "sending message:\n";
vb@3251
    99
vb@3251
   100
    for (bloblist_t *b = msg->attachments; b && b->value; b = b->next) {
vb@3817
   101
        if (b->mime_type && strcasecmp(b->mime_type, "application/pEp-sync") == 0) {
vb@3251
   102
            assert(msg->from && msg->from->address && msg->from->username);
vb@3251
   103
            cout << "<!-- " << msg->from->username << " <" << msg->from->address << "> -->\n";
vb@3251
   104
            char *text = NULL;
vb@3251
   105
            PEP_STATUS status = PER_to_XER_Sync_msg(msg->attachments->value, msg->attachments->size, &text);
vb@3251
   106
            assert(status == PEP_STATUS_OK);
vb@3251
   107
            cout << text << "\n";
vb@3251
   108
            free(text);
vb@3251
   109
        }
vb@3251
   110
    }
vb@3251
   111
vb@3251
   112
    free_message(msg);
vb@3251
   113
    return PEP_STATUS_OK;
vb@3251
   114
}
vb@3251
   115
vb@3251
   116
void Sync_Adapter::sync_thread(PEP_SESSION session, Sync_Adapter *adapter)
vb@3251
   117
{
vb@3251
   118
    cout << "sync_thread: startup\n";
vb@3251
   119
    do_sync_protocol(session, adapter);
vb@3251
   120
    cout << "sync_thread: shutdown\n";
vb@3251
   121
}
vb@3251
   122
vb@3251
   123
SyncTests::SyncTests(string suitename, string test_home_dir) :
vb@3251
   124
    EngineTestSessionSuite::EngineTestSessionSuite(suitename, test_home_dir) {
vb@3251
   125
    add_test_to_suite(std::pair<std::string, void (Test::Suite::*)()>(string("SyncTests::check_sync"),
vb@3251
   126
                                                                      static_cast<Func>(&SyncTests::check_sync)));
vb@3251
   127
}
vb@3251
   128
vb@3251
   129
void SyncTests::setup()
vb@3251
   130
{
vb@3251
   131
    EngineTestSessionSuite::setup();
vb@3251
   132
vb@3251
   133
    pEp_identity *self = new_identity("alice@synctests.pEp", nullptr, "23", "Alice Miller");
vb@3251
   134
    assert(self);
vb@3251
   135
    cout << "setting own identity for " << self->address << "\n";
vb@3251
   136
    PEP_STATUS status = myself(session, self);
vb@3251
   137
    assert(self->me);
vb@3251
   138
    assert(self->fpr);
vb@3251
   139
    cout << "fpr: " << self->fpr << "\n";
vb@3251
   140
    free_identity(self);
vb@3251
   141
vb@3251
   142
    status = init(&sync, Sync_Adapter::messageToSend, Sync_Adapter::inject_sync_event);
krista@3431
   143
    if (status != PEP_STATUS_OK)
krista@3431
   144
        throw std::runtime_error((string("init returned ") + tl_status_string(status)).c_str()); 
vb@3251
   145
vb@3251
   146
    cout << "initialize sync and start first state machine\n";
vb@3251
   147
    status = register_sync_callbacks(
vb@3251
   148
            sync,
vb@3251
   149
            (void *) &adapter.q,
vb@3251
   150
            Sync_Adapter::notifyHandshake,
vb@3251
   151
            Sync_Adapter::retrieve_next_sync_event
vb@3251
   152
        );
krista@3431
   153
    if (status != PEP_STATUS_OK)
krista@3431
   154
        throw std::runtime_error((string("register sync status returned ") + tl_status_string(status)).c_str()); 
krista@3431
   155
    if (sync->sync_state.keysync.state != Sole) 
krista@3431
   156
        throw std::runtime_error((string("keysync.state was supposed to be ") + to_string((int)Sole) + " but was " + to_string((int)(sync->sync_state.keysync.state))).c_str()); 
krista@3431
   157
      
vb@3251
   158
vb@3251
   159
    cout << "creating thread for sync\n";
vb@3251
   160
    sync_thread = new thread(Sync_Adapter::sync_thread, sync, &adapter);
vb@3251
   161
}
vb@3251
   162
vb@3251
   163
void SyncTests::tear_down()
vb@3251
   164
{
vb@3251
   165
    adapter.processing();
vb@3251
   166
vb@3251
   167
    cout << "sending shutdown to sync thread\n";
vb@3251
   168
    adapter.q.push_front(nullptr);
vb@3251
   169
    sync_thread->join();
vb@3251
   170
vb@3251
   171
    unregister_sync_callbacks(sync);
vb@3251
   172
    release(sync);
vb@3251
   173
vb@3251
   174
    EngineTestSessionSuite::tear_down();
vb@3251
   175
}
vb@3251
   176
vb@3251
   177
void SyncTests::check_sync()
vb@3251
   178
{
vb@3251
   179
    cout << "check_sync(): trigger KeyGen event\n";
vb@3540
   180
    signal_Sync_event(sync, Sync_PR_keysync, KeyGen, NULL);
vb@3251
   181
    adapter.processing();
vb@3251
   182
vb@3251
   183
    cout << "check_sync(): cry for unknown key\n";
vb@3540
   184
    signal_Sync_event(sync, Sync_PR_keysync, CannotDecrypt, NULL);
vb@3251
   185
}