--- /dev/null
+/*
+ * test
+ *
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#include <stdio.h>
+#include "test.h"
+
+#define METHOD_BATTERY_TIMETOFULL "TimeToFull"
+#define METHOD_BATTERY_TIMETOEMPTY "TimeToEmpty"
+#define METHOD_BATTERY_SETLOWBATLEVEL "SetLowbatLevel"
+#define METHOD_BATTERY_GETLOWBATLEVEL "GetLowbatLevel"
+#define METHOD_BATTERY_CHARGERSTATUS "ChargerStatus"
+#define METHOD_BATTERY_CHARGENOW "ChargeNow"
+#define METHOD_BATTERY_STATUSLOW "BatteryStatusLow"
+#define METHOD_BATTERY_GETPERCENT "GetPercent"
+#define METHOD_BATTERY_GETPERCENTRAW "GetPercentRaw"
+#define METHOD_BATTERY_ISFULL "IsFull"
+#define METHOD_BATTERY_HEALTH "GetHealth"
+#define METHOD_BATTERY_GETINFO "GetBatteryInfo"
+#define METHOD_BATTERY_POWERSUPPLY "power_supply"
+
+#define CHARGEFULL_NAME "Full"
+#define CHARGENOW_NAME "Charging"
+#define DISCHARGE_NAME "Discharging"
+#define NOTCHARGE_NAME "Not charging"
+
+#define GOOD_NAME "Good"
+#define OVERHEAT_NAME "Overheat"
+#define TEMPCOLD_NAME "Cold"
+#define OVERVOLT_NAME "Over voltage"
+
+#define POWER_SUPPLY_TYPE_BATTERY "1"
+#define POWER_SUPPLY_TYPE_UPS "2"
+
+#define PRESENT_ABNORMAL "0"
+#define PRESENT_NORMAL "1"
+
+#define DEFAULT_LOWBATLEVEL 15
+
+#define S_ENTER 1
+#define S_LEAVE 0
+
+static struct power_supply_type {
+ char *scenario;
+ int status;
+ char *capacity;
+ char *charge_status;
+ char *health;
+ char *online;
+ char *present;
+ char *name;
+} power_supply_types[] = {
+ {"norm", S_ENTER, "100", CHARGENOW_NAME, GOOD_NAME, POWER_SUPPLY_TYPE_UPS, PRESENT_NORMAL, "CHARGE"},
+ {"norm", S_ENTER, "100", DISCHARGE_NAME, GOOD_NAME, POWER_SUPPLY_TYPE_BATTERY, PRESENT_NORMAL, "DISCHARGE"},
+ {"norm", S_LEAVE, "100", DISCHARGE_NAME, GOOD_NAME, POWER_SUPPLY_TYPE_BATTERY, PRESENT_NORMAL, NULL}, /* init */
+
+ {"heat1", S_ENTER, "100", DISCHARGE_NAME, OVERHEAT_NAME, POWER_SUPPLY_TYPE_BATTERY, PRESENT_NORMAL, NULL},
+ {"heat1", S_ENTER, "100", NOTCHARGE_NAME, OVERHEAT_NAME, POWER_SUPPLY_TYPE_UPS, PRESENT_NORMAL, "HEALTH(H) BEFORE CHARGE"},
+ {"heat1", S_LEAVE, "100", DISCHARGE_NAME, OVERHEAT_NAME, POWER_SUPPLY_TYPE_BATTERY, PRESENT_NORMAL, "DISCHARGE"},
+ {"heat1", S_LEAVE, "100", DISCHARGE_NAME, GOOD_NAME, POWER_SUPPLY_TYPE_BATTERY, PRESENT_NORMAL, NULL}, /* init */
+
+ {"heat2", S_ENTER, "100", CHARGENOW_NAME, GOOD_NAME, POWER_SUPPLY_TYPE_UPS, PRESENT_NORMAL, NULL},
+ {"heat2", S_ENTER, "100", NOTCHARGE_NAME, OVERHEAT_NAME, POWER_SUPPLY_TYPE_UPS, PRESENT_NORMAL, "HEALTH(H) AFTER CHARGE"},
+ {"heat2", S_LEAVE, "100", DISCHARGE_NAME, OVERHEAT_NAME, POWER_SUPPLY_TYPE_BATTERY, PRESENT_NORMAL, "DISCHARGE"},
+ {"heat2", S_LEAVE, "100", DISCHARGE_NAME, GOOD_NAME, POWER_SUPPLY_TYPE_BATTERY, PRESENT_NORMAL, NULL}, /* init */
+
+ {"cold1", S_ENTER, "100", DISCHARGE_NAME, TEMPCOLD_NAME, POWER_SUPPLY_TYPE_BATTERY, PRESENT_NORMAL, NULL},
+ {"cold1", S_ENTER, "100", NOTCHARGE_NAME, TEMPCOLD_NAME, POWER_SUPPLY_TYPE_UPS, PRESENT_NORMAL, "HEALTH(L) BEFORE CHARGE"},
+ {"cold1", S_LEAVE, "100", DISCHARGE_NAME, TEMPCOLD_NAME, POWER_SUPPLY_TYPE_BATTERY, PRESENT_NORMAL, "DISCHARGE"},
+ {"cold1", S_LEAVE, "100", DISCHARGE_NAME, GOOD_NAME, POWER_SUPPLY_TYPE_BATTERY, PRESENT_NORMAL, NULL}, /* init */
+
+ {"cold2", S_ENTER, "100", CHARGENOW_NAME, GOOD_NAME, POWER_SUPPLY_TYPE_UPS, PRESENT_NORMAL, NULL},
+ {"cold2", S_ENTER, "100", NOTCHARGE_NAME, TEMPCOLD_NAME, POWER_SUPPLY_TYPE_UPS, PRESENT_NORMAL, "HEALTH(L) AFTER CHARGE"},
+ {"cold2", S_LEAVE, "100", DISCHARGE_NAME, TEMPCOLD_NAME, POWER_SUPPLY_TYPE_BATTERY, PRESENT_NORMAL, "DISCHARGE"},
+ {"cold2", S_LEAVE, "100", DISCHARGE_NAME, GOOD_NAME, POWER_SUPPLY_TYPE_BATTERY, PRESENT_NORMAL, NULL}, /* init */
+
+ {"ovp", S_ENTER, "100", DISCHARGE_NAME, OVERVOLT_NAME, POWER_SUPPLY_TYPE_BATTERY, PRESENT_NORMAL, "OVP"},
+ {"ovp", S_LEAVE, "100", DISCHARGE_NAME, GOOD_NAME, POWER_SUPPLY_TYPE_BATTERY, PRESENT_NORMAL, NULL}, /* init */
+
+ {"pres1", S_ENTER, "100", DISCHARGE_NAME, GOOD_NAME, POWER_SUPPLY_TYPE_BATTERY, PRESENT_ABNORMAL, NULL},
+ {"pres1", S_ENTER, "100", NOTCHARGE_NAME, GOOD_NAME, POWER_SUPPLY_TYPE_UPS, PRESENT_ABNORMAL, "PRESENT BEFORE CHARGE"},
+ {"pres1", S_LEAVE, "100", DISCHARGE_NAME, GOOD_NAME, POWER_SUPPLY_TYPE_BATTERY, PRESENT_ABNORMAL, "DISCHARGE"},
+ {"pres1", S_LEAVE, "100", DISCHARGE_NAME, GOOD_NAME, POWER_SUPPLY_TYPE_BATTERY, PRESENT_NORMAL, NULL}, /* init */
+
+ {"pres2", S_ENTER, "100", CHARGENOW_NAME, GOOD_NAME, POWER_SUPPLY_TYPE_UPS, PRESENT_NORMAL, NULL},
+ {"pres2", S_ENTER, "100", NOTCHARGE_NAME, GOOD_NAME, POWER_SUPPLY_TYPE_UPS, PRESENT_ABNORMAL, "PRESENT AFTER CHARGE"},
+ {"pres2", S_LEAVE, "100", DISCHARGE_NAME, GOOD_NAME, POWER_SUPPLY_TYPE_BATTERY, PRESENT_ABNORMAL, "DISCHARGE"},
+ {"pres2", S_LEAVE, "100", DISCHARGE_NAME, GOOD_NAME, POWER_SUPPLY_TYPE_BATTERY, PRESENT_NORMAL, NULL}, /* init */
+
+ {"bat15", S_ENTER, "15", DISCHARGE_NAME, GOOD_NAME, POWER_SUPPLY_TYPE_BATTERY, PRESENT_NORMAL, "LOWBAT 15%"}, /* lowbat 15% */
+ {"bat15", S_LEAVE, "15", CHARGENOW_NAME, GOOD_NAME, POWER_SUPPLY_TYPE_UPS, PRESENT_NORMAL, "LOWBAT 15%"},
+ {"bat5", S_ENTER, "5", DISCHARGE_NAME, GOOD_NAME, POWER_SUPPLY_TYPE_BATTERY, PRESENT_NORMAL, "LOWBAT 5%"}, /* lowbat 5% */
+ {"bat5", S_LEAVE, "5", CHARGENOW_NAME, GOOD_NAME, POWER_SUPPLY_TYPE_UPS, PRESENT_NORMAL, "LOWBAT 5%"},
+ {"bat3", S_ENTER, "3", DISCHARGE_NAME, GOOD_NAME, POWER_SUPPLY_TYPE_BATTERY, PRESENT_NORMAL, "LOWBAT 3%"}, /* lowbat 3% */
+ {"bat3", S_LEAVE, "3", CHARGENOW_NAME, GOOD_NAME, POWER_SUPPLY_TYPE_UPS, PRESENT_NORMAL, "LOWBAT 3%"},
+ {"bat1", S_ENTER, "1", DISCHARGE_NAME, GOOD_NAME, POWER_SUPPLY_TYPE_BATTERY, PRESENT_NORMAL, "LOWBAT 1%"}, /* lowbat 1% */
+ {"bat1", S_LEAVE, "1", CHARGENOW_NAME, GOOD_NAME, POWER_SUPPLY_TYPE_UPS, PRESENT_NORMAL, "LOWBAT 1%"},
+
+ {"ta", S_ENTER, "100", CHARGENOW_NAME, GOOD_NAME, POWER_SUPPLY_TYPE_UPS, PRESENT_NORMAL, "CHARGE"}, /* charging */
+ {"ta", S_LEAVE, "100", DISCHARGE_NAME, GOOD_NAME, POWER_SUPPLY_TYPE_BATTERY, PRESENT_NORMAL, "DISCHARGE"},/* discharging */
+
+ {"full", S_ENTER, "100", CHARGEFULL_NAME, GOOD_NAME, POWER_SUPPLY_TYPE_UPS, PRESENT_NORMAL, "CHARGE"}, /* full */
+ {"full", S_LEAVE, "100", DISCHARGE_NAME, GOOD_NAME, POWER_SUPPLY_TYPE_BATTERY, PRESENT_NORMAL, "DISCHARGE"},/* discharging */
+
+ {"capa", S_ENTER, "100", DISCHARGE_NAME, GOOD_NAME, POWER_SUPPLY_TYPE_BATTERY, PRESENT_NORMAL, "CAPACITY"},/* discharging */
+ {"capa", S_LEAVE, "100", CHARGENOW_NAME, GOOD_NAME, POWER_SUPPLY_TYPE_UPS, PRESENT_NORMAL, "CAPACITY"},/* charging */
+};
+
+
+static bool get_battery_method(const char *method, int *value)
+{
+ DBusMessage *msg;
+ int val;
+ bool ret = FALSE;
+
+ msg = dbus_method_sync_with_reply(DEVICED_BUS_NAME,
+ DEVICED_PATH_BATTERY,
+ DEVICED_INTERFACE_BATTERY,
+ method, NULL, NULL);
+ if (!msg) {
+ _E("fail (%s): no reply", method);
+ return ret;
+ }
+
+ if (dbus_message_get_args(msg, NULL, DBUS_TYPE_INT32, &val, DBUS_TYPE_INVALID) == 0)
+ _E("fail (%s): no message", method);
+ else {
+ _I("success (%s): %d", method, val);
+ ret = TRUE;
+ if (NULL != value)
+ *value = val;
+ }
+
+ dbus_message_unref(msg);
+ return ret;
+}
+
+static bool get_battery_method_vconf(const char *method)
+{
+ DBusMessage *msg;
+ int val;
+ bool ret = FALSE;
+
+ msg = dbus_method_sync_with_reply(DEVICED_BUS_NAME,
+ DEVICED_PATH_BATTERY,
+ DEVICED_INTERFACE_BATTERY,
+ method, NULL, NULL);
+ if (!msg) {
+ _E("fail (%s): no reply", method);
+ return ret;
+ }
+
+ if (dbus_message_get_args(msg, NULL, DBUS_TYPE_INT32, &val, DBUS_TYPE_INVALID) == 0)
+ _E("fail (%s): no message", method);
+ else {
+ if (val == -EIO) {
+ _E("fail (%s): return fail", method);
+ } else {
+ _I("success (%s): %d", method, val);
+ ret = TRUE;
+ }
+ }
+
+ dbus_message_unref(msg);
+ return ret;
+}
+
+static bool get_battery_time_to_full(void)
+{
+ return get_battery_method(METHOD_BATTERY_TIMETOFULL, NULL);
+}
+
+static bool get_battery_time_to_empty(void)
+{
+ return get_battery_method(METHOD_BATTERY_TIMETOEMPTY, NULL);
+}
+
+static bool get_battery_low_level(int *value)
+{
+ return get_battery_method(METHOD_BATTERY_GETLOWBATLEVEL, value);
+}
+
+static bool set_battery_low_level(int newlevel)
+{
+ DBusMessage *msg;
+ int getlevel = -1;
+ int val = -1;
+ char *param[1];
+ char str_mode[10];
+ bool ret = FALSE;
+
+ snprintf(str_mode, sizeof(str_mode), "%d", newlevel);
+ param[0] = str_mode;
+
+ msg = dbus_method_sync_with_reply(DEVICED_BUS_NAME,
+ DEVICED_PATH_BATTERY,
+ DEVICED_INTERFACE_BATTERY,
+ METHOD_BATTERY_SETLOWBATLEVEL, "i", param);
+
+ if (!msg) {
+ _E("fail : no reply");
+ return ret;
+ }
+
+ if (dbus_message_get_args(msg, NULL, DBUS_TYPE_INT32, &val, DBUS_TYPE_INVALID) == 0) {
+ _E("fail : no message");
+ goto out;
+ } else {
+ if (newlevel <= DEFAULT_LOWBATLEVEL) {
+ if (0 != val) {
+ _I("success : can't set low level (%d) smaller than default (%d)", newlevel, DEFAULT_LOWBATLEVEL);
+ ret = TRUE;
+ } else {
+ _E("fail : can't set low level (%d) smaller than default (%d), but returned success", newlevel, DEFAULT_LOWBATLEVEL);
+ }
+ goto out;
+ } else {
+ if (0 != val) {
+ _E("fail : return fail");
+ goto out;
+ }
+ }
+ }
+
+ if (!get_battery_low_level(&getlevel)) {
+ _E("fail : can't get battery low level");
+ } else {
+ if (getlevel == newlevel) {
+ _I("success : %d", newlevel);
+ ret = TRUE;
+ } else {
+ _E("fail : set low level %d, but current low level %d", newlevel, getlevel);
+ }
+ }
+out:
+ dbus_message_unref(msg);
+ return ret;
+}
+
+static bool get_battery_charger_status()
+{
+ return get_battery_method_vconf(METHOD_BATTERY_CHARGERSTATUS);
+}
+
+static bool get_battery_charge_now()
+{
+ return get_battery_method(METHOD_BATTERY_CHARGENOW, NULL);
+}
+
+static bool get_battery_status_low()
+{
+ return get_battery_method_vconf(METHOD_BATTERY_STATUSLOW);
+}
+
+static bool get_battery_percent()
+{
+ return get_battery_method(METHOD_BATTERY_GETPERCENT, NULL);
+}
+
+static bool get_battery_percent_raw()
+{
+ return get_battery_method(METHOD_BATTERY_GETPERCENTRAW, NULL);
+}
+
+static bool get_battery_is_full()
+{
+ return get_battery_method(METHOD_BATTERY_ISFULL, NULL);
+}
+
+static bool get_battery_health()
+{
+ return get_battery_method(METHOD_BATTERY_HEALTH, NULL);
+}
+
+static bool get_battery_info()
+{
+ DBusMessage *msg;
+ int val[6];
+ bool ret = FALSE;
+ char *argv[3];
+
+ msg = dbus_method_sync_with_reply(DEVICED_BUS_NAME,
+ DEVICED_PATH_BATTERY,
+ DEVICED_INTERFACE_BATTERY,
+ METHOD_BATTERY_GETINFO, NULL, NULL);
+ if (!msg) {
+ _E("fail: no reply");
+ return ret;
+ }
+
+ if (dbus_message_get_args(msg, NULL,
+ DBUS_TYPE_INT32, &val[0], //return value
+ DBUS_TYPE_STRING, &argv[0], //status
+ DBUS_TYPE_STRING, &argv[1], //health
+ DBUS_TYPE_STRING, &argv[2], //power source
+ DBUS_TYPE_INT32, &val[1], //online
+ DBUS_TYPE_INT32, &val[2], //present
+ DBUS_TYPE_INT32, &val[3], //capacity
+ DBUS_TYPE_INT32, &val[4], //current_now
+ DBUS_TYPE_INT32, &val[5], //current_average
+ DBUS_TYPE_INVALID) == 0)
+ _E("fail: no message");
+ else {
+ if (val[0] < 0) {
+ _E("fail: return fail");
+ } else {
+ _I("success: %s %s %s %d %d %d %d %d", argv[0], argv[1], argv[2], val[1], val[2], val[3], val[4], val[5]);
+ ret = TRUE;
+ }
+ }
+
+ dbus_message_unref(msg);
+ return ret;
+}
+
+static bool set_battery_power_supply(int index)
+{
+ DBusError err;
+ DBusMessage *msg;
+ int val;
+ bool ret = FALSE;
+ char *param[7];
+
+ param[0] = POWER_SUBSYSTEM;
+ param[1] = "5";
+ param[2] = power_supply_types[index].capacity;
+ param[3] = power_supply_types[index].charge_status;
+ param[4] = power_supply_types[index].health;
+ param[5] = power_supply_types[index].online;
+ param[6] = power_supply_types[index].present;
+
+ _I("C(%s , %s) P(%s) STATUS(%s) HEALTH(%s)",
+ power_supply_types[index].capacity,
+ power_supply_types[index].online,
+ power_supply_types[index].present,
+ power_supply_types[index].charge_status,
+ power_supply_types[index].health);
+
+ msg = dbus_method_sync_with_reply(DEVICED_BUS_NAME,
+ DEVICED_PATH_BATTERY,
+ DEVICED_INTERFACE_BATTERY,
+ POWER_SUBSYSTEM, "sisssss", param);
+ if (!msg) {
+ _E("fail: no reply");
+ return ret;
+ }
+
+ dbus_error_init(&err);
+
+ if (dbus_message_get_args(msg, &err, DBUS_TYPE_INT32, &val, DBUS_TYPE_INVALID) == 0) {
+ _E("fail: no message : [%s:%s]", err.name, err.message);
+ val = -EBADMSG;
+ } else {
+ if (val < 0) {
+ _E("fail: return fail");
+ } else {
+ _I("success: %d", val);
+ ret = TRUE;
+ }
+ }
+
+ /*
+ if (power_supply_types[index].name != NULL)
+ _I("++++++++++[START] %s ++++++++++", power_supply_types[index].name);
+ _I("C(%s , %s) P(%s) STATUS(%s) HEALTH(%s)",
+ power_supply_types[index].capacity,
+ power_supply_types[index].online,
+ power_supply_types[index].present,
+ power_supply_types[index].charge_status,
+ power_supply_types[index].health);
+ if (power_supply_types[index].name != NULL)
+ _I("++++++++++[END] %s ++++++++++", power_supply_types[index].name);
+ if (val < 0)
+ _R("[NG] ---- %s", __func__);
+ else
+ _R("[OK] ---- %s : C(%s , %s) P(%s) S(%s) H(%s)",
+ __func__,
+ power_supply_types[index].capacity,
+ power_supply_types[index].online,
+ power_supply_types[index].present,
+ power_supply_types[index].charge_status,
+ power_supply_types[index].health);
+ */
+ dbus_message_unref(msg);
+ dbus_error_free(&err);
+ sleep(TEST_WAIT_TIME_INTERVAL);
+
+ return ret;
+}
+
+void battery_test_all(int *success, int *fail)
+{
+ int s = 0;
+ int f = 0;
+
+ (get_battery_time_to_full()) ? s++ : f++;
+ (get_battery_time_to_empty()) ? s++ : f++;
+ (get_battery_low_level(NULL)) ? s++ : f++;
+ (set_battery_low_level(10)) ? s++ : f++;
+ (set_battery_low_level(50)) ? s++ : f++;
+ (get_battery_charger_status()) ? s++ : f++;
+ (get_battery_charge_now()) ? s++ : f++;
+ (get_battery_status_low()) ? s++ : f++;
+ (get_battery_percent()) ? s++ : f++;
+ (get_battery_percent_raw()) ? s++ : f++;
+ (get_battery_is_full()) ? s++ : f++;
+ (get_battery_health()) ? s++ : f++;
+ (get_battery_info()) ? s++ : f++;
+
+ for (int index = 0; index < ARRAY_SIZE(power_supply_types); index++)
+ (set_battery_power_supply(index)) ? s++ : f++;
+
+ if (NULL != success) *success = s;
+ if (NULL != fail) *fail = f;
+}
+
+static void battery_init(void *data)
+{
+ int success = 0;
+ int fail = 0;
+
+ _I("start test");
+
+ battery_test_all(&success, &fail);
+
+ _I("Total: %d, Success: %d, Fail: %d", success+fail, success, fail);
+}
+
+static void battery_exit(void *data)
+{
+ _I("end test");
+
+}
+
+static int battery_unit(int argc, char **argv)
+{
+ if (argc < 4) {
+ int success = 0;
+ int fail = 0;
+ _I("start test");
+ battery_test_all(&success, &fail);
+ _I("Total: %d, Success: %d, Fail: %d", success+fail, success, fail);
+ } else if (0 == strcasecmp(argv[3], METHOD_BATTERY_TIMETOFULL)) {
+ get_battery_time_to_full();
+ } else if (0 == strcasecmp(argv[3], METHOD_BATTERY_TIMETOEMPTY)) {
+ get_battery_time_to_empty();
+ } else if (0 == strcasecmp(argv[3], METHOD_BATTERY_GETLOWBATLEVEL)) {
+ get_battery_low_level(NULL);
+ } else if (0 == strcasecmp(argv[3], METHOD_BATTERY_SETLOWBATLEVEL)) {
+ set_battery_low_level(atoi(argv[4]));
+ } else if (0 == strcasecmp(argv[3], METHOD_BATTERY_CHARGERSTATUS)) {
+ get_battery_charger_status();
+ } else if (0 == strcasecmp(argv[3], METHOD_BATTERY_CHARGENOW)) {
+ get_battery_charge_now();
+ } else if (0 == strcasecmp(argv[3], METHOD_BATTERY_STATUSLOW)) {
+ get_battery_status_low();
+ } else if (0 == strcasecmp(argv[3], METHOD_BATTERY_GETPERCENT)) {
+ get_battery_percent();
+ } else if (0 == strcasecmp(argv[3], METHOD_BATTERY_GETPERCENTRAW)) {
+ get_battery_percent_raw();
+ } else if (0 == strcasecmp(argv[3], METHOD_BATTERY_ISFULL)) {
+ get_battery_is_full();
+ } else if (0 == strcasecmp(argv[3], METHOD_BATTERY_HEALTH)) {
+ get_battery_health();
+ } else if (0 == strcasecmp(argv[3], METHOD_BATTERY_GETINFO)) {
+ get_battery_info();
+ } else if (0 == strcasecmp(argv[3], METHOD_BATTERY_POWERSUPPLY)) {
+ for (int index = 0; index < ARRAY_SIZE(power_supply_types); index++)
+ set_battery_power_supply(index);
+ } else {
+ _E("Unknown test case!!!");
+ }
+
+ return 0;
+}
+
+static const struct test_ops battery_test_ops = {
+ .priority = TEST_PRIORITY_NORMAL,
+ .name = "battery",
+ .init = battery_init,
+ .exit = battery_exit,
+ .unit = battery_unit,
+};
+
+TEST_OPS_REGISTER(&battery_test_ops)