Skip to content

grpctest: minor improvements to the test logger implementation #8370

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 22 commits into
base: master
Choose a base branch
from

Conversation

asheshvidyut
Copy link
Member

@asheshvidyut asheshvidyut commented May 30, 2025

Fixes: #7475

  • Unexport the test logger implementation which is currently a package global here:
    grpc-go/internal/grpctest/tlogger.go

  • Make the above package global accessed atomically from tests. We have had test failures because of data races in the past because of this.

  • Change receiver names in method of the tLogger type to be tl instead of g

RELEASE NOTES: N/A

Copy link

codecov bot commented May 30, 2025

Codecov Report

Attention: Patch coverage is 76.13636% with 21 lines in your changes missing coverage. Please review.

Project coverage is 82.41%. Comparing base (20bd1e7) to head (a4b8b96).

Files with missing lines Patch % Lines
internal/grpctest/tlogger.go 75.58% 19 Missing and 2 partials ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##           master    #8370      +/-   ##
==========================================
- Coverage   82.44%   82.41%   -0.04%     
==========================================
  Files         413      413              
  Lines       40424    40432       +8     
==========================================
- Hits        33328    33321       -7     
- Misses       5742     5754      +12     
- Partials     1354     1357       +3     
Files with missing lines Coverage Δ
internal/grpctest/grpctest.go 78.43% <100.00%> (ø)
internal/grpctest/tlogger.go 70.92% <75.58%> (-3.52%) ⬇️

... and 22 files with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@arjan-bal arjan-bal self-requested a review May 30, 2025 04:48
@arjan-bal arjan-bal self-assigned this May 30, 2025
@arjan-bal arjan-bal added the Type: Internal Cleanup Refactors, etc label May 30, 2025
@arjan-bal arjan-bal added this to the 1.74 Release milestone May 30, 2025
@arjan-bal arjan-bal changed the title Fixes - grpctest: minor improvements to the test logger implementation #7475 grpctest: minor improvements to the test logger implementation May 30, 2025
@arjan-bal arjan-bal added Type: Testing and removed Type: Internal Cleanup Refactors, etc labels May 30, 2025
// expected errors are declared in tests.
var TLogger *tLogger
var tLoggerAtomic atomic.Value
Copy link
Contributor

@arjan-bal arjan-bal Jun 3, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@easwars, the logger is mutated only once, in the init() function of this package. The race usually happens in the Update method (e.g: b/416700146#comment4) when it calls grpclog.SetLoggerV2:

func SetLoggerV2(l LoggerV2) {
if _, ok := l.(*componentData); ok {
panic("cannot use component logger as grpclog logger")
}
internal.LoggerV2Impl = l
internal.DepthLoggerV2Impl, _ = l.(internal.DepthLoggerV2)
}

Ideally Update should be called serially at the beginning of a test function. I've seen race conditions reported when a test doesn't wait for its goroutines to return before the test function exits. Using an atomic for LoggerV2Impl and DepthLoggerV2Impl might hide those errors and make it appear as though the next test has logged something. Do you think we should really change this to use an atomic?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Talked to @easwars and he mentioned that we can revert the changes to make the logger an atomic.

@arjan-bal arjan-bal assigned easwars and asheshvidyut and unassigned arjan-bal Jun 3, 2025
@arjan-bal arjan-bal requested a review from easwars June 3, 2025 05:32
Copy link
Contributor

@arjan-bal arjan-bal left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, pending the removal of the atomic. Over to Easwar for the second review.

@asheshvidyut asheshvidyut removed their assignment Jun 19, 2025
Copy link
Contributor

@easwars easwars left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, modulo minor nits

Comment on lines 83 to 85
func getLogger() *tLogger {
return tLogr
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we really need this function?

Comment on lines 76 to 80
tLogr = &tLogger{errors: map[*regexp.Regexp]int{}}
vLevel := os.Getenv("GRPC_GO_LOG_VERBOSITY_LEVEL")
if vl, err := strconv.Atoi(vLevel); err == nil {
TLogger.v = vl
tLogr.v = vl
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

While you are here, you could reorder this such that we read the env var first, and then initialize the tLogger. That way, you could directly set the v field using the literal struct initialization syntax.

Also, you could use os.LookupEnv instead of os.GetEnv to distinguish between an empty value and an unset value.

@@ -53,7 +53,7 @@ type Tester struct{}

// Setup updates the tlogger.
func (Tester) Setup(t *testing.T) {
TLogger.Update(t)
tLogr.Update(t)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

While you are here, could we unexport the Update and EndTest methods on tLogger?

Copy link
Contributor

@easwars easwars left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, modulo minor nits

@easwars easwars assigned asheshvidyut and unassigned easwars Jun 23, 2025
vLevel = val
} else {
// Log the error if the environment variable is not a valid integer.
fmt.Printf("Warning: GRPC_GO_LOG_VERBOSITY_LEVEL environment variable '%s' is not a valid integer. "+
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@arjan-bal is it fine if we print this message?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

grpctest: minor improvements to the test logger implementation
4 participants