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..b5fdba5 100644 --- a/server/Makefile +++ b/server/Makefile @@ -2,16 +2,21 @@ 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..cde9533 100644 --- a/server/cmd/crasher/main.go +++ b/server/cmd/crasher/main.go @@ -7,6 +7,8 @@ import ( "server/internal/app/controllers" "server/internal/app/repositories/mongodb_repository" "server/internal/app/services" + "strconv" + "time" "github.com/gorilla/mux" "go.mongodb.org/mongo-driver/mongo" @@ -45,8 +47,22 @@ func main() { } }() - appsRepo := mongodb_repositories.NewApplicationsRepository(dbClient, logger) - coreDumpsRepo := mongodb_repositories.NewCoreDumpsRepository(dbClient, logger) + if app.DatabaseTimeout == "" { + app.DatabaseTimeout = "5" + } + + timeoutInt, err := strconv.Atoi(app.DatabaseTimeout) + if err != nil { + logger.Fatal( + "failed to parse timeout env", + zap.Error(err), + ) + } + + timeout := time.Duration(timeoutInt) * time.Second + + 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/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..4fc4624 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") + 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/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..4241573 100644 --- a/server/internal/app/entities/core_dump.go +++ b/server/internal/app/entities/core_dump.go @@ -1,6 +1,8 @@ package entities -import "time" +import ( + "time" +) type CoreDumpStatus int @@ -12,53 +14,69 @@ const ( ) type CoreDump struct { - osInfo *OSInfo - appInfo *AppInfo - status CoreDumpStatus - data string - timestamp time.Time + ID string + OsInfo *OSInfo + AppInfo *AppInfo + Status CoreDumpStatus + Data string + Timestamp time.Time + Extensions []CoreDumpExtension +} + +type CoreDumpExtension 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) GetExtensions() []CoreDumpExtension { + return c.Extensions } 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 +} + +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 3ff6c6c..1213023 100644 --- a/server/internal/app/entities/core_dump_test.go +++ b/server/internal/app/entities/core_dump_test.go @@ -10,27 +10,34 @@ 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() timestamp := time.Now() status := SolvedCoreDumpStatus data := "server/internal/app/entities/core_dump_test.go@TestCoreDump:100" + extension := &CoreDumpExtension{ + Key: "key", + Value: "value", + } coreDump.SetOSInfo(osInfo) coreDump.SetAppInfo(appInfo) coreDump.SetTimestamp(timestamp) coreDump.SetStatus(status) coreDump.SetData(data) + coreDump.AddExtensions(extension.Key, extension.Value) - 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()) + assert.Equal(t, extension.Key, coreDump.GetExtensions()[0].Key) + assert.Equal(t, extension.Value, coreDump.GetExtensions()[0].Value) } diff --git a/server/internal/app/entities/os_info.go b/server/internal/app/entities/os_info.go index 5cd424d..71f6822 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/helper.go b/server/internal/app/helper.go new file mode 100644 index 0000000..a6eb94c --- /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 487ee5f..b7be735 100644 --- a/server/internal/app/repositories/core_dumps_repository.go +++ b/server/internal/app/repositories/core_dumps_repository.go @@ -1,9 +1,14 @@ package repositories -import "server/internal/app/entities" +import ( + "server/internal/app/entities" +) type CoreDumpsRepository 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 } 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..d89f31f --- /dev/null +++ b/server/internal/app/repositories/mock/core_dumps_repository.go @@ -0,0 +1,125 @@ +// 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) +} + +// 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(parameters ...interface{}) ([]entities.CoreDump, error) { + m.ctrl.T.Helper() + varargs := []interface{}{} + for _, a := range parameters { + 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(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, "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 e528ac6..d817702 100644 --- a/server/internal/app/repositories/mongodb_repository/applications_repository.go +++ b/server/internal/app/repositories/mongodb_repository/applications_repository.go @@ -1,26 +1,51 @@ -package mongodb_repositories +package mongodb_repository import ( + "context" + "fmt" "server/internal/app/repositories" + "server/internal/app/repositories/mongodb_repository/mongo_configs" + "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 time.Duration } var _ repositories.ApplicationsRepository = (*ApplicationsRepository)(nil) -func NewApplicationsRepository(db *mongo.Client, l *zap.Logger) *ApplicationsRepository { +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, - 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(), 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 new file mode 100644 index 0000000..0094d53 --- /dev/null +++ b/server/internal/app/repositories/mongodb_repository/applications_repository_test.go @@ -0,0 +1,92 @@ +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 := time.Duration(5) * time.Second + applicationsRepository := NewApplicationsRepository(&mongo.Client{}, &zap.Logger{}, ctxTimeout) + + 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() + + c := gomock.NewController(t) + defer c.Finish() + r := mock_repositories.NewMockApplicationsRepository(c) + + tests := []struct { + name string + stubs func(store *mock_repositories.MockApplicationsRepository, slice []string) + slice []string + error error + }{ + { + name: "get many application names", + stubs: func(r *mock_repositories.MockApplicationsRepository, slice []string) { + r.EXPECT().GetApplicationNames().Return(slice, nil) + }, + slice: []string{"app1", "app2", "app3"}, + error: nil, + }, + { + name: "get one application name", + stubs: func(r *mock_repositories.MockApplicationsRepository, slice []string) { + r.EXPECT().GetApplicationNames().Return(slice, nil) + }, + slice: []string{"app1"}, + error: nil, + }, + { + name: "get empty application names", + stubs: func(r *mock_repositories.MockApplicationsRepository, slice []string) { + r.EXPECT().GetApplicationNames().Return(slice, nil) + }, + slice: []string{}, + error: nil, + }, + { + name: "get error while getting application names", + stubs: func(r *mock_repositories.MockApplicationsRepository, slice []string) { + r.EXPECT().GetApplicationNames().Return(slice, errors.New("error")) + }, + 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(6 * time.Second) + return slice, errors.New("error") + }) + }, + slice: []string{}, + error: errors.New("error"), + }, + } + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + test.stubs(r, test.slice) + + result, err := r.GetApplicationNames() + 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 904dfaa..8afa0e1 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,108 @@ -package mongodb_repositories +package mongodb_repository 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" + "go.mongodb.org/mongo-driver/bson" "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 time.Duration } var _ repositories.CoreDumpsRepository = (*CoreDumpsRepository)(nil) -func NewCoreDumpsRepository(db *mongo.Client, l *zap.Logger) *CoreDumpsRepository { +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, - logger: l, + dbClient: db, + collection: collection, + logger: l, + timeout: timeout, } } -func (r *CoreDumpsRepository) GetCoreDumps() ([]entities.CoreDump, error) { - return nil, nil +func (r *CoreDumpsRepository) GetCoreDumps(parameters ...interface{}) ([]entities.CoreDump, error) { + setters := make([]mongo_options.OptionsMongo, len(parameters)) + for _, setter := range parameters { + 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(), r.timeout) + 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 { +func (r *CoreDumpsRepository) GetCoreDumpByID(id string) (entities.CoreDump, error) { + 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 { return nil } +func (r *CoreDumpsRepository) AddCoreDump(coreDump entities.CoreDump) error { + 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 { - return nil + 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(), 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 new file mode 100644 index 0000000..662e519 --- /dev/null +++ b/server/internal/app/repositories/mongodb_repository/core_dumps_repository_test.go @@ -0,0 +1,371 @@ +package mongodb_repository + +import ( + "errors" + "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" +) + +func TestNewCoreDumpsRepository(t *testing.T) { + t.Parallel() + + ctxTimeout := time.Duration(5) * time.Second + coredumpsRepository := NewCoreDumpsRepository(&mongo.Client{}, &zap.Logger{}, ctxTimeout) + + 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() + + c := gomock.NewController(t) + defer c.Finish() + r := mock_repositories.NewMockCoreDumpsRepository(c) + + randomDump := generateSliceOfCoreDumps(1) + tests := []struct { + name string + dump entities.CoreDump + stubs func(store *mock_repositories.MockCoreDumpsRepository, dump entities.CoreDump) + error error + }{ + { + name: "add dump", + dump: randomDump[0], + stubs: func(r *mock_repositories.MockCoreDumpsRepository, dump entities.CoreDump) { + r.EXPECT().AddCoreDump(dump).Return(nil) + }, + error: nil, + }, + { + 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")) + + }, + error: errors.New("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(6 * time.Second) + return errors.New("error") + }) + }, + error: errors.New("error"), + }, + } + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + test.stubs(r, test.dump) + + err := r.AddCoreDump(test.dump) + + assert.Equal(t, test.error, err) + }) + } +} + +func TestGetCoreDumps(t *testing.T) { + t.Parallel() + + c := gomock.NewController(t) + defer c.Finish() + r := mock_repositories.NewMockCoreDumpsRepository(c) + + sliceOfDumps := generateSliceOfCoreDumps(5) + + tests := []struct { + name string + stubs func(store *mock_repositories.MockCoreDumpsRepository) + dumps []entities.CoreDump + error error + }{ + { + name: "get core dumps", + stubs: func(r *mock_repositories.MockCoreDumpsRepository) { + r.EXPECT().GetCoreDumps().Return(sliceOfDumps, nil) + }, + dumps: sliceOfDumps, + error: nil, + }, + { + name: "get core dumps with error", + stubs: func(r *mock_repositories.MockCoreDumpsRepository) { + r.EXPECT().GetCoreDumps().Return(nil, errors.New("error")) + }, + dumps: nil, + error: errors.New("error"), + }, + { + name: "get core dumps with error timeout", + stubs: func(r *mock_repositories.MockCoreDumpsRepository) { + r.EXPECT().GetCoreDumps().Do(func(options ...interface{}) { + time.Sleep(6 * time.Second) + }).Return(nil, errors.New("error")) + }, + dumps: nil, + error: errors.New("error"), + }, + } + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + test.stubs(r) + + res, err := r.GetCoreDumps() + + assert.Equal(t, test.error, err) + assert.Equal(t, test.dumps, res) + }) + } +} + +func TestGetCoreDumpByID(t *testing.T) { + t.Parallel() + + c := gomock.NewController(t) + defer c.Finish() + r := mock_repositories.NewMockCoreDumpsRepository(c) + + sliceOfDumps := generateSliceOfCoreDumps(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 with 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 with timeout error ", + stubs: func(r *mock_repositories.MockCoreDumpsRepository, id string) { + r.EXPECT().GetCoreDumpByID(id).Do(func(id string) { + time.Sleep(6 * time.Second) + }).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) + assert.Equal(t, test.error, err) + assert.Equal(t, test.dumpID, res.ID) + }) + } +} + +func TestDeleteCoreDump(t *testing.T) { + t.Parallel() + + c := gomock.NewController(t) + defer c.Finish() + r := mock_repositories.NewMockCoreDumpsRepository(c) + + tests := []struct { + name string + stubs func(store *mock_repositories.MockCoreDumpsRepository, dumpID string) + dumpID string + error error + }{ + { + name: "delete dump", + stubs: func(r *mock_repositories.MockCoreDumpsRepository, dumpID string) { + r.EXPECT().DeleteCoreDump(dumpID).Return(nil) + }, + dumpID: "dsfdfds454", + error: nil, + }, + { + name: "delete dump- empty id, with error", + stubs: func(r *mock_repositories.MockCoreDumpsRepository, dumpID string) { + r.EXPECT().DeleteCoreDump(dumpID).Return(errors.New("error")) + }, + dumpID: "", + error: errors.New("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(6 * time.Second) + }).Return(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) + + err := r.DeleteCoreDump(test.dumpID) + assert.Equal(t, test.error, err) + }) + } +} + +func TestDeleteAllCoreDump(t *testing.T) { + t.Parallel() + + 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 with timeout error", + stubs: func(r *mock_repositories.MockCoreDumpsRepository) { + r.EXPECT().DeleteAllCoreDumps().Do(func() { + time.Sleep(6 * time.Second) + }).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() + + assert.Equal(t, test.error, err) + }) + } +} + +func generateSliceOfCoreDumps(quantity int) []entities.CoreDump { + type osInfo struct { + Name string + Arch string + Version string + } + + type appInfo struct { + Name string + Version string + } + osArr := []osInfo{ + { + 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", + }, + } + appsArr := []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() + coreDump.ID = fmt.Sprint(i) + osInfo := entities.NewOSInfo() + osInfo.SetName(osArr[i].Name) + osInfo.SetArchitecture(osArr[i].Arch) + osInfo.SetVersion(osArr[i].Version) + coreDump.SetOSInfo(osInfo) + + appInfo := entities.NewAppInfo() + 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")) + + coreDump.SetTimestamp(time.Unix(1663511325, 0)) + + result = append(result, *coreDump) + } + + return result +} 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.go b/server/internal/app/repositories/mongodb_repository/mongo_options/query_fields_mongo.go new file mode 100644 index 0000000..9083ff1 --- /dev/null +++ b/server/internal/app/repositories/mongodb_repository/mongo_options/query_fields_mongo.go @@ -0,0 +1,43 @@ +package mongo_options + +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/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..79dde64 --- /dev/null +++ b/server/internal/app/repositories/mongodb_repository/mongo_options/query_fields_mongo_test.go @@ -0,0 +1,77 @@ +package mongo_options + +import ( + "testing" + "time" + + 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" +) + +func TestSetApplication(t *testing.T) { + filter := bson.M{} + assert.Equal(t, 0, len(filter)) + + options := options.Find() + setter := SetApplication("app") + setter(filter, options) + res := filter["appinfo.name"] + + assert.Equal(t, "app", res) +} + +func TestSetStartTimestamp(t *testing.T) { + filter := bson.M{} + assert.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"] + + assert.Equal(t, primitive.M(primitive.M{"$gte": requiredDate}), res) +} + +func TestSetEndTimestamp(t *testing.T) { + filter := bson.M{} + assert.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"] + + assert.Equal(t, primitive.M(primitive.M{"$lt": requiredDate}), res) +} + +func TestSetLimit(t *testing.T) { + filter := bson.M{} + assert.Equal(t, 0, len(filter)) + + options := options.Find() + assert.Equal(t, true, options.Limit == nil) + + setter := SetLimit(1) + setter(filter, options) + + assert.Equal(t, int64(1), *options.Limit) +} + +func TestSetOffeset(t *testing.T) { + filter := bson.M{} + assert.Equal(t, 0, len(filter)) + + options := options.Find() + assert.Equal(t, true, options.Skip == nil) + + setter := SetOffset(1) + setter(filter, options) + + 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 9b9ee38..1ee13dc 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 +}