[utest] Add 108 test cases 94/159694/2
authorKonstantin Drabeniuk <k.drabeniuk@samsung.com>
Fri, 10 Nov 2017 15:39:07 +0000 (17:39 +0200)
committerKonstantin Drabeniuk <k.drabeniuk@samsung.com>
Fri, 10 Nov 2017 15:49:59 +0000 (17:49 +0200)
Covered API funcs. from the tdm_vblank.c file.

Change-Id: I7bc8557863c088fd9623a12bb83fa2415e4351b8
Signed-off-by: Konstantin Drabeniuk <k.drabeniuk@samsung.com>
utests/Makefile.am
utests/src/ut_tdm_vblank.cpp [new file with mode: 0644]

index f44d3e0..6317645 100644 (file)
@@ -6,7 +6,8 @@ tdm_utests_SOURCES = \
        src/ut_tdm_pp.cpp \
        src/ut_tdm_capture.cpp \
        src/ut_tdm_output.cpp \
-       src/ut_tdm_layer.cpp
+       src/ut_tdm_layer.cpp \
+       src/ut_tdm_vblank.cpp
 
 tdm_utests_CXXFLAGS = \
        $(CXXFLAGS) \
diff --git a/utests/src/ut_tdm_vblank.cpp b/utests/src/ut_tdm_vblank.cpp
new file mode 100644 (file)
index 0000000..cde635f
--- /dev/null
@@ -0,0 +1,2125 @@
+/**************************************************************************
+ *
+ * Copyright 2016 Samsung Electronics co., Ltd. All Rights Reserved.
+ *
+ * Contact: Konstantin Drabeniuk <k.drabeniuk@samsung.com>
+ * Contact: Andrii Sokolenko <a.sokolenko@samsung.com>
+ * Contact: Roman Marchenko <r.marchenko@samsung.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+**************************************************************************/
+
+#include "gtest/gtest.h"
+#include "tdm.h"
+#include "tbm_bufmgr.h"
+#include "ut_common.h"
+#include <sys/epoll.h>
+#include <sys/timerfd.h>
+#include <pthread.h>
+
+class TDMVblankWithoutCreating: public ::testing::Test {
+protected:
+       tbm_bufmgr bufmgr;
+       tdm_display *dpy;
+       int output_count;
+       bool has_output;
+       tdm_output *connected_output;
+       const tdm_output_mode *preferred_mode;
+       tdm_output *disconnected_output;
+       tdm_output *default_output;
+
+       void SetUp(void) {
+               tdm_output *output;
+               tdm_output_conn_status status;
+               tdm_error error = TDM_ERROR_NONE;
+
+               bufmgr = NULL;
+               dpy = NULL;
+               output_count = 0;
+               connected_output = NULL;
+               connected_output = NULL;
+               default_output = NULL;
+               preferred_mode = NULL;
+
+               setenv("TDM_DLOG", "1", 1);
+               setenv("XDG_RUNTIME_DIR", ".", 1);
+               setenv("TBM_DLOG", "1", 1);
+               setenv("TBM_DISPLAY_SERVER", "1", 1);
+
+               bufmgr = tbm_bufmgr_init(-1);
+               ASSERT_FALSE(bufmgr == NULL);
+
+               dpy = tdm_display_init(&error);
+               ASSERT_TRUE(error == TDM_ERROR_NONE);
+               ASSERT_FALSE(dpy == NULL);
+
+               error = tdm_display_get_output_count(dpy, &output_count);
+               ASSERT_TRUE(error == TDM_ERROR_NONE);
+               if (output_count > 0)
+                       has_output = true;
+               else
+                       has_output = false;
+
+               for(int i = 0; i < output_count; i++) {
+                       output = tdm_display_get_output(dpy, i, &error);
+                       ASSERT_TRUE(error == TDM_ERROR_NONE);
+                       ASSERT_FALSE(dpy == NULL);
+
+                       error = tdm_output_get_conn_status(output, &status);
+                       ASSERT_TRUE(error == TDM_ERROR_NONE);
+
+                       if (status != TDM_OUTPUT_CONN_STATUS_DISCONNECTED)
+                               connected_output = output;
+                       else
+                               disconnected_output = output;
+               }
+
+               default_output = disconnected_output;
+
+               if (connected_output) {
+                       int output_modes_cnt = 0;
+                       const tdm_output_mode* output_modes;
+
+                       error = tdm_output_get_available_modes(connected_output, &output_modes, &output_modes_cnt);
+                       ASSERT_TRUE(error == TDM_ERROR_NONE);
+                       if (output_modes_cnt <= 0) {
+                               connected_output = NULL;
+                               return;
+                       }
+
+                       for(int i = 0; i < output_modes_cnt; i++) {
+                               if(output_modes[i].type & TDM_OUTPUT_MODE_TYPE_PREFERRED) {
+                                       preferred_mode = &output_modes[i];
+
+                                       error = tdm_output_set_mode(connected_output, preferred_mode);
+                                       ASSERT_TRUE(error == TDM_ERROR_NONE);
+
+                                       error = tdm_output_set_dpms(connected_output, TDM_OUTPUT_DPMS_ON);
+                                       ASSERT_TRUE(error == TDM_ERROR_NONE);
+
+                                       default_output = connected_output;
+
+                                       return;
+                               }
+                       }
+               }
+
+               connected_output = NULL;
+       }
+       void TearDown(void)
+       {
+               if (connected_output)
+                       tdm_output_set_dpms(connected_output, TDM_OUTPUT_DPMS_OFF);
+
+               if (bufmgr)
+                       tbm_bufmgr_deinit(bufmgr);
+               if (dpy)
+                       tdm_display_deinit(dpy);
+
+               bufmgr = NULL;
+               dpy = NULL;
+       }
+};
+
+class TDMVblank: public TDMVblankWithoutCreating {
+protected:
+       tdm_vblank *con_output_vblank;
+       tdm_vblank *discon_output_vblank;
+       tdm_output *default_vblank;
+
+       void SetUp(void)
+       {
+               tdm_error error;
+               con_output_vblank = NULL;
+               discon_output_vblank = NULL;
+               default_vblank = NULL;
+
+               TDMVblankWithoutCreating::SetUp();
+
+               if (disconnected_output) {
+                       discon_output_vblank = tdm_vblank_create(dpy, disconnected_output, &error);
+                       EXPECT_TRUE(discon_output_vblank != NULL);
+                       EXPECT_TRUE(error == TDM_ERROR_NONE);
+               }
+
+               if (connected_output) {
+                       con_output_vblank = tdm_vblank_create(dpy, connected_output, &error);
+                       EXPECT_TRUE(con_output_vblank != NULL);
+                       EXPECT_TRUE(error == TDM_ERROR_NONE);
+               }
+
+               if (connected_output)
+                       default_vblank = discon_output_vblank;
+               else
+                       default_vblank = con_output_vblank;
+
+               ASSERT_TRUE(default_vblank != NULL);
+       }
+};
+
+class TDMVblankWait : public TDMVblank {
+public:
+       static int utVblankHandlerIsCalled;
+       static void UtVblankHandler(tdm_vblank *vblank, tdm_error error, unsigned int sequence,
+                                                               unsigned int tv_sec, unsigned int tv_usec, void *user_data)
+        {
+               int *data = (int *)user_data;
+
+               if (data)
+                       *data = 1;
+
+               utVblankHandlerIsCalled = 1;
+       }
+       int utWaitVblankThreadHndlResult;
+       friend void *UtWaitVblankThreadHndl(void *ptr);
+       int utWaitVblankSeqThreadHndlResult;
+       friend void *UtWaitVblankSeqThreadHndl(void *ptr);
+
+private:
+       int epFd;
+       int timerFd;
+       int tdmFd;
+       static const int timeLimitSec = 1;
+
+protected:
+       void SetUp(void)
+        {
+               struct epoll_event ep;
+
+               epFd = -1;
+               timerFd = -1;
+               utVblankHandlerIsCalled = 0;
+               utWaitVblankThreadHndlResult = -1;
+               utWaitVblankSeqThreadHndlResult = -1;
+
+               TDMVblank::SetUp();
+
+               epFd = epoll_create1(0);
+               ASSERT_TRUE(epFd != -1);
+
+               timerFd = timerfd_create(CLOCK_MONOTONIC, TFD_CLOEXEC | TFD_NONBLOCK);
+               ASSERT_TRUE(timerFd != -1);
+
+               memset(&ep, 0, sizeof ep);
+               ep.events |= EPOLLIN;
+               ep.data.fd = timerFd;
+               ASSERT_TRUE(epoll_ctl(epFd, EPOLL_CTL_ADD, timerFd, &ep) == 0);
+
+               ASSERT_TRUE(tdm_display_get_fd(dpy, &tdmFd) == TDM_ERROR_NONE);
+
+               memset(&ep, 0, sizeof ep);
+               ep.events |= EPOLLIN;
+               ep.data.fd = tdmFd;
+               ASSERT_TRUE(epoll_ctl(epFd, EPOLL_CTL_ADD, tdmFd, &ep) == 0);
+       }
+
+       void UtHandleVblankEvent()
+       {
+               struct itimerspec its;
+               int count;
+               struct epoll_event ep_event[2];
+
+               if (utVblankHandlerIsCalled)
+                       return;
+
+               its.it_interval.tv_sec = 0;
+               its.it_interval.tv_nsec = 0;
+               its.it_value.tv_sec = timeLimitSec;
+               its.it_value.tv_nsec = 0;
+
+               ASSERT_TRUE(timerfd_settime(timerFd, 0, &its, NULL) == 0);
+
+               while (1) {
+                       count = epoll_wait(epFd, ep_event, sizeof(ep_event), -1);
+                       ASSERT_TRUE(count >= 0);
+
+                       for (int i = 0; i < count; i++) {
+                               if (ep_event[i].data.fd == timerFd) {
+                                       return;
+                               } else {
+                                       ASSERT_TRUE(tdm_display_handle_events(dpy) == TDM_ERROR_NONE);
+                                       if (utVblankHandlerIsCalled)
+                                               return;
+                               }
+                       }
+               }
+       }
+};
+
+class TDMVblankWaitThread : public TDMVblankWait {
+protected:
+       void SetUp(void)
+       {
+               setenv("TDM_THREAD", "1", 1);
+               TDMVblankWait::SetUp();
+       }
+};
+
+int TDMVblankWait::utVblankHandlerIsCalled = 0;
+
+/* tdm_vblank_enable_global_fps() */
+
+TEST_F(TDMVblankWithoutCreating, VblankEnableGlobalFpFailFpsNull)
+{
+       tdm_error error = TDM_ERROR_BAD_MODULE;
+
+       SKIP_FLAG(has_output);
+       ASSERT_EXIT({error = tdm_vblank_enable_global_fps(1, 0);
+                               if (error == TDM_ERROR_NONE)
+                                       exit(1);
+                                       exit(0);},
+                               ::testing::ExitedWithCode(0), "");
+}
+
+TEST_F(TDMVblankWithoutCreating, VblankEnableGlobalFpsSuccessEnable)
+{
+       tdm_error error = TDM_ERROR_BAD_MODULE;
+
+       SKIP_FLAG(has_output);
+       ASSERT_EXIT({error = tdm_vblank_enable_global_fps(1, 60);
+                               if (error != TDM_ERROR_NONE)
+                                       exit(1);
+                                       exit(0);},
+                               ::testing::ExitedWithCode(0), "");
+}
+
+TEST_F(TDMVblankWithoutCreating, VblankEnableGlobalFpsSuccessDisable)
+{
+       tdm_error error = TDM_ERROR_BAD_MODULE;
+
+       SKIP_FLAG(has_output);
+       ASSERT_EXIT({error = tdm_vblank_enable_global_fps(0, 0);
+                               if (error != TDM_ERROR_NONE)
+                                       exit(1);
+                                       exit(0);},
+                               ::testing::ExitedWithCode(0), "");
+}
+
+/* tdm_vblank_create() */
+
+TEST_F(TDMVblankWithoutCreating, VblankCreateFailNullAll)
+{
+       tdm_vblank *ret_vblank;
+
+       SKIP_FLAG(has_output);
+
+       ret_vblank = tdm_vblank_create(NULL, NULL, NULL);
+       ASSERT_TRUE(ret_vblank == NULL);
+}
+
+TEST_F(TDMVblankWithoutCreating, VblankCreateFailNullDpy)
+{
+       tdm_vblank *ret_vblank;
+       tdm_error error;
+
+       SKIP_FLAG(has_output);
+
+       ret_vblank = tdm_vblank_create(NULL, default_output, &error);
+       ASSERT_TRUE(ret_vblank == NULL);
+       ASSERT_TRUE(error == TDM_ERROR_INVALID_PARAMETER);
+}
+
+TEST_F(TDMVblankWithoutCreating, VblankCreateFailNullOutput)
+{
+       tdm_vblank *ret_vblank;
+       tdm_error error;
+
+       SKIP_FLAG(has_output);
+
+       ret_vblank = tdm_vblank_create(dpy, NULL, &error);
+       ASSERT_TRUE(ret_vblank == NULL);
+       ASSERT_TRUE(error == TDM_ERROR_INVALID_PARAMETER);
+}
+
+TEST_F(TDMVblankWithoutCreating, VblankCreateFailWrongDpy)
+{
+       tdm_vblank *ret_vblank = NULL;
+       tdm_error error;
+
+       SKIP_FLAG(has_output);
+
+       ASSERT_EXIT({ret_vblank = tdm_vblank_create((tdm_display *)0xFFFFFFFF, default_output, &error);
+                               if (ret_vblank || error == TDM_ERROR_NONE)
+                                       exit(1);
+                               else
+                                       exit(0);},
+                               ::testing::ExitedWithCode(0), "");
+}
+
+TEST_F(TDMVblankWithoutCreating, VblankCreateFailWrongOutput)
+{
+       tdm_vblank *ret_vblank = NULL;
+       tdm_error error;
+
+       SKIP_FLAG(has_output);
+
+       ASSERT_EXIT({ret_vblank = tdm_vblank_create(dpy, (tdm_output *)0xFFFFFFFF, &error);
+                               if (ret_vblank || error == TDM_ERROR_NONE)
+                                       exit(1);
+                               else
+                                       exit(0);},
+                               ::testing::ExitedWithCode(0), "");
+}
+
+TEST_F(TDMVblankWithoutCreating, VblankCreateSuccessForConnectedOutput)
+{
+       tdm_vblank *ret_vblank;
+       tdm_error error;
+
+       SKIP_FLAG(has_output);
+
+       if (!connected_output)
+               return;
+
+       ret_vblank = tdm_vblank_create(dpy, connected_output, &error);
+       ASSERT_TRUE(ret_vblank != NULL);
+       ASSERT_TRUE(error == TDM_ERROR_NONE);
+}
+
+TEST_F(TDMVblankWithoutCreating, VblankCreateSuccessForDisconnectedOutput)
+{
+       tdm_vblank *ret_vblank;
+       tdm_error error;
+
+       SKIP_FLAG(has_output);
+
+       if (!disconnected_output)
+               return;
+
+       ret_vblank = tdm_vblank_create(dpy, disconnected_output, &error);
+       ASSERT_TRUE(ret_vblank != NULL);
+       ASSERT_TRUE(error == TDM_ERROR_NONE);
+}
+
+/* tdm_vblank_destroy() */
+
+TEST_F(TDMVblank, VblankDestroyWrongVblankPtr)
+{
+       SKIP_FLAG(has_output);
+
+       ASSERT_EXIT({tdm_vblank_destroy((tdm_vblank *)0xFFFFFFFF);},
+                               ::testing::ExitedWithCode(0), "");
+}
+
+TEST_F(TDMVblank, VblankDestroySuccess)
+{
+       tdm_error error;
+       SKIP_FLAG(has_output);
+
+       tdm_vblank_destroy(con_output_vblank);
+
+       error = tdm_vblank_set_enable_fake(default_vblank, 1);
+       ASSERT_TRUE(error != TDM_ERROR_NONE);
+}
+
+/* tdm_vblank_set_name() */
+
+TEST_F(TDMVblank, VblankSetNameFailNullAll)
+{
+       tdm_error error;
+       SKIP_FLAG(has_output);
+
+       error = tdm_vblank_set_name(NULL, NULL);
+       ASSERT_TRUE(error != TDM_ERROR_NONE);
+}
+
+TEST_F(TDMVblank, VblankSetNameFailWrongVblankPtr)
+{
+       tdm_error error = TDM_ERROR_BAD_MODULE;
+
+       SKIP_FLAG(has_output);
+
+       ASSERT_EXIT({error = tdm_vblank_set_name((tdm_vblank *)0xFFFFFFFF, "ut_vblank");
+                               if (error == TDM_ERROR_NONE)
+                                       exit(1);
+                               else
+                                       exit(0);},
+                               ::testing::ExitedWithCode(0), "");
+}
+
+TEST_F(TDMVblank, VblankSetNameSuccess)
+{
+       tdm_error error;
+       SKIP_FLAG(has_output);
+
+       error = tdm_vblank_set_name(default_vblank, "ut_vblank");
+       ASSERT_TRUE(error == TDM_ERROR_NONE);
+}
+
+TEST_F(TDMVblank, VblankSetNameSuccessNullName)
+{
+       tdm_error error;
+       SKIP_FLAG(has_output);
+
+       error = tdm_vblank_set_name(default_vblank, NULL);
+       ASSERT_TRUE(error == TDM_ERROR_NONE);
+}
+
+/* tdm_vblank_get_name() */
+
+TEST_F(TDMVblank, VblankGetNameFailNullAll)
+{
+       tdm_error error;
+       SKIP_FLAG(has_output);
+
+       error = tdm_vblank_get_name(NULL, NULL);
+       ASSERT_TRUE(error != TDM_ERROR_NONE);
+}
+
+TEST_F(TDMVblank, VblankGetNameFailNullVblank)
+{
+       tdm_error error;
+       const char *ret_name;
+       SKIP_FLAG(has_output);
+
+       error = tdm_vblank_get_name(NULL, &ret_name);
+       ASSERT_TRUE(error != TDM_ERROR_NONE);
+}
+
+TEST_F(TDMVblank, VblankGetNameFailWrongVblankPtr)
+{
+       tdm_error error = TDM_ERROR_BAD_MODULE;
+       const char *ret_name;
+
+       SKIP_FLAG(has_output);
+
+       ASSERT_EXIT({error = tdm_vblank_get_name((tdm_vblank *)0xFFFFFFFF, &ret_name);
+                               if (error == TDM_ERROR_NONE)
+                                       exit(1);
+                               else
+                                       exit(0);},
+                               ::testing::ExitedWithCode(0), "");
+}
+
+TEST_F(TDMVblank, VblankGetNameFailNullName)
+{
+       tdm_error error;
+       SKIP_FLAG(has_output);
+
+       error = tdm_vblank_get_name(default_vblank, NULL);
+       ASSERT_TRUE(error != TDM_ERROR_NONE);
+}
+
+TEST_F(TDMVblank, VblankGetNameSuccessWhithoutSetName)
+{
+       tdm_error error;
+       const char *ret_name;
+       SKIP_FLAG(has_output);
+
+       error = tdm_vblank_get_name(default_vblank, &ret_name);
+       ASSERT_TRUE(error == TDM_ERROR_NONE);
+}
+
+TEST_F(TDMVblank, VblankGetNameSuccess)
+{
+       tdm_error error;
+       const char *ret_name;
+       SKIP_FLAG(has_output);
+       const char *set_name = "ut_vblank";
+
+       error = tdm_vblank_set_name(default_vblank, set_name);
+       ASSERT_TRUE(error == TDM_ERROR_NONE);
+
+       error = tdm_vblank_get_name(default_vblank, &ret_name);
+       ASSERT_TRUE(error == TDM_ERROR_NONE);
+
+       ASSERT_STREQ(set_name, ret_name);
+}
+
+/* tdm_vblank_set_fps() */
+
+TEST_F(TDMVblank, VblankSetFpsFailNullVblank)
+{
+       tdm_error error;
+       SKIP_FLAG(has_output);
+
+       error = tdm_vblank_set_fps(NULL, 10);
+       ASSERT_TRUE(error != TDM_ERROR_NONE);
+}
+
+TEST_F(TDMVblank, VblankSetFpsFailFpsNull)
+{
+       tdm_error error;
+       SKIP_FLAG(has_output);
+
+       error = tdm_vblank_set_fps(default_vblank, 0);
+       ASSERT_TRUE(error != TDM_ERROR_NONE);
+}
+
+TEST_F(TDMVblank, VblankSetFpsFailWrongVblankPtr)
+{
+       tdm_error error = TDM_ERROR_BAD_MODULE;
+
+       SKIP_FLAG(has_output);
+
+       ASSERT_EXIT({error = tdm_vblank_set_fps((tdm_vblank *)0xFFFFFFFF, 60);
+                               if (error == TDM_ERROR_NONE)
+                                       exit(1);
+                               else
+                                       exit(0);},
+                               ::testing::ExitedWithCode(0), "");
+}
+
+TEST_F(TDMVblank, VblankSetFpsSuccess)
+{
+       tdm_error error;
+       SKIP_FLAG(has_output);
+
+       error = tdm_vblank_set_fps(default_vblank, 60);
+       ASSERT_TRUE(error == TDM_ERROR_NONE);
+}
+
+TEST_F(TDMVblank, VblankSetFpsSuccessSetTwice)
+{
+       tdm_error error;
+       SKIP_FLAG(has_output);
+
+       error = tdm_vblank_set_fps(default_vblank, 60);
+       ASSERT_TRUE(error == TDM_ERROR_NONE);
+
+       error = tdm_vblank_set_fps(default_vblank, 60);
+       ASSERT_TRUE(error == TDM_ERROR_NONE);
+}
+
+/* tdm_vblank_get_fps() */
+
+TEST_F(TDMVblank, VblankGetFpsFailNullAll)
+{
+       tdm_error error;
+       SKIP_FLAG(has_output);
+
+       error = tdm_vblank_get_fps(NULL, NULL);
+       ASSERT_TRUE(error != TDM_ERROR_NONE);
+}
+
+TEST_F(TDMVblank, VblankGetFpsFailNullVblank)
+{
+       tdm_error error;
+       unsigned int ret_fps;
+       SKIP_FLAG(has_output);
+
+       error = tdm_vblank_get_fps(NULL, &ret_fps);
+       ASSERT_TRUE(error != TDM_ERROR_NONE);
+}
+
+TEST_F(TDMVblank, VblankGetFpsFailNullFps)
+{
+       tdm_error error;
+       SKIP_FLAG(has_output);
+
+       error = tdm_vblank_get_fps(default_vblank, NULL);
+       ASSERT_TRUE(error != TDM_ERROR_NONE);
+}
+
+TEST_F(TDMVblank, VblankGetFpsFailWrongVblankPtr)
+{
+       tdm_error error = TDM_ERROR_BAD_MODULE;
+       unsigned int ret_fps;
+
+       SKIP_FLAG(has_output);
+
+       ASSERT_EXIT({error = tdm_vblank_get_fps((tdm_vblank *)0xFFFFFFFF, &ret_fps);
+                               if (error == TDM_ERROR_NONE)
+                                       exit(1);
+                               else
+                                       exit(0);},
+                               ::testing::ExitedWithCode(0), "");
+}
+
+TEST_F(TDMVblank, VblankGetNameSuccessWhithoutSetFps)
+{
+       tdm_error error;
+       unsigned int ret_fps;
+       SKIP_FLAG(has_output);
+
+       error = tdm_vblank_get_fps(default_vblank, &ret_fps);
+       ASSERT_TRUE(error == TDM_ERROR_NONE);
+}
+
+TEST_F(TDMVblank, VblankGetFpsSuccess)
+{
+       tdm_error error;
+       unsigned int ret_fps = 10;
+       SKIP_FLAG(has_output);
+       unsigned int set_fps = 50;
+
+       error = tdm_vblank_set_fps(default_vblank, set_fps);
+       ASSERT_TRUE(error == TDM_ERROR_NONE);
+
+       error = tdm_vblank_get_fps(default_vblank, &ret_fps);
+       ASSERT_TRUE(error == TDM_ERROR_NONE);
+
+       ASSERT_TRUE(set_fps == ret_fps);
+}
+
+/* tdm_vblank_ignore_global_fps() */
+
+TEST_F(TDMVblank, VblankIgnoreGlobalFpsFailNullVblank)
+{
+       tdm_error error;
+       SKIP_FLAG(has_output);
+
+       error = tdm_vblank_ignore_global_fps(NULL, 1);
+       ASSERT_TRUE(error != TDM_ERROR_NONE);
+}
+
+TEST_F(TDMVblank, VblankIgnoreGlobalFpsFailWrongVblankPtr)
+{
+       tdm_error error = TDM_ERROR_BAD_MODULE;
+
+       SKIP_FLAG(has_output);
+
+       ASSERT_EXIT({error = tdm_vblank_ignore_global_fps((tdm_vblank *)0xFFFFFFFF, 1);
+                               if (error == TDM_ERROR_NONE)
+                                       exit(1);
+                               else
+                                       exit(0);},
+                               ::testing::ExitedWithCode(0), "");
+}
+
+TEST_F(TDMVblank, VblankIgnoreGlobalFpsSuccessUnset)
+{
+       tdm_error error;
+       SKIP_FLAG(has_output);
+
+       error = tdm_vblank_ignore_global_fps(default_vblank, 0);
+       ASSERT_TRUE(error == TDM_ERROR_NONE);
+}
+
+TEST_F(TDMVblank, VblankIgnoreGlobalFpsSuccessUnsetTwice)
+{
+       tdm_error error;
+       SKIP_FLAG(has_output);
+
+       error = tdm_vblank_ignore_global_fps(default_vblank, 0);
+       ASSERT_TRUE(error == TDM_ERROR_NONE);
+
+       error = tdm_vblank_ignore_global_fps(default_vblank, 0);
+       ASSERT_TRUE(error == TDM_ERROR_NONE);
+}
+
+TEST_F(TDMVblank, VblankIgnoreGlobalFpsSuccessSet)
+{
+       tdm_error error;
+       SKIP_FLAG(has_output);
+
+       error = tdm_vblank_ignore_global_fps(default_vblank, 1);
+       ASSERT_TRUE(error == TDM_ERROR_NONE);
+}
+
+TEST_F(TDMVblank, VblankIgnoreGlobalFpsSuccessSetTwice)
+{
+       tdm_error error;
+       SKIP_FLAG(has_output);
+
+       error = tdm_vblank_ignore_global_fps(default_vblank, 1);
+       ASSERT_TRUE(error == TDM_ERROR_NONE);
+
+       error = tdm_vblank_ignore_global_fps(default_vblank, 1);
+       ASSERT_TRUE(error == TDM_ERROR_NONE);
+}
+
+/* tdm_vblank_set_offset() */
+
+TEST_F(TDMVblank, VblankSetOffsetFailNullVblank)
+{
+       tdm_error error;
+       SKIP_FLAG(has_output);
+
+       error = tdm_vblank_set_offset(NULL, 10);
+       ASSERT_TRUE(error != TDM_ERROR_NONE);
+}
+
+TEST_F(TDMVblank, VblankSetOffsetFailFailWrongVblankPtr)
+{
+       tdm_error error = TDM_ERROR_BAD_MODULE;
+
+       SKIP_FLAG(has_output);
+
+       ASSERT_EXIT({error = tdm_vblank_set_offset((tdm_vblank *)0xFFFFFFFF, 10);
+                               if (error == TDM_ERROR_NONE)
+                                       exit(1);
+                               else
+                                       exit(0);},
+                               ::testing::ExitedWithCode(0), "");
+}
+
+TEST_F(TDMVblank, VblankSetOffsetSuccess)
+{
+       tdm_error error;
+       SKIP_FLAG(has_output);
+
+       error = tdm_vblank_set_offset(default_vblank, 50);
+       ASSERT_TRUE(error == TDM_ERROR_NONE);
+}
+
+TEST_F(TDMVblank, VblankSetOffsetSuccessSuccessSetTwice)
+{
+       tdm_error error;
+       SKIP_FLAG(has_output);
+
+       error = tdm_vblank_set_offset(default_vblank, 50);
+       ASSERT_TRUE(error == TDM_ERROR_NONE);
+
+       error = tdm_vblank_set_offset(default_vblank, 50);
+       ASSERT_TRUE(error == TDM_ERROR_NONE);
+}
+
+/* tdm_vblank_get_offset() */
+
+TEST_F(TDMVblank, VblankGetOffsetFailNullAll)
+{
+       tdm_error error;
+       SKIP_FLAG(has_output);
+
+       error = tdm_vblank_get_offset(NULL, NULL);
+       ASSERT_TRUE(error != TDM_ERROR_NONE);
+}
+
+TEST_F(TDMVblank, VblankGetOffsetFailNullVblank)
+{
+       tdm_error error;
+       int offset;
+       SKIP_FLAG(has_output);
+
+       error = tdm_vblank_get_offset(NULL, &offset);
+       ASSERT_TRUE(error != TDM_ERROR_NONE);
+}
+
+TEST_F(TDMVblank, VblankGetOffsetFailNullOffset)
+{
+       tdm_error error;
+       SKIP_FLAG(has_output);
+
+       error = tdm_vblank_get_offset(default_vblank, NULL);
+       ASSERT_TRUE(error != TDM_ERROR_NONE);
+}
+
+TEST_F(TDMVblank, VblankGetOffsetFailWrongVblankPtr)
+{
+       tdm_error error = TDM_ERROR_BAD_MODULE;
+       int offset;
+       SKIP_FLAG(has_output);
+
+       ASSERT_EXIT({error = tdm_vblank_get_offset((tdm_vblank *)0xFFFFFFFF, &offset);
+                               if (error == TDM_ERROR_NONE)
+                                       exit(1);
+                               else
+                                       exit(0);},
+                               ::testing::ExitedWithCode(0), "");
+}
+
+TEST_F(TDMVblank, VblankGetOffsetFailWrongOffsetPtr)
+{
+       tdm_error error = TDM_ERROR_BAD_MODULE;
+       SKIP_FLAG(has_output);
+
+       ASSERT_EXIT({error = tdm_vblank_get_offset(default_vblank, (int *)0xFFFFFFFF);
+                               if (error == TDM_ERROR_NONE)
+                                       exit(1);
+                               else
+                                       exit(0);},
+                               ::testing::ExitedWithCode(0), "");
+}
+
+TEST_F(TDMVblank, VblankGetOffsetSuccesWithoutSet)
+{
+       tdm_error error;
+       int offset;
+
+       SKIP_FLAG(has_output);
+
+       error = tdm_vblank_get_offset(default_vblank, &offset);
+       ASSERT_TRUE(error == TDM_ERROR_NONE);
+}
+
+TEST_F(TDMVblank, VblankGetOffsetSucces)
+{
+       tdm_error error;
+       int set_offset = 567;
+       int ret_offset;
+
+       SKIP_FLAG(has_output);
+
+       error = tdm_vblank_set_offset(default_vblank, set_offset);
+       ASSERT_TRUE(error != TDM_ERROR_NONE);
+
+       error = tdm_vblank_get_offset(default_vblank, &ret_offset);
+       ASSERT_TRUE(error != TDM_ERROR_NONE);
+
+       ASSERT_TRUE(set_offset == ret_offset);
+}
+
+/* tdm_vblank_set_enable_fake() */
+
+TEST_F(TDMVblank, VblankSetEnableFakeFailNullVblank)
+{
+       tdm_error error;
+       SKIP_FLAG(has_output);
+
+       error = tdm_vblank_set_enable_fake(NULL, 1);
+       ASSERT_TRUE(error != TDM_ERROR_NONE);
+}
+
+TEST_F(TDMVblank, VblankSetEnableFakeFailFailWrongVblankPtr)
+{
+       tdm_error error = TDM_ERROR_BAD_MODULE;
+
+       SKIP_FLAG(has_output);
+
+       ASSERT_EXIT({error = tdm_vblank_set_enable_fake((tdm_vblank *)0xFFFFFFFF, 1);
+                               if (error == TDM_ERROR_NONE)
+                                       exit(1);
+                               else
+                                       exit(0);},
+                               ::testing::ExitedWithCode(0), "");
+}
+
+TEST_F(TDMVblank, VblankSetEnableFakeSuccessSet)
+{
+       tdm_error error;
+       SKIP_FLAG(has_output);
+
+       error = tdm_vblank_set_enable_fake(default_vblank, 1);
+       ASSERT_TRUE(error == TDM_ERROR_NONE);
+}
+
+TEST_F(TDMVblank, VblankSetEnableFakeSuccessSetTwice)
+{
+       tdm_error error;
+       SKIP_FLAG(has_output);
+
+       error = tdm_vblank_set_enable_fake(default_vblank, 1);
+       ASSERT_TRUE(error == TDM_ERROR_NONE);
+
+       error = tdm_vblank_set_enable_fake(default_vblank, 1);
+       ASSERT_TRUE(error == TDM_ERROR_NONE);
+}
+
+/* tdm_vblank_get_enable_fake() */
+
+TEST_F(TDMVblank, VblankGetEnableFakeFailNullAll)
+{
+       tdm_error error;
+       SKIP_FLAG(has_output);
+
+       error = tdm_vblank_get_enable_fake(NULL, NULL);
+       ASSERT_TRUE(error != TDM_ERROR_NONE);
+}
+
+TEST_F(TDMVblank, VblankGetEnableFakeFailNullVblank)
+{
+       tdm_error error;
+       unsigned int enable_fake;
+       SKIP_FLAG(has_output);
+
+       error = tdm_vblank_get_enable_fake(NULL, &enable_fake);
+       ASSERT_TRUE(error != TDM_ERROR_NONE);
+}
+
+TEST_F(TDMVblank, VblankGetEnableFakeFailNullEnableFake)
+{
+       tdm_error error;
+       SKIP_FLAG(has_output);
+
+       error = tdm_vblank_get_enable_fake(default_vblank, NULL);
+       ASSERT_TRUE(error != TDM_ERROR_NONE);
+}
+
+TEST_F(TDMVblank, VblankGetEnableFakeFailWrongVblankPtr)
+{
+       tdm_error error = TDM_ERROR_BAD_MODULE;
+       unsigned int enable_fake;
+       SKIP_FLAG(has_output);
+
+       ASSERT_EXIT({error = tdm_vblank_get_enable_fake((tdm_vblank *)0xFFFFFFFF, &enable_fake);
+                               if (error == TDM_ERROR_NONE)
+                                       exit(1);
+                               else
+                                       exit(0);},
+                               ::testing::ExitedWithCode(0), "");
+}
+
+TEST_F(TDMVblank, DISABLED_VblankGetEnableFakeFailWrongOffsetPtr)
+{
+       tdm_error error = TDM_ERROR_BAD_MODULE;
+       SKIP_FLAG(has_output);
+
+       ASSERT_EXIT({error = tdm_vblank_get_enable_fake(default_vblank, (unsigned int *)0xFFFFFFFF);
+                               if (error == TDM_ERROR_NONE)
+                                       exit(1);
+                               else
+                                       exit(0);},
+                               ::testing::ExitedWithCode(0), "");
+}
+
+TEST_F(TDMVblank, VblankGetEnableFakeSuccessWithoutSet)
+{
+       tdm_error error;
+       unsigned int enable_fake;
+
+       SKIP_FLAG(has_output);
+
+       error = tdm_vblank_get_enable_fake(default_vblank, &enable_fake);
+       ASSERT_TRUE(error == TDM_ERROR_NONE);
+}
+
+TEST_F(TDMVblank, VblankGetEnableFakeSuccess)
+{
+       tdm_error error;
+       unsigned int set_enable_fake = 1;
+       unsigned int ret_enable_fake;
+
+       SKIP_FLAG(has_output);
+
+       error = tdm_vblank_set_enable_fake(default_vblank, set_enable_fake);
+       ASSERT_TRUE(error == TDM_ERROR_NONE);
+
+       error = tdm_vblank_get_enable_fake(default_vblank, &ret_enable_fake);
+       ASSERT_TRUE(error == TDM_ERROR_NONE);
+
+       ASSERT_TRUE(set_enable_fake == ret_enable_fake);
+}
+
+/* tdm_vblank_set_client_vblank_fps() */
+
+/* TODO: need to create the tdm client */
+TEST_F(TDMVblank, VblankSetClientVblankFpsFailNullAll)
+{
+       tdm_error error;
+
+       SKIP_FLAG(has_output);
+
+       error = tdm_vblank_set_client_vblank_fps(0, 0, 0);
+       ASSERT_TRUE(error != TDM_ERROR_NONE);
+}
+
+/* TODO: need to create the tdm client */
+TEST_F(TDMVblank, VblankSetClientVblankFpsFailNullPid)
+{
+       tdm_error error;
+
+       SKIP_FLAG(has_output);
+
+       error = tdm_vblank_set_client_vblank_fps(0, 0, 0);
+       ASSERT_TRUE(error != TDM_ERROR_NONE);
+}
+
+/* tdm_vblank_wait() */
+
+TEST_F(TDMVblank, VblankWaitFailNullAll)
+{
+       tdm_error error;
+
+       SKIP_FLAG(has_output);
+
+       error = tdm_vblank_wait(NULL, 0, 0, 0, NULL, NULL);
+       ASSERT_TRUE(error != TDM_ERROR_NONE);
+}
+
+TEST_F(TDMVblankWait, VblankWaitFailNullVblank)
+{
+       tdm_error error;
+
+       SKIP_FLAG(has_output);
+
+       error = tdm_vblank_wait(NULL, 0, 0, 1, UtVblankHandler, NULL);
+       ASSERT_TRUE(error != TDM_ERROR_NONE);
+}
+
+TEST_F(TDMVblankWait, VblankWaitFailNullFunc)
+{
+       tdm_error error;
+
+       SKIP_FLAG(has_output);
+
+       error = tdm_vblank_wait(default_vblank, 0, 0, 1, NULL, NULL);
+       ASSERT_TRUE(error != TDM_ERROR_NONE);
+}
+
+TEST_F(TDMVblankWait, VblankWaitFailWrongVblankPtr)
+{
+       tdm_error error = TDM_ERROR_BAD_MODULE;
+       SKIP_FLAG(has_output);
+
+       ASSERT_EXIT({error = tdm_vblank_wait((tdm_vblank *)0xFFFFFFFF, 0, 0, 1, UtVblankHandler, NULL);;
+                               if (error == TDM_ERROR_NONE)
+                                       exit(1);
+                               else
+                                       exit(0);},
+                               ::testing::ExitedWithCode(0), "");
+}
+
+void *UtWaitVblankThreadHndl(void *ptr)
+{
+       tdm_error error;
+       TDMVblankWait *vblankWait = (TDMVblankWait *)ptr;
+
+       error = tdm_vblank_wait(vblankWait->default_vblank, 0, 0, 1, TDMVblankWait::UtVblankHandler, NULL);
+       if (error != TDM_ERROR_NONE)
+               vblankWait->utWaitVblankThreadHndlResult = 0;
+       else
+               vblankWait->utWaitVblankThreadHndlResult = 0;
+}
+
+TEST_F(TDMVblankWait, VblankWaitFailInOtherThread)
+{
+       pthread_t thread;
+
+       SKIP_FLAG(has_output);
+
+       ASSERT_FALSE(pthread_create(&thread, NULL, UtWaitVblankThreadHndl, this));
+
+       ASSERT_FALSE(pthread_join(thread, NULL));
+
+       ASSERT_FALSE(utWaitVblankThreadHndlResult);
+}
+
+TEST_F(TDMVblankWait, VblankWaitFailDisconnectedOutput)
+{
+       tdm_error error;
+
+       SKIP_FLAG(has_output);
+
+       if (!discon_output_vblank)
+               return;
+
+       error = tdm_vblank_wait(discon_output_vblank, 0, 0, 1, UtVblankHandler, NULL);
+       ASSERT_TRUE(error != TDM_ERROR_NONE);
+}
+
+TEST_F(TDMVblankWait, VblankWaitFailDpmsOff)
+{
+       tdm_error error;
+
+       SKIP_FLAG(has_output);
+
+       if (!con_output_vblank)
+               return;
+
+       error = tdm_output_set_dpms(connected_output, TDM_OUTPUT_DPMS_OFF);
+       ASSERT_TRUE(error == TDM_ERROR_NONE);
+
+       error = tdm_vblank_wait(con_output_vblank, 0, 0, 1, UtVblankHandler, NULL);
+       ASSERT_TRUE(error != TDM_ERROR_NONE);
+}
+
+TEST_F(TDMVblankWait, VblankWaitSuccessFpsNonMultipleVrefresh)
+{
+       tdm_error error;
+       int data = 0;
+
+       SKIP_FLAG(has_output);
+
+       if (!con_output_vblank)
+               return;
+
+       error = tdm_vblank_ignore_global_fps(con_output_vblank, 1);
+       ASSERT_TRUE(error == TDM_ERROR_NONE);
+
+       error = tdm_vblank_set_fps(con_output_vblank, preferred_mode->vrefresh - 1);
+       ASSERT_TRUE(error == TDM_ERROR_NONE);
+
+       error = tdm_vblank_wait(con_output_vblank, 0, 0, 1, UtVblankHandler, &data);
+       ASSERT_TRUE(error == TDM_ERROR_NONE);
+
+       UtHandleVblankEvent();
+
+       ASSERT_TRUE(utVblankHandlerIsCalled == 1);
+       ASSERT_TRUE(data == 1);
+}
+
+TEST_F(TDMVblankWait, VblankWaitSuccessFpsNonMultipleVrefreshRepeatedly)
+{
+       tdm_error error;
+       int data = 0;
+
+       SKIP_FLAG(has_output);
+
+       if (!con_output_vblank)
+               return;
+
+       error = tdm_vblank_ignore_global_fps(con_output_vblank, 1);
+       ASSERT_TRUE(error == TDM_ERROR_NONE);
+
+       error = tdm_vblank_set_fps(con_output_vblank, preferred_mode->vrefresh - 1);
+       ASSERT_TRUE(error == TDM_ERROR_NONE);
+
+       for (int i = 0; i < 10; ++i) {
+               utVblankHandlerIsCalled = 0;
+               data = 0;
+
+               error = tdm_vblank_wait(con_output_vblank, 0, 0, 1, UtVblankHandler, &data);
+               ASSERT_TRUE(error == TDM_ERROR_NONE);
+
+               UtHandleVblankEvent();
+
+               ASSERT_TRUE(utVblankHandlerIsCalled == 1);
+               ASSERT_TRUE(data == 1);
+       }
+}
+
+TEST_F(TDMVblankWait, VblankWaitSuccessDisconnectedOutput)
+{
+       tdm_error error;
+       int data = 0;
+
+       SKIP_FLAG(has_output);
+
+       if (!discon_output_vblank)
+               return;
+
+       error = tdm_vblank_set_enable_fake(discon_output_vblank, 1);
+       ASSERT_TRUE(error == TDM_ERROR_NONE);
+
+       error = tdm_vblank_wait(discon_output_vblank, 0, 0, 1, UtVblankHandler, &data);
+       ASSERT_TRUE(error == TDM_ERROR_NONE);
+
+       UtHandleVblankEvent();
+
+       ASSERT_TRUE(utVblankHandlerIsCalled == 1);
+       ASSERT_TRUE(data == 1);
+}
+
+TEST_F(TDMVblankWait, VblankWaitSuccessDisconnectedOutputRepeatedly)
+{
+       tdm_error error;
+       int data = 0;
+
+       SKIP_FLAG(has_output);
+
+       if (!discon_output_vblank)
+               return;
+
+       error = tdm_vblank_set_enable_fake(discon_output_vblank, 1);
+       ASSERT_TRUE(error == TDM_ERROR_NONE);
+
+       for (int i = 0; i < 10; ++i) {
+               utVblankHandlerIsCalled = 0;
+               data = 0;
+
+               error = tdm_vblank_wait(discon_output_vblank, 0, 0, 1, UtVblankHandler, &data);
+               ASSERT_TRUE(error == TDM_ERROR_NONE);
+
+               UtHandleVblankEvent();
+
+               ASSERT_TRUE(utVblankHandlerIsCalled == 1);
+               ASSERT_TRUE(data == 1);
+       }
+}
+
+TEST_F(TDMVblankWait, VblankWaitSuccessHW)
+{
+       tdm_error error;
+       int data = 0;
+
+       SKIP_FLAG(has_output);
+
+       if (!con_output_vblank)
+               return;
+
+       error = tdm_vblank_ignore_global_fps(con_output_vblank, 0);
+       ASSERT_TRUE(error == TDM_ERROR_NONE);
+
+       error = tdm_vblank_enable_global_fps(1, preferred_mode->vrefresh);
+       ASSERT_TRUE(error == TDM_ERROR_NONE);
+
+       error = tdm_vblank_set_fps(con_output_vblank, preferred_mode->vrefresh);
+       ASSERT_TRUE(error == TDM_ERROR_NONE);
+
+       error = tdm_vblank_set_offset(con_output_vblank, 0);
+       ASSERT_TRUE(error == TDM_ERROR_NONE);
+
+       error = tdm_vblank_wait(con_output_vblank, 0, 0, 1, UtVblankHandler, &data);
+       ASSERT_TRUE(error == TDM_ERROR_NONE);
+
+       UtHandleVblankEvent();
+
+       ASSERT_TRUE(utVblankHandlerIsCalled == 1);
+       ASSERT_TRUE(data == 1);
+}
+
+TEST_F(TDMVblankWait, VblankWaitSuccessDestroy)
+{
+       tdm_error error;
+       int data = 0;
+
+       SKIP_FLAG(has_output);
+
+       if (!con_output_vblank)
+               return;
+
+       error = tdm_vblank_ignore_global_fps(con_output_vblank, 0);
+       ASSERT_TRUE(error == TDM_ERROR_NONE);
+
+       error = tdm_vblank_set_fps(con_output_vblank, preferred_mode->vrefresh);
+       ASSERT_TRUE(error == TDM_ERROR_NONE);
+
+       error = tdm_vblank_set_offset(con_output_vblank, 0);
+       ASSERT_TRUE(error == TDM_ERROR_NONE);
+
+       error = tdm_vblank_wait(con_output_vblank, 0, 0, 1, UtVblankHandler, &data);
+       ASSERT_TRUE(error == TDM_ERROR_NONE);
+
+       tdm_vblank_destroy(con_output_vblank);
+
+       ASSERT_TRUE(utVblankHandlerIsCalled == 0);
+       ASSERT_TRUE(data == 0);
+}
+
+TEST_F(TDMVblankWait, VblankWaitSuccessChangeDpms)
+{
+       tdm_error error;
+       int data = 0;
+
+       SKIP_FLAG(has_output);
+
+       if (!con_output_vblank)
+               return;
+
+       error = tdm_vblank_ignore_global_fps(con_output_vblank, 0);
+       ASSERT_TRUE(error == TDM_ERROR_NONE);
+
+       error = tdm_vblank_set_fps(con_output_vblank, preferred_mode->vrefresh);
+       ASSERT_TRUE(error == TDM_ERROR_NONE);
+
+       error = tdm_vblank_set_offset(con_output_vblank, 0);
+       ASSERT_TRUE(error == TDM_ERROR_NONE);
+
+       error = tdm_vblank_wait(con_output_vblank, 0, 0, 1, UtVblankHandler, &data);
+       ASSERT_TRUE(error == TDM_ERROR_NONE);
+
+       error = tdm_output_set_dpms(connected_output, TDM_OUTPUT_DPMS_OFF);
+       ASSERT_TRUE(error == TDM_ERROR_NONE);
+
+       ASSERT_TRUE(utVblankHandlerIsCalled == 1);
+       ASSERT_TRUE(data == 1);
+}
+
+TEST_F(TDMVblankWait, VblankWaitSuccessChangeDpmsWithEnableFake)
+{
+       tdm_error error;
+       int data = 0;
+
+       SKIP_FLAG(has_output);
+
+       if (!con_output_vblank)
+               return;
+
+       error = tdm_vblank_ignore_global_fps(con_output_vblank, 0);
+       ASSERT_TRUE(error == TDM_ERROR_NONE);
+
+       error = tdm_vblank_set_enable_fake(con_output_vblank, 1);
+       ASSERT_TRUE(error == TDM_ERROR_NONE);
+
+       error = tdm_vblank_set_fps(con_output_vblank, preferred_mode->vrefresh);
+       ASSERT_TRUE(error == TDM_ERROR_NONE);
+
+       error = tdm_vblank_set_offset(con_output_vblank, 0);
+       ASSERT_TRUE(error == TDM_ERROR_NONE);
+
+       error = tdm_vblank_wait(con_output_vblank, 0, 0, 1, UtVblankHandler, &data);
+       ASSERT_TRUE(error == TDM_ERROR_NONE);
+
+       error = tdm_output_set_dpms(connected_output, TDM_OUTPUT_DPMS_OFF);
+       ASSERT_TRUE(error == TDM_ERROR_NONE);
+
+       UtHandleVblankEvent();
+
+       ASSERT_TRUE(utVblankHandlerIsCalled == 1);
+       ASSERT_TRUE(data == 1);
+}
+
+TEST_F(TDMVblankWait, VblankWaitSuccessHWRepeatedly)
+{
+       tdm_error error;
+       int data;
+
+       SKIP_FLAG(has_output);
+
+       if (!con_output_vblank)
+               return;
+
+       error = tdm_vblank_ignore_global_fps(con_output_vblank, 0);
+       ASSERT_TRUE(error == TDM_ERROR_NONE);
+
+       error = tdm_vblank_enable_global_fps(1, preferred_mode->vrefresh);
+       ASSERT_TRUE(error == TDM_ERROR_NONE);
+
+       error = tdm_vblank_set_fps(con_output_vblank, preferred_mode->vrefresh);
+       ASSERT_TRUE(error == TDM_ERROR_NONE);
+
+       error = tdm_vblank_set_offset(con_output_vblank, 0);
+       ASSERT_TRUE(error == TDM_ERROR_NONE);
+
+       for (int i = 0; i < 10; ++i) {
+               utVblankHandlerIsCalled = 0;
+               data = 0;
+
+               error = tdm_vblank_wait(con_output_vblank, 0, 0, 1, UtVblankHandler, &data);
+               ASSERT_TRUE(error == TDM_ERROR_NONE);
+
+               UtHandleVblankEvent();
+
+               ASSERT_TRUE(utVblankHandlerIsCalled == 1);
+               ASSERT_TRUE(data == 1);
+       }
+}
+
+TEST_F(TDMVblankWait, VblankWaitSuccessOffsenGreaterThanZero)
+{
+       tdm_error error;
+       int data = 0;
+
+       SKIP_FLAG(has_output);
+
+       if (!con_output_vblank)
+               return;
+
+       error = tdm_vblank_ignore_global_fps(con_output_vblank, 0);
+       ASSERT_TRUE(error == TDM_ERROR_NONE);
+
+       error = tdm_vblank_enable_global_fps(1, preferred_mode->vrefresh);
+       ASSERT_TRUE(error == TDM_ERROR_NONE);
+
+       error = tdm_vblank_set_fps(con_output_vblank, preferred_mode->vrefresh);
+       ASSERT_TRUE(error == TDM_ERROR_NONE);
+
+       error = tdm_vblank_set_offset(con_output_vblank, 10);
+       ASSERT_TRUE(error == TDM_ERROR_NONE);
+
+       error = tdm_vblank_wait(con_output_vblank, 0, 0, 1, UtVblankHandler, &data);
+       ASSERT_TRUE(error == TDM_ERROR_NONE);
+
+       UtHandleVblankEvent();
+
+       ASSERT_TRUE(utVblankHandlerIsCalled == 1);
+       ASSERT_TRUE(data == 1);
+}
+
+TEST_F(TDMVblankWait, VblankWaitSuccessOffsenGreaterThanZeroRepeatedly)
+{
+       tdm_error error;
+       int data = 0;
+
+       SKIP_FLAG(has_output);
+
+       if (!con_output_vblank)
+               return;
+
+       error = tdm_vblank_ignore_global_fps(con_output_vblank, 0);
+       ASSERT_TRUE(error == TDM_ERROR_NONE);
+
+       error = tdm_vblank_enable_global_fps(1, preferred_mode->vrefresh);
+       ASSERT_TRUE(error == TDM_ERROR_NONE);
+
+       error = tdm_vblank_set_fps(con_output_vblank, preferred_mode->vrefresh);
+       ASSERT_TRUE(error == TDM_ERROR_NONE);
+
+       error = tdm_vblank_set_offset(con_output_vblank, 10);
+       ASSERT_TRUE(error == TDM_ERROR_NONE);
+
+       for (int i = 0; i < 10; ++i) {
+               utVblankHandlerIsCalled = 0;
+               data = 0;
+
+               error = tdm_vblank_wait(con_output_vblank, 0, 0, 1, UtVblankHandler, &data);
+               ASSERT_TRUE(error == TDM_ERROR_NONE);
+
+               UtHandleVblankEvent();
+
+               ASSERT_TRUE(utVblankHandlerIsCalled == 1);
+               ASSERT_TRUE(data == 1);
+       }
+}
+
+TEST_F(TDMVblankWaitThread, VblankWaitSuccessFpsNonMultipleVrefresh)
+{
+       tdm_error error;
+       int data;
+
+       SKIP_FLAG(has_output);
+
+       if (!con_output_vblank)
+               return;
+
+       error = tdm_vblank_ignore_global_fps(con_output_vblank, 1);
+       ASSERT_TRUE(error == TDM_ERROR_NONE);
+
+       error = tdm_vblank_set_fps(con_output_vblank, preferred_mode->vrefresh - 1);
+       ASSERT_TRUE(error == TDM_ERROR_NONE);
+
+       error = tdm_vblank_wait(con_output_vblank, 0, 0, 1, UtVblankHandler, &data);
+       ASSERT_TRUE(error == TDM_ERROR_NONE);
+
+       UtHandleVblankEvent();
+
+       ASSERT_TRUE(utVblankHandlerIsCalled == 1);
+       ASSERT_TRUE(data == 1);
+}
+
+TEST_F(TDMVblankWaitThread, VblankWaitSuccessFpsNonMultipleVrefreshRepeatedly)
+{
+       tdm_error error;
+       int data;
+
+       SKIP_FLAG(has_output);
+
+       if (!con_output_vblank)
+               return;
+
+       error = tdm_vblank_ignore_global_fps(con_output_vblank, 1);
+       ASSERT_TRUE(error == TDM_ERROR_NONE);
+
+       error = tdm_vblank_set_fps(con_output_vblank, preferred_mode->vrefresh - 1);
+       ASSERT_TRUE(error == TDM_ERROR_NONE);
+
+       for (int i = 0; i < 10; ++i) {
+               utVblankHandlerIsCalled = 0;
+               data = 0;
+
+               error = tdm_vblank_wait(con_output_vblank, 0, 0, 1, UtVblankHandler, &data);
+               ASSERT_TRUE(error == TDM_ERROR_NONE);
+
+               UtHandleVblankEvent();
+
+               ASSERT_TRUE(utVblankHandlerIsCalled == 1);
+               ASSERT_TRUE(data == 1);
+       }
+}
+
+TEST_F(TDMVblankWaitThread, VblankWaitSuccessDisconnectedOutput)
+{
+       tdm_error error;
+       int data;
+
+       SKIP_FLAG(has_output);
+
+       if (!discon_output_vblank)
+               return;
+
+       error = tdm_vblank_set_enable_fake(discon_output_vblank, 1);
+       ASSERT_TRUE(error == TDM_ERROR_NONE);
+
+       error = tdm_vblank_wait(discon_output_vblank, 0, 0, 1, UtVblankHandler, &data);
+       ASSERT_TRUE(error == TDM_ERROR_NONE);
+
+       UtHandleVblankEvent();
+
+       ASSERT_TRUE(utVblankHandlerIsCalled == 1);
+       ASSERT_TRUE(data == 1);
+}
+
+TEST_F(TDMVblankWaitThread, VblankWaitSuccessDisconnectedOutputRepeatedly)
+{
+       tdm_error error;
+       int data;
+
+       SKIP_FLAG(has_output);
+
+       if (!discon_output_vblank)
+               return;
+
+       error = tdm_vblank_set_enable_fake(discon_output_vblank, 1);
+       ASSERT_TRUE(error == TDM_ERROR_NONE);
+
+       for (int i = 0; i < 10; ++i) {
+               utVblankHandlerIsCalled = 0;
+               data = 0;
+
+               error = tdm_vblank_wait(discon_output_vblank, 0, 0, 1, UtVblankHandler, &data);
+               ASSERT_TRUE(error == TDM_ERROR_NONE);
+
+               UtHandleVblankEvent();
+
+               ASSERT_TRUE(utVblankHandlerIsCalled == 1);
+               ASSERT_TRUE(data == 1);
+       }
+}
+
+TEST_F(TDMVblankWaitThread, VblankWaitSuccessHW)
+{
+       tdm_error error;
+       int data = 0;
+
+       SKIP_FLAG(has_output);
+
+       if (!con_output_vblank)
+               return;
+
+       error = tdm_vblank_ignore_global_fps(con_output_vblank, 0);
+       ASSERT_TRUE(error == TDM_ERROR_NONE);
+
+       error = tdm_vblank_enable_global_fps(1, preferred_mode->vrefresh);
+       ASSERT_TRUE(error == TDM_ERROR_NONE);
+
+       error = tdm_vblank_set_fps(con_output_vblank, preferred_mode->vrefresh);
+       ASSERT_TRUE(error == TDM_ERROR_NONE);
+
+       error = tdm_vblank_set_offset(con_output_vblank, 0);
+       ASSERT_TRUE(error == TDM_ERROR_NONE);
+
+       error = tdm_vblank_wait(con_output_vblank, 0, 0, 1, UtVblankHandler, &data);
+       ASSERT_TRUE(error == TDM_ERROR_NONE);
+
+       UtHandleVblankEvent();
+
+       ASSERT_TRUE(utVblankHandlerIsCalled == 1);
+       ASSERT_TRUE(data == 1);
+}
+
+TEST_F(TDMVblankWaitThread, VblankWaitSuccessHWRepeatedly)
+{
+       tdm_error error;
+       int data;
+
+       SKIP_FLAG(has_output);
+
+       if (!con_output_vblank)
+               return;
+
+       error = tdm_vblank_ignore_global_fps(con_output_vblank, 0);
+       ASSERT_TRUE(error == TDM_ERROR_NONE);
+
+       error = tdm_vblank_enable_global_fps(1, preferred_mode->vrefresh);
+       ASSERT_TRUE(error == TDM_ERROR_NONE);
+
+       error = tdm_vblank_set_fps(con_output_vblank, preferred_mode->vrefresh);
+       ASSERT_TRUE(error == TDM_ERROR_NONE);
+
+       error = tdm_vblank_set_offset(con_output_vblank, 0);
+       ASSERT_TRUE(error == TDM_ERROR_NONE);
+
+       for (int i = 0; i < 10; ++i) {
+               utVblankHandlerIsCalled = 0;
+               data = 0;
+
+               error = tdm_vblank_wait(con_output_vblank, 0, 0, 1, UtVblankHandler, &data);
+               ASSERT_TRUE(error == TDM_ERROR_NONE);
+
+               UtHandleVblankEvent();
+
+               ASSERT_TRUE(utVblankHandlerIsCalled == 1);
+               ASSERT_TRUE(data == 1);
+       }
+}
+
+TEST_F(TDMVblankWaitThread, VblankWaitSuccessOffsenGreaterThanZero)
+{
+       tdm_error error;
+       int data = 0;
+
+       SKIP_FLAG(has_output);
+
+       if (!con_output_vblank)
+               return;
+
+       error = tdm_vblank_ignore_global_fps(con_output_vblank, 0);
+       ASSERT_TRUE(error == TDM_ERROR_NONE);
+
+       error = tdm_vblank_enable_global_fps(1, preferred_mode->vrefresh);
+       ASSERT_TRUE(error == TDM_ERROR_NONE);
+
+       error = tdm_vblank_set_fps(con_output_vblank, preferred_mode->vrefresh);
+       ASSERT_TRUE(error == TDM_ERROR_NONE);
+
+       error = tdm_vblank_set_offset(con_output_vblank, 10);
+       ASSERT_TRUE(error == TDM_ERROR_NONE);
+
+       error = tdm_vblank_wait(con_output_vblank, 0, 0, 1, UtVblankHandler, &data);
+       ASSERT_TRUE(error == TDM_ERROR_NONE);
+
+       UtHandleVblankEvent();
+
+       ASSERT_TRUE(utVblankHandlerIsCalled == 1);
+       ASSERT_TRUE(data == 1);
+}
+
+TEST_F(TDMVblankWaitThread, VblankWaitSuccessOffsenGreaterThanZeroRepeatedly)
+{
+       tdm_error error;
+       int data;
+
+       SKIP_FLAG(has_output);
+
+       if (!con_output_vblank)
+               return;
+
+       error = tdm_vblank_ignore_global_fps(con_output_vblank, 0);
+       ASSERT_TRUE(error == TDM_ERROR_NONE);
+
+       error = tdm_vblank_enable_global_fps(1, preferred_mode->vrefresh);
+       ASSERT_TRUE(error == TDM_ERROR_NONE);
+
+       error = tdm_vblank_set_fps(con_output_vblank, preferred_mode->vrefresh);
+       ASSERT_TRUE(error == TDM_ERROR_NONE);
+
+       error = tdm_vblank_set_offset(con_output_vblank, 10);
+       ASSERT_TRUE(error == TDM_ERROR_NONE);
+
+       for (int i = 0; i < 10; ++i) {
+               utVblankHandlerIsCalled = 0;
+               data = 0;
+
+               error = tdm_vblank_wait(con_output_vblank, 0, 0, 1, UtVblankHandler, &data);
+               ASSERT_TRUE(error == TDM_ERROR_NONE);
+
+               UtHandleVblankEvent();
+
+               ASSERT_TRUE(utVblankHandlerIsCalled == 1);
+               ASSERT_TRUE(data == 1);
+       }
+}
+
+/* tdm_vblank_wait_seq() */
+
+TEST_F(TDMVblank, VblankWaitSeqFailNullAll)
+{
+       tdm_error error;
+
+       SKIP_FLAG(has_output);
+
+       error = tdm_vblank_wait_seq(NULL, 0, 0, 0, NULL, NULL);
+       ASSERT_TRUE(error != TDM_ERROR_NONE);
+}
+
+TEST_F(TDMVblankWait, VblankWaitSeqFailNullVblank)
+{
+       tdm_error error;
+
+       SKIP_FLAG(has_output);
+
+       error = tdm_vblank_wait_seq(NULL, 0, 0, 1, UtVblankHandler, NULL);
+       ASSERT_TRUE(error != TDM_ERROR_NONE);
+}
+
+TEST_F(TDMVblankWait, VblankWaitSeqFailWrongVblankPtr)
+{
+       tdm_error error = TDM_ERROR_BAD_MODULE;
+       SKIP_FLAG(has_output);
+
+       ASSERT_EXIT({error = tdm_vblank_wait_seq((tdm_vblank *)0xFFFFFFFF, 0, 0, 1, UtVblankHandler, NULL);;
+                               if (error == TDM_ERROR_NONE)
+                                       exit(1);
+                               else
+                                       exit(0);},
+                               ::testing::ExitedWithCode(0), "");
+}
+
+TEST_F(TDMVblankWait, VblankWaitSeqFailNullFunc)
+{
+       tdm_error error;
+
+       SKIP_FLAG(has_output);
+
+       error = tdm_vblank_wait_seq(NULL, 0, 0, 1, UtVblankHandler, NULL);
+       ASSERT_TRUE(error != TDM_ERROR_NONE);
+}
+
+void *UtWaitVblankSeqThreadHndl(void *ptr)
+{
+       tdm_error error;
+       TDMVblankWait *vblankWait = (TDMVblankWait *)ptr;
+
+       error = tdm_vblank_wait_seq(vblankWait->default_vblank, 0, 0, 1, TDMVblankWait::UtVblankHandler, NULL);
+       if (error != TDM_ERROR_NONE)
+               vblankWait->utWaitVblankSeqThreadHndlResult = 0;
+       else
+               vblankWait->utWaitVblankSeqThreadHndlResult = 0;
+}
+
+TEST_F(TDMVblankWait, VblankWaitSeqFailInOtherThread)
+{
+       pthread_t thread;
+
+       SKIP_FLAG(has_output);
+
+       ASSERT_FALSE(pthread_create(&thread, NULL, UtWaitVblankSeqThreadHndl, this));
+
+       ASSERT_FALSE(pthread_join(thread, NULL));
+
+       ASSERT_FALSE(utWaitVblankSeqThreadHndlResult);
+}
+
+TEST_F(TDMVblankWait, VblankWaitSeqFailDisconnectedOutput)
+{
+       tdm_error error;
+
+       SKIP_FLAG(has_output);
+
+       if (!discon_output_vblank)
+               return;
+
+       error = tdm_vblank_wait_seq(discon_output_vblank, 0, 0, 1, UtVblankHandler, NULL);
+       ASSERT_TRUE(error != TDM_ERROR_NONE);
+}
+
+TEST_F(TDMVblankWait, VblankWaitSeqFailDpmsOff)
+{
+       tdm_error error;
+
+       SKIP_FLAG(has_output);
+
+       if (!con_output_vblank)
+               return;
+
+       error = tdm_output_set_dpms(connected_output, TDM_OUTPUT_DPMS_OFF);
+       ASSERT_TRUE(error == TDM_ERROR_NONE);
+
+       error = tdm_vblank_wait_seq(con_output_vblank, 0, 0, 1, UtVblankHandler, NULL);
+       ASSERT_TRUE(error != TDM_ERROR_NONE);
+}
+
+TEST_F(TDMVblankWait, VblankWaitSeqSuccessFpsNonMultipleVrefresh)
+{
+       tdm_error error;
+       int data = 0;
+
+       SKIP_FLAG(has_output);
+
+       if (!con_output_vblank)
+               return;
+
+       error = tdm_vblank_ignore_global_fps(con_output_vblank, 1);
+       ASSERT_TRUE(error == TDM_ERROR_NONE);
+
+       error = tdm_vblank_set_fps(con_output_vblank, preferred_mode->vrefresh - 1);
+       ASSERT_TRUE(error == TDM_ERROR_NONE);
+
+       error = tdm_vblank_wait_seq(con_output_vblank, 0, 0, 1, UtVblankHandler, &data);
+       ASSERT_TRUE(error == TDM_ERROR_NONE);
+
+       UtHandleVblankEvent();
+
+       ASSERT_TRUE(utVblankHandlerIsCalled == 1);
+       ASSERT_TRUE(data == 1);
+}
+
+TEST_F(TDMVblankWait, VblankWaitSeqSuccessFpsNonMultipleVrefreshRepeatedly)
+{
+       tdm_error error;
+       int data;
+
+       SKIP_FLAG(has_output);
+
+       if (!con_output_vblank)
+               return;
+
+       error = tdm_vblank_ignore_global_fps(con_output_vblank, 1);
+       ASSERT_TRUE(error == TDM_ERROR_NONE);
+
+       error = tdm_vblank_set_fps(con_output_vblank, preferred_mode->vrefresh - 1);
+       ASSERT_TRUE(error == TDM_ERROR_NONE);
+
+       for (int i = 1; i < 10; ++i) {
+               utVblankHandlerIsCalled = 0;
+               data = 0;
+
+               error = tdm_vblank_wait_seq(con_output_vblank, 0, 0, i, UtVblankHandler, &data);
+               ASSERT_TRUE(error == TDM_ERROR_NONE);
+
+               UtHandleVblankEvent();
+
+               ASSERT_TRUE(utVblankHandlerIsCalled == 1);
+               ASSERT_TRUE(data == 1);
+       }
+}
+
+TEST_F(TDMVblankWait, VblankWaitSeqSuccessDisconnectedOutput)
+{
+       tdm_error error;
+       int data;
+
+       SKIP_FLAG(has_output);
+
+       if (!discon_output_vblank)
+               return;
+
+       error = tdm_vblank_set_enable_fake(discon_output_vblank, 1);
+       ASSERT_TRUE(error == TDM_ERROR_NONE);
+
+       error = tdm_vblank_wait_seq(discon_output_vblank, 0, 0, 1, UtVblankHandler, &data);
+       ASSERT_TRUE(error == TDM_ERROR_NONE);
+
+       UtHandleVblankEvent();
+
+       ASSERT_TRUE(utVblankHandlerIsCalled == 1);
+       ASSERT_TRUE(data == 1);
+}
+
+TEST_F(TDMVblankWait, VblankWaitSeqSuccessDisconnectedOutputRepeatedly)
+{
+       tdm_error error;
+       int data;
+
+       SKIP_FLAG(has_output);
+
+       if (!discon_output_vblank)
+               return;
+
+       error = tdm_vblank_set_enable_fake(discon_output_vblank, 1);
+       ASSERT_TRUE(error == TDM_ERROR_NONE);
+
+       for (int i = 1; i < 10; ++i) {
+               utVblankHandlerIsCalled = 0;
+               data = 0;
+
+               error = tdm_vblank_wait_seq(discon_output_vblank, 0, 0, i, UtVblankHandler, &data);
+               ASSERT_TRUE(error == TDM_ERROR_NONE);
+
+               UtHandleVblankEvent();
+
+               ASSERT_TRUE(utVblankHandlerIsCalled == 1);
+               ASSERT_TRUE(data == 1);
+       }
+}
+
+TEST_F(TDMVblankWait, VblankWaitSeqSuccessHW)
+{
+       tdm_error error;
+       int data;
+
+       SKIP_FLAG(has_output);
+
+       if (!con_output_vblank)
+               return;
+
+       error = tdm_vblank_ignore_global_fps(con_output_vblank, 0);
+       ASSERT_TRUE(error == TDM_ERROR_NONE);
+
+       error = tdm_vblank_enable_global_fps(1, preferred_mode->vrefresh);
+       ASSERT_TRUE(error == TDM_ERROR_NONE);
+
+       error = tdm_vblank_set_fps(con_output_vblank, preferred_mode->vrefresh);
+       ASSERT_TRUE(error == TDM_ERROR_NONE);
+
+       error = tdm_vblank_set_offset(con_output_vblank, 0);
+       ASSERT_TRUE(error == TDM_ERROR_NONE);
+
+       error = tdm_vblank_wait_seq(con_output_vblank, 0, 0, 1, UtVblankHandler, &data);
+       ASSERT_TRUE(error == TDM_ERROR_NONE);
+
+       UtHandleVblankEvent();
+
+       ASSERT_TRUE(utVblankHandlerIsCalled == 1);
+       ASSERT_TRUE(data == 1);
+}
+
+TEST_F(TDMVblankWait, VblankWaitSeqSuccessHWRepeatedly)
+{
+       tdm_error error;
+       int data;
+
+       SKIP_FLAG(has_output);
+
+       if (!con_output_vblank)
+               return;
+
+       error = tdm_vblank_ignore_global_fps(con_output_vblank, 0);
+       ASSERT_TRUE(error == TDM_ERROR_NONE);
+
+       error = tdm_vblank_enable_global_fps(1, preferred_mode->vrefresh);
+       ASSERT_TRUE(error == TDM_ERROR_NONE);
+
+       error = tdm_vblank_set_fps(con_output_vblank, preferred_mode->vrefresh);
+       ASSERT_TRUE(error == TDM_ERROR_NONE);
+
+       error = tdm_vblank_set_offset(con_output_vblank, 0);
+       ASSERT_TRUE(error == TDM_ERROR_NONE);
+
+       for (int i = 1; i < 10; ++i) {
+               utVblankHandlerIsCalled = 0;
+               data = 0;
+
+               error = tdm_vblank_wait_seq(con_output_vblank, 0, 0, i, UtVblankHandler, &data);
+               ASSERT_TRUE(error == TDM_ERROR_NONE);
+
+               UtHandleVblankEvent();
+
+               ASSERT_TRUE(utVblankHandlerIsCalled == 1);
+               ASSERT_TRUE(data == 1);
+       }
+}
+
+TEST_F(TDMVblankWait, VblankWaitSeqSuccessOffsenGreaterThanZero)
+{
+       tdm_error error;
+       int data = 0;
+
+       SKIP_FLAG(has_output);
+
+       if (!con_output_vblank)
+               return;
+
+       error = tdm_vblank_ignore_global_fps(con_output_vblank, 0);
+       ASSERT_TRUE(error == TDM_ERROR_NONE);
+
+       error = tdm_vblank_enable_global_fps(1, preferred_mode->vrefresh);
+       ASSERT_TRUE(error == TDM_ERROR_NONE);
+
+       error = tdm_vblank_set_fps(con_output_vblank, preferred_mode->vrefresh);
+       ASSERT_TRUE(error == TDM_ERROR_NONE);
+
+       error = tdm_vblank_set_offset(con_output_vblank, 10);
+       ASSERT_TRUE(error == TDM_ERROR_NONE);
+
+       error = tdm_vblank_wait_seq(con_output_vblank, 0, 0, 1, UtVblankHandler, &data);
+       ASSERT_TRUE(error == TDM_ERROR_NONE);
+
+       UtHandleVblankEvent();
+
+       ASSERT_TRUE(utVblankHandlerIsCalled == 1);
+       ASSERT_TRUE(data == 1);
+}
+
+TEST_F(TDMVblankWait, VblankWaitSeqSuccessOffsenGreaterThanZeroRepeatedly)
+{
+       tdm_error error;
+       int data;
+
+       SKIP_FLAG(has_output);
+
+       if (!con_output_vblank)
+               return;
+
+       error = tdm_vblank_ignore_global_fps(con_output_vblank, 0);
+       ASSERT_TRUE(error == TDM_ERROR_NONE);
+
+       error = tdm_vblank_enable_global_fps(1, preferred_mode->vrefresh);
+       ASSERT_TRUE(error == TDM_ERROR_NONE);
+
+       error = tdm_vblank_set_fps(con_output_vblank, preferred_mode->vrefresh);
+       ASSERT_TRUE(error == TDM_ERROR_NONE);
+
+       error = tdm_vblank_set_offset(con_output_vblank, 10);
+       ASSERT_TRUE(error == TDM_ERROR_NONE);
+
+       for (int i = 1; i < 10; ++i) {
+               utVblankHandlerIsCalled = 0;
+
+               error = tdm_vblank_wait_seq(con_output_vblank, 0, 0, i, UtVblankHandler, &data);
+               ASSERT_TRUE(error == TDM_ERROR_NONE);
+
+               UtHandleVblankEvent();
+
+               ASSERT_TRUE(utVblankHandlerIsCalled == 1);
+               ASSERT_TRUE(data == 1);
+       }
+}
+
+TEST_F(TDMVblankWait, VblankWaitSeqSuccessRepeatedlyWithSameSeq)
+{
+       tdm_error error;
+       int data = 0;
+
+       SKIP_FLAG(has_output);
+
+       if (!con_output_vblank)
+               return;
+
+       error = tdm_vblank_ignore_global_fps(con_output_vblank, 0);
+       ASSERT_TRUE(error == TDM_ERROR_NONE);
+
+       error = tdm_vblank_set_fps(con_output_vblank, preferred_mode->vrefresh);
+       ASSERT_TRUE(error == TDM_ERROR_NONE);
+
+       error = tdm_vblank_set_offset(con_output_vblank, 0);
+       ASSERT_TRUE(error == TDM_ERROR_NONE);
+
+       for (int i = 1; i < 10; ++i) {
+               utVblankHandlerIsCalled = 0;
+               data = 0;
+
+               error = tdm_vblank_wait_seq(con_output_vblank, 0, 0, 2, UtVblankHandler, &data);
+               ASSERT_TRUE(error == TDM_ERROR_NONE);
+
+               UtHandleVblankEvent();
+
+               ASSERT_TRUE(utVblankHandlerIsCalled == 1);
+               ASSERT_TRUE(data == 1);
+       }
+}
+
+TEST_F(TDMVblankWait, VblankWaitSeqSuccessRepeatedlyWithBigFps)
+{
+       tdm_error error;
+       int data = 0;
+
+       SKIP_FLAG(has_output);
+
+       if (!con_output_vblank)
+               return;
+
+       error = tdm_vblank_ignore_global_fps(con_output_vblank, 0);
+       ASSERT_TRUE(error == TDM_ERROR_NONE);
+
+       error = tdm_vblank_set_fps(con_output_vblank, 5000);
+       ASSERT_TRUE(error == TDM_ERROR_NONE);
+
+       for (int i = 1; i < 10; ++i) {
+               utVblankHandlerIsCalled = 0;
+               data = 0;
+
+               error = tdm_vblank_wait_seq(con_output_vblank, 0, 0, i, UtVblankHandler, &data);
+               ASSERT_TRUE(error == TDM_ERROR_NONE);
+
+               if (i < 4)
+                       continue;
+
+               UtHandleVblankEvent();
+
+               ASSERT_TRUE(utVblankHandlerIsCalled == 1);
+               ASSERT_TRUE(data == 1);
+       }
+}
+
+TEST_F(TDMVblankWait, VblankWaitSeqSuccessRepeatedlyWithDelay)
+{
+       tdm_error error;
+       int data = 0;
+
+       SKIP_FLAG(has_output);
+
+       if (!con_output_vblank)
+               return;
+
+       error = tdm_vblank_ignore_global_fps(con_output_vblank, 0);
+       ASSERT_TRUE(error == TDM_ERROR_NONE);
+
+       error = tdm_vblank_set_fps(con_output_vblank, preferred_mode->vrefresh);
+       ASSERT_TRUE(error == TDM_ERROR_NONE);
+
+       for (int i = 1; i < 10; ++i) {
+               utVblankHandlerIsCalled = 0;
+               data = 0;
+
+               error = tdm_vblank_wait_seq(con_output_vblank, 0, 0, i, UtVblankHandler, &data);
+               ASSERT_TRUE(error == TDM_ERROR_NONE);
+
+               usleep(100000);
+
+               UtHandleVblankEvent();
+
+               ASSERT_TRUE(utVblankHandlerIsCalled == 1);
+               ASSERT_TRUE(data == 1);
+       }
+}