Serenity Operating System
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

at master 218 lines 5.9 kB view raw
1/* 2 * Copyright (c) 2021, Jan de Visser <jan@de-visser.net> 3 * 4 * SPDX-License-Identifier: BSD-2-Clause 5 */ 6 7#include <unistd.h> 8 9#include <AK/ScopeGuard.h> 10#include <LibSQL/BTree.h> 11#include <LibSQL/Database.h> 12#include <LibSQL/Heap.h> 13#include <LibSQL/Meta.h> 14#include <LibSQL/Row.h> 15#include <LibSQL/Value.h> 16#include <LibTest/TestCase.h> 17 18NonnullRefPtr<SQL::SchemaDef> setup_schema(SQL::Database&); 19NonnullRefPtr<SQL::TableDef> setup_table(SQL::Database&); 20void insert_into_table(SQL::Database&, int); 21void verify_table_contents(SQL::Database&, int); 22void insert_and_verify(int); 23void commit(SQL::Database&); 24 25NonnullRefPtr<SQL::SchemaDef> setup_schema(SQL::Database& db) 26{ 27 auto schema = SQL::SchemaDef::construct("TestSchema"); 28 auto maybe_error = db.add_schema(schema); 29 EXPECT(!maybe_error.is_error()); 30 return schema; 31} 32 33NonnullRefPtr<SQL::TableDef> setup_table(SQL::Database& db) 34{ 35 auto schema = setup_schema(db); 36 auto table = SQL::TableDef::construct(schema, "TestTable"); 37 table->append_column("TextColumn", SQL::SQLType::Text); 38 table->append_column("IntColumn", SQL::SQLType::Integer); 39 EXPECT_EQ(table->num_columns(), 2u); 40 auto maybe_error = db.add_table(table); 41 EXPECT(!maybe_error.is_error()); 42 return table; 43} 44 45void insert_into_table(SQL::Database& db, int count) 46{ 47 auto table = MUST(db.get_table("TestSchema", "TestTable")); 48 49 for (int ix = 0; ix < count; ix++) { 50 SQL::Row row(*table); 51 StringBuilder builder; 52 builder.appendff("Test{}", ix); 53 54 row["TextColumn"] = builder.to_deprecated_string(); 55 row["IntColumn"] = ix; 56 auto maybe_error = db.insert(row); 57 EXPECT(!maybe_error.is_error()); 58 } 59} 60 61void verify_table_contents(SQL::Database& db, int expected_count) 62{ 63 auto table = MUST(db.get_table("TestSchema", "TestTable")); 64 65 int sum = 0; 66 int count = 0; 67 auto rows_or_error = db.select_all(*table); 68 EXPECT(!rows_or_error.is_error()); 69 for (auto& row : rows_or_error.value()) { 70 StringBuilder builder; 71 builder.appendff("Test{}", row["IntColumn"].to_int<i32>().value()); 72 EXPECT_EQ(row["TextColumn"].to_deprecated_string(), builder.to_deprecated_string()); 73 count++; 74 sum += row["IntColumn"].to_int<i32>().value(); 75 } 76 EXPECT_EQ(count, expected_count); 77 EXPECT_EQ(sum, (expected_count * (expected_count - 1)) / 2); 78} 79 80void commit(SQL::Database& db) 81{ 82 auto maybe_error = db.commit(); 83 EXPECT(!maybe_error.is_error()); 84} 85 86void insert_and_verify(int count) 87{ 88 ScopeGuard guard([]() { unlink("/tmp/test.db"); }); 89 { 90 auto db = SQL::Database::construct("/tmp/test.db"); 91 EXPECT(!db->open().is_error()); 92 (void)setup_table(db); 93 commit(db); 94 } 95 { 96 auto db = SQL::Database::construct("/tmp/test.db"); 97 EXPECT(!db->open().is_error()); 98 insert_into_table(db, count); 99 commit(db); 100 } 101 { 102 auto db = SQL::Database::construct("/tmp/test.db"); 103 EXPECT(!db->open().is_error()); 104 verify_table_contents(db, count); 105 } 106} 107 108TEST_CASE(create_heap) 109{ 110 ScopeGuard guard([]() { unlink("/tmp/test.db"); }); 111 auto heap = SQL::Heap::construct("/tmp/test.db"); 112 EXPECT(!heap->open().is_error()); 113 EXPECT_EQ(heap->version(), SQL::Heap::current_version); 114} 115 116TEST_CASE(create_from_dev_random) 117{ 118 auto heap = SQL::Heap::construct("/dev/random"); 119 auto should_be_error = heap->open(); 120 EXPECT(should_be_error.is_error()); 121} 122 123TEST_CASE(create_from_unreadable_file) 124{ 125 auto heap = SQL::Heap::construct("/etc/shadow"); 126 auto should_be_error = heap->open(); 127 EXPECT(should_be_error.is_error()); 128} 129 130TEST_CASE(create_in_non_existing_dir) 131{ 132 auto heap = SQL::Heap::construct("/tmp/bogus/test.db"); 133 auto should_be_error = heap->open(); 134 EXPECT(should_be_error.is_error()); 135} 136 137TEST_CASE(create_database) 138{ 139 ScopeGuard guard([]() { unlink("/tmp/test.db"); }); 140 auto db = SQL::Database::construct("/tmp/test.db"); 141 auto should_not_be_error = db->open(); 142 EXPECT(!should_not_be_error.is_error()); 143 commit(db); 144} 145 146TEST_CASE(add_schema_to_database) 147{ 148 ScopeGuard guard([]() { unlink("/tmp/test.db"); }); 149 auto db = SQL::Database::construct("/tmp/test.db"); 150 EXPECT(!db->open().is_error()); 151 (void)setup_schema(db); 152 commit(db); 153} 154 155TEST_CASE(get_schema_from_database) 156{ 157 ScopeGuard guard([]() { unlink("/tmp/test.db"); }); 158 { 159 auto db = SQL::Database::construct("/tmp/test.db"); 160 EXPECT(!db->open().is_error()); 161 (void)setup_schema(db); 162 commit(db); 163 } 164 { 165 auto db = SQL::Database::construct("/tmp/test.db"); 166 EXPECT(!db->open().is_error()); 167 auto schema_or_error = db->get_schema("TestSchema"); 168 EXPECT(!schema_or_error.is_error()); 169 } 170} 171 172TEST_CASE(add_table_to_database) 173{ 174 ScopeGuard guard([]() { unlink("/tmp/test.db"); }); 175 auto db = SQL::Database::construct("/tmp/test.db"); 176 EXPECT(!db->open().is_error()); 177 (void)setup_table(db); 178 commit(db); 179} 180 181TEST_CASE(get_table_from_database) 182{ 183 ScopeGuard guard([]() { unlink("/tmp/test.db"); }); 184 { 185 auto db = SQL::Database::construct("/tmp/test.db"); 186 EXPECT(!db->open().is_error()); 187 (void)setup_table(db); 188 commit(db); 189 } 190 { 191 auto db = SQL::Database::construct("/tmp/test.db"); 192 EXPECT(!db->open().is_error()); 193 194 auto table = MUST(db->get_table("TestSchema", "TestTable")); 195 EXPECT_EQ(table->name(), "TestTable"); 196 EXPECT_EQ(table->num_columns(), 2u); 197 } 198} 199 200TEST_CASE(insert_one_into_and_select_from_table) 201{ 202 insert_and_verify(1); 203} 204 205TEST_CASE(insert_two_into_table) 206{ 207 insert_and_verify(2); 208} 209 210TEST_CASE(insert_10_into_table) 211{ 212 insert_and_verify(10); 213} 214 215TEST_CASE(insert_100_into_table) 216{ 217 insert_and_verify(100); 218}