blob: fa903fe3658a80361ccf3f15999eab9f3158132a [file] [log] [blame]
Peter Qiuc0beca52015-09-03 11:25:46 -07001//
2// Copyright (C) 2013 The Android Open Source Project
3//
4// Licensed under the Apache License, Version 2.0 (the "License");
5// you may not use this file except in compliance with the License.
6// You may obtain a copy of the License at
7//
8// http://www.apache.org/licenses/LICENSE-2.0
9//
10// Unless required by applicable law or agreed to in writing, software
11// distributed under the License is distributed on an "AS IS" BASIS,
12// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13// See the License for the specific language governing permissions and
14// limitations under the License.
15//
mukesh agrawal46c27cc2013-07-10 16:39:10 -070016
17#include "shill/result_aggregator.h"
18
19#include <base/bind.h>
20#include <base/memory/ref_counted.h>
21#include <gmock/gmock.h>
22#include <gtest/gtest.h>
23
Samuel Tan7c1aacb2014-09-15 17:13:40 -070024#include "shill/mock_event_dispatcher.h"
Peter Qiua92b0a02015-08-13 14:13:08 -070025#include "shill/test_event_dispatcher.h"
Samuel Tanfa3043c2015-07-17 11:01:20 -070026#include "shill/testing.h"
Samuel Tan7c1aacb2014-09-15 17:13:40 -070027
mukesh agrawal46c27cc2013-07-10 16:39:10 -070028namespace shill {
29
Samuel Tan7c1aacb2014-09-15 17:13:40 -070030using testing::StrictMock;
31using testing::_;
mukesh agrawal46c27cc2013-07-10 16:39:10 -070032using base::Bind;
33using base::Unretained;
34
Samuel Tan7c1aacb2014-09-15 17:13:40 -070035namespace {
36
37const int kTimeoutMilliseconds = 0;
38
39} // namespace
40
mukesh agrawal46c27cc2013-07-10 16:39:10 -070041class ResultAggregatorTest : public ::testing::Test {
42 public:
43 ResultAggregatorTest()
44 : aggregator_(new ResultAggregator(
45 Bind(&ResultAggregatorTest::ReportResult, Unretained(this)))) {}
46 virtual ~ResultAggregatorTest() {}
47
48 virtual void TearDown() {
Ben Chancc225ef2014-09-30 13:26:51 -070049 aggregator_ = nullptr; // Ensure ReportResult is invoked before our dtor.
mukesh agrawal46c27cc2013-07-10 16:39:10 -070050 }
51
Paul Stewart3b30ca52015-06-16 13:13:10 -070052 MOCK_METHOD1(ReportResult, void(const Error&));
Samuel Tan7c1aacb2014-09-15 17:13:40 -070053
54 protected:
mukesh agrawal46c27cc2013-07-10 16:39:10 -070055 scoped_refptr<ResultAggregator> aggregator_;
56};
57
Samuel Tan7c1aacb2014-09-15 17:13:40 -070058class ResultAggregatorTestWithDispatcher : public ResultAggregatorTest {
59 public:
60 ResultAggregatorTestWithDispatcher() : ResultAggregatorTest() {}
61 virtual ~ResultAggregatorTestWithDispatcher() {}
62
63 void InitializeResultAggregatorWithTimeout() {
64 aggregator_ = new ResultAggregator(
65 Bind(&ResultAggregatorTest::ReportResult, Unretained(this)),
66 &dispatcher_, kTimeoutMilliseconds);
67 }
68
69 protected:
Peter Qiua92b0a02015-08-13 14:13:08 -070070 EventDispatcherForTest dispatcher_;
Samuel Tan7c1aacb2014-09-15 17:13:40 -070071};
72
73class ResultAggregatorTestWithMockDispatcher : public ResultAggregatorTest {
74 public:
75 ResultAggregatorTestWithMockDispatcher() : ResultAggregatorTest() {}
76 virtual ~ResultAggregatorTestWithMockDispatcher() {}
77
78 protected:
79 StrictMock<MockEventDispatcher> dispatcher_;
80};
81
mukesh agrawal46c27cc2013-07-10 16:39:10 -070082class ResultGenerator {
83 public:
Paul Stewart3b30ca52015-06-16 13:13:10 -070084 explicit ResultGenerator(const scoped_refptr<ResultAggregator>& aggregator)
mukesh agrawal46c27cc2013-07-10 16:39:10 -070085 : aggregator_(aggregator) {}
86 ~ResultGenerator() {}
87
88 void GenerateResult(const Error::Type error_type) {
89 aggregator_->ReportResult(Error(error_type));
90 }
91
92 private:
93 scoped_refptr<ResultAggregator> aggregator_;
94 DISALLOW_COPY_AND_ASSIGN(ResultGenerator);
95};
96
Samuel Tan7c1aacb2014-09-15 17:13:40 -070097TEST_F(ResultAggregatorTestWithMockDispatcher, Unused) {
Samuel Tanfa3043c2015-07-17 11:01:20 -070098 EXPECT_CALL(*this, ReportResult(ErrorTypeIs(Error::kSuccess))).Times(0);
mukesh agrawal46c27cc2013-07-10 16:39:10 -070099}
100
Samuel Tan7c1aacb2014-09-15 17:13:40 -0700101TEST_F(ResultAggregatorTestWithMockDispatcher, BothSucceed) {
Samuel Tanfa3043c2015-07-17 11:01:20 -0700102 EXPECT_CALL(*this, ReportResult(ErrorTypeIs(Error::kSuccess)));
mukesh agrawal46c27cc2013-07-10 16:39:10 -0700103 ResultGenerator first_generator(aggregator_);
104 ResultGenerator second_generator(aggregator_);
105 first_generator.GenerateResult(Error::kSuccess);
106 second_generator.GenerateResult(Error::kSuccess);
107}
108
Samuel Tan7c1aacb2014-09-15 17:13:40 -0700109TEST_F(ResultAggregatorTestWithMockDispatcher, FirstFails) {
Samuel Tanfa3043c2015-07-17 11:01:20 -0700110 EXPECT_CALL(*this, ReportResult(ErrorTypeIs(Error::kOperationTimeout)));
mukesh agrawal46c27cc2013-07-10 16:39:10 -0700111 ResultGenerator first_generator(aggregator_);
112 ResultGenerator second_generator(aggregator_);
113 first_generator.GenerateResult(Error::kOperationTimeout);
114 second_generator.GenerateResult(Error::kSuccess);
115}
116
Samuel Tan7c1aacb2014-09-15 17:13:40 -0700117TEST_F(ResultAggregatorTestWithMockDispatcher, SecondFails) {
Samuel Tanfa3043c2015-07-17 11:01:20 -0700118 EXPECT_CALL(*this, ReportResult(ErrorTypeIs(Error::kOperationTimeout)));
mukesh agrawal46c27cc2013-07-10 16:39:10 -0700119 ResultGenerator first_generator(aggregator_);
120 ResultGenerator second_generator(aggregator_);
121 first_generator.GenerateResult(Error::kSuccess);
122 second_generator.GenerateResult(Error::kOperationTimeout);
123}
124
Samuel Tan7c1aacb2014-09-15 17:13:40 -0700125TEST_F(ResultAggregatorTestWithMockDispatcher, BothFail) {
Samuel Tanfa3043c2015-07-17 11:01:20 -0700126 EXPECT_CALL(*this, ReportResult(ErrorTypeIs(Error::kOperationTimeout)));
mukesh agrawal46c27cc2013-07-10 16:39:10 -0700127 ResultGenerator first_generator(aggregator_);
128 ResultGenerator second_generator(aggregator_);
129 first_generator.GenerateResult(Error::kOperationTimeout);
130 second_generator.GenerateResult(Error::kPermissionDenied);
131}
132
Samuel Tan7c1aacb2014-09-15 17:13:40 -0700133TEST_F(ResultAggregatorTestWithMockDispatcher,
134 TimeoutCallbackPostedOnConstruction) {
135 EXPECT_CALL(dispatcher_, PostDelayedTask(_, kTimeoutMilliseconds));
136 auto result_aggregator = make_scoped_refptr(new ResultAggregator(
137 Bind(&ResultAggregatorTest::ReportResult, Unretained(this)), &dispatcher_,
138 kTimeoutMilliseconds));
139}
140
141TEST_F(ResultAggregatorTestWithDispatcher,
142 TimeoutReceivedWithoutAnyResultsReceived) {
143 InitializeResultAggregatorWithTimeout();
Samuel Tanfa3043c2015-07-17 11:01:20 -0700144 EXPECT_CALL(*this, ReportResult(ErrorTypeIs(Error::kOperationTimeout)));
Samuel Tan7c1aacb2014-09-15 17:13:40 -0700145 ResultGenerator generator(aggregator_);
146 dispatcher_.DispatchPendingEvents(); // Invoke timeout callback.
147}
148
149TEST_F(ResultAggregatorTestWithDispatcher, TimeoutAndOtherResultReceived) {
150 // Timeout should override any other error results.
151 InitializeResultAggregatorWithTimeout();
Samuel Tanfa3043c2015-07-17 11:01:20 -0700152 EXPECT_CALL(*this, ReportResult(ErrorTypeIs(Error::kOperationTimeout)));
Samuel Tan7c1aacb2014-09-15 17:13:40 -0700153 ResultGenerator first_generator(aggregator_);
154 ResultGenerator second_generator(aggregator_);
155 first_generator.GenerateResult(Error::kSuccess);
156 dispatcher_.DispatchPendingEvents(); // Invoke timeout callback.
157 second_generator.GenerateResult(Error::kPermissionDenied);
158}
159
160TEST_F(ResultAggregatorTestWithDispatcher,
161 TimeoutCallbackNotInvokedIfAllActionsComplete) {
162 {
163 auto result_aggregator = make_scoped_refptr(new ResultAggregator(
164 Bind(&ResultAggregatorTest::ReportResult, Unretained(this)),
165 &dispatcher_, kTimeoutMilliseconds));
166 // The result aggregator receives the one callback it expects, and goes
167 // out of scope. At this point, it should invoke the ReportResult callback
168 // with the error type kPermissionDenied that it copied.
169 ResultGenerator generator(result_aggregator);
170 generator.GenerateResult(Error::kPermissionDenied);
Samuel Tanfa3043c2015-07-17 11:01:20 -0700171 EXPECT_CALL(*this, ReportResult(ErrorTypeIs(Error::kPermissionDenied)));
Samuel Tan7c1aacb2014-09-15 17:13:40 -0700172 }
173 // The timeout callback should be canceled after the ResultAggregator went
174 // out of scope and was destructed.
Samuel Tanfa3043c2015-07-17 11:01:20 -0700175 EXPECT_CALL(*this, ReportResult(ErrorTypeIs(Error::kOperationTimeout)))
Samuel Tan7c1aacb2014-09-15 17:13:40 -0700176 .Times(0);
177 dispatcher_.DispatchPendingEvents();
178}
179
mukesh agrawal46c27cc2013-07-10 16:39:10 -0700180} // namespace shill