blob: 10ab42a798e4cbd72b6075ef1643077ca388d934 [file] [log] [blame]
Alexei Frolov7fb63af2020-07-09 17:05:52 -07001// Copyright 2020 The Pigweed Authors
2//
3// Licensed under the Apache License, Version 2.0 (the "License"); you may not
4// use this file except in compliance with the License. You may obtain a copy of
5// the License at
6//
7// https://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
11// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12// License for the specific language governing permissions and limitations under
13// the License.
14
15#include "gtest/gtest.h"
Alexei Frolov15255c52020-07-17 08:25:49 -070016#include "pw_rpc/internal/hash.h"
Wyatt Hepler8aa02922020-07-17 08:54:37 -070017#include "pw_rpc/test_method_context.h"
Alexei Frolov3ab26ff2020-07-21 10:44:58 -070018#include "pw_rpc_test_protos/test.rpc.pb.h"
Alexei Frolov7fb63af2020-07-09 17:05:52 -070019
Wyatt Hepler8aa02922020-07-17 08:54:37 -070020namespace pw::rpc {
21namespace test {
22
Alexei Frolov3ab26ff2020-07-21 10:44:58 -070023class TestService final : public generated::TestService<TestService> {
Alexei Frolovabb0f992020-07-17 16:34:41 -070024 public:
25 Status TestRpc(ServerContext&,
26 const pw_rpc_test_TestRequest& request,
27 pw_rpc_test_TestResponse& response) {
28 response.value = request.integer + 1;
29 return static_cast<Status::Code>(request.status_code);
Wyatt Hepler8aa02922020-07-17 08:54:37 -070030 }
31
Alexei Frolovabb0f992020-07-17 16:34:41 -070032 void TestStreamRpc(ServerContext&,
33 const pw_rpc_test_TestRequest& request,
34 ServerWriter<pw_rpc_test_TestStreamResponse>& writer) {
35 for (int i = 0; i < request.integer; ++i) {
Wyatt Hepler85eb7c92020-08-06 13:45:20 -070036 writer.Write({.chunk = {}, .number = static_cast<uint32_t>(i)});
Alexei Frolovabb0f992020-07-17 16:34:41 -070037 }
38
39 writer.Finish(static_cast<Status::Code>(request.status_code));
40 }
41};
Wyatt Hepler8aa02922020-07-17 08:54:37 -070042
43} // namespace test
44
Alexei Frolov7fb63af2020-07-09 17:05:52 -070045namespace {
46
47TEST(NanopbCodegen, CompilesProperly) {
Alexei Frolov3ab26ff2020-07-21 10:44:58 -070048 test::TestService service;
Wyatt Hepler1532e522020-07-30 11:44:58 -070049 EXPECT_EQ(service.id(), internal::Hash("pw.rpc.test.TestService"));
Alexei Frolov7fb63af2020-07-09 17:05:52 -070050 EXPECT_STREQ(service.name(), "TestService");
51}
52
Wyatt Hepler8aa02922020-07-17 08:54:37 -070053TEST(NanopbCodegen, InvokeUnaryRpc) {
Wyatt Hepler1532e522020-07-30 11:44:58 -070054 TestMethodContext<&test::TestService::TestRpc> context;
Wyatt Hepler8aa02922020-07-17 08:54:37 -070055
Wyatt Heplerd78f7c62020-09-28 14:27:32 -070056 EXPECT_EQ(Status::Ok(),
57 context.call({.integer = 123, .status_code = Status::Ok()}));
Wyatt Hepler8aa02922020-07-17 08:54:37 -070058
59 EXPECT_EQ(124, context.response().value);
60
61 EXPECT_EQ(
Wyatt Heplerd78f7c62020-09-28 14:27:32 -070062 Status::InvalidArgument(),
63 context.call({.integer = 999, .status_code = Status::InvalidArgument()}));
Wyatt Hepler8aa02922020-07-17 08:54:37 -070064 EXPECT_EQ(1000, context.response().value);
65}
66
67TEST(NanopbCodegen, InvokeStreamingRpc) {
Wyatt Hepler1532e522020-07-30 11:44:58 -070068 TestMethodContext<&test::TestService::TestStreamRpc> context;
Wyatt Hepler8aa02922020-07-17 08:54:37 -070069
Wyatt Heplerd78f7c62020-09-28 14:27:32 -070070 context.call({.integer = 0, .status_code = Status::Aborted()});
Wyatt Hepler8aa02922020-07-17 08:54:37 -070071
Wyatt Heplerd78f7c62020-09-28 14:27:32 -070072 EXPECT_EQ(Status::Aborted(), context.status());
Wyatt Hepler8aa02922020-07-17 08:54:37 -070073 EXPECT_TRUE(context.done());
74 EXPECT_TRUE(context.responses().empty());
75 EXPECT_EQ(0u, context.total_responses());
76
Wyatt Heplerd78f7c62020-09-28 14:27:32 -070077 context.call({.integer = 4, .status_code = Status::Ok()});
Wyatt Hepler8aa02922020-07-17 08:54:37 -070078
79 ASSERT_EQ(4u, context.responses().size());
80 ASSERT_EQ(4u, context.total_responses());
81
82 for (size_t i = 0; i < context.responses().size(); ++i) {
83 EXPECT_EQ(context.responses()[i].number, i);
84 }
85
Wyatt Heplerd78f7c62020-09-28 14:27:32 -070086 EXPECT_EQ(Status::Ok(), context.status());
Wyatt Hepler8aa02922020-07-17 08:54:37 -070087}
88
89TEST(NanopbCodegen, InvokeStreamingRpc_ContextKeepsFixedNumberOfResponses) {
Wyatt Hepler1532e522020-07-30 11:44:58 -070090 TestMethodContext<&test::TestService::TestStreamRpc, 3> context;
Wyatt Hepler8aa02922020-07-17 08:54:37 -070091
92 ASSERT_EQ(3u, context.responses().max_size());
93
Wyatt Heplerd78f7c62020-09-28 14:27:32 -070094 context.call({.integer = 5, .status_code = Status::NotFound()});
Wyatt Hepler8aa02922020-07-17 08:54:37 -070095
96 ASSERT_EQ(3u, context.responses().size());
97 ASSERT_EQ(5u, context.total_responses());
98
99 EXPECT_EQ(context.responses()[0].number, 0u);
100 EXPECT_EQ(context.responses()[1].number, 1u);
101 EXPECT_EQ(context.responses()[2].number, 4u);
102}
103
Alexei Frolov91172612020-07-21 17:08:03 -0700104TEST(NanopbCodegen, InvokeStreamingRpc_ManualWriting) {
Wyatt Hepler1532e522020-07-30 11:44:58 -0700105 TestMethodContext<&test::TestService::TestStreamRpc, 3> context;
Alexei Frolov91172612020-07-21 17:08:03 -0700106
107 ASSERT_EQ(3u, context.responses().max_size());
108
109 auto writer = context.writer();
110
Wyatt Hepler85eb7c92020-08-06 13:45:20 -0700111 writer.Write({.chunk = {}, .number = 3});
112 writer.Write({.chunk = {}, .number = 6});
113 writer.Write({.chunk = {}, .number = 9});
Alexei Frolov91172612020-07-21 17:08:03 -0700114
115 EXPECT_FALSE(context.done());
116
Wyatt Heplerd78f7c62020-09-28 14:27:32 -0700117 writer.Finish(Status::Cancelled());
Alexei Frolov91172612020-07-21 17:08:03 -0700118 ASSERT_TRUE(context.done());
Wyatt Heplerd78f7c62020-09-28 14:27:32 -0700119 EXPECT_EQ(Status::Cancelled(), context.status());
Alexei Frolov91172612020-07-21 17:08:03 -0700120
121 ASSERT_EQ(3u, context.responses().size());
122 ASSERT_EQ(3u, context.total_responses());
123
124 EXPECT_EQ(context.responses()[0].number, 3u);
125 EXPECT_EQ(context.responses()[1].number, 6u);
126 EXPECT_EQ(context.responses()[2].number, 9u);
127}
128
Alexei Frolov7fb63af2020-07-09 17:05:52 -0700129} // namespace
Wyatt Hepler8aa02922020-07-17 08:54:37 -0700130} // namespace pw::rpc