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

Unified Diff: mojo/public/cpp/bindings/tests/validation_unittest.cc

Issue 318123003: Add input data parser for Mojo message validation tests. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: rebase3 Created 6 years, 6 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: mojo/public/cpp/bindings/tests/validation_unittest.cc
diff --git a/mojo/public/cpp/bindings/tests/validation_unittest.cc b/mojo/public/cpp/bindings/tests/validation_unittest.cc
index 4bd1cb594fdb07465790a8522418d1ad8feb19c7..f111091472309c9e0b19aa7faf14f03f908a486c 100644
--- a/mojo/public/cpp/bindings/tests/validation_unittest.cc
+++ b/mojo/public/cpp/bindings/tests/validation_unittest.cc
@@ -11,6 +11,7 @@
#include "mojo/public/cpp/bindings/lib/message_header_validator.h"
#include "mojo/public/cpp/bindings/lib/validation_errors.h"
+#include "mojo/public/cpp/bindings/tests/validation_test_input_parser.h"
#include "mojo/public/cpp/test_support/test_support.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -18,10 +19,35 @@ namespace mojo {
namespace test {
namespace {
-std::string ValidationErrorToResultString(internal::ValidationError error) {
- std::string result = internal::ValidationErrorToString(error);
- result.push_back('\n');
- return result;
+template <typename T>
+void Append(std::vector<uint8_t>* data_vector, T data) {
+ size_t pos = data_vector->size();
+ data_vector->resize(pos + sizeof(T));
+ memcpy(&(*data_vector)[pos], &data, sizeof(T));
+}
+
+bool TestInputParser(const std::string& input,
+ bool expected_result,
+ const std::vector<uint8_t>& expected_parsed_input) {
+ std::vector<uint8_t> parsed_input;
+ std::string error_message;
+
+ bool result = ParseValidationTestInput(input, &parsed_input, &error_message);
+ if (expected_result) {
+ if (result && error_message.empty() &&
+ expected_parsed_input == parsed_input) {
+ return true;
+ }
+
+ // Compare with an empty string instead of checking |error_message.empty()|,
+ // so that the message will be printed out if the two are not equal.
+ EXPECT_EQ(std::string(), error_message);
+ EXPECT_EQ(expected_parsed_input, parsed_input);
+ return false;
+ }
+
+ EXPECT_FALSE(error_message.empty());
+ return !result && !error_message.empty();
}
std::vector<std::string> GetMatchingTests(const std::vector<std::string>& names,
@@ -37,44 +63,55 @@ std::vector<std::string> GetMatchingTests(const std::vector<std::string>& names,
return tests;
}
-bool ReadDataFile(const std::string& path, std::vector<uint8_t>* result) {
+bool ReadFile(const std::string& path, std::string* result) {
FILE* fp = OpenSourceRootRelativeFile(path.c_str());
if (!fp) {
ADD_FAILURE() << "File not found: " << path;
return false;
}
- for (;;) {
- unsigned int value;
- int rv = fscanf(fp, "%x", &value);
- if (rv != 1)
- break;
- result->push_back(static_cast<uint8_t>(value & 0xFF));
- }
- bool error = ferror(fp);
- fclose(fp);
- return !error;
-}
-
-bool ReadResultFile(const std::string& path, std::string* result) {
- FILE* fp = OpenSourceRootRelativeFile(path.c_str());
- if (!fp)
- return false;
fseek(fp, 0, SEEK_END);
size_t size = static_cast<size_t>(ftell(fp));
if (size == 0) {
- // Result files should never be empty.
+ result->clear();
fclose(fp);
- return false;
+ return true;
}
fseek(fp, 0, SEEK_SET);
result->resize(size);
size_t size_read = fread(&result->at(0), 1, size, fp);
fclose(fp);
- if (size != size_read)
+ return size == size_read;
+}
+
+bool ReadAndParseDataFile(const std::string& path, std::vector<uint8_t>* data) {
+ std::string input;
+ if (!ReadFile(path, &input))
+ return false;
+
+ std::string error_message;
+ if (!ParseValidationTestInput(input, data, &error_message)) {
+ ADD_FAILURE() << error_message;
return false;
+ }
+
+ return true;
+}
+
+bool ReadResultFile(const std::string& path, std::string* result) {
+ if (!ReadFile(path, result))
+ return false;
+
// Result files are new-line delimited text files. Remove any CRs.
result->erase(std::remove(result->begin(), result->end(), '\r'),
result->end());
+
+ // Remove trailing LFs.
+ size_t pos = result->find_last_not_of('\n');
+ if (pos == std::string::npos)
+ result->clear();
+ else
+ result->resize(pos + 1);
+
return true;
}
@@ -84,7 +121,7 @@ std::string GetPath(const std::string& root, const std::string& suffix) {
void RunValidationTest(const std::string& root, std::string (*func)(Message*)) {
std::vector<uint8_t> data;
- ASSERT_TRUE(ReadDataFile(GetPath(root, ".data"), &data));
+ ASSERT_TRUE(ReadAndParseDataFile(GetPath(root, ".data"), &data));
std::string expected;
ASSERT_TRUE(ReadResultFile(GetPath(root, ".expected"), &expected));
@@ -112,17 +149,111 @@ std::string DumpMessageHeader(Message* message) {
bool rv = validator.Accept(message);
if (!rv) {
EXPECT_NE(internal::VALIDATION_ERROR_NONE, observer.last_error());
- return ValidationErrorToResultString(observer.last_error());
+ return internal::ValidationErrorToString(observer.last_error());
}
std::ostringstream os;
os << "num_bytes: " << message->header()->num_bytes << "\n"
<< "num_fields: " << message->header()->num_fields << "\n"
<< "name: " << message->header()->name << "\n"
- << "flags: " << message->header()->flags << "\n";
+ << "flags: " << message->header()->flags;
return os.str();
}
+TEST(ValidationTest, InputParser) {
+ {
+ // The parser, as well as Append() defined above, assumes that this code is
+ // running on a little-endian platform. Test whether that is true.
+ uint16_t x = 1;
+ ASSERT_EQ(1, *(reinterpret_cast<char*>(&x)));
+ }
+ {
+ // Test empty input.
+ std::string input;
+ std::vector<uint8_t> expected;
+
+ EXPECT_TRUE(TestInputParser(input, true, expected));
+ }
+ {
+ // Test input that only consists of comments and whitespaces.
+ std::string input = " \t // hello world \n\r \t// the answer is 42 ";
+ std::vector<uint8_t> expected;
+
+ EXPECT_TRUE(TestInputParser(input, true, expected));
+ }
+ {
+ std::string input = "[u1]0x10// hello world !! \n\r \t [u2]65535 \n"
+ "[u4]65536 [u8]0xFFFFFFFFFFFFFFFF 0 0Xff";
+ std::vector<uint8_t> expected;
+ Append(&expected, static_cast<uint8_t>(0x10));
+ Append(&expected, static_cast<uint16_t>(65535));
+ Append(&expected, static_cast<uint32_t>(65536));
+ Append(&expected, static_cast<uint64_t>(0xffffffffffffffff));
+ Append(&expected, static_cast<uint8_t>(0));
+ Append(&expected, static_cast<uint8_t>(0xff));
+
+ EXPECT_TRUE(TestInputParser(input, true, expected));
+ }
+ {
+ std::string input = "[s8]-0x800 [s1]-128\t[s2]+0 [s4]-40";
+ std::vector<uint8_t> expected;
+ Append(&expected, -static_cast<int64_t>(0x800));
+ Append(&expected, static_cast<int8_t>(-128));
+ Append(&expected, static_cast<int16_t>(0));
+ Append(&expected, static_cast<int32_t>(-40));
+
+ EXPECT_TRUE(TestInputParser(input, true, expected));
+ }
+ {
+ std::string input = "[b]00001011 [b]10000000 // hello world\r [b]00000000";
+ std::vector<uint8_t> expected;
+ Append(&expected, static_cast<uint8_t>(11));
+ Append(&expected, static_cast<uint8_t>(128));
+ Append(&expected, static_cast<uint8_t>(0));
+
+ EXPECT_TRUE(TestInputParser(input, true, expected));
+ }
+ {
+ std::string input = "[f]+.3e9 [d]-10.03";
+ std::vector<uint8_t> expected;
+ Append(&expected, +.3e9f);
+ Append(&expected, -10.03);
+
+ EXPECT_TRUE(TestInputParser(input, true, expected));
+ }
+ {
+ std::string input = "[dist4]foo 0 [dist8]bar 0 [anchr]foo [anchr]bar";
+ std::vector<uint8_t> expected;
+ Append(&expected, static_cast<uint32_t>(14));
+ Append(&expected, static_cast<uint8_t>(0));
+ Append(&expected, static_cast<uint64_t>(9));
+ Append(&expected, static_cast<uint8_t>(0));
+
+ EXPECT_TRUE(TestInputParser(input, true, expected));
+ }
+
+ // Test some failure cases.
+ {
+ const char* error_inputs[] = {
+ "/ hello world",
+ "[u1]x",
+ "[u1]0x100",
+ "[s2]-0x8001",
+ "[b]1",
+ "[b]1111111k",
+ "[dist4]unmatched",
+ "[anchr]hello [dist8]hello",
+ NULL
+ };
+
+ for (size_t i = 0; error_inputs[i]; ++i) {
+ std::vector<uint8_t> expected;
+ if (!TestInputParser(error_inputs[i], false, expected))
+ ADD_FAILURE() << "Unexpected test result for: " << error_inputs[i];
+ }
+ }
+}
+
TEST(ValidationTest, TestAll) {
std::vector<std::string> names =
EnumerateSourceRootRelativeDirectory(GetPath("", ""));

Powered by Google App Engine
This is Rietveld 408576698