Skip to content

Commit

Permalink
Add mojo bindings backpointer tests.
Browse files Browse the repository at this point in the history
Simple bit-flipping won't generate negative offsets (e.g. large
positive offsets that overflow), so we add a test where we specifically
create the possibility of such.

Also simplify argument passing in the cpp -> js direction, since there isn't
a need to build lists here.  We're only interested in the other direction.

Remove some stray "explicit" keywords and reduce the echo
test iterations since it doesn't prove much.

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

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@271806 0039d316-1c4b-4281-b951-d872f2087c98
  • Loading branch information
tsepez@chromium.org committed May 21, 2014
1 parent fe55240 commit 5efb527
Show file tree
Hide file tree
Showing 3 changed files with 132 additions and 33 deletions.
8 changes: 5 additions & 3 deletions mojo/apps/js/test/js_to_cpp.mojom
Original file line number Diff line number Diff line change
Expand Up @@ -30,17 +30,19 @@ struct EchoArgsList {

interface CppSide {
StartTest(); // Sent for all tests to notify that the JS side is now ready.
TestFinished(); // Sent in echo / bit-flip tests to indicate end.
TestFinished(); // Indicates end for echo, bit-flip, and back-pointer tests.
PingResponse();
EchoResponse(EchoArgsList list);
BitFlipResponse(EchoArgs arg);
BitFlipResponse(EchoArgsList arg);
BackPointerResponse(EchoArgsList arg);
};

[Client=CppSide]
interface JsSide {
Ping();
Echo(int32 numIterations, EchoArgsList list);
Echo(int32 numIterations, EchoArgs arg);
BitFlip(EchoArgs arg);
BackPointer(EchoArgs arg);
};

}
88 changes: 69 additions & 19 deletions mojo/apps/js/test/js_to_cpp_unittest.cc
Original file line number Diff line number Diff line change
Expand Up @@ -126,12 +126,6 @@ void CheckSampleEchoArgs(const js_to_cpp::EchoArgs& arg) {
CheckDataPipe(arg.data_handle().get().value());
}

js_to_cpp::EchoArgsList BuildSampleEchoArgsList() {
js_to_cpp::EchoArgsList::Builder builder;
builder.set_item(BuildSampleEchoArgs());
return builder.Finish();
}

void CheckSampleEchoArgsList(const js_to_cpp::EchoArgsList& list) {
if (list.is_null())
return;
Expand All @@ -154,6 +148,22 @@ void CheckCorruptedStringArray(const mojo::Array<mojo::String>& string_array) {
CheckCorruptedString(string_array[i]);
}

void CheckCorruptedEchoArgs(const js_to_cpp::EchoArgs& arg) {
if (arg.is_null())
return;
CheckCorruptedString(arg.name());
CheckCorruptedStringArray(arg.string_array());
if (arg.data_handle().is_valid())
CheckDataPipe(arg.data_handle().get().value());
}

void CheckCorruptedEchoArgsList(const js_to_cpp::EchoArgsList& list) {
if (list.is_null())
return;
CheckCorruptedEchoArgs(list.item());
CheckCorruptedEchoArgsList(list.next());
}

// Base Provider implementation class. It's expected that tests subclass and
// override the appropriate Provider functions. When test is done quit the
// run_loop().
Expand Down Expand Up @@ -186,10 +196,14 @@ class CppSideConnection : public js_to_cpp::CppSide {
NOTREACHED();
}

virtual void BitFlipResponse(const js_to_cpp::EchoArgs& arg1) OVERRIDE {
virtual void BitFlipResponse(const js_to_cpp::EchoArgsList& list) OVERRIDE {
NOTREACHED();
}

virtual void BackPointerResponse(
const js_to_cpp::EchoArgsList& list) OVERRIDE {
NOTREACHED();
}
protected:
base::RunLoop* run_loop_;
js_to_cpp::JsSide* js_side_;
Expand All @@ -201,7 +215,7 @@ class CppSideConnection : public js_to_cpp::CppSide {
// Trivial test to verify a message sent from JS is received.
class PingCppSideConnection : public CppSideConnection {
public:
explicit PingCppSideConnection() : got_message_(false) {}
PingCppSideConnection() : got_message_(false) {}
virtual ~PingCppSideConnection() {}

// js_to_cpp::CppSide:
Expand All @@ -226,7 +240,7 @@ class PingCppSideConnection : public CppSideConnection {
// Test that parameters are passed with correct values.
class EchoCppSideConnection : public CppSideConnection {
public:
explicit EchoCppSideConnection() :
EchoCppSideConnection() :
message_count_(0),
termination_seen_(false) {
}
Expand All @@ -235,7 +249,7 @@ class EchoCppSideConnection : public CppSideConnection {
// js_to_cpp::CppSide:
virtual void StartTest() OVERRIDE {
AllocationScope scope;
js_side_->Echo(kExpectedMessageCount, BuildSampleEchoArgsList());
js_side_->Echo(kExpectedMessageCount, BuildSampleEchoArgs());
}

virtual void EchoResponse(const js_to_cpp::EchoArgsList& list) OVERRIDE {
Expand All @@ -259,7 +273,7 @@ class EchoCppSideConnection : public CppSideConnection {
}

private:
static const int kExpectedMessageCount = 100;
static const int kExpectedMessageCount = 10;
int message_count_;
bool termination_seen_;
DISALLOW_COPY_AND_ASSIGN(EchoCppSideConnection);
Expand All @@ -268,7 +282,7 @@ class EchoCppSideConnection : public CppSideConnection {
// Test that corrupted messages don't wreak havoc.
class BitFlipCppSideConnection : public CppSideConnection {
public:
explicit BitFlipCppSideConnection() : termination_seen_(false) {}
BitFlipCppSideConnection() : termination_seen_(false) {}
virtual ~BitFlipCppSideConnection() {}

// js_to_cpp::CppSide:
Expand All @@ -277,13 +291,8 @@ class BitFlipCppSideConnection : public CppSideConnection {
js_side_->BitFlip(BuildSampleEchoArgs());
}

virtual void BitFlipResponse(const js_to_cpp::EchoArgs& arg) OVERRIDE {
if (arg.is_null())
return;
CheckCorruptedString(arg.name());
CheckCorruptedStringArray(arg.string_array());
if (arg.data_handle().is_valid())
CheckDataPipe(arg.data_handle().get().value());
virtual void BitFlipResponse(const js_to_cpp::EchoArgsList& list) OVERRIDE {
CheckCorruptedEchoArgsList(list);
}

virtual void TestFinished() OVERRIDE {
Expand All @@ -300,6 +309,37 @@ class BitFlipCppSideConnection : public CppSideConnection {
DISALLOW_COPY_AND_ASSIGN(BitFlipCppSideConnection);
};

// Test that severely random messages don't wreak havoc.
class BackPointerCppSideConnection : public CppSideConnection {
public:
BackPointerCppSideConnection() : termination_seen_(false) {}
virtual ~BackPointerCppSideConnection() {}

// js_to_cpp::CppSide:
virtual void StartTest() OVERRIDE {
AllocationScope scope;
js_side_->BackPointer(BuildSampleEchoArgs());
}

virtual void BackPointerResponse(
const js_to_cpp::EchoArgsList& list) OVERRIDE {
CheckCorruptedEchoArgsList(list);
}

virtual void TestFinished() OVERRIDE {
termination_seen_ = true;
run_loop()->Quit();
}

bool DidSucceed() {
return termination_seen_;
}

private:
bool termination_seen_;
DISALLOW_COPY_AND_ASSIGN(BackPointerCppSideConnection);
};

} // namespace

class JsToCppTest : public testing::Test {
Expand Down Expand Up @@ -363,5 +403,15 @@ TEST_F(JsToCppTest, DISABLED_BitFlip) {
EXPECT_TRUE(cpp_side_connection.DidSucceed());
}

// TODO(tsepez): Disabled due to http://crbug.com/366797.
TEST_F(JsToCppTest, DISABLED_BackPointer) {
if (IsRunningOnIsolatedBot())
return;

BackPointerCppSideConnection cpp_side_connection;
RunTest("mojo/apps/js/test/js_to_cpp_unittest", &cpp_side_connection);
EXPECT_TRUE(cpp_side_connection.DidSucceed());
}

} // namespace js
} // namespace mojo
69 changes: 58 additions & 11 deletions mojo/apps/js/test/js_to_cpp_unittest.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,14 +29,12 @@ define('mojo/apps/js/test/js_to_cpp_unittest', [
this.cppSide_.pingResponse();
};

JsSideConnection.prototype.echo = function (numIterations, list) {
var arg = list.item;
JsSideConnection.prototype.echo = function (numIterations, arg) {
var dataPipe1;
var dataPipe2;
var i;
var messagePipe1;
var messagePipe2;
var resultList;
var specialArg;

// Ensure expected negative values are negative.
Expand Down Expand Up @@ -73,12 +71,7 @@ define('mojo/apps/js/test/js_to_cpp_unittest', [
writeDataPipe(dataPipe1, senderData);
writeDataPipe(dataPipe2, senderData);

resultList = new jsToCpp.EchoArgsList();
resultList.next = new jsToCpp.EchoArgsList();
resultList.item = specialArg;
resultList.next.item = arg;

this.cppSide_.echoResponse(resultList);
this.cppSide_.echoResponse(createEchoArgsList(specialArg, arg));

core.close(dataPipe1.producerHandle);
core.close(dataPipe2.producerHandle);
Expand All @@ -92,8 +85,9 @@ define('mojo/apps/js/test/js_to_cpp_unittest', [
var iteration = 0;
var dataPipe;
var messagePipe;
var stopSignalled = false;
var proto = connector.Connector.prototype;
var resultList;
var stopSignalled = false;

proto.realAccept = proto.accept;
proto.accept = function (message) {
Expand All @@ -116,7 +110,46 @@ define('mojo/apps/js/test/js_to_cpp_unittest', [
writeDataPipe(dataPipe, senderData);
arg.data_handle = dataPipe.consumerHandle;
arg.message_handle = messagePipe.handle1;
this.cppSide_.bitFlipResponse(arg);
resultList = createEchoArgsList(arg);
this.cppSide_.bitFlipResponse(resultList);
core.close(dataPipe.producerHandle);
core.close(messagePipe.handle0);
iteration += 1;
}

proto.accept = proto.realAccept;
proto.realAccept = null;
this.cppSide_.testFinished();
};

JsSideConnection.prototype.backPointer = function (arg) {
var iteration = 0;
var dataPipe;
var messagePipe;
var proto = connector.Connector.prototype;
var resultList = createEchoArgsList(arg);
var stopSignalled = false;

proto.realAccept = proto.accept;
proto.accept = function (message) {
var delta = 8 * (1 + iteration % 32);
var offset = 8 * ((iteration / 32) | 0);
if (offset < message.buffer.arrayBuffer.byteLength - 4) {
message.buffer.dataView.setUint32(offset, 0x100000000 - delta, true);
message.buffer.dataView.setUint32(offset + 4, 0xffffffff, true);
return this.realAccept(message);
}
stopSignalled = true;
return false;
};

while (!stopSignalled) {
dataPipe = core.createDataPipe(DATA_PIPE_PARAMS);
messagePipe = core.createMessagePipe();
writeDataPipe(dataPipe, senderData);
arg.data_handle = dataPipe.consumerHandle;
arg.message_handle = messagePipe.handle1;
this.cppSide_.backPointerResponse(resultList);
core.close(dataPipe.producerHandle);
core.close(messagePipe.handle0);
iteration += 1;
Expand All @@ -142,6 +175,20 @@ define('mojo/apps/js/test/js_to_cpp_unittest', [
return true;
}

function createEchoArgsListElement(item, next) {
var list = new jsToCpp.EchoArgsList();
list.item = item;
list.next = next;
return list;
}

function createEchoArgsList() {
var genuineArray = Array.prototype.slice.call(arguments);
return genuineArray.reduceRight(function (previous, current) {
return createEchoArgsListElement(current, previous);
}, null);
}

return function(handle) {
var i;
senderData = new Uint8Array(DATA_PIPE_PARAMS.capacityNumBytes);
Expand Down

0 comments on commit 5efb527

Please sign in to comment.