Home | History | Annotate | Download | only in nacl
      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