14615e0d5aa416ab1a8596bde68f71f7ebe431b86Vitaly Buka// Copyright 2015 The Weave Authors. All rights reserved. 211b2f2382db08ce26f4c4875a4e2d77586165720Vitaly Buka// Use of this source code is governed by a BSD-style license that can be 311b2f2382db08ce26f4c4875a4e2d77586165720Vitaly Buka// found in the LICENSE file. 411b2f2382db08ce26f4c4875a4e2d77586165720Vitaly Buka 511b2f2382db08ce26f4c4875a4e2d77586165720Vitaly Buka#include <weave/device.h> 611b2f2382db08ce26f4c4875a4e2d77586165720Vitaly Buka 711b2f2382db08ce26f4c4875a4e2d77586165720Vitaly Buka#include <gmock/gmock.h> 811b2f2382db08ce26f4c4875a4e2d77586165720Vitaly Buka#include <gtest/gtest.h> 9727f3e675fece0ebdcdb0bf0aaf083c374d64d95Vitaly Buka#include <weave/provider/test/fake_task_runner.h> 101e3636732171afb8cceb9e5cb835ec6a93787dbaVitaly Buka#include <weave/provider/test/mock_bluetooth.h> 111e3636732171afb8cceb9e5cb835ec6a93787dbaVitaly Buka#include <weave/provider/test/mock_config_store.h> 121e3636732171afb8cceb9e5cb835ec6a93787dbaVitaly Buka#include <weave/provider/test/mock_dns_service_discovery.h> 131e3636732171afb8cceb9e5cb835ec6a93787dbaVitaly Buka#include <weave/provider/test/mock_http_client.h> 141e3636732171afb8cceb9e5cb835ec6a93787dbaVitaly Buka#include <weave/provider/test/mock_http_server.h> 151e3636732171afb8cceb9e5cb835ec6a93787dbaVitaly Buka#include <weave/provider/test/mock_network.h> 161e3636732171afb8cceb9e5cb835ec6a93787dbaVitaly Buka#include <weave/provider/test/mock_wifi.h> 17ef213d7f63585accbb7ac9bd5112aeeb1b593c9dVitaly Buka#include <weave/test/mock_command.h> 18a8ece8f8534ca9b551f93bdba2982f40aff3d619Vitaly Buka#include <weave/test/mock_device.h> 190f6b2eccc9ca4aa35cf0ee1e3ac7bc6edc38f0a4Vitaly Buka#include <weave/test/unittest_utils.h> 2011b2f2382db08ce26f4c4875a4e2d77586165720Vitaly Buka 212d16dfa768282b29f3fd5a905b52e3393a083e0dStefan Sauer#include "src/bind_lambda.h" 2211b2f2382db08ce26f4c4875a4e2d77586165720Vitaly Buka 2311b2f2382db08ce26f4c4875a4e2d77586165720Vitaly Bukausing testing::_; 2465e1f21f13102b076156e2e6a07486c06f5b25d1Vitaly Bukausing testing::AtLeast; 2511b2f2382db08ce26f4c4875a4e2d77586165720Vitaly Bukausing testing::AtMost; 2611b2f2382db08ce26f4c4875a4e2d77586165720Vitaly Bukausing testing::HasSubstr; 2765e1f21f13102b076156e2e6a07486c06f5b25d1Vitaly Bukausing testing::InSequence; 2811b2f2382db08ce26f4c4875a4e2d77586165720Vitaly Bukausing testing::Invoke; 2911b2f2382db08ce26f4c4875a4e2d77586165720Vitaly Bukausing testing::InvokeWithoutArgs; 3011b2f2382db08ce26f4c4875a4e2d77586165720Vitaly Bukausing testing::MatchesRegex; 3111b2f2382db08ce26f4c4875a4e2d77586165720Vitaly Bukausing testing::Mock; 3211b2f2382db08ce26f4c4875a4e2d77586165720Vitaly Bukausing testing::Return; 3311b2f2382db08ce26f4c4875a4e2d77586165720Vitaly Bukausing testing::ReturnRefOfCopy; 3411b2f2382db08ce26f4c4875a4e2d77586165720Vitaly Bukausing testing::StartsWith; 3511b2f2382db08ce26f4c4875a4e2d77586165720Vitaly Bukausing testing::StrictMock; 3611b2f2382db08ce26f4c4875a4e2d77586165720Vitaly Bukausing testing::WithArgs; 3711b2f2382db08ce26f4c4875a4e2d77586165720Vitaly Buka 3811b2f2382db08ce26f4c4875a4e2d77586165720Vitaly Bukanamespace weave { 3911b2f2382db08ce26f4c4875a4e2d77586165720Vitaly Buka 40e69e4ee64c466730b98fb7fa3049aabcc85f8984Vitaly Bukanamespace { 41e69e4ee64c466730b98fb7fa3049aabcc85f8984Vitaly Buka 421a42e1466de3edd0c79215b739cd8e929ef8a7e8Vitaly Bukausing provider::HttpClient; 431a42e1466de3edd0c79215b739cd8e929ef8a7e8Vitaly Bukausing provider::Network; 441a42e1466de3edd0c79215b739cd8e929ef8a7e8Vitaly Bukausing provider::test::MockHttpClientResponse; 450f6b2eccc9ca4aa35cf0ee1e3ac7bc6edc38f0a4Vitaly Bukausing test::CreateDictionaryValue; 460f6b2eccc9ca4aa35cf0ee1e3ac7bc6edc38f0a4Vitaly Bukausing test::ValueToString; 4711b2f2382db08ce26f4c4875a4e2d77586165720Vitaly Buka 48551a82bbefbfd6dc83309eec440a41ca737062b4Alex Vakulenkoconst char kTraitDefs[] = R"({ 49551a82bbefbfd6dc83309eec440a41ca737062b4Alex Vakulenko "trait1": { 50551a82bbefbfd6dc83309eec440a41ca737062b4Alex Vakulenko "commands": { 51551a82bbefbfd6dc83309eec440a41ca737062b4Alex Vakulenko "reboot": { 52551a82bbefbfd6dc83309eec440a41ca737062b4Alex Vakulenko "minimalRole": "user" 53551a82bbefbfd6dc83309eec440a41ca737062b4Alex Vakulenko }, 54551a82bbefbfd6dc83309eec440a41ca737062b4Alex Vakulenko "shutdown": { 55551a82bbefbfd6dc83309eec440a41ca737062b4Alex Vakulenko "minimalRole": "user", 56551a82bbefbfd6dc83309eec440a41ca737062b4Alex Vakulenko "parameters": {}, 57551a82bbefbfd6dc83309eec440a41ca737062b4Alex Vakulenko "results": {} 58551a82bbefbfd6dc83309eec440a41ca737062b4Alex Vakulenko } 592c7740aac024de03aafcf09ee69f157384d44038Alex Vakulenko }, 60551a82bbefbfd6dc83309eec440a41ca737062b4Alex Vakulenko "state": { 61551a82bbefbfd6dc83309eec440a41ca737062b4Alex Vakulenko "firmwareVersion": {"type": "string"} 62551a82bbefbfd6dc83309eec440a41ca737062b4Alex Vakulenko } 63551a82bbefbfd6dc83309eec440a41ca737062b4Alex Vakulenko }, 64551a82bbefbfd6dc83309eec440a41ca737062b4Alex Vakulenko "trait2": { 65551a82bbefbfd6dc83309eec440a41ca737062b4Alex Vakulenko "state": { 66551a82bbefbfd6dc83309eec440a41ca737062b4Alex Vakulenko "battery_level": {"type": "integer"} 6711b2f2382db08ce26f4c4875a4e2d77586165720Vitaly Buka } 6811b2f2382db08ce26f4c4875a4e2d77586165720Vitaly Buka } 6911b2f2382db08ce26f4c4875a4e2d77586165720Vitaly Buka})"; 7011b2f2382db08ce26f4c4875a4e2d77586165720Vitaly Buka 7111b2f2382db08ce26f4c4875a4e2d77586165720Vitaly Bukaconst char kDeviceResource[] = R"({ 7288272d5b9e88dfd253c18aea4792fe57ee51696dVitaly Buka "kind": "weave#device", 730b7bb9f1484126e098d0c2a295d4213583005b19Johan Euphrosine "id": "CLOUD_ID", 7411b2f2382db08ce26f4c4875a4e2d77586165720Vitaly Buka "channel": { 7511b2f2382db08ce26f4c4875a4e2d77586165720Vitaly Buka "supportedType": "pull" 7611b2f2382db08ce26f4c4875a4e2d77586165720Vitaly Buka }, 7711b2f2382db08ce26f4c4875a4e2d77586165720Vitaly Buka "deviceKind": "vendor", 7811b2f2382db08ce26f4c4875a4e2d77586165720Vitaly Buka "modelManifestId": "ABCDE", 7911b2f2382db08ce26f4c4875a4e2d77586165720Vitaly Buka "systemName": "", 80a05eadb5a34b90e3aec184c41b9e3481e18902b3Vitaly Buka "name": "TEST_NAME", 8111b2f2382db08ce26f4c4875a4e2d77586165720Vitaly Buka "displayName": "", 8211b2f2382db08ce26f4c4875a4e2d77586165720Vitaly Buka "description": "Developer device", 8311b2f2382db08ce26f4c4875a4e2d77586165720Vitaly Buka "stateValidationEnabled": true, 8411b2f2382db08ce26f4c4875a4e2d77586165720Vitaly Buka "commandDefs":{ 85551a82bbefbfd6dc83309eec440a41ca737062b4Alex Vakulenko "trait1": { 8611b2f2382db08ce26f4c4875a4e2d77586165720Vitaly Buka "reboot": { 8711b2f2382db08ce26f4c4875a4e2d77586165720Vitaly Buka "minimalRole": "user", 887e894da1c5fcc4fafa6cc69b612c9c14f78aed51Alex Vakulenko "parameters": {"delay": {"type": "integer"}}, 8911b2f2382db08ce26f4c4875a4e2d77586165720Vitaly Buka "results": {} 9011b2f2382db08ce26f4c4875a4e2d77586165720Vitaly Buka }, 9111b2f2382db08ce26f4c4875a4e2d77586165720Vitaly Buka "shutdown": { 9211b2f2382db08ce26f4c4875a4e2d77586165720Vitaly Buka "minimalRole": "user", 9311b2f2382db08ce26f4c4875a4e2d77586165720Vitaly Buka "parameters": {}, 9411b2f2382db08ce26f4c4875a4e2d77586165720Vitaly Buka "results": {} 9511b2f2382db08ce26f4c4875a4e2d77586165720Vitaly Buka } 9611b2f2382db08ce26f4c4875a4e2d77586165720Vitaly Buka } 9711b2f2382db08ce26f4c4875a4e2d77586165720Vitaly Buka }, 9811b2f2382db08ce26f4c4875a4e2d77586165720Vitaly Buka "state":{ 99551a82bbefbfd6dc83309eec440a41ca737062b4Alex Vakulenko "trait1": {"firmwareVersion":"FIRMWARE_VERSION"}, 100551a82bbefbfd6dc83309eec440a41ca737062b4Alex Vakulenko "trait2": {"battery_level":44} 101551a82bbefbfd6dc83309eec440a41ca737062b4Alex Vakulenko }, 102551a82bbefbfd6dc83309eec440a41ca737062b4Alex Vakulenko "traits": { 103551a82bbefbfd6dc83309eec440a41ca737062b4Alex Vakulenko "trait1": { 104551a82bbefbfd6dc83309eec440a41ca737062b4Alex Vakulenko "commands": { 105551a82bbefbfd6dc83309eec440a41ca737062b4Alex Vakulenko "reboot": { 106551a82bbefbfd6dc83309eec440a41ca737062b4Alex Vakulenko "minimalRole": "user" 107551a82bbefbfd6dc83309eec440a41ca737062b4Alex Vakulenko }, 108551a82bbefbfd6dc83309eec440a41ca737062b4Alex Vakulenko "shutdown": { 109551a82bbefbfd6dc83309eec440a41ca737062b4Alex Vakulenko "minimalRole": "user", 110551a82bbefbfd6dc83309eec440a41ca737062b4Alex Vakulenko "parameters": {}, 111551a82bbefbfd6dc83309eec440a41ca737062b4Alex Vakulenko "results": {} 112551a82bbefbfd6dc83309eec440a41ca737062b4Alex Vakulenko } 113551a82bbefbfd6dc83309eec440a41ca737062b4Alex Vakulenko }, 114551a82bbefbfd6dc83309eec440a41ca737062b4Alex Vakulenko "state": { 115551a82bbefbfd6dc83309eec440a41ca737062b4Alex Vakulenko "firmwareVersion": {"type": "string"} 11611b2f2382db08ce26f4c4875a4e2d77586165720Vitaly Buka } 11711b2f2382db08ce26f4c4875a4e2d77586165720Vitaly Buka }, 118551a82bbefbfd6dc83309eec440a41ca737062b4Alex Vakulenko "trait2": { 119551a82bbefbfd6dc83309eec440a41ca737062b4Alex Vakulenko "state": { 120551a82bbefbfd6dc83309eec440a41ca737062b4Alex Vakulenko "battery_level": {"type": "integer"} 121551a82bbefbfd6dc83309eec440a41ca737062b4Alex Vakulenko } 122551a82bbefbfd6dc83309eec440a41ca737062b4Alex Vakulenko } 123551a82bbefbfd6dc83309eec440a41ca737062b4Alex Vakulenko }, 124551a82bbefbfd6dc83309eec440a41ca737062b4Alex Vakulenko "components": { 125551a82bbefbfd6dc83309eec440a41ca737062b4Alex Vakulenko "myComponent": { 126551a82bbefbfd6dc83309eec440a41ca737062b4Alex Vakulenko "traits": ["trait1", "trait2"], 127551a82bbefbfd6dc83309eec440a41ca737062b4Alex Vakulenko "state": { 128551a82bbefbfd6dc83309eec440a41ca737062b4Alex Vakulenko "trait1": {"firmwareVersion":"FIRMWARE_VERSION"}, 129551a82bbefbfd6dc83309eec440a41ca737062b4Alex Vakulenko "trait2": {"battery_level":44} 130551a82bbefbfd6dc83309eec440a41ca737062b4Alex Vakulenko } 131551a82bbefbfd6dc83309eec440a41ca737062b4Alex Vakulenko } 13211b2f2382db08ce26f4c4875a4e2d77586165720Vitaly Buka } 13311b2f2382db08ce26f4c4875a4e2d77586165720Vitaly Buka})"; 13411b2f2382db08ce26f4c4875a4e2d77586165720Vitaly Buka 13511b2f2382db08ce26f4c4875a4e2d77586165720Vitaly Bukaconst char kRegistrationResponse[] = R"({ 13688272d5b9e88dfd253c18aea4792fe57ee51696dVitaly Buka "kind": "weave#registrationTicket", 1370b7bb9f1484126e098d0c2a295d4213583005b19Johan Euphrosine "id": "TICKET_ID", 1380b7bb9f1484126e098d0c2a295d4213583005b19Johan Euphrosine "deviceId": "CLOUD_ID", 13911b2f2382db08ce26f4c4875a4e2d77586165720Vitaly Buka "oauthClientId": "CLIENT_ID", 14011b2f2382db08ce26f4c4875a4e2d77586165720Vitaly Buka "userEmail": "USER@gmail.com", 14111b2f2382db08ce26f4c4875a4e2d77586165720Vitaly Buka "creationTimeMs": "1440087183738", 14211b2f2382db08ce26f4c4875a4e2d77586165720Vitaly Buka "expirationTimeMs": "1440087423738" 14311b2f2382db08ce26f4c4875a4e2d77586165720Vitaly Buka})"; 14411b2f2382db08ce26f4c4875a4e2d77586165720Vitaly Buka 14511b2f2382db08ce26f4c4875a4e2d77586165720Vitaly Bukaconst char kRegistrationFinalResponse[] = R"({ 14688272d5b9e88dfd253c18aea4792fe57ee51696dVitaly Buka "kind": "weave#registrationTicket", 1470b7bb9f1484126e098d0c2a295d4213583005b19Johan Euphrosine "id": "TICKET_ID", 1480b7bb9f1484126e098d0c2a295d4213583005b19Johan Euphrosine "deviceId": "CLOUD_ID", 14911b2f2382db08ce26f4c4875a4e2d77586165720Vitaly Buka "oauthClientId": "CLIENT_ID", 15011b2f2382db08ce26f4c4875a4e2d77586165720Vitaly Buka "userEmail": "USER@gmail.com", 15111b2f2382db08ce26f4c4875a4e2d77586165720Vitaly Buka "robotAccountEmail": "ROBO@gmail.com", 15211b2f2382db08ce26f4c4875a4e2d77586165720Vitaly Buka "robotAccountAuthorizationCode": "AUTH_CODE", 15311b2f2382db08ce26f4c4875a4e2d77586165720Vitaly Buka "creationTimeMs": "1440087183738", 15411b2f2382db08ce26f4c4875a4e2d77586165720Vitaly Buka "expirationTimeMs": "1440087423738" 15511b2f2382db08ce26f4c4875a4e2d77586165720Vitaly Buka})"; 15611b2f2382db08ce26f4c4875a4e2d77586165720Vitaly Buka 15711b2f2382db08ce26f4c4875a4e2d77586165720Vitaly Bukaconst char kAuthTokenResponse[] = R"({ 15811b2f2382db08ce26f4c4875a4e2d77586165720Vitaly Buka "access_token" : "ACCESS_TOKEN", 15911b2f2382db08ce26f4c4875a4e2d77586165720Vitaly Buka "token_type" : "Bearer", 16011b2f2382db08ce26f4c4875a4e2d77586165720Vitaly Buka "expires_in" : 3599, 16111b2f2382db08ce26f4c4875a4e2d77586165720Vitaly Buka "refresh_token" : "REFRESH_TOKEN" 16211b2f2382db08ce26f4c4875a4e2d77586165720Vitaly Buka})"; 16311b2f2382db08ce26f4c4875a4e2d77586165720Vitaly Buka 1643dc2f53ffba89aa380a0474205b57681537b6159Vitaly BukaMATCHER_P(MatchTxt, txt, "") { 1653dc2f53ffba89aa380a0474205b57681537b6159Vitaly Buka std::vector<std::string> txt_copy = txt; 1663dc2f53ffba89aa380a0474205b57681537b6159Vitaly Buka std::sort(txt_copy.begin(), txt_copy.end()); 1673dc2f53ffba89aa380a0474205b57681537b6159Vitaly Buka std::vector<std::string> arg_copy = arg; 1683dc2f53ffba89aa380a0474205b57681537b6159Vitaly Buka std::sort(arg_copy.begin(), arg_copy.end()); 1693dc2f53ffba89aa380a0474205b57681537b6159Vitaly Buka return (arg_copy == txt_copy); 1703dc2f53ffba89aa380a0474205b57681537b6159Vitaly Buka} 1713dc2f53ffba89aa380a0474205b57681537b6159Vitaly Buka 172e69e4ee64c466730b98fb7fa3049aabcc85f8984Vitaly Bukatemplate <class Map> 173e69e4ee64c466730b98fb7fa3049aabcc85f8984Vitaly Bukastd::set<typename Map::key_type> GetKeys(const Map& map) { 174e69e4ee64c466730b98fb7fa3049aabcc85f8984Vitaly Buka std::set<typename Map::key_type> result; 175e69e4ee64c466730b98fb7fa3049aabcc85f8984Vitaly Buka for (const auto& pair : map) 176e69e4ee64c466730b98fb7fa3049aabcc85f8984Vitaly Buka result.insert(pair.first); 177e69e4ee64c466730b98fb7fa3049aabcc85f8984Vitaly Buka return result; 178e69e4ee64c466730b98fb7fa3049aabcc85f8984Vitaly Buka} 179e69e4ee64c466730b98fb7fa3049aabcc85f8984Vitaly Buka 180e69e4ee64c466730b98fb7fa3049aabcc85f8984Vitaly Buka} // namespace 181e69e4ee64c466730b98fb7fa3049aabcc85f8984Vitaly Buka 18211b2f2382db08ce26f4c4875a4e2d77586165720Vitaly Bukaclass WeaveTest : public ::testing::Test { 18311b2f2382db08ce26f4c4875a4e2d77586165720Vitaly Buka protected: 1846a1ba84d9b295dcc0c8f50b580182a665c4aa8ceVitaly Buka void SetUp() override { 1856a1ba84d9b295dcc0c8f50b580182a665c4aa8ceVitaly Buka EXPECT_CALL(wifi_, IsWifi24Supported()).WillRepeatedly(Return(true)); 1866a1ba84d9b295dcc0c8f50b580182a665c4aa8ceVitaly Buka EXPECT_CALL(wifi_, IsWifi50Supported()).WillRepeatedly(Return(false)); 1876a1ba84d9b295dcc0c8f50b580182a665c4aa8ceVitaly Buka } 18811b2f2382db08ce26f4c4875a4e2d77586165720Vitaly Buka 18972d8d1611efb8c0dd87d466e971bea9468b7c3a1Vitaly Buka template <class UrlMatcher> 1901a42e1466de3edd0c79215b739cd8e929ef8a7e8Vitaly Buka void ExpectRequest(HttpClient::Method method, 19172d8d1611efb8c0dd87d466e971bea9468b7c3a1Vitaly Buka const UrlMatcher& url_matcher, 19211b2f2382db08ce26f4c4875a4e2d77586165720Vitaly Buka const std::string& json_response) { 19372d8d1611efb8c0dd87d466e971bea9468b7c3a1Vitaly Buka EXPECT_CALL(http_client_, SendRequest(method, url_matcher, _, _, _)) 19434668e731bb194b443bc0e6029d6d3583f08de28Vitaly Buka .WillOnce(WithArgs<4>(Invoke( 19534668e731bb194b443bc0e6029d6d3583f08de28Vitaly Buka [json_response](const HttpClient::SendRequestCallback& callback) { 19634668e731bb194b443bc0e6029d6d3583f08de28Vitaly Buka std::unique_ptr<provider::test::MockHttpClientResponse> response{ 19734668e731bb194b443bc0e6029d6d3583f08de28Vitaly Buka new StrictMock<provider::test::MockHttpClientResponse>}; 19834668e731bb194b443bc0e6029d6d3583f08de28Vitaly Buka EXPECT_CALL(*response, GetStatusCode()) 19934668e731bb194b443bc0e6029d6d3583f08de28Vitaly Buka .Times(AtLeast(1)) 20034668e731bb194b443bc0e6029d6d3583f08de28Vitaly Buka .WillRepeatedly(Return(200)); 20134668e731bb194b443bc0e6029d6d3583f08de28Vitaly Buka EXPECT_CALL(*response, GetContentType()) 20234668e731bb194b443bc0e6029d6d3583f08de28Vitaly Buka .Times(AtLeast(1)) 20334668e731bb194b443bc0e6029d6d3583f08de28Vitaly Buka .WillRepeatedly(Return("application/json; charset=utf-8")); 20434668e731bb194b443bc0e6029d6d3583f08de28Vitaly Buka EXPECT_CALL(*response, GetData()) 20534668e731bb194b443bc0e6029d6d3583f08de28Vitaly Buka .WillRepeatedly(Return(json_response)); 20634668e731bb194b443bc0e6029d6d3583f08de28Vitaly Buka callback.Run(std::move(response), nullptr); 20734668e731bb194b443bc0e6029d6d3583f08de28Vitaly Buka }))); 20811b2f2382db08ce26f4c4875a4e2d77586165720Vitaly Buka } 20911b2f2382db08ce26f4c4875a4e2d77586165720Vitaly Buka 21011b2f2382db08ce26f4c4875a4e2d77586165720Vitaly Buka void InitNetwork() { 2113ab6f6e82d3feda765336c3ddd5cfbb8187f17f5Vitaly Buka EXPECT_CALL(network_, AddConnectionChangedCallback(_)) 2123ab6f6e82d3feda765336c3ddd5cfbb8187f17f5Vitaly Buka .WillRepeatedly(Invoke( 2131e3636732171afb8cceb9e5cb835ec6a93787dbaVitaly Buka [this](const provider::Network::ConnectionChangedCallback& cb) { 214ca365fb44ec9064043375936c28434b3950a98a3Vitaly Buka network_callbacks_.push_back(cb); 215ca365fb44ec9064043375936c28434b3950a98a3Vitaly Buka })); 21611b2f2382db08ce26f4c4875a4e2d77586165720Vitaly Buka EXPECT_CALL(network_, GetConnectionState()) 21735f317dacc5176ccc8a7b2b80eeb518ed1f632cdVitaly Buka .WillRepeatedly(Return(Network::State::kOffline)); 218ca365fb44ec9064043375936c28434b3950a98a3Vitaly Buka } 219ca365fb44ec9064043375936c28434b3950a98a3Vitaly Buka 220beddc6023ef95fdf2c45ad9a300411a2b3895692Vitaly Buka void InitDnsSd() { 221beddc6023ef95fdf2c45ad9a300411a2b3895692Vitaly Buka EXPECT_CALL(dns_sd_, PublishService(_, _, _)).WillRepeatedly(Return()); 222beddc6023ef95fdf2c45ad9a300411a2b3895692Vitaly Buka EXPECT_CALL(dns_sd_, StopPublishing("_privet._tcp")).WillOnce(Return()); 22311b2f2382db08ce26f4c4875a4e2d77586165720Vitaly Buka } 22411b2f2382db08ce26f4c4875a4e2d77586165720Vitaly Buka 225beddc6023ef95fdf2c45ad9a300411a2b3895692Vitaly Buka void InitDnsSdPublishing(bool registered, const std::string& flags) { 22687eb78898cd2e8e632ed1a6eac641bd3bd1435a9Vitaly Buka std::vector<std::string> txt{ 22787eb78898cd2e8e632ed1a6eac641bd3bd1435a9Vitaly Buka {"id=TEST_DEVICE_ID"}, {"flags=" + flags}, {"mmid=ABCDE"}, 22887eb78898cd2e8e632ed1a6eac641bd3bd1435a9Vitaly Buka {"services=developmentBoard"}, {"txtvers=3"}, {"ty=TEST_NAME"}}; 22911b2f2382db08ce26f4c4875a4e2d77586165720Vitaly Buka if (registered) { 2300b7bb9f1484126e098d0c2a295d4213583005b19Johan Euphrosine txt.push_back("gcd_id=CLOUD_ID"); 23111b2f2382db08ce26f4c4875a4e2d77586165720Vitaly Buka 23211b2f2382db08ce26f4c4875a4e2d77586165720Vitaly Buka // During registration device may announce itself twice: 23311b2f2382db08ce26f4c4875a4e2d77586165720Vitaly Buka // 1. with GCD ID but not connected (DB) 23411b2f2382db08ce26f4c4875a4e2d77586165720Vitaly Buka // 2. with GCD ID and connected (BB) 235beddc6023ef95fdf2c45ad9a300411a2b3895692Vitaly Buka EXPECT_CALL(dns_sd_, PublishService("_privet._tcp", 11, MatchTxt(txt))) 23611b2f2382db08ce26f4c4875a4e2d77586165720Vitaly Buka .Times(AtMost(1)) 23711b2f2382db08ce26f4c4875a4e2d77586165720Vitaly Buka .WillOnce(Return()); 23811b2f2382db08ce26f4c4875a4e2d77586165720Vitaly Buka 2393dc2f53ffba89aa380a0474205b57681537b6159Vitaly Buka txt[1] = "flags=BB"; 24011b2f2382db08ce26f4c4875a4e2d77586165720Vitaly Buka } 24111b2f2382db08ce26f4c4875a4e2d77586165720Vitaly Buka 242beddc6023ef95fdf2c45ad9a300411a2b3895692Vitaly Buka EXPECT_CALL(dns_sd_, PublishService("_privet._tcp", 11, MatchTxt(txt))) 243bced5affdc79322da2ac334463e0aa0cf5fe0649Vitaly Buka .Times(AtMost(1)) 2443dc2f53ffba89aa380a0474205b57681537b6159Vitaly Buka .WillOnce(Return()); 24511b2f2382db08ce26f4c4875a4e2d77586165720Vitaly Buka } 24611b2f2382db08ce26f4c4875a4e2d77586165720Vitaly Buka 24711b2f2382db08ce26f4c4875a4e2d77586165720Vitaly Buka void InitHttpServer() { 24811b2f2382db08ce26f4c4875a4e2d77586165720Vitaly Buka EXPECT_CALL(http_server_, GetHttpPort()).WillRepeatedly(Return(11)); 24911b2f2382db08ce26f4c4875a4e2d77586165720Vitaly Buka EXPECT_CALL(http_server_, GetHttpsPort()).WillRepeatedly(Return(12)); 250efee3a281cddd7975d4f732bf8179b1e32ce6806Alex Vakulenko EXPECT_CALL(http_server_, GetRequestTimeout()) 251efee3a281cddd7975d4f732bf8179b1e32ce6806Alex Vakulenko .WillRepeatedly(Return(base::TimeDelta::Max())); 25211b2f2382db08ce26f4c4875a4e2d77586165720Vitaly Buka EXPECT_CALL(http_server_, GetHttpsCertificateFingerprint()) 253138aec4d9486974563a63903f2a74b7a797c2aeeVitaly Buka .WillRepeatedly(Return(std::vector<uint8_t>{1, 2, 3})); 2541a39c81c169e677601ddf67ad0a443ca6226033cVitaly Buka EXPECT_CALL(http_server_, AddHttpRequestHandler(_, _)) 2551a39c81c169e677601ddf67ad0a443ca6226033cVitaly Buka .WillRepeatedly(Invoke( 2561a39c81c169e677601ddf67ad0a443ca6226033cVitaly Buka [this](const std::string& path_prefix, 2571a39c81c169e677601ddf67ad0a443ca6226033cVitaly Buka const provider::HttpServer::RequestHandlerCallback& cb) { 258e69e4ee64c466730b98fb7fa3049aabcc85f8984Vitaly Buka http_handlers_[path_prefix] = cb; 2591a39c81c169e677601ddf67ad0a443ca6226033cVitaly Buka })); 2601a39c81c169e677601ddf67ad0a443ca6226033cVitaly Buka EXPECT_CALL(http_server_, AddHttpsRequestHandler(_, _)) 26101893cc3989f53fd9832e8aa7029039ebd2d2877Vitaly Buka .WillRepeatedly(Invoke( 26201893cc3989f53fd9832e8aa7029039ebd2d2877Vitaly Buka [this](const std::string& path_prefix, 26301893cc3989f53fd9832e8aa7029039ebd2d2877Vitaly Buka const provider::HttpServer::RequestHandlerCallback& cb) { 264e69e4ee64c466730b98fb7fa3049aabcc85f8984Vitaly Buka https_handlers_[path_prefix] = cb; 2651e3636732171afb8cceb9e5cb835ec6a93787dbaVitaly Buka })); 26611b2f2382db08ce26f4c4875a4e2d77586165720Vitaly Buka } 26711b2f2382db08ce26f4c4875a4e2d77586165720Vitaly Buka 268ca365fb44ec9064043375936c28434b3950a98a3Vitaly Buka void InitDefaultExpectations() { 26911b2f2382db08ce26f4c4875a4e2d77586165720Vitaly Buka InitNetwork(); 270a05eadb5a34b90e3aec184c41b9e3481e18902b3Vitaly Buka EXPECT_CALL(wifi_, StartAccessPoint(MatchesRegex("TEST_NAME.*prv"))) 271ca365fb44ec9064043375936c28434b3950a98a3Vitaly Buka .WillOnce(Return()); 27211b2f2382db08ce26f4c4875a4e2d77586165720Vitaly Buka InitHttpServer(); 273beddc6023ef95fdf2c45ad9a300411a2b3895692Vitaly Buka InitDnsSd(); 274ca365fb44ec9064043375936c28434b3950a98a3Vitaly Buka } 27511b2f2382db08ce26f4c4875a4e2d77586165720Vitaly Buka 276ca365fb44ec9064043375936c28434b3950a98a3Vitaly Buka void StartDevice() { 277c5bdd173a217503710bf1d700a03bfe9a614bb4aVitaly Buka device_ = weave::Device::Create(&config_store_, &task_runner_, 278c5bdd173a217503710bf1d700a03bfe9a614bb4aVitaly Buka &http_client_, &network_, &dns_sd_, 279c5bdd173a217503710bf1d700a03bfe9a614bb4aVitaly Buka &http_server_, &wifi_, &bluetooth_); 28011b2f2382db08ce26f4c4875a4e2d77586165720Vitaly Buka 281e69e4ee64c466730b98fb7fa3049aabcc85f8984Vitaly Buka EXPECT_EQ((std::set<std::string>{ 28234668e731bb194b443bc0e6029d6d3583f08de28Vitaly Buka // clang-format off 28334668e731bb194b443bc0e6029d6d3583f08de28Vitaly Buka "/privet/info", 28434668e731bb194b443bc0e6029d6d3583f08de28Vitaly Buka "/privet/v3/pairing/cancel", 28534668e731bb194b443bc0e6029d6d3583f08de28Vitaly Buka "/privet/v3/pairing/confirm", 28634668e731bb194b443bc0e6029d6d3583f08de28Vitaly Buka "/privet/v3/pairing/start", 28734668e731bb194b443bc0e6029d6d3583f08de28Vitaly Buka // clang-format on 28834668e731bb194b443bc0e6029d6d3583f08de28Vitaly Buka }), 289e69e4ee64c466730b98fb7fa3049aabcc85f8984Vitaly Buka GetKeys(http_handlers_)); 290e69e4ee64c466730b98fb7fa3049aabcc85f8984Vitaly Buka EXPECT_EQ((std::set<std::string>{ 29134668e731bb194b443bc0e6029d6d3583f08de28Vitaly Buka // clang-format off 29234668e731bb194b443bc0e6029d6d3583f08de28Vitaly Buka "/privet/info", 2932d24e0ea050085e91bb8282a0408561d6a17797aVitaly Buka "/privet/v3/accessControl/claim", 2942d24e0ea050085e91bb8282a0408561d6a17797aVitaly Buka "/privet/v3/accessControl/confirm", 29534668e731bb194b443bc0e6029d6d3583f08de28Vitaly Buka "/privet/v3/auth", 29634668e731bb194b443bc0e6029d6d3583f08de28Vitaly Buka "/privet/v3/checkForUpdates", 29734668e731bb194b443bc0e6029d6d3583f08de28Vitaly Buka "/privet/v3/commandDefs", 29834668e731bb194b443bc0e6029d6d3583f08de28Vitaly Buka "/privet/v3/commands/cancel", 29934668e731bb194b443bc0e6029d6d3583f08de28Vitaly Buka "/privet/v3/commands/execute", 30034668e731bb194b443bc0e6029d6d3583f08de28Vitaly Buka "/privet/v3/commands/list", 30134668e731bb194b443bc0e6029d6d3583f08de28Vitaly Buka "/privet/v3/commands/status", 30234668e731bb194b443bc0e6029d6d3583f08de28Vitaly Buka "/privet/v3/components", 30334668e731bb194b443bc0e6029d6d3583f08de28Vitaly Buka "/privet/v3/pairing/cancel", 30434668e731bb194b443bc0e6029d6d3583f08de28Vitaly Buka "/privet/v3/pairing/confirm", 30534668e731bb194b443bc0e6029d6d3583f08de28Vitaly Buka "/privet/v3/pairing/start", 30634668e731bb194b443bc0e6029d6d3583f08de28Vitaly Buka "/privet/v3/setup/start", 30734668e731bb194b443bc0e6029d6d3583f08de28Vitaly Buka "/privet/v3/setup/status", 30834668e731bb194b443bc0e6029d6d3583f08de28Vitaly Buka "/privet/v3/state", 30934668e731bb194b443bc0e6029d6d3583f08de28Vitaly Buka "/privet/v3/traits", 31034668e731bb194b443bc0e6029d6d3583f08de28Vitaly Buka // clang-format on 31134668e731bb194b443bc0e6029d6d3583f08de28Vitaly Buka }), 312e69e4ee64c466730b98fb7fa3049aabcc85f8984Vitaly Buka GetKeys(https_handlers_)); 313e69e4ee64c466730b98fb7fa3049aabcc85f8984Vitaly Buka 314551a82bbefbfd6dc83309eec440a41ca737062b4Alex Vakulenko device_->AddTraitDefinitionsFromJson(kTraitDefs); 31534668e731bb194b443bc0e6029d6d3583f08de28Vitaly Buka EXPECT_TRUE( 31634668e731bb194b443bc0e6029d6d3583f08de28Vitaly Buka device_->AddComponent("myComponent", {"trait1", "trait2"}, nullptr)); 317551a82bbefbfd6dc83309eec440a41ca737062b4Alex Vakulenko EXPECT_TRUE(device_->SetStatePropertiesFromJson( 318551a82bbefbfd6dc83309eec440a41ca737062b4Alex Vakulenko "myComponent", R"({"trait2": {"battery_level":44}})", nullptr)); 3190ac6ca687c519367158c6be76c5b7bff2064bac4Vitaly Buka 32011b2f2382db08ce26f4c4875a4e2d77586165720Vitaly Buka task_runner_.Run(); 32111b2f2382db08ce26f4c4875a4e2d77586165720Vitaly Buka } 32211b2f2382db08ce26f4c4875a4e2d77586165720Vitaly Buka 32335f317dacc5176ccc8a7b2b80eeb518ed1f632cdVitaly Buka void NotifyNetworkChanged(provider::Network::State state, 3241e3636732171afb8cceb9e5cb835ec6a93787dbaVitaly Buka base::TimeDelta delay) { 32565e1f21f13102b076156e2e6a07486c06f5b25d1Vitaly Buka auto task = [this, state] { 32665e1f21f13102b076156e2e6a07486c06f5b25d1Vitaly Buka EXPECT_CALL(network_, GetConnectionState()).WillRepeatedly(Return(state)); 32765e1f21f13102b076156e2e6a07486c06f5b25d1Vitaly Buka for (const auto& cb : network_callbacks_) 32865e1f21f13102b076156e2e6a07486c06f5b25d1Vitaly Buka cb.Run(); 32965e1f21f13102b076156e2e6a07486c06f5b25d1Vitaly Buka }; 33065e1f21f13102b076156e2e6a07486c06f5b25d1Vitaly Buka 33165e1f21f13102b076156e2e6a07486c06f5b25d1Vitaly Buka task_runner_.PostDelayedTask(FROM_HERE, base::Bind(task), delay); 3323884ce15b28039b7c73cf2e79a4c060ca3701bf3Vitaly Buka } 3333884ce15b28039b7c73cf2e79a4c060ca3701bf3Vitaly Buka 334e69e4ee64c466730b98fb7fa3049aabcc85f8984Vitaly Buka std::map<std::string, provider::HttpServer::RequestHandlerCallback> 335e69e4ee64c466730b98fb7fa3049aabcc85f8984Vitaly Buka http_handlers_; 336e69e4ee64c466730b98fb7fa3049aabcc85f8984Vitaly Buka std::map<std::string, provider::HttpServer::RequestHandlerCallback> 337e69e4ee64c466730b98fb7fa3049aabcc85f8984Vitaly Buka https_handlers_; 33811b2f2382db08ce26f4c4875a4e2d77586165720Vitaly Buka 3391e3636732171afb8cceb9e5cb835ec6a93787dbaVitaly Buka StrictMock<provider::test::MockConfigStore> config_store_; 340727f3e675fece0ebdcdb0bf0aaf083c374d64d95Vitaly Buka StrictMock<provider::test::FakeTaskRunner> task_runner_; 3411e3636732171afb8cceb9e5cb835ec6a93787dbaVitaly Buka StrictMock<provider::test::MockHttpClient> http_client_; 3421e3636732171afb8cceb9e5cb835ec6a93787dbaVitaly Buka StrictMock<provider::test::MockNetwork> network_; 3431e3636732171afb8cceb9e5cb835ec6a93787dbaVitaly Buka StrictMock<provider::test::MockDnsServiceDiscovery> dns_sd_; 3441e3636732171afb8cceb9e5cb835ec6a93787dbaVitaly Buka StrictMock<provider::test::MockHttpServer> http_server_; 3451e3636732171afb8cceb9e5cb835ec6a93787dbaVitaly Buka StrictMock<provider::test::MockWifi> wifi_; 3461e3636732171afb8cceb9e5cb835ec6a93787dbaVitaly Buka StrictMock<provider::test::MockBluetooth> bluetooth_; 34711b2f2382db08ce26f4c4875a4e2d77586165720Vitaly Buka 3481e3636732171afb8cceb9e5cb835ec6a93787dbaVitaly Buka std::vector<provider::Network::ConnectionChangedCallback> network_callbacks_; 349ca365fb44ec9064043375936c28434b3950a98a3Vitaly Buka 35011b2f2382db08ce26f4c4875a4e2d77586165720Vitaly Buka std::unique_ptr<weave::Device> device_; 35111b2f2382db08ce26f4c4875a4e2d77586165720Vitaly Buka}; 35211b2f2382db08ce26f4c4875a4e2d77586165720Vitaly Buka 353ef213d7f63585accbb7ac9bd5112aeeb1b593c9dVitaly BukaTEST_F(WeaveTest, Mocks) { 354a8ece8f8534ca9b551f93bdba2982f40aff3d619Vitaly Buka // Test checks if mock implements entire interface and mock can be 355a8ece8f8534ca9b551f93bdba2982f40aff3d619Vitaly Buka // instantiated. 356a8ece8f8534ca9b551f93bdba2982f40aff3d619Vitaly Buka test::MockDevice device; 357ef213d7f63585accbb7ac9bd5112aeeb1b593c9dVitaly Buka test::MockCommand command; 358a8ece8f8534ca9b551f93bdba2982f40aff3d619Vitaly Buka} 359a8ece8f8534ca9b551f93bdba2982f40aff3d619Vitaly Buka 36011b2f2382db08ce26f4c4875a4e2d77586165720Vitaly BukaTEST_F(WeaveTest, StartMinimal) { 361c5bdd173a217503710bf1d700a03bfe9a614bb4aVitaly Buka device_ = weave::Device::Create(&config_store_, &task_runner_, &http_client_, 362c5bdd173a217503710bf1d700a03bfe9a614bb4aVitaly Buka &network_, nullptr, nullptr, &wifi_, nullptr); 363b1041e7c3cc58ca919e2924028c03978c7864c5cVitaly Buka} 364b1041e7c3cc58ca919e2924028c03978c7864c5cVitaly Buka 365b1041e7c3cc58ca919e2924028c03978c7864c5cVitaly BukaTEST_F(WeaveTest, StartNoWifi) { 366b1041e7c3cc58ca919e2924028c03978c7864c5cVitaly Buka InitNetwork(); 367b1041e7c3cc58ca919e2924028c03978c7864c5cVitaly Buka InitHttpServer(); 368beddc6023ef95fdf2c45ad9a300411a2b3895692Vitaly Buka InitDnsSd(); 369beddc6023ef95fdf2c45ad9a300411a2b3895692Vitaly Buka InitDnsSdPublishing(false, "CB"); 370b1041e7c3cc58ca919e2924028c03978c7864c5cVitaly Buka 371c5bdd173a217503710bf1d700a03bfe9a614bb4aVitaly Buka device_ = weave::Device::Create(&config_store_, &task_runner_, &http_client_, 372c5bdd173a217503710bf1d700a03bfe9a614bb4aVitaly Buka &network_, &dns_sd_, &http_server_, nullptr, 373c5bdd173a217503710bf1d700a03bfe9a614bb4aVitaly Buka &bluetooth_); 374551a82bbefbfd6dc83309eec440a41ca737062b4Alex Vakulenko device_->AddTraitDefinitionsFromJson(kTraitDefs); 37534668e731bb194b443bc0e6029d6d3583f08de28Vitaly Buka EXPECT_TRUE( 37634668e731bb194b443bc0e6029d6d3583f08de28Vitaly Buka device_->AddComponent("myComponent", {"trait1", "trait2"}, nullptr)); 377b1041e7c3cc58ca919e2924028c03978c7864c5cVitaly Buka 378b1041e7c3cc58ca919e2924028c03978c7864c5cVitaly Buka task_runner_.Run(); 37911b2f2382db08ce26f4c4875a4e2d77586165720Vitaly Buka} 38011b2f2382db08ce26f4c4875a4e2d77586165720Vitaly Buka 381ca365fb44ec9064043375936c28434b3950a98a3Vitaly Bukaclass WeaveBasicTest : public WeaveTest { 382ca365fb44ec9064043375936c28434b3950a98a3Vitaly Buka public: 383ca365fb44ec9064043375936c28434b3950a98a3Vitaly Buka void SetUp() override { 384ca365fb44ec9064043375936c28434b3950a98a3Vitaly Buka WeaveTest::SetUp(); 3853884ce15b28039b7c73cf2e79a4c060ca3701bf3Vitaly Buka 386ca365fb44ec9064043375936c28434b3950a98a3Vitaly Buka InitDefaultExpectations(); 387beddc6023ef95fdf2c45ad9a300411a2b3895692Vitaly Buka InitDnsSdPublishing(false, "DB"); 388ca365fb44ec9064043375936c28434b3950a98a3Vitaly Buka } 389ca365fb44ec9064043375936c28434b3950a98a3Vitaly Buka}; 390ca365fb44ec9064043375936c28434b3950a98a3Vitaly Buka 391ca365fb44ec9064043375936c28434b3950a98a3Vitaly BukaTEST_F(WeaveBasicTest, Start) { 39211b2f2382db08ce26f4c4875a4e2d77586165720Vitaly Buka StartDevice(); 39311b2f2382db08ce26f4c4875a4e2d77586165720Vitaly Buka} 39411b2f2382db08ce26f4c4875a4e2d77586165720Vitaly Buka 395ca365fb44ec9064043375936c28434b3950a98a3Vitaly BukaTEST_F(WeaveBasicTest, Register) { 396747634273144e0df7b37475375ad4790b6a7b0e8Vitaly Buka EXPECT_CALL(network_, OpenSslSocket(_, _, _)).WillRepeatedly(Return()); 39711b2f2382db08ce26f4c4875a4e2d77586165720Vitaly Buka StartDevice(); 39811b2f2382db08ce26f4c4875a4e2d77586165720Vitaly Buka 39911b2f2382db08ce26f4c4875a4e2d77586165720Vitaly Buka auto draft = CreateDictionaryValue(kDeviceResource); 40011b2f2382db08ce26f4c4875a4e2d77586165720Vitaly Buka auto response = CreateDictionaryValue(kRegistrationResponse); 40111b2f2382db08ce26f4c4875a4e2d77586165720Vitaly Buka response->Set("deviceDraft", draft->DeepCopy()); 4020d7aac840eaf1cfc14af1e5e39f3fe281d86ead5Vitaly Buka ExpectRequest(HttpClient::Method::kPatch, 4030d7aac840eaf1cfc14af1e5e39f3fe281d86ead5Vitaly Buka "https://www.googleapis.com/weave/v1/registrationTickets/" 4040d7aac840eaf1cfc14af1e5e39f3fe281d86ead5Vitaly Buka "TICKET_ID?key=TEST_API_KEY", 4050d7aac840eaf1cfc14af1e5e39f3fe281d86ead5Vitaly Buka ValueToString(*response)); 40611b2f2382db08ce26f4c4875a4e2d77586165720Vitaly Buka 40711b2f2382db08ce26f4c4875a4e2d77586165720Vitaly Buka response = CreateDictionaryValue(kRegistrationFinalResponse); 40811b2f2382db08ce26f4c4875a4e2d77586165720Vitaly Buka response->Set("deviceDraft", draft->DeepCopy()); 4090d7aac840eaf1cfc14af1e5e39f3fe281d86ead5Vitaly Buka ExpectRequest(HttpClient::Method::kPost, 4100d7aac840eaf1cfc14af1e5e39f3fe281d86ead5Vitaly Buka "https://www.googleapis.com/weave/v1/registrationTickets/" 4110d7aac840eaf1cfc14af1e5e39f3fe281d86ead5Vitaly Buka "TICKET_ID/finalize?key=TEST_API_KEY", 4120d7aac840eaf1cfc14af1e5e39f3fe281d86ead5Vitaly Buka ValueToString(*response)); 41311b2f2382db08ce26f4c4875a4e2d77586165720Vitaly Buka 4141a42e1466de3edd0c79215b739cd8e929ef8a7e8Vitaly Buka ExpectRequest(HttpClient::Method::kPost, 4151a42e1466de3edd0c79215b739cd8e929ef8a7e8Vitaly Buka "https://accounts.google.com/o/oauth2/token", 41611b2f2382db08ce26f4c4875a4e2d77586165720Vitaly Buka kAuthTokenResponse); 41711b2f2382db08ce26f4c4875a4e2d77586165720Vitaly Buka 41872d8d1611efb8c0dd87d466e971bea9468b7c3a1Vitaly Buka ExpectRequest(HttpClient::Method::kPost, HasSubstr("upsertLocalAuthInfo"), 41972d8d1611efb8c0dd87d466e971bea9468b7c3a1Vitaly Buka {}); 42072d8d1611efb8c0dd87d466e971bea9468b7c3a1Vitaly Buka 421beddc6023ef95fdf2c45ad9a300411a2b3895692Vitaly Buka InitDnsSdPublishing(true, "DB"); 42211b2f2382db08ce26f4c4875a4e2d77586165720Vitaly Buka 42312870bd07dd3c8f44528638a9c290b72e22d32d2Vitaly Buka bool done = false; 424747634273144e0df7b37475375ad4790b6a7b0e8Vitaly Buka device_->Register("TICKET_ID", base::Bind([this, &done](ErrorPtr error) { 425747634273144e0df7b37475375ad4790b6a7b0e8Vitaly Buka EXPECT_FALSE(error); 42612870bd07dd3c8f44528638a9c290b72e22d32d2Vitaly Buka done = true; 42712870bd07dd3c8f44528638a9c290b72e22d32d2Vitaly Buka task_runner_.Break(); 42812870bd07dd3c8f44528638a9c290b72e22d32d2Vitaly Buka EXPECT_EQ("CLOUD_ID", device_->GetSettings().cloud_id); 429747634273144e0df7b37475375ad4790b6a7b0e8Vitaly Buka })); 43012870bd07dd3c8f44528638a9c290b72e22d32d2Vitaly Buka task_runner_.Run(); 43112870bd07dd3c8f44528638a9c290b72e22d32d2Vitaly Buka EXPECT_TRUE(done); 4320a8ab9973e1fdf6b41d8f7b49529c9bd97a9071cVitaly Buka 4330a8ab9973e1fdf6b41d8f7b49529c9bd97a9071cVitaly Buka done = false; 43448a8669ddc2e8d785aad9ad18a5abbf8f1224fdeVitaly Buka device_->Register("TICKET_ID2", base::Bind([this, &done](ErrorPtr error) { 43548a8669ddc2e8d785aad9ad18a5abbf8f1224fdeVitaly Buka EXPECT_TRUE(error->HasError("already_registered")); 43648a8669ddc2e8d785aad9ad18a5abbf8f1224fdeVitaly Buka done = true; 43748a8669ddc2e8d785aad9ad18a5abbf8f1224fdeVitaly Buka task_runner_.Break(); 43848a8669ddc2e8d785aad9ad18a5abbf8f1224fdeVitaly Buka EXPECT_EQ("CLOUD_ID", device_->GetSettings().cloud_id); 43948a8669ddc2e8d785aad9ad18a5abbf8f1224fdeVitaly Buka })); 4400a8ab9973e1fdf6b41d8f7b49529c9bd97a9071cVitaly Buka task_runner_.Run(); 4410a8ab9973e1fdf6b41d8f7b49529c9bd97a9071cVitaly Buka EXPECT_TRUE(done); 44211b2f2382db08ce26f4c4875a4e2d77586165720Vitaly Buka} 44311b2f2382db08ce26f4c4875a4e2d77586165720Vitaly Buka 444ca365fb44ec9064043375936c28434b3950a98a3Vitaly Bukaclass WeaveWiFiSetupTest : public WeaveTest { 445ca365fb44ec9064043375936c28434b3950a98a3Vitaly Buka public: 446ca365fb44ec9064043375936c28434b3950a98a3Vitaly Buka void SetUp() override { 447ca365fb44ec9064043375936c28434b3950a98a3Vitaly Buka WeaveTest::SetUp(); 448ca365fb44ec9064043375936c28434b3950a98a3Vitaly Buka 449ca365fb44ec9064043375936c28434b3950a98a3Vitaly Buka InitHttpServer(); 450ca365fb44ec9064043375936c28434b3950a98a3Vitaly Buka InitNetwork(); 451beddc6023ef95fdf2c45ad9a300411a2b3895692Vitaly Buka InitDnsSd(); 452ca365fb44ec9064043375936c28434b3950a98a3Vitaly Buka 453ca365fb44ec9064043375936c28434b3950a98a3Vitaly Buka EXPECT_CALL(network_, GetConnectionState()) 454efad5b25439063124eccf100fd79c9489c9705beVitaly Buka .WillRepeatedly(Return(provider::Network::State::kOnline)); 455ca365fb44ec9064043375936c28434b3950a98a3Vitaly Buka } 456ca365fb44ec9064043375936c28434b3950a98a3Vitaly Buka}; 457ca365fb44ec9064043375936c28434b3950a98a3Vitaly Buka 458ca365fb44ec9064043375936c28434b3950a98a3Vitaly BukaTEST_F(WeaveWiFiSetupTest, StartOnlineNoPrevSsid) { 459ca365fb44ec9064043375936c28434b3950a98a3Vitaly Buka StartDevice(); 460ca365fb44ec9064043375936c28434b3950a98a3Vitaly Buka 461ca365fb44ec9064043375936c28434b3950a98a3Vitaly Buka // Short disconnect. 46235f317dacc5176ccc8a7b2b80eeb518ed1f632cdVitaly Buka NotifyNetworkChanged(provider::Network::State::kOffline, {}); 463efad5b25439063124eccf100fd79c9489c9705beVitaly Buka NotifyNetworkChanged(provider::Network::State::kOnline, 4643884ce15b28039b7c73cf2e79a4c060ca3701bf3Vitaly Buka base::TimeDelta::FromSeconds(10)); 465ca365fb44ec9064043375936c28434b3950a98a3Vitaly Buka task_runner_.Run(); 466ca365fb44ec9064043375936c28434b3950a98a3Vitaly Buka 467ca365fb44ec9064043375936c28434b3950a98a3Vitaly Buka // Long disconnect. 46835f317dacc5176ccc8a7b2b80eeb518ed1f632cdVitaly Buka NotifyNetworkChanged(Network::State::kOffline, {}); 469ca365fb44ec9064043375936c28434b3950a98a3Vitaly Buka auto offline_from = task_runner_.GetClock()->Now(); 470a05eadb5a34b90e3aec184c41b9e3481e18902b3Vitaly Buka EXPECT_CALL(wifi_, StartAccessPoint(MatchesRegex("TEST_NAME.*prv"))) 471ca365fb44ec9064043375936c28434b3950a98a3Vitaly Buka .WillOnce(InvokeWithoutArgs([this, offline_from]() { 472ca365fb44ec9064043375936c28434b3950a98a3Vitaly Buka EXPECT_GT(task_runner_.GetClock()->Now() - offline_from, 473ca365fb44ec9064043375936c28434b3950a98a3Vitaly Buka base::TimeDelta::FromMinutes(1)); 474caf42bdc1c8cb18c2663f2c8ade3f47c436f8637Vitaly Buka task_runner_.Break(); 475ca365fb44ec9064043375936c28434b3950a98a3Vitaly Buka })); 476ca365fb44ec9064043375936c28434b3950a98a3Vitaly Buka task_runner_.Run(); 477ca365fb44ec9064043375936c28434b3950a98a3Vitaly Buka} 478ca365fb44ec9064043375936c28434b3950a98a3Vitaly Buka 479ca365fb44ec9064043375936c28434b3950a98a3Vitaly Buka// If device has previously configured WiFi it will run AP for limited time 480ca365fb44ec9064043375936c28434b3950a98a3Vitaly Buka// after which it will try to re-connect. 481ca365fb44ec9064043375936c28434b3950a98a3Vitaly BukaTEST_F(WeaveWiFiSetupTest, StartOnlineWithPrevSsid) { 482ca365fb44ec9064043375936c28434b3950a98a3Vitaly Buka EXPECT_CALL(config_store_, LoadSettings()) 483ca365fb44ec9064043375936c28434b3950a98a3Vitaly Buka .WillRepeatedly(Return(R"({"last_configured_ssid": "TEST_ssid"})")); 484ca365fb44ec9064043375936c28434b3950a98a3Vitaly Buka StartDevice(); 485ca365fb44ec9064043375936c28434b3950a98a3Vitaly Buka 486ca365fb44ec9064043375936c28434b3950a98a3Vitaly Buka // Long disconnect. 48735f317dacc5176ccc8a7b2b80eeb518ed1f632cdVitaly Buka NotifyNetworkChanged(Network::State::kOffline, {}); 488ca365fb44ec9064043375936c28434b3950a98a3Vitaly Buka 489ca365fb44ec9064043375936c28434b3950a98a3Vitaly Buka for (int i = 0; i < 5; ++i) { 490ca365fb44ec9064043375936c28434b3950a98a3Vitaly Buka auto offline_from = task_runner_.GetClock()->Now(); 491ca365fb44ec9064043375936c28434b3950a98a3Vitaly Buka // Temporarily offline mode. 492a05eadb5a34b90e3aec184c41b9e3481e18902b3Vitaly Buka EXPECT_CALL(wifi_, StartAccessPoint(MatchesRegex("TEST_NAME.*prv"))) 493ca365fb44ec9064043375936c28434b3950a98a3Vitaly Buka .WillOnce(InvokeWithoutArgs([this, &offline_from]() { 494ca365fb44ec9064043375936c28434b3950a98a3Vitaly Buka EXPECT_GT(task_runner_.GetClock()->Now() - offline_from, 495ca365fb44ec9064043375936c28434b3950a98a3Vitaly Buka base::TimeDelta::FromMinutes(1)); 496ca365fb44ec9064043375936c28434b3950a98a3Vitaly Buka task_runner_.Break(); 497ca365fb44ec9064043375936c28434b3950a98a3Vitaly Buka })); 498ca365fb44ec9064043375936c28434b3950a98a3Vitaly Buka task_runner_.Run(); 499ca365fb44ec9064043375936c28434b3950a98a3Vitaly Buka 500ca365fb44ec9064043375936c28434b3950a98a3Vitaly Buka // Try to reconnect again. 501ca365fb44ec9064043375936c28434b3950a98a3Vitaly Buka offline_from = task_runner_.GetClock()->Now(); 5021fd619a3ff996aac12bd0ef2ed99090e4dc6b6ddVitaly Buka EXPECT_CALL(wifi_, StopAccessPoint()) 503ca365fb44ec9064043375936c28434b3950a98a3Vitaly Buka .WillOnce(InvokeWithoutArgs([this, offline_from]() { 504ca365fb44ec9064043375936c28434b3950a98a3Vitaly Buka EXPECT_GT(task_runner_.GetClock()->Now() - offline_from, 505ca365fb44ec9064043375936c28434b3950a98a3Vitaly Buka base::TimeDelta::FromMinutes(5)); 506ca365fb44ec9064043375936c28434b3950a98a3Vitaly Buka task_runner_.Break(); 507ca365fb44ec9064043375936c28434b3950a98a3Vitaly Buka })); 508ca365fb44ec9064043375936c28434b3950a98a3Vitaly Buka task_runner_.Run(); 509ca365fb44ec9064043375936c28434b3950a98a3Vitaly Buka } 510ca365fb44ec9064043375936c28434b3950a98a3Vitaly Buka 511efad5b25439063124eccf100fd79c9489c9705beVitaly Buka NotifyNetworkChanged(Network::State::kOnline, {}); 512ca365fb44ec9064043375936c28434b3950a98a3Vitaly Buka task_runner_.Run(); 513ca365fb44ec9064043375936c28434b3950a98a3Vitaly Buka} 514ca365fb44ec9064043375936c28434b3950a98a3Vitaly Buka 515caf42bdc1c8cb18c2663f2c8ade3f47c436f8637Vitaly BukaTEST_F(WeaveWiFiSetupTest, StartOfflineWithSsid) { 516caf42bdc1c8cb18c2663f2c8ade3f47c436f8637Vitaly Buka EXPECT_CALL(config_store_, LoadSettings()) 517caf42bdc1c8cb18c2663f2c8ade3f47c436f8637Vitaly Buka .WillRepeatedly(Return(R"({"last_configured_ssid": "TEST_ssid"})")); 518caf42bdc1c8cb18c2663f2c8ade3f47c436f8637Vitaly Buka EXPECT_CALL(network_, GetConnectionState()) 51935f317dacc5176ccc8a7b2b80eeb518ed1f632cdVitaly Buka .WillRepeatedly(Return(Network::State::kOffline)); 520caf42bdc1c8cb18c2663f2c8ade3f47c436f8637Vitaly Buka 521caf42bdc1c8cb18c2663f2c8ade3f47c436f8637Vitaly Buka auto offline_from = task_runner_.GetClock()->Now(); 522a05eadb5a34b90e3aec184c41b9e3481e18902b3Vitaly Buka EXPECT_CALL(wifi_, StartAccessPoint(MatchesRegex("TEST_NAME.*prv"))) 523caf42bdc1c8cb18c2663f2c8ade3f47c436f8637Vitaly Buka .WillOnce(InvokeWithoutArgs([this, &offline_from]() { 524caf42bdc1c8cb18c2663f2c8ade3f47c436f8637Vitaly Buka EXPECT_GT(task_runner_.GetClock()->Now() - offline_from, 525caf42bdc1c8cb18c2663f2c8ade3f47c436f8637Vitaly Buka base::TimeDelta::FromMinutes(1)); 526caf42bdc1c8cb18c2663f2c8ade3f47c436f8637Vitaly Buka task_runner_.Break(); 527caf42bdc1c8cb18c2663f2c8ade3f47c436f8637Vitaly Buka })); 528caf42bdc1c8cb18c2663f2c8ade3f47c436f8637Vitaly Buka 529caf42bdc1c8cb18c2663f2c8ade3f47c436f8637Vitaly Buka StartDevice(); 530caf42bdc1c8cb18c2663f2c8ade3f47c436f8637Vitaly Buka} 531caf42bdc1c8cb18c2663f2c8ade3f47c436f8637Vitaly Buka 53265e1f21f13102b076156e2e6a07486c06f5b25d1Vitaly BukaTEST_F(WeaveWiFiSetupTest, OfflineLongTimeWithNoSsid) { 53365e1f21f13102b076156e2e6a07486c06f5b25d1Vitaly Buka EXPECT_CALL(network_, GetConnectionState()) 53465e1f21f13102b076156e2e6a07486c06f5b25d1Vitaly Buka .WillRepeatedly(Return(Network::State::kOffline)); 53565e1f21f13102b076156e2e6a07486c06f5b25d1Vitaly Buka NotifyNetworkChanged(provider::Network::State::kOnline, 53665e1f21f13102b076156e2e6a07486c06f5b25d1Vitaly Buka base::TimeDelta::FromHours(15)); 53765e1f21f13102b076156e2e6a07486c06f5b25d1Vitaly Buka 53865e1f21f13102b076156e2e6a07486c06f5b25d1Vitaly Buka { 53965e1f21f13102b076156e2e6a07486c06f5b25d1Vitaly Buka InSequence s; 54065e1f21f13102b076156e2e6a07486c06f5b25d1Vitaly Buka auto time_stamp = task_runner_.GetClock()->Now(); 54165e1f21f13102b076156e2e6a07486c06f5b25d1Vitaly Buka 54265e1f21f13102b076156e2e6a07486c06f5b25d1Vitaly Buka EXPECT_CALL(wifi_, StartAccessPoint(MatchesRegex("TEST_NAME.*prv"))) 54365e1f21f13102b076156e2e6a07486c06f5b25d1Vitaly Buka .WillOnce(InvokeWithoutArgs([this, &time_stamp]() { 54465e1f21f13102b076156e2e6a07486c06f5b25d1Vitaly Buka EXPECT_LE(task_runner_.GetClock()->Now() - time_stamp, 54565e1f21f13102b076156e2e6a07486c06f5b25d1Vitaly Buka base::TimeDelta::FromMinutes(1)); 54665e1f21f13102b076156e2e6a07486c06f5b25d1Vitaly Buka time_stamp = task_runner_.GetClock()->Now(); 54765e1f21f13102b076156e2e6a07486c06f5b25d1Vitaly Buka })); 54865e1f21f13102b076156e2e6a07486c06f5b25d1Vitaly Buka 54965e1f21f13102b076156e2e6a07486c06f5b25d1Vitaly Buka EXPECT_CALL(wifi_, StopAccessPoint()) 55065e1f21f13102b076156e2e6a07486c06f5b25d1Vitaly Buka .WillOnce(InvokeWithoutArgs([this, &time_stamp]() { 55165e1f21f13102b076156e2e6a07486c06f5b25d1Vitaly Buka EXPECT_GT(task_runner_.GetClock()->Now() - time_stamp, 55265e1f21f13102b076156e2e6a07486c06f5b25d1Vitaly Buka base::TimeDelta::FromMinutes(5)); 55365e1f21f13102b076156e2e6a07486c06f5b25d1Vitaly Buka time_stamp = task_runner_.GetClock()->Now(); 55465e1f21f13102b076156e2e6a07486c06f5b25d1Vitaly Buka task_runner_.Break(); 55565e1f21f13102b076156e2e6a07486c06f5b25d1Vitaly Buka })); 55665e1f21f13102b076156e2e6a07486c06f5b25d1Vitaly Buka } 55765e1f21f13102b076156e2e6a07486c06f5b25d1Vitaly Buka 55865e1f21f13102b076156e2e6a07486c06f5b25d1Vitaly Buka StartDevice(); 55965e1f21f13102b076156e2e6a07486c06f5b25d1Vitaly Buka} 56065e1f21f13102b076156e2e6a07486c06f5b25d1Vitaly Buka 56165e1f21f13102b076156e2e6a07486c06f5b25d1Vitaly BukaTEST_F(WeaveWiFiSetupTest, OfflineLongTimeWithSsid) { 56265e1f21f13102b076156e2e6a07486c06f5b25d1Vitaly Buka EXPECT_CALL(config_store_, LoadSettings()) 56365e1f21f13102b076156e2e6a07486c06f5b25d1Vitaly Buka .WillRepeatedly(Return(R"({"last_configured_ssid": "TEST_ssid"})")); 56465e1f21f13102b076156e2e6a07486c06f5b25d1Vitaly Buka EXPECT_CALL(network_, GetConnectionState()) 56565e1f21f13102b076156e2e6a07486c06f5b25d1Vitaly Buka .WillRepeatedly(Return(Network::State::kOffline)); 56665e1f21f13102b076156e2e6a07486c06f5b25d1Vitaly Buka NotifyNetworkChanged(provider::Network::State::kOnline, 56765e1f21f13102b076156e2e6a07486c06f5b25d1Vitaly Buka base::TimeDelta::FromHours(15)); 56865e1f21f13102b076156e2e6a07486c06f5b25d1Vitaly Buka 56965e1f21f13102b076156e2e6a07486c06f5b25d1Vitaly Buka { 57065e1f21f13102b076156e2e6a07486c06f5b25d1Vitaly Buka InSequence s; 57165e1f21f13102b076156e2e6a07486c06f5b25d1Vitaly Buka auto time_stamp = task_runner_.GetClock()->Now(); 57265e1f21f13102b076156e2e6a07486c06f5b25d1Vitaly Buka for (size_t i = 0; i < 10; ++i) { 57365e1f21f13102b076156e2e6a07486c06f5b25d1Vitaly Buka EXPECT_CALL(wifi_, StartAccessPoint(MatchesRegex("TEST_NAME.*prv"))) 57465e1f21f13102b076156e2e6a07486c06f5b25d1Vitaly Buka .WillOnce(InvokeWithoutArgs([this, &time_stamp]() { 57565e1f21f13102b076156e2e6a07486c06f5b25d1Vitaly Buka EXPECT_GT(task_runner_.GetClock()->Now() - time_stamp, 57665e1f21f13102b076156e2e6a07486c06f5b25d1Vitaly Buka base::TimeDelta::FromMinutes(1)); 57765e1f21f13102b076156e2e6a07486c06f5b25d1Vitaly Buka time_stamp = task_runner_.GetClock()->Now(); 57865e1f21f13102b076156e2e6a07486c06f5b25d1Vitaly Buka })); 57965e1f21f13102b076156e2e6a07486c06f5b25d1Vitaly Buka 58065e1f21f13102b076156e2e6a07486c06f5b25d1Vitaly Buka EXPECT_CALL(wifi_, StopAccessPoint()) 58165e1f21f13102b076156e2e6a07486c06f5b25d1Vitaly Buka .WillOnce(InvokeWithoutArgs([this, &time_stamp]() { 58265e1f21f13102b076156e2e6a07486c06f5b25d1Vitaly Buka EXPECT_GT(task_runner_.GetClock()->Now() - time_stamp, 58365e1f21f13102b076156e2e6a07486c06f5b25d1Vitaly Buka base::TimeDelta::FromMinutes(5)); 58465e1f21f13102b076156e2e6a07486c06f5b25d1Vitaly Buka time_stamp = task_runner_.GetClock()->Now(); 58565e1f21f13102b076156e2e6a07486c06f5b25d1Vitaly Buka })); 58665e1f21f13102b076156e2e6a07486c06f5b25d1Vitaly Buka } 58765e1f21f13102b076156e2e6a07486c06f5b25d1Vitaly Buka 58865e1f21f13102b076156e2e6a07486c06f5b25d1Vitaly Buka EXPECT_CALL(wifi_, StartAccessPoint(MatchesRegex("TEST_NAME.*prv"))) 58965e1f21f13102b076156e2e6a07486c06f5b25d1Vitaly Buka .WillOnce(InvokeWithoutArgs([this]() { task_runner_.Break(); })); 59065e1f21f13102b076156e2e6a07486c06f5b25d1Vitaly Buka } 59165e1f21f13102b076156e2e6a07486c06f5b25d1Vitaly Buka 59265e1f21f13102b076156e2e6a07486c06f5b25d1Vitaly Buka StartDevice(); 59365e1f21f13102b076156e2e6a07486c06f5b25d1Vitaly Buka} 59465e1f21f13102b076156e2e6a07486c06f5b25d1Vitaly Buka 59511b2f2382db08ce26f4c4875a4e2d77586165720Vitaly Buka} // namespace weave 596