utest: check the return value.
[platform/core/uifw/libtdm.git] / utests / src / ut_tdm_client.cpp
1 /**************************************************************************
2  *
3  * Copyright 2017 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  * Contact: Sergey Sizonov <s.sizonov@samsung.com>
9  *
10  * Permission is hereby granted, free of charge, to any person obtaining a
11  * copy of this software and associated documentation files (the
12  * "Software"), to deal in the Software without restriction, including
13  * without limitation the rights to use, copy, modify, merge, publish,
14  * distribute, sub license, and/or sell copies of the Software, and to
15  * permit persons to whom the Software is furnished to do so, subject to
16  * the following conditions:
17  *
18  * The above copyright notice and this permission notice (including the
19  * next paragraph) shall be included in all copies or substantial portions
20  * of the Software.
21  *
22  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
23  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
24  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
25  * IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
26  * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
27  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
28  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
29  *
30 **************************************************************************/
31
32 #include "gtest/gtest.h"
33 #include "ut_common.h"
34
35 #include <cstring>
36
37 #include <sys/eventfd.h>
38 #include <unistd.h>
39 #include <fcntl.h>
40 #include <semaphore.h>
41 #include <sys/signalfd.h>
42 #include <poll.h>
43 #include <sys/prctl.h>
44 #include <sys/socket.h>
45 #include <sys/timerfd.h>
46
47 extern "C"
48 {
49 #include "tdm.h"
50 #include "tdm_client.h"
51
52 #include "tbm_surface.h"
53
54 #include "wayland-client.h"
55 }
56
57 class tdm_client_test_prepare
58 {
59 public:
60         tdm_client_test_prepare()
61         {
62                 /* we have to deal with a named semaphore to protect an access to tdm across several instances
63                  * of servers */
64                 semaphore = sem_open(semaphore_name.c_str(), O_CREAT | O_EXCL | O_RDWR, S_IRUSR | S_IWUSR, 1);
65                 if (semaphore == SEM_FAILED)
66                 {
67                         if (errno == EEXIST)
68                                 sem_unlink(semaphore_name.c_str());
69                         else
70                         {
71                                 std::cout << "can't create semaphore(1): " << semaphore_name << ", errno: " << errno << ".\n";
72                                 exit(EXIT_FAILURE);
73                         }
74                 } else {
75                         return;
76                 }
77
78                 semaphore = sem_open(semaphore_name.c_str(), O_CREAT | O_EXCL | O_RDWR, S_IRUSR | S_IWUSR, 1);
79                 if (semaphore == SEM_FAILED)
80                 {
81                         std::cout << "can't create semaphore(2): " << semaphore_name << ", errno: " << errno << ".\n";
82                         exit(EXIT_FAILURE);
83                 }
84         }
85
86         ~tdm_client_test_prepare()
87         {
88                 sem_close(semaphore);
89                 sem_unlink(semaphore_name.c_str());
90         }
91
92         static sem_t *semaphore;
93
94         /* /dev/shm/sem.tdm-client-utests */
95         static const std::string semaphore_name;
96 };
97
98 sem_t *tdm_client_test_prepare::semaphore;
99 const std::string tdm_client_test_prepare::semaphore_name = "/tdm-client-utests";
100
101 /* global object is created before main() */
102 tdm_client_test_prepare dont_use_it;
103
104 /* real mess, sorry... */
105 class TDMClientTest : public ::testing::Test
106 {
107 protected:
108         TDMClientTest() : error(TDM_ERROR_NONE), server_pid(0),
109                 dsp(nullptr), output(nullptr), layer(nullptr), buffer(nullptr), is_server_stopped(false)
110         {
111                 set_env_vars();
112                 start_server(); /* as a separate process */
113                 wait_till_server_ready();
114         }
115
116         ~TDMClientTest()
117         {
118                 stop_server();
119                 unset_env_vars();
120         }
121
122         void send_request_to_server(int req)
123         {
124                 switch(req)
125                 {
126                         case ChangeDPMS:
127                                 send_request(ChangeDPMS);
128                         break;
129
130                         default:
131                         break;
132                 }
133         }
134
135         /* to stop server by user demand */
136         void stop_server(void)
137         {
138                 _stop_server();
139                 wait_till_serv_is_over();
140
141                 /* TODO: maybe it makes a sense to use this approach in the dtor too */
142         }
143
144         enum
145         {
146                 ChangeDPMS,
147         };
148
149 private:
150         void set_env_vars(void)
151         {
152                 setenv("XDG_RUNTIME_DIR", "/run", 1);
153                 setenv("TBM_DISPLAY_SERVER", "1", 1);
154         }
155
156         void unset_env_vars(void)
157         {
158                 unsetenv("TBM_DISPLAY_SERVER");
159                 unsetenv("XDG_RUNTIME_DIR");
160         }
161
162         void start_server(void)
163         {
164                 cl_serv_lock_fd = eventfd(0, 0);
165                 socketpair(AF_UNIX, SOCK_STREAM, 0, reinterpret_cast<int*>(&socks_pair));
166
167                 server_pid = fork();
168
169                 if (server_pid)
170                 {
171                         close(socks_pair.server_socket);
172                         return;
173                 }
174
175                 close(socks_pair.client_socket);
176
177                 wait_till_serv_resources_available();
178                 run_server();
179         }
180
181         void _stop_server(void)
182         {
183                 if (is_server_stopped) return;
184
185                 close(socks_pair.client_socket);
186                 close(cl_serv_lock_fd);
187                 kill(server_pid, SIGINT);
188
189                 is_server_stopped = true;
190         }
191
192         void wait_till_server_ready(void)
193         {
194                 uint64_t val;
195
196                 if (read(cl_serv_lock_fd, &val, sizeof val) < 0)
197                         std::cout << "error while trying to read from cl_serv_lock_fd eventfd object.\n";
198         }
199
200         void notify_server_ready(void)
201         {
202                 uint64_t val;
203
204                 val = 1;
205
206                 if (write(cl_serv_lock_fd, &val, sizeof val) < 0)
207                         std::cout << "error while trying to write to cl_serv_lock_fd evenfd object.\n";
208         }
209
210         void wait_till_serv_resources_available(void)
211         {
212                 while (1)
213                 {
214                         int ret;
215
216                         ret = sem_wait(tdm_client_test_prepare::semaphore);
217                         if (ret < 0 && errno == EINTR)
218                                 continue;
219                         else
220                                 break;
221                 }
222         }
223
224         void notify_serv_resources_available(void)
225         {
226                 sem_post(tdm_client_test_prepare::semaphore);
227
228                 sem_close(tdm_client_test_prepare::semaphore);
229                 sem_unlink(tdm_client_test_prepare::semaphore_name.c_str());
230         }
231
232         void wait_till_serv_is_over(void)
233         {
234                 wait_till_serv_resources_available();
235                 sem_post(tdm_client_test_prepare::semaphore);
236         }
237
238         void send_request(int req)
239         {
240                 int count;
241
242                 count = send(socks_pair.client_socket, &req, sizeof req, 0);
243
244                 if (count != sizeof req)
245                         std::cout << "error while trying to send request to socks_pair.client_socket.\n";
246         }
247
248         void handle_client_request()
249         {
250                 int req;
251                 int count;
252
253                 count = recv(socks_pair.server_socket, &req, sizeof req, 0);
254
255                 if (count != sizeof req) {
256                         std::cout << "error while trying to reserve data from socks_pair.server_socket.\n";
257                         return;
258                 }
259
260                 switch(req)
261                 {
262                         case ChangeDPMS:
263                                 change_dpms_request_handler();
264                         break;
265
266                         default:
267                                 break;
268                 }
269         }
270
271         void run_server(void)
272         {
273                 sigset_t mask;
274                 int signal_fd;
275                 int tdm_fd;
276                 pollfd work_fds[3];
277
278                 /* ask kernel to notify us about parent's die via SIGHUP signal */
279                 prctl(PR_SET_PDEATHSIG, SIGHUP);
280
281                 sigemptyset(&mask);
282                 sigaddset(&mask, SIGINT);
283                 sigaddset(&mask, SIGHUP);
284
285                 sigprocmask(SIG_BLOCK, &mask, NULL);
286
287                 signal_fd = signalfd(-1, &mask, 0);
288
289                 init_tdm();
290                 tdm_display_get_fd(dsp, &tdm_fd);
291
292                 std::memset(&work_fds, 0, sizeof work_fds);
293
294                 work_fds[0].fd = signal_fd;
295                 work_fds[0].events = POLLIN;
296
297                 work_fds[1].fd = tdm_fd;
298                 work_fds[1].events = POLLIN;
299
300                 work_fds[2].fd = socks_pair.server_socket;
301                 work_fds[2].events = POLLIN;
302
303                 notify_server_ready();
304
305                 while (1)
306                 {
307                         int ret;
308
309                         ret = poll(work_fds, 3, -1);
310                         if (ret < 0 && errno == EINTR) continue;
311
312                         if (work_fds[0].revents == POLLIN)
313                         {
314                                 signal_hndl();
315                                 exit(EXIT_SUCCESS);
316                         }
317
318                         if(work_fds[1].revents == POLLIN)
319                                 tdm_display_handle_events(dsp);
320
321                         if(work_fds[2].revents == POLLIN)
322                                 handle_client_request();
323                 }
324         }
325
326         void signal_hndl(void)
327         {
328                 close(socks_pair.server_socket);
329                 close(cl_serv_lock_fd);
330
331                 deinit_tdm();
332                 notify_serv_resources_available();
333         }
334
335         void init_tdm(void);
336         void deinit_tdm(void);
337
338         void set_layer_geometry(int w, int h);
339         void set_image_on_screen(int w, int h);
340
341         void change_dpms_request_handler(void);
342
343         struct sockets_pair
344         {
345                 sockets_pair() : server_socket(0), client_socket(0) {}
346                 int server_socket;
347                 int client_socket;
348         };
349
350 protected:
351         tdm_error error;
352
353 private:
354         pid_t server_pid;
355         int cl_serv_lock_fd;
356         sockets_pair socks_pair;
357
358         tdm_display *dsp;
359         tdm_output *output;
360         tdm_layer *layer;
361
362         tbm_surface_h buffer;
363
364         bool is_server_stopped;
365 };
366
367 class TDMClientTestClient : public TDMClientTest
368 {
369 protected:
370         TDMClientTestClient() : TDMClientTest()
371         {
372                 tdm_cl = tdm_client_create(nullptr);
373         }
374         ~TDMClientTestClient()
375         {
376                 tdm_client_destroy(tdm_cl);
377         }
378
379 protected:
380         tdm_client *tdm_cl;
381 };
382
383 class TDMClientTestClientOutput : public TDMClientTestClient
384 {
385 protected:
386         TDMClientTestClientOutput() : TDMClientTestClient()
387         {
388                 cl_output = tdm_client_get_output(tdm_cl, const_cast<char*>("primary"), nullptr);
389         }
390         ~TDMClientTestClientOutput()
391         {
392         }
393
394 protected:
395         tdm_client_output* cl_output;
396 };
397
398 class TDMClientTestVblank : public TDMClientTestClientOutput
399 {
400 protected:
401         TDMClientTestVblank() : TDMClientTestClientOutput()
402         {
403                 cl_vblank =  tdm_client_output_create_vblank(cl_output, nullptr);
404         }
405         ~TDMClientTestVblank()
406         {
407                 tdm_client_vblank_destroy(cl_vblank);
408         }
409
410 protected:
411         tdm_client_vblank* cl_vblank;
412 };
413
414 typedef TDMClientTest TDMClientTestDeathTest;
415 typedef TDMClientTestClient TDMClientTestClientDeathTest;
416 typedef TDMClientTestClientOutput TDMClientTestClientOutputDeathTest;
417 typedef TDMClientTestVblank TDMClientTestVblankDeathTest;
418
419
420 void TDMClientTest::set_layer_geometry(int w, int h)
421 {
422         tdm_info_layer layer_info;
423
424         std::memset(&layer_info, 0, sizeof(tdm_info_layer));
425
426         layer_info.src_config.size.h = w;
427         layer_info.src_config.size.v = h;
428         layer_info.src_config.pos.x = 0;
429         layer_info.src_config.pos.y = 0;
430         layer_info.src_config.pos.w = w;
431         layer_info.src_config.pos.h = h;
432         layer_info.src_config.format = TBM_FORMAT_ARGB8888;
433         layer_info.dst_pos.x = 0;
434         layer_info.dst_pos.y = 0;
435         layer_info.dst_pos.w = w;
436         layer_info.dst_pos.h = h;
437         layer_info.transform = TDM_TRANSFORM_NORMAL;
438
439         tdm_layer_set_info(layer, &layer_info);
440 }
441
442 void TDMClientTest::set_image_on_screen(int w, int h)
443 {
444         tbm_surface_info_s tbm_surface_info;
445
446         /* to have a hw vblank we have to make at least one tdm_commit */
447         buffer = tbm_surface_create(w, h, TBM_FORMAT_ARGB8888);
448
449         std::memset(&tbm_surface_info, 0, sizeof(tbm_surface_info_s));
450
451         tbm_surface_map(buffer, TBM_SURF_OPTION_WRITE, &tbm_surface_info);
452
453         int *img = (int *)tbm_surface_info.planes[0].ptr;
454
455         for (uint32_t i = 0; i < tbm_surface_info.height; i++)
456                 for (uint32_t j = 0; j < tbm_surface_info.planes[0].stride / 4; j++)
457                         *img++ = 0x0000000;
458
459         tbm_surface_unmap(buffer);
460
461         set_layer_geometry(w, h);
462         tdm_layer_set_buffer(layer, buffer);
463         tdm_output_commit(output, 0, nullptr, nullptr);
464 }
465
466 void TDMClientTest::init_tdm(void)
467 {
468         int outputs_cnt = 0;
469         tdm_output_type tdm_output_type;
470         tdm_error error;
471
472         int output_modes_cnt = 0;
473         const tdm_output_mode* output_modes;
474         const tdm_output_mode* preferred_mode = NULL;
475
476         int layers_cnt = 0;
477         tdm_layer_capability tdm_layer_capability;
478
479         dsp = tdm_display_init(nullptr);
480
481         tdm_display_get_output_count(dsp, &outputs_cnt);
482
483         /* this part is hardware dependent, how to resolve this issue ? */
484         for (int i = 0; i < outputs_cnt; i++)
485         {
486                 output = tdm_display_get_output(dsp, i, nullptr);
487                 if (output == NULL) {
488                         std::cout << "tdm_display_get_output faild, server's gonna be stopped.\n";
489                         deinit_tdm();
490                         exit(EXIT_FAILURE);
491                 }
492                 error = tdm_output_get_output_type(output, &tdm_output_type);
493                 if (error != TDM_ERROR_NONE) {
494                         std::cout << "tdm_output_get_output_type faild, server's gonna be stopped.\n";
495                         deinit_tdm();
496                         exit(EXIT_FAILURE);
497                 }
498
499                 /* we're not interesting about other outputs */
500                 if (tdm_output_type != TDM_OUTPUT_TYPE_VIRTUAL &&
501                         tdm_output_type != TDM_OUTPUT_TYPE_HDMIA)
502                         break;
503         }
504
505         /* get output's preferred mode to obtain width & height we'll use later to create surface */
506         tdm_output_get_available_modes(output, &output_modes, &output_modes_cnt);
507
508         /* look for output's preferred mode */
509         for (int i = 0; i < output_modes_cnt; i++)
510         {
511                 if (output_modes[i].type & TDM_OUTPUT_MODE_TYPE_PREFERRED)
512                 {
513                         preferred_mode = &output_modes[i];
514                         break;
515                 }
516         }
517
518         if (!preferred_mode)
519         {
520                 std::cout << "no preferred mode, server's gonna be stopped.\n";
521
522                 deinit_tdm();
523                 exit(EXIT_FAILURE);
524         }
525
526         tdm_output_set_mode(output, preferred_mode);
527
528         tdm_output_get_layer_count(output, &layers_cnt);
529
530         /* it supposed that output always has primary & graphic layer */
531         for (int i = 0; i < layers_cnt; i++)
532         {
533                 layer = tdm_output_get_layer(output, i, nullptr);
534                 tdm_layer_get_capabilities(layer, &tdm_layer_capability);
535
536                 if ((tdm_layer_capability & TDM_LAYER_CAPABILITY_PRIMARY) &&
537                         (tdm_layer_capability & TDM_LAYER_CAPABILITY_GRAPHIC))
538                         break;
539         }
540
541         tdm_output_set_dpms(output, TDM_OUTPUT_DPMS_ON);
542
543         set_image_on_screen(preferred_mode->hdisplay, preferred_mode->vdisplay);
544 }
545
546 void TDMClientTest::deinit_tdm(void)
547 {
548         if (layer)
549         {
550                 tdm_layer_unset_buffer(layer);
551                 tdm_output_commit(output, 1, nullptr, nullptr);
552         }
553
554         if (buffer)
555                 tbm_surface_internal_unref(buffer);
556
557         if (dsp)
558                 tdm_display_deinit(dsp);
559 }
560
561 void TDMClientTest::change_dpms_request_handler(void)
562 {
563         std::cout << "tdm_output_set_dpms.\n";
564         tdm_output_set_dpms(output, TDM_OUTPUT_DPMS_OFF);
565 }
566
567 TEST_F(TDMClientTest, TdmClientCreateSuccessfulCheckClient)
568 {
569         tdm_client *tdm_cl = tdm_client_create(nullptr);
570         ASSERT_TRUE(nullptr != tdm_cl);
571
572         tdm_client_destroy(tdm_cl);
573 }
574
575 TEST_F(TDMClientTest, TdmClientCreateSuccessfulCheckError)
576 {
577         tdm_client* tdm_cl = tdm_client_create(&error);
578         ASSERT_TRUE(TDM_ERROR_NONE == error);
579
580         tdm_client_destroy(tdm_cl);
581 }
582
583 TEST_F(TDMClientTest, TdmClientCreateFailServerStoppedCheckError)
584 {
585         stop_server();
586
587         tdm_client_create(&error);
588         ASSERT_TRUE(TDM_ERROR_OPERATION_FAILED == error);
589 }
590
591 TEST_F(TDMClientTest, TdmClientCreateFailServerStopped)
592 {
593         stop_server();
594
595         tdm_client *tdm_cl = tdm_client_create(nullptr);
596         ASSERT_TRUE(nullptr == tdm_cl);
597 }
598
599 TEST_F(TDMClientTestDeathTest, TdmClientDestroySuccessful)
600 {
601         ASSERT_EXIT(
602                 {
603                         tdm_client_destroy(nullptr);
604
605                         exit(EXIT_SUCCESS);
606                 },
607                 ::testing::ExitedWithCode(EXIT_SUCCESS), "");
608 }
609
610 TEST_F(TDMClientTestDeathTest, TdmClientDestroySuccessfulServerStopped)
611 {
612         ASSERT_EXIT(
613                 {
614                         tdm_client *tdm_cl = tdm_client_create(nullptr);
615
616                         stop_server();
617
618                         tdm_client_destroy(tdm_cl);
619
620                         exit(EXIT_SUCCESS);
621                 },
622                 ::testing::ExitedWithCode(EXIT_SUCCESS), "");
623 }
624
625 TEST_F(TDMClientTestClient, TdmClientGetFdSuccessful)
626 {
627         int fd;
628
629         tdm_client_get_fd(tdm_cl, &fd);
630         ASSERT_TRUE(0 < fd);
631 }
632
633 TEST_F(TDMClientTestClient, TdmClientGetFdSuccessfulCheckError)
634 {
635         int fd;
636
637         error = tdm_client_get_fd(tdm_cl, &fd);
638         ASSERT_TRUE(TDM_ERROR_NONE == error);
639 }
640
641 TEST_F(TDMClientTestClient, TdmClientGetFdFailNullTdmClient)
642 {
643         int fd;
644
645         error = tdm_client_get_fd(nullptr, &fd);
646         ASSERT_TRUE(TDM_ERROR_INVALID_PARAMETER == error);
647 }
648
649 TEST_F(TDMClientTestClient, TdmClientGetFdFailNullFd)
650 {
651         error = tdm_client_get_fd(nullptr, nullptr);
652         ASSERT_TRUE(TDM_ERROR_INVALID_PARAMETER == error);
653 }
654
655 TEST_F(TDMClientTestClient, TdmClientHandleEventsSuccessful)
656 {
657         ASSERT_EXIT(
658         {
659                 pollfd work_fds[2];
660                 itimerspec times_up;
661
662                 std::memset(&work_fds, 0, sizeof work_fds);
663                 std::memset(&times_up, 0, sizeof times_up);
664
665                 tdm_client_get_fd(tdm_cl, &work_fds[0].fd);
666                 work_fds[0].events = POLLIN;
667
668                 work_fds[1].fd = timerfd_create(CLOCK_MONOTONIC, 0);
669                 work_fds[1].events = POLLIN;
670
671                 times_up.it_value.tv_nsec = 100000000;  /* 100ms */
672                 timerfd_settime(work_fds[1].fd, 0, &times_up, nullptr);
673
674                 while (1)
675                 {
676                         int ret;
677
678                         ret = poll(work_fds, 2, -1);
679                         if (ret < 0 && errno == EINTR) continue;
680
681                         if (work_fds[0].revents == POLLIN)
682                         {
683                                 tdm_client_handle_events(tdm_cl);
684                                 std::cout << "ha.\n";
685                         }
686
687                         if(work_fds[1].revents == POLLIN)
688                                 exit(EXIT_SUCCESS);
689                 }
690         },
691         ::testing::ExitedWithCode(EXIT_SUCCESS), "");
692 }
693
694 TEST_F(TDMClientTestClient, TdmClientHandleEventsFailNullTDMClient)
695 {
696         error = tdm_client_handle_events(nullptr);
697         ASSERT_TRUE(TDM_ERROR_INVALID_PARAMETER == error);
698 }
699
700 TEST_F(TDMClientTestClient, TdmClientGetOutputSuccessful)
701 {
702         tdm_client_output* cl_output;
703
704         cl_output = tdm_client_get_output(tdm_cl, const_cast<char*>("primary"), nullptr);
705         ASSERT_TRUE(nullptr != cl_output);
706 }
707
708 TEST_F(TDMClientTestClient, TdmClientGetOutputSuccessfulCallTwice)
709 {
710         tdm_client_output* cl_output_1, *cl_output_2;
711
712         cl_output_1 = tdm_client_get_output(tdm_cl, const_cast<char*>("primary"), nullptr);
713         cl_output_2 = tdm_client_get_output(tdm_cl, const_cast<char*>("primary"), nullptr);
714         ASSERT_TRUE(cl_output_1 == cl_output_2);
715 }
716
717 TEST_F(TDMClientTestClient, TdmClientGetOutputSuccessfulCheckError)
718 {
719         tdm_client_get_output(tdm_cl, const_cast<char*>("primary"), &error);
720         ASSERT_TRUE(TDM_ERROR_NONE == error);
721 }
722
723 TEST_F(TDMClientTestClient, TdmClientGetOutputSuccessfulNullName)
724 {
725         tdm_client_output* cl_output;
726
727         cl_output = tdm_client_get_output(tdm_cl, nullptr, nullptr);
728         ASSERT_TRUE(nullptr != cl_output);
729 }
730
731 TEST_F(TDMClientTestClient, TdmClientGetOutputSuccessfulNullNameCheckError)
732 {
733         tdm_client_get_output(tdm_cl, nullptr, &error);
734         ASSERT_TRUE(TDM_ERROR_NONE == error);
735 }
736
737 TEST_F(TDMClientTestClient, TdmClientGetOutputFailNullTdmClient)
738 {
739         tdm_client_output* cl_output;
740
741         cl_output = tdm_client_get_output(nullptr, const_cast<char*>("primary"), nullptr);
742         ASSERT_TRUE(nullptr == cl_output);
743 }
744
745 TEST_F(TDMClientTestClient, TdmClientGetOutputFailNullTdmClientCheckError)
746 {
747         tdm_client_get_output(nullptr, const_cast<char*>("primary"), &error);
748         ASSERT_TRUE(TDM_ERROR_INVALID_PARAMETER == error);
749 }
750
751 TEST_F(TDMClientTestClientOutput, TdmClientOutputAddChangeHandlerSuccessful)
752 {
753         static bool got_an_event = false;
754         wl_display *wl_dsp;
755
756         /* is this function implemented fully? */
757         tdm_client_output_add_change_handler(cl_output, [] (tdm_client_output *output,
758                                                                         tdm_output_change_type type,
759                                                                         tdm_value value,
760                                                                         void *user_data) { got_an_event = true; }, nullptr);
761
762         /* force a requests flush */
763         wl_dsp = wl_display_connect("tdm-socket");
764         ASSERT_TRUE(nullptr != wl_dsp);
765         wl_display_flush(wl_dsp);
766         wl_display_roundtrip(wl_dsp);
767         wl_display_disconnect(wl_dsp);
768
769         send_request_to_server(TDMClientTest::ChangeDPMS);
770         tdm_client_handle_events(tdm_cl);
771
772         ASSERT_TRUE(true == got_an_event);
773 }
774
775 TEST_F(TDMClientTestClientOutput, TdmClientOutputAddChangeHandlerFailNullOutput)
776 {
777         error = tdm_client_output_add_change_handler(nullptr, [] (tdm_client_output *output,
778                                                                         tdm_output_change_type type,
779                                                                         tdm_value value,
780                                                                         void *user_data) {}, nullptr);
781         ASSERT_TRUE(TDM_ERROR_INVALID_PARAMETER == error);
782 }
783
784 TEST_F(TDMClientTestClientOutput, TdmClientOutputAddChangeHandlerFailNullHandler)
785 {
786         error = tdm_client_output_add_change_handler(cl_output, nullptr, nullptr);
787         ASSERT_TRUE(TDM_ERROR_INVALID_PARAMETER == error);
788 }
789
790 TEST_F(TDMClientTestClientOutputDeathTest, TdmClientOutputRemoveChangeHandlerSuccessful)
791 {
792         ASSERT_EXIT(
793         {
794                 auto func = [] (tdm_client_output *output, tdm_output_change_type type, tdm_value value,
795                                 void *user_data) {};
796
797                 tdm_client_output_add_change_handler(cl_output, func, nullptr);
798
799                 tdm_client_output_remove_change_handler(cl_output, func, nullptr);
800
801                 exit(EXIT_SUCCESS);
802         },
803         ::testing::ExitedWithCode(EXIT_SUCCESS), "");
804 }
805
806 TEST_F(TDMClientTestClientOutputDeathTest, TdmClientOutputRemoveChangeHandlerSuccessfulInvalidHandler)
807 {
808         ASSERT_EXIT(
809         {
810                 auto func = [] (tdm_client_output *output, tdm_output_change_type type, tdm_value value,
811                                 void *user_data) {};
812
813                 tdm_client_output_remove_change_handler(cl_output, func, nullptr);
814
815                 exit(EXIT_SUCCESS);
816         },
817         ::testing::ExitedWithCode(EXIT_SUCCESS), "");
818 }
819
820 TEST_F(TDMClientTestClientOutputDeathTest, TdmClientOutputRemoveChangeHandlerFailNullOutput)
821 {
822         ASSERT_EXIT(
823         {
824                 auto func = [] (tdm_client_output *output, tdm_output_change_type type, tdm_value value,
825                                 void *user_data) {};
826
827                 tdm_client_output_remove_change_handler(nullptr, func, nullptr);
828
829                 exit(EXIT_SUCCESS);
830         },
831         ::testing::ExitedWithCode(EXIT_SUCCESS), "");
832 }
833
834 TEST_F(TDMClientTestClientOutputDeathTest, TdmClientOutputRemoveChangeHandlerFailNullHandler)
835 {
836         ASSERT_EXIT(
837         {
838                 tdm_client_output_remove_change_handler(cl_output, nullptr, nullptr);
839
840                 exit(EXIT_SUCCESS);
841         },
842         ::testing::ExitedWithCode(EXIT_SUCCESS), "");
843 }
844
845 TEST_F(TDMClientTestClientOutput, TdmClientOutputGetRefreshRateSuccessful)
846 {
847         uint32_t refresh_rate;
848
849         error = tdm_client_output_get_refresh_rate(cl_output, &refresh_rate);
850         ASSERT_TRUE(TDM_ERROR_NONE == error);
851 }
852
853 TEST_F(TDMClientTestClientOutput, TdmClientOutputGetRefreshRateFailNullOutput)
854 {
855         uint32_t refresh_rate;
856
857         error = tdm_client_output_get_refresh_rate(nullptr, &refresh_rate);
858         ASSERT_TRUE(TDM_ERROR_INVALID_PARAMETER == error);
859 }
860
861 TEST_F(TDMClientTestClientOutput, TdmClientOutputGetRefreshRateFailNullRefreshRate)
862 {
863         error = tdm_client_output_get_refresh_rate(cl_output, nullptr);
864         ASSERT_TRUE(TDM_ERROR_INVALID_PARAMETER == error);
865 }
866
867 TEST_F(TDMClientTestClientOutput, TdmClientOutputGetConnectionStatusSuccessful)
868 {
869         tdm_output_conn_status conn_status;
870
871         error = tdm_client_output_get_conn_status(cl_output, &conn_status);
872         ASSERT_TRUE(TDM_ERROR_NONE == error);
873 }
874
875 TEST_F(TDMClientTestClientOutput, TdmClientOutputGetConnectionStatusFailNullOutput)
876 {
877         tdm_output_conn_status conn_status;
878
879         error = tdm_client_output_get_conn_status(nullptr, &conn_status);
880         ASSERT_TRUE(TDM_ERROR_INVALID_PARAMETER == error);
881 }
882
883 TEST_F(TDMClientTestClientOutput, TTdmClientOutputGetConnectionStatusFailNullConnState)
884 {
885         error = tdm_client_output_get_conn_status(cl_output, nullptr);
886         ASSERT_TRUE(TDM_ERROR_INVALID_PARAMETER == error);
887 }
888
889 TEST_F(TDMClientTestClientOutput, TdmClientOutputGetDpmsSuccessful)
890 {
891         tdm_output_dpms dpms_val;
892
893         error = tdm_client_output_get_dpms(cl_output, &dpms_val);
894         ASSERT_TRUE(TDM_ERROR_NONE == error);
895 }
896
897 TEST_F(TDMClientTestClientOutput, TdmClientOutputGetDpmsFailNullOutput)
898 {
899         tdm_output_dpms dpms_val;
900
901         error = tdm_client_output_get_dpms(nullptr, &dpms_val);
902         ASSERT_TRUE(TDM_ERROR_INVALID_PARAMETER == error);
903 }
904
905 TEST_F(TDMClientTestClientOutput, TdmClientOutputGetDpmsFailNullDpmsArg)
906 {
907         error = tdm_client_output_get_dpms(cl_output, nullptr);
908         ASSERT_TRUE(TDM_ERROR_INVALID_PARAMETER == error);
909 }
910
911 TEST_F(TDMClientTestClientOutput, TdmClientOutputCreateVblankSuccessful)
912 {
913         tdm_client_vblank* cl_vblank;
914
915         cl_vblank = tdm_client_output_create_vblank(cl_output, nullptr);
916         ASSERT_TRUE(nullptr != cl_vblank);
917
918         tdm_client_vblank_destroy(cl_vblank);
919 }
920
921 TEST_F(TDMClientTestClientOutput, TdmClientOutputCreateVblankSuccessfulCheckError)
922 {
923         tdm_client_vblank* cl_vblank;
924
925         cl_vblank = tdm_client_output_create_vblank(cl_output, &error);
926         ASSERT_TRUE(TDM_ERROR_NONE == error);
927
928         tdm_client_vblank_destroy(cl_vblank);
929 }
930
931 TEST_F(TDMClientTestClientOutput, TdmClientOutputCreateVblankFailNullOutput)
932 {
933         tdm_client_vblank* cl_vblank;
934
935         cl_vblank = tdm_client_output_create_vblank(nullptr, nullptr);
936         ASSERT_TRUE(nullptr == cl_vblank);
937 }
938
939 TEST_F(TDMClientTestClientOutput, TdmClientOutputCreateVblankFailNullOutputCheckError)
940 {
941         tdm_client_output_create_vblank(nullptr, &error);
942         ASSERT_TRUE(TDM_ERROR_INVALID_PARAMETER == error);
943 }
944
945 TEST_F(TDMClientTestClientOutputDeathTest, TdmClientDestroyVblankSuccessful)
946 {
947         ASSERT_EXIT(
948         {
949                 tdm_client_vblank *cl_vblank = tdm_client_output_create_vblank(cl_output, nullptr);
950
951                 tdm_client_vblank_destroy(cl_vblank);
952                 exit(EXIT_SUCCESS);
953         },
954         ::testing::ExitedWithCode(EXIT_SUCCESS), "");
955 }
956
957 TEST_F(TDMClientTestClientOutputDeathTest, TdmClientDestroyVblankFailNoClientVblankArg)
958 {
959         ASSERT_EXIT(
960         {
961                 tdm_client_vblank_destroy(nullptr);
962                 exit(EXIT_SUCCESS);
963         },
964         ::testing::ExitedWithCode(EXIT_SUCCESS), "");
965 }
966
967 TEST_F(TDMClientTestVblank, TdmClientVblankSetNameSuccessful)
968 {
969         error = tdm_client_vblank_set_name(cl_vblank, "wassup");
970         ASSERT_TRUE(TDM_ERROR_NONE == error);
971 }
972
973 TEST_F(TDMClientTestVblank, TdmClientVblankSetNameSuccessfulNoExplicitName)
974 {
975         error = tdm_client_vblank_set_name(cl_vblank, nullptr);
976         ASSERT_TRUE(TDM_ERROR_NONE == error);
977 }
978
979 TEST_F(TDMClientTestVblank, TdmClientVblankSetNameFailNullClientVblank)
980 {
981         error = tdm_client_vblank_set_name(nullptr, "wassup");
982         ASSERT_TRUE(TDM_ERROR_INVALID_PARAMETER == error);
983 }
984
985 TEST_F(TDMClientTestVblank, TdmClientVblankSetSyncSuccessful)
986 {
987         error = tdm_client_vblank_set_sync(cl_vblank, 0);
988         ASSERT_TRUE(TDM_ERROR_NONE == error);
989 }
990
991 TEST_F(TDMClientTestVblank, TdmClientVblankSetSyncFailNullClientVblank)
992 {
993         error = tdm_client_vblank_set_sync(nullptr, 0);
994         ASSERT_TRUE(TDM_ERROR_INVALID_PARAMETER == error);
995 }
996
997 TEST_F(TDMClientTestVblank, TdmClientVblankSetFpsSuccessful)
998 {
999         error = tdm_client_vblank_set_fps(cl_vblank, 60);
1000         ASSERT_TRUE(TDM_ERROR_NONE == error);
1001 }
1002
1003 TEST_F(TDMClientTestVblank, TdmClientVblankSetFpsSuccessfulSetTwice)
1004 {
1005         tdm_client_vblank_set_fps(cl_vblank, 60);
1006         error = tdm_client_vblank_set_fps(cl_vblank, 60);
1007         ASSERT_TRUE(TDM_ERROR_NONE == error);
1008 }
1009
1010 TEST_F(TDMClientTestVblank, TdmClientVblankSetFpsFailNullClientVblank)
1011 {
1012         error = tdm_client_vblank_set_fps(nullptr, 60);
1013         ASSERT_TRUE(TDM_ERROR_INVALID_PARAMETER == error);
1014 }
1015
1016 TEST_F(TDMClientTestVblank, TdmClientVblankSetFpsFailInvalidFpsArg)
1017 {
1018         error = tdm_client_vblank_set_fps(cl_vblank, 0);
1019         ASSERT_TRUE(TDM_ERROR_INVALID_PARAMETER == error);
1020 }
1021
1022 TEST_F(TDMClientTestVblank, TdmClientVblankSetOffsetSuccessful)
1023 {
1024         error = tdm_client_vblank_set_offset(cl_vblank, 10);
1025         ASSERT_TRUE(TDM_ERROR_NONE == error);
1026 }
1027
1028 TEST_F(TDMClientTestVblank, TdmClientVblankSetOffsetSuccessfulSetTwice)
1029 {
1030         tdm_client_vblank_set_offset(cl_vblank, 10);
1031         error = tdm_client_vblank_set_offset(cl_vblank, 10);
1032         ASSERT_TRUE(TDM_ERROR_NONE == error);
1033 }
1034
1035 TEST_F(TDMClientTestVblank, TdmClientVblankSetOffsetFailNullClientVblank)
1036 {
1037         error = tdm_client_vblank_set_offset(nullptr, 10);
1038         ASSERT_TRUE(TDM_ERROR_INVALID_PARAMETER == error);
1039 }
1040
1041 TEST_F(TDMClientTestVblank, TdmClientVblankSetFakeSuccessfulEnableFake)
1042 {
1043         error = tdm_client_vblank_set_enable_fake(cl_vblank, 1);
1044         ASSERT_TRUE(TDM_ERROR_NONE == error);
1045 }
1046
1047 TEST_F(TDMClientTestVblank, TdmClientVblankSetFakeSuccessfulDisableFake)
1048 {
1049         error = tdm_client_vblank_set_enable_fake(cl_vblank, 0);
1050         ASSERT_TRUE(TDM_ERROR_NONE == error);
1051 }
1052
1053 TEST_F(TDMClientTestVblank, TdmClientVblankSetFakeSuccessfulSetTwice)
1054 {
1055         tdm_client_vblank_set_enable_fake(cl_vblank, 0);
1056         error = tdm_client_vblank_set_enable_fake(cl_vblank, 0);
1057         ASSERT_TRUE(TDM_ERROR_NONE == error);
1058 }
1059
1060 TEST_F(TDMClientTestVblank, TdmClientVblankSetFakeFailNullClientVblank)
1061 {
1062         error = tdm_client_vblank_set_enable_fake(nullptr, 0);
1063         ASSERT_TRUE(TDM_ERROR_INVALID_PARAMETER == error);
1064 }
1065
1066 TEST_F(TDMClientTestVblank, TdmClientVblankWaitSuccessful)
1067 {
1068         auto func = [](tdm_client_vblank *vblank, tdm_error error, unsigned int sequence,
1069                          unsigned int tv_sec, unsigned int tv_usec,  void *user_data) {};
1070
1071         tdm_client_vblank_set_sync(cl_vblank, 0);
1072         tdm_client_vblank_set_enable_fake(cl_vblank, 1);
1073
1074         error = tdm_client_vblank_wait(cl_vblank, 1, func, nullptr);
1075         ASSERT_TRUE(TDM_ERROR_NONE == error);
1076 }
1077
1078 TEST_F(TDMClientTestVblank, TdmClientVblankWaitFailNullClientVblank)
1079 {
1080         auto func = [](tdm_client_vblank *vblank, tdm_error error, unsigned int sequence,
1081                          unsigned int tv_sec, unsigned int tv_usec,  void *user_data) {};
1082
1083         error = tdm_client_vblank_wait(nullptr, 1, func, nullptr);
1084         ASSERT_TRUE(TDM_ERROR_INVALID_PARAMETER == error);
1085 }
1086
1087 TEST_F(TDMClientTestVblank, TdmClientVblankWaitFailNullHandler)
1088 {
1089         error = tdm_client_vblank_wait(cl_vblank, 1, nullptr, nullptr);
1090         ASSERT_TRUE(TDM_ERROR_INVALID_PARAMETER == error);
1091 }
1092
1093 TEST_F(TDMClientTestVblank, TdmClientVblankWaitFailInvalidInterval)
1094 {
1095         auto func = [](tdm_client_vblank *vblank, tdm_error error, unsigned int sequence,
1096                          unsigned int tv_sec, unsigned int tv_usec,  void *user_data) {};
1097
1098         error = tdm_client_vblank_wait(cl_vblank, 0, func, nullptr);
1099         ASSERT_TRUE(TDM_ERROR_INVALID_PARAMETER == error);
1100 }
1101
1102 TEST_F(TDMClientTestVblank, TdmClientVblankWaitSequencySuccessful)
1103 {
1104         auto func = [](tdm_client_vblank *vblank, tdm_error error, unsigned int sequence,
1105                          unsigned int tv_sec, unsigned int tv_usec,  void *user_data) {};
1106
1107         tdm_client_vblank_set_sync(cl_vblank, 0);
1108         tdm_client_vblank_set_enable_fake(cl_vblank, 1);
1109
1110         error = tdm_client_vblank_wait_seq(cl_vblank, 100, func, nullptr);
1111         ASSERT_TRUE(TDM_ERROR_NONE == error);
1112 }
1113
1114 TEST_F(TDMClientTestVblank, TdmClientVblankWaitSequencyFailNullClientVblank)
1115 {
1116         auto func = [](tdm_client_vblank *vblank, tdm_error error, unsigned int sequence,
1117                          unsigned int tv_sec, unsigned int tv_usec,  void *user_data) {};
1118
1119         error = tdm_client_vblank_wait_seq(nullptr, 1, func, nullptr);
1120         ASSERT_TRUE(TDM_ERROR_INVALID_PARAMETER == error);
1121 }
1122
1123 TEST_F(TDMClientTestVblank, TdmClientVblankWaitSequencyFailNullHandler)
1124 {
1125         error = tdm_client_vblank_wait_seq(cl_vblank, 1, nullptr, nullptr);
1126         ASSERT_TRUE(TDM_ERROR_INVALID_PARAMETER == error);
1127 }
1128