summaryrefslogtreecommitdiffstats
path: root/native_client_sdk
diff options
context:
space:
mode:
authorbinji@chromium.org <binji@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-07-01 21:56:21 +0000
committerbinji@chromium.org <binji@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-07-01 21:56:21 +0000
commitaaa269340ebd7e630e895afbdc5479fcc97bd0fe (patch)
treeaefc5f17ab3b651374a645897bf08d42582bcecf /native_client_sdk
parentf7ebc11ae5c44a771d470f313aef5f35e6ad888f (diff)
downloadchromium_src-aaa269340ebd7e630e895afbdc5479fcc97bd0fe.zip
chromium_src-aaa269340ebd7e630e895afbdc5479fcc97bd0fe.tar.gz
chromium_src-aaa269340ebd7e630e895afbdc5479fcc97bd0fe.tar.bz2
[NaCl SDK] nacl_io: Add test for write/read fix.
I've also changed the MountFactory used by the KernelProxy into an object instead of a function. This makes it easier to replace in tests. I've also added MountMock and MountNodeMock which are gmock wrappers for Mount and MountNode, respectively. BUG=254675 R=noelallen@chromium.org Review URL: https://codereview.chromium.org/17955003 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@209510 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'native_client_sdk')
-rw-r--r--native_client_sdk/src/build_tools/sdk_files.list2
-rw-r--r--native_client_sdk/src/libraries/nacl_io/kernel_proxy.cc26
-rw-r--r--native_client_sdk/src/libraries/nacl_io/kernel_proxy.h17
-rw-r--r--native_client_sdk/src/libraries/nacl_io/library.dsc2
-rw-r--r--native_client_sdk/src/libraries/nacl_io/mount.h24
-rw-r--r--native_client_sdk/src/libraries/nacl_io/mount_dev.h4
-rw-r--r--native_client_sdk/src/libraries/nacl_io/mount_factory.h29
-rw-r--r--native_client_sdk/src/libraries/nacl_io/mount_html5fs.h4
-rw-r--r--native_client_sdk/src/libraries/nacl_io/mount_http.h5
-rw-r--r--native_client_sdk/src/libraries/nacl_io/mount_mem.h6
-rw-r--r--native_client_sdk/src/libraries/nacl_io/mount_node.cc29
-rw-r--r--native_client_sdk/src/libraries/nacl_io/mount_node.h5
-rw-r--r--native_client_sdk/src/libraries/nacl_io/mount_passthrough.h5
-rw-r--r--native_client_sdk/src/libraries/nacl_io/typed_mount_factory.h29
-rw-r--r--native_client_sdk/src/libraries/nacl_io_test/example.dsc6
-rw-r--r--native_client_sdk/src/libraries/nacl_io_test/example.js5
-rw-r--r--native_client_sdk/src/libraries/nacl_io_test/kernel_proxy_mock.cc3
-rw-r--r--native_client_sdk/src/libraries/nacl_io_test/kernel_proxy_test.cc142
-rw-r--r--native_client_sdk/src/libraries/nacl_io_test/mount_mock.cc11
-rw-r--r--native_client_sdk/src/libraries/nacl_io_test/mount_mock.h30
-rw-r--r--native_client_sdk/src/libraries/nacl_io_test/mount_node_mock.cc11
-rw-r--r--native_client_sdk/src/libraries/nacl_io_test/mount_node_mock.h44
-rw-r--r--native_client_sdk/src/libraries/sdk_util/scoped_ref.h26
23 files changed, 361 insertions, 104 deletions
diff --git a/native_client_sdk/src/build_tools/sdk_files.list b/native_client_sdk/src/build_tools/sdk_files.list
index fd6fc1f..ffc959a 100644
--- a/native_client_sdk/src/build_tools/sdk_files.list
+++ b/native_client_sdk/src/build_tools/sdk_files.list
@@ -265,6 +265,7 @@ include/nacl_io/kernel_wrap.h
include/nacl_io/kernel_wrap_real.h
include/nacl_io/mount_dev.h
include/nacl_io/mount.h
+include/nacl_io/mount_factory.h
include/nacl_io/mount_html5fs.h
include/nacl_io/mount_http.h
include/nacl_io/mount_mem.h
@@ -288,6 +289,7 @@ include/nacl_io/pepper/define_empty_macros.h
include/nacl_io/pepper_interface.h
include/nacl_io/pepper/undef_macros.h
include/nacl_io/real_pepper_interface.h
+include/nacl_io/typed_mount_factory.h
include/ppapi/c/dev/deprecated_bool.h
include/ppapi/c/dev/ppb_audio_input_dev.h
include/ppapi/c/dev/ppb_buffer_dev.h
diff --git a/native_client_sdk/src/libraries/nacl_io/kernel_proxy.cc b/native_client_sdk/src/libraries/nacl_io/kernel_proxy.cc
index bc62c37..8d5655a 100644
--- a/native_client_sdk/src/libraries/nacl_io/kernel_proxy.cc
+++ b/native_client_sdk/src/libraries/nacl_io/kernel_proxy.cc
@@ -25,6 +25,7 @@
#include "nacl_io/osstat.h"
#include "nacl_io/path.h"
#include "nacl_io/pepper_interface.h"
+#include "nacl_io/typed_mount_factory.h"
#include "sdk_util/auto_lock.h"
#include "sdk_util/ref_object.h"
@@ -38,18 +39,27 @@
KernelProxy::KernelProxy() : dev_(0), ppapi_(NULL) {}
-KernelProxy::~KernelProxy() { delete ppapi_; }
+KernelProxy::~KernelProxy() {
+ // Clean up the MountFactories.
+ for (MountFactoryMap_t::iterator i = factories_.begin();
+ i != factories_.end();
+ ++i) {
+ delete i->second;
+ }
+
+ delete ppapi_;
+}
void KernelProxy::Init(PepperInterface* ppapi) {
ppapi_ = ppapi;
cwd_ = "/";
dev_ = 1;
- factories_["memfs"] = MountMem::Create<MountMem>;
- factories_["dev"] = MountDev::Create<MountDev>;
- factories_["html5fs"] = MountHtml5Fs::Create<MountHtml5Fs>;
- factories_["httpfs"] = MountHttp::Create<MountHttp>;
- factories_["passthroughfs"] = MountPassthrough::Create<MountPassthrough>;
+ factories_["memfs"] = new TypedMountFactory<MountMem>;
+ factories_["dev"] = new TypedMountFactory<MountDev>;
+ factories_["html5fs"] = new TypedMountFactory<MountHtml5Fs>;
+ factories_["httpfs"] = new TypedMountFactory<MountHttp>;
+ factories_["passthroughfs"] = new TypedMountFactory<MountPassthrough>;
int result;
result = mount("", "/", "passthroughfs", 0, NULL);
@@ -91,7 +101,6 @@ int KernelProxy::open(const char* path, int oflags) {
return AllocateFD(handle);
}
-
int KernelProxy::close(int fd) {
ScopedKernelHandle handle;
Error error = AcquireHandle(fd, &handle);
@@ -302,7 +311,8 @@ int KernelProxy::mount(const char* source,
free(str);
}
- Error error = factory->second(dev_++, smap, ppapi_, &mounts_[abs_targ]);
+ Error error =
+ factory->second->CreateMount(dev_++, smap, ppapi_, &mounts_[abs_targ]);
if (error) {
errno = error;
return -1;
diff --git a/native_client_sdk/src/libraries/nacl_io/kernel_proxy.h b/native_client_sdk/src/libraries/nacl_io/kernel_proxy.h
index ac3b936..554a75ca 100644
--- a/native_client_sdk/src/libraries/nacl_io/kernel_proxy.h
+++ b/native_client_sdk/src/libraries/nacl_io/kernel_proxy.h
@@ -5,22 +5,14 @@
#ifndef LIBRARIES_NACL_IO_KERNEL_PROXY_H_
#define LIBRARIES_NACL_IO_KERNEL_PROXY_H_
-#include <ppapi/c/pp_instance.h>
-#include <ppapi/c/ppb.h>
-#include <pthread.h>
#include <map>
#include <string>
-#include <vector>
#include "nacl_io/kernel_object.h"
-#include "nacl_io/mount.h"
+#include "nacl_io/mount_factory.h"
#include "nacl_io/ostypes.h"
#include "nacl_io/osutime.h"
-#include "nacl_io/path.h"
-class KernelHandle;
-class Mount;
-class MountNode;
class PepperInterface;
// KernelProxy provide one-to-one mapping for libc kernel calls. Calls to the
@@ -30,12 +22,7 @@ class PepperInterface;
// other classes should return Error (as defined by nacl_io/error.h).
class KernelProxy : protected KernelObject {
public:
- typedef Error (*MountFactory_t)(int,
- StringMap_t&,
- PepperInterface*,
- ScopedMount*);
- typedef std::map<std::string, std::string> StringMap_t;
- typedef std::map<std::string, MountFactory_t> MountFactoryMap_t;
+ typedef std::map<std::string, MountFactory*> MountFactoryMap_t;
KernelProxy();
virtual ~KernelProxy();
diff --git a/native_client_sdk/src/libraries/nacl_io/library.dsc b/native_client_sdk/src/libraries/nacl_io/library.dsc
index c582991..eef0ac6 100644
--- a/native_client_sdk/src/libraries/nacl_io/library.dsc
+++ b/native_client_sdk/src/libraries/nacl_io/library.dsc
@@ -48,6 +48,7 @@
"kernel_wrap_real.h",
"mount.h",
"mount_dev.h",
+ "mount_factory.h",
"mount_html5fs.h",
"mount_http.h",
"mount_mem.h",
@@ -68,6 +69,7 @@
"path.h",
"pepper_interface.h",
"real_pepper_interface.h",
+ "typed_mount_factory.h",
],
'DEST': 'include/nacl_io',
},
diff --git a/native_client_sdk/src/libraries/nacl_io/mount.h b/native_client_sdk/src/libraries/nacl_io/mount.h
index 89f9b88..58cf1a4 100644
--- a/native_client_sdk/src/libraries/nacl_io/mount.h
+++ b/native_client_sdk/src/libraries/nacl_io/mount.h
@@ -24,7 +24,6 @@ class PepperInterface;
typedef ScopedRef<Mount> ScopedMount;
typedef std::map<std::string, std::string> StringMap_t;
-
// NOTE: The KernelProxy is the only class that should be setting errno. All
// other classes should return Error (as defined by nacl_io/error.h).
class Mount : public RefObject {
@@ -41,13 +40,6 @@ class Mount : public RefObject {
virtual void Destroy();
public:
- template <class M>
- // Assumes that |out_mount| is non-NULL.
- static Error Create(int dev,
- StringMap_t& args,
- PepperInterface* ppapi,
- ScopedMount* out_mount);
-
PepperInterface* ppapi() { return ppapi_; }
// All paths in functions below are expected to containing a leading "/".
@@ -98,20 +90,4 @@ class Mount : public RefObject {
DISALLOW_COPY_AND_ASSIGN(Mount);
};
-/*static*/
-template <class M>
-Error Mount::Create(int dev,
- StringMap_t& args,
- PepperInterface* ppapi,
- ScopedMount* out_mount) {
- ScopedMount mnt(new M());
- Error error = mnt->Init(dev, args, ppapi);
- if (error)
- return error;
-
- *out_mount = mnt;
- return 0;
-}
-
-
#endif // LIBRARIES_NACL_IO_MOUNT_H_
diff --git a/native_client_sdk/src/libraries/nacl_io/mount_dev.h b/native_client_sdk/src/libraries/nacl_io/mount_dev.h
index 2d57102..5d47838 100644
--- a/native_client_sdk/src/libraries/nacl_io/mount_dev.h
+++ b/native_client_sdk/src/libraries/nacl_io/mount_dev.h
@@ -6,6 +6,7 @@
#define LIBRARIES_NACL_IO_MOUNT_DEV_H_
#include "nacl_io/mount.h"
+#include "nacl_io/typed_mount_factory.h"
class MountNode;
@@ -26,7 +27,8 @@ class MountDev : public Mount {
private:
ScopedMountNode root_;
- friend class Mount;
+ friend class TypedMountFactory<MountDev>;
+ DISALLOW_COPY_AND_ASSIGN(MountDev);
};
#endif // LIBRARIES_NACL_IO_MOUNT_DEV_H_
diff --git a/native_client_sdk/src/libraries/nacl_io/mount_factory.h b/native_client_sdk/src/libraries/nacl_io/mount_factory.h
new file mode 100644
index 0000000..35f77d7
--- /dev/null
+++ b/native_client_sdk/src/libraries/nacl_io/mount_factory.h
@@ -0,0 +1,29 @@
+/* Copyright (c) 2013 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.
+ */
+#ifndef LIBRARIES_NACL_IO_MOUNT_FACTORY_H_
+#define LIBRARIES_NACL_IO_MOUNT_FACTORY_H_
+
+#include <map>
+#include <string>
+
+#include "nacl_io/error.h"
+#include "sdk_util/scoped_ref.h"
+
+class PepperInterface;
+class Mount;
+
+typedef std::map<std::string, std::string> StringMap_t;
+
+class MountFactory {
+ public:
+ virtual ~MountFactory() {}
+ virtual Error CreateMount(int dev,
+ StringMap_t& args,
+ PepperInterface* ppapi,
+ ScopedRef<Mount>* out_mount) = 0;
+};
+
+#endif // LIBRARIES_NACL_IO_MOUNT_FACTORY_H_
+
diff --git a/native_client_sdk/src/libraries/nacl_io/mount_html5fs.h b/native_client_sdk/src/libraries/nacl_io/mount_html5fs.h
index ff25e53..d2e1b08 100644
--- a/native_client_sdk/src/libraries/nacl_io/mount_html5fs.h
+++ b/native_client_sdk/src/libraries/nacl_io/mount_html5fs.h
@@ -6,8 +6,10 @@
#define LIBRARIES_NACL_IO_MOUNT_HTML5FS_H_
#include <pthread.h>
+
#include "nacl_io/mount.h"
#include "nacl_io/pepper_interface.h"
+#include "nacl_io/typed_mount_factory.h"
class MountNode;
@@ -39,7 +41,7 @@ class MountHtml5Fs : public Mount {
Error filesystem_open_error_; // protected by lock_.
pthread_cond_t filesystem_open_cond_;
- friend class Mount;
+ friend class TypedMountFactory<MountHtml5Fs>;
};
#endif // LIBRARIES_NACL_IO_MOUNT_HTML5FS_H_
diff --git a/native_client_sdk/src/libraries/nacl_io/mount_http.h b/native_client_sdk/src/libraries/nacl_io/mount_http.h
index cf3feb9..e804f37 100644
--- a/native_client_sdk/src/libraries/nacl_io/mount_http.h
+++ b/native_client_sdk/src/libraries/nacl_io/mount_http.h
@@ -9,10 +9,9 @@
#include <string>
#include "nacl_io/mount.h"
#include "nacl_io/pepper_interface.h"
+#include "nacl_io/typed_mount_factory.h"
class MountNode;
-class MountNodeDir;
-class MountNodeHttp;
class MountHttpMock;
std::string NormalizeHeaderKey(const std::string& s);
@@ -54,7 +53,7 @@ class MountHttp : public Mount {
bool cache_stat_;
bool cache_content_;
- friend class Mount;
+ friend class TypedMountFactory<MountHttp>;
friend class MountNodeHttp;
friend class MountHttpMock;
};
diff --git a/native_client_sdk/src/libraries/nacl_io/mount_mem.h b/native_client_sdk/src/libraries/nacl_io/mount_mem.h
index 523ca4f..9bd679d 100644
--- a/native_client_sdk/src/libraries/nacl_io/mount_mem.h
+++ b/native_client_sdk/src/libraries/nacl_io/mount_mem.h
@@ -5,10 +5,8 @@
#ifndef LIBRARIES_NACL_IO_MOUNT_MEM_H_
#define LIBRARIES_NACL_IO_MOUNT_MEM_H_
-#include <map>
-#include <string>
-
#include "nacl_io/mount.h"
+#include "nacl_io/typed_mount_factory.h"
class MountMem : public Mount {
protected:
@@ -44,7 +42,7 @@ private:
ScopedMountNode root_;
- friend class Mount;
+ friend class TypedMountFactory<MountMem>;
DISALLOW_COPY_AND_ASSIGN(MountMem);
};
diff --git a/native_client_sdk/src/libraries/nacl_io/mount_node.cc b/native_client_sdk/src/libraries/nacl_io/mount_node.cc
index ec77b97..424df70 100644
--- a/native_client_sdk/src/libraries/nacl_io/mount_node.cc
+++ b/native_client_sdk/src/libraries/nacl_io/mount_node.cc
@@ -1,5 +1,5 @@
/* Copyright (c) 2012 The Chromium Authors. All rights reserved.
-x * Use of this source code is governed by a BSD-style license that can be
+ * Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#include "nacl_io/mount_node.h"
@@ -48,9 +48,7 @@ void MountNode::Destroy() {
Error MountNode::FSync() { return 0; }
-Error MountNode::FTruncate(off_t length) {
- return EINVAL;
-}
+Error MountNode::FTruncate(off_t length) { return EINVAL; }
Error MountNode::GetDents(size_t offs,
struct dirent* pdir,
@@ -66,9 +64,7 @@ Error MountNode::GetStat(struct stat* pstat) {
return 0;
}
-Error MountNode::Ioctl(int request, char* arg) {
- return EINVAL;
-}
+Error MountNode::Ioctl(int request, char* arg) { return EINVAL; }
Error MountNode::Read(size_t offs, void* buf, size_t count, int* out_bytes) {
*out_bytes = 0;
@@ -140,25 +136,16 @@ Error MountNode::AddChild(const std::string& name,
return ENOTDIR;
}
-Error MountNode::RemoveChild(const std::string& name) {
- return ENOTDIR;
-}
+Error MountNode::RemoveChild(const std::string& name) { return ENOTDIR; }
-Error MountNode::FindChild(const std::string& name,
- ScopedMountNode* out_node) {
+Error MountNode::FindChild(const std::string& name, ScopedMountNode* out_node) {
out_node->reset(NULL);
return ENOTDIR;
}
-int MountNode::ChildCount() {
- return 0;
-}
+int MountNode::ChildCount() { return 0; }
-void MountNode::Link() {
- stat_.st_nlink++;
-}
+void MountNode::Link() { stat_.st_nlink++; }
-void MountNode::Unlink() {
- stat_.st_nlink--;
-}
+void MountNode::Unlink() { stat_.st_nlink--; }
diff --git a/native_client_sdk/src/libraries/nacl_io/mount_node.h b/native_client_sdk/src/libraries/nacl_io/mount_node.h
index f790b33..fb0f14f 100644
--- a/native_client_sdk/src/libraries/nacl_io/mount_node.h
+++ b/native_client_sdk/src/libraries/nacl_io/mount_node.h
@@ -21,7 +21,6 @@ class MountNode;
typedef ScopedRef<MountNode> ScopedMountNode;
-
// NOTE: The KernelProxy is the only class that should be setting errno. All
// other classes should return Error (as defined by nacl_io/error.h).
class MountNode : public RefObject {
@@ -70,7 +69,7 @@ class MountNode : public RefObject {
virtual int GetMode();
virtual int GetType();
// Assume that |out_size| is non-NULL.
- virtual Error GetSize(size_t *out_size);
+ virtual Error GetSize(size_t* out_size);
virtual bool IsaDir();
virtual bool IsaFile();
virtual bool IsaTTY();
@@ -99,7 +98,7 @@ class MountNode : public RefObject {
struct stat stat_;
// We use a pointer directly to avoid cycles in the ref count.
- // TODO(noelallen) We should change this to it's unnecessary for the node
+ // TODO(noelallen) We should change this so it's unnecessary for the node
// to track it's parent. When a node is unlinked, the mount should do
// any cleanup it needs.
Mount* mount_;
diff --git a/native_client_sdk/src/libraries/nacl_io/mount_passthrough.h b/native_client_sdk/src/libraries/nacl_io/mount_passthrough.h
index 7b59b05..4d441a0 100644
--- a/native_client_sdk/src/libraries/nacl_io/mount_passthrough.h
+++ b/native_client_sdk/src/libraries/nacl_io/mount_passthrough.h
@@ -6,6 +6,7 @@
#define LIBRARIES_NACL_IO_MOUNT_PASSTHROUGH_H_
#include "nacl_io/mount.h"
+#include "nacl_io/typed_mount_factory.h"
class MountPassthrough : public Mount {
protected:
@@ -24,8 +25,8 @@ class MountPassthrough : public Mount {
virtual Error Remove(const Path& path);
private:
- friend class Mount;
- DISALLOW_COPY_AND_ASSIGN(MountPassthrough);
+ friend class TypedMountFactory<MountPassthrough>;
+ DISALLOW_COPY_AND_ASSIGN(MountPassthrough);
};
#endif // LIBRARIES_NACL_IO_MOUNT_PASSTHROUGH_H_
diff --git a/native_client_sdk/src/libraries/nacl_io/typed_mount_factory.h b/native_client_sdk/src/libraries/nacl_io/typed_mount_factory.h
new file mode 100644
index 0000000..c859b0b
--- /dev/null
+++ b/native_client_sdk/src/libraries/nacl_io/typed_mount_factory.h
@@ -0,0 +1,29 @@
+/* Copyright (c) 2013 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.
+ */
+#ifndef LIBRARIES_NACL_IO_TYPED_MOUNT_FACTORY_H_
+#define LIBRARIES_NACL_IO_TYPED_MOUNT_FACTORY_H_
+
+#include "nacl_io/mount.h"
+#include "nacl_io/mount_factory.h"
+
+template <typename T>
+class TypedMountFactory : public MountFactory {
+ public:
+ virtual Error CreateMount(int dev,
+ StringMap_t& args,
+ PepperInterface* ppapi,
+ ScopedRef<Mount>* out_mount) {
+ ScopedRef<T> mnt(new T());
+ Error error = mnt->Init(dev, args, ppapi);
+ if (error)
+ return error;
+
+ *out_mount = mnt;
+ return 0;
+ }
+};
+
+#endif // LIBRARIES_NACL_IO_TYPED_MOUNT_FACTORY_H_
+
diff --git a/native_client_sdk/src/libraries/nacl_io_test/example.dsc b/native_client_sdk/src/libraries/nacl_io_test/example.dsc
index 63b0ef4..b26cd7c 100644
--- a/native_client_sdk/src/libraries/nacl_io_test/example.dsc
+++ b/native_client_sdk/src/libraries/nacl_io_test/example.dsc
@@ -15,9 +15,13 @@
'kernel_wrap_test.cc',
'main.cc',
'mock_util.h',
- 'mount_node_test.cc',
'mount_html5fs_test.cc',
'mount_http_test.cc',
+ 'mount_mock.cc',
+ 'mount_mock.h',
+ 'mount_node_mock.cc',
+ 'mount_node_mock.h',
+ 'mount_node_test.cc',
'mount_test.cc',
'path_test.cc',
'pepper_interface_mock.cc',
diff --git a/native_client_sdk/src/libraries/nacl_io_test/example.js b/native_client_sdk/src/libraries/nacl_io_test/example.js
index 3b4de45..bd17594 100644
--- a/native_client_sdk/src/libraries/nacl_io_test/example.js
+++ b/native_client_sdk/src/libraries/nacl_io_test/example.js
@@ -60,7 +60,7 @@ function handleMessage(event) {
// in the test failure summary).
var argList = msg.substr(firstColon + 1);
args = [];
- for (var i = 0; i < argCount; ++i) {
+ for (var i = 0; i < argCount - 1; ++i) {
var arg;
var comma = argList.indexOf(',');
if (comma === -1) {
@@ -78,5 +78,8 @@ function handleMessage(event) {
args.push(arg);
}
+ // Last argument is the rest of the message.
+ args.push(argList);
+
cmdFunction.apply(null, args);
}
diff --git a/native_client_sdk/src/libraries/nacl_io_test/kernel_proxy_mock.cc b/native_client_sdk/src/libraries/nacl_io_test/kernel_proxy_mock.cc
index 279a8ea..367569e 100644
--- a/native_client_sdk/src/libraries/nacl_io_test/kernel_proxy_mock.cc
+++ b/native_client_sdk/src/libraries/nacl_io_test/kernel_proxy_mock.cc
@@ -6,8 +6,7 @@
#include "kernel_proxy_mock.h"
#include "nacl_io/kernel_intercept.h"
-KernelProxyMock::KernelProxyMock() {
-}
+KernelProxyMock::KernelProxyMock() {}
KernelProxyMock::~KernelProxyMock() {
// Uninitialize the kernel proxy so wrapped functions passthrough to their
diff --git a/native_client_sdk/src/libraries/nacl_io_test/kernel_proxy_test.cc b/native_client_sdk/src/libraries/nacl_io_test/kernel_proxy_test.cc
index 601f3b7..70e76e1 100644
--- a/native_client_sdk/src/libraries/nacl_io_test/kernel_proxy_test.cc
+++ b/native_client_sdk/src/libraries/nacl_io_test/kernel_proxy_test.cc
@@ -11,15 +11,30 @@
#include <map>
#include <string>
-#include "nacl_io/kernel_handle.h"
+#include "gmock/gmock.h"
+#include "gtest/gtest.h"
+
+#include "mount_mock.h"
+#include "mount_node_mock.h"
+
#include "nacl_io/kernel_intercept.h"
#include "nacl_io/kernel_proxy.h"
#include "nacl_io/mount.h"
#include "nacl_io/mount_mem.h"
#include "nacl_io/osmman.h"
#include "nacl_io/path.h"
+#include "nacl_io/typed_mount_factory.h"
-#include "gtest/gtest.h"
+using ::testing::_;
+using ::testing::DoAll;
+using ::testing::Invoke;
+using ::testing::Return;
+using ::testing::SaveArg;
+using ::testing::SetArgPointee;
+using ::testing::StrEq;
+using ::testing::WithArgs;
+
+namespace {
class KernelProxyFriend : public KernelProxy {
public:
@@ -44,22 +59,24 @@ class KernelProxyTest : public ::testing::Test {
KernelProxyFriend* kp_;
};
+} // namespace
+
TEST_F(KernelProxyTest, FileLeak) {
const size_t buffer_size = 1024;
char filename[128];
int file_num;
int garbage[buffer_size];
- MountMem* mount = (MountMem*) kp_->RootMount();
+ MountMem* mount = (MountMem*)kp_->RootMount();
ScopedMountNode root;
EXPECT_EQ(0, mount->Open(Path("/"), O_RDONLY, &root));
EXPECT_EQ(0, root->ChildCount());
- for (file_num=0; file_num < 4096; file_num++) {
+ for (file_num = 0; file_num < 4096; file_num++) {
sprintf(filename, "/foo%i.tmp", file_num++);
- FILE *f = fopen(filename, "w");
- EXPECT_NE((FILE *) 0, f);
+ FILE* f = fopen(filename, "w");
+ EXPECT_NE((FILE*)0, f);
EXPECT_EQ(1, root->ChildCount());
EXPECT_EQ(buffer_size, fwrite(garbage, 1, buffer_size, f));
fclose(f);
@@ -227,6 +244,8 @@ TEST_F(KernelProxyTest, MemMountDup) {
// fd, new_fd, dup_fd -> "/bar"
}
+namespace {
+
StringMap_t g_StringMap;
class MountMockInit : public MountMem {
@@ -237,13 +256,14 @@ class MountMockInit : public MountMem {
return EINVAL;
return 0;
}
- ;
+
+ friend class TypedMountFactory<MountMockInit>;
};
class KernelProxyMountMock : public KernelProxy {
virtual void Init(PepperInterface* ppapi) {
KernelProxy::Init(NULL);
- factories_["initfs"] = MountMockInit::Create<MountMockInit>;
+ factories_["initfs"] = new TypedMountFactory<MountMockInit>;
}
};
@@ -260,6 +280,8 @@ class KernelProxyMountTest : public ::testing::Test {
KernelProxy* kp_;
};
+} // namespace
+
TEST_F(KernelProxyMountTest, MountInit) {
int res1 = ki_mount("/", "/mnt1", "initfs", 0, "false,foo=bar");
@@ -326,12 +348,14 @@ class MountMockMMap : public Mount {
virtual Error Mkdir(const Path& path, int permissions) { return ENOSYS; }
virtual Error Rmdir(const Path& path) { return ENOSYS; }
virtual Error Remove(const Path& path) { return ENOSYS; }
+
+ friend class TypedMountFactory<MountMockMMap>;
};
class KernelProxyMockMMap : public KernelProxy {
virtual void Init(PepperInterface* ppapi) {
KernelProxy::Init(NULL);
- factories_["mmapfs"] = MountMockInit::Create<MountMockMMap>;
+ factories_["mmapfs"] = new TypedMountFactory<MountMockMMap>;
}
};
@@ -376,3 +400,103 @@ TEST_F(KernelProxyMMapTest, MMap) {
EXPECT_EQ(3, g_MMapCount);
}
+namespace {
+
+class SingletonMountFactory : public MountFactory {
+ public:
+ SingletonMountFactory(const ScopedMount& mount) : mount_(mount) {}
+
+ virtual Error CreateMount(int dev,
+ StringMap_t& args,
+ PepperInterface* ppapi,
+ ScopedMount* out_mount) {
+ *out_mount = mount_;
+ return 0;
+ }
+
+ private:
+ ScopedMount mount_;
+};
+
+class KernelProxyError : public KernelProxy {
+ public:
+ KernelProxyError() : mnt_(new MountMock) {}
+
+ virtual void Init(PepperInterface* ppapi) {
+ KernelProxy::Init(ppapi);
+ factories_["testfs"] = new SingletonMountFactory(mnt_);
+
+ EXPECT_CALL(*mnt_, Destroy()).Times(1);
+ }
+
+ ScopedRef<MountMock> mnt() { return mnt_; }
+
+ private:
+ ScopedRef<MountMock> mnt_;
+};
+
+class KernelProxyErrorTest : public ::testing::Test {
+ public:
+ KernelProxyErrorTest() : kp_(new KernelProxyError) {
+ ki_init(kp_);
+ // Unmount the passthrough FS and mount a testfs.
+ EXPECT_EQ(0, kp_->umount("/"));
+ EXPECT_EQ(0, kp_->mount("", "/", "testfs", 0, NULL));
+ }
+
+ ~KernelProxyErrorTest() {
+ ki_uninit();
+ delete kp_;
+ }
+
+ ScopedRef<MountMock> mnt() { return kp_->mnt(); }
+
+ private:
+ KernelProxyError* kp_;
+};
+
+} // namespace
+
+TEST_F(KernelProxyErrorTest, WriteError) {
+ ScopedRef<MountMock> mock_mnt(mnt());
+ ScopedRef<MountNodeMock> mock_node(new MountNodeMock(&*mock_mnt));
+ EXPECT_CALL(*mock_mnt, Open(_, _, _))
+ .WillOnce(DoAll(SetArgPointee<2>(mock_node), Return(0)));
+
+ EXPECT_CALL(*mock_node, Write(_, _, _, _))
+ .WillOnce(DoAll(SetArgPointee<3>(0), // Wrote 0 bytes.
+ Return(1234))); // Returned error 1234.
+
+ EXPECT_CALL(*mock_node, Destroy()).Times(1);
+
+ int fd = ki_open("/dummy", O_WRONLY);
+ EXPECT_NE(0, fd);
+
+ char buf[20];
+ EXPECT_EQ(-1, ki_write(fd, &buf[0], 20));
+ // The Mount should be able to return whatever error it wants and have it
+ // propagate through.
+ EXPECT_EQ(1234, errno);
+}
+
+TEST_F(KernelProxyErrorTest, ReadError) {
+ ScopedRef<MountMock> mock_mnt(mnt());
+ ScopedRef<MountNodeMock> mock_node(new MountNodeMock(&*mock_mnt));
+ EXPECT_CALL(*mock_mnt, Open(_, _, _))
+ .WillOnce(DoAll(SetArgPointee<2>(mock_node), Return(0)));
+
+ EXPECT_CALL(*mock_node, Read(_, _, _, _))
+ .WillOnce(DoAll(SetArgPointee<3>(0), // Read 0 bytes.
+ Return(1234))); // Returned error 1234.
+
+ EXPECT_CALL(*mock_node, Destroy()).Times(1);
+
+ int fd = ki_open("/dummy", O_RDONLY);
+ EXPECT_NE(0, fd);
+
+ char buf[20];
+ EXPECT_EQ(-1, ki_read(fd, &buf[0], 20));
+ // The Mount should be able to return whatever error it wants and have it
+ // propagate through.
+ EXPECT_EQ(1234, errno);
+}
diff --git a/native_client_sdk/src/libraries/nacl_io_test/mount_mock.cc b/native_client_sdk/src/libraries/nacl_io_test/mount_mock.cc
new file mode 100644
index 0000000..4b69108
--- /dev/null
+++ b/native_client_sdk/src/libraries/nacl_io_test/mount_mock.cc
@@ -0,0 +1,11 @@
+/* Copyright (c) 2013 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 "mount_mock.h"
+
+MountMock::MountMock() {}
+
+MountMock::~MountMock() {}
+
diff --git a/native_client_sdk/src/libraries/nacl_io_test/mount_mock.h b/native_client_sdk/src/libraries/nacl_io_test/mount_mock.h
new file mode 100644
index 0000000..7ceebc4
--- /dev/null
+++ b/native_client_sdk/src/libraries/nacl_io_test/mount_mock.h
@@ -0,0 +1,30 @@
+/* Copyright (c) 2013 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.
+ */
+
+#ifndef LIBRARIES_NACL_IO_TEST_MOUNT_MOCK_H_
+#define LIBRARIES_NACL_IO_TEST_MOUNT_MOCK_H_
+
+#include "gmock/gmock.h"
+
+#include "nacl_io/mount.h"
+
+class MountMock : public Mount {
+ public:
+ MountMock();
+ virtual ~MountMock();
+
+ MOCK_METHOD3(Init, Error(int, StringMap_t&, PepperInterface*));
+ MOCK_METHOD0(Destroy, void());
+ MOCK_METHOD2(Access, Error(const Path&, int));
+ MOCK_METHOD3(Open, Error(const Path&, int, ScopedMountNode*));
+ MOCK_METHOD2(OpenResource, Error(const Path&, ScopedMountNode*));
+ MOCK_METHOD1(Unlink, Error(const Path&));
+ MOCK_METHOD2(Mkdir, Error(const Path&, int));
+ MOCK_METHOD1(Rmdir, Error(const Path&));
+ MOCK_METHOD1(Remove, Error(const Path&));
+};
+
+#endif // LIBRARIES_NACL_IO_TEST_MOUNT_MOCK_H_
+
diff --git a/native_client_sdk/src/libraries/nacl_io_test/mount_node_mock.cc b/native_client_sdk/src/libraries/nacl_io_test/mount_node_mock.cc
new file mode 100644
index 0000000..b925b56
--- /dev/null
+++ b/native_client_sdk/src/libraries/nacl_io_test/mount_node_mock.cc
@@ -0,0 +1,11 @@
+/* Copyright (c) 2013 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 "mount_node_mock.h"
+
+MountNodeMock::MountNodeMock(Mount* mount) : MountNode(mount) {}
+
+MountNodeMock::~MountNodeMock() {}
+
diff --git a/native_client_sdk/src/libraries/nacl_io_test/mount_node_mock.h b/native_client_sdk/src/libraries/nacl_io_test/mount_node_mock.h
new file mode 100644
index 0000000..dbbfda1
--- /dev/null
+++ b/native_client_sdk/src/libraries/nacl_io_test/mount_node_mock.h
@@ -0,0 +1,44 @@
+/* Copyright (c) 2013 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.
+ */
+
+#ifndef LIBRARIES_NACL_IO_TEST_MOUNT_NODE_MOCK_H_
+#define LIBRARIES_NACL_IO_TEST_MOUNT_NODE_MOCK_H_
+
+#include "gmock/gmock.h"
+
+#include "nacl_io/mount.h"
+
+class MountNodeMock : public MountNode {
+ public:
+ explicit MountNodeMock(Mount*);
+ virtual ~MountNodeMock();
+
+ MOCK_METHOD1(Init, Error(int));
+ MOCK_METHOD0(Destroy, void());
+ MOCK_METHOD0(FSync, Error());
+ MOCK_METHOD1(FTruncate, Error(off_t));
+ MOCK_METHOD4(GetDents, Error(size_t, struct dirent*, size_t, int*));
+ MOCK_METHOD1(GetStat, Error(struct stat*));
+ MOCK_METHOD2(Ioctl, Error(int, char*));
+ MOCK_METHOD4(Read, Error(size_t, void*, size_t, int*));
+ MOCK_METHOD4(Write, Error(size_t, const void*, size_t, int*));
+ MOCK_METHOD6(MMap, Error(void*, size_t, int, int, size_t, void**));
+ MOCK_METHOD0(GetLinks, int());
+ MOCK_METHOD0(GetMode, int());
+ MOCK_METHOD0(GetType, int());
+ MOCK_METHOD1(GetSize, Error(size_t*));
+ MOCK_METHOD0(IsaDir, bool());
+ MOCK_METHOD0(IsaFile, bool());
+ MOCK_METHOD0(IsaTTY, bool());
+ MOCK_METHOD0(ChildCount, int());
+ MOCK_METHOD2(AddChild, Error(const std::string&, const ScopedMountNode&));
+ MOCK_METHOD1(RemoveChild, Error(const std::string&));
+ MOCK_METHOD2(FindChild, Error(const std::string&, ScopedMountNode*));
+ MOCK_METHOD0(Link, void());
+ MOCK_METHOD0(Unlink, void());
+};
+
+#endif // LIBRARIES_NACL_IO_TEST_MOUNT_NODE_MOCK_H_
+
diff --git a/native_client_sdk/src/libraries/sdk_util/scoped_ref.h b/native_client_sdk/src/libraries/sdk_util/scoped_ref.h
index d446325..0bbba71 100644
--- a/native_client_sdk/src/libraries/sdk_util/scoped_ref.h
+++ b/native_client_sdk/src/libraries/sdk_util/scoped_ref.h
@@ -30,7 +30,8 @@ class ScopedRefBase {
RefObject* ptr_;
};
-template<class T> class ScopedRef : public ScopedRefBase {
+template <class T>
+class ScopedRef : public ScopedRefBase {
public:
ScopedRef() {}
ScopedRef(const ScopedRef& ptr) { reset(ptr.get()); }
@@ -41,7 +42,13 @@ template<class T> class ScopedRef : public ScopedRefBase {
return *this;
}
- template<typename U> ScopedRef& operator=(const ScopedRef<U>& ptr) {
+ template <typename U>
+ ScopedRef(const ScopedRef<U>& ptr) {
+ reset(ptr.get());
+ }
+
+ template <typename U>
+ ScopedRef& operator=(const ScopedRef<U>& ptr) {
reset(ptr.get());
return *this;
}
@@ -49,17 +56,19 @@ template<class T> class ScopedRef : public ScopedRefBase {
void reset(T* obj = NULL) { ScopedRefBase::reset(obj); }
T* get() const { return static_cast<T*>(ptr_); }
- template<typename U> bool operator==(const ScopedRef<U>& p) const {
+ template <typename U>
+ bool operator==(const ScopedRef<U>& p) const {
return get() == p.get();
}
- template<typename U> bool operator!=(const ScopedRef<U>& p) const {
+ template <typename U>
+ bool operator!=(const ScopedRef<U>& p) const {
return get() != p.get();
}
public:
T& operator*() const { return *get(); }
- T* operator->() const { return get(); }
+ T* operator->() const { return get(); }
#ifndef __llvm__
private:
@@ -68,16 +77,15 @@ template<class T> class ScopedRef : public ScopedRefBase {
public:
operator bool_as_func_ptr() const {
- return (ptr_ != NULL) ?
- &ScopedRef::bool_as_func_impl : 0;
+ return (ptr_ != NULL) ? &ScopedRef::bool_as_func_impl : 0;
}
#else
/*
* TODO Remove when bug 3514 is fixed see:
* https://code.google.com/p/nativeclient/issues/detail?id=3514
*/
- operator T*() const { return get(); };
+ operator T*() const { return get(); }
#endif
};
-#endif // LIBRARIES_SDK_UTIL_SCOPED_REF_H_
+#endif // LIBRARIES_SDK_UTIL_SCOPED_REF_H_