shill: DHCPConfig: Optionally use minimal config

Add another argument to the DHCPConfig constructor to specify
whether a cut-down minimal set of options should be requested
from the DHCP server.  This adds a command line argument to
the startup of the DHCP client.  Propagate this upwards to the
Device, and add a placeholder Device::ShouldUseMinimalConfig()
method which will decide whether to enable this feature in the
DHCPConfig in a later CL.

A few ancillary changes went into this CL:

  - The DHCPProvider needed another argument to CreateConfig
    since it constructs DHCPConfig objects.
  - Added a unit test for the Device::ShouldUseArpGateway()
    superclass function next to Device::ShouldUseMinimalConfig()
    test.
  - Fixed the DHCPConfigTest::Start* tests to use the IsDHCPCDArgs
    matcher.  For some reason that matcher sat unused and
    atrophied.  Added a new test that exercises the minimal config
    flag.

BUG=chromium:297607
TEST=Unit tests.  Run network_DhcpNegotiationSuccess autotest.

Change-Id: If0dcaf328ca6dfac7127a6badd409a4138c95760
Reviewed-on: https://chromium-review.googlesource.com/174531
Reviewed-by: Paul Stewart <pstew@chromium.org>
Commit-Queue: Paul Stewart <pstew@chromium.org>
Tested-by: Paul Stewart <pstew@chromium.org>
diff --git a/dhcp_config_unittest.cc b/dhcp_config_unittest.cc
index 0b2272d..312530d 100644
--- a/dhcp_config_unittest.cc
+++ b/dhcp_config_unittest.cc
@@ -42,6 +42,9 @@
 const char kHostName[] = "hostname";
 const char kLeaseFileSuffix[] = "leasefilesuffix";
 const bool kArpGateway = true;
+const bool kHasHostname = true;
+const bool kHasLeaseSuffix = true;
+const bool kMinimalConfig = true;
 }  // namespace {}
 
 class DHCPConfigTest : public PropertyStoreTest {
@@ -57,6 +60,7 @@
                                kHostName,
                                kLeaseFileSuffix,
                                kArpGateway,
+                               !kMinimalConfig,
                                glib())) {}
 
   virtual void SetUp() {
@@ -70,11 +74,13 @@
   }
 
   DHCPConfigRefPtr CreateMockMinijailConfig(const string &hostname,
-                                       const string &lease_suffix,
-                                       bool arp_gateway);
+                                            const string &lease_suffix,
+                                            bool arp_gateway,
+                                            bool minimal_config);
   DHCPConfigRefPtr CreateRunningConfig(const string &hostname,
                                        const string &lease_suffix,
-                                       bool arp_gateway);
+                                       bool arp_gateway,
+                                       bool minimal_config);
   void StopRunningConfigAndExpect(DHCPConfigRefPtr config,
                                   bool lease_file_exists);
 
@@ -108,9 +114,10 @@
 const unsigned int DHCPConfigTest::kTag = 77;
 
 DHCPConfigRefPtr DHCPConfigTest::CreateMockMinijailConfig(
-                                     const string &hostname,
-                                     const string &lease_suffix,
-                                     bool arp_gateway) {
+    const string &hostname,
+    const string &lease_suffix,
+    bool arp_gateway,
+    bool minimal_config) {
   DHCPConfigRefPtr config(new DHCPConfig(&control_,
                                          dispatcher(),
                                          DHCPProvider::GetInstance(),
@@ -118,16 +125,18 @@
                                          hostname,
                                          lease_suffix,
                                          arp_gateway,
+                                         minimal_config,
                                          glib()));
   config->minijail_ = minijail_.get();
-  EXPECT_CALL(*minijail_, RunAndDestroy(_, _, _)).WillOnce(Return(false));
 
   return config;
 }
 
-DHCPConfigRefPtr DHCPConfigTest::CreateRunningConfig(const string &hostname,
-                                                     const string &lease_suffix,
-                                                     bool arp_gateway) {
+DHCPConfigRefPtr DHCPConfigTest::CreateRunningConfig(
+    const string &hostname,
+    const string &lease_suffix,
+    bool arp_gateway,
+    bool minimal_config) {
   DHCPConfigRefPtr config(new DHCPConfig(&control_,
                                          dispatcher(),
                                          DHCPProvider::GetInstance(),
@@ -135,6 +144,7 @@
                                          hostname,
                                          lease_suffix,
                                          arp_gateway,
+                                         minimal_config,
                                          glib()));
   config->minijail_ = minijail_.get();
   EXPECT_CALL(*minijail_, RunAndDestroy(_, _, _))
@@ -304,13 +314,15 @@
   EXPECT_EQ(0, config_->pid_);
 }
 
-MATCHER_P3(IsDHCPCDArgs, has_hostname, has_arp_gateway, has_lease_suffix, "") {
+MATCHER_P4(IsDHCPCDArgs, has_hostname, has_arp_gateway, has_lease_suffix,
+           has_minimal_config, "") {
   if (string(arg[0]) != "/sbin/dhcpcd" ||
-      string(arg[1]) != "-B") {
+      string(arg[1]) != "-B" ||
+      string(arg[2]) != "-q") {
     return false;
   }
 
-  int end_offset = 2;
+  int end_offset = 3;
   if (has_hostname) {
     if (string(arg[end_offset]) != "-h" ||
         string(arg[end_offset + 1]) != kHostName) {
@@ -320,9 +332,19 @@
   }
 
   if (has_arp_gateway) {
-    if (string(arg[end_offset]) != "-R")
+    if (string(arg[end_offset]) != "-R" ||
+        string(arg[end_offset + 1]) != "-U") {
       return false;
-    ++end_offset;
+    }
+    end_offset += 2;
+  }
+
+  if (has_minimal_config) {
+    if (string(arg[end_offset]) != "-f" ||
+        string(arg[end_offset + 1]) != "/etc/dhcpcd-minimal.conf") {
+      return false;
+    }
+    end_offset += 2;
   }
 
   string device_arg = has_lease_suffix ?
@@ -331,28 +353,63 @@
 }
 
 TEST_F(DHCPConfigTest, StartWithHostname) {
-  EXPECT_CALL(*minijail_, RunAndDestroy(_, _, _)).WillOnce(Return(false));
+  EXPECT_CALL(*minijail_, RunAndDestroy(_, IsDHCPCDArgs(kHasHostname,
+                                                        kArpGateway,
+                                                        kHasLeaseSuffix,
+                                                        !kMinimalConfig), _))
+      .WillOnce(Return(false));
   EXPECT_FALSE(config_->Start());
 }
 
 TEST_F(DHCPConfigTest, StartWithoutHostname) {
   DHCPConfigRefPtr config = CreateMockMinijailConfig("",
                                                      kLeaseFileSuffix,
-                                                     kArpGateway);
+                                                     kArpGateway,
+                                                     !kMinimalConfig);
+  EXPECT_CALL(*minijail_, RunAndDestroy(_, IsDHCPCDArgs(!kHasHostname,
+                                                        kArpGateway,
+                                                        kHasLeaseSuffix,
+                                                        !kMinimalConfig), _))
+      .WillOnce(Return(false));
   EXPECT_FALSE(config->Start());
 }
 
 TEST_F(DHCPConfigTest, StartWithoutArpGateway) {
   DHCPConfigRefPtr config = CreateMockMinijailConfig(kHostName,
                                                      kLeaseFileSuffix,
-                                                     false);
+                                                     !kArpGateway,
+                                                     !kMinimalConfig);
+  EXPECT_CALL(*minijail_, RunAndDestroy(_, IsDHCPCDArgs(kHasHostname,
+                                                        !kArpGateway,
+                                                        kHasLeaseSuffix,
+                                                        !kMinimalConfig), _))
+      .WillOnce(Return(false));
   EXPECT_FALSE(config->Start());
 }
 
 TEST_F(DHCPConfigTest, StartWithoutLeaseSuffix) {
   DHCPConfigRefPtr config = CreateMockMinijailConfig(kHostName,
                                                      kDeviceName,
-                                                     kArpGateway);
+                                                     kArpGateway,
+                                                     !kMinimalConfig);
+  EXPECT_CALL(*minijail_, RunAndDestroy(_, IsDHCPCDArgs(kHasHostname,
+                                                        kArpGateway,
+                                                        !kHasLeaseSuffix,
+                                                        !kMinimalConfig), _))
+      .WillOnce(Return(false));
+  EXPECT_FALSE(config->Start());
+}
+
+TEST_F(DHCPConfigTest, StartWithMinimalConfig) {
+  DHCPConfigRefPtr config = CreateMockMinijailConfig(kHostName,
+                                                     kLeaseFileSuffix,
+                                                     kArpGateway,
+                                                     kMinimalConfig);
+  EXPECT_CALL(*minijail_, RunAndDestroy(_, IsDHCPCDArgs(kHasHostname,
+                                                        kArpGateway,
+                                                        kHasLeaseSuffix,
+                                                        kMinimalConfig), _))
+      .WillOnce(Return(false));
   EXPECT_FALSE(config->Start());
 }
 
@@ -620,13 +677,14 @@
 
 TEST_F(DHCPConfigTest, StartSuccessEphemeral) {
   DHCPConfigRefPtr config =
-      CreateRunningConfig(kHostName, kDeviceName, kArpGateway);
+      CreateRunningConfig(kHostName, kDeviceName, kArpGateway, !kMinimalConfig);
   StopRunningConfigAndExpect(config, false);
 }
 
 TEST_F(DHCPConfigTest, StartSuccessPersistent) {
   DHCPConfigRefPtr config =
-      CreateRunningConfig(kHostName, kLeaseFileSuffix, kArpGateway);
+      CreateRunningConfig(kHostName, kLeaseFileSuffix, kArpGateway,
+                          !kMinimalConfig);
   StopRunningConfigAndExpect(config, true);
 }