diff options
author | Vitaly Buka <vitalybuka@google.com> | 2016-01-30 01:35:26 +0000 |
---|---|---|
committer | android-build-merger <android-build-merger@google.com> | 2016-01-30 01:35:26 +0000 |
commit | 2c074980c0aab9c25475e8291905769047731d33 (patch) | |
tree | 4794622a3f5869eb9fda027f152051a2618073e3 | |
parent | 355ac651275cd4258b8699228460b7ed3f4f61fe (diff) | |
parent | 9d187e6ddb3c0a570dd363c77cab2dc7f4966260 (diff) | |
download | libweave-2c074980c0aab9c25475e8291905769047731d33.tar.gz |
Merge remote-tracking branch \'weave/master\' into weave/aosp-master
am: 9d187e6ddb
* commit '9d187e6ddb3c0a570dd363c77cab2dc7f4966260':
Merge: Add write callback into SaveSettings function
Merge: Add |name| into LoadSettings/SaveSettings
Remove event_http_client example provider.
examples/provider/wifi_manager: find iface name
Update gtest
Include of gtest_prod.h only building unittests
-rw-r--r-- | Makefile | 8 | ||||
-rw-r--r-- | examples/daemon/common/daemon.h | 11 | ||||
-rw-r--r-- | examples/provider/event_http_client.cc | 145 | ||||
-rw-r--r-- | examples/provider/event_http_client.h | 38 | ||||
-rw-r--r-- | examples/provider/file_config_store.cc | 33 | ||||
-rw-r--r-- | examples/provider/file_config_store.h | 14 | ||||
-rw-r--r-- | examples/provider/wifi_manager.cc | 58 | ||||
-rw-r--r-- | examples/provider/wifi_manager.h | 1 | ||||
-rw-r--r-- | file_lists.mk | 1 | ||||
-rw-r--r-- | include/weave/provider/config_store.h | 26 | ||||
-rw-r--r-- | include/weave/provider/test/mock_config_store.h | 14 | ||||
-rw-r--r-- | src/config.cc | 16 | ||||
-rw-r--r-- | src/config_unittest.cc | 43 | ||||
-rw-r--r-- | src/weave_unittest.cc | 8 | ||||
-rw-r--r-- | tests.mk | 29 | ||||
-rw-r--r-- | third_party/chromium/base/gtest_prod_util.h | 8 | ||||
-rwxr-xr-x | third_party/get_gtest.sh | 19 | ||||
-rw-r--r-- | third_party/third_party.mk | 13 |
18 files changed, 213 insertions, 272 deletions
@@ -71,6 +71,10 @@ CFLAGS += -MMD OBJFILES = $(shell find out/$(BUILD_MODE)/ -type f -name '*.o') -include $(OBJFILES:.o=.d) +DEFS_TEST := \ + $(DEFS_$(BUILD_MODE)) \ + -DHAS_GTEST=1 + ### # libweave.so @@ -85,7 +89,7 @@ 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 third_party/include/gtest/gtest.h +$(weave_obj_files) : out/$(BUILD_MODE)/%.o : %.cc mkdir -p $(dir $@) $(CXX) $(DEFS_$(BUILD_MODE)) $(INCLUDES) $(CFLAGS) $(CFLAGS_$(BUILD_MODE)) $(CFLAGS_CC) -c -o $@ $< @@ -93,7 +97,7 @@ out/$(BUILD_MODE)/libweave_common.a : $(weave_obj_files) $(third_party_chromium_ rm -f $@ $(AR) crsT $@ $^ -all : out/$(BUILD_MODE)/libweave.so out/$(BUILD_MODE)/libweave_exports_testrunner out/$(BUILD_MODE)/libweave_testrunner all-examples +all : out/$(BUILD_MODE)/libweave.so all-examples out/$(BUILD_MODE)/libweave_exports_testrunner out/$(BUILD_MODE)/libweave_testrunner clean : rm -rf out diff --git a/examples/daemon/common/daemon.h b/examples/daemon/common/daemon.h index 4cccff3..6dc021d 100644 --- a/examples/daemon/common/daemon.h +++ b/examples/daemon/common/daemon.h @@ -69,10 +69,11 @@ class Daemon { }; Daemon(const Options& opts) - : config_store_{new weave::examples::FileConfigStore( - opts.disable_security_, - opts.model_id_)}, - task_runner_{new weave::examples::EventTaskRunner}, + : task_runner_{new weave::examples::EventTaskRunner}, + config_store_{ + new weave::examples::FileConfigStore(opts.disable_security_, + opts.model_id_, + task_runner_.get())}, http_client_{new weave::examples::CurlHttpClient(task_runner_.get())}, network_{new weave::examples::EventNetworkImpl(task_runner_.get())}, bluetooth_{new weave::examples::BluetoothImpl} { @@ -114,8 +115,8 @@ class Daemon { LOG(INFO) << "Device registered: " << device->GetSettings().cloud_id; } - std::unique_ptr<weave::examples::FileConfigStore> config_store_; std::unique_ptr<weave::examples::EventTaskRunner> task_runner_; + std::unique_ptr<weave::examples::FileConfigStore> config_store_; std::unique_ptr<weave::examples::CurlHttpClient> http_client_; std::unique_ptr<weave::examples::EventNetworkImpl> network_; std::unique_ptr<weave::examples::BluetoothImpl> bluetooth_; diff --git a/examples/provider/event_http_client.cc b/examples/provider/event_http_client.cc deleted file mode 100644 index 0346a67..0000000 --- a/examples/provider/event_http_client.cc +++ /dev/null @@ -1,145 +0,0 @@ -// 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. - -#include "examples/provider/event_http_client.h" -#include "examples/provider/event_task_runner.h" - -#include <base/bind.h> -#include <event2/buffer.h> -#include <event2/bufferevent.h> -#include <event2/http.h> -#include <weave/enum_to_string.h> - -#include "examples/provider/event_deleter.h" - -// EventHttpClient based on libevent2 http-client sample -// TODO(proppy): https -// TODO(proppy): hostname validation -namespace weave { - -namespace { -const weave::EnumToStringMap<evhttp_cmd_type>::Map kMapMethod[] = { - {EVHTTP_REQ_GET, "GET"}, {EVHTTP_REQ_POST, "POST"}, - {EVHTTP_REQ_HEAD, "HEAD"}, {EVHTTP_REQ_PUT, "PUT"}, - {EVHTTP_REQ_PATCH, "PATCH"}, {EVHTTP_REQ_DELETE, "DELETE"}, - {EVHTTP_REQ_OPTIONS, "OPTIONS"}}; -} // namespace - -template <> -EnumToStringMap<evhttp_cmd_type>::EnumToStringMap() - : EnumToStringMap(kMapMethod) {} - -using namespace provider; - -namespace examples { - -namespace { - -class EventHttpResponse : public weave::provider::HttpClient::Response { - public: - int GetStatusCode() const override { return status; } - std::string GetContentType() const override { return content_type; } - std::string GetData() const { return data; } - - int status; - std::string content_type; - std::string data; -}; - -struct EventRequestState { - TaskRunner* task_runner_; - EventPtr<evhttp_uri> http_uri_; - EventPtr<evhttp_connection> evcon_; - HttpClient::SendRequestCallback callback_; -}; - -void RequestDoneCallback(evhttp_request* req, void* ctx) { - std::unique_ptr<EventRequestState> state{ - static_cast<EventRequestState*>(ctx)}; - if (!req) { - ErrorPtr error; - auto err = EVUTIL_SOCKET_ERROR(); - Error::AddToPrintf(&error, FROM_HERE, "request_failed", - "request failed: %s", - evutil_socket_error_to_string(err)); - state->task_runner_->PostDelayedTask( - FROM_HERE, base::Bind(state->callback_, nullptr, base::Passed(&error)), - {}); - return; - } - std::unique_ptr<EventHttpResponse> response{new EventHttpResponse()}; - response->status = evhttp_request_get_response_code(req); - auto buffer = evhttp_request_get_input_buffer(req); - auto length = evbuffer_get_length(buffer); - response->data.resize(length); - auto n = evbuffer_remove(buffer, &response->data[0], length); - CHECK_EQ(n, int(length)); - state->task_runner_->PostDelayedTask( - FROM_HERE, base::Bind(state->callback_, base::Passed(&response), nullptr), - {}); -} - -} // namespace - -EventHttpClient::EventHttpClient(EventTaskRunner* task_runner) - : task_runner_{task_runner} {} - -void EventHttpClient::SendRequest(Method method, - const std::string& url, - const Headers& headers, - const std::string& data, - const SendRequestCallback& callback) { - evhttp_cmd_type method_id = EVHTTP_REQ_GET; - CHECK(weave::StringToEnum(weave::EnumToString(method), &method_id)); - EventPtr<evhttp_uri> http_uri{evhttp_uri_parse(url.c_str())}; - CHECK(http_uri); - auto host = evhttp_uri_get_host(http_uri.get()); - CHECK(host); - auto port = evhttp_uri_get_port(http_uri.get()); - if (port == -1) - port = 80; - std::string path{evhttp_uri_get_path(http_uri.get())}; - if (path.length() == 0) { - path = "/"; - } - std::string uri{path}; - auto query = evhttp_uri_get_query(http_uri.get()); - if (query) { - uri = path + "?" + query; - } - auto bev = bufferevent_socket_new(task_runner_->GetEventBase(), -1, - BEV_OPT_CLOSE_ON_FREE); - CHECK(bev); - EventPtr<evhttp_connection> conn{evhttp_connection_base_bufferevent_new( - task_runner_->GetEventBase(), NULL, bev, host, port)}; - CHECK(conn); - EventPtr<evhttp_request> req{evhttp_request_new( - &RequestDoneCallback, - new EventRequestState{task_runner_, std::move(http_uri), std::move(conn), - callback})}; - CHECK(req); - auto output_headers = evhttp_request_get_output_headers(req.get()); - evhttp_add_header(output_headers, "Host", host); - for (auto& kv : headers) - evhttp_add_header(output_headers, kv.first.c_str(), kv.second.c_str()); - if (!data.empty()) { - auto output_buffer = evhttp_request_get_output_buffer(req.get()); - evbuffer_add(output_buffer, data.c_str(), data.length()); - evhttp_add_header(output_headers, "Content-Length", - std::to_string(data.length()).c_str()); - } - auto res = - evhttp_make_request(conn.get(), req.release(), method_id, uri.c_str()); - if (res >= 0) - return; - ErrorPtr error; - Error::AddToPrintf(&error, FROM_HERE, "request_failed", - "request failed: %s %s", EnumToString(method).c_str(), - url.c_str()); - task_runner_->PostDelayedTask( - FROM_HERE, base::Bind(callback, nullptr, base::Passed(&error)), {}); -} - -} // namespace examples -} // namespace weave diff --git a/examples/provider/event_http_client.h b/examples/provider/event_http_client.h deleted file mode 100644 index 378c4a3..0000000 --- a/examples/provider/event_http_client.h +++ /dev/null @@ -1,38 +0,0 @@ -// 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. - -#ifndef LIBWEAVE_EXAMPLES_PROVIDER_EVENT_HTTP_CLIENT_H_ -#define LIBWEAVE_EXAMPLES_PROVIDER_EVENT_HTTP_CLIENT_H_ - -#include <string> - -#include <base/memory/weak_ptr.h> -#include <weave/provider/http_client.h> - -#include "examples/provider/event_task_runner.h" - -namespace weave { -namespace examples { - -// Basic implementation of weave::HttpClient using libevent. -class EventHttpClient : public provider::HttpClient { - public: - explicit EventHttpClient(EventTaskRunner* task_runner); - - void SendRequest(Method method, - const std::string& url, - const Headers& headers, - const std::string& data, - const SendRequestCallback& callback) override; - - private: - EventTaskRunner* task_runner_{nullptr}; - - base::WeakPtrFactory<EventHttpClient> weak_ptr_factory_{this}; -}; - -} // namespace examples -} // namespace weave - -#endif // LIBWEAVE_EXAMPLES_PROVIDER_EVENT_HTTP_CLIENT_H_ diff --git a/examples/provider/file_config_store.cc b/examples/provider/file_config_store.cc index 6faa242..31efaa7 100644 --- a/examples/provider/file_config_store.cc +++ b/examples/provider/file_config_store.cc @@ -12,16 +12,27 @@ #include <string> #include <vector> +#include <base/bind.h> + namespace weave { namespace examples { const char kSettingsDir[] = "/var/lib/weave/"; FileConfigStore::FileConfigStore(bool disable_security, - const std::string& model_id) + const std::string& model_id, + provider::TaskRunner* task_runner) : disable_security_{disable_security}, model_id_{model_id}, - settings_path_{"/var/lib/weave/weave_settings_" + model_id + ".json"} {} + task_runner_{task_runner} {} + +std::string FileConfigStore::GetPath(const std::string& name) const { + std::string path{kSettingsDir}; + path += path + "weave_settings_" + model_id_; + if (!name.empty()) + path += "_" + name; + return path + ".json"; +} bool FileConfigStore::LoadDefaults(Settings* settings) { char host_name[HOST_NAME_MAX] = {}; @@ -55,17 +66,25 @@ bool FileConfigStore::LoadDefaults(Settings* settings) { } std::string FileConfigStore::LoadSettings() { - LOG(INFO) << "Loading settings from " << settings_path_; - std::ifstream str(settings_path_); + return LoadSettings(""); +} + +std::string FileConfigStore::LoadSettings(const std::string& name) { + LOG(INFO) << "Loading settings from " << GetPath(name); + std::ifstream str(GetPath(name)); return std::string(std::istreambuf_iterator<char>(str), std::istreambuf_iterator<char>()); } -void FileConfigStore::SaveSettings(const std::string& settings) { +void FileConfigStore::SaveSettings(const std::string& name, + const std::string& settings, + const DoneCallback& callback) { CHECK(mkdir(kSettingsDir, S_IRWXU) == 0 || errno == EEXIST); - LOG(INFO) << "Saving settings to " << settings_path_; - std::ofstream str(settings_path_); + LOG(INFO) << "Saving settings to " << GetPath(name); + std::ofstream str(GetPath(name)); str << settings; + if (!callback.is_null()) + task_runner_->PostDelayedTask(FROM_HERE, base::Bind(callback, nullptr), {}); } } // namespace examples diff --git a/examples/provider/file_config_store.h b/examples/provider/file_config_store.h index 578f940..e7398d1 100644 --- a/examples/provider/file_config_store.h +++ b/examples/provider/file_config_store.h @@ -10,22 +10,30 @@ #include <vector> #include <weave/provider/config_store.h> +#include <weave/provider/task_runner.h> namespace weave { namespace examples { class FileConfigStore : public provider::ConfigStore { public: - FileConfigStore(bool disable_security, const std::string& model_id); + FileConfigStore(bool disable_security, + const std::string& model_id, + provider::TaskRunner* task_runner); bool LoadDefaults(Settings* settings) override; + std::string LoadSettings(const std::string& name) override; + void SaveSettings(const std::string& name, + const std::string& settings, + const DoneCallback& callback) override; + std::string LoadSettings() override; - void SaveSettings(const std::string& settings) override; private: + std::string GetPath(const std::string& name) const; const bool disable_security_; const std::string model_id_; - const std::string settings_path_; + provider::TaskRunner* task_runner_{nullptr}; }; } // namespace examples diff --git a/examples/provider/wifi_manager.cc b/examples/provider/wifi_manager.cc index cad882d..7597e47 100644 --- a/examples/provider/wifi_manager.cc +++ b/examples/provider/wifi_manager.cc @@ -5,6 +5,7 @@ #include "examples/provider/wifi_manager.h" #include <arpa/inet.h> +#include <dirent.h> #include <linux/wireless.h> #include <sys/ioctl.h> #include <sys/wait.h> @@ -32,18 +33,43 @@ int ForkCmd(const std::string& path, const std::vector<std::string>& args) { for (auto& i : args) args_vector.push_back(i.c_str()); args_vector.push_back(nullptr); - execvp(path.c_str(), const_cast<char**>(args_vector.data())); NOTREACHED(); return 0; } +int ForkCmdAndWait(const std::string& path, + const std::vector<std::string>& args) { + int pid = ForkCmd(path, args); + int status = 0; + CHECK_EQ(pid, waitpid(pid, &status, 0)); + return status; +} + +std::string FindWirelessInterface() { + std::string sysfs_net{"/sys/class/net"}; + DIR* net_dir = opendir(sysfs_net.c_str()); + dirent* iface; + while ((iface = readdir(net_dir))) { + auto path = sysfs_net + "/" + iface->d_name + "/wireless"; + DIR* wireless_dir = opendir(path.c_str()); + if (wireless_dir != nullptr) { + closedir(net_dir); + closedir(wireless_dir); + return iface->d_name; + } + } + closedir(net_dir); + return ""; +} + } // namespace WifiImpl::WifiImpl(provider::TaskRunner* task_runner, EventNetworkImpl* network) - : task_runner_{task_runner}, network_{network} { + : task_runner_{task_runner}, network_{network}, iface_{FindWirelessInterface()} { + CHECK(!iface_.empty()) << "WiFi interface not found"; CHECK_EQ(0u, getuid()) - << "WiFi manager expects root access to control WiFi capabilities"; + << "\nWiFi manager expects root access to control WiFi capabilities"; StopAccessPoint(); } WifiImpl::~WifiImpl() { @@ -62,7 +88,7 @@ void WifiImpl::TryToConnect(const std::string& ssid, CHECK_GE(sockf_d, 0) << strerror(errno); iwreq wreq = {}; - snprintf(wreq.ifr_name, sizeof(wreq.ifr_name), "wlan0"); + strncpy(wreq.ifr_name, iface_.c_str(), sizeof(wreq.ifr_name)); std::string essid(' ', IW_ESSID_MAX_SIZE + 1); wreq.u.essid.pointer = &essid[0]; wreq.u.essid.length = essid.size(); @@ -119,24 +145,24 @@ void WifiImpl::StartAccessPoint(const std::string& ssid) { if (hostapd_started_) return; - // Release wlan0 interface. - CHECK_EQ(0, std::system("nmcli nm wifi off")); - CHECK_EQ(0, std::system("rfkill unblock wlan")); + // Release wifi interface. + CHECK_EQ(0, ForkCmdAndWait("nmcli", {"nm", "wifi", "off"})); + CHECK_EQ(0, ForkCmdAndWait("rfkill", {"unblock", "wlan"})); sleep(1); std::string hostapd_conf = "/tmp/weave_hostapd.conf"; { std::ofstream ofs(hostapd_conf); - ofs << "interface=wlan0" << std::endl; + ofs << "interface=" << iface_ << std::endl; ofs << "channel=1" << std::endl; ofs << "ssid=" << ssid << std::endl; } - CHECK_EQ(0, std::system(("hostapd -B -K " + hostapd_conf).c_str())); + CHECK_EQ(0, ForkCmdAndWait("hostapd", {"-B", "-K", hostapd_conf})); hostapd_started_ = true; for (size_t i = 0; i < 10; ++i) { - if (0 == std::system("ifconfig wlan0 192.168.76.1/24")) + if (0 == ForkCmdAndWait("ifconfig", {iface_, "192.168.76.1/24"})) break; sleep(1); } @@ -148,22 +174,22 @@ void WifiImpl::StartAccessPoint(const std::string& ssid) { ofs << "bind-interfaces" << std::endl; ofs << "log-dhcp" << std::endl; ofs << "dhcp-range=192.168.76.10,192.168.76.100" << std::endl; - ofs << "interface=wlan0" << std::endl; + ofs << "interface=" << iface_ << std::endl; ofs << "dhcp-leasefile=" << dnsmasq_conf << ".leases" << std::endl; } - CHECK_EQ(0, std::system(("dnsmasq --conf-file=" + dnsmasq_conf).c_str())); + CHECK_EQ(0, ForkCmdAndWait("dnsmasq", {"--conf-file=" + dnsmasq_conf})); } void WifiImpl::StopAccessPoint() { - base::IgnoreResult(std::system("pkill -f dnsmasq.*/tmp/weave")); - base::IgnoreResult(std::system("pkill -f hostapd.*/tmp/weave")); - CHECK_EQ(0, std::system("nmcli nm wifi on")); + base::IgnoreResult(ForkCmdAndWait("pkill", {"-f", "dnsmasq.*/tmp/weave"})); + base::IgnoreResult(ForkCmdAndWait("pkill", {"-f", "hostapd.*/tmp/weave"})); + CHECK_EQ(0, ForkCmdAndWait("nmcli", {"nm", "wifi", "on"})); hostapd_started_ = false; } bool WifiImpl::HasWifiCapability() { - return std::system("nmcli dev | grep ^wlan0") == 0; + return !FindWirelessInterface().empty(); } } // namespace examples diff --git a/examples/provider/wifi_manager.h b/examples/provider/wifi_manager.h index c043523..2bfc5ca 100644 --- a/examples/provider/wifi_manager.h +++ b/examples/provider/wifi_manager.h @@ -48,6 +48,7 @@ class WifiImpl : public provider::Wifi { provider::TaskRunner* task_runner_{nullptr}; EventNetworkImpl* network_{nullptr}; base::WeakPtrFactory<WifiImpl> weak_ptr_factory_{this}; + std::string iface_; }; } // namespace examples diff --git a/file_lists.mk b/file_lists.mk index a018178..b944c3a 100644 --- a/file_lists.mk +++ b/file_lists.mk @@ -79,7 +79,6 @@ EXAMPLES_PROVIDER_SRC_FILES := \ examples/provider/avahi_client.cc \ examples/provider/bluez_client.cc \ examples/provider/curl_http_client.cc \ - examples/provider/event_http_client.cc \ examples/provider/event_http_server.cc \ examples/provider/event_network.cc \ examples/provider/event_task_runner.cc \ diff --git a/include/weave/provider/config_store.h b/include/weave/provider/config_store.h index 1b7988f..128eccc 100644 --- a/include/weave/provider/config_store.h +++ b/include/weave/provider/config_store.h @@ -13,6 +13,7 @@ #include <base/callback.h> #include <base/time/time.h> #include <weave/enum_to_string.h> +#include <weave/error.h> #include <weave/settings.h> namespace weave { @@ -36,8 +37,8 @@ namespace provider { // Implementation of LoadSettings() method should load previously // stored settings from the persistent storage (file, flash, etc). // For example: -// std::string FileConfigStore::LoadSettings() { -// std::ifstream str("/var/lib/weave/weave_settings.json"); +// std::string FileConfigStore::LoadSettings(const std::string& name) { +// std::ifstream str("/var/lib/weave/weave_" + name + ".json"); // return std::string(std::istreambuf_iterator<char>(str), // std::istreambuf_iterator<char>()); // } @@ -47,9 +48,14 @@ namespace provider { // Implementation of SaveSettings(...) method should store data in the // persistent storage (file, flash, etc). // For example: -// void FileConfigStore::SaveSettings(const std::string& settings) { -// std::ofstream str(kSettingsPath); +// void FileConfigStore::SaveSettings(const std::string& name, +// const std::string& settings, +// const DoneCallback& callback) { +// std::ofstream str("/var/lib/weave/weave_" + name + ".json"); // str << settings; +// if (!callback.is_null()) +// task_runner_->PostDelayedTask(FROM_HERE, base::Bind(callback, nullptr), +// {}); // } // It is highly recommended to protected data using encryption with // hardware backed key. @@ -67,12 +73,20 @@ class ConfigStore { // Returns settings saved by SaveSettings during last run of libweave. // Implementation should return data as-is without parsing or modifications. - virtual std::string LoadSettings() = 0; + // |name| is the name of settings blob. Could be used as filename. + virtual std::string LoadSettings(const std::string& name) = 0; // Saves settings. Implementation should save data as-is without parsing or // modifications. Data stored in settings can be sensitive, so it's highly // recommended to protect data, e.g. using encryption. - virtual void SaveSettings(const std::string& settings) = 0; + // |name| is the name of settings blob. Could be used as filename. + // Implementation must call or post callback + virtual void SaveSettings(const std::string& name, + const std::string& settings, + const DoneCallback& callback) = 0; + + // Deprecated: only for migration of old configs to version with |name|. + virtual std::string LoadSettings() = 0; protected: virtual ~ConfigStore() {} diff --git a/include/weave/provider/test/mock_config_store.h b/include/weave/provider/test/mock_config_store.h index 3873251..e6411d6 100644 --- a/include/weave/provider/test/mock_config_store.h +++ b/include/weave/provider/test/mock_config_store.h @@ -39,11 +39,21 @@ class MockConfigStore : public ConfigStore { "version": 1, "device_id": "TEST_DEVICE_ID" })")); - EXPECT_CALL(*this, SaveSettings(_)).WillRepeatedly(Return()); + EXPECT_CALL(*this, LoadSettings("config")).WillRepeatedly(Return("")); + EXPECT_CALL(*this, SaveSettings("config", _, _)) + .WillRepeatedly(testing::WithArgs<1, 2>(testing::Invoke( + [](const std::string& json, const DoneCallback& callback) { + if (!callback.is_null()) + callback.Run(nullptr); + }))); } MOCK_METHOD1(LoadDefaults, bool(Settings*)); + MOCK_METHOD1(LoadSettings, std::string(const std::string&)); + MOCK_METHOD3(SaveSettings, + void(const std::string&, + const std::string&, + const DoneCallback&)); MOCK_METHOD0(LoadSettings, std::string()); - MOCK_METHOD1(SaveSettings, void(const std::string&)); }; } // namespace test diff --git a/src/config.cc b/src/config.cc index 76be205..44d20dd 100644 --- a/src/config.cc +++ b/src/config.cc @@ -18,9 +18,12 @@ #include "src/data_encoding.h" #include "src/privet/privet_types.h" #include "src/string_utils.h" +#include "src/bind_lambda.h" namespace weave { +const char kConfigName[] = "config"; + namespace config_keys { const char kVersion[] = "version"; @@ -139,9 +142,12 @@ void Config::Load() { void Config::Transaction::LoadState() { if (!config_->config_store_) return; - std::string json_string = config_->config_store_->LoadSettings(); - if (json_string.empty()) - return; + std::string json_string = config_->config_store_->LoadSettings(kConfigName); + if (json_string.empty()) { + json_string = config_->config_store_->LoadSettings(); + if (json_string.empty()) + return; + } auto value = base::JSONReader::Read(json_string); base::DictionaryValue* dict = nullptr; @@ -266,7 +272,9 @@ void Config::Save() { base::JSONWriter::WriteWithOptions( dict, base::JSONWriter::OPTIONS_PRETTY_PRINT, &json_string); - config_store_->SaveSettings(json_string); + config_store_->SaveSettings( + kConfigName, json_string, + base::Bind([](ErrorPtr error) { CHECK(!error); })); } Config::Transaction::~Transaction() { diff --git a/src/config_unittest.cc b/src/config_unittest.cc index 0367516..fbb558a 100644 --- a/src/config_unittest.cc +++ b/src/config_unittest.cc @@ -17,18 +17,20 @@ using testing::_; using testing::Invoke; using testing::Return; +using testing::WithArgs; namespace weave { +const char kConfigName[] = "config"; + class ConfigTest : public ::testing::Test { protected: void SetUp() override { - EXPECT_CALL(*this, OnConfigChanged(_)) - .Times(1); // Called from AddOnChangedCallback Reload(); } void Reload() { + EXPECT_CALL(*this, OnConfigChanged(_)).Times(1); config_.reset(new Config{&config_store_}); config_->AddOnChangedCallback( base::Bind(&ConfigTest::OnConfigChanged, base::Unretained(this))); @@ -86,31 +88,45 @@ TEST_F(ConfigTest, Defaults) { } TEST_F(ConfigTest, LoadStateV0) { - EXPECT_CALL(config_store_, LoadSettings()) + EXPECT_CALL(config_store_, LoadSettings(kConfigName)) .WillOnce(Return(R"({ "device_id": "state_device_id" })")); - EXPECT_CALL(*this, OnConfigChanged(_)).Times(1); Reload(); EXPECT_EQ("state_device_id", GetSettings().cloud_id); EXPECT_FALSE(GetSettings().device_id.empty()); EXPECT_NE(GetSettings().cloud_id, GetSettings().device_id); - EXPECT_CALL(config_store_, LoadSettings()) + EXPECT_CALL(config_store_, LoadSettings(kConfigName)) .WillOnce(Return(R"({ "device_id": "state_device_id", "cloud_id": "state_cloud_id" })")); - EXPECT_CALL(*this, OnConfigChanged(_)).Times(1); Reload(); EXPECT_EQ("state_cloud_id", GetSettings().cloud_id); EXPECT_EQ("state_device_id", GetSettings().device_id); } +TEST_F(ConfigTest, LoadStateUnnamed) { + EXPECT_CALL(config_store_, LoadSettings(kConfigName)).WillOnce(Return("")); + + EXPECT_CALL(config_store_, LoadSettings()).Times(1); + + Reload(); +} + +TEST_F(ConfigTest, LoadStateNamed) { + EXPECT_CALL(config_store_, LoadSettings(kConfigName)).WillOnce(Return("{}")); + + EXPECT_CALL(config_store_, LoadSettings()).Times(0); + + Reload(); +} + TEST_F(ConfigTest, LoadState) { auto state = R"({ "version": 1, @@ -133,9 +149,8 @@ TEST_F(ConfigTest, LoadState) { "secret": "c3RhdGVfc2VjcmV0", "service_url": "state_service_url" })"; - EXPECT_CALL(config_store_, LoadSettings()).WillOnce(Return(state)); + EXPECT_CALL(config_store_, LoadSettings(kConfigName)).WillOnce(Return(state)); - EXPECT_CALL(*this, OnConfigChanged(_)).Times(1); Reload(); EXPECT_EQ("state_client_id", GetSettings().client_id); @@ -243,9 +258,10 @@ TEST_F(ConfigTest, Setters) { EXPECT_CALL(*this, OnConfigChanged(_)).Times(1); - EXPECT_CALL(config_store_, SaveSettings(_)) - .WillOnce(Invoke([](const std::string& json) { - auto expected = R"({ + EXPECT_CALL(config_store_, SaveSettings(kConfigName, _, _)) + .WillOnce(WithArgs<1, 2>( + Invoke([](const std::string& json, const DoneCallback& callback) { + auto expected = R"({ 'version': 1, 'api_key': 'set_api_key', 'client_id': 'set_client_id', @@ -266,8 +282,9 @@ TEST_F(ConfigTest, Setters) { 'secret': 'AQIDBAU=', 'service_url': 'set_service_url' })"; - EXPECT_JSON_EQ(expected, *test::CreateValue(json)); - })); + EXPECT_JSON_EQ(expected, *test::CreateValue(json)); + callback.Run(nullptr); + }))); change.Commit(); } diff --git a/src/weave_unittest.cc b/src/weave_unittest.cc index 5bef931..ebc66cd 100644 --- a/src/weave_unittest.cc +++ b/src/weave_unittest.cc @@ -204,10 +204,6 @@ class WeaveTest : public ::testing::Test { }))); } - void InitConfigStore() { - EXPECT_CALL(config_store_, SaveSettings("")).WillRepeatedly(Return()); - } - void InitNetwork() { EXPECT_CALL(network_, AddConnectionChangedCallback(_)) .WillRepeatedly(Invoke( @@ -267,7 +263,6 @@ class WeaveTest : public ::testing::Test { } void InitDefaultExpectations() { - InitConfigStore(); InitNetwork(); EXPECT_CALL(wifi_, StartAccessPoint(MatchesRegex("TEST_NAME.*prv"))) .WillOnce(Return()); @@ -360,13 +355,11 @@ TEST_F(WeaveTest, Mocks) { } TEST_F(WeaveTest, StartMinimal) { - InitConfigStore(); device_ = weave::Device::Create(&config_store_, &task_runner_, &http_client_, &network_, nullptr, nullptr, &wifi_, nullptr); } TEST_F(WeaveTest, StartNoWifi) { - InitConfigStore(); InitNetwork(); InitHttpServer(); InitDnsSd(); @@ -450,7 +443,6 @@ class WeaveWiFiSetupTest : public WeaveTest { void SetUp() override { WeaveTest::SetUp(); - InitConfigStore(); InitHttpServer(); InitNetwork(); InitDnsSd(); @@ -26,10 +26,17 @@ weave_unittest_obj_files := $(WEAVE_UNITTEST_SRC_FILES:%.cc=out/$(BUILD_MODE)/%. $(weave_unittest_obj_files) : out/$(BUILD_MODE)/%.o : %.cc third_party/include/gtest/gtest.h mkdir -p $(dir $@) - $(CXX) $(DEFS_$(BUILD_MODE)) $(INCLUDES) $(CFLAGS) $(CFLAGS_$(BUILD_MODE)) $(CFLAGS_CC) -c -o $@ $< - -out/$(BUILD_MODE)/libweave_testrunner : $(weave_unittest_obj_files) $(third_party_chromium_crypto_unittest_obj_files) $(third_party_chromium_base_unittest_obj_files) out/$(BUILD_MODE)/libweave_common.a out/$(BUILD_MODE)/libweave-test.a - $(CXX) -o $@ $^ $(CFLAGS) -lcrypto -lexpat -lgmock -lgtest -lpthread -lrt -Lthird_party/lib + $(CXX) $(DEFS_TEST) $(INCLUDES) $(CFLAGS) $(CFLAGS_$(BUILD_MODE)) $(CFLAGS_CC) -c -o $@ $< + +out/$(BUILD_MODE)/libweave_testrunner : \ + $(weave_unittest_obj_files) \ + $(third_party_chromium_crypto_unittest_obj_files) \ + $(third_party_chromium_base_unittest_obj_files) \ + out/$(BUILD_MODE)/libweave_common.a \ + out/$(BUILD_MODE)/libweave-test.a \ + third_party/lib/gmock.a \ + third_party/lib/gtest.a + $(CXX) -o $@ $^ $(CFLAGS) -lcrypto -lexpat -lpthread -lrt -Lthird_party/lib test : out/$(BUILD_MODE)/libweave_testrunner $(TEST_ENV) $< $(TEST_FLAGS) @@ -41,10 +48,16 @@ weave_exports_unittest_obj_files := $(WEAVE_EXPORTS_UNITTEST_SRC_FILES:%.cc=out/ $(weave_exports_unittest_obj_files) : out/$(BUILD_MODE)/%.o : %.cc third_party/include/gtest/gtest.h mkdir -p $(dir $@) - $(CXX) $(DEFS_$(BUILD_MODE)) $(INCLUDES) $(CFLAGS) $(CFLAGS_$(BUILD_MODE)) $(CFLAGS_CC) -c -o $@ $< - -out/$(BUILD_MODE)/libweave_exports_testrunner : $(weave_exports_unittest_obj_files) out/$(BUILD_MODE)/libweave.so out/$(BUILD_MODE)/libweave-test.a out/$(BUILD_MODE)/src/test/weave_testrunner.o - $(CXX) -o $@ $^ $(CFLAGS) -lcrypto -lexpat -lgmock -lgtest -lpthread -lrt -Lthird_party/lib -Wl,-rpath=out/$(BUILD_MODE)/ + $(CXX) $(DEFS_TEST) $(INCLUDES) $(CFLAGS) $(CFLAGS_$(BUILD_MODE)) $(CFLAGS_CC) -c -o $@ $< + +out/$(BUILD_MODE)/libweave_exports_testrunner : \ + $(weave_exports_unittest_obj_files) \ + out/$(BUILD_MODE)/libweave.so \ + out/$(BUILD_MODE)/libweave-test.a \ + out/$(BUILD_MODE)/src/test/weave_testrunner.o \ + third_party/lib/gmock.a \ + third_party/lib/gtest.a + $(CXX) -o $@ $^ $(CFLAGS) -lcrypto -lexpat -lpthread -lrt -Lthird_party/lib -Wl,-rpath=out/$(BUILD_MODE)/ export-test : out/$(BUILD_MODE)/libweave_exports_testrunner $(TEST_ENV) $< $(TEST_FLAGS) diff --git a/third_party/chromium/base/gtest_prod_util.h b/third_party/chromium/base/gtest_prod_util.h index b90cd4e..b3db728 100644 --- a/third_party/chromium/base/gtest_prod_util.h +++ b/third_party/chromium/base/gtest_prod_util.h @@ -5,6 +5,8 @@ #ifndef BASE_GTEST_PROD_UTIL_H_ #define BASE_GTEST_PROD_UTIL_H_ +#if defined(HAS_GTEST) + #include <gtest/gtest_prod.h> // This is a wrapper for gtest's FRIEND_TEST macro that friends @@ -63,4 +65,10 @@ class test_case_name##_##DISABLED_##test_name##_Test; \ class test_case_name##_##FLAKY_##test_name##_Test +#else // defined(HAS_GTEST) + +#define FRIEND_TEST_ALL_PREFIXES(test_case_name, test_name) + +#endif // defined(HAS_GTEST) + #endif // BASE_GTEST_PROD_UTIL_H_ diff --git a/third_party/get_gtest.sh b/third_party/get_gtest.sh index 0a2e952..9b546ab 100755 --- a/third_party/get_gtest.sh +++ b/third_party/get_gtest.sh @@ -15,16 +15,17 @@ cd googletest # gtest is in process of changing of dir structure and it has broken build # files. So this is temporarily workaround to fix that. -git reset --hard d945d8c000a0ade73585d143532266968339bbb3 +git reset --hard 82b11b8cfcca464c2ac74b623d04e74452e74f32 mv googletest googlemock/gtest -for SUB_DIR in googlemock/gtest googlemock; do - cd $THIRD_PARTY/googletest/$SUB_DIR || exit 1 - autoreconf -fvi || exit 1 - ./configure --disable-shared || exit 1 - make || exit 1 - cp -rf include/* $THIRD_PARTY/include/ || exit 1 - cp -rf lib/.libs/* $THIRD_PARTY/lib/ || exit 1 -done +cd $THIRD_PARTY/googletest/googlemock/gtest/make || exit 1 +make gtest.a || exit 1 +cp -rf ../include/* $THIRD_PARTY/include/ || exit 1 +cp -rf gtest.a $THIRD_PARTY/lib/ || exit 1 + +cd $THIRD_PARTY/googletest/googlemock/make || exit 1 +make gmock.a || exit 1 +cp -rf ../include/* $THIRD_PARTY/include/ || exit 1 +cp -rf gmock.a $THIRD_PARTY/lib/ || exit 1 rm -rf $THIRD_PARTY/googletest diff --git a/third_party/third_party.mk b/third_party/third_party.mk index c3e1cf0..8a11e2d 100644 --- a/third_party/third_party.mk +++ b/third_party/third_party.mk @@ -7,7 +7,7 @@ third_party_chromium_base_obj_files := $(THIRD_PARTY_CHROMIUM_BASE_SRC_FILES:%.cc=out/$(BUILD_MODE)/%.o) -$(third_party_chromium_base_obj_files) : out/$(BUILD_MODE)/%.o : %.cc third_party/include/gtest/gtest.h +$(third_party_chromium_base_obj_files) : out/$(BUILD_MODE)/%.o : %.cc mkdir -p $(dir $@) $(CXX) $(DEFS_$(BUILD_MODE)) $(INCLUDES) $(CFLAGS) $(CFLAGS_$(BUILD_MODE)) $(CFLAGS_CC) -c -o $@ $< @@ -15,11 +15,11 @@ third_party_chromium_base_unittest_obj_files := $(THIRD_PARTY_CHROMIUM_BASE_UNIT $(third_party_chromium_base_unittest_obj_files) : out/$(BUILD_MODE)/%.o : %.cc third_party/include/gtest/gtest.h mkdir -p $(dir $@) - $(CXX) $(DEFS_$(BUILD_MODE)) $(INCLUDES) $(CFLAGS) $(CFLAGS_$(BUILD_MODE)) $(CFLAGS_CC) -c -o $@ $< + $(CXX) $(DEFS_TEST) $(INCLUDES) $(CFLAGS) $(CFLAGS_$(BUILD_MODE)) $(CFLAGS_CC) -c -o $@ $< third_party_chromium_crypto_obj_files := $(THIRD_PARTY_CHROMIUM_CRYPTO_SRC_FILES:%.cc=out/$(BUILD_MODE)/%.o) -$(third_party_chromium_crypto_obj_files) : out/$(BUILD_MODE)/%.o : %.cc third_party/include/gtest/gtest.h +$(third_party_chromium_crypto_obj_files) : out/$(BUILD_MODE)/%.o : %.cc mkdir -p $(dir $@) $(CXX) $(DEFS_$(BUILD_MODE)) $(INCLUDES) $(CFLAGS) $(CFLAGS_$(BUILD_MODE)) $(CFLAGS_CC) -c -o $@ $< @@ -27,7 +27,7 @@ third_party_chromium_crypto_unittest_obj_files := $(THIRD_PARTY_CHROMIUM_CRYPTO_ $(third_party_chromium_crypto_unittest_obj_files) : out/$(BUILD_MODE)/%.o : %.cc third_party/include/gtest/gtest.h mkdir -p $(dir $@) - $(CXX) $(DEFS_$(BUILD_MODE)) $(INCLUDES) $(CFLAGS) $(CFLAGS_$(BUILD_MODE)) $(CFLAGS_CC) -c -o $@ $< + $(CXX) $(DEFS_TEST) $(INCLUDES) $(CFLAGS) $(CFLAGS_$(BUILD_MODE)) $(CFLAGS_CC) -c -o $@ $< ### # third_party/modp_b64/ @@ -50,7 +50,10 @@ $(third_party_libuweave_obj_files) : out/$(BUILD_MODE)/%.o : %.c ### # libgtest and libgmock (third_party, downloaded on build) -third_party/include/gtest/gtest.h : +third_party/lib/gtest.a: third_party/include/gtest/gtest.h +third_party/lib/gmock.a: third_party/include/gtest/gtest.h + +third_party/include/gtest/gtest.h: @echo Downloading and building libgtest and libgmock... third_party/get_gtest.sh @echo Finished downloading and building libgtest and libgmock. |