~thomas-voss/location-service/remove-cell-aging-heuristics

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
/*
 * Copyright © 2014 Canonical Ltd.
 *
 * This program is free software: you can redistribute it and/or modify it
 * under the terms of the GNU Lesser General Public License version 3,
 * as published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 * Authored by: Thomas Voß <thomas.voss@canonical.com>
 */
#ifndef MOCK_EVENT_CONSUMER_H_
#define MOCK_EVENT_CONSUMER_H_

#include <gmock/gmock.h>

#include <condition_variable>
#include <mutex>

class MockEventConsumer
{
 public:
    MockEventConsumer()
    {
        using namespace ::testing;

        ON_CALL(*this, on_new_position(_))
                .WillByDefault(
                    InvokeWithoutArgs(
                        this,
                        &MockEventConsumer::notify_position_update_arrived));
        ON_CALL(*this, on_new_heading(_))
                .WillByDefault(
                    InvokeWithoutArgs(
                        this,
                        &MockEventConsumer::notify_heading_update_arrived));
        ON_CALL(*this, on_new_velocity(_))
                .WillByDefault(
                    InvokeWithoutArgs(
                        this,
                        &MockEventConsumer::notify_velocity_update_arrived));
    }

    bool wait_for_position_update_for(const std::chrono::milliseconds& timeout)
    {
        std::unique_lock<std::mutex> ul{position.guard};
        return position.wait_condition.wait_for(ul, timeout, [this] { return position.update_arrived; });
    }

    bool wait_for_heading_update_for(const std::chrono::milliseconds& timeout)
    {
        std::unique_lock<std::mutex> ul{heading.guard};
        return heading.wait_condition.wait_for(ul, timeout, [this] { return heading.update_arrived; });
    }

    bool wait_for_velocity_update_for(const std::chrono::milliseconds& timeout)
    {
        std::unique_lock<std::mutex> ul{velocity.guard};
        return velocity.wait_condition.wait_for(ul, timeout, [this] { return velocity.update_arrived; });
    }

    MOCK_METHOD1(on_new_position, void(const com::ubuntu::location::Update<com::ubuntu::location::Position>&));
    MOCK_METHOD1(on_new_heading, void(const com::ubuntu::location::Update<com::ubuntu::location::Heading>&));
    MOCK_METHOD1(on_new_velocity, void(const com::ubuntu::location::Update<com::ubuntu::location::Velocity>&));

private:
    // Notes down the arrival of a position update
    // and notifies any waiting threads about the event.
    void notify_position_update_arrived()
    {
        position.update_arrived = true;
        position.wait_condition.notify_all();
    }

    // Notes down the arrival of a heading update
    // and notifies any waiting threads about the event.
    void notify_heading_update_arrived()
    {
        heading.update_arrived = true;
        heading.wait_condition.notify_all();
    }

    // Notes down the arrival of a heading update
    // and notifies any waiting threads about the event.
    void notify_velocity_update_arrived()
    {
        velocity.update_arrived = true;
        velocity.wait_condition.notify_all();
    }

    struct
    {
        std::mutex guard;
        std::condition_variable wait_condition;
        bool update_arrived{false};
    } position;

    struct
    {
        std::mutex guard;
        std::condition_variable wait_condition;
        bool update_arrived{false};
    } heading;

    struct
    {
        std::mutex guard;
        std::condition_variable wait_condition;
        bool update_arrived{false};
    } velocity;
};

#endif // MOCK_EVENT_CONSUMER_H_