Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
74626c9
Merge branch 'main' of github.com:go-vela/server
jbrockopp Feb 14, 2023
974c8e6
Merge branch 'main' of github.com:go-vela/server
jbrockopp Mar 3, 2023
2f2c425
Merge branch 'main' of github.com:go-vela/server
jbrockopp Mar 20, 2023
528291a
Merge branch 'main' of github.com:go-vela/server
jbrockopp Apr 8, 2023
b53c687
Merge branch 'main' of github.com:go-vela/server
jbrockopp Apr 8, 2023
4734dcb
Merge branch 'main' of github.com:go-vela/server
jbrockopp Apr 16, 2023
1fb52df
Merge branch 'main' of github.com:go-vela/server
jbrockopp Apr 21, 2023
e996aa6
Merge branch 'main' of github.com:go-vela/server
jbrockopp Apr 27, 2023
c299ee4
Merge branch 'main' of github.com:go-vela/server
jbrockopp May 11, 2023
c8da9e3
Merge branch 'main' of github.com:go-vela/server
jbrockopp May 16, 2023
1ee254f
Merge branch 'main' of github.com:go-vela/server
jbrockopp May 22, 2023
8dd6033
Merge branch 'main' of github.com:go-vela/server
jbrockopp May 22, 2023
0eb92b1
Merge branch 'main' of github.com:go-vela/server
jbrockopp May 26, 2023
d5dcb6d
Merge branch 'main' of github.com:go-vela/server
jbrockopp Jun 1, 2023
1b8ab7c
feat(database): add agnostic engine
jbrockopp Jun 1, 2023
19bf93b
feat(database): add config.Validate()
jbrockopp Jun 1, 2023
f820f6a
feat(database): add engine.Close()
jbrockopp Jun 1, 2023
5d5490c
feat(database): add engine.Driver()
jbrockopp Jun 1, 2023
ab04f2f
chore: minor fixes
jbrockopp Jun 1, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions database/close.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
// Copyright (c) 2023 Target Brands, Inc. All rights reserved.
//
// Use of this source code is governed by the LICENSE file in this repository.

package database

// Close stops and terminates the connection to the database.
func (e *engine) Close() error {
e.Logger.Tracef("closing connection to the %s database", e.Driver())

// capture database/sql database from gorm.io/gorm database
_sql, err := e.Database.DB()
if err != nil {
return err
}

return _sql.Close()
}
83 changes: 83 additions & 0 deletions database/close_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
// Copyright (c) 2023 Target Brands, Inc. All rights reserved.
//
// Use of this source code is governed by the LICENSE file in this repository.

package database

import (
"testing"

"github.com/sirupsen/logrus"

"gorm.io/gorm"
)

func TestDatabase_Engine_Close(t *testing.T) {
_postgres, _mock := testPostgres(t)
defer _postgres.Close()
// ensure the mock expects the close
_mock.ExpectClose()

// create a test database without mocking the call
_unmocked, _ := testPostgres(t)

_sqlite := testSqlite(t)
defer _sqlite.Close()

// setup tests
tests := []struct {
failure bool
name string
database *engine
}{
{
name: "success with postgres",
failure: false,
database: _postgres,
},
{
name: "success with sqlite3",
failure: false,
database: _sqlite,
},
{
name: "failure without mocked call",
failure: true,
database: _unmocked,
},
{
name: "failure with invalid gorm database",
failure: true,
database: &engine{
Config: &Config{
Driver: "invalid",
},
Database: &gorm.DB{
Config: &gorm.Config{
ConnPool: nil,
},
},
Logger: logrus.NewEntry(logrus.StandardLogger()),
},
},
}

// run tests
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
err := test.database.Close()

if test.failure {
if err == nil {
t.Errorf("Close for %s should have returned err", test.name)
}

return
}

if err != nil {
t.Errorf("Close for %s returned err: %v", test.name, err)
}
})
}
}
58 changes: 56 additions & 2 deletions database/database.go
Original file line number Diff line number Diff line change
@@ -1,15 +1,69 @@
// Copyright (c) 2022 Target Brands, Inc. All rights reserved.
// Copyright (c) 2023 Target Brands, Inc. All rights reserved.
//
// Use of this source code is governed by the LICENSE file in this repository.

package database

import (
"fmt"
"time"

"github.com/go-vela/server/database/build"
"github.com/go-vela/server/database/hook"
"github.com/go-vela/server/database/log"
"github.com/go-vela/server/database/pipeline"
"github.com/go-vela/server/database/repo"
"github.com/go-vela/server/database/schedule"
"github.com/go-vela/server/database/secret"
"github.com/go-vela/server/database/service"
"github.com/go-vela/server/database/step"
"github.com/go-vela/server/database/user"
"github.com/go-vela/server/database/worker"
"github.com/go-vela/types/constants"

"github.com/sirupsen/logrus"

"gorm.io/gorm"
)

type (
// Config represents the settings required to create the engine that implements the Interface.
Config struct {
// specifies the address to use for the database engine
Address string
// specifies the level of compression to use for the database engine
CompressionLevel int
// specifies the maximum idle connections for the database engine
ConnectionIdle int
// specifies the connection duration to use for the database engine
ConnectionLife time.Duration
// specifies the maximum open connections for the database engine
ConnectionOpen int
// specifies the driver to use for the database engine
Driver string
// specifies the encryption key to use for the database engine
EncryptionKey string
// specifies to skip creating tables and indexes for the database engine
SkipCreation bool
}

// engine represents the functionality that implements the Interface.
engine struct {
Config *Config
Database *gorm.DB
Logger *logrus.Entry

build.BuildInterface
hook.HookInterface
log.LogInterface
pipeline.PipelineInterface
repo.RepoInterface
schedule.ScheduleInterface
secret.SecretInterface
service.ServiceInterface
step.StepInterface
user.UserInterface
worker.WorkerInterface
}
)

// New creates and returns a Vela service capable of
Expand Down
79 changes: 78 additions & 1 deletion database/database_test.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright (c) 2022 Target Brands, Inc. All rights reserved.
// Copyright (c) 2023 Target Brands, Inc. All rights reserved.
//
// Use of this source code is governed by the LICENSE file in this repository.

Expand All @@ -7,6 +7,13 @@ package database
import (
"testing"
"time"

"github.com/DATA-DOG/go-sqlmock"
"github.com/sirupsen/logrus"

"gorm.io/driver/postgres"
"gorm.io/driver/sqlite"
"gorm.io/gorm"
)

func TestDatabase_New(t *testing.T) {
Expand Down Expand Up @@ -86,3 +93,73 @@ func TestDatabase_New(t *testing.T) {
}
}
}

// testPostgres is a helper function to create a Postgres engine for testing.
func testPostgres(t *testing.T) (*engine, sqlmock.Sqlmock) {
// create the engine with test configuration
_engine := &engine{
Config: &Config{
CompressionLevel: 3,
ConnectionLife: 30 * time.Minute,
ConnectionIdle: 2,
ConnectionOpen: 0,
Driver: "postgres",
EncryptionKey: "A1B2C3D4E5G6H7I8J9K0LMNOPQRSTUVW",
SkipCreation: false,
},
Logger: logrus.NewEntry(logrus.StandardLogger()),
}

// create the new mock sql database
_sql, _mock, err := sqlmock.New(
sqlmock.MonitorPingsOption(true),
sqlmock.QueryMatcherOption(sqlmock.QueryMatcherEqual),
)
if err != nil {
t.Errorf("unable to create new SQL mock: %v", err)
}
// ensure the mock expects the ping
_mock.ExpectPing()

// create the new mock Postgres database client
_engine.Database, err = gorm.Open(
postgres.New(postgres.Config{Conn: _sql}),
&gorm.Config{SkipDefaultTransaction: true},
)
if err != nil {
t.Errorf("unable to create new test postgres database: %v", err)
}

return _engine, _mock
}

// testSqlite is a helper function to create a Sqlite engine for testing.
func testSqlite(t *testing.T) *engine {
var err error

// create the engine with test configuration
_engine := &engine{
Config: &Config{
Address: "file::memory:?cache=shared",
CompressionLevel: 3,
ConnectionLife: 30 * time.Minute,
ConnectionIdle: 2,
ConnectionOpen: 0,
Driver: "sqlite3",
EncryptionKey: "A1B2C3D4E5G6H7I8J9K0LMNOPQRSTUVW",
SkipCreation: false,
},
Logger: logrus.NewEntry(logrus.StandardLogger()),
}

// create the new mock Sqlite database client
_engine.Database, err = gorm.Open(
sqlite.Open(_engine.Config.Address),
&gorm.Config{SkipDefaultTransaction: true},
)
if err != nil {
t.Errorf("unable to create new test sqlite database: %v", err)
}

return _engine
}
10 changes: 10 additions & 0 deletions database/driver.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
// Copyright (c) 2023 Target Brands, Inc. All rights reserved.
//
// Use of this source code is governed by the LICENSE file in this repository.

package database

// Driver outputs the configured database driver.
func (e *engine) Driver() string {
return e.Config.Driver
}
47 changes: 47 additions & 0 deletions database/driver_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
// Copyright (c) 2023 Target Brands, Inc. All rights reserved.
//
// Use of this source code is governed by the LICENSE file in this repository.

package database

import (
"strings"
"testing"
)

func TestDatabase_Engine_Driver(t *testing.T) {
_postgres, _ := testPostgres(t)
defer _postgres.Close()

_sqlite := testSqlite(t)
defer _sqlite.Close()

// setup tests
tests := []struct {
name string
database *engine
want string
}{
{
name: "success with postgres",
database: _postgres,
want: "postgres",
},
{
name: "success with sqlite3",
database: _sqlite,
want: "sqlite3",
},
}

// run tests
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
got := test.database.Driver()

if !strings.EqualFold(got, test.want) {
t.Errorf("Driver for %s is %v, want %v", test.name, got, test.want)
}
})
}
}
Loading