aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVitaly Buka <vitalybuka@google.com>2016-01-30 01:35:26 +0000
committerandroid-build-merger <android-build-merger@google.com>2016-01-30 01:35:26 +0000
commit2c074980c0aab9c25475e8291905769047731d33 (patch)
tree4794622a3f5869eb9fda027f152051a2618073e3
parent355ac651275cd4258b8699228460b7ed3f4f61fe (diff)
parent9d187e6ddb3c0a570dd363c77cab2dc7f4966260 (diff)
downloadlibweave-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--Makefile8
-rw-r--r--examples/daemon/common/daemon.h11
-rw-r--r--examples/provider/event_http_client.cc145
-rw-r--r--examples/provider/event_http_client.h38
-rw-r--r--examples/provider/file_config_store.cc33
-rw-r--r--examples/provider/file_config_store.h14
-rw-r--r--examples/provider/wifi_manager.cc58
-rw-r--r--examples/provider/wifi_manager.h1
-rw-r--r--file_lists.mk1
-rw-r--r--include/weave/provider/config_store.h26
-rw-r--r--include/weave/provider/test/mock_config_store.h14
-rw-r--r--src/config.cc16
-rw-r--r--src/config_unittest.cc43
-rw-r--r--src/weave_unittest.cc8
-rw-r--r--tests.mk29
-rw-r--r--third_party/chromium/base/gtest_prod_util.h8
-rwxr-xr-xthird_party/get_gtest.sh19
-rw-r--r--third_party/third_party.mk13
18 files changed, 213 insertions, 272 deletions
diff --git a/Makefile b/Makefile
index 4ea625f..de69f40 100644
--- a/Makefile
+++ b/Makefile
@@ -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();
diff --git a/tests.mk b/tests.mk
index 1ae3b81..4e11f7e 100644
--- a/tests.mk
+++ b/tests.mk
@@ -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.