@@ -5,7 +5,6 @@ package litestream
55import (
66 "fmt"
77 "log/slog"
8- "strconv"
98 "sync"
109 "testing"
1110 "time"
@@ -100,6 +99,26 @@ func TestVFSConfig_NilOptionalFields(t *testing.T) {
10099 }
101100}
102101
102+ func TestVFSConfig_CopyOnSetAndGet (t * testing.T ) {
103+ defer clearVFSConfigs ()
104+
105+ cfg := & VFSConfig {ReplicaURL : "s3://bucket/original" }
106+ SetVFSConfig ("copy.db" , cfg )
107+
108+ cfg .ReplicaURL = "s3://bucket/mutated"
109+
110+ got := GetVFSConfig ("copy.db" )
111+ if got .ReplicaURL != "s3://bucket/original" {
112+ t .Fatalf ("expected original url, got %q (SetVFSConfig did not copy)" , got .ReplicaURL )
113+ }
114+
115+ got .ReplicaURL = "s3://bucket/mutated-via-get"
116+ got2 := GetVFSConfig ("copy.db" )
117+ if got2 .ReplicaURL != "s3://bucket/original" {
118+ t .Fatalf ("expected original url, got %q (GetVFSConfig did not copy)" , got2 .ReplicaURL )
119+ }
120+ }
121+
103122func TestVFSConfig_PerConnectionOverrides (t * testing.T ) {
104123 defer clearVFSConfigs ()
105124
@@ -115,7 +134,7 @@ func TestVFSConfig_PerConnectionOverrides(t *testing.T) {
115134
116135 vfs := NewVFS (client , slog .Default ())
117136
118- f , _ , err := vfs .openMainDB ("config-override.db" , 0x00000100 ) // OpenMainDB
137+ f , _ , err := vfs .openMainDB ("config-override.db" , 0x00000100 )
119138 if err != nil {
120139 t .Fatalf ("open main db: %v" , err )
121140 }
@@ -130,174 +149,14 @@ func TestVFSConfig_PerConnectionOverrides(t *testing.T) {
130149 }
131150}
132151
133- func TestVFSFile_PRAGMAPollInterval (t * testing.T ) {
134- client := newMockReplicaClient ()
135- client .addFixture (t , buildLTXFixture (t , 1 , 'a' ))
136-
137- f := NewVFSFile (client , "test.db" , slog .Default ())
138- if err := f .Open (); err != nil {
139- t .Fatalf ("open vfs file: %v" , err )
140- }
141- defer f .Close ()
142-
143- const SQLITE_FCNTL_PRAGMA = 14
144-
145- result , err := f .FileControl (SQLITE_FCNTL_PRAGMA , "litestream_poll_interval" , nil )
146- if err != nil {
147- t .Fatalf ("get poll_interval: %v" , err )
148- }
149- if result == nil || * result != DefaultPollInterval .String () {
150- t .Fatalf ("expected default poll interval, got %v" , result )
151- }
152-
153- newInterval := "5s"
154- _ , err = f .FileControl (SQLITE_FCNTL_PRAGMA , "litestream_poll_interval" , & newInterval )
155- if err != nil {
156- t .Fatalf ("set poll_interval: %v" , err )
157- }
158-
159- result , err = f .FileControl (SQLITE_FCNTL_PRAGMA , "litestream_poll_interval" , nil )
160- if err != nil {
161- t .Fatalf ("get poll_interval after set: %v" , err )
162- }
163- if result == nil || * result != "5s" {
164- t .Fatalf ("expected 5s, got %v" , result )
165- }
166- }
167-
168- func TestVFSFile_PRAGMACacheSize (t * testing.T ) {
169- client := newMockReplicaClient ()
170- client .addFixture (t , buildLTXFixture (t , 1 , 'a' ))
171-
172- f := NewVFSFile (client , "test.db" , slog .Default ())
173- if err := f .Open (); err != nil {
174- t .Fatalf ("open vfs file: %v" , err )
175- }
176- defer f .Close ()
177-
178- const SQLITE_FCNTL_PRAGMA = 14
179-
180- result , err := f .FileControl (SQLITE_FCNTL_PRAGMA , "litestream_cache_size" , nil )
181- if err != nil {
182- t .Fatalf ("get cache_size: %v" , err )
183- }
184- if result == nil || * result != strconv .Itoa (DefaultCacheSize ) {
185- t .Fatalf ("expected default cache size, got %v" , result )
186- }
187-
188- newSize := "20971520"
189- _ , err = f .FileControl (SQLITE_FCNTL_PRAGMA , "litestream_cache_size" , & newSize )
190- if err != nil {
191- t .Fatalf ("set cache_size: %v" , err )
192- }
193-
194- result , err = f .FileControl (SQLITE_FCNTL_PRAGMA , "litestream_cache_size" , nil )
195- if err != nil {
196- t .Fatalf ("get cache_size after set: %v" , err )
197- }
198- if result == nil || * result != "20971520" {
199- t .Fatalf ("expected 20971520, got %v" , result )
200- }
201- }
202-
203- func TestVFSFile_PRAGMALogLevel (t * testing.T ) {
204- client := newMockReplicaClient ()
205- client .addFixture (t , buildLTXFixture (t , 1 , 'a' ))
206-
207- f := NewVFSFile (client , "test.db" , slog .Default ())
208- if err := f .Open (); err != nil {
209- t .Fatalf ("open vfs file: %v" , err )
210- }
211- defer f .Close ()
212-
213- const SQLITE_FCNTL_PRAGMA = 14
214-
215- debugLevel := "debug"
216- _ , err := f .FileControl (SQLITE_FCNTL_PRAGMA , "litestream_log_level" , & debugLevel )
217- if err != nil {
218- t .Fatalf ("set log_level to debug: %v" , err )
219- }
220-
221- result , err := f .FileControl (SQLITE_FCNTL_PRAGMA , "litestream_log_level" , nil )
222- if err != nil {
223- t .Fatalf ("get log_level: %v" , err )
224- }
225- if result == nil || * result != "debug" {
226- t .Fatalf ("expected debug, got %v" , result )
227- }
228-
229- infoLevel := "info"
230- _ , err = f .FileControl (SQLITE_FCNTL_PRAGMA , "litestream_log_level" , & infoLevel )
231- if err != nil {
232- t .Fatalf ("set log_level to info: %v" , err )
233- }
234-
235- result , err = f .FileControl (SQLITE_FCNTL_PRAGMA , "litestream_log_level" , nil )
236- if err != nil {
237- t .Fatalf ("get log_level: %v" , err )
238- }
239- if result == nil || * result != "info" {
240- t .Fatalf ("expected info, got %v" , result )
241- }
242- }
243-
244- func TestVFSFile_PRAGMAHydrationEnabled (t * testing.T ) {
245- client := newMockReplicaClient ()
246- client .addFixture (t , buildLTXFixture (t , 1 , 'a' ))
247-
248- f := NewVFSFile (client , "test.db" , slog .Default ())
249- if err := f .Open (); err != nil {
250- t .Fatalf ("open vfs file: %v" , err )
251- }
252- defer f .Close ()
253-
254- const SQLITE_FCNTL_PRAGMA = 14
255-
256- result , err := f .FileControl (SQLITE_FCNTL_PRAGMA , "litestream_hydration_enabled" , nil )
257- if err != nil {
258- t .Fatalf ("get hydration_enabled: %v" , err )
259- }
260- if result == nil || * result != "0" {
261- t .Fatalf ("expected 0, got %v" , result )
262- }
263-
264- writeVal := "1"
265- _ , err = f .FileControl (SQLITE_FCNTL_PRAGMA , "litestream_hydration_enabled" , & writeVal )
266- if err == nil {
267- t .Fatal ("expected error for read-only pragma, got nil" )
268- }
269- }
270-
271- func TestVFSFile_PRAGMAReplicaURL (t * testing.T ) {
152+ func TestVFS_NilClientReturnsError (t * testing.T ) {
272153 defer clearVFSConfigs ()
273154
274- client := newMockReplicaClient ()
275- client .addFixture (t , buildLTXFixture (t , 1 , 'a' ))
276-
277- SetVFSConfig ("replica-url-test.db" , & VFSConfig {
278- ReplicaURL : "s3://my-bucket/db" ,
279- })
280-
281- f := NewVFSFile (client , "replica-url-test.db" , slog .Default ())
282- if err := f .Open (); err != nil {
283- t .Fatalf ("open vfs file: %v" , err )
284- }
285- defer f .Close ()
286-
287- const SQLITE_FCNTL_PRAGMA = 14
288-
289- result , err := f .FileControl (SQLITE_FCNTL_PRAGMA , "litestream_replica_url" , nil )
290- if err != nil {
291- t .Fatalf ("get replica_url: %v" , err )
292- }
293- if result == nil || * result != "s3://my-bucket/db" {
294- t .Fatalf ("expected s3://my-bucket/db, got %v" , result )
295- }
155+ vfs := NewVFS (nil , slog .Default ())
296156
297- writeVal := "s3://other/path"
298- _ , err = f .FileControl (SQLITE_FCNTL_PRAGMA , "litestream_replica_url" , & writeVal )
157+ _ , _ , err := vfs .openMainDB ("no-client.db" , 0x00000100 )
299158 if err == nil {
300- t .Fatal ("expected error for read-only pragma , got nil" )
159+ t .Fatal ("expected error when no client configured , got nil" )
301160 }
302161}
303162
0 commit comments