1// Copyright 2014 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 <queue>
6
7#include "device/serial/data_sink_receiver.h"
8#include "device/serial/data_stream.mojom.h"
9#include "extensions/renderer/api_test_base.h"
10#include "grit/extensions_renderer_resources.h"
11
12namespace extensions {
13
14// Runs tests defined in extensions/test/data/data_sender_unittest.js
15class DataSenderTest : public ApiTestBase {
16 public:
17  DataSenderTest() {}
18
19  virtual void SetUp() OVERRIDE {
20    ApiTestBase::SetUp();
21    env()->RegisterModule("async_waiter", IDR_ASYNC_WAITER_JS);
22    env()->RegisterModule("data_sender", IDR_DATA_SENDER_JS);
23    env()->RegisterModule("device/serial/data_stream.mojom",
24                          IDR_DATA_STREAM_MOJOM_JS);
25    env()->RegisterModule("device/serial/data_stream_serialization.mojom",
26                          IDR_DATA_STREAM_SERIALIZATION_MOJOM_JS);
27    service_provider()->AddService(
28        base::Bind(&DataSenderTest::CreateDataSink, base::Unretained(this)));
29  }
30
31  virtual void TearDown() OVERRIDE {
32    if (receiver_.get()) {
33      receiver_->ShutDown();
34      receiver_ = NULL;
35    }
36    EXPECT_FALSE(buffer_);
37    buffer_.reset();
38    ApiTestBase::TearDown();
39  }
40
41  std::queue<int32_t> error_to_report_;
42  std::queue<std::string> expected_data_;
43
44 private:
45  void CreateDataSink(
46      mojo::InterfaceRequest<device::serial::DataSink> request) {
47    receiver_ = mojo::WeakBindToRequest(
48        new device::DataSinkReceiver(
49            base::Bind(&DataSenderTest::ReadyToReceive, base::Unretained(this)),
50            base::Bind(&DataSenderTest::OnCancel, base::Unretained(this)),
51            base::Bind(base::DoNothing)),
52        &request);
53  }
54
55  void ReadyToReceive(scoped_ptr<device::ReadOnlyBuffer> buffer) {
56    std::string data(buffer->GetData(), buffer->GetSize());
57    if (expected_data_.empty()) {
58      buffer_ = buffer.Pass();
59      return;
60    }
61
62    std::string& expected = expected_data_.front();
63    if (expected.size() > buffer->GetSize()) {
64      EXPECT_EQ(expected.substr(0, buffer->GetSize()), data);
65      expected = expected.substr(buffer->GetSize());
66      buffer->Done(buffer->GetSize());
67      return;
68    }
69    if (expected.size() < buffer->GetSize())
70      data = data.substr(0, expected.size());
71    EXPECT_EQ(expected, data);
72    expected_data_.pop();
73    int32_t error = 0;
74    if (!error_to_report_.empty()) {
75      error = error_to_report_.front();
76      error_to_report_.pop();
77    }
78    if (error)
79      buffer->DoneWithError(data.size(), error);
80    else
81      buffer->Done(data.size());
82  }
83
84  void OnCancel(int32_t error) {
85    ASSERT_TRUE(buffer_);
86    buffer_->DoneWithError(0, error);
87    buffer_.reset();
88  }
89
90  scoped_refptr<device::DataSinkReceiver> receiver_;
91  scoped_ptr<device::ReadOnlyBuffer> buffer_;
92
93  DISALLOW_COPY_AND_ASSIGN(DataSenderTest);
94};
95
96TEST_F(DataSenderTest, Send) {
97  expected_data_.push("aa");
98  RunTest("data_sender_unittest.js", "testSend");
99}
100
101TEST_F(DataSenderTest, LargeSend) {
102  std::string pattern = "123";
103  std::string expected_data;
104  for (int i = 0; i < 11; i++)
105    expected_data += pattern;
106  expected_data_.push(expected_data);
107  RunTest("data_sender_unittest.js", "testLargeSend");
108}
109
110TEST_F(DataSenderTest, SendError) {
111  expected_data_.push("");
112  expected_data_.push("a");
113  error_to_report_.push(1);
114  RunTest("data_sender_unittest.js", "testSendError");
115}
116
117TEST_F(DataSenderTest, SendErrorPartialSuccess) {
118  expected_data_.push(std::string(5, 'b'));
119  expected_data_.push("a");
120  error_to_report_.push(1);
121  RunTest("data_sender_unittest.js", "testSendErrorPartialSuccess");
122}
123
124TEST_F(DataSenderTest, SendErrorBetweenPackets) {
125  expected_data_.push(std::string(2, 'b'));
126  expected_data_.push("a");
127  error_to_report_.push(1);
128  RunTest("data_sender_unittest.js", "testSendErrorBetweenPackets");
129}
130
131TEST_F(DataSenderTest, SendErrorInSecondPacket) {
132  expected_data_.push(std::string(3, 'b'));
133  expected_data_.push("a");
134  error_to_report_.push(1);
135  RunTest("data_sender_unittest.js", "testSendErrorInSecondPacket");
136}
137
138TEST_F(DataSenderTest, SendErrorInLargeSend) {
139  expected_data_.push("123456789012");
140  expected_data_.push("a");
141  error_to_report_.push(1);
142  RunTest("data_sender_unittest.js", "testSendErrorInLargeSend");
143}
144
145TEST_F(DataSenderTest, SendErrorBeforeLargeSend) {
146  expected_data_.push(std::string(2, 'b'));
147  expected_data_.push("a");
148  error_to_report_.push(1);
149  RunTest("data_sender_unittest.js", "testSendErrorBeforeLargeSend");
150}
151
152TEST_F(DataSenderTest, CancelWithoutSend) {
153  RunTest("data_sender_unittest.js", "testCancelWithoutSend");
154}
155
156TEST_F(DataSenderTest, Cancel) {
157  RunTest("data_sender_unittest.js", "testCancel");
158}
159
160TEST_F(DataSenderTest, Close) {
161  RunTest("data_sender_unittest.js", "testClose");
162}
163
164TEST_F(DataSenderTest, SendAfterSerialization) {
165  expected_data_.push("aa");
166  RunTest("data_sender_unittest.js", "testSendAfterSerialization");
167}
168
169TEST_F(DataSenderTest, SendErrorAfterSerialization) {
170  expected_data_.push("");
171  expected_data_.push("a");
172  error_to_report_.push(1);
173  RunTest("data_sender_unittest.js", "testSendErrorAfterSerialization");
174}
175
176TEST_F(DataSenderTest, CancelAfterSerialization) {
177  RunTest("data_sender_unittest.js", "testCancelAfterSerialization");
178}
179
180TEST_F(DataSenderTest, SerializeCancelsSendsInProgress) {
181  RunTest("data_sender_unittest.js", "testSerializeCancelsSendsInProgress");
182}
183
184TEST_F(DataSenderTest, SerializeWaitsForCancel) {
185  RunTest("data_sender_unittest.js", "testSerializeWaitsForCancel");
186}
187
188TEST_F(DataSenderTest, SerializeAfterClose) {
189  RunTest("data_sender_unittest.js", "testSerializeAfterClose");
190}
191
192}  // namespace extensions
193