summaryrefslogtreecommitdiffstats
path: root/chrome/browser/nacl_host/nacl_validation_cache_unittest.cc
diff options
context:
space:
mode:
authorncbray@chromium.org <ncbray@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-05-26 04:30:12 +0000
committerncbray@chromium.org <ncbray@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-05-26 04:30:12 +0000
commit8c67083771dd35498e832fa241aa3adb815b47e9 (patch)
treeb23112e2d07565e48e46c8a5e46e1ad14c539ff7 /chrome/browser/nacl_host/nacl_validation_cache_unittest.cc
parentb74b4885d8268a943bb9498abbe1d4a288d97f70 (diff)
downloadchromium_src-8c67083771dd35498e832fa241aa3adb815b47e9.zip
chromium_src-8c67083771dd35498e832fa241aa3adb815b47e9.tar.gz
chromium_src-8c67083771dd35498e832fa241aa3adb815b47e9.tar.bz2
Persist NaCl's validation cache to disk.
Persisting the cache is straightforward: it is pickled, and the pickle data is sent to the blocking pool to be written to disk. Reading the cache off disk is a little trickier, because it needs to be done before sel_ldr is started in the NaCl process. This is implemented as an asynchronous task that blocks starting sel_ldr, similar to opening the IRT. Functionality to serialize and deserialize the validation cache was also added. To improve testability, features such as cache enabling / disabling and UMA reporting were shifted from NaClValidationCache onto the NaClBrowser singleton. This allowed unit tests to be written for NaClValidationCache. BUG= http://code.google.com/p/nativeclient/issues/detail?id=2515 TEST= Run nexe in browser with NACL_VALIDATION_CACHE=1 Review URL: https://chromiumcodereview.appspot.com/10399053 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@139179 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser/nacl_host/nacl_validation_cache_unittest.cc')
-rw-r--r--chrome/browser/nacl_host/nacl_validation_cache_unittest.cc180
1 files changed, 180 insertions, 0 deletions
diff --git a/chrome/browser/nacl_host/nacl_validation_cache_unittest.cc b/chrome/browser/nacl_host/nacl_validation_cache_unittest.cc
new file mode 100644
index 0000000..42c9653
--- /dev/null
+++ b/chrome/browser/nacl_host/nacl_validation_cache_unittest.cc
@@ -0,0 +1,180 @@
+// Copyright (c) 2012 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 "base/pickle.h"
+#include "chrome/browser/nacl_host/nacl_validation_cache.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace {
+
+const char key1[65] =
+ "0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF";
+const char key2[65] =
+ "a 64-byte string of various junk................................";
+const char sig1[33] = "0123456789ABCDEF0123456789ABCDEF";
+const char sig2[33] = "a 32-byte string of various junk";
+
+class NaClValidationCacheTest : public ::testing::Test {
+ protected:
+ NaClValidationCache cache1;
+ NaClValidationCache cache2;
+
+ void SetUp() {
+ // The compiler chokes if std::string(key1) is passed directly as an arg.
+ std::string key(key1);
+ cache1.SetValidationCacheKey(key);
+ cache2.SetValidationCacheKey(key);
+ }
+
+ bool IsIdentical(const NaClValidationCache& a,
+ const NaClValidationCache& b) const {
+ if (a.GetValidationCacheKey() != b.GetValidationCacheKey())
+ return false;
+ if (a.size() != b.size())
+ return false;
+ return a.GetContents() == b.GetContents();
+ }
+};
+
+TEST_F(NaClValidationCacheTest, Sanity) {
+ ASSERT_EQ(0, (int) cache1.size());
+ ASSERT_FALSE(cache1.QueryKnownToValidate(sig1));
+ ASSERT_FALSE(cache1.QueryKnownToValidate(sig2));
+}
+
+TEST_F(NaClValidationCacheTest, Sig1) {
+ cache1.SetKnownToValidate(sig1);
+ ASSERT_EQ(1, (int) cache1.size());
+ ASSERT_TRUE(cache1.QueryKnownToValidate(sig1));
+ ASSERT_FALSE(cache1.QueryKnownToValidate(sig2));
+}
+
+TEST_F(NaClValidationCacheTest, Sig2) {
+ cache1.SetKnownToValidate(sig2);
+ ASSERT_EQ(1, (int) cache1.size());
+ ASSERT_FALSE(cache1.QueryKnownToValidate(sig1));
+ ASSERT_TRUE(cache1.QueryKnownToValidate(sig2));
+}
+
+TEST_F(NaClValidationCacheTest, SigBoth) {
+ cache1.SetKnownToValidate(sig1);
+ cache1.SetKnownToValidate(sig2);
+ ASSERT_EQ(2, (int) cache1.size());
+ ASSERT_TRUE(cache1.QueryKnownToValidate(sig1));
+ ASSERT_TRUE(cache1.QueryKnownToValidate(sig2));
+}
+
+TEST_F(NaClValidationCacheTest, DoubleSet) {
+ cache1.SetKnownToValidate(sig1);
+ cache1.SetKnownToValidate(sig1);
+ ASSERT_EQ(1, (int) cache1.size());
+ ASSERT_TRUE(cache1.QueryKnownToValidate(sig1));
+}
+
+TEST_F(NaClValidationCacheTest, EmptyIdentical) {
+ ASSERT_TRUE(IsIdentical(cache1, cache2));
+}
+
+TEST_F(NaClValidationCacheTest, DifferentKeysNotIdentical) {
+ std::string key(key2);
+ cache2.SetValidationCacheKey(key);
+ ASSERT_FALSE(IsIdentical(cache1, cache2));
+}
+
+
+TEST_F(NaClValidationCacheTest, DifferentSizesNotIdentical) {
+ cache1.SetKnownToValidate(sig1);
+
+ ASSERT_FALSE(IsIdentical(cache1, cache2));
+}
+
+TEST_F(NaClValidationCacheTest, SameSigsIdentical) {
+ cache1.SetKnownToValidate(sig1);
+
+ cache2.SetKnownToValidate(sig1);
+
+ ASSERT_TRUE(IsIdentical(cache1, cache2));
+}
+
+TEST_F(NaClValidationCacheTest, DifferentSigsNotIdentical) {
+ cache1.SetKnownToValidate(sig1);
+
+ cache2.SetKnownToValidate(sig2);
+
+ ASSERT_FALSE(IsIdentical(cache1, cache2));
+}
+
+TEST_F(NaClValidationCacheTest, InOrderIdentical) {
+ cache1.SetKnownToValidate(sig1);
+ cache1.SetKnownToValidate(sig2);
+
+ cache2.SetKnownToValidate(sig1);
+ cache2.SetKnownToValidate(sig2);
+
+ ASSERT_TRUE(IsIdentical(cache1, cache2));
+}
+
+TEST_F(NaClValidationCacheTest, OutOfOrderNotIdentical) {
+ cache1.SetKnownToValidate(sig1);
+ cache1.SetKnownToValidate(sig2);
+
+ cache2.SetKnownToValidate(sig2);
+ cache2.SetKnownToValidate(sig1);
+
+ ASSERT_FALSE(IsIdentical(cache1, cache2));
+}
+
+TEST_F(NaClValidationCacheTest, SerializeDeserialize) {
+ std::string key(key2);
+ cache1.SetValidationCacheKey(key);
+ cache1.SetKnownToValidate(sig1);
+ cache1.SetKnownToValidate(sig2);
+
+ Pickle pickle;
+ cache1.Serialize(&pickle);
+ ASSERT_TRUE(cache2.Deserialize(&pickle));
+ ASSERT_EQ(2, (int) cache2.size());
+ ASSERT_TRUE(IsIdentical(cache1, cache2));
+}
+
+TEST_F(NaClValidationCacheTest, SerializeDeserializeTruncated) {
+ std::string key(key2);
+ cache1.SetValidationCacheKey(key);
+ cache1.SetKnownToValidate(sig1);
+ cache1.SetKnownToValidate(sig2);
+
+ Pickle pickle;
+ cache1.Serialize(&pickle);
+ Pickle truncated(static_cast<const char*>(pickle.data()), pickle.size()-20);
+ ASSERT_FALSE(cache2.Deserialize(&truncated));
+ ASSERT_EQ(0, (int) cache2.size());
+}
+
+TEST_F(NaClValidationCacheTest, DeserializeBadKey) {
+ std::string key(sig1); // Too short, will cause the deserialization to error.
+ cache1.SetValidationCacheKey(key);
+ cache1.SetKnownToValidate(sig1);
+ cache1.SetKnownToValidate(sig2);
+
+ Pickle pickle;
+ cache1.Serialize(&pickle);
+ ASSERT_FALSE(cache2.Deserialize(&pickle));
+ ASSERT_EQ(0, (int) cache2.size());
+}
+
+TEST_F(NaClValidationCacheTest, DeserializeNothing) {
+ cache1.SetKnownToValidate(sig1);
+ Pickle pickle("", 0);
+ ASSERT_FALSE(cache1.Deserialize(&pickle));
+ ASSERT_EQ(0, (int) cache1.size());
+}
+
+TEST_F(NaClValidationCacheTest, DeserializeJunk) {
+ cache1.SetKnownToValidate(sig1);
+ Pickle pickle(key1, strlen(key1));
+ ASSERT_FALSE(cache1.Deserialize(&pickle));
+ ASSERT_EQ(0, (int) cache1.size());
+}
+
+}