aboutsummaryrefslogtreecommitdiff
path: root/components/service/common/provider/test/service_framework_tests.cpp
blob: 4aa3fdcee381a2d2c6a12443497ffe19cefe6dab (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
/*
 * Copyright (c) 2020, Arm Limited and Contributors. All rights reserved.
 *
 * SPDX-License-Identifier: BSD-3-Clause
 */

#include <string>
#include <cstring>
#include <service/common/provider/service_provider.h>
#include <protocols/rpc/common/packed-c/status.h>
#include <rpc/direct/direct_caller.h>
#include <CppUTest/TestHarness.h>


TEST_GROUP(ServiceFrameworkTests)
{
    static rpc_status_t handlerThatSucceeds(void *context, struct call_req* req)
    {
        (void)context;

        struct call_param_buf *respBuf = call_req_get_resp_buf(req);

        std::string responseString("Yay!");
        respBuf->data_len = responseString.copy((char*)respBuf->data, respBuf->size);

        call_req_set_opstatus(req, SERVICE_SPECIFIC_SUCCESS_CODE);

        return TS_RPC_CALL_ACCEPTED;
    }

    static rpc_status_t handlerThatFails(void *context, struct call_req* req)
    {
        (void)context;

        struct call_param_buf *respBuf = call_req_get_resp_buf(req);

        std::string responseString("Ehh!");
        respBuf->data_len = responseString.copy((char*)respBuf->data, respBuf->size);

        call_req_set_opstatus(req, SERVICE_SPECIFIC_ERROR_CODE);

        return TS_RPC_CALL_ACCEPTED;
    }

    void setup()
    {
        memset(&m_direct_caller, sizeof(m_direct_caller), 0);
    }

    void teardown()
    {
        direct_caller_deinit(&m_direct_caller);
    }

    static const uint32_t SOME_ARBITRARY_OPCODE = 666;
    static const uint32_t ANOTHER_ARBITRARY_OPCODE = 901;
    static const uint32_t YET_ANOTHER_ARBITRARY_OPCODE = 7;
    static const int SERVICE_SPECIFIC_ERROR_CODE = 101;
    static const int SERVICE_SPECIFIC_SUCCESS_CODE = 100;

    struct direct_caller m_direct_caller;
};

TEST(ServiceFrameworkTests, serviceWithNoOps)
{
    /* Constructs a service endpoint with no handlers */
    struct service_provider ep;

    service_provider_init(&ep, &ep, NULL, 0);
    struct rpc_caller *caller = direct_caller_init_default(&m_direct_caller,
                                            service_provider_get_call_ep(&ep));

    rpc_call_handle handle;
    uint8_t *req_buf;
    uint8_t *resp_buf;
    size_t req_len = 100;
    size_t resp_len;
    int opstatus;

    handle = rpc_caller_begin(caller, &req_buf, req_len);
    CHECK(handle);

    rpc_status_t rpc_status = rpc_caller_invoke(caller, handle, SOME_ARBITRARY_OPCODE,
                                    &opstatus, &resp_buf, &resp_len);

    rpc_caller_end(caller, handle);

    CHECK_EQUAL(TS_RPC_ERROR_INVALID_OPCODE, rpc_status);
}

TEST(ServiceFrameworkTests, serviceWithOps)
{
    /* Constructs a service endpoint with a couple of handlers */
    struct service_handler handlers[2];
    handlers[0].opcode = SOME_ARBITRARY_OPCODE;
    handlers[0].invoke = handlerThatSucceeds;
    handlers[1].opcode = ANOTHER_ARBITRARY_OPCODE;
    handlers[1].invoke = handlerThatFails;

    struct service_provider ep;

    service_provider_init(&ep, &ep, handlers, 2);
    struct rpc_caller *caller = direct_caller_init_default(&m_direct_caller,
                                            service_provider_get_call_ep(&ep));

    rpc_call_handle handle;
    rpc_status_t rpc_status;
    uint8_t *req_buf;
    uint8_t *resp_buf;
    size_t req_len = 100;
    size_t resp_len;
    int opstatus;
    std::string respString;

    /* Expect this call transaction to succeed */
    handle = rpc_caller_begin(caller, &req_buf, req_len);
    CHECK(handle);

    rpc_status = rpc_caller_invoke(caller, handle, SOME_ARBITRARY_OPCODE,
                                    &opstatus, &resp_buf, &resp_len);

    respString = std::string((const char*)resp_buf, resp_len);

    rpc_caller_end(caller, handle);

    CHECK_EQUAL(TS_RPC_CALL_ACCEPTED, rpc_status);
    CHECK_EQUAL(SERVICE_SPECIFIC_SUCCESS_CODE, opstatus);
    CHECK(respString == "Yay!");

    /* Expect this call transaction to fail */
    handle = rpc_caller_begin(caller, &req_buf, req_len);
    CHECK(handle);

    rpc_status = rpc_caller_invoke(caller, handle, ANOTHER_ARBITRARY_OPCODE,
        &opstatus, &resp_buf, &resp_len);

    respString = std::string((const char*)resp_buf, resp_len);

    rpc_caller_end(caller, handle);

    CHECK_EQUAL(TS_RPC_CALL_ACCEPTED, rpc_status);
    CHECK_EQUAL(SERVICE_SPECIFIC_ERROR_CODE, opstatus);
    CHECK(respString == "Ehh!");

    /* Try an unsupported opcode */
    handle = rpc_caller_begin(caller, &req_buf, req_len);
    CHECK(handle);

    rpc_status = rpc_caller_invoke(caller, handle, YET_ANOTHER_ARBITRARY_OPCODE,
        &opstatus, &resp_buf, &resp_len);

    rpc_caller_end(caller, handle);

    CHECK_EQUAL(TS_RPC_ERROR_INVALID_OPCODE, rpc_status);
}