1/*
2 * Copyright (C) 2016, 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 <memory>
18#include <vector>
19
20#include <gmock/gmock.h>
21#include <gtest/gtest.h>
22#include <wifi_system_test/mock_hostapd_manager.h>
23#include <wifi_system_test/mock_interface_tool.h>
24
25#include "wificond/tests/mock_netlink_manager.h"
26#include "wificond/tests/mock_netlink_utils.h"
27
28#include "wificond/ap_interface_impl.h"
29
30using android::wifi_system::HostapdManager;
31using android::wifi_system::MockHostapdManager;
32using android::wifi_system::MockInterfaceTool;
33using std::placeholders::_1;
34using std::placeholders::_2;
35using std::unique_ptr;
36using std::vector;
37using testing::NiceMock;
38using testing::Invoke;
39using testing::Return;
40using testing::Sequence;
41using testing::StrEq;
42using testing::_;
43
44namespace android {
45namespace wificond {
46namespace {
47
48const char kTestInterfaceName[] = "testwifi0";
49const uint32_t kTestInterfaceIndex = 42;
50const uint8_t kFakeMacAddress[] = {0x45, 0x54, 0xad, 0x67, 0x98, 0xf6};
51
52void CaptureStationEventHandler(
53    OnStationEventHandler* out_handler,
54    uint32_t interface_index,
55    OnStationEventHandler handler) {
56  *out_handler = handler;
57}
58
59class ApInterfaceImplTest : public ::testing::Test {
60 protected:
61  unique_ptr<NiceMock<MockInterfaceTool>> if_tool_{
62      new NiceMock<MockInterfaceTool>};
63  unique_ptr<NiceMock<MockHostapdManager>> hostapd_manager_{
64      new NiceMock<MockHostapdManager>};
65  unique_ptr<NiceMock<MockNetlinkManager>> netlink_manager_{
66      new NiceMock<MockNetlinkManager>()};
67  unique_ptr<NiceMock<MockNetlinkUtils>> netlink_utils_{
68      new NiceMock<MockNetlinkUtils>(netlink_manager_.get())};
69
70  unique_ptr<ApInterfaceImpl> ap_interface_;
71
72  void SetUp() override {
73    ap_interface_.reset(new ApInterfaceImpl(
74        kTestInterfaceName,
75        kTestInterfaceIndex,
76        netlink_utils_.get(),
77        if_tool_.get(),
78        hostapd_manager_.get()));
79  }
80};  // class ApInterfaceImplTest
81
82}  // namespace
83
84TEST_F(ApInterfaceImplTest, ShouldReportStartFailure) {
85  EXPECT_CALL(*hostapd_manager_, StartHostapd())
86      .WillOnce(Return(false));
87  EXPECT_FALSE(ap_interface_->StartHostapd());
88}
89
90TEST_F(ApInterfaceImplTest, ShouldReportStartSuccess) {
91  EXPECT_CALL(*hostapd_manager_, StartHostapd())
92      .WillOnce(Return(true));
93  EXPECT_TRUE(ap_interface_->StartHostapd());
94}
95
96TEST_F(ApInterfaceImplTest, ShouldReportStopFailure) {
97  EXPECT_CALL(*hostapd_manager_, StopHostapd())
98      .WillOnce(Return(false));
99  EXPECT_FALSE(ap_interface_->StopHostapd());
100}
101
102TEST_F(ApInterfaceImplTest, ShouldReportStopSuccess) {
103  EXPECT_CALL(*hostapd_manager_, StopHostapd())
104      .WillOnce(Return(true));
105  EXPECT_CALL(*if_tool_, SetUpState(StrEq(kTestInterfaceName), false))
106      .WillOnce(Return(true));
107  EXPECT_CALL(*netlink_utils_, SetInterfaceMode(
108      kTestInterfaceIndex,
109      NetlinkUtils::STATION_MODE)).WillOnce(Return(true));
110  EXPECT_TRUE(ap_interface_->StopHostapd());
111  testing::Mock::VerifyAndClearExpectations(if_tool_.get());
112}
113
114TEST_F(ApInterfaceImplTest, ShouldRejectInvalidConfig) {
115  EXPECT_CALL(*hostapd_manager_, CreateHostapdConfig(_, _, _, _, _, _))
116      .WillOnce(Return(""));
117  EXPECT_CALL(*hostapd_manager_, WriteHostapdConfig(_)).Times(0);
118  EXPECT_FALSE(ap_interface_->WriteHostapdConfig(
119        vector<uint8_t>(),
120        false,
121        0,
122        HostapdManager::EncryptionType::kWpa2,
123        vector<uint8_t>()));
124}
125
126TEST_F(ApInterfaceImplTest, CanGetNumberOfAssociatedStations) {
127  OnStationEventHandler handler;
128  EXPECT_CALL(*netlink_utils_,
129      SubscribeStationEvent(kTestInterfaceIndex, _)).
130          WillOnce(Invoke(bind(CaptureStationEventHandler, &handler, _1, _2)));
131
132  ap_interface_.reset(new ApInterfaceImpl(
133        kTestInterfaceName,
134        kTestInterfaceIndex,
135        netlink_utils_.get(),
136        if_tool_.get(),
137        hostapd_manager_.get()));
138
139  vector<uint8_t> fake_mac_address(kFakeMacAddress,
140                                   kFakeMacAddress + sizeof(kFakeMacAddress));
141  EXPECT_EQ(0, ap_interface_->GetNumberOfAssociatedStations());
142  handler(NEW_STATION, fake_mac_address);
143  EXPECT_EQ(1, ap_interface_->GetNumberOfAssociatedStations());
144  handler(NEW_STATION, fake_mac_address);
145  EXPECT_EQ(2, ap_interface_->GetNumberOfAssociatedStations());
146  handler(DEL_STATION, fake_mac_address);
147  EXPECT_EQ(1, ap_interface_->GetNumberOfAssociatedStations());
148}
149
150}  // namespace wificond
151}  // namespace android
152