| // Copyright 2020 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "remoting/base/protobuf_http_stream_parser.h" |
| |
| #include <memory> |
| #include <string> |
| |
| #include "base/test/mock_callback.h" |
| #include "remoting/base/protobuf_http_client_messages.pb.h" |
| #include "remoting/base/protobuf_http_status.h" |
| #include "testing/gmock/include/gmock/gmock.h" |
| #include "testing/gtest/include/gtest/gtest.h" |
| |
| namespace remoting { |
| |
| namespace { |
| |
| using ::testing::_; |
| |
| constexpr char kFirstTestMessage[] = "This is the first message."; |
| constexpr char kSecondTestMessage[] = "This is the second message."; |
| constexpr char kThirdTestMessage[] = "This is the third message."; |
| |
| MATCHER(IsCancelStatus, "") { |
| return arg.error_code() == ProtobufHttpStatus::Code::CANCELLED && |
| arg.error_message() == "Cancelled"; |
| } |
| |
| protobufhttpclient::StreamBody CreateDefaultStream() { |
| protobufhttpclient::StreamBody stream_body; |
| stream_body.add_messages(kFirstTestMessage); |
| stream_body.add_messages(kSecondTestMessage); |
| stream_body.add_messages(kThirdTestMessage); |
| return stream_body; |
| } |
| |
| std::string CreateDefaultStreamData() { |
| return CreateDefaultStream().SerializeAsString(); |
| } |
| |
| void SplitStringInMiddle(const std::string& input, |
| std::string* str_1, |
| std::string* str_2) { |
| size_t message_split_pos = input.size() / 2; |
| *str_1 = input.substr(0, message_split_pos); |
| *str_2 = input.substr(message_split_pos); |
| } |
| |
| } // namespace |
| |
| class ProtobufHttpStreamParserTest : public testing::Test { |
| protected: |
| void ExpectReceiveDefaultStreamData(); |
| |
| base::MockCallback<ProtobufHttpStreamParser::MessageCallback> |
| message_callback_; |
| base::MockCallback<ProtobufHttpStreamParser::StreamClosedCallback> |
| stream_closed_callback_; |
| ProtobufHttpStreamParser stream_parser_{message_callback_.Get(), |
| stream_closed_callback_.Get()}; |
| }; |
| |
| void ProtobufHttpStreamParserTest::ExpectReceiveDefaultStreamData() { |
| EXPECT_CALL(message_callback_, Run(kFirstTestMessage)); |
| EXPECT_CALL(message_callback_, Run(kSecondTestMessage)); |
| EXPECT_CALL(message_callback_, Run(kThirdTestMessage)); |
| } |
| |
| TEST_F(ProtobufHttpStreamParserTest, ParseStreamBodyInOneShot) { |
| ExpectReceiveDefaultStreamData(); |
| |
| ASSERT_FALSE(stream_parser_.HasPendingData()); |
| stream_parser_.Append(CreateDefaultStreamData()); |
| ASSERT_FALSE(stream_parser_.HasPendingData()); |
| } |
| |
| TEST_F(ProtobufHttpStreamParserTest, ParseSplitStreamBody) { |
| ExpectReceiveDefaultStreamData(); |
| |
| std::string stream_data = CreateDefaultStreamData(); |
| std::string data_1, data_2; |
| SplitStringInMiddle(stream_data, &data_1, &data_2); |
| stream_parser_.Append(data_1); |
| ASSERT_TRUE(stream_parser_.HasPendingData()); |
| stream_parser_.Append(data_2); |
| ASSERT_FALSE(stream_parser_.HasPendingData()); |
| } |
| |
| TEST_F(ProtobufHttpStreamParserTest, CloseStreamWithCancelled) { |
| EXPECT_CALL(stream_closed_callback_, Run(IsCancelStatus())); |
| |
| protobufhttpclient::StreamBody stream_body; |
| stream_body.mutable_status()->set_code( |
| static_cast<int>(ProtobufHttpStatus::Code::CANCELLED)); |
| stream_body.mutable_status()->set_message("Cancelled"); |
| stream_parser_.Append(stream_body.SerializeAsString()); |
| } |
| |
| TEST_F(ProtobufHttpStreamParserTest, ParseStreamBodyWithNoops_NoopsIgnored) { |
| ExpectReceiveDefaultStreamData(); |
| |
| protobufhttpclient::StreamBody stream_body = CreateDefaultStream(); |
| stream_body.add_noop("111111111111111"); |
| stream_body.add_noop("111111111111111"); |
| stream_body.add_noop("111111111111111"); |
| |
| stream_parser_.Append(stream_body.SerializeAsString()); |
| ASSERT_FALSE(stream_parser_.HasPendingData()); |
| } |
| |
| TEST_F(ProtobufHttpStreamParserTest, |
| ParseSplitStreamBodyWithOnlyNoops_NoopsIgnored) { |
| protobufhttpclient::StreamBody stream_body; |
| stream_body.add_noop("111111111111111"); |
| stream_body.add_noop("111111111111111"); |
| stream_body.add_noop("111111111111111"); |
| std::string stream_data = stream_body.SerializeAsString(); |
| std::string data_1, data_2; |
| SplitStringInMiddle(stream_data, &data_1, &data_2); |
| |
| stream_parser_.Append(data_1); |
| ASSERT_TRUE(stream_parser_.HasPendingData()); |
| stream_parser_.Append(data_2); |
| ASSERT_FALSE(stream_parser_.HasPendingData()); |
| } |
| |
| } // namespace remoting |