Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2014 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2014 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include <pthread.h> | |
| 6 #include <unistd.h> | |
| 7 | |
| 8 #include <sstream> | |
| 9 #include <string> | |
| 10 | |
| 11 #include "native_client/src/untrusted/irt/irt.h" | |
| 12 | |
| 13 #include "ppapi/cpp/completion_callback.h" | |
| 5 #include "ppapi/cpp/instance.h" | 14 #include "ppapi/cpp/instance.h" |
| 6 #include "ppapi/cpp/module.h" | 15 #include "ppapi/cpp/module.h" |
| 7 #include "ppapi/cpp/var.h" | 16 #include "ppapi/cpp/var.h" |
| 8 | 17 |
| 9 namespace { | 18 namespace { |
| 10 | 19 |
| 20 std::string g_last_error; | |
| 21 pp::Instance* g_instance = NULL; | |
| 22 | |
| 23 // This should be the same as FileDescriptorSet::kMaxDescriptorsPerMessage in | |
| 24 // ipc/file_descriptor_set_posix.h. | |
| 25 const size_t kMaxDescriptorsPerMessage = 7; | |
| 26 | |
| 27 // Returns true if the resource file whose name is |key| exists and its content | |
| 28 // matches |content|. | |
| 29 bool LoadManifestInternal(nacl_irt_resource_open* nacl_irt_resource_open, | |
| 30 const std::string& key, | |
| 31 const std::string& content) { | |
| 32 int desc; | |
| 33 int error; | |
| 34 error = nacl_irt_resource_open->open_resource(key.c_str(), &desc); | |
| 35 if (0 != error) { | |
| 36 g_last_error = "Can't open file " + key; | |
| 37 return false; | |
| 38 } | |
| 39 | |
| 40 std::string str; | |
| 41 | |
| 42 char buffer[4096]; | |
| 43 int len; | |
| 44 while ((len = read(desc, buffer, sizeof(buffer) - 1)) > 0) { | |
| 45 // Null terminate. | |
| 46 buffer[len] = '\0'; | |
| 47 str += buffer; | |
| 48 } | |
| 49 close(desc); | |
|
Mark Seaborn
2014/12/08 23:27:14
Nit: Check return value
Yusuke Sato
2014/12/09 03:45:54
Done.
| |
| 50 | |
| 51 if (str != content) { | |
| 52 g_last_error = "Wrong file content: file=" + key + ", expected=" + content + | |
| 53 ", actual=" + str; | |
| 54 return false; | |
| 55 } | |
| 56 | |
| 57 return true; | |
| 58 } | |
| 59 | |
| 60 // Tests if open_resource works in a packaged app. This test is similar to | |
| 61 // NaClBrowserTest*.IrtManifestFile, but unlike the NaCl test, this one tests | |
| 62 // the "fast path" in DownloadNexe() in ppb_nacl_private_impl.cc which opens | |
| 63 // resource files without using URLLoader. | |
| 64 void LoadManifest() { | |
| 65 struct nacl_irt_resource_open nacl_irt_resource_open; | |
| 66 if (sizeof(nacl_irt_resource_open) != | |
| 67 nacl_interface_query(NACL_IRT_RESOURCE_OPEN_v0_1, | |
| 68 &nacl_irt_resource_open, | |
| 69 sizeof(nacl_irt_resource_open))) { | |
| 70 g_last_error = "NACL_IRT_RESOURCE_OPEN_v0_1 not found"; | |
| 71 return; | |
| 72 } | |
| 73 | |
| 74 for (size_t i = 0; i <= kMaxDescriptorsPerMessage; ++i) { | |
| 75 std::stringstream key; | |
| 76 key << "test_file" << i; | |
| 77 std::string content = "Test File Content" + std::string(i % 2 ? "2" : ""); | |
|
Mark Seaborn
2014/12/08 23:27:14
BTW, something like "Example contents for open_res
Yusuke Sato
2014/12/09 03:45:54
Done.
| |
| 78 if (!LoadManifestInternal(&nacl_irt_resource_open, key.str(), content)) | |
| 79 break; | |
| 80 // Open the same resource file again to make sure each file descriptor | |
| 81 // returned from open_resource has its own file offset. | |
| 82 if (!LoadManifestInternal(&nacl_irt_resource_open, key.str(), content)) | |
| 83 break; | |
| 84 } | |
| 85 } | |
| 86 | |
| 87 void PostReply(void* user_data, int32_t status) { | |
| 88 if (!g_last_error.empty()) | |
| 89 g_instance->PostMessage(g_last_error.c_str()); | |
| 90 else | |
| 91 g_instance->PostMessage("hello"); | |
|
Mark Seaborn
2014/12/08 23:27:14
Maybe change "hello" to "Test passed" now that the
Yusuke Sato
2014/12/09 03:45:54
Done.
| |
| 92 } | |
| 93 | |
| 94 void* RunTestsOnBackgroundThread(void* thread_id) { | |
| 95 LoadManifest(); | |
| 96 pp::Module::Get()->core()->CallOnMainThread( | |
| 97 0, pp::CompletionCallback(&PostReply, NULL)); | |
| 98 return NULL; | |
| 99 } | |
| 100 | |
| 11 class MyInstance : public pp::Instance { | 101 class MyInstance : public pp::Instance { |
| 12 public: | 102 public: |
| 13 explicit MyInstance(PP_Instance instance) : pp::Instance(instance) { } | 103 explicit MyInstance(PP_Instance instance) : pp::Instance(instance) { |
| 104 g_instance = this; | |
| 105 } | |
| 14 virtual ~MyInstance() { } | 106 virtual ~MyInstance() { } |
| 15 | 107 |
| 16 virtual bool Init(uint32_t argc, const char* argn[], const char* argv[]) { | 108 virtual bool Init(uint32_t argc, const char* argn[], const char* argv[]) { |
| 17 PostMessage("hello"); | 109 pthread_t thread; |
| 110 // irt_open_resource() isn't allowed to be called on the main thread once | |
| 111 // Pepper starts, so the test must happen on a background thread. | |
| 112 if (pthread_create(&thread, NULL, &RunTestsOnBackgroundThread, NULL)) { | |
| 113 g_last_error = "pthread_create failed"; | |
| 114 PostReply(NULL, 0); | |
| 115 } else { | |
| 116 pthread_detach(thread); | |
|
Mark Seaborn
2014/12/08 23:27:14
Nit: check return value (e.g. with CHECK)
Yusuke Sato
2014/12/09 03:45:54
Done.
| |
| 117 } | |
| 18 return true; | 118 return true; |
| 19 } | 119 } |
| 20 }; | 120 }; |
| 21 | 121 |
| 22 class MyModule : public pp::Module { | 122 class MyModule : public pp::Module { |
| 23 public: | 123 public: |
| 24 MyModule() : pp::Module() { } | 124 MyModule() : pp::Module() { } |
| 25 virtual ~MyModule() { } | 125 virtual ~MyModule() { } |
| 26 | 126 |
| 27 virtual pp::Instance* CreateInstance(PP_Instance instance) { | 127 virtual pp::Instance* CreateInstance(PP_Instance instance) { |
| 28 return new MyInstance(instance); | 128 return new MyInstance(instance); |
| 29 } | 129 } |
| 30 }; | 130 }; |
| 31 | 131 |
| 32 } // namespace | 132 } // namespace |
| 33 | 133 |
| 34 namespace pp { | 134 namespace pp { |
| 35 | 135 |
| 36 Module* CreateModule() { | 136 Module* CreateModule() { |
| 37 return new MyModule(); | 137 return new MyModule(); |
| 38 } | 138 } |
| 39 | 139 |
| 40 } // namespace pp | 140 } // namespace pp |
| OLD | NEW |