加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 大数据 > 正文

测试 – 如何在golang中测试并发和锁定?

发布时间:2020-12-16 09:27:40 所属栏目:大数据 来源:网络整理
导读:我们正在尝试测试锁.基本上,有多个客户端试图获取特定密钥的锁定.在下面的示例中,我们使用了键“x”. 我不知道如何测试锁定是否正常.我只能读取日志以确定它是否正常工作. 正确的事件顺序应该是: client1获取密钥“x”的锁定 client2尝试获取密钥“x”(fmt.
我们正在尝试测试锁.基本上,有多个客户端试图获取特定密钥的锁定.在下面的示例中,我们使用了键“x”.

我不知道如何测试锁定是否正常.我只能读取日志以确定它是否正常工作.

正确的事件顺序应该是:

> client1获取密钥“x”的锁定
> client2尝试获取密钥“x”(fmt.Println(“2获取锁定”))的锁定 – 但被阻止并等待
> client1释放锁定键“x”
> client2获取密钥“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测试装置可以很好地完成.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读