【问题标题】:Golang test with external package dependency isn't passing with Gitlab Ci, but pass in local具有外部包依赖的Golang测试没有通过Gitlab Ci,而是通过本地
【发布时间】:2019-01-31 14:17:58
【问题描述】:

我有测试:

package misc

var (
    Trace   *log.Logger
    Info    *log.Logger
    Warning *log.Logger
    Error   *log.Logger
)

func TestFTPGetFilesFromServer(t *testing.T) {
    misc.InitLogger(4) 
}

with InitLogger is located in another package

func InitSimpleLogger(level int) {
    if level == 1 {
        Trace = log.New(ioutil.Discard, "[TRACE]\t", log.Ldate|log.Ltime|log.Lshortfile)
        Info = log.New(ioutil.Discard, "[INFO]\t", log.Ldate|log.Ltime|log.Lshortfile)
        Warning = log.New(ioutil.Discard, "[WARNING]\t", log.Ldate|log.Ltime|log.Lshortfile)
        Error = log.New(os.Stdout, "[ERROR]\t", log.Ldate|log.Ltime|log.Lshortfile)
    } else if level == 2 {
        Trace = log.New(ioutil.Discard, "[TRACE]\t", log.Ldate|log.Ltime|log.Lshortfile)
        Info = log.New(ioutil.Discard, "[INFO]\t", log.Ldate|log.Ltime|log.Lshortfile)
        Warning = log.New(os.Stdout, "[WARNING]\t", log.Ldate|log.Ltime|log.Lshortfile)
        Error = log.New(os.Stdout, "[ERROR]\t", log.Ldate|log.Ltime|log.Lshortfile)
    } else if level == 3 {
        Trace = log.New(os.Stdout, "[TRACE]\t", log.Ldate|log.Ltime|log.Lshortfile)
        Info = log.New(ioutil.Discard, "[INFO]\t", log.Ldate|log.Ltime|log.Lshortfile)
        Warning = log.New(os.Stdout, "[WARNING]\t", log.Ldate|log.Ltime|log.Lshortfile)
        Error = log.New(os.Stdout, "[ERROR]\t", log.Ldate|log.Ltime|log.Lshortfile)
    } else {
        Trace = log.New(os.Stdout, "[TRACE]\t", log.Ldate|log.Ltime|log.Lshortfile)
        Info = log.New(os.Stdout, "[INFO]\t", log.Ldate|log.Ltime|log.Lshortfile)
        Warning = log.New(os.Stdout, "[WARNING]\t", log.Ldate|log.Ltime|log.Lshortfile)
        Error = log.New(os.Stdout, "[ERROR]\t", log.Ldate|log.Ltime|log.Lshortfile)
    }
}

编辑:

我有:

ftph := ftp_handler.NewFTPHandler()
ftp, err = ftph.connect()

使用 NewFTPHandler()

func NewFTPHandler() *FTPHandler {
    return &FTPHandler{
        Addr:     os.Getenv("FTP_ADDR"),
        username: os.Getenv("FTP_USER"),
        password: os.Getenv("FTP_PASSWD"),
        key:      os.Getenv("FTP_SGEKEY"),
        iv:       os.Getenv("FTP_SGEIV"),
        Port:     os.Getenv("FTP_PORT"),
    }
}

并调用connect():

func (fh *FTPHandler) connect() (*goftp.FTP, error) {
    var err error
    var ftp *goftp.FTP
    if ftp, err = goftp.Connect(fh.Addr + ":" + fh.Port); err != nil {
        misc.Error.Println("Cannot reach the FTP server", fh.Addr, "with port", fh.Port, "\t:", err)
        return nil, err
    }
    if err = ftp.Login(fh.username, fh.password); err != nil {
        misc.Error.Println("Bad credential for the FTP server", fh.Addr, "with port", fh.Port, "\t:", err)
        return nil, err
    }
    return ftp, nil
}

当我在 gitlab-ci 中运行测试时,行:

misc.InitLogger(4) 

运行时失败

--- FAIL: TestFTPConnect (0.00s)
panic: runtime error: invalid memory address or nil pointer dereference [recovered]
    panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x0 pc=0x5ef467]

goroutine 5 [running]:
testing.tRunner.func1(0xc0000ea100)
    /usr/local/go/src/testing/testing.go:792 +0x387
panic(0x6af2a0, 0x9205a0)
    /usr/local/go/src/runtime/panic.go:513 +0x1b9
log.(*Logger).Output(0x0, 0x2, 0xc00004e0e0, 0x63, 0x0, 0x0)
    /usr/local/go/src/log/log.go:153 +0x47
log.(*Logger).Println(0x0, 0xc0000f9ef8, 0x6, 0x6)
    /usr/local/go/src/log/log.go:188 +0x6a
gitlab.com/ColinBois/pamela/ftp_handler.(*FTPHandler).connect(0xc000050480, 0xc00002c798, 0x4766a6, 0x5c52ff3a)
    /root/go/src/gitlab.com/ColinBois/pamela/ftp_handler/ftpHandler.go:45 +0x1f3
gitlab.com/ColinBois/pamela/ftp_handler.TestFTPConnect(0xc0000ea100)
    /root/go/src/gitlab.com/ColinBois/pamela/ftp_handler/ftpHandler_test.go:20 +0x27
testing.tRunner(0xc0000ea100, 0x717140)
    /usr/local/go/src/testing/testing.go:827 +0xbf
created by testing.(*T).Run

这是我的 gitlab-ci.yml

test:
  image: docker:18
  services:
    - docker:dind
  stage: test
  before_script:
    - touch test.env
    - apk update
    - apk upgrade
    - apk add --no-cache py-pip
    - pip install docker-compose
    - docker network create mygoapp_network
    - mkdir -p volume/log

  script:
    - docker-compose -f docker-local.yaml up --build -d
    - docker exec mygoapp go test ./... -v

【问题讨论】:

  • (*FTPHandler).connect 正在调用 nil 记录器上的方法。显示该代码。
  • 已编辑!这是你需要的代码吗?
  • 我觉得现在可以了:)
  • 测试是否依赖TestFTPGetFilesFromServer来初始化misc.Error?如果是这样,测试对它们的运行顺序很敏感。
  • misc.Error 由 misc.InitSimpleLogger(4) 初始化 - 在应用程序中,它在 main.go 中初始化一次

标签: docker go docker-compose gitlab-ci


【解决方案1】:

测试不能确保misc.InitSimpleLogger(4) 在依赖此函数调用副作用的测试之前执行。将调用移至 init() 函数以确保它在测试之前执行。改变

func TestFTPGetFilesFromServer(t *testing.T) {
    misc.InitLogger(4) 
}

func init() {
    misc.InitLogger(4) 
}

【讨论】:

    猜你喜欢
    • 2021-08-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-06-29
    • 2020-10-26
    • 2018-07-05
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多