1 // Copyright 2018 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "osp/impl/service_publisher_impl.h"
6
7 #include <memory>
8 #include <utility>
9
10 #include "gmock/gmock.h"
11 #include "gtest/gtest.h"
12
13 namespace openscreen {
14 namespace osp {
15 namespace {
16
17 using ::testing::_;
18 using ::testing::Expectation;
19 using ::testing::NiceMock;
20
21 using State = ServicePublisher::State;
22
23 class MockObserver final : public ServicePublisher::Observer {
24 public:
25 ~MockObserver() = default;
26
27 MOCK_METHOD0(OnStarted, void());
28 MOCK_METHOD0(OnStopped, void());
29 MOCK_METHOD0(OnSuspended, void());
30
31 MOCK_METHOD1(OnError, void(Error));
32
33 MOCK_METHOD1(OnMetrics, void(ServicePublisher::Metrics));
34 };
35
36 class MockMdnsDelegate : public ServicePublisherImpl::Delegate {
37 public:
38 MockMdnsDelegate() = default;
39 ~MockMdnsDelegate() override = default;
40
41 using ServicePublisherImpl::Delegate::SetState;
42
43 MOCK_METHOD1(StartPublisher, void(const ServicePublisher::Config&));
44 MOCK_METHOD1(StartAndSuspendPublisher, void(const ServicePublisher::Config&));
45 MOCK_METHOD0(StopPublisher, void());
46 MOCK_METHOD0(SuspendPublisher, void());
47 MOCK_METHOD1(ResumePublisher, void(const ServicePublisher::Config&));
48 MOCK_METHOD0(RunTasksPublisher, void());
49 };
50
51 class ServicePublisherImplTest : public ::testing::Test {
52 protected:
SetUp()53 void SetUp() override {
54 auto mock_delegate = std::make_unique<NiceMock<MockMdnsDelegate>>();
55 mock_delegate_ = mock_delegate.get();
56 service_publisher_ = std::make_unique<ServicePublisherImpl>(
57 nullptr, std::move(mock_delegate));
58 service_publisher_->SetConfig(config);
59 }
60
61 NiceMock<MockMdnsDelegate>* mock_delegate_ = nullptr;
62 std::unique_ptr<ServicePublisherImpl> service_publisher_;
63 ServicePublisher::Config config;
64 };
65
66 } // namespace
67
TEST_F(ServicePublisherImplTest,NormalStartStop)68 TEST_F(ServicePublisherImplTest, NormalStartStop) {
69 ASSERT_EQ(State::kStopped, service_publisher_->state());
70
71 EXPECT_CALL(*mock_delegate_, StartPublisher(_));
72 EXPECT_TRUE(service_publisher_->Start());
73 EXPECT_FALSE(service_publisher_->Start());
74 EXPECT_EQ(State::kStarting, service_publisher_->state());
75
76 mock_delegate_->SetState(State::kRunning);
77 EXPECT_EQ(State::kRunning, service_publisher_->state());
78
79 EXPECT_CALL(*mock_delegate_, StopPublisher());
80 EXPECT_TRUE(service_publisher_->Stop());
81 EXPECT_FALSE(service_publisher_->Stop());
82 EXPECT_EQ(State::kStopping, service_publisher_->state());
83
84 mock_delegate_->SetState(State::kStopped);
85 EXPECT_EQ(State::kStopped, service_publisher_->state());
86 }
87
TEST_F(ServicePublisherImplTest,StopBeforeRunning)88 TEST_F(ServicePublisherImplTest, StopBeforeRunning) {
89 EXPECT_CALL(*mock_delegate_, StartPublisher(_));
90 EXPECT_TRUE(service_publisher_->Start());
91 EXPECT_EQ(State::kStarting, service_publisher_->state());
92
93 EXPECT_CALL(*mock_delegate_, StopPublisher());
94 EXPECT_TRUE(service_publisher_->Stop());
95 EXPECT_FALSE(service_publisher_->Stop());
96 EXPECT_EQ(State::kStopping, service_publisher_->state());
97
98 mock_delegate_->SetState(State::kStopped);
99 EXPECT_EQ(State::kStopped, service_publisher_->state());
100 }
101
TEST_F(ServicePublisherImplTest,StartSuspended)102 TEST_F(ServicePublisherImplTest, StartSuspended) {
103 EXPECT_CALL(*mock_delegate_, StartAndSuspendPublisher(_));
104 EXPECT_CALL(*mock_delegate_, StartPublisher(_)).Times(0);
105 EXPECT_TRUE(service_publisher_->StartAndSuspend());
106 EXPECT_FALSE(service_publisher_->Start());
107 EXPECT_EQ(State::kStarting, service_publisher_->state());
108
109 mock_delegate_->SetState(State::kSuspended);
110 EXPECT_EQ(State::kSuspended, service_publisher_->state());
111 }
112
TEST_F(ServicePublisherImplTest,SuspendAndResume)113 TEST_F(ServicePublisherImplTest, SuspendAndResume) {
114 EXPECT_TRUE(service_publisher_->Start());
115 mock_delegate_->SetState(State::kRunning);
116
117 EXPECT_CALL(*mock_delegate_, ResumePublisher(_)).Times(0);
118 EXPECT_CALL(*mock_delegate_, SuspendPublisher()).Times(2);
119 EXPECT_FALSE(service_publisher_->Resume());
120 EXPECT_TRUE(service_publisher_->Suspend());
121 EXPECT_TRUE(service_publisher_->Suspend());
122
123 mock_delegate_->SetState(State::kSuspended);
124 EXPECT_EQ(State::kSuspended, service_publisher_->state());
125
126 EXPECT_CALL(*mock_delegate_, StartPublisher(_)).Times(0);
127 EXPECT_CALL(*mock_delegate_, SuspendPublisher()).Times(0);
128 EXPECT_CALL(*mock_delegate_, ResumePublisher(_)).Times(2);
129 EXPECT_FALSE(service_publisher_->Start());
130 EXPECT_FALSE(service_publisher_->Suspend());
131 EXPECT_TRUE(service_publisher_->Resume());
132 EXPECT_TRUE(service_publisher_->Resume());
133
134 mock_delegate_->SetState(State::kRunning);
135 EXPECT_EQ(State::kRunning, service_publisher_->state());
136
137 EXPECT_CALL(*mock_delegate_, ResumePublisher(_)).Times(0);
138 EXPECT_FALSE(service_publisher_->Resume());
139 }
140
TEST_F(ServicePublisherImplTest,ObserverTransitions)141 TEST_F(ServicePublisherImplTest, ObserverTransitions) {
142 MockObserver observer;
143 auto mock_delegate = std::make_unique<NiceMock<MockMdnsDelegate>>();
144 NiceMock<MockMdnsDelegate>* const mock_delegate_ptr = mock_delegate.get();
145 auto service_publisher = std::make_unique<ServicePublisherImpl>(
146 &observer, std::move(mock_delegate));
147
148 service_publisher->Start();
149 Expectation start_from_stopped = EXPECT_CALL(observer, OnStarted());
150 mock_delegate_ptr->SetState(State::kRunning);
151
152 service_publisher->Suspend();
153 Expectation suspend_from_running =
154 EXPECT_CALL(observer, OnSuspended()).After(start_from_stopped);
155 mock_delegate_ptr->SetState(State::kSuspended);
156
157 service_publisher->Resume();
158 Expectation resume_from_suspended =
159 EXPECT_CALL(observer, OnStarted()).After(suspend_from_running);
160 mock_delegate_ptr->SetState(State::kRunning);
161
162 service_publisher->Stop();
163 EXPECT_CALL(observer, OnStopped()).After(resume_from_suspended);
164 mock_delegate_ptr->SetState(State::kStopped);
165 }
166
167 } // namespace osp
168 } // namespace openscreen
169