From 919a8a9908cd48271a0b3e6afa5a444d912459e2 Mon Sep 17 00:00:00 2001 From: Vitaly Buka Date: Wed, 27 Jan 2016 15:59:28 -0800 Subject: Remove crypto type "None" Unused for a while. If necessary better to set local_anonymous_access_role into kOwner. Change-Id: Ifdd39a9a6069f54ac641730550ed71da106fe10e Reviewed-on: https://weave-review.googlesource.com/2377 Reviewed-by: Alex Vakulenko (cherry picked from commit d7c6deb0576805c0e043686e220a7a27e17b50d4) Reviewed-on: https://weave-review.googlesource.com/2423 Reviewed-by: Vitaly Buka --- examples/daemon/common/daemon.h | 7 +------ examples/provider/file_config_store.cc | 7 ++----- examples/provider/file_config_store.h | 4 +--- include/weave/settings.h | 1 - src/config_unittest.cc | 3 --- src/privet/privet_manager.cc | 5 ----- src/privet/privet_manager.h | 1 - src/privet/privet_types.cc | 1 - src/privet/privet_types.h | 1 - src/privet/security_manager.cc | 31 ------------------------------- 10 files changed, 4 insertions(+), 57 deletions(-) diff --git a/examples/daemon/common/daemon.h b/examples/daemon/common/daemon.h index 6dc021d..985c5e5 100644 --- a/examples/daemon/common/daemon.h +++ b/examples/daemon/common/daemon.h @@ -20,7 +20,6 @@ class Daemon { public: struct Options { bool force_bootstrapping_{false}; - bool disable_security_{false}; bool disable_privet_{false}; std::string registration_ticket_; std::string model_id_{"AAAAA"}; @@ -31,7 +30,6 @@ class Daemon { << "\t-h,--help Show this help message\n" << "\t--v=LEVEL Logging level\n" << "\t-b,--bootstrapping Force WiFi bootstrapping\n" - << "\t-d,--disable_security Disable privet security\n" << "\t--registration_ticket=TICKET Register device with the " "given ticket\n" << "\t--disable_privet Disable local privet\n"; @@ -44,8 +42,6 @@ class Daemon { return false; } else if (arg == "-b" || arg == "--bootstrapping") { force_bootstrapping_ = true; - } else if (arg == "-d" || arg == "--disable_security") { - disable_security_ = true; } else if (arg == "--disable_privet") { disable_privet_ = true; } else if (arg.find("--registration_ticket") != std::string::npos) { @@ -71,8 +67,7 @@ class Daemon { Daemon(const Options& opts) : task_runner_{new weave::examples::EventTaskRunner}, config_store_{ - new weave::examples::FileConfigStore(opts.disable_security_, - opts.model_id_, + new weave::examples::FileConfigStore(opts.model_id_, task_runner_.get())}, http_client_{new weave::examples::CurlHttpClient(task_runner_.get())}, network_{new weave::examples::EventNetworkImpl(task_runner_.get())}, diff --git a/examples/provider/file_config_store.cc b/examples/provider/file_config_store.cc index 31efaa7..a6c2e60 100644 --- a/examples/provider/file_config_store.cc +++ b/examples/provider/file_config_store.cc @@ -19,11 +19,9 @@ namespace examples { const char kSettingsDir[] = "/var/lib/weave/"; -FileConfigStore::FileConfigStore(bool disable_security, - const std::string& model_id, +FileConfigStore::FileConfigStore(const std::string& model_id, provider::TaskRunner* task_runner) - : disable_security_{disable_security}, - model_id_{model_id}, + : model_id_{model_id}, task_runner_{task_runner} {} std::string FileConfigStore::GetPath(const std::string& name) const { @@ -61,7 +59,6 @@ bool FileConfigStore::LoadDefaults(Settings* settings) { settings->client_secret = "LS_iPYo_WIOE0m2VnLdduhnx"; settings->api_key = "AIzaSyACK3oZtmIylUKXiTMqkZqfuRiCgQmQSAQ"; - settings->disable_security = disable_security_; return true; } diff --git a/examples/provider/file_config_store.h b/examples/provider/file_config_store.h index e7398d1..337e82a 100644 --- a/examples/provider/file_config_store.h +++ b/examples/provider/file_config_store.h @@ -17,8 +17,7 @@ namespace examples { class FileConfigStore : public provider::ConfigStore { public: - FileConfigStore(bool disable_security, - const std::string& model_id, + FileConfigStore(const std::string& model_id, provider::TaskRunner* task_runner); bool LoadDefaults(Settings* settings) override; @@ -31,7 +30,6 @@ class FileConfigStore : public provider::ConfigStore { private: std::string GetPath(const std::string& name) const; - const bool disable_security_; const std::string model_id_; provider::TaskRunner* task_runner_{nullptr}; }; diff --git a/include/weave/settings.h b/include/weave/settings.h index eeb3f93..741fff2 100644 --- a/include/weave/settings.h +++ b/include/weave/settings.h @@ -71,7 +71,6 @@ struct Settings { // Internal options to tweak some library functionality. External code should // avoid using them. bool wifi_auto_setup_enabled{true}; - bool disable_security{false}; std::string test_privet_ssid; }; diff --git a/src/config_unittest.cc b/src/config_unittest.cc index fbb558a..4b0e5b4 100644 --- a/src/config_unittest.cc +++ b/src/config_unittest.cc @@ -68,7 +68,6 @@ TEST_F(ConfigTest, Defaults) { EXPECT_FALSE(GetSettings().device_id.empty()); EXPECT_EQ("", GetSettings().firmware_version); EXPECT_TRUE(GetSettings().wifi_auto_setup_enabled); - EXPECT_FALSE(GetSettings().disable_security); EXPECT_EQ("", GetSettings().test_privet_ssid); EXPECT_EQ(std::set{PairingType::kPinCode}, GetSettings().pairing_modes); @@ -164,8 +163,6 @@ TEST_F(ConfigTest, LoadState) { EXPECT_EQ("state_device_id", GetSettings().device_id); EXPECT_EQ(GetDefaultSettings().wifi_auto_setup_enabled, GetSettings().wifi_auto_setup_enabled); - EXPECT_EQ(GetDefaultSettings().disable_security, - GetSettings().disable_security); EXPECT_EQ(GetDefaultSettings().test_privet_ssid, GetSettings().test_privet_ssid); EXPECT_EQ(GetDefaultSettings().pairing_modes, GetSettings().pairing_modes); diff --git a/src/privet/privet_manager.cc b/src/privet/privet_manager.cc index edc7907..9c717ce 100644 --- a/src/privet/privet_manager.cc +++ b/src/privet/privet_manager.cc @@ -53,8 +53,6 @@ void Manager::Start(Network* network, CHECK(auth_manager); CHECK(device); - disable_security_ = device->GetSettings().disable_security; - device_ = DeviceDelegate::CreateDefault( task_runner_, http_server->GetHttpPort(), http_server->GetHttpsPort(), http_server->GetRequestTimeout()); @@ -129,9 +127,6 @@ void Manager::PrivetRequestHandlerWithData( const std::shared_ptr& request, const std::string& data) { std::string auth_header = request->GetFirstHeader(http::kAuthorization); - if (auth_header.empty() && disable_security_) - auth_header = "Privet anonymous"; - base::DictionaryValue empty; auto value = base::JSONReader::Read(data); const base::DictionaryValue* dictionary = ∅ diff --git a/src/privet/privet_manager.h b/src/privet/privet_manager.h index 371d843..06eb89a 100644 --- a/src/privet/privet_manager.h +++ b/src/privet/privet_manager.h @@ -79,7 +79,6 @@ class Manager : public CloudDelegate::Observer { void OnChanged(); void OnConnectivityChanged(); - bool disable_security_{false}; provider::TaskRunner* task_runner_{nullptr}; std::unique_ptr cloud_; std::unique_ptr device_; diff --git a/src/privet/privet_types.cc b/src/privet/privet_types.cc index dd291b3..9e50f94 100644 --- a/src/privet/privet_types.cc +++ b/src/privet/privet_types.cc @@ -52,7 +52,6 @@ const EnumToStringMap::Map kWifiTypeMap[] = { }; const EnumToStringMap::Map kCryptoTypeMap[] = { - {CryptoType::kNone, "none"}, {CryptoType::kSpake_p224, "p224_spake2"}, }; diff --git a/src/privet/privet_types.h b/src/privet/privet_types.h index c738865..49c4522 100644 --- a/src/privet/privet_types.h +++ b/src/privet/privet_types.h @@ -15,7 +15,6 @@ namespace weave { namespace privet { enum class CryptoType { - kNone, kSpake_p224, }; diff --git a/src/privet/security_manager.cc b/src/privet/security_manager.cc index 358876d..0f00699 100644 --- a/src/privet/security_manager.cc +++ b/src/privet/security_manager.cc @@ -67,25 +67,6 @@ class Spakep224Exchanger : public SecurityManager::KeyExchanger { crypto::P224EncryptedKeyExchange spake_; }; -class UnsecureKeyExchanger : public SecurityManager::KeyExchanger { - public: - explicit UnsecureKeyExchanger(const std::string& password) - : password_(password) {} - ~UnsecureKeyExchanger() override = default; - - // SecurityManager::KeyExchanger methods. - const std::string& GetMessage() override { return password_; } - - bool ProcessMessage(const std::string& message, ErrorPtr* error) override { - return true; - } - - const std::string& GetKey() const override { return password_; } - - private: - std::string password_; -}; - } // namespace SecurityManager::SecurityManager(const Config* config, @@ -218,8 +199,6 @@ std::set SecurityManager::GetPairingTypes() const { std::set SecurityManager::GetCryptoTypes() const { std::set result{CryptoType::kSpake_p224}; - if (GetSettings().disable_security) - result.insert(CryptoType::kNone); return result; } @@ -259,8 +238,6 @@ const Config::Settings& SecurityManager::GetSettings() const { bool SecurityManager::IsValidPairingCode( const std::vector& auth_code) const { - if (GetSettings().disable_security) - return true; for (const auto& session : confirmed_sessions_) { const std::string& key = session.second->GetKey(); const std::string& id = session.first; @@ -309,11 +286,6 @@ bool SecurityManager::StartPairing(PairingType mode, case CryptoType::kSpake_p224: spake.reset(new Spakep224Exchanger(code)); break; - case CryptoType::kNone: - if (GetSettings().disable_security) { - spake.reset(new UnsecureKeyExchanger(code)); - break; - } // Fall through... default: return Error::AddTo(error, FROM_HERE, errors::kInvalidParams, @@ -428,9 +400,6 @@ void SecurityManager::RegisterPairingListeners( } bool SecurityManager::CheckIfPairingAllowed(ErrorPtr* error) { - if (GetSettings().disable_security) - return true; - if (block_pairing_until_ > auth_manager_->Now()) { return Error::AddTo(error, FROM_HERE, errors::kDeviceBusy, "Too many pairing attempts"); -- cgit v1.2.3 From 331355869fb6f8e11427f35807b7c310ec7743ca Mon Sep 17 00:00:00 2001 From: Jacob Marble Date: Thu, 28 Jan 2016 10:29:23 -0800 Subject: Replace bleeding-edge libevent with libevhtp. A libevhtp package exists for recent releases of Linux distros. An exception for these will come in a future patch. Change-Id: I15b96be469b91f19c06c326fc52b42027c097df9 Bug: 26850406 Bug: 24204638 Reviewed-on: https://weave-review.googlesource.com/2384 Reviewed-by: Vitaly Buka --- .gitignore | 2 + Makefile | 3 +- examples/examples.mk | 16 ++-- examples/provider/event_deleter.h | 23 ++++-- examples/provider/event_http_server.cc | 146 ++++++++++++++++----------------- examples/provider/event_http_server.h | 30 +++---- examples/provider/event_task_runner.cc | 6 +- third_party/get_libevent.sh | 29 ------- third_party/get_libevhtp.sh | 25 ++++++ third_party/third_party.mk | 24 +++--- 10 files changed, 152 insertions(+), 152 deletions(-) delete mode 100755 third_party/get_libevent.sh create mode 100755 third_party/get_libevhtp.sh diff --git a/.gitignore b/.gitignore index a256906..86c649b 100644 --- a/.gitignore +++ b/.gitignore @@ -2,4 +2,6 @@ /out/ /third_party/include /third_party/lib +/third_party/libevhtp +/third_party/googletest gomacc.lock diff --git a/Makefile b/Makefile index de69f40..6fd30f5 100644 --- a/Makefile +++ b/Makefile @@ -88,7 +88,6 @@ include file_lists.mk third_party/third_party.mk examples/examples.mk tests.mk weave_obj_files := $(WEAVE_SRC_FILES:%.cc=out/$(BUILD_MODE)/%.o) -# TODO(jacobmarble): There are too many gtest/gmock deps in non-test targets. Fix. $(weave_obj_files) : out/$(BUILD_MODE)/%.o : %.cc mkdir -p $(dir $@) $(CXX) $(DEFS_$(BUILD_MODE)) $(INCLUDES) $(CFLAGS) $(CFLAGS_$(BUILD_MODE)) $(CFLAGS_CC) -c -o $@ $< @@ -102,7 +101,7 @@ all : out/$(BUILD_MODE)/libweave.so all-examples out/$(BUILD_MODE)/libweave_expo clean : rm -rf out -cleanall : clean clean-gtest clean-libevent +cleanall : clean clean-gtest clean-libevhtp .PHONY : clean cleanall all diff --git a/examples/examples.mk b/examples/examples.mk index 06266a3..f1e92b6 100644 --- a/examples/examples.mk +++ b/examples/examples.mk @@ -7,7 +7,7 @@ examples_provider_obj_files := $(EXAMPLES_PROVIDER_SRC_FILES:%.cc=out/$(BUILD_MODE)/%.o) -$(examples_provider_obj_files) : out/$(BUILD_MODE)/%.o : %.cc third_party/include/event2/event.h +$(examples_provider_obj_files) : out/$(BUILD_MODE)/%.o : %.cc third_party/include/evhtp.h mkdir -p $(dir $@) $(CXX) $(DEFS_$(BUILD_MODE)) $(INCLUDES) $(CFLAGS) $(CFLAGS_$(BUILD_MODE)) $(CFLAGS_CC) -c -o $@ $< @@ -15,7 +15,7 @@ out/$(BUILD_MODE)/examples_provider.a : $(examples_provider_obj_files) rm -f $@ $(AR) crsT $@ $^ -out/$(BUILD_MODE)/examples/daemon/%.o : examples/daemon/%.cc third_party/include/event2/event.h +out/$(BUILD_MODE)/examples/daemon/%.o : examples/daemon/%.cc third_party/include/evhtp.h mkdir -p $(dir $@) $(CXX) $(DEFS_$(BUILD_MODE)) $(INCLUDES) $(CFLAGS) $(CFLAGS_$(BUILD_MODE)) $(CFLAGS_CC) -c -o $@ $< @@ -32,22 +32,22 @@ daemon_common_flags := \ -lssl \ -lcrypto -out/$(BUILD_MODE)/weave_daemon_ledflasher : out/$(BUILD_MODE)/examples/daemon/ledflasher/ledflasher.o out/$(BUILD_MODE)/examples_provider.a out/$(BUILD_MODE)/libweave.so +out/$(BUILD_MODE)/weave_daemon_ledflasher : out/$(BUILD_MODE)/examples/daemon/ledflasher/ledflasher.o out/$(BUILD_MODE)/examples_provider.a out/$(BUILD_MODE)/libweave.so third_party/lib/libevhtp.a $(CXX) -o $@ $^ $(CFLAGS) $(daemon_common_flags) -out/$(BUILD_MODE)/weave_daemon_light : out/$(BUILD_MODE)/examples/daemon/light/light.o out/$(BUILD_MODE)/examples_provider.a out/$(BUILD_MODE)/libweave.so +out/$(BUILD_MODE)/weave_daemon_light : out/$(BUILD_MODE)/examples/daemon/light/light.o out/$(BUILD_MODE)/examples_provider.a out/$(BUILD_MODE)/libweave.so third_party/lib/libevhtp.a $(CXX) -o $@ $^ $(CFLAGS) $(daemon_common_flags) -out/$(BUILD_MODE)/weave_daemon_lock : out/$(BUILD_MODE)/examples/daemon/lock/lock.o out/$(BUILD_MODE)/examples_provider.a out/$(BUILD_MODE)/libweave.so +out/$(BUILD_MODE)/weave_daemon_lock : out/$(BUILD_MODE)/examples/daemon/lock/lock.o out/$(BUILD_MODE)/examples_provider.a out/$(BUILD_MODE)/libweave.so third_party/lib/libevhtp.a $(CXX) -o $@ $^ $(CFLAGS) $(daemon_common_flags) -out/$(BUILD_MODE)/weave_daemon_oven : out/$(BUILD_MODE)/examples/daemon/oven/oven.o out/$(BUILD_MODE)/examples_provider.a out/$(BUILD_MODE)/libweave.so +out/$(BUILD_MODE)/weave_daemon_oven : out/$(BUILD_MODE)/examples/daemon/oven/oven.o out/$(BUILD_MODE)/examples_provider.a out/$(BUILD_MODE)/libweave.so third_party/lib/libevhtp.a $(CXX) -o $@ $^ $(CFLAGS) $(daemon_common_flags) -out/$(BUILD_MODE)/weave_daemon_sample : out/$(BUILD_MODE)/examples/daemon/sample/sample.o out/$(BUILD_MODE)/examples_provider.a out/$(BUILD_MODE)/libweave.so +out/$(BUILD_MODE)/weave_daemon_sample : out/$(BUILD_MODE)/examples/daemon/sample/sample.o out/$(BUILD_MODE)/examples_provider.a out/$(BUILD_MODE)/libweave.so third_party/lib/libevhtp.a $(CXX) -o $@ $^ $(CFLAGS) $(daemon_common_flags) -out/$(BUILD_MODE)/weave_daemon_speaker : out/$(BUILD_MODE)/examples/daemon/speaker/speaker.o out/$(BUILD_MODE)/examples_provider.a out/$(BUILD_MODE)/libweave.so +out/$(BUILD_MODE)/weave_daemon_speaker : out/$(BUILD_MODE)/examples/daemon/speaker/speaker.o out/$(BUILD_MODE)/examples_provider.a out/$(BUILD_MODE)/libweave.so third_party/lib/libevhtp.a $(CXX) -o $@ $^ $(CFLAGS) $(daemon_common_flags) all-examples : out/$(BUILD_MODE)/weave_daemon_ledflasher out/$(BUILD_MODE)/weave_daemon_light out/$(BUILD_MODE)/weave_daemon_lock out/$(BUILD_MODE)/weave_daemon_oven out/$(BUILD_MODE)/weave_daemon_sample out/$(BUILD_MODE)/weave_daemon_speaker diff --git a/examples/provider/event_deleter.h b/examples/provider/event_deleter.h index 078c326..9bb53f4 100644 --- a/examples/provider/event_deleter.h +++ b/examples/provider/event_deleter.h @@ -7,9 +7,10 @@ #include -#include -#include -#include +#include +#include +#include +#include namespace weave { namespace examples { @@ -18,9 +19,19 @@ namespace examples { // so we can use one unique_ptr definition for all of them class EventDeleter { public: - void operator()(evhttp_uri* http_uri) { evhttp_uri_free(http_uri); } - void operator()(evhttp_connection* conn) { evhttp_connection_free(conn); } - void operator()(evhttp_request* req) { evhttp_request_free(req); } + void operator()(evbuffer* buf) { evbuffer_free(buf); } + void operator()(evhtp_t* evhtp) { + if (evhtp->ssl_ctx) { + // Work around a double-free bug in recent versions of libevhtp. + // https://github.com/ellzey/libevhtp/pull/208 + SSL_CTX_free(evhtp->ssl_ctx); + evhtp->ssl_ctx = nullptr; + } + evhtp_unbind_socket(evhtp); + evhtp_free(evhtp); + } + void operator()(evhtp_connection_t* conn) { evhtp_connection_free(conn); } + void operator()(evhtp_request_t* req) { evhtp_request_free(req); } void operator()(event_base* base) { event_base_free(base); } void operator()(event* ev) { event_del(ev); diff --git a/examples/provider/event_http_server.cc b/examples/provider/event_http_server.cc index ae9833e..1bf58f6 100644 --- a/examples/provider/event_http_server.cc +++ b/examples/provider/event_http_server.cc @@ -9,6 +9,7 @@ #include #include #include +#include #include #include "examples/provider/event_task_runner.h" @@ -24,53 +25,45 @@ std::string GetSslError() { return error; } -bufferevent* BuffetEventCallback(event_base* base, void* arg) { - SSL_CTX* ctx = static_cast(arg); - return bufferevent_openssl_socket_new( - base, -1, SSL_new(ctx), BUFFEREVENT_SSL_ACCEPTING, BEV_OPT_CLOSE_ON_FREE); -} - } // namespace class HttpServerImpl::RequestImpl : public Request { public: - RequestImpl(evhttp_request* req) { - req_.reset(req); - uri_ = evhttp_request_get_evhttp_uri(req_.get()); - - data_.resize(evbuffer_get_length(req_->input_buffer)); - evbuffer_remove(req_->input_buffer, &data_[0], data_.size()); + RequestImpl(EventPtr req) : req_(std::move(req)) { + evbuf_t* input_buffer = + bufferevent_get_input(evhtp_request_get_bev(req_.get())); + data_.resize(evbuffer_get_length(input_buffer)); + evbuffer_remove(input_buffer, &data_[0], data_.size()); } ~RequestImpl() {} - std::string GetPath() const override { - const char* path = evhttp_uri_get_path(uri_); - return path ? path : ""; - } + std::string GetPath() const override { return req_->uri->path->path; } + std::string GetFirstHeader(const std::string& name) const override { - const char* header = evhttp_find_header(req_->input_headers, name.c_str()); + const char* header = evhtp_header_find(req_->headers_in, name.c_str()); if (!header) return {}; return header; } + std::string GetData() { return data_; } void SendReply(int status_code, const std::string& data, const std::string& mime_type) override { - std::unique_ptr buf{evbuffer_new(), - &evbuffer_free}; + EventPtr buf{evbuffer_new()}; evbuffer_add(buf.get(), data.data(), data.size()); - evhttp_add_header(req_->output_headers, "Content-Type", mime_type.c_str()); - evhttp_send_reply(req_.release(), status_code, "None", buf.get()); + evhtp_header_key_add(req_->headers_out, "Content-Type", 0); + evhtp_header_val_add(req_->headers_out, mime_type.c_str(), 1); + evhtp_send_reply_start(req_.get(), status_code); + evhtp_send_reply_body(req_.get(), buf.get()); + evhtp_send_reply_end(req_.get()); } private: - std::unique_ptr req_{ - nullptr, &evhttp_cancel_request}; + EventPtr req_; std::string data_; - const evhttp_uri* uri_{nullptr}; }; HttpServerImpl::HttpServerImpl(EventTaskRunner* task_runner) @@ -78,74 +71,75 @@ HttpServerImpl::HttpServerImpl(EventTaskRunner* task_runner) SSL_load_error_strings(); SSL_library_init(); - ctx_.reset(SSL_CTX_new(TLSv1_2_server_method())); - SSL_CTX_set_options(ctx_.get(), SSL_OP_SINGLE_DH_USE | - SSL_OP_SINGLE_ECDH_USE | SSL_OP_NO_SSLv2); - - ec_key_.reset(EC_KEY_new_by_curve_name(NID_X9_62_prime256v1)); - CHECK(ec_key_) << GetSslError(); - CHECK_EQ(1, SSL_CTX_set_tmp_ecdh(ctx_.get(), ec_key_.get())) << GetSslError(); - - GenerateX509(); - CHECK_EQ(1, SSL_CTX_use_PrivateKey(ctx_.get(), pkey_.get())) << GetSslError(); - CHECK_EQ(1, SSL_CTX_use_certificate(ctx_.get(), x509_.get())) - << GetSslError(); - - CHECK_EQ(1, SSL_CTX_check_private_key(ctx_.get())) << GetSslError(); - - httpd_.reset(evhttp_new(task_runner_->GetEventBase())); + std::unique_ptr ctx{ + SSL_CTX_new(TLSv1_2_server_method()), &SSL_CTX_free}; + CHECK(ctx); + SSL_CTX_set_options(ctx.get(), SSL_OP_SINGLE_DH_USE | SSL_OP_SINGLE_ECDH_USE | + SSL_OP_NO_SSLv2); + + std::unique_ptr ec_key{ + EC_KEY_new_by_curve_name(NID_X9_62_prime256v1), &EC_KEY_free}; + CHECK(ec_key) << GetSslError(); + CHECK_EQ(1, SSL_CTX_set_tmp_ecdh(ctx.get(), ec_key.get())) << GetSslError(); + + std::unique_ptr x509{X509_new(), &X509_free}; + CHECK(x509); + std::unique_ptr pkey{EVP_PKEY_new(), + &EVP_PKEY_free}; + CHECK(pkey); + GenerateX509(x509.get(), pkey.get()); + CHECK_EQ(1, SSL_CTX_use_PrivateKey(ctx.get(), pkey.get())) << GetSslError(); + CHECK_EQ(1, SSL_CTX_use_certificate(ctx.get(), x509.get())) << GetSslError(); + + CHECK_EQ(1, SSL_CTX_check_private_key(ctx.get())) << GetSslError(); + + httpd_.reset(evhtp_new(task_runner_->GetEventBase(), nullptr)); CHECK(httpd_); - httpsd_.reset(evhttp_new(task_runner_->GetEventBase())); + httpsd_.reset(evhtp_new(task_runner_->GetEventBase(), nullptr)); CHECK(httpsd_); - evhttp_set_bevcb(httpsd_.get(), BuffetEventCallback, ctx_.get()); + httpsd_.get()->ssl_ctx = ctx.release(); - CHECK_EQ(0, evhttp_bind_socket(httpd_.get(), "0.0.0.0", GetHttpPort())); - CHECK_EQ(0, evhttp_bind_socket(httpsd_.get(), "0.0.0.0", GetHttpsPort())); + CHECK_EQ(0, evhtp_bind_socket(httpd_.get(), "0.0.0.0", GetHttpPort(), -1)); + CHECK_EQ(0, evhtp_bind_socket(httpsd_.get(), "0.0.0.0", GetHttpsPort(), -1)); } -void HttpServerImpl::GenerateX509() { - x509_.reset(X509_new()); - CHECK(x509_) << GetSslError(); +void HttpServerImpl::GenerateX509(X509* x509, EVP_PKEY* pkey) { + CHECK(x509) << GetSslError(); - X509_set_version(x509_.get(), 2); + X509_set_version(x509, 2); - X509_gmtime_adj(X509_get_notBefore(x509_.get()), 0); - X509_gmtime_adj(X509_get_notAfter(x509_.get()), + X509_gmtime_adj(X509_get_notBefore(x509), 0); + X509_gmtime_adj(X509_get_notAfter(x509), base::TimeDelta::FromDays(365).InSeconds()); - pkey_.reset(EVP_PKEY_new()); - CHECK(pkey_) << GetSslError(); + CHECK(pkey) << GetSslError(); std::unique_ptr big_num(BN_new(), &BN_free); CHECK(BN_set_word(big_num.get(), 65537)) << GetSslError(); auto rsa = RSA_new(); RSA_generate_key_ex(rsa, 2048, big_num.get(), nullptr); - CHECK(EVP_PKEY_assign_RSA(pkey_.get(), rsa)) << GetSslError(); + CHECK(EVP_PKEY_assign_RSA(pkey, rsa)) << GetSslError(); - X509_set_pubkey(x509_.get(), pkey_.get()); + X509_set_pubkey(x509, pkey); - CHECK(X509_sign(x509_.get(), pkey_.get(), EVP_sha256())) << GetSslError(); + CHECK(X509_sign(x509, pkey, EVP_sha256())) << GetSslError(); cert_fingerprint_.resize(EVP_MD_size(EVP_sha256())); uint32_t len = 0; - CHECK(X509_digest(x509_.get(), EVP_sha256(), cert_fingerprint_.data(), &len)); + CHECK(X509_digest(x509, EVP_sha256(), cert_fingerprint_.data(), &len)); CHECK_EQ(len, cert_fingerprint_.size()); } -void HttpServerImpl::ProcessRequestCallback(evhttp_request* req, void* arg) { - static_cast(arg)->ProcessRequest(req); -} - -void HttpServerImpl::NotFound(evhttp_request* req) { - std::unique_ptr buf{evbuffer_new(), - &evbuffer_free}; - evbuffer_add_printf(buf.get(), "404 Not Found: %s\n", - evhttp_request_uri(req)); - evhttp_send_reply(req, 404, "Not Found", buf.get()); +void HttpServerImpl::NotFound(evhtp_request_t* req) { + EventPtr buf{evbuffer_new()}; + evbuffer_add_printf(buf.get(), "404 Not Found: %s\n", req->uri->path->path); + evhtp_send_reply_start(req, 404); + evhtp_send_reply_body(req, buf.get()); + evhtp_send_reply_end(req); } -void HttpServerImpl::ProcessRequest(evhttp_request* req) { - std::unique_ptr request{new RequestImpl{req}}; +void HttpServerImpl::ProcessRequest(evhtp_request_t* req) { + std::unique_ptr request{new RequestImpl{EventPtr{req}}}; std::string path = request->GetPath(); auto it = handlers_.find(path); if (it != handlers_.end()) { @@ -154,25 +148,29 @@ void HttpServerImpl::ProcessRequest(evhttp_request* req) { NotFound(req); } -void HttpServerImpl::ProcessReply(std::shared_ptr request, - int status_code, - const std::string& data, - const std::string& mime_type) {} +void HttpServerImpl::ProcessRequestCallback(evhtp_request_t* req, void* arg) { + static_cast(arg)->ProcessRequest(req); +} void HttpServerImpl::AddHttpRequestHandler( const std::string& path, const RequestHandlerCallback& callback) { handlers_.insert(std::make_pair(path, callback)); - evhttp_set_cb(httpd_.get(), path.c_str(), &ProcessRequestCallback, this); + evhtp_set_cb(httpd_.get(), path.c_str(), &ProcessRequestCallback, this); } void HttpServerImpl::AddHttpsRequestHandler( const std::string& path, const RequestHandlerCallback& callback) { handlers_.insert(std::make_pair(path, callback)); - evhttp_set_cb(httpsd_.get(), path.c_str(), &ProcessRequestCallback, this); + evhtp_set_cb(httpsd_.get(), path.c_str(), &ProcessRequestCallback, this); } +void HttpServerImpl::ProcessReply(std::shared_ptr request, + int status_code, + const std::string& data, + const std::string& mime_type) {} + uint16_t HttpServerImpl::GetHttpPort() const { return 7780; } diff --git a/examples/provider/event_http_server.h b/examples/provider/event_http_server.h index 950e536..8bb5dd9 100644 --- a/examples/provider/event_http_server.h +++ b/examples/provider/event_http_server.h @@ -5,8 +5,7 @@ #ifndef LIBWEAVE_EXAMPLES_PROVIDER_EVENT_HTTP_SERVER_H_ #define LIBWEAVE_EXAMPLES_PROVIDER_EVENT_HTTP_SERVER_H_ -#include -#include +#include #include #include @@ -16,12 +15,14 @@ #include #include +#include "examples/provider/event_deleter.h" + namespace weave { namespace examples { class EventTaskRunner; -// HTTP/HTTPS server implemented with libevent. +// HTTP/HTTPS server implemented with libevhtp. class HttpServerImpl : public provider::HttpServer { public: class RequestImpl; @@ -38,32 +39,21 @@ class HttpServerImpl : public provider::HttpServer { std::vector GetHttpsCertificateFingerprint() const override; private: - void GenerateX509(); - static void ProcessRequestCallback(evhttp_request* req, void* arg); - void ProcessRequest(evhttp_request* req); + void GenerateX509(X509* x509, EVP_PKEY* pkey); + static void ProcessRequestCallback(evhtp_request_t* req, void* arg); + void ProcessRequest(evhtp_request_t* req); void ProcessReply(std::shared_ptr request, int status_code, const std::string& data, const std::string& mime_type); - void NotFound(evhttp_request* req); + void NotFound(evhtp_request_t* req); std::map handlers_; - std::unique_ptr ec_key_{nullptr, - &EC_KEY_free}; - - std::unique_ptr pkey_{nullptr, - &EVP_PKEY_free}; - - std::unique_ptr x509_{nullptr, &X509_free}; - - std::unique_ptr ctx_{nullptr, - &SSL_CTX_free}; std::vector cert_fingerprint_; EventTaskRunner* task_runner_{nullptr}; - std::unique_ptr httpd_{nullptr, &evhttp_free}; - std::unique_ptr httpsd_{nullptr, - &evhttp_free}; + EventPtr httpd_; + EventPtr httpsd_; base::WeakPtrFactory weak_ptr_factory_{this}; }; diff --git a/examples/provider/event_task_runner.cc b/examples/provider/event_task_runner.cc index 1d94612..a86ffff 100644 --- a/examples/provider/event_task_runner.cc +++ b/examples/provider/event_task_runner.cc @@ -31,7 +31,9 @@ void EventTaskRunner::AddIoCompletionTask( int16_t flags = EV_PERSIST | EV_ET; flags |= (what & kReadable) ? EV_READ : 0; flags |= (what & kWriteable) ? EV_WRITE : 0; +#if LIBEVENT_VERSION_NUMBER >= 0x02010400 flags |= (what & kClosed) ? EV_CLOSED : 0; +#endif event* ioevent = event_new(base_.get(), fd, flags, FdEventHandler, this); EventPtr ioeventPtr{ioevent}; fd_task_map_.insert( @@ -53,7 +55,9 @@ void EventTaskRunner::Run() { sigfillset(&sa.sa_mask); sigaction(SIGINT, &sa, nullptr); - event_base_loop(g_event_base, EVLOOP_NO_EXIT_ON_EMPTY); + do { + event_base_loop(g_event_base, EVLOOP_ONCE); + } while (!event_base_got_exit(g_event_base)); g_event_base = nullptr; } diff --git a/third_party/get_libevent.sh b/third_party/get_libevent.sh deleted file mode 100755 index 9985bc0..0000000 --- a/third_party/get_libevent.sh +++ /dev/null @@ -1,29 +0,0 @@ -#!/bin/bash -# Copyright 2015 The Weave Authors. All rights reserved. -# Use of this source code is governed by a BSD-style license that can be -# found in the LICENSE file. - -# Make libevent. -# Example uses libevent to implement HTTPS server. This capability is -# available only in version 2.1.x-alpha. Step could be replaced with apt-get -# in future. -cd $(dirname "$0") -THIRD_PARTY=$(pwd) - -mkdir -p include lib - -rm -rf $THIRD_PARTY/libevent -git clone https://github.com/libevent/libevent.git || exit 1 -cd libevent || exit 1 - -./autogen.sh || exit 1 -./configure --disable-shared || exit 1 -make || exit 1 -if [ -z "$DISABLE_LIBEVENT_TEST" ]; then - echo -e "\n\nTesting libevent...\nCan take several minutes.\n" - make verify || exit 1 -fi -cp -rf include/*.h include/event2 $THIRD_PARTY/include/ || exit 1 -cp -f .libs/lib* $THIRD_PARTY/lib/ || exit 1 - -rm -rf $THIRD_PARTY/libevent diff --git a/third_party/get_libevhtp.sh b/third_party/get_libevhtp.sh new file mode 100755 index 0000000..c270813 --- /dev/null +++ b/third_party/get_libevhtp.sh @@ -0,0 +1,25 @@ +#!/bin/bash +# Copyright 2016 The Weave Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +# Make libevhtp. +# Example uses libevhtp to implement HTTPS server. This step could be +# replaced with apt-get in future (Debian jessie, Ubuntu vivid). +cd $(dirname "$0") +THIRD_PARTY=$(pwd) + +mkdir -p include lib + +rm -rf $THIRD_PARTY/libevhtp +curl -L https://github.com/ellzey/libevhtp/archive/1.2.10.tar.gz | tar xz || exit 1 +mv libevhtp-1.2.10 $THIRD_PARTY/libevhtp || exit 1 +cd $THIRD_PARTY/libevhtp || exit 1 + +cmake -D EVHTP_DISABLE_REGEX:BOOL=ON . || exit 1 +make evhtp || exit 1 + +cp -rf evhtp-config.h evhtp.h evthr/evthr.h htparse/htparse.h $THIRD_PARTY/include/ || exit 1 +cp -f libevhtp.a $THIRD_PARTY/lib/ || exit 1 + +rm -rf $THIRD_PARTY/libevhtp diff --git a/third_party/third_party.mk b/third_party/third_party.mk index 8a11e2d..7f651a2 100644 --- a/third_party/third_party.mk +++ b/third_party/third_party.mk @@ -64,15 +64,15 @@ clean-gtest : rm -rf third_party/googletest ### -# libevent (third_party, downloaded on build) - -third_party/include/event2/event.h : - @echo Downloading and building libevent... - DISABLE_LIBEVENT_TEST=1 third_party/get_libevent.sh - @echo Finished downloading and building libevent. - -clean-libevent : - rm -rf third_party/include/ev* third_party/include/event2 - rm -rf third_party/lib/libevent* - rm -rf third_party/libevent - +# libevhtp (third_party, downloaded on build) + +third_party/lib/libevhtp.a : third_party/include/evhtp.h +third_party/include/evhtp.h : + @echo Downloading and building libevhtp... + third_party/get_libevhtp.sh + @echo Finished downloading and building libevhtp. + +clean-libevhtp : + rm -rf third_party/include/evhtp.h third_party/include/evhtp-config.h third_party/include/evthr.h third_party/include/htparse.h + rm -rf third_party/lib/libevhtp.a + rm -rf third_party/libevhtp -- cgit v1.2.3 From c3d77144acaf4ac88ee3db5ce27d5a31ed3b8750 Mon Sep 17 00:00:00 2001 From: Jacob Marble Date: Mon, 1 Feb 2016 12:30:57 -0800 Subject: Make default Makefile target "all". Change-Id: I6b020876586fdbcf2952e4fddee86353d62b9ad0 Reviewed-on: https://weave-review.googlesource.com/2432 Reviewed-by: Alex Vakulenko --- Makefile | 1 + README.md | 11 +++++------ 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/Makefile b/Makefile index 6fd30f5..df27b58 100644 --- a/Makefile +++ b/Makefile @@ -104,4 +104,5 @@ clean : cleanall : clean clean-gtest clean-libevhtp .PHONY : clean cleanall all +.DEFAULT_GOAL := all diff --git a/README.md b/README.md index fc042b7..a0dc2e7 100644 --- a/README.md +++ b/README.md @@ -80,17 +80,16 @@ sudo apt-get install autoconf automake binutils g++ hostapd libavahi-client-dev The `make --jobs/-j` flag is encouraged, to speed up build time. For example ``` -make all -j +make -j ``` -### Build library - -``` -make +which happens to be the same as ``` +make all -j +```` -or +### Build library ``` make out/Debug/libweave.so -- cgit v1.2.3 From d9e30616f9948fa77b763efec739e97c7fe031e5 Mon Sep 17 00:00:00 2001 From: Jacob Marble Date: Mon, 1 Feb 2016 12:22:21 -0800 Subject: Add libevent-dev to README. Bug: 26906928 Change-Id: Ia4ca1b77c342b9e9a2d21daebb75659a7ff3fa48 Reviewed-on: https://weave-review.googlesource.com/2430 Reviewed-by: Jacob Marble --- README.md | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index a0dc2e7..211033c 100644 --- a/README.md +++ b/README.md @@ -49,7 +49,20 @@ repo sync ``` sudo apt-get update -sudo apt-get install autoconf automake binutils g++ hostapd libavahi-client-dev libcurl4-openssl-dev libexpat1-dev libnl-3-dev libnl-route-3-dev libssl-dev libtool +sudo apt-get install \ + autoconf \ + automake \ + binutils \ + g++ \ + hostapd \ + libavahi-client-dev \ + libcurl4-openssl-dev \ + libevent-dev \ + libexpat1-dev \ + libnl-3-dev \ + libnl-route-3-dev \ + libssl-dev \ + libtool ``` # Prerequisites @@ -72,7 +85,8 @@ sudo apt-get install autoconf automake binutils g++ hostapd libavahi-client-dev - hostapd - libavahi-client-dev - libcurl4-openssl-dev - - libevent 2.1.x-alpha (included; see third_party/get_libevent.sh) + - libevent 2.0.x + - libevhtp (included; see third_party/get_libevhtp.sh) # Compiling -- cgit v1.2.3 From ebfa60b581c3bd2d949e0af01abf761d83e802cf Mon Sep 17 00:00:00 2001 From: Alex Vakulenko Date: Mon, 1 Feb 2016 11:52:30 -0800 Subject: Add a unit tests for deleting CloudCommandProxy along with CommandInstance When CommandInstance is deleted, it should trigger destruction of associated CloudCommandProxy. Add a unit test to confirm this is the case. BUG: 25707196 Change-Id: I95cadf60e99302d236f1bc67782b7315efcec6d6 Reviewed-on: https://weave-review.googlesource.com/2427 Reviewed-by: Vitaly Buka --- src/commands/cloud_command_proxy.h | 2 +- src/commands/cloud_command_proxy_unittest.cc | 41 ++++++++++++++++++++++++++-- 2 files changed, 40 insertions(+), 3 deletions(-) diff --git a/src/commands/cloud_command_proxy.h b/src/commands/cloud_command_proxy.h index 13f4654..80efd70 100644 --- a/src/commands/cloud_command_proxy.h +++ b/src/commands/cloud_command_proxy.h @@ -29,7 +29,7 @@ class TaskRunner; } // Command proxy which publishes command updates to the cloud. -class CloudCommandProxy final : public CommandInstance::Observer { +class CloudCommandProxy : public CommandInstance::Observer { public: CloudCommandProxy(CommandInstance* command_instance, CloudCommandUpdateInterface* cloud_command_updater, diff --git a/src/commands/cloud_command_proxy_unittest.cc b/src/commands/cloud_command_proxy_unittest.cc index 013769d..0de67fe 100644 --- a/src/commands/cloud_command_proxy_unittest.cc +++ b/src/commands/cloud_command_proxy_unittest.cc @@ -7,6 +7,7 @@ #include #include +#include #include #include #include @@ -16,6 +17,7 @@ #include "src/mock_component_manager.h" using testing::_; +using testing::AnyNumber; using testing::DoAll; using testing::Invoke; using testing::Return; @@ -62,6 +64,27 @@ class TestBackoffEntry : public BackoffEntry { base::Time creation_time_; }; +class CloudCommandProxyWrapper : public CloudCommandProxy { + public: + CloudCommandProxyWrapper(CommandInstance* command_instance, + CloudCommandUpdateInterface* cloud_command_updater, + ComponentManager* component_manager, + std::unique_ptr backoff_entry, + provider::TaskRunner* task_runner, + const base::Closure& destruct_callback) + : CloudCommandProxy{command_instance, cloud_command_updater, + component_manager, std::move(backoff_entry), + task_runner}, + destruct_callback_{destruct_callback} {} + + ~CloudCommandProxyWrapper() { + destruct_callback_.Run(); + } + + private: + base::Closure destruct_callback_; +}; + class CloudCommandProxyTest : public ::testing::Test { protected: void SetUp() override { @@ -100,15 +123,21 @@ class CloudCommandProxyTest : public ::testing::Test { new TestBackoffEntry{&policy, task_runner_.GetClock()}}; // Finally construct the CloudCommandProxy we are going to test here. - std::unique_ptr proxy{new CloudCommandProxy{ + std::unique_ptr proxy{new CloudCommandProxyWrapper{ command_instance_.get(), &cloud_updater_, &component_manager_, - std::move(backoff), &task_runner_}}; + std::move(backoff), &task_runner_, + base::Bind(&CloudCommandProxyTest::OnProxyDestroyed, + base::Unretained(this))}}; // CloudCommandProxy::CloudCommandProxy() subscribe itself to weave::Command // notifications. When weave::Command is being destroyed it sends // ::OnCommandDestroyed() and CloudCommandProxy deletes itself. proxy.release(); + + EXPECT_CALL(*this, OnProxyDestroyed()).Times(AnyNumber()); } + MOCK_METHOD0(OnProxyDestroyed, void()); + ComponentManager::UpdateID current_state_update_id_{0}; base::CallbackList callbacks_; testing::StrictMock cloud_updater_; @@ -120,6 +149,14 @@ class CloudCommandProxyTest : public ::testing::Test { } // anonymous namespace +TEST_F(CloudCommandProxyTest, EnsureDestroyed) { + EXPECT_CALL(*this, OnProxyDestroyed()).Times(1); + command_instance_.reset(); + // Verify that CloudCommandProxy has been destroyed already and not at some + // point during the destruction of CloudCommandProxyTest class. + testing::Mock::VerifyAndClearExpectations(this); +} + TEST_F(CloudCommandProxyTest, ImmediateUpdate) { const char expected[] = "{'state':'done'}"; EXPECT_CALL(cloud_updater_, UpdateCommand(kCmdID, MatchJson(expected), _)); -- cgit v1.2.3 From c920bb27fd72b4dec235ce6831bb2258f8fd5da1 Mon Sep 17 00:00:00 2001 From: Alex Vakulenko Date: Mon, 1 Feb 2016 11:54:23 -0800 Subject: Fix memory leak when removing CommandInstance from CommandQueue The observers for CommandInstance were forcefully cleared in CommandInstance::DetachFromQueue which caused failure of invoking CommandInstance::Observer::OnCommandDestroyed() and, as a result, CloudCommandProxy::OnCommandDestroyed was not called which caused leaking CloudCommandProxy object instance. BUG: 25707196 Change-Id: I119a67efce4968ffaa528632e77045265b8e8f2b Reviewed-on: https://weave-review.googlesource.com/2428 Reviewed-by: Vitaly Buka --- src/commands/command_instance.h | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/commands/command_instance.h b/src/commands/command_instance.h index b1028d0..febe5c5 100644 --- a/src/commands/command_instance.h +++ b/src/commands/command_instance.h @@ -89,10 +89,7 @@ class CommandInstance final : public Command { // Sets the pointer to queue this command is part of. void AttachToQueue(CommandQueue* queue) { queue_ = queue; } - void DetachFromQueue() { - observers_.Clear(); - queue_ = nullptr; - } + void DetachFromQueue() { queue_ = nullptr; } private: // Helper function to update the command status. -- cgit v1.2.3 From 329ad806d155a45f5450f998801b5ca16351bc88 Mon Sep 17 00:00:00 2001 From: Alex Vakulenko Date: Mon, 1 Feb 2016 12:11:30 -0800 Subject: Rename CommandQueue::DelayedRemove into RemoveLater() Changed the method name to be more consistent with similar primitives of base/ (e.g. MessageLoop::DeleteSoon). Change-Id: I4038e3a77c014e0adf83a44baf770c834246b5a1 Reviewed-on: https://weave-review.googlesource.com/2429 Reviewed-by: Vitaly Buka --- src/commands/command_instance.cc | 2 +- src/commands/command_queue.cc | 2 +- src/commands/command_queue.h | 2 +- src/commands/command_queue_unittest.cc | 4 ++-- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/commands/command_instance.cc b/src/commands/command_instance.cc index fc9b0e7..590bbb1 100644 --- a/src/commands/command_instance.cc +++ b/src/commands/command_instance.cc @@ -284,7 +284,7 @@ bool CommandInstance::SetStatus(Command::State status, ErrorPtr* error) { void CommandInstance::RemoveFromQueue() { if (queue_) - queue_->DelayedRemove(GetID()); + queue_->RemoveLater(GetID()); } } // namespace weave diff --git a/src/commands/command_queue.cc b/src/commands/command_queue.cc index 134dc1c..cdb251f 100644 --- a/src/commands/command_queue.cc +++ b/src/commands/command_queue.cc @@ -88,7 +88,7 @@ void CommandQueue::Add(std::unique_ptr instance) { Cleanup(); } -void CommandQueue::DelayedRemove(const std::string& id) { +void CommandQueue::RemoveLater(const std::string& id) { auto p = map_.find(id); if (p == map_.end()) return; diff --git a/src/commands/command_queue.h b/src/commands/command_queue.h index 0f0a18b..01839d8 100644 --- a/src/commands/command_queue.h +++ b/src/commands/command_queue.h @@ -51,7 +51,7 @@ class CommandQueue final { // Selects command identified by |id| ready for removal. Command will actually // be removed after some time. - void DelayedRemove(const std::string& id); + void RemoveLater(const std::string& id); // Finds a command instance in the queue by the instance |id|. Returns // nullptr if the command with the given |id| is not found. The returned diff --git a/src/commands/command_queue_unittest.cc b/src/commands/command_queue_unittest.cc index b4c5938..fdb9e81 100644 --- a/src/commands/command_queue_unittest.cc +++ b/src/commands/command_queue_unittest.cc @@ -105,12 +105,12 @@ TEST_F(CommandQueueTest, Remove) { EXPECT_TRUE(queue_.IsEmpty()); } -TEST_F(CommandQueueTest, DelayedRemove) { +TEST_F(CommandQueueTest, RemoveLater) { const std::string id1 = "id1"; queue_.Add(CreateDummyCommandInstance("base.reboot", id1)); EXPECT_EQ(1u, queue_.GetCount()); - queue_.DelayedRemove(id1); + queue_.RemoveLater(id1); EXPECT_EQ(1u, queue_.GetCount()); Cleanup(base::TimeDelta::FromMinutes(1)); -- cgit v1.2.3 From 6a1ba84d9b295dcc0c8f50b580182a665c4aa8ce Mon Sep 17 00:00:00 2001 From: Vitaly Buka Date: Mon, 1 Feb 2016 14:41:45 -0800 Subject: Changed meaning of some SSID flags Added "WiFi 2.4Ghz" support flag. Added "WiFi 5.0Ghz" support flag. Make "WiFi Setup" flag more aggressive, (!online && !configured). BUG: 26570030 BUG: 25820726 BUG: 22558499 Change-Id: I6fedc6abe863ab1de40ad5b0763ece2369b61c06 Reviewed-on: https://weave-review.googlesource.com/2436 Reviewed-by: Vitaly Buka --- examples/provider/wifi_manager.h | 2 ++ include/weave/provider/test/mock_wifi.h | 2 ++ include/weave/provider/wifi.h | 3 +++ src/privet/wifi_bootstrap_manager.cc | 16 +++++++++++++--- src/privet/wifi_ssid_generator.cc | 17 ++++++++++++----- src/privet/wifi_ssid_generator.h | 2 +- src/privet/wifi_ssid_generator_unittest.cc | 28 ++++++++++++++++------------ src/weave_unittest.cc | 5 ++++- 8 files changed, 53 insertions(+), 22 deletions(-) diff --git a/examples/provider/wifi_manager.h b/examples/provider/wifi_manager.h index 2bfc5ca..72f54df 100644 --- a/examples/provider/wifi_manager.h +++ b/examples/provider/wifi_manager.h @@ -35,6 +35,8 @@ class WifiImpl : public provider::Wifi { const DoneCallback& callback) override; void StartAccessPoint(const std::string& ssid) override; void StopAccessPoint() override; + bool IsWifi24Supported() const override {return true;}; + bool IsWifi50Supported() const override {return false;}; static bool HasWifiCapability(); diff --git a/include/weave/provider/test/mock_wifi.h b/include/weave/provider/test/mock_wifi.h index 9fbe10f..7ede55e 100644 --- a/include/weave/provider/test/mock_wifi.h +++ b/include/weave/provider/test/mock_wifi.h @@ -23,6 +23,8 @@ class MockWifi : public Wifi { const DoneCallback&)); MOCK_METHOD1(StartAccessPoint, void(const std::string&)); MOCK_METHOD0(StopAccessPoint, void()); + MOCK_CONST_METHOD0(IsWifi24Supported, bool()); + MOCK_CONST_METHOD0(IsWifi50Supported, bool()); }; } // namespace test diff --git a/include/weave/provider/wifi.h b/include/weave/provider/wifi.h index 48ac651..9c7cfca 100644 --- a/include/weave/provider/wifi.h +++ b/include/weave/provider/wifi.h @@ -28,6 +28,9 @@ class Wifi { // Stops WiFi access point. virtual void StopAccessPoint() = 0; + virtual bool IsWifi24Supported() const = 0; + virtual bool IsWifi50Supported() const = 0; + protected: virtual ~Wifi() {} }; diff --git a/src/privet/wifi_bootstrap_manager.cc b/src/privet/wifi_bootstrap_manager.cc index 566da80..ce2016a 100644 --- a/src/privet/wifi_bootstrap_manager.cc +++ b/src/privet/wifi_bootstrap_manager.cc @@ -204,8 +204,12 @@ std::string WifiBootstrapManager::GetHostedSsid() const { } std::set WifiBootstrapManager::GetTypes() const { - // TODO(wiley) This should do some system work to figure this out. - return {WifiType::kWifi24}; + std::set result; + if (wifi_->IsWifi24Supported()) + result.insert(WifiType::kWifi24); + if (wifi_->IsWifi50Supported()) + result.insert(WifiType::kWifi50); + return result; } void WifiBootstrapManager::OnConnectDone(const std::string& ssid, @@ -255,9 +259,15 @@ void WifiBootstrapManager::OnMonitorTimeout() { void WifiBootstrapManager::UpdateConnectionState() { connection_state_ = ConnectionState{ConnectionState::kUnconfigured}; - Network::State service_state{network_->GetConnectionState()}; VLOG(3) << "New network state: " << EnumToString(service_state); + + // TODO: Make it true wifi state, currently it's rather online state. + if (service_state != Network::State::kOnline && + config_->GetSettings().last_configured_ssid.empty()) { + return; + } + switch (service_state) { case Network::State::kOffline: connection_state_ = ConnectionState{ConnectionState::kOffline}; diff --git a/src/privet/wifi_ssid_generator.cc b/src/privet/wifi_ssid_generator.cc index 697e5d8..4ad1602 100644 --- a/src/privet/wifi_ssid_generator.cc +++ b/src/privet/wifi_ssid_generator.cc @@ -52,20 +52,27 @@ WifiSsidGenerator::WifiSsidGenerator(const CloudDelegate* cloud, } std::string WifiSsidGenerator::GenerateFlags() const { - return GenerateFlagsInternal(false); + return GenerateFlagsInternal(); } -std::string WifiSsidGenerator::GenerateFlagsInternal(bool for_ssid) const { +std::string WifiSsidGenerator::GenerateFlagsInternal() const { std::bitset<6> flags1; // Device needs WiFi configuration. flags1[0] = wifi_ && IsSetupNeeded(wifi_->GetConnectionState()); + // Device needs GCD registration. flags1[1] = IsSetupNeeded(gcd_->GetConnectionState()); std::bitset<6> flags2; - // Device is discoverable over WiFi. - flags2[0] = for_ssid || (wifi_ && !wifi_->GetHostedSsid().empty()); + if (wifi_) { + std::set types = wifi_->GetTypes(); + // Device supports 2.4Ghz WiFi networks. + flags2[0] = types.find(WifiType::kWifi24) != types.end(); + + // Device supports 5.0Ghz WiFi networks. + flags2[1] = types.find(WifiType::kWifi50) != types.end(); + } std::string result{2, base64chars[0]}; result[0] = base64chars[flags1.to_ulong()]; @@ -82,7 +89,7 @@ std::string WifiSsidGenerator::GenerateSsid() const { std::string result = base::StringPrintf(kSsidFormat, name.c_str(), idx.c_str(), - model_id.c_str(), GenerateFlagsInternal(true).c_str()); + model_id.c_str(), GenerateFlagsInternal().c_str()); CHECK_EQ(result[result.size() - 11], '.'); return result; } diff --git a/src/privet/wifi_ssid_generator.h b/src/privet/wifi_ssid_generator.h index 2b86f28..1197e73 100644 --- a/src/privet/wifi_ssid_generator.h +++ b/src/privet/wifi_ssid_generator.h @@ -30,7 +30,7 @@ class WifiSsidGenerator final { // Sets object to use |n| instead of random number for SSID generation. void SetRandomForTests(int n); - std::string GenerateFlagsInternal(bool for_ssid) const; + std::string GenerateFlagsInternal() const; const CloudDelegate* gcd_{nullptr}; const WifiDelegate* wifi_{nullptr}; diff --git a/src/privet/wifi_ssid_generator_unittest.cc b/src/privet/wifi_ssid_generator_unittest.cc index 10680c8..406576d 100644 --- a/src/privet/wifi_ssid_generator_unittest.cc +++ b/src/privet/wifi_ssid_generator_unittest.cc @@ -22,40 +22,44 @@ class WifiSsidGeneratorTest : public testing::Test { WifiSsidGenerator ssid_generator_{&gcd_, &wifi_}; }; -TEST_F(WifiSsidGeneratorTest, GenerateFlagsNoHostedAp) { +TEST_F(WifiSsidGeneratorTest, GenerateFlagsWithWifi24) { + EXPECT_CALL(wifi_, GetTypes()) + .WillRepeatedly(Return(std::set{WifiType::kWifi24})); + EXPECT_EQ(ssid_generator_.GenerateFlags().size(), 2u); wifi_.connection_state_ = ConnectionState{ConnectionState::kUnconfigured}; gcd_.connection_state_ = ConnectionState{ConnectionState::kUnconfigured}; - EXPECT_EQ("DA", ssid_generator_.GenerateFlags()); + EXPECT_EQ("DB", ssid_generator_.GenerateFlags()); wifi_.connection_state_ = ConnectionState{ConnectionState::kOnline}; - EXPECT_EQ("CA", ssid_generator_.GenerateFlags()); + EXPECT_EQ("CB", ssid_generator_.GenerateFlags()); gcd_.connection_state_ = ConnectionState{ConnectionState::kOffline}; - EXPECT_EQ("AA", ssid_generator_.GenerateFlags()); + EXPECT_EQ("AB", ssid_generator_.GenerateFlags()); wifi_.connection_state_ = ConnectionState{ConnectionState::kUnconfigured}; - EXPECT_EQ("BA", ssid_generator_.GenerateFlags()); + EXPECT_EQ("BB", ssid_generator_.GenerateFlags()); } -TEST_F(WifiSsidGeneratorTest, GenerateFlagsWithHostedAp) { - EXPECT_CALL(wifi_, GetHostedSsid()) - .WillRepeatedly(Return(ssid_generator_.GenerateSsid())); +TEST_F(WifiSsidGeneratorTest, GenerateFlagsWithWifi50) { + EXPECT_CALL(wifi_, GetTypes()) + .WillRepeatedly(Return(std::set{WifiType::kWifi50})); + EXPECT_EQ(ssid_generator_.GenerateFlags().size(), 2u); wifi_.connection_state_ = ConnectionState{ConnectionState::kUnconfigured}; gcd_.connection_state_ = ConnectionState{ConnectionState::kUnconfigured}; - EXPECT_EQ("DB", ssid_generator_.GenerateFlags()); + EXPECT_EQ("DC", ssid_generator_.GenerateFlags()); wifi_.connection_state_ = ConnectionState{ConnectionState::kOnline}; - EXPECT_EQ("CB", ssid_generator_.GenerateFlags()); + EXPECT_EQ("CC", ssid_generator_.GenerateFlags()); gcd_.connection_state_ = ConnectionState{ConnectionState::kOffline}; - EXPECT_EQ("AB", ssid_generator_.GenerateFlags()); + EXPECT_EQ("AC", ssid_generator_.GenerateFlags()); wifi_.connection_state_ = ConnectionState{ConnectionState::kUnconfigured}; - EXPECT_EQ("BB", ssid_generator_.GenerateFlags()); + EXPECT_EQ("BC", ssid_generator_.GenerateFlags()); } TEST_F(WifiSsidGeneratorTest, GenerateSsid31orLess) { diff --git a/src/weave_unittest.cc b/src/weave_unittest.cc index ebc66cd..b300f57 100644 --- a/src/weave_unittest.cc +++ b/src/weave_unittest.cc @@ -181,7 +181,10 @@ std::set GetKeys(const Map& map) { class WeaveTest : public ::testing::Test { protected: - void SetUp() override {} + void SetUp() override { + EXPECT_CALL(wifi_, IsWifi24Supported()).WillRepeatedly(Return(true)); + EXPECT_CALL(wifi_, IsWifi50Supported()).WillRepeatedly(Return(false)); + } template void ExpectRequest(HttpClient::Method method, -- cgit v1.2.3 From 98d1fee994302f5e2ad7a7b60de2f2d74f35408b Mon Sep 17 00:00:00 2001 From: Alex Vakulenko Date: Mon, 1 Feb 2016 12:25:21 -0800 Subject: Periodicly clean up command queue and remove old processed commands Do periodic command queue cleanup to reclaim memory from commands that have been in terminal state for certain period of time (5 mins). Change-Id: Ief9cdbf023a222412c296644c9e927c4be000024 Reviewed-on: https://weave-review.googlesource.com/2434 Reviewed-by: Alex Vakulenko --- include/weave/provider/test/fake_task_runner.h | 1 + src/base_api_handler_unittest.cc | 4 +- src/commands/command_queue.cc | 38 +++++++++++------ src/commands/command_queue.h | 33 ++++++++++----- src/commands/command_queue_unittest.cc | 56 ++++++++++++++++++++++++-- src/component_manager_impl.cc | 6 ++- src/component_manager_impl.h | 3 +- src/component_manager_unittest.cc | 4 +- src/device_manager.cc | 2 +- src/device_registration_info_unittest.cc | 2 +- src/test/fake_task_runner.cc | 4 ++ 11 files changed, 119 insertions(+), 34 deletions(-) diff --git a/include/weave/provider/test/fake_task_runner.h b/include/weave/provider/test/fake_task_runner.h index bb79455..4080072 100644 --- a/include/weave/provider/test/fake_task_runner.h +++ b/include/weave/provider/test/fake_task_runner.h @@ -31,6 +31,7 @@ class FakeTaskRunner : public TaskRunner { void Run(size_t number_of_iterations = 1000); void Break(); base::Clock* GetClock(); + size_t GetTaskQueueSize() const; private: void SaveTask(const tracked_objects::Location& from_here, diff --git a/src/base_api_handler_unittest.cc b/src/base_api_handler_unittest.cc index 8b0f0b2..2a202d1 100644 --- a/src/base_api_handler_unittest.cc +++ b/src/base_api_handler_unittest.cc @@ -8,6 +8,7 @@ #include #include #include +#include #include #include #include @@ -93,7 +94,8 @@ class BaseApiHandlerTest : public ::testing::Test { Config config_{&config_store_}; StrictMock http_client_; std::unique_ptr dev_reg_; - ComponentManagerImpl component_manager_; + StrictMock task_runner_; + ComponentManagerImpl component_manager_{&task_runner_}; std::unique_ptr handler_; StrictMock device_; }; diff --git a/src/commands/command_queue.cc b/src/commands/command_queue.cc index cdb251f..f0d2228 100644 --- a/src/commands/command_queue.cc +++ b/src/commands/command_queue.cc @@ -18,6 +18,10 @@ std::string GetCommandHandlerKey(const std::string& component_path, } } +CommandQueue::CommandQueue(provider::TaskRunner* task_runner, + base::Clock* clock) + : task_runner_{task_runner}, clock_{clock} {} + void CommandQueue::AddCommandAddedCallback(const CommandCallback& callback) { on_command_added_.push_back(callback); // Send all pre-existed commands. @@ -84,18 +88,19 @@ void CommandQueue::Add(std::unique_ptr instance) { it_handler->second.Run(pair.first->second); else if (!default_command_callback_.is_null()) default_command_callback_.Run(pair.first->second); - - Cleanup(); } void CommandQueue::RemoveLater(const std::string& id) { auto p = map_.find(id); if (p == map_.end()) return; - remove_queue_.push(std::make_pair( - base::Time::Now() + base::TimeDelta::FromMinutes(kRemoveCommandDelayMin), - id)); - Cleanup(); + auto remove_delay = base::TimeDelta::FromMinutes(kRemoveCommandDelayMin); + remove_queue_.push(std::make_pair(clock_->Now() + remove_delay, id)); + if (remove_queue_.size() == 1) { + // The queue was empty, this is the first command to be removed, schedule + // a clean-up task. + ScheduleCleanup(remove_delay); + } } bool CommandQueue::Remove(const std::string& id) { @@ -110,19 +115,26 @@ bool CommandQueue::Remove(const std::string& id) { return true; } -void CommandQueue::Cleanup() { - while (!remove_queue_.empty() && remove_queue_.front().first < Now()) { - Remove(remove_queue_.front().second); +void CommandQueue::Cleanup(const base::Time& cutoff_time) { + while (!remove_queue_.empty() && remove_queue_.top().first <= cutoff_time) { + Remove(remove_queue_.top().second); remove_queue_.pop(); } } -void CommandQueue::SetNowForTest(base::Time now) { - test_now_ = now; +void CommandQueue::ScheduleCleanup(base::TimeDelta delay) { + task_runner_->PostDelayedTask( + FROM_HERE, + base::Bind(&CommandQueue::PerformScheduledCleanup, + weak_ptr_factory_.GetWeakPtr()), + delay); } -base::Time CommandQueue::Now() const { - return test_now_.is_null() ? base::Time::Now() : test_now_; +void CommandQueue::PerformScheduledCleanup() { + base::Time now = clock_->Now(); + Cleanup(now); + if (!remove_queue_.empty()) + ScheduleCleanup(remove_queue_.top().first - now); } CommandInstance* CommandQueue::Find(const std::string& id) const { diff --git a/src/commands/command_queue.h b/src/commands/command_queue.h index 01839d8..a092c12 100644 --- a/src/commands/command_queue.h +++ b/src/commands/command_queue.h @@ -14,8 +14,10 @@ #include #include +#include #include #include +#include #include "src/commands/command_instance.h" @@ -23,7 +25,7 @@ namespace weave { class CommandQueue final { public: - CommandQueue() = default; + CommandQueue(provider::TaskRunner* task_runner, base::Clock* clock); // TODO: Remove AddCommandAddedCallback and AddCommandRemovedCallback. using CommandCallback = base::Callback; @@ -64,23 +66,29 @@ class CommandQueue final { // Removes a command identified by |id| from the queue. bool Remove(const std::string& id); - // Removes old commands selected with DelayedRemove. - void Cleanup(); + // Removes old commands scheduled by RemoveLater() to be deleted after + // |cutoff_time|. + void Cleanup(const base::Time& cutoff_time); - // Overrides CommandQueue::Now() for tests. - void SetNowForTest(base::Time now); + // Schedule a cleanup task to be run after the specified |delay|. + void ScheduleCleanup(base::TimeDelta delay); - // Returns current time. - base::Time Now() const; + // Perform removal of scheduled commands (by calling Cleanup()) and scheduling + // another cleanup task if the removal queue is still not empty. + void PerformScheduledCleanup(); - // Overridden value to be returned from Now(). - base::Time test_now_; + provider::TaskRunner* task_runner_{nullptr}; + base::Clock* clock_{nullptr}; // ID-to-CommandInstance map. std::map> map_; - // Queue of commands to be removed. - std::queue> remove_queue_; + // Queue of commands to be removed, keeps them sorted by the timestamp + // (earliest first). This is done to tolerate system clock changes. + template + using InversePriorityQueue = + std::priority_queue, std::greater>; + InversePriorityQueue> remove_queue_; using CallbackList = std::vector; CallbackList on_command_added_; @@ -88,6 +96,9 @@ class CommandQueue final { std::map command_callbacks_; Device::CommandHandlerCallback default_command_callback_; + // WeakPtr factory for controlling the lifetime of command queue cleanup + // tasks. + base::WeakPtrFactory weak_ptr_factory_{this}; DISALLOW_COPY_AND_ASSIGN(CommandQueue); }; diff --git a/src/commands/command_queue_unittest.cc b/src/commands/command_queue_unittest.cc index fdb9e81..1e2e0ac 100644 --- a/src/commands/command_queue_unittest.cc +++ b/src/commands/command_queue_unittest.cc @@ -10,12 +10,18 @@ #include #include +#include #include +#include +#include "src/bind_lambda.h" #include "src/string_utils.h" namespace weave { +using testing::Return; +using testing::StrictMock; + class CommandQueueTest : public testing::Test { public: std::unique_ptr CreateDummyCommandInstance( @@ -30,11 +36,15 @@ class CommandQueueTest : public testing::Test { bool Remove(const std::string& id) { return queue_.Remove(id); } void Cleanup(const base::TimeDelta& interval) { - queue_.SetNowForTest(base::Time::Now() + interval); - return queue_.Cleanup(); + return queue_.Cleanup(task_runner_.GetClock()->Now() + interval); + } + + std::string GetFirstCommandToBeRemoved() const { + return queue_.remove_queue_.top().second; } - CommandQueue queue_; + StrictMock task_runner_; + CommandQueue queue_{&task_runner_, task_runner_.GetClock()}; }; // Keeps track of commands being added to and removed from the queue_. @@ -120,6 +130,46 @@ TEST_F(CommandQueueTest, RemoveLater) { EXPECT_EQ(0u, queue_.GetCount()); } +TEST_F(CommandQueueTest, RemoveLaterOnCleanupTask) { + const std::string id1 = "id1"; + queue_.Add(CreateDummyCommandInstance("base.reboot", id1)); + EXPECT_EQ(1u, queue_.GetCount()); + + queue_.RemoveLater(id1); + EXPECT_EQ(1u, queue_.GetCount()); + ASSERT_EQ(1u, task_runner_.GetTaskQueueSize()); + + task_runner_.RunOnce(); + + EXPECT_EQ(0u, queue_.GetCount()); + EXPECT_EQ(0u, task_runner_.GetTaskQueueSize()); +} + +TEST_F(CommandQueueTest, CleanupMultipleCommands) { + const std::string id1 = "id1"; + const std::string id2 = "id2"; + + queue_.Add(CreateDummyCommandInstance("base.reboot", id1)); + queue_.Add(CreateDummyCommandInstance("base.reboot", id2)); + auto remove_task = [this](const std::string& id) { queue_.RemoveLater(id); }; + remove_task(id1); + task_runner_.PostDelayedTask(FROM_HERE, base::Bind(remove_task, id2), + base::TimeDelta::FromSeconds(10)); + EXPECT_EQ(2u, queue_.GetCount()); + ASSERT_EQ(2u, task_runner_.GetTaskQueueSize()); + task_runner_.RunOnce(); // Executes "remove_task(id2) @ T+10s". + ASSERT_EQ(2u, queue_.GetCount()); + ASSERT_EQ(1u, task_runner_.GetTaskQueueSize()); + EXPECT_EQ(id1, GetFirstCommandToBeRemoved()); + task_runner_.RunOnce(); // Should remove task "id1" from queue. + ASSERT_EQ(1u, queue_.GetCount()); + ASSERT_EQ(1u, task_runner_.GetTaskQueueSize()); + EXPECT_EQ(id2, GetFirstCommandToBeRemoved()); + task_runner_.RunOnce(); // Should remove task "id2" from queue. + EXPECT_EQ(0u, queue_.GetCount()); + EXPECT_EQ(0u, task_runner_.GetTaskQueueSize()); +} + TEST_F(CommandQueueTest, Dispatch) { FakeDispatcher dispatch(&queue_); const std::string id1 = "id1"; diff --git a/src/component_manager_impl.cc b/src/component_manager_impl.cc index 550775d..dec4a48 100644 --- a/src/component_manager_impl.cc +++ b/src/component_manager_impl.cc @@ -31,8 +31,10 @@ template <> LIBWEAVE_EXPORT EnumToStringMap::EnumToStringMap() : EnumToStringMap(kMap) {} -ComponentManagerImpl::ComponentManagerImpl(base::Clock* clock) - : clock_{clock ? clock : &default_clock_} {} +ComponentManagerImpl::ComponentManagerImpl(provider::TaskRunner* task_runner, + base::Clock* clock) + : clock_{clock ? clock : &default_clock_}, + command_queue_{task_runner, clock_} {} ComponentManagerImpl::~ComponentManagerImpl() {} diff --git a/src/component_manager_impl.h b/src/component_manager_impl.h index 8c4ad16..f3c5451 100644 --- a/src/component_manager_impl.h +++ b/src/component_manager_impl.h @@ -15,7 +15,8 @@ namespace weave { class ComponentManagerImpl final : public ComponentManager { public: - explicit ComponentManagerImpl(base::Clock* clock = nullptr); + explicit ComponentManagerImpl(provider::TaskRunner* task_runner, + base::Clock* clock = nullptr); ~ComponentManagerImpl() override; // Loads trait definition schema. diff --git a/src/component_manager_unittest.cc b/src/component_manager_unittest.cc index 63fedac..97dc00d 100644 --- a/src/component_manager_unittest.cc +++ b/src/component_manager_unittest.cc @@ -7,6 +7,7 @@ #include #include +#include #include #include "src/bind_lambda.h" @@ -90,8 +91,9 @@ class ComponentManagerTest : public ::testing::Test { {"t5", "t6"}, nullptr)); } + StrictMock task_runner_; StrictMock clock_; - ComponentManagerImpl manager_{&clock_}; + ComponentManagerImpl manager_{&task_runner_, &clock_}; }; } // anonymous namespace diff --git a/src/device_manager.cc b/src/device_manager.cc index 04d7a6b..097f854 100644 --- a/src/device_manager.cc +++ b/src/device_manager.cc @@ -29,7 +29,7 @@ DeviceManager::DeviceManager(provider::ConfigStore* config_store, provider::Wifi* wifi, provider::Bluetooth* bluetooth) : config_{new Config{config_store}}, - component_manager_{new ComponentManagerImpl} { + component_manager_{new ComponentManagerImpl{task_runner}} { if (http_server) { auth_manager_.reset(new privet::AuthManager( config_.get(), http_server->GetHttpsCertificateFingerprint())); diff --git a/src/device_registration_info_unittest.cc b/src/device_registration_info_unittest.cc index cd11ac9..7908c8b 100644 --- a/src/device_registration_info_unittest.cc +++ b/src/device_registration_info_unittest.cc @@ -208,7 +208,7 @@ class DeviceRegistrationInfoTest : public ::testing::Test { {}, &clock_}; std::unique_ptr dev_reg_; - ComponentManagerImpl component_manager_; + ComponentManagerImpl component_manager_{&task_runner_}; }; TEST_F(DeviceRegistrationInfoTest, GetServiceURL) { diff --git a/src/test/fake_task_runner.cc b/src/test/fake_task_runner.cc index 88e078b..68d5e32 100644 --- a/src/test/fake_task_runner.cc +++ b/src/test/fake_task_runner.cc @@ -52,6 +52,10 @@ void FakeTaskRunner::PostDelayedTask(const tracked_objects::Location& from_here, queue_.emplace(std::make_pair(test_clock_->Now() + delay, ++counter_), task); } +size_t FakeTaskRunner::GetTaskQueueSize() const { + return queue_.size(); +} + } // namespace test } // namespace provider } // namespace weave -- cgit v1.2.3