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/dhcp/dhcp_provider.h"
18
19#include <base/files/file_util.h>
20#include <base/files/scoped_temp_dir.h>
21#include <base/strings/stringprintf.h>
22
23#include "shill/dhcp/dhcp_config.h"
24#include "shill/mock_control.h"
25#include "shill/mock_dhcp_properties.h"
26#include "shill/mock_event_dispatcher.h"
27
28using base::FilePath;
29using base::ScopedTempDir;
30using testing::_;
31using testing::DoAll;
32using testing::Return;
33using testing::SaveArg;
34using testing::SetArgPointee;
35using testing::StrictMock;
36using testing::Test;
37
38namespace shill {
39
40namespace {
41const char kDeviceName[] = "testdevicename";
42const char kStorageIdentifier[] = "teststorageidentifier";
43const bool kArpGateway = false;
44}  // namespace
45
46class DHCPProviderTest : public Test {
47 public:
48  DHCPProviderTest() : provider_(DHCPProvider::GetInstance()) {
49    provider_->control_interface_ = &control_;
50    provider_->dispatcher_ = &dispatcher_;
51  }
52
53  void SetUp() {
54    // DHCPProvider is a singleton, there is no guarentee that it is
55    // not setup/used elsewhere, so reset its state before running our
56    // tests.
57    provider_->configs_.clear();
58    provider_->recently_unbound_pids_.clear();
59  }
60
61 protected:
62  void RetireUnboundPID(int pid) { provider_->RetireUnboundPID(pid); }
63
64  MockControl control_;
65  DHCPProvider* provider_;
66  StrictMock<MockEventDispatcher> dispatcher_;
67};
68
69TEST_F(DHCPProviderTest, CreateIPv4Config) {
70  DhcpProperties dhcp_props;
71
72  DHCPConfigRefPtr config = provider_->CreateIPv4Config(kDeviceName,
73                                                        kStorageIdentifier,
74                                                        kArpGateway,
75                                                        dhcp_props);
76  EXPECT_TRUE(config.get());
77  EXPECT_EQ(kDeviceName, config->device_name());
78  EXPECT_TRUE(provider_->configs_.empty());
79}
80
81TEST_F(DHCPProviderTest, DestroyLease) {
82  ScopedTempDir temp_dir;
83  FilePath lease_file;
84  EXPECT_TRUE(temp_dir.CreateUniqueTempDir());
85  provider_->root_ = temp_dir.path();
86  lease_file = provider_->root_.Append(base::StringPrintf(
87      DHCPProvider::kDHCPCDPathFormatLease,
88      kDeviceName));
89  EXPECT_TRUE(base::CreateDirectory(lease_file.DirName()));
90  EXPECT_EQ(0, base::WriteFile(lease_file, "", 0));
91  EXPECT_TRUE(base::PathExists(lease_file));
92  provider_->DestroyLease(kDeviceName);
93  EXPECT_FALSE(base::PathExists(lease_file));
94}
95
96TEST_F(DHCPProviderTest, BindAndUnbind) {
97  int kPid = 999;
98  EXPECT_EQ(nullptr, provider_->GetConfig(kPid));
99  EXPECT_FALSE(provider_->IsRecentlyUnbound(kPid));
100  DhcpProperties dhcp_props;
101
102  DHCPConfigRefPtr config = provider_->CreateIPv4Config(kDeviceName,
103                                                        kStorageIdentifier,
104                                                        kArpGateway,
105                                                        dhcp_props);
106  provider_->BindPID(kPid, config);
107  EXPECT_NE(nullptr, provider_->GetConfig(kPid));
108  EXPECT_FALSE(provider_->IsRecentlyUnbound(kPid));
109
110  base::Closure task;
111  EXPECT_CALL(dispatcher_, PostDelayedTask(_, _));  // TODO(pstew): crbug/502320
112  provider_->UnbindPID(kPid);
113  EXPECT_EQ(nullptr, provider_->GetConfig(kPid));
114  EXPECT_TRUE(provider_->IsRecentlyUnbound(kPid));
115
116  RetireUnboundPID(kPid);  // Execute as if the PostDelayedTask() timer expired.
117  EXPECT_EQ(nullptr, provider_->GetConfig(kPid));
118  EXPECT_FALSE(provider_->IsRecentlyUnbound(kPid));
119}
120
121}  // namespace shill
122