2

I modified my app recently and found that tests started hanging. This the stripped down test code:

package app_test                                                                    
                                                                                    
import (                                                                            
    "testing"                                                                   
    "github.com/kargirwar/prosql-go/db"                                         
)                                                                                   
                                                                                    
func TestApp(t *testing.T) {                                                        
    db.SetDbPath("")                                                            
}

The db package is as follows:

package db                                                                          
                                                                                    
import (                                                                            
        "os"                                                                        
        "context"                                                                   
        "database/sql"                                                              
        _ "github.com/mattn/go-sqlite3"                                             
        "path/filepath"                                                             
)                                                                                   
                                                                                    
var dbPath string                                                                   
                                                                                    
func SetDbPath(path string) {                                                       
        dbPath = path                                                               
}                                                                                   
                                                                                    
func OpenDb(ctx context.Context, db string) (*sql.DB, error) {                      
        db = filepath.Join(dbPath, db)                                              
                                                                                    
        _, err := os.OpenFile(db, os.O_RDWR, 0600)                                  
                                                                                    
        if err != nil {                                                             
                return nil, err                                                     
        }                                                                           
                                                                                    
        return sql.Open("sqlite3", "file:"+db+"?_foreign_keys=true")                
}  

I traced down the problem to this dependency:

_ "github.com/mattn/go-sqlite3" 

If I comment this out then the test runs fine, otherwise it hangs.
Strangely go run works just fine. Google says go-sqlite3 takes time to compile but then why is go run working normally?

kargirwar
  • 536
  • 2
  • 7
  • 19

1 Answers1

3

The sqlite3 package uses cgo. The first time the sqlite3 package is referenced, the associated sqlite3 C code is compiled and cached for later use.


$ cat x.go
package main

import _ "github.com/mattn/go-sqlite3" 

func main(){}
$ cat x_test.go
package main

import "testing"

func TestSQLite(t *testing.T) {}

$ go clean -cache
$ time go run -v x.go
github.com/mattn/go-sqlite3
command-line-arguments
real    0m41.378s
user    0m41.176s
sys     0m1.353s
$ time go run -v x.go
real    0m0.506s
user    0m0.571s
sys     0m0.209s

$ go clean -cache
$ time go build -v x.go 
github.com/mattn/go-sqlite3
real    0m41.038s
user    0m40.779s
sys     0m1.280s
$ time go build -v x.go 
real    0m0.239s
user    0m0.379s
sys     0m0.101s

$ go clean -cache
$ time go test -v x.go x_test.go
=== RUN   TestSQLite
--- PASS: TestSQLite (0.00s)
PASS
ok      command-line-arguments  0.003s
real    0m42.751s
user    0m44.702s
sys     0m2.097s
$ time go test -v x.go x_test.go
=== RUN   TestSQLite
--- PASS: TestSQLite (0.00s)
PASS
ok      command-line-arguments  0.002s
real    0m0.618s
user    0m0.752s
sys     0m0.306s
$ 
rocka2q
  • 2,473
  • 4
  • 11