Почему тест Go с заблокированным каналом не сообщает о тупике
Я столкнулся со странной проблемой при тестировании каналов.
В нормальной функции main следующий код сообщит об ошибке взаимоблокировки.
package main
import (
"fmt"
)
func main() {
c := make(chan int)
c <- 1
fmt.Println(<-c)
}
Но на моей машине этот простой тест кажется заблокированным или заблокированным навсегда, или просто не удается завершить работу по неизвестной мне причине. Я вызвал тест и в Emacs, и в терминале, и получил тот же результат. Командаgo test -run TestChan\$ . -v -count=1
. Я пробовал более простой командой (go test -run TestChan
), но результат тот же. Я попробовал его на игровой площадке Go (здесь), и он сообщил об ошибке взаимоблокировки. Что-то не так с моей средой Go?
package main
import (
"fmt"
"testing"
)
func TestChan(t *testing.T) {
c := make(chan int)
c <- 1
fmt.Println(<-c)
}
-------------------------------------------------- --------------------------------------------------
Обновить
Похоже, я не уточнил свой вопрос. Ситуация такова: один и тот же тест по-разному ведет себя на моей машине и на игровой площадке Go. Теперь я установил-timeout 5s
, но сообщение об ошибке отличается от сообщения на игровой площадке Go. Еще одна вещь, которую я нашел отличной от моего локального, заключается в том, что тестовый бегун отличается от моего локального. Это под пакетомgo-faketime
.
локальный выход
$ go test main_test.go -timeout 5s
panic: test timed out after 5s
goroutine 17 [running]:
testing.(*M).startAlarm.func1()
/usr/local/go/src/testing/testing.go:1460 +0xdf
created by time.goFunc
/usr/local/go/src/time/sleep.go:168 +0x44
goroutine 1 [chan receive]:
testing.(*T).Run(0xc000108120, 0x1141975, 0x8, 0x114a528, 0x1075a96)
/usr/local/go/src/testing/testing.go:1044 +0x37e
testing.runTests.func1(0xc000108000)
/usr/local/go/src/testing/testing.go:1285 +0x78
testing.tRunner(0xc000108000, 0xc000066e10)
/usr/local/go/src/testing/testing.go:992 +0xdc
testing.runTests(0xc00000c060, 0x1236220, 0x1, 0x1, 0x0)
/usr/local/go/src/testing/testing.go:1283 +0x2a7
testing.(*M).Run(0xc000106000, 0x0)
/usr/local/go/src/testing/testing.go:1200 +0x15f
main.main()
_testmain.go:44 +0x135
goroutine 6 [chan send]:
command-line-arguments.TestChan(0xc000108120)
/Users/james/prog/allez/mtest/main_test.go:10 +0x59
testing.tRunner(0xc000108120, 0x114a528)
/usr/local/go/src/testing/testing.go:992 +0xdc
created by testing.(*T).Run
/usr/local/go/src/testing/testing.go:1043 +0x357
FAIL command-line-arguments 5.013s
FAIL
Выход на игровую площадку
=== RUN TestChan
fatal error: all goroutines are asleep - deadlock!
goroutine 1 [chan receive]:
testing.(*T).Run(0xc00011a120, 0x4f71c0, 0x8, 0x4ff688, 0x498336)
/usr/local/go-faketime/src/testing/testing.go:1043 +0x37e
testing.runTests.func1(0xc00011a000)
/usr/local/go-faketime/src/testing/testing.go:1284 +0x78
testing.tRunner(0xc00011a000, 0xc000066df8)
/usr/local/go-faketime/src/testing/testing.go:991 +0xdc
testing.runTests(0xc00010c040, 0xc00010c020, 0x1, 0x1, 0x0)
/usr/local/go-faketime/src/testing/testing.go:1282 +0x2a7
testing.(*M).Run(0xc000118000, 0x0)
/usr/local/go-faketime/src/testing/testing.go:1199 +0x15f
testing.Main(0x4ff690, 0xc00010c020, 0x1, 0x1, 0x0, 0x0, 0x0, 0x5e8860, 0x0, 0x0)
/usr/local/go-faketime/src/testing/testing.go:1126 +0xd4
main.main()
/tmp/sandbox970213620/prog.go:24 +0x9c
goroutine 18 [chan send]:
main.TestChan(0xc00011a120)
/tmp/sandbox970213620/prog.go:10 +0x59
testing.tRunner(0xc00011a120, 0x4ff688)
/usr/local/go-faketime/src/testing/testing.go:991 +0xdc
created by testing.(*T).Run
/usr/local/go-faketime/src/testing/testing.go:1042 +0x357
Мои вопросы
- Почему Go при тестировании заблокированного канала не сообщает о тупике?
- Если он работает как проект (потому что в это время работают другие горутины), то как тот же тест на игровой площадке Go выдает такое же сообщение об ошибке, как если бы код был запущен в основной функции? (этот вопрос отличается от домена канала Go и того, как Go Playground проводит тестирование)