| OLD | NEW | 
|---|
|  | (Empty) | 
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. |  | 
| 2 // Use of this source code is governed by a BSD-style license that can be |  | 
| 3 // found in the LICENSE file. |  | 
| 4 |  | 
| 5 #include "blimp/net/blimp_message_output_buffer.h" |  | 
| 6 |  | 
| 7 #include "base/callback_helpers.h" |  | 
| 8 #include "base/logging.h" |  | 
| 9 #include "base/memory/ptr_util.h" |  | 
| 10 #include "base/message_loop/message_loop.h" |  | 
| 11 #include "blimp/common/proto/blimp_message.pb.h" |  | 
| 12 #include "blimp/net/test_common.h" |  | 
| 13 #include "net/base/net_errors.h" |  | 
| 14 #include "net/base/test_completion_callback.h" |  | 
| 15 #include "testing/gmock/include/gmock/gmock.h" |  | 
| 16 #include "testing/gtest/include/gtest/gtest.h" |  | 
| 17 |  | 
| 18 using testing::_; |  | 
| 19 using testing::InvokeArgument; |  | 
| 20 using testing::Ref; |  | 
| 21 using testing::Return; |  | 
| 22 using testing::SaveArg; |  | 
| 23 |  | 
| 24 namespace blimp { |  | 
| 25 namespace { |  | 
| 26 |  | 
| 27 class BlimpMessageOutputBufferTest : public testing::Test { |  | 
| 28  public: |  | 
| 29   BlimpMessageOutputBufferTest() {} |  | 
| 30 |  | 
| 31   void SetUp() override { |  | 
| 32     input_msg_.mutable_input(); |  | 
| 33     input_msg_.set_message_id(1); |  | 
| 34     compositor_msg_.mutable_compositor(); |  | 
| 35     compositor_msg_.set_message_id(2); |  | 
| 36 |  | 
| 37     // Buffer should only have space for two unacknowledged messages |  | 
| 38     // (with message IDs). |  | 
| 39     ASSERT_EQ(input_msg_.ByteSize(), compositor_msg_.ByteSize()); |  | 
| 40     buffer_.reset(new BlimpMessageOutputBuffer(2 * input_msg_.GetCachedSize())); |  | 
| 41   } |  | 
| 42 |  | 
| 43  protected: |  | 
| 44   void AddOutputExpectation(const BlimpMessage& msg) { |  | 
| 45     EXPECT_CALL(output_processor_, MockableProcessMessage(EqualsProto(msg), _)) |  | 
| 46         .WillOnce(SaveArg<1>(&captured_cb_)) |  | 
| 47         .RetiresOnSaturation(); |  | 
| 48   } |  | 
| 49 |  | 
| 50   BlimpMessage WithMessageId(const BlimpMessage& message, int64_t message_id) { |  | 
| 51     BlimpMessage output = message; |  | 
| 52     output.set_message_id(message_id); |  | 
| 53     return output; |  | 
| 54   } |  | 
| 55 |  | 
| 56   BlimpMessage input_msg_; |  | 
| 57   BlimpMessage compositor_msg_; |  | 
| 58 |  | 
| 59   base::MessageLoop message_loop_; |  | 
| 60   net::CompletionCallback captured_cb_; |  | 
| 61   MockBlimpMessageProcessor output_processor_; |  | 
| 62   std::unique_ptr<BlimpMessageOutputBuffer> buffer_; |  | 
| 63   testing::InSequence s; |  | 
| 64 }; |  | 
| 65 |  | 
| 66 // Verify batched writes and acknowledgements. |  | 
| 67 TEST_F(BlimpMessageOutputBufferTest, SeparatelyBufferWriteAck) { |  | 
| 68   net::TestCompletionCallback complete_cb_1; |  | 
| 69   net::TestCompletionCallback complete_cb_2; |  | 
| 70 |  | 
| 71   AddOutputExpectation(input_msg_); |  | 
| 72   AddOutputExpectation(compositor_msg_); |  | 
| 73 |  | 
| 74   // Accumulate two messages. |  | 
| 75   buffer_->ProcessMessage(base::WrapUnique(new BlimpMessage(input_msg_)), |  | 
| 76                           complete_cb_1.callback()); |  | 
| 77   buffer_->ProcessMessage(base::WrapUnique(new BlimpMessage(compositor_msg_)), |  | 
| 78                           complete_cb_2.callback()); |  | 
| 79   ASSERT_EQ(2, buffer_->GetBufferByteSizeForTest()); |  | 
| 80 |  | 
| 81   // Write two messages. |  | 
| 82   ASSERT_TRUE(captured_cb_.is_null()); |  | 
| 83   buffer_->SetOutputProcessor(&output_processor_); |  | 
| 84   ASSERT_FALSE(captured_cb_.is_null()); |  | 
| 85   base::ResetAndReturn(&captured_cb_).Run(net::OK); |  | 
| 86   ASSERT_EQ(2, buffer_->GetBufferByteSizeForTest()); |  | 
| 87   ASSERT_EQ(1, buffer_->GetUnacknowledgedMessageCountForTest()); |  | 
| 88   base::ResetAndReturn(&captured_cb_).Run(net::OK); |  | 
| 89   ASSERT_EQ(2, buffer_->GetBufferByteSizeForTest()); |  | 
| 90   ASSERT_EQ(2, buffer_->GetUnacknowledgedMessageCountForTest()); |  | 
| 91 |  | 
| 92   // Both messages are acknowledged by separate checkpoints. |  | 
| 93   buffer_->OnMessageCheckpoint(1); |  | 
| 94   ASSERT_EQ(1, buffer_->GetBufferByteSizeForTest()); |  | 
| 95   ASSERT_EQ(1, buffer_->GetUnacknowledgedMessageCountForTest()); |  | 
| 96   EXPECT_EQ(net::OK, complete_cb_1.WaitForResult()); |  | 
| 97   buffer_->OnMessageCheckpoint(2); |  | 
| 98   ASSERT_EQ(0, buffer_->GetBufferByteSizeForTest()); |  | 
| 99   ASSERT_EQ(0, buffer_->GetUnacknowledgedMessageCountForTest()); |  | 
| 100   EXPECT_EQ(net::OK, complete_cb_2.WaitForResult()); |  | 
| 101 } |  | 
| 102 |  | 
| 103 // Verify buffer writes from an empty state. |  | 
| 104 TEST_F(BlimpMessageOutputBufferTest, WritesFromEmptyBuffer) { |  | 
| 105   net::TestCompletionCallback complete_cb_1; |  | 
| 106   net::TestCompletionCallback complete_cb_2; |  | 
| 107 |  | 
| 108   AddOutputExpectation(input_msg_); |  | 
| 109   AddOutputExpectation(compositor_msg_); |  | 
| 110 |  | 
| 111   ASSERT_TRUE(captured_cb_.is_null()); |  | 
| 112   buffer_->SetOutputProcessor(&output_processor_); |  | 
| 113 |  | 
| 114   // Message #0 is buffered, sent, acknowledged. |  | 
| 115   buffer_->ProcessMessage(base::WrapUnique(new BlimpMessage(input_msg_)), |  | 
| 116                           complete_cb_1.callback()); |  | 
| 117   ASSERT_EQ(1, buffer_->GetBufferByteSizeForTest()); |  | 
| 118   ASSERT_FALSE(captured_cb_.is_null()); |  | 
| 119   base::ResetAndReturn(&captured_cb_).Run(net::OK); |  | 
| 120   ASSERT_EQ(1, buffer_->GetBufferByteSizeForTest()); |  | 
| 121   ASSERT_EQ(1, buffer_->GetUnacknowledgedMessageCountForTest()); |  | 
| 122   buffer_->OnMessageCheckpoint(1); |  | 
| 123   ASSERT_EQ(0, buffer_->GetBufferByteSizeForTest()); |  | 
| 124   ASSERT_EQ(0, buffer_->GetUnacknowledgedMessageCountForTest()); |  | 
| 125 |  | 
| 126   buffer_->ProcessMessage(base::WrapUnique(new BlimpMessage(compositor_msg_)), |  | 
| 127                           complete_cb_2.callback()); |  | 
| 128   ASSERT_EQ(1, buffer_->GetBufferByteSizeForTest()); |  | 
| 129   ASSERT_FALSE(captured_cb_.is_null()); |  | 
| 130   base::ResetAndReturn(&captured_cb_).Run(net::OK); |  | 
| 131   ASSERT_EQ(1, buffer_->GetBufferByteSizeForTest()); |  | 
| 132   ASSERT_EQ(1, buffer_->GetUnacknowledgedMessageCountForTest()); |  | 
| 133   buffer_->OnMessageCheckpoint(2); |  | 
| 134   ASSERT_EQ(0, buffer_->GetBufferByteSizeForTest()); |  | 
| 135   ASSERT_EQ(0, buffer_->GetUnacknowledgedMessageCountForTest()); |  | 
| 136 } |  | 
| 137 |  | 
| 138 // Verify that a single checkpoint can be used to acknowledge two writes. |  | 
| 139 TEST_F(BlimpMessageOutputBufferTest, SharedCheckpoint) { |  | 
| 140   net::TestCompletionCallback complete_cb_1; |  | 
| 141   net::TestCompletionCallback complete_cb_2; |  | 
| 142 |  | 
| 143   AddOutputExpectation(input_msg_); |  | 
| 144   AddOutputExpectation(compositor_msg_); |  | 
| 145 |  | 
| 146   // Message #1 is written but unacknowledged. |  | 
| 147   buffer_->ProcessMessage(base::WrapUnique(new BlimpMessage(input_msg_)), |  | 
| 148                           complete_cb_1.callback()); |  | 
| 149   ASSERT_EQ(1, buffer_->GetBufferByteSizeForTest()); |  | 
| 150   ASSERT_TRUE(captured_cb_.is_null()); |  | 
| 151   buffer_->SetOutputProcessor(&output_processor_); |  | 
| 152   ASSERT_FALSE(captured_cb_.is_null()); |  | 
| 153   base::ResetAndReturn(&captured_cb_).Run(net::OK); |  | 
| 154   ASSERT_EQ(1, buffer_->GetBufferByteSizeForTest()); |  | 
| 155   ASSERT_EQ(1, buffer_->GetUnacknowledgedMessageCountForTest()); |  | 
| 156 |  | 
| 157   // Message #2 is written but unacknowledged. |  | 
| 158   buffer_->ProcessMessage(base::WrapUnique(new BlimpMessage(compositor_msg_)), |  | 
| 159                           complete_cb_2.callback()); |  | 
| 160   ASSERT_EQ(2, buffer_->GetBufferByteSizeForTest()); |  | 
| 161   ASSERT_FALSE(captured_cb_.is_null()); |  | 
| 162   base::ResetAndReturn(&captured_cb_).Run(net::OK); |  | 
| 163   ASSERT_TRUE(captured_cb_.is_null()); |  | 
| 164   ASSERT_EQ(2, buffer_->GetBufferByteSizeForTest()); |  | 
| 165   ASSERT_EQ(2, buffer_->GetUnacknowledgedMessageCountForTest()); |  | 
| 166 |  | 
| 167   // Both messages are acknowledged in one checkpoint. |  | 
| 168   buffer_->OnMessageCheckpoint(2); |  | 
| 169   ASSERT_EQ(0, buffer_->GetBufferByteSizeForTest()); |  | 
| 170   ASSERT_EQ(0, buffer_->GetUnacknowledgedMessageCountForTest()); |  | 
| 171   EXPECT_EQ(net::OK, complete_cb_1.WaitForResult()); |  | 
| 172   EXPECT_EQ(net::OK, complete_cb_2.WaitForResult()); |  | 
| 173 } |  | 
| 174 |  | 
| 175 // Verify that messages that fail to write are kept in a pending write state. |  | 
| 176 TEST_F(BlimpMessageOutputBufferTest, WriteError) { |  | 
| 177   net::TestCompletionCallback complete_cb_1; |  | 
| 178   net::TestCompletionCallback complete_cb_2; |  | 
| 179 |  | 
| 180   AddOutputExpectation(input_msg_); |  | 
| 181   AddOutputExpectation(input_msg_); |  | 
| 182 |  | 
| 183   // Accumulate two messages. |  | 
| 184   buffer_->ProcessMessage(base::WrapUnique(new BlimpMessage(input_msg_)), |  | 
| 185                           complete_cb_1.callback()); |  | 
| 186   ASSERT_EQ(1, buffer_->GetBufferByteSizeForTest()); |  | 
| 187 |  | 
| 188   // First write attempt, which fails. |  | 
| 189   ASSERT_TRUE(captured_cb_.is_null()); |  | 
| 190   buffer_->SetOutputProcessor(&output_processor_); |  | 
| 191   ASSERT_FALSE(captured_cb_.is_null()); |  | 
| 192   base::ResetAndReturn(&captured_cb_).Run(net::ERR_FAILED); |  | 
| 193   ASSERT_EQ(1, buffer_->GetBufferByteSizeForTest()); |  | 
| 194   ASSERT_EQ(0, buffer_->GetUnacknowledgedMessageCountForTest()); |  | 
| 195 |  | 
| 196   // Simulate disconnect. |  | 
| 197   buffer_->SetOutputProcessor(nullptr); |  | 
| 198 |  | 
| 199   // Reconnect. Should immediately try to write the contents of the buffer. |  | 
| 200   buffer_->SetOutputProcessor(&output_processor_); |  | 
| 201   ASSERT_FALSE(captured_cb_.is_null()); |  | 
| 202   base::ResetAndReturn(&captured_cb_).Run(net::OK); |  | 
| 203   ASSERT_EQ(1, buffer_->GetBufferByteSizeForTest()); |  | 
| 204   ASSERT_EQ(1, buffer_->GetUnacknowledgedMessageCountForTest()); |  | 
| 205   buffer_->OnMessageCheckpoint(1); |  | 
| 206   ASSERT_EQ(0, buffer_->GetBufferByteSizeForTest()); |  | 
| 207   ASSERT_EQ(0, buffer_->GetUnacknowledgedMessageCountForTest()); |  | 
| 208   EXPECT_EQ(net::OK, complete_cb_1.WaitForResult()); |  | 
| 209 } |  | 
| 210 |  | 
| 211 // Verify that unacknowledged messages can be moved back to a pending write |  | 
| 212 // state (recovery after a lost connection.) |  | 
| 213 TEST_F(BlimpMessageOutputBufferTest, MessageRetransmit) { |  | 
| 214   net::TestCompletionCallback complete_cb_1; |  | 
| 215   net::TestCompletionCallback complete_cb_2; |  | 
| 216 |  | 
| 217   AddOutputExpectation(input_msg_); |  | 
| 218   AddOutputExpectation(compositor_msg_); |  | 
| 219   AddOutputExpectation(compositor_msg_);  // Retransmitted message. |  | 
| 220 |  | 
| 221   // Accumulate two messages. |  | 
| 222   buffer_->ProcessMessage(base::WrapUnique(new BlimpMessage(input_msg_)), |  | 
| 223                           complete_cb_1.callback()); |  | 
| 224   buffer_->ProcessMessage(base::WrapUnique(new BlimpMessage(compositor_msg_)), |  | 
| 225                           complete_cb_2.callback()); |  | 
| 226   ASSERT_EQ(2, buffer_->GetBufferByteSizeForTest()); |  | 
| 227 |  | 
| 228   // Write two messages. |  | 
| 229   ASSERT_TRUE(captured_cb_.is_null()); |  | 
| 230   buffer_->SetOutputProcessor(&output_processor_); |  | 
| 231   ASSERT_FALSE(captured_cb_.is_null()); |  | 
| 232   base::ResetAndReturn(&captured_cb_).Run(net::OK); |  | 
| 233   ASSERT_EQ(2, buffer_->GetBufferByteSizeForTest()); |  | 
| 234   ASSERT_EQ(1, buffer_->GetUnacknowledgedMessageCountForTest()); |  | 
| 235   base::ResetAndReturn(&captured_cb_).Run(net::OK); |  | 
| 236   ASSERT_EQ(2, buffer_->GetBufferByteSizeForTest()); |  | 
| 237   ASSERT_EQ(2, buffer_->GetUnacknowledgedMessageCountForTest()); |  | 
| 238 |  | 
| 239   // Simulate disconnect & reconnect. |  | 
| 240   buffer_->SetOutputProcessor(nullptr); |  | 
| 241   buffer_->SetOutputProcessor(&output_processor_); |  | 
| 242 |  | 
| 243   // Remote end indicates that it only received message #0. |  | 
| 244   // Message #1 should be moved from an unacknowledged state to a pending write |  | 
| 245   // state. |  | 
| 246   ASSERT_TRUE(captured_cb_.is_null()); |  | 
| 247   buffer_->OnMessageCheckpoint(1); |  | 
| 248   buffer_->RetransmitBufferedMessages(); |  | 
| 249   ASSERT_FALSE(captured_cb_.is_null()); |  | 
| 250   ASSERT_EQ(1, buffer_->GetBufferByteSizeForTest()); |  | 
| 251   ASSERT_EQ(0, buffer_->GetUnacknowledgedMessageCountForTest()); |  | 
| 252   base::ResetAndReturn(&captured_cb_).Run(net::OK); |  | 
| 253   ASSERT_EQ(1, buffer_->GetUnacknowledgedMessageCountForTest()); |  | 
| 254 |  | 
| 255   // Remote end acknowledges #1, buffer should be empty. |  | 
| 256   buffer_->OnMessageCheckpoint(2); |  | 
| 257   ASSERT_EQ(0, buffer_->GetBufferByteSizeForTest()); |  | 
| 258   ASSERT_EQ(0, buffer_->GetUnacknowledgedMessageCountForTest()); |  | 
| 259   EXPECT_EQ(net::OK, complete_cb_2.WaitForResult()); |  | 
| 260 } |  | 
| 261 |  | 
| 262 }  // namespace |  | 
| 263 }  // namespace blimp |  | 
| OLD | NEW | 
|---|