cloudwatch_facade_test.cpp
Go to the documentation of this file.
1 /*
2  * Copyright 2019 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 <aws/core/Aws.h>
17 #include <aws/core/client/AWSClient.h>
18 #include <aws/core/NoResult.h>
22 #include <gtest/gtest.h>
23 
24 using namespace Aws::CloudWatchLogs::Utils;
25 
26 constexpr char LOG_GROUP_NAME1[] = "TestGroup1";
27 constexpr char LOG_GROUP_NAME2[] = "TestGroup2";
28 constexpr char LOG_STREAM_NAME1[] = "TestStream1";
29 constexpr char LOG_STREAM_NAME2[] = "TestStream2";
30 
31 class TestCloudWatchFacade : public ::testing::Test
32 {
33 protected:
34  std::list<Aws::CloudWatchLogs::Model::InputLogEvent> logs_list_;
35  Aws::SDKOptions options_;
36  std::shared_ptr<CloudWatchLogsFacade> facade_;
37  std::shared_ptr<CloudWatchLogsClientMock> mock_client;
38  CloudWatchLogsClientMock* mock_client_p{};
39 
40  void SetUp() override
41  {
42  // the tests require non-empty logs_list_
43  logs_list_.emplace_back();
44  logs_list_.emplace_back();
45 
46  Aws::InitAPI(options_);
47  mock_client = std::make_shared<CloudWatchLogsClientMock>();
48  mock_client_p = mock_client.get();
49  facade_ = std::make_shared<CloudWatchLogsFacade>(mock_client);
50  }
51 
52  void TearDown() override
53  {
54  logs_list_.clear();
55  Aws::ShutdownAPI(options_);
56  }
57 
58  std::chrono::milliseconds Now() const {
59  return std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::steady_clock::now().time_since_epoch());
60  }
61 };
62 
63 /*
64  * SendLogsToCloudWatch Tests
65  */
66 TEST_F(TestCloudWatchFacade, TestCWLogsFacade_SendLogsToCloudWatch_EmptyLogs)
67 {
68  std::list<Aws::CloudWatchLogs::Model::InputLogEvent> empty_logs_list;
69  Aws::String nextToken;
71  facade_->SendLogsToCloudWatch(nextToken, "", "", empty_logs_list));
72 }
73 
74 TEST_F(TestCloudWatchFacade, TestCWLogsFacade_SendLogsToCloudWatch_FailedResponse)
75 {
76  Aws::CloudWatchLogs::Model::PutLogEventsOutcome failedOutcome;
77  EXPECT_CALL(*mock_client_p, PutLogEvents(testing::_))
78  .WillOnce(testing::Return(failedOutcome));
79  Aws::String nextToken;
80 
82  facade_->SendLogsToCloudWatch(nextToken, "", "", logs_list_));
83 }
84 
85 TEST_F(TestCloudWatchFacade, TestCWLogsFacade_SendLogsToCloudWatch_SuccessResponse)
86 {
87  Aws::CloudWatchLogs::Model::PutLogEventsResult successResult;
88  Aws::CloudWatchLogs::Model::PutLogEventsOutcome successOutcome(successResult);
89  EXPECT_CALL(*mock_client_p, PutLogEvents(testing::_))
90  .WillOnce(testing::Return(successOutcome));
91  Aws::String nextToken;
92 
94  facade_->SendLogsToCloudWatch(nextToken, "", "", logs_list_));
95 }
96 
97 TEST_F(TestCloudWatchFacade, TestCWLogsFacade_SendLogsToCloudWatch_LongSuccessResponse)
98 {
99  Aws::CloudWatchLogs::Model::PutLogEventsResult successResult;
100  Aws::CloudWatchLogs::Model::PutLogEventsOutcome successOutcome(successResult);
101  EXPECT_CALL(*mock_client_p, PutLogEvents(testing::_))
102  .Times(2)
103  .WillRepeatedly(testing::Return(successOutcome));
104 
105  Aws::String nextToken;
106  std::list<Aws::CloudWatchLogs::Model::InputLogEvent> logs_list;
107  for (int i=0;i<200;i++) {
108  logs_list.emplace_back();
109  }
110 
112  facade_->SendLogsToCloudWatch(nextToken, "", "", logs_list));
113 }
114 
115 TEST_F(TestCloudWatchFacade, TestCWLogsFacade_SendLogsToCloudWatch_RateLimitsPutLogEvents)
116 {
117  Aws::CloudWatchLogs::Model::PutLogEventsResult successResult;
118  Aws::CloudWatchLogs::Model::PutLogEventsOutcome successOutcome(successResult);
119  EXPECT_CALL(*mock_client_p, PutLogEvents(testing::_))
120  .WillRepeatedly(testing::Return(successOutcome));
121 
122  const size_t count = 20;
123  // Note - it is hardcoded here that we are limiting to 5 Hz
124  // which is a hidden implementation variable of CloudWatchLogsFacade
125  // Also note we check count-1, because the first call goes immediately
126  const double expect_seconds = (count - 1) / 5.0;
127  const std::chrono::milliseconds min_time(int(expect_seconds * 1000));
128 
129  Aws::String nextToken;
130  const auto start = Now();
131  for (int i = 0; i < 20; i++) {
133  facade_->SendLogsToCloudWatch(nextToken, "", "", logs_list_));
134  }
135  const auto end = Now();
136  // The elapsed time must be at least min_time, or we know rate limiting did not occur
137  EXPECT_GE((end - start).count(), min_time.count());
138 }
139 
140 
141 /*
142  * CreateLogGroup Tests
143  */
144 
145 TEST_F(TestCloudWatchFacade, TestCWLogsFacade_CreateLogGroup_SuccessResponse)
146 {
147  Aws::CloudWatchLogs::Model::CreateLogGroupOutcome* successOutcome =
148  new Aws::CloudWatchLogs::Model::CreateLogGroupOutcome(Aws::NoResult());
149 
150  EXPECT_CALL(*mock_client_p, CreateLogGroup(testing::_))
151  .WillOnce(testing::Return(*successOutcome));
152 
154  facade_->CreateLogGroup(LOG_GROUP_NAME1));
155 }
156 
157 TEST_F(TestCloudWatchFacade, TestCWLogsFacade_CreateLogGroup_FailedResponse)
158 {
159  auto* failedOutcome =
160  new Aws::CloudWatchLogs::Model::CreateLogGroupOutcome();
161 
162  EXPECT_CALL(*mock_client_p, CreateLogGroup(testing::_))
163  .WillOnce(testing::Return(*failedOutcome));
164 
166  facade_->CreateLogGroup(LOG_GROUP_NAME1));
167 }
168 
169 TEST_F(TestCloudWatchFacade, TestCWLogsFacade_CreateLogGroup_AlreadyExists)
170 {
171  Aws::Client::AWSError<Aws::CloudWatchLogs::CloudWatchLogsErrors> error
172  (Aws::CloudWatchLogs::CloudWatchLogsErrors::RESOURCE_ALREADY_EXISTS, false);
173 
174  auto* failedOutcome =
175  new Aws::CloudWatchLogs::Model::CreateLogGroupOutcome(error);
176 
177  EXPECT_CALL(*mock_client_p, CreateLogGroup(testing::_))
178  .WillOnce(testing::Return(*failedOutcome));
179 
181  facade_->CreateLogGroup(LOG_GROUP_NAME1));
182 }
183 
184 /*
185  * CheckLogGroupExists Tests
186  */
187 
188 TEST_F(TestCloudWatchFacade, TestCWLogsFacade_CheckLogGroupExists_FailedResponse)
189 {
190  Aws::CloudWatchLogs::Model::DescribeLogGroupsOutcome failedOutcome;
191  EXPECT_CALL(*mock_client_p, DescribeLogGroups(testing::_))
192  .WillOnce(testing::Return(failedOutcome));
193 
195  facade_->CheckLogGroupExists(LOG_GROUP_NAME1));
196 }
197 
198 TEST_F(TestCloudWatchFacade, TestCWLogsFacade_CheckLogGroupExists_LogGroupExists)
199 {
200  Aws::CloudWatchLogs::Model::LogGroup TestGroup;
201  TestGroup.SetLogGroupName(LOG_GROUP_NAME1);
202  Aws::CloudWatchLogs::Model::DescribeLogGroupsResult existsResult;
203  existsResult.AddLogGroups(TestGroup);
204  existsResult.SetNextToken("token");
205  Aws::CloudWatchLogs::Model::DescribeLogGroupsOutcome existsOutcome(existsResult);
206  EXPECT_CALL(*mock_client_p, DescribeLogGroups(testing::_))
207  .WillOnce(testing::Return(existsOutcome));
208 
210  facade_->CheckLogGroupExists(LOG_GROUP_NAME1));
211 }
212 
213 TEST_F(TestCloudWatchFacade, TestCWLogsFacade_CheckLogGroupExists_LogGroupDoesntExist)
214 { Aws::CloudWatchLogs::Model::LogGroup TestGroup;
215  TestGroup.SetLogGroupName(LOG_GROUP_NAME1);
216  Aws::CloudWatchLogs::Model::DescribeLogGroupsResult doesntExistResult;
217  doesntExistResult.AddLogGroups(TestGroup);
218  doesntExistResult.SetNextToken("");
219  Aws::CloudWatchLogs::Model::DescribeLogGroupsOutcome doesntExistOutcome(doesntExistResult);
220  EXPECT_CALL(*mock_client_p, DescribeLogGroups(testing::_))
221  .WillOnce(testing::Return(doesntExistOutcome));
222 
224  facade_->CheckLogGroupExists(LOG_GROUP_NAME2));
225 }
226 
227 /*
228  * CreateLogStream Tests
229  */
230 
231 TEST_F(TestCloudWatchFacade, TestCWLogsFacade_CreateLogStream_SuccessResponse)
232 {
233  Aws::CloudWatchLogs::Model::CreateLogStreamOutcome* successOutcome =
234  new Aws::CloudWatchLogs::Model::CreateLogStreamOutcome(Aws::NoResult());
235 
236  EXPECT_CALL(*mock_client_p, CreateLogStream(testing::_))
237  .WillOnce(testing::Return(*successOutcome));
238 
240  facade_->CreateLogStream(LOG_GROUP_NAME1, LOG_STREAM_NAME1));
241 }
242 
243 TEST_F(TestCloudWatchFacade, TestCWLogsFacade_CreateLogStream_FailedResponse)
244 {
245  // Choosing an arbitrary unhandled error code to initialize, for deterministic behavior
246  // When left uninitialized, on some systems it may come out as RESOURCE_ALREADY_EXISTS
247  Aws::Client::AWSError<Aws::CloudWatchLogs::CloudWatchLogsErrors> error(
248  Aws::CloudWatchLogs::CloudWatchLogsErrors::INTERNAL_FAILURE, false);
249 
250  auto* failedOutcome = new Aws::CloudWatchLogs::Model::CreateLogStreamOutcome(error);
251 
252  EXPECT_CALL(*mock_client_p, CreateLogStream(testing::_))
253  .WillOnce(testing::Return(*failedOutcome));
254 
256  facade_->CreateLogStream(LOG_GROUP_NAME1, LOG_STREAM_NAME1));
257 }
258 
259 TEST_F(TestCloudWatchFacade, TestCWLogsFacade_CreateLogStream_AlreadyExists)
260 {
261  Aws::Client::AWSError<Aws::CloudWatchLogs::CloudWatchLogsErrors> error
262  (Aws::CloudWatchLogs::CloudWatchLogsErrors::RESOURCE_ALREADY_EXISTS, false);
263 
264  auto* failedOutcome =
265  new Aws::CloudWatchLogs::Model::CreateLogStreamOutcome(error);
266 
267  EXPECT_CALL(*mock_client_p, CreateLogStream(testing::_))
268  .WillOnce(testing::Return(*failedOutcome));
269 
271  facade_->CreateLogStream(LOG_GROUP_NAME1, LOG_STREAM_NAME1));
272 }
273 
274 /*
275  * CheckLogStreamExists Tests
276  */
277 
278 TEST_F(TestCloudWatchFacade, TestCWLogsFacade_CheckLogStreamExists_FailedResponse)
279 {
280  Aws::CloudWatchLogs::Model::DescribeLogStreamsOutcome failedOutcome;
281  Aws::CloudWatchLogs::Model::LogStream * log_stream_object = nullptr;
282  EXPECT_CALL(*mock_client_p, DescribeLogStreams(testing::_))
283  .WillOnce(testing::Return(failedOutcome));
284 
286  facade_->CheckLogStreamExists(LOG_GROUP_NAME1, LOG_STREAM_NAME1, log_stream_object));
287 }
288 
289 TEST_F(TestCloudWatchFacade, TestCWLogsFacade_CheckLogStreamExists_LogStreamExists)
290 {
291  Aws::CloudWatchLogs::Model::LogStream TestStream;
292  TestStream.SetLogStreamName(LOG_STREAM_NAME1);
293  Aws::CloudWatchLogs::Model::DescribeLogStreamsResult existsResult;
294  existsResult.AddLogStreams(TestStream);
295  existsResult.SetNextToken("token");
296  Aws::CloudWatchLogs::Model::DescribeLogStreamsOutcome existsOutcome(existsResult);
297  EXPECT_CALL(*mock_client_p, DescribeLogStreams(testing::_))
298  .WillOnce(testing::Return(existsOutcome));
299 
300  auto * log_stream_object = new Aws::CloudWatchLogs::Model::LogStream();
302  facade_->CheckLogStreamExists(LOG_GROUP_NAME1, LOG_STREAM_NAME1, log_stream_object));
303 }
304 
305 
306 TEST_F(TestCloudWatchFacade, TestCWLogsFacade_CheckLogStreamExists_LogStreamDoesntExist)
307 { Aws::CloudWatchLogs::Model::LogStream TestStream;
308  TestStream.SetLogStreamName(LOG_STREAM_NAME2);
309  Aws::CloudWatchLogs::Model::DescribeLogStreamsResult doesntExistResult;
310  doesntExistResult.AddLogStreams(TestStream);
311  Aws::CloudWatchLogs::Model::DescribeLogStreamsOutcome doesntExistOutcome(doesntExistResult);
312  EXPECT_CALL(*mock_client_p, DescribeLogStreams(testing::_))
313  .WillOnce(testing::Return(doesntExistOutcome));
314 
315  Aws::CloudWatchLogs::Model::LogStream * log_stream_object = nullptr;
317  facade_->CheckLogStreamExists(LOG_GROUP_NAME1, LOG_STREAM_NAME1, log_stream_object));
318 }
std::shared_ptr< CloudWatchLogsFacade > facade_
constexpr char LOG_GROUP_NAME2[]
constexpr char LOG_STREAM_NAME1[]
TEST_F(TestCloudWatchFacade, TestCWLogsFacade_SendLogsToCloudWatch_EmptyLogs)
constexpr char LOG_STREAM_NAME2[]
Contains Error handling functionality for ROS AWS CloudWatch Logs libraries.
std::chrono::milliseconds Now() const
constexpr char LOG_GROUP_NAME1[]
std::shared_ptr< CloudWatchLogsClientMock > mock_client
std::list< Aws::CloudWatchLogs::Model::InputLogEvent > logs_list_


cloudwatch_logs_common
Author(s): AWS RoboMaker
autogenerated on Fri May 7 2021 02:18:24