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/http_fetcher_unittest.cc b/http_fetcher_unittest.cc
index f1e9c26..8d9c3f8 100644
--- a/http_fetcher_unittest.cc
+++ b/http_fetcher_unittest.cc
@@ -3,13 +3,18 @@
// found in the LICENSE file.
#include <unistd.h>
+#include <string>
+#include <vector>
#include <base/scoped_ptr.h>
#include <glib.h>
-#include <base/logging.h>
#include <gtest/gtest.h>
+#include "chromeos/obsolete_logging.h"
#include "update_engine/libcurl_http_fetcher.h"
#include "update_engine/mock_http_fetcher.h"
+using std::string;
+using std::vector;
+
namespace chromeos_update_engine {
namespace {
@@ -27,6 +32,7 @@
HttpFetcher* NewSmallFetcher() = 0;
string BigUrl() const = 0;
string SmallUrl() const = 0;
+ bool IsMock() const = 0;
};
class NullHttpServer {
@@ -53,13 +59,14 @@
string SmallUrl() const {
return "unused://unused";
}
+ bool IsMock() const { return true; }
typedef NullHttpServer HttpServer;
};
class PythonHttpServer {
public:
PythonHttpServer() {
- char *argv[2] = {strdup("./test_http_server.py"), NULL};
+ char *argv[2] = {strdup("./test_http_server"), NULL};
GError *err;
started_ = false;
if (!g_spawn_async(NULL,
@@ -74,7 +81,6 @@
}
int rc = 1;
while (0 != rc) {
-
rc = system((string("wget --output-document=/dev/null ") +
LocalServerUrlForPath("/test")).c_str());
usleep(10 * 1000); // 10 ms
@@ -112,6 +118,7 @@
string SmallUrl() const {
return LocalServerUrlForPath("/foo");
}
+ bool IsMock() const { return false; }
typedef PythonHttpServer HttpServer;
};
@@ -121,7 +128,7 @@
namespace {
class HttpFetcherTestDelegate : public HttpFetcherDelegate {
-public:
+ public:
virtual void ReceivedBytes(HttpFetcher* fetcher,
const char* bytes, int length) {
char str[length + 1];
@@ -133,6 +140,17 @@
}
GMainLoop* loop_;
};
+
+struct StartTransferArgs {
+ HttpFetcher *http_fetcher;
+ string url;
+};
+
+gboolean StartTransfer(gpointer data) {
+ StartTransferArgs *args = reinterpret_cast<StartTransferArgs*>(data);
+ args->http_fetcher->BeginTransfer(args->url);
+ return FALSE;
+}
} // namespace {}
TYPED_TEST(HttpFetcherTest, SimpleTest) {
@@ -146,7 +164,9 @@
typename TestFixture::HttpServer server;
ASSERT_TRUE(server.started_);
- fetcher->BeginTransfer(this->SmallUrl());
+ StartTransferArgs start_xfer_args = {fetcher.get(), this->SmallUrl()};
+
+ g_timeout_add(0, StartTransfer, &start_xfer_args);
g_main_loop_run(loop);
}
g_main_loop_unref(loop);
@@ -158,13 +178,11 @@
virtual void ReceivedBytes(HttpFetcher* fetcher,
const char* bytes, int length) {
char str[length + 1];
- LOG(INFO) << "got " << length << " bytes";
memset(str, 0, length + 1);
memcpy(str, bytes, length);
CHECK(!paused_);
paused_ = true;
fetcher->Pause();
- LOG(INFO) << "calling pause";
}
virtual void TransferComplete(HttpFetcher* fetcher, bool successful) {
g_main_loop_quit(loop_);
@@ -173,7 +191,6 @@
CHECK(paused_);
paused_ = false;
fetcher_->Unpause();
- LOG(INFO) << "calling unpause";
}
bool paused_;
HttpFetcher* fetcher_;
@@ -274,4 +291,50 @@
g_main_loop_unref(loop);
}
+namespace {
+class FlakyHttpFetcherTestDelegate : public HttpFetcherDelegate {
+ public:
+ virtual void ReceivedBytes(HttpFetcher* fetcher,
+ const char* bytes, int length) {
+ data.append(bytes, length);
+ }
+ virtual void TransferComplete(HttpFetcher* fetcher, bool successful) {
+ g_main_loop_quit(loop_);
+ }
+ string data;
+ GMainLoop* loop_;
+};
+} // namespace {}
+
+TYPED_TEST(HttpFetcherTest, FlakyTest) {
+ if (this->IsMock())
+ return;
+ GMainLoop *loop = g_main_loop_new(g_main_context_default(), FALSE);
+ {
+ FlakyHttpFetcherTestDelegate delegate;
+ delegate.loop_ = loop;
+ scoped_ptr<HttpFetcher> fetcher(this->NewSmallFetcher());
+ fetcher->set_delegate(&delegate);
+
+ typename TestFixture::HttpServer server;
+ ASSERT_TRUE(server.started_);
+
+ StartTransferArgs start_xfer_args = {
+ fetcher.get(),
+ LocalServerUrlForPath("/flaky")
+ };
+
+ g_timeout_add(0, StartTransfer, &start_xfer_args);
+ g_main_loop_run(loop);
+
+ // verify the data we get back
+ ASSERT_EQ(100000, delegate.data.size());
+ for (int i = 0; i < 100000; i += 10) {
+ // Assert so that we don't flood the screen w/ EXPECT errors on failure.
+ ASSERT_EQ(delegate.data.substr(i, 10), "abcdefghij");
+ }
+ }
+ g_main_loop_unref(loop);
+}
+
} // namespace chromeos_update_engine