Add unit test for Attention class

Signed-off-by: austinfcui <austinfcui@gmail.com>
Change-Id: Ia1f451b7e990ecdf29903944e12c5a9ea5585eeb
diff --git a/test/meson.build b/test/meson.build
index 2f04365..82c972e 100644
--- a/test/meson.build
+++ b/test/meson.build
@@ -229,3 +229,24 @@
                  cpp_args: test_arg, include_directories: incdir)
 
 test(tc, exe, env: var)
+
+################################################################################
+
+tc = 'test-attention'
+
+src = [
+  files(
+    tc + '.cpp',
+  ),
+  pdbg_test_dtb,
+]
+
+dep = [ gtest_dep ]
+
+var = [ pdbg_env ]
+
+exe = executable(tc.underscorify(), src, dependencies: dep,
+                 link_with : hwdiags_libs,
+                 cpp_args: test_arg, include_directories: incdir)
+
+test(tc, exe, env: var)
diff --git a/test/test-attention.cpp b/test/test-attention.cpp
new file mode 100644
index 0000000..ec92089
--- /dev/null
+++ b/test/test-attention.cpp
@@ -0,0 +1,171 @@
+#include <attn/attention.hpp>
+#include <attn/attn_common.hpp>
+#include <attn/attn_config.hpp>
+#include <attn/attn_handler.hpp>
+#include <util/pdbg.hpp>
+#include <util/trace.hpp>
+
+#include "gtest/gtest.h"
+
+namespace attn
+{
+// these are in the attn_lib but not all exposed via headers
+int handleSpecial(Attention* i_attention);
+} // namespace attn
+
+using namespace attn;
+using namespace util::pdbg;
+
+/** @brief global function to be called back. */
+int handleAttention(Attention* attention)
+{
+    int rc = RC_SUCCESS;
+    if (attention != nullptr)
+    {
+        return rc;
+    }
+    else
+    {
+        return RC_NOT_HANDLED;
+    }
+}
+
+// Global variables for UT #1 and UT#2.
+// Attention type
+Attention::AttentionType gType = Attention::AttentionType::Special;
+// pointer to handler callback function
+int (*gHandler)(Attention*)   = &(handleSpecial);
+const AttentionFlag gAttnFlag = AttentionFlag::enBreakpoints;
+
+// Start preparation for UT case #1.
+
+// Global variables for UT #1
+const char* gPosPath = "/proc0/pib/perv12";
+const uint32_t gPos  = 12;
+
+/** @brief Fixture class for TEST_F(). */
+class AttentionTestPos : public testing::Test
+{
+  public:
+    AttentionTestPos() {}
+
+    void SetUp()
+    {
+        pdbg_targets_init(nullptr);
+
+        target = pdbg_target_from_path(nullptr, gPosPath);
+        EXPECT_NE(nullptr, target);
+
+        config = new Config;
+        EXPECT_EQ(true, config->getFlag(gAttnFlag));
+
+        pAttn = std::make_unique<Attention>(
+            Attention(gType, gHandler, target, config));
+    }
+
+    void TearDown()
+    {
+        delete config;
+    }
+
+    std::unique_ptr<Attention> pAttn;
+    Config* config;
+    pdbg_target* target = nullptr;
+};
+
+TEST_F(AttentionTestPos, TestAttnTargetPos)
+{
+    EXPECT_EQ(0, pAttn->getPriority());
+    EXPECT_EQ(RC_SUCCESS, pAttn->handle());
+
+    // Verify the global target_tmp.
+    EXPECT_NE(nullptr, target);
+    uint32_t attr = std::numeric_limits<uint32_t>::max();
+    pdbg_target_get_attribute(target, "ATTR_FAPI_POS", 4, 1, &attr);
+    EXPECT_EQ(gPos, attr);
+
+    // Verify the target in Attention object.
+    attr                    = std::numeric_limits<uint32_t>::max();
+    pdbg_target* target_tmp = pAttn->getTarget();
+    EXPECT_NE(nullptr, target_tmp);
+    pdbg_target_get_attribute(target_tmp, "ATTR_FAPI_POS", 4, 1, &attr);
+    EXPECT_EQ(gPos, attr);
+
+    // Verify the config in Attention object.
+    Config* config_tmp = pAttn->getConfig();
+    EXPECT_EQ(true, config_tmp->getFlag(gAttnFlag));
+    config_tmp->clearFlag(gAttnFlag);
+    EXPECT_EQ(false, config_tmp->getFlag(gAttnFlag));
+    config_tmp->setFlag(gAttnFlag);
+    EXPECT_EQ(true, config_tmp->getFlag(gAttnFlag));
+}
+
+// Start preparation for UT case #2.
+
+// Global variables for UT #2
+const uint32_t gChipId = 0; // ID for proc0.
+
+/** @brief Fixture class for TEST_F(). */
+class AttentionTestProc : public testing::Test
+{
+  public:
+    AttentionTestProc() {}
+
+    void SetUp()
+    {
+        pdbg_targets_init(nullptr);
+        target = getPrimaryProcessor();
+
+        EXPECT_NE(nullptr, target);
+
+        attr = std::numeric_limits<uint32_t>::max();
+        attr = getTrgtType(target);
+
+        EXPECT_EQ(TYPE_PROC, attr);
+
+        attr = std::numeric_limits<uint32_t>::max();
+        pdbg_target_get_attribute(target, "ATTR_CHIP_ID", 4, 1, &attr);
+        EXPECT_EQ(attr, gChipId);
+
+        config = new Config;
+        EXPECT_EQ(true, config->getFlag(gAttnFlag));
+
+        pAttn = std::make_unique<Attention>(
+            Attention(gType, gHandler, target, config));
+    }
+
+    void TearDown()
+    {
+        delete config;
+    }
+
+    std::unique_ptr<Attention> pAttn;
+    Config* config;
+    pdbg_target* target = nullptr;
+    uint32_t attr;
+};
+
+TEST_F(AttentionTestProc, TestAttentionProc)
+{
+    EXPECT_EQ(0, pAttn->getPriority());
+    EXPECT_EQ(RC_SUCCESS, pAttn->handle());
+
+    // Verify the target in Attention object.
+    attr                    = std::numeric_limits<uint32_t>::max();
+    pdbg_target* target_tmp = pAttn->getTarget();
+    EXPECT_NE(nullptr, target_tmp);
+    attr = getTrgtType(target_tmp);
+    EXPECT_EQ(TYPE_PROC, attr);
+
+    attr = std::numeric_limits<uint32_t>::max();
+    pdbg_target_get_attribute(target_tmp, "ATTR_CHIP_ID", 4, 1, &attr);
+    EXPECT_EQ(attr, gChipId);
+
+    // Verify the config in Attention object.
+    Config* config_tmp = pAttn->getConfig();
+    EXPECT_EQ(true, config_tmp->getFlag(gAttnFlag));
+    config_tmp->clearFlag(gAttnFlag);
+    EXPECT_EQ(false, config_tmp->getFlag(gAttnFlag));
+    config_tmp->setFlag(gAttnFlag);
+    EXPECT_EQ(true, config_tmp->getFlag(gAttnFlag));
+}
\ No newline at end of file