tests: add some protocol tests.
authorDavin McCall <davmac@davmac.org>
Mon, 9 Jul 2018 17:39:27 +0000 (18:39 +0100)
committerDavin McCall <davmac@davmac.org>
Mon, 9 Jul 2018 21:00:22 +0000 (22:00 +0100)
src/includes/control.h
src/tests/cptests/cptests.cc

index c9d981e38fa3f7e0ad20d785f06dd1f06f107f2b..b914bd033a832fc653dc08feae6368bac4905773 100644 (file)
@@ -79,6 +79,12 @@ class control_conn_t : private service_listener
 {
     friend rearm control_conn_cb(eventloop_t *loop, control_conn_watcher *watcher, int revents);
     
+    public:
+    // A mapping between service records and their associated numerical identifier used
+    // in communction
+    using handle_t = uint32_t;
+
+    private:
     control_conn_watcher iob;
     eventloop_t &loop;
     service_set *services;
@@ -96,9 +102,6 @@ class control_conn_t : private service_listener
     template <typename T> using list = std::list<T>;
     template <typename T> using vector = std::vector<T>;
     
-    // A mapping between service records and their associated numerical identifier used
-    // in communction
-    using handle_t = uint32_t;
     std::unordered_multimap<service_record *, handle_t> service_key_map;
     std::map<handle_t, service_record *> key_service_map;
     
index 00a8176a2b6fb673ef9ccfdb9299564328ea191c..1041c1de67479895c7b712b2ae1e62117e386d02 100644 (file)
@@ -93,6 +93,141 @@ void cptest_listservices()
        delete cc;
 }
 
+void cptest_findservice1()
+{
+    service_set sset;
+
+    const char * const service_name_2 = "test-service-2";
+
+    service_record *s1 = new service_record(&sset, "test-service-1", service_type_t::INTERNAL, {});
+    sset.add_service(s1);
+    service_record *s2 = new service_record(&sset, "test-service-2", service_type_t::INTERNAL, {});
+    sset.add_service(s2);
+    service_record *s3 = new service_record(&sset, "test-service-3", service_type_t::INTERNAL, {});
+    sset.add_service(s3);
+
+    int fd = bp_sys::allocfd();
+    auto *cc = new control_conn_t(event_loop, &sset, fd);
+
+    std::vector<char> cmd = { DINIT_CP_FINDSERVICE };
+    uint16_t name_len = strlen(service_name_2);
+    char *name_len_cptr = reinterpret_cast<char *>(&name_len);
+    cmd.insert(cmd.end(), name_len_cptr, name_len_cptr + sizeof(name_len));
+    cmd.insert(cmd.end(), service_name_2, service_name_2 + name_len);
+
+    bp_sys::supply_read_data(fd, std::move(cmd));
+
+    event_loop.regd_bidi_watchers[fd]->read_ready(event_loop, fd);
+
+    // We expect:
+    // (1 byte)   DINIT_RP_SERVICERECORD
+    // (1 byte)   state
+    // (handle_t) handle
+    // (1 byte)   target state
+
+    std::vector<char> wdata;
+    bp_sys::extract_written_data(fd, wdata);
+
+    assert(wdata.size() == 3 + sizeof(control_conn_t::handle_t));
+    assert(wdata[0] == DINIT_RP_SERVICERECORD);
+    service_state_t s = static_cast<service_state_t>(wdata[1]);
+    assert(s == service_state_t::STOPPED);
+    service_state_t ts = static_cast<service_state_t>(wdata[6]);
+    assert(ts == service_state_t::STOPPED);
+
+    delete cc;
+}
+
+void cptest_findservice2()
+{
+    service_set sset;
+
+    const char * const service_name_2 = "test-service-2";
+
+    service_record *s1 = new service_record(&sset, "test-service-1", service_type_t::INTERNAL, {});
+    sset.add_service(s1);
+    service_record *s2 = new service_record(&sset, "test-service-2", service_type_t::INTERNAL, {});
+    sset.add_service(s2);
+    service_record *s3 = new service_record(&sset, "test-service-3", service_type_t::INTERNAL, {});
+    sset.add_service(s3);
+
+    sset.start_service(s2);
+    sset.process_queues();
+
+    int fd = bp_sys::allocfd();
+    auto *cc = new control_conn_t(event_loop, &sset, fd);
+
+    std::vector<char> cmd = { DINIT_CP_FINDSERVICE };
+    uint16_t name_len = strlen(service_name_2);
+    char *name_len_cptr = reinterpret_cast<char *>(&name_len);
+    cmd.insert(cmd.end(), name_len_cptr, name_len_cptr + sizeof(name_len));
+    cmd.insert(cmd.end(), service_name_2, service_name_2 + name_len);
+
+    bp_sys::supply_read_data(fd, std::move(cmd));
+
+    event_loop.regd_bidi_watchers[fd]->read_ready(event_loop, fd);
+
+    // We expect:
+    // (1 byte)   DINIT_RP_SERVICERECORD
+    // (1 byte)   state
+    // (handle_t) handle
+    // (1 byte)   target state
+
+    std::vector<char> wdata;
+    bp_sys::extract_written_data(fd, wdata);
+
+    assert(wdata.size() == 3 + sizeof(control_conn_t::handle_t));
+    assert(wdata[0] == DINIT_RP_SERVICERECORD);
+    service_state_t s = static_cast<service_state_t>(wdata[1]);
+    assert(s == service_state_t::STARTED);
+    service_state_t ts = static_cast<service_state_t>(wdata[6]);
+    assert(ts == service_state_t::STARTED);
+
+    delete cc;
+}
+
+// test finding non-existing service
+void cptest_findservice3()
+{
+    service_set sset;
+
+    const char * const service_name_2 = "test-service-n";
+
+    service_record *s1 = new service_record(&sset, "test-service-1", service_type_t::INTERNAL, {});
+    sset.add_service(s1);
+    service_record *s2 = new service_record(&sset, "test-service-2", service_type_t::INTERNAL, {});
+    sset.add_service(s2);
+    service_record *s3 = new service_record(&sset, "test-service-3", service_type_t::INTERNAL, {});
+    sset.add_service(s3);
+
+    sset.start_service(s2);
+    sset.process_queues();
+
+    int fd = bp_sys::allocfd();
+    auto *cc = new control_conn_t(event_loop, &sset, fd);
+
+    std::vector<char> cmd = { DINIT_CP_FINDSERVICE };
+    uint16_t name_len = strlen(service_name_2);
+    char *name_len_cptr = reinterpret_cast<char *>(&name_len);
+    cmd.insert(cmd.end(), name_len_cptr, name_len_cptr + sizeof(name_len));
+    cmd.insert(cmd.end(), service_name_2, service_name_2 + name_len);
+
+    bp_sys::supply_read_data(fd, std::move(cmd));
+
+    event_loop.regd_bidi_watchers[fd]->read_ready(event_loop, fd);
+
+    // We expect:
+    // (1 byte)   DINIT_RP_NOSERVICE
+
+    std::vector<char> wdata;
+    bp_sys::extract_written_data(fd, wdata);
+
+    assert(wdata.size() == 1);
+    assert(wdata[0] == DINIT_RP_NOSERVICE);
+
+    delete cc;
+}
+
 
 #define RUN_TEST(name, spacing) \
     std::cout << #name "..." spacing; \
@@ -103,5 +238,8 @@ int main(int argc, char **argv)
 {
     RUN_TEST(cptest_queryver, "    ");
     RUN_TEST(cptest_listservices, "");
+    RUN_TEST(cptest_findservice1, "");
+    RUN_TEST(cptest_findservice2, "");
+    RUN_TEST(cptest_findservice3, "");
     return 0;
 }