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