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 
34 using base::Bind;
35 using base::Callback;
36 using base::Unretained;
37 using std::string;
38 using std::vector;
39 using testing::_;
40 using testing::AtLeast;
41 using testing::DoAll;
42 using testing::InSequence;
43 using testing::Mock;
44 using testing::NiceMock;
45 using testing::Return;
46 using testing::ReturnRef;
47 using testing::SetArgumentPointee;
48 using testing::StrictMock;
49 using testing::Test;
50 
51 namespace shill {
52 
53 namespace {
54 const char kInterfaceName[] = "int0";
55 const char kDNSServer0[] = "8.8.8.8";
56 const char kDNSServer1[] = "8.8.4.4";
57 const char* kDNSServers[] = { kDNSServer0, kDNSServer1 };
58 }  // namespace
59 
60 class DNSServerTesterTest : public Test {
61  public:
DNSServerTesterTest()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 
SetUp()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:
CallbackTarget()83     CallbackTarget()
84         : result_callback_(Bind(&CallbackTarget::ResultCallback,
85                                 Unretained(this))) {
86     }
87 
88     MOCK_METHOD1(ResultCallback, void(const DNSServerTester::Status status));
result_callback()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 
dns_server_tester()97   DNSServerTester* dns_server_tester() { return dns_server_tester_.get(); }
dispatcher()98   MockEventDispatcher& dispatcher() { return dispatcher_; }
callback_target()99   CallbackTarget& callback_target() { return callback_target_; }
100 
ExpectReset()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 
TEST_F(DNSServerTesterTest,Constructor)117 TEST_F(DNSServerTesterTest, Constructor) {
118   ExpectReset();
119 }
120 
TEST_F(DNSServerTesterTest,StartAttempt)121 TEST_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 
TEST_F(DNSServerTesterTest,StartAttemptTask)131 TEST_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 
TEST_F(DNSServerTesterTest,AttemptCompleted)150 TEST_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 
TEST_F(DNSServerTesterTest,StopAttempt)176 TEST_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