storage/test/unit/test_connection_executeAsync.js

Tue, 06 Jan 2015 21:39:09 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Tue, 06 Jan 2015 21:39:09 +0100
branch
TOR_BUG_9701
changeset 8
97036ab72558
permissions
-rw-r--r--

Conditionally force memory storage according to privacy.thirdparty.isolate;
This solves Tor bug #9701, complying with disk avoidance documented in
https://www.torproject.org/projects/torbrowser/design/#disk-avoidance.

     1 /* This Source Code Form is subject to the terms of the Mozilla Public
     2  * License, v. 2.0. If a copy of the MPL was not distributed with this
     3  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     5 /*
     6  * This file tests the functionality of mozIStorageConnection::executeAsync for
     7  * both mozIStorageStatement and mozIStorageAsyncStatement.
     8  */
    10 const INTEGER = 1;
    11 const TEXT = "this is test text";
    12 const REAL = 3.23;
    13 const BLOB = [1, 2];
    15 function test_create_and_add()
    16 {
    17   getOpenedDatabase().executeSimpleSQL(
    18     "CREATE TABLE test (" +
    19       "id INTEGER, " +
    20       "string TEXT, " +
    21       "number REAL, " +
    22       "nuller NULL, " +
    23       "blober BLOB" +
    24     ")"
    25   );
    27   let stmts = [];
    28   stmts[0] = getOpenedDatabase().createStatement(
    29     "INSERT INTO test (id, string, number, nuller, blober) VALUES (?, ?, ?, ?, ?)"
    30   );
    31   stmts[0].bindByIndex(0, INTEGER);
    32   stmts[0].bindByIndex(1, TEXT);
    33   stmts[0].bindByIndex(2, REAL);
    34   stmts[0].bindByIndex(3, null);
    35   stmts[0].bindBlobByIndex(4, BLOB, BLOB.length);
    36   stmts[1] = getOpenedDatabase().createAsyncStatement(
    37     "INSERT INTO test (string, number, nuller, blober) VALUES (?, ?, ?, ?)"
    38   );
    39   stmts[1].bindByIndex(0, TEXT);
    40   stmts[1].bindByIndex(1, REAL);
    41   stmts[1].bindByIndex(2, null);
    42   stmts[1].bindBlobByIndex(3, BLOB, BLOB.length);
    44   getOpenedDatabase().executeAsync(stmts, stmts.length, {
    45     handleResult: function(aResultSet)
    46     {
    47       dump("handleResult("+aResultSet+")\n");
    48       do_throw("unexpected results obtained!");
    49     },
    50     handleError: function(aError)
    51     {
    52       dump("handleError("+aError.result+")\n");
    53       do_throw("unexpected error!");
    54     },
    55     handleCompletion: function(aReason)
    56     {
    57       dump("handleCompletion("+aReason+")\n");
    58       do_check_eq(Ci.mozIStorageStatementCallback.REASON_FINISHED, aReason);
    60       // Check that the result is in the table
    61       let stmt = getOpenedDatabase().createStatement(
    62         "SELECT string, number, nuller, blober FROM test WHERE id = ?"
    63       );
    64       stmt.bindByIndex(0, INTEGER);
    65       try {
    66         do_check_true(stmt.executeStep());
    67         do_check_eq(TEXT, stmt.getString(0));
    68         do_check_eq(REAL, stmt.getDouble(1));
    69         do_check_true(stmt.getIsNull(2));
    70         let count = { value: 0 };
    71         let blob = { value: null };
    72         stmt.getBlob(3, count, blob);
    73         do_check_eq(BLOB.length, count.value);
    74         for (let i = 0; i < BLOB.length; i++)
    75           do_check_eq(BLOB[i], blob.value[i]);
    76       }
    77       finally {
    78         stmt.finalize();
    79       }
    81       // Make sure we have two rows in the table
    82       stmt = getOpenedDatabase().createStatement(
    83         "SELECT COUNT(1) FROM test"
    84       );
    85       try {
    86         do_check_true(stmt.executeStep());
    87         do_check_eq(2, stmt.getInt32(0));
    88       }
    89       finally {
    90         stmt.finalize();
    91       }
    93       // Run the next test.
    94       run_next_test();
    95     }
    96   });
    97   stmts[0].finalize();
    98   stmts[1].finalize();
    99 }
   101 function test_multiple_bindings_on_statements()
   102 {
   103   // This tests to make sure that we pass all the statements multiply bound
   104   // parameters when we call executeAsync.
   105   const AMOUNT_TO_ADD = 5;
   106   const ITERATIONS = 5;
   108   let stmts = [];
   109   let db = getOpenedDatabase();
   110   let sqlString = "INSERT INTO test (id, string, number, nuller, blober) " +
   111                     "VALUES (:int, :text, :real, :null, :blob)";
   112   // We run the same statement twice, and should insert 2 * AMOUNT_TO_ADD.
   113   for (let i = 0; i < ITERATIONS; i++) {
   114     // alternate the type of statement we create
   115     if (i % 2)
   116       stmts[i] = db.createStatement(sqlString);
   117     else
   118       stmts[i] = db.createAsyncStatement(sqlString);
   120     let params = stmts[i].newBindingParamsArray();
   121     for (let j = 0; j < AMOUNT_TO_ADD; j++) {
   122       let bp = params.newBindingParams();
   123       bp.bindByName("int", INTEGER);
   124       bp.bindByName("text", TEXT);
   125       bp.bindByName("real", REAL);
   126       bp.bindByName("null", null);
   127       bp.bindBlobByName("blob", BLOB, BLOB.length);
   128       params.addParams(bp);
   129     }
   130     stmts[i].bindParameters(params);
   131   }
   133   // Get our current number of rows in the table.
   134   let currentRows = 0;
   135   let countStmt = getOpenedDatabase().createStatement(
   136     "SELECT COUNT(1) AS count FROM test"
   137   );
   138   try {
   139     do_check_true(countStmt.executeStep());
   140     currentRows = countStmt.row.count;
   141   }
   142   finally {
   143     countStmt.reset();
   144   }
   146   // Execute asynchronously.
   147   getOpenedDatabase().executeAsync(stmts, stmts.length, {
   148     handleResult: function(aResultSet)
   149     {
   150       do_throw("Unexpected call to handleResult!");
   151     },
   152     handleError: function(aError)
   153     {
   154       print("Error code " + aError.result + " with message '" +
   155             aError.message + "' returned.");
   156       do_throw("Unexpected error!");
   157     },
   158     handleCompletion: function(aReason)
   159     {
   160       print("handleCompletion(" + aReason +
   161             ") for test_multiple_bindings_on_statements");
   162       do_check_eq(Ci.mozIStorageStatementCallback.REASON_FINISHED, aReason);
   164       // Check to make sure we added all of our rows.
   165       try {
   166         do_check_true(countStmt.executeStep());
   167         do_check_eq(currentRows + (ITERATIONS * AMOUNT_TO_ADD),
   168                     countStmt.row.count);
   169       }
   170       finally {
   171         countStmt.finalize();
   172       }
   174       // Run the next test.
   175       run_next_test();
   176     }
   177   });
   178   stmts.forEach(function(stmt) stmt.finalize());
   179 }
   181 function test_asyncClose_does_not_complete_before_statements()
   182 {
   183   let stmt = createStatement("SELECT * FROM sqlite_master");
   184   let executed = false;
   185   stmt.executeAsync({
   186     handleResult: function(aResultSet)
   187     {
   188     },
   189     handleError: function(aError)
   190     {
   191       print("Error code " + aError.result + " with message '" +
   192             aError.message + "' returned.");
   193       do_throw("Unexpected error!");
   194     },
   195     handleCompletion: function(aReason)
   196     {
   197       print("handleCompletion(" + aReason +
   198             ") for test_asyncClose_does_not_complete_before_statements");
   199       do_check_eq(Ci.mozIStorageStatementCallback.REASON_FINISHED, aReason);
   200       executed = true;
   201     }
   202   });
   203   stmt.finalize();
   205   getOpenedDatabase().asyncClose(function() {
   206     // Ensure that the statement executed to completion.
   207     do_check_true(executed);
   209     // Reset gDBConn so that later tests will get a new connection object.
   210     gDBConn = null;
   211     run_next_test();
   212   });
   213 }
   215 function test_asyncClose_does_not_throw_no_callback()
   216 {
   217   getOpenedDatabase().asyncClose();
   219   // Reset gDBConn so that later tests will get a new connection object.
   220   gDBConn = null;
   221   run_next_test();
   222 }
   224 function test_double_asyncClose_throws()
   225 {
   226   let conn = getOpenedDatabase();
   227   conn.asyncClose();
   228   try {
   229     conn.asyncClose();
   230     do_throw("should have thrown");
   231     // There is a small race condition here, which can cause either of
   232     // Cr.NS_ERROR_NOT_INITIALIZED or Cr.NS_ERROR_UNEXPECTED to be thrown.
   233   } catch (e if "result" in e && e.result == Cr.NS_ERROR_NOT_INITIALIZED) {
   234     do_print("NS_ERROR_NOT_INITIALIZED");
   235   } catch (e if "result" in e && e.result == Cr.NS_ERROR_UNEXPECTED) {
   236     do_print("NS_ERROR_UNEXPECTED");
   237   } catch (e) {
   238   }
   240   // Reset gDBConn so that later tests will get a new connection object.
   241   gDBConn = null;
   242   run_next_test();
   243 }
   245 ////////////////////////////////////////////////////////////////////////////////
   246 //// Test Runner
   248 [
   249   test_create_and_add,
   250   test_multiple_bindings_on_statements,
   251   test_asyncClose_does_not_complete_before_statements,
   252   test_asyncClose_does_not_throw_no_callback,
   253   test_double_asyncClose_throws,
   254 ].forEach(add_test);
   256 function run_test()
   257 {
   258   cleanup();
   259   run_next_test();
   260 }

mercurial