UpdateEngine-side changes to allow updates over 3G based on device policy.

Some enterprise chromebooks have only 3G and hence they need the ability
to update over 3G if the enterprise policy allows that. This CL adds
the support in update_engine to enable that.

BUG=chromium-os:31099
TEST=Tested E2E on 3G, added unit tests and did regression testing.
CQ-DEPEND=I1a55a392f3dc0f12d917eb45dcf0456b57735514
Change-Id: I121bda35e54fa6c35e002a76db198d13b72b650e
Reviewed-on: https://gerrit.chromium.org/gerrit/25470
Commit-Ready: Jay Srinivasan <jaysri@chromium.org>
Reviewed-by: Jay Srinivasan <jaysri@chromium.org>
Tested-by: Jay Srinivasan <jaysri@chromium.org>
diff --git a/http_fetcher_unittest.cc b/http_fetcher_unittest.cc
index 2a0d5a6..f2f1272 100644
--- a/http_fetcher_unittest.cc
+++ b/http_fetcher_unittest.cc
@@ -12,12 +12,14 @@
 #include <base/memory/scoped_ptr.h>
 #include <base/string_util.h>
 #include <base/stringprintf.h>
+#include <chromeos/dbus/service_constants.h>
 #include <glib.h>
 #include <gtest/gtest.h>
 
 #include "update_engine/http_common.h"
 #include "update_engine/http_fetcher_unittest.h"
 #include "update_engine/libcurl_http_fetcher.h"
+#include "update_engine/mock_connection_manager.h"
 #include "update_engine/mock_http_fetcher.h"
 #include "update_engine/mock_system_state.h"
 #include "update_engine/multi_range_http_fetcher.h"
@@ -29,6 +31,11 @@
 using std::string;
 using std::vector;
 
+using testing::_;
+using testing::SetArgumentPointee;
+using testing::DoAll;
+using testing::Return;
+
 namespace {
 
 const int kBigLength           = 100000;
@@ -44,10 +51,9 @@
 static const char *kUnusedUrl = "unused://unused";
 
 static inline string LocalServerUrlForPath(const string& path) {
-  return (string("http://127.0.0.1:") + base::StringPrintf("%d", kServerPort) + path);
+  return base::StringPrintf("http://127.0.0.1:%d%s", kServerPort, path.c_str());
 }
 
-
 //
 // Class hierarchy for HTTP server implementations.
 //
@@ -131,15 +137,18 @@
   bool validate_quit_;
 };
 
-
-
 //
 // Class hierarchy for HTTP fetcher test wrappers.
 //
 
 class AnyHttpFetcherTest {
  public:
-  virtual HttpFetcher* NewLargeFetcher(size_t num_proxies) = 0;
+  AnyHttpFetcherTest()
+      : mock_connection_manager_(&mock_system_state_) {
+    mock_system_state_.SetConnectionManager(&mock_connection_manager_);
+  }
+
+ virtual HttpFetcher* NewLargeFetcher(size_t num_proxies) = 0;
   HttpFetcher* NewLargeFetcher() {
     return NewLargeFetcher(1);
   }
@@ -162,6 +171,8 @@
 
  protected:
   DirectProxyResolver proxy_resolver_;
+  MockSystemState mock_system_state_;
+  MockConnectionManager mock_connection_manager_;
 };
 
 class MockHttpFetcherTest : public AnyHttpFetcherTest {
@@ -210,7 +221,6 @@
     // Speed up test execution.
     ret->set_idle_seconds(1);
     ret->set_retry_seconds(1);
-    ret->SetConnectionAsExpensive(false);
     ret->SetBuildType(false);
     return ret;
   }
@@ -243,8 +253,6 @@
   virtual HttpServer *CreateServer() {
     return new PythonHttpServer;
   }
-
-  MockSystemState mock_system_state_;
 };
 
 class MultiRangeHttpFetcherTest : public LibcurlHttpFetcherTest {
@@ -263,7 +271,6 @@
     // Speed up test execution.
     ret->set_idle_seconds(1);
     ret->set_retry_seconds(1);
-    ret->SetConnectionAsExpensive(false);
     ret->SetBuildType(false);
     return ret;
   }
@@ -368,6 +375,15 @@
     scoped_ptr<HttpFetcher> fetcher(this->test_.NewSmallFetcher());
     fetcher->set_delegate(&delegate);
 
+    MockConnectionManager* mock_cm = dynamic_cast<MockConnectionManager*>(
+        fetcher->GetSystemState()->GetConnectionManager());
+    EXPECT_CALL(*mock_cm, GetConnectionType(_,_))
+      .WillRepeatedly(DoAll(SetArgumentPointee<1>(kNetWifi), Return(true)));
+    EXPECT_CALL(*mock_cm, IsUpdateAllowedOver(kNetWifi))
+      .WillRepeatedly(Return(true));
+    EXPECT_CALL(*mock_cm, StringForConnectionType(kNetWifi))
+      .WillRepeatedly(Return(flimflam::kTypeWifi));
+
     scoped_ptr<HttpServer> server(this->test_.CreateServer());
     ASSERT_TRUE(server->started_);
 
@@ -387,6 +403,15 @@
     scoped_ptr<HttpFetcher> fetcher(this->test_.NewLargeFetcher());
     fetcher->set_delegate(&delegate);
 
+    MockConnectionManager* mock_cm = dynamic_cast<MockConnectionManager*>(
+        fetcher->GetSystemState()->GetConnectionManager());
+    EXPECT_CALL(*mock_cm, GetConnectionType(_,_))
+      .WillRepeatedly(DoAll(SetArgumentPointee<1>(kNetEthernet), Return(true)));
+    EXPECT_CALL(*mock_cm, IsUpdateAllowedOver(kNetEthernet))
+      .WillRepeatedly(Return(true));
+    EXPECT_CALL(*mock_cm, StringForConnectionType(kNetEthernet))
+      .WillRepeatedly(Return(flimflam::kTypeEthernet));
+
     scoped_ptr<HttpServer> server(this->test_.CreateServer());
     ASSERT_TRUE(server->started_);
 
@@ -414,6 +439,15 @@
     scoped_ptr<HttpFetcher> fetcher(this->test_.NewSmallFetcher());
     fetcher->set_delegate(&delegate);
 
+    MockConnectionManager* mock_cm = dynamic_cast<MockConnectionManager*>(
+        fetcher->GetSystemState()->GetConnectionManager());
+    EXPECT_CALL(*mock_cm, GetConnectionType(_,_))
+      .WillRepeatedly(DoAll(SetArgumentPointee<1>(kNetWimax), Return(true)));
+    EXPECT_CALL(*mock_cm, IsUpdateAllowedOver(kNetWimax))
+      .WillRepeatedly(Return(true));
+    EXPECT_CALL(*mock_cm, StringForConnectionType(kNetWimax))
+      .WillRepeatedly(Return(flimflam::kTypeWimax));
+
     scoped_ptr<HttpServer> server(this->test_.CreateServer());
     ASSERT_TRUE(server->started_);
 
@@ -484,6 +518,15 @@
     delegate.fetcher_ = fetcher.get();
     fetcher->set_delegate(&delegate);
 
+    MockConnectionManager* mock_cm = dynamic_cast<MockConnectionManager*>(
+        fetcher->GetSystemState()->GetConnectionManager());
+    EXPECT_CALL(*mock_cm, GetConnectionType(_,_))
+      .WillRepeatedly(DoAll(SetArgumentPointee<1>(kNetCellular), Return(true)));
+    EXPECT_CALL(*mock_cm, IsUpdateAllowedOver(kNetCellular))
+      .WillRepeatedly(Return(true));
+    EXPECT_CALL(*mock_cm, StringForConnectionType(kNetCellular))
+      .WillRepeatedly(Return(flimflam::kTypeCellular));
+
     scoped_ptr<HttpServer> server(this->test_.CreateServer());
     ASSERT_TRUE(server->started_);
 
@@ -551,6 +594,15 @@
     delegate.loop_ = loop;
     delegate.fetcher_->set_delegate(&delegate);
 
+    MockConnectionManager* mock_cm = dynamic_cast<MockConnectionManager*>(
+        delegate.fetcher_->GetSystemState()->GetConnectionManager());
+    EXPECT_CALL(*mock_cm, GetConnectionType(_,_))
+      .WillRepeatedly(DoAll(SetArgumentPointee<1>(kNetWifi), Return(true)));
+    EXPECT_CALL(*mock_cm, IsUpdateAllowedOver(kNetWifi))
+      .WillRepeatedly(Return(true));
+    EXPECT_CALL(*mock_cm, StringForConnectionType(kNetWifi))
+      .WillRepeatedly(Return(flimflam::kTypeWifi));
+
     scoped_ptr<HttpServer> server(this->test_.CreateServer());
     this->test_.IgnoreServerAborting(server.get());
     ASSERT_TRUE(server->started_);
@@ -600,6 +652,16 @@
     scoped_ptr<HttpFetcher> fetcher(this->test_.NewSmallFetcher());
     fetcher->set_delegate(&delegate);
 
+    MockConnectionManager* mock_cm = dynamic_cast<MockConnectionManager*>(
+        fetcher->GetSystemState()->GetConnectionManager());
+    EXPECT_CALL(*mock_cm, GetConnectionType(_,_))
+      .WillRepeatedly(DoAll(SetArgumentPointee<1>(kNetWifi), Return(true)));
+    EXPECT_CALL(*mock_cm, IsUpdateAllowedOver(kNetWifi))
+      .WillRepeatedly(Return(true));
+    EXPECT_CALL(*mock_cm, StringForConnectionType(kNetWifi))
+      .WillRepeatedly(Return(flimflam::kTypeWifi));
+
+
     scoped_ptr<HttpServer> server(this->test_.CreateServer());
     ASSERT_TRUE(server->started_);
 
@@ -661,6 +723,16 @@
     scoped_ptr<HttpFetcher> fetcher(this->test_.NewSmallFetcher());
     fetcher->set_delegate(&delegate);
 
+    MockConnectionManager* mock_cm = dynamic_cast<MockConnectionManager*>(
+        fetcher->GetSystemState()->GetConnectionManager());
+    EXPECT_CALL(*mock_cm, GetConnectionType(_,_))
+      .WillRepeatedly(DoAll(SetArgumentPointee<1>(kNetEthernet), Return(true)));
+    EXPECT_CALL(*mock_cm, IsUpdateAllowedOver(kNetEthernet))
+      .WillRepeatedly(Return(true));
+    EXPECT_CALL(*mock_cm, StringForConnectionType(kNetEthernet))
+      .WillRepeatedly(Return(flimflam::kTypeEthernet));
+
+
     StartTransferArgs start_xfer_args = {
       fetcher.get(),
       LocalServerUrlForPath(this->test_.SmallUrl())
@@ -743,6 +815,15 @@
   scoped_ptr<HttpFetcher> fetcher(http_fetcher);
   fetcher->set_delegate(&delegate);
 
+  MockConnectionManager* mock_cm = dynamic_cast<MockConnectionManager*>(
+      fetcher->GetSystemState()->GetConnectionManager());
+  EXPECT_CALL(*mock_cm, GetConnectionType(_,_))
+    .WillRepeatedly(DoAll(SetArgumentPointee<1>(kNetEthernet), Return(true)));
+  EXPECT_CALL(*mock_cm, IsUpdateAllowedOver(kNetEthernet))
+    .WillRepeatedly(Return(true));
+  EXPECT_CALL(*mock_cm, StringForConnectionType(kNetEthernet))
+    .WillRepeatedly(Return(flimflam::kTypeEthernet));
+
   StartTransferArgs start_xfer_args =
       { fetcher.get(), LocalServerUrlForPath(url) };
 
@@ -850,6 +931,16 @@
     MultiHttpFetcherTestDelegate delegate(expected_response_code);
     delegate.loop_ = loop;
     delegate.fetcher_.reset(fetcher_in);
+
+    MockConnectionManager* mock_cm = dynamic_cast<MockConnectionManager*>(
+        fetcher_in->GetSystemState()->GetConnectionManager());
+    EXPECT_CALL(*mock_cm, GetConnectionType(_,_))
+      .WillRepeatedly(DoAll(SetArgumentPointee<1>(kNetWifi), Return(true)));
+    EXPECT_CALL(*mock_cm, IsUpdateAllowedOver(kNetWifi))
+      .WillRepeatedly(Return(true));
+    EXPECT_CALL(*mock_cm, StringForConnectionType(kNetWifi))
+      .WillRepeatedly(Return(flimflam::kTypeWifi));
+
     MultiRangeHttpFetcher* multi_fetcher =
         dynamic_cast<MultiRangeHttpFetcher*>(fetcher_in);
     ASSERT_TRUE(multi_fetcher);
@@ -866,7 +957,6 @@
       }
       LOG(INFO) << "added range: " << tmp_str;
     }
-    multi_fetcher->SetConnectionAsExpensive(false);
     multi_fetcher->SetBuildType(false);
     multi_fetcher->set_delegate(&delegate);
 
@@ -1035,15 +1125,21 @@
     BlockedTransferTestDelegate delegate;
     delegate.loop_ = loop;
 
+    bool is_allowed = (i != 0);
     scoped_ptr<HttpFetcher> fetcher(this->test_.NewLargeFetcher());
-    LibcurlHttpFetcher* curl_fetcher =
-        dynamic_cast<LibcurlHttpFetcher*>(fetcher.get());
-    bool is_expensive_connection = (i == 0);
+    MockConnectionManager* mock_cm = dynamic_cast<MockConnectionManager*>(
+        fetcher->GetSystemState()->GetConnectionManager());
+    EXPECT_CALL(*mock_cm, GetConnectionType(_,_))
+      .WillRepeatedly(DoAll(SetArgumentPointee<1>(kNetWifi), Return(true)));
+    EXPECT_CALL(*mock_cm, IsUpdateAllowedOver(kNetWifi))
+      .WillRepeatedly(Return(is_allowed));
+    EXPECT_CALL(*mock_cm, StringForConnectionType(kNetWifi))
+      .WillRepeatedly(Return(flimflam::kTypeWifi));
+
     bool is_official_build = (i == 1);
-    LOG(INFO) << "is_expensive_connection: " << is_expensive_connection;
+    LOG(INFO) << "is_update_allowed_over_connection: " << is_allowed;
     LOG(INFO) << "is_official_build: " << is_official_build;
-    curl_fetcher->SetConnectionAsExpensive(is_expensive_connection);
-    curl_fetcher->SetBuildType(is_official_build);
+    fetcher->SetBuildType(is_official_build);
     fetcher->set_delegate(&delegate);
 
     StartTransferArgs start_xfer_args =