From e0446207a6afc993abbd9b70fe28283d39872fff Mon Sep 17 00:00:00 2001 From: srjchsv Date: Tue, 13 Sep 2022 18:51:37 +0300 Subject: [PATCH 1/3] feat: CoreDumpsRepository implementation and test feat: CoreDumpsRepository implementation and test --- .travis.yml | 4 +- server/Makefile | 16 +- server/cmd/crasher/main.go | 4 +- server/go.mod | 25 +- server/internal/app/configuration.go | 4 +- server/internal/app/entities/app_info.go | 24 +- server/internal/app/entities/app_info_test.go | 12 +- server/internal/app/entities/core_dump.go | 53 ++-- .../internal/app/entities/core_dump_test.go | 20 +- server/internal/app/entities/os_info.go | 24 +- server/internal/app/entities/os_info_test.go | 12 +- .../app/entities/query_fields_mongo.go | 43 ++++ .../app/entities/query_fields_mongo_test.go | 18 ++ .../app/repositories/core_dumps_repository.go | 7 +- .../mock/applications_repository.go | 49 ++++ .../mock/core_dumps_repository.go | 96 +++++++ .../applications_repository.go | 39 ++- .../applications_repository_test.go | 69 +++++ .../core_dumps_repository.go | 68 ++++- .../core_dumps_repository_test.go | 243 ++++++++++++++++++ .../mongodb_repository/helpers.go | 11 + 21 files changed, 738 insertions(+), 103 deletions(-) create mode 100644 server/internal/app/entities/query_fields_mongo.go create mode 100644 server/internal/app/entities/query_fields_mongo_test.go create mode 100644 server/internal/app/repositories/mock/applications_repository.go create mode 100644 server/internal/app/repositories/mock/core_dumps_repository.go create mode 100644 server/internal/app/repositories/mongodb_repository/applications_repository_test.go create mode 100644 server/internal/app/repositories/mongodb_repository/core_dumps_repository_test.go create mode 100644 server/internal/app/repositories/mongodb_repository/helpers.go diff --git a/.travis.yml b/.travis.yml index b07d7db..9e95720 100644 --- a/.travis.yml +++ b/.travis.yml @@ -16,7 +16,5 @@ install: - go mod tidy script: - - go build -o bin/crasher cmd/crasher/main.go - - go test -v -race ./... - - golangci-lint run ./... + - make all diff --git a/server/Makefile b/server/Makefile index 6bf836d..2a185a8 100644 --- a/server/Makefile +++ b/server/Makefile @@ -2,16 +2,20 @@ BINARY_NAME=crasher BIN_PATH=bin/ LINTER=golangci-lint -.ONESHELL: test build lint all -.PHONY: test build lint all +.ONESHELL: test build lint all run +.PHONY: test build lint all run -all: test build lint - -test: - @go test ./... +all: build test lint build: @go build -o $(BIN_PATH)$(BINARY_NAME) cmd/crasher/main.go +test: + @go test -v -race -cover ./... + lint: @$(LINTER) run ./... + +run: + @export CRASHER_SERVER_ADDRESS=:8080 + @go run cmd/crasher/main.go diff --git a/server/cmd/crasher/main.go b/server/cmd/crasher/main.go index 0a918cf..f71b1eb 100644 --- a/server/cmd/crasher/main.go +++ b/server/cmd/crasher/main.go @@ -45,8 +45,8 @@ func main() { } }() - appsRepo := mongodb_repositories.NewApplicationsRepository(dbClient, logger) - coreDumpsRepo := mongodb_repositories.NewCoreDumpsRepository(dbClient, logger) + appsRepo := mongodb_repository.NewApplicationsRepository(dbClient, logger) + coreDumpsRepo := mongodb_repository.NewCoreDumpsRepository(dbClient, logger) appsService := services.NewApplicationsService(appsRepo, logger) coreDumpsService := services.NewCoreDumpsService(coreDumpsRepo, logger) diff --git a/server/go.mod b/server/go.mod index e365a14..043e9df 100644 --- a/server/go.mod +++ b/server/go.mod @@ -3,15 +3,28 @@ module server go 1.19 require ( - github.com/codegangsta/inject v0.0.0-20150114235600-33e0aa1cb7c0 // indirect + github.com/golang/mock v1.6.0 + github.com/gorilla/mux v1.8.0 + github.com/stretchr/testify v1.8.0 + go.mongodb.org/mongo-driver v1.8.4 + go.uber.org/zap v1.22.0 +) + +require ( github.com/davecgh/go-spew v1.1.1 // indirect - github.com/gorilla/mux v1.8.0 // indirect + github.com/go-stack/stack v1.8.0 // indirect + github.com/golang/snappy v0.0.1 // indirect + github.com/klauspost/compress v1.13.6 // indirect + github.com/pkg/errors v0.9.1 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect - github.com/stretchr/objx v0.4.0 // indirect - github.com/stretchr/testify v1.8.0 // indirect - go.mongodb.org/mongo-driver v1.8.4 // indirect + github.com/xdg-go/pbkdf2 v1.0.0 // indirect + github.com/xdg-go/scram v1.0.2 // indirect + github.com/xdg-go/stringprep v1.0.2 // indirect + github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d // indirect go.uber.org/atomic v1.10.0 // indirect go.uber.org/multierr v1.8.0 // indirect - go.uber.org/zap v1.22.0 // indirect + golang.org/x/crypto v0.0.0-20201216223049-8b5274cf687f // indirect + golang.org/x/sync v0.0.0-20210220032951-036812b2e83c // indirect + golang.org/x/text v0.3.5 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/server/internal/app/configuration.go b/server/internal/app/configuration.go index f36703b..7683c23 100644 --- a/server/internal/app/configuration.go +++ b/server/internal/app/configuration.go @@ -3,8 +3,8 @@ package app import "os" var ( - ServerAddress = os.Getenv("CRASHER_SERVER_ADDRESS") - + ServerAddress = os.Getenv("CRASHER_SERVER_ADDRESS") + CtxTimeout = os.Getenv("CRASHER_DATABASE_TIMEOUTgit") DatabaseAddress = os.Getenv("CRASHER_DATABASE_ADDRESS") DatabaseUsername = os.Getenv("CRASHER_DATABASE_USERNAME") DatabasePassword = os.Getenv("CRASHER_DATABASE_PASSWORD") diff --git a/server/internal/app/entities/app_info.go b/server/internal/app/entities/app_info.go index 24d280a..30b0092 100644 --- a/server/internal/app/entities/app_info.go +++ b/server/internal/app/entities/app_info.go @@ -10,35 +10,35 @@ const ( ) type AppInfo struct { - name string - version string - programmingLanguage ProgrammingLanguage + Name string + Version string + ProgrammingLanguage ProgrammingLanguage } func NewAppInfo() *AppInfo { return &AppInfo{} } -func (app *AppInfo) Name() string { - return app.name +func (app *AppInfo) GetName() string { + return app.Name } -func (app *AppInfo) Version() string { - return app.version +func (app *AppInfo) GetVersion() string { + return app.Version } -func (app *AppInfo) ProgrammingLanguage() ProgrammingLanguage { - return app.programmingLanguage +func (app *AppInfo) GetProgrammingLanguage() ProgrammingLanguage { + return app.ProgrammingLanguage } func (app *AppInfo) SetName(name string) { - app.name = name + app.Name = name } func (app *AppInfo) SetVersion(version string) { - app.version = version + app.Version = version } func (app *AppInfo) SetProgrammingLanguage(language ProgrammingLanguage) { - app.programmingLanguage = language + app.ProgrammingLanguage = language } diff --git a/server/internal/app/entities/app_info_test.go b/server/internal/app/entities/app_info_test.go index 3dce43d..f57513f 100644 --- a/server/internal/app/entities/app_info_test.go +++ b/server/internal/app/entities/app_info_test.go @@ -9,9 +9,9 @@ import ( func TestAppInfo(t *testing.T) { appInfo := NewAppInfo() - require.Equal(t, 0, len(appInfo.Name())) - require.Equal(t, 0, len(appInfo.Version())) - require.Equal(t, UnknownProgrammingLanguage, appInfo.ProgrammingLanguage()) + require.Equal(t, 0, len(appInfo.GetName())) + require.Equal(t, 0, len(appInfo.GetVersion())) + require.Equal(t, UnknownProgrammingLanguage, appInfo.GetProgrammingLanguage()) name := "publisher-app" version := "v0.0.1" @@ -21,7 +21,7 @@ func TestAppInfo(t *testing.T) { appInfo.SetVersion(version) appInfo.SetProgrammingLanguage(language) - assert.Equal(t, name, appInfo.Name()) - assert.Equal(t, version, appInfo.Version()) - assert.Equal(t, language, appInfo.ProgrammingLanguage()) + assert.Equal(t, name, appInfo.GetName()) + assert.Equal(t, version, appInfo.GetVersion()) + assert.Equal(t, language, appInfo.GetProgrammingLanguage()) } diff --git a/server/internal/app/entities/core_dump.go b/server/internal/app/entities/core_dump.go index e3d7bfb..65ed6c5 100644 --- a/server/internal/app/entities/core_dump.go +++ b/server/internal/app/entities/core_dump.go @@ -1,6 +1,10 @@ package entities -import "time" +import ( + "time" + + "go.mongodb.org/mongo-driver/bson/primitive" +) type CoreDumpStatus int @@ -12,53 +16,60 @@ const ( ) type CoreDump struct { - osInfo *OSInfo - appInfo *AppInfo - status CoreDumpStatus - data string - timestamp time.Time + ID primitive.ObjectID + OsInfo *OSInfo + AppInfo *AppInfo + Status CoreDumpStatus + Data string + Timestamp time.Time + Extensions []Extensions +} + +type Extensions struct { + Key string + Value string } func NewCoreDump() *CoreDump { return &CoreDump{} } -func (c *CoreDump) OSInfo() *OSInfo { - return c.osInfo +func (c *CoreDump) GetOSInfo() *OSInfo { + return c.OsInfo } -func (c *CoreDump) AppInfo() *AppInfo { - return c.appInfo +func (c *CoreDump) GetAppInfo() *AppInfo { + return c.AppInfo } -func (c *CoreDump) Status() CoreDumpStatus { - return c.status +func (c *CoreDump) GetStatus() CoreDumpStatus { + return c.Status } -func (c *CoreDump) Data() string { - return c.data +func (c *CoreDump) GetData() string { + return c.Data } -func (c *CoreDump) Timestamp() time.Time { - return c.timestamp +func (c *CoreDump) GetTimestamp() time.Time { + return c.Timestamp } func (c *CoreDump) SetOSInfo(info *OSInfo) { - c.osInfo = info + c.OsInfo = info } func (c *CoreDump) SetAppInfo(info *AppInfo) { - c.appInfo = info + c.AppInfo = info } func (c *CoreDump) SetStatus(status CoreDumpStatus) { - c.status = status + c.Status = status } func (c *CoreDump) SetData(data string) { - c.data = data + c.Data = data } func (c *CoreDump) SetTimestamp(timestamp time.Time) { - c.timestamp = timestamp + c.Timestamp = timestamp } diff --git a/server/internal/app/entities/core_dump_test.go b/server/internal/app/entities/core_dump_test.go index 3ff6c6c..53c23a5 100644 --- a/server/internal/app/entities/core_dump_test.go +++ b/server/internal/app/entities/core_dump_test.go @@ -10,11 +10,11 @@ import ( func TestCoreDump(t *testing.T) { coreDump := NewCoreDump() - require.Nil(t, coreDump.OSInfo()) - require.Nil(t, coreDump.AppInfo()) - require.Equal(t, ToDoCoreDumpStatus, coreDump.Status()) - require.Equal(t, time.Time{}, coreDump.Timestamp()) - require.Equal(t, 0, len(coreDump.Data())) + require.Nil(t, coreDump.GetOSInfo()) + require.Nil(t, coreDump.GetAppInfo()) + require.Equal(t, ToDoCoreDumpStatus, coreDump.GetStatus()) + require.Equal(t, time.Time{}, coreDump.GetTimestamp()) + require.Equal(t, 0, len(coreDump.GetData())) osInfo := NewOSInfo() appInfo := NewAppInfo() @@ -28,9 +28,9 @@ func TestCoreDump(t *testing.T) { coreDump.SetStatus(status) coreDump.SetData(data) - assert.Equal(t, osInfo, coreDump.OSInfo()) - assert.Equal(t, appInfo, coreDump.AppInfo()) - assert.Equal(t, timestamp, coreDump.Timestamp()) - assert.Equal(t, status, coreDump.Status()) - assert.Equal(t, data, coreDump.Data()) + assert.Equal(t, osInfo, coreDump.GetOSInfo()) + assert.Equal(t, appInfo, coreDump.GetAppInfo()) + assert.Equal(t, timestamp, coreDump.GetTimestamp()) + assert.Equal(t, status, coreDump.GetStatus()) + assert.Equal(t, data, coreDump.GetData()) } diff --git a/server/internal/app/entities/os_info.go b/server/internal/app/entities/os_info.go index 5cd424d..59ce8c6 100644 --- a/server/internal/app/entities/os_info.go +++ b/server/internal/app/entities/os_info.go @@ -1,35 +1,35 @@ package entities type OSInfo struct { - name string - version string - architecture string + Name string + Version string + Architecture string } func NewOSInfo() *OSInfo { return &OSInfo{} } -func (os *OSInfo) Name() string { - return os.name +func (os *OSInfo) GetName() string { + return os.Name } -func (os *OSInfo) Version() string { - return os.version +func (os *OSInfo) GetVersion() string { + return os.Version } -func (os *OSInfo) Architecture() string { - return os.architecture +func (os *OSInfo) GetArchitecture() string { + return os.Architecture } func (os *OSInfo) SetName(name string) { - os.name = name + os.Name = name } func (os *OSInfo) SetVersion(version string) { - os.version = version + os.Version = version } func (os *OSInfo) SetArchitecture(architecture string) { - os.architecture = architecture + os.Architecture = architecture } diff --git a/server/internal/app/entities/os_info_test.go b/server/internal/app/entities/os_info_test.go index 13a6ef5..e79ab9f 100644 --- a/server/internal/app/entities/os_info_test.go +++ b/server/internal/app/entities/os_info_test.go @@ -9,9 +9,9 @@ import ( func TestOSInfo(t *testing.T) { osInfo := NewOSInfo() - require.Equal(t, 0, len(osInfo.Name())) - require.Equal(t, 0, len(osInfo.Version())) - require.Equal(t, 0, len(osInfo.Architecture())) + require.Equal(t, 0, len(osInfo.GetName())) + require.Equal(t, 0, len(osInfo.GetVersion())) + require.Equal(t, 0, len(osInfo.GetArchitecture())) name := "windows" version := "10" @@ -21,7 +21,7 @@ func TestOSInfo(t *testing.T) { osInfo.SetVersion(version) osInfo.SetArchitecture(architecture) - assert.Equal(t, name, osInfo.Name()) - assert.Equal(t, version, osInfo.Version()) - assert.Equal(t, architecture, osInfo.Architecture()) + assert.Equal(t, name, osInfo.GetName()) + assert.Equal(t, version, osInfo.GetVersion()) + assert.Equal(t, architecture, osInfo.GetArchitecture()) } diff --git a/server/internal/app/entities/query_fields_mongo.go b/server/internal/app/entities/query_fields_mongo.go new file mode 100644 index 0000000..35d0c50 --- /dev/null +++ b/server/internal/app/entities/query_fields_mongo.go @@ -0,0 +1,43 @@ +package entities + +import ( + "go.mongodb.org/mongo-driver/bson" + "go.mongodb.org/mongo-driver/bson/primitive" + "go.mongodb.org/mongo-driver/mongo/options" +) + +type OptionsMongo func(bson.M, *options.FindOptions) + +func SetApplication(application string) OptionsMongo { + return func(filter bson.M, options *options.FindOptions) { + filter["appinfo.name"] = application + } +} + +func SetStartTimestamp(start primitive.DateTime) OptionsMongo { + return func(filter bson.M, options *options.FindOptions) { + filter["timestamp"] = bson.M{ + "$gte": start, + } + } +} + +func SetEndTimestamp(end primitive.DateTime) OptionsMongo { + return func(filter bson.M, options *options.FindOptions) { + filter["timestamp"] = bson.M{ + "$lt": end, + } + } +} + +func SetLimit(limit int) OptionsMongo { + return func(filter bson.M, options *options.FindOptions) { + options.SetLimit(int64(limit)) + } +} + +func SetOffset(offset int) OptionsMongo { + return func(filter bson.M, options *options.FindOptions) { + options.SetSkip(int64(offset)) + } +} diff --git a/server/internal/app/entities/query_fields_mongo_test.go b/server/internal/app/entities/query_fields_mongo_test.go new file mode 100644 index 0000000..454ef96 --- /dev/null +++ b/server/internal/app/entities/query_fields_mongo_test.go @@ -0,0 +1,18 @@ +package entities + +import ( + "testing" + + "github.com/stretchr/testify/require" + "go.mongodb.org/mongo-driver/bson" + "go.mongodb.org/mongo-driver/mongo/options" +) + +func Test_SetApplication(t *testing.T) { + filter := bson.M{} + options := options.Find() + setter := SetApplication("app") + setter(filter, options) + res := filter["appinfo.name"] + require.Equal(t, "app", res) +} diff --git a/server/internal/app/repositories/core_dumps_repository.go b/server/internal/app/repositories/core_dumps_repository.go index 487ee5f..21d5c98 100644 --- a/server/internal/app/repositories/core_dumps_repository.go +++ b/server/internal/app/repositories/core_dumps_repository.go @@ -1,9 +1,12 @@ package repositories -import "server/internal/app/entities" +import ( + "server/internal/app/entities" +) type CoreDumpsRepository interface { - GetCoreDumps() ([]entities.CoreDump, error) + GetCoreDumps(setters ...entities.OptionsMongo) ([]entities.CoreDump, error) AddCoreDump(coreDump entities.CoreDump) error DeleteCoreDump(id string) error + DeleteAllCoreDumps() error } diff --git a/server/internal/app/repositories/mock/applications_repository.go b/server/internal/app/repositories/mock/applications_repository.go new file mode 100644 index 0000000..e87b57c --- /dev/null +++ b/server/internal/app/repositories/mock/applications_repository.go @@ -0,0 +1,49 @@ +// Code generated by MockGen. DO NOT EDIT. +// Source: internal/app/repositories/applications_repository.go + +// Package mock_repositories is a generated GoMock package. +package mock_repositories + +import ( + reflect "reflect" + + gomock "github.com/golang/mock/gomock" +) + +// MockApplicationsRepository is a mock of ApplicationsRepository interface. +type MockApplicationsRepository struct { + ctrl *gomock.Controller + recorder *MockApplicationsRepositoryMockRecorder +} + +// MockApplicationsRepositoryMockRecorder is the mock recorder for MockApplicationsRepository. +type MockApplicationsRepositoryMockRecorder struct { + mock *MockApplicationsRepository +} + +// NewMockApplicationsRepository creates a new mock instance. +func NewMockApplicationsRepository(ctrl *gomock.Controller) *MockApplicationsRepository { + mock := &MockApplicationsRepository{ctrl: ctrl} + mock.recorder = &MockApplicationsRepositoryMockRecorder{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use. +func (m *MockApplicationsRepository) EXPECT() *MockApplicationsRepositoryMockRecorder { + return m.recorder +} + +// GetApplicationNames mocks base method. +func (m *MockApplicationsRepository) GetApplicationNames() ([]string, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetApplicationNames") + ret0, _ := ret[0].([]string) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetApplicationNames indicates an expected call of GetApplicationNames. +func (mr *MockApplicationsRepositoryMockRecorder) GetApplicationNames() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetApplicationNames", reflect.TypeOf((*MockApplicationsRepository)(nil).GetApplicationNames)) +} diff --git a/server/internal/app/repositories/mock/core_dumps_repository.go b/server/internal/app/repositories/mock/core_dumps_repository.go new file mode 100644 index 0000000..9590321 --- /dev/null +++ b/server/internal/app/repositories/mock/core_dumps_repository.go @@ -0,0 +1,96 @@ +// Code generated by MockGen. DO NOT EDIT. +// Source: internal/app/repositories/core_dumps_repository.go + +// Package mock_repositories is a generated GoMock package. +package mock_repositories + +import ( + reflect "reflect" + entities "server/internal/app/entities" + + gomock "github.com/golang/mock/gomock" +) + +// MockCoreDumpsRepository is a mock of CoreDumpsRepository interface. +type MockCoreDumpsRepository struct { + ctrl *gomock.Controller + recorder *MockCoreDumpsRepositoryMockRecorder +} + +// MockCoreDumpsRepositoryMockRecorder is the mock recorder for MockCoreDumpsRepository. +type MockCoreDumpsRepositoryMockRecorder struct { + mock *MockCoreDumpsRepository +} + +// NewMockCoreDumpsRepository creates a new mock instance. +func NewMockCoreDumpsRepository(ctrl *gomock.Controller) *MockCoreDumpsRepository { + mock := &MockCoreDumpsRepository{ctrl: ctrl} + mock.recorder = &MockCoreDumpsRepositoryMockRecorder{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use. +func (m *MockCoreDumpsRepository) EXPECT() *MockCoreDumpsRepositoryMockRecorder { + return m.recorder +} + +// AddCoreDump mocks base method. +func (m *MockCoreDumpsRepository) AddCoreDump(coreDump entities.CoreDump) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "AddCoreDump", coreDump) + ret0, _ := ret[0].(error) + return ret0 +} + +// AddCoreDump indicates an expected call of AddCoreDump. +func (mr *MockCoreDumpsRepositoryMockRecorder) AddCoreDump(coreDump interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddCoreDump", reflect.TypeOf((*MockCoreDumpsRepository)(nil).AddCoreDump), coreDump) +} + +// DeleteAllCoreDumps mocks base method. +func (m *MockCoreDumpsRepository) DeleteAllCoreDumps() error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "DeleteAllCoreDumps") + ret0, _ := ret[0].(error) + return ret0 +} + +// DeleteAllCoreDumps indicates an expected call of DeleteAllCoreDumps. +func (mr *MockCoreDumpsRepositoryMockRecorder) DeleteAllCoreDumps() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteAllCoreDumps", reflect.TypeOf((*MockCoreDumpsRepository)(nil).DeleteAllCoreDumps)) +} + +// DeleteCoreDump mocks base method. +func (m *MockCoreDumpsRepository) DeleteCoreDump(id string) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "DeleteCoreDump", id) + ret0, _ := ret[0].(error) + return ret0 +} + +// DeleteCoreDump indicates an expected call of DeleteCoreDump. +func (mr *MockCoreDumpsRepositoryMockRecorder) DeleteCoreDump(id interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteCoreDump", reflect.TypeOf((*MockCoreDumpsRepository)(nil).DeleteCoreDump), id) +} + +// GetCoreDumps mocks base method. +func (m *MockCoreDumpsRepository) GetCoreDumps(setters ...entities.OptionsMongo) ([]entities.CoreDump, error) { + m.ctrl.T.Helper() + varargs := []interface{}{} + for _, a := range setters { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "GetCoreDumps", varargs...) + ret0, _ := ret[0].([]entities.CoreDump) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetCoreDumps indicates an expected call of GetCoreDumps. +func (mr *MockCoreDumpsRepositoryMockRecorder) GetCoreDumps(setters ...interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetCoreDumps", reflect.TypeOf((*MockCoreDumpsRepository)(nil).GetCoreDumps), setters...) +} diff --git a/server/internal/app/repositories/mongodb_repository/applications_repository.go b/server/internal/app/repositories/mongodb_repository/applications_repository.go index e528ac6..bff6a68 100644 --- a/server/internal/app/repositories/mongodb_repository/applications_repository.go +++ b/server/internal/app/repositories/mongodb_repository/applications_repository.go @@ -1,26 +1,53 @@ -package mongodb_repositories +package mongodb_repository import ( + "context" + "fmt" "server/internal/app/repositories" + "time" + "go.mongodb.org/mongo-driver/bson" "go.mongodb.org/mongo-driver/mongo" "go.uber.org/zap" ) type ApplicationsRepository struct { - dbClient *mongo.Client - logger *zap.Logger + dbClient *mongo.Client + collection *mongo.Collection + logger *zap.Logger + timeout int } var _ repositories.ApplicationsRepository = (*ApplicationsRepository)(nil) func NewApplicationsRepository(db *mongo.Client, l *zap.Logger) *ApplicationsRepository { + mongoDB := db.Database("crasher") + collection := mongoDB.Collection("coredumps") + timeout, err := ParseCtxTimeoutEnv() + if err != nil { + l.Fatal( + "failed to parse ctx timeout env", + zap.Error(err), + ) + } return &ApplicationsRepository{ - dbClient: db, - logger: l, + dbClient: db, + collection: collection, + logger: l, + timeout: timeout, } } func (r *ApplicationsRepository) GetApplicationNames() ([]string, error) { - return nil, nil + ctx, cancel := context.WithTimeout(context.Background(), time.Duration(r.timeout)*time.Second) + defer cancel() + res, err := r.collection.Distinct(ctx, "appinfo.name", bson.D{}) + if err != nil { + return nil, err + } + applications := make([]string, len(res)) + for i, v := range res { + applications[i] = fmt.Sprint(v) + } + return applications, nil } diff --git a/server/internal/app/repositories/mongodb_repository/applications_repository_test.go b/server/internal/app/repositories/mongodb_repository/applications_repository_test.go new file mode 100644 index 0000000..ca94850 --- /dev/null +++ b/server/internal/app/repositories/mongodb_repository/applications_repository_test.go @@ -0,0 +1,69 @@ +package mongodb_repository + +import ( + "errors" + mock_repositories "server/internal/app/repositories/mock" + "testing" + + "github.com/golang/mock/gomock" + "github.com/stretchr/testify/require" +) + +func TestGetApplicationNames(t *testing.T) { + many := []string{"app1", "app2", "app3"} + one := []string{"app1"} + empty := []string{} + + c := gomock.NewController(t) + defer c.Finish() + + tests := []struct { + name string + stubs func(store *mock_repositories.MockApplicationsRepository, slice []string) + slice []string + error error + }{ + { + name: "ok - many elements", + stubs: func(r *mock_repositories.MockApplicationsRepository, slice []string) { + r.EXPECT().GetApplicationNames().Return(slice, nil) + }, + slice: many, + error: nil, + }, + { + name: "ok - one app", + stubs: func(r *mock_repositories.MockApplicationsRepository, slice []string) { + r.EXPECT().GetApplicationNames().Return(slice, nil) + }, + slice: one, + error: nil, + }, + { + name: "ok - empty slice", + stubs: func(r *mock_repositories.MockApplicationsRepository, slice []string) { + r.EXPECT().GetApplicationNames().Return(slice, nil) + }, + slice: empty, + error: nil, + }, + { + name: "error", + stubs: func(r *mock_repositories.MockApplicationsRepository, slice []string) { + r.EXPECT().GetApplicationNames().Return(slice, errors.New("error getting application names")) + }, + slice: empty, + error: errors.New("error getting application names"), + }, + } + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + r := mock_repositories.NewMockApplicationsRepository(c) + test.stubs(r, test.slice) + + result, err := r.GetApplicationNames() + require.Equal(t, test.error, err) + require.Equal(t, len(test.slice), len(result)) + }) + } +} diff --git a/server/internal/app/repositories/mongodb_repository/core_dumps_repository.go b/server/internal/app/repositories/mongodb_repository/core_dumps_repository.go index 904dfaa..f635a73 100644 --- a/server/internal/app/repositories/mongodb_repository/core_dumps_repository.go +++ b/server/internal/app/repositories/mongodb_repository/core_dumps_repository.go @@ -1,35 +1,85 @@ -package mongodb_repositories +package mongodb_repository import ( + "context" "server/internal/app/entities" "server/internal/app/repositories" + "time" + "go.mongodb.org/mongo-driver/bson" + "go.mongodb.org/mongo-driver/bson/primitive" "go.mongodb.org/mongo-driver/mongo" + "go.mongodb.org/mongo-driver/mongo/options" "go.uber.org/zap" ) type CoreDumpsRepository struct { - dbClient *mongo.Client - logger *zap.Logger + dbClient *mongo.Client + collection *mongo.Collection + logger *zap.Logger + timeout int } var _ repositories.CoreDumpsRepository = (*CoreDumpsRepository)(nil) func NewCoreDumpsRepository(db *mongo.Client, l *zap.Logger) *CoreDumpsRepository { + mongoDB := db.Database("crasher") + collection := mongoDB.Collection("coredumps") + timeout, err := ParseCtxTimeoutEnv() + if err != nil { + l.Fatal( + "failed to parse ctx timeout env", + zap.Error(err), + ) + } return &CoreDumpsRepository{ - dbClient: db, - logger: l, + dbClient: db, + collection: collection, + logger: l, + timeout: timeout, } } -func (r *CoreDumpsRepository) GetCoreDumps() ([]entities.CoreDump, error) { - return nil, nil +func (r *CoreDumpsRepository) GetCoreDumps(setters ...entities.OptionsMongo) ([]entities.CoreDump, error) { + options := options.Find() + filter := bson.M{} + for _, setter := range setters { + setter(filter, options) + } + var result []entities.CoreDump + ctx, cancel := context.WithTimeout(context.Background(), time.Duration(r.timeout)*time.Second) + defer cancel() + + cur, err := r.collection.Find(ctx, filter) + if err != nil { + return nil, err + } + err = cur.All(ctx, &result) + return result, err } func (r *CoreDumpsRepository) AddCoreDump(coreDump entities.CoreDump) error { - return nil + ctx, cancel := context.WithTimeout(context.Background(), time.Duration(r.timeout)*time.Second) + defer cancel() + _, err := r.collection.InsertOne(ctx, coreDump) + return err } func (r *CoreDumpsRepository) DeleteCoreDump(id string) error { - return nil + idHex, err := primitive.ObjectIDFromHex(id) + if err != nil { + return err + } + ctx, cancel := context.WithTimeout(context.Background(), time.Duration(r.timeout)*time.Second) + defer cancel() + + _, err = r.collection.DeleteOne(ctx, bson.D{{Key: "_id", Value: idHex}}) + return err +} + +func (r *CoreDumpsRepository) DeleteAllCoreDumps() error { + ctx, cancel := context.WithTimeout(context.Background(), time.Duration(r.timeout)*time.Second) + defer cancel() + _, err := r.collection.DeleteMany(ctx, bson.D{}) + return err } diff --git a/server/internal/app/repositories/mongodb_repository/core_dumps_repository_test.go b/server/internal/app/repositories/mongodb_repository/core_dumps_repository_test.go new file mode 100644 index 0000000..85b7706 --- /dev/null +++ b/server/internal/app/repositories/mongodb_repository/core_dumps_repository_test.go @@ -0,0 +1,243 @@ +package mongodb_repository + +import ( + "errors" + "math/rand" + "server/internal/app/entities" + mock_repositories "server/internal/app/repositories/mock" + "testing" + "time" + + "github.com/golang/mock/gomock" + "github.com/stretchr/testify/require" +) + +func Test_AddCoreDump(t *testing.T) { + t.Parallel() + c := gomock.NewController(t) + defer c.Finish() + + randomDump := generateRandomSliceOfCoreDumps(1) + tests := []struct { + name string + dump entities.CoreDump + stubs func(store *mock_repositories.MockCoreDumpsRepository, dump entities.CoreDump) + error error + }{ + { + name: "ok", + dump: randomDump[0], + stubs: func(r *mock_repositories.MockCoreDumpsRepository, dump entities.CoreDump) { + r.EXPECT().AddCoreDump(dump).Return(nil) + }, + error: nil, + }, + { + name: "error", + dump: entities.CoreDump{}, + stubs: func(r *mock_repositories.MockCoreDumpsRepository, dump entities.CoreDump) { + r.EXPECT().AddCoreDump(dump).Return(errors.New("error adding core dump")) + + }, + error: errors.New("error adding core dump"), + }, + { + name: "timeout", + dump: entities.CoreDump{}, + stubs: func(r *mock_repositories.MockCoreDumpsRepository, dump entities.CoreDump) { + r.EXPECT().AddCoreDump(dump).Return(errors.New("timeout")) + + }, + error: errors.New("timeout"), + }, + } + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + r := mock_repositories.NewMockCoreDumpsRepository(c) + + test.stubs(r, test.dump) + err := r.AddCoreDump(test.dump) + require.Equal(t, test.error, err) + }) + } +} + +func Test_GetCoreDump(t *testing.T) { + t.Parallel() + c := gomock.NewController(t) + defer c.Finish() + + sliceOfDumps := generateRandomSliceOfCoreDumps(5) + + tests := []struct { + name string + stubs func(store *mock_repositories.MockCoreDumpsRepository) + dumps []entities.CoreDump + error error + }{ + { + name: "ok", + stubs: func(r *mock_repositories.MockCoreDumpsRepository) { + r.EXPECT().GetCoreDumps().Return(sliceOfDumps, nil) + }, + dumps: sliceOfDumps, + error: nil, + }, + { + name: "error", + stubs: func(r *mock_repositories.MockCoreDumpsRepository) { + r.EXPECT().GetCoreDumps().Return(nil, errors.New("error getting dumps")) + }, + dumps: nil, + error: errors.New("error getting dumps"), + }, + } + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + r := mock_repositories.NewMockCoreDumpsRepository(c) + test.stubs(r) + + res, err := r.GetCoreDumps() + require.Equal(t, test.error, err) + require.Equal(t, test.dumps, res) + }) + } +} + +func Test_DeleteCoreDump(t *testing.T) { + t.Parallel() + c := gomock.NewController(t) + defer c.Finish() + + tests := []struct { + name string + stubs func(store *mock_repositories.MockCoreDumpsRepository, dumpID string) + dumpID string + error error + }{ + { + name: "ok", + stubs: func(r *mock_repositories.MockCoreDumpsRepository, dumpID string) { + r.EXPECT().DeleteCoreDump(dumpID).Return(nil) + }, + dumpID: "dsfdfds454", + error: nil, + }, + { + name: "error", + stubs: func(r *mock_repositories.MockCoreDumpsRepository, dumpID string) { + r.EXPECT().DeleteCoreDump(dumpID).Return(errors.New("error enter dump id")) + }, + dumpID: "", + error: errors.New("error enter dump id"), + }, + } + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + r := mock_repositories.NewMockCoreDumpsRepository(c) + test.stubs(r, test.dumpID) + + err := r.DeleteCoreDump(test.dumpID) + require.Equal(t, test.error, err) + }) + } +} + +func init() { + rand.Seed(time.Now().Unix()) +} + +func generateRandomSliceOfCoreDumps(quantity int) []entities.CoreDump { + type asInfo struct { + Name string + Arch string + Version string + } + + type appInfo struct { + Name string + Version string + } + osArr := []asInfo{ + { + Name: "linux", + Arch: "amd64", + Version: "ubuntu 22.04", + }, + { + Name: "linux", + Arch: "amd64", + Version: "ubuntu 18.06", + }, + { + Name: "windows", + Arch: "amd64", + Version: "10", + }, + { + Name: "darwin", + Arch: "amd64", + Version: "10.0.3", + }, + { + Name: "darwin", + Arch: "amd64", + Version: "10.0.1", + }, + } + appArr := []appInfo{ + { + Name: "financial", + Version: "v0.0.1", + }, + { + Name: "financial", + Version: "v1.0.1", + }, + { + Name: "sports", + Version: "v2.1.1", + }, + { + Name: "sports", + Version: "v1.1.1", + }, + { + Name: "educational", + Version: "v0.1.1", + }, + { + Name: "educational", + Version: "v3.1.1", + }, + } + var result []entities.CoreDump + for i := 0; i < quantity; i++ { + coreDump := entities.NewCoreDump() + randomIdxOs := rand.Intn(len(osArr)) + randomIdxApp := rand.Intn(len(appArr)) + + osInfo := entities.NewOSInfo() + osInfo.SetName(osArr[randomIdxOs].Name) + osInfo.SetArchitecture(osArr[randomIdxOs].Arch) + osInfo.SetVersion(osArr[randomIdxOs].Version) + coreDump.SetOSInfo(osInfo) + + appInfo := entities.NewAppInfo() + appInfo.SetName(appArr[randomIdxApp].Name) + appInfo.SetProgrammingLanguage(entities.ProgrammingLanguage(rand.Intn(4))) + appInfo.SetVersion(appArr[randomIdxApp].Version) + coreDump.SetAppInfo(appInfo) + + coreDump.SetStatus(1) + coreDump.SetData(time.Now().Format("2006-01-02")) + + randomTime := rand.Int63n(time.Now().Unix()-94608000) + 94608000 + randomNow := time.Unix(randomTime, 0) + coreDump.SetTimestamp(randomNow) + + result = append(result, *coreDump) + } + + return result +} diff --git a/server/internal/app/repositories/mongodb_repository/helpers.go b/server/internal/app/repositories/mongodb_repository/helpers.go new file mode 100644 index 0000000..8ef6c77 --- /dev/null +++ b/server/internal/app/repositories/mongodb_repository/helpers.go @@ -0,0 +1,11 @@ +package mongodb_repository + +import ( + "server/internal/app" + "strconv" +) + +func ParseCtxTimeoutEnv() (int, error) { + ctxTimeout, err := strconv.Atoi(app.CtxTimeout) + return ctxTimeout, err +} From ae80ef35af18f1f414d8cf035349bd21b1725d07 Mon Sep 17 00:00:00 2001 From: srjchsv Date: Sun, 18 Sep 2022 18:59:48 +0300 Subject: [PATCH 2/3] feat: CoreDumpsRepository implementation and test --- server/Makefile | 1 + server/cmd/crasher/main.go | 13 +- server/internal/app/configuration.go | 2 +- server/internal/app/entities/core_dump.go | 21 +- .../internal/app/entities/core_dump_test.go | 7 + server/internal/app/entities/os_info.go | 6 +- .../app/entities/query_fields_mongo_test.go | 18 -- server/internal/app/helper.go | 11 + .../app/repositories/core_dumps_repository.go | 4 +- .../mock/core_dumps_repository.go | 37 ++- .../applications_repository.go | 10 +- .../applications_repository_test.go | 51 ++-- .../core_dumps_repository.go | 46 ++-- .../core_dumps_repository_test.go | 218 ++++++++++++++---- .../mongodb_repository/helpers.go | 11 - .../mongo_options}/query_fields_mongo.go | 2 +- .../mongo_options/query_fields_mongo_test.go | 82 +++++++ .../app/services/core_dumps_service.go | 19 +- 18 files changed, 432 insertions(+), 127 deletions(-) delete mode 100644 server/internal/app/entities/query_fields_mongo_test.go create mode 100644 server/internal/app/helper.go delete mode 100644 server/internal/app/repositories/mongodb_repository/helpers.go rename server/internal/app/{entities => repositories/mongodb_repository/mongo_options}/query_fields_mongo.go (97%) create mode 100644 server/internal/app/repositories/mongodb_repository/mongo_options/query_fields_mongo_test.go diff --git a/server/Makefile b/server/Makefile index 2a185a8..b5fdba5 100644 --- a/server/Makefile +++ b/server/Makefile @@ -19,3 +19,4 @@ lint: run: @export CRASHER_SERVER_ADDRESS=:8080 @go run cmd/crasher/main.go + diff --git a/server/cmd/crasher/main.go b/server/cmd/crasher/main.go index f71b1eb..b3f7ca7 100644 --- a/server/cmd/crasher/main.go +++ b/server/cmd/crasher/main.go @@ -7,6 +7,7 @@ import ( "server/internal/app/controllers" "server/internal/app/repositories/mongodb_repository" "server/internal/app/services" + "strconv" "github.com/gorilla/mux" "go.mongodb.org/mongo-driver/mongo" @@ -45,8 +46,16 @@ func main() { } }() - appsRepo := mongodb_repository.NewApplicationsRepository(dbClient, logger) - coreDumpsRepo := mongodb_repository.NewCoreDumpsRepository(dbClient, logger) + timeout, err := strconv.Atoi(app.CtxTimeout) + if err != nil { + logger.Fatal( + "failed to parse timeout env", + zap.Error(err), + ) + } + + appsRepo := mongodb_repository.NewApplicationsRepository(dbClient, logger, timeout) + coreDumpsRepo := mongodb_repository.NewCoreDumpsRepository(dbClient, logger,timeout) appsService := services.NewApplicationsService(appsRepo, logger) coreDumpsService := services.NewCoreDumpsService(coreDumpsRepo, logger) diff --git a/server/internal/app/configuration.go b/server/internal/app/configuration.go index 7683c23..6106c39 100644 --- a/server/internal/app/configuration.go +++ b/server/internal/app/configuration.go @@ -4,7 +4,7 @@ import "os" var ( ServerAddress = os.Getenv("CRASHER_SERVER_ADDRESS") - CtxTimeout = os.Getenv("CRASHER_DATABASE_TIMEOUTgit") + CtxTimeout = parseEnvOrDefaultValue("CRASHER_DATABASE_TIMEOUT", "5") DatabaseAddress = os.Getenv("CRASHER_DATABASE_ADDRESS") DatabaseUsername = os.Getenv("CRASHER_DATABASE_USERNAME") DatabasePassword = os.Getenv("CRASHER_DATABASE_PASSWORD") diff --git a/server/internal/app/entities/core_dump.go b/server/internal/app/entities/core_dump.go index 65ed6c5..403b983 100644 --- a/server/internal/app/entities/core_dump.go +++ b/server/internal/app/entities/core_dump.go @@ -2,8 +2,6 @@ package entities import ( "time" - - "go.mongodb.org/mongo-driver/bson/primitive" ) type CoreDumpStatus int @@ -16,16 +14,16 @@ const ( ) type CoreDump struct { - ID primitive.ObjectID + ID string OsInfo *OSInfo AppInfo *AppInfo Status CoreDumpStatus Data string Timestamp time.Time - Extensions []Extensions + Extensions []Extension } -type Extensions struct { +type Extension struct { Key string Value string } @@ -54,6 +52,14 @@ func (c *CoreDump) GetTimestamp() time.Time { return c.Timestamp } +func (c *CoreDump) GetExtension(index int) *Extension { + return &c.Extensions[index] +} + +func (c *CoreDump) GetExtensions() *[]Extension { + return &c.Extensions +} + func (c *CoreDump) SetOSInfo(info *OSInfo) { c.OsInfo = info } @@ -73,3 +79,8 @@ func (c *CoreDump) SetData(data string) { func (c *CoreDump) SetTimestamp(timestamp time.Time) { c.Timestamp = timestamp } + +func (c *CoreDump) SetExtensions(key, value string) { + extension := &Extension{Key: key, Value: value} + c.Extensions = append(c.Extensions, *extension) +} diff --git a/server/internal/app/entities/core_dump_test.go b/server/internal/app/entities/core_dump_test.go index 53c23a5..0a11551 100644 --- a/server/internal/app/entities/core_dump_test.go +++ b/server/internal/app/entities/core_dump_test.go @@ -21,16 +21,23 @@ func TestCoreDump(t *testing.T) { timestamp := time.Now() status := SolvedCoreDumpStatus data := "server/internal/app/entities/core_dump_test.go@TestCoreDump:100" + extension := &Extension{ + Key: "key", + Value: "value", + } coreDump.SetOSInfo(osInfo) coreDump.SetAppInfo(appInfo) coreDump.SetTimestamp(timestamp) coreDump.SetStatus(status) coreDump.SetData(data) + coreDump.SetExtensions(extension.Key, extension.Value) assert.Equal(t, osInfo, coreDump.GetOSInfo()) assert.Equal(t, appInfo, coreDump.GetAppInfo()) assert.Equal(t, timestamp, coreDump.GetTimestamp()) assert.Equal(t, status, coreDump.GetStatus()) assert.Equal(t, data, coreDump.GetData()) + assert.Equal(t, extension, coreDump.GetExtension(0)) + assert.Equal(t, true, len(*coreDump.GetExtensions()) > 0) } diff --git a/server/internal/app/entities/os_info.go b/server/internal/app/entities/os_info.go index 59ce8c6..71f6822 100644 --- a/server/internal/app/entities/os_info.go +++ b/server/internal/app/entities/os_info.go @@ -1,9 +1,9 @@ package entities type OSInfo struct { - Name string - Version string - Architecture string + Name string + Version string + Architecture string } func NewOSInfo() *OSInfo { diff --git a/server/internal/app/entities/query_fields_mongo_test.go b/server/internal/app/entities/query_fields_mongo_test.go deleted file mode 100644 index 454ef96..0000000 --- a/server/internal/app/entities/query_fields_mongo_test.go +++ /dev/null @@ -1,18 +0,0 @@ -package entities - -import ( - "testing" - - "github.com/stretchr/testify/require" - "go.mongodb.org/mongo-driver/bson" - "go.mongodb.org/mongo-driver/mongo/options" -) - -func Test_SetApplication(t *testing.T) { - filter := bson.M{} - options := options.Find() - setter := SetApplication("app") - setter(filter, options) - res := filter["appinfo.name"] - require.Equal(t, "app", res) -} diff --git a/server/internal/app/helper.go b/server/internal/app/helper.go new file mode 100644 index 0000000..ac9db48 --- /dev/null +++ b/server/internal/app/helper.go @@ -0,0 +1,11 @@ +package app + +import "os" + +func parseEnvOrDefaultValue(env, defaultValue string) string { + parsedEnv := os.Getenv(env) + if parsedEnv == "" { + return defaultValue + } + return parsedEnv +} diff --git a/server/internal/app/repositories/core_dumps_repository.go b/server/internal/app/repositories/core_dumps_repository.go index 21d5c98..aa8fd06 100644 --- a/server/internal/app/repositories/core_dumps_repository.go +++ b/server/internal/app/repositories/core_dumps_repository.go @@ -5,8 +5,10 @@ import ( ) type CoreDumpsRepository interface { - GetCoreDumps(setters ...entities.OptionsMongo) ([]entities.CoreDump, error) + GetCoreDumps(parameters ...interface{}) ([]entities.CoreDump, error) + GetCoreDumpByID(id string) (entities.CoreDump, error) AddCoreDump(coreDump entities.CoreDump) error + UpdateCoreDump(parameters interface{}) error DeleteCoreDump(id string) error DeleteAllCoreDumps() error } diff --git a/server/internal/app/repositories/mock/core_dumps_repository.go b/server/internal/app/repositories/mock/core_dumps_repository.go index 9590321..d89f31f 100644 --- a/server/internal/app/repositories/mock/core_dumps_repository.go +++ b/server/internal/app/repositories/mock/core_dumps_repository.go @@ -76,11 +76,26 @@ func (mr *MockCoreDumpsRepositoryMockRecorder) DeleteCoreDump(id interface{}) *g return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteCoreDump", reflect.TypeOf((*MockCoreDumpsRepository)(nil).DeleteCoreDump), id) } +// GetCoreDumpByID mocks base method. +func (m *MockCoreDumpsRepository) GetCoreDumpByID(id string) (entities.CoreDump, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetCoreDumpByID", id) + ret0, _ := ret[0].(entities.CoreDump) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetCoreDumpByID indicates an expected call of GetCoreDumpByID. +func (mr *MockCoreDumpsRepositoryMockRecorder) GetCoreDumpByID(id interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetCoreDumpByID", reflect.TypeOf((*MockCoreDumpsRepository)(nil).GetCoreDumpByID), id) +} + // GetCoreDumps mocks base method. -func (m *MockCoreDumpsRepository) GetCoreDumps(setters ...entities.OptionsMongo) ([]entities.CoreDump, error) { +func (m *MockCoreDumpsRepository) GetCoreDumps(parameters ...interface{}) ([]entities.CoreDump, error) { m.ctrl.T.Helper() varargs := []interface{}{} - for _, a := range setters { + for _, a := range parameters { varargs = append(varargs, a) } ret := m.ctrl.Call(m, "GetCoreDumps", varargs...) @@ -90,7 +105,21 @@ func (m *MockCoreDumpsRepository) GetCoreDumps(setters ...entities.OptionsMongo) } // GetCoreDumps indicates an expected call of GetCoreDumps. -func (mr *MockCoreDumpsRepositoryMockRecorder) GetCoreDumps(setters ...interface{}) *gomock.Call { +func (mr *MockCoreDumpsRepositoryMockRecorder) GetCoreDumps(parameters ...interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetCoreDumps", reflect.TypeOf((*MockCoreDumpsRepository)(nil).GetCoreDumps), parameters...) +} + +// UpdateCoreDump mocks base method. +func (m *MockCoreDumpsRepository) UpdateCoreDump(coreDump entities.CoreDump) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "UpdateCoreDump", coreDump) + ret0, _ := ret[0].(error) + return ret0 +} + +// UpdateCoreDump indicates an expected call of UpdateCoreDump. +func (mr *MockCoreDumpsRepositoryMockRecorder) UpdateCoreDump(coreDump interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetCoreDumps", reflect.TypeOf((*MockCoreDumpsRepository)(nil).GetCoreDumps), setters...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdateCoreDump", reflect.TypeOf((*MockCoreDumpsRepository)(nil).UpdateCoreDump), coreDump) } diff --git a/server/internal/app/repositories/mongodb_repository/applications_repository.go b/server/internal/app/repositories/mongodb_repository/applications_repository.go index bff6a68..3abcd97 100644 --- a/server/internal/app/repositories/mongodb_repository/applications_repository.go +++ b/server/internal/app/repositories/mongodb_repository/applications_repository.go @@ -20,16 +20,10 @@ type ApplicationsRepository struct { var _ repositories.ApplicationsRepository = (*ApplicationsRepository)(nil) -func NewApplicationsRepository(db *mongo.Client, l *zap.Logger) *ApplicationsRepository { +func NewApplicationsRepository(db *mongo.Client, l *zap.Logger, timeout int) *ApplicationsRepository { mongoDB := db.Database("crasher") collection := mongoDB.Collection("coredumps") - timeout, err := ParseCtxTimeoutEnv() - if err != nil { - l.Fatal( - "failed to parse ctx timeout env", - zap.Error(err), - ) - } + return &ApplicationsRepository{ dbClient: db, collection: collection, diff --git a/server/internal/app/repositories/mongodb_repository/applications_repository_test.go b/server/internal/app/repositories/mongodb_repository/applications_repository_test.go index ca94850..58f9093 100644 --- a/server/internal/app/repositories/mongodb_repository/applications_repository_test.go +++ b/server/internal/app/repositories/mongodb_repository/applications_repository_test.go @@ -4,18 +4,31 @@ import ( "errors" mock_repositories "server/internal/app/repositories/mock" "testing" + "time" "github.com/golang/mock/gomock" "github.com/stretchr/testify/require" + "go.mongodb.org/mongo-driver/mongo" + "go.uber.org/zap" ) +func TestNewApplicationsRepository(t *testing.T) { + ctxTimeout := 5 + applicationsRepository := NewApplicationsRepository(&mongo.Client{}, &zap.Logger{}, ctxTimeout) + + require.Equal(t, "crasher", applicationsRepository.collection.Database().Name()) + require.Equal(t, "coredumps", applicationsRepository.collection.Name()) + require.Equal(t, &zap.Logger{}, applicationsRepository.logger) + require.Equal(t, ctxTimeout, applicationsRepository.timeout) +} func TestGetApplicationNames(t *testing.T) { - many := []string{"app1", "app2", "app3"} - one := []string{"app1"} - empty := []string{} + t.Parallel() + + slowResponse := time.Second * 6 c := gomock.NewController(t) defer c.Finish() + r := mock_repositories.NewMockApplicationsRepository(c) tests := []struct { name string @@ -24,41 +37,51 @@ func TestGetApplicationNames(t *testing.T) { error error }{ { - name: "ok - many elements", + name: "get many application names", stubs: func(r *mock_repositories.MockApplicationsRepository, slice []string) { r.EXPECT().GetApplicationNames().Return(slice, nil) }, - slice: many, + slice: []string{"app1", "app2", "app3"}, error: nil, }, { - name: "ok - one app", + name: "get one application name", stubs: func(r *mock_repositories.MockApplicationsRepository, slice []string) { r.EXPECT().GetApplicationNames().Return(slice, nil) }, - slice: one, + slice: []string{"app1"}, error: nil, }, { - name: "ok - empty slice", + name: "get empty application names", stubs: func(r *mock_repositories.MockApplicationsRepository, slice []string) { r.EXPECT().GetApplicationNames().Return(slice, nil) }, - slice: empty, + slice: nil, error: nil, }, { - name: "error", + name: "get error while getting application names", + stubs: func(r *mock_repositories.MockApplicationsRepository, slice []string) { + r.EXPECT().GetApplicationNames().Return(slice, errors.New("error")) + }, + slice: nil, + error: errors.New("error"), + }, + { + name: "get timeout error while getting application names", stubs: func(r *mock_repositories.MockApplicationsRepository, slice []string) { - r.EXPECT().GetApplicationNames().Return(slice, errors.New("error getting application names")) + r.EXPECT().GetApplicationNames().DoAndReturn(func() ([]string, error) { + time.Sleep(slowResponse) + return slice, errors.New("error") + }) }, - slice: empty, - error: errors.New("error getting application names"), + slice: nil, + error: errors.New("error"), }, } for _, test := range tests { t.Run(test.name, func(t *testing.T) { - r := mock_repositories.NewMockApplicationsRepository(c) test.stubs(r, test.slice) result, err := r.GetApplicationNames() diff --git a/server/internal/app/repositories/mongodb_repository/core_dumps_repository.go b/server/internal/app/repositories/mongodb_repository/core_dumps_repository.go index f635a73..05a2f09 100644 --- a/server/internal/app/repositories/mongodb_repository/core_dumps_repository.go +++ b/server/internal/app/repositories/mongodb_repository/core_dumps_repository.go @@ -4,10 +4,10 @@ import ( "context" "server/internal/app/entities" "server/internal/app/repositories" + "server/internal/app/repositories/mongodb_repository/mongo_options" "time" "go.mongodb.org/mongo-driver/bson" - "go.mongodb.org/mongo-driver/bson/primitive" "go.mongodb.org/mongo-driver/mongo" "go.mongodb.org/mongo-driver/mongo/options" "go.uber.org/zap" @@ -22,16 +22,10 @@ type CoreDumpsRepository struct { var _ repositories.CoreDumpsRepository = (*CoreDumpsRepository)(nil) -func NewCoreDumpsRepository(db *mongo.Client, l *zap.Logger) *CoreDumpsRepository { +func NewCoreDumpsRepository(db *mongo.Client, l *zap.Logger, timeout int) *CoreDumpsRepository { mongoDB := db.Database("crasher") collection := mongoDB.Collection("coredumps") - timeout, err := ParseCtxTimeoutEnv() - if err != nil { - l.Fatal( - "failed to parse ctx timeout env", - zap.Error(err), - ) - } + return &CoreDumpsRepository{ dbClient: db, collection: collection, @@ -40,13 +34,22 @@ func NewCoreDumpsRepository(db *mongo.Client, l *zap.Logger) *CoreDumpsRepositor } } -func (r *CoreDumpsRepository) GetCoreDumps(setters ...entities.OptionsMongo) ([]entities.CoreDump, error) { +func (r *CoreDumpsRepository) GetCoreDumps(parameters ...interface{}) ([]entities.CoreDump, error) { + setters := make([]mongo_options.OptionsMongo, len(parameters)) + for _, setter := range parameters { + if isMongo, ok := setter.(mongo_options.OptionsMongo); ok { + setters = append(setters, isMongo) + } + } + options := options.Find() filter := bson.M{} for _, setter := range setters { setter(filter, options) } + var result []entities.CoreDump + ctx, cancel := context.WithTimeout(context.Background(), time.Duration(r.timeout)*time.Second) defer cancel() @@ -54,32 +57,45 @@ func (r *CoreDumpsRepository) GetCoreDumps(setters ...entities.OptionsMongo) ([] if err != nil { return nil, err } + err = cur.All(ctx, &result) return result, err } +func (r *CoreDumpsRepository) GetCoreDumpByID(id string) (entities.CoreDump, error) { + var coreDump entities.CoreDump + + ctx, cancel := context.WithTimeout(context.Background(), time.Duration(r.timeout)*time.Second) + defer cancel() + + err := r.collection.FindOne(ctx, bson.D{{Key: "id", Value: id}}).Decode(&coreDump) + return coreDump, err +} + +func (r *CoreDumpsRepository) UpdateCoreDump(parameters interface{}) error { + return nil +} + func (r *CoreDumpsRepository) AddCoreDump(coreDump entities.CoreDump) error { ctx, cancel := context.WithTimeout(context.Background(), time.Duration(r.timeout)*time.Second) defer cancel() + _, err := r.collection.InsertOne(ctx, coreDump) return err } func (r *CoreDumpsRepository) DeleteCoreDump(id string) error { - idHex, err := primitive.ObjectIDFromHex(id) - if err != nil { - return err - } ctx, cancel := context.WithTimeout(context.Background(), time.Duration(r.timeout)*time.Second) defer cancel() - _, err = r.collection.DeleteOne(ctx, bson.D{{Key: "_id", Value: idHex}}) + _, err := r.collection.DeleteOne(ctx, bson.D{{Key: "id", Value: id}}) return err } func (r *CoreDumpsRepository) DeleteAllCoreDumps() error { ctx, cancel := context.WithTimeout(context.Background(), time.Duration(r.timeout)*time.Second) defer cancel() + _, err := r.collection.DeleteMany(ctx, bson.D{}) return err } diff --git a/server/internal/app/repositories/mongodb_repository/core_dumps_repository_test.go b/server/internal/app/repositories/mongodb_repository/core_dumps_repository_test.go index 85b7706..2126b46 100644 --- a/server/internal/app/repositories/mongodb_repository/core_dumps_repository_test.go +++ b/server/internal/app/repositories/mongodb_repository/core_dumps_repository_test.go @@ -2,7 +2,7 @@ package mongodb_repository import ( "errors" - "math/rand" + "fmt" "server/internal/app/entities" mock_repositories "server/internal/app/repositories/mock" "testing" @@ -10,12 +10,30 @@ import ( "github.com/golang/mock/gomock" "github.com/stretchr/testify/require" + "go.mongodb.org/mongo-driver/mongo" + "go.uber.org/zap" ) -func Test_AddCoreDump(t *testing.T) { +func TestNewCoreDumpsRepository(t *testing.T) { t.Parallel() + + ctxTimeout := 5 + + applicationsRepository := NewApplicationsRepository(&mongo.Client{}, &zap.Logger{}, ctxTimeout) + + require.Equal(t, "crasher", applicationsRepository.collection.Database().Name()) + require.Equal(t, "coredumps", applicationsRepository.collection.Name()) + require.Equal(t, &zap.Logger{}, applicationsRepository.logger) + require.Equal(t, ctxTimeout, applicationsRepository.timeout) +} +func TestAddCoreDump(t *testing.T) { + t.Parallel() + + slowResponse := time.Second * 6 + c := gomock.NewController(t) defer c.Finish() + r := mock_repositories.NewMockCoreDumpsRepository(c) randomDump := generateRandomSliceOfCoreDumps(1) tests := []struct { @@ -25,7 +43,7 @@ func Test_AddCoreDump(t *testing.T) { error error }{ { - name: "ok", + name: "add dump", dump: randomDump[0], stubs: func(r *mock_repositories.MockCoreDumpsRepository, dump entities.CoreDump) { r.EXPECT().AddCoreDump(dump).Return(nil) @@ -33,39 +51,44 @@ func Test_AddCoreDump(t *testing.T) { error: nil, }, { - name: "error", + name: "add dump error", dump: entities.CoreDump{}, stubs: func(r *mock_repositories.MockCoreDumpsRepository, dump entities.CoreDump) { - r.EXPECT().AddCoreDump(dump).Return(errors.New("error adding core dump")) + r.EXPECT().AddCoreDump(dump).Return(errors.New("error")) }, - error: errors.New("error adding core dump"), + error: errors.New("error"), }, { - name: "timeout", - dump: entities.CoreDump{}, + name: "add dump timeout error", + dump: randomDump[0], stubs: func(r *mock_repositories.MockCoreDumpsRepository, dump entities.CoreDump) { - r.EXPECT().AddCoreDump(dump).Return(errors.New("timeout")) - + r.EXPECT().AddCoreDump(dump).DoAndReturn(func(dump entities.CoreDump) error { + time.Sleep(slowResponse) + return errors.New("error") + }) }, - error: errors.New("timeout"), + error: errors.New("error"), }, } for _, test := range tests { t.Run(test.name, func(t *testing.T) { - r := mock_repositories.NewMockCoreDumpsRepository(c) - test.stubs(r, test.dump) + err := r.AddCoreDump(test.dump) require.Equal(t, test.error, err) }) } } -func Test_GetCoreDump(t *testing.T) { +func TestGetCoreDumps(t *testing.T) { t.Parallel() + + slowResponse := time.Second * 6 + c := gomock.NewController(t) defer c.Finish() + r := mock_repositories.NewMockCoreDumpsRepository(c) sliceOfDumps := generateRandomSliceOfCoreDumps(5) @@ -76,7 +99,7 @@ func Test_GetCoreDump(t *testing.T) { error error }{ { - name: "ok", + name: "get core dumps", stubs: func(r *mock_repositories.MockCoreDumpsRepository) { r.EXPECT().GetCoreDumps().Return(sliceOfDumps, nil) }, @@ -84,17 +107,26 @@ func Test_GetCoreDump(t *testing.T) { error: nil, }, { - name: "error", + name: "get core dumps error", stubs: func(r *mock_repositories.MockCoreDumpsRepository) { - r.EXPECT().GetCoreDumps().Return(nil, errors.New("error getting dumps")) + r.EXPECT().GetCoreDumps().Return(nil, errors.New("error")) }, dumps: nil, - error: errors.New("error getting dumps"), + error: errors.New("error"), + }, + { + name: "get core dumps error timeout", + stubs: func(r *mock_repositories.MockCoreDumpsRepository) { + r.EXPECT().GetCoreDumps().Do(func(options ...interface{}) { + time.Sleep(slowResponse) + }).Return(nil, errors.New("error")) + }, + dumps: nil, + error: errors.New("error"), }, } for _, test := range tests { t.Run(test.name, func(t *testing.T) { - r := mock_repositories.NewMockCoreDumpsRepository(c) test.stubs(r) res, err := r.GetCoreDumps() @@ -104,10 +136,69 @@ func Test_GetCoreDump(t *testing.T) { } } -func Test_DeleteCoreDump(t *testing.T) { +func TestGetCoreDumpByID(t *testing.T) { + t.Parallel() + + slowResponse := time.Second * 6 + + c := gomock.NewController(t) + defer c.Finish() + r := mock_repositories.NewMockCoreDumpsRepository(c) + + sliceOfDumps := generateRandomSliceOfCoreDumps(1) + + tests := []struct { + name string + stubs func(store *mock_repositories.MockCoreDumpsRepository, id string) + dumpID string + error error + }{ + { + name: "get core dump by id", + stubs: func(r *mock_repositories.MockCoreDumpsRepository, id string) { + r.EXPECT().GetCoreDumpByID(id).Return(sliceOfDumps[0], nil) + }, + dumpID: sliceOfDumps[0].ID, + error: nil, + }, + { + name: "get core dump by id error", + stubs: func(r *mock_repositories.MockCoreDumpsRepository, id string) { + r.EXPECT().GetCoreDumpByID(id).Return(entities.CoreDump{}, errors.New("error")) + }, + dumpID: "", + error: errors.New("error"), + }, + { + name: "get core dump by id error timeout", + stubs: func(r *mock_repositories.MockCoreDumpsRepository, id string) { + r.EXPECT().GetCoreDumpByID(id).Do(func(id string) { + time.Sleep(slowResponse) + }).Return(entities.CoreDump{}, errors.New("error")) + }, + dumpID: "", + error: errors.New("error"), + }, + } + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + test.stubs(r, test.dumpID) + + res, err := r.GetCoreDumpByID(test.dumpID) + require.Equal(t, test.error, err) + require.Equal(t, test.dumpID, res.ID) + }) + } +} + +func TestDeleteCoreDump(t *testing.T) { t.Parallel() + + slowResponse := time.Second * 6 + c := gomock.NewController(t) defer c.Finish() + r := mock_repositories.NewMockCoreDumpsRepository(c) tests := []struct { name string @@ -116,7 +207,7 @@ func Test_DeleteCoreDump(t *testing.T) { error error }{ { - name: "ok", + name: "delete dump", stubs: func(r *mock_repositories.MockCoreDumpsRepository, dumpID string) { r.EXPECT().DeleteCoreDump(dumpID).Return(nil) }, @@ -124,17 +215,26 @@ func Test_DeleteCoreDump(t *testing.T) { error: nil, }, { - name: "error", + name: "delete dump error empty id", stubs: func(r *mock_repositories.MockCoreDumpsRepository, dumpID string) { - r.EXPECT().DeleteCoreDump(dumpID).Return(errors.New("error enter dump id")) + r.EXPECT().DeleteCoreDump(dumpID).Return(errors.New("error")) }, dumpID: "", - error: errors.New("error enter dump id"), + error: errors.New("error"), + }, + { + name: "delete dump timeout error", + stubs: func(r *mock_repositories.MockCoreDumpsRepository, dumpID string) { + r.EXPECT().DeleteCoreDump(dumpID).Do(func(dumpID string) { + time.Sleep(slowResponse) + }).Return(errors.New("error")) + }, + dumpID: "", + error: errors.New("error"), }, } for _, test := range tests { t.Run(test.name, func(t *testing.T) { - r := mock_repositories.NewMockCoreDumpsRepository(c) test.stubs(r, test.dumpID) err := r.DeleteCoreDump(test.dumpID) @@ -143,12 +243,50 @@ func Test_DeleteCoreDump(t *testing.T) { } } -func init() { - rand.Seed(time.Now().Unix()) +func TestDeleteAllCoreDump(t *testing.T) { + t.Parallel() + + slowResponse := time.Second * 6 + + c := gomock.NewController(t) + defer c.Finish() + + r := mock_repositories.NewMockCoreDumpsRepository(c) + + tests := []struct { + name string + stubs func(store *mock_repositories.MockCoreDumpsRepository) + error error + }{ + { + name: "delete all dumps", + stubs: func(r *mock_repositories.MockCoreDumpsRepository) { + r.EXPECT().DeleteAllCoreDumps().Return(nil) + }, + error: nil, + }, + { + name: "delete dump timeout error", + stubs: func(r *mock_repositories.MockCoreDumpsRepository) { + r.EXPECT().DeleteAllCoreDumps().Do(func() { + time.Sleep(slowResponse) + }).Return(errors.New("error")) + }, + error: errors.New("error"), + }, + } + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + test.stubs(r) + + err := r.DeleteAllCoreDumps() + require.Equal(t, test.error, err) + }) + } } func generateRandomSliceOfCoreDumps(quantity int) []entities.CoreDump { - type asInfo struct { + type osInfo struct { Name string Arch string Version string @@ -158,7 +296,7 @@ func generateRandomSliceOfCoreDumps(quantity int) []entities.CoreDump { Name string Version string } - osArr := []asInfo{ + osArr := []osInfo{ { Name: "linux", Arch: "amd64", @@ -185,7 +323,7 @@ func generateRandomSliceOfCoreDumps(quantity int) []entities.CoreDump { Version: "10.0.1", }, } - appArr := []appInfo{ + appsArr := []appInfo{ { Name: "financial", Version: "v0.0.1", @@ -214,27 +352,23 @@ func generateRandomSliceOfCoreDumps(quantity int) []entities.CoreDump { var result []entities.CoreDump for i := 0; i < quantity; i++ { coreDump := entities.NewCoreDump() - randomIdxOs := rand.Intn(len(osArr)) - randomIdxApp := rand.Intn(len(appArr)) - + coreDump.ID = fmt.Sprint(i) osInfo := entities.NewOSInfo() - osInfo.SetName(osArr[randomIdxOs].Name) - osInfo.SetArchitecture(osArr[randomIdxOs].Arch) - osInfo.SetVersion(osArr[randomIdxOs].Version) + osInfo.SetName(osArr[i].Name) + osInfo.SetArchitecture(osArr[i].Arch) + osInfo.SetVersion(osArr[i].Version) coreDump.SetOSInfo(osInfo) appInfo := entities.NewAppInfo() - appInfo.SetName(appArr[randomIdxApp].Name) - appInfo.SetProgrammingLanguage(entities.ProgrammingLanguage(rand.Intn(4))) - appInfo.SetVersion(appArr[randomIdxApp].Version) + appInfo.SetName(appsArr[i].Name) + appInfo.SetProgrammingLanguage(entities.ProgrammingLanguage(1)) + appInfo.SetVersion(appsArr[i].Version) coreDump.SetAppInfo(appInfo) coreDump.SetStatus(1) coreDump.SetData(time.Now().Format("2006-01-02")) - randomTime := rand.Int63n(time.Now().Unix()-94608000) + 94608000 - randomNow := time.Unix(randomTime, 0) - coreDump.SetTimestamp(randomNow) + coreDump.SetTimestamp(time.Unix(1663511325, 0)) result = append(result, *coreDump) } diff --git a/server/internal/app/repositories/mongodb_repository/helpers.go b/server/internal/app/repositories/mongodb_repository/helpers.go deleted file mode 100644 index 8ef6c77..0000000 --- a/server/internal/app/repositories/mongodb_repository/helpers.go +++ /dev/null @@ -1,11 +0,0 @@ -package mongodb_repository - -import ( - "server/internal/app" - "strconv" -) - -func ParseCtxTimeoutEnv() (int, error) { - ctxTimeout, err := strconv.Atoi(app.CtxTimeout) - return ctxTimeout, err -} diff --git a/server/internal/app/entities/query_fields_mongo.go b/server/internal/app/repositories/mongodb_repository/mongo_options/query_fields_mongo.go similarity index 97% rename from server/internal/app/entities/query_fields_mongo.go rename to server/internal/app/repositories/mongodb_repository/mongo_options/query_fields_mongo.go index 35d0c50..9083ff1 100644 --- a/server/internal/app/entities/query_fields_mongo.go +++ b/server/internal/app/repositories/mongodb_repository/mongo_options/query_fields_mongo.go @@ -1,4 +1,4 @@ -package entities +package mongo_options import ( "go.mongodb.org/mongo-driver/bson" diff --git a/server/internal/app/repositories/mongodb_repository/mongo_options/query_fields_mongo_test.go b/server/internal/app/repositories/mongodb_repository/mongo_options/query_fields_mongo_test.go new file mode 100644 index 0000000..c17e90f --- /dev/null +++ b/server/internal/app/repositories/mongodb_repository/mongo_options/query_fields_mongo_test.go @@ -0,0 +1,82 @@ +package mongo_options + +import ( + "testing" + "time" + + "github.com/stretchr/testify/require" + "go.mongodb.org/mongo-driver/bson" + "go.mongodb.org/mongo-driver/bson/primitive" + "go.mongodb.org/mongo-driver/mongo/options" +) + +func TestSetApplication(t *testing.T) { + filter := bson.M{} + require.Equal(t, 0, len(filter)) + + options := options.Find() + setter := SetApplication("app") + setter(filter, options) + res := filter["appinfo.name"] + + require.Equal(t, "app", res) + require.Equal(t, true, len(filter) > 0) +} + +func TestSetStartTimestamp(t *testing.T) { + filter := bson.M{} + require.Equal(t, 0, len(filter)) + + requiredDate := primitive.NewDateTimeFromTime(time.Now().AddDate(0, 0, -1)) + + options := options.Find() + setter := SetStartTimestamp(requiredDate) + setter(filter, options) + res := filter["timestamp"] + + require.Equal(t, primitive.M(primitive.M{"$gte": requiredDate}), res) + require.Equal(t, true, len(filter) > 0) +} + +func TestSetEndTimestamp(t *testing.T) { + filter := bson.M{} + require.Equal(t, 0, len(filter)) + + requiredDate := primitive.NewDateTimeFromTime(time.Now().AddDate(0, 0, 0)) + + options := options.Find() + setter := SetEndTimestamp(requiredDate) + setter(filter, options) + res := filter["timestamp"] + + require.Equal(t, primitive.M(primitive.M{"$lt": requiredDate}), res) + require.Equal(t, true, len(filter) > 0) +} + +func TestSetLimit(t *testing.T) { + filter := bson.M{} + require.Equal(t, 0, len(filter)) + + options := options.Find() + require.Equal(t, true, options.Limit == nil) + + setter := SetLimit(1) + setter(filter, options) + + require.Equal(t, int64(1), *options.Limit) + require.Equal(t, false, options == nil) +} + +func TestSetOffeset(t *testing.T) { + filter := bson.M{} + require.Equal(t, 0, len(filter)) + + options := options.Find() + require.Equal(t, true, options.Skip == nil) + + setter := SetOffset(1) + setter(filter, options) + + require.Equal(t, int64(1), *options.Skip) + require.Equal(t, false, options == nil) +} diff --git a/server/internal/app/services/core_dumps_service.go b/server/internal/app/services/core_dumps_service.go index 9b9ee38..95f8ff2 100644 --- a/server/internal/app/services/core_dumps_service.go +++ b/server/internal/app/services/core_dumps_service.go @@ -8,9 +8,12 @@ import ( ) type CoreDumpsService interface { - GetCoreDumps() ([]entities.CoreDump, error) + GetCoreDumps(parameters ...interface{}) ([]entities.CoreDump, error) + GetCoreDumpByID(id string) (entities.CoreDump, error) AddCoreDump(coreDump entities.CoreDump) error + UpdateCoreDump(parameters interface{}) error DeleteCoreDump(id string) error + DeleteAllCoreDumps() error } type CoreDumpServiceImpl struct { @@ -25,14 +28,26 @@ func NewCoreDumpsService(r repositories.CoreDumpsRepository, l *zap.Logger) Core } } -func (s *CoreDumpServiceImpl) GetCoreDumps() ([]entities.CoreDump, error) { +func (s *CoreDumpServiceImpl) GetCoreDumps(parameters ...interface{}) ([]entities.CoreDump, error) { return nil, nil } +func (s *CoreDumpServiceImpl) GetCoreDumpByID(id string) (entities.CoreDump, error) { + return entities.CoreDump{}, nil +} + func (s *CoreDumpServiceImpl) AddCoreDump(coreDump entities.CoreDump) error { return nil } +func (r *CoreDumpServiceImpl) UpdateCoreDump(parameters interface{}) error { + return nil +} + func (s *CoreDumpServiceImpl) DeleteCoreDump(id string) error { return nil } + +func (s *CoreDumpServiceImpl) DeleteAllCoreDumps() error { + return nil +} From ed81e3f60fafca8f416eb3483068c128b789edbe Mon Sep 17 00:00:00 2001 From: srjchsv Date: Mon, 19 Sep 2022 20:04:53 +0300 Subject: [PATCH 3/3] feat: CoreDumpsRepository implementation and test --- server/cmd/crasher/main.go | 11 ++- server/internal/app/configuration.go | 2 +- server/internal/app/entities/core_dump.go | 16 ++-- .../internal/app/entities/core_dump_test.go | 8 +- server/internal/app/helper.go | 2 +- .../app/repositories/core_dumps_repository.go | 2 +- .../applications_repository.go | 14 ++-- .../applications_repository_test.go | 24 +++--- .../core_dumps_repository.go | 35 +++++---- .../core_dumps_repository_test.go | 78 +++++++++---------- .../mongo_configs/configuration.go | 6 ++ .../mongo_options/query_fields_mongo_test.go | 31 ++++---- .../app/services/core_dumps_service.go | 4 +- 13 files changed, 121 insertions(+), 112 deletions(-) create mode 100644 server/internal/app/repositories/mongodb_repository/mongo_configs/configuration.go diff --git a/server/cmd/crasher/main.go b/server/cmd/crasher/main.go index b3f7ca7..cde9533 100644 --- a/server/cmd/crasher/main.go +++ b/server/cmd/crasher/main.go @@ -8,6 +8,7 @@ import ( "server/internal/app/repositories/mongodb_repository" "server/internal/app/services" "strconv" + "time" "github.com/gorilla/mux" "go.mongodb.org/mongo-driver/mongo" @@ -46,7 +47,11 @@ func main() { } }() - timeout, err := strconv.Atoi(app.CtxTimeout) + if app.DatabaseTimeout == "" { + app.DatabaseTimeout = "5" + } + + timeoutInt, err := strconv.Atoi(app.DatabaseTimeout) if err != nil { logger.Fatal( "failed to parse timeout env", @@ -54,8 +59,10 @@ func main() { ) } + timeout := time.Duration(timeoutInt) * time.Second + appsRepo := mongodb_repository.NewApplicationsRepository(dbClient, logger, timeout) - coreDumpsRepo := mongodb_repository.NewCoreDumpsRepository(dbClient, logger,timeout) + coreDumpsRepo := mongodb_repository.NewCoreDumpsRepository(dbClient, logger, timeout) appsService := services.NewApplicationsService(appsRepo, logger) coreDumpsService := services.NewCoreDumpsService(coreDumpsRepo, logger) diff --git a/server/internal/app/configuration.go b/server/internal/app/configuration.go index 6106c39..4fc4624 100644 --- a/server/internal/app/configuration.go +++ b/server/internal/app/configuration.go @@ -4,7 +4,7 @@ import "os" var ( ServerAddress = os.Getenv("CRASHER_SERVER_ADDRESS") - CtxTimeout = parseEnvOrDefaultValue("CRASHER_DATABASE_TIMEOUT", "5") + DatabaseTimeout = os.Getenv("CRASHER_DATABASE_TIMEOUT") DatabaseAddress = os.Getenv("CRASHER_DATABASE_ADDRESS") DatabaseUsername = os.Getenv("CRASHER_DATABASE_USERNAME") DatabasePassword = os.Getenv("CRASHER_DATABASE_PASSWORD") diff --git a/server/internal/app/entities/core_dump.go b/server/internal/app/entities/core_dump.go index 403b983..4241573 100644 --- a/server/internal/app/entities/core_dump.go +++ b/server/internal/app/entities/core_dump.go @@ -20,10 +20,10 @@ type CoreDump struct { Status CoreDumpStatus Data string Timestamp time.Time - Extensions []Extension + Extensions []CoreDumpExtension } -type Extension struct { +type CoreDumpExtension struct { Key string Value string } @@ -52,12 +52,8 @@ func (c *CoreDump) GetTimestamp() time.Time { return c.Timestamp } -func (c *CoreDump) GetExtension(index int) *Extension { - return &c.Extensions[index] -} - -func (c *CoreDump) GetExtensions() *[]Extension { - return &c.Extensions +func (c *CoreDump) GetExtensions() []CoreDumpExtension { + return c.Extensions } func (c *CoreDump) SetOSInfo(info *OSInfo) { @@ -80,7 +76,7 @@ func (c *CoreDump) SetTimestamp(timestamp time.Time) { c.Timestamp = timestamp } -func (c *CoreDump) SetExtensions(key, value string) { - extension := &Extension{Key: key, Value: value} +func (c *CoreDump) AddExtensions(key, value string) { + extension := &CoreDumpExtension{Key: key, Value: value} c.Extensions = append(c.Extensions, *extension) } diff --git a/server/internal/app/entities/core_dump_test.go b/server/internal/app/entities/core_dump_test.go index 0a11551..1213023 100644 --- a/server/internal/app/entities/core_dump_test.go +++ b/server/internal/app/entities/core_dump_test.go @@ -21,7 +21,7 @@ func TestCoreDump(t *testing.T) { timestamp := time.Now() status := SolvedCoreDumpStatus data := "server/internal/app/entities/core_dump_test.go@TestCoreDump:100" - extension := &Extension{ + extension := &CoreDumpExtension{ Key: "key", Value: "value", } @@ -31,13 +31,13 @@ func TestCoreDump(t *testing.T) { coreDump.SetTimestamp(timestamp) coreDump.SetStatus(status) coreDump.SetData(data) - coreDump.SetExtensions(extension.Key, extension.Value) + coreDump.AddExtensions(extension.Key, extension.Value) assert.Equal(t, osInfo, coreDump.GetOSInfo()) assert.Equal(t, appInfo, coreDump.GetAppInfo()) assert.Equal(t, timestamp, coreDump.GetTimestamp()) assert.Equal(t, status, coreDump.GetStatus()) assert.Equal(t, data, coreDump.GetData()) - assert.Equal(t, extension, coreDump.GetExtension(0)) - assert.Equal(t, true, len(*coreDump.GetExtensions()) > 0) + assert.Equal(t, extension.Key, coreDump.GetExtensions()[0].Key) + assert.Equal(t, extension.Value, coreDump.GetExtensions()[0].Value) } diff --git a/server/internal/app/helper.go b/server/internal/app/helper.go index ac9db48..a6eb94c 100644 --- a/server/internal/app/helper.go +++ b/server/internal/app/helper.go @@ -2,7 +2,7 @@ package app import "os" -func parseEnvOrDefaultValue(env, defaultValue string) string { +func ParseEnvOrDefaultValue(env, defaultValue string) string { parsedEnv := os.Getenv(env) if parsedEnv == "" { return defaultValue diff --git a/server/internal/app/repositories/core_dumps_repository.go b/server/internal/app/repositories/core_dumps_repository.go index aa8fd06..b7be735 100644 --- a/server/internal/app/repositories/core_dumps_repository.go +++ b/server/internal/app/repositories/core_dumps_repository.go @@ -8,7 +8,7 @@ type CoreDumpsRepository interface { GetCoreDumps(parameters ...interface{}) ([]entities.CoreDump, error) GetCoreDumpByID(id string) (entities.CoreDump, error) AddCoreDump(coreDump entities.CoreDump) error - UpdateCoreDump(parameters interface{}) error + UpdateCoreDump(parameters ...interface{}) error DeleteCoreDump(id string) error DeleteAllCoreDumps() error } diff --git a/server/internal/app/repositories/mongodb_repository/applications_repository.go b/server/internal/app/repositories/mongodb_repository/applications_repository.go index 3abcd97..d817702 100644 --- a/server/internal/app/repositories/mongodb_repository/applications_repository.go +++ b/server/internal/app/repositories/mongodb_repository/applications_repository.go @@ -4,6 +4,7 @@ import ( "context" "fmt" "server/internal/app/repositories" + "server/internal/app/repositories/mongodb_repository/mongo_configs" "time" "go.mongodb.org/mongo-driver/bson" @@ -15,14 +16,14 @@ type ApplicationsRepository struct { dbClient *mongo.Client collection *mongo.Collection logger *zap.Logger - timeout int + timeout time.Duration } var _ repositories.ApplicationsRepository = (*ApplicationsRepository)(nil) -func NewApplicationsRepository(db *mongo.Client, l *zap.Logger, timeout int) *ApplicationsRepository { - mongoDB := db.Database("crasher") - collection := mongoDB.Collection("coredumps") +func NewApplicationsRepository(db *mongo.Client, l *zap.Logger, timeout time.Duration) *ApplicationsRepository { + mongoDB := db.Database(mongo_configs.DBname) + collection := mongoDB.Collection(mongo_configs.CollectionName) return &ApplicationsRepository{ dbClient: db, @@ -33,15 +34,18 @@ func NewApplicationsRepository(db *mongo.Client, l *zap.Logger, timeout int) *Ap } func (r *ApplicationsRepository) GetApplicationNames() ([]string, error) { - ctx, cancel := context.WithTimeout(context.Background(), time.Duration(r.timeout)*time.Second) + ctx, cancel := context.WithTimeout(context.Background(), r.timeout) defer cancel() + res, err := r.collection.Distinct(ctx, "appinfo.name", bson.D{}) if err != nil { return nil, err } + applications := make([]string, len(res)) for i, v := range res { applications[i] = fmt.Sprint(v) } + return applications, nil } diff --git a/server/internal/app/repositories/mongodb_repository/applications_repository_test.go b/server/internal/app/repositories/mongodb_repository/applications_repository_test.go index 58f9093..0094d53 100644 --- a/server/internal/app/repositories/mongodb_repository/applications_repository_test.go +++ b/server/internal/app/repositories/mongodb_repository/applications_repository_test.go @@ -3,29 +3,29 @@ package mongodb_repository import ( "errors" mock_repositories "server/internal/app/repositories/mock" + "server/internal/app/repositories/mongodb_repository/mongo_configs" "testing" "time" "github.com/golang/mock/gomock" + "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "go.mongodb.org/mongo-driver/mongo" "go.uber.org/zap" ) func TestNewApplicationsRepository(t *testing.T) { - ctxTimeout := 5 + ctxTimeout := time.Duration(5) * time.Second applicationsRepository := NewApplicationsRepository(&mongo.Client{}, &zap.Logger{}, ctxTimeout) - require.Equal(t, "crasher", applicationsRepository.collection.Database().Name()) - require.Equal(t, "coredumps", applicationsRepository.collection.Name()) - require.Equal(t, &zap.Logger{}, applicationsRepository.logger) + require.Equal(t, mongo_configs.DBname, applicationsRepository.collection.Database().Name()) + require.Equal(t, mongo_configs.CollectionName, applicationsRepository.collection.Name()) + require.NotNil(t, applicationsRepository.logger) require.Equal(t, ctxTimeout, applicationsRepository.timeout) } func TestGetApplicationNames(t *testing.T) { t.Parallel() - slowResponse := time.Second * 6 - c := gomock.NewController(t) defer c.Finish() r := mock_repositories.NewMockApplicationsRepository(c) @@ -57,7 +57,7 @@ func TestGetApplicationNames(t *testing.T) { stubs: func(r *mock_repositories.MockApplicationsRepository, slice []string) { r.EXPECT().GetApplicationNames().Return(slice, nil) }, - slice: nil, + slice: []string{}, error: nil, }, { @@ -65,18 +65,18 @@ func TestGetApplicationNames(t *testing.T) { stubs: func(r *mock_repositories.MockApplicationsRepository, slice []string) { r.EXPECT().GetApplicationNames().Return(slice, errors.New("error")) }, - slice: nil, + slice: []string{}, error: errors.New("error"), }, { name: "get timeout error while getting application names", stubs: func(r *mock_repositories.MockApplicationsRepository, slice []string) { r.EXPECT().GetApplicationNames().DoAndReturn(func() ([]string, error) { - time.Sleep(slowResponse) + time.Sleep(6 * time.Second) return slice, errors.New("error") }) }, - slice: nil, + slice: []string{}, error: errors.New("error"), }, } @@ -85,8 +85,8 @@ func TestGetApplicationNames(t *testing.T) { test.stubs(r, test.slice) result, err := r.GetApplicationNames() - require.Equal(t, test.error, err) - require.Equal(t, len(test.slice), len(result)) + assert.Equal(t, test.error, err) + assert.Equal(t, len(test.slice), len(result)) }) } } diff --git a/server/internal/app/repositories/mongodb_repository/core_dumps_repository.go b/server/internal/app/repositories/mongodb_repository/core_dumps_repository.go index 05a2f09..8afa0e1 100644 --- a/server/internal/app/repositories/mongodb_repository/core_dumps_repository.go +++ b/server/internal/app/repositories/mongodb_repository/core_dumps_repository.go @@ -4,6 +4,7 @@ import ( "context" "server/internal/app/entities" "server/internal/app/repositories" + "server/internal/app/repositories/mongodb_repository/mongo_configs" "server/internal/app/repositories/mongodb_repository/mongo_options" "time" @@ -17,14 +18,14 @@ type CoreDumpsRepository struct { dbClient *mongo.Client collection *mongo.Collection logger *zap.Logger - timeout int + timeout time.Duration } var _ repositories.CoreDumpsRepository = (*CoreDumpsRepository)(nil) -func NewCoreDumpsRepository(db *mongo.Client, l *zap.Logger, timeout int) *CoreDumpsRepository { - mongoDB := db.Database("crasher") - collection := mongoDB.Collection("coredumps") +func NewCoreDumpsRepository(db *mongo.Client, l *zap.Logger, timeout time.Duration) *CoreDumpsRepository { + mongoDB := db.Database(mongo_configs.DBname) + collection := mongoDB.Collection(mongo_configs.CollectionName) return &CoreDumpsRepository{ dbClient: db, @@ -37,20 +38,21 @@ func NewCoreDumpsRepository(db *mongo.Client, l *zap.Logger, timeout int) *CoreD func (r *CoreDumpsRepository) GetCoreDumps(parameters ...interface{}) ([]entities.CoreDump, error) { setters := make([]mongo_options.OptionsMongo, len(parameters)) for _, setter := range parameters { - if isMongo, ok := setter.(mongo_options.OptionsMongo); ok { - setters = append(setters, isMongo) + if parameter, ok := setter.(mongo_options.OptionsMongo); ok { + setters = append(setters, parameter) } } options := options.Find() filter := bson.M{} + for _, setter := range setters { setter(filter, options) } var result []entities.CoreDump - ctx, cancel := context.WithTimeout(context.Background(), time.Duration(r.timeout)*time.Second) + ctx, cancel := context.WithTimeout(context.Background(), r.timeout) defer cancel() cur, err := r.collection.Find(ctx, filter) @@ -59,43 +61,48 @@ func (r *CoreDumpsRepository) GetCoreDumps(parameters ...interface{}) ([]entitie } err = cur.All(ctx, &result) + return result, err } func (r *CoreDumpsRepository) GetCoreDumpByID(id string) (entities.CoreDump, error) { - var coreDump entities.CoreDump - - ctx, cancel := context.WithTimeout(context.Background(), time.Duration(r.timeout)*time.Second) + ctx, cancel := context.WithTimeout(context.Background(), r.timeout) defer cancel() + var coreDump entities.CoreDump + err := r.collection.FindOne(ctx, bson.D{{Key: "id", Value: id}}).Decode(&coreDump) + return coreDump, err } -func (r *CoreDumpsRepository) UpdateCoreDump(parameters interface{}) error { +func (r *CoreDumpsRepository) UpdateCoreDump(parameters ...interface{}) error { return nil } func (r *CoreDumpsRepository) AddCoreDump(coreDump entities.CoreDump) error { - ctx, cancel := context.WithTimeout(context.Background(), time.Duration(r.timeout)*time.Second) + ctx, cancel := context.WithTimeout(context.Background(), r.timeout) defer cancel() _, err := r.collection.InsertOne(ctx, coreDump) + return err } func (r *CoreDumpsRepository) DeleteCoreDump(id string) error { - ctx, cancel := context.WithTimeout(context.Background(), time.Duration(r.timeout)*time.Second) + ctx, cancel := context.WithTimeout(context.Background(), r.timeout) defer cancel() _, err := r.collection.DeleteOne(ctx, bson.D{{Key: "id", Value: id}}) + return err } func (r *CoreDumpsRepository) DeleteAllCoreDumps() error { - ctx, cancel := context.WithTimeout(context.Background(), time.Duration(r.timeout)*time.Second) + ctx, cancel := context.WithTimeout(context.Background(), r.timeout) defer cancel() _, err := r.collection.DeleteMany(ctx, bson.D{}) + return err } diff --git a/server/internal/app/repositories/mongodb_repository/core_dumps_repository_test.go b/server/internal/app/repositories/mongodb_repository/core_dumps_repository_test.go index 2126b46..662e519 100644 --- a/server/internal/app/repositories/mongodb_repository/core_dumps_repository_test.go +++ b/server/internal/app/repositories/mongodb_repository/core_dumps_repository_test.go @@ -5,10 +5,12 @@ import ( "fmt" "server/internal/app/entities" mock_repositories "server/internal/app/repositories/mock" + "server/internal/app/repositories/mongodb_repository/mongo_configs" "testing" "time" "github.com/golang/mock/gomock" + "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "go.mongodb.org/mongo-driver/mongo" "go.uber.org/zap" @@ -17,25 +19,22 @@ import ( func TestNewCoreDumpsRepository(t *testing.T) { t.Parallel() - ctxTimeout := 5 + ctxTimeout := time.Duration(5) * time.Second + coredumpsRepository := NewCoreDumpsRepository(&mongo.Client{}, &zap.Logger{}, ctxTimeout) - applicationsRepository := NewApplicationsRepository(&mongo.Client{}, &zap.Logger{}, ctxTimeout) - - require.Equal(t, "crasher", applicationsRepository.collection.Database().Name()) - require.Equal(t, "coredumps", applicationsRepository.collection.Name()) - require.Equal(t, &zap.Logger{}, applicationsRepository.logger) - require.Equal(t, ctxTimeout, applicationsRepository.timeout) + require.Equal(t, mongo_configs.DBname, coredumpsRepository.collection.Database().Name()) + require.Equal(t, mongo_configs.CollectionName, coredumpsRepository.collection.Name()) + require.NotNil(t, coredumpsRepository.logger) + require.Equal(t, ctxTimeout, coredumpsRepository.timeout) } func TestAddCoreDump(t *testing.T) { t.Parallel() - slowResponse := time.Second * 6 - c := gomock.NewController(t) defer c.Finish() r := mock_repositories.NewMockCoreDumpsRepository(c) - randomDump := generateRandomSliceOfCoreDumps(1) + randomDump := generateSliceOfCoreDumps(1) tests := []struct { name string dump entities.CoreDump @@ -51,7 +50,7 @@ func TestAddCoreDump(t *testing.T) { error: nil, }, { - name: "add dump error", + name: "add dump with error", dump: entities.CoreDump{}, stubs: func(r *mock_repositories.MockCoreDumpsRepository, dump entities.CoreDump) { r.EXPECT().AddCoreDump(dump).Return(errors.New("error")) @@ -60,11 +59,11 @@ func TestAddCoreDump(t *testing.T) { error: errors.New("error"), }, { - name: "add dump timeout error", + name: "add dump with timeout error", dump: randomDump[0], stubs: func(r *mock_repositories.MockCoreDumpsRepository, dump entities.CoreDump) { r.EXPECT().AddCoreDump(dump).DoAndReturn(func(dump entities.CoreDump) error { - time.Sleep(slowResponse) + time.Sleep(6 * time.Second) return errors.New("error") }) }, @@ -76,7 +75,8 @@ func TestAddCoreDump(t *testing.T) { test.stubs(r, test.dump) err := r.AddCoreDump(test.dump) - require.Equal(t, test.error, err) + + assert.Equal(t, test.error, err) }) } } @@ -84,13 +84,11 @@ func TestAddCoreDump(t *testing.T) { func TestGetCoreDumps(t *testing.T) { t.Parallel() - slowResponse := time.Second * 6 - c := gomock.NewController(t) defer c.Finish() r := mock_repositories.NewMockCoreDumpsRepository(c) - sliceOfDumps := generateRandomSliceOfCoreDumps(5) + sliceOfDumps := generateSliceOfCoreDumps(5) tests := []struct { name string @@ -107,7 +105,7 @@ func TestGetCoreDumps(t *testing.T) { error: nil, }, { - name: "get core dumps error", + name: "get core dumps with error", stubs: func(r *mock_repositories.MockCoreDumpsRepository) { r.EXPECT().GetCoreDumps().Return(nil, errors.New("error")) }, @@ -115,10 +113,10 @@ func TestGetCoreDumps(t *testing.T) { error: errors.New("error"), }, { - name: "get core dumps error timeout", + name: "get core dumps with error timeout", stubs: func(r *mock_repositories.MockCoreDumpsRepository) { r.EXPECT().GetCoreDumps().Do(func(options ...interface{}) { - time.Sleep(slowResponse) + time.Sleep(6 * time.Second) }).Return(nil, errors.New("error")) }, dumps: nil, @@ -130,8 +128,9 @@ func TestGetCoreDumps(t *testing.T) { test.stubs(r) res, err := r.GetCoreDumps() - require.Equal(t, test.error, err) - require.Equal(t, test.dumps, res) + + assert.Equal(t, test.error, err) + assert.Equal(t, test.dumps, res) }) } } @@ -139,13 +138,11 @@ func TestGetCoreDumps(t *testing.T) { func TestGetCoreDumpByID(t *testing.T) { t.Parallel() - slowResponse := time.Second * 6 - c := gomock.NewController(t) defer c.Finish() r := mock_repositories.NewMockCoreDumpsRepository(c) - sliceOfDumps := generateRandomSliceOfCoreDumps(1) + sliceOfDumps := generateSliceOfCoreDumps(1) tests := []struct { name string @@ -162,7 +159,7 @@ func TestGetCoreDumpByID(t *testing.T) { error: nil, }, { - name: "get core dump by id error", + name: "get core dump by id with error", stubs: func(r *mock_repositories.MockCoreDumpsRepository, id string) { r.EXPECT().GetCoreDumpByID(id).Return(entities.CoreDump{}, errors.New("error")) }, @@ -170,10 +167,10 @@ func TestGetCoreDumpByID(t *testing.T) { error: errors.New("error"), }, { - name: "get core dump by id error timeout", + name: "get core dump by id with timeout error ", stubs: func(r *mock_repositories.MockCoreDumpsRepository, id string) { r.EXPECT().GetCoreDumpByID(id).Do(func(id string) { - time.Sleep(slowResponse) + time.Sleep(6 * time.Second) }).Return(entities.CoreDump{}, errors.New("error")) }, dumpID: "", @@ -185,8 +182,8 @@ func TestGetCoreDumpByID(t *testing.T) { test.stubs(r, test.dumpID) res, err := r.GetCoreDumpByID(test.dumpID) - require.Equal(t, test.error, err) - require.Equal(t, test.dumpID, res.ID) + assert.Equal(t, test.error, err) + assert.Equal(t, test.dumpID, res.ID) }) } } @@ -194,8 +191,6 @@ func TestGetCoreDumpByID(t *testing.T) { func TestDeleteCoreDump(t *testing.T) { t.Parallel() - slowResponse := time.Second * 6 - c := gomock.NewController(t) defer c.Finish() r := mock_repositories.NewMockCoreDumpsRepository(c) @@ -215,7 +210,7 @@ func TestDeleteCoreDump(t *testing.T) { error: nil, }, { - name: "delete dump error empty id", + name: "delete dump- empty id, with error", stubs: func(r *mock_repositories.MockCoreDumpsRepository, dumpID string) { r.EXPECT().DeleteCoreDump(dumpID).Return(errors.New("error")) }, @@ -223,10 +218,10 @@ func TestDeleteCoreDump(t *testing.T) { error: errors.New("error"), }, { - name: "delete dump timeout error", + name: "delete dump with timeout error", stubs: func(r *mock_repositories.MockCoreDumpsRepository, dumpID string) { r.EXPECT().DeleteCoreDump(dumpID).Do(func(dumpID string) { - time.Sleep(slowResponse) + time.Sleep(6 * time.Second) }).Return(errors.New("error")) }, dumpID: "", @@ -238,7 +233,7 @@ func TestDeleteCoreDump(t *testing.T) { test.stubs(r, test.dumpID) err := r.DeleteCoreDump(test.dumpID) - require.Equal(t, test.error, err) + assert.Equal(t, test.error, err) }) } } @@ -246,8 +241,6 @@ func TestDeleteCoreDump(t *testing.T) { func TestDeleteAllCoreDump(t *testing.T) { t.Parallel() - slowResponse := time.Second * 6 - c := gomock.NewController(t) defer c.Finish() @@ -266,10 +259,10 @@ func TestDeleteAllCoreDump(t *testing.T) { error: nil, }, { - name: "delete dump timeout error", + name: "delete dump with timeout error", stubs: func(r *mock_repositories.MockCoreDumpsRepository) { r.EXPECT().DeleteAllCoreDumps().Do(func() { - time.Sleep(slowResponse) + time.Sleep(6 * time.Second) }).Return(errors.New("error")) }, error: errors.New("error"), @@ -280,12 +273,13 @@ func TestDeleteAllCoreDump(t *testing.T) { test.stubs(r) err := r.DeleteAllCoreDumps() - require.Equal(t, test.error, err) + + assert.Equal(t, test.error, err) }) } } -func generateRandomSliceOfCoreDumps(quantity int) []entities.CoreDump { +func generateSliceOfCoreDumps(quantity int) []entities.CoreDump { type osInfo struct { Name string Arch string diff --git a/server/internal/app/repositories/mongodb_repository/mongo_configs/configuration.go b/server/internal/app/repositories/mongodb_repository/mongo_configs/configuration.go new file mode 100644 index 0000000..467c9d0 --- /dev/null +++ b/server/internal/app/repositories/mongodb_repository/mongo_configs/configuration.go @@ -0,0 +1,6 @@ +package mongo_configs + +var ( + DBname = "crashser" + CollectionName = "core_dumps" +) diff --git a/server/internal/app/repositories/mongodb_repository/mongo_options/query_fields_mongo_test.go b/server/internal/app/repositories/mongodb_repository/mongo_options/query_fields_mongo_test.go index c17e90f..79dde64 100644 --- a/server/internal/app/repositories/mongodb_repository/mongo_options/query_fields_mongo_test.go +++ b/server/internal/app/repositories/mongodb_repository/mongo_options/query_fields_mongo_test.go @@ -4,7 +4,7 @@ import ( "testing" "time" - "github.com/stretchr/testify/require" + assert "github.com/stretchr/testify/require" "go.mongodb.org/mongo-driver/bson" "go.mongodb.org/mongo-driver/bson/primitive" "go.mongodb.org/mongo-driver/mongo/options" @@ -12,20 +12,19 @@ import ( func TestSetApplication(t *testing.T) { filter := bson.M{} - require.Equal(t, 0, len(filter)) + assert.Equal(t, 0, len(filter)) options := options.Find() setter := SetApplication("app") setter(filter, options) res := filter["appinfo.name"] - require.Equal(t, "app", res) - require.Equal(t, true, len(filter) > 0) + assert.Equal(t, "app", res) } func TestSetStartTimestamp(t *testing.T) { filter := bson.M{} - require.Equal(t, 0, len(filter)) + assert.Equal(t, 0, len(filter)) requiredDate := primitive.NewDateTimeFromTime(time.Now().AddDate(0, 0, -1)) @@ -34,13 +33,12 @@ func TestSetStartTimestamp(t *testing.T) { setter(filter, options) res := filter["timestamp"] - require.Equal(t, primitive.M(primitive.M{"$gte": requiredDate}), res) - require.Equal(t, true, len(filter) > 0) + assert.Equal(t, primitive.M(primitive.M{"$gte": requiredDate}), res) } func TestSetEndTimestamp(t *testing.T) { filter := bson.M{} - require.Equal(t, 0, len(filter)) + assert.Equal(t, 0, len(filter)) requiredDate := primitive.NewDateTimeFromTime(time.Now().AddDate(0, 0, 0)) @@ -49,34 +47,31 @@ func TestSetEndTimestamp(t *testing.T) { setter(filter, options) res := filter["timestamp"] - require.Equal(t, primitive.M(primitive.M{"$lt": requiredDate}), res) - require.Equal(t, true, len(filter) > 0) + assert.Equal(t, primitive.M(primitive.M{"$lt": requiredDate}), res) } func TestSetLimit(t *testing.T) { filter := bson.M{} - require.Equal(t, 0, len(filter)) + assert.Equal(t, 0, len(filter)) options := options.Find() - require.Equal(t, true, options.Limit == nil) + assert.Equal(t, true, options.Limit == nil) setter := SetLimit(1) setter(filter, options) - require.Equal(t, int64(1), *options.Limit) - require.Equal(t, false, options == nil) + assert.Equal(t, int64(1), *options.Limit) } func TestSetOffeset(t *testing.T) { filter := bson.M{} - require.Equal(t, 0, len(filter)) + assert.Equal(t, 0, len(filter)) options := options.Find() - require.Equal(t, true, options.Skip == nil) + assert.Equal(t, true, options.Skip == nil) setter := SetOffset(1) setter(filter, options) - require.Equal(t, int64(1), *options.Skip) - require.Equal(t, false, options == nil) + assert.Equal(t, int64(1), *options.Skip) } diff --git a/server/internal/app/services/core_dumps_service.go b/server/internal/app/services/core_dumps_service.go index 95f8ff2..1ee13dc 100644 --- a/server/internal/app/services/core_dumps_service.go +++ b/server/internal/app/services/core_dumps_service.go @@ -11,7 +11,7 @@ type CoreDumpsService interface { GetCoreDumps(parameters ...interface{}) ([]entities.CoreDump, error) GetCoreDumpByID(id string) (entities.CoreDump, error) AddCoreDump(coreDump entities.CoreDump) error - UpdateCoreDump(parameters interface{}) error + UpdateCoreDump(parameters ...interface{}) error DeleteCoreDump(id string) error DeleteAllCoreDumps() error } @@ -40,7 +40,7 @@ func (s *CoreDumpServiceImpl) AddCoreDump(coreDump entities.CoreDump) error { return nil } -func (r *CoreDumpServiceImpl) UpdateCoreDump(parameters interface{}) error { +func (r *CoreDumpServiceImpl) UpdateCoreDump(parameters ...interface{}) error { return nil }