test_helpers.h 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139
  1. // Copyright 2013 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. #ifndef SQL_TEST_TEST_HELPERS_H_
  5. #define SQL_TEST_TEST_HELPERS_H_
  6. #include <stddef.h>
  7. #include <stdint.h>
  8. #include <string>
  9. #include "base/strings/string_piece_forward.h"
  10. #include "third_party/abseil-cpp/absl/types/optional.h"
  11. // Collection of test-only convenience functions.
  12. namespace base {
  13. class FilePath;
  14. }
  15. namespace sql {
  16. class Database;
  17. }
  18. namespace sql::test {
  19. // Read a database's page size. Returns nullopt in case of error.
  20. absl::optional<int> ReadDatabasePageSize(const base::FilePath& db_path);
  21. // SQLite stores the database size in the header, and if the actual
  22. // OS-derived size is smaller, the database is considered corrupt.
  23. // [This case is actually a common form of corruption in the wild.]
  24. // This helper sets the in-header size to one page larger than the
  25. // actual file size. The resulting file will return SQLITE_CORRUPT
  26. // for most operations unless PRAGMA writable_schema is turned ON.
  27. //
  28. // This function operates on the raw database file, outstanding database
  29. // connections may not see the change because of the database cache. See
  30. // CorruptSizeInHeaderWithLock().
  31. //
  32. // Returns false if any error occurs accessing the file.
  33. [[nodiscard]] bool CorruptSizeInHeader(const base::FilePath& db_path);
  34. // Call CorruptSizeInHeader() while holding a SQLite-compatible lock
  35. // on the database. This can be used to corrupt a database which is
  36. // already open elsewhere. Blocks until a write lock can be acquired.
  37. [[nodiscard]] bool CorruptSizeInHeaderWithLock(const base::FilePath& db_path);
  38. // Simulates total index corruption by zeroing the root page of an index B-tree.
  39. //
  40. // The corrupted database will still open successfully. SELECTs on the table
  41. // associated with the index will work, as long as they don't access the index.
  42. // However, any query that accesses the index will fail with SQLITE_CORRUPT.
  43. // DROPping the table or the index will fail.
  44. [[nodiscard]] bool CorruptIndexRootPage(const base::FilePath& db_path,
  45. base::StringPiece index_name);
  46. // Return the number of tables in sqlite_schema.
  47. [[nodiscard]] size_t CountSQLTables(sql::Database* db);
  48. // Return the number of indices in sqlite_schema.
  49. [[nodiscard]] size_t CountSQLIndices(sql::Database* db);
  50. // Returns the number of columns in the named table. 0 indicates an
  51. // error (probably no such table).
  52. [[nodiscard]] size_t CountTableColumns(sql::Database* db, const char* table);
  53. // Sets |*count| to the number of rows in |table|. Returns false in
  54. // case of error, such as the table not existing.
  55. bool CountTableRows(sql::Database* db, const char* table, size_t* count);
  56. // Creates a SQLite database at |db_path| from the sqlite .dump output
  57. // at |sql_path|. Returns false if |db_path| already exists, or if
  58. // sql_path does not exist or cannot be read, or if there is an error
  59. // executing the statements.
  60. [[nodiscard]] bool CreateDatabaseFromSQL(const base::FilePath& db_path,
  61. const base::FilePath& sql_path);
  62. // Test-friendly wrapper around sql::Database::IntegrityCheck().
  63. [[nodiscard]] std::string IntegrityCheck(sql::Database& db);
  64. // ExecuteWithResult() executes |sql| and returns the first column of the first
  65. // row as a string. The empty string is returned for no rows. This makes it
  66. // easier to test simple query results using EXPECT_EQ(). For instance:
  67. // EXPECT_EQ("1024", ExecuteWithResult(db, "PRAGMA page_size"));
  68. //
  69. // ExecuteWithResults() stringifies a larger result set by putting |column_sep|
  70. // between columns and |row_sep| between rows. For instance:
  71. // EXPECT_EQ("1,3,5", ExecuteWithResults(
  72. // db, "SELECT id FROM t ORDER BY id", "|", ","));
  73. // Note that EXPECT_EQ() can nicely diff when using \n as |row_sep|.
  74. //
  75. // To test NULL, use the COALESCE() function:
  76. // EXPECT_EQ("<NULL>", ExecuteWithResult(
  77. // db, "SELECT c || '<NULL>' FROM t WHERE id = 1"));
  78. // To test blobs use the HEX() function.
  79. std::string ExecuteWithResult(sql::Database* db, const char* sql);
  80. std::string ExecuteWithResults(sql::Database* db,
  81. const char* sql,
  82. const char* column_sep,
  83. const char* row_sep);
  84. // Returns the database size, in pages. Crashes on SQLite errors.
  85. int GetPageCount(sql::Database* db);
  86. // Column information returned by GetColumnInfo.
  87. //
  88. // C++ wrapper around the out-params of sqlite3_table_column_metadata().
  89. struct ColumnInfo {
  90. // Retrieves schema information for a column in a table.
  91. //
  92. // Crashes on SQLite errors.
  93. //
  94. // |db_name| should be "main" for the connection's main (opened) database, and
  95. // "temp" for the connection's temporary (in-memory) database.
  96. //
  97. // This is a static method rather than a function so it can be listed in the
  98. // InternalApiToken access control list.
  99. [[nodiscard]] static ColumnInfo Create(sql::Database* db,
  100. const std::string& db_name,
  101. const std::string& table_name,
  102. const std::string& column_name);
  103. // The native data type. Example: "INTEGER".
  104. std::string data_type;
  105. // Default collation sequence for sorting. Example: "BINARY".
  106. std::string collation_sequence;
  107. // True if the column has a "NOT NULL" constraint.
  108. bool has_non_null_constraint;
  109. // True if the column is included in the table's PRIMARY KEY.
  110. bool is_in_primary_key;
  111. // True if the column is AUTOINCREMENT.
  112. bool is_auto_incremented;
  113. };
  114. } // namespace sql::test
  115. #endif // SQL_TEST_TEST_HELPERS_H_