From c41592ba5fb28876af3ac0ed2cb6fce31767c53b Mon Sep 17 00:00:00 2001 From: Arjun Mahishi Date: Sat, 17 Feb 2024 01:12:25 +0530 Subject: [PATCH] suite: fix deadlock in suite.Require()/Assert() As pointed out in issue #1520, if the suite is not initialised properly (buy calling the Run function), then calling suite.Require() or suite.Assert() will result in a deadlock. This commit fixes that by panicking if the suite is not initialised properly. This is justified because, the suite is intended to be triggered in the right way. If the user does not do that, this panic will nudge them in the right direction. It has to be a panic because, at this point, we don't have access to any testing.T context to gracefully call a t.Fail(). Also, these two functions are not expected to return an error. Fixes #1520 --- suite/suite.go | 4 ++-- suite/suite_test.go | 24 ++++++++++++++++++++++++ 2 files changed, 26 insertions(+), 2 deletions(-) diff --git a/suite/suite.go b/suite/suite.go index eac6909b4..18443a91c 100644 --- a/suite/suite.go +++ b/suite/suite.go @@ -58,7 +58,7 @@ func (suite *Suite) Require() *require.Assertions { suite.mu.Lock() defer suite.mu.Unlock() if suite.require == nil { - suite.require = require.New(suite.T()) + panic("'Require' must not be called before 'Run' or 'SetT'") } return suite.require } @@ -72,7 +72,7 @@ func (suite *Suite) Assert() *assert.Assertions { suite.mu.Lock() defer suite.mu.Unlock() if suite.Assertions == nil { - suite.Assertions = assert.New(suite.T()) + panic("'Assert' must not be called before 'Run' or 'SetT'") } return suite.Assertions } diff --git a/suite/suite_test.go b/suite/suite_test.go index 292dc298c..b31eb3596 100644 --- a/suite/suite_test.go +++ b/suite/suite_test.go @@ -692,3 +692,27 @@ func TestSubtestPanic(t *testing.T) { assert.True(t, suite.inTearDownTest) assert.True(t, suite.inTearDownSuite) } + +type unInitialisedSuite struct { + Suite +} + +// TestUnInitialisedSuites asserts the behaviour of the suite methods when the +// suite is not initialised +func TestUnInitialisedSuites(t *testing.T) { + t.Run("should panic on Require", func(t *testing.T) { + suite := new(unInitialisedSuite) + + assert.Panics(t, func() { + suite.Require().True(true) + }) + }) + + t.Run("should panic on Assert", func(t *testing.T) { + suite := new(unInitialisedSuite) + + assert.Panics(t, func() { + suite.Assert().True(true) + }) + }) +}