Register
Login
Resources
Docs Blog Datasets Glossary Case Studies Tutorials & Webinars
Product
Data Engine LLMs Platform Enterprise
Pricing Explore
Connect to our Discord channel

database.test.ts 3.8 KB

You have to be logged in to leave a comment. Sign In
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
  1. import fs from 'fs';
  2. import * as os from 'os';
  3. import * as path from 'path';
  4. import Database from 'better-sqlite3';
  5. const ORIGINAL_ENV = { ...process.env };
  6. describe('database WAL mode', () => {
  7. let tempDir: string;
  8. beforeEach(() => {
  9. jest.resetModules();
  10. process.env = { ...ORIGINAL_ENV };
  11. tempDir = fs.mkdtempSync(path.join(os.tmpdir(), 'promptfoo-dbtest-'));
  12. process.env.PROMPTFOO_CONFIG_DIR = tempDir;
  13. delete process.env.IS_TESTING;
  14. delete process.env.PROMPTFOO_DISABLE_WAL_MODE;
  15. });
  16. afterEach(async () => {
  17. process.env = ORIGINAL_ENV;
  18. // Close the database connection if it exists
  19. try {
  20. const database = await import('../src/database');
  21. database.closeDb();
  22. } catch (err) {
  23. console.error('Error closing database:', err);
  24. }
  25. // Add a small delay to ensure connections are fully closed on Windows
  26. if (process.platform === 'win32') {
  27. await new Promise((resolve) => setTimeout(resolve, 100));
  28. }
  29. try {
  30. fs.rmSync(tempDir, { recursive: true, force: true });
  31. } catch (err) {
  32. console.warn(`Could not remove temp directory ${tempDir}:`, err);
  33. // On Windows, sometimes we need multiple attempts
  34. if (process.platform === 'win32') {
  35. try {
  36. // Try a second time after a short delay
  37. await new Promise((resolve) => setTimeout(resolve, 500));
  38. fs.rmSync(tempDir, { recursive: true, force: true });
  39. } catch {
  40. console.error(`Failed to remove temp directory after retry: ${tempDir}`);
  41. }
  42. }
  43. }
  44. });
  45. it('enables WAL journal mode by default', async () => {
  46. // First import and initialize the database to trigger WAL mode configuration
  47. const database = await import('../src/database');
  48. database.getDb();
  49. // Close it to ensure we don't get resource conflicts
  50. database.closeDb();
  51. // Then independently verify the journal mode using a direct connection
  52. const dbPath = database.getDbPath();
  53. const directDb = new Database(dbPath);
  54. try {
  55. const result = directDb.prepare('PRAGMA journal_mode;').get() as { journal_mode: string };
  56. expect(result.journal_mode.toLowerCase()).toBe('wal');
  57. } finally {
  58. // Make sure to close this connection too
  59. directDb.close();
  60. }
  61. });
  62. it('skips WAL mode when PROMPTFOO_DISABLE_WAL_MODE is set', async () => {
  63. process.env.PROMPTFOO_DISABLE_WAL_MODE = 'true';
  64. const database = await import('../src/database');
  65. database.getDb();
  66. database.closeDb();
  67. const dbPath = database.getDbPath();
  68. const directDb = new Database(dbPath);
  69. try {
  70. const result = directDb.prepare('PRAGMA journal_mode;').get() as { journal_mode: string };
  71. // Should be in default mode (delete) when WAL is disabled
  72. expect(result.journal_mode.toLowerCase()).toBe('delete');
  73. } finally {
  74. directDb.close();
  75. }
  76. });
  77. it('does not enable WAL mode for in-memory databases', async () => {
  78. process.env.IS_TESTING = 'true';
  79. const database = await import('../src/database');
  80. const db = database.getDb();
  81. // For in-memory databases, we can't verify the journal mode
  82. // but we can ensure it doesn't throw
  83. expect(db).toBeDefined();
  84. });
  85. it('verifies WAL checkpoint settings', async () => {
  86. const database = await import('../src/database');
  87. database.getDb();
  88. database.closeDb();
  89. const dbPath = database.getDbPath();
  90. const directDb = new Database(dbPath);
  91. try {
  92. const autocheckpoint = directDb.prepare('PRAGMA wal_autocheckpoint;').get() as {
  93. wal_autocheckpoint: number;
  94. };
  95. expect(autocheckpoint.wal_autocheckpoint).toBe(1000);
  96. const synchronous = directDb.prepare('PRAGMA synchronous;').get() as { synchronous: number };
  97. // NORMAL = 1 in SQLite
  98. expect(synchronous.synchronous).toBe(1);
  99. } finally {
  100. directDb.close();
  101. }
  102. });
  103. });
Tip!

Press p or to see the previous file or, n or to see the next file

Comments

Loading...