fix_: create request logger ad-hoc in tests

Fixes `TestCall` failing when run concurrently.
This commit is contained in:
Patryk Osmaczko 2024-10-29 13:30:14 +01:00 committed by osmaczko
parent 9d41652a2d
commit 9240222fbe
6 changed files with 79 additions and 61 deletions

View File

@ -14,23 +14,14 @@ var (
requestLogger *zap.Logger requestLogger *zap.Logger
) )
// IsRequestLoggingEnabled returns whether RPC logging is enabled
func IsRequestLoggingEnabled() bool {
return requestLogger != nil
}
// GetRequestLogger returns the RPC logger object // GetRequestLogger returns the RPC logger object
func GetRequestLogger() *zap.Logger { func GetRequestLogger() *zap.Logger {
return requestLogger return requestLogger
} }
func ConfigureAndEnableRequestLogging(file string) error { func CreateRequestLogger(file string) (*zap.Logger, error) {
if len(file) == 0 { if len(file) == 0 {
return errors.New("file is required") return nil, errors.New("file is required")
}
if IsRequestLoggingEnabled() {
return errors.New("request logging is already enabled")
} }
fileOpts := logutils.FileOptions{ fileOpts := logutils.FileOptions{
@ -44,7 +35,16 @@ func ConfigureAndEnableRequestLogging(file string) error {
zap.DebugLevel, zap.DebugLevel,
) )
requestLogger = zap.New(core).Named("RequestLogger") return zap.New(core).Named("RequestLogger"), nil
}
func ConfigureAndEnableRequestLogging(file string) error {
logger, err := CreateRequestLogger(file)
if err != nil {
return err
}
requestLogger = logger
return nil return nil
} }

View File

@ -1,4 +1,4 @@
package statusgo package callog
import ( import (
"fmt" "fmt"
@ -11,7 +11,6 @@ import (
"go.uber.org/zap" "go.uber.org/zap"
"github.com/status-im/status-go/logutils" "github.com/status-im/status-go/logutils"
"github.com/status-im/status-go/logutils/requestlog"
) )
var sensitiveKeys = []string{ var sensitiveKeys = []string{
@ -47,7 +46,7 @@ func getShortFunctionName(fn any) string {
return parts[len(parts)-1] return parts[len(parts)-1]
} }
// call executes the given function and logs request details if logging is enabled // Call executes the given function and logs request details if logging is enabled
// //
// Parameters: // Parameters:
// - fn: The function to be executed // - fn: The function to be executed
@ -59,10 +58,10 @@ func getShortFunctionName(fn any) string {
// Functionality: // Functionality:
// 1. Sets up panic recovery to log and re-panic // 1. Sets up panic recovery to log and re-panic
// 2. Records start time if request logging is enabled // 2. Records start time if request logging is enabled
// 3. Uses reflection to call the given function // 3. Uses reflection to Call the given function
// 4. If request logging is enabled, logs method name, parameters, response, and execution duration // 4. If request logging is enabled, logs method name, parameters, response, and execution duration
// 5. Removes sensitive information before logging // 5. Removes sensitive information before logging
func call(fn any, params ...any) any { func Call(logger *zap.Logger, fn any, params ...any) any {
defer func() { defer func() {
if r := recover(); r != nil { if r := recover(); r != nil {
logutils.ZapLogger().Error("panic found in call", zap.Any("error", r), zap.Stack("stacktrace")) logutils.ZapLogger().Error("panic found in call", zap.Any("error", r), zap.Stack("stacktrace"))
@ -72,7 +71,7 @@ func call(fn any, params ...any) any {
var startTime time.Time var startTime time.Time
requestLoggingEnabled := requestlog.IsRequestLoggingEnabled() requestLoggingEnabled := logger != nil
if requestLoggingEnabled { if requestLoggingEnabled {
startTime = time.Now() startTime = time.Now()
} }
@ -102,7 +101,7 @@ func call(fn any, params ...any) any {
paramsString := removeSensitiveInfo(fmt.Sprintf("%+v", params)) paramsString := removeSensitiveInfo(fmt.Sprintf("%+v", params))
respString := removeSensitiveInfo(fmt.Sprintf("%+v", resp)) respString := removeSensitiveInfo(fmt.Sprintf("%+v", resp))
requestlog.GetRequestLogger().Debug("call", logger.Debug("call",
zap.String("method", methodName), zap.String("method", methodName),
zap.String("params", paramsString), zap.String("params", paramsString),
zap.String("resp", respString), zap.String("resp", respString),
@ -113,8 +112,8 @@ func call(fn any, params ...any) any {
return resp return resp
} }
func callWithResponse(fn any, params ...any) string { func CallWithResponse(logger *zap.Logger, fn any, params ...any) string {
resp := call(fn, params...) resp := Call(logger, fn, params...)
if resp == nil { if resp == nil {
return "" return ""
} }

View File

@ -1,7 +1,6 @@
package statusgo package callog
import ( import (
"encoding/json"
"fmt" "fmt"
"os" "os"
"strings" "strings"
@ -12,9 +11,6 @@ import (
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
"github.com/status-im/status-go/logutils/requestlog" "github.com/status-im/status-go/logutils/requestlog"
"github.com/status-im/status-go/multiaccounts"
"github.com/status-im/status-go/multiaccounts/settings"
"github.com/status-im/status-go/signal"
) )
func TestRemoveSensitiveInfo(t *testing.T) { func TestRemoveSensitiveInfo(t *testing.T) {
@ -66,11 +62,8 @@ func TestCall(t *testing.T) {
require.NoError(t, err) require.NoError(t, err)
// Enable request logging // Enable request logging
err = requestlog.ConfigureAndEnableRequestLogging(tempLogFile.Name()) logger, err := requestlog.CreateRequestLogger(tempLogFile.Name())
require.NoError(t, err) require.NoError(t, err)
// Logger must not be nil after enabling
logger := requestlog.GetRequestLogger()
require.NotNil(t, logger) require.NotNil(t, logger)
// Test case 1: Normal execution // Test case 1: Normal execution
@ -80,7 +73,7 @@ func TestCall(t *testing.T) {
testParam := "test input" testParam := "test input"
expectedResult := "test result: test input" expectedResult := "test result: test input"
result := callWithResponse(testFunc, testParam) result := CallWithResponse(logger, testFunc, testParam)
// Check the result // Check the result
if result != expectedResult { if result != expectedResult {
@ -120,7 +113,7 @@ func TestCall(t *testing.T) {
} }
require.PanicsWithValue(t, e, func() { require.PanicsWithValue(t, e, func() {
call(panicFunc) Call(logger, panicFunc)
}) })
// Check if the panic was logged // Check if the panic was logged
@ -135,35 +128,11 @@ func TestCall(t *testing.T) {
} }
} }
func initializeApplication(requestJSON string) string {
return ""
}
func TestGetFunctionName(t *testing.T) { func TestGetFunctionName(t *testing.T) {
fn := getShortFunctionName(initializeApplication) fn := getShortFunctionName(initializeApplication)
require.Equal(t, "initializeApplication", fn) require.Equal(t, "initializeApplication", fn)
} }
type testSignalHandler struct {
receivedSignal string
}
func (t *testSignalHandler) HandleSignal(data string) {
t.receivedSignal = data
}
func TestSetMobileSignalHandler(t *testing.T) {
// Setup
handler := &testSignalHandler{}
SetMobileSignalHandler(handler)
t.Cleanup(signal.ResetMobileSignalHandler)
// Test data
testAccount := &multiaccounts.Account{Name: "test"}
testSettings := &settings.Settings{KeyUID: "0x1"}
testEnsUsernames := json.RawMessage(`{"test": "test"}`)
// Action
signal.SendLoggedIn(testAccount, testSettings, testEnsUsernames, nil)
// Assertions
require.Contains(t, handler.receivedSignal, `"key-uid":"0x1"`, "Signal should contain the correct KeyUID")
require.Contains(t, handler.receivedSignal, `"name":"test"`, "Signal should contain the correct account name")
require.Contains(t, handler.receivedSignal, `"ensUsernames":{"test":"test"}`, "Signal should contain the correct ENS usernames")
}

View File

@ -22,7 +22,7 @@ func TestInitLogging(t *testing.T) {
require.Equal(t, `{"error":""}`, response) require.Equal(t, `{"error":""}`, response)
_, err := os.Stat(gethLogFile) _, err := os.Stat(gethLogFile)
require.NoError(t, err) require.NoError(t, err)
require.True(t, requestlog.IsRequestLoggingEnabled()) require.NotNil(t, requestlog.GetRequestLogger())
// requests log file should not be created yet // requests log file should not be created yet
_, err = os.Stat(requestsLogFile) _, err = os.Stat(requestsLogFile)

View File

@ -47,8 +47,18 @@ import (
"github.com/status-im/status-go/services/typeddata" "github.com/status-im/status-go/services/typeddata"
"github.com/status-im/status-go/signal" "github.com/status-im/status-go/signal"
"github.com/status-im/status-go/transactions" "github.com/status-im/status-go/transactions"
"github.com/status-im/status-go/mobile/callog"
) )
func call(fn any, params ...any) any {
return callog.Call(requestlog.GetRequestLogger(), fn, params...)
}
func callWithResponse(fn any, params ...any) string {
return callog.CallWithResponse(requestlog.GetRequestLogger(), fn, params...)
}
type InitializeApplicationResponse struct { type InitializeApplicationResponse struct {
Accounts []multiaccounts.Account `json:"accounts"` Accounts []multiaccounts.Account `json:"accounts"`
CentralizedMetricsInfo *centralizedmetrics.MetricsInfo `json:"centralizedMetricsInfo"` CentralizedMetricsInfo *centralizedmetrics.MetricsInfo `json:"centralizedMetricsInfo"`

40
mobile/status_test.go Normal file
View File

@ -0,0 +1,40 @@
package statusgo
import (
"encoding/json"
"testing"
"github.com/stretchr/testify/require"
"github.com/status-im/status-go/multiaccounts"
"github.com/status-im/status-go/multiaccounts/settings"
"github.com/status-im/status-go/signal"
)
type testSignalHandler struct {
receivedSignal string
}
func (t *testSignalHandler) HandleSignal(data string) {
t.receivedSignal = data
}
func TestSetMobileSignalHandler(t *testing.T) {
// Setup
handler := &testSignalHandler{}
SetMobileSignalHandler(handler)
t.Cleanup(signal.ResetMobileSignalHandler)
// Test data
testAccount := &multiaccounts.Account{Name: "test"}
testSettings := &settings.Settings{KeyUID: "0x1"}
testEnsUsernames := json.RawMessage(`{"test": "test"}`)
// Action
signal.SendLoggedIn(testAccount, testSettings, testEnsUsernames, nil)
// Assertions
require.Contains(t, handler.receivedSignal, `"key-uid":"0x1"`, "Signal should contain the correct KeyUID")
require.Contains(t, handler.receivedSignal, `"name":"test"`, "Signal should contain the correct account name")
require.Contains(t, handler.receivedSignal, `"ensUsernames":{"test":"test"}`, "Signal should contain the correct ENS usernames")
}