From 766c3e306617cd827cc62e87c74123b933f0e4cb Mon Sep 17 00:00:00 2001 From: Rachit Sonthalia <54906134+rachit77@users.noreply.github.com> Date: Tue, 24 Sep 2024 18:30:15 +0530 Subject: [PATCH] Rachit77/tests (#137) * wip * wip * change permission * wip * wip * wip * lint fix --- datastreamer/datastreamer_test.go | 18 +++++- datastreamer/streambookmark_test.go | 72 +++++++++++++++++++++++ datastreamer/streamfile_test.go | 56 ++++++++++++++++++ datastreamer/streamserver_test.go | 40 +++++++++++++ go.mod | 1 + go.sum | 2 + log/log_test.go | 89 +++++++++++++++++++++++++++++ relay/relay_test.go | 70 +++++++++++++++++++++++ 8 files changed, 347 insertions(+), 1 deletion(-) create mode 100644 datastreamer/streambookmark_test.go create mode 100644 datastreamer/streamfile_test.go create mode 100644 datastreamer/streamserver_test.go create mode 100644 relay/relay_test.go diff --git a/datastreamer/datastreamer_test.go b/datastreamer/datastreamer_test.go index 9239896..4f2cb1a 100644 --- a/datastreamer/datastreamer_test.go +++ b/datastreamer/datastreamer_test.go @@ -240,8 +240,20 @@ func TestServer(t *testing.T) { require.NoError(t, err) require.Equal(t, uint64(3), entryNumber) + // Case: Start atomic operation with atomic operation in progress -> FAIL + _ = streamServer.StartAtomicOp() + err = streamServer.StartAtomicOp() + _ = streamServer.CommitAtomicOp() + require.EqualError(t, datastreamer.ErrStartAtomicOpNotAllowed, err.Error()) + + // Case: Commit atomic operation without starting atomic operation -> FAIL err = streamServer.CommitAtomicOp() - require.NoError(t, err) + require.EqualError(t, datastreamer.ErrCommitNotAllowed, err.Error()) + + // Case: AddStreamBookmark without atomic operation in progress -> FAIL + entryNumber, err = streamServer.AddStreamBookmark(testBookmark.Encode()) + require.Equal(t, uint64(0), entryNumber) + require.EqualError(t, datastreamer.ErrAddEntryNotAllowed, err.Error()) // Check get data between 2 bookmarks data, err := streamServer.GetDataBetweenBookmarks(testBookmark.Encode(), testBookmark2.Encode()) @@ -356,6 +368,10 @@ func TestServer(t *testing.T) { err = streamServer.RollbackAtomicOp() require.NoError(t, err) + // Case: Rollback operation without starting atomic operation -> FAIL + err = streamServer.RollbackAtomicOp() + require.EqualError(t, datastreamer.ErrRollbackNotAllowed, err.Error()) + // Case: Get entry data of previous rollback entry number (doesn't exist) -> FAIL entry, err = streamServer.GetEntry(7) require.EqualError(t, datastreamer.ErrInvalidEntryNumber, err.Error()) diff --git a/datastreamer/streambookmark_test.go b/datastreamer/streambookmark_test.go new file mode 100644 index 0000000..f3dea11 --- /dev/null +++ b/datastreamer/streambookmark_test.go @@ -0,0 +1,72 @@ +package datastreamer + +import ( + "os" + "testing" + + "github.com/stretchr/testify/assert" +) + +func createTempDB(t *testing.T) *StreamBookmark { + t.Helper() + + tempFile := "test_bookmarks_db" + b, err := NewBookmark(tempFile) + if err != nil { + t.Fatalf("Failed to create bookmark: %v", err) + } + + return b +} + +func cleanUpDB(t *testing.T, b *StreamBookmark) { + t.Helper() + + err := b.db.Close() + if err != nil { + t.Fatalf("Failed to close bookmark database: %v", err) + } + + err = os.RemoveAll(b.dbName) + if err != nil { + t.Fatalf("Failed to remove test database: %v", err) + } +} + +func TestNewBookmark(t *testing.T) { + b := createTempDB(t) + defer cleanUpDB(t, b) + + if b == nil || b.db == nil { + t.Fatalf("Expected non-nil bookmark and database") + } +} + +func TestAddBookmark(t *testing.T) { + b := createTempDB(t) + defer cleanUpDB(t, b) + + bookmark := []byte("testBookmark") + entryNum := uint64(12345) + + err := b.AddBookmark(bookmark, entryNum) + if err != nil { + t.Fatalf("Failed to add bookmark: %v", err) + } + + value, err := b.GetBookmark(bookmark) + if err != nil { + t.Fatalf("Failed to get bookmark after adding: %v", err) + } + + assert.Equal(t, entryNum, value, "Expected bookmark value %d, got %d", entryNum, value) +} + +func TestGetBookmarkNotFound(t *testing.T) { + b := createTempDB(t) + defer cleanUpDB(t, b) + + nonExistentBookmark := []byte("nonExistentBookmark") + _, err := b.GetBookmark(nonExistentBookmark) + assert.Error(t, err, "Expected error when getting a non-existent bookmark") +} diff --git a/datastreamer/streamfile_test.go b/datastreamer/streamfile_test.go new file mode 100644 index 0000000..fca11ed --- /dev/null +++ b/datastreamer/streamfile_test.go @@ -0,0 +1,56 @@ +package datastreamer + +import ( + "os" + "testing" + + "github.com/stretchr/testify/assert" +) + +func setupTestFile(t *testing.T, filename string) *StreamFile { + t.Helper() + + sf, err := NewStreamFile(filename, 1, 12345, 1) + assert.NoError(t, err) + assert.NotNil(t, sf) + + return sf +} + +func cleanupTestFile(filename string) { + _ = os.Remove(filename) +} + +func TestNewStreamFile(t *testing.T) { + filename := "test_streamfile.bin" + defer cleanupTestFile(filename) + + sf := setupTestFile(t, filename) + + assert.Equal(t, filename, sf.fileName) + assert.Equal(t, uint32(PageDataSize), sf.pageSize) + assert.Equal(t, uint64(4096), sf.header.TotalLength) + assert.Equal(t, uint64(0), sf.header.TotalEntries) + + info, err := os.Stat(filename) + assert.NoError(t, err) + assert.Equal(t, int64(PageHeaderSize+initPages*PageDataSize), info.Size()) +} + +func TestWriteAndReadHeader(t *testing.T) { + filename := "test_streamfile_header.bin" + defer cleanupTestFile(filename) + + sf := setupTestFile(t, filename) + + sf.header.TotalEntries = 10 + sf.header.TotalLength = 4096 + err := sf.writeHeaderEntry() + assert.NoError(t, err) + + err = sf.readHeaderEntry() + assert.NoError(t, err) + + assert.Equal(t, uint64(10), sf.header.TotalEntries) + assert.Equal(t, uint64(4096), sf.header.TotalLength) +} diff --git a/datastreamer/streamserver_test.go b/datastreamer/streamserver_test.go new file mode 100644 index 0000000..e0ab4ff --- /dev/null +++ b/datastreamer/streamserver_test.go @@ -0,0 +1,40 @@ +package datastreamer + +import ( + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestProcessCommand(t *testing.T) { + server := new(StreamServer) + cli := &client{status: csSyncing} + + // Test CmdStart + err := server.processCommand(CmdStart, cli) + assert.EqualError(t, ErrClientAlreadyStarted, err.Error()) + + // Test CmdStartBookmark + err = server.processCommand(CmdStartBookmark, cli) + assert.EqualError(t, ErrClientAlreadyStarted, err.Error()) + + // Test CmdStop + err = server.processCommand(CmdStop, cli) + assert.EqualError(t, ErrClientAlreadyStopped, err.Error()) + + // Test CmdHeader + err = server.processCommand(CmdHeader, cli) + assert.EqualError(t, ErrHeaderCommandNotAllowed, err.Error()) + + // Test CmdEntry + err = server.processCommand(CmdEntry, cli) + assert.EqualError(t, ErrEntryCommandNotAllowed, err.Error()) + + // Test CmdBookmark + err = server.processCommand(CmdBookmark, cli) + assert.EqualError(t, ErrBookmarkCommandNotAllowed, err.Error()) + + // Test invalid command + err = server.processCommand(Command(100), cli) + assert.EqualError(t, ErrInvalidCommand, err.Error()) +} diff --git a/go.mod b/go.mod index cc742e7..7da51ba 100644 --- a/go.mod +++ b/go.mod @@ -32,6 +32,7 @@ require ( github.com/spf13/cast v1.5.1 // indirect github.com/spf13/jwalterweatherman v1.1.0 // indirect github.com/spf13/pflag v1.0.5 // indirect + github.com/stretchr/objx v0.5.2 // indirect github.com/subosito/gotenv v1.6.0 // indirect github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 // indirect go.uber.org/multierr v1.10.0 // indirect diff --git a/go.sum b/go.sum index bac23fc..927cc58 100644 --- a/go.sum +++ b/go.sum @@ -191,6 +191,8 @@ github.com/spf13/viper v1.16.0/go.mod h1:yg78JgCJcbrQOvV9YLXgkLaZqUidkY9K+Dd1Fof github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= +github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY= +github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= diff --git a/log/log_test.go b/log/log_test.go index 9bbc255..f64cbb2 100644 --- a/log/log_test.go +++ b/log/log_test.go @@ -1,17 +1,25 @@ package log import ( + "errors" + "fmt" "testing" + + "github.com/hermeznetwork/tracerr" + "github.com/stretchr/testify/assert" ) func TestLogNotInitialized(t *testing.T) { Info("Test log.Info value is ", 10) Infof("Test log.Infof %d", 10) Infow("Test log.Infow", "value", 10) + Debug("Test log.Debug value is ", 10) Debugf("Test log.Debugf %d", 10) + Debugw("Test log.Debugw value", 10) Error("Test log.Error value is ", 10) Errorf("Test log.Errorf %d", 10) Errorw("Test log.Errorw value", 10) + Warn("Test log.Warn value is ", 10) Warnf("Test log.Warnf %d", 10) Warnw("Test log.Warnw value", 10) } @@ -35,3 +43,84 @@ func TestLog(t *testing.T) { Warnf("Test log.Warnf %d", 10) Warnw("Test log.Warnw value", 10) } + +func TestLogger_WithFields(t *testing.T) { + cfg := Config{ + Environment: EnvironmentDevelopment, + Level: "debug", + Outputs: []string{"stderr"}, + } + Init(cfg) + + originalLogger := WithFields("originalField", "originalValue") + derivedLogger := originalLogger.WithFields("newField", "newValue") + + originalCore := originalLogger.x.Desugar().Core() + assert.NotNil(t, originalCore) + assert.NotEqual(t, derivedLogger.x, originalLogger.x) + + derivedCore := derivedLogger.x.Desugar().Core() + assert.NotNil(t, derivedCore) + assert.NotEqual(t, derivedCore, originalCore) +} + +func TestSprintStackTrace(t *testing.T) { + err := func() error { + return tracerr.Wrap(func() error { + return tracerr.New("dummy error") + }()) + }() + + st := tracerr.StackTrace(err) + fmt.Println(st) + + stackTraceStr := sprintStackTrace(st) + fmt.Println(stackTraceStr) + + assert.Contains(t, stackTraceStr, "/log/log_test.go") + assert.Contains(t, stackTraceStr, "TestSprintStackTrace") +} + +func TestAppendStackTraceMaybeArgs(t *testing.T) { + err := errors.New("test error") + args := []interface{}{"some value", err} + newArgs := appendStackTraceMaybeArgs(args) + + assert.Greater(t, len(newArgs), len(args)) + + stackTraceStr, ok := newArgs[len(newArgs)-1].(string) + fmt.Println(stackTraceStr) + assert.True(t, ok) + assert.Contains(t, stackTraceStr, "/log/log_test.go") + assert.Contains(t, stackTraceStr, "TestAppendStackTraceMaybeArgs") +} + +func TestAppendStackTraceMaybeKV(t *testing.T) { + msg := "Test message" + + // Test case: No error in key-value pairs + kv := []interface{}{"key1", "value1", "key2", "value2"} + result := appendStackTraceMaybeKV(msg, kv) + assert.Equal(t, msg, result, "Expected message to be unchanged when no error is present") + + // Test case: Error in key-value pairs + err := errors.New("Test error") + wrappedErr := tracerr.Wrap(err) + expectedErrMsg := fmt.Sprintf("%v: %v", msg, wrappedErr.Error()) + kv = []interface{}{"key1", "value1", "errorKey", err} + result = appendStackTraceMaybeKV(msg, kv) + + assert.Contains(t, result, expectedErrMsg, "Expected message to include the error and its stack trace") + assert.Contains(t, result, "log_test.go", "Expected stack trace to include 'log_test.go'") + assert.Contains( + t, + result, + "TestAppendStackTraceMaybeKV", + "Expected stack trace to include 'TestAppendStackTraceMaybeKV'", + ) + + // Test case: Error at an even index should be ignored + kv = []interface{}{err, "value2", "key2", "value2"} + result = appendStackTraceMaybeKV(msg, kv) + assert.Equal(t, msg, result, "Expected message to be unchanged when error is at an odd index") +} diff --git a/relay/relay_test.go b/relay/relay_test.go new file mode 100644 index 0000000..d68c002 --- /dev/null +++ b/relay/relay_test.go @@ -0,0 +1,70 @@ +package main + +import ( + "flag" + "fmt" + "os" + "path/filepath" + "testing" + "time" + + "github.com/spf13/viper" + "github.com/stretchr/testify/assert" + "github.com/urfave/cli/v2" +) + +func TestDefaultConfig(t *testing.T) { + expectedConfig := &config{ + Server: "127.0.0.1:6900", + Port: 7900, + File: "datarelay.bin", + WriteTimeout: 3 * time.Second, + InactivityTimeout: 120 * time.Second, + Log: "info", + } + + cfg, err := defaultConfig() + assert.NoError(t, err) + assert.Equal(t, expectedConfig, cfg) +} + +func TestLoadConfig(t *testing.T) { + tempDir := t.TempDir() + configFile := filepath.Join(tempDir, "test_config.toml") + configContent := ` +Server = "127.0.0.1:8080" +Port = 8000 +File = "testfile.bin" +WriteTimeout = 2 +InactivityTimeout = 60 +Log = "debug" +` + + err := os.WriteFile(configFile, []byte(configContent), 0600) + assert.NoError(t, err) + + app := cli.NewApp() + set := flag.NewFlagSet("test", 0) + set.String("cfg", configFile, "doc") + ctx := cli.NewContext(app, set, nil) + + cfg, err := loadConfig(ctx) + fmt.Println(cfg) + assert.NoError(t, err) + + assert.Equal(t, "127.0.0.1:8080", cfg.Server) + assert.Equal(t, uint64(8000), cfg.Port) + assert.Equal(t, "testfile.bin", cfg.File) + assert.Equal(t, 2*time.Nanosecond, cfg.WriteTimeout) + assert.Equal(t, 60*time.Nanosecond, cfg.InactivityTimeout) + assert.Equal(t, "debug", cfg.Log) + + viper.Reset() + + os.Setenv("ZKEVM_STREAM_SERVER", "127.0.0.1:9090") + defer os.Unsetenv("ZKEVM_STREAM_SERVER") + + cfg, err = loadConfig(ctx) + assert.NoError(t, err) + assert.Equal(t, "127.0.0.1:9090", cfg.Server) +}