stretchr / testify

A toolkit with common assertions and mocks that plays nicely with the standard library
MIT License
22.52k stars 1.56k forks source link

`suite.Require` deadlock #1520

Closed vitalyisaev2 closed 4 months ago

vitalyisaev2 commented 6 months ago

If require object hasn't been initialized before calling suite.Require method, it will be created on the base of *testing.T returned from suite.T() (code):

// Require returns a require context for suite.
func (suite *Suite) Require() *require.Assertions {
    suite.mu.Lock()
    defer suite.mu.Unlock()
    if suite.require == nil {
        suite.require = require.New(suite.T())
    }
    return suite.require
}

This will result in a deadlock because suite.T() wants to acquire the lock that has been already acquired:

// T retrieves the current *testing.T context.
func (suite *Suite) T() *testing.T {
    suite.mu.RLock()
    defer suite.mu.RUnlock()
    return suite.t
}
arjunmahishi commented 4 months ago

Thanks for reporting this @vitalyisaev2!

I've put up a PR for fixing this. If you have any thoughts about the approach, please comment on #1535