diff --git a/api/build/executable.go b/api/build/executable.go index 832e5abeb..9df63467d 100644 --- a/api/build/executable.go +++ b/api/build/executable.go @@ -70,6 +70,7 @@ func GetBuildExecutable(c *gin.Context) { o := org.Retrieve(c) r := repo.Retrieve(c) cl := claims.Retrieve(c) + ctx := c.Request.Context() // update engine logger with API metadata // @@ -81,7 +82,7 @@ func GetBuildExecutable(c *gin.Context) { "subject": cl.Subject, }).Infof("reading build executable %s/%d", r.GetFullName(), b.GetNumber()) - bExecutable, err := database.FromContext(c).PopBuildExecutable(b.GetID()) + bExecutable, err := database.FromContext(c).PopBuildExecutable(ctx, b.GetID()) if err != nil { retErr := fmt.Errorf("unable to pop build executable: %w", err) util.HandleError(c, http.StatusInternalServerError, retErr) diff --git a/api/build/publish.go b/api/build/publish.go index f5e144232..51f94cff2 100644 --- a/api/build/publish.go +++ b/api/build/publish.go @@ -34,7 +34,7 @@ func PublishToQueue(ctx context.Context, queue queue.Service, db database.Interf bExecutable.SetBuildID(b.GetID()) bExecutable.SetData(byteExecutable) - err = db.CreateBuildExecutable(bExecutable) + err = db.CreateBuildExecutable(ctx, bExecutable) if err != nil { logrus.Errorf("Failed to publish build executable to database %d for %s: %v", b.GetNumber(), r.GetFullName(), err) diff --git a/database/executable/create.go b/database/executable/create.go index 002ac03bc..ac29ec768 100644 --- a/database/executable/create.go +++ b/database/executable/create.go @@ -5,6 +5,7 @@ package executable import ( + "context" "fmt" "github.com/go-vela/types/constants" @@ -14,7 +15,7 @@ import ( ) // CreateBuildExecutable creates a new build executable in the database. -func (e *engine) CreateBuildExecutable(b *library.BuildExecutable) error { +func (e *engine) CreateBuildExecutable(ctx context.Context, b *library.BuildExecutable) error { e.logger.WithFields(logrus.Fields{ "build": b.GetBuildID(), }).Tracef("creating build executable for build %d in the database", b.GetBuildID()) diff --git a/database/executable/create_test.go b/database/executable/create_test.go index abf047f79..e3f664314 100644 --- a/database/executable/create_test.go +++ b/database/executable/create_test.go @@ -5,6 +5,7 @@ package executable import ( + "context" "testing" "github.com/DATA-DOG/go-sqlmock" @@ -53,7 +54,7 @@ VALUES ($1,$2,$3) RETURNING "id"`). // run tests for _, test := range tests { t.Run(test.name, func(t *testing.T) { - err := test.database.CreateBuildExecutable(_bExecutable) + err := test.database.CreateBuildExecutable(context.TODO(), _bExecutable) if test.failure { if err == nil { diff --git a/database/executable/executable.go b/database/executable/executable.go index c53759192..556d86754 100644 --- a/database/executable/executable.go +++ b/database/executable/executable.go @@ -5,6 +5,7 @@ package executable import ( + "context" "fmt" "github.com/go-vela/types/constants" @@ -31,6 +32,8 @@ type ( // engine configuration settings used in build executable functions config *config + ctx context.Context + // gorm.io/gorm database client used in build executable functions // // https://pkg.go.dev/gorm.io/gorm#DB @@ -71,7 +74,7 @@ func New(opts ...EngineOpt) (*engine, error) { } // create the build executables table - err := e.CreateBuildExecutableTable(e.client.Config.Dialector.Name()) + err := e.CreateBuildExecutableTable(e.ctx, e.client.Config.Dialector.Name()) if err != nil { return nil, fmt.Errorf("unable to create %s table: %w", constants.TableBuildExecutable, err) } diff --git a/database/executable/interface.go b/database/executable/interface.go index 852d77872..9e3bd50b3 100644 --- a/database/executable/interface.go +++ b/database/executable/interface.go @@ -4,7 +4,11 @@ package executable -import "github.com/go-vela/types/library" +import ( + "context" + + "github.com/go-vela/types/library" +) // BuildExecutableInterface represents the Vela interface for build executable // functions with the supported Database backends. @@ -12,14 +16,14 @@ type BuildExecutableInterface interface { // BuildExecutable Data Definition Language Functions // // https://en.wikipedia.org/wiki/Data_definition_language - CreateBuildExecutableTable(string) error + CreateBuildExecutableTable(context.Context, string) error // BuildExecutable Data Manipulation Language Functions // // https://en.wikipedia.org/wiki/Data_manipulation_language // CreateBuildExecutable defines a function that creates a build executable. - CreateBuildExecutable(*library.BuildExecutable) error + CreateBuildExecutable(context.Context, *library.BuildExecutable) error // PopBuildExecutable defines a function that gets and deletes a build executable. - PopBuildExecutable(int64) (*library.BuildExecutable, error) + PopBuildExecutable(context.Context, int64) (*library.BuildExecutable, error) } diff --git a/database/executable/opts.go b/database/executable/opts.go index 1d91a4a54..fa601a03d 100644 --- a/database/executable/opts.go +++ b/database/executable/opts.go @@ -5,6 +5,8 @@ package executable import ( + "context" + "github.com/sirupsen/logrus" "gorm.io/gorm" @@ -72,3 +74,12 @@ func WithSkipCreation(skipCreation bool) EngineOpt { return nil } } + +// WithContext sets the context in the database engine for build executables. +func WithContext(ctx context.Context) EngineOpt { + return func(e *engine) error { + e.ctx = ctx + + return nil + } +} diff --git a/database/executable/opts_test.go b/database/executable/opts_test.go index 6bb89d0ae..61876dd32 100644 --- a/database/executable/opts_test.go +++ b/database/executable/opts_test.go @@ -5,6 +5,7 @@ package executable import ( + "context" "reflect" "testing" @@ -263,3 +264,52 @@ func TestExecutable_EngineOpt_WithSkipCreation(t *testing.T) { }) } } + +func TestExecutable_EngineOpt_WithContext(t *testing.T) { + // setup types + e := &engine{config: new(config)} + + // setup tests + tests := []struct { + failure bool + name string + ctx context.Context + want context.Context + }{ + { + failure: false, + name: "context set to TODO", + ctx: context.TODO(), + want: context.TODO(), + }, + { + failure: false, + name: "context set to nil", + ctx: nil, + want: nil, + }, + } + + // run tests + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + err := WithContext(test.ctx)(e) + + if test.failure { + if err == nil { + t.Errorf("WithContext for %s should have returned err", test.name) + } + + return + } + + if err != nil { + t.Errorf("WithContext returned err: %v", err) + } + + if !reflect.DeepEqual(e.ctx, test.want) { + t.Errorf("WithContext is %v, want %v", e.ctx, test.want) + } + }) + } +} diff --git a/database/executable/pop.go b/database/executable/pop.go index c38d472bc..64a2fbcf5 100644 --- a/database/executable/pop.go +++ b/database/executable/pop.go @@ -5,6 +5,8 @@ package executable import ( + "context" + "github.com/go-vela/types/constants" "github.com/go-vela/types/database" "github.com/go-vela/types/library" @@ -12,7 +14,7 @@ import ( ) // PopBuildExecutable pops a build executable by build_id from the database. -func (e *engine) PopBuildExecutable(id int64) (*library.BuildExecutable, error) { +func (e *engine) PopBuildExecutable(ctx context.Context, id int64) (*library.BuildExecutable, error) { e.logger.Tracef("popping build executable for build %d from the database", id) // variable to store query results diff --git a/database/executable/pop_test.go b/database/executable/pop_test.go index b89dcec9e..cf282d013 100644 --- a/database/executable/pop_test.go +++ b/database/executable/pop_test.go @@ -5,6 +5,7 @@ package executable import ( + "context" "reflect" "testing" @@ -33,7 +34,7 @@ func TestExecutable_Engine_PopBuildExecutable(t *testing.T) { _sqlite := testSqlite(t) defer func() { _sql, _ := _sqlite.client.DB(); _sql.Close() }() - err := _sqlite.CreateBuildExecutable(_bExecutable) + err := _sqlite.CreateBuildExecutable(context.TODO(), _bExecutable) if err != nil { t.Errorf("unable to create test build executable for sqlite: %v", err) } @@ -62,7 +63,7 @@ func TestExecutable_Engine_PopBuildExecutable(t *testing.T) { // run tests for _, test := range tests { t.Run(test.name, func(t *testing.T) { - got, err := test.database.PopBuildExecutable(1) + got, err := test.database.PopBuildExecutable(context.TODO(), 1) if test.failure { if err == nil { diff --git a/database/executable/table.go b/database/executable/table.go index c2b3323b2..c36834fe6 100644 --- a/database/executable/table.go +++ b/database/executable/table.go @@ -4,7 +4,11 @@ package executable -import "github.com/go-vela/types/constants" +import ( + "context" + + "github.com/go-vela/types/constants" +) const ( // CreatePostgresTable represents a query to create the Postgres build_executables table. @@ -33,7 +37,7 @@ build_executables ( ) // CreateBuildExecutableTable creates the build executables table in the database. -func (e *engine) CreateBuildExecutableTable(driver string) error { +func (e *engine) CreateBuildExecutableTable(ctx context.Context, driver string) error { e.logger.Tracef("creating build_executables table in the database") // handle the driver provided to create the table diff --git a/database/executable/table_test.go b/database/executable/table_test.go index ed203b113..b4f3cd057 100644 --- a/database/executable/table_test.go +++ b/database/executable/table_test.go @@ -5,6 +5,7 @@ package executable import ( + "context" "testing" "github.com/DATA-DOG/go-sqlmock" @@ -41,7 +42,7 @@ func TestExecutable_Engine_CreateBuildExecutableTable(t *testing.T) { // run tests for _, test := range tests { t.Run(test.name, func(t *testing.T) { - err := test.database.CreateBuildExecutableTable(test.name) + err := test.database.CreateBuildExecutableTable(context.TODO(), test.name) if test.failure { if err == nil { diff --git a/database/integration_test.go b/database/integration_test.go index 669fa3907..30d6ff696 100644 --- a/database/integration_test.go +++ b/database/integration_test.go @@ -405,7 +405,7 @@ func testExecutables(t *testing.T, db Interface, resources *Resources) { // create the pipelines for _, executable := range resources.Executables { - err := db.CreateBuildExecutable(executable) + err := db.CreateBuildExecutable(context.TODO(), executable) if err != nil { t.Errorf("unable to create executable %d: %v", executable.GetID(), err) } @@ -414,7 +414,7 @@ func testExecutables(t *testing.T, db Interface, resources *Resources) { // pop executables for builds for _, executable := range resources.Executables { - got, err := db.PopBuildExecutable(executable.GetBuildID()) + got, err := db.PopBuildExecutable(context.TODO(), executable.GetBuildID()) if err != nil { t.Errorf("unable to get executable %d for build %d: %v", executable.GetID(), executable.GetBuildID(), err) } diff --git a/database/resource.go b/database/resource.go index 482834ecf..74a4b8fe5 100644 --- a/database/resource.go +++ b/database/resource.go @@ -38,6 +38,7 @@ func (e *engine) NewResources(ctx context.Context) error { // create the database agnostic engine for build_executables e.BuildExecutableInterface, err = executable.New( + executable.WithContext(e.ctx), executable.WithClient(e.client), executable.WithLogger(e.logger), executable.WithSkipCreation(e.config.SkipCreation),