Bug 619623 - Wait for the WAL checkpoint in case that helps avoiding the intermittent failure in test_IHistory.cpp
authorMarco Bonardo <mbonardo@mozilla.com>
Tue, 22 Jan 2013 14:25:03 +0100
changeset 129354 275fdd66aa4cc4bc39f12eaecde9e5b520931eb2
parent 129353 23e803630aca76e9a696ebd7a64c2bad622020fd
child 129355 c7b78d418a1e516888187e6ce1501797401cf5c6
push id2323
push userbbajaj@mozilla.com
push dateMon, 01 Apr 2013 19:47:02 +0000
treeherdermozilla-beta@7712be144d91 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
bugs619623
milestone21.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 619623 - Wait for the WAL checkpoint in case that helps avoiding the intermittent failure in test_IHistory.cpp r=test-only-experiment-not-worth-it a=nonlibxul
toolkit/components/places/tests/cpp/places_test_harness.h
toolkit/components/places/tests/cpp/test_IHistory.cpp
--- a/toolkit/components/places/tests/cpp/places_test_harness.h
+++ b/toolkit/components/places/tests/cpp/places_test_harness.h
@@ -11,16 +11,19 @@
 #include "nsDocShellCID.h"
 
 #include "nsToolkitCompsCID.h"
 #include "nsINavHistoryService.h"
 #include "nsIObserverService.h"
 #include "mozilla/IHistory.h"
 #include "mozIStorageConnection.h"
 #include "mozIStorageStatement.h"
+#include "mozIStorageAsyncStatement.h"
+#include "mozIStorageStatementCallback.h"
+#include "mozIStoragePendingStatement.h"
 #include "nsPIPlacesDatabase.h"
 #include "nsIObserver.h"
 #include "prinrval.h"
 #include "mozilla/Attributes.h"
 
 #define TOPIC_FRECENCY_UPDATED "places-frecency-updated"
 #define WAITFORTOPIC_TIMEOUT_SECONDS 5
 
@@ -138,16 +141,72 @@ private:
   PRIntervalTime mStartTime;
 };
 NS_IMPL_ISUPPORTS1(
   WaitForTopicSpinner,
   nsIObserver
 )
 
 /**
+ * Spins current thread until an async statement is executed.
+ */
+class AsyncStatementSpinner MOZ_FINAL : public mozIStorageStatementCallback
+{
+public:
+  NS_DECL_ISUPPORTS
+  NS_DECL_MOZISTORAGESTATEMENTCALLBACK
+
+  AsyncStatementSpinner();
+  void SpinUntilCompleted();
+  uint16_t completionReason;
+
+protected:
+  volatile bool mCompleted;
+};
+
+NS_IMPL_ISUPPORTS1(AsyncStatementSpinner,
+                   mozIStorageStatementCallback)
+
+AsyncStatementSpinner::AsyncStatementSpinner()
+: completionReason(0)
+, mCompleted(false)
+{
+}
+
+NS_IMETHODIMP
+AsyncStatementSpinner::HandleResult(mozIStorageResultSet *aResultSet)
+{
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+AsyncStatementSpinner::HandleError(mozIStorageError *aError)
+{
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+AsyncStatementSpinner::HandleCompletion(uint16_t aReason)
+{
+  completionReason = aReason;
+  mCompleted = true;
+  return NS_OK;
+}
+
+void AsyncStatementSpinner::SpinUntilCompleted()
+{
+  nsCOMPtr<nsIThread> thread(::do_GetCurrentThread());
+  nsresult rv = NS_OK;
+  bool processed = true;
+  while (!mCompleted && NS_SUCCEEDED(rv)) {
+    rv = thread->ProcessNextEvent(true, &processed);
+  }
+}
+
+/**
  * Adds a URI to the database.
  *
  * @param aURI
  *        The URI to add to the database.
  */
 void
 addURI(nsIURI* aURI)
 {
--- a/toolkit/components/places/tests/cpp/test_IHistory.cpp
+++ b/toolkit/components/places/tests/cpp/test_IHistory.cpp
@@ -109,16 +109,36 @@ test_set_places_enabled()
 
   rv = prefBranch->SetBoolPref("places.history.enabled", true);
   do_check_success(rv);
 
   // Run the next test.
   run_next_test();
 }
 
+
+void
+test_wait_checkpoint()
+{
+  // This "fake" test is here to wait for the initial WAL checkpoint we force
+  // after creating the database schema, since that may happen at any time,
+  // and cause concurrent readers to access an older checkpoint.
+  nsCOMPtr<mozIStorageConnection> db = do_get_db();
+  nsCOMPtr<mozIStorageAsyncStatement> stmt;
+  db->CreateAsyncStatement(NS_LITERAL_CSTRING("SELECT 1"),
+                           getter_AddRefs(stmt));
+  nsRefPtr<AsyncStatementSpinner> spinner = new AsyncStatementSpinner();
+  nsCOMPtr<mozIStoragePendingStatement> pending;
+  (void)stmt->ExecuteAsync(spinner, getter_AddRefs(pending));
+  spinner->SpinUntilCompleted();
+
+  // Run the next test.
+  run_next_test();
+}
+
 // These variables are shared between part 1 and part 2 of the test.  Part 2
 // sets the nsCOMPtr's to nullptr, freeing the reference.
 namespace test_unvisited_does_not_notify {
   nsCOMPtr<nsIURI> testURI;
   nsRefPtr<Link> testLink;
 }
 void
 test_unvisited_does_not_notify_part1()
@@ -586,16 +606,17 @@ test_two_null_links_same_uri()
 ////////////////////////////////////////////////////////////////////////////////
 //// Test Harness
 
 /**
  * Note: for tests marked "Order Important!", please see the test for details.
  */
 Test gTests[] = {
   TEST(test_set_places_enabled), // Must come first!
+  TEST(test_wait_checkpoint), // Must come second!
   TEST(test_unvisited_does_not_notify_part1), // Order Important!
   TEST(test_visited_notifies),
   TEST(test_unvisited_does_not_notify_part2), // Order Important!
   TEST(test_same_uri_notifies_both),
   TEST(test_unregistered_visited_does_not_notify), // Order Important!
   TEST(test_new_visit_notifies_waiting_Link),
   TEST(test_RegisterVisitedCallback_returns_before_notifying),
   TEST(test_observer_topic_dispatched),