Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(804)

Unified Diff: runtime/vm/port_test.cc

Issue 8297004: Allow embedders to provide custom message delivery for an isolate. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: '' Created 9 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: runtime/vm/port_test.cc
===================================================================
--- runtime/vm/port_test.cc (revision 460)
+++ runtime/vm/port_test.cc (working copy)
@@ -3,52 +3,146 @@
// BSD-style license that can be found in the LICENSE file.
#include "vm/assert.h"
+#include "vm/message_queue.h"
+#include "vm/os.h"
#include "vm/port.h"
#include "vm/unit_test.h"
namespace dart {
-TEST_CASE(Port) {
- const char* msg_data = "Hallo Velo!";
- intptr_t port1 = PortMap::CreatePort();
- intptr_t port2 = PortMap::CreatePort();
- EXPECT(port1 != port2);
+// Intercept the post message callback and just store a copy of the message.
+static const int kMaxSavedMsg = 80;
+static char saved_msg[kMaxSavedMsg];
+static bool MyPostMessageCallback(Dart_Isolate dest_isolate,
+ Dart_Port dest_port,
+ Dart_Port reply_port,
+ Dart_Message dart_message) {
+ const char* msg = reinterpret_cast<char*>(dart_message);
+ OS::SNPrint(saved_msg, kMaxSavedMsg, "%s", msg);
+ bool result = (strcmp(msg, "fail") != 0);
+ free(dart_message);
+ return result;
+}
- PortMessage* msg1 = new PortMessage(port1, 0, strdup(msg_data));
- EXPECT_EQ(true, PortMap::PostMessage(msg1));
- PortMessage* msg = PortMap::ReceiveMessage(10);
- EXPECT_EQ(port1, msg->dest_id());
- EXPECT_EQ(msg1, msg);
- delete msg1;
- msg1 = new PortMessage(port2, 0, strdup(msg_data));
- EXPECT_EQ(true, PortMap::PostMessage(msg1));
- msg = PortMap::ReceiveMessage(10);
- EXPECT_EQ(port2, msg->dest_id());
- EXPECT_EQ(msg1, msg);
- delete msg1;
+// Intercept the close port callback and remember which port was closed.
+static Dart_Port saved_port = 0;
+static void MyClosePortCallback(Dart_Isolate dart_isolate,
+ Dart_Port port) {
+ saved_port = port;
+}
+
+static void InitPortMapTest() {
+ Dart_SetPostMessageCallback(&MyPostMessageCallback);
+ Dart_SetClosePortCallback(&MyClosePortCallback);
+ saved_port = 0;
+ saved_msg[0] = '\0';
+}
+
+
+TEST_CASE(PortMap_CreateAndCloseOnePort) {
+ InitPortMapTest();
+ intptr_t port = PortMap::CreatePort();
+ EXPECT_NE(0, port);
+ EXPECT(PortMap::IsActivePort(port));
+
+ PortMap::ClosePort(port);
+ EXPECT(!PortMap::IsActivePort(port));
+
+ // Embedder was notified of port closure.
+ EXPECT_EQ(port, saved_port);
+}
+
+
+TEST_CASE(PortMap_CreateAndCloseTwoPorts) {
+ InitPortMapTest();
+ Dart_Port port1 = PortMap::CreatePort();
+ Dart_Port port2 = PortMap::CreatePort();
+ EXPECT(PortMap::IsActivePort(port1));
+ EXPECT(PortMap::IsActivePort(port2));
+
+ // Uniqueness.
+ EXPECT_NE(port1, port2);
+
PortMap::ClosePort(port1);
- EXPECT_EQ(false, PortMap::IsActivePort(port1));
- msg1 = new PortMessage(port1, 0, strdup(msg_data));
- EXPECT_EQ(false, PortMap::PostMessage(msg1));
- delete msg1;
- EXPECT(PortMap::ReceiveMessage(10) == NULL);
+ EXPECT(!PortMap::IsActivePort(port1));
+ EXPECT(PortMap::IsActivePort(port2));
+ EXPECT_EQ(port1, saved_port);
- EXPECT_EQ(true, PortMap::IsActivePort(port2));
- msg1 = new PortMessage(port2, 0, strdup(msg_data));
- EXPECT_EQ(true, PortMap::PostMessage(msg1));
PortMap::ClosePort(port2);
- EXPECT(PortMap::ReceiveMessage(10) == NULL);
+ EXPECT(!PortMap::IsActivePort(port1));
+ EXPECT(!PortMap::IsActivePort(port2));
+ EXPECT_EQ(port2, saved_port);
+}
+
+TEST_CASE(PortMap_ClosePorts) {
+ InitPortMapTest();
+ Dart_Port port1 = PortMap::CreatePort();
+ Dart_Port port2 = PortMap::CreatePort();
+ EXPECT(PortMap::IsActivePort(port1));
+ EXPECT(PortMap::IsActivePort(port2));
+
+ // Close all ports at once.
+ PortMap::ClosePorts();
+ EXPECT(!PortMap::IsActivePort(port1));
+ EXPECT(!PortMap::IsActivePort(port2));
+
+ // Embedder is notified to close all ports as well.
+ EXPECT_EQ(kCloseAllPorts, saved_port);
+}
+
+
+TEST_CASE(PortMap_CreateManyPorts) {
+ InitPortMapTest();
for (int i = 0; i < 32; i++) {
- intptr_t port = PortMap::CreatePort();
+ Dart_Port port = PortMap::CreatePort();
+ EXPECT(PortMap::IsActivePort(port));
PortMap::ClosePort(port);
+ EXPECT(!PortMap::IsActivePort(port));
}
}
+TEST_CASE(PortMap_PostMessage) {
+ InitPortMapTest();
+ Dart_Port port = PortMap::CreatePort();
+ EXPECT(PortMap::PostMessage(
+ port, 0, reinterpret_cast<Dart_Message>(strdup("msg"))));
+
+ // Check that the post message callback was called.
+ EXPECT_STREQ("msg", saved_msg);
+ PortMap::ClosePorts();
+}
+
+
+TEST_CASE(PortMap_PostMessageInvalidPort) {
+ InitPortMapTest();
+ EXPECT(!PortMap::PostMessage(
+ 0, 0, reinterpret_cast<Dart_Message>(strdup("msg"))));
+
+ // Check that the post message callback was not called.
+ EXPECT_STREQ("", saved_msg);
+}
+
+
+TEST_CASE(PortMap_PostMessageFailureInCallback) {
+ InitPortMapTest();
+ Dart_Port port = PortMap::CreatePort();
+
+ // Our callback is rigged to return false when it sees the message
+ // "fail". This return value is propagated out of PostMessage.
+ EXPECT(!PortMap::PostMessage(
+ port, 0, reinterpret_cast<Dart_Message>(strdup("fail"))));
+
+ // Check that the post message callback was called.
+ EXPECT_STREQ("fail", saved_msg);
+ PortMap::ClosePorts();
+}
+
+
// End-of-test marker.
static const intptr_t kEOT = 0xFFFF;
@@ -64,28 +158,35 @@
}
+static PortMessage* NextMessage() {
+ Isolate* isolate = Isolate::Current();
+ PortMessage* result = isolate->message_queue()->Dequeue(0);
+ return result;
+}
+
+
void ThreadedPort_start(uword parameter) {
Dart::CreateIsolate(NULL, NULL);
intptr_t remote = parameter;
intptr_t local = PortMap::CreatePort();
- PortMap::PostMessage(new PortMessage(remote, 0, AllocIntData(local)));
+ PortMap::PostMessage(remote, 0, AllocIntData(local));
intptr_t count = 0;
while (true) {
- PortMessage* msg = PortMap::ReceiveMessage(0);
- EXPECT_EQ(local, msg->dest_id());
+ PortMessage* msg = NextMessage();
+ EXPECT_EQ(local, msg->dest_port());
EXPECT(msg != NULL);
if (GetIntData(msg->data()) == kEOT) {
break;
}
EXPECT(GetIntData(msg->data()) == count);
delete msg;
- PortMap::PostMessage(new PortMessage(remote, 0, AllocIntData(count * 2)));
+ PortMap::PostMessage(remote, 0, AllocIntData(count * 2));
count++;
}
- PortMap::PostMessage(new PortMessage(remote, 0, AllocIntData(kEOT)));
+ PortMap::PostMessage(remote, 0, AllocIntData(kEOT));
Dart::ShutdownIsolate();
}
@@ -97,24 +198,24 @@
Thread* thr = new Thread(ThreadedPort_start, local);
EXPECT(thr != NULL);
- PortMessage* msg = PortMap::ReceiveMessage(0);
- EXPECT_EQ(local, msg->dest_id());
+ PortMessage* msg = NextMessage();
+ EXPECT_EQ(local, msg->dest_port());
EXPECT(msg != NULL);
intptr_t remote = GetIntData(msg->data()); // Get the remote port.
delete msg;
for (intptr_t i = 0; i < 10; i++) {
- PortMap::PostMessage(new PortMessage(remote, 0, AllocIntData(i)));
- PortMessage* msg = PortMap::ReceiveMessage(0);
- EXPECT_EQ(local, msg->dest_id());
+ PortMap::PostMessage(remote, 0, AllocIntData(i));
+ PortMessage* msg = NextMessage();
+ EXPECT_EQ(local, msg->dest_port());
EXPECT(msg != NULL);
EXPECT_EQ(i * 2, GetIntData(msg->data()));
delete msg;
}
- PortMap::PostMessage(new PortMessage(remote, 0, AllocIntData(kEOT)));
- msg = PortMap::ReceiveMessage(0);
- EXPECT_EQ(local, msg->dest_id());
+ PortMap::PostMessage(remote, 0, AllocIntData(kEOT));
+ msg = NextMessage();
+ EXPECT_EQ(local, msg->dest_port());
EXPECT(msg != NULL);
EXPECT_EQ(kEOT, GetIntData(msg->data()));
delete msg;

Powered by Google App Engine
This is Rietveld 408576698