Commit 5efb527a authored by tsepez@chromium.org's avatar tsepez@chromium.org

Add mojo bindings backpointer tests.

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
parent fe552401
...@@ -30,17 +30,19 @@ struct EchoArgsList { ...@@ -30,17 +30,19 @@ struct EchoArgsList {
interface CppSide { interface CppSide {
StartTest(); // Sent for all tests to notify that the JS side is now ready. 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(); PingResponse();
EchoResponse(EchoArgsList list); EchoResponse(EchoArgsList list);
BitFlipResponse(EchoArgs arg); BitFlipResponse(EchoArgsList arg);
BackPointerResponse(EchoArgsList arg);
}; };
[Client=CppSide] [Client=CppSide]
interface JsSide { interface JsSide {
Ping(); Ping();
Echo(int32 numIterations, EchoArgsList list); Echo(int32 numIterations, EchoArgs arg);
BitFlip(EchoArgs arg); BitFlip(EchoArgs arg);
BackPointer(EchoArgs arg);
}; };
} }
...@@ -126,12 +126,6 @@ void CheckSampleEchoArgs(const js_to_cpp::EchoArgs& arg) { ...@@ -126,12 +126,6 @@ void CheckSampleEchoArgs(const js_to_cpp::EchoArgs& arg) {
CheckDataPipe(arg.data_handle().get().value()); 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) { void CheckSampleEchoArgsList(const js_to_cpp::EchoArgsList& list) {
if (list.is_null()) if (list.is_null())
return; return;
...@@ -154,6 +148,22 @@ void CheckCorruptedStringArray(const mojo::Array<mojo::String>& string_array) { ...@@ -154,6 +148,22 @@ void CheckCorruptedStringArray(const mojo::Array<mojo::String>& string_array) {
CheckCorruptedString(string_array[i]); 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 // Base Provider implementation class. It's expected that tests subclass and
// override the appropriate Provider functions. When test is done quit the // override the appropriate Provider functions. When test is done quit the
// run_loop(). // run_loop().
...@@ -186,10 +196,14 @@ class CppSideConnection : public js_to_cpp::CppSide { ...@@ -186,10 +196,14 @@ class CppSideConnection : public js_to_cpp::CppSide {
NOTREACHED(); NOTREACHED();
} }
virtual void BitFlipResponse(const js_to_cpp::EchoArgs& arg1) OVERRIDE { virtual void BitFlipResponse(const js_to_cpp::EchoArgsList& list) OVERRIDE {
NOTREACHED(); NOTREACHED();
} }
virtual void BackPointerResponse(
const js_to_cpp::EchoArgsList& list) OVERRIDE {
NOTREACHED();
}
protected: protected:
base::RunLoop* run_loop_; base::RunLoop* run_loop_;
js_to_cpp::JsSide* js_side_; js_to_cpp::JsSide* js_side_;
...@@ -201,7 +215,7 @@ class CppSideConnection : public js_to_cpp::CppSide { ...@@ -201,7 +215,7 @@ class CppSideConnection : public js_to_cpp::CppSide {
// Trivial test to verify a message sent from JS is received. // Trivial test to verify a message sent from JS is received.
class PingCppSideConnection : public CppSideConnection { class PingCppSideConnection : public CppSideConnection {
public: public:
explicit PingCppSideConnection() : got_message_(false) {} PingCppSideConnection() : got_message_(false) {}
virtual ~PingCppSideConnection() {} virtual ~PingCppSideConnection() {}
// js_to_cpp::CppSide: // js_to_cpp::CppSide:
...@@ -226,7 +240,7 @@ class PingCppSideConnection : public CppSideConnection { ...@@ -226,7 +240,7 @@ class PingCppSideConnection : public CppSideConnection {
// Test that parameters are passed with correct values. // Test that parameters are passed with correct values.
class EchoCppSideConnection : public CppSideConnection { class EchoCppSideConnection : public CppSideConnection {
public: public:
explicit EchoCppSideConnection() : EchoCppSideConnection() :
message_count_(0), message_count_(0),
termination_seen_(false) { termination_seen_(false) {
} }
...@@ -235,7 +249,7 @@ class EchoCppSideConnection : public CppSideConnection { ...@@ -235,7 +249,7 @@ class EchoCppSideConnection : public CppSideConnection {
// js_to_cpp::CppSide: // js_to_cpp::CppSide:
virtual void StartTest() OVERRIDE { virtual void StartTest() OVERRIDE {
AllocationScope scope; AllocationScope scope;
js_side_->Echo(kExpectedMessageCount, BuildSampleEchoArgsList()); js_side_->Echo(kExpectedMessageCount, BuildSampleEchoArgs());
} }
virtual void EchoResponse(const js_to_cpp::EchoArgsList& list) OVERRIDE { virtual void EchoResponse(const js_to_cpp::EchoArgsList& list) OVERRIDE {
...@@ -259,7 +273,7 @@ class EchoCppSideConnection : public CppSideConnection { ...@@ -259,7 +273,7 @@ class EchoCppSideConnection : public CppSideConnection {
} }
private: private:
static const int kExpectedMessageCount = 100; static const int kExpectedMessageCount = 10;
int message_count_; int message_count_;
bool termination_seen_; bool termination_seen_;
DISALLOW_COPY_AND_ASSIGN(EchoCppSideConnection); DISALLOW_COPY_AND_ASSIGN(EchoCppSideConnection);
...@@ -268,7 +282,7 @@ class EchoCppSideConnection : public CppSideConnection { ...@@ -268,7 +282,7 @@ class EchoCppSideConnection : public CppSideConnection {
// Test that corrupted messages don't wreak havoc. // Test that corrupted messages don't wreak havoc.
class BitFlipCppSideConnection : public CppSideConnection { class BitFlipCppSideConnection : public CppSideConnection {
public: public:
explicit BitFlipCppSideConnection() : termination_seen_(false) {} BitFlipCppSideConnection() : termination_seen_(false) {}
virtual ~BitFlipCppSideConnection() {} virtual ~BitFlipCppSideConnection() {}
// js_to_cpp::CppSide: // js_to_cpp::CppSide:
...@@ -277,13 +291,8 @@ class BitFlipCppSideConnection : public CppSideConnection { ...@@ -277,13 +291,8 @@ class BitFlipCppSideConnection : public CppSideConnection {
js_side_->BitFlip(BuildSampleEchoArgs()); js_side_->BitFlip(BuildSampleEchoArgs());
} }
virtual void BitFlipResponse(const js_to_cpp::EchoArgs& arg) OVERRIDE { virtual void BitFlipResponse(const js_to_cpp::EchoArgsList& list) OVERRIDE {
if (arg.is_null()) CheckCorruptedEchoArgsList(list);
return;
CheckCorruptedString(arg.name());
CheckCorruptedStringArray(arg.string_array());
if (arg.data_handle().is_valid())
CheckDataPipe(arg.data_handle().get().value());
} }
virtual void TestFinished() OVERRIDE { virtual void TestFinished() OVERRIDE {
...@@ -300,6 +309,37 @@ class BitFlipCppSideConnection : public CppSideConnection { ...@@ -300,6 +309,37 @@ class BitFlipCppSideConnection : public CppSideConnection {
DISALLOW_COPY_AND_ASSIGN(BitFlipCppSideConnection); 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 } // namespace
class JsToCppTest : public testing::Test { class JsToCppTest : public testing::Test {
...@@ -363,5 +403,15 @@ TEST_F(JsToCppTest, DISABLED_BitFlip) { ...@@ -363,5 +403,15 @@ TEST_F(JsToCppTest, DISABLED_BitFlip) {
EXPECT_TRUE(cpp_side_connection.DidSucceed()); 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 js
} // namespace mojo } // namespace mojo
...@@ -29,14 +29,12 @@ define('mojo/apps/js/test/js_to_cpp_unittest', [ ...@@ -29,14 +29,12 @@ define('mojo/apps/js/test/js_to_cpp_unittest', [
this.cppSide_.pingResponse(); this.cppSide_.pingResponse();
}; };
JsSideConnection.prototype.echo = function (numIterations, list) { JsSideConnection.prototype.echo = function (numIterations, arg) {
var arg = list.item;
var dataPipe1; var dataPipe1;
var dataPipe2; var dataPipe2;
var i; var i;
var messagePipe1; var messagePipe1;
var messagePipe2; var messagePipe2;
var resultList;
var specialArg; var specialArg;
// Ensure expected negative values are negative. // Ensure expected negative values are negative.
...@@ -73,12 +71,7 @@ define('mojo/apps/js/test/js_to_cpp_unittest', [ ...@@ -73,12 +71,7 @@ define('mojo/apps/js/test/js_to_cpp_unittest', [
writeDataPipe(dataPipe1, senderData); writeDataPipe(dataPipe1, senderData);
writeDataPipe(dataPipe2, senderData); writeDataPipe(dataPipe2, senderData);
resultList = new jsToCpp.EchoArgsList(); this.cppSide_.echoResponse(createEchoArgsList(specialArg, arg));
resultList.next = new jsToCpp.EchoArgsList();
resultList.item = specialArg;
resultList.next.item = arg;
this.cppSide_.echoResponse(resultList);
core.close(dataPipe1.producerHandle); core.close(dataPipe1.producerHandle);
core.close(dataPipe2.producerHandle); core.close(dataPipe2.producerHandle);
...@@ -92,8 +85,9 @@ define('mojo/apps/js/test/js_to_cpp_unittest', [ ...@@ -92,8 +85,9 @@ define('mojo/apps/js/test/js_to_cpp_unittest', [
var iteration = 0; var iteration = 0;
var dataPipe; var dataPipe;
var messagePipe; var messagePipe;
var stopSignalled = false;
var proto = connector.Connector.prototype; var proto = connector.Connector.prototype;
var resultList;
var stopSignalled = false;
proto.realAccept = proto.accept; proto.realAccept = proto.accept;
proto.accept = function (message) { proto.accept = function (message) {
...@@ -116,7 +110,46 @@ define('mojo/apps/js/test/js_to_cpp_unittest', [ ...@@ -116,7 +110,46 @@ define('mojo/apps/js/test/js_to_cpp_unittest', [
writeDataPipe(dataPipe, senderData); writeDataPipe(dataPipe, senderData);
arg.data_handle = dataPipe.consumerHandle; arg.data_handle = dataPipe.consumerHandle;
arg.message_handle = messagePipe.handle1; 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(dataPipe.producerHandle);
core.close(messagePipe.handle0); core.close(messagePipe.handle0);
iteration += 1; iteration += 1;
...@@ -142,6 +175,20 @@ define('mojo/apps/js/test/js_to_cpp_unittest', [ ...@@ -142,6 +175,20 @@ define('mojo/apps/js/test/js_to_cpp_unittest', [
return true; 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) { return function(handle) {
var i; var i;
senderData = new Uint8Array(DATA_PIPE_PARAMS.capacityNumBytes); senderData = new Uint8Array(DATA_PIPE_PARAMS.capacityNumBytes);
......
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