diff --git a/src/faceauth_tests.cc b/src/faceauth_tests.cc
index cd41d98..5aff16e 100644
--- a/src/faceauth_tests.cc
+++ b/src/faceauth_tests.cc
@@ -16,36 +16,28 @@
 
 namespace {
 
+const uint8_t EMBEDDING_VECTOR_NULL = 0x0;
+const uint8_t EMBEDDING_VECTOR_1 = 0x11;
+const uint8_t EMBEDDING_VECTOR_2 = 0xAA;
+
 class FaceAuthTest: public testing::Test {
+ public:
+  const uint32_t PROFILE_1 = 1;
+  const uint32_t PROFILE_2 = 2;
+  const uint32_t PROFILE_3 = 3;
+  const uint32_t PROFILE_4 = 4;
+  const uint32_t PROFILE_5 = 5;
+  const uint32_t PROFILE_6 = 6;
+  static unique_ptr<nos::NuggetClientInterface> client;
+  static unique_ptr<test_harness::TestHarness> uart_printer;
+
  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;
 
@@ -83,504 +75,1100 @@
   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 output_data3 = 0) {
-  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.output.data.third = output_data3;
-  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);
+class Task {
+ public:
+  Task(uint32_t profile_id, uint32_t cmd,
+       uint32_t version = FACEAUTH_MIN_ABH_VERSION) {
+    memset(&task, 0, sizeof(task));
+    task.version = version;
+    task.session_id = 0xFACEBEEFBEEFFACEull;
+    task.profile_id = profile_id;
+    task.cmd = cmd;
   }
 
-  if (token) {
-    for (size_t i = 0; i < sizeof(fa_token_t); ++i) {
-      buffer.push_back(*(reinterpret_cast<const uint8_t*>(token) + i));
+  Task& SetFirst(uint64_t first) {
+    task.input.data.first = first;
+    return *this;
+  }
+
+  Task& SetChallenge(uint64_t challenge) {
+    memcpy(task.input.challenge, &challenge, sizeof(challenge));
+    return *this;
+  }
+
+  Task& Finalize() {
+    task.crc = CalcCrc8(reinterpret_cast<const uint8_t*>(&task),
+                        offsetof(struct fa_task_t, crc));
+    return *this;
+  }
+
+  vector<uint8_t> ToBuffer() {
+    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));
     }
+    return buffer;
   }
 
-  return buffer;
+ private:
+  fa_task_t task;
+};
+
+class Embedding {
+ public:
+  Embedding() { memset(&embed, 0, sizeof(embed)); }
+  Embedding(uint8_t base, uint32_t version = 1) {
+    memset(&embed, base, sizeof(embed));
+    embed.version = version;
+    embed.valid = 0;
+  }
+
+  void Finalize() {
+    embed.crc = CalcCrc8(reinterpret_cast<const uint8_t*>(&embed),
+                         offsetof(struct fa_embedding_t, crc));
+  }
+
+  vector<uint8_t> ToBuffer() {
+    vector<uint8_t> buffer;
+    for (size_t i = 0; i < sizeof(fa_embedding_t); ++i) {
+      buffer.push_back(*(reinterpret_cast<const uint8_t*>(&embed) + i));
+    }
+    return buffer;
+  }
+
+ private:
+  fa_embedding_t embed;
+};
+
+class Token {
+ public:
+  Token() { memset(&token, 0, sizeof(token)); }
+
+  Token(fa_token_t token) : token(token) {}
+
+  Token(uint64_t challenge, uint64_t user_id, uint64_t auth_id) {
+    memset(&token, 0, sizeof(token));
+    token.challenge = challenge;
+    token.user_id = user_id;
+    token.authenticator_id = auth_id;
+  }
+
+  vector<uint8_t> ToBuffer() {
+    vector<uint8_t> buffer;
+    for (size_t i = 0; i < sizeof(fa_token_t); ++i) {
+      buffer.push_back(*(reinterpret_cast<const uint8_t*>(&token) + i));
+    }
+    return buffer;
+  }
+
+  fa_token_t GetRaw() { return token; }
+
+ private:
+  fa_token_t token;
+};
+
+class Result {
+ public:
+  Result() { memset(&result, 0, sizeof(result)); }
+
+  Result(fa_result_t result) : result(result) {}
+
+  Result(int32_t error) {
+    memset(&result, 0, sizeof(result));
+    SetError(error);
+  }
+
+  fa_result_t GetRaw() {
+    Finalize();
+    return result;
+  }
+
+  Result& SetError(int32_t error) {
+    result.error = error;
+    return *this;
+  }
+
+  Result& SetChallenge(uint64_t challenge) {
+    memcpy(result.output.challenge, &challenge, sizeof(challenge));
+    return *this;
+  }
+
+  Result& SetSecond(uint32_t second) {
+    result.output.data.second = second;
+    return *this;
+  }
+
+  Result& SetThird(uint32_t third) {
+    result.output.data.third = third;
+    return *this;
+  }
+
+  uint64_t GetChallenge() {
+    uint64_t challenge;
+    memcpy(&challenge, result.output.challenge, sizeof(challenge));
+    return challenge;
+  }
+
+  uint32_t GetFirst() { return result.output.data.first; }
+  uint32_t GetSecond() { return result.output.data.second; }
+
+  Result& Finalize() {
+    result.version = 1;
+    result.session_id = 0xFACEBEEFBEEFFACEull;
+    result.complete = 1;
+    result.crc = CalcCrc8(reinterpret_cast<const uint8_t*>(&result),
+                          offsetof(struct fa_result_t, crc));
+    return *this;
+  }
+
+ protected:
+  fa_result_t result;
+};
+
+static void EXPECT_REQ(Result r1, Result r2) {
+  fa_result_t observed = r1.GetRaw();
+  fa_result_t expected = r2.GetRaw();
+
+  EXPECT_EQ(observed.version, expected.version);
+  EXPECT_EQ(observed.session_id, expected.session_id);
+  EXPECT_EQ(observed.error, expected.error);
+  EXPECT_EQ(observed.output.data.first, expected.output.data.first);
+  EXPECT_EQ(observed.output.data.second, expected.output.data.second);
+  EXPECT_EQ(observed.output.data.third, expected.output.data.third);
+  EXPECT_EQ(observed.complete, expected.complete);
+  EXPECT_EQ(observed.crc, expected.crc);
 }
 
-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;
+class ResetLockoutResult : public Result {
+ public:
+  ResetLockoutResult(Result result) : Result(result) {}
+
+  ResetLockoutResult(int32_t error) : Result(error) {}
+
+  ResetLockoutResult& SetLockoutEvent(uint32_t lockout_event) {
+    result.output.data.third = lockout_event;
+    return *this;
+  }
+};
+
+class MigrateResult : public Result {
+ public:
+  MigrateResult(Result result) : Result(result) {}
+
+  MigrateResult(int32_t error) : Result(error) {}
+
+  MigrateResult& SetEmbeddingNum(uint32_t num) {
+    result.output.data.second = num;
+    return *this;
+  }
+
+  MigrateResult& SetMatch(bool m) {
+    result.output.data.third = m;
+    return *this;
+  }
+};
+
+class AuthenticateResult : public Result {
+ public:
+  AuthenticateResult(Result result, Token token)
+      : Result(result), token(token) {}
+
+  AuthenticateResult(int32_t error) : Result(error) {}
+
+  AuthenticateResult& SetMatch(bool m) {
+    result.output.data.first = m;
+    return *this;
+  }
+
+  AuthenticateResult& SetLockoutEvent(uint32_t lockout_event) {
+    result.output.data.third = lockout_event;
+    return *this;
+  }
+
+  Token GetToken() { return token; }
+
+ protected:
+  Token token;
+};
+
+static void EXPECT_AEQ(AuthenticateResult r1, AuthenticateResult r2) {
+  EXPECT_REQ(r1, r2);
+
+  fa_token_t observed = r1.GetToken().GetRaw();
+  fa_token_t expected = r2.GetToken().GetRaw();
+
+  EXPECT_EQ(observed.challenge, expected.challenge);
+  EXPECT_EQ(observed.user_id, expected.user_id);
+  EXPECT_EQ(observed.authenticator_id, expected.authenticator_id);
 }
 
-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.output.data.third, r2.output.data.third);
-  EXPECT_EQ(r1.complete, r2.complete);
-  EXPECT_EQ(r1.crc, r2.crc);
-}
+class Transaction {
+ public:
+  Transaction(Task task, Embedding embed, Token token)
+      : input_task(task), input_embed(embed), input_token(token) {}
 
-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(512);
+  Transaction& Finalize() {
+    input_task.Finalize();
+    input_embed.Finalize();
+    return *this;
+  }
 
-  vector<uint8_t> buffer_tx = Task2Buffer(task, embed, token);
-  FaceAuthTest::client->CallApp(APP_ID_FACEAUTH_TEST, 1, buffer_tx, &buffer_rx);
+  Transaction& Run() {
+    vector<uint8_t> task = input_task.ToBuffer();
+    vector<uint8_t> embed = input_embed.ToBuffer();
+    vector<uint8_t> token = input_token.ToBuffer();
 
-  return Buffer2Result(buffer_rx);
-}
+    vector<uint8_t> buffer_rx;
+    buffer_rx.resize(512);
 
-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));
-}
+    vector<uint8_t> buffer_tx;
+    buffer_tx.insert(buffer_tx.end(), task.begin(), task.end());
+    buffer_tx.insert(buffer_tx.end(), embed.begin(), embed.end());
+    buffer_tx.insert(buffer_tx.end(), token.begin(), token.end());
+
+    FaceAuthTest::client->CallApp(APP_ID_FACEAUTH_TEST, 1, buffer_tx,
+                                  &buffer_rx);
+
+    struct fa_output_t {
+      fa_result_t result;
+      fa_token_t token;
+    } __attribute__((packed));
+
+    fa_output_t output =
+        *(reinterpret_cast<struct fa_output_t*>(buffer_rx.data()));
+
+    output_result = output.result;
+    output_token = output.token;
+
+    return *this;
+  }
+
+  Result GetResult() { return Result(output_result); }
+  Token GetToken() { return Token(output_token); }
+
+ private:
+  Task input_task;
+  Embedding input_embed;
+  Token input_token;
+  fa_result_t output_result;
+  fa_token_t output_token;
+};
+
+class Device {
+ public:
+  static Result Erase(uint32_t profile_id) {
+    return Transaction(Task(profile_id, FACEAUTH_CMD_ERASE), Embedding(),
+                       Token())
+        .Finalize()
+        .Run()
+        .GetResult();
+  }
+
+  static Result GenerateChallenge() {
+    Result ret =
+        Transaction(Task(0, FACEAUTH_CMD_GET_CHALLENGE), Embedding(), Token())
+            .Finalize()
+            .Run()
+            .GetResult();
+    memcpy(&challenge, ret.GetRaw().output.challenge, sizeof(challenge));
+    return ret;
+  }
+
+  static Result RevokeChallenge() {
+    return Transaction(Task(0, FACEAUTH_CMD_REVOKE_CHALLENGE), Embedding(),
+                       Token())
+        .Finalize()
+        .Run()
+        .GetResult();
+  }
+
+  static uint64_t GetChallenge() { return challenge; }
+
+ private:
+  static uint64_t challenge;
+};
+
+uint64_t Device::challenge;
 
 void FaceAuthTest::SetUp() {
-  user_ids.clear();
-  for (int i = 0; i <= MAX_NUM_PROFILES; ++i) {
-    user_ids.push_back(rand());
-  }
-
-  fa_task_t task;
-  fa_embedding_t embed;
-  fa_token_t token;
-  memset(&task, 0, sizeof(task));
-  memset(&embed, 0, sizeof(embed));
-  memset(&token, 0, sizeof(token));
-  RunTask(task, &embed, &token);
-
-  for (int profiles = 1; profiles <= MAX_NUM_PROFILES; ++profiles) {
-    Run(MakeResult(0x0, FACEAUTH_SUCCESS),
-        MakeTask(0x0, profiles, FACEAUTH_CMD_ERASE));
-  }
+  for (int i = 0; i < MAX_NUM_PROFILES; ++i)
+    EXPECT_REQ(Device::Erase(i + 1), Result(FACEAUTH_SUCCESS));
 }
 
-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, 0, 0, 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));
+TEST_F(FaceAuthTest, OldFirmwareVersionShouldError) {
+  EXPECT_REQ(Transaction(Task(PROFILE_1, FACEAUTH_CMD_ERASE,
+                              FACEAUTH_MIN_ABH_VERSION - 0x100),
+                         Embedding(), Token())
+                 .Finalize()
+                 .Run()
+                 .GetResult(),
+             Result(FACEAUTH_ERR_VERSION));
 }
 
-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, 0, 0, profile1),
-        MakeTask(session_id, profile1, FACEAUTH_CMD_ENROLL),
-        MakeEmbedding((i == slot1) ? 0x11 : 0x0));
-
-    session_id++;
-    Run(MakeResult(session_id, FACEAUTH_SUCCESS, 0, 0, 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, NewFirmwareVersionShouldNotError) {
+  EXPECT_REQ(Transaction(Task(PROFILE_1, FACEAUTH_CMD_ERASE,
+                              FACEAUTH_MIN_ABH_VERSION + 0x100),
+                         Embedding(), Token())
+                 .Finalize()
+                 .Run()
+                 .GetResult(),
+             Result(FACEAUTH_SUCCESS));
 }
 
-TEST_F(FaceAuthTest, SFSFullTest) {
-  uint64_t session_id = 0xFACE000033330000ull;
-  for (int i = 0; i < 20; ++i) {
-    session_id++;
-    Run(MakeResult(session_id, FACEAUTH_SUCCESS, 0, 0, 0x1),
-        MakeTask(session_id, 0x1, FACEAUTH_CMD_ENROLL), MakeEmbedding(0x0));
-  }
-
-  session_id++;
-  Run(MakeResult(session_id, FACEAUTH_ERR_SFS_FULL, 0, 0, 0x1),
-      MakeTask(session_id, 0x1, FACEAUTH_CMD_ENROLL), MakeEmbedding(0x0));
+TEST_F(FaceAuthTest, TaskCRCErrorShouldBeDetected) {
+  EXPECT_REQ(
+      Transaction(Task(PROFILE_1, FACEAUTH_CMD_ERASE), Embedding(), Token())
+          .Run()
+          .GetResult(),
+      Result(FACEAUTH_ERR_CRC));
 }
 
-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));
+TEST_F(FaceAuthTest, ZeroChallengeShouldError) {
+  EXPECT_REQ(Transaction(Task(PROFILE_1, FACEAUTH_CMD_ENROLL),
+                         Embedding(EMBEDDING_VECTOR_1, 1), Token())
+                 .Finalize()
+                 .Run()
+                 .GetResult(),
+             Result(FACEAUTH_ERR_INVALID_CHALLENGE));
+  EXPECT_REQ(Transaction(Task(PROFILE_1, FACEAUTH_CMD_SET_FEATURE),
+                         Embedding(EMBEDDING_VECTOR_1, 1), Token())
+                 .Finalize()
+                 .Run()
+                 .GetResult(),
+             Result(FACEAUTH_ERR_INVALID_CHALLENGE));
+  EXPECT_REQ(Transaction(Task(PROFILE_1, FACEAUTH_CMD_CLR_FEATURE),
+                         Embedding(EMBEDDING_VECTOR_1, 1), Token())
+                 .Finalize()
+                 .Run()
+                 .GetResult(),
+             Result(FACEAUTH_ERR_INVALID_CHALLENGE));
+  EXPECT_REQ(Transaction(Task(PROFILE_1, FACEAUTH_CMD_RESET_LOCKOUT),
+                         Embedding(EMBEDDING_VECTOR_1, 1), Token())
+                 .Finalize()
+                 .Run()
+                 .GetResult(),
+             Result(FACEAUTH_ERR_INVALID_CHALLENGE));
 }
 
-bool FaceAuthTest::IsProfileLocked(uint32_t profile1) {
-  uint64_t session_id = 0xFACE000066660000ull;
+TEST_F(FaceAuthTest, InvalidChallengeShouldError) {
+  Result generate_result = Device::GenerateChallenge();
+  EXPECT_REQ(generate_result,
+             Result(FACEAUTH_SUCCESS).SetChallenge(Device::GetChallenge()));
 
-  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;
+  EXPECT_REQ(Transaction(Task(PROFILE_1, FACEAUTH_CMD_ENROLL),
+                         Embedding(EMBEDDING_VECTOR_1, 1), Token(rand(), 0, 0))
+                 .Finalize()
+                 .Run()
+                 .GetResult(),
+             Result(FACEAUTH_ERR_INVALID_CHALLENGE));
+  EXPECT_REQ(Transaction(Task(PROFILE_1, FACEAUTH_CMD_SET_FEATURE),
+                         Embedding(EMBEDDING_VECTOR_1, 1), Token(rand(), 0, 0))
+                 .Finalize()
+                 .Run()
+                 .GetResult(),
+             Result(FACEAUTH_ERR_INVALID_CHALLENGE));
+  EXPECT_REQ(Transaction(Task(PROFILE_1, FACEAUTH_CMD_CLR_FEATURE),
+                         Embedding(EMBEDDING_VECTOR_1, 1), Token(rand(), 0, 0))
+                 .Finalize()
+                 .Run()
+                 .GetResult(),
+             Result(FACEAUTH_ERR_INVALID_CHALLENGE));
+  EXPECT_REQ(Transaction(Task(PROFILE_1, FACEAUTH_CMD_RESET_LOCKOUT),
+                         Embedding(EMBEDDING_VECTOR_1, 1), Token(rand(), 0, 0))
+                 .Finalize()
+                 .Run()
+                 .GetResult(),
+             Result(FACEAUTH_ERR_INVALID_CHALLENGE));
 }
 
-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, EmbeddingCRCErrorShouldBeDetected) {
+  EXPECT_REQ(Transaction(Task(PROFILE_1, FACEAUTH_CMD_COMP).Finalize(),
+                         Embedding(EMBEDDING_VECTOR_1, 1), Token())
+                 .Run()
+                 .GetResult(),
+             Result(FACEAUTH_ERR_CRC));
+  EXPECT_REQ(Transaction(Task(PROFILE_1, FACEAUTH_CMD_MIGRATE).Finalize(),
+                         Embedding(EMBEDDING_VECTOR_1, 1), Token())
+                 .Run()
+                 .GetResult(),
+             Result(FACEAUTH_ERR_CRC));
+
+  Result generate_result = Device::GenerateChallenge();
+  EXPECT_REQ(generate_result,
+             Result(FACEAUTH_SUCCESS).SetChallenge(Device::GetChallenge()));
+  EXPECT_REQ(Transaction(Task(PROFILE_1, FACEAUTH_CMD_ENROLL).Finalize(),
+                         Embedding(EMBEDDING_VECTOR_1, 1),
+                         Token(Device::GetChallenge(), 0, 0))
+                 .Run()
+                 .GetResult(),
+             Result(FACEAUTH_ERR_CRC));
 }
 
-TEST_F(FaceAuthTest, ExhaustiveLockoutTest) {
-  EXPECT_EQ(IsProfileLocked(1), false);
-  EXPECT_EQ(IsProfileLocked(4), false);
-  EXPECT_EQ(IsProfileLocked(5), false);
-  EXPECT_EQ(IsProfileLocked(6), false);
+TEST_F(FaceAuthTest, InvalidCommandShouldError) {
+  Task task(PROFILE_1, 0);
+  Embedding embed;
+  Token token;
 
-  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);
+  EXPECT_REQ(Transaction(task, embed, token).Finalize().Run().GetResult(),
+             Result(FACEAUTH_ERR_INVALID_ARGS));
 }
 
 TEST_F(FaceAuthTest, ValidProfileIDTest) {
-  uint64_t session_id = 0xFACE000088880000ull;
-  session_id++;
-  Run(MakeResult(session_id, FACEAUTH_ERR_INVALID_ARGS),
-      MakeTask(session_id, 0, FACEAUTH_CMD_ENROLL), MakeEmbedding(0x0));
+  Embedding embed;
+  Token token;
+
+  EXPECT_REQ(Transaction(Task(0, FACEAUTH_CMD_GET_USER_INFO), embed, token)
+                 .Finalize()
+                 .Run()
+                 .GetResult(),
+             Result(FACEAUTH_ERR_INVALID_ARGS));
 
   for (int i = 1; i <= MAX_NUM_PROFILES; ++i) {
-    session_id++;
-    Run(MakeResult(session_id, FACEAUTH_SUCCESS, 0, 0, i),
-        MakeTask(session_id, i, FACEAUTH_CMD_ENROLL), MakeEmbedding(0x0));
+    EXPECT_REQ(Transaction(Task(i, FACEAUTH_CMD_GET_USER_INFO), embed, token)
+                   .Finalize()
+                   .Run()
+                   .GetResult(),
+               Result(FACEAUTH_SUCCESS));
   }
 
-  session_id++;
-  Run(MakeResult(session_id, FACEAUTH_ERR_INVALID_ARGS),
-      MakeTask(session_id, MAX_NUM_PROFILES + 1, FACEAUTH_CMD_ENROLL));
+  EXPECT_REQ(Transaction(Task(MAX_NUM_PROFILES + 1, FACEAUTH_CMD_GET_USER_INFO),
+                         embed, token)
+                 .Finalize()
+                 .Run()
+                 .GetResult(),
+             Result(FACEAUTH_ERR_INVALID_ARGS));
 }
 
-TEST_F(FaceAuthTest, InvalidCommandTest) {
-  uint64_t session_id = 0xFACE000099990000ull;
-  session_id++;
-  Run(MakeResult(session_id, FACEAUTH_ERR_INVALID_ARGS),
-      MakeTask(session_id, 0x1, 0x0));
-}
+class User {
+ public:
+  User(uint8_t embed_base) : embed_base(embed_base) {
+    user_id = rand();
+    user_id <<= 32;
+    user_id += rand();
+  }
 
-TEST_F(FaceAuthTest, SimpleFeatureTest) {
-  uint64_t session_id = 0xFACE0000AAAA0000ull;
-  uint32_t index = 0;
-  uint32_t feature_msk[MAX_NUM_PROFILES] = {0};
+  User& SetEmbeddingVersion(uint8_t version) {
+    embed_version = version;
+    return *this;
+  }
 
-  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));
+  User& SetEmbeddingBase(uint8_t base) {
+    embed_base = base;
+    return *this;
+  }
+
+  User& SetUserID(uint64_t sid) {
+    user_id = sid;
+    return *this;
+  }
+
+  Result GetProfileInfo() {
+    return Transaction(Task(0, FACEAUTH_CMD_GET_PROFILE_INFO), Embedding(),
+                       Token(0, user_id, 0))
+        .Finalize()
+        .Run()
+        .GetResult();
+  }
+
+  Result GetUserInfo(uint32_t profile_id) {
+    return Transaction(Task(profile_id, FACEAUTH_CMD_GET_USER_INFO),
+                       Embedding(), Token())
+        .Finalize()
+        .Run()
+        .GetResult();
+  }
+
+  Result Enroll(uint32_t profile_id) {
+    Result generate_result = Device::GenerateChallenge();
+    EXPECT_REQ(generate_result,
+               Result(FACEAUTH_SUCCESS).SetChallenge(Device::GetChallenge()));
+
+    Result ret = Transaction(Task(profile_id, FACEAUTH_CMD_ENROLL),
+                             Embedding(embed_base, embed_version),
+                             Token(Device::GetChallenge(), user_id, 0))
+                     .Finalize()
+                     .Run()
+                     .GetResult();
+
+    uint64_t auth_id_temp = ret.GetChallenge();
+    memcpy(&auth_id, &auth_id_temp, sizeof(auth_id));
+    EXPECT_REQ(Device::RevokeChallenge(), Result(FACEAUTH_SUCCESS));
+
+    return ret;
+  }
+
+  MigrateResult Migrate(uint32_t profile_id, bool should_migrate) {
+    return Transaction(
+               Task(profile_id, FACEAUTH_CMD_MIGRATE).SetFirst(should_migrate),
+               Embedding(embed_base, embed_version), Token(0, user_id, 0))
+        .Finalize()
+        .Run()
+        .GetResult();
+  }
+
+  AuthenticateResult Authenticate(uint32_t profile_id) {
+    operation_id = rand();
+    operation_id <<= 32;
+    operation_id += rand();
+
+    Transaction t =
+        Transaction(
+            Task(profile_id, FACEAUTH_CMD_COMP).SetChallenge(operation_id),
+            Embedding(embed_base, embed_version), Token())
+            .Finalize()
+            .Run();
+
+    return AuthenticateResult(t.GetResult(), t.GetToken());
+  }
+
+  ResetLockoutResult ResetLockout(uint32_t profile_id) {
+    Result generate_result = Device::GenerateChallenge();
+    EXPECT_REQ(generate_result,
+               Result(FACEAUTH_SUCCESS).SetChallenge(Device::GetChallenge()));
+
+    Result ret =
+        Transaction(Task(profile_id, FACEAUTH_CMD_RESET_LOCKOUT), Embedding(),
+                    Token(Device::GetChallenge(), user_id, 0))
+            .Finalize()
+            .Run()
+            .GetResult();
+
+    EXPECT_REQ(Device::RevokeChallenge(), Result(FACEAUTH_SUCCESS));
+
+    return ret;
+  }
+
+  bool IsProfileLocked(uint32_t profile_id) {
+    return (GetUserInfo(profile_id).GetSecond() > 0);
+  }
+
+  void LockProfile(uint32_t profile_id) {
+    uint8_t original_embed_base = embed_base;
+    embed_base = EMBEDDING_VECTOR_NULL;
+    /* Fail Authentication 4 times */
+    for (int i = 0; i < 4; ++i) {
+      EXPECT_REQ(Authenticate(profile_id),
+                 AuthenticateResult(FACEAUTH_SUCCESS).SetMatch(false));
     }
 
-    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);
+    /* Fifth Authentication failure should trigger lockout event */
+    EXPECT_REQ(Authenticate(profile_id),
+               AuthenticateResult(FACEAUTH_SUCCESS)
+                   .SetMatch(false)
+                   .SetLockoutEvent(FACEAUTH_LOCKOUT_ENFORCED));
+
+    embed_base = original_embed_base;
+  }
+
+  uint32_t GetFeature(uint32_t profile_id) {
+    return GetUserInfo(profile_id).GetFirst();
+  }
+
+  Result SetFeature(uint32_t profile_id, uint32_t feature) {
+    Result generate_result = Device::GenerateChallenge();
+    EXPECT_REQ(generate_result,
+               Result(FACEAUTH_SUCCESS).SetChallenge(Device::GetChallenge()));
+
+    Result ret =
+        Transaction(
+            Task(profile_id, FACEAUTH_CMD_SET_FEATURE).SetFirst(feature),
+            Embedding(), Token(Device::GetChallenge(), user_id, 0))
+            .Finalize()
+            .Run()
+            .GetResult();
+
+    EXPECT_REQ(Device::RevokeChallenge(), Result(FACEAUTH_SUCCESS));
+
+    return ret;
+  }
+
+  Result ClrFeature(uint32_t profile_id, uint32_t feature) {
+    Result generate_result = Device::GenerateChallenge();
+    EXPECT_REQ(generate_result,
+               Result(FACEAUTH_SUCCESS).SetChallenge(Device::GetChallenge()));
+
+    Result ret =
+        Transaction(
+            Task(profile_id, FACEAUTH_CMD_CLR_FEATURE).SetFirst(feature),
+            Embedding(), Token(Device::GetChallenge(), user_id, 0))
+            .Finalize()
+            .Run()
+            .GetResult();
+
+    EXPECT_REQ(Device::RevokeChallenge(), Result(FACEAUTH_SUCCESS));
+
+    return ret;
+  }
+
+  uint64_t GetOperationID() { return operation_id; }
+  uint64_t GetAuthID() { return auth_id; }
+  uint64_t GetUserID() { return user_id; }
+
+ private:
+  uint64_t operation_id;
+  uint64_t auth_id = 0;
+  uint64_t user_id;
+  uint8_t embed_base;
+  uint8_t embed_version;
+};
+
+class SuccessfulAuthenticateResult : public AuthenticateResult {
+ public:
+  SuccessfulAuthenticateResult(User u) : AuthenticateResult(FACEAUTH_SUCCESS) {
+    token = Token(u.GetOperationID(), u.GetUserID(), u.GetAuthID());
+    SetMatch(true);
+  }
+};
+
+TEST_F(FaceAuthTest, GetProfileInfoTest) {
+  vector<User> users;
+  for (int i = 0; i < MAX_NUM_PROFILES; ++i) {
+    users.push_back(User(EMBEDDING_VECTOR_1));
+    users[i].SetEmbeddingVersion(1);
+  }
+
+  users[0].SetUserID(0x1122334455667788);
+  users[1].SetUserID(0x1122334455667788);
+  users[3].SetUserID(0x1122334455667788);
+
+  for (int i = 0; i < MAX_NUM_PROFILES; ++i) users[i].Enroll(i + 1);
+
+  union {
+    uint8_t map[8] = {0};
+    uint64_t info;
+  };
+
+  for (int i = 0; i < MAX_NUM_PROFILES; ++i) {
+    for (int j = 0; j < MAX_NUM_PROFILES; ++j) {
+      map[i] |= ((users[i].GetUserID() == users[j].GetUserID()) << j);
+    }
+  }
+
+  for (int i = 0; i < MAX_NUM_PROFILES; ++i) {
+    map[MAX_NUM_PROFILES] = map[i];
+    EXPECT_REQ(users[i].GetProfileInfo(),
+               Result(FACEAUTH_SUCCESS).SetChallenge(info));
+    EXPECT_REQ(users[i].GetUserInfo(i + 1),
+               Result(FACEAUTH_SUCCESS).SetThird(map[i]));
+  }
+}
+
+TEST_F(FaceAuthTest, EnrollShouldOnlyAcceptSameUser) {
+  User user1(EMBEDDING_VECTOR_1);
+  user1.SetEmbeddingVersion(1);
+
+  User user2(EMBEDDING_VECTOR_NULL);
+  user2.SetEmbeddingVersion(1);
+
+  /* User 1 Enroll to Profile 1 */
+  Result enroll_result = user1.Enroll(PROFILE_1);
+  EXPECT_REQ(enroll_result,
+             Result(FACEAUTH_SUCCESS).SetChallenge(user1.GetAuthID()));
+
+  /* User 2 Enroll to Profile 1 should fail */
+  enroll_result = user2.Enroll(PROFILE_1);
+  EXPECT_REQ(enroll_result, Result(FACEAUTH_ERR_INVALID_USER_ID));
+
+  /* User 1 Enroll to Profile 1 should be successful */
+  enroll_result = user1.Enroll(PROFILE_1);
+  EXPECT_REQ(enroll_result,
+             Result(FACEAUTH_SUCCESS).SetChallenge(user1.GetAuthID()));
+}
+
+TEST_F(FaceAuthTest, EnrollAfterWipeShouldBeSuccessful) {
+  User user1(EMBEDDING_VECTOR_1);
+  user1.SetEmbeddingVersion(1);
+
+  User user2(EMBEDDING_VECTOR_1);
+  user2.SetEmbeddingVersion(1);
+
+  /* Enroll to Profile 1 */
+  Result enroll_result = user1.Enroll(PROFILE_1);
+  EXPECT_REQ(enroll_result,
+             Result(FACEAUTH_SUCCESS).SetChallenge(user1.GetAuthID()));
+
+  /* Profile 1 Authentication should now pass */
+  AuthenticateResult auth_result = user1.Authenticate(PROFILE_1);
+  EXPECT_AEQ(auth_result, SuccessfulAuthenticateResult(user1));
+
+  ASSERT_TRUE(nugget_tools::WipeUserData(client.get()));
+
+  /* Enroll to Profile 1 */
+  enroll_result = user2.Enroll(PROFILE_1);
+  EXPECT_REQ(enroll_result,
+             Result(FACEAUTH_SUCCESS).SetChallenge(user2.GetAuthID()));
+
+  /* Profile 1 Authentication should now pass */
+  auth_result = user2.Authenticate(PROFILE_1);
+  EXPECT_AEQ(auth_result, SuccessfulAuthenticateResult(user2));
+}
+
+TEST_F(FaceAuthTest, ValidUserIDCheck) {
+  User user1(EMBEDDING_VECTOR_1);
+  user1.SetEmbeddingVersion(1);
+
+  User user2(EMBEDDING_VECTOR_1);
+  user2.SetEmbeddingVersion(1);
+
+  /* User 1 Enroll to Profile 1 */
+  Result enroll_result = user1.Enroll(PROFILE_1);
+  EXPECT_REQ(enroll_result,
+             Result(FACEAUTH_SUCCESS).SetChallenge(user1.GetAuthID()));
+
+  /* Reset Lockout User ID Check */
+  EXPECT_REQ(user1.ResetLockout(PROFILE_1), Result(FACEAUTH_SUCCESS));
+  EXPECT_REQ(user2.ResetLockout(PROFILE_1),
+             Result(FACEAUTH_ERR_INVALID_USER_ID));
+  /* Set Feature User ID Check */
+  EXPECT_REQ(user1.SetFeature(PROFILE_1, 0), Result(FACEAUTH_SUCCESS));
+  EXPECT_REQ(user2.SetFeature(PROFILE_1, 0),
+             Result(FACEAUTH_ERR_INVALID_USER_ID));
+  /* Clear Feature User ID Check */
+  EXPECT_REQ(user1.ClrFeature(PROFILE_1, 0), Result(FACEAUTH_SUCCESS));
+  EXPECT_REQ(user2.ClrFeature(PROFILE_1, 0),
+             Result(FACEAUTH_ERR_INVALID_USER_ID));
+}
+
+TEST_F(FaceAuthTest, EnrollMismatchVersionShouldFail) {
+  User user1(EMBEDDING_VECTOR_1);
+  user1.SetEmbeddingVersion(1);
+
+  /* Enroll using version 1 to profile 1 */
+  Result enroll_result = user1.Enroll(PROFILE_1);
+  EXPECT_REQ(enroll_result,
+             Result(FACEAUTH_SUCCESS).SetChallenge(user1.GetAuthID()));
+
+  /* Enroll using version 2 to the same profile slot should fail */
+  EXPECT_REQ(user1.SetEmbeddingVersion(2).Enroll(PROFILE_1),
+             Result(FACEAUTH_ERR_EMBEDDING_VERSION));
+}
+
+TEST_F(FaceAuthTest, SFSFullTest) {
+  User user1(EMBEDDING_VECTOR_1);
+  user1.SetEmbeddingVersion(1);
+
+  /* Enroll to Profile1 20 times */
+  for (int i = 0; i < 20; ++i) {
+    Result enroll_result = user1.Enroll(PROFILE_1);
+    EXPECT_REQ(enroll_result,
+               Result(FACEAUTH_SUCCESS).SetChallenge(user1.GetAuthID()));
+  }
+
+  /* Enrolling one more time should fail */
+  EXPECT_REQ(user1.Enroll(PROFILE_1), Result(FACEAUTH_ERR_SFS_FULL));
+}
+
+TEST_F(FaceAuthTest, SimpleMatchMismatchTest) {
+  User user1(EMBEDDING_VECTOR_1);
+  user1.SetEmbeddingVersion(1);
+
+  /* Profile 1 is empty: authentication will fail */
+  EXPECT_REQ(user1.Authenticate(PROFILE_1),
+             AuthenticateResult(FACEAUTH_SUCCESS).SetMatch(false));
+
+  /* Enroll to Profile 1 */
+  Result enroll_result = user1.Enroll(PROFILE_1);
+  EXPECT_REQ(enroll_result,
+             Result(FACEAUTH_SUCCESS).SetChallenge(user1.GetAuthID()));
+
+  /* Profile 1 Authentication should now pass */
+  AuthenticateResult auth_result = user1.Authenticate(PROFILE_1);
+  EXPECT_AEQ(auth_result, SuccessfulAuthenticateResult(user1));
+
+  /* Erase Profile 1*/
+  EXPECT_REQ(Device::Erase(PROFILE_1), Result(FACEAUTH_SUCCESS));
+
+  /* Profile 1 is now empty again: authentication should fail */
+  EXPECT_REQ(user1.Authenticate(PROFILE_1),
+             AuthenticateResult(FACEAUTH_SUCCESS).SetMatch(false));
+}
+
+TEST_F(FaceAuthTest, EmbeddingMismatchVersionComparisonShouldError) {
+  User user1(EMBEDDING_VECTOR_1);
+  user1.SetEmbeddingVersion(1);
+
+  /* Enroll to Profile 1 */
+  Result enroll_result = user1.Enroll(PROFILE_1);
+  EXPECT_REQ(enroll_result,
+             Result(FACEAUTH_SUCCESS).SetChallenge(user1.GetAuthID()));
+
+  /* Upgrade Embedding Version for User 1 */
+  user1.SetEmbeddingVersion(2);
+
+  /* Authenticate should now return recalibration error */
+  EXPECT_REQ(user1.Authenticate(PROFILE_1), Result(FACEAUTH_ERR_RECALIBRATE));
+}
+
+TEST_F(FaceAuthTest, MigrateShouldPreventDowngrade) {
+  User user1(EMBEDDING_VECTOR_1);
+  user1.SetEmbeddingVersion(5);
+
+  /* User1: enroll to profile 1 */
+  Result enroll_result = user1.Enroll(PROFILE_1);
+  EXPECT_REQ(enroll_result,
+             Result(FACEAUTH_SUCCESS).SetChallenge(user1.GetAuthID()));
+
+  /* User1: authenticate successfully to profile 1 */
+  AuthenticateResult auth_result = user1.Authenticate(PROFILE_1);
+  EXPECT_AEQ(auth_result, SuccessfulAuthenticateResult(user1));
+
+  /* User1: downgrade and attempt to migrate to profile 3 */
+  EXPECT_REQ(user1.SetEmbeddingVersion(4).Migrate(PROFILE_3, 0),
+             Result(FACEAUTH_ERR_EMBEDDING_DOWNGRADE));
+}
+
+TEST_F(FaceAuthTest, MigrateShouldPreventMismatchVersion) {
+  User user1(EMBEDDING_VECTOR_1);
+  user1.SetEmbeddingVersion(5);
+
+  /* User1: enroll to profile 1 */
+  Result enroll_result = user1.Enroll(PROFILE_1);
+  EXPECT_REQ(enroll_result,
+             Result(FACEAUTH_SUCCESS).SetChallenge(user1.GetAuthID()));
+
+  /* User1: authenticate successfully to profile 1 */
+  AuthenticateResult auth_result = user1.Authenticate(PROFILE_1);
+  EXPECT_AEQ(auth_result, SuccessfulAuthenticateResult(user1));
+
+  /* User1: upgrade and migrate to profile 3 */
+  EXPECT_REQ(user1.SetEmbeddingVersion(6).Migrate(PROFILE_3, 1),
+             MigrateResult(FACEAUTH_SUCCESS).SetEmbeddingNum(1).SetMatch(true));
+  EXPECT_REQ(user1.SetEmbeddingVersion(7).Migrate(PROFILE_3, 0),
+             Result(FACEAUTH_ERR_EMBEDDING_VERSION));
+}
+
+TEST_F(FaceAuthTest, MigrateShouldCopyUserInfo) {
+  User user1(EMBEDDING_VECTOR_1);
+  user1.SetEmbeddingVersion(5);
+
+  /* User1: enroll to profile 1 */
+  Result enroll_result = user1.Enroll(PROFILE_1);
+  EXPECT_REQ(enroll_result,
+             Result(FACEAUTH_SUCCESS).SetChallenge(user1.GetAuthID()));
+
+  /* User1: set feature */
+  EXPECT_REQ(user1.SetFeature(PROFILE_1, 0xFACEDEAD), Result(FACEAUTH_SUCCESS));
+
+  /* User1: authenticate successfully to profile 1 */
+  AuthenticateResult auth_result = user1.Authenticate(PROFILE_1);
+  EXPECT_AEQ(auth_result, SuccessfulAuthenticateResult(user1));
+
+  /* User1: migrate to profile 3 */
+  EXPECT_REQ(user1.SetEmbeddingVersion(8).Migrate(PROFILE_3, 1),
+             MigrateResult(FACEAUTH_SUCCESS).SetEmbeddingNum(1).SetMatch(true));
+
+  EXPECT_EQ(0xFACEDEAD, user1.GetFeature(PROFILE_3));
+
+  /* User1: authenticate successfully using profile 3 */
+  auth_result = user1.Authenticate(PROFILE_3);
+  EXPECT_AEQ(auth_result, SuccessfulAuthenticateResult(user1));
+}
+
+TEST_F(FaceAuthTest, SimpleAuthenticateMigrateFlow) {
+  User user1(EMBEDDING_VECTOR_1);
+  user1.SetEmbeddingVersion(1);
+
+  User user2(EMBEDDING_VECTOR_1);
+  user2.SetEmbeddingVersion(1);
+
+  /* User1: enroll to profile 1 */
+  Result enroll_result = user1.Enroll(PROFILE_1);
+  EXPECT_REQ(enroll_result,
+             Result(FACEAUTH_SUCCESS).SetChallenge(user1.GetAuthID()));
+
+  /* User2: enroll to profile 2 */
+  enroll_result = user2.Enroll(PROFILE_2);
+  EXPECT_REQ(enroll_result,
+             Result(FACEAUTH_SUCCESS).SetChallenge(user2.GetAuthID()));
+
+  /* User1: authenticate successfully to profile 1 */
+  AuthenticateResult auth_result = user1.Authenticate(PROFILE_1);
+  EXPECT_AEQ(auth_result, SuccessfulAuthenticateResult(user1));
+
+  /* User1: migrate to profile 3 */
+  EXPECT_REQ(user1.Migrate(PROFILE_3, 0), MigrateResult(FACEAUTH_SUCCESS));
+
+  /* User2: authenticate successfully to profile 2 */
+  auth_result = user2.Authenticate(PROFILE_2);
+  EXPECT_AEQ(auth_result, SuccessfulAuthenticateResult(user2));
+
+  /* User2: migrate to profile 3 should fail */
+  EXPECT_REQ(user2.Migrate(PROFILE_3, 0),
+             MigrateResult(FACEAUTH_ERR_INVALID_USER_ID));
+
+  /* User2: migrate to profile 4 */
+  EXPECT_REQ(user2.Migrate(PROFILE_4, 1),
+             MigrateResult(FACEAUTH_SUCCESS).SetEmbeddingNum(1).SetMatch(true));
+  EXPECT_REQ(user2.Migrate(PROFILE_4, 1),
+             MigrateResult(FACEAUTH_SUCCESS).SetEmbeddingNum(2).SetMatch(true));
+}
+
+TEST_F(FaceAuthTest, FiveAuthenticationFailureSequenceTest) {
+  User user1(EMBEDDING_VECTOR_1);
+  user1.SetEmbeddingVersion(1);
+
+  User user2(EMBEDDING_VECTOR_NULL);
+  user2.SetEmbeddingVersion(1);
+
+  /* Enroll to Profile 1 */
+  Result enroll_result = user1.Enroll(PROFILE_1);
+  EXPECT_REQ(enroll_result,
+             Result(FACEAUTH_SUCCESS).SetChallenge(user1.GetAuthID()));
+
+  /* Fail Authentication 4 times */
+  for (int i = 0; i < 4; ++i) {
+    EXPECT_REQ(user2.Authenticate(PROFILE_1),
+               AuthenticateResult(FACEAUTH_SUCCESS).SetMatch(false));
+  }
+
+  /* Fifth Authentication failure should trigger lockout event */
+  EXPECT_REQ(user2.Authenticate(PROFILE_1),
+             AuthenticateResult(FACEAUTH_SUCCESS)
+                 .SetMatch(false)
+                 .SetLockoutEvent(FACEAUTH_LOCKOUT_ENFORCED));
+
+  /* User will be throttled for 30 seconds */
+  Result result = user2.GetUserInfo(PROFILE_1);
+  EXPECT_GE(result.GetSecond(), 25);
+  EXPECT_REQ(
+      result,
+      Result(FACEAUTH_SUCCESS).SetSecond(result.GetSecond()).SetThird(1));
+
+  /* Following Authentication attempt will be throttled */
+  EXPECT_REQ(user2.Authenticate(PROFILE_1),
+             AuthenticateResult(FACEAUTH_ERR_THROTTLE));
+
+  /* Reset Lockout should trigger lockout event */
+  EXPECT_REQ(user1.ResetLockout(PROFILE_1),
+             ResetLockoutResult(FACEAUTH_SUCCESS)
+                 .SetLockoutEvent(FACEAUTH_LOCKOUT_REMOVED));
+}
+
+TEST_F(FaceAuthTest, ExhaustiveLockoutTest) {
+  vector<User> users;
+
+  for (int i = 0; i < MAX_NUM_PROFILES; ++i) {
+    users.push_back(User(EMBEDDING_VECTOR_NULL).SetEmbeddingVersion(1));
+    Result enroll_result = users[i].Enroll(i + 1);
+    EXPECT_REQ(enroll_result,
+               Result(FACEAUTH_SUCCESS).SetChallenge(users[i].GetAuthID()));
+    EXPECT_EQ(users[i].IsProfileLocked(i + 1), false);
+  }
+
+  bool lock_test_vectors[6] = {true, false, false, false, true, true};
+  for (int i = 0; i < MAX_NUM_PROFILES; ++i) {
+    if (lock_test_vectors[i]) {
+      users[i].LockProfile(i + 1);
+    }
+  }
+
+  for (int i = 0; i < MAX_NUM_PROFILES; ++i) {
+    EXPECT_EQ(users[i].IsProfileLocked(i + 1), lock_test_vectors[i]);
+  }
+
+  bool unlock_test_vectors[6] = {true, false, false, false, true, false};
+  for (int i = 0; i < MAX_NUM_PROFILES; ++i) {
+    if (unlock_test_vectors[i]) {
+      users[i].ResetLockout(i + 1);
+    }
+  }
+
+  for (int i = 0; i < MAX_NUM_PROFILES; ++i) {
+    EXPECT_EQ(users[i].IsProfileLocked(i + 1),
+              lock_test_vectors[i] && !unlock_test_vectors[i]);
+  }
+}
+
+TEST_F(FaceAuthTest, ExhaustiveFeatureTest) {
+  vector<User> users;
+
+  uint32_t feature_msk[MAX_NUM_PROFILES] = {0};
+  for (int i = 0; i < MAX_NUM_PROFILES; ++i) {
+    users.push_back(User(EMBEDDING_VECTOR_NULL).SetEmbeddingVersion(1));
+    Result enroll_result = users[i].Enroll(i + 1);
+    EXPECT_REQ(enroll_result,
+               Result(FACEAUTH_SUCCESS).SetChallenge(users[i].GetAuthID()));
+  }
+
+  uint32_t index = 0;
+  for (int k = 0; k < 5; ++k) {
+    for (int i = 0; i < MAX_NUM_PROFILES; ++i)
+      EXPECT_EQ(users[i].GetFeature(i + 1), feature_msk[i]);
+
+    for (int i = 0; i < MAX_NUM_PROFILES; ++i) {
+      EXPECT_REQ(users[i].SetFeature(i + 1, 1 << index),
+                 Result(FACEAUTH_SUCCESS));
+      feature_msk[i] |= (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 = 0; i < MAX_NUM_PROFILES; ++i)
+      EXPECT_EQ(users[i].GetFeature(i + 1), feature_msk[i]);
 
-    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);
+    for (int i = 0; i < MAX_NUM_PROFILES; ++i) {
+      EXPECT_REQ(users[i].ClrFeature(i + 1, 1 << index),
+                 Result(FACEAUTH_SUCCESS));
+      feature_msk[i] &= ~(1 << index);
       index++;
     }
   }
 }
 
-TEST_F(FaceAuthTest, EmbeddingVersionTest) {
-  uint64_t session_id = 0xFACE0000BBBB0000ull;
-  session_id++;
-  Run(MakeResult(session_id, FACEAUTH_SUCCESS, 0, 0, 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));
-}
+static void FullMatchMismatchTest(uint32_t profile_1, uint32_t profile_2,
+                                  uint32_t slot_1, uint32_t slot_2) {
+  User user1(EMBEDDING_VECTOR_1);
+  user1.SetEmbeddingVersion(1);
 
-TEST_F(FaceAuthTest, FirmwareVersionTest) {
-  uint64_t session_id = 0xFACE0000CCCC0000ull;
-  session_id++;
-  Run(MakeResult(session_id, FACEAUTH_SUCCESS, 0, 0, 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));
-}
+  User user2(EMBEDDING_VECTOR_NULL);
+  user2.SetEmbeddingVersion(1);
 
-TEST_F(FaceAuthTest, GetProfileInfoTest) {
-  uint64_t session_id = 0xFACE0000CCCC0000ull;
-  user_ids[1] = user_ids[4];
-  user_ids[2] = user_ids[4];
+  for (uint32_t i = 0; i < 20; ++i) {
+    Result result;
+    if (i == slot_1)
+      result = user1.SetEmbeddingBase(EMBEDDING_VECTOR_1).Enroll(profile_1);
+    else
+      result = user1.SetEmbeddingBase(EMBEDDING_VECTOR_NULL).Enroll(profile_1);
+    EXPECT_REQ(result,
+               Result(FACEAUTH_SUCCESS).SetChallenge(user1.GetAuthID()));
 
-  for (int i = 1; i <= MAX_NUM_PROFILES; ++i) {
-    session_id++;
-    fa_token_t token = MakeToken(i);
-    Run(MakeResult(session_id, FACEAUTH_SUCCESS, 0, 0, i),
-        MakeTask(session_id, i, FACEAUTH_CMD_ENROLL), MakeEmbedding(0x11),
-        &token);
+    if (i == slot_2)
+      result = user2.SetEmbeddingBase(EMBEDDING_VECTOR_2).Enroll(profile_2);
+    else
+      result = user2.SetEmbeddingBase(EMBEDDING_VECTOR_NULL).Enroll(profile_2);
+    EXPECT_REQ(result,
+               Result(FACEAUTH_SUCCESS).SetChallenge(user2.GetAuthID()));
   }
 
-  union {
-    uint8_t map[8];
-    struct {
-      uint32_t first;
-      uint32_t second;
-    };
-  } expected = {0};
+  user1.SetEmbeddingBase(EMBEDDING_VECTOR_1);
+  user2.SetEmbeddingBase(EMBEDDING_VECTOR_2);
 
-  for (int i = 0; i < MAX_NUM_PROFILES; ++i) {
-    for (int j = 0; j < MAX_NUM_PROFILES; ++j) {
-      expected.map[i] |= ((user_ids[i + 1] == user_ids[j + 1]) << j);
-    }
-  }
-
-  for (int i = 1; i <= MAX_NUM_PROFILES; ++i) {
-    session_id++;
-    fa_token_t token = MakeToken(i);
-    expected.map[MAX_NUM_PROFILES] = expected.map[i - 1];
-    Run(MakeResult(session_id, FACEAUTH_SUCCESS, expected.first,
-                   expected.second),
-        MakeTask(session_id, 1, FACEAUTH_CMD_GET_PROFILE_INFO),
-        MakeEmbedding(0x11), &token);
-  }
-
-  for (int i = 1; i <= MAX_NUM_PROFILES; ++i) {
-    session_id++;
-    Run(MakeResult(session_id, FACEAUTH_SUCCESS, 0, 0, expected.map[i - 1]),
-        MakeTask(session_id, i, FACEAUTH_CMD_GET_USER_INFO),
-        MakeEmbedding(0x11));
-  }
-}
-
-TEST_F(FaceAuthTest, EnrollShouldOnlyAcceptSameUser) {
-  uint64_t session_id = 0xFACE0000DDDD0000ull;
-  session_id++;
-
-  session_id++;
-  fa_token_t token = MakeToken(1);
-  Run(MakeResult(session_id, FACEAUTH_SUCCESS, 0, 0, 0x1),
-      MakeTask(session_id, 0x1, FACEAUTH_CMD_ENROLL), MakeEmbedding(0x11),
-      &token);
-  session_id++;
-  token = MakeToken(2);
-  Run(MakeResult(session_id, FACEAUTH_ERR_INVALID_TOKEN),
-      MakeTask(session_id, 0x1, FACEAUTH_CMD_ENROLL), MakeEmbedding(0x11),
-      &token);
-  session_id++;
-  token = MakeToken(1);
-  Run(MakeResult(session_id, FACEAUTH_SUCCESS, 0, 0, 0x1),
-      MakeTask(session_id, 0x1, FACEAUTH_CMD_ENROLL), MakeEmbedding(0x11),
-      &token);
-}
-
-TEST_F(FaceAuthTest, MigrateShouldOnlyAcceptSameUser) {
-  uint64_t session_id = 0xFACE0000DDDD0000ull;
-  session_id++;
-
-  session_id++;
-  fa_token_t token = MakeToken(1);
-  Run(MakeResult(session_id, FACEAUTH_SUCCESS, 0x1),
-      MakeTask(session_id, 0x1, FACEAUTH_CMD_MIGRATE), MakeEmbedding(0x11),
-      &token);
-  session_id++;
-  token = MakeToken(2);
-  Run(MakeResult(session_id, FACEAUTH_ERR_INVALID_TOKEN),
-      MakeTask(session_id, 0x1, FACEAUTH_CMD_MIGRATE), MakeEmbedding(0x11),
-      &token);
-  session_id++;
-  token = MakeToken(1);
-  Run(MakeResult(session_id, FACEAUTH_SUCCESS, 0x1),
-      MakeTask(session_id, 0x1, FACEAUTH_CMD_MIGRATE), MakeEmbedding(0x11),
-      &token);
-}
-
-TEST_F(FaceAuthTest, SimpleAuthenticateMigrateFlow) {
-  uint64_t session_id = 0xFACE0000EEEE0000ull;
-  session_id++;
-
-  session_id++;
-  fa_token_t token = MakeToken(1);
-  Run(MakeResult(session_id, FACEAUTH_SUCCESS, 0, 0, 0x1),
-      MakeTask(session_id, 0x1, FACEAUTH_CMD_ENROLL), MakeEmbedding(0x11),
-      &token);
-  session_id++;
-  token = MakeToken(2);
-  Run(MakeResult(session_id, FACEAUTH_SUCCESS, 0, 0, 0x2),
-      MakeTask(session_id, 0x2, FACEAUTH_CMD_ENROLL), MakeEmbedding(0x11),
-      &token);
-
-  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, 3, 0, FACEAUTH_NOMATCH),
-      MakeTask(session_id, 0x3, FACEAUTH_CMD_MIGRATE), MakeEmbedding(0x11));
-
-  session_id++;
-  Run(MakeResult(session_id, FACEAUTH_SUCCESS, FACEAUTH_MATCH),
-      MakeTask(session_id, 0x2, FACEAUTH_CMD_COMP), MakeEmbedding(0x11));
-  session_id++;
-  Run(MakeResult(session_id, FACEAUTH_ERR_INVALID_TOKEN),
-      MakeTask(session_id, 0x3, FACEAUTH_CMD_MIGRATE), MakeEmbedding(0x11));
-  session_id++;
-  Run(MakeResult(session_id, FACEAUTH_SUCCESS, 4, 1, FACEAUTH_MATCH),
-      MakeTask(session_id, 0x4, FACEAUTH_CMD_MIGRATE, 1), MakeEmbedding(0x11));
-  session_id++;
-  Run(MakeResult(session_id, FACEAUTH_SUCCESS, 4, 2, FACEAUTH_MATCH),
-      MakeTask(session_id, 0x4, FACEAUTH_CMD_MIGRATE, 1), MakeEmbedding(0x11));
-
-  session_id++;
-  Run(MakeResult(session_id, FACEAUTH_SUCCESS, FACEAUTH_NOMATCH),
-      MakeTask(session_id, 0x3, FACEAUTH_CMD_COMP), MakeEmbedding(0x11));
-  session_id++;
-  Run(MakeResult(session_id, FACEAUTH_SUCCESS, FACEAUTH_MATCH),
-      MakeTask(session_id, 0x4, FACEAUTH_CMD_COMP), MakeEmbedding(0x11));
+  AuthenticateResult auth_result = user1.Authenticate(profile_1);
+  EXPECT_AEQ(auth_result, SuccessfulAuthenticateResult(user1));
+  auth_result = user2.Authenticate(profile_1);
+  EXPECT_REQ(auth_result, AuthenticateResult(FACEAUTH_SUCCESS).SetMatch(false));
+  auth_result = user1.Authenticate(profile_2);
+  EXPECT_REQ(auth_result, AuthenticateResult(FACEAUTH_SUCCESS).SetMatch(false));
+  auth_result = user2.Authenticate(profile_2);
+  EXPECT_AEQ(auth_result, SuccessfulAuthenticateResult(user2));
 }
 
 TEST_F(FaceAuthTest, ExhaustiveMatchMismatchTest) {
-  FullMatchMismatchTest(1, 6, 0, 19);
-  FullMatchMismatchTest(2, 5, 1, 18);
-  FullMatchMismatchTest(3, 4, 2, 17);
+  FullMatchMismatchTest(PROFILE_1, PROFILE_6, 0, 19);
+  FullMatchMismatchTest(PROFILE_2, PROFILE_5, 1, 18);
+  FullMatchMismatchTest(PROFILE_3, PROFILE_4, 2, 17);
   SetUp();
-  FullMatchMismatchTest(2, 4, 3, 16);
-  FullMatchMismatchTest(1, 5, 4, 15);
-  FullMatchMismatchTest(3, 6, 5, 14);
+  FullMatchMismatchTest(PROFILE_2, PROFILE_4, 3, 16);
+  FullMatchMismatchTest(PROFILE_1, PROFILE_5, 4, 15);
+  FullMatchMismatchTest(PROFILE_3, PROFILE_6, 5, 14);
   SetUp();
-  FullMatchMismatchTest(3, 5, 6, 13);
-  FullMatchMismatchTest(1, 4, 7, 12);
-  FullMatchMismatchTest(2, 6, 8, 11);
+  FullMatchMismatchTest(PROFILE_3, PROFILE_5, 6, 13);
+  FullMatchMismatchTest(PROFILE_1, PROFILE_4, 7, 12);
+  FullMatchMismatchTest(PROFILE_2, PROFILE_6, 8, 11);
   SetUp();
-  FullMatchMismatchTest(3, 6, 9, 10);
+  FullMatchMismatchTest(PROFILE_3, PROFILE_6, 9, 10);
 }
 }
 
