LCOV - code coverage report
Current view: directory - storage/test - test_async_callbacks_with_spun_event_loops.cpp (source / functions) Found Hit Coverage
Test: app.info Lines: 73 71 97.3 %
Date: 2012-06-02 Functions: 11 11 100.0 %

       1                 : /* Any copyright is dedicated to the Public Domain.
       2                 :    http://creativecommons.org/publicdomain/zero/1.0/ */
       3                 : 
       4                 : #include "storage_test_harness.h"
       5                 : #include "prthread.h"
       6                 : #include "nsIEventTarget.h"
       7                 : #include "nsIInterfaceRequestorUtils.h"
       8                 : 
       9                 : #include "sqlite3.h"
      10                 : 
      11                 : ////////////////////////////////////////////////////////////////////////////////
      12                 : //// Async Helpers
      13                 : 
      14                 : /**
      15                 :  * Spins the events loop for current thread until aCondition is true.
      16                 :  */
      17                 : void
      18               5 : spin_events_loop_until_true(const bool* const aCondition)
      19                 : {
      20              10 :   nsCOMPtr<nsIThread> thread(::do_GetCurrentThread());
      21               5 :   nsresult rv = NS_OK;
      22               5 :   bool processed = true;
      23              15 :   while (!(*aCondition) && NS_SUCCEEDED(rv)) {
      24               5 :     rv = thread->ProcessNextEvent(true, &processed);
      25                 :   }
      26               5 : }
      27                 : 
      28                 : ////////////////////////////////////////////////////////////////////////////////
      29                 : //// mozIStorageStatementCallback implementation
      30                 : 
      31                 : class UnownedCallback : public mozIStorageStatementCallback
      32                 : {
      33                 : public:
      34                 :   NS_DECL_ISUPPORTS
      35                 : 
      36                 :   // Whether the object has been destroyed.
      37                 :   static bool sAlive;
      38                 :   // Whether the first result was received.
      39                 :   static bool sResult;
      40                 :   // Whether an error was received.
      41                 :   static bool sError;
      42                 : 
      43               2 :   UnownedCallback(mozIStorageConnection* aDBConn)
      44                 :   : mDBConn(aDBConn)
      45               2 :   , mCompleted(false)
      46                 :   {
      47               2 :     sAlive = true;
      48               2 :     sResult = false;
      49               2 :     sError = false;
      50               2 :   }
      51                 : 
      52               2 :   ~UnownedCallback()
      53               4 :   {
      54               2 :     sAlive = false;
      55               2 :     blocking_async_close(mDBConn);
      56               2 :   }
      57                 : 
      58               2 :   NS_IMETHOD HandleResult(mozIStorageResultSet* aResultSet)
      59                 :   {
      60               2 :     sResult = true;
      61               2 :     spin_events_loop_until_true(&mCompleted);
      62               2 :     if (!sAlive) {
      63               0 :       NS_RUNTIMEABORT("The statement callback was destroyed prematurely.");
      64                 :     }
      65               2 :     return NS_OK;
      66                 :   }
      67                 : 
      68               1 :   NS_IMETHOD HandleError(mozIStorageError* aError)
      69                 :   {
      70               1 :     sError = true;
      71               1 :     spin_events_loop_until_true(&mCompleted);
      72               1 :     if (!sAlive) {
      73               0 :       NS_RUNTIMEABORT("The statement callback was destroyed prematurely.");
      74                 :     }
      75               1 :     return NS_OK;
      76                 :   }
      77                 : 
      78               2 :   NS_IMETHOD HandleCompletion(PRUint16 aReason)
      79                 :   {
      80               2 :     mCompleted = true;
      81               2 :     return NS_OK;
      82                 :   }
      83                 : 
      84                 : protected:
      85                 :   nsCOMPtr<mozIStorageConnection> mDBConn;
      86                 :   bool mCompleted;
      87                 : };
      88                 : 
      89              15 : NS_IMPL_ISUPPORTS1(UnownedCallback, mozIStorageStatementCallback)
      90                 : 
      91                 : bool UnownedCallback::sAlive = false;
      92                 : bool UnownedCallback::sResult = false;
      93                 : bool UnownedCallback::sError = false;
      94                 : 
      95                 : ////////////////////////////////////////////////////////////////////////////////
      96                 : //// Tests
      97                 : 
      98                 : void
      99               1 : test_SpinEventsLoopInHandleResult()
     100                 : {
     101               2 :   nsCOMPtr<mozIStorageConnection> db(getMemoryDatabase());
     102                 : 
     103                 :   // Create a test table and populate it.
     104               2 :   nsCOMPtr<mozIStorageStatement> stmt;
     105               2 :   db->CreateStatement(NS_LITERAL_CSTRING(
     106                 :     "CREATE TABLE test (id INTEGER PRIMARY KEY)"
     107               2 :   ), getter_AddRefs(stmt));
     108               1 :   stmt->Execute();
     109               1 :   stmt->Finalize();
     110                 : 
     111               2 :   db->CreateStatement(NS_LITERAL_CSTRING(
     112                 :     "INSERT INTO test (id) VALUES (?)"
     113               2 :   ), getter_AddRefs(stmt));
     114              31 :   for (PRInt32 i = 0; i < 30; ++i) {
     115              30 :     stmt->BindInt32ByIndex(0, i);
     116              30 :     stmt->Execute();
     117              30 :     stmt->Reset();
     118                 :   }
     119               1 :   stmt->Finalize();
     120                 : 
     121               2 :   db->CreateStatement(NS_LITERAL_CSTRING(
     122                 :     "SELECT * FROM test"
     123               2 :   ), getter_AddRefs(stmt));
     124               2 :   nsCOMPtr<mozIStoragePendingStatement> ps;
     125               2 :   do_check_success(stmt->ExecuteAsync(new UnownedCallback(db),
     126                 :                                       getter_AddRefs(ps)));
     127               1 :   stmt->Finalize();
     128                 : 
     129               1 :   spin_events_loop_until_true(&UnownedCallback::sResult);
     130               1 : }
     131                 : 
     132                 : void
     133               1 : test_SpinEventsLoopInHandleError()
     134                 : {
     135               2 :   nsCOMPtr<mozIStorageConnection> db(getMemoryDatabase());
     136                 : 
     137                 :   // Create a test table and populate it.
     138               2 :   nsCOMPtr<mozIStorageStatement> stmt;
     139               2 :   db->CreateStatement(NS_LITERAL_CSTRING(
     140                 :     "CREATE TABLE test (id INTEGER PRIMARY KEY)"
     141               2 :   ), getter_AddRefs(stmt));
     142               1 :   stmt->Execute();
     143               1 :   stmt->Finalize();
     144                 : 
     145               2 :   db->CreateStatement(NS_LITERAL_CSTRING(
     146                 :     "INSERT INTO test (id) VALUES (1)"
     147               2 :   ), getter_AddRefs(stmt));
     148               1 :   stmt->Execute();
     149               1 :   stmt->Finalize();
     150                 : 
     151                 :   // This will cause a constraint error.
     152               2 :   db->CreateStatement(NS_LITERAL_CSTRING(
     153                 :     "INSERT INTO test (id) VALUES (1)"
     154               2 :   ), getter_AddRefs(stmt));
     155               2 :   nsCOMPtr<mozIStoragePendingStatement> ps;
     156               2 :   do_check_success(stmt->ExecuteAsync(new UnownedCallback(db),
     157                 :                                       getter_AddRefs(ps)));
     158               1 :   stmt->Finalize();
     159                 : 
     160               1 :   spin_events_loop_until_true(&UnownedCallback::sError);
     161               1 : }
     162                 : 
     163                 : void (*gTests[])(void) = {
     164                 :   test_SpinEventsLoopInHandleResult,
     165                 :   test_SpinEventsLoopInHandleError,
     166                 : };
     167                 : 
     168                 : const char *file = __FILE__;
     169                 : #define TEST_NAME "test async callbacks with spun event loops"
     170                 : #define TEST_FILE file
     171                 : #include "storage_test_harness_tail.h"

Generated by: LCOV version 1.7