package version up to 1.18.0
[platform/core/uifw/libtdm.git] / utests / src / ut_tdm_client.cpp
index ba4bb07..e72510a 100644 (file)
  *
 **************************************************************************/
 
-#include "gtest/gtest.h"
-#include "ut_common.h"
-
-#include <cstring>
-
-#include <sys/eventfd.h>
 #include <unistd.h>
 #include <fcntl.h>
-#include <semaphore.h>
 #include <sys/signalfd.h>
 #include <poll.h>
 #include <sys/prctl.h>
-#include <sys/socket.h>
-#include <sys/timerfd.h>
 
-extern "C"
-{
-#include "tdm.h"
+#include "ut_tdm.h"
 #include "tdm_client.h"
 
-#include "tbm_surface.h"
+/* LCOV_EXCL_START */
 
-#include "wayland-client.h"
-}
+enum {
+       TDM_UT_PIPE_MSG_NONE,
+       TDM_UT_PIPE_MSG_REPLY,
+       TDM_UT_PIPE_MSG_SERVER_READY,
+       TDM_UT_PIPE_MSG_SERVER_FAILED,
+       TDM_UT_PIPE_MSG_DPMS_ON,
+       TDM_UT_PIPE_MSG_DPMS_OFF,
+       TDM_UT_PIPE_MSG_TERMINATE_SERVER,
+};
+
+static int _ut_tdm_pipe_read_msg(int fd);
+static bool _ut_tdm_pipe_write_msg(int fd, int reply_fd, int msg);
+static pid_t _ut_tdm_client_server_fork(int *pipe_to_parent, int *pipe_to_child);
 
-class tdm_client_test_prepare
+class TDMClient : public TDMEnv
 {
 public:
-       tdm_client_test_prepare()
-       {
-               /* we have to deal with a named semaphore to protect an access to tdm across several instances
-                * of servers */
-               semaphore = sem_open(semaphore_name.c_str(), O_CREAT | O_EXCL | O_RDWR, S_IRUSR | S_IWUSR, 1);
-               if (semaphore == SEM_FAILED)
-               {
-                       if (errno == EEXIST)
-                               sem_unlink(semaphore_name.c_str());
-                       else
-                       {
-                               std::cout << "can't create semaphore(1): " << semaphore_name << ", errno: " << errno << ".\n";
-                               exit(EXIT_FAILURE);
-                       }
-               } else {
-                       return;
-               }
+       static pid_t server_pid;
 
-               semaphore = sem_open(semaphore_name.c_str(), O_CREAT | O_EXCL | O_RDWR, S_IRUSR | S_IWUSR, 1);
-               if (semaphore == SEM_FAILED)
-               {
-                       std::cout << "can't create semaphore(2): " << semaphore_name << ", errno: " << errno << ".\n";
-                       exit(EXIT_FAILURE);
-               }
-       }
+       /* 0: read, 1: write */
+       static int pipe_parent[2];
+       static int pipe_child[2];
 
-       ~tdm_client_test_prepare()
-       {
-               sem_close(semaphore);
-               sem_unlink(semaphore_name.c_str());
-       }
+       tdm_client *client;
+       tdm_client_output *output;
+       tdm_client_vblank *vblank;
 
-       static sem_t *semaphore;
+       double vrefresh_interval, start, end;
 
-       /* /dev/shm/sem.tdm-client-utests */
-       static const std::string semaphore_name;
-};
+       TDMClient();
 
-sem_t *tdm_client_test_prepare::semaphore;
-const std::string tdm_client_test_prepare::semaphore_name = "/tdm-client-utests";
+       void SetUp(void);
+       void TearDown(void);
+       bool PrepareClient(void);
+       bool PrepareOutput(void);
+       bool PrepareVblank(void);
 
-/* global object is created before main() */
-tdm_client_test_prepare dont_use_it;
+       static void TearDownTestCase(void);
+       static void ServerFork(void);
+       static void ServerKill(void);
+};
+
+pid_t TDMClient::server_pid = -1;
+int TDMClient::pipe_parent[2] = {-1, -1};
+int TDMClient::pipe_child[2] = {-1, -1};
 
-/* real mess, sorry... */
-class TDMClientTest : public ::testing::Test
+void TDMClient::TearDownTestCase(void)
 {
-protected:
-       TDMClientTest() : error(TDM_ERROR_NONE), server_pid(0),
-               dsp(nullptr), output(nullptr), layer(nullptr), buffer(nullptr), is_server_stopped(false)
-       {
-               set_env_vars();
-               start_server(); /* as a separate process */
-               wait_till_server_ready();
-       }
+       ServerKill();
+}
 
-       ~TDMClientTest()
-       {
-               _stop_server();
-               unset_env_vars();
-       }
+void TDMClient::ServerFork(void)
+{
+       if (server_pid > 0)
+               return;
 
-       void send_request_to_server(int req)
-       {
-               switch(req)
-               {
-                       case ChangeDPMS:
-                               send_request(ChangeDPMS);
-                       break;
+       server_pid = _ut_tdm_client_server_fork(pipe_parent, pipe_child);
+       ASSERT_GT(server_pid, 0);
+}
 
-                       default:
-                       break;
+void TDMClient::ServerKill(void)
+{
+       if (pipe_child[0] >= 0)
+               close(pipe_child[0]);
+       if (pipe_child[1] >= 0) {
+               if (server_pid > 0) {
+                       bool ret = _ut_tdm_pipe_write_msg(pipe_child[1], pipe_parent[0], TDM_UT_PIPE_MSG_TERMINATE_SERVER);
+                       if (ret) {
+                               if (waitpid(server_pid, NULL, 0) == server_pid)
+                                       TDM_INFO("*** server terminated ***");
+                               else
+                                       TDM_ERR("*** failed to terminate server ***");
+                       } else {
+                               if (kill(server_pid, 9) < 0)
+                                       TDM_ERR("*** failed to kill server ***");
+                       }
                }
+               close(pipe_child[1]);
        }
 
-       /* to stop server by user demand */
-       void stop_server(void)
-       {
-               _stop_server();
-               wait_till_serv_is_over();
+       if (pipe_parent[0] >= 0)
+               close(pipe_parent[0]);
+       if (pipe_parent[1] >= 0)
+               close(pipe_parent[1]);
 
-               /* TODO: maybe it makes a sense to use this approach in the dtor too */
-       }
-
-       enum
-       {
-               ChangeDPMS,
-       };
+       server_pid = -1;
+       pipe_parent[0] = pipe_parent[1] = -1;
+       pipe_child[0] = pipe_child[1] = -1;
+}
 
-private:
-       void set_env_vars(void)
-       {
-               setenv("XDG_RUNTIME_DIR", "/run", 1);
-               setenv("TBM_DISPLAY_SERVER", "1", 1);
-       }
+TDMClient::TDMClient()
+{
+       client = NULL;
+       output = NULL;
+       vblank = NULL;
+       vrefresh_interval = start = end = 0.0;
+}
 
-       void unset_env_vars(void)
-       {
-               unsetenv("TBM_DISPLAY_SERVER");
-               unsetenv("XDG_RUNTIME_DIR");
-       }
+void TDMClient::SetUp(void)
+{
+       TDMEnv::SetUp();
 
-       void start_server(void)
-       {
-               cl_serv_lock_fd = eventfd(0, 0);
-               socketpair(AF_UNIX, SOCK_STREAM, 0, reinterpret_cast<int*>(&socks_pair));
+       if (server_pid == -1)
+               ServerFork();
+}
 
-               server_pid = fork();
+void TDMClient::TearDown(void)
+{
+       if (vblank)
+               tdm_client_vblank_destroy(vblank);
+       if (client)
+               tdm_client_destroy(client);
 
-               if (server_pid)
-               {
-                       close(socks_pair.server_socket);
-                       return;
-               }
+       TDMEnv::TearDown();
+}
 
-               close(socks_pair.client_socket);
+bool TDMClient::PrepareClient(void)
+{
+       tdm_error ret;
+       client = tdm_client_create(&ret);
+       TDM_UT_RETURN_FALSE_IF_FAIL(ret == TDM_ERROR_NONE);
+       TDM_UT_RETURN_FALSE_IF_FAIL(client != NULL);
 
-               wait_till_serv_resources_available();
-               run_server();
-       }
+       return true;
+}
 
-       void _stop_server(void)
-       {
-               if (is_server_stopped) return;
+bool TDMClient::PrepareOutput(void)
+{
+       tdm_error ret;
 
-               close(socks_pair.client_socket);
-               close(cl_serv_lock_fd);
-               kill(server_pid, SIGINT);
+       TDM_UT_RETURN_FALSE_IF_FAIL(client != NULL);
 
-               is_server_stopped = true;
-       }
+       output = tdm_client_get_output(client, NULL, &ret);
+       TDM_UT_RETURN_FALSE_IF_FAIL(ret == TDM_ERROR_NONE);
+       TDM_UT_RETURN_FALSE_IF_FAIL(output != NULL);
 
-       void wait_till_server_ready(void)
-       {
-               uint64_t val;
+       return true;
+}
 
-               if (read(cl_serv_lock_fd, &val, sizeof val) < 0)
-                       std::cout << "error while trying to read from cl_serv_lock_fd eventfd object.\n";
-       }
+bool TDMClient::PrepareVblank(void)
+{
+       tdm_error ret;
+       unsigned int refresh;
 
-       void notify_server_ready(void)
-       {
-               uint64_t val;
+       TDM_UT_RETURN_FALSE_IF_FAIL(output != NULL);
 
-               val = 1;
+       vblank = tdm_client_output_create_vblank(output, &ret);
+       TDM_UT_RETURN_FALSE_IF_FAIL(ret == TDM_ERROR_NONE);
+       TDM_UT_RETURN_FALSE_IF_FAIL(vblank != NULL);
 
-               if (write(cl_serv_lock_fd, &val, sizeof val) < 0)
-                       std::cout << "error while trying to write to cl_serv_lock_fd evenfd object.\n";
-       }
+       TDM_UT_RETURN_FALSE_IF_FAIL(tdm_client_output_get_refresh_rate(output, &refresh) == TDM_ERROR_NONE);
+       TDM_UT_RETURN_FALSE_IF_FAIL(refresh > 0);
 
-       void wait_till_serv_resources_available(void)
-       {
-               while (1)
-               {
-                       int ret;
+       vrefresh_interval = 1.0 / (double)refresh;
+       TDM_UT_RETURN_FALSE_IF_FAIL(vrefresh_interval > 0);
 
-                       ret = sem_wait(tdm_client_test_prepare::semaphore);
-                       if (ret < 0 && errno == EINTR)
-                               continue;
-                       else
-                               break;
-               }
-       }
+       return true;
+}
 
-       void notify_serv_resources_available(void)
-       {
-               sem_post(tdm_client_test_prepare::semaphore);
+static int
+_ut_tdm_pipe_read_msg(int fd)
+{
+       ssize_t len;
+       int msg;
 
-               sem_close(tdm_client_test_prepare::semaphore);
-               sem_unlink(tdm_client_test_prepare::semaphore_name.c_str());
-       }
+       do {
+               len = read(fd, &msg, sizeof msg);
+       } while (len < 0 && errno == EINTR);
 
-       void wait_till_serv_is_over(void)
-       {
-               wait_till_serv_resources_available();
-               sem_post(tdm_client_test_prepare::semaphore);
-       }
+       if (len <= 0)
+               msg = TDM_UT_PIPE_MSG_NONE;
 
-       void send_request(int req)
-       {
-               int count;
+       return msg;
+}
 
-               count = send(socks_pair.client_socket, &req, sizeof req, 0);
+static bool
+_ut_tdm_pipe_write_msg(int fd, int reply_fd, int msg)
+{
+       ssize_t len = write(fd, &msg, sizeof msg);
+       TDM_UT_RETURN_FALSE_IF_FAIL(len == sizeof msg);
 
-               if (count != sizeof req)
-                       std::cout << "error while trying to send request to socks_pair.client_socket.\n";
+       if (reply_fd >= 0) {
+               int reply = _ut_tdm_pipe_read_msg(reply_fd);
+               TDM_UT_RETURN_FALSE_IF_FAIL(reply == TDM_UT_PIPE_MSG_REPLY);
        }
 
-       void handle_client_request()
-       {
-               int req;
-               int count;
-
-               count = recv(socks_pair.server_socket, &req, sizeof req, 0);
-
-               if (count != sizeof req) {
-                       std::cout << "error while trying to reserve data from socks_pair.server_socket.\n";
-                       return;
-               }
-
-               switch(req)
-               {
-                       case ChangeDPMS:
-                               change_dpms_request_handler();
-                       break;
+       return true;
+}
 
-                       default:
-                               break;
-               }
+static bool
+_ut_tdm_server_set_output_dpms(tdm_display *dpy, int msg)
+{
+       tdm_error ret;
+       tdm_output *output;
+       tdm_output_dpms dpms;
+
+       output = tdm_display_find_output(dpy, "primary", &ret);
+       TDM_UT_RETURN_FALSE_IF_FAIL(ret == TDM_ERROR_NONE);
+       TDM_UT_RETURN_FALSE_IF_FAIL(output != NULL);
+
+       TDM_UT_RETURN_FALSE_IF_FAIL(tdm_output_get_dpms(output, &dpms) == TDM_ERROR_NONE);
+
+       switch (msg) {
+       case TDM_UT_PIPE_MSG_DPMS_ON:
+               if (dpms != TDM_OUTPUT_DPMS_ON)
+                       TDM_UT_RETURN_FALSE_IF_FAIL(tdm_output_set_dpms(output, TDM_OUTPUT_DPMS_ON) == TDM_ERROR_NONE);
+               break;
+       case TDM_UT_PIPE_MSG_DPMS_OFF:
+               if (dpms != TDM_OUTPUT_DPMS_OFF)
+                       TDM_UT_RETURN_FALSE_IF_FAIL(tdm_output_set_dpms(output, TDM_OUTPUT_DPMS_OFF) == TDM_ERROR_NONE);
+               break;
+       default:
+               break;
        }
 
-       void run_server(void)
-       {
-               sigset_t mask;
-               int signal_fd;
-               int tdm_fd;
-               pollfd work_fds[3];
+       return true;
+}
 
-               /* ask kernel to notify us about parent's die via SIGHUP signal */
-               prctl(PR_SET_PDEATHSIG, SIGHUP);
+static void
+_ut_tdm_server_run(int *pipe_parent, int *pipe_child)
+{
+       tdm_display *dpy = NULL;
+       tdm_error ret;
+       struct pollfd fds[2];
+       int tdm_fd, err;
+       int output_count = 0;
 
-               sigemptyset(&mask);
-               sigaddset(&mask, SIGINT);
-               sigaddset(&mask, SIGHUP);
+       dpy = tdm_display_init(&ret);
+       TDM_UT_GOTO_IF_FAIL(ret == TDM_ERROR_NONE, failed);
+       TDM_UT_GOTO_IF_FAIL(dpy != NULL, failed);
 
-               sigprocmask(SIG_BLOCK, &mask, NULL);
+       TDM_UT_GOTO_IF_FAIL(tdm_display_get_output_count(dpy, &output_count) == TDM_ERROR_NONE, failed);
 
-               signal_fd = signalfd(-1, &mask, 0);
+       for (int o = 0; o < output_count; o++) {
+               tdm_output *output = tdm_display_get_output(dpy, o, &ret);
+               TDM_UT_GOTO_IF_FAIL(ret == TDM_ERROR_NONE, failed);
+               TDM_UT_GOTO_IF_FAIL(output != NULL, failed);
 
-               init_tdm();
-               tdm_display_get_fd(dsp, &tdm_fd);
+               if (!ut_tdm_output_is_connected(output))
+                       continue;
 
-               std::memset(&work_fds, 0, sizeof work_fds);
+               TDM_UT_GOTO_IF_FAIL(ut_tdm_output_prepare(dpy, output, true) == true, failed);
+       }
 
-               work_fds[0].fd = signal_fd;
-               work_fds[0].events = POLLIN;
+       TDM_UT_GOTO_IF_FAIL(_ut_tdm_pipe_write_msg(pipe_parent[1], -1, TDM_UT_PIPE_MSG_SERVER_READY) == true, done);
 
-               work_fds[1].fd = tdm_fd;
-               work_fds[1].events = POLLIN;
+       TDM_INFO("*** server ready ***");
 
-               work_fds[2].fd = socks_pair.server_socket;
-               work_fds[2].events = POLLIN;
+       ret = tdm_display_get_fd(dpy, &tdm_fd);
+       TDM_UT_GOTO_IF_FAIL(ret == TDM_ERROR_NONE, done);
 
-               notify_server_ready();
+       fds[0].events = POLLIN;
+       fds[0].fd = tdm_fd;
+       fds[0].revents = 0;
 
-               while (1)
-               {
-                       int ret;
+       fds[1].events = POLLIN;
+       fds[1].fd = pipe_child[0];
+       fds[1].revents = 0;
 
-                       ret = poll(work_fds, 3, -1);
-                       if (ret < 0 && errno == EINTR) continue;
+       while (1) {
+               /* make sure all events are flushed to clients before falling in sleep */
+               tdm_display_flush(dpy);
 
-                       if (work_fds[0].revents == POLLIN)
-                       {
-                               signal_hndl();
-                               exit(EXIT_SUCCESS);
+               err = poll(fds, 2, -1);
+               if (err < 0) {
+                       if (errno == EINTR || errno == EAGAIN) {
+                               continue;
+                       } else {
+                               TDM_ERR("server-process: poll failed: %m\n");
+                               goto done;
                        }
+               }
 
-                       if(work_fds[1].revents == POLLIN)
-                               tdm_display_handle_events(dsp);
+               if (fds[0].revents & POLLIN)
+                       ret = ut_tdm_display_handle_events(dpy);
 
-                       if(work_fds[2].revents == POLLIN)
-                               handle_client_request();
+               if (fds[1].revents & POLLIN) {
+                       int msg = _ut_tdm_pipe_read_msg(pipe_child[0]);
+                       _ut_tdm_pipe_write_msg(pipe_parent[1], -1, TDM_UT_PIPE_MSG_REPLY);
+
+                       switch (msg) {
+                       case TDM_UT_PIPE_MSG_DPMS_ON:
+                       case TDM_UT_PIPE_MSG_DPMS_OFF:
+                               _ut_tdm_server_set_output_dpms(dpy, msg);
+                               break;
+                       case TDM_UT_PIPE_MSG_TERMINATE_SERVER:
+                               goto done;
+                       default:
+                               break;
+                       }
                }
        }
 
-       void signal_hndl(void)
-       {
-               close(socks_pair.server_socket);
-               close(cl_serv_lock_fd);
-
-               deinit_tdm();
-               notify_serv_resources_available();
-       }
+done:
+       if (dpy)
+               tdm_display_deinit(dpy);
+       return;
 
-       void init_tdm(void);
-       void deinit_tdm(void);
+failed:
+       TDM_UT_GOTO_IF_FAIL(_ut_tdm_pipe_write_msg(pipe_parent[1], -1, TDM_UT_PIPE_MSG_SERVER_FAILED) == true, done);
+       TDM_INFO("*** server failed ***");
 
-       void set_layer_geometry(int w, int h);
-       void set_image_on_screen(int w, int h);
+       if (dpy)
+               tdm_display_deinit(dpy);
+       return;
 
-       void change_dpms_request_handler(void);
+}
 
-       struct sockets_pair
-       {
-               sockets_pair() : server_socket(0), client_socket(0) {}
-               int server_socket;
-               int client_socket;
-       };
+static void _ut_tdm_client_sig_handler(int sig)
+{
+       TDM_UT_ERR("got signal: %d", sig);
+       kill(TDMClient::server_pid, 9);
+       abort();
+}
 
-protected:
-       tdm_error error;
+static pid_t
+_ut_tdm_client_server_fork(int *pipe_parent, int *pipe_child)
+{
+       pid_t pid;
+       int msg;
 
-private:
-       pid_t server_pid;
-       int cl_serv_lock_fd;
-       sockets_pair socks_pair;
+       TDM_UT_GOTO_IF_FAIL(pipe(pipe_parent) == 0, failed);
+       TDM_UT_GOTO_IF_FAIL(pipe(pipe_child) == 0, failed);
 
-       tdm_display *dsp;
-       tdm_output *output;
-       tdm_layer *layer;
+       signal(SIGCHLD, SIG_IGN);
+       signal(SIGSEGV, _ut_tdm_client_sig_handler);
 
-       tbm_surface_h buffer;
+       prctl(PR_SET_PDEATHSIG, SIGHUP);
 
-       bool is_server_stopped;
-};
+       pid = fork();
+       TDM_UT_GOTO_IF_FAIL(pid >= 0, failed);
 
-class TDMClientTestClient : public TDMClientTest
-{
-protected:
-       TDMClientTestClient() : TDMClientTest()
-       {
-               tdm_cl = tdm_client_create(nullptr);
-       }
-       ~TDMClientTestClient()
-       {
-               tdm_client_destroy(tdm_cl);
-       }
+       if (pid == 0) {
+               _ut_tdm_server_run(pipe_parent, pipe_child);
+               close(pipe_child[0]);
+               close(pipe_child[1]);
+               close(pipe_parent[0]);
+               close(pipe_parent[1]);
 
-protected:
-       tdm_client *tdm_cl;
-};
+#ifdef TIZEN_TEST_GCOV
+               __gcov_flush();
+#endif
 
-class TDMClientTestClientOutput : public TDMClientTestClient
-{
-protected:
-       TDMClientTestClientOutput() : TDMClientTestClient()
-       {
-               cl_output = tdm_client_get_output(tdm_cl, const_cast<char*>("primary"), nullptr);
-       }
-       ~TDMClientTestClientOutput()
-       {
+               exit(0);
        }
 
-protected:
-       tdm_client_output* cl_output;
-};
+       msg = _ut_tdm_pipe_read_msg(pipe_parent[0]);
+       TDM_UT_GOTO_IF_FAIL(msg == TDM_UT_PIPE_MSG_SERVER_READY, failed);
 
-class TDMClientTestVblank : public TDMClientTestClientOutput
-{
-protected:
-       TDMClientTestVblank() : TDMClientTestClientOutput()
-       {
-               cl_vblank =  tdm_client_output_create_vblank(cl_output, nullptr);
-       }
-       ~TDMClientTestVblank()
-       {
-               tdm_client_vblank_destroy(cl_vblank);
-       }
-
-protected:
-       tdm_client_vblank* cl_vblank;
-};
+       TDM_INFO("*** server fork done ***");
 
-typedef TDMClientTest TDMClientTestDeathTest;
-typedef TDMClientTestClient TDMClientTestClientDeathTest;
-typedef TDMClientTestClientOutput TDMClientTestClientOutputDeathTest;
-typedef TDMClientTestVblank TDMClientTestVblankDeathTest;
+       return pid;
 
+failed:
+       return -1;
+}
 
-void TDMClientTest::set_layer_geometry(int w, int h)
+TEST_P(TDMClient, ClientCreate)
 {
-       tdm_info_layer layer_info;
+       tdm_error ret;
 
-       std::memset(&layer_info, 0, sizeof(tdm_info_layer));
-
-       layer_info.src_config.size.h = w;
-       layer_info.src_config.size.v = h;
-       layer_info.src_config.pos.x = 0;
-       layer_info.src_config.pos.y = 0;
-       layer_info.src_config.pos.w = w;
-       layer_info.src_config.pos.h = h;
-       layer_info.src_config.format = TBM_FORMAT_ARGB8888;
-       layer_info.dst_pos.x = 0;
-       layer_info.dst_pos.y = 0;
-       layer_info.dst_pos.w = w;
-       layer_info.dst_pos.h = h;
-       layer_info.transform = TDM_TRANSFORM_NORMAL;
-
-       tdm_layer_set_info(layer, &layer_info);
+       client = tdm_client_create(&ret);
+       ASSERT_EQ(ret, TDM_ERROR_NONE);
+       ASSERT_NE(client, NULL);
 }
 
-void TDMClientTest::set_image_on_screen(int w, int h)
+TEST_P(TDMClient, ClientCreateNullOther)
 {
-       tbm_surface_info_s tbm_surface_info;
+       client = tdm_client_create(NULL);
+       ASSERT_NE(client, NULL);
+}
 
-       /* to have a hw vblank we have to make at least one tdm_commit */
-       buffer = tbm_surface_create(w, h, TBM_FORMAT_ARGB8888);
+TEST_P(TDMClient, ClientDestroy)
+{
+       tdm_error ret;
 
-       std::memset(&tbm_surface_info, 0, sizeof(tbm_surface_info_s));
+       client = tdm_client_create(&ret);
+       ASSERT_EQ(ret, TDM_ERROR_NONE);
+       ASSERT_NE(client, NULL);
 
-       tbm_surface_map(buffer, TBM_SURF_OPTION_WRITE, &tbm_surface_info);
+       tdm_client_destroy(client);
+       client = NULL;
+}
 
-       int *img = (int *)tbm_surface_info.planes[0].ptr;
+TEST_P(TDMClient, ClientNullObject)
+{
+       tdm_client_destroy(NULL);
+}
 
-       for (uint32_t i = 0; i < tbm_surface_info.height; i++)
-               for (uint32_t j = 0; j < tbm_surface_info.planes[0].stride / 4; j++)
-                       *img++ = 0x0000000;
+/* tdm_client_get_fd */
+TEST_P(TDMClient, ClientGetFd)
+{
+       int fd = TDM_UT_INVALID_VALUE;
 
-       tbm_surface_unmap(buffer);
+       ASSERT_EQ(PrepareClient(), true);
 
-       set_layer_geometry(w, h);
-       tdm_layer_set_buffer(layer, buffer);
-       tdm_output_commit(output, 0, nullptr, nullptr);
+       ASSERT_EQ(tdm_client_get_fd(client, &fd), TDM_ERROR_NONE);
+       ASSERT_GE(fd, 0);
 }
 
-void TDMClientTest::init_tdm(void)
+TEST_P(TDMClient, ClientGetFdNullObject)
 {
-       int outputs_cnt = 0;
-       tdm_output_type tdm_output_type;
-
-       int output_modes_cnt = 0;
-       const tdm_output_mode* output_modes;
-       const tdm_output_mode* preferred_mode = NULL;
+       int fd = TDM_UT_INVALID_VALUE;
+       ASSERT_EQ(tdm_client_get_fd(NULL, &fd), TDM_ERROR_INVALID_PARAMETER);
+       ASSERT_EQ(fd, TDM_UT_INVALID_VALUE);
+}
 
-       int layers_cnt = 0;
-       tdm_layer_capability tdm_layer_capability;
+TEST_P(TDMClient, ClientGetFdNullOther)
+{
+       ASSERT_EQ(PrepareClient(), true);
 
-       dsp = tdm_display_init(nullptr);
+       ASSERT_EQ(tdm_client_get_fd(client, NULL), TDM_ERROR_INVALID_PARAMETER);
+}
 
-       tdm_display_get_output_count(dsp, &outputs_cnt);
+static void
+_ut_tdm_client_vblank_cb(unsigned int sequence, unsigned int tv_sec, unsigned int tv_usec, void *user_data)
+{
+       bool *done = (bool *)user_data;
+       if (done)
+               *done = true;
+}
 
-       /* this part is hardware dependent, how to resolve this issue ? */
-       for (int i = 0; i < outputs_cnt; i++)
-       {
-               output = tdm_display_get_output(dsp, i, nullptr);
-               if (output == NULL) {
-                       std::cout << "tdm_display_get_output faild, server's gonna be stopped.\n";
-                       deinit_tdm();
-                       exit(EXIT_FAILURE);
-               }
-               tdm_output_get_output_type(output, &tdm_output_type);
+/* tdm_client_handle_events_timeout */
+TEST_P(TDMClient, ClientHandleEvent)
+{
+       bool done = false;
 
-               /* we're not interesting about other outputs */
-               if (tdm_output_type != TDM_OUTPUT_TYPE_VIRTUAL &&
-                       tdm_output_type != TDM_OUTPUT_TYPE_HDMIA)
-                       break;
-       }
+       ASSERT_EQ(PrepareClient(), true);
 
-       /* get output's preferred mode to obtain width & height we'll use later to create surface */
-       tdm_output_get_available_modes(output, &output_modes, &output_modes_cnt);
+       ASSERT_EQ(tdm_client_wait_vblank(client, NULL, 1, 1, 0, _ut_tdm_client_vblank_cb, &done), TDM_ERROR_NONE);
+       ASSERT_EQ(done, false);
 
-       /* look for output's preferred mode */
-       for (int i = 0; i < output_modes_cnt; i++)
-       {
-               if (output_modes[i].type & TDM_OUTPUT_MODE_TYPE_PREFERRED)
-               {
-                       preferred_mode = &output_modes[i];
-                       break;
-               }
-       }
+       while (!done)
+               ASSERT_EQ(tdm_client_handle_events(client), TDM_ERROR_NONE);
+}
 
-       if (!preferred_mode)
-       {
-               std::cout << "no preferred mode, server's gonna be stopped.\n";
+TEST_P(TDMClient, ClientHandleEventNullObject)
+{
+       ASSERT_EQ(tdm_client_handle_events(NULL), TDM_ERROR_INVALID_PARAMETER);
+}
 
-               deinit_tdm();
-               exit(EXIT_FAILURE);
-       }
+/* tdm_client_wait_vblank, deprecated */
+TEST_P(TDMClient, ClientWaitVblank)
+{
+       bool done = false;
 
-       tdm_output_set_mode(output, preferred_mode);
+       ASSERT_EQ(PrepareClient(), true);
 
-       tdm_output_get_layer_count(output, &layers_cnt);
+       ASSERT_EQ(tdm_client_wait_vblank(client, NULL, 1, 1, 0, _ut_tdm_client_vblank_cb, &done), TDM_ERROR_NONE);
+       ASSERT_EQ(done, false);
 
-       /* it supposed that output always has primary & graphic layer */
-       for (int i = 0; i < layers_cnt; i++)
-       {
-               layer = tdm_output_get_layer(output, i, nullptr);
-               tdm_layer_get_capabilities(layer, &tdm_layer_capability);
+       while (!done)
+               ASSERT_EQ(tdm_client_handle_events_timeout(client, 3000), TDM_ERROR_NONE);
+}
 
-               if ((tdm_layer_capability & TDM_LAYER_CAPABILITY_PRIMARY) &&
-                       (tdm_layer_capability & TDM_LAYER_CAPABILITY_GRAPHIC))
-                       break;
-       }
+/* tdm_client_get_output */
+TEST_P(TDMClient, ClientGetOutput)
+{
+       tdm_error ret;
 
-       tdm_output_set_dpms(output, TDM_OUTPUT_DPMS_ON);
+       ASSERT_EQ(PrepareClient(), true);
 
-       set_image_on_screen(preferred_mode->hdisplay, preferred_mode->vdisplay);
+       output = tdm_client_get_output(client, NULL, &ret);
+       ASSERT_EQ(ret, TDM_ERROR_NONE);
+       ASSERT_NE(output, NULL);
 }
 
-void TDMClientTest::deinit_tdm(void)
+TEST_P(TDMClient, ClientGetOutputPrimary)
 {
-       if (layer)
-       {
-               tdm_layer_unset_buffer(layer);
-               tdm_output_commit(output, 1, nullptr, nullptr);
-       }
+       tdm_error ret;
 
-       if (buffer)
-               tbm_surface_internal_unref(buffer);
+       ASSERT_EQ(PrepareClient(), true);
 
-       if (dsp)
-               tdm_display_deinit(dsp);
+       output = tdm_client_get_output(client, (char*)"primary", &ret);
+       ASSERT_EQ(ret, TDM_ERROR_NONE);
+       ASSERT_NE(output, NULL);
 }
 
-void TDMClientTest::change_dpms_request_handler(void)
+TEST_P(TDMClient, ClientGetOutputDefault)
 {
-       std::cout << "tdm_output_set_dpms.\n";
-       tdm_output_set_dpms(output, TDM_OUTPUT_DPMS_OFF);
-}
+       tdm_error ret;
 
-TEST_F(TDMClientTest, TdmClientCreateSuccessfulCheckClient)
-{
-       tdm_client *tdm_cl = tdm_client_create(nullptr);
-       ASSERT_TRUE(nullptr != tdm_cl);
+       ASSERT_EQ(PrepareClient(), true);
 
-       tdm_client_destroy(tdm_cl);
+       output = tdm_client_get_output(client, (char*)"default", &ret);
+       ASSERT_EQ(ret, TDM_ERROR_NONE);
+       ASSERT_NE(output, NULL);
 }
 
-TEST_F(TDMClientTest, TdmClientCreateSuccessfulCheckError)
+TEST_P(TDMClient, ClientGetOutputInvalidName)
 {
-       tdm_client* tdm_cl = tdm_client_create(&error);
-       ASSERT_TRUE(TDM_ERROR_NONE == error);
+       tdm_error ret;
+
+       ASSERT_EQ(PrepareClient(), true);
 
-       tdm_client_destroy(tdm_cl);
+       output = tdm_client_get_output(client, (char*)"invalid", &ret);
+       ASSERT_EQ(ret, TDM_ERROR_INVALID_PARAMETER);
+       ASSERT_EQ(output, NULL);
 }
 
-TEST_F(TDMClientTest, TdmClientCreateFailServerStoppedCheckError)
+TEST_P(TDMClient, ClientGetOutputNullObject)
 {
-       stop_server();
+       tdm_error ret;
 
-       tdm_client_create(&error);
-       ASSERT_TRUE(TDM_ERROR_OPERATION_FAILED == error);
+       output = tdm_client_get_output(NULL, NULL, &ret);
+       ASSERT_EQ(ret, TDM_ERROR_INVALID_PARAMETER);
+       ASSERT_EQ(output, NULL);
 }
 
-TEST_F(TDMClientTest, TdmClientCreateFailServerStopped)
+TEST_P(TDMClient, ClientGetOutputNullOther)
 {
-       stop_server();
+       ASSERT_EQ(PrepareClient(), true);
 
-       tdm_client *tdm_cl = tdm_client_create(nullptr);
-       ASSERT_TRUE(nullptr == tdm_cl);
+       output = tdm_client_get_output(client, NULL, NULL);
+       ASSERT_NE(output, NULL);
 }
 
-TEST_F(TDMClientTestDeathTest, TdmClientDestroySuccessful)
+static void
+_ut_tdm_client_output_change_dpms_cb(tdm_client_output *output,
+                                                                        tdm_output_change_type type,
+                                                                        tdm_value value,
+                                                                        void *user_data)
 {
-       ASSERT_EXIT(
-               {
-                       tdm_client_destroy(nullptr);
+       bool *done = (bool *)user_data;
 
-                       exit(EXIT_SUCCESS);
-               },
-               ::testing::ExitedWithCode(EXIT_SUCCESS), "");
+       switch (type) {
+       case TDM_OUTPUT_CHANGE_DPMS:
+               if (done)
+                       *done = true;
+               break;
+       default:
+               break;
+       }
 }
 
-TEST_F(TDMClientTestDeathTest, TdmClientDestroySuccessfulServerStopped)
+/* tdm_client_output_add_change_handler */
+TEST_P(TDMClient, ClientOutputAddChangeHandler)
 {
-       ASSERT_EXIT(
-               {
-                       tdm_client *tdm_cl = tdm_client_create(nullptr);
+       bool done = false;
+       tdm_output_dpms dpms;
+
+       ASSERT_EQ(PrepareClient(), true);
+       ASSERT_EQ(PrepareOutput(), true);
 
-                       stop_server();
+       ASSERT_EQ(tdm_client_output_add_change_handler(output, _ut_tdm_client_output_change_dpms_cb, &done), TDM_ERROR_NONE);
+       ASSERT_EQ(_ut_tdm_pipe_write_msg(pipe_child[1], pipe_parent[0], TDM_UT_PIPE_MSG_DPMS_OFF), true);
 
-                       tdm_client_destroy(tdm_cl);
+       while (!done)
+               ASSERT_EQ(tdm_client_handle_events_timeout(client, 3000), TDM_ERROR_NONE);
 
-                       exit(EXIT_SUCCESS);
-               },
-               ::testing::ExitedWithCode(EXIT_SUCCESS), "");
+       ASSERT_EQ(tdm_client_output_get_dpms(output, &dpms), TDM_ERROR_NONE);
+       ASSERT_EQ(dpms, TDM_OUTPUT_DPMS_OFF);
+
+       ASSERT_EQ(_ut_tdm_pipe_write_msg(pipe_child[1], pipe_parent[0], TDM_UT_PIPE_MSG_DPMS_ON), true);
+       while (dpms != TDM_OUTPUT_DPMS_ON) {
+               ASSERT_EQ(tdm_client_handle_events_timeout(client, 3000), TDM_ERROR_NONE);
+               ASSERT_EQ(tdm_client_output_get_dpms(output, &dpms), TDM_ERROR_NONE);
+       }
 }
 
-TEST_F(TDMClientTestClient, TdmClientGetFdSuccessful)
+TEST_P(TDMClient, ClientOutputAddChangeHandlerTwice)
 {
-       int fd;
+       ASSERT_EQ(PrepareClient(), true);
+       ASSERT_EQ(PrepareOutput(), true);
 
-       tdm_client_get_fd(tdm_cl, &fd);
-       ASSERT_TRUE(0 < fd);
+       ASSERT_EQ(tdm_client_output_add_change_handler(output, _ut_tdm_client_output_change_dpms_cb, NULL), TDM_ERROR_NONE);
+       ASSERT_EQ(tdm_client_output_add_change_handler(output, _ut_tdm_client_output_change_dpms_cb, NULL), TDM_ERROR_BAD_REQUEST);
 }
 
-TEST_F(TDMClientTestClient, TdmClientGetFdSuccessfulCheckError)
+TEST_P(TDMClient, ClientOutputAddChangeHandlerNullObject)
 {
-       int fd;
-
-       error = tdm_client_get_fd(tdm_cl, &fd);
-       ASSERT_TRUE(TDM_ERROR_NONE == error);
+       ASSERT_EQ(tdm_client_output_add_change_handler(NULL, _ut_tdm_client_output_change_dpms_cb, NULL), TDM_ERROR_INVALID_PARAMETER);
 }
 
-TEST_F(TDMClientTestClient, TdmClientGetFdFailNullTdmClient)
+TEST_P(TDMClient, ClientOutputAddChangeHandlerNullOther)
 {
-       int fd;
+       ASSERT_EQ(PrepareClient(), true);
+       ASSERT_EQ(PrepareOutput(), true);
 
-       error = tdm_client_get_fd(nullptr, &fd);
-       ASSERT_TRUE(TDM_ERROR_INVALID_PARAMETER == error);
+       ASSERT_EQ(tdm_client_output_add_change_handler(output, NULL, NULL), TDM_ERROR_INVALID_PARAMETER);
 }
 
-TEST_F(TDMClientTestClient, TdmClientGetFdFailNullFd)
+/* tdm_client_output_remove_change_handler */
+TEST_P(TDMClient, ClientOutputRemoveChangeHandler)
 {
-       error = tdm_client_get_fd(nullptr, nullptr);
-       ASSERT_TRUE(TDM_ERROR_INVALID_PARAMETER == error);
+       ASSERT_EQ(PrepareClient(), true);
+       ASSERT_EQ(PrepareOutput(), true);
+
+       ASSERT_EQ(tdm_client_output_add_change_handler(output, _ut_tdm_client_output_change_dpms_cb, NULL), TDM_ERROR_NONE);
+       tdm_client_output_remove_change_handler(output, _ut_tdm_client_output_change_dpms_cb, NULL);
 }
 
-TEST_F(TDMClientTestClient, DISABLED_TdmClientHandleEventsSuccessful)
+TEST_P(TDMClient, ClientOutputRemoveChangeHandlerDifferentData)
 {
-       ASSERT_EXIT(
-       {
-               pollfd work_fds[2];
-               itimerspec times_up;
+       bool done = (bool)TDM_UT_INVALID_VALUE;
 
-               std::memset(&work_fds, 0, sizeof work_fds);
-               std::memset(&times_up, 0, sizeof times_up);
+       ASSERT_EQ(PrepareClient(), true);
+       ASSERT_EQ(PrepareOutput(), true);
 
-               tdm_client_get_fd(tdm_cl, &work_fds[0].fd);
-               work_fds[0].events = POLLIN;
-
-               work_fds[1].fd = timerfd_create(CLOCK_MONOTONIC, 0);
-               work_fds[1].events = POLLIN;
+       ASSERT_EQ(tdm_client_output_add_change_handler(output, _ut_tdm_client_output_change_dpms_cb, &done), TDM_ERROR_NONE);
+       tdm_client_output_remove_change_handler(output, _ut_tdm_client_output_change_dpms_cb, NULL);
+}
 
-               times_up.it_value.tv_nsec = 100000000;  /* 100ms */
-               timerfd_settime(work_fds[1].fd, 0, &times_up, nullptr);
+static void
+_ut_tdm_client_output_change_dpms_cb2(tdm_client_output *output,
+                                                                         tdm_output_change_type type,
+                                                                         tdm_value value,
+                                                                         void *user_data)
+{
+       switch (type) {
+       case TDM_OUTPUT_CHANGE_DPMS:
+               tdm_client_output_remove_change_handler(output, _ut_tdm_client_output_change_dpms_cb2, user_data);
+               break;
+       default:
+               break;
+       }
+}
 
-               while (1)
-               {
-                       int ret;
+TEST_P(TDMClient, ClientOutputRemoveChangeHandlerInHandler)
+{
+       tdm_output_dpms dpms = TDM_OUTPUT_DPMS_ON;
 
-                       ret = poll(work_fds, 2, -1);
-                       if (ret < 0 && errno == EINTR) continue;
+       ASSERT_EQ(PrepareClient(), true);
+       ASSERT_EQ(PrepareOutput(), true);
 
-                       if (work_fds[0].revents == POLLIN)
-                       {
-                               tdm_client_handle_events(tdm_cl);
-                               std::cout << "ha.\n";
-                       }
+       ASSERT_EQ(tdm_client_output_add_change_handler(output, _ut_tdm_client_output_change_dpms_cb2, NULL), TDM_ERROR_NONE);
+       ASSERT_EQ(_ut_tdm_pipe_write_msg(pipe_child[1], pipe_parent[0], TDM_UT_PIPE_MSG_DPMS_OFF), true);
+       ASSERT_EQ(tdm_client_output_get_dpms(output, &dpms), TDM_ERROR_NONE);
+       while (dpms != TDM_OUTPUT_DPMS_OFF) {
+               ASSERT_EQ(tdm_client_handle_events_timeout(client, 3000), TDM_ERROR_NONE);
+               ASSERT_EQ(tdm_client_output_get_dpms(output, &dpms), TDM_ERROR_NONE);
+       }
 
-                       if(work_fds[1].revents == POLLIN)
-                               exit(EXIT_SUCCESS);
-               }
-       },
-       ::testing::ExitedWithCode(EXIT_SUCCESS), "");
+       ASSERT_EQ(_ut_tdm_pipe_write_msg(pipe_child[1], pipe_parent[0], TDM_UT_PIPE_MSG_DPMS_ON), true);
+       while (dpms != TDM_OUTPUT_DPMS_ON)
+               ASSERT_EQ(tdm_client_output_get_dpms(output, &dpms), TDM_ERROR_NONE);
 }
 
-TEST_F(TDMClientTestClient, TdmClientHandleEventsFailNullTDMClient)
+TEST_P(TDMClient, ClientOutputRemoveChangeHandlerNullObject)
 {
-       error = tdm_client_handle_events(nullptr);
-       ASSERT_TRUE(TDM_ERROR_INVALID_PARAMETER == error);
+       tdm_client_output_remove_change_handler(NULL, _ut_tdm_client_output_change_dpms_cb, NULL);
 }
 
-TEST_F(TDMClientTestClient, TdmClientGetOutputSuccessful)
+TEST_P(TDMClient, ClientOutputRemoveChangeHandlerNullOther)
 {
-       tdm_client_output* cl_output;
+       ASSERT_EQ(PrepareClient(), true);
+       ASSERT_EQ(PrepareOutput(), true);
 
-       cl_output = tdm_client_get_output(tdm_cl, const_cast<char*>("primary"), nullptr);
-       ASSERT_TRUE(nullptr != cl_output);
+       tdm_client_output_remove_change_handler(output, NULL, NULL);
 }
 
-TEST_F(TDMClientTestClient, TdmClientGetOutputSuccessfulCallTwice)
+/* tdm_client_output_get_refresh_rate */
+TEST_P(TDMClient, ClientOutputGetRefreshRate)
 {
-       tdm_client_output* cl_output_1, *cl_output_2;
+       unsigned int refresh = 0;
 
-       cl_output_1 = tdm_client_get_output(tdm_cl, const_cast<char*>("primary"), nullptr);
-       cl_output_2 = tdm_client_get_output(tdm_cl, const_cast<char*>("primary"), nullptr);
-       ASSERT_TRUE(cl_output_1 == cl_output_2);
-}
+       ASSERT_EQ(PrepareClient(), true);
+       ASSERT_EQ(PrepareOutput(), true);
 
-TEST_F(TDMClientTestClient, TdmClientGetOutputSuccessfulCheckError)
-{
-       tdm_client_get_output(tdm_cl, const_cast<char*>("primary"), &error);
-       ASSERT_TRUE(TDM_ERROR_NONE == error);
+       ASSERT_EQ(tdm_client_output_get_refresh_rate(output, &refresh), TDM_ERROR_NONE);
+       ASSERT_GT(refresh, 0);
 }
 
-TEST_F(TDMClientTestClient, TdmClientGetOutputSuccessfulNullName)
+TEST_P(TDMClient, ClientOutputGetRefreshRateNullObject)
 {
-       tdm_client_output* cl_output;
+       unsigned int refresh = (unsigned int)TDM_UT_INVALID_VALUE;
 
-       cl_output = tdm_client_get_output(tdm_cl, nullptr, nullptr);
-       ASSERT_TRUE(nullptr != cl_output);
+       ASSERT_EQ(tdm_client_output_get_refresh_rate(NULL, &refresh), TDM_ERROR_INVALID_PARAMETER);
+       ASSERT_EQ(refresh, (unsigned int)TDM_UT_INVALID_VALUE);
 }
 
-TEST_F(TDMClientTestClient, TdmClientGetOutputSuccessfulNullNameCheckError)
+TEST_P(TDMClient, ClientOutputGetRefreshRateNullOther)
 {
-       tdm_client_get_output(tdm_cl, nullptr, &error);
-       ASSERT_TRUE(TDM_ERROR_NONE == error);
+       ASSERT_EQ(PrepareClient(), true);
+       ASSERT_EQ(PrepareOutput(), true);
+
+       ASSERT_EQ(tdm_client_output_get_refresh_rate(output, NULL), TDM_ERROR_INVALID_PARAMETER);
 }
 
-TEST_F(TDMClientTestClient, TdmClientGetOutputFailNullTdmClient)
+/* tdm_client_output_get_refresh_rate */
+TEST_P(TDMClient, ClientOutputGetConnStatus)
 {
-       tdm_client_output* cl_output;
+       tdm_output_conn_status status = (tdm_output_conn_status)TDM_UT_INVALID_VALUE;
+
+       ASSERT_EQ(PrepareClient(), true);
+       ASSERT_EQ(PrepareOutput(), true);
 
-       cl_output = tdm_client_get_output(nullptr, const_cast<char*>("primary"), nullptr);
-       ASSERT_TRUE(nullptr == cl_output);
+       ASSERT_EQ(tdm_client_output_get_conn_status(output, &status), TDM_ERROR_NONE);
+       ASSERT_NE(status, (tdm_output_conn_status)TDM_UT_INVALID_VALUE);
 }
 
-TEST_F(TDMClientTestClient, TdmClientGetOutputFailNullTdmClientCheckError)
+TEST_P(TDMClient, ClientOutputGetConnStatusNullObject)
 {
-       tdm_client_get_output(nullptr, const_cast<char*>("primary"), &error);
-       ASSERT_TRUE(TDM_ERROR_INVALID_PARAMETER == error);
+       tdm_output_conn_status status = (tdm_output_conn_status)TDM_UT_INVALID_VALUE;
+
+       ASSERT_EQ(tdm_client_output_get_conn_status(NULL, &status), TDM_ERROR_INVALID_PARAMETER);
+       ASSERT_EQ(status, (tdm_output_conn_status)TDM_UT_INVALID_VALUE);
 }
 
-TEST_F(TDMClientTestClientOutput, DISABLED_TdmClientOutputAddChangeHandlerSuccessful)
+TEST_P(TDMClient, ClientOutputGetConnStatusNullOther)
 {
-       static bool got_an_event = false;
-       wl_display *wl_dsp;
+       ASSERT_EQ(PrepareClient(), true);
+       ASSERT_EQ(PrepareOutput(), true);
 
-       /* is this function implemented fully? */
-       tdm_client_output_add_change_handler(cl_output, [] (tdm_client_output *output,
-                                                                       tdm_output_change_type type,
-                                                                       tdm_value value,
-                                                                       void *user_data) { got_an_event = true; }, nullptr);
+       ASSERT_EQ(tdm_client_output_get_conn_status(output, NULL), TDM_ERROR_INVALID_PARAMETER);
+}
 
-       /* force a requests flush */
-       wl_dsp = wl_display_connect("tdm-socket");
-       wl_display_flush(wl_dsp);
-       wl_display_roundtrip(wl_dsp);
-       wl_display_disconnect(wl_dsp);
+/* tdm_client_output_get_dpms */
+TEST_P(TDMClient, ClientOutputGetDpms)
+{
+       tdm_output_dpms dpms = (tdm_output_dpms)TDM_UT_INVALID_VALUE;
 
-       send_request_to_server(TDMClientTest::ChangeDPMS);
-       tdm_client_handle_events(tdm_cl);
+       ASSERT_EQ(PrepareClient(), true);
+       ASSERT_EQ(PrepareOutput(), true);
 
-       ASSERT_TRUE(true == got_an_event);
+       ASSERT_EQ(tdm_client_output_get_dpms(output, &dpms), TDM_ERROR_NONE);
+       ASSERT_NE(dpms, (tdm_output_dpms)TDM_UT_INVALID_VALUE);
 }
 
-TEST_F(TDMClientTestClientOutput, TdmClientOutputAddChangeHandlerFailNullOutput)
+TEST_P(TDMClient, ClientOutputGetDpmsNullObject)
 {
-       error = tdm_client_output_add_change_handler(nullptr, [] (tdm_client_output *output,
-                                                                       tdm_output_change_type type,
-                                                                       tdm_value value,
-                                                                       void *user_data) {}, nullptr);
-       ASSERT_TRUE(TDM_ERROR_INVALID_PARAMETER == error);
-}
+       tdm_output_dpms dpms = (tdm_output_dpms)TDM_UT_INVALID_VALUE;
 
-TEST_F(TDMClientTestClientOutput, TdmClientOutputAddChangeHandlerFailNullHandler)
-{
-       error = tdm_client_output_add_change_handler(cl_output, nullptr, nullptr);
-       ASSERT_TRUE(TDM_ERROR_INVALID_PARAMETER == error);
+       ASSERT_EQ(tdm_client_output_get_dpms(NULL, &dpms), TDM_ERROR_INVALID_PARAMETER);
+       ASSERT_EQ(dpms, (tdm_output_dpms)TDM_UT_INVALID_VALUE);
 }
 
-TEST_F(TDMClientTestClientOutputDeathTest, TdmClientOutputRemoveChangeHandlerSuccessful)
+TEST_P(TDMClient, ClientOutputGetDpmsNullOther)
 {
-       ASSERT_EXIT(
-       {
-               auto func = [] (tdm_client_output *output, tdm_output_change_type type, tdm_value value,
-                               void *user_data) {};
+       ASSERT_EQ(PrepareClient(), true);
+       ASSERT_EQ(PrepareOutput(), true);
 
-               tdm_client_output_add_change_handler(cl_output, func, nullptr);
-
-               tdm_client_output_remove_change_handler(cl_output, func, nullptr);
-
-               exit(EXIT_SUCCESS);
-       },
-       ::testing::ExitedWithCode(EXIT_SUCCESS), "");
+       ASSERT_EQ(tdm_client_output_get_dpms(output, NULL), TDM_ERROR_INVALID_PARAMETER);
 }
 
-TEST_F(TDMClientTestClientOutputDeathTest, TdmClientOutputRemoveChangeHandlerSuccessfulInvalidHandler)
+/* tdm_client_output_create_vblank */
+TEST_P(TDMClient, ClientOutputCreateVblank)
 {
-       ASSERT_EXIT(
-       {
-               auto func = [] (tdm_client_output *output, tdm_output_change_type type, tdm_value value,
-                               void *user_data) {};
+       tdm_error ret;
 
-               tdm_client_output_remove_change_handler(cl_output, func, nullptr);
+       ASSERT_EQ(PrepareClient(), true);
+       ASSERT_EQ(PrepareOutput(), true);
 
-               exit(EXIT_SUCCESS);
-       },
-       ::testing::ExitedWithCode(EXIT_SUCCESS), "");
+       vblank = tdm_client_output_create_vblank(output, &ret);
+       ASSERT_EQ(ret, TDM_ERROR_NONE);
+       ASSERT_NE(vblank, NULL);
 }
 
-TEST_F(TDMClientTestClientOutputDeathTest, TdmClientOutputRemoveChangeHandlerFailNullOutput)
+TEST_P(TDMClient, ClientOutputCreateVblankNullObject)
 {
-       ASSERT_EXIT(
-       {
-               auto func = [] (tdm_client_output *output, tdm_output_change_type type, tdm_value value,
-                               void *user_data) {};
+       tdm_error ret;
 
-               tdm_client_output_remove_change_handler(nullptr, func, nullptr);
-
-               exit(EXIT_SUCCESS);
-       },
-       ::testing::ExitedWithCode(EXIT_SUCCESS), "");
+       vblank = tdm_client_output_create_vblank(NULL, &ret);
+       ASSERT_EQ(ret, TDM_ERROR_INVALID_PARAMETER);
+       ASSERT_EQ(vblank, NULL);
 }
 
-TEST_F(TDMClientTestClientOutputDeathTest, TdmClientOutputRemoveChangeHandlerFailNullHandler)
+TEST_P(TDMClient, ClientOutputCreateVblankNullOther)
 {
-       ASSERT_EXIT(
-       {
-               tdm_client_output_remove_change_handler(cl_output, nullptr, nullptr);
+       ASSERT_EQ(PrepareClient(), true);
+       ASSERT_EQ(PrepareOutput(), true);
 
-               exit(EXIT_SUCCESS);
-       },
-       ::testing::ExitedWithCode(EXIT_SUCCESS), "");
+       vblank = tdm_client_output_create_vblank(output, NULL);
+       ASSERT_NE(vblank, NULL);
 }
 
-TEST_F(TDMClientTestClientOutput, TdmClientOutputGetRefreshRateSuccessful)
+/* tdm_client_vblank_destroy */
+TEST_P(TDMClient, ClientVblankDestroy)
 {
-       uint32_t refresh_rate;
+       tdm_error ret;
 
-       error = tdm_client_output_get_refresh_rate(cl_output, &refresh_rate);
-       ASSERT_TRUE(TDM_ERROR_NONE == error);
-}
+       ASSERT_EQ(PrepareClient(), true);
+       ASSERT_EQ(PrepareOutput(), true);
 
-TEST_F(TDMClientTestClientOutput, TdmClientOutputGetRefreshRateFailNullOutput)
-{
-       uint32_t refresh_rate;
+       vblank = tdm_client_output_create_vblank(output, &ret);
+       ASSERT_EQ(ret, TDM_ERROR_NONE);
+       ASSERT_NE(vblank, NULL);
 
-       error = tdm_client_output_get_refresh_rate(nullptr, &refresh_rate);
-       ASSERT_TRUE(TDM_ERROR_INVALID_PARAMETER == error);
+       tdm_client_vblank_destroy(vblank);
+       vblank = NULL;
 }
 
-TEST_F(TDMClientTestClientOutput, TdmClientOutputGetRefreshRateFailNullRefreshRate)
+TEST_P(TDMClient, ClientVblankDestroyNullObject)
 {
-       error = tdm_client_output_get_refresh_rate(cl_output, nullptr);
-       ASSERT_TRUE(TDM_ERROR_INVALID_PARAMETER == error);
+       tdm_client_vblank_destroy(NULL);
 }
 
-TEST_F(TDMClientTestClientOutput, TdmClientOutputGetConnectionStatusSuccessful)
+/* tdm_client_vblank_set_name */
+TEST_P(TDMClient, ClientVblankSetName)
 {
-       tdm_output_conn_status conn_status;
+       ASSERT_EQ(PrepareClient(), true);
+       ASSERT_EQ(PrepareOutput(), true);
+       ASSERT_EQ(PrepareVblank(), true);
 
-       error = tdm_client_output_get_conn_status(cl_output, &conn_status);
-       ASSERT_TRUE(TDM_ERROR_NONE == error);
+       ASSERT_EQ(tdm_client_vblank_set_name(vblank, TDM_UT_VBLANK_NAME), TDM_ERROR_NONE);
 }
 
-TEST_F(TDMClientTestClientOutput, TdmClientOutputGetConnectionStatusFailNullOutput)
+TEST_P(TDMClient, ClientVblankSetNameTwice)
 {
-       tdm_output_conn_status conn_status;
+       ASSERT_EQ(PrepareClient(), true);
+       ASSERT_EQ(PrepareOutput(), true);
+       ASSERT_EQ(PrepareVblank(), true);
 
-       error = tdm_client_output_get_conn_status(nullptr, &conn_status);
-       ASSERT_TRUE(TDM_ERROR_INVALID_PARAMETER == error);
+       ASSERT_EQ(tdm_client_vblank_set_name(vblank, TDM_UT_VBLANK_NAME), TDM_ERROR_NONE);
+       ASSERT_EQ(tdm_client_vblank_set_name(vblank, TDM_UT_VBLANK_NAME), TDM_ERROR_NONE);
 }
 
-TEST_F(TDMClientTestClientOutput, TTdmClientOutputGetConnectionStatusFailNullConnState)
+TEST_P(TDMClient, ClientVblankSetNameNullObject)
 {
-       error = tdm_client_output_get_conn_status(cl_output, nullptr);
-       ASSERT_TRUE(TDM_ERROR_INVALID_PARAMETER == error);
+       ASSERT_EQ(tdm_client_vblank_set_name(NULL, TDM_UT_VBLANK_NAME), TDM_ERROR_INVALID_PARAMETER);
 }
 
-TEST_F(TDMClientTestClientOutput, TdmClientOutputGetDpmsSuccessful)
+/* tdm_client_vblank_set_sync */
+TEST_P(TDMClient, ClientVblankSetSync)
 {
-       tdm_output_dpms dpms_val;
+       ASSERT_EQ(PrepareClient(), true);
+       ASSERT_EQ(PrepareOutput(), true);
+       ASSERT_EQ(PrepareVblank(), true);
 
-       error = tdm_client_output_get_dpms(cl_output, &dpms_val);
-       ASSERT_TRUE(TDM_ERROR_NONE == error);
+       ASSERT_EQ(tdm_client_vblank_set_sync(vblank, 1), TDM_ERROR_NONE);
 }
 
-TEST_F(TDMClientTestClientOutput, TdmClientOutputGetDpmsFailNullOutput)
+TEST_P(TDMClient, ClientVblankSetSyncTwice)
 {
-       tdm_output_dpms dpms_val;
+       ASSERT_EQ(PrepareClient(), true);
+       ASSERT_EQ(PrepareOutput(), true);
+       ASSERT_EQ(PrepareVblank(), true);
 
-       error = tdm_client_output_get_dpms(nullptr, &dpms_val);
-       ASSERT_TRUE(TDM_ERROR_INVALID_PARAMETER == error);
+       ASSERT_EQ(tdm_client_vblank_set_sync(vblank, 1), TDM_ERROR_NONE);
+       ASSERT_EQ(tdm_client_vblank_set_sync(vblank, 1), TDM_ERROR_NONE);
 }
 
-TEST_F(TDMClientTestClientOutput, TdmClientOutputGetDpmsFailNullDpmsArg)
+TEST_P(TDMClient, ClientVblankSetSyncNullObject)
 {
-       error = tdm_client_output_get_dpms(cl_output, nullptr);
-       ASSERT_TRUE(TDM_ERROR_INVALID_PARAMETER == error);
+       ASSERT_EQ(tdm_client_vblank_set_sync(NULL, 1), TDM_ERROR_INVALID_PARAMETER);
 }
 
-TEST_F(TDMClientTestClientOutput, TdmClientOutputCreateVblankSuccessful)
+/* tdm_client_vblank_set_fps */
+TEST_P(TDMClient, ClientVblankSetFps)
 {
-       tdm_client_vblank* cl_vblank;
-
-       cl_vblank = tdm_client_output_create_vblank(cl_output, nullptr);
-       ASSERT_TRUE(nullptr != cl_vblank);
+       ASSERT_EQ(PrepareClient(), true);
+       ASSERT_EQ(PrepareOutput(), true);
+       ASSERT_EQ(PrepareVblank(), true);
 
-       tdm_client_vblank_destroy(cl_vblank);
+       ASSERT_EQ(tdm_client_vblank_set_fps(vblank, 30), TDM_ERROR_NONE);
 }
 
-TEST_F(TDMClientTestClientOutput, TdmClientOutputCreateVblankSuccessfulCheckError)
+TEST_P(TDMClient, ClientVblankSetFpsTwice)
 {
-       tdm_client_vblank* cl_vblank;
+       ASSERT_EQ(PrepareClient(), true);
+       ASSERT_EQ(PrepareOutput(), true);
+       ASSERT_EQ(PrepareVblank(), true);
 
-       cl_vblank = tdm_client_output_create_vblank(cl_output, &error);
-       ASSERT_TRUE(TDM_ERROR_NONE == error);
-
-       tdm_client_vblank_destroy(cl_vblank);
+       ASSERT_EQ(tdm_client_vblank_set_fps(vblank, 30), TDM_ERROR_NONE);
+       ASSERT_EQ(tdm_client_vblank_set_fps(vblank, 30), TDM_ERROR_NONE);
 }
 
-TEST_F(TDMClientTestClientOutput, TdmClientOutputCreateVblankFailNullOutput)
+TEST_P(TDMClient, ClientVblankSetFpsNullObject)
 {
-       tdm_client_vblank* cl_vblank;
-
-       cl_vblank = tdm_client_output_create_vblank(nullptr, nullptr);
-       ASSERT_TRUE(nullptr == cl_vblank);
+       ASSERT_EQ(tdm_client_vblank_set_fps(NULL, 30), TDM_ERROR_INVALID_PARAMETER);
 }
 
-TEST_F(TDMClientTestClientOutput, TdmClientOutputCreateVblankFailNullOutputCheckError)
+/* tdm_client_vblank_set_offset */
+TEST_P(TDMClient, ClientVblankSetOffset)
 {
-       tdm_client_output_create_vblank(nullptr, &error);
-       ASSERT_TRUE(TDM_ERROR_INVALID_PARAMETER == error);
+       ASSERT_EQ(PrepareClient(), true);
+       ASSERT_EQ(PrepareOutput(), true);
+       ASSERT_EQ(PrepareVblank(), true);
+
+       ASSERT_EQ(tdm_client_vblank_set_offset(vblank, 10), TDM_ERROR_NONE);
 }
 
-TEST_F(TDMClientTestClientOutputDeathTest, TdmClientDestroyVblankSuccessful)
+TEST_P(TDMClient, ClientVblankSetOffsetTwice)
 {
-       ASSERT_EXIT(
-       {
-               tdm_client_vblank *cl_vblank = tdm_client_output_create_vblank(cl_output, nullptr);
+       ASSERT_EQ(PrepareClient(), true);
+       ASSERT_EQ(PrepareOutput(), true);
+       ASSERT_EQ(PrepareVblank(), true);
 
-               tdm_client_vblank_destroy(cl_vblank);
-               exit(EXIT_SUCCESS);
-       },
-       ::testing::ExitedWithCode(EXIT_SUCCESS), "");
+       ASSERT_EQ(tdm_client_vblank_set_offset(vblank, 10), TDM_ERROR_NONE);
+       ASSERT_EQ(tdm_client_vblank_set_offset(vblank, 10), TDM_ERROR_NONE);
 }
 
-TEST_F(TDMClientTestClientOutputDeathTest, TdmClientDestroyVblankFailNoClientVblankArg)
+TEST_P(TDMClient, ClientVblankSetOffsetNullObject)
 {
-       ASSERT_EXIT(
-       {
-               tdm_client_vblank_destroy(nullptr);
-               exit(EXIT_SUCCESS);
-       },
-       ::testing::ExitedWithCode(EXIT_SUCCESS), "");
+       ASSERT_EQ(tdm_client_vblank_set_offset(NULL, 10), TDM_ERROR_INVALID_PARAMETER);
 }
 
-TEST_F(TDMClientTestVblank, TdmClientVblankSetNameSuccessful)
+/* tdm_client_vblank_set_enable_fake */
+TEST_P(TDMClient, ClientVblankSetEnableFake)
 {
-       error = tdm_client_vblank_set_name(cl_vblank, "wassup");
-       ASSERT_TRUE(TDM_ERROR_NONE == error);
-}
+       ASSERT_EQ(PrepareClient(), true);
+       ASSERT_EQ(PrepareOutput(), true);
+       ASSERT_EQ(PrepareVblank(), true);
 
-TEST_F(TDMClientTestVblank, TdmClientVblankSetNameSuccessfulNoExplicitName)
-{
-       error = tdm_client_vblank_set_name(cl_vblank, nullptr);
-       ASSERT_TRUE(TDM_ERROR_NONE == error);
+       ASSERT_EQ(tdm_client_vblank_set_enable_fake(vblank, 1), TDM_ERROR_NONE);
 }
 
-TEST_F(TDMClientTestVblank, TdmClientVblankSetNameFailNullClientVblank)
+TEST_P(TDMClient, ClientVblankSetEnableFakeTwice)
 {
-       error = tdm_client_vblank_set_name(nullptr, "wassup");
-       ASSERT_TRUE(TDM_ERROR_INVALID_PARAMETER == error);
-}
+       ASSERT_EQ(PrepareClient(), true);
+       ASSERT_EQ(PrepareOutput(), true);
+       ASSERT_EQ(PrepareVblank(), true);
 
-TEST_F(TDMClientTestVblank, TdmClientVblankSetSyncSuccessful)
-{
-       error = tdm_client_vblank_set_sync(cl_vblank, 0);
-       ASSERT_TRUE(TDM_ERROR_NONE == error);
+       ASSERT_EQ(tdm_client_vblank_set_enable_fake(vblank, 1), TDM_ERROR_NONE);
+       ASSERT_EQ(tdm_client_vblank_set_enable_fake(vblank, 1), TDM_ERROR_NONE);
 }
 
-TEST_F(TDMClientTestVblank, TdmClientVblankSetSyncFailNullClientVblank)
+TEST_P(TDMClient, ClientVblankSetEnableFakeNullObject)
 {
-       error = tdm_client_vblank_set_sync(nullptr, 0);
-       ASSERT_TRUE(TDM_ERROR_INVALID_PARAMETER == error);
+       ASSERT_EQ(tdm_client_vblank_set_enable_fake(NULL, 1), TDM_ERROR_INVALID_PARAMETER);
 }
 
-TEST_F(TDMClientTestVblank, TdmClientVblankSetFpsSuccessful)
+static void
+_ut_tdm_client_vblank_cb2(tdm_client_vblank *vblank,
+                                                 tdm_error error,
+                                                 unsigned int sequence,
+                                                 unsigned int tv_sec,
+                                                 unsigned int tv_usec,
+                                                 void *user_data)
 {
-       error = tdm_client_vblank_set_fps(cl_vblank, 60);
-       ASSERT_TRUE(TDM_ERROR_NONE == error);
+       bool *done = (bool *)user_data;
+       if (done)
+               *done = true;
 }
 
-TEST_F(TDMClientTestVblank, TdmClientVblankSetFpsSuccessfulSetTwice)
+/* tdm_client_vblank_wait */
+TEST_P(TDMClient, ClientVblankWait)
 {
-       tdm_client_vblank_set_fps(cl_vblank, 60);
-       error = tdm_client_vblank_set_fps(cl_vblank, 60);
-       ASSERT_TRUE(TDM_ERROR_NONE == error);
+       bool done;
+
+       ASSERT_EQ(PrepareClient(), true);
+       ASSERT_EQ(PrepareOutput(), true);
+       ASSERT_EQ(PrepareVblank(), true);
+
+       done = false;
+       ASSERT_EQ(tdm_client_vblank_wait(vblank, 1, _ut_tdm_client_vblank_cb2, &done), TDM_ERROR_NONE);
+
+       start = tdm_helper_get_time();
+       while (!done)
+               ASSERT_EQ(tdm_client_handle_events_timeout(client, 3000), TDM_ERROR_NONE);
+       end = tdm_helper_get_time();
+
+       /* "+ vrefresh_interval" consider the delay of socket communication between kernel and platform */
+       ASSERT_LT((end - start), (vrefresh_interval + vrefresh_interval));
 }
 
-TEST_F(TDMClientTestVblank, TdmClientVblankSetFpsFailNullClientVblank)
+TEST_P(TDMClient, ClientVblankWaitFewTime)
 {
-       error = tdm_client_vblank_set_fps(nullptr, 60);
-       ASSERT_TRUE(TDM_ERROR_INVALID_PARAMETER == error);
+       bool done1, done2, done3;
+
+       ASSERT_EQ(PrepareClient(), true);
+       ASSERT_EQ(PrepareOutput(), true);
+       ASSERT_EQ(PrepareVblank(), true);
+
+       done1 = done2 = done3 = false;
+       ASSERT_EQ(tdm_client_vblank_wait(vblank, 1, _ut_tdm_client_vblank_cb2, &done1), TDM_ERROR_NONE);
+       ASSERT_EQ(tdm_client_vblank_wait(vblank, 1, _ut_tdm_client_vblank_cb2, &done2), TDM_ERROR_NONE);
+       ASSERT_EQ(tdm_client_vblank_wait(vblank, 1, _ut_tdm_client_vblank_cb2, &done3), TDM_ERROR_NONE);
+
+       start = tdm_helper_get_time();
+       while (!done1 || !done2 || !done3)
+               ASSERT_EQ(tdm_client_handle_events_timeout(client, 3000), TDM_ERROR_NONE);
+       end = tdm_helper_get_time();
+
+       /* "+ vrefresh_interval" consider the delay of socket communication between kernel and platform */
+       ASSERT_LT((end - start), (vrefresh_interval + vrefresh_interval));
+
 }
 
-TEST_F(TDMClientTestVblank, TdmClientVblankSetFpsFailInvalidFpsArg)
+TEST_P(TDMClient, ClientVblankWaitInterval0)
 {
-       error = tdm_client_vblank_set_fps(cl_vblank, 0);
-       ASSERT_TRUE(TDM_ERROR_INVALID_PARAMETER == error);
+       ASSERT_EQ(PrepareClient(), true);
+       ASSERT_EQ(PrepareOutput(), true);
+       ASSERT_EQ(PrepareVblank(), true);
+
+       ASSERT_EQ(tdm_client_vblank_wait(vblank, 0, _ut_tdm_client_vblank_cb2, NULL), TDM_ERROR_INVALID_PARAMETER);
 }
 
-TEST_F(TDMClientTestVblank, TdmClientVblankSetOffsetSuccessful)
+TEST_P(TDMClient, ClientVblankWaitInterval)
 {
-       error = tdm_client_vblank_set_offset(cl_vblank, 10);
-       ASSERT_TRUE(TDM_ERROR_NONE == error);
+       bool done;
+
+       ASSERT_EQ(PrepareClient(), true);
+       ASSERT_EQ(PrepareOutput(), true);
+       ASSERT_EQ(PrepareVblank(), true);
+
+       /* start from 1 */
+       for (int t = 1; t < 10; t++) {
+               done = false;
+               ASSERT_EQ(tdm_client_vblank_wait(vblank, t, _ut_tdm_client_vblank_cb2, &done), TDM_ERROR_NONE);
+
+               start = tdm_helper_get_time();
+               while (!done)
+                       ASSERT_EQ(tdm_client_handle_events_timeout(client, 3000), TDM_ERROR_NONE);
+               end = tdm_helper_get_time();
+
+               /* "+ vrefresh_interval" consider the delay of socket communication between kernel and platform */
+               ASSERT_GT((end - start), (vrefresh_interval * (t - 1)));
+               ASSERT_LT((end - start), (vrefresh_interval * t + vrefresh_interval));
+       }
 }
 
-TEST_F(TDMClientTestVblank, TdmClientVblankSetOffsetSuccessfulSetTwice)
+static void
+_ut_tdm_client_vblank_cb3(tdm_client_vblank *vblank,
+                                                 tdm_error error,
+                                                 unsigned int sequence,
+                                                 unsigned int tv_sec,
+                                                 unsigned int tv_usec,
+                                                 void *user_data)
 {
-       tdm_client_vblank_set_offset(cl_vblank, 10);
-       error = tdm_client_vblank_set_offset(cl_vblank, 10);
-       ASSERT_TRUE(TDM_ERROR_NONE == error);
+       unsigned int *cur_seq = (unsigned int *)user_data;
+       if (cur_seq)
+               *cur_seq = sequence;
 }
 
-TEST_F(TDMClientTestVblank, TdmClientVblankSetOffsetFailNullClientVblank)
+TEST_P(TDMClient, ClientVblankWaitSeq)
 {
-       error = tdm_client_vblank_set_offset(nullptr, 10);
-       ASSERT_TRUE(TDM_ERROR_INVALID_PARAMETER == error);
+       ASSERT_EQ(PrepareClient(), true);
+       ASSERT_EQ(PrepareOutput(), true);
+       ASSERT_EQ(PrepareVblank(), true);
+
+       for (int t = 0; t < 10; t++) {
+               unsigned int cur_seq = 0, temp = 0;
+
+               ASSERT_EQ(tdm_client_vblank_wait(vblank, 1, _ut_tdm_client_vblank_cb3, &cur_seq), TDM_ERROR_NONE);
+               while (cur_seq == 0)
+                       ASSERT_EQ(tdm_client_handle_events_timeout(client, 3000), TDM_ERROR_NONE);
+
+               start = tdm_helper_get_time();
+               ASSERT_EQ(tdm_client_vblank_wait_seq(vblank, cur_seq + 1, _ut_tdm_client_vblank_cb3, &temp), TDM_ERROR_NONE);
+               while (temp == 0)
+                       ASSERT_EQ(tdm_client_handle_events_timeout(client, 3000), TDM_ERROR_NONE);
+               end = tdm_helper_get_time();
+
+               /* "+ vrefresh_interval" consider the delay of socket communication between kernel and platform */
+               ASSERT_LT((end - start), (vrefresh_interval + vrefresh_interval));
+       }
 }
 
-TEST_F(TDMClientTestVblank, TdmClientVblankSetFakeSuccessfulEnableFake)
+TEST_P(TDMClient, ClientVblankWaitSeqInterval)
 {
-       error = tdm_client_vblank_set_enable_fake(cl_vblank, 1);
-       ASSERT_TRUE(TDM_ERROR_NONE == error);
+       ASSERT_EQ(PrepareClient(), true);
+       ASSERT_EQ(PrepareOutput(), true);
+       ASSERT_EQ(PrepareVblank(), true);
+
+       /* start from 1 */
+       for (int t = 1; t < 10; t++) {
+               unsigned int cur_seq = 0, temp = 0;
+
+               ASSERT_EQ(tdm_client_vblank_wait(vblank, 1, _ut_tdm_client_vblank_cb3, &cur_seq), TDM_ERROR_NONE);
+               while (cur_seq == 0)
+                       ASSERT_EQ(tdm_client_handle_events_timeout(client, 3000), TDM_ERROR_NONE);
+
+               start = tdm_helper_get_time();
+               ASSERT_EQ(tdm_client_vblank_wait_seq(vblank, cur_seq + t, _ut_tdm_client_vblank_cb3, &temp), TDM_ERROR_NONE);
+               while (temp == 0)
+                       ASSERT_EQ(tdm_client_handle_events_timeout(client, 3000), TDM_ERROR_NONE);
+               end = tdm_helper_get_time();
+
+               /* "+ vrefresh_interval" consider the delay of socket communication between kernel and platform */
+               ASSERT_GT((end - start), (vrefresh_interval * (t - 1)));
+               ASSERT_LT((end - start), (vrefresh_interval * t + vrefresh_interval));
+       }
 }
 
-TEST_F(TDMClientTestVblank, TdmClientVblankSetFakeSuccessfulDisableFake)
+TEST_P(TDMClient, ClientVblankWaitSetOffset)
 {
-       error = tdm_client_vblank_set_enable_fake(cl_vblank, 0);
-       ASSERT_TRUE(TDM_ERROR_NONE == error);
+       bool done;
+
+       ASSERT_EQ(PrepareClient(), true);
+       ASSERT_EQ(PrepareOutput(), true);
+       ASSERT_EQ(PrepareVblank(), true);
+
+       ASSERT_EQ(tdm_client_vblank_set_offset(vblank, 100), TDM_ERROR_NONE);
+
+       done = false;
+       ASSERT_EQ(tdm_client_vblank_wait(vblank, 1, _ut_tdm_client_vblank_cb2, &done), TDM_ERROR_NONE);
+
+       start = tdm_helper_get_time();
+       while (!done)
+               ASSERT_EQ(tdm_client_handle_events_timeout(client, 3000), TDM_ERROR_NONE);
+       end = tdm_helper_get_time();
+
+       /* "+ vrefresh_interval" consider the delay of socket communication between kernel and platform */
+       ASSERT_GT((end - start), (0.1));
+       ASSERT_LT((end - start), (vrefresh_interval + vrefresh_interval + 0.1));
 }
 
-TEST_F(TDMClientTestVblank, TdmClientVblankSetFakeSuccessfulSetTwice)
+TEST_P(TDMClient, ClientVblankWaitSetFps)
 {
-       tdm_client_vblank_set_enable_fake(cl_vblank, 0);
-       error = tdm_client_vblank_set_enable_fake(cl_vblank, 0);
-       ASSERT_TRUE(TDM_ERROR_NONE == error);
+       bool done;
+       double interval;
+       unsigned int fps = 10;
+
+       ASSERT_EQ(PrepareClient(), true);
+       ASSERT_EQ(PrepareOutput(), true);
+       ASSERT_EQ(PrepareVblank(), true);
+
+       ASSERT_EQ(tdm_client_vblank_set_fps(vblank, fps), TDM_ERROR_NONE);
+       interval = 1.0 / (double)fps;
+
+       done = false;
+       ASSERT_EQ(tdm_client_vblank_wait(vblank, 1, _ut_tdm_client_vblank_cb2, &done), TDM_ERROR_NONE);
+
+       start = tdm_helper_get_time();
+       while (!done)
+               ASSERT_EQ(tdm_client_handle_events_timeout(client, 3000), TDM_ERROR_NONE);
+       end = tdm_helper_get_time();
+
+       /* "+ vrefresh_interval" consider the delay of socket communication between kernel and platform */
+       ASSERT_GT((end - start), (interval - vrefresh_interval));
+       ASSERT_LT((end - start), (interval + vrefresh_interval));
 }
 
-TEST_F(TDMClientTestVblank, TdmClientVblankSetFakeFailNullClientVblank)
+#if 0
+
+TEST_P(TDMVblank, VblankWaitEnableDisableGlobalFps)
 {
-       error = tdm_client_vblank_set_enable_fake(nullptr, 0);
-       ASSERT_TRUE(TDM_ERROR_INVALID_PARAMETER == error);
+       TDM_UT_SKIP_FLAG(has_outputs);
+
+       unsigned int fps = (unsigned int)TDM_UT_INVALID_VALUE;
+       double vrefresh_interval;
+       unsigned int cur_seq[3];
+       unsigned int global_fps = 5;
+       double start, end, interval;
+
+       ASSERT_EQ(TestPrepareOutput(), true);
+       ASSERT_EQ(TestCreateVblanks3(), true);
+       ASSERT_EQ(vblank_count, 3);
+
+       ASSERT_EQ(tdm_vblank_get_fps(vblanks[0], &fps), TDM_ERROR_NONE);
+       ASSERT_TRUE(fps >= 30 && fps != (unsigned int)TDM_UT_INVALID_VALUE);
+       vrefresh_interval = 1.0 / (double)fps;
+
+       for (int v = 0; v < 3; v++)
+               ASSERT_EQ(tdm_vblank_set_fixed_fps(vblanks[v], 10 * (v + 1)), TDM_ERROR_NONE);
+
+       /* enable test */
+       tdm_vblank_enable_global_fps(1, global_fps);
+       interval = 1.0 / (double)global_fps;
+
+       for (int v = 0; v < 3; v++) {
+               cur_seq[v] = 0;
+               ASSERT_EQ(tdm_vblank_wait(vblanks[v], 0, 0, 1, _ut_tdm_vblank_cb, &cur_seq[v]), TDM_ERROR_NONE);
+       }
+
+       start = tdm_helper_get_time();
+       while (cur_seq[0] == 0)
+               ASSERT_EQ(ut_tdm_display_handle_events(dpy), TDM_ERROR_NONE);
+       end = tdm_helper_get_time();
+
+       ASSERT_NE(cur_seq[1], 0);
+       ASSERT_NE(cur_seq[2], 0);
+
+       /* "+- vrefresh_interval" consider the delay of socket communication between kernel and platform */
+       ASSERT_GT((end - start), (interval - vrefresh_interval));
+       ASSERT_LT((end - start), (interval + vrefresh_interval));
+
+       /* disable test */
+       tdm_vblank_enable_global_fps(0, 0);
+
+       for (int v = 0; v < 3; v++) {
+               cur_seq[v] = 0;
+               ASSERT_EQ(tdm_vblank_wait(vblanks[v], 0, 0, 1, _ut_tdm_vblank_cb, &cur_seq[v]), TDM_ERROR_NONE);
+       }
+
+       while (cur_seq[0] == 0)
+               ASSERT_EQ(ut_tdm_display_handle_events(dpy), TDM_ERROR_NONE);
+       ASSERT_EQ(cur_seq[1], 0);
+       ASSERT_EQ(cur_seq[2], 0);
+
+       while (cur_seq[1] == 0)
+               ASSERT_EQ(ut_tdm_display_handle_events(dpy), TDM_ERROR_NONE);
+       ASSERT_EQ(cur_seq[2], 0);
 }
 
-TEST_F(TDMClientTestVblank, TdmClientVblankWaitSuccessful)
+TEST_P(TDMVblank, VblankWaitIgnoreGlobalFps)
 {
-       auto func = [](tdm_client_vblank *vblank, tdm_error error, unsigned int sequence,
-                        unsigned int tv_sec, unsigned int tv_usec,  void *user_data) {};
+       TDM_UT_SKIP_FLAG(has_outputs);
+
+       unsigned int fps = (unsigned int)TDM_UT_INVALID_VALUE;
+       unsigned int cur_seq[3];
+       unsigned int global_fps = 5;
+       double start, end, interval;
+
+       ASSERT_EQ(TestPrepareOutput(), true);
+       ASSERT_EQ(TestCreateVblanks3(), true);
+       ASSERT_EQ(vblank_count, 3);
+
+       ASSERT_EQ(tdm_vblank_get_fps(vblanks[0], &fps), TDM_ERROR_NONE);
+       ASSERT_TRUE(fps >= 30 && fps != (unsigned int)TDM_UT_INVALID_VALUE);
+       interval = 1.0 / (double)fps;
 
-       tdm_client_vblank_set_sync(cl_vblank, 0);
-       tdm_client_vblank_set_enable_fake(cl_vblank, 1);
+       /* 2nd vblank will ignore the global fps. */
+       ASSERT_EQ(tdm_vblank_ignore_global_fps(vblanks[1], 1), TDM_ERROR_NONE);
 
-       error = tdm_client_vblank_wait(cl_vblank, 1, func, nullptr);
-       ASSERT_TRUE(TDM_ERROR_NONE == error);
+       tdm_vblank_enable_global_fps(1, global_fps);
+
+       for (int v = 0; v < 3; v++) {
+               cur_seq[v] = 0;
+               ASSERT_EQ(tdm_vblank_wait(vblanks[v], 0, 0, 1, _ut_tdm_vblank_cb, &cur_seq[v]), TDM_ERROR_NONE);
+       }
+
+       start = tdm_helper_get_time();
+       while (cur_seq[1] == 0)
+               ASSERT_EQ(ut_tdm_display_handle_events(dpy), TDM_ERROR_NONE);
+       end = tdm_helper_get_time();
+
+       ASSERT_EQ(cur_seq[0], 0);
+       ASSERT_EQ(cur_seq[2], 0);
+
+       /* "+ vrefresh_interval" consider the delay of socket communication between kernel and platform */
+       ASSERT_LT((end - start), (interval + interval));
+
+       while (cur_seq[0] == 0)
+               ASSERT_EQ(ut_tdm_display_handle_events(dpy), TDM_ERROR_NONE);
+       ASSERT_NE(cur_seq[2], 0);
 }
 
-TEST_F(TDMClientTestVblank, TdmClientVblankWaitFailNullClientVblank)
+#endif
+
+TEST_P(TDMClient, ClientVblankWaitNullObject)
 {
-       auto func = [](tdm_client_vblank *vblank, tdm_error error, unsigned int sequence,
-                        unsigned int tv_sec, unsigned int tv_usec,  void *user_data) {};
+       unsigned int cur_seq = 0;
 
-       error = tdm_client_vblank_wait(nullptr, 1, func, nullptr);
-       ASSERT_TRUE(TDM_ERROR_INVALID_PARAMETER == error);
+       ASSERT_EQ(tdm_client_vblank_wait(NULL, 1, _ut_tdm_client_vblank_cb3, &cur_seq), TDM_ERROR_INVALID_PARAMETER);
 }
 
-TEST_F(TDMClientTestVblank, TdmClientVblankWaitFailNullHandler)
+TEST_P(TDMClient, ClientVblankWaitNullOther)
 {
-       error = tdm_client_vblank_wait(cl_vblank, 1, nullptr, nullptr);
-       ASSERT_TRUE(TDM_ERROR_INVALID_PARAMETER == error);
+       ASSERT_EQ(PrepareClient(), true);
+       ASSERT_EQ(PrepareOutput(), true);
+       ASSERT_EQ(PrepareVblank(), true);
+
+       ASSERT_EQ(tdm_client_vblank_wait(vblank, 1, NULL, NULL), TDM_ERROR_INVALID_PARAMETER);
 }
 
-TEST_F(TDMClientTestVblank, TdmClientVblankWaitFailInvalidInterval)
+TEST_P(TDMClient, ClientVblankWaitDpmsOff)
 {
-       auto func = [](tdm_client_vblank *vblank, tdm_error error, unsigned int sequence,
-                        unsigned int tv_sec, unsigned int tv_usec,  void *user_data) {};
+       tdm_output_dpms dpms = (tdm_output_dpms)TDM_UT_INVALID_VALUE;
+
+       ASSERT_EQ(PrepareClient(), true);
+       ASSERT_EQ(PrepareOutput(), true);
+       ASSERT_EQ(PrepareVblank(), true);
+
+       ASSERT_EQ(_ut_tdm_pipe_write_msg(pipe_child[1], pipe_parent[0], TDM_UT_PIPE_MSG_DPMS_OFF), true);
+       while (dpms != TDM_OUTPUT_DPMS_OFF)
+               ASSERT_EQ(tdm_client_output_get_dpms(output, &dpms), TDM_ERROR_NONE);
+       ASSERT_EQ(dpms, TDM_OUTPUT_DPMS_OFF);
+
+       ASSERT_EQ(tdm_client_vblank_wait(vblank, 1, _ut_tdm_client_vblank_cb2, NULL), TDM_ERROR_DPMS_OFF);
 
-       error = tdm_client_vblank_wait(cl_vblank, 0, func, nullptr);
-       ASSERT_TRUE(TDM_ERROR_INVALID_PARAMETER == error);
+       ASSERT_EQ(_ut_tdm_pipe_write_msg(pipe_child[1], pipe_parent[0], TDM_UT_PIPE_MSG_DPMS_ON), true);
+       while (dpms != TDM_OUTPUT_DPMS_ON)
+               ASSERT_EQ(tdm_client_output_get_dpms(output, &dpms), TDM_ERROR_NONE);
 }
 
-TEST_F(TDMClientTestVblank, TdmClientVblankWaitSequencySuccessful)
+TEST_P(TDMClient, ClientVblankWaitSetEnableFakeDpmsOff)
 {
-       auto func = [](tdm_client_vblank *vblank, tdm_error error, unsigned int sequence,
-                        unsigned int tv_sec, unsigned int tv_usec,  void *user_data) {};
+       tdm_output_dpms dpms = (tdm_output_dpms)TDM_UT_INVALID_VALUE;
+       bool done;
+
+       ASSERT_EQ(PrepareClient(), true);
+       ASSERT_EQ(PrepareOutput(), true);
+       ASSERT_EQ(PrepareVblank(), true);
+
+       ASSERT_EQ(_ut_tdm_pipe_write_msg(pipe_child[1], pipe_parent[0], TDM_UT_PIPE_MSG_DPMS_OFF), true);
+       while (dpms != TDM_OUTPUT_DPMS_OFF)
+               ASSERT_EQ(tdm_client_output_get_dpms(output, &dpms), TDM_ERROR_NONE);
+
+       ASSERT_EQ(tdm_client_vblank_set_enable_fake(vblank, 1), TDM_ERROR_NONE);
 
-       tdm_client_vblank_set_sync(cl_vblank, 0);
-       tdm_client_vblank_set_enable_fake(cl_vblank, 1);
+       done = false;
+       ASSERT_EQ(tdm_client_vblank_wait(vblank, 1, _ut_tdm_client_vblank_cb2, &done), TDM_ERROR_NONE);
 
-       error = tdm_client_vblank_wait_seq(cl_vblank, 100, func, nullptr);
-       ASSERT_TRUE(TDM_ERROR_NONE == error);
+       while (!done)
+               ASSERT_EQ(tdm_client_handle_events_timeout(client, 3000), TDM_ERROR_NONE);
+
+       ASSERT_EQ(_ut_tdm_pipe_write_msg(pipe_child[1], pipe_parent[0], TDM_UT_PIPE_MSG_DPMS_ON), true);
+       while (dpms != TDM_OUTPUT_DPMS_ON)
+               ASSERT_EQ(tdm_client_output_get_dpms(output, &dpms), TDM_ERROR_NONE);
 }
 
-TEST_F(TDMClientTestVblank, TdmClientVblankWaitSequencyFailNullClientVblank)
+/* tdm_client_vblank_wait */
+TEST_P(TDMClient, ClientVblankIsWaiting)
 {
-       auto func = [](tdm_client_vblank *vblank, tdm_error error, unsigned int sequence,
-                        unsigned int tv_sec, unsigned int tv_usec,  void *user_data) {};
+       bool done;
+       unsigned int waiting;
+
+       ASSERT_EQ(PrepareClient(), true);
+       ASSERT_EQ(PrepareOutput(), true);
+       ASSERT_EQ(PrepareVblank(), true);
+
+       done = false;
+       ASSERT_EQ(tdm_client_vblank_wait(vblank, 1, _ut_tdm_client_vblank_cb2, &done), TDM_ERROR_NONE);
+
+       waiting = tdm_client_vblank_is_waiting(vblank);
+       ASSERT_EQ(waiting, 1);
 
-       error = tdm_client_vblank_wait_seq(nullptr, 1, func, nullptr);
-       ASSERT_TRUE(TDM_ERROR_INVALID_PARAMETER == error);
+       start = tdm_helper_get_time();
+       while (!done)
+               ASSERT_EQ(tdm_client_handle_events_timeout(client, 3000), TDM_ERROR_NONE);
+       end = tdm_helper_get_time();
+
+       /* "+ vrefresh_interval" consider the delay of socket communication between kernel and platform */
+       ASSERT_LT((end - start), (vrefresh_interval + vrefresh_interval));
+
+       waiting = tdm_client_vblank_is_waiting(vblank);
+       ASSERT_EQ(waiting, 0);
 }
 
-TEST_F(TDMClientTestVblank, TdmClientVblankWaitSequencyFailNullHandler)
+/* tdm_client_vblank_wait */
+TEST_P(TDMClient, ClientVblankIsWaitingNullObject)
 {
-       error = tdm_client_vblank_wait_seq(cl_vblank, 1, nullptr, nullptr);
-       ASSERT_TRUE(TDM_ERROR_INVALID_PARAMETER == error);
+       unsigned int waiting = tdm_client_vblank_is_waiting(NULL);
+       ASSERT_EQ(waiting, 0);
 }
 
+#ifdef TDM_UT_TEST_WITH_PARAMS
+INSTANTIATE_TEST_CASE_P(TDMClientParams,
+                                               TDMClient,
+                                               Combine(Bool(), Bool(), Values(TDM_DEFAULT_MODULE)));
+#else
+INSTANTIATE_TEST_CASE_P(TDMClientParams,
+                                               TDMClient,
+                                               Values(TDM_DEFAULT_MODULE));
+#endif
+
+/* LCOV_EXCL_END */
\ No newline at end of file