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 +}