Skip to content
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

e2e: add logfile for e2e tests #1775

Merged
merged 2 commits into from
Feb 2, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -53,3 +53,7 @@ ramenctl/build
# Generated disk images
*.qcow2
*.iso

# e2e generated files
/e2e/ramen-e2e
/e2e/ramen-e2e.log
6 changes: 2 additions & 4 deletions e2e/main_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ import (

"github.com/ramendr/ramen/e2e/test"
"github.com/ramendr/ramen/e2e/util"
"go.uber.org/zap"
)

func init() {
Expand All @@ -22,12 +21,11 @@ func TestMain(m *testing.M) {

flag.Parse()

logger, err := zap.NewDevelopment()
log, err := test.CreateLogger()
if err != nil {
panic(err)
}
parikshithb marked this conversation as resolved.
Show resolved Hide resolved

log := logger.Sugar()
// TODO: Sync the log on exit
Copy link
Member

Choose a reason for hiding this comment

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

It seems that the best way to handle the conflict between os.Exit() and defer is to call it only once in main() or in the case of tests, in TestMain(). This also means we cannot call any function that calls os.Exit() like log.Fatal().

We can do this like this:

func TestMain(m *testing.M) {
    os.Exit(run(m))
}

func run(m *testing.M) int {
    log := ...
    defer func() {
        _ = log.Sync()
    }()
    
    ...
    if err != nil {
        log.Errorf("error message... : %s", err)
        return 1
    }

    return m.Run()
}

With this we ensure that test failure or setup failure will return non-zero exit code, and defer function will run, and the code is very simple.

But lets no dalay this good change, we can improve this later.


util.Ctx, err = util.NewContext(log, util.ConfigFile)
if err != nil {
Expand Down
2 changes: 1 addition & 1 deletion e2e/run.sh
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,4 @@ set -o pipefail
go test -c -o ramen-e2e

# With an executable -test.timeout is disabled by default.
./ramen-e2e -test.v "$@" 2>&1 | tee ramen-e2e.log
./ramen-e2e -test.v "$@"
41 changes: 41 additions & 0 deletions e2e/test/log.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
// SPDX-FileCopyrightText: The RamenDR authors
// SPDX-License-Identifier: Apache-2.0

package test

import (
"os"

"go.uber.org/zap"
"go.uber.org/zap/zapcore"
)

const logFilePath = "ramen-e2e.log"

func CreateLogger() (*zap.SugaredLogger, error) {
// Console encoder config
consoleConfig := zap.NewProductionEncoderConfig()
consoleConfig.EncodeTime = zapcore.ISO8601TimeEncoder
consoleConfig.EncodeLevel = zapcore.CapitalLevelEncoder
consoleConfig.CallerKey = zapcore.OmitKey
consoleEncoder := zapcore.NewConsoleEncoder(consoleConfig)

// Logfile encoder config
logfileConfig := zap.NewProductionEncoderConfig()
logfileConfig.EncodeTime = zapcore.ISO8601TimeEncoder
logfileConfig.EncodeLevel = zapcore.CapitalLevelEncoder
logfileEncoder := zapcore.NewConsoleEncoder(logfileConfig)

logfile, err := os.Create(logFilePath)
if err != nil {
return nil, err
}

core := zapcore.NewTee(
zapcore.NewCore(logfileEncoder, zapcore.AddSync(logfile), zapcore.DebugLevel),
zapcore.NewCore(consoleEncoder, zapcore.AddSync(os.Stderr), zapcore.InfoLevel),
)
logger := zap.New(core).Sugar()

return logger, nil
}