resource-manager: Add API for fine-tuned event listening 92/299792/5
authorYoungjae Cho <y0.cho@samsung.com>
Fri, 6 Oct 2023 07:23:04 +0000 (16:23 +0900)
committerYoungjae Cho <y0.cho@samsung.com>
Mon, 16 Oct 2023 07:43:37 +0000 (16:43 +0900)
The syscommon_resman_subscribe_resource_event() has been split into
3 variants, each of which can narrow down the range of events that
we want to listen to.
- syscommon_resman_subscribe_event(...)
  : It is identical to the existing one. Listen any events from any
    type of resources.

- syscommon_resman_subscribe_resource_event(resource_type, ...)
  : Listen any changes of attribute from specific type of resources.

- syscommon_resman_subscribe_resource_attribute_event(resource_type,
     attr_mask, ...)
  : Listen change of specific attributes from specific type of resources.

In addition, the event callback has been changed to receive an additional
parameter, void *user_data.

Change-Id: I41876fa746d1d042bc1595db55d29e3b8ff13e86
Signed-off-by: Youngjae Cho <y0.cho@samsung.com>
include/libsyscommon/resource-manager.h
src/resource-manager/resource-manager.c
tests/resource-manager/battery-interface.h [new file with mode: 0644]
tests/resource-manager/common-interface.h
tests/resource-manager/resource-battery.c [new file with mode: 0644]
tests/resource-manager/resource-battery.h [new file with mode: 0644]
tests/resource-manager/resource-display.c
tests/resource-manager/test.c

index d6d3264..efac317 100644 (file)
@@ -250,10 +250,15 @@ int syscommon_resman_unset_resource_attr_interest(int resource_id, u_int64_t int
 bool syscommon_resman_is_resource_attr_interested(int resource_id, u_int64_t interest_mask);
 
 typedef void (*syscommon_resman_resource_event_cb) (int resource_type,
-       int resource_id, int attr_id, const void *data, int count);
-
-int syscommon_resman_subscribe_resource_event(syscommon_resman_resource_event_cb callback, int *id);
-void syscommon_resman_unsubscribe_resource_event(int id);
+       int resource_id, int attr_id, const void *data, void *user_data, int count);
+
+int syscommon_resman_subscribe_resource_attribute_event(int resource_type,
+       u_int64_t attr_mask, syscommon_resman_resource_event_cb callback, void *user_data, int *id);
+int syscommon_resman_subscribe_resource_event(int resource_type,
+       syscommon_resman_resource_event_cb callback, void *user_data, int *id);
+int syscommon_resman_subscribe_event(syscommon_resman_resource_event_cb callback,
+       void *user_data, int *id);
+void syscommon_resman_unsubscribe_event(int id);
 
 const char *syscommon_resman_get_resource_attr_name(int resource_id, u_int64_t attr_id);
 const char *syscommon_resman_get_resource_name(int resource_id);
index 61fbe59..83b9da3 100644 (file)
@@ -41,6 +41,9 @@
 #define INSTANCE_TYPE_NORMAL                   0
 #define INSTANCE_TYPE_MONITOR                  1
 
+#define RESOURCE_TYPE_ALL                      (-1)
+#define RESOURCE_ATTR_ALL                      (~0ULL)
+
 struct syscommon_resman_resource {
        char *name;
        int id;
@@ -72,14 +75,17 @@ struct attribute_is_supported_ops {
 
 struct resource_event_data {
        int id;
+       int resource_type;
+       int attr_mask;
        syscommon_resman_resource_event_cb callback;
+       void *user_data;
 };
 
 static int set_resource_attr_interest(struct syscommon_resman_resource *resource, u_int64_t interest_mask);
 static int unset_resource_attr_interest(struct syscommon_resman_resource *resource, u_int64_t interest_mask);
 static bool is_resource_attr_interested(struct syscommon_resman_resource *resource, u_int64_t interest_mask);
 static void
-notify_resource_event(int resource_type, int resource_id, int attr_id, const void *data, int count);
+notify_resource_event(int resource_type, int resource_id, u_int64_t attr_id, const void *data, int count);
 
 static GList *g_resource_driver_head;
 static GList *g_resource_event_data_list;
@@ -1950,7 +1956,7 @@ syscommon_resman_is_resource_attr_interested(int resource_id, u_int64_t interest
 }
 
 static void
-notify_resource_event(int resource_type, int resource_id, int attr_id, const void *data, int count)
+notify_resource_event(int resource_type, int resource_id, u_int64_t attr_id, const void *data, int count)
 {
        GList *elem;
        struct resource_event_data *event_data;
@@ -1959,7 +1965,14 @@ notify_resource_event(int resource_type, int resource_id, int attr_id, const voi
                event_data = (struct resource_event_data *) elem->data;
 
                assert(event_data);
-               event_data->callback(resource_type, resource_id, attr_id, data, count);
+
+               if ((event_data->resource_type != RESOURCE_TYPE_ALL) && (event_data->resource_type != resource_type))
+                       continue;
+
+               if ((event_data->attr_mask & attr_id) == 0)
+                       continue;
+
+               event_data->callback(resource_type, resource_id, attr_id, data, event_data->user_data, count);
        }
 }
 
@@ -1971,8 +1984,8 @@ static gboolean find_resource_event_data(gconstpointer data, gconstpointer id)
        return (_event_data->id - _id);
 }
 
-int
-syscommon_resman_subscribe_resource_event(syscommon_resman_resource_event_cb callback, int *id)
+int syscommon_resman_subscribe_resource_attribute_event(int resource_type,
+       u_int64_t attr_mask, syscommon_resman_resource_event_cb callback, void *user_data, int *id)
 {
        struct resource_event_data *event_data = NULL;
 
@@ -1985,7 +1998,10 @@ syscommon_resman_subscribe_resource_event(syscommon_resman_resource_event_cb cal
 
        *event_data = (struct resource_event_data) {
                .id = alloc_resource_id(),
-               .callback = callback
+               .resource_type = resource_type,
+               .attr_mask = attr_mask,
+               .callback = callback,
+               .user_data = user_data,
        };
 
        g_resource_event_data_list = g_list_append(g_resource_event_data_list, event_data);
@@ -1995,7 +2011,20 @@ syscommon_resman_subscribe_resource_event(syscommon_resman_resource_event_cb cal
        return 0;
 }
 
-void syscommon_resman_unsubscribe_resource_event(int id)
+int syscommon_resman_subscribe_resource_event(int resource_type,
+       syscommon_resman_resource_event_cb callback, void *user_data, int *id)
+{
+       return syscommon_resman_subscribe_resource_attribute_event(resource_type,
+               RESOURCE_ATTR_ALL, callback, user_data, id);
+}
+
+int syscommon_resman_subscribe_event(syscommon_resman_resource_event_cb callback,
+       void *user_data, int *id)
+{
+       return syscommon_resman_subscribe_resource_event(RESOURCE_TYPE_ALL, callback, user_data, id);
+}
+
+void syscommon_resman_unsubscribe_event(int id)
 {
        GList *list;
 
diff --git a/tests/resource-manager/battery-interface.h b/tests/resource-manager/battery-interface.h
new file mode 100644 (file)
index 0000000..dd4bfb4
--- /dev/null
@@ -0,0 +1,7 @@
+#ifndef __BATTERY_INTERFACE_H__
+#define __BATTERY_INTERFACE_H__
+
+#define BATTERY_ATTR_INT               (1ULL << 0)
+#define BATTERY_ATTR_UINT              (1ULL << 1)
+
+#endif /* __BATTERY_INTERFACE_H__ */
index b47baaf..2876175 100644 (file)
@@ -1,9 +1,23 @@
 #ifndef __TEST_COMMON_INTERFACE_H__
 #define __TEST_COMMON_INTERFACE_H__
 
+#include <stdint.h>
+#include <stdbool.h>
+
 enum libsyscommon_test_resource_type {
        TEST_RESOURCE_TYPE_DISPLAY,
+       TEST_RESOURCE_TYPE_BATTERY,
        TEST_RESOURCE_TYPE_NOT_EXIST,
 };
 
+typedef union {
+       int32_t i32;
+       int64_t i64;
+       uint32_t u32;
+       uint64_t u64;
+       double d;
+       void* p;
+       bool b;
+} resource_attr_data_t;
+
 #endif /* __TEST_COMMON_INTERFACE_H__ */
diff --git a/tests/resource-manager/resource-battery.c b/tests/resource-manager/resource-battery.c
new file mode 100644 (file)
index 0000000..9de225e
--- /dev/null
@@ -0,0 +1,132 @@
+#include <stdio.h>
+
+#include <libsyscommon/resource-manager.h>
+#include <libsyscommon/resource-type.h>
+
+#include "common-interface.h"
+#include "battery-interface.h"
+#include "../test-main.h"
+
+static int test_battery_get(int resource_id,
+    const struct syscommon_resman_resource_attribute *attr,
+    void *data)
+{
+       int ret = 0;
+       resource_attr_data_t attr_data = { 0, };
+
+       switch (attr->id) {
+       case BATTERY_ATTR_INT:
+               attr_data.i32 = mock_type(int);
+               break;
+       case BATTERY_ATTR_UINT:
+               attr_data.u32 = mock_type(uint32_t);
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       ret = mock_type(int);
+
+       if (ret < 0)
+               return ret;
+
+       switch (attr->type) {
+       case SYSCOMMON_RESMAN_DATA_TYPE_INT:
+               *(int32_t *) data = attr_data.i32;
+               break;
+       case SYSCOMMON_RESMAN_DATA_TYPE_INT64:
+               *(int64_t *) data = attr_data.i64;
+               break;
+       case SYSCOMMON_RESMAN_DATA_TYPE_UINT:
+               *(uint32_t *) data = attr_data.u32;
+               break;
+       case SYSCOMMON_RESMAN_DATA_TYPE_UINT64:
+               *(uint64_t *) data = attr_data.u64;
+               break;
+       case SYSCOMMON_RESMAN_DATA_TYPE_DOUBLE:
+               *(double *) data = attr_data.d;
+               break;
+       case SYSCOMMON_RESMAN_DATA_TYPE_PTR:
+               *(void **) data = attr_data.p;
+               break;
+       case SYSCOMMON_RESMAN_DATA_TYPE_BOOLEAN:
+               *(bool *) data = attr_data.b;
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       return ret;
+}
+
+static int test_battery_set(int resource_id,
+       const struct syscommon_resman_resource_attribute *attr,
+       const void *data, int count)
+{
+       check_expected_ptr(data);
+
+       return mock_type(int);
+}
+
+static const struct syscommon_resman_resource_attribute battery_attrs[] = {
+       {
+               .name           = "BATTERY_ATTR_INT",
+               .id                     = BATTERY_ATTR_INT,
+               .type           = SYSCOMMON_RESMAN_DATA_TYPE_INT,
+               .flag           = SYSCOMMON_RESMAN_RESOURCE_ATTR_FLAG_PUBLIC,
+               .ops            = {
+                                       .get = test_battery_get,
+                                       .set = test_battery_set,
+                                       .is_supported = syscommon_resman_resource_attr_supported_always,
+               },
+       } ,{
+               .name           = "BATTERY_ATTR_UINT",
+               .id                     = BATTERY_ATTR_UINT,
+               .type           = SYSCOMMON_RESMAN_DATA_TYPE_UINT,
+               .flag           = SYSCOMMON_RESMAN_RESOURCE_ATTR_FLAG_PUBLIC,
+               .ops            = {
+                                       .get = test_battery_get,
+                                       .set = test_battery_set,
+                                       .is_supported = syscommon_resman_resource_attr_supported_always,
+               },
+       }
+};
+
+static const struct syscommon_resman_resource_driver battery_resource_driver = {
+       .name           = "test-battery",
+       .type           = TEST_RESOURCE_TYPE_BATTERY,
+       .flag           = SYSCOMMON_RESMAN_RESOURCE_DRIVER_FLAG_COUNT_ONLY_ONE,
+       .attrs          = battery_attrs,
+       .num_attrs      = sizeof(battery_attrs)/sizeof(battery_attrs[0]),
+};
+
+int create_battery_resource(void)
+{
+       int resource_id;
+       int ret;
+
+       ret = syscommon_resman_create_resource(&resource_id, TEST_RESOURCE_TYPE_BATTERY);
+       assert_int_equal(ret, 0);
+
+       return resource_id;
+}
+
+void delete_battery_resource(int resource_id)
+{
+       syscommon_resman_delete_resource(resource_id);
+}
+
+void setup_battery_resource_driver(void)
+{
+       /**
+        * Instead of using macro SYSCOMMON_RESMAN_RESOURCE_DRIVER_REGISTER(),
+        * use function.
+        *
+        * There two macros, SYSCOMMON_RESMAN_RESOURCE_DRIVER_REGISTER() and TESTSUITE(),
+        * are both using __attribute__((constructor)). And its order cannot be explicitly
+        * specified. However, the SYSCOMMON_RESMAN_RESOURCE_DRIVER_REGISTER() must be followed
+        * by the TESTSUITE(). Therefore, explicitly registers the driver via setup function
+        * prior to the execution of the testsuite.
+        */
+       syscommon_resman_add_resource_driver(&battery_resource_driver);
+}
diff --git a/tests/resource-manager/resource-battery.h b/tests/resource-manager/resource-battery.h
new file mode 100644 (file)
index 0000000..8426b6c
--- /dev/null
@@ -0,0 +1,9 @@
+#ifndef __RESOURCE_BATTERY_H__
+#define __RESOURCE_BATTERY_H__
+
+int create_battery_resource(void);
+void delete_battery_resource(int resource_id);
+void setup_battery_resource_driver(void);
+
+#endif /* __RESOURCE_BATTERY_H__ */
+
index 570115c..795a72a 100644 (file)
@@ -1,5 +1,4 @@
 #include <stdio.h>
-#include <stdint.h>
 
 #include <libsyscommon/resource-manager.h>
 #include <libsyscommon/resource-type.h>
@@ -8,16 +7,6 @@
 #include "display-interface.h"
 #include "../test-main.h"
 
-typedef union {
-       int32_t i32;
-       int64_t i64;
-       uint32_t u32;
-       uint64_t u64;
-       double d;
-       void* p;
-       bool b;
-} resource_attr_data_t;
-
 static int display_resource_driver_create(int resource_id)
 {
        return mock_type(int);
index 00d205b..a8bc52a 100644 (file)
@@ -2,10 +2,21 @@
 
 #include "common-interface.h"
 #include "display-interface.h"
+#include "battery-interface.h"
 
 #include "resource-display.h"
+#include "resource-battery.h"
+
 #include "../test-main.h"
 
+static int setup_resource_drivers(void **state)
+{
+       setup_display_resource_driver();
+       setup_battery_resource_driver();
+
+       return 0;
+}
+
 static void test_create_resource_pass(void **state)
 {
        int resource_id;
@@ -364,7 +375,7 @@ static void test_set_resource_attr_int_fail_invalid_parameter_1(void **state)
        delete_display_resource(resource_id);
 }
 
-static void test_event_callback1(int resource_type, int resource_id, int attr_id, const void *data, int count)
+static void test_event_callback1(int resource_type, int resource_id, int attr_id, const void *data, void *user_data, int count)
 {
        check_expected(resource_type);
        check_expected(resource_id);
@@ -373,7 +384,7 @@ static void test_event_callback1(int resource_type, int resource_id, int attr_id
        check_expected(count);
 }
 
-static void test_event_callback2(int resource_type, int resource_id, int attr_id, const void *data, int count)
+static void test_event_callback2(int resource_type, int resource_id, int attr_id, const void *data, void *user_data, int count)
 {
        check_expected(resource_type);
        check_expected(resource_id);
@@ -395,7 +406,7 @@ static void test_subscribe_event_pass(void **state)
        resource_id1 = create_display_resource();
        resource_id2 = create_display_resource();
 
-       ret = syscommon_resman_subscribe_resource_event(test_event_callback1, &callback_id1);
+       ret = syscommon_resman_subscribe_event(test_event_callback1, NULL, &callback_id1);
        assert_int_equal(ret, 0);
 
        /* configure mock setter, success */
@@ -412,7 +423,7 @@ static void test_subscribe_event_pass(void **state)
        assert_int_equal(ret, 0);
 
        /* register additional callback2 */
-       ret = syscommon_resman_subscribe_resource_event(test_event_callback2, &callback_id2);
+       ret = syscommon_resman_subscribe_event(test_event_callback2, NULL, &callback_id2);
        assert_int_equal(ret, 0);
 
        /* second try, configure mock setter, success */
@@ -436,7 +447,7 @@ static void test_subscribe_event_pass(void **state)
        assert_int_equal(ret, 0);
 
        /* unregister the callback1 */
-       syscommon_resman_unsubscribe_resource_event(callback_id1);
+       syscommon_resman_unsubscribe_event(callback_id1);
 
        /* third try, configure mock setter, success */
        int_value = 10101;
@@ -453,7 +464,7 @@ static void test_subscribe_event_pass(void **state)
        assert_int_equal(ret, 0);
 
        /* unregister the callback2 */
-       syscommon_resman_unsubscribe_resource_event(callback_id2);
+       syscommon_resman_unsubscribe_event(callback_id2);
 
        /* the last try, configure mock setter, success */
        double_value = 5959.95;
@@ -473,7 +484,7 @@ static void test_subscribe_event_fail_invalid_parameter_1(void **state)
        int callback_id;
        int ret;
 
-       ret = syscommon_resman_subscribe_resource_event(NULL, &callback_id);
+       ret = syscommon_resman_subscribe_event(NULL, NULL, &callback_id);
        assert_int_equal(ret, -EINVAL);
 }
 
@@ -481,7 +492,7 @@ static void test_subscribe_event_fail_invalid_parameter_2(void **state)
 {
        int ret;
 
-       ret = syscommon_resman_subscribe_resource_event(test_event_callback1, NULL);
+       ret = syscommon_resman_subscribe_event(test_event_callback1, NULL, NULL);
        assert_int_equal(ret, -EINVAL);
 }
 
@@ -494,7 +505,7 @@ static void test_subscribe_event_fail_setter(void **state)
 
        resource_id = create_display_resource();
 
-       ret = syscommon_resman_subscribe_resource_event(test_event_callback1, &callback_id);
+       ret = syscommon_resman_subscribe_event(test_event_callback1, NULL, &callback_id);
        assert_int_equal(ret, 0);
 
        /* configure mock setter, fail */
@@ -505,16 +516,159 @@ static void test_subscribe_event_fail_setter(void **state)
        ret = syscommon_resman_set_resource_attr_int(resource_id, DISPLAY_ATTR_INT, value);
        assert_int_equal(ret, -ENOENT);
 
-       syscommon_resman_unsubscribe_resource_event(callback_id);
+       syscommon_resman_unsubscribe_event(callback_id);
 
        delete_display_resource(resource_id);
 }
 
-static int setup_resource_drivers(void **state)
+static void test_subscribe_resource_event_pass(void **state)
 {
-       setup_display_resource_driver();
+       int display_resource_id;
+       int battery_resource_id;
+       int callback_id;
+       int int_value = -12345;
+       uint32_t uint_value = 494949;
+       int ret;
 
-       return 0;
+       display_resource_id = create_display_resource();
+       battery_resource_id = create_battery_resource();
+
+       ret = syscommon_resman_subscribe_resource_event(TEST_RESOURCE_TYPE_BATTERY,
+               test_event_callback1, NULL, &callback_id);
+       assert_int_equal(ret, 0);
+
+       /* Test 1: subscribe battery event, generate display event */
+       /* configure display mock setter, success */
+       expect_memory(test_display_set, data, &int_value, sizeof(int));
+       will_return(test_display_set, 0);
+       /* do not configure mock callback as it is only invoked by battery setter */
+
+       ret = syscommon_resman_set_resource_attr_int(display_resource_id, DISPLAY_ATTR_INT, int_value);
+       assert_int_equal(ret, 0);
+
+       /* Test 2: subscribe battery event, generate battery event BATTERY_ATTR_INT */
+       /* configure battery mock setter, success */
+       expect_memory(test_battery_set, data, &int_value, sizeof(int));
+       will_return(test_battery_set, 0);
+       /* configure battery mock callback1 */
+       expect_value(test_event_callback1, resource_type, TEST_RESOURCE_TYPE_BATTERY);
+       expect_value(test_event_callback1, resource_id, battery_resource_id);
+       expect_value(test_event_callback1, attr_id, BATTERY_ATTR_INT);
+       expect_memory(test_event_callback1, data, &int_value, sizeof(int));
+       expect_value(test_event_callback1, count, 1);
+
+       ret = syscommon_resman_set_resource_attr_int(battery_resource_id, BATTERY_ATTR_INT, int_value);
+       assert_int_equal(ret, 0);
+
+       /* Test 3: subscribe battery event, generate battery event BATTERY_ATTR_UINT */
+       /* configure battery mock setter, success */
+       expect_memory(test_battery_set, data, &uint_value, sizeof(int));
+       will_return(test_battery_set, 0);
+       /* configure battery mock callback1 */
+       expect_value(test_event_callback1, resource_type, TEST_RESOURCE_TYPE_BATTERY);
+       expect_value(test_event_callback1, resource_id, battery_resource_id);
+       expect_value(test_event_callback1, attr_id, BATTERY_ATTR_UINT);
+       expect_memory(test_event_callback1, data, &uint_value, sizeof(uint32_t));
+       expect_value(test_event_callback1, count, 1);
+
+       ret = syscommon_resman_set_resource_attr_uint(battery_resource_id, BATTERY_ATTR_UINT, uint_value);
+       assert_int_equal(ret, 0);
+
+       syscommon_resman_unsubscribe_event(callback_id);
+       delete_display_resource(display_resource_id);
+       delete_battery_resource(battery_resource_id);
+}
+
+static void test_subscribe_resource_event_fail_invalid_parameter_1(void **state)
+{
+       int ret;
+       int callback_id;
+
+       ret = syscommon_resman_subscribe_resource_event(TEST_RESOURCE_TYPE_BATTERY,
+               NULL, NULL, &callback_id);
+       assert_int_equal(ret, -EINVAL);
+}
+
+static void test_subscribe_resource_event_fail_invalid_parameter_2(void **state)
+{
+       int ret;
+
+       ret = syscommon_resman_subscribe_resource_event(TEST_RESOURCE_TYPE_BATTERY,
+               test_event_callback1, NULL, NULL);
+       assert_int_equal(ret, -EINVAL);
+}
+
+static void test_subscribe_resource_attribute_event_pass(void **state)
+{
+       int display_resource_id;
+       int battery_resource_id;
+       int callback_id;
+       int int_value = -12345;
+       uint32_t uint_value = 494949;
+       double double_value = -100.001;
+       int ret;
+
+       display_resource_id = create_display_resource();
+       battery_resource_id = create_battery_resource();
+
+       ret = syscommon_resman_subscribe_resource_attribute_event(TEST_RESOURCE_TYPE_DISPLAY,
+               DISPLAY_ATTR_INT | DISPLAY_ATTR_DOUBLE, test_event_callback1, NULL, &callback_id);
+       assert_int_equal(ret, 0);
+
+       /* Test 1: subscribe display event, generate battery event */
+       /* configure battery mock setter, success */
+       expect_memory(test_battery_set, data, &int_value, sizeof(int));
+       will_return(test_battery_set, 0);
+       /* do not configure mock callback as it is only invoked by display setter */
+
+       ret = syscommon_resman_set_resource_attr_int(battery_resource_id, BATTERY_ATTR_INT, int_value);
+       assert_int_equal(ret, 0);
+
+       /* Test 2: subscribe display event, generate display event that we aren't interested in */
+       /* configure display mock setter, success */
+       expect_memory(test_display_set, data, &uint_value, sizeof(uint32_t));
+       will_return(test_display_set, 0);
+       /* do not configure mock callback as it is not interesting display event*/
+
+       ret = syscommon_resman_set_resource_attr_uint(display_resource_id, DISPLAY_ATTR_UINT, uint_value);
+       assert_int_equal(ret, 0);
+
+       /* Test 3: subscribe display event, generate display event that we are interested in */
+       /* configure display mock setter, success */
+       expect_memory(test_display_set, data, &double_value, sizeof(double));
+       will_return(test_display_set, 0);
+       /* configure display mock callback1 */
+       expect_value(test_event_callback1, resource_type, TEST_RESOURCE_TYPE_DISPLAY);
+       expect_value(test_event_callback1, resource_id, display_resource_id);
+       expect_value(test_event_callback1, attr_id, DISPLAY_ATTR_DOUBLE);
+       expect_memory(test_event_callback1, data, &double_value, sizeof(double));
+       expect_value(test_event_callback1, count, 1);
+
+       ret = syscommon_resman_set_resource_attr_double(display_resource_id, DISPLAY_ATTR_DOUBLE, double_value);
+       assert_int_equal(ret, 0);
+
+       syscommon_resman_unsubscribe_event(callback_id);
+       delete_display_resource(display_resource_id);
+       delete_battery_resource(battery_resource_id);
+}
+
+static void test_subscribe_resource_attribute_event_fail_invalid_parameter_1(void **state)
+{
+       int ret;
+       int callback_id;
+
+       ret = syscommon_resman_subscribe_resource_attribute_event(TEST_RESOURCE_TYPE_BATTERY,
+               BATTERY_ATTR_INT, NULL, NULL, &callback_id);
+       assert_int_equal(ret, -EINVAL);
+}
+
+static void test_subscribe_resource_attribute_event_fail_invalid_parameter_2(void **state)
+{
+       int ret;
+
+       ret = syscommon_resman_subscribe_resource_attribute_event(TEST_RESOURCE_TYPE_BATTERY,
+               BATTERY_ATTR_INT, test_event_callback1, NULL, NULL);
+       assert_int_equal(ret, -EINVAL);
 }
 
 static const struct CMUnitTest resource_manager_testsuite[] = {
@@ -547,5 +701,13 @@ static const struct CMUnitTest resource_manager_testsuite[] = {
        cmocka_unit_test(test_subscribe_event_fail_invalid_parameter_1),
        cmocka_unit_test(test_subscribe_event_fail_invalid_parameter_2),
        cmocka_unit_test(test_subscribe_event_fail_setter),
+
+       cmocka_unit_test(test_subscribe_resource_event_pass),
+       cmocka_unit_test(test_subscribe_resource_event_fail_invalid_parameter_1),
+       cmocka_unit_test(test_subscribe_resource_event_fail_invalid_parameter_2),
+
+       cmocka_unit_test(test_subscribe_resource_attribute_event_pass),
+       cmocka_unit_test(test_subscribe_resource_attribute_event_fail_invalid_parameter_1),
+       cmocka_unit_test(test_subscribe_resource_attribute_event_fail_invalid_parameter_2),
 };
 TESTSUITE_FIXTURE(resource_manager_testsuite, setup_resource_drivers, NULL);