1 // Copyright 2020 Google LLC
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://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,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14
15 #include "google/cloud/pubsub/internal/publisher_logging.h"
16 #include "google/cloud/pubsub/testing/mock_publisher_stub.h"
17 #include "google/cloud/testing_util/assert_ok.h"
18 #include "google/cloud/testing_util/capture_log_lines_backend.h"
19 #include "absl/memory/memory.h"
20 #include <gmock/gmock.h>
21
22 namespace google {
23 namespace cloud {
24 namespace pubsub_internal {
25 inline namespace GOOGLE_CLOUD_CPP_PUBSUB_NS {
26 namespace {
27
28 using ::testing::AllOf;
29 using ::testing::Contains;
30 using ::testing::HasSubstr;
31 using ::testing::Return;
32
33 class PublisherLoggingTest : public ::testing::Test {
34 protected:
SetUp()35 void SetUp() override {
36 backend_ =
37 std::make_shared<google::cloud::testing_util::CaptureLogLinesBackend>();
38 logger_id_ = google::cloud::LogSink::Instance().AddBackend(backend_);
39 }
40
TearDown()41 void TearDown() override {
42 google::cloud::LogSink::Instance().RemoveBackend(logger_id_);
43 logger_id_ = 0;
44 }
45
TransientError()46 static Status TransientError() {
47 return Status(StatusCode::kUnavailable, "try-again");
48 }
49
50 std::shared_ptr<google::cloud::testing_util::CaptureLogLinesBackend> backend_;
51
52 private:
53 long logger_id_ = 0; // NOLINT(google-runtime-int)
54 };
55
TEST_F(PublisherLoggingTest,CreateTopic)56 TEST_F(PublisherLoggingTest, CreateTopic) {
57 auto mock = std::make_shared<pubsub_testing::MockPublisherStub>();
58 EXPECT_CALL(*mock, CreateTopic)
59 .WillOnce(Return(make_status_or(google::pubsub::v1::Topic{})));
60 PublisherLogging stub(mock, TracingOptions{}.SetOptions("single_line_mode"));
61 grpc::ClientContext context;
62 google::pubsub::v1::Topic topic;
63 topic.set_name("test-topic-name");
64 auto status = stub.CreateTopic(context, topic);
65 EXPECT_STATUS_OK(status);
66 EXPECT_THAT(backend_->ClearLogLines(), Contains(HasSubstr("CreateTopic")));
67 }
68
TEST_F(PublisherLoggingTest,GetTopic)69 TEST_F(PublisherLoggingTest, GetTopic) {
70 auto mock = std::make_shared<pubsub_testing::MockPublisherStub>();
71 EXPECT_CALL(*mock, GetTopic)
72 .WillOnce(Return(make_status_or(google::pubsub::v1::Topic{})));
73 PublisherLogging stub(mock, TracingOptions{}.SetOptions("single_line_mode"));
74 grpc::ClientContext context;
75 google::pubsub::v1::GetTopicRequest request;
76 request.set_topic("test-topic-name");
77 auto status = stub.GetTopic(context, request);
78 EXPECT_STATUS_OK(status);
79 EXPECT_THAT(backend_->ClearLogLines(), Contains(HasSubstr("GetTopic")));
80 }
81
TEST_F(PublisherLoggingTest,UpdateTopic)82 TEST_F(PublisherLoggingTest, UpdateTopic) {
83 auto mock = std::make_shared<pubsub_testing::MockPublisherStub>();
84 EXPECT_CALL(*mock, UpdateTopic)
85 .WillOnce(Return(make_status_or(google::pubsub::v1::Topic{})));
86 PublisherLogging stub(mock, TracingOptions{}.SetOptions("single_line_mode"));
87 grpc::ClientContext context;
88 google::pubsub::v1::UpdateTopicRequest request;
89 request.mutable_topic()->set_name("test-topic-name");
90 auto status = stub.UpdateTopic(context, request);
91 EXPECT_STATUS_OK(status);
92 EXPECT_THAT(backend_->ClearLogLines(), Contains(HasSubstr("UpdateTopic")));
93 }
94
TEST_F(PublisherLoggingTest,ListTopics)95 TEST_F(PublisherLoggingTest, ListTopics) {
96 auto mock = std::make_shared<pubsub_testing::MockPublisherStub>();
97 EXPECT_CALL(*mock, ListTopics)
98 .WillOnce(
99 Return(make_status_or(google::pubsub::v1::ListTopicsResponse{})));
100 PublisherLogging stub(mock, TracingOptions{}.SetOptions("single_line_mode"));
101 grpc::ClientContext context;
102 google::pubsub::v1::ListTopicsRequest request;
103 request.set_project("test-project-name");
104 auto status = stub.ListTopics(context, request);
105 EXPECT_STATUS_OK(status);
106 EXPECT_THAT(
107 backend_->ClearLogLines(),
108 Contains(AllOf(HasSubstr("ListTopics"), HasSubstr("test-project-name"))));
109 }
110
TEST_F(PublisherLoggingTest,DeleteTopic)111 TEST_F(PublisherLoggingTest, DeleteTopic) {
112 auto mock = std::make_shared<pubsub_testing::MockPublisherStub>();
113 EXPECT_CALL(*mock, DeleteTopic).WillOnce(Return(Status{}));
114 PublisherLogging stub(mock, TracingOptions{}.SetOptions("single_line_mode"));
115 grpc::ClientContext context;
116 google::pubsub::v1::DeleteTopicRequest request;
117 request.set_topic("test-topic-name");
118 auto status = stub.DeleteTopic(context, request);
119 EXPECT_STATUS_OK(status);
120 EXPECT_THAT(
121 backend_->ClearLogLines(),
122 Contains(AllOf(HasSubstr("DeleteTopic"), HasSubstr("test-topic-name"))));
123 }
124
TEST_F(PublisherLoggingTest,DetachSubscription)125 TEST_F(PublisherLoggingTest, DetachSubscription) {
126 auto mock = std::make_shared<pubsub_testing::MockPublisherStub>();
127 EXPECT_CALL(*mock, DetachSubscription)
128 .WillOnce(Return(
129 make_status_or(google::pubsub::v1::DetachSubscriptionResponse{})));
130 PublisherLogging stub(mock, TracingOptions{}.SetOptions("single_line_mode"));
131 grpc::ClientContext context;
132 google::pubsub::v1::DetachSubscriptionRequest request;
133 request.set_subscription("test-subscription-name");
134 auto status = stub.DetachSubscription(context, request);
135 EXPECT_STATUS_OK(status);
136 EXPECT_THAT(backend_->ClearLogLines(),
137 Contains(AllOf(HasSubstr("DetachSubscription"),
138 HasSubstr("test-subscription-name"))));
139 }
140
TEST_F(PublisherLoggingTest,ListTopicSubscriptions)141 TEST_F(PublisherLoggingTest, ListTopicSubscriptions) {
142 auto mock = std::make_shared<pubsub_testing::MockPublisherStub>();
143 EXPECT_CALL(*mock, ListTopicSubscriptions)
144 .WillOnce(Return(make_status_or(
145 google::pubsub::v1::ListTopicSubscriptionsResponse{})));
146 PublisherLogging stub(mock, TracingOptions{}.SetOptions("single_line_mode"));
147 grpc::ClientContext context;
148 google::pubsub::v1::ListTopicSubscriptionsRequest request;
149 request.set_topic("test-topic-name");
150 auto status = stub.ListTopicSubscriptions(context, request);
151 EXPECT_STATUS_OK(status);
152 EXPECT_THAT(backend_->ClearLogLines(),
153 Contains(AllOf(HasSubstr("ListTopicSubscriptions"),
154 HasSubstr("test-topic-name"))));
155 }
156
TEST_F(PublisherLoggingTest,ListTopicSnapshots)157 TEST_F(PublisherLoggingTest, ListTopicSnapshots) {
158 auto mock = std::make_shared<pubsub_testing::MockPublisherStub>();
159 EXPECT_CALL(*mock, ListTopicSnapshots)
160 .WillOnce(Return(
161 make_status_or(google::pubsub::v1::ListTopicSnapshotsResponse{})));
162 PublisherLogging stub(mock, TracingOptions{}.SetOptions("single_line_mode"));
163 grpc::ClientContext context;
164 google::pubsub::v1::ListTopicSnapshotsRequest request;
165 request.set_topic("test-topic-name");
166 auto status = stub.ListTopicSnapshots(context, request);
167 EXPECT_STATUS_OK(status);
168 EXPECT_THAT(backend_->ClearLogLines(),
169 Contains(AllOf(HasSubstr("ListTopicSnapshots"),
170 HasSubstr("test-topic-name"))));
171 }
172
TEST_F(PublisherLoggingTest,AsyncPublish)173 TEST_F(PublisherLoggingTest, AsyncPublish) {
174 auto mock = std::make_shared<pubsub_testing::MockPublisherStub>();
175 EXPECT_CALL(*mock, AsyncPublish)
176 .WillOnce([](google::cloud::CompletionQueue&,
177 std::unique_ptr<grpc::ClientContext>,
178 google::pubsub::v1::PublishRequest const&) {
179 return make_ready_future(
180 make_status_or(google::pubsub::v1::PublishResponse{}));
181 });
182 PublisherLogging stub(mock, TracingOptions{}.SetOptions("single_line_mode"));
183 google::cloud::CompletionQueue cq;
184 google::pubsub::v1::PublishRequest request;
185 request.set_topic("test-topic-name");
186 auto status =
187 stub.AsyncPublish(cq, absl::make_unique<grpc::ClientContext>(), request)
188 .get();
189 EXPECT_STATUS_OK(status);
190 EXPECT_THAT(
191 backend_->ClearLogLines(),
192 Contains(AllOf(HasSubstr("AsyncPublish"), HasSubstr("test-topic-name"))));
193 }
194
195 } // namespace
196 } // namespace GOOGLE_CLOUD_CPP_PUBSUB_NS
197 } // namespace pubsub_internal
198 } // namespace cloud
199 } // namespace google
200