@@ -11,6 +11,7 @@ import (
11
11
"context"
12
12
"database/sql"
13
13
"fmt"
14
+ "io/ioutil"
14
15
"math/rand"
15
16
"os"
16
17
"testing"
@@ -154,3 +155,217 @@ func TestExecCancel(t *testing.T) {
154
155
}
155
156
}
156
157
}
158
+
159
+ func doTestOpenContext (t * testing.T , option string ) (string , error ) {
160
+ tempFilename := TempFilename (t )
161
+ url := tempFilename + option
162
+
163
+ defer func () {
164
+ err := os .Remove (tempFilename )
165
+ if err != nil {
166
+ t .Error ("temp file remove error:" , err )
167
+ }
168
+ }()
169
+
170
+ db , err := sql .Open ("sqlite3" , url )
171
+ if err != nil {
172
+ return "Failed to open database:" , err
173
+ }
174
+
175
+ defer func () {
176
+ err = db .Close ()
177
+ if err != nil {
178
+ t .Error ("db close error:" , err )
179
+ }
180
+ }()
181
+
182
+ ctx , cancel := context .WithTimeout (context .Background (), 55 * time .Second )
183
+ err = db .PingContext (ctx )
184
+ cancel ()
185
+ if err != nil {
186
+ return "ping error:" , err
187
+ }
188
+
189
+ ctx , cancel = context .WithTimeout (context .Background (), 55 * time .Second )
190
+ _ , err = db .ExecContext (ctx , "drop table foo" )
191
+ cancel ()
192
+ ctx , cancel = context .WithTimeout (context .Background (), 55 * time .Second )
193
+ _ , err = db .ExecContext (ctx , "create table foo (id integer)" )
194
+ cancel ()
195
+ if err != nil {
196
+ return "Failed to create table:" , err
197
+ }
198
+
199
+ if stat , err := os .Stat (tempFilename ); err != nil || stat .IsDir () {
200
+ return "Failed to create ./foo.db" , nil
201
+ }
202
+
203
+ return "" , nil
204
+ }
205
+
206
+ func TestOpenContext (t * testing.T ) {
207
+ cases := map [string ]bool {
208
+ "" : true ,
209
+ "?_txlock=immediate" : true ,
210
+ "?_txlock=deferred" : true ,
211
+ "?_txlock=exclusive" : true ,
212
+ "?_txlock=bogus" : false ,
213
+ }
214
+ for option , expectedPass := range cases {
215
+ result , err := doTestOpenContext (t , option )
216
+ if result == "" {
217
+ if ! expectedPass {
218
+ errmsg := fmt .Sprintf ("_txlock error not caught at dbOpen with option: %s" , option )
219
+ t .Fatal (errmsg )
220
+ }
221
+ } else if expectedPass {
222
+ if err == nil {
223
+ t .Fatal (result )
224
+ } else {
225
+ t .Fatal (result , err )
226
+ }
227
+ }
228
+ }
229
+ }
230
+
231
+ func TestFileCopyTruncate (t * testing.T ) {
232
+ var err error
233
+ tempFilename := TempFilename (t )
234
+
235
+ defer func () {
236
+ err = os .Remove (tempFilename )
237
+ if err != nil {
238
+ t .Error ("temp file remove error:" , err )
239
+ }
240
+ }()
241
+
242
+ db , err := sql .Open ("sqlite3" , tempFilename )
243
+ if err != nil {
244
+ t .Fatal ("open error:" , err )
245
+ }
246
+
247
+ defer func () {
248
+ err = db .Close ()
249
+ if err != nil {
250
+ t .Error ("db close error:" , err )
251
+ }
252
+ }()
253
+
254
+ ctx , cancel := context .WithTimeout (context .Background (), 55 * time .Second )
255
+ err = db .PingContext (ctx )
256
+ cancel ()
257
+ if err != nil {
258
+ t .Fatal ("ping error:" , err )
259
+ }
260
+
261
+ ctx , cancel = context .WithTimeout (context .Background (), 55 * time .Second )
262
+ _ , err = db .ExecContext (ctx , "drop table foo" )
263
+ cancel ()
264
+ ctx , cancel = context .WithTimeout (context .Background (), 55 * time .Second )
265
+ _ , err = db .ExecContext (ctx , "create table foo (id integer)" )
266
+ cancel ()
267
+ if err != nil {
268
+ t .Fatal ("create table error:" , err )
269
+ }
270
+
271
+ // copy db to new file
272
+ var data []byte
273
+ data , err = ioutil .ReadFile (tempFilename )
274
+ if err != nil {
275
+ t .Fatal ("read file error:" , err )
276
+ }
277
+
278
+ var f * os.File
279
+ f , err = os .Create (tempFilename + "-db-copy" )
280
+ if err != nil {
281
+ t .Fatal ("create file error:" , err )
282
+ }
283
+
284
+ defer func () {
285
+ err = os .Remove (tempFilename + "-db-copy" )
286
+ if err != nil {
287
+ t .Error ("temp file moved remove error:" , err )
288
+ }
289
+ }()
290
+
291
+ _ , err = f .Write (data )
292
+ if err != nil {
293
+ f .Close ()
294
+ t .Fatal ("write file error:" , err )
295
+ }
296
+ err = f .Close ()
297
+ if err != nil {
298
+ t .Fatal ("close file error:" , err )
299
+ }
300
+
301
+ // truncate current db file
302
+ f , err = os .OpenFile (tempFilename , os .O_WRONLY | os .O_TRUNC , 0666 )
303
+ if err != nil {
304
+ t .Fatal ("open file error:" , err )
305
+ }
306
+ err = f .Close ()
307
+ if err != nil {
308
+ t .Fatal ("close file error:" , err )
309
+ }
310
+
311
+ // test db after file truncate
312
+ ctx , cancel = context .WithTimeout (context .Background (), 55 * time .Second )
313
+ err = db .PingContext (ctx )
314
+ cancel ()
315
+ if err != nil {
316
+ t .Fatal ("ping error:" , err )
317
+ }
318
+
319
+ ctx , cancel = context .WithTimeout (context .Background (), 55 * time .Second )
320
+ _ , err = db .ExecContext (ctx , "drop table foo" )
321
+ cancel ()
322
+ if err == nil {
323
+ t .Fatal ("drop table no error" )
324
+ }
325
+
326
+ ctx , cancel = context .WithTimeout (context .Background (), 55 * time .Second )
327
+ _ , err = db .ExecContext (ctx , "create table foo (id integer)" )
328
+ cancel ()
329
+ if err != nil {
330
+ t .Fatal ("create table error:" , err )
331
+ }
332
+
333
+ err = db .Close ()
334
+ if err != nil {
335
+ t .Error ("db close error:" , err )
336
+ }
337
+
338
+ // test copied file
339
+ db , err = sql .Open ("sqlite3" , tempFilename + "-db-copy" )
340
+ if err != nil {
341
+ t .Fatal ("open error:" , err )
342
+ }
343
+
344
+ defer func () {
345
+ err = db .Close ()
346
+ if err != nil {
347
+ t .Error ("db close error:" , err )
348
+ }
349
+ }()
350
+
351
+ ctx , cancel = context .WithTimeout (context .Background (), 55 * time .Second )
352
+ err = db .PingContext (ctx )
353
+ cancel ()
354
+ if err != nil {
355
+ t .Fatal ("ping error:" , err )
356
+ }
357
+
358
+ ctx , cancel = context .WithTimeout (context .Background (), 55 * time .Second )
359
+ _ , err = db .ExecContext (ctx , "drop table foo" )
360
+ cancel ()
361
+ if err != nil {
362
+ t .Fatal ("drop table error:" , err )
363
+ }
364
+
365
+ ctx , cancel = context .WithTimeout (context .Background (), 55 * time .Second )
366
+ _ , err = db .ExecContext (ctx , "create table foo (id integer)" )
367
+ cancel ()
368
+ if err != nil {
369
+ t .Fatal ("create table error:" , err )
370
+ }
371
+ }
0 commit comments