-
Notifications
You must be signed in to change notification settings - Fork 58
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
This is an alternative to #1596, trying to keep the test code more idiomatic, cleaner, and easier to use correctly. Add e2e/test.T type, embedding the standard library *testing.T, and keeping a logger. This type overrides testing.T methods logging to the standard library logger with methods logging to the specific logger. The Fatal[f] and Error[]f methods log an ERROR messages to make errors easy to find. To use the our T type, a test need to wrap the standard library *testing.T with the per-test logger: func TestFoo(dt *testing.T) { t := e2etesting.WithLog(dt, ctx.Logger()) Now we can use t transparently in this test: t.Log("This logs an INFO message to our logger") Note that the wrapped Error() and Fatal() method accept an error and will log a stracktrace: if err := ...; err != nil { // Log an error with a stracktrace and mark the test as failed. t.Error(err, "Failed, trying next step") } if err := ...; err != nil { // Log an error with a stracktrace and fail the test immediately. t.Fatal(err, "Failed, cannot continue") } Example error log (wrapped for readability): 2024-11-29T03:12:32.837+0200 ERROR subscr-deploy-rbd-busybox test/testing.go:55 Failed to failover workload: fake error in waitAndUpdateDRPC: failover to cluster "dr1" github.com/ramendr/ramen/e2e/test.(*T).Fatalf /Users/nsoffer/src/ramen/e2e/test/testing.go:55 github.com/ramendr/ramen/e2e/test.(*Context).Failover /Users/nsoffer/src/ramen/e2e/test/context.go:102 testing.tRunner /opt/homebrew/Cellar/go/1.23.3/libexec/src/testing/testing.go:1690 Notes: - All the test functions were updated to accept a `*testing.T` and wrap it with per-test log. Test helper functions accept now a `*e2e/test.T` so they don't need extra wrapping. - Sub tests requires wrapping the standard library t again, since testing.T is a type, not an interface. This adds one line of boilerplate for every sub test. - All Error[f] and Fatal[f] calls changed to format an error message with the underlying error so we should get more helpful error messages when something fails deep in the utility functions. - When DR sub test (e.g. Deploy) fails, we already logged the error by failing the sub test, so we call FailNow() in the parent test to abort the parent test silently. Issues: - The stracktrace does not include all callers leading the point the error was created, since fmt.Errorf() does not capture the stack. We can get better stacktrace by using another error package that does this like https://pkg.go.dev/github.com/go-errors/errors. - We need to disable the `thelper` linter in test.Context to allow using `dt *testing.T` and keep the test code idiomatic. Another way is to keep `t *testing.T`, and use `et` for the wrapped t. This makes the test code less idiomatic but it may be more clear that this is a non standard `t`. Fixes: #1595 Signed-off-by: Nir Soffer <[email protected]>
- Loading branch information
Showing
5 changed files
with
122 additions
and
33 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,69 @@ | ||
// SPDX-FileCopyrightText: The RamenDR authors | ||
// SPDX-License-Identifier: Apache-2.0 | ||
|
||
package test | ||
|
||
import ( | ||
"fmt" | ||
"testing" | ||
|
||
"github.com/go-logr/logr" | ||
) | ||
|
||
// T extends testing.T to use a custom logger. | ||
type T struct { | ||
*testing.T | ||
log logr.Logger | ||
} | ||
|
||
// WithLog returns a t wrapped with a specified log. | ||
// nolint: thelper | ||
func WithLog(t *testing.T, log logr.Logger) *T { | ||
return &T{T: t, log: log} | ||
} | ||
|
||
// Log writes a message to the log. | ||
func (t *T) Log(msg string) { | ||
t.log.Info(msg) | ||
} | ||
|
||
// Log writes a formatted message to the log. | ||
func (t *T) Logf(format string, args ...any) { | ||
t.log.Info(fmt.Sprintf(format, args...)) | ||
} | ||
|
||
// Error writes an error message to the log and mark the test as failed. | ||
func (t *T) Error(msg string) { | ||
t.log.Error(nil, msg) | ||
t.T.Fail() | ||
} | ||
|
||
// Errorf writes a formatted error message to the log and markd the test as failed. | ||
func (t *T) Errorf(format string, args ...any) { | ||
t.log.Error(nil, fmt.Sprintf(format, args...)) | ||
t.T.Fail() | ||
} | ||
|
||
// Fatal writes an error message to the log and fail the text immediately. | ||
func (t *T) Fatal(msg string) { | ||
t.log.Error(nil, msg) | ||
t.T.FailNow() | ||
} | ||
|
||
// Fatalf writes a formatted error message to the log and fail the text immediately. | ||
func (t *T) Fatalf(format string, args ...any) { | ||
t.log.Error(nil, fmt.Sprintf(format, args...)) | ||
t.T.FailNow() | ||
} | ||
|
||
// Skip is equivalent to Log followed by SkipNow. | ||
func (t *T) Skip(msg string) { | ||
t.log.Info(msg) | ||
t.T.SkipNow() | ||
} | ||
|
||
// Skipf is equivalent to Logf followed by SkipNow. | ||
func (t *T) Skipf(format string, args ...any) { | ||
t.log.Info(fmt.Sprintf(format, args...)) | ||
t.T.SkipNow() | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters