File: actor_termination.cpp

package info (click to toggle)
actor-framework 0.17.6-3.2
  • links: PTS
  • area: main
  • in suites: forky, sid
  • size: 9,008 kB
  • sloc: cpp: 77,684; sh: 674; python: 309; makefile: 13
file content (133 lines) | stat: -rw-r--r-- 4,325 bytes parent folder | download | duplicates (4)
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
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
/******************************************************************************
 *                       ____    _    _____                                   *
 *                      / ___|  / \  |  ___|    C++                           *
 *                     | |     / _ \ | |_       Actor                         *
 *                     | |___ / ___ \|  _|      Framework                     *
 *                      \____/_/   \_|_|                                      *
 *                                                                            *
 * Copyright 2011-2018 Dominik Charousset                                     *
 *                                                                            *
 * Distributed under the terms and conditions of the BSD 3-Clause License or  *
 * (at your option) under the terms and conditions of the Boost Software      *
 * License 1.0. See accompanying files LICENSE and LICENSE_ALTERNATIVE.       *
 *                                                                            *
 * If you did not receive a copy of the license files, see                    *
 * http://opensource.org/licenses/BSD-3-Clause and                            *
 * http://www.boost.org/LICENSE_1_0.txt.                                      *
 ******************************************************************************/

#include "caf/config.hpp"

// this suite tests whether actors terminate as expect in several use cases
#define CAF_SUITE actor_termination
#include "caf/test/dsl.hpp"

using namespace caf;

namespace {

behavior mirror_impl(event_based_actor* self) {
  self->set_default_handler(reflect);
  return [] {
    // nop
  };
}

struct fixture :  test_coordinator_fixture<> {
  actor mirror;
  actor testee;

  fixture() {
    mirror = sys.spawn(mirror_impl);
    // run initialization code or mirror
    sched.run_once();
  }

  template <class... Ts>
  void spawn(Ts&&... xs) {
    testee = self->spawn(std::forward<Ts>(xs)...);
  }

  ~fixture() {
    self->wait_for(testee);
  }
};

} // namespace

CAF_TEST_FIXTURE_SCOPE(actor_termination_tests, fixture)

CAF_TEST(single_multiplexed_request) {
  auto f = [&](event_based_actor* self, actor server) {
    self->request(server, infinite, 42).then(
      [=](int x) {
        CAF_REQUIRE_EQUAL(x, 42);
      }
    );
  };
  spawn(f, mirror);
  // run initialization code of testee
  sched.run_once();
  expect((int), from(testee).to(mirror).with(42));
  expect((int), from(mirror).to(testee).with(42));
}

CAF_TEST(multiple_multiplexed_requests) {
  auto f = [&](event_based_actor* self, actor server) {
    for (int i = 0; i < 3; ++i)
      self->request(server, infinite, 42).then(
        [=](int x) {
          CAF_REQUIRE_EQUAL(x, 42);
        }
      );
  };
  spawn(f, mirror);
  // run initialization code of testee
  sched.run_once();
  expect((int), from(testee).to(mirror).with(42));
  expect((int), from(testee).to(mirror).with(42));
  expect((int), from(testee).to(mirror).with(42));
  expect((int), from(mirror).to(testee).with(42));
  expect((int), from(mirror).to(testee).with(42));
  expect((int), from(mirror).to(testee).with(42));
}

CAF_TEST(single_awaited_request) {
  auto f = [&](event_based_actor* self, actor server) {
    self->request(server, infinite, 42).await(
      [=](int x) {
        CAF_REQUIRE_EQUAL(x, 42);
      }
    );
  };
  spawn(f, mirror);
  // run initialization code of testee
  sched.run_once();
  expect((int), from(testee).to(mirror).with(42));
  expect((int), from(mirror).to(testee).with(42));
}

CAF_TEST(multiple_awaited_requests) {
  auto f = [&](event_based_actor* self, actor server) {
    for (int i = 0; i < 3; ++i)
      self->request(server, infinite, i).await(
        [=](int x) {
          CAF_MESSAGE("received response #" << (i + 1));
          CAF_REQUIRE_EQUAL(x, i);
        }
      );
  };
  spawn(f, mirror);
  // run initialization code of testee
  sched.run_once();
  self->monitor(testee);
  expect((int), from(testee).to(mirror).with(0));
  expect((int), from(testee).to(mirror).with(1));
  expect((int), from(testee).to(mirror).with(2));
  // request().await() processes messages out-of-order,
  // which means we cannot check using expect()
  sched.run();
  expect((down_msg), from(testee).to(self).with(_));
}

CAF_TEST_FIXTURE_SCOPE_END()