apmanager: monitor events from hostapd control interface
Monitor hostapd control interface for unsolicited event notifications,
such as station connect and disconnect events.
BUG=chromium:431759
TEST=USE="asan clang" FEATURES=test emerge-$BOARD apmanager
Manual Test:
1. Setup an AP service using apmanager.
2. Connect a client to the AP, verify that "Station connected" message is
in "/var/log/message".
3. Disconnect the client from the AP, verify that "Station disconnect"
message is in "/var/log/message".
Change-Id: I7410411c43db9670d7ae5e4cf4f9d83a2a2c6337
Reviewed-on: https://chromium-review.googlesource.com/240548
Trybot-Ready: Zeping Qiu <zqiu@chromium.org>
Tested-by: Zeping Qiu <zqiu@chromium.org>
Reviewed-by: Paul Stewart <pstew@chromium.org>
Commit-Queue: Zeping Qiu <zqiu@chromium.org>
diff --git a/hostapd_monitor_unittest.cc b/hostapd_monitor_unittest.cc
new file mode 100644
index 0000000..44f0304
--- /dev/null
+++ b/hostapd_monitor_unittest.cc
@@ -0,0 +1,104 @@
+// Copyright 2014 The Chromium OS Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "apmanager/hostapd_monitor.h"
+
+#include <base/bind.h>
+#include <gmock/gmock.h>
+#include <gtest/gtest.h>
+#include <shill/net/io_handler.h>
+
+#include "apmanager/mock_event_dispatcher.h"
+
+using base::Bind;
+using base::Unretained;
+using ::testing::_;
+
+namespace {
+ const char kStationMac[] = "00:11:22:33:44:55";
+ const char kHostapdEventStationConnected[] =
+ "<2>AP-STA-CONNECTED 00:11:22:33:44:55";
+ const char kHostapdEventStationDisconnected[] =
+ "<2>AP-STA-DISCONNECTED 00:11:22:33:44:55";
+} // namespace
+
+namespace apmanager {
+
+class HostapdEventCallbackObserver {
+ public:
+ HostapdEventCallbackObserver()
+ : event_callback_(
+ Bind(&HostapdEventCallbackObserver::OnEventCallback,
+ Unretained(this))) {}
+ virtual ~HostapdEventCallbackObserver() {}
+
+ MOCK_METHOD2(OnEventCallback,
+ void(HostapdMonitor::Event event, const std::string& data));
+
+ const HostapdMonitor::EventCallback event_callback() {
+ return event_callback_;
+ }
+
+ private:
+ HostapdMonitor::EventCallback event_callback_;
+
+ DISALLOW_COPY_AND_ASSIGN(HostapdEventCallbackObserver);
+};
+
+class HostapdMonitorTest : public testing::Test {
+ public:
+ HostapdMonitorTest()
+ : hostapd_monitor_(observer_.event_callback(), "", ""),
+ event_dispatcher_(MockEventDispatcher::GetInstance()) {}
+
+ virtual void SetUp() {
+ hostapd_monitor_.event_dispatcher_ = event_dispatcher_;
+ }
+
+ void Start() {
+ hostapd_monitor_.Start();
+ }
+
+ void ParseMessage(shill::InputData* data) {
+ hostapd_monitor_.ParseMessage(data);
+ }
+
+ protected:
+ HostapdEventCallbackObserver observer_;
+ HostapdMonitor hostapd_monitor_;
+ MockEventDispatcher* event_dispatcher_;
+};
+
+TEST_F(HostapdMonitorTest, Start) {
+ EXPECT_CALL(*event_dispatcher_, PostTask(_)).Times(1);
+ Start();
+
+ // Monitor already started, nothing to be done.
+ EXPECT_CALL(*event_dispatcher_, PostTask(_)).Times(0);
+ Start();
+}
+
+TEST_F(HostapdMonitorTest, StationConnected) {
+ shill::InputData data;
+ data.buf = reinterpret_cast<unsigned char*>(
+ const_cast<char*>(kHostapdEventStationConnected));
+ data.len = strlen(kHostapdEventStationConnected);
+ EXPECT_CALL(observer_,
+ OnEventCallback(HostapdMonitor::kStationConnected,
+ kStationMac)).Times(1);
+ ParseMessage(&data);
+}
+
+TEST_F(HostapdMonitorTest, StationDisconnected) {
+ shill::InputData data;
+ data.buf = reinterpret_cast<unsigned char*>(
+ const_cast<char*>(kHostapdEventStationDisconnected));
+ data.len = strlen(kHostapdEventStationDisconnected);
+ EXPECT_CALL(observer_,
+ OnEventCallback(HostapdMonitor::kStationDisconnected,
+ kStationMac)).Times(1);
+ ParseMessage(&data);
+}
+
+} // namespace apmanager