Golang测试挂起

huangapple go评论70阅读模式
英文:

Golang test hanging

问题

我最近修改了我的应用程序,并发现测试开始出现了卡住的情况。以下是简化后的测试代码:

package app_test

import (
    "testing"
    "github.com/kargirwar/prosql-go/db"
)

func TestApp(t *testing.T) {
    db.SetDbPath("")
}

db 包的代码如下:

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")
}

我追踪到了这个依赖项:

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

如果我将其注释掉,测试就可以正常运行,否则就会卡住。奇怪的是,go run 命令可以正常工作。谷歌说 go-sqlite3 需要一些时间来编译,但是为什么 go run 正常运行呢?

英文:

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?

答案1

得分: 2

sqlite3包使用cgo。第一次引用sqlite3包时,相关的sqlite3 C代码会被编译并缓存以供后续使用。

以下是一些命令行输出的示例:

$ 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
英文:

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
$ 

huangapple
  • 本文由 发表于 2022年10月4日 13:31:44
  • 转载请务必保留本文链接:https://go.coder-hub.com/73943467.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定