aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorXin Li <delphij@google.com>2019-09-04 13:33:47 -0700
committerXin Li <delphij@google.com>2019-09-04 13:33:47 -0700
commitfdee69ef6f6ea333dd7c344cc50185ffd3b1708a (patch)
tree98050401381afa3d32622cd25157ed31dab72790
parent8b2d90441ce22ab647ff046d992508799d093e7b (diff)
parent40244925c5432a16aba68850648506f311050c91 (diff)
downloadsystem-test-harness-fdee69ef6f6ea333dd7c344cc50185ffd3b1708a.tar.gz
DO NOT MERGE - Merge Android 10 into masterndk-sysroot-r21
Bug: 139893257 Change-Id: Id5785b498d8cc341cea8c4f7a69e6cd469fcbae2
-rw-r--r--.checkpatch.conf7
-rw-r--r--.clang-format2
-rw-r--r--BUILD2
-rw-r--r--WORKSPACE7
-rwxr-xr-xscripts/release-tests.sh2
-rw-r--r--src/faceauth_tests.cc454
6 files changed, 469 insertions, 5 deletions
diff --git a/.checkpatch.conf b/.checkpatch.conf
new file mode 100644
index 0000000..2bc17ab
--- /dev/null
+++ b/.checkpatch.conf
@@ -0,0 +1,7 @@
+# Not Linux, so don't expect a Linux tree.
+--no-tree
+
+# Ignore aspects we don't follow here.
+--ignore SPLIT_STRING
+--ignore GIT_COMMIT_ID
+--ignore FILE_PATH_CHANGES
diff --git a/.clang-format b/.clang-format
new file mode 100644
index 0000000..d13eeba
--- /dev/null
+++ b/.clang-format
@@ -0,0 +1,2 @@
+BasedOnStyle: Google
+ColumnLimit: 80
diff --git a/BUILD b/BUILD
index 7aae4d5..caa28a8 100644
--- a/BUILD
+++ b/BUILD
@@ -9,6 +9,7 @@ cc_binary(
name = "runtests",
srcs = [
"src/aes-cmac-tests.cc",
+ "src/faceauth_tests.cc",
"src/gtest_with_gflags_main.cc",
"src/keymaster-import-key-tests.cc",
"src/keymaster-import-wrapped-key-tests.cc",
@@ -29,6 +30,7 @@ cc_binary(
"@com_github_gflags_gflags//:gflags",
"@gtest//:gtest",
"@nugget_core_nugget//:config_chip",
+ "@nugget_core_nugget//:faceauth_common",
"@nugget_host_generic_libnos//:libnos",
"@nugget_host_generic_nugget_proto//:keymaster_client_proto",
"@nugget_host_generic_nugget_proto//:nugget_app_keymaster_keymaster_cc_proto",
diff --git a/WORKSPACE b/WORKSPACE
index c30e236..342cafd 100644
--- a/WORKSPACE
+++ b/WORKSPACE
@@ -4,10 +4,9 @@ load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
http_archive(
name = "gtest",
- url = "https://github.com/google/googletest/archive/release-1.8.0.zip",
- build_file = "@//:BUILD.gtest",
- sha256 = "f3ed3b58511efd272eb074a3a6d6fb79d7c2e6a0e374323d1e6bcbcc1ef141bf",
- strip_prefix = "googletest-release-1.8.0",
+ url = "https://github.com/google/googletest/archive/release-1.8.1.zip",
+ sha256 = "927827c183d01734cc5cfef85e0ff3f5a92ffe6188e0d18e909c5efebf28a0c7",
+ strip_prefix = "googletest-release-1.8.1",
)
http_archive(
diff --git a/scripts/release-tests.sh b/scripts/release-tests.sh
index 9b7378f..24805b6 100755
--- a/scripts/release-tests.sh
+++ b/scripts/release-tests.sh
@@ -19,7 +19,7 @@ function oem_lock_vts_tests() {
}
function keymaster_cts_tests() {
- return 0
+ atest CtsKeystoreTestCases || return 1
}
function keymaster_vts_tests() {
diff --git a/src/faceauth_tests.cc b/src/faceauth_tests.cc
new file mode 100644
index 0000000..32088fa
--- /dev/null
+++ b/src/faceauth_tests.cc
@@ -0,0 +1,454 @@
+
+#include <app_nugget.h>
+#include <nos/NuggetClientInterface.h>
+#include <gtest/gtest.h>
+
+#include <memory>
+
+#include "user/faceauth/include/fa_common.h"
+
+#include "nugget_tools.h"
+#include "util.h"
+
+using std::string;
+using std::vector;
+using std::unique_ptr;
+
+namespace {
+
+class FaceAuthTest: public testing::Test {
+ protected:
+ void SetUp() override;
+
+ static void SetUpTestCase();
+ static void TearDownTestCase();
+
+ static unique_ptr<nos::NuggetClientInterface> client;
+ static unique_ptr<test_harness::TestHarness> uart_printer;
+
+ static const fa_result_t RunTask(const fa_task_t task,
+ const fa_embedding_t* embed = NULL,
+ const fa_token_t* token = NULL);
+ static void Run(const fa_result_t expected, const fa_task_t task,
+ const fa_embedding_t* embed = NULL,
+ const fa_token_t* token = NULL);
+
+ static void LockProfileTest(uint32_t profile1);
+ static void UnlockProfileTest(uint32_t profile1);
+ static bool IsProfileLocked(uint32_t profile1);
+ static void UnockProfileTest(uint32_t profile1);
+ static void FullMatchMismatchTest(uint32_t profile1, uint32_t profile2,
+ uint32_t slot1, uint32_t slot2);
+ static fa_token_t MakeToken(uint32_t profile_id);
+
+ static vector<uint64_t> user_ids;
+};
+
+vector<uint64_t> FaceAuthTest::user_ids;
+
+unique_ptr<nos::NuggetClientInterface> FaceAuthTest::client;
+unique_ptr<test_harness::TestHarness> FaceAuthTest::uart_printer;
+
+void FaceAuthTest::SetUpTestCase() {
+ srand(time(NULL));
+ for (int i = 0; i < MAX_NUM_PROFILES; ++i) {
+ user_ids.push_back(rand());
+ }
+ uart_printer = test_harness::TestHarness::MakeUnique();
+
+ client = nugget_tools::MakeNuggetClient();
+ client->Open();
+ EXPECT_TRUE(client->IsOpen()) << "Unable to connect";
+}
+
+void FaceAuthTest::TearDownTestCase() {
+ client->Close();
+ client = unique_ptr<nos::NuggetClientInterface>();
+
+ uart_printer = nullptr;
+}
+
+uint8_t CalcCrc8(const uint8_t *data, int len)
+{
+ unsigned crc = 0;
+ int i, j;
+
+ for (j = len; j; j--, data++) {
+ crc ^= (*data << 8);
+ for (i = 8; i; i--) {
+ if (crc & 0x8000) {
+ crc ^= (0x1070 << 3);
+ }
+ crc <<= 1;
+ }
+ }
+
+ return (uint8_t)(crc >> 8);
+}
+
+static fa_task_t MakeTask(uint64_t session_id, uint32_t profile_id,
+ uint32_t cmd, uint32_t input_data1 = 0,
+ uint32_t input_data2 = 0,
+ uint32_t version = FACEAUTH_MIN_ABH_VERSION) {
+ fa_task_t task;
+ task.version = version;
+ task.session_id = session_id;
+ task.profile_id = profile_id;
+ task.cmd = cmd;
+ task.input.data.first = input_data1;
+ task.input.data.second = input_data2;
+ task.crc = CalcCrc8(reinterpret_cast<const uint8_t*>(&task),
+ offsetof(struct fa_task_t, crc));
+ return task;
+}
+
+static fa_embedding_t* MakeEmbedding(uint32_t base, uint32_t version = 1) {
+ static fa_embedding_t embed;
+ memset(&embed, base, sizeof(fa_embedding_t));
+ embed.version = version;
+ embed.valid = 0;
+ embed.crc = CalcCrc8(reinterpret_cast<const uint8_t*>(&embed),
+ offsetof(struct fa_embedding_t, crc));
+ return &embed;
+}
+
+static fa_result_t MakeResult(uint64_t session_id, int32_t error,
+ uint32_t output_data1 = 0,
+ uint32_t output_data2 = 0,
+ uint32_t lockout_event = FACEAUTH_LOCKOUT_NOP) {
+ fa_result_t result;
+ memset(&result, 0, sizeof(fa_result_t));
+ result.version = 1;
+ result.session_id = session_id;
+ result.error = error;
+ result.output.data.first = output_data1;
+ result.output.data.second = output_data2;
+ result.lockout_event = lockout_event;
+ result.complete = 1;
+ result.crc = CalcCrc8(reinterpret_cast<const uint8_t*>(&result),
+ offsetof(struct fa_result_t, crc));
+ return result;
+}
+
+fa_token_t FaceAuthTest::MakeToken(uint32_t profile_id) {
+ fa_token_t token;
+ token.user_id = user_ids[profile_id];
+ return token;
+}
+
+vector<uint8_t> Task2Buffer(const fa_task_t task, const fa_embedding_t* embed,
+ const fa_token_t* token) {
+ vector<uint8_t> buffer;
+ for (size_t i = 0; i < sizeof(fa_task_t); ++i) {
+ buffer.push_back(*(reinterpret_cast<const uint8_t*>(&task) + i));
+ }
+ for (size_t i = 0; i < sizeof(fa_embedding_t); ++i) {
+ if (embed)
+ buffer.push_back(*(reinterpret_cast<const uint8_t*>(embed) + i));
+ else
+ buffer.push_back(0);
+ }
+ for (size_t i = 0; i < sizeof(fa_token_t); ++i) {
+ if (token)
+ buffer.push_back(*(reinterpret_cast<const uint8_t*>(token) + i));
+ else
+ buffer.push_back(0);
+ }
+
+ return buffer;
+}
+
+static const fa_result_t Buffer2Result(const vector<uint8_t>& buffer)
+{
+ const fa_result_t result = *(reinterpret_cast<const fa_result_t*>(
+ buffer.data()));
+ return result;
+}
+
+static void EXPECT_RESULT_EQ(const fa_result_t& r1, const fa_result_t& r2)
+{
+ EXPECT_EQ(r1.version, r2.version);
+ EXPECT_EQ(r1.session_id, r2.session_id);
+ EXPECT_EQ(r1.error, r2.error);
+ EXPECT_EQ(r1.output.data.first, r2.output.data.first);
+ EXPECT_EQ(r1.output.data.second, r2.output.data.second);
+ EXPECT_EQ(r1.lockout_event, r2.lockout_event);
+ EXPECT_EQ(r1.complete, r2.complete);
+ EXPECT_EQ(r1.crc, r2.crc);
+}
+
+const fa_result_t FaceAuthTest::RunTask(const fa_task_t task,
+ const fa_embedding_t* embed,
+ const fa_token_t* token) {
+ vector<uint8_t> buffer_rx;
+ buffer_rx.resize(1024);
+
+ vector<uint8_t> buffer_tx = Task2Buffer(task, embed, token);
+ FaceAuthTest::client->CallApp(APP_ID_FACEAUTH_TEST, 1, buffer_tx, &buffer_rx);
+
+ return Buffer2Result(buffer_rx);
+}
+
+void FaceAuthTest::Run(const fa_result_t expected, const fa_task_t task,
+ const fa_embedding_t* embed, const fa_token_t* token) {
+ EXPECT_RESULT_EQ(expected, RunTask(task, embed, token));
+}
+
+void FaceAuthTest::SetUp() {
+ for (int profiles = 1; profiles <= MAX_NUM_PROFILES; ++profiles) {
+ Run(MakeResult(0x0, FACEAUTH_SUCCESS),
+ MakeTask(0x0, profiles, FACEAUTH_CMD_ERASE));
+ }
+}
+
+TEST_F(FaceAuthTest, SimpleMatchMismatchTest) {
+ uint64_t session_id = 0xFACE000011110000ull;
+ session_id++;
+
+ Run(MakeResult(session_id, FACEAUTH_SUCCESS, FACEAUTH_NOMATCH),
+ MakeTask(session_id, 0x1, FACEAUTH_CMD_COMP), MakeEmbedding(0x11));
+ session_id++;
+ Run(MakeResult(session_id, FACEAUTH_SUCCESS, 0x1),
+ MakeTask(session_id, 0x1, FACEAUTH_CMD_ENROLL), MakeEmbedding(0x11));
+ session_id++;
+ Run(MakeResult(session_id, FACEAUTH_SUCCESS, FACEAUTH_MATCH),
+ MakeTask(session_id, 0x1, FACEAUTH_CMD_COMP), MakeEmbedding(0x11));
+ session_id++;
+ Run(MakeResult(session_id, FACEAUTH_SUCCESS),
+ MakeTask(session_id, 0x1, FACEAUTH_CMD_ERASE));
+ session_id++;
+ Run(MakeResult(session_id, FACEAUTH_SUCCESS, FACEAUTH_NOMATCH),
+ MakeTask(session_id, 0x1, FACEAUTH_CMD_COMP), MakeEmbedding(0x11));
+}
+
+void FaceAuthTest::FullMatchMismatchTest(uint32_t profile1, uint32_t profile2,
+ uint32_t slot1, uint32_t slot2) {
+ uint64_t session_id = 0xFACE000022220000ull;
+ for (uint32_t i = 0; i < 20; ++i) {
+ session_id++;
+ Run(MakeResult(session_id, FACEAUTH_SUCCESS, profile1),
+ MakeTask(session_id, profile1, FACEAUTH_CMD_ENROLL),
+ MakeEmbedding((i == slot1) ? 0x11 : 0x0));
+
+ session_id++;
+ Run(MakeResult(session_id, FACEAUTH_SUCCESS, profile2),
+ MakeTask(session_id, profile2, FACEAUTH_CMD_ENROLL),
+ MakeEmbedding((i == slot2) ? 0xAA : 0x0));
+ }
+
+ session_id++;
+ Run(MakeResult(session_id, FACEAUTH_SUCCESS, FACEAUTH_MATCH),
+ MakeTask(session_id, profile1, FACEAUTH_CMD_COMP), MakeEmbedding(0x11));
+ session_id++;
+ Run(MakeResult(session_id, FACEAUTH_SUCCESS, FACEAUTH_NOMATCH),
+ MakeTask(session_id, profile1, FACEAUTH_CMD_COMP), MakeEmbedding(0xAA));
+ session_id++;
+ Run(MakeResult(session_id, FACEAUTH_SUCCESS, FACEAUTH_NOMATCH),
+ MakeTask(session_id, profile2, FACEAUTH_CMD_COMP), MakeEmbedding(0x11));
+ session_id++;
+ Run(MakeResult(session_id, FACEAUTH_SUCCESS, FACEAUTH_MATCH),
+ MakeTask(session_id, profile2, FACEAUTH_CMD_COMP), MakeEmbedding(0xAA));
+}
+
+TEST_F(FaceAuthTest, SFSFullTest) {
+ uint64_t session_id = 0xFACE000033330000ull;
+ for (int i = 0; i < 20; ++i) {
+ session_id++;
+ Run(MakeResult(session_id, FACEAUTH_SUCCESS, 0x1),
+ MakeTask(session_id, 0x1, FACEAUTH_CMD_ENROLL), MakeEmbedding(0x0));
+ }
+
+ session_id++;
+ Run(MakeResult(session_id, FACEAUTH_ERR_SFS_FULL, 0x1),
+ MakeTask(session_id, 0x1, FACEAUTH_CMD_ENROLL), MakeEmbedding(0x0));
+}
+
+void FaceAuthTest::LockProfileTest(uint32_t profile1) {
+ uint64_t session_id = 0xFACE000044440000ull;
+
+ for (int i = 0; i < 4; ++i) {
+ session_id++;
+ Run(MakeResult(session_id, FACEAUTH_SUCCESS, FACEAUTH_NOMATCH),
+ MakeTask(session_id, profile1, FACEAUTH_CMD_COMP), MakeEmbedding(0x0));
+ }
+
+ session_id++;
+ Run(MakeResult(session_id, FACEAUTH_SUCCESS, FACEAUTH_NOMATCH, 0,
+ FACEAUTH_LOCKOUT_ENFORCED),
+ MakeTask(session_id, profile1, FACEAUTH_CMD_COMP), MakeEmbedding(0x0));
+
+ session_id++;
+ Run(MakeResult(session_id, FACEAUTH_ERR_THROTTLE, FACEAUTH_NOMATCH),
+ MakeTask(session_id, profile1, FACEAUTH_CMD_COMP), MakeEmbedding(0x0));
+}
+
+bool FaceAuthTest::IsProfileLocked(uint32_t profile1) {
+ uint64_t session_id = 0xFACE000066660000ull;
+
+ const fa_result_t observed =
+ RunTask(MakeTask(session_id, profile1, FACEAUTH_CMD_GET_USER_INFO));
+ const fa_result_t expected =
+ MakeResult(session_id, FACEAUTH_SUCCESS, 0, observed.output.data.second);
+ EXPECT_RESULT_EQ(expected, observed);
+ return observed.output.data.second;
+}
+
+void FaceAuthTest::UnlockProfileTest(uint32_t profile1) {
+ uint64_t session_id = 0xFACE000077770000ull;
+ session_id++;
+ Run(MakeResult(session_id, FACEAUTH_SUCCESS, 0, 0, FACEAUTH_LOCKOUT_REMOVED),
+ MakeTask(session_id, profile1, FACEAUTH_CMD_RESET_LOCKOUT));
+}
+
+TEST_F(FaceAuthTest, ExhaustiveLockoutTest) {
+ EXPECT_EQ(IsProfileLocked(1), false);
+ EXPECT_EQ(IsProfileLocked(4), false);
+ EXPECT_EQ(IsProfileLocked(5), false);
+ EXPECT_EQ(IsProfileLocked(6), false);
+
+ LockProfileTest(1);
+ LockProfileTest(5);
+ LockProfileTest(6);
+
+ EXPECT_EQ(IsProfileLocked(1), true);
+ EXPECT_EQ(IsProfileLocked(4), false);
+ EXPECT_EQ(IsProfileLocked(5), true);
+ EXPECT_EQ(IsProfileLocked(6), true);
+
+ UnlockProfileTest(1);
+ UnlockProfileTest(6);
+
+ EXPECT_EQ(IsProfileLocked(1), false);
+ EXPECT_EQ(IsProfileLocked(4), false);
+ EXPECT_EQ(IsProfileLocked(5), true);
+ EXPECT_EQ(IsProfileLocked(6), false);
+}
+
+TEST_F(FaceAuthTest, ValidProfileUserIDTest) {
+ fa_token_t token;
+ uint64_t session_id = 0xFACE000088880000ull;
+ session_id++;
+ token = MakeToken(1);
+ Run(MakeResult(session_id, FACEAUTH_SUCCESS, 1),
+ MakeTask(session_id, 0, FACEAUTH_CMD_ENROLL), MakeEmbedding(0x0), &token);
+
+ for (int i = 1; i <= 6; ++i) {
+ session_id++;
+ token = MakeToken(i);
+ Run(MakeResult(session_id, FACEAUTH_SUCCESS, i),
+ MakeTask(session_id, (i % 2) ? i : 0, FACEAUTH_CMD_ENROLL),
+ MakeEmbedding(0x0), &token);
+ }
+
+ session_id++;
+ token = MakeToken(2);
+ Run(MakeResult(session_id, FACEAUTH_ERR_INVALID_TOKEN),
+ MakeTask(session_id, 3, FACEAUTH_CMD_ENROLL), MakeEmbedding(0x0), &token);
+ session_id++;
+ Run(MakeResult(session_id, FACEAUTH_ERR_SFS_FULL),
+ MakeTask(session_id, 0, FACEAUTH_CMD_ENROLL));
+}
+
+TEST_F(FaceAuthTest, InvalidCommandTest) {
+ uint64_t session_id = 0xFACE000099990000ull;
+ session_id++;
+ Run(MakeResult(session_id, FACEAUTH_ERR_INVALID_ARGS),
+ MakeTask(session_id, 0x1, 0x0));
+}
+
+TEST_F(FaceAuthTest, SimpleFeatureTest) {
+ uint64_t session_id = 0xFACE0000AAAA0000ull;
+ uint32_t index = 0;
+ uint32_t feature_msk[MAX_NUM_PROFILES] = {0};
+
+ for (int k = 0; k < 5; ++k) {
+ for (int i = 1; i <= MAX_NUM_PROFILES; ++i) {
+ session_id++;
+ Run(MakeResult(session_id, FACEAUTH_SUCCESS, feature_msk[i - 1]),
+ MakeTask(session_id, i, FACEAUTH_CMD_GET_USER_INFO));
+ }
+
+ for (int i = 1; i <= MAX_NUM_PROFILES; ++i) {
+ session_id++;
+ Run(MakeResult(session_id, FACEAUTH_SUCCESS),
+ MakeTask(session_id, i, FACEAUTH_CMD_SET_FEATURE, (1 << index)));
+ feature_msk[i - 1] |= (1 << index);
+ index++;
+ }
+ }
+
+ index = 0;
+
+ for (int k = 0; k < 5; ++k) {
+ for (int i = 1; i <= MAX_NUM_PROFILES; ++i) {
+ session_id++;
+ Run(MakeResult(session_id, FACEAUTH_SUCCESS, feature_msk[i - 1]),
+ MakeTask(session_id, i, FACEAUTH_CMD_GET_USER_INFO));
+ }
+
+ for (int i = 1; i <= MAX_NUM_PROFILES; ++i) {
+ session_id++;
+ Run(MakeResult(session_id, FACEAUTH_SUCCESS),
+ MakeTask(session_id, i, FACEAUTH_CMD_CLR_FEATURE, (1 << index)));
+ feature_msk[i - 1] &= ~(1 << index);
+ index++;
+ }
+ }
+}
+
+TEST_F(FaceAuthTest, EmbeddingVersionTest) {
+ uint64_t session_id = 0xFACE0000BBBB0000ull;
+ session_id++;
+ Run(MakeResult(session_id, FACEAUTH_SUCCESS, 1),
+ MakeTask(session_id, 0x1, FACEAUTH_CMD_ENROLL), MakeEmbedding(0x11));
+ session_id++;
+ Run(MakeResult(session_id, FACEAUTH_SUCCESS, FACEAUTH_MATCH),
+ MakeTask(session_id, 0x1, FACEAUTH_CMD_COMP), MakeEmbedding(0x11));
+ session_id++;
+ Run(MakeResult(session_id, FACEAUTH_ERR_RECALIBRATE, FACEAUTH_NOMATCH),
+ MakeTask(session_id, 0x1, FACEAUTH_CMD_COMP), MakeEmbedding(0x11, 0x2));
+}
+
+TEST_F(FaceAuthTest, FirmwareVersionTest) {
+ uint64_t session_id = 0xFACE0000CCCC0000ull;
+ session_id++;
+ Run(MakeResult(session_id, FACEAUTH_SUCCESS, 1),
+ MakeTask(session_id, 0x1, FACEAUTH_CMD_ENROLL), MakeEmbedding(0x11));
+ session_id++;
+ Run(MakeResult(session_id, FACEAUTH_ERR_VERSION, FACEAUTH_NOMATCH),
+ MakeTask(session_id, 0x1, FACEAUTH_CMD_COMP, 0, 0, 0x1),
+ MakeEmbedding(0x11));
+ session_id++;
+ Run(MakeResult(session_id, FACEAUTH_ERR_VERSION, FACEAUTH_NOMATCH),
+ MakeTask(session_id, 0x1, FACEAUTH_CMD_COMP, 0, 0,
+ FACEAUTH_MIN_ABH_VERSION - 0x100),
+ MakeEmbedding(0x11));
+ session_id++;
+ Run(MakeResult(session_id, FACEAUTH_SUCCESS, FACEAUTH_MATCH),
+ MakeTask(session_id, 0x1, FACEAUTH_CMD_COMP, 0, 0,
+ FACEAUTH_MIN_ABH_VERSION),
+ MakeEmbedding(0x11));
+ session_id++;
+ Run(MakeResult(session_id, FACEAUTH_SUCCESS, FACEAUTH_MATCH),
+ MakeTask(session_id, 0x1, FACEAUTH_CMD_COMP, 0, 0,
+ FACEAUTH_MIN_ABH_VERSION + 0x100),
+ MakeEmbedding(0x11));
+}
+
+TEST_F(FaceAuthTest, ExhaustiveMatchMismatchTest) {
+ FullMatchMismatchTest(1, 6, 0, 19);
+ FullMatchMismatchTest(2, 5, 1, 18);
+ FullMatchMismatchTest(3, 4, 2, 17);
+ SetUp();
+ FullMatchMismatchTest(2, 4, 3, 16);
+ FullMatchMismatchTest(1, 5, 4, 15);
+ FullMatchMismatchTest(3, 6, 5, 14);
+ SetUp();
+ FullMatchMismatchTest(3, 5, 6, 13);
+ FullMatchMismatchTest(1, 4, 7, 12);
+ FullMatchMismatchTest(2, 6, 8, 11);
+ SetUp();
+ FullMatchMismatchTest(3, 6, 9, 10);
+}
+}
+