aboutsummaryrefslogtreecommitdiff
path: root/test/base/platform/unix/EventLoopTest.cpp
blob: 3a9e32815f8e9b781ad2dd6b3e30a5f94ca397ba (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
#include "cru/base/platform/unix/EventLoop.h"

#include <catch2/catch_test_macros.hpp>

#include <poll.h>
#include <chrono>

TEST_CASE("UnixTimerFile Work", "[unix][time]") {
  using namespace cru;
  using namespace cru::platform::unix;

  auto test_miliseconds = 300;
  auto test_duration = std::chrono::milliseconds(test_miliseconds);
  auto start = std::chrono::steady_clock::now();
  REQUIRE((std::chrono::steady_clock::now() - start) < test_duration);

  UnixTimerFile timer(test_duration);

  struct pollfd fds[1];
  fds[0].fd = timer.GetReadFd();
  fds[0].events = POLLIN;
  REQUIRE(::poll(fds, 1, test_miliseconds * 2) == 1);
  auto delay = std::chrono::steady_clock::now() - start;
  REQUIRE(delay > test_duration);
  REQUIRE(delay < std::chrono::milliseconds(500));
}

TEST_CASE("UnixEventLoop Timer Work", "[unix][time]") {
  using namespace cru;
  using namespace cru::platform::unix;

  UnixEventLoop loop;

  auto test_miliseconds = 300;
  auto test_duration = std::chrono::milliseconds(test_miliseconds);
  auto start = std::chrono::steady_clock::now();

  auto test_pipe = OpenUniDirectionalPipe();

  int counter = 0;

  loop.SetTimeout(
      [test_duration, start] {
        auto delay = std::chrono::steady_clock::now() - start;
        REQUIRE(delay > test_duration);
        REQUIRE(delay < std::chrono::milliseconds(500));
      },
      test_duration);

  int timer_id;
  timer_id = loop.SetInterval(
      [&loop, timer_id, test_duration, start, &counter] {
        switch (counter) {
          case 0: {
            auto delay = std::chrono::steady_clock::now() - start;
            REQUIRE(delay > test_duration);
            REQUIRE(delay < std::chrono::milliseconds(500));
            counter++;
            break;
          }
          case 1: {
            auto delay = std::chrono::steady_clock::now() - start;
            REQUIRE(delay > test_duration * 2);
            REQUIRE(delay < std::chrono::milliseconds(1000));
            counter++;
            break;
          }
          default: {
            loop.CancelTimer(timer_id);
            loop.RequestQuit();
            break;
          }
        }
      },
      test_duration);

  auto exit_code = loop.Run();
  REQUIRE(exit_code == 0);
  REQUIRE(counter == 2);
}

TEST_CASE("UnixEventLoop Poll Work", "[unix][time]") {
  using namespace cru;
  using namespace cru::platform::unix;

  UnixEventLoop loop;

  auto test_pipe = OpenUniDirectionalPipe();

  bool triggered = false;

  loop.SetPoll(test_pipe.read, POLLIN, [&loop, &triggered](auto revent) {
    REQUIRE(revent & POLLIN);
    REQUIRE(!triggered);
    triggered = true;
    loop.RequestQuit();
  });

  loop.SetTimeout(
      [&test_pipe] {
        auto buffer = "";
        test_pipe.write.Write(buffer, 1);
      },
      std::chrono::milliseconds(300));

  auto exit_code = loop.Run();

  REQUIRE(exit_code == 0);
  REQUIRE(triggered);
}