blob: 3c583032d3e01c3283b899b710a351d056d96b68 [file] [log] [blame]
Prashanth Swaminathan49a4a822021-01-12 18:41:52 -08001// Copyright 2021 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 "pw_log_sink/log_sink.h"
16
17#include <string>
18
19#include "gtest/gtest.h"
20#include "pw_log/levels.h"
21#include "pw_log_proto/log.pwpb.h"
22#include "pw_protobuf/decoder.h"
23
24namespace pw::log_sink {
25namespace {
26constexpr size_t kMaxTokenizedMessageSize = 512;
27constexpr char kTokenizedMessage[] = "Test Message";
28
29class TestSink : public Sink {
30 public:
31 void HandleEntry(ConstByteSpan message) {
32 pw::protobuf::Decoder log_decoder(message);
33 std::string_view log_entry_message;
34
35 EXPECT_TRUE(log_decoder.Next().ok()); // line_level - 2
36 EXPECT_TRUE(log_decoder.Next().ok()); // flags - 3
37 EXPECT_TRUE(log_decoder.Next().ok()); // timestamp - 5
38 EXPECT_TRUE(log_decoder.Next().ok()); // message_string - 16
39 EXPECT_EQ(16U, log_decoder.FieldNumber());
40 EXPECT_TRUE(log_decoder.ReadString(&log_entry_message).ok());
41
42 last_message_string_ = log_entry_message;
43 message_count_++;
44 }
45
46 void HandleDropped(size_t count) { drop_count_ += count; }
47
48 void VerifyMessage(std::string tokenized_message) {
49 EXPECT_EQ(tokenized_message, last_message_string_);
50 }
51
52 size_t GetMessageCount() { return message_count_; }
53 size_t GetDropCount() { return drop_count_; }
54
55 private:
56 std::string last_message_string_;
57 size_t message_count_ = 0;
58 size_t drop_count_ = 0;
59};
60
61void LogMessageForTest(const char* message) {
62 pw_LogSink_Log(0, 0, nullptr, nullptr, 0, nullptr, "%s", message);
63}
64
65void LogInvalidMessageForTest() {
66 char long_message[kMaxTokenizedMessageSize + 1];
67 memset(long_message, 'A', sizeof(long_message));
68 long_message[kMaxTokenizedMessageSize] = '\0';
69
70 pw_LogSink_Log(0, 0, nullptr, nullptr, 0, nullptr, "%s", long_message);
71}
72
73} // namespace
74
75TEST(LogSink, NoSink) {
76 // Confirm that the log function does not crash when no sink is present.
77 LogMessageForTest(kTokenizedMessage);
78}
79
80TEST(LogSink, SingleSink) {
81 TestSink test_sink;
82
83 AddSink(test_sink);
84 LogMessageForTest(kTokenizedMessage);
85 test_sink.VerifyMessage(kTokenizedMessage);
86 RemoveSink(test_sink);
87}
88
89TEST(LogSink, MultipleSink) {
90 TestSink test_sink_io;
91 TestSink test_sink_bt;
92
93 AddSink(test_sink_io);
94 AddSink(test_sink_bt);
95 LogMessageForTest(kTokenizedMessage);
96 test_sink_io.VerifyMessage(kTokenizedMessage);
97 test_sink_bt.VerifyMessage(kTokenizedMessage);
98
99 RemoveSink(test_sink_io);
100 LogMessageForTest(kTokenizedMessage);
101 test_sink_io.VerifyMessage(kTokenizedMessage);
102 EXPECT_EQ(test_sink_io.GetMessageCount(), 1U);
103 EXPECT_EQ(test_sink_bt.GetMessageCount(), 2U);
104
105 RemoveSink(test_sink_bt);
106}
107
108TEST(LogSink, DroppedEntries) {
109 TestSink test_sink;
110
111 LogMessageForTest(kTokenizedMessage);
112
113 AddSink(test_sink);
114 LogMessageForTest(kTokenizedMessage);
115 EXPECT_EQ(test_sink.GetMessageCount(), 1U);
116 EXPECT_EQ(test_sink.GetDropCount(), 1U);
117
118 LogInvalidMessageForTest();
119 EXPECT_EQ(test_sink.GetMessageCount(), 1U);
120 EXPECT_EQ(test_sink.GetDropCount(), 2U);
121
122 LogMessageForTest(kTokenizedMessage);
123 EXPECT_EQ(test_sink.GetMessageCount(), 2U);
124 EXPECT_EQ(test_sink.GetDropCount(), 2U);
125
126 RemoveSink(test_sink);
127}
128
129} // namespace pw::log_sink