AU: Beginnings of delta support

- proto file for delta files; still needs hardlink support

- code to generate a delta update from two directory trees (old, new).

- code to parse delta update

- Actions: postinst-runner, install, bootable flag setter, filesystem
 copier, Omaha response handler, Omaha request preparer,

- misc utility functions, like StringHasSuffix(), templatized Action
 classes to feed/collect an object from another action.

- FilesystemIterator: iterates a directory tree with optional
 exclusion path. Tolerates deleting of files during iteration.

- Subprocess class: support for synchronously or asynchronously
 running an external command. Doesn't pass any env variables.

- Integration test that strings many Actions together and tests using
 actual Omaha/Lorry. Currently only tests full updates.

- New simple HTTP server for unittest that supports fake flaky
 connections.

- Some refactoring.

Review URL: http://codereview.chromium.org/466036


git-svn-id: svn://chrome-svn/chromeos/trunk@334 06c00378-0e64-4dae-be16-12b19f9950a1
diff --git a/update_check_action_unittest.cc b/update_check_action_unittest.cc
index 9b8436c..723fc22 100644
--- a/update_check_action_unittest.cc
+++ b/update_check_action_unittest.cc
@@ -3,6 +3,7 @@
 // found in the LICENSE file.
 
 #include <string>
+#include <vector>
 #include <glib.h>
 #include <gtest/gtest.h>
 #include "update_engine/action_pipe.h"
@@ -11,9 +12,10 @@
 #include "update_engine/omaha_hash_calculator.h"
 #include "update_engine/test_utils.h"
 
-namespace chromeos_update_engine {
-
 using std::string;
+using std::vector;
+
+namespace chromeos_update_engine {
 
 class UpdateCheckActionTest : public ::testing::Test { };
 
@@ -35,8 +37,9 @@
                          const string& needsadmin,
                          const string& size) {
   return string("<?xml version=\"1.0\" encoding=\"UTF-8\"?><gupdate "
-      "xmlns=\"http://www.google.com/update2/response\" protocol=\"2.0\"><app "
-      "appid=\"") + app_id + "\" status=\"ok\"><ping "
+                "xmlns=\"http://www.google.com/update2/response\" "
+                "protocol=\"2.0\"><app "
+                "appid=\"") + app_id + "\" status=\"ok\"><ping "
       "status=\"ok\"/><updatecheck DisplayVersion=\"" + display_version + "\" "
       "MoreInfo=\"" + more_info_url + "\" Prompt=\"" + prompt + "\" "
       "codebase=\"" + codebase + "\" "
@@ -56,11 +59,11 @@
     g_main_loop_quit(loop_);
   }
 
-  virtual void ActionCompleted(const ActionProcessor* processor,
-                               const AbstractAction* action,
+  virtual void ActionCompleted(ActionProcessor* processor,
+                               AbstractAction* action,
                                bool success) {
     // make sure actions always succeed
-    if (action->Type() == "UpdateCheckAction")
+    if (action->Type() == UpdateCheckAction::StaticType())
       EXPECT_EQ(expected_success_, success);
     else
       EXPECT_TRUE(success);
@@ -102,7 +105,10 @@
     CHECK(false);
   }
   // Debugging/logging
-  std::string Type() const { return "OutputObjectCollectorAction"; }
+  static std::string StaticType() {
+    return "OutputObjectCollectorAction";
+  }
+  std::string Type() const { return StaticType(); }
   bool has_input_object_;
   UpdateCheckResponse update_check_response_;
 };
@@ -119,17 +125,20 @@
   GMainLoop *loop = g_main_loop_new(g_main_context_default(), FALSE);
   MockHttpFetcher *fetcher = new MockHttpFetcher(http_response.data(),
                                                  http_response.size());
-
-  UpdateCheckAction action(params, fetcher);  // takes ownership of fetcher
+  ObjectFeederAction<UpdateCheckParams> feeder_action;
+  UpdateCheckAction action(fetcher);  // takes ownership of fetcher
   UpdateCheckActionTestProcessorDelegate delegate;
   delegate.loop_ = loop;
   delegate.expected_success_ = expected_success;
   ActionProcessor processor;
+  feeder_action.set_obj(params);
   processor.set_delegate(&delegate);
+  processor.EnqueueAction(&feeder_action);
   processor.EnqueueAction(&action);
 
   OutputObjectCollectorAction collector_action;
 
+  BondActions(&feeder_action, &action);
   BondActions(&action, &collector_action);
   processor.EnqueueAction(&collector_action);
 
@@ -211,14 +220,17 @@
 
   GMainLoop *loop = g_main_loop_new(g_main_context_default(), FALSE);
 
-  UpdateCheckAction action(params,
-                           new MockHttpFetcher(http_response.data(),
+  ObjectFeederAction<UpdateCheckParams> feeder_action;
+  feeder_action.set_obj(params);
+  UpdateCheckAction action(new MockHttpFetcher(http_response.data(),
                                                http_response.size()));
   UpdateCheckActionTestProcessorDelegate delegate;
   delegate.loop_ = loop;
   ActionProcessor processor;
   processor.set_delegate(&delegate);
+  processor.EnqueueAction(&feeder_action);
   processor.EnqueueAction(&action);
+  BondActions(&feeder_action, &action);
 
   g_timeout_add(0, &StartProcessorInRunLoop, &processor);
   g_main_loop_run(loop);
@@ -327,18 +339,23 @@
                            "unittest_track");
   UpdateCheckResponse response;
   ASSERT_TRUE(TestUpdateCheckAction(params,
-      string("<?xml version=\"1.0\" encoding=\"UTF-8\"?><gupdate "
-          "xmlns=\"http://www.google.com/update2/response\" "
-          "protocol=\"2.0\"><app  appid=\"") +
-          UpdateCheckParams::kAppId + "\" status=\"ok\"><ping "
-          "status=\"ok\"/><updatecheck DisplayVersion=\"1.2.3.4\" "
-          "Prompt=\"false\" "
-          "codebase=\"http://code/base\" "
-          "hash=\"HASH1234=\" needsadmin=\"true\" "
-          "size=\"123\" status=\"ok\"/></app></gupdate>",
-      true,
-      &response,
-      NULL));
+                                    string("<?xml version=\"1.0\" "
+                                           "encoding=\"UTF-8\"?><gupdate "
+                                           "xmlns=\"http://www.google.com/"
+                                           "update2/response\" "
+                                           "protocol=\"2.0\"><app  appid=\"") +
+                                    UpdateCheckParams::kAppId
+                                    + "\" status=\"ok\"><ping "
+                                    "status=\"ok\"/><updatecheck "
+                                    "DisplayVersion=\"1.2.3.4\" "
+                                    "Prompt=\"false\" "
+                                    "codebase=\"http://code/base\" "
+                                    "hash=\"HASH1234=\" needsadmin=\"true\" "
+                                    "size=\"123\" "
+                                    "status=\"ok\"/></app></gupdate>",
+                                    true,
+                                    &response,
+                                    NULL));
   EXPECT_TRUE(response.update_exists);
   EXPECT_EQ("1.2.3.4", response.display_version);
   EXPECT_EQ("http://code/base", response.codebase);
@@ -381,14 +398,17 @@
   string http_response("doesn't matter");
   GMainLoop *loop = g_main_loop_new(g_main_context_default(), FALSE);
 
-  UpdateCheckAction action(params,
-                           new MockHttpFetcher(http_response.data(),
+  ObjectFeederAction<UpdateCheckParams> feeder_action;
+  feeder_action.set_obj(params);
+  UpdateCheckAction action(new MockHttpFetcher(http_response.data(),
                                                http_response.size()));
   TerminateEarlyTestProcessorDelegate delegate;
   delegate.loop_ = loop;
   ActionProcessor processor;
   processor.set_delegate(&delegate);
+  processor.EnqueueAction(&feeder_action);
   processor.EnqueueAction(&action);
+  BondActions(&feeder_action, &action);
 
   g_timeout_add(0, &TerminateTransferTestStarter, &processor);
   g_main_loop_run(loop);