1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #include "base/test/histogram_tester.h" 6 #include "chrome/test/nacl/nacl_browsertest_util.h" 7 #include "components/nacl/browser/nacl_browser.h" 8 #include "content/public/test/browser_test_utils.h" 9 #include "native_client/src/trusted/service_runtime/nacl_error_code.h" 10 #include "ppapi/c/private/ppb_nacl_private.h" 11 12 namespace { 13 14 NACL_BROWSER_TEST_F(NaClBrowserTest, SuccessfulLoadUMA, { 15 base::HistogramTester histograms; 16 // Load a NaCl module to generate UMA data. 17 RunLoadTest(FILE_PATH_LITERAL("nacl_load_test.html")); 18 19 // Make sure histograms from child processes have been accumulated in the 20 // browser brocess. 21 content::FetchHistogramsFromChildProcesses(); 22 23 // Did the plugin report success? 24 histograms.ExpectUniqueSample("NaCl.LoadStatus.Plugin", 25 PP_NACL_ERROR_LOAD_SUCCESS, 1); 26 27 // Did the sel_ldr report success? 28 histograms.ExpectUniqueSample("NaCl.LoadStatus.SelLdr", 29 LOAD_OK, 1); 30 31 // Check validation cache usage: 32 if (IsAPnaclTest()) { 33 // Should have received 3 validation queries: 34 // - One for IRT for actual application 35 // - Two for two translator nexes 36 // The translators don't currently use the IRT, so there is no IRT cache 37 // query for those two loads. The PNaCl main nexe comes from a 38 // delete-on-close temp file, so it doesn't have a stable identity 39 // for validation caching. All three query results should be misses. 40 histograms.ExpectUniqueSample("NaCl.ValidationCache.Query", 41 nacl::NaClBrowser::CACHE_MISS, 3); 42 // Should have received a cache setting afterwards for IRT and translators. 43 histograms.ExpectUniqueSample("NaCl.ValidationCache.Set", 44 nacl::NaClBrowser::CACHE_HIT, 3); 45 } else { 46 // For the open-web, only the IRT is considered a "safe" and 47 // identity-cachable file. The nexes and .so files are not. 48 // Should have one cache query for the IRT. 49 histograms.ExpectUniqueSample("NaCl.ValidationCache.Query", 50 nacl::NaClBrowser::CACHE_MISS, 1); 51 // Should have received a cache setting afterwards for IRT and translators. 52 histograms.ExpectUniqueSample("NaCl.ValidationCache.Set", 53 nacl::NaClBrowser::CACHE_HIT, 1); 54 } 55 56 // Make sure we have other important histograms. 57 if (!IsAPnaclTest()) { 58 histograms.ExpectTotalCount("NaCl.Perf.StartupTime.LoadModule", 1); 59 histograms.ExpectTotalCount("NaCl.Perf.StartupTime.Total", 1); 60 histograms.ExpectTotalCount("NaCl.Perf.Size.Manifest", 1); 61 histograms.ExpectTotalCount("NaCl.Perf.Size.Nexe", 1); 62 } else { 63 histograms.ExpectTotalCount("NaCl.Options.PNaCl.OptLevel", 1); 64 histograms.ExpectTotalCount("NaCl.Perf.Size.Manifest", 1); 65 histograms.ExpectTotalCount("NaCl.Perf.Size.Pexe", 1); 66 histograms.ExpectTotalCount("NaCl.Perf.Size.PNaClTranslatedNexe", 1); 67 histograms.ExpectTotalCount("NaCl.Perf.Size.PexeNexeSizePct", 1); 68 histograms.ExpectTotalCount("NaCl.Perf.PNaClLoadTime.LoadCompiler", 1); 69 histograms.ExpectTotalCount("NaCl.Perf.PNaClLoadTime.LoadLinker", 1); 70 histograms.ExpectTotalCount("NaCl.Perf.PNaClLoadTime.CompileTime", 1); 71 histograms.ExpectTotalCount("NaCl.Perf.PNaClLoadTime.CompileKBPerSec", 1); 72 histograms.ExpectTotalCount("NaCl.Perf.PNaClLoadTime.LinkTime", 1); 73 histograms.ExpectTotalCount( 74 "NaCl.Perf.PNaClLoadTime.PctCompiledWhenFullyDownloaded", 1); 75 histograms.ExpectTotalCount("NaCl.Perf.PNaClLoadTime.TotalUncachedTime", 1); 76 histograms.ExpectTotalCount( 77 "NaCl.Perf.PNaClLoadTime.TotalUncachedKBPerSec", 1); 78 histograms.ExpectTotalCount("NaCl.Perf.PNaClCache.IsHit", 1); 79 } 80 }) 81 82 class NaClBrowserTestNewlibVcacheExtension: 83 public NaClBrowserTestNewlibExtension { 84 public: 85 virtual base::FilePath::StringType Variant() OVERRIDE { 86 return FILE_PATH_LITERAL("extension_vcache_test/newlib"); 87 } 88 }; 89 90 IN_PROC_BROWSER_TEST_F(NaClBrowserTestNewlibVcacheExtension, 91 ValidationCacheOfMainNexe) { 92 base::HistogramTester histograms; 93 // Hardcoded extension AppID that corresponds to the hardcoded 94 // public key in the manifest.json file. We need to load the extension 95 // nexe from the same origin, so we can't just try to load the extension 96 // nexe as a mime-type handler from a non-extension URL. 97 base::FilePath::StringType full_url = 98 FILE_PATH_LITERAL("chrome-extension://cbcdidchbppangcjoddlpdjlenngjldk/") 99 FILE_PATH_LITERAL("extension_validation_cache.html"); 100 RunNaClIntegrationTest(full_url, true); 101 102 // Make sure histograms from child processes have been accumulated in the 103 // browser brocess. 104 content::FetchHistogramsFromChildProcesses(); 105 // Should have received 2 validation queries (one for IRT and one for NEXE), 106 // and responded with a miss. 107 histograms.ExpectBucketCount("NaCl.ValidationCache.Query", 108 nacl::NaClBrowser::CACHE_MISS, 2); 109 // TOTAL should then be 2 queries so far. 110 histograms.ExpectTotalCount("NaCl.ValidationCache.Query", 2); 111 // Should have received a cache setting afterwards for IRT and nexe. 112 histograms.ExpectBucketCount("NaCl.ValidationCache.Set", 113 nacl::NaClBrowser::CACHE_HIT, 2); 114 115 // Load it again to hit the cache. 116 RunNaClIntegrationTest(full_url, true); 117 content::FetchHistogramsFromChildProcesses(); 118 // Should have received 2 more validation queries later (IRT and NEXE), 119 // and responded with a hit. 120 histograms.ExpectBucketCount("NaCl.ValidationCache.Query", 121 nacl::NaClBrowser::CACHE_HIT, 2); 122 // TOTAL should then be 4 queries now. 123 histograms.ExpectTotalCount("NaCl.ValidationCache.Query", 4); 124 // Still only 2 settings. 125 histograms.ExpectTotalCount("NaCl.ValidationCache.Set", 2); 126 } 127 128 class NaClBrowserTestGLibcVcacheExtension: 129 public NaClBrowserTestGLibcExtension { 130 public: 131 virtual base::FilePath::StringType Variant() OVERRIDE { 132 return FILE_PATH_LITERAL("extension_vcache_test/glibc"); 133 } 134 }; 135 136 IN_PROC_BROWSER_TEST_F(NaClBrowserTestGLibcVcacheExtension, 137 ValidationCacheOfMainNexe) { 138 // Make sure histograms from child processes have been accumulated in the 139 // browser process. 140 base::HistogramTester histograms; 141 // Hardcoded extension AppID that corresponds to the hardcoded 142 // public key in the manifest.json file. We need to load the extension 143 // nexe from the same origin, so we can't just try to load the extension 144 // nexe as a mime-type handler from a non-extension URL. 145 base::FilePath::StringType full_url = 146 FILE_PATH_LITERAL("chrome-extension://cbcdidchbppangcjoddlpdjlenngjldk/") 147 FILE_PATH_LITERAL("extension_validation_cache.html"); 148 RunNaClIntegrationTest(full_url, true); 149 150 // Should have received 9 validation queries, which respond with misses: 151 // - the IRT 152 // - ld.so (the initial nexe) 153 // - main.nexe 154 // - libppapi_cpp.so 155 // - libpthread.so.9b15f6a6 156 // - libstdc++.so.6 157 // - libgcc_s.so.1 158 // - libc.so.9b15f6a6 159 // - libm.so.9b15f6a6 160 histograms.ExpectBucketCount("NaCl.ValidationCache.Query", 161 nacl::NaClBrowser::CACHE_MISS, 9); 162 // TOTAL should then be 9 queries so far. 163 histograms.ExpectTotalCount("NaCl.ValidationCache.Query", 9); 164 // Should have received a cache setting afterwards for IRT and nexe. 165 histograms.ExpectBucketCount("NaCl.ValidationCache.Set", 166 nacl::NaClBrowser::CACHE_HIT, 9); 167 168 // Load it again to hit the cache. 169 RunNaClIntegrationTest(full_url, true); 170 // Should have received 9 more validation queries and responded with hits. 171 histograms.ExpectBucketCount("NaCl.ValidationCache.Query", 172 nacl::NaClBrowser::CACHE_HIT, 9); 173 histograms.ExpectTotalCount("NaCl.ValidationCache.Query", 18); 174 histograms.ExpectTotalCount("NaCl.ValidationCache.Set", 9); 175 } 176 177 // Test that validation for the 2 PNaCl translator nexes can be cached. 178 IN_PROC_BROWSER_TEST_F(NaClBrowserTestPnacl, 179 ValidationCacheOfTranslatorNexes) { 180 base::HistogramTester histograms; 181 // Run a load test w/ one pexe cache identity. 182 RunLoadTest(FILE_PATH_LITERAL("pnacl_options.html?use_nmf=o_0")); 183 184 content::FetchHistogramsFromChildProcesses(); 185 // Should have received 3 validation queries: 186 // - One for IRT for actual application 187 // - Two for two translator nexes 188 // The translators don't currently use the IRT, so there is no IRT cache 189 // query for those two loads. The PNaCl main nexe comes from a 190 // delete-on-close temp file, so it doesn't have a stable identity 191 // for validation caching. All three query results should be misses. 192 histograms.ExpectUniqueSample("NaCl.ValidationCache.Query", 193 nacl::NaClBrowser::CACHE_MISS, 3); 194 // Should have received a cache setting afterwards for IRT and translators. 195 histograms.ExpectUniqueSample("NaCl.ValidationCache.Set", 196 nacl::NaClBrowser::CACHE_HIT, 3); 197 198 // Load the same pexe, but with a different cache identity. 199 // This means that translation will actually be redone, 200 // forcing the translators to be loaded a second time (but now with 201 // cache hits!) 202 RunLoadTest(FILE_PATH_LITERAL("pnacl_options.html?use_nmf=o_2")); 203 204 // Should now have 3 more queries on top of the previous ones. 205 histograms.ExpectTotalCount("NaCl.ValidationCache.Query", 6); 206 // With the 3 extra queries being cache hits. 207 histograms.ExpectBucketCount("NaCl.ValidationCache.Query", 208 nacl::NaClBrowser::CACHE_HIT, 3); 209 // No extra cache settings. 210 histograms.ExpectUniqueSample("NaCl.ValidationCache.Set", 211 nacl::NaClBrowser::CACHE_HIT, 3); 212 } 213 214 215 // TODO(ncbray) convert the rest of nacl_uma.py (currently in the NaCl repo.) 216 // Test validation failures and crashes. 217 218 } // namespace 219