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
This commit is contained in:
Marco Bonardo 2013-01-22 14:25:03 +01:00
parent 5596d1028a
commit 63b4e0b3f5
2 changed files with 80 additions and 0 deletions

View File

@ -16,6 +16,9 @@
#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"
@ -142,6 +145,62 @@ NS_IMPL_ISUPPORTS1(
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.
*

View File

@ -114,6 +114,26 @@ test_set_places_enabled()
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 {
@ -591,6 +611,7 @@ test_two_null_links_same_uri()
*/
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!