Support averaging power values

Support new env variables 'AVERAGE_power* = "true"' in hwmon config file.
When this env variable is set, power value is the calculated average value.
Otherwise, power value is from power*_input by default.
The new average of power is calculated since the last time the sensor's
values were changed and read.

average =
(cur_average*cur_average_interval - pre_average*pre_average_interval) /
(cur_average_interval - pre_average_interval)

hwmon config example:
AVERAGE_power2 = "true"
AVERAGE_power3 = "true"
AVERAGE_power4 = "true"

Tested: Set AVERAGE_power* in p0 OCC hwmon conf but not in p1 OCC hwmon conf,
then get power sensor info with restapi to check the values.
1. The values of p0*power are all average values.
2. The values of p1*power are all input values.

Note:
Delete $(CODE_COVERAGE_CPPFLAGS) in AM_CPPFLAGS in test/Makefile.am.
This option will define NDEBUG during configuration, then assert in
code doesn't work.

Resolves: openbmc/openbmc#3187
Signed-off-by: Carol Wang <wangkair@cn.ibm.com>
Change-Id: I8d97a7b2905c79cd4f2c276b32e7f5590ffc0483
diff --git a/test/Makefile.am b/test/Makefile.am
index a40391a..dce609a 100644
--- a/test/Makefile.am
+++ b/test/Makefile.am
@@ -5,8 +5,7 @@
 	$(GTEST_CFLAGS) \
 	$(GMOCK_CFLAGS) \
 	$(SDBUSPLUS_CFLAGS) \
-	$(PHOSPHOR_DBUS_INTERFACES_CFLAGS) \
-	$(CODE_COVERAGE_CPPFLAGS)
+	$(PHOSPHOR_DBUS_INTERFACES_CFLAGS)
 AM_CFLAGS = \
 	$(CODE_COVERAGE_CFLAGS)
 AM_CXXFLAGS = \
@@ -21,9 +20,15 @@
 	$(CODE_COVERAGE_LIBS)
 
 # Run all 'check' test programs
-check_PROGRAMS = hwmon_unittest fanpwm_unittest sensor_unittest hwmonio_default_unittest
+check_PROGRAMS = hwmon_unittest fanpwm_unittest sensor_unittest hwmonio_default_unittest env_unittest average_unittest
 TESTS = $(check_PROGRAMS)
 
+env_unittest_SOURCES = env_unittest.cpp
+env_unittest_LDADD = env.o
+
+average_unittest_SOURCES = average_unittest.cpp
+average_unittest_LDADD = $(top_builddir)/average.o
+
 hwmon_unittest_SOURCES = hwmon_unittest.cpp
 hwmon_unittest_LDADD = $(top_builddir)/hwmon.o
 
diff --git a/test/average_unittest.cpp b/test/average_unittest.cpp
new file mode 100644
index 0000000..9eef0f8
--- /dev/null
+++ b/test/average_unittest.cpp
@@ -0,0 +1,49 @@
+#include "average.hpp"
+
+#include <gmock/gmock.h>
+#include <gtest/gtest.h>
+
+using ::testing::Return;
+
+TEST(SensorKeyTest, InvalidSensorKey)
+{
+    Average av;
+
+    av.setAverageValue(std::make_pair("power", "0"), std::make_pair(0L, 0L));
+    av.setAverageValue(std::make_pair("power", "1"), std::make_pair(0L, 0L));
+
+    EXPECT_FALSE(av.getAverageValue(std::make_pair("power", "4")));
+}
+
+TEST(SensorKeyTest, ValidSensorKey)
+{
+    Average av;
+
+    av.setAverageValue(std::make_pair("power", "0"), std::make_pair(0L, 0L));
+    av.setAverageValue(std::make_pair("power", "1"), std::make_pair(2L, 2L));
+
+    auto value = av.getAverageValue(std::make_pair("power", "1"));
+    EXPECT_TRUE(value == std::make_pair(2L, 2L));
+}
+
+TEST(AverageTest, ZeroDelta)
+{
+    Average av;
+
+    EXPECT_FALSE(av.calcAverage(1L, 1L, 2L, 1L));
+}
+
+TEST(AverageTest, NegativeDelta)
+{
+    Average av;
+
+    ASSERT_DEATH(av.calcAverage(1L, 1L, 2L, 0L), "");
+}
+
+TEST(AverageTest, RightAverage)
+{
+    Average av;
+
+    EXPECT_TRUE(38837438L == av.calcAverage(27624108L, 132864155500L, 27626120L,
+                                            132887999500L));
+}
diff --git a/test/env_unittest.cpp b/test/env_unittest.cpp
new file mode 100644
index 0000000..665f8a5
--- /dev/null
+++ b/test/env_unittest.cpp
@@ -0,0 +1,35 @@
+#include "env.hpp"
+#include "env_mock.hpp"
+#include "util.hpp"
+
+#include <gmock/gmock.h>
+#include <gtest/gtest.h>
+
+using ::testing::Return;
+using ::testing::StrEq;
+using ::testing::StrictMock;
+
+TEST(EnvTest, EmptyEnv)
+{
+    EXPECT_FALSE(
+        phosphor::utility::isAverageEnvSet(std::make_pair("power", "1")));
+}
+
+TEST(EnvTest, ValidAverageEnv)
+{
+    StrictMock<EnvMock> eMock;
+    envIntf = &eMock;
+
+    std::string power = "power";
+    std::string one = "1";
+    std::string two = "2";
+
+    EXPECT_CALL(eMock, getEnv(StrEq("AVERAGE"), power, one))
+        .WillOnce(Return("true"));
+    EXPECT_CALL(eMock, getEnv(StrEq("AVERAGE"), power, two))
+        .WillOnce(Return("bar"));
+
+    EXPECT_TRUE(phosphor::utility::isAverageEnvSet(std::make_pair(power, one)));
+    EXPECT_FALSE(
+        phosphor::utility::isAverageEnvSet(std::make_pair(power, two)));
+}