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

Unified Diff: native_client_sdk/src/libraries/nacl_io_test/mount_html5fs_test.cc

Issue 13951014: [NaCl SDK] nacl_io: opening a node immediately after mounting would fail. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: fix windows Created 7 years, 8 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: native_client_sdk/src/libraries/nacl_io_test/mount_html5fs_test.cc
diff --git a/native_client_sdk/src/libraries/nacl_io_test/mount_html5fs_test.cc b/native_client_sdk/src/libraries/nacl_io_test/mount_html5fs_test.cc
index d6a15308d792c862f802a40861c8696895c6cc74..5b5d19668cc4c8ce27aea5a9c8bdbe50a04f172c 100644
--- a/native_client_sdk/src/libraries/nacl_io_test/mount_html5fs_test.cc
+++ b/native_client_sdk/src/libraries/nacl_io_test/mount_html5fs_test.cc
@@ -9,6 +9,9 @@
#include <ppapi/c/ppb_file_io.h>
#include <ppapi/c/pp_errors.h>
#include <ppapi/c/pp_instance.h>
+#if defined(WIN32)
+#include <windows.h> // For Sleep()
+#endif
#include "mock_util.h"
#include "nacl_io/mount_html5fs.h"
@@ -19,6 +22,7 @@ using ::testing::_;
using ::testing::DoAll;
using ::testing::Invoke;
using ::testing::Return;
+using ::testing::SaveArg;
using ::testing::SetArgPointee;
using ::testing::StrEq;
using ::testing::WithArgs;
@@ -40,32 +44,44 @@ class MountHtml5FsTest : public ::testing::Test {
public:
MountHtml5FsTest();
~MountHtml5FsTest();
- void SetUpFilesystem(PP_FileSystemType, int);
+ void SetUpFilesystemExpectations(PP_FileSystemType, int,
+ bool async_callback=false);
protected:
PepperInterfaceMock* ppapi_;
+ PP_CompletionCallback open_filesystem_callback_;
static const PP_Instance instance_ = 123;
static const PP_Resource filesystem_resource_ = 234;
};
MountHtml5FsTest::MountHtml5FsTest()
- : ppapi_(NULL) {
+ : ppapi_(new PepperInterfaceMock(instance_)) {
}
MountHtml5FsTest::~MountHtml5FsTest() {
delete ppapi_;
}
-void MountHtml5FsTest::SetUpFilesystem(PP_FileSystemType fstype,
- int expected_size) {
- ppapi_ = new PepperInterfaceMock(instance_);
+void MountHtml5FsTest::SetUpFilesystemExpectations(
+ PP_FileSystemType fstype,
+ int expected_size,
+ bool async_callback) {
FileSystemInterfaceMock* filesystem = ppapi_->GetFileSystemInterface();
EXPECT_CALL(*filesystem, Create(instance_, fstype))
.Times(1)
.WillOnce(Return(filesystem_resource_));
- EXPECT_CALL(*filesystem, Open(filesystem_resource_, expected_size, _))
- .WillOnce(CallCallback<2>(int32_t(PP_OK)));
+
+ if (async_callback) {
+ EXPECT_CALL(*filesystem, Open(filesystem_resource_, expected_size, _))
+ .WillOnce(DoAll(SaveArg<2>(&open_filesystem_callback_),
+ Return(int32_t(PP_OK))));
+ EXPECT_CALL(*ppapi_, IsMainThread()).WillOnce(Return(PP_TRUE));
+ } else {
+ EXPECT_CALL(*filesystem, Open(filesystem_resource_, expected_size, _))
+ .WillOnce(CallCallback<2>(int32_t(PP_OK)));
+ EXPECT_CALL(*ppapi_, IsMainThread()).WillOnce(Return(PP_FALSE));
+ }
EXPECT_CALL(*ppapi_, ReleaseResource(filesystem_resource_));
}
@@ -76,6 +92,10 @@ class MountHtml5FsNodeTest : public MountHtml5FsTest {
virtual void SetUp();
virtual void TearDown();
+ void SetUpNodeExpectations();
+ void InitFilesystem();
+ void InitNode();
+
protected:
MountHtml5FsMock* mnt_;
MountNode* node_;
@@ -99,13 +119,18 @@ MountHtml5FsNodeTest::MountHtml5FsNodeTest()
}
void MountHtml5FsNodeTest::SetUp() {
- SetUpFilesystem(PP_FILESYSTEMTYPE_LOCALPERSISTENT, 0);
- StringMap_t map;
- mnt_ = new MountHtml5FsMock(map, ppapi_);
-
fileref_ = ppapi_->GetFileRefInterface();
fileio_ = ppapi_->GetFileIoInterface();
+}
+
+void MountHtml5FsNodeTest::TearDown() {
+ if (mnt_) {
+ mnt_->ReleaseNode(node_);
+ delete mnt_;
+ }
+}
+void MountHtml5FsNodeTest::SetUpNodeExpectations() {
// Open.
EXPECT_CALL(*fileref_, Create(filesystem_resource_, StrEq(&path_[0])))
.WillOnce(Return(fileref_resource_));
@@ -121,14 +146,31 @@ void MountHtml5FsNodeTest::SetUp() {
EXPECT_CALL(*ppapi_, ReleaseResource(fileref_resource_));
EXPECT_CALL(*ppapi_, ReleaseResource(fileio_resource_));
EXPECT_CALL(*fileio_, Flush(fileio_resource_, _));
+}
+
+void MountHtml5FsNodeTest::InitFilesystem() {
+ StringMap_t map;
+ mnt_ = new MountHtml5FsMock(map, ppapi_);
+}
+void MountHtml5FsNodeTest::InitNode() {
node_ = mnt_->Open(Path(path_), O_CREAT | O_RDWR);
ASSERT_NE((MountNode*)NULL, node_);
}
-void MountHtml5FsNodeTest::TearDown() {
- mnt_->ReleaseNode(node_);
- delete mnt_;
+// Node test where the filesystem is opened synchronously; that is, the
+// creation of the mount blocks until the filesystem is ready.
+class MountHtml5FsNodeSyncTest : public MountHtml5FsNodeTest {
+ public:
+ virtual void SetUp();
+};
+
+void MountHtml5FsNodeSyncTest::SetUp() {
+ MountHtml5FsNodeTest::SetUp();
+ SetUpFilesystemExpectations(PP_FILESYSTEMTYPE_LOCALPERSISTENT, 0);
+ InitFilesystem();
+ SetUpNodeExpectations();
+ InitNode();
}
void ReadEntriesAction(const PP_ArrayOutput& output) {
@@ -146,11 +188,101 @@ void ReadEntriesAction(const PP_ArrayOutput& output) {
memcpy(dest, &entries[0], sizeof(PP_DirectoryEntry_Dev) * 2);
}
+class MountHtml5FsNodeAsyncTest : public MountHtml5FsNodeTest {
+ public:
+ virtual void SetUp();
+ virtual void TearDown();
+
+ private:
+ static void* ThreadThunk(void* param);
+ void Thread();
+
+ enum {
+ STATE_INIT,
+ STATE_INIT_NODE,
+ STATE_INIT_NODE_FINISHED,
+ } state_;
+
+ pthread_t thread_;
+ pthread_cond_t cond_;
+ pthread_mutex_t mutex_;
+};
+
+void MountHtml5FsNodeAsyncTest::SetUp() {
+ MountHtml5FsNodeTest::SetUp();
+
+ state_ = STATE_INIT;
+
+ pthread_create(&thread_, NULL, &MountHtml5FsNodeAsyncTest::ThreadThunk, this);
+ pthread_mutex_init(&mutex_, NULL);
+ pthread_cond_init(&cond_, NULL);
+
+ // This test shows that even if the filesystem open callback happens after an
+ // attempt to open a node, it still works (opening the node blocks until the
+ // filesystem is ready).
+ // true => asynchronous filesystem open.
+ SetUpFilesystemExpectations(PP_FILESYSTEMTYPE_LOCALPERSISTENT, 0, true);
+ InitFilesystem();
+ SetUpNodeExpectations();
+
+ // Signal the other thread to try opening a Node.
+ pthread_mutex_lock(&mutex_);
+ state_ = STATE_INIT_NODE;
+ pthread_cond_signal(&cond_);
+ pthread_mutex_unlock(&mutex_);
+
+ // Wait for a bit...
+ // TODO(binji): this will be flaky. How to test this better?
+#if defined(WIN32)
+ Sleep(500); // milliseconds
+#else
+ usleep(500*1000); // microseconds
+#endif
+
+ // Call the filesystem open callback.
+ (*open_filesystem_callback_.func)(open_filesystem_callback_.user_data, PP_OK);
+
+ // Wait for the other thread to unblock and signal us.
+ pthread_mutex_lock(&mutex_);
+ while (state_ != STATE_INIT_NODE_FINISHED)
+ pthread_cond_wait(&cond_, &mutex_);
+ pthread_mutex_unlock(&mutex_);
+}
+
+void MountHtml5FsNodeAsyncTest::TearDown() {
+ pthread_cond_destroy(&cond_);
+ pthread_mutex_destroy(&mutex_);
+
+ MountHtml5FsNodeTest::TearDown();
+}
+
+void* MountHtml5FsNodeAsyncTest::ThreadThunk(void* param) {
+ static_cast<MountHtml5FsNodeAsyncTest*>(param)->Thread();
+ return NULL;
+}
+
+void MountHtml5FsNodeAsyncTest::Thread() {
+ // Wait for the "main" thread to tell us to open the Node.
+ pthread_mutex_lock(&mutex_);
+ while (state_ != STATE_INIT_NODE)
+ pthread_cond_wait(&cond_, &mutex_);
+ pthread_mutex_unlock(&mutex_);
+
+ // Opening the node blocks until the filesystem is open...
+ InitNode();
+
+ // Signal the "main" thread to tell it we're unblocked.
+ pthread_mutex_lock(&mutex_);
+ state_ = STATE_INIT_NODE_FINISHED;
+ pthread_cond_signal(&cond_);
+ pthread_mutex_unlock(&mutex_);
+}
+
} // namespace
TEST_F(MountHtml5FsTest, FilesystemType) {
- SetUpFilesystem(PP_FILESYSTEMTYPE_LOCALPERSISTENT, 100);
+ SetUpFilesystemExpectations(PP_FILESYSTEMTYPE_LOCALPERSISTENT, 100);
StringMap_t map;
map["type"] = "PERSISTENT";
@@ -163,7 +295,7 @@ TEST_F(MountHtml5FsTest, Mkdir) {
const PP_Resource fileref_resource = 235;
// These are the default values.
- SetUpFilesystem(PP_FILESYSTEMTYPE_LOCALPERSISTENT, 0);
+ SetUpFilesystemExpectations(PP_FILESYSTEMTYPE_LOCALPERSISTENT, 0);
FileRefInterfaceMock* fileref = ppapi_->GetFileRefInterface();
@@ -186,7 +318,7 @@ TEST_F(MountHtml5FsTest, Remove) {
const PP_Resource fileref_resource = 235;
// These are the default values.
- SetUpFilesystem(PP_FILESYSTEMTYPE_LOCALPERSISTENT, 0);
+ SetUpFilesystemExpectations(PP_FILESYSTEMTYPE_LOCALPERSISTENT, 0);
FileRefInterfaceMock* fileref = ppapi_->GetFileRefInterface();
@@ -203,10 +335,13 @@ TEST_F(MountHtml5FsTest, Remove) {
ASSERT_EQ(0, result);
}
-TEST_F(MountHtml5FsNodeTest, OpenAndClose) {
+TEST_F(MountHtml5FsNodeAsyncTest, AsyncFilesystemOpen) {
+}
+
+TEST_F(MountHtml5FsNodeSyncTest, OpenAndClose) {
}
-TEST_F(MountHtml5FsNodeTest, Write) {
+TEST_F(MountHtml5FsNodeSyncTest, Write) {
const int offset = 10;
const int count = 20;
const char buffer[30] = {0};
@@ -218,7 +353,7 @@ TEST_F(MountHtml5FsNodeTest, Write) {
EXPECT_EQ(count, result);
}
-TEST_F(MountHtml5FsNodeTest, Read) {
+TEST_F(MountHtml5FsNodeSyncTest, Read) {
const int offset = 10;
const int count = 20;
char buffer[30] = {0};
@@ -230,7 +365,7 @@ TEST_F(MountHtml5FsNodeTest, Read) {
EXPECT_EQ(count, result);
}
-TEST_F(MountHtml5FsNodeTest, GetStat) {
+TEST_F(MountHtml5FsNodeSyncTest, GetStat) {
const int size = 123;
const int creation_time = 1000;
const int access_time = 2000;
@@ -259,7 +394,7 @@ TEST_F(MountHtml5FsNodeTest, GetStat) {
EXPECT_EQ(creation_time, statbuf.st_ctime);
}
-TEST_F(MountHtml5FsNodeTest, Truncate) {
+TEST_F(MountHtml5FsNodeSyncTest, Truncate) {
const int size = 123;
EXPECT_CALL(*fileio_, SetLength(fileio_resource_, size, _))
.WillOnce(Return(int32_t(PP_OK)));
@@ -268,7 +403,7 @@ TEST_F(MountHtml5FsNodeTest, Truncate) {
EXPECT_EQ(0, result);
}
-TEST_F(MountHtml5FsNodeTest, GetDents) {
+TEST_F(MountHtml5FsNodeSyncTest, GetDents) {
const int dir_reader_resource = 237;
const int fileref_resource_1 = 238;
const int fileref_resource_2 = 239;

Powered by Google App Engine
This is Rietveld 408576698