From 1376f3849aef06c5a5a86491552cc272c94303e1 Mon Sep 17 00:00:00 2001 From: Justin Viiret Date: Wed, 1 Mar 2017 16:07:28 +1100 Subject: [PATCH] serialize: parameterize on pattern as well --- unit/hyperscan/serialize.cpp | 93 ++++++++++++++++++++---------------- unit/hyperscan/test_util.cpp | 9 +++- unit/hyperscan/test_util.h | 27 +++++++---- 3 files changed, 76 insertions(+), 53 deletions(-) diff --git a/unit/hyperscan/serialize.cpp b/unit/hyperscan/serialize.cpp index 5f668ffd..4248fa91 100644 --- a/unit/hyperscan/serialize.cpp +++ b/unit/hyperscan/serialize.cpp @@ -45,46 +45,64 @@ namespace { using namespace std; using namespace testing; -static constexpr unsigned validModes[] = { - HS_MODE_STREAM, +static const unsigned validModes[] = { HS_MODE_NOSTREAM, + HS_MODE_STREAM | HS_MODE_SOM_HORIZON_LARGE, HS_MODE_VECTORED }; -class Serializep : public TestWithParam { +static const pattern testPatterns[] = { + pattern("hatstand.*teakettle.*badgerbrush", HS_FLAG_CASELESS, 1000), + pattern("hatstand.*teakettle.*badgerbrush", HS_FLAG_DOTALL, 1001), + pattern("hatstand|teakettle|badgerbrush", 0, 1002), + pattern("^hatstand|teakettle|badgerbrush$", 0, 1003), + pattern("foobar.{10,1000}xyzzy", HS_FLAG_DOTALL, 1004), + pattern("foobar.{2,501}roobar", 0, 1005), + pattern("abc.*def.*ghi", HS_FLAG_SOM_LEFTMOST, 1006), + pattern("(\\p{L}){4}", HS_FLAG_UTF8|HS_FLAG_UCP, 1007), + pattern("\\.(exe|pdf|gif|jpg|png|wav|riff|mp4)\\z", 0, 1008) }; +class SerializeP : public TestWithParam> {}; + +static +const char *getModeString(unsigned mode) { + if (mode & HS_MODE_STREAM) { + return "STREAM"; + } + if (mode & HS_MODE_BLOCK) { + return "BLOCK"; + } + if (mode & HS_MODE_VECTORED) { + return "VECTORED"; + } + return "UNKNOWN"; +} + // Check that we can deserialize from a char array at any alignment and the info // is consistent -TEST_P(Serializep, DeserializeFromAnyAlignment) { - const unsigned mode = GetParam(); +TEST_P(SerializeP, DeserializeFromAnyAlignment) { + const unsigned mode = get<0>(GetParam()); + const pattern &pat = get<1>(GetParam()); SCOPED_TRACE(mode); + SCOPED_TRACE(pat); hs_error_t err; - hs_database_t *db = buildDB("hatstand.*teakettle.*badgerbrush", - HS_FLAG_CASELESS, 1000, mode); + hs_database_t *db = buildDB(pat, mode); ASSERT_TRUE(db != nullptr) << "database build failed."; char *original_info = nullptr; err = hs_database_info(db, &original_info); ASSERT_EQ(HS_SUCCESS, err); - const char *mode_string = nullptr; - switch (mode) { - case HS_MODE_STREAM: - mode_string = "STREAM"; - break; - case HS_MODE_NOSTREAM: - mode_string = "BLOCK"; - break; - case HS_MODE_VECTORED: - mode_string = "VECTORED"; - break; - } + const char *mode_string = getModeString(mode); - ASSERT_NE(nullptr, original_info) << "hs_serialized_database_info returned null."; + ASSERT_NE(nullptr, original_info) + << "hs_serialized_database_info returned null."; ASSERT_STREQ("Version:", string(original_info).substr(0, 8).c_str()); - ASSERT_TRUE(strstr(original_info, mode_string) != nullptr); + ASSERT_TRUE(strstr(original_info, mode_string) != nullptr) + << "Original info \"" << original_info + << "\" does not contain " << mode_string; char *bytes = nullptr; size_t length = 0; @@ -138,35 +156,28 @@ TEST_P(Serializep, DeserializeFromAnyAlignment) { // Check that we can deserialize_at from a char array at any alignment and the // info is consistent -TEST_P(Serializep, DeserializeAtFromAnyAlignment) { - const unsigned mode = GetParam(); +TEST_P(SerializeP, DeserializeAtFromAnyAlignment) { + const unsigned mode = get<0>(GetParam()); + const pattern &pat = get<1>(GetParam()); SCOPED_TRACE(mode); + SCOPED_TRACE(pat); hs_error_t err; - hs_database_t *db = buildDB("hatstand.*teakettle.*badgerbrush", - HS_FLAG_CASELESS, 1000, mode); + hs_database_t *db = buildDB(pat, mode); ASSERT_TRUE(db != nullptr) << "database build failed."; char *original_info; err = hs_database_info(db, &original_info); ASSERT_EQ(HS_SUCCESS, err); - const char *mode_string = nullptr; - switch (mode) { - case HS_MODE_STREAM: - mode_string = "STREAM"; - break; - case HS_MODE_NOSTREAM: - mode_string = "BLOCK"; - break; - case HS_MODE_VECTORED: - mode_string = "VECTORED"; - break; - } + const char *mode_string = getModeString(mode); - ASSERT_NE(nullptr, original_info) << "hs_serialized_database_info returned null."; + ASSERT_NE(nullptr, original_info) + << "hs_serialized_database_info returned null."; ASSERT_STREQ("Version:", string(original_info).substr(0, 8).c_str()); - ASSERT_TRUE(strstr(original_info, mode_string) != nullptr); + ASSERT_TRUE(strstr(original_info, mode_string) != nullptr) + << "Original info \"" << original_info + << "\" does not contain " << mode_string; char *bytes = nullptr; size_t length = 0; @@ -226,8 +237,8 @@ TEST_P(Serializep, DeserializeAtFromAnyAlignment) { delete[] mem; } -INSTANTIATE_TEST_CASE_P(Serialize, Serializep, - ValuesIn(validModes)); +INSTANTIATE_TEST_CASE_P(Serialize, SerializeP, + Combine(ValuesIn(validModes), ValuesIn(testPatterns))); // Attempt to reproduce the scenario in UE-1946. TEST(Serialize, CrossCompileSom) { diff --git a/unit/hyperscan/test_util.cpp b/unit/hyperscan/test_util.cpp index 345b05d0..f3f6e610 100644 --- a/unit/hyperscan/test_util.cpp +++ b/unit/hyperscan/test_util.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, Intel Corporation + * Copyright (c) 2015-2017, Intel Corporation * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -48,10 +48,15 @@ int record_cb(unsigned id, unsigned long long, unsigned long long to, return (int)c->halt; } -std::ostream &operator<< (std::ostream &o, const MatchRecord &m) { +std::ostream &operator<<(std::ostream &o, const MatchRecord &m) { return o << "[" << m.to << ", " << m.id << "]"; } +std::ostream &operator<<(std::ostream &o, const pattern &p) { + return o << "[" << "expr=\"" << p.expression << "\", flags=" << p.flags + << ", id=" << p.id << "]"; +} + hs_database_t *buildDB(const vector &patterns, unsigned int mode, hs_platform_info *plat) { vector expressions; diff --git a/unit/hyperscan/test_util.h b/unit/hyperscan/test_util.h index fad6137c..9b963529 100644 --- a/unit/hyperscan/test_util.h +++ b/unit/hyperscan/test_util.h @@ -53,7 +53,7 @@ struct MatchRecord { int id; }; -std::ostream &operator<< (std::ostream &o, const MatchRecord &m); +std::ostream &operator<<(std::ostream &o, const MatchRecord &m); struct CallBackContext { CallBackContext() : halt(false) {} @@ -79,22 +79,29 @@ int dummy_cb(unsigned, unsigned long long, unsigned long long, unsigned, struct pattern { std::string expression; - unsigned int flags; - unsigned int id; + unsigned int flags = 0; + unsigned int id = 0; hs_expr_ext ext; - pattern(const std::string &expression_in, unsigned int flags_in = 0, - unsigned int id_in = 0) : expression(expression_in), - flags(flags_in), id(id_in) { + // We need a default constructor for combining in parameterised tests. + pattern() { memset(&ext, 0, sizeof(ext)); } - pattern(const std::string &expression_in, unsigned int flags_in, - unsigned int id_in, const hs_expr_ext &ext_in) : - expression(expression_in), flags(flags_in), id(id_in), - ext(ext_in) { } + explicit pattern(std::string expression_in, + unsigned int flags_in = 0, unsigned int id_in = 0) + : expression(std::move(expression_in)), flags(flags_in), id(id_in) { + memset(&ext, 0, sizeof(ext)); + } + + pattern(std::string expression_in, unsigned int flags_in, + unsigned int id_in, hs_expr_ext ext_in) + : expression(std::move(expression_in)), flags(flags_in), id(id_in), + ext(std::move(ext_in)) {} }; +std::ostream &operator<<(std::ostream &o, const pattern &p); + hs_database_t *buildDB(const std::vector &patterns, unsigned int mode, hs_platform_info *plat = nullptr); hs_database_t *buildDB(const pattern &pat, unsigned int mode);