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