Commit 558bdb6d authored by sammc@chromium.org's avatar sammc@chromium.org

Add the JS data pipe client to be used to implement serial send.

BUG=389016

Review URL: https://codereview.chromium.org/488003002

Cr-Commit-Position: refs/heads/master@{#290797}
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@290797 0039d316-1c4b-4281-b951-d872f2087c98
parent 21d3f3af
......@@ -148,6 +148,7 @@ test("unittests") {
"common/user_script_unittest.cc",
"renderer/activity_log_converter_strategy_unittest.cc",
"renderer/api/serial/data_receiver_unittest.cc",
"renderer/api/serial/data_sender_unittest.cc",
"renderer/api/serial/serial_api_unittest.cc",
"renderer/api_test_base.cc",
"renderer/api_test_base.h",
......
......@@ -906,6 +906,7 @@
'common/user_script_unittest.cc',
'renderer/activity_log_converter_strategy_unittest.cc',
'renderer/api/serial/data_receiver_unittest.cc',
'renderer/api/serial/data_sender_unittest.cc',
'renderer/api/serial/serial_api_unittest.cc',
'renderer/api_test_base.cc',
'renderer/api_test_base.h',
......
// Copyright 2014 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 <queue>
#include "device/serial/data_sink_receiver.h"
#include "device/serial/data_stream.mojom.h"
#include "extensions/renderer/api_test_base.h"
#include "grit/extensions_renderer_resources.h"
namespace extensions {
// Runs tests defined in extensions/test/data/data_sender_unittest.js
class DataSenderTest : public ApiTestBase {
public:
DataSenderTest() {}
virtual void SetUp() OVERRIDE {
ApiTestBase::SetUp();
env()->RegisterModule("async_waiter", IDR_ASYNC_WAITER_JS);
env()->RegisterModule("data_sender", IDR_DATA_SENDER_JS);
env()->RegisterModule("device/serial/data_stream.mojom",
IDR_DATA_STREAM_MOJOM_JS);
service_provider()->AddService(
base::Bind(&DataSenderTest::CreateDataSink, base::Unretained(this)));
}
virtual void TearDown() OVERRIDE {
if (receiver_) {
receiver_->ShutDown();
receiver_ = NULL;
}
EXPECT_FALSE(buffer_);
buffer_.reset();
ApiTestBase::TearDown();
}
std::queue<int32_t> error_to_report_;
std::queue<std::string> expected_data_;
private:
void CreateDataSink(
mojo::InterfaceRequest<device::serial::DataSink> request) {
receiver_ = mojo::WeakBindToRequest(
new device::DataSinkReceiver(
base::Bind(&DataSenderTest::ReadyToReceive, base::Unretained(this)),
base::Bind(&DataSenderTest::OnCancel, base::Unretained(this)),
base::Bind(base::DoNothing)),
&request);
}
void ReadyToReceive(scoped_ptr<device::ReadOnlyBuffer> buffer) {
std::string data(buffer->GetData(), buffer->GetSize());
if (expected_data_.empty()) {
buffer_ = buffer.Pass();
return;
}
std::string& expected = expected_data_.front();
if (expected.size() > buffer->GetSize()) {
EXPECT_EQ(expected.substr(0, buffer->GetSize()), data);
expected = expected.substr(buffer->GetSize());
buffer->Done(buffer->GetSize());
return;
}
if (expected.size() < buffer->GetSize())
data = data.substr(0, expected.size());
EXPECT_EQ(expected, data);
expected_data_.pop();
int32_t error = 0;
if (!error_to_report_.empty()) {
error = error_to_report_.front();
error_to_report_.pop();
}
if (error)
buffer->DoneWithError(data.size(), error);
else
buffer->Done(data.size());
}
void OnCancel(int32_t error) {
ASSERT_TRUE(buffer_);
buffer_->DoneWithError(0, error);
buffer_.reset();
}
scoped_refptr<device::DataSinkReceiver> receiver_;
scoped_ptr<device::ReadOnlyBuffer> buffer_;
DISALLOW_COPY_AND_ASSIGN(DataSenderTest);
};
TEST_F(DataSenderTest, Send) {
expected_data_.push("aa");
RunTest("data_sender_unittest.js", "testSend");
}
TEST_F(DataSenderTest, LargeSend) {
std::string pattern = "1234567890";
std::string expected_data;
for (int i = 0; i < 110; i++)
expected_data += pattern;
expected_data_.push(expected_data);
RunTest("data_sender_unittest.js", "testLargeSend");
}
TEST_F(DataSenderTest, SendError) {
expected_data_.push("");
expected_data_.push("a");
error_to_report_.push(1);
RunTest("data_sender_unittest.js", "testSendError");
}
TEST_F(DataSenderTest, SendErrorPartialSuccess) {
expected_data_.push(std::string(5, 'b'));
expected_data_.push("a");
error_to_report_.push(1);
RunTest("data_sender_unittest.js", "testSendErrorPartialSuccess");
}
TEST_F(DataSenderTest, SendErrorBetweenPackets) {
expected_data_.push(std::string(2, 'b'));
expected_data_.push("a");
error_to_report_.push(1);
RunTest("data_sender_unittest.js", "testSendErrorBetweenPackets");
}
TEST_F(DataSenderTest, SendErrorInSecondPacket) {
expected_data_.push(std::string(3, 'b'));
expected_data_.push("a");
error_to_report_.push(1);
RunTest("data_sender_unittest.js", "testSendErrorInSecondPacket");
}
TEST_F(DataSenderTest, SendErrorInLargeSend) {
expected_data_.push("123456789012");
expected_data_.push("a");
error_to_report_.push(1);
RunTest("data_sender_unittest.js", "testSendErrorInLargeSend");
}
TEST_F(DataSenderTest, SendErrorBeforeLargeSend) {
expected_data_.push(std::string(2, 'b'));
expected_data_.push("a");
error_to_report_.push(1);
RunTest("data_sender_unittest.js", "testSendErrorBeforeLargeSend");
}
TEST_F(DataSenderTest, CancelWithoutSend) {
RunTest("data_sender_unittest.js", "testCancelWithoutSend");
}
TEST_F(DataSenderTest, Cancel) {
RunTest("data_sender_unittest.js", "testCancel");
}
TEST_F(DataSenderTest, Close) {
RunTest("data_sender_unittest.js", "testClose");
}
} // namespace extensions
This diff is collapsed.
......@@ -11,6 +11,7 @@
<!-- Extension libraries. -->
<include name="IDR_ASYNC_WAITER_JS" file="async_waiter.js" type="BINDATA" />
<include name="IDR_DATA_RECEIVER_JS" file="data_receiver.js" type="BINDATA" />
<include name="IDR_DATA_SENDER_JS" file="data_sender.js" type="BINDATA" />
<include name="IDR_DATA_STREAM_MOJOM_JS" file="${mojom_root}\device\serial\data_stream.mojom.js" use_base_dir="false" type="BINDATA" />
<include name="IDR_ENTRY_ID_MANAGER" file="entry_id_manager.js" type="BINDATA" />
<include name="IDR_EVENT_BINDINGS_JS" file="event.js" type="BINDATA" />
......
// Copyright 2014 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.
// Tests launched by extensions/renderer/api/serial/data_sender_unittest.cc
var test = require('test').binding;
var unittestBindings = require('test_environment_specific_bindings');
var BUFFER_SIZE = 11;
var FATAL_ERROR = 2;
function generateData(size, pattern) {
if (!pattern)
pattern = 'a';
var buffer = new ArrayBuffer(size);
var intView = new Int8Array(buffer);
for (var i = 0; i < size; i++) {
intView[i] = pattern.charCodeAt(i % pattern.length);
}
return buffer;
}
function createSender() {
return Promise.all([
requireAsync('content/public/renderer/service_provider'),
requireAsync('data_sender'),
requireAsync('device/serial/data_stream.mojom'),
]).then(test.callbackPass(function(modules) {
var serviceProvider = modules[0];
var dataSender = modules[1];
var dataStream = modules[2];
return new dataSender.DataSender(
serviceProvider.connectToService(dataStream.DataSinkProxy.NAME_),
BUFFER_SIZE,
FATAL_ERROR);
}));
}
unittestBindings.exportTests([
function testSend() {
createSender().then(test.callbackPass(function(sender) {
var seen = null;
sender.send(generateData(1)).then(test.callbackPass(function(bytesSent) {
test.assertEq(1, bytesSent);
test.assertEq(null, seen);
seen = 'first';
}));
sender.send(generateData(1)).then(test.callbackPass(function(bytesSent) {
sender.close();
test.assertEq(1, bytesSent);
test.assertEq('first', seen);
seen = 'second';
}));
}));
},
function testLargeSend() {
createSender().then(test.callbackPass(function(sender) {
sender.send(generateData(BUFFER_SIZE * 100, '1234567890')).then(
test.callbackPass(function(bytesSent) {
test.assertEq(BUFFER_SIZE * 100, bytesSent);
sender.close();
}));
}));
},
function testSendError() {
createSender().then(test.callbackPass(function(sender) {
sender.send(generateData(BUFFER_SIZE * 100, 'b')).catch(test.callbackPass(
function(e) {
test.assertEq(1, e.error);
test.assertEq(0, e.bytesSent);
sender.send(generateData(1)).then(test.callbackPass(
function(bytesSent) {
test.assertEq(1, bytesSent);
sender.close();
}));
}));
}));
},
function testSendErrorPartialSuccess() {
createSender().then(test.callbackPass(function(sender) {
sender.send(generateData(BUFFER_SIZE * 100, 'b')).catch(test.callbackPass(
function(e) {
test.assertEq(1, e.error);
test.assertEq(5, e.bytesSent);
sender.send(generateData(1)).then(test.callbackPass(
function(bytesSent) {
test.assertEq(1, bytesSent);
sender.close();
}));
}));
}));
},
function testSendErrorBetweenPackets() {
createSender().then(test.callbackPass(function(sender) {
sender.send(generateData(2, 'b')).catch(test.callbackPass(function(e) {
test.assertEq(1, e.error);
test.assertEq(2, e.bytesSent);
}));
// After an error, all sends in progress will be cancelled.
sender.send(generateData(2, 'b')).catch(test.callbackPass(function(e) {
test.assertEq(1, e.error);
test.assertEq(0, e.bytesSent);
sender.send(generateData(1)).then(test.callbackPass(
function(bytesSent) {
test.assertEq(1, bytesSent);
sender.close();
}));
}));
}));
},
function testSendErrorInSecondPacket() {
createSender().then(test.callbackPass(function(sender) {
sender.send(generateData(2, 'b')).then(test.callbackPass(
function(bytesSent) {
test.assertEq(2, bytesSent);
}));
sender.send(generateData(2, 'b')).catch(test.callbackPass(function(e) {
test.assertEq(1, e.error);
test.assertEq(1, e.bytesSent);
sender.send(generateData(1)).then(test.callbackPass(
function(bytesSent) {
test.assertEq(1, bytesSent);
sender.close();
}));
}));
}));
},
function testSendErrorInLargeSend() {
createSender().then(test.callbackPass(function(sender) {
sender.send(generateData(BUFFER_SIZE * 100, '1234567890')).catch(
test.callbackPass(function(e) {
test.assertEq(1, e.error);
test.assertEq(12, e.bytesSent);
sender.send(generateData(1)).then(test.callbackPass(
function(bytesSent) {
test.assertEq(1, bytesSent);
sender.close();
}));
}));
}));
},
function testSendErrorBeforeLargeSend() {
createSender().then(test.callbackPass(function(sender) {
sender.send(generateData(5, 'b')).catch(test.callbackPass(function(e) {
test.assertEq(1, e.error);
test.assertEq(2, e.bytesSent);
}));
sender.send(generateData(BUFFER_SIZE * 100, '1234567890')).catch(
test.callbackPass(function(e) {
test.assertEq(1, e.error);
test.assertEq(0, e.bytesSent);
sender.send(generateData(1)).then(test.callbackPass(
function(bytesSent) {
test.assertEq(1, bytesSent);
sender.close();
}));
}));
}));
},
function testCancelWithoutSend() {
createSender().then(test.callbackPass(function(sender) {
sender.cancel(3).then(test.callbackPass(function() {
sender.close();
}));
}));
},
function testCancel() {
createSender().then(test.callbackPass(function(sender) {
var seen = null;
sender.send(generateData(1, 'b')).catch(test.callbackPass(function(e) {
test.assertEq(3, e.error);
test.assertEq(0, e.bytesSent);
test.assertEq(null, seen);
seen = 'send';
}));
sender.cancel(3).then(test.callbackPass(function() {
test.assertEq('send', seen);
seen = 'cancel';
sender.close();
}));
test.assertThrows(
sender.cancel, sender, [], 'Cancel already in progress');
test.assertThrows(sender.send, sender, [], 'Cancel in progress');
}));
},
function testClose() {
createSender().then(test.callbackPass(function(sender) {
var seen = null;
sender.send(generateData(1, 'b')).catch(test.callbackPass(function(e) {
test.assertEq(FATAL_ERROR, e.error);
test.assertEq(0, e.bytesSent);
test.assertEq(null, seen);
seen = 'send';
}));
sender.cancel(3).then(test.callbackPass(function() {
test.assertEq('send', seen);
seen = 'cancel';
sender.close();
}));
sender.close();
test.assertThrows(
sender.cancel, sender, [], 'DataSender has been closed');
test.assertThrows(sender.send, sender, [], 'DataSender has been closed');
}));
},
], test.runTests, exports);
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment