测试 – 如何在golang中测试并发和锁定?
我们正在尝试测试锁.基本上,有多个客户端试图获取特定密钥的锁定.在下面的示例中,我们使用了键“x”.
我不知道如何测试锁定是否正常.我只能读取日志以确定它是否正常工作. 正确的事件顺序应该是: > client1获取密钥“x”的锁定 Q1:我如何自动化流程并将其转变为测试? Q2:一般来说测试并发/互斥锁定的一些技巧是什么? func TestLockUnlock(t *testing.T) { client1,err := NewClient() if err != nil { t.Error("Unexpected new client error: ",err) } fmt.Println("1 getting lock") id1,err := client1.Lock("x",10*time.Second) if err != nil { t.Error("Unexpected lock error: ",err) } fmt.Println("1 got lock") go func() { client2,err := NewClient() if err != nil { t.Error("Unexpected new client error: ",err) } fmt.Println("2 getting lock") id2,err := client2.Lock("x",10*time.Second) if err != nil { t.Error("Unexpected lock error: ",err) } fmt.Println("2 got lock") fmt.Println("2 releasing lock") err = client2.Unlock("x",id2) if err != nil { t.Error("Unexpected Unlock error: ",err) } fmt.Println("2 released lock") err = client2.Close() if err != nil { t.Error("Unexpected connection close error: ",err) } }() fmt.Println("sleeping") time.Sleep(2 * time.Second) fmt.Println("finished sleeping") fmt.Println("1 releasing lock") err = client1.Unlock("x",id1) if err != nil { t.Error("Unexpected Unlock error: ",err) } fmt.Println("1 released lock") err = client1.Close() if err != nil { t.Error("Unexpected connection close error: ",err) } time.Sleep(5 * time.Second) } func NewClient() *Client { .... } func (c *Client) Lock(lockKey string,timeout time.Duration) (lockId int64,err error){ .... } func (c *Client) Unlock(lockKey string) err error { .... } 解决方法
基于锁的代码的并发测试很难,因为很难得到可证明正确的解决方案.通过打印报表进行的临时手动测试并不理想.
有四个动态并发问题基本上是不可测试的(more).除了性能测试之外,统计方法是通过测试代码可以实现的最佳方法(例如,确定90%的性能优于10ms或者死锁可能小于1%). 这是Go提供的通信顺序进程(CSP)方法比共享内存锁更好使用的原因之一.考虑您的Goroutine正在测试中提供具有指定行为的单位.这可以针对其他Goroutines进行测试,这些Goroutine通过通道提供必要的测试输入,并通过通道监控结果输出. 使用CSP,使用没有任何共享内存的Goroutines(并且没有任何无意中通过指针共享的内存)将保证在任何数据访问中都不会出现竞争条件.使用某些经过验证的设计模式(例如,到Welch,Justo and WIllcock)可以确定Goroutines之间不会出现僵局.然后,仍然需要确定功能行为是正确的,上面提到的Goroutine测试装置可以很好地完成. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |