Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(874)

Unified Diff: src/trusted/validator/validation_cache_test.cc

Issue 9535001: Add validation caching interface. (Closed) Base URL: svn://svn.chromium.org/native_client/trunk/src/native_client
Patch Set: Edits Created 8 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: src/trusted/validator/validation_cache_test.cc
diff --git a/src/trusted/validator/validation_cache_test.cc b/src/trusted/validator/validation_cache_test.cc
new file mode 100644
index 0000000000000000000000000000000000000000..8b5f3931640b0c12b3538135e9a8b237cd5afb3e
--- /dev/null
+++ b/src/trusted/validator/validation_cache_test.cc
@@ -0,0 +1,215 @@
+/*
+ * Copyright (c) 2012 The Native Client 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 "gtest/gtest.h"
+
+#include "native_client/src/shared/platform/nacl_log.h"
+#include "native_client/src/trusted/validator/ncvalidate.h"
+#include "native_client/src/trusted/validator/validation_cache.h"
+
+#if NACL_WINDOWS
+# define UNREFERENCED_PARAMETER(P) (P)
Mark Seaborn 2012/03/01 00:26:20 Why is this here? Use src/include/nacl_compiler_a
Nick Bray (chromium) 2012/03/01 01:25:16 Done.
+#else
+# define UNREFERENCED_PARAMETER(P) do { (void) P; } while (0)
+#endif
+
+const char nop[33] =
+ "\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"
+ "\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90";
+
+// ret
+const char ret[33] =
+ "\xc3\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"
+ "\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90";
+
+// pblendw $0xc0,%xmm0,%xmm2
+const char sse41[33] =
+ "\x66\x0f\x3a\x0e\xd0\xc0\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"
+ "\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90";
+
+const int code_size = 32;
+
+struct MockContext {
+ /* Sanity check that we're getting the right object. */
+ int marker;
+ int query_result;
+ int set_validates_expected;
+ int query_destroyed;
+};
+
+struct MockQuery {
+ /* Sanity check that we're getting the right object. */
+ int marker;
+ int state;
+ int add_count;
+ MockContext *context;
+};
+
+void *MockCreateQuery(void *context) {
+ MockContext *mcontext = (MockContext *) context;
+ MockQuery *mquery = (MockQuery *) malloc(sizeof(MockQuery));
+ EXPECT_EQ(31, mcontext->marker);
+ mquery->marker = 37;
+ mquery->state = 0;
+ mquery->add_count = 0;
+ mquery->context = mcontext;
+ return mquery;
+}
+
+void MockAddData(void *query, const unsigned char *data, size_t length) {
+ MockQuery *mquery = (MockQuery *) query;
+ ASSERT_EQ(37, mquery->marker);
+ UNREFERENCED_PARAMETER(data);
+ EXPECT_EQ(0, mquery->state);
+ /* Small data is supicious. */
+ EXPECT_LE((size_t) 2, length);
+ mquery->add_count += 1;
+}
+
+int MockDoQuery(void *query) {
+ MockQuery *mquery = (MockQuery *) query;
+ EXPECT_EQ(37, mquery->marker);
+ EXPECT_EQ(0, mquery->state);
+ /* Less than two pieces of data is suspicious. */
+ EXPECT_LE(2, mquery->add_count);
+ mquery->state = 1;
+ return mquery->context->query_result;
+}
+
+void MockSetValidates(void *query) {
+ MockQuery *mquery = (MockQuery *) query;
+ ASSERT_EQ(37, mquery->marker);
+ EXPECT_EQ(1, mquery->state);
+ EXPECT_EQ(1, mquery->context->set_validates_expected);
+ mquery->state = 2;
+}
+
+void MockDestroyQuery(void *query) {
+ MockQuery *mquery = (MockQuery *) query;
+ ASSERT_EQ(37, mquery->marker);
+ EXPECT_EQ(mquery->context->set_validates_expected ? 2 : 1, mquery->state);
+ mquery->context->query_destroyed = 1;
+ free(mquery);
+}
+
+class ValidationCachingInterfaceTests : public ::testing::Test {
+ protected:
+ MockContext context;
+ NaClValidationCache cache;
+ NaClCPUFeatures cpu_features;
+ int bundle_size;
+
+ unsigned char code_buffer[32];
+
+ void SetUp() {
+ context.marker = 31;
+ context.query_result = 1;
+ context.set_validates_expected = 0;
+ context.query_destroyed = 0;
+
+ cache.context = &context;
+ cache.CreateQuery = MockCreateQuery;
+ cache.AddData = MockAddData;
+ cache.DoQuery = MockDoQuery;
+ cache.SetValidates = MockSetValidates;
+ cache.DestroyQuery = MockDestroyQuery;
+
+ NaClSetAllCPUFeatures(&cpu_features);
+
+ bundle_size = 32;
Mark Seaborn 2012/03/01 00:26:20 Rename the global code_size to bundle_size?
Nick Bray (chromium) 2012/03/01 01:25:16 bundle_size and code_size only happen to be the sa
+
+ memset(code_buffer, 0x90, 32);
+ }
+
+ NaClValidationStatus Validate() {
+ return NACL_SUBARCH_NAME(ApplyValidator,
+ NACL_TARGET_ARCH,
+ NACL_TARGET_SUBARCH)(
+ NACL_SB_DEFAULT,
+ NaClApplyCodeValidation,
+ 0, code_buffer, 32,
+ bundle_size, &cpu_features,
+ &cache);
+ }
+};
+
+TEST_F(ValidationCachingInterfaceTests, Sanity) {
+ void *query = cache.CreateQuery(cache.context);
+ cache.AddData(query, 0, 6);
+ cache.AddData(query, 0, 128);
+ EXPECT_EQ(1, cache.DoQuery(query));
+ cache.DestroyQuery(query);
+ EXPECT_EQ(1, context.query_destroyed);
+}
+
+TEST_F(ValidationCachingInterfaceTests, NoCache) {
+ NaClValidationStatus status;
+ status = NACL_SUBARCH_NAME(ApplyValidator,
+ NACL_TARGET_ARCH,
+ NACL_TARGET_SUBARCH)(
+ NACL_SB_DEFAULT,
+ NaClApplyCodeValidation,
+ 0, code_buffer, code_size,
+ bundle_size, &cpu_features,
+ NULL);
+ EXPECT_EQ(NaClValidationSucceeded, status);
+}
+
+TEST_F(ValidationCachingInterfaceTests, CacheHit) {
Mark Seaborn 2012/03/01 00:26:20 You can check cache hit more thoroughly by passing
Nick Bray (chromium) 2012/03/01 01:25:16 Done.
+ NaClValidationStatus status;
+ status = Validate();
+ EXPECT_EQ(NaClValidationSucceeded, status);
+ EXPECT_EQ(1, context.query_destroyed);
+}
+
+TEST_F(ValidationCachingInterfaceTests, CacheMiss) {
+ NaClValidationStatus status;
+ context.query_result = 0;
+ context.set_validates_expected = 1;
+ status = Validate();
+ EXPECT_EQ(NaClValidationSucceeded, status);
+ EXPECT_EQ(1, context.query_destroyed);
+}
+
+TEST_F(ValidationCachingInterfaceTests, SSE4Allowed) {
+ NaClValidationStatus status;
+ memcpy(code_buffer, sse41, 32);
+ context.query_result = 0;
+ context.set_validates_expected = 1;
+ status = Validate();
+ EXPECT_EQ(NaClValidationSucceeded, status);
+ EXPECT_EQ(1, context.query_destroyed);
+}
+
+TEST_F(ValidationCachingInterfaceTests, SSE4Stubout) {
+ NaClValidationStatus status;
+ memcpy(code_buffer, sse41, 32);
+ context.query_result = 0;
+ NaClSetCPUFeature(&cpu_features, NaClCPUFeature_SSE41, 0);
+ status = Validate();
+ EXPECT_EQ(NaClValidationSucceeded, status);
+ EXPECT_EQ(1, context.query_destroyed);
+}
+
+TEST_F(ValidationCachingInterfaceTests, IllegalInst) {
+ NaClValidationStatus status;
+ memcpy(code_buffer, ret, 32);
Mark Seaborn 2012/03/01 00:26:20 32 -> code_size?
Nick Bray (chromium) 2012/03/01 01:25:16 Done.
+ context.query_result = 0;
+ status = Validate();
Mark Seaborn 2012/03/01 00:26:20 This is C++ so you can write NaClValidationStatus
Nick Bray (chromium) 2012/03/01 01:25:16 Done.
+ EXPECT_EQ(NaClValidationFailed, status);
+ EXPECT_EQ(1, context.query_destroyed);
Mark Seaborn 2012/03/01 00:26:20 More conventional is: EXPECT_EQ(context.query_dest
Nick Bray (chromium) 2012/03/01 01:25:16 No. EXPECT_EQ(EXPECTED, ACTUAL);
+}
+
+// Test driver function.
+int main(int argc, char *argv[]) {
+ // The IllegalInst test touches the log mutex deep inside the validator.
+ // This causes an SEH exception to be thrown on Windows if the mutex is not
Mark Seaborn 2012/03/01 00:26:20 Unnecessary detail? Just say: "Initialise the log
Nick Bray (chromium) 2012/03/01 01:25:16 Detail is good in this case, it may provide breadc
+ // initialized.
+ // http://code.google.com/p/nativeclient/issues/detail?id=1696
+ NaClLogModuleInit();
+ testing::InitGoogleTest(&argc, argv);
+ return RUN_ALL_TESTS();
+}

Powered by Google App Engine
This is Rietveld 408576698