log_node_test.cpp
Go to the documentation of this file.
1 /*
2  * Copyright 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License").
5  * You may not use this file except in compliance with the License.
6  * A copy of the License is located at
7  *
8  * http://aws.amazon.com/apache2.0
9  *
10  * or in the "license" file accompanying this file. This file is distributed
11  * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
12  * express or implied. See the License for the specific language governing
13  * permissions and limitations under the License.
14  */
15 
16 #include <gtest/gtest.h>
17 #include <gmock/gmock.h>
18 
24 #include <rosgraph_msgs/Log.h>
25 
26 #include <utility>
27 
28 using namespace Aws::CloudWatchLogs;
29 using namespace Aws::CloudWatchLogs::Utils;
30 using namespace Aws::FileManagement;
31 using ::testing::_;
32 using ::testing::AllOf;
33 using ::testing::HasSubstr;
34 using ::testing::Return;
35 using ::testing::StrEq;
36 using ::testing::Eq;
37 using ::testing::InSequence;
38 
40 {
41  public:
42  MOCK_METHOD5(CreateLogService,
43  std::shared_ptr<LogService>(
44  const std::string & log_group,
45  const std::string & log_stream,
46  const Aws::Client::ClientConfiguration & client_config,
47  const Aws::SDKOptions & sdk_options,
48  const CloudWatchOptions & cloudwatch_option
49  )
50  );
51 };
52 
53 class LogBatcherMock : public LogBatcher
54 {
55 public:
56 
57  MOCK_METHOD0(publishBatchedData, bool());
58 };
59 
61 {
62 public:
63  LogPublisherMock(const std::string & log_group,
64  const std::string & log_stream,
65  const Aws::Client::ClientConfiguration & client_config)
66  : LogPublisher(log_group, log_stream, client_config) {}
67 };
68 
69 class LogServiceMock : public LogService
70 {
71 public:
72  LogServiceMock(std::shared_ptr<Publisher<LogCollection>> log_publisher,
73  std::shared_ptr<DataBatcher<LogType>> log_batcher,
74  std::shared_ptr<FileUploadStreamer<LogCollection>> log_file_upload_streamer = nullptr)
75  : LogService(std::move(log_publisher), std::move(log_batcher), std::move(log_file_upload_streamer)) {}
76 
77  MOCK_METHOD1(batchData, bool(const std::string & data_to_batch));
78  MOCK_METHOD0(start, bool());
79  MOCK_METHOD0(shutdown, bool());
80  MOCK_METHOD0(publishBatchedData, bool());
81 };
82 
83 class LogNodeFixture : public ::testing::Test
84 {
85 protected:
86 
87  std::shared_ptr<LogServiceMock> log_service;
88  std::shared_ptr<LogServiceFactoryMock> log_service_factory;
89  std::shared_ptr<LogBatcherMock> log_batcher;
90  std::shared_ptr<LogPublisherMock> log_publisher;
91  std::shared_ptr<LogNode> log_node;
92 
93  rosgraph_msgs::Log log_message_;
94 
95  void SetUp() override
96  {
97  log_message_.name = "NjhkYjRkZjQ3N2Qw";
98  log_message_.msg = "ZjQxOGE2MWM5MTFkMWNjMDVkMGY2OTZm";
99  log_message_.level = rosgraph_msgs::Log::DEBUG;
100  Aws::Client::ClientConfiguration config;
101 
102  log_publisher = std::make_shared<LogPublisherMock>(
103  std::string("test_group"), std::string("test_stream"), config);
104  log_batcher = std::make_shared<LogBatcherMock>();
105  log_service = std::make_shared<LogServiceMock>(log_publisher, log_batcher);
106  log_service_factory = std::make_shared<LogServiceFactoryMock>();
107  }
108 
109  std::shared_ptr<LogNode> build_test_subject(
110  int8_t severity_level = rosgraph_msgs::Log::DEBUG,
111  bool publish_topic_names = true,
112  const std::unordered_set<std::string> & ignore_nodes = std::unordered_set<std::string>())
113  {
115  severity_level,
116  publish_topic_names,
117  ignore_nodes
118  };
119  return std::make_shared<LogNode>(logger_options);
120  }
121 
122  rosgraph_msgs::Log::ConstPtr message_to_constptr(rosgraph_msgs::Log log_message)
123  {
124  return boost::make_shared<rosgraph_msgs::Log const>(log_message);
125  }
126 
127  void initialize_log_node(std::shared_ptr<LogNode> & ln) {
128 
129  log_node = ln;
130 
131  std::string log_group = "YjFjMTM5YTEyNzliMjdlNjBlZGY1ZjQy";
132  std::string log_stream = "hZDExYmNmMGJkMjMw";
133  Aws::Client::ClientConfiguration config;
134  Aws::SDKOptions sdk_options;
135  Aws::CloudWatchLogs::CloudWatchOptions cloudwatch_options;
136 
137  EXPECT_CALL(*log_service_factory,
138  CreateLogService(StrEq(log_group), StrEq(log_stream), Eq(config), _, _))
139  .WillOnce(Return(log_service));
140 
141  log_node->Initialize(log_group, log_stream, config, sdk_options, cloudwatch_options, log_service_factory);
142 
143  EXPECT_CALL(*log_service, start()).Times(1);
144 
145  log_node->start();
146  }
147 
148  void TearDown() override {
149 
150  if(log_node) {
151 
152  EXPECT_CALL(*log_service, shutdown()).Times(1);
153  log_node->shutdown();
154  }
155  }
156 };
157 
158 TEST_F(LogNodeFixture, TestInitialize)
159 {
160  std::shared_ptr<LogNode> test_subject = build_test_subject();
161  initialize_log_node(test_subject);
162 }
163 
164 TEST_F(LogNodeFixture, TestRecordLogsUninitialized)
165 {
166  std::shared_ptr<LogNode> test_subject = build_test_subject();
167 
168  EXPECT_CALL(*log_service, batchData(_)).Times(0);
169  EXPECT_CALL(*log_service, start()).Times(0);
170 
171  test_subject->RecordLogs(message_to_constptr(log_message_));
172 }
173 
174 TEST_F(LogNodeFixture, TestRecordLogsInitialized)
175 {
176  std::shared_ptr<LogNode> test_subject = build_test_subject();
177 
178  EXPECT_CALL(*log_service, batchData(_)).Times(1);
179 
180  initialize_log_node(test_subject);
181  test_subject->RecordLogs(message_to_constptr(log_message_));
182 }
183 
184 TEST_F(LogNodeFixture, TestRecordLogSevBelowMinSeverity)
185 {
186  std::shared_ptr<LogNode> test_subject = build_test_subject(rosgraph_msgs::Log::ERROR);
187 
188  initialize_log_node(test_subject);
189 
190  ON_CALL(*log_service, batchData(_))
191  .WillByDefault(Return(true));
192  EXPECT_CALL(*log_service, batchData(_))
193  .Times(0);
194 
195  log_message_.level = rosgraph_msgs::Log::DEBUG;
196  test_subject->RecordLogs(message_to_constptr(log_message_));
197  log_message_.level = rosgraph_msgs::Log::INFO;
198  test_subject->RecordLogs(message_to_constptr(log_message_));
199  log_message_.level = rosgraph_msgs::Log::WARN;
200  test_subject->RecordLogs(message_to_constptr(log_message_));
201 }
202 
203 TEST_F(LogNodeFixture, TestDontPublishTopicNames)
204 {
205  std::shared_ptr<LogNode> test_subject = build_test_subject(rosgraph_msgs::Log::DEBUG, false);
206  initialize_log_node(test_subject);
207 
208  const std::string log_name_reference_str = std::string("[node name: ") + log_message_.name + "]";
209  const std::string log_topics_reference_str = "[topics: ]";
210 
211  EXPECT_CALL(*log_service,
212  batchData(AllOf(
213  HasSubstr("DEBUG"),
214  HasSubstr(log_message_.msg),
215  HasSubstr(log_name_reference_str),
216  Not(HasSubstr(log_topics_reference_str))
217  )))
218  .WillOnce(Return(true));
219 
220  test_subject->RecordLogs(message_to_constptr(log_message_));
221 }
222 
223 TEST_F(LogNodeFixture, TestRecordLogSevEqGtMinSeverity)
224 {
225  std::shared_ptr<LogNode> test_subject = build_test_subject(rosgraph_msgs::Log::ERROR);
226 
227  initialize_log_node(test_subject);
228 
229  ON_CALL(*log_service, batchData(_))
230  .WillByDefault(Return(true));
231  EXPECT_CALL(*log_service, batchData(_))
232  .Times(2);
233 
234  log_message_.level = rosgraph_msgs::Log::ERROR;
235  test_subject->RecordLogs(message_to_constptr(log_message_));
236  log_message_.level = rosgraph_msgs::Log::FATAL;
237  test_subject->RecordLogs(message_to_constptr(log_message_));
238 
239  ON_CALL(*log_service, publishBatchedData())
240  .WillByDefault(Return(true));
241  EXPECT_CALL(*log_service, publishBatchedData())
242  .Times(1);
243 
244  // this is usually called by a timer, manually test
245  ros::TimerEvent timer_event;
246  test_subject->TriggerLogPublisher(timer_event);
247 }
248 
249 TEST_F(LogNodeFixture, TestRecordLogTopicsOk)
250 {
251  std::shared_ptr<LogNode> test_subject = build_test_subject();
252 
253  initialize_log_node(test_subject);
254 
255  const char* node_name2 = "zNzQwNjU4NWRi";
256  std::ostringstream log_name_reference_stream2;
257  log_name_reference_stream2 << "[node name: " << node_name2 << "]";
258 
259  const char* topic1 = "ZjlkYmUzOTI5ODA0ZT";
260  const char* topic2 = "jNjIxMWRm";
261  std::ostringstream log_topics_reference_stream2;
262  log_topics_reference_stream2 << "[topics: " << topic1 << ", " << topic2 << "] ";
263 
264  {
265  InSequence record_log_seq;
266 
267  std::ostringstream log_name_reference_stream1;
268  log_name_reference_stream1 << "[node name: " << log_message_.name << "]";
269  std::ostringstream log_topics_reference_stream1;
270  log_topics_reference_stream1 << "[topics: ]";
271 
272  EXPECT_CALL(*log_service,
273  batchData(AllOf(
274  HasSubstr("DEBUG"), HasSubstr(log_message_.msg),
275  HasSubstr(log_name_reference_stream1.str()), HasSubstr(log_topics_reference_stream1.str())
276  )))
277  .WillOnce(Return(true));
278 
279  EXPECT_CALL(*log_service,
280  batchData(AllOf(
281  HasSubstr("INFO"), HasSubstr(log_message_.msg),
282  HasSubstr(log_name_reference_stream2.str()), HasSubstr(log_topics_reference_stream1.str())
283  )))
284  .WillOnce(Return(true));
285 
286  EXPECT_CALL(*log_service,
287  batchData(AllOf(
288  HasSubstr("WARN"), HasSubstr(log_message_.msg),
289  HasSubstr(log_name_reference_stream1.str()), HasSubstr(log_topics_reference_stream2.str())
290  )))
291  .WillOnce(Return(true));
292  }
293 
294  log_message_.level = rosgraph_msgs::Log::DEBUG;
295  test_subject->RecordLogs(message_to_constptr(log_message_));
296 
297  rosgraph_msgs::Log log_message2 = log_message_;
298  log_message2.level = rosgraph_msgs::Log::INFO;
299  log_message2.name = node_name2;
300  test_subject->RecordLogs(message_to_constptr(log_message2));
301 
302  rosgraph_msgs::Log log_message3 = log_message_;
303  log_message3.topics.push_back(topic1);
304  log_message3.topics.push_back(topic2);
305  log_message3.level = rosgraph_msgs::Log::WARN;
306  test_subject->RecordLogs(message_to_constptr(log_message3));
307 }
308 
309 TEST_F(LogNodeFixture, TestRecordLogIgnoreList)
310 {
311  std::unordered_set<std::string> ignore_nodes;
312  ignore_nodes.emplace(log_message_.name);
313  std::shared_ptr<LogNode> test_subject = build_test_subject(rosgraph_msgs::Log::DEBUG, true, ignore_nodes);
314 
315  initialize_log_node(test_subject);
316 
317  ON_CALL(*log_service, batchData(_))
318  .WillByDefault(Return(true));
319  EXPECT_CALL(*log_service, batchData(_))
320  .Times(0);
321 
322  log_message_.level = rosgraph_msgs::Log::INFO;
323  test_subject->RecordLogs(message_to_constptr(log_message_));
324 }
325 
327  ASSERT_TRUE(true);
328 }
329 
330 int main(int argc, char ** argv)
331 {
332  testing::InitGoogleTest(&argc, argv);
333  return RUN_ALL_TESTS();
334 }
ROSCPP_DECL void start()
std::shared_ptr< LogNode > log_node
LogPublisherMock(const std::string &log_group, const std::string &log_stream, const Aws::Client::ClientConfiguration &client_config)
std::shared_ptr< LogServiceMock > log_service
std::shared_ptr< LogPublisherMock > log_publisher
std::shared_ptr< LogServiceFactoryMock > log_service_factory
void initialize_log_node(std::shared_ptr< LogNode > &ln)
void SetUp() override
rosgraph_msgs::Log::ConstPtr message_to_constptr(rosgraph_msgs::Log log_message)
LogServiceMock(std::shared_ptr< Publisher< LogCollection >> log_publisher, std::shared_ptr< DataBatcher< LogType >> log_batcher, std::shared_ptr< FileUploadStreamer< LogCollection >> log_file_upload_streamer=nullptr)
std::shared_ptr< LogBatcherMock > log_batcher
std::shared_ptr< LogNode > build_test_subject(int8_t severity_level=rosgraph_msgs::Log::DEBUG, bool publish_topic_names=true, const std::unordered_set< std::string > &ignore_nodes=std::unordered_set< std::string >())
void TearDown() override
ROSCONSOLE_DECL void shutdown()
rosgraph_msgs::Log log_message_
int main(int argc, char **argv)
TEST_F(LogNodeFixture, TestInitialize)


cloudwatch_logger
Author(s): AWS RoboMaker
autogenerated on Sat Mar 6 2021 03:55:46