fix the typo
[platform/core/uifw/libtdm.git] / utests / src / ut_tdm_output.cpp
1 /**************************************************************************
2  *
3  * Copyright 2016 Samsung Electronics co., Ltd. All Rights Reserved.
4  *
5  * Contact: Konstantin Drabeniuk <k.drabeniuk@samsung.com>
6  * Contact: Andrii Sokolenko <a.sokolenko@samsung.com>
7  * Contact: Roman Marchenko <r.marchenko@samsung.com>
8  *
9  * Permission is hereby granted, free of charge, to any person obtaining a
10  * copy of this software and associated documentation files (the
11  * "Software"), to deal in the Software without restriction, including
12  * without limitation the rights to use, copy, modify, merge, publish,
13  * distribute, sub license, and/or sell copies of the Software, and to
14  * permit persons to whom the Software is furnished to do so, subject to
15  * the following conditions:
16  *
17  * The above copyright notice and this permission notice (including the
18  * next paragraph) shall be included in all copies or substantial portions
19  * of the Software.
20  *
21  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
22  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
23  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
24  * IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
25  * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
26  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
27  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
28  *
29 **************************************************************************/
30
31 #include "gtest/gtest.h"
32 #include "ut_common.h"
33 #include <climits>
34 #include "tdm.h"
35 extern "C" {
36 #include "tbm_bufmgr.h"
37 #include "tbm_drm_helper.h"
38 }
39 #include <vector>
40 #include <sys/epoll.h>
41 #include <sys/timerfd.h>
42 #include <pthread.h>
43
44 class TDMOutput : public ::testing::Test {
45 protected:
46         tdm_display *dpy = NULL;
47         int output_count = 0, master_fd = -42, tbm_fd = -42;
48         bool has_output = false;
49         tbm_bufmgr tbm_bufmgr = NULL;
50         static unsigned int handle_call;
51         static void tdm_output_change_handler_test_func(tdm_output *output,
52                                                                                                         tdm_output_change_type type,
53                                                                                                         tdm_value value,
54                                                                                                         void *u_data)
55         {
56                 if ( ((intptr_t) u_data) < -100) {
57                         TDMOutput::handle_call++;
58                 }
59         }
60         virtual void SetEnvs()
61         {
62                 setenv("TDM_DEBUG_MODULE", "all", 1);
63                 setenv("TDM_DEBUG", "1", 1);
64                 setenv("TDM_DLOG", "1", 1);
65                 setenv("XDG_RUNTIME_DIR", ".", 1);
66                 setenv("TBM_DLOG", "1", 1);
67                 setenv("TBM_DISPLAY_SERVER", "1", 1);
68                 setenv("TDM_COMMIT_PER_VBLANK", "0", 1);
69         }
70
71         virtual void UnsetEnvs()
72         {
73                 unsetenv("TDM_DEBUG_MODULE");
74                 unsetenv("TDM_DEBUG");
75                 unsetenv("TDM_DLOG");
76                 unsetenv("XDG_RUNTIME_DIR");
77                 unsetenv("TBM_DLOG");
78                 unsetenv("TBM_DISPLAY_SERVER");
79                 unsetenv("TDM_COMMIT_PER_VBLANK");
80         }
81
82         void SetUp(void)
83         {
84                 SetEnvs();
85
86                 tdm_error error = TDM_ERROR_NONE;
87                 dpy = tdm_display_init(&error);
88                 ASSERT_TRUE(error == TDM_ERROR_NONE);
89                 ASSERT_FALSE(dpy == NULL);
90                 tbm_bufmgr = tbm_bufmgr_init(-1);
91                 ASSERT_FALSE(tbm_bufmgr == NULL);
92                 master_fd = tbm_drm_helper_get_master_fd();
93                 tbm_fd = tbm_drm_helper_get_fd();
94                 error = tdm_display_get_output_count(dpy, &output_count);
95 #ifdef FAIL_ON_UNSUPPORTED
96                 ASSERT_GT(output_count, 0);
97 #endif
98                 if (output_count > 0)
99                         has_output = true;
100                 handle_call = 0;
101         }
102         void TearDown(void)
103         {
104                 tdm_display_deinit(dpy);
105                 dpy = NULL;
106                 tbm_bufmgr_deinit(tbm_bufmgr);
107                 tbm_bufmgr = NULL;
108                 if (master_fd > -1) {
109                         int temp_master_fd = tbm_drm_helper_get_master_fd();
110                         EXPECT_EQ(temp_master_fd, -1) << "Fatal Error. Can't deinit tdm/tbm" << std::endl;
111                         if (temp_master_fd > -1)
112                                 exit(1);
113                         close(master_fd);
114                 }
115                 if (tbm_fd > -1) {
116                         int temp_tbm_fd = tbm_drm_helper_get_fd();
117                         EXPECT_EQ(temp_tbm_fd, -1) << "Fatal Error. Can't deinit tdm/tbm" << std::endl;
118                         if (temp_tbm_fd > -1)
119                                 exit(1);
120                         close(tbm_fd);
121                 }
122
123                 UnsetEnvs();
124         }
125 };
126
127 class TDMOutputHWC : public TDMOutput {
128         void SetEnvs(void)
129         {
130                 TDMOutput::SetEnvs();
131                 setenv("TDM_HWC", "1", 1);
132         }
133         void UnsetEnvs(void)
134         {
135                 TDMOutput::UnsetEnvs();
136                 unsetenv("TDM_HWC");
137         }
138 };
139
140 class TDMOutputThread : public TDMOutput {
141         void SetEnvs(void)
142         {
143
144                 TDMOutput::SetEnvs();
145                 setenv("TDM_THREAD", "1", 1);
146         }
147         void UnsetEnvs(void)
148         {
149                 TDMOutput::UnsetEnvs();
150                 unsetenv("TDM_THREAD");
151         }
152 };
153
154 class TDMOutputCommit : public TDMOutput {
155 private:
156         int epFd = -1;
157         int timerFd = -1;
158         int tdmFd = -1;
159         static const int timeLimitSec = 1;
160         static const int timeLimitNsec = 0;
161 protected:
162         int conn_output_count = 0;
163         tdm_output ** connected_output_array = NULL;
164         const tdm_output_mode** preferred_mode = NULL;
165         bool has_output = false;
166         std::vector<std::vector<tdm_layer *>> layers_array;
167         std::vector<tbm_surface_h> buffers;
168         static unsigned int utOutputCommitHandlerCounter;
169         static void UtOutputCommitHandler(tdm_output *output, unsigned int sequence,
170                                                            unsigned int tv_sec, unsigned int tv_usec,
171                                                            void *user_data)
172         {
173                 utOutputCommitHandlerCounter++;
174         }
175
176         static unsigned int utOutputVblankHandlerCounter;
177         static void UtOutputVblankHandler(tdm_output *output, unsigned int sequence,
178                                                            unsigned int tv_sec, unsigned int tv_usec,
179                                                            void *user_data)
180         {
181                 utOutputVblankHandlerCounter++;
182         }
183         friend void *UtOutputRemoveChangeHandlerSuccessfulThread(void *ptr);
184
185         void SetUp(void)
186         {
187                 struct epoll_event ep;
188
189                 utOutputCommitHandlerCounter = 0;
190                 utOutputVblankHandlerCounter = 0;
191
192                 ASSERT_NO_FATAL_FAILURE(TDMOutput::SetUp());
193                 if (TDMOutput::output_count > 0) {
194                         connected_output_array = (tdm_output **) calloc(TDMOutput::output_count, sizeof(tdm_output *));
195                         ASSERT_FALSE(NULL == connected_output_array);
196                         preferred_mode = (const tdm_output_mode **) calloc(TDMOutput::output_count, sizeof(tdm_output_mode*));
197                         ASSERT_FALSE(NULL == preferred_mode);
198                 }
199                 conn_output_count = 0;
200                 for (int i = 0; i < TDMOutput::output_count; i++) {
201                         tdm_error error = TDM_ERROR_NONE;
202                         int output_modes_cnt = 0;
203                         int layer_count = 0;
204                         const tdm_output_mode* output_modes = NULL;
205                         tdm_output * output = tdm_display_get_output(TDMOutput::dpy, i, &error);
206                         std::vector<tdm_layer *> layers;
207                         if (TDM_ERROR_NONE != error || NULL == output)
208                                 continue;
209                         tdm_output_conn_status status = TDM_OUTPUT_CONN_STATUS_DISCONNECTED;
210                         if (TDM_ERROR_NONE != tdm_output_get_conn_status(output, &status))
211                                 continue;
212                         if (TDM_OUTPUT_CONN_STATUS_DISCONNECTED == status)
213                                 continue;
214                         if (TDM_ERROR_NONE != tdm_output_set_dpms(output, TDM_OUTPUT_DPMS_ON))
215                                 continue;
216                         if(TDM_ERROR_NONE != tdm_output_get_available_modes(output,
217                                                                                                                                 &output_modes,
218                                                                                                                                 &output_modes_cnt))
219                                 continue;
220                         for(int k = 0; k < output_modes_cnt; k++) {
221                                 if(output_modes[k].type & TDM_OUTPUT_MODE_TYPE_PREFERRED) {
222                                         preferred_mode[conn_output_count] = &output_modes[k];
223                                         break;
224                                 }
225                         }
226                         if (NULL == preferred_mode[conn_output_count])
227                                 continue;
228
229                         if (TDM_ERROR_NONE != tdm_output_get_layer_count(output, &layer_count))
230                                 continue;
231                         if (0 == layer_count)
232                                 continue;
233
234                         for (int i = 0; i < layer_count; ++i) {
235                                 tdm_layer *layer;
236                                 layer = tdm_output_get_layer(output, i, &error);
237                                 if (layer == nullptr)
238                                         continue;
239                                 layers.push_back(layer);
240                         }
241                         connected_output_array[conn_output_count++] = output;
242                         layers_array.push_back(layers);
243                 }
244 #ifdef FAIL_ON_UNSUPPORTED
245                 ASSERT_GT(conn_output_count, 0);
246 #endif
247
248                 if (conn_output_count > 0)
249                         has_output = true;
250
251                 epFd = epoll_create1(0);
252                 ASSERT_TRUE(epFd != -1);
253
254                 timerFd = timerfd_create(CLOCK_MONOTONIC, TFD_CLOEXEC | TFD_NONBLOCK);
255                 ASSERT_TRUE(timerFd != -1);
256
257                 memset(&ep, 0, sizeof ep);
258                 ep.events |= EPOLLIN;
259                 ep.data.fd = timerFd;
260                 ASSERT_TRUE(epoll_ctl(epFd, EPOLL_CTL_ADD, timerFd, &ep) == 0);
261
262                 ASSERT_TRUE(tdm_display_get_fd(dpy, &tdmFd) == TDM_ERROR_NONE);
263
264                 memset(&ep, 0, sizeof ep);
265                 ep.events |= EPOLLIN;
266                 ep.data.fd = tdmFd;
267                 ASSERT_TRUE(epoll_ctl(epFd, EPOLL_CTL_ADD, tdmFd, &ep) == 0);
268         }
269         void TearDown(void)
270         {
271                 for (size_t i = 0; i < layers_array.size(); ++i) {
272                         for (tdm_layer *layer : layers_array[i]) {
273                                 tdm_layer_unset_buffer(layer);
274                         }
275                 }
276
277                 for (tbm_surface_h buffer : buffers) {
278                         tbm_surface_destroy(buffer);
279                 }
280
281                 for (int i = 0; i < conn_output_count; i++) {
282                         EXPECT_TRUE(TDM_ERROR_NONE == tdm_output_set_dpms(connected_output_array[i],
283                                                                                                                           TDM_OUTPUT_DPMS_OFF));
284                 }
285                 if (connected_output_array)
286                         free(connected_output_array);
287                 if (preferred_mode)
288                         free(preferred_mode);
289                 ASSERT_NO_FATAL_FAILURE(TDMOutput::TearDown());
290         }
291
292         tbm_surface_h UtCreateBuffer(int width, int height, tbm_format format)
293         {
294                 tbm_surface_h buffer;
295
296                 buffer = tbm_surface_internal_create_with_flags(width, height, format, TBM_BO_SCANOUT);
297
298                 if (buffer)
299                         buffers.push_back(buffer);
300
301                 return buffer;
302         }
303
304         void UtPrepareToCommit()
305         {
306                 for (size_t i = 0; i < layers_array.size(); ++i) {
307                         for (tdm_layer *layer : layers_array[i]) {
308                                 int w, h;
309                                 tdm_error error;
310                                 tdm_layer_capability lcapabilities;
311                                 tbm_surface_h buffer;
312                                 tdm_info_layer layer_info = {0};
313
314                                 w = preferred_mode[i]->hdisplay;
315                                 h = preferred_mode[i]->vdisplay;
316
317                                 error = tdm_output_set_mode(connected_output_array[i], preferred_mode[i]);
318                                 ASSERT_EQ(TDM_ERROR_NONE, error);
319
320                                 error = tdm_layer_get_capabilities(layer, &lcapabilities);
321                                 ASSERT_EQ(TDM_ERROR_NONE, error);
322                                 if (!(lcapabilities & TDM_LAYER_CAPABILITY_PRIMARY)) {
323                                         w = w / 2;
324                                         h = h / 2;
325                                 }
326
327                                 buffer = UtCreateBuffer(w, h, TBM_FORMAT_ARGB8888);
328                                 ASSERT_NE(nullptr, buffer);
329
330                                 layer_info.src_config.size.h = w;
331                                 layer_info.src_config.size.v = h;
332                                 layer_info.src_config.pos.x = 0;
333                                 layer_info.src_config.pos.y = 0;
334                                 layer_info.src_config.pos.w = w;
335                                 layer_info.src_config.pos.h = h;
336                                 layer_info.src_config.format = TBM_FORMAT_ARGB8888;
337                                 layer_info.dst_pos.x = 0;
338                                 layer_info.dst_pos.y = 0;
339                                 layer_info.dst_pos.w = w;
340                                 layer_info.dst_pos.h = h;
341                                 layer_info.transform = TDM_TRANSFORM_NORMAL;
342
343                                 error = tdm_layer_set_info(layer, &layer_info);
344                                 ASSERT_EQ(TDM_ERROR_NONE, error);
345
346                                 error = tdm_layer_set_buffer(layer, buffer);
347                                 ASSERT_EQ(TDM_ERROR_NONE, error);
348                         }
349                 }
350         }
351
352         void UtHandleEvent(unsigned int & wait_var, unsigned int num)
353         {
354                 struct itimerspec its;
355                 int count;
356                 struct epoll_event ep_event[2];
357
358                 if (wait_var == num)
359                         return;
360
361                 its.it_interval.tv_sec = 0;
362                 its.it_interval.tv_nsec = 0;
363                 its.it_value.tv_sec = timeLimitSec;
364                 its.it_value.tv_nsec = timeLimitNsec;
365
366                 ASSERT_TRUE(timerfd_settime(timerFd, 0, &its, NULL) == 0);
367
368                 while (1) {
369                         count = epoll_wait(epFd, ep_event, sizeof(ep_event), -1);
370                         ASSERT_TRUE(count >= 0);
371
372                         for (int i = 0; i < count; i++) {
373                                 if (ep_event[i].data.fd == timerFd) {
374                                         return;
375                                 } else {
376                                         ASSERT_TRUE(tdm_display_handle_events(dpy) == TDM_ERROR_NONE);
377                                         if (wait_var == num)
378                                                 return;
379                                 }
380                         }
381                 }
382         }
383
384         void UtHandleCommitEvent()
385         {
386                 UtHandleEvent(utOutputCommitHandlerCounter, (unsigned int)conn_output_count);
387         }
388
389         void UtHandleVblankEvent()
390         {
391                 UtHandleEvent(utOutputVblankHandlerCounter, conn_output_count);
392         }
393 };
394
395 class TDMOutputCommitPerVblankEnabled : public TDMOutputCommit {
396         void SetEnvs(void)
397         {
398
399                 TDMOutputCommit::SetEnvs();
400                 setenv("TDM_COMMIT_PER_VBLANK", "1", 1);
401         }
402         void UnsetEnvs(void)
403         {
404                 TDMOutputCommit::UnsetEnvs();
405                 unsetenv("TDM_COMMIT_PER_VBLANK");
406         }
407 };
408
409 class TDMOutputCommitThread : public TDMOutputCommit {
410         void SetEnvs(void)
411         {
412                 TDMOutputCommit::SetEnvs();
413                 setenv("TDM_THREAD", "1", 1);
414         }
415
416         void UnsetEnvs(void)
417         {
418                 TDMOutputCommit::UnsetEnvs();
419                 unsetenv("TDM_THREAD");
420         }
421 };
422
423 unsigned int TDMOutput::handle_call = 0;
424 unsigned int TDMOutputCommit::utOutputCommitHandlerCounter = 0;
425 unsigned int TDMOutputCommit::utOutputVblankHandlerCounter = 0;
426
427 TEST_F(TDMOutput, DisplayGetOutputSuccessful)
428 {
429         SKIP_FLAG(has_output);
430         for (int i = 0; i < output_count; i++) {
431                 tdm_error error = TDM_ERROR_NONE;
432                 ASSERT_FALSE(NULL == tdm_display_get_output(dpy, i, &error));
433                 ASSERT_TRUE(TDM_ERROR_NONE == error);
434         }
435 }
436
437 TEST_F(TDMOutput, DisplayGetOutputSuccessfulWrongIndex)
438 {
439         SKIP_FLAG(has_output);
440         tdm_error error = TDM_ERROR_NONE;
441         ASSERT_TRUE(NULL == tdm_display_get_output(dpy, -1, &error));
442         ASSERT_TRUE(TDM_ERROR_NONE == error);
443 }
444
445 TEST_F(TDMOutput, DisplayGetOutputSuccessfulBigIndex)
446 {
447         SKIP_FLAG(has_output);
448         tdm_error error = TDM_ERROR_NONE;
449         ASSERT_TRUE(NULL == tdm_display_get_output(dpy, INT_MAX, &error));
450         ASSERT_TRUE(TDM_ERROR_NONE == error);
451 }
452
453 TEST_F(TDMOutput, DisplayGetOutputSuccessfulSmallIndex)
454 {
455         SKIP_FLAG(has_output);
456         tdm_error error = TDM_ERROR_NONE;
457         ASSERT_TRUE(NULL == tdm_display_get_output(dpy, INT_MIN, &error));
458         ASSERT_TRUE(TDM_ERROR_NONE == error);
459 }
460
461 TEST_F(TDMOutput, DisplayGetOutputSuccessfulErrorNull)
462 {
463         SKIP_FLAG(has_output);
464         ASSERT_FALSE(NULL == tdm_display_get_output(dpy, 0, NULL));
465 }
466
467 TEST_F(TDMOutput, DisplayOutputGetCapabilitiesSuccessful)
468 {
469         SKIP_FLAG(has_output);
470         for (int i = 0; i < output_count; i++) {
471                 tdm_error error = TDM_ERROR_NONE;
472                 tdm_output_capability capabilities = (tdm_output_capability) -42;
473                 tdm_output * output = tdm_display_get_output(dpy, i, &error);
474                 ASSERT_FALSE(NULL == output);
475                 ASSERT_TRUE(TDM_ERROR_NONE == error);
476                 ASSERT_TRUE(TDM_ERROR_NONE == tdm_output_get_capabilities(output, &capabilities));
477                 ASSERT_FALSE(-42 == capabilities);
478         }
479 }
480
481 TEST_F(TDMOutput, DisplayOutputGetCapabilitiesFailAllNull)
482 {
483         SKIP_FLAG(has_output);
484         ASSERT_FALSE(TDM_ERROR_NONE == tdm_output_get_capabilities(NULL, NULL));
485 }
486
487 TEST_F(TDMOutput, DisplayOutputGetCapabilitiesFailOnlyOutput)
488 {
489         SKIP_FLAG(has_output);
490         for (int i = 0; i < output_count; i++) {
491                 tdm_error error = TDM_ERROR_NONE;
492                 tdm_output * output = tdm_display_get_output(dpy, i, &error);
493                 ASSERT_FALSE(NULL == output);
494                 ASSERT_TRUE(TDM_ERROR_NONE == error);
495                 ASSERT_FALSE(TDM_ERROR_NONE == tdm_output_get_capabilities(output, NULL));
496         }
497 }
498
499 TEST_F(TDMOutput, OutputGetModelInfoSuccessful)
500 {
501         SKIP_FLAG(has_output);
502         for (int i = 0; i < output_count; i++) {
503                 tdm_error error = TDM_ERROR_NONE;
504                 const char * maker = NULL, * model = NULL, * name = NULL;
505                 tdm_output * output = tdm_display_get_output(dpy, i, &error);
506                 ASSERT_FALSE(NULL == output);
507                 ASSERT_TRUE(TDM_ERROR_NONE == error);
508                 ASSERT_TRUE(TDM_ERROR_NONE == tdm_output_get_model_info(output, &maker, &model, &name));
509                 ASSERT_FALSE(NULL == maker);
510                 ASSERT_FALSE(NULL == model);
511                 ASSERT_FALSE(NULL == name);
512         }
513 }
514
515 TEST_F(TDMOutput, OutputGetModelInfoFailAllNull)
516 {
517         SKIP_FLAG(has_output);
518         ASSERT_FALSE(TDM_ERROR_NONE == tdm_output_get_model_info(NULL, NULL, NULL, NULL));
519 }
520
521 TEST_F(TDMOutput, OutputGetModelInfoSuccessfulOnlyOutput)
522 {
523         SKIP_FLAG(has_output);
524         for (int i = 0; i < output_count; i++) {
525                 tdm_error error = TDM_ERROR_NONE;
526                 tdm_output * output = tdm_display_get_output(dpy, i, &error);
527                 ASSERT_FALSE(NULL == output);
528                 ASSERT_TRUE(TDM_ERROR_NONE == error);
529                 ASSERT_TRUE(TDM_ERROR_NONE == tdm_output_get_model_info(output, NULL, NULL, NULL));
530         }
531 }
532
533 TEST_F(TDMOutput, OutputGetConnStatusSuccessful)
534 {
535         SKIP_FLAG(has_output);
536         for (int i = 0; i < output_count; i++) {
537                 tdm_error error = TDM_ERROR_NONE;
538                 tdm_output_conn_status status = (tdm_output_conn_status) -42;
539                 tdm_output * output = tdm_display_get_output(dpy, i, &error);
540                 ASSERT_FALSE(NULL == output);
541                 ASSERT_TRUE(TDM_ERROR_NONE == error);
542                 ASSERT_TRUE(TDM_ERROR_NONE == tdm_output_get_conn_status(output, &status));
543                 ASSERT_FALSE(-42 == status);
544         }
545 }
546
547 TEST_F(TDMOutput, OutputGetConnStatusFailAllNull)
548 {
549         SKIP_FLAG(has_output);
550         ASSERT_FALSE(TDM_ERROR_NONE == tdm_output_get_conn_status(NULL, NULL));
551 }
552
553 TEST_F(TDMOutput, OutputGetConnStatusFailOnlyOutput)
554 {
555         SKIP_FLAG(has_output);
556         for (int i = 0; i < output_count; i++) {
557                 tdm_error error = TDM_ERROR_NONE;
558                 tdm_output * output = tdm_display_get_output(dpy, i, &error);
559                 ASSERT_FALSE(NULL == output);
560                 ASSERT_TRUE(TDM_ERROR_NONE == error);
561                 ASSERT_FALSE(TDM_ERROR_NONE == tdm_output_get_conn_status(output, NULL));
562         }
563 }
564
565 TEST_F(TDMOutput, OutputSetDPMSSuccessful)
566 {
567         SKIP_FLAG(has_output);
568         bool checked = false;
569         for (int i = 0; i < output_count; i++) {
570                 tdm_error error = TDM_ERROR_NONE;
571                 tdm_output_conn_status status;
572                 tdm_output * output = tdm_display_get_output(dpy, i, &error);
573                 ASSERT_FALSE(NULL == output);
574                 ASSERT_TRUE(TDM_ERROR_NONE == error);
575                 ASSERT_TRUE(TDM_ERROR_NONE == tdm_output_get_conn_status(output, &status));
576                 if (status == TDM_OUTPUT_CONN_STATUS_DISCONNECTED)
577                         continue;
578                 checked = true;
579                 ASSERT_TRUE(TDM_ERROR_NONE == tdm_output_set_dpms(output, TDM_OUTPUT_DPMS_ON));
580                 ASSERT_TRUE(TDM_ERROR_NONE == tdm_output_set_dpms(output, TDM_OUTPUT_DPMS_STANDBY));
581                 ASSERT_TRUE(TDM_ERROR_NONE == tdm_output_set_dpms(output, TDM_OUTPUT_DPMS_SUSPEND));
582                 ASSERT_TRUE(TDM_ERROR_NONE == tdm_output_set_dpms(output, TDM_OUTPUT_DPMS_OFF));
583         }
584         if (false == checked) {
585                 FAIL() << "All outputs are disconnected. Testcase skipped" << std::endl;
586         }
587 }
588
589 TEST_F(TDMOutput, OutputAddChangeHandlerSuccessful)
590 {
591         SKIP_FLAG(has_output);
592         bool checked = false;
593         for (int i = 0; i < output_count; i++) {
594                 tdm_error error = TDM_ERROR_NONE;
595                 tdm_output * output = tdm_display_get_output(dpy, i, &error);
596                 ASSERT_FALSE(NULL == output);
597                 ASSERT_TRUE(TDM_ERROR_NONE == error);
598                 tdm_output_conn_status status;
599                 ASSERT_TRUE(TDM_ERROR_NONE == tdm_output_get_conn_status(output, &status));
600                 if (status == TDM_OUTPUT_CONN_STATUS_DISCONNECTED)
601                         continue;
602                 checked = true;
603                 ASSERT_TRUE(TDM_ERROR_NONE == tdm_output_add_change_handler(output,
604                                                                                                                                         tdm_output_change_handler_test_func,
605                                                                                                                                         (void *) -101));
606                 ASSERT_TRUE(TDM_ERROR_NONE == tdm_output_set_dpms(output, TDM_OUTPUT_DPMS_ON));
607                 ASSERT_TRUE(TDM_ERROR_NONE == tdm_output_set_dpms(output, TDM_OUTPUT_DPMS_OFF));
608                 ASSERT_GT(handle_call, 0);
609         }
610         if (false == checked) {
611                 FAIL() << "All outputs are disconnected. Testcase skipped" << std::endl;
612         }
613 }
614
615 TEST_F(TDMOutput, OutputAddChangeHandlerSuccessfulFewFuncs)
616 {
617         SKIP_FLAG(has_output);
618         bool checked = false;
619         for (int i = 0; i < output_count; i++) {
620                 tdm_error error = TDM_ERROR_NONE;
621                 tdm_output * output = tdm_display_get_output(dpy, i, &error);
622                 ASSERT_FALSE(NULL == output);
623                 ASSERT_TRUE(TDM_ERROR_NONE == error);
624                 tdm_output_conn_status status;
625                 ASSERT_TRUE(TDM_ERROR_NONE == tdm_output_get_conn_status(output, &status));
626                 if (status == TDM_OUTPUT_CONN_STATUS_DISCONNECTED)
627                         continue;
628                 checked = true;
629                 for (intptr_t k = 0; k < 20; k++) {
630                         ASSERT_TRUE(TDM_ERROR_NONE == tdm_output_add_change_handler(output,
631                                                                                                                                                 tdm_output_change_handler_test_func,
632                                                                                                                                                 (void *) (-101-k)));
633                 }
634                 ASSERT_TRUE(TDM_ERROR_NONE == tdm_output_set_dpms(output, TDM_OUTPUT_DPMS_ON));
635                 ASSERT_TRUE(TDM_ERROR_NONE == tdm_output_set_dpms(output, TDM_OUTPUT_DPMS_OFF));
636                 ASSERT_GT(handle_call, 20);
637         }
638         if (false == checked) {
639                 FAIL() << "All outputs are disconnected. Testcase skipped" << std::endl;
640         }
641 }
642
643
644 TEST_F(TDMOutput, OutputAddChangeHandlerFailAllNull)
645 {
646         SKIP_FLAG(has_output);
647         ASSERT_FALSE(TDM_ERROR_NONE == tdm_output_add_change_handler(NULL, NULL, NULL));
648 }
649
650 TEST_F(TDMOutput, OutputAddChangeHandlerFailOnlyOutput)
651 {
652         SKIP_FLAG(has_output);
653         for (int i = 0; i < output_count; i++) {
654                 tdm_error error = TDM_ERROR_NONE;
655                 tdm_output * output = tdm_display_get_output(dpy, i, &error);
656                 ASSERT_FALSE(NULL == output);
657                 ASSERT_TRUE(TDM_ERROR_NONE == error);
658                 ASSERT_FALSE(TDM_ERROR_NONE == tdm_output_add_change_handler(output, NULL, NULL));
659         }
660 }
661
662 TEST_F(TDMOutput, OutputAddChangeHandlerFailWrongOutput)
663 {
664         SKIP_FLAG(has_output);
665         ASSERT_EXIT({tdm_output *output = (tdm_output *) 0xBEAF;
666                                  tdm_output_add_change_handler(output,
667                                                                                            tdm_output_change_handler_test_func,
668                                                                                            (void *) -101);
669                                  exit(0);}, ::testing::ExitedWithCode(0), "");
670 }
671
672 TEST_F(TDMOutput, OutputRemoveChangeHandlerSuccessful)
673 {
674         SKIP_FLAG(has_output);
675         bool checked = false;
676         for (int i = 0; i < output_count; i++) {
677                 tdm_error error = TDM_ERROR_NONE;
678                 tdm_output * output = tdm_display_get_output(dpy, i, &error);
679                 ASSERT_FALSE(NULL == output);
680                 ASSERT_TRUE(TDM_ERROR_NONE == error);
681                 tdm_output_conn_status status;
682                 ASSERT_TRUE(TDM_ERROR_NONE == tdm_output_get_conn_status(output, &status));
683                 if (status == TDM_OUTPUT_CONN_STATUS_DISCONNECTED)
684                         continue;
685                 checked = true;
686                 ASSERT_TRUE(TDM_ERROR_NONE == tdm_output_add_change_handler(output,
687                                                                                                                                         tdm_output_change_handler_test_func,
688                                                                                                                                         (void *) -101));
689                 ASSERT_TRUE(TDM_ERROR_NONE == tdm_output_set_dpms(output, TDM_OUTPUT_DPMS_ON));
690                 ASSERT_TRUE(TDM_ERROR_NONE == tdm_output_set_dpms(output, TDM_OUTPUT_DPMS_OFF));
691                 ASSERT_GT(handle_call, 0);
692                 handle_call = 0;
693                 tdm_output_remove_change_handler(output, tdm_output_change_handler_test_func, (void *) -101);
694                 ASSERT_TRUE(TDM_ERROR_NONE == tdm_output_set_dpms(output, TDM_OUTPUT_DPMS_ON));
695                 ASSERT_TRUE(TDM_ERROR_NONE == tdm_output_set_dpms(output, TDM_OUTPUT_DPMS_OFF));
696                 ASSERT_EQ(handle_call, 0);
697         }
698         if (false == checked) {
699                 FAIL() << "All outputs are disconnected. Testcase skipped" << std::endl;
700         }
701 }
702
703 void *UtOutputRemoveChangeHandlerSuccessfulThread(void *ptr)
704 {
705         TDMOutputCommitThread *FTDMOutput = (TDMOutputCommitThread *)ptr;
706
707         bool checked = false;
708         for (int i = 0; i < FTDMOutput->output_count; i++) {
709                 tdm_error error = TDM_ERROR_NONE;
710                 tdm_output * output = tdm_display_get_output(FTDMOutput->dpy, i, &error);
711                 if (NULL == output || TDM_ERROR_NONE != error)
712                         return (void *)1;
713                 tdm_output_conn_status status;
714                 error = tdm_output_get_conn_status(output, &status);
715                 if (TDM_ERROR_NONE != error)
716                         return (void *)2;
717                 if (status == TDM_OUTPUT_CONN_STATUS_DISCONNECTED)
718                         continue;
719                 checked = true;
720                 error = tdm_output_add_change_handler(output,
721                                                                                                 FTDMOutput->tdm_output_change_handler_test_func,
722                                                                                                 (void *) -101);
723                 if (TDM_ERROR_NONE != error)
724                         return (void *)3;
725                 error = tdm_output_set_dpms(output, TDM_OUTPUT_DPMS_ON);
726                 if (TDM_ERROR_NONE != error)
727                         return (void *)4;
728                 error = tdm_output_set_dpms(output, TDM_OUTPUT_DPMS_OFF);
729                 if (TDM_ERROR_NONE != error)
730                         return (void *)5;
731                 FTDMOutput->UtHandleEvent(FTDMOutput->handle_call, 1);
732                 if (FTDMOutput->handle_call <= 0)
733                         return (void *)6;
734                 FTDMOutput->handle_call = 0;
735                 tdm_output_remove_change_handler(output, FTDMOutput->tdm_output_change_handler_test_func, (void *) -101);
736                 error = tdm_output_set_dpms(output, TDM_OUTPUT_DPMS_ON);
737                 if (TDM_ERROR_NONE != error)
738                         return (void *)7;
739                 error = tdm_output_set_dpms(output, TDM_OUTPUT_DPMS_OFF);
740                 if (TDM_ERROR_NONE != error)
741                         return (void *)8;
742                 FTDMOutput->UtHandleEvent(FTDMOutput->handle_call, 1);
743                 if (FTDMOutput->handle_call != 0)
744                         return (void *)9;
745         }
746         if (false == checked) {
747                 return (void *)10;
748         }
749
750         return nullptr;
751 }
752
753 TEST_F(TDMOutputCommitThread, OutputRemoveChangeHandlerSuccessfulThread)
754 {
755         SKIP_FLAG(has_output);
756         pthread_t thread = 0;
757         int *status = nullptr;
758
759         ASSERT_FALSE(pthread_create(&thread, NULL, UtOutputRemoveChangeHandlerSuccessfulThread, this));
760
761         ASSERT_FALSE(pthread_join(thread, (void **)&status));
762
763         ASSERT_EQ(nullptr, status);
764 }
765
766 TEST_F(TDMOutput, OutputRemoveChangeHandlerSuccessfulFewFuncs)
767 {
768         SKIP_FLAG(has_output);
769         bool checked = false;
770         for (int i = 0; i < output_count; i++) {
771                 tdm_error error = TDM_ERROR_NONE;
772                 tdm_output * output = tdm_display_get_output(dpy, i, &error);
773                 ASSERT_FALSE(NULL == output);
774                 ASSERT_TRUE(TDM_ERROR_NONE == error);
775                 tdm_output_conn_status status;
776                 ASSERT_TRUE(TDM_ERROR_NONE == tdm_output_get_conn_status(output, &status));
777                 if (status == TDM_OUTPUT_CONN_STATUS_DISCONNECTED)
778                         continue;
779                 checked = true;
780                 for (intptr_t k = 0; k < 20; k++) {
781                         ASSERT_TRUE(TDM_ERROR_NONE == tdm_output_add_change_handler(output,
782                                                                                                                                                 tdm_output_change_handler_test_func,
783                                                                                                                                                 (void *) (-101-k)));
784                 }
785                 ASSERT_TRUE(TDM_ERROR_NONE == tdm_output_set_dpms(output, TDM_OUTPUT_DPMS_ON));
786                 ASSERT_TRUE(TDM_ERROR_NONE == tdm_output_set_dpms(output, TDM_OUTPUT_DPMS_OFF));
787                 ASSERT_GT(handle_call, 20);
788                 handle_call = 0;
789                 for (intptr_t k = 0; k < 20; k++) {
790                         tdm_output_remove_change_handler(output, tdm_output_change_handler_test_func, (void *) (-101-k));
791                 }
792                 ASSERT_TRUE(TDM_ERROR_NONE == tdm_output_set_dpms(output, TDM_OUTPUT_DPMS_ON));
793                 ASSERT_TRUE(TDM_ERROR_NONE == tdm_output_set_dpms(output, TDM_OUTPUT_DPMS_OFF));
794                 ASSERT_EQ(handle_call, 0);
795         }
796         if (false == checked) {
797                 FAIL() << "All outputs are disconnected. Testcase skipped" << std::endl;
798         }
799 }
800
801 TEST_F(TDMOutput, OutputRemoveChangeHandlerFailAllNull)
802 {
803         SKIP_FLAG(has_output);
804         ASSERT_EXIT({tdm_output_remove_change_handler(NULL, NULL, NULL);
805                                  exit(0);}, ::testing::ExitedWithCode(0), "");
806 }
807
808 TEST_F(TDMOutput, OutputRemoveChangeHandlerFailOnlyOutput)
809 {
810         SKIP_FLAG(has_output);
811         ASSERT_EXIT({for (int i = 0; i < output_count; i++) {
812                                          tdm_error error = TDM_ERROR_NONE;
813                                          tdm_output * output = tdm_display_get_output(dpy, i, &error);
814                                          if (NULL == output) exit(1);
815                                          if (TDM_ERROR_NONE != error) exit(1);
816                                          tdm_output_remove_change_handler(output, NULL, NULL);
817                                  } exit(0);}, ::testing::ExitedWithCode(0), "");
818 }
819
820 TEST_F(TDMOutput, OutputRemoveChangeHandlerFailWrongOutput)
821 {
822         SKIP_FLAG(has_output);
823         ASSERT_EXIT({tdm_output *output = (tdm_output *) 0xBEAF;
824                                  tdm_output_remove_change_handler(output,
825                                                                                            tdm_output_change_handler_test_func,
826                                                                                            (void *) -101);
827                                  exit(0);}, ::testing::ExitedWithCode(0), "");
828 }
829
830 TEST_F(TDMOutput, OutputGetOutputTypeSuccessful)
831 {
832         SKIP_FLAG(has_output);
833         for (int i = 0; i < output_count; i++) {
834                 tdm_error error = TDM_ERROR_NONE;
835                 tdm_output_type type = (tdm_output_type) -42;
836                 tdm_output * output = tdm_display_get_output(dpy, i, &error);
837                 ASSERT_FALSE(NULL == output);
838                 ASSERT_TRUE(TDM_ERROR_NONE == error);
839                 ASSERT_TRUE(TDM_ERROR_NONE == tdm_output_get_output_type(output, &type));
840                 ASSERT_NE(type, -42);
841         }
842 }
843
844 TEST_F(TDMOutput, OutputGetOutputTypeFailNullAll)
845 {
846         SKIP_FLAG(has_output);
847         ASSERT_EXIT({if (tdm_output_get_output_type(NULL, NULL) == TDM_ERROR_NONE) exit(1);
848                                  exit(0);}, ::testing::ExitedWithCode(0), "");
849 }
850
851 TEST_F(TDMOutput, OutputGetOutputTypeFailOnlyOutput)
852 {
853         SKIP_FLAG(has_output);
854         ASSERT_EXIT({for (int i = 0; i < output_count; i++) {
855                                          tdm_error error = TDM_ERROR_NONE;
856                                          tdm_output * output = tdm_display_get_output(dpy, i, &error);
857                                          if (NULL == output) exit(1);
858                                          if (TDM_ERROR_NONE != error) exit(1);
859                                          if (tdm_output_get_output_type(output, NULL) == TDM_ERROR_NONE) exit(1);
860                                 }
861                                 exit(0);}, ::testing::ExitedWithCode(0), "");
862 }
863
864 TEST_F(TDMOutput, OutputGetLayerCountSuccessful)
865 {
866         SKIP_FLAG(has_output);
867         for (int i = 0; i < output_count; i++) {
868                 tdm_error error = TDM_ERROR_NONE;
869                 int count = -42;
870                 tdm_output * output = tdm_display_get_output(dpy, i, &error);
871                 ASSERT_FALSE(NULL == output);
872                 ASSERT_TRUE(TDM_ERROR_NONE == error);
873                 ASSERT_TRUE(TDM_ERROR_NONE == tdm_output_get_layer_count(output, &count));
874                 ASSERT_NE(count, -42);
875         }
876 }
877
878 TEST_F(TDMOutputHWC, OutputGetLayerCountFailHWC)
879 {
880         SKIP_FLAG(has_output);
881         for (int i = 0; i < output_count; i++) {
882                 tdm_error error = TDM_ERROR_NONE;
883                 int count = -42;
884                 tdm_output * output = tdm_display_get_output(dpy, i, &error);
885                 ASSERT_FALSE(NULL == output);
886                 ASSERT_TRUE(TDM_ERROR_NONE == error);
887                 ASSERT_TRUE(TDM_ERROR_NONE != tdm_output_get_layer_count(output, &count));
888         }
889 }
890
891 TEST_F(TDMOutputHWC, OutputGetLayerFailHWC)
892 {
893         SKIP_FLAG(has_output);
894
895         for (int i = 0; i < output_count; i++) {
896                 tdm_error error = TDM_ERROR_NONE;
897                 tdm_output * output = tdm_display_get_output(dpy, i, &error);
898                 ASSERT_FALSE(NULL == output);
899                 ASSERT_TRUE(TDM_ERROR_NONE == error);
900                 ASSERT_TRUE(nullptr == tdm_output_get_layer(output, 0, &error));
901                 ASSERT_TRUE(TDM_ERROR_NONE != error);
902         }
903 }
904
905 TEST_F(TDMOutput, OutputGetLayerCountFailNullAll)
906 {
907         SKIP_FLAG(has_output);
908         ASSERT_EXIT({if (tdm_output_get_layer_count(NULL, NULL) == TDM_ERROR_NONE) exit(1);
909                                  exit(0);}, ::testing::ExitedWithCode(0), "");
910 }
911
912 TEST_F(TDMOutput, OutputGetLayerCountFailOnlyOutput)
913 {
914         SKIP_FLAG(has_output);
915         ASSERT_EXIT({for (int i = 0; i < output_count; i++) {
916                                          tdm_error error = TDM_ERROR_NONE;
917                                          tdm_output * output = tdm_display_get_output(dpy, i, &error);
918                                          if (NULL == output) exit(1);
919                                          if (TDM_ERROR_NONE != error) exit(1);
920                                          if (TDM_ERROR_NONE == tdm_output_get_layer_count(output, NULL)) exit(1);
921                                 }
922                                 exit(0);}, ::testing::ExitedWithCode(0), "");
923 }
924
925 TEST_F(TDMOutput, OutputGetAvailablePropertiesSuccessful)
926 {
927         SKIP_FLAG(has_output);
928         for (int i = 0; i < output_count; i++) {
929                 tdm_error error = TDM_ERROR_NONE;
930                 int count = -42;
931                 const tdm_prop *tdm_prop_array = (const tdm_prop *) 0xBEAF;
932                 tdm_output * output = tdm_display_get_output(dpy, i, &error);
933                 ASSERT_FALSE(NULL == output);
934                 ASSERT_TRUE(TDM_ERROR_NONE == error);
935                 ASSERT_TRUE(TDM_ERROR_NONE == tdm_output_get_available_properties(output,
936                                                                                                                                                   &tdm_prop_array,
937                                                                                                                                                   &count));
938                 ASSERT_NE(count, -42);
939                 ASSERT_NE(tdm_prop_array, 0xBEAF);
940         }
941 }
942
943 TEST_F(TDMOutput, OutputGetAvailablePropertiesFailNullAll)
944 {
945         SKIP_FLAG(has_output);
946         ASSERT_EXIT({if (tdm_output_get_available_properties(NULL, NULL, NULL) == TDM_ERROR_NONE) exit(1);
947                                  exit(0);}, ::testing::ExitedWithCode(0), "");
948 }
949
950 TEST_F(TDMOutput, OutputGetAvailablePropertiesFailOnlyOutput)
951 {
952         SKIP_FLAG(has_output);
953         ASSERT_EXIT({for (int i = 0; i < output_count; i++) {
954                                          tdm_error error = TDM_ERROR_NONE;
955                                          tdm_output * output = tdm_display_get_output(dpy, i, &error);
956                                          if (NULL == output) exit(1);
957                                          if (TDM_ERROR_NONE != error) exit(1);
958                                          if (TDM_ERROR_NONE == tdm_output_get_available_properties(output, NULL, NULL)) exit(1);
959                                 }
960                                 exit(0);}, ::testing::ExitedWithCode(0), "");
961 }
962
963 TEST_F(TDMOutput, OutputGetAvailablePropertiesFailNullCount)
964 {
965         SKIP_FLAG(has_output);
966         ASSERT_EXIT({for (int i = 0; i < output_count; i++) {
967                                          tdm_error error = TDM_ERROR_NONE;
968                                          const tdm_prop *tdm_prop_array = NULL;
969                                          tdm_output * output = tdm_display_get_output(dpy, i, &error);
970                                          if (NULL == output) exit(1);
971                                          if (TDM_ERROR_NONE != error) exit(1);
972                                          if (TDM_ERROR_NONE == tdm_output_get_available_properties(output,
973                                                                                                                                                            &tdm_prop_array,
974                                                                                                                                                            NULL)) exit(1);
975                                 }
976                                 exit(0);}, ::testing::ExitedWithCode(0), "");
977 }
978
979 TEST_F(TDMOutput, OutputGetAvailablePropertiesFailNullProperty)
980 {
981         SKIP_FLAG(has_output);
982         ASSERT_EXIT({for (int i = 0; i < output_count; i++) {
983                                          tdm_error error = TDM_ERROR_NONE;
984                                          int count = -42;
985                                          tdm_output * output = tdm_display_get_output(dpy, i, &error);
986                                          if (NULL == output) exit(1);
987                                          if (TDM_ERROR_NONE != error) exit(1);
988                                          if (TDM_ERROR_NONE == tdm_output_get_available_properties(output,
989                                                                                                                                                            NULL,
990                                                                                                                                                            &count)) exit(1);
991                                 }
992                                 exit(0);}, ::testing::ExitedWithCode(0), "");
993 }
994
995 TEST_F(TDMOutput, OutputGetAvailableModesSuccessful)
996 {
997         SKIP_FLAG(has_output);
998         for (int i = 0; i < output_count; i++) {
999                 tdm_error error = TDM_ERROR_NONE;
1000                 int count = -42;
1001                 const tdm_output_mode *modes_array = (const tdm_output_mode *) 0xBEAF;
1002                 tdm_output * output = tdm_display_get_output(dpy, i, &error);
1003                 ASSERT_FALSE(NULL == output);
1004                 ASSERT_TRUE(TDM_ERROR_NONE == error);
1005                 ASSERT_TRUE(TDM_ERROR_NONE == tdm_output_get_available_modes(output,
1006                                                                                                                                          &modes_array,
1007                                                                                                                                          &count));
1008                 ASSERT_NE(count, -42);
1009                 ASSERT_NE(modes_array, 0xBEAF);
1010         }
1011 }
1012
1013 TEST_F(TDMOutput, OutputGetAvailableModesFailNullAll)
1014 {
1015         SKIP_FLAG(has_output);
1016         ASSERT_EXIT({if (tdm_output_get_available_modes(NULL, NULL, NULL) == TDM_ERROR_NONE) exit(1);
1017                                  exit(0);}, ::testing::ExitedWithCode(0), "");
1018 }
1019
1020 TEST_F(TDMOutput, OutputGetAvailableModesFailOnlyOutput)
1021 {
1022         SKIP_FLAG(has_output);
1023         ASSERT_EXIT({for (int i = 0; i < output_count; i++) {
1024                                          tdm_error error = TDM_ERROR_NONE;
1025                                          tdm_output * output = tdm_display_get_output(dpy, i, &error);
1026                                          if (NULL == output) exit(1);
1027                                          if (TDM_ERROR_NONE != error) exit(1);
1028                                          if (TDM_ERROR_NONE == tdm_output_get_available_modes(output, NULL, NULL)) exit(1);
1029                                 }
1030                                 exit(0);}, ::testing::ExitedWithCode(0), "");
1031 }
1032
1033 TEST_F(TDMOutput, OutputGetAvailableModesFailNullCount)
1034 {
1035         SKIP_FLAG(has_output);
1036         ASSERT_EXIT({for (int i = 0; i < output_count; i++) {
1037                                          tdm_error error = TDM_ERROR_NONE;
1038                                          const tdm_output_mode *modes_array = NULL;
1039                                          tdm_output * output = tdm_display_get_output(dpy, i, &error);
1040                                          if (NULL == output) exit(1);
1041                                          if (TDM_ERROR_NONE != error) exit(1);
1042                                          if (TDM_ERROR_NONE == tdm_output_get_available_modes(output,
1043                                                                                                                                                   &modes_array,
1044                                                                                                                                                   NULL)) exit(1);
1045                                 }
1046                                 exit(0);}, ::testing::ExitedWithCode(0), "");
1047 }
1048
1049 TEST_F(TDMOutput, OutputGetAvailableModesFailNullModes)
1050 {
1051         SKIP_FLAG(has_output);
1052         ASSERT_EXIT({for (int i = 0; i < output_count; i++) {
1053                                          tdm_error error = TDM_ERROR_NONE;
1054                                          int count = -42;
1055                                          tdm_output * output = tdm_display_get_output(dpy, i, &error);
1056                                          if (NULL == output) exit(1);
1057                                          if (TDM_ERROR_NONE != error) exit(1);
1058                                          if (TDM_ERROR_NONE == tdm_output_get_available_modes(output,
1059                                                                                                                                                   NULL,
1060                                                                                                                                                   &count)) exit(1);
1061                                 }
1062                                 exit(0);}, ::testing::ExitedWithCode(0), "");
1063 }
1064
1065 TEST_F(TDMOutput, OutputGetAvailableSizeSuccessful)
1066 {
1067         SKIP_FLAG(has_output);
1068         for (int i = 0; i < output_count; i++) {
1069                 tdm_error error = TDM_ERROR_NONE;
1070                 int min_w = -42, min_h = -42, max_w = -42, max_h = -42, preferred_align = -42;
1071                 tdm_output * output = tdm_display_get_output(dpy, i, &error);
1072                 ASSERT_FALSE(NULL == output);
1073                 ASSERT_TRUE(TDM_ERROR_NONE == error);
1074                 ASSERT_TRUE(TDM_ERROR_NONE == tdm_output_get_available_size(output, &min_w, &min_h,
1075                                                                                                                                         &max_w, &max_h, &preferred_align));
1076                 ASSERT_NE(min_w, -42);
1077                 ASSERT_NE(min_h, -42);
1078                 ASSERT_NE(max_w, -42);
1079                 ASSERT_NE(max_h, -42);
1080                 ASSERT_NE(preferred_align, -42);
1081         }
1082 }
1083
1084 TEST_F(TDMOutput, OutputGetAvailableSizeFailNullAll)
1085 {
1086         SKIP_FLAG(has_output);
1087         ASSERT_EXIT({if (tdm_output_get_available_size(NULL, NULL, NULL,
1088                                                                                                    NULL, NULL, NULL) == TDM_ERROR_NONE) exit(1);
1089                                  exit(0);}, ::testing::ExitedWithCode(0), "");
1090 }
1091
1092 TEST_F(TDMOutput, OutputGetAvailableSizeSuccessfulOnlyOutput)
1093 {
1094         SKIP_FLAG(has_output);
1095         ASSERT_EXIT({for (int i = 0; i < output_count; i++) {
1096                                          tdm_error error = TDM_ERROR_NONE;
1097                                          tdm_output * output = tdm_display_get_output(dpy, i, &error);
1098                                          if (NULL == output) exit(1);
1099                                          if (TDM_ERROR_NONE != error) exit(1);
1100                                          if (tdm_output_get_available_size(output, NULL, NULL,
1101                                                                                                                 NULL, NULL, NULL) != TDM_ERROR_NONE) exit(1);
1102                                 }
1103                                 exit(0);}, ::testing::ExitedWithCode(0), "");
1104 }
1105
1106 TEST_F(TDMOutput, OutputGetCursorAvailableSizeSuccessful)
1107 {
1108         SKIP_FLAG(has_output);
1109         for (int i = 0; i < output_count; i++) {
1110                 tdm_error error = TDM_ERROR_NONE;
1111                 int min_w = -42, min_h = -42, max_w = -42, max_h = -42, preferred_align = -42;
1112                 tdm_output * output = tdm_display_get_output(dpy, i, &error);
1113                 ASSERT_FALSE(NULL == output);
1114                 ASSERT_TRUE(TDM_ERROR_NONE == error);
1115                 ASSERT_TRUE(TDM_ERROR_NONE == tdm_output_get_cursor_available_size(output, &min_w, &min_h,
1116                                                                                                                                                    &max_w, &max_h, &preferred_align));
1117                 ASSERT_NE(min_w, -42);
1118                 ASSERT_NE(min_h, -42);
1119                 ASSERT_NE(max_w, -42);
1120                 ASSERT_NE(max_h, -42);
1121                 ASSERT_NE(preferred_align, -42);
1122         }
1123 }
1124
1125 TEST_F(TDMOutput, OutputGetCursorAvailableSizeFailNullAll)
1126 {
1127         SKIP_FLAG(has_output);
1128         ASSERT_EXIT({if (tdm_output_get_cursor_available_size(NULL, NULL, NULL,
1129                                                                                                                   NULL, NULL, NULL) == TDM_ERROR_NONE) exit(1);
1130                                  exit(0);}, ::testing::ExitedWithCode(0), "");
1131 }
1132
1133 TEST_F(TDMOutput, OutputGetCursorAvailableSizeSuccessfulOnlyOutput)
1134 {
1135         SKIP_FLAG(has_output);
1136         ASSERT_EXIT({for (int i = 0; i < output_count; i++) {
1137                                          tdm_error error = TDM_ERROR_NONE;
1138                                          tdm_output * output = tdm_display_get_output(dpy, i, &error);
1139                                          if (NULL == output) exit(1);
1140                                          if (TDM_ERROR_NONE != error) exit(1);
1141                                          if (tdm_output_get_cursor_available_size(output, NULL, NULL,
1142                                                                                                                           NULL, NULL, NULL) != TDM_ERROR_NONE) exit(1);
1143                                 }
1144                                 exit(0);}, ::testing::ExitedWithCode(0), "");
1145 }
1146
1147 TEST_F(TDMOutput, OutputGetPhysicalSizeSuccessful)
1148 {
1149         SKIP_FLAG(has_output);
1150         for (int i = 0; i < output_count; i++) {
1151                 tdm_error error = TDM_ERROR_NONE;
1152                 unsigned int mmWidth = UINT_MAX, mmHeight = UINT_MAX;
1153                 tdm_output * output = tdm_display_get_output(dpy, i, &error);
1154                 ASSERT_FALSE(NULL == output);
1155                 ASSERT_TRUE(TDM_ERROR_NONE == error);
1156                 ASSERT_TRUE(TDM_ERROR_NONE == tdm_output_get_physical_size(output, &mmWidth, &mmHeight));
1157                 ASSERT_NE(mmWidth, UINT_MAX);
1158                 ASSERT_NE(mmHeight, UINT_MAX);
1159         }
1160 }
1161
1162 TEST_F(TDMOutput, OutputGetPhysicalSizeFailNullAll)
1163 {
1164         SKIP_FLAG(has_output);
1165         ASSERT_EXIT({if (tdm_output_get_physical_size(NULL, NULL, NULL) == TDM_ERROR_NONE) exit(1);
1166                                  exit(0);}, ::testing::ExitedWithCode(0), "");
1167 }
1168
1169 TEST_F(TDMOutput, OutputGetPhysicalSuccessfulOnlyOutput)
1170 {
1171         SKIP_FLAG(has_output);
1172         ASSERT_EXIT({for (int i = 0; i < output_count; i++) {
1173                                          tdm_error error = TDM_ERROR_NONE;
1174                                          tdm_output * output = tdm_display_get_output(dpy, i, &error);
1175                                          if (NULL == output) exit(1);
1176                                          if (TDM_ERROR_NONE != error) exit(1);
1177                                          if (tdm_output_get_physical_size(output, NULL, NULL) != TDM_ERROR_NONE) exit(1);
1178                                 }
1179                                 exit(0);}, ::testing::ExitedWithCode(0), "");
1180 }
1181
1182 TEST_F(TDMOutput, OutputGetSubpixelSuccessful)
1183 {
1184         SKIP_FLAG(has_output);
1185         for (int i = 0; i < output_count; i++) {
1186                 tdm_error error = TDM_ERROR_NONE;
1187                 unsigned int subpixel = UINT_MAX;
1188                 tdm_output * output = tdm_display_get_output(dpy, i, &error);
1189                 ASSERT_FALSE(NULL == output);
1190                 ASSERT_TRUE(TDM_ERROR_NONE == error);
1191                 ASSERT_TRUE(TDM_ERROR_NONE == tdm_output_get_subpixel(output, &subpixel));
1192                 ASSERT_NE(subpixel, UINT_MAX);
1193         }
1194 }
1195
1196 TEST_F(TDMOutput, OutputGetSubpixelFailNullAll)
1197 {
1198         SKIP_FLAG(has_output);
1199         ASSERT_EXIT({if (tdm_output_get_subpixel(NULL, NULL) == TDM_ERROR_NONE) exit(1);
1200                                  exit(0);}, ::testing::ExitedWithCode(0), "");
1201 }
1202
1203 TEST_F(TDMOutput, OutputGetSubpixelFailOnlyOutput)
1204 {
1205         SKIP_FLAG(has_output);
1206         ASSERT_EXIT({for (int i = 0; i < output_count; i++) {
1207                                          tdm_error error = TDM_ERROR_NONE;
1208                                          tdm_output * output = tdm_display_get_output(dpy, i, &error);
1209                                          if (NULL == output) exit(1);
1210                                          if (TDM_ERROR_NONE != error) exit(1);
1211                                          if (tdm_output_get_subpixel(output, NULL) == TDM_ERROR_NONE) exit(1);
1212                                 }
1213                                 exit(0);}, ::testing::ExitedWithCode(0), "");
1214 }
1215
1216 TEST_F(TDMOutput, OutputGetPipeSuccessful)
1217 {
1218         SKIP_FLAG(has_output);
1219         for (int i = 0; i < output_count; i++) {
1220                 tdm_error error = TDM_ERROR_NONE;
1221                 unsigned int pipe = UINT_MAX;
1222                 tdm_output * output = tdm_display_get_output(dpy, i, &error);
1223                 ASSERT_FALSE(NULL == output);
1224                 ASSERT_TRUE(TDM_ERROR_NONE == error);
1225                 ASSERT_TRUE(TDM_ERROR_NONE == tdm_output_get_pipe(output, &pipe));
1226                 ASSERT_NE(pipe, UINT_MAX);
1227         }
1228 }
1229
1230 TEST_F(TDMOutput, OutputGetPipeFailNullAll)
1231 {
1232         SKIP_FLAG(has_output);
1233         ASSERT_EXIT({if (tdm_output_get_pipe(NULL, NULL) == TDM_ERROR_NONE) exit(1);
1234                                  exit(0);}, ::testing::ExitedWithCode(0), "");
1235 }
1236
1237 TEST_F(TDMOutput, OutputGetPipeFailOnlyOutput)
1238 {
1239         SKIP_FLAG(has_output);
1240         ASSERT_EXIT({for (int i = 0; i < output_count; i++) {
1241                                          tdm_error error = TDM_ERROR_NONE;
1242                                          tdm_output * output = tdm_display_get_output(dpy, i, &error);
1243                                          if (NULL == output) exit(1);
1244                                          if (TDM_ERROR_NONE != error) exit(1);
1245                                          if (tdm_output_get_pipe(output, NULL) == TDM_ERROR_NONE) exit(1);
1246                                 }
1247                                 exit(0);}, ::testing::ExitedWithCode(0), "");
1248 }
1249
1250 TEST_F(TDMOutput, OutputGetPrimaryIndexSuccessful)
1251 {
1252         SKIP_FLAG(has_output);
1253         for (int i = 0; i < output_count; i++) {
1254                 tdm_error error = TDM_ERROR_NONE;
1255                 int primary_index = INT_MAX;
1256                 tdm_output * output = tdm_display_get_output(dpy, i, &error);
1257                 ASSERT_FALSE(NULL == output);
1258                 ASSERT_TRUE(TDM_ERROR_NONE == error);
1259                 ASSERT_TRUE(TDM_ERROR_NONE == tdm_output_get_primary_index(output, &primary_index));
1260                 ASSERT_NE(primary_index, INT_MAX);
1261         }
1262 }
1263
1264 TEST_F(TDMOutput, OutputGetPrimaryIndexFailNullAll)
1265 {
1266         SKIP_FLAG(has_output);
1267         ASSERT_EXIT({if (tdm_output_get_primary_index(NULL, NULL) == TDM_ERROR_NONE) exit(1);
1268                                  exit(0);}, ::testing::ExitedWithCode(0), "");
1269 }
1270
1271 TEST_F(TDMOutput, OutputGetPrimaryIndexFailOnlyOutput)
1272 {
1273         SKIP_FLAG(has_output);
1274         ASSERT_EXIT({for (int i = 0; i < output_count; i++) {
1275                                          tdm_error error = TDM_ERROR_NONE;
1276                                          tdm_output * output = tdm_display_get_output(dpy, i, &error);
1277                                          if (NULL == output) exit(1);
1278                                          if (TDM_ERROR_NONE != error) exit(1);
1279                                          if (tdm_output_get_primary_index(output, NULL) == TDM_ERROR_NONE) exit(1);
1280                                 }
1281                                 exit(0);}, ::testing::ExitedWithCode(0), "");
1282 }
1283
1284 TEST_F(TDMOutput, OutputSetPropertySuccessful)
1285 {
1286         SKIP_FLAG(has_output);
1287         for (int i = 0; i < output_count; i++) {
1288                 tdm_error error = TDM_ERROR_NONE;
1289                 tdm_value value = {.u32 = 0};
1290                 tdm_output * output = tdm_display_get_output(dpy, i, &error);
1291                 ASSERT_FALSE(NULL == output);
1292                 ASSERT_TRUE(TDM_ERROR_NONE == error);
1293                 error = tdm_output_set_property(output, UINT_MAX, value);
1294                 ASSERT_TRUE(error == TDM_ERROR_NOT_IMPLEMENTED || error == TDM_ERROR_OPERATION_FAILED);
1295         }
1296 }
1297
1298 TEST_F(TDMOutput, OutputSetPropertyFailNullAll)
1299 {
1300         SKIP_FLAG(has_output);
1301         ASSERT_EXIT({tdm_error error = TDM_ERROR_NONE;
1302                                  tdm_value value = {.u32 = 0};
1303                                  error = tdm_output_set_property(NULL, 0, value);
1304                                  if (error == TDM_ERROR_NONE || error == TDM_ERROR_NOT_IMPLEMENTED ||
1305                                         error == TDM_ERROR_OPERATION_FAILED) exit(1);
1306                                  exit(0);}, ::testing::ExitedWithCode(0), "");
1307 }
1308
1309 TEST_F(TDMOutput, OutputGetPropertySuccessful)
1310 {
1311         SKIP_FLAG(has_output);
1312         for (int i = 0; i < output_count; i++) {
1313                 tdm_error error = TDM_ERROR_NONE;
1314                 tdm_value value = {.u32 = 0};
1315                 tdm_output * output = tdm_display_get_output(dpy, i, &error);
1316                 ASSERT_FALSE(NULL == output);
1317                 ASSERT_TRUE(TDM_ERROR_NONE == error);
1318                 error = tdm_output_get_property(output, UINT_MAX, &value);
1319                 ASSERT_TRUE(error == TDM_ERROR_NOT_IMPLEMENTED || error == TDM_ERROR_OPERATION_FAILED);
1320         }
1321 }
1322
1323 TEST_F(TDMOutput, OutputGetPropertyFailNullAll)
1324 {
1325         SKIP_FLAG(has_output);
1326         ASSERT_EXIT({tdm_error error = TDM_ERROR_NONE;
1327                                  error = tdm_output_get_property(NULL, 0, NULL);
1328                                  if (error == TDM_ERROR_NONE || error == TDM_ERROR_NOT_IMPLEMENTED ||
1329                                          error == TDM_ERROR_OPERATION_FAILED) exit(1);
1330                                  exit(0);}, ::testing::ExitedWithCode(0), "");
1331 }
1332
1333 TEST_F(TDMOutputCommit, OutputCommitFailNullAll)
1334 {
1335         SKIP_FLAG(has_output);
1336
1337         ASSERT_TRUE(TDM_ERROR_NONE != tdm_output_commit(NULL, 0, NULL, NULL));
1338 }
1339
1340 TEST_F(TDMOutputCommit, OutputCommit)
1341 {
1342         SKIP_FLAG(has_output);
1343
1344         ASSERT_NO_FATAL_FAILURE(UtPrepareToCommit());
1345
1346         for (int i = 0; i < conn_output_count; i++)
1347                 ASSERT_TRUE(TDM_ERROR_NONE == tdm_output_commit(connected_output_array[i], 0, UtOutputCommitHandler, NULL));
1348
1349         UtHandleCommitEvent();
1350
1351         ASSERT_EQ(conn_output_count, utOutputCommitHandlerCounter);
1352 }
1353
1354 TEST_F(TDMOutputCommitThread, OutputCommit)
1355 {
1356         SKIP_FLAG(has_output);
1357
1358         ASSERT_NO_FATAL_FAILURE(UtPrepareToCommit());
1359
1360         for (int i = 0; i < conn_output_count; i++)
1361                 ASSERT_TRUE(TDM_ERROR_NONE == tdm_output_commit(connected_output_array[i], 0, UtOutputCommitHandler, NULL));
1362
1363         UtHandleCommitEvent();
1364
1365         ASSERT_EQ(conn_output_count, utOutputCommitHandlerCounter);
1366 }
1367
1368 TEST_F(TDMOutputCommitPerVblankEnabled, OutputCommitFailLayerCommit)
1369 {
1370         SKIP_FLAG(has_output);
1371
1372         ASSERT_NO_FATAL_FAILURE(UtPrepareToCommit());
1373
1374         for (size_t i = 0; i < layers_array.size(); ++i) {
1375                 for (tdm_layer *layer : layers_array[i]) {
1376                         tdm_layer_commit(layer, NULL, NULL);
1377                 }
1378         }
1379
1380         for (int i = 0; i < conn_output_count; i++)
1381                 ASSERT_TRUE(TDM_ERROR_NONE != tdm_output_commit(connected_output_array[i], 0, UtOutputCommitHandler, NULL));
1382 }
1383
1384 TEST_F(TDMOutputCommitPerVblankEnabled, OutputCommitFailCommitPerVblankEnabled)
1385 {
1386         SKIP_FLAG(has_output);
1387
1388         ASSERT_NO_FATAL_FAILURE(UtPrepareToCommit());
1389
1390         for (int i = 0; i < conn_output_count; i++)
1391                 ASSERT_TRUE(TDM_ERROR_NONE != tdm_output_commit(connected_output_array[i], 0, UtOutputCommitHandler, NULL));
1392 }
1393
1394 TEST_F(TDMOutputCommit, OutputCommitFailDpmsOff)
1395 {
1396         SKIP_FLAG(has_output);
1397
1398         ASSERT_NO_FATAL_FAILURE(UtPrepareToCommit());
1399
1400         for (int i = 0; i < conn_output_count; i++) {
1401                 ASSERT_TRUE(TDM_ERROR_NONE == tdm_output_set_dpms(connected_output_array[i], TDM_OUTPUT_DPMS_OFF));
1402
1403                 ASSERT_TRUE(TDM_ERROR_NONE != tdm_output_commit(connected_output_array[i], 0, UtOutputCommitHandler, NULL));
1404         }
1405 }
1406
1407 TEST_F(TDMOutputCommit, OutputWaitVBlankFailNullAll)
1408 {
1409         SKIP_FLAG(has_output);
1410
1411         ASSERT_TRUE(TDM_ERROR_NONE != tdm_output_wait_vblank(nullptr, 1, 0, nullptr, nullptr));
1412 }
1413
1414 TEST_F(TDMOutputCommit, OutputWaitVBlankFailDpmsOff)
1415 {
1416         SKIP_FLAG(has_output);
1417
1418         ASSERT_NO_FATAL_FAILURE(UtPrepareToCommit());
1419
1420         for (int i = 0; i < conn_output_count; i++) {
1421                 ASSERT_TRUE(TDM_ERROR_NONE == tdm_output_set_dpms(connected_output_array[i], TDM_OUTPUT_DPMS_OFF));
1422
1423                 for (int i = 0; i < conn_output_count; i++)
1424                         ASSERT_TRUE(TDM_ERROR_NONE != tdm_output_wait_vblank(connected_output_array[i], 1, 0, UtOutputVblankHandler, nullptr));
1425         }
1426 }
1427
1428 TEST_F(TDMOutputCommit, OutputWaitVBlank)
1429 {
1430         SKIP_FLAG(has_output);
1431
1432         ASSERT_NO_FATAL_FAILURE(UtPrepareToCommit());
1433
1434         for (int i = 0; i < conn_output_count; i++)
1435                 ASSERT_TRUE(TDM_ERROR_NONE == tdm_output_commit(connected_output_array[i], 0, UtOutputCommitHandler, nullptr));
1436
1437         UtHandleCommitEvent();
1438
1439         ASSERT_EQ(conn_output_count, utOutputCommitHandlerCounter);
1440
1441         for (int i = 0; i < conn_output_count; i++)
1442                 ASSERT_TRUE(TDM_ERROR_NONE == tdm_output_wait_vblank(connected_output_array[i], 1, 0, UtOutputVblankHandler, nullptr));
1443
1444         UtHandleVblankEvent();
1445
1446         ASSERT_EQ(conn_output_count, utOutputVblankHandlerCounter);
1447 }
1448
1449 TEST_F(TDMOutputCommitThread, OutputWaitVBlank)
1450 {
1451         SKIP_FLAG(has_output);
1452
1453         ASSERT_NO_FATAL_FAILURE(UtPrepareToCommit());
1454
1455         for (int i = 0; i < conn_output_count; i++)
1456                 ASSERT_TRUE(TDM_ERROR_NONE == tdm_output_commit(connected_output_array[i], 0, UtOutputCommitHandler, NULL));
1457
1458         UtHandleCommitEvent();
1459
1460         ASSERT_EQ(conn_output_count, utOutputCommitHandlerCounter);
1461
1462         for (int i = 0; i < conn_output_count; i++)
1463                 ASSERT_TRUE(TDM_ERROR_NONE == tdm_output_wait_vblank(connected_output_array[i], 1, 0, UtOutputVblankHandler, NULL));
1464
1465         UtHandleVblankEvent();
1466
1467         ASSERT_EQ(conn_output_count, utOutputVblankHandlerCounter);
1468 }
1469
1470 TEST_F(TDMOutputCommit, OutputRemoveVblankHandlerFailNullAll)
1471 {
1472         SKIP_FLAG(has_output);
1473
1474         ASSERT_TRUE(TDM_ERROR_NONE != tdm_output_remove_vblank_handler(nullptr, nullptr, nullptr));
1475 }
1476
1477 TEST_F(TDMOutputCommitThread, OutputRemoveVblankHandlerSuccess)
1478 {
1479         SKIP_FLAG(has_output);
1480
1481         ASSERT_NO_FATAL_FAILURE(UtPrepareToCommit());
1482
1483         for (int i = 0; i < conn_output_count; i++)
1484                 ASSERT_TRUE(TDM_ERROR_NONE == tdm_output_commit(connected_output_array[i], 0, UtOutputCommitHandler, NULL));
1485
1486         UtHandleCommitEvent();
1487
1488         ASSERT_EQ(conn_output_count, utOutputCommitHandlerCounter);
1489
1490         for (int i = 0; i < conn_output_count; i++)
1491                 ASSERT_TRUE(TDM_ERROR_NONE == tdm_output_wait_vblank(connected_output_array[i], 2, 0, UtOutputVblankHandler, NULL));
1492
1493         for (int i = 0; i < conn_output_count; i++) {
1494                 ASSERT_TRUE(TDM_ERROR_NONE == tdm_output_remove_vblank_handler(connected_output_array[i], UtOutputVblankHandler, NULL));
1495         }
1496
1497         UtHandleVblankEvent();
1498
1499         ASSERT_EQ(0, utOutputVblankHandlerCounter);
1500 }
1501
1502 TEST_F(TDMOutputCommit, OutputRemoveCommitHandlerFailNullAll)
1503 {
1504         SKIP_FLAG(has_output);
1505
1506         ASSERT_TRUE(TDM_ERROR_NONE != tdm_output_remove_commit_handler(nullptr, nullptr, nullptr));
1507 }
1508
1509 TEST_F(TDMOutputCommitThread, OutputRemoveCommitHandlerSuccess)
1510 {
1511         SKIP_FLAG(has_output);
1512
1513         ASSERT_NO_FATAL_FAILURE(UtPrepareToCommit());
1514
1515         for (int i = 0; i < conn_output_count; i++)
1516                 ASSERT_TRUE(TDM_ERROR_NONE == tdm_output_commit(connected_output_array[i], 0, UtOutputCommitHandler, NULL));
1517
1518         for (int i = 0; i < conn_output_count; i++) {
1519                 ASSERT_TRUE(TDM_ERROR_NONE == tdm_output_remove_commit_handler(connected_output_array[i], UtOutputCommitHandler, NULL));
1520         }
1521
1522         UtHandleCommitEvent();
1523 }