• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1// Copyright (c) 2006-2009 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5/**
6 * @fileoverview A collection of common functions used by all database
7 * performance tests.
8 */
9
10var CANNOT_OPEN_DB = -1;
11var SETUP_FAILED = -2;
12var TEST_FAILED = -3;
13
14var TRANSACTIONS = 1000;  // number of transactions; number of rows in the DB
15var RANDOM_STRING_LENGTH = 20;  // the length of the string on each row
16
17/**
18 * Generates a random string of upper-case letters of
19 * RANDOM_STRING_LENGTH length.
20 */
21function getRandomString() {
22  var s = '';
23  for (var i = 0; i < RANDOM_STRING_LENGTH; i++)
24    s += String.fromCharCode(Math.floor(Math.random() * 26) + 64);
25  return s;
26}
27
28/**
29 * Sets up and runs a performance test.
30 * @param {!Object} params An object which must have the following fields:
31 *   dbName: The database name.
32 *   readOnly: If true, transactions will be run using the readTransaction()
33 *       method. Otherwise, transaction() will be used.
34 *   insertRowsAtSetup: Determines if setting up the database should include
35 *       inserting TRANSACTIONS rows in it.
36 *   transactionCallback: The transaction callback that should be timed. This
37 *       function will be run TRANSACTIONS times and must take a transaction
38 *       object as its only parameter.
39 *   customRunTransactions: A custom function for running and timing
40 *       transactions. If this parameter is not null, runPerformanceTest() will
41 *       ignore the txFnct parameter and will call customRunTransactions() as
42 *       soon as the setup is complete. In this case, the user is responsible
43 *       for running and timing the transactions. If not null, this parameter
44 *       must be a function that takes a database object as its only parameter.
45 */
46function runPerformanceTest(params) {
47  var db = openTestDatabase(params.dbName);
48  if (!db) {
49    testComplete(CANNOT_OPEN_DB);
50    return;
51  }
52
53  db.transaction(
54      function(tx) {
55        tx.executeSql('CREATE TABLE IF NOT EXISTS Test (ID INT, Foo TEXT)', [],
56                      function(tx, data) {}, function(tx, error) {});
57        tx.executeSql('DELETE FROM Test');
58        if (params.insertRowsAtSetup) {
59          var randomString = getRandomString();
60          for (var i = 0; i < TRANSACTIONS; i++) {
61            tx.executeSql('INSERT INTO Test VALUES (?, ?)',
62                          [i, randomString]);
63          }
64        }
65      }, function(error) {
66        testComplete(SETUP_FAILED);
67      }, function() {
68        if (params.customRunTransactions)
69          params.customRunTransactions(db);
70        else
71          runTransactions(db, params.readOnly, params.transactionCallback);
72      });
73}
74
75/**
76 * Opens a database with the given name.
77 * @param {string} name The name of the database.
78 */
79function openTestDatabase(name) {
80  if (window.openDatabase) {
81    return window.openDatabase(name, '1.0', 'Test database.',
82                               TRANSACTIONS * RANDOM_STRING_LENGTH);
83  }
84
85  return null;
86}
87
88/**
89 * Runs the given transaction TRANSACTIONS times.
90 * @param {!Object} db The database to run transactions on.
91 * @param {boolean} readOnly If true, all transactions will be run using the
92 *     db.readTransaction() call. Otherwise, the transactions will be run
93 *     using the db.transaction() call.
94 * @param {function(!Object)} The transaction callback.
95 */
96function runTransactions(db, readOnly, transactionCallback) {
97  var transactionsCompleted = 0;
98  var transactionFunction = readOnly ? db.readTransaction : db.transaction;
99  var startTime = Date.now();
100  for (var i = 0; i < TRANSACTIONS; i++) {
101    transactionFunction.call(db, transactionCallback,
102                             function(error) {
103                               testComplete(TEST_FAILED);
104                             }, function() {
105                               if (++transactionsCompleted == TRANSACTIONS)
106                                 testComplete(Date.now() - startTime);
107                             });
108  }
109}
110