1//
2// Copyright (C) 2012 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//
16
17#include "shill/dns_server_tester.h"
18
19#include <memory>
20#include <string>
21
22#include <base/bind.h>
23#include <gmock/gmock.h>
24#include <gtest/gtest.h>
25
26#include "shill/mock_connection.h"
27#include "shill/mock_control.h"
28#include "shill/mock_device_info.h"
29#include "shill/mock_dns_client.h"
30#include "shill/mock_dns_client_factory.h"
31#include "shill/mock_event_dispatcher.h"
32#include "shill/net/mock_time.h"
33
34using base::Bind;
35using base::Callback;
36using base::Unretained;
37using std::string;
38using std::vector;
39using testing::_;
40using testing::AtLeast;
41using testing::DoAll;
42using testing::InSequence;
43using testing::Mock;
44using testing::NiceMock;
45using testing::Return;
46using testing::ReturnRef;
47using testing::SetArgumentPointee;
48using testing::StrictMock;
49using testing::Test;
50
51namespace shill {
52
53namespace {
54const char kInterfaceName[] = "int0";
55const char kDNSServer0[] = "8.8.8.8";
56const char kDNSServer1[] = "8.8.4.4";
57const char* kDNSServers[] = { kDNSServer0, kDNSServer1 };
58}  // namespace
59
60class DNSServerTesterTest : public Test {
61 public:
62  DNSServerTesterTest()
63      : device_info_(
64            new NiceMock<MockDeviceInfo>(&control_, nullptr, nullptr, nullptr)),
65        connection_(new StrictMock<MockConnection>(device_info_.get())),
66        interface_name_(kInterfaceName),
67        dns_servers_(kDNSServers, kDNSServers + 2) {}
68
69  virtual void SetUp() {
70    EXPECT_CALL(*connection_.get(), interface_name())
71          .WillRepeatedly(ReturnRef(interface_name_));
72    dns_server_tester_.reset(
73        new DNSServerTester(connection_.get(),
74                            &dispatcher_,
75                            dns_servers_,
76                            false,
77                            callback_target_.result_callback()));
78  }
79
80 protected:
81  class CallbackTarget {
82   public:
83    CallbackTarget()
84        : result_callback_(Bind(&CallbackTarget::ResultCallback,
85                                Unretained(this))) {
86    }
87
88    MOCK_METHOD1(ResultCallback, void(const DNSServerTester::Status status));
89    Callback<void(const DNSServerTester::Status)>& result_callback() {
90      return result_callback_;
91    }
92
93   private:
94    Callback<void(const DNSServerTester::Status)> result_callback_;
95  };
96
97  DNSServerTester* dns_server_tester() { return dns_server_tester_.get(); }
98  MockEventDispatcher& dispatcher() { return dispatcher_; }
99  CallbackTarget& callback_target() { return callback_target_; }
100
101  void ExpectReset() {
102    EXPECT_TRUE(callback_target_.result_callback().Equals(
103        dns_server_tester_->dns_result_callback_));
104  }
105
106 private:
107  StrictMock<MockEventDispatcher> dispatcher_;
108  MockControl control_;
109  std::unique_ptr<MockDeviceInfo> device_info_;
110  scoped_refptr<MockConnection> connection_;
111  CallbackTarget callback_target_;
112  const string interface_name_;
113  vector<string> dns_servers_;
114  std::unique_ptr<DNSServerTester> dns_server_tester_;
115};
116
117TEST_F(DNSServerTesterTest, Constructor) {
118  ExpectReset();
119}
120
121TEST_F(DNSServerTesterTest, StartAttempt) {
122  // Start attempt with no delay.
123  EXPECT_CALL(dispatcher(), PostDelayedTask(_, 0));
124  dns_server_tester()->StartAttempt(0);
125
126  // Start attempt with delay.
127  EXPECT_CALL(dispatcher(), PostDelayedTask(_, 100));
128  dns_server_tester()->StartAttempt(100);
129}
130
131TEST_F(DNSServerTesterTest, StartAttemptTask) {
132  // Setup mock DNS test client.
133  MockDNSClient* dns_test_client = new MockDNSClient();
134  dns_server_tester()->dns_test_client_.reset(dns_test_client);
135
136  // DNS test task started successfully.
137  EXPECT_CALL(*dns_test_client, Start(_, _)).WillOnce(Return(true));
138  EXPECT_CALL(callback_target(), ResultCallback(_)).Times(0);
139  dns_server_tester()->StartAttemptTask();
140  Mock::VerifyAndClearExpectations(dns_test_client);
141
142  // DNS test task failed to start.
143  EXPECT_CALL(*dns_test_client, Start(_, _)).WillOnce(Return(false));
144  EXPECT_CALL(callback_target(),
145              ResultCallback(DNSServerTester::kStatusFailure)).Times(1);
146  dns_server_tester()->StartAttemptTask();
147  Mock::VerifyAndClearExpectations(dns_test_client);
148}
149
150TEST_F(DNSServerTesterTest, AttemptCompleted) {
151  // DNS test attempt succeed with retry_until_success_ not set.
152  dns_server_tester()->retry_until_success_ = false;
153  EXPECT_CALL(callback_target(),
154              ResultCallback(DNSServerTester::kStatusSuccess)).Times(1);
155  dns_server_tester()->CompleteAttempt(DNSServerTester::kStatusSuccess);
156
157  // DNS test attempt succeed with retry_until_success_ being set.
158  dns_server_tester()->retry_until_success_ = true;
159  EXPECT_CALL(callback_target(),
160              ResultCallback(DNSServerTester::kStatusSuccess)).Times(1);
161  dns_server_tester()->CompleteAttempt(DNSServerTester::kStatusSuccess);
162
163  // DNS test attempt failed with retry_until_success_ not set.
164  dns_server_tester()->retry_until_success_ = false;
165  EXPECT_CALL(callback_target(),
166              ResultCallback(DNSServerTester::kStatusFailure)).Times(1);
167  dns_server_tester()->CompleteAttempt(DNSServerTester::kStatusFailure);
168
169  // DNS test attempt failed with retry_until_success_ being set.
170  dns_server_tester()->retry_until_success_ = true;
171  EXPECT_CALL(callback_target(), ResultCallback(_)).Times(0);
172  EXPECT_CALL(dispatcher(), PostDelayedTask(_, _)).Times(1);
173  dns_server_tester()->CompleteAttempt(DNSServerTester::kStatusFailure);
174}
175
176TEST_F(DNSServerTesterTest, StopAttempt) {
177  // Setup mock DNS test client.
178  MockDNSClient* dns_test_client = new MockDNSClient();
179  dns_server_tester()->dns_test_client_.reset(dns_test_client);
180
181  // DNS test task started successfully.
182  EXPECT_CALL(*dns_test_client, Start(_, _)).WillOnce(Return(true));
183  EXPECT_CALL(callback_target(), ResultCallback(_)).Times(0);
184  dns_server_tester()->StartAttemptTask();
185  Mock::VerifyAndClearExpectations(dns_test_client);
186
187  // Stop the DNS test attempt.
188  EXPECT_CALL(*dns_test_client, Stop()).Times(1);
189  EXPECT_CALL(callback_target(), ResultCallback(_)).Times(0);
190  dns_server_tester()->StopAttempt();
191  Mock::VerifyAndClearExpectations(dns_test_client);
192}
193
194}  // namespace shill
195