| // Copyright 2020 The Pigweed Authors |
| // |
| // Licensed under the Apache License, Version 2.0 (the "License"); you may not |
| // use this file except in compliance with the License. You may obtain a copy of |
| // the License at |
| // |
| // https://www.apache.org/licenses/LICENSE-2.0 |
| // |
| // Unless required by applicable law or agreed to in writing, software |
| // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT |
| // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the |
| // License for the specific language governing permissions and limitations under |
| // the License. |
| |
| #include "pw_log_rpc/logs_rpc.h" |
| |
| #include "gtest/gtest.h" |
| #include "pw_log/log.h" |
| #include "pw_rpc/raw_test_method_context.h" |
| |
| namespace pw::log_rpc { |
| namespace { |
| |
| #define LOGS_METHOD_CONTEXT PW_RAW_TEST_METHOD_CONTEXT(Logs, Get) |
| |
| constexpr size_t kEncodeBufferSize = 128; |
| constexpr size_t kLogBufferSize = 4096; |
| |
| class LogQueueTester : public LogQueueWithEncodeBuffer<kLogBufferSize> { |
| public: |
| LogQueueTester(ByteSpan log_queue) |
| : LogQueueWithEncodeBuffer<kLogBufferSize>(log_queue) {} |
| |
| void SetPopStatus(Status error_status) { |
| pop_status_for_test_ = error_status; |
| } |
| }; |
| |
| class LogsService : public ::testing::Test { |
| public: |
| LogsService() : log_queue_(log_queue_buffer_) {} |
| |
| protected: |
| void AddLogs(const size_t log_count = 1) { |
| constexpr char kTokenizedMessage[] = "message"; |
| for (size_t i = 0; i < log_count; i++) { |
| EXPECT_EQ( |
| OkStatus(), |
| log_queue_.PushTokenizedMessage( |
| std::as_bytes(std::span(kTokenizedMessage)), 0, 0, 0, 0, 0)); |
| } |
| } |
| |
| static Logs& GetLogs(LOGS_METHOD_CONTEXT& context) { |
| return (Logs&)(context.service()); |
| } |
| |
| std::array<std::byte, kEncodeBufferSize> log_queue_buffer_; |
| LogQueueWithEncodeBuffer<kLogBufferSize> log_queue_; |
| }; |
| |
| TEST_F(LogsService, Get) { |
| constexpr size_t kLogEntryCount = 3; |
| std::array<std::byte, 1> rpc_buffer; |
| LOGS_METHOD_CONTEXT context(log_queue_); |
| |
| context.call(rpc_buffer); |
| |
| // Flush all logs from the buffer, then close the RPC. |
| AddLogs(kLogEntryCount); |
| GetLogs(context).Flush(); |
| GetLogs(context).Finish(); |
| |
| EXPECT_TRUE(context.done()); |
| EXPECT_EQ(OkStatus(), context.status()); |
| |
| // Although |kLogEntryCount| messages were in the queue, they are batched |
| // before being written to the client, so there is only one response. |
| EXPECT_EQ(1U, context.total_responses()); |
| } |
| |
| TEST_F(LogsService, GetMultiple) { |
| constexpr size_t kLogEntryCount = 1; |
| constexpr size_t kFlushCount = 3; |
| std::array<std::byte, 1> rpc_buffer; |
| LOGS_METHOD_CONTEXT context(log_queue_); |
| |
| context.call(rpc_buffer); |
| |
| for (size_t i = 0; i < kFlushCount; i++) { |
| AddLogs(kLogEntryCount); |
| GetLogs(context).Flush(); |
| } |
| GetLogs(context).Finish(); |
| |
| EXPECT_TRUE(context.done()); |
| EXPECT_EQ(OkStatus(), context.status()); |
| EXPECT_EQ(kFlushCount, context.total_responses()); |
| } |
| |
| TEST_F(LogsService, NoEntriesOnEmptyQueue) { |
| std::array<std::byte, 1> rpc_buffer; |
| LOGS_METHOD_CONTEXT context(log_queue_); |
| |
| // Invoking flush with no logs in the queue should behave like a no-op. |
| context.call(rpc_buffer); |
| GetLogs(context).Flush(); |
| GetLogs(context).Finish(); |
| |
| EXPECT_TRUE(context.done()); |
| EXPECT_EQ(OkStatus(), context.status()); |
| EXPECT_EQ(0U, context.total_responses()); |
| } |
| |
| TEST_F(LogsService, QueueError) { |
| std::array<std::byte, 1> rpc_buffer; |
| LogQueueTester log_queue_tester(log_queue_buffer_); |
| LOGS_METHOD_CONTEXT context(log_queue_tester); |
| |
| // Generate failure on log queue. |
| log_queue_tester.SetPopStatus(Status::Internal()); |
| context.call(rpc_buffer); |
| GetLogs(context).Flush(); |
| GetLogs(context).Finish(); |
| |
| EXPECT_TRUE(context.done()); |
| EXPECT_EQ(OkStatus(), context.status()); |
| EXPECT_EQ(0U, context.total_responses()); |
| } |
| |
| } // namespace |
| } // namespace pw::log_rpc |