diff --git a/.github/workflows/integration-test.yml b/.github/workflows/integration-test.yml new file mode 100644 index 000000000..655ec6c0e --- /dev/null +++ b/.github/workflows/integration-test.yml @@ -0,0 +1,49 @@ +# name of the action +name: integration-test + +# trigger on pull_request events that modify this file or any database files +on: + pull_request: + paths: + - '.github/workflows/integration-test.yml' + - 'database/**' + +# pipeline to execute +jobs: + database: + runs-on: ubuntu-latest + + services: + postgres: + image: postgres:15-alpine + env: + POSTGRES_DB: vela + POSTGRES_PASSWORD: notARealPassword12345 + POSTGRES_USER: vela + options: >- + --health-cmd pg_isready + --health-interval 10s + --health-timeout 5s + --health-retries 5 + ports: + - 5432:5432 + + env: + POSTGRES_ADDR: postgres://vela:notARealPassword12345@localhost:5432/vela + SQLITE_ADDR: vela.db + + steps: + - name: clone + uses: actions/checkout@v3 + + - name: install go + uses: actions/setup-go@v4 + with: + # use version from go.mod file + go-version-file: 'go.mod' + cache: true + check-latest: true + + - name: test + run: | + make integration-test \ No newline at end of file diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index f3cf03420..cdc0c6aa3 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -25,10 +25,10 @@ jobs: - name: test run: | - go test -race -covermode=atomic -coverprofile=coverage.out ./... + make test - name: coverage uses: codecov/codecov-action@v3 with: token: ${{ secrets.CODECOV_TOKEN }} - file: coverage.out + file: coverage.out \ No newline at end of file diff --git a/Makefile b/Makefile index 61dce5988..f46e05a3f 100644 --- a/Makefile +++ b/Makefile @@ -91,6 +91,13 @@ fix: @echo "### Fixing Go Code" @go fix ./... +# The `integration-test` target is intended to run all integration tests for the Go source code. +.PHONY: integration-test +integration-test: + @echo + @echo "### Integration Testing" + INTEGRATION=1 go test -run TestDatabase_Integration ./... + # The `test` target is intended to run # the tests for the Go source code. # @@ -99,7 +106,7 @@ fix: test: @echo @echo "### Testing Go Code" - @go test -race ./... + @go test -race -covermode=atomic -coverprofile=coverage.out ./... # The `test-cover` target is intended to run # the tests for the Go source code and then @@ -107,10 +114,7 @@ test: # # Usage: `make test-cover` .PHONY: test-cover -test-cover: - @echo - @echo "### Creating test coverage report" - @go test -race -covermode=atomic -coverprofile=coverage.out ./... +test-cover: test @echo @echo "### Opening test coverage report" @go tool cover -html=coverage.out diff --git a/api/admin/repo.go b/api/admin/repo.go index 0f7327193..53ad236b9 100644 --- a/api/admin/repo.go +++ b/api/admin/repo.go @@ -66,7 +66,7 @@ func UpdateRepo(c *gin.Context) { } // send API call to update the repo - err = database.FromContext(c).UpdateRepo(input) + r, err := database.FromContext(c).UpdateRepo(input) if err != nil { retErr := fmt.Errorf("unable to update repo %d: %w", input.GetID(), err) @@ -75,5 +75,5 @@ func UpdateRepo(c *gin.Context) { return } - c.JSON(http.StatusOK, input) + c.JSON(http.StatusOK, r) } diff --git a/api/build/create.go b/api/build/create.go index 38a8867c2..cac912867 100644 --- a/api/build/create.go +++ b/api/build/create.go @@ -329,7 +329,7 @@ func CreateBuild(c *gin.Context) { } // send API call to update repo for ensuring counter is incremented - err = database.FromContext(c).UpdateRepo(r) + r, err = database.FromContext(c).UpdateRepo(r) if err != nil { retErr := fmt.Errorf("unable to create new build: failed to update repo %s: %w", r.GetFullName(), err) diff --git a/api/build/restart.go b/api/build/restart.go index 8bb85e798..7b7dcca69 100644 --- a/api/build/restart.go +++ b/api/build/restart.go @@ -320,7 +320,7 @@ func RestartBuild(c *gin.Context) { } // send API call to update repo for ensuring counter is incremented - err = database.FromContext(c).UpdateRepo(r) + r, err = database.FromContext(c).UpdateRepo(r) if err != nil { retErr := fmt.Errorf("unable to restart build: failed to update repo %s: %w", r.GetFullName(), err) util.HandleError(c, http.StatusBadRequest, retErr) diff --git a/api/pipeline/compile.go b/api/pipeline/compile.go index 723bf2522..8ac5fed93 100644 --- a/api/pipeline/compile.go +++ b/api/pipeline/compile.go @@ -97,7 +97,7 @@ func CompilePipeline(c *gin.Context) { compiler := compiler.FromContext(c).Duplicate().WithCommit(p.GetCommit()).WithMetadata(m).WithRepo(r).WithUser(u) // compile the pipeline - pipeline, _, err := compiler.CompileLite(p.GetData(), true, true, nil) + pipeline, _, err := compiler.CompileLite(p.GetData(), true, true) if err != nil { retErr := fmt.Errorf("unable to compile pipeline %s: %w", entry, err) diff --git a/api/pipeline/expand.go b/api/pipeline/expand.go index 05e5c7dd8..17f782fee 100644 --- a/api/pipeline/expand.go +++ b/api/pipeline/expand.go @@ -98,7 +98,7 @@ func ExpandPipeline(c *gin.Context) { compiler := compiler.FromContext(c).Duplicate().WithCommit(p.GetCommit()).WithMetadata(m).WithRepo(r).WithUser(u) // expand the templates in the pipeline - pipeline, _, err := compiler.CompileLite(p.GetData(), true, false, nil) + pipeline, _, err := compiler.CompileLite(p.GetData(), true, false) if err != nil { retErr := fmt.Errorf("unable to expand pipeline %s: %w", entry, err) diff --git a/api/pipeline/validate.go b/api/pipeline/validate.go index 42e49e2ae..45aae1ff8 100644 --- a/api/pipeline/validate.go +++ b/api/pipeline/validate.go @@ -105,7 +105,7 @@ func ValidatePipeline(c *gin.Context) { } // validate the pipeline - pipeline, _, err := compiler.CompileLite(p.GetData(), template, false, nil) + pipeline, _, err := compiler.CompileLite(p.GetData(), template, false) if err != nil { retErr := fmt.Errorf("unable to validate pipeline %s: %w", entry, err) diff --git a/api/repo/chown.go b/api/repo/chown.go index 00e728128..671e5a438 100644 --- a/api/repo/chown.go +++ b/api/repo/chown.go @@ -68,7 +68,7 @@ func ChownRepo(c *gin.Context) { r.SetUserID(u.GetID()) // send API call to update the repo - err := database.FromContext(c).UpdateRepo(r) + _, err := database.FromContext(c).UpdateRepo(r) if err != nil { retErr := fmt.Errorf("unable to change owner of repo %s to %s: %w", r.GetFullName(), u.GetName(), err) diff --git a/api/repo/create.go b/api/repo/create.go index e52cd23f4..ca0dc2d6e 100644 --- a/api/repo/create.go +++ b/api/repo/create.go @@ -140,10 +140,8 @@ func CreateRepo(c *gin.Context) { } // set the visibility field based off the input provided - if len(input.GetVisibility()) == 0 { - // default visibility field to public - r.SetVisibility(constants.VisibilityPublic) - } else { + if len(input.GetVisibility()) > 0 { + // default visibility field to the input visibility r.SetVisibility(input.GetVisibility()) } @@ -285,7 +283,7 @@ func CreateRepo(c *gin.Context) { dbRepo.SetActive(true) // send API call to update the repo - err = database.FromContext(c).UpdateRepo(dbRepo) + r, err = database.FromContext(c).UpdateRepo(dbRepo) if err != nil { retErr := fmt.Errorf("unable to set repo %s to active: %w", dbRepo.GetFullName(), err) @@ -293,12 +291,9 @@ func CreateRepo(c *gin.Context) { return } - - // send API call to capture the updated repo - r, _ = database.FromContext(c).GetRepoForOrg(dbRepo.GetOrg(), dbRepo.GetName()) } else { // send API call to create the repo - err = database.FromContext(c).CreateRepo(r) + r, err = database.FromContext(c).CreateRepo(r) if err != nil { retErr := fmt.Errorf("unable to create new repo %s: %w", r.GetFullName(), err) @@ -306,9 +301,6 @@ func CreateRepo(c *gin.Context) { return } - - // send API call to capture the created repo - r, _ = database.FromContext(c).GetRepoForOrg(r.GetOrg(), r.GetName()) } // create init hook in the DB after repo has been added in order to capture its ID diff --git a/api/repo/delete.go b/api/repo/delete.go index 63649f2eb..cc3ca66b9 100644 --- a/api/repo/delete.go +++ b/api/repo/delete.go @@ -88,7 +88,7 @@ func DeleteRepo(c *gin.Context) { // Mark the repo as inactive r.SetActive(false) - err = database.FromContext(c).UpdateRepo(r) + _, err = database.FromContext(c).UpdateRepo(r) if err != nil { retErr := fmt.Errorf("unable to set repo %s to inactive: %w", r.GetFullName(), err) diff --git a/api/repo/repair.go b/api/repo/repair.go index 192983d1c..7b7f0e98d 100644 --- a/api/repo/repair.go +++ b/api/repo/repair.go @@ -122,7 +122,7 @@ func RepairRepo(c *gin.Context) { r.SetActive(true) // send API call to update the repo - err := database.FromContext(c).UpdateRepo(r) + _, err := database.FromContext(c).UpdateRepo(r) if err != nil { retErr := fmt.Errorf("unable to set repo %s to active: %w", r.GetFullName(), err) diff --git a/api/repo/update.go b/api/repo/update.go index 374772d42..2f299bdc1 100644 --- a/api/repo/update.go +++ b/api/repo/update.go @@ -295,7 +295,7 @@ func UpdateRepo(c *gin.Context) { } // send API call to update the repo - err = database.FromContext(c).UpdateRepo(r) + r, err = database.FromContext(c).UpdateRepo(r) if err != nil { retErr := fmt.Errorf("unable to update repo %s: %w", r.GetFullName(), err) @@ -304,8 +304,5 @@ func UpdateRepo(c *gin.Context) { return } - // send API call to capture the updated repo - r, _ = database.FromContext(c).GetRepoForOrg(r.GetOrg(), r.GetName()) - c.JSON(http.StatusOK, r) } diff --git a/api/scm/sync.go b/api/scm/sync.go index b160f5fa0..c98ea82e4 100644 --- a/api/scm/sync.go +++ b/api/scm/sync.go @@ -80,7 +80,7 @@ func SyncRepo(c *gin.Context) { r.SetActive(false) // update repo in database - err := database.FromContext(c).UpdateRepo(r) + _, err := database.FromContext(c).UpdateRepo(r) if err != nil { retErr := fmt.Errorf("unable to update repo for org %s: %w", o, err) diff --git a/api/scm/sync_org.go b/api/scm/sync_org.go index ac18ec551..9cda091ef 100644 --- a/api/scm/sync_org.go +++ b/api/scm/sync_org.go @@ -113,7 +113,7 @@ func SyncReposForOrg(c *gin.Context) { if err != nil { repo.SetActive(false) - err := database.FromContext(c).UpdateRepo(repo) + _, err := database.FromContext(c).UpdateRepo(repo) if err != nil { retErr := fmt.Errorf("unable to update repo for org %s: %w", o, err) diff --git a/api/webhook/post.go b/api/webhook/post.go index 7eab225f5..bae23a863 100644 --- a/api/webhook/post.go +++ b/api/webhook/post.go @@ -621,7 +621,7 @@ func PostWebhook(c *gin.Context) { } // end of retry loop // send API call to update repo for ensuring counter is incremented - err = database.FromContext(c).UpdateRepo(repo) + repo, err = database.FromContext(c).UpdateRepo(repo) if err != nil { retErr := fmt.Errorf("%s: failed to update repo %s: %w", baseErr, repo.GetFullName(), err) util.HandleError(c, http.StatusBadRequest, retErr) @@ -759,7 +759,7 @@ func handleRepositoryEvent(c *gin.Context, m *types.Metadata, h *library.Hook, r } // update repo object in the database after applying edits - err = database.FromContext(c).UpdateRepo(dbRepo) + dbRepo, err = database.FromContext(c).UpdateRepo(dbRepo) if err != nil { retErr := fmt.Errorf("%s: failed to update repo %s: %w", baseErr, r.GetFullName(), err) @@ -891,7 +891,7 @@ func renameRepository(h *library.Hook, r *library.Repo, c *gin.Context, m *types dbR.SetPreviousName(r.GetPreviousName()) // update the repo in the database - err = database.FromContext(c).UpdateRepo(dbR) + dbR, err = database.FromContext(c).UpdateRepo(dbR) if err != nil { retErr := fmt.Errorf("%s: failed to update repo %s/%s in database", baseErr, prevOrg, prevRepo) util.HandleError(c, http.StatusBadRequest, retErr) diff --git a/cmd/vela-server/schedule.go b/cmd/vela-server/schedule.go index 08e7867cc..e5b1a78c1 100644 --- a/cmd/vela-server/schedule.go +++ b/cmd/vela-server/schedule.go @@ -373,7 +373,7 @@ func processSchedule(s *library.Schedule, compiler compiler.Engine, database dat } // end of retry loop // send API call to update repo for ensuring counter is incremented - err = database.UpdateRepo(r) + r, err = database.UpdateRepo(r) if err != nil { return fmt.Errorf("unable to update repo %s: %w", r.GetFullName(), err) } diff --git a/compiler/engine.go b/compiler/engine.go index 5d1d32993..0296c99d4 100644 --- a/compiler/engine.go +++ b/compiler/engine.go @@ -25,7 +25,7 @@ type Engine interface { // CompileLite defines a function that produces an light executable // representation of a pipeline from an object. This calls // Parse internally to convert the object to a yaml configuration. - CompileLite(interface{}, bool, bool, []string) (*yaml.Build, *library.Pipeline, error) + CompileLite(interface{}, bool, bool) (*yaml.Build, *library.Pipeline, error) // Duplicate defines a function that // creates a clone of the Engine. @@ -130,6 +130,9 @@ type Engine interface { // WithLocal defines a function that sets // the compiler local field in the Engine. WithLocal(bool) Engine + // WithLocalTemplates defines a function that sets + // the compiler local templates field in the Engine. + WithLocalTemplates([]string) Engine // WithMetadata defines a function that sets // the compiler Metadata type in the Engine. WithMetadata(*types.Metadata) Engine diff --git a/compiler/native/compile.go b/compiler/native/compile.go index f74e19bab..d106fa480 100644 --- a/compiler/native/compile.go +++ b/compiler/native/compile.go @@ -82,7 +82,7 @@ func (c *client) Compile(v interface{}) (*pipeline.Build, *library.Pipeline, err switch { case p.Metadata.RenderInline: - newPipeline, err := c.compileInline(p, nil, c.TemplateDepth) + newPipeline, err := c.compileInline(p, c.TemplateDepth) if err != nil { return nil, _pipeline, err } @@ -105,7 +105,7 @@ func (c *client) Compile(v interface{}) (*pipeline.Build, *library.Pipeline, err } // CompileLite produces a partial of an executable pipeline from a yaml configuration. -func (c *client) CompileLite(v interface{}, template, substitute bool, localTemplates []string) (*yaml.Build, *library.Pipeline, error) { +func (c *client) CompileLite(v interface{}, template, substitute bool) (*yaml.Build, *library.Pipeline, error) { p, data, err := c.Parse(v, c.repo.GetPipelineType(), new(yaml.Template)) if err != nil { return nil, nil, err @@ -117,7 +117,7 @@ func (c *client) CompileLite(v interface{}, template, substitute bool, localTemp _pipeline.SetType(c.repo.GetPipelineType()) if p.Metadata.RenderInline { - newPipeline, err := c.compileInline(p, localTemplates, c.TemplateDepth) + newPipeline, err := c.compileInline(p, c.TemplateDepth) if err != nil { return nil, _pipeline, err } @@ -134,24 +134,6 @@ func (c *client) CompileLite(v interface{}, template, substitute bool, localTemp // create map of templates for easy lookup templates := mapFromTemplates(p.Templates) - if c.local { - for _, file := range localTemplates { - // local templates override format is : - // - // example: example:/path/to/template.yml - parts := strings.Split(file, ":") - - // make sure the template was configured - _, ok := templates[parts[0]] - if !ok { - return nil, _pipeline, fmt.Errorf("template with name %s is not configured", parts[0]) - } - - // override the source for the given template - templates[parts[0]].Source = parts[1] - } - } - switch { case len(p.Stages) > 0: // inject the templates into the steps @@ -194,7 +176,7 @@ func (c *client) CompileLite(v interface{}, template, substitute bool, localTemp } // compileInline parses and expands out inline pipelines. -func (c *client) compileInline(p *yaml.Build, localTemplates []string, depth int) (*yaml.Build, error) { +func (c *client) compileInline(p *yaml.Build, depth int) (*yaml.Build, error) { newPipeline := *p newPipeline.Templates = yaml.TemplateSlice{} @@ -206,21 +188,6 @@ func (c *client) compileInline(p *yaml.Build, localTemplates []string, depth int } for _, template := range p.Templates { - if c.local { - for _, file := range localTemplates { - // local templates override format is : - // - // example: example:/path/to/template.yml - parts := strings.Split(file, ":") - - // make sure we're referencing the proper template - if parts[0] == template.Name { - // override the source for the given template - template.Source = parts[1] - } - } - } - bytes, err := c.getTemplate(template, template.Name) if err != nil { return nil, err @@ -240,7 +207,7 @@ func (c *client) compileInline(p *yaml.Build, localTemplates []string, depth int // if template parsed contains a template reference, recurse with decremented depth if len(parsed.Templates) > 0 && parsed.Metadata.RenderInline { - parsed, err = c.compileInline(parsed, localTemplates, depth-1) + parsed, err = c.compileInline(parsed, depth-1) if err != nil { return nil, err } diff --git a/compiler/native/compile_test.go b/compiler/native/compile_test.go index 5281dccd1..3a37703d6 100644 --- a/compiler/native/compile_test.go +++ b/compiler/native/compile_test.go @@ -3422,7 +3422,7 @@ func Test_CompileLite(t *testing.T) { t.Errorf("Reading yaml file return err: %v", err) } - got, _, err := compiler.CompileLite(yaml, tt.args.template, tt.args.substitute, nil) + got, _, err := compiler.CompileLite(yaml, tt.args.template, tt.args.substitute) if (err != nil) != tt.wantErr { t.Errorf("CompileLite() error = %v, wantErr %v", err, tt.wantErr) return diff --git a/compiler/native/expand.go b/compiler/native/expand.go index 5314cf25e..d593bc26e 100644 --- a/compiler/native/expand.go +++ b/compiler/native/expand.go @@ -206,15 +206,30 @@ func (c *client) getTemplate(tmpl *yaml.Template, name string) ([]byte, error) { switch { case c.local: - a := &afero.Afero{ - Fs: afero.NewOsFs(), - } + // iterate over locally provided templates + for _, t := range c.localTemplates { + parts := strings.Split(t, ":") + if len(parts) != 2 { + return nil, fmt.Errorf("local templates must be provided in the form :, got %s", t) + } - bytes, err = a.ReadFile(tmpl.Source) - if err != nil { - return bytes, err + if strings.EqualFold(tmpl.Name, parts[0]) { + a := &afero.Afero{ + Fs: afero.NewOsFs(), + } + + bytes, err = a.ReadFile(parts[1]) + if err != nil { + return bytes, err + } + + return bytes, nil + } } + // no template found in provided templates, exit with error + return nil, fmt.Errorf("unable to find template %s: not supplied in list %s", tmpl.Name, c.localTemplates) + case strings.EqualFold(tmpl.Type, "github"): // parse source from template src, err := c.Github.Parse(tmpl.Source) diff --git a/compiler/native/native.go b/compiler/native/native.go index 733a32407..c394af933 100644 --- a/compiler/native/native.go +++ b/compiler/native/native.go @@ -34,14 +34,15 @@ type client struct { CloneImage string TemplateDepth int - build *library.Build - comment string - commit string - files []string - local bool - metadata *types.Metadata - repo *library.Repo - user *library.User + build *library.Build + comment string + commit string + files []string + local bool + localTemplates []string + metadata *types.Metadata + repo *library.Repo + user *library.User } // New returns a Pipeline implementation that integrates with the supported registries. @@ -161,6 +162,13 @@ func (c *client) WithLocal(local bool) compiler.Engine { return c } +// WithLocalTemplates sets the compiler local templates in the Engine. +func (c *client) WithLocalTemplates(templates []string) compiler.Engine { + c.localTemplates = templates + + return c +} + // WithMetadata sets the compiler metadata type in the Engine. func (c *client) WithMetadata(m *types.Metadata) compiler.Engine { if m != nil { diff --git a/compiler/native/native_test.go b/compiler/native/native_test.go index 62c6fb7ed..de1f60631 100644 --- a/compiler/native/native_test.go +++ b/compiler/native/native_test.go @@ -202,6 +202,26 @@ func TestNative_WithLocal(t *testing.T) { } } +func TestNative_WithLocalTemplates(t *testing.T) { + // setup types + set := flag.NewFlagSet("test", 0) + c := cli.NewContext(nil, set, nil) + + localTemplates := []string{"example:tmpl.yml", "exmpl:template.yml"} + want, _ := New(c) + want.localTemplates = []string{"example:tmpl.yml", "exmpl:template.yml"} + + // run test + got, err := New(c) + if err != nil { + t.Errorf("Unable to create new compiler: %v", err) + } + + if !reflect.DeepEqual(got.WithLocalTemplates(localTemplates), want) { + t.Errorf("WithLocalTemplates is %v, want %v", got, want) + } +} + func TestNative_WithMetadata(t *testing.T) { // setup types set := flag.NewFlagSet("test", 0) diff --git a/database/hook/table.go b/database/hook/table.go index 9be4616c4..90419508f 100644 --- a/database/hook/table.go +++ b/database/hook/table.go @@ -51,7 +51,7 @@ hooks ( status TEXT, link TEXT, webhook_id INTEGER, - UNIQUE(repo_id, build_id) + UNIQUE(repo_id, number) ); ` ) diff --git a/database/integration_test.go b/database/integration_test.go new file mode 100644 index 000000000..2cebb815a --- /dev/null +++ b/database/integration_test.go @@ -0,0 +1,2255 @@ +// 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 ( + "os" + "reflect" + "strings" + "testing" + "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/go-vela/types/library" + "github.com/go-vela/types/raw" +) + +// Resources represents the object containing test resources. +type Resources struct { + Builds []*library.Build + Deployments []*library.Deployment + Hooks []*library.Hook + Logs []*library.Log + Pipelines []*library.Pipeline + Repos []*library.Repo + Schedules []*library.Schedule + Secrets []*library.Secret + Services []*library.Service + Steps []*library.Step + Users []*library.User + Workers []*library.Worker +} + +func TestDatabase_Integration(t *testing.T) { + // check if we should skip the integration test + // + // https://konradreiche.com/blog/how-to-separate-integration-tests-in-go + if os.Getenv("INTEGRATION") == "" { + t.Skipf("skipping %s integration test due to environment variable constraint", t.Name()) + } + + // setup tests + tests := []struct { + name string + config *config + }{ + { + name: "postgres", + config: &config{ + Driver: "postgres", + Address: os.Getenv("POSTGRES_ADDR"), + CompressionLevel: 3, + ConnectionLife: 10 * time.Second, + ConnectionIdle: 5, + ConnectionOpen: 20, + EncryptionKey: "A1B2C3D4E5G6H7I8J9K0LMNOPQRSTUVW", + SkipCreation: false, + }, + }, + { + name: "sqlite3", + config: &config{ + Driver: "sqlite3", + Address: os.Getenv("SQLITE_ADDR"), + CompressionLevel: 3, + ConnectionLife: 10 * time.Second, + ConnectionIdle: 5, + ConnectionOpen: 20, + EncryptionKey: "A1B2C3D4E5G6H7I8J9K0LMNOPQRSTUVW", + SkipCreation: false, + }, + }, + } + + // run tests + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + // create resources for testing + resources := newResources() + + db, err := New( + WithAddress(test.config.Address), + WithCompressionLevel(test.config.CompressionLevel), + WithConnectionLife(test.config.ConnectionLife), + WithConnectionIdle(test.config.ConnectionIdle), + WithConnectionOpen(test.config.ConnectionOpen), + WithDriver(test.config.Driver), + WithEncryptionKey(test.config.EncryptionKey), + WithSkipCreation(test.config.SkipCreation), + ) + if err != nil { + t.Errorf("unable to create new database engine for %s: %v", test.name, err) + } + + driver := db.Driver() + if !strings.EqualFold(driver, test.config.Driver) { + t.Errorf("Driver() is %v, want %v", driver, test.config.Driver) + } + + err = db.Ping() + if err != nil { + t.Errorf("unable to ping database engine for %s: %v", test.name, err) + } + + t.Run("test_builds", func(t *testing.T) { testBuilds(t, db, resources) }) + + t.Run("test_hooks", func(t *testing.T) { testHooks(t, db, resources) }) + + t.Run("test_logs", func(t *testing.T) { testLogs(t, db, resources) }) + + t.Run("test_pipelines", func(t *testing.T) { testPipelines(t, db, resources) }) + + t.Run("test_repos", func(t *testing.T) { testRepos(t, db, resources) }) + + t.Run("test_schedules", func(t *testing.T) { testSchedules(t, db, resources) }) + + t.Run("test_secrets", func(t *testing.T) { testSecrets(t, db, resources) }) + + t.Run("test_services", func(t *testing.T) { testServices(t, db, resources) }) + + t.Run("test_steps", func(t *testing.T) { testSteps(t, db, resources) }) + + t.Run("test_users", func(t *testing.T) { testUsers(t, db, resources) }) + + t.Run("test_workers", func(t *testing.T) { testWorkers(t, db, resources) }) + + err = db.Close() + if err != nil { + t.Errorf("unable to close database engine for %s: %v", test.name, err) + } + }) + } +} + +func testBuilds(t *testing.T, db Interface, resources *Resources) { + // create a variable to track the number of methods called for builds + methods := make(map[string]bool) + // capture the element type of the build interface + element := reflect.TypeOf(new(build.BuildInterface)).Elem() + // iterate through all methods found in the build interface + for i := 0; i < element.NumMethod(); i++ { + // skip tracking the methods to create indexes and tables for builds + // since those are already called when the database engine starts + if strings.Contains(element.Method(i).Name, "Index") || + strings.Contains(element.Method(i).Name, "Table") { + continue + } + + // add the method name to the list of functions + methods[element.Method(i).Name] = false + } + + // create the repos for build related functions + for _, repo := range resources.Repos { + _, err := db.CreateRepo(repo) + if err != nil { + t.Errorf("unable to create repo %d: %v", repo.GetID(), err) + } + } + + buildOne := new(library.BuildQueue) + buildOne.SetCreated(1563474076) + buildOne.SetFullName("github/octocat") + buildOne.SetNumber(1) + buildOne.SetStatus("running") + + buildTwo := new(library.BuildQueue) + buildTwo.SetCreated(1563474076) + buildTwo.SetFullName("github/octocat") + buildTwo.SetNumber(2) + buildTwo.SetStatus("running") + + queueBuilds := []*library.BuildQueue{buildOne, buildTwo} + + // create the builds + for _, build := range resources.Builds { + _, err := db.CreateBuild(build) + if err != nil { + t.Errorf("unable to create build %d: %v", build.GetID(), err) + } + } + methods["CreateBuild"] = true + + // count the builds + count, err := db.CountBuilds() + if err != nil { + t.Errorf("unable to count builds: %v", err) + } + if int(count) != len(resources.Builds) { + t.Errorf("CountBuilds() is %v, want %v", count, len(resources.Builds)) + } + methods["CountBuilds"] = true + + // count the builds for a deployment + count, err = db.CountBuildsForDeployment(resources.Deployments[0], nil) + if err != nil { + t.Errorf("unable to count builds for deployment %d: %v", resources.Deployments[0].GetID(), err) + } + if int(count) != len(resources.Builds) { + t.Errorf("CountBuildsForDeployment() is %v, want %v", count, len(resources.Builds)) + } + methods["CountBuildsForDeployment"] = true + + // count the builds for an org + count, err = db.CountBuildsForOrg(resources.Repos[0].GetOrg(), nil) + if err != nil { + t.Errorf("unable to count builds for org %s: %v", resources.Repos[0].GetOrg(), err) + } + if int(count) != len(resources.Builds) { + t.Errorf("CountBuildsForOrg() is %v, want %v", count, len(resources.Builds)) + } + methods["CountBuildsForOrg"] = true + + // count the builds for a repo + count, err = db.CountBuildsForRepo(resources.Repos[0], nil) + if err != nil { + t.Errorf("unable to count builds for repo %d: %v", resources.Repos[0].GetID(), err) + } + if int(count) != len(resources.Builds) { + t.Errorf("CountBuildsForRepo() is %v, want %v", count, len(resources.Builds)) + } + methods["CountBuildsForRepo"] = true + + // count the builds for a status + count, err = db.CountBuildsForStatus("running", nil) + if err != nil { + t.Errorf("unable to count builds for status %s: %v", "running", err) + } + if int(count) != len(resources.Builds) { + t.Errorf("CountBuildsForStatus() is %v, want %v", count, len(resources.Builds)) + } + methods["CountBuildsForStatus"] = true + + // list the builds + list, err := db.ListBuilds() + if err != nil { + t.Errorf("unable to list builds: %v", err) + } + if !reflect.DeepEqual(list, resources.Builds) { + t.Errorf("ListBuilds() is %v, want %v", list, resources.Builds) + } + methods["ListBuilds"] = true + + // list the builds for a deployment + list, count, err = db.ListBuildsForDeployment(resources.Deployments[0], nil, 1, 10) + if err != nil { + t.Errorf("unable to list builds for deployment %d: %v", resources.Deployments[0].GetID(), err) + } + if int(count) != len(resources.Builds) { + t.Errorf("ListBuildsForDeployment() is %v, want %v", count, len(resources.Builds)) + } + if !reflect.DeepEqual(list, []*library.Build{resources.Builds[1], resources.Builds[0]}) { + t.Errorf("ListBuildsForDeployment() is %v, want %v", list, []*library.Build{resources.Builds[1], resources.Builds[0]}) + } + methods["ListBuildsForDeployment"] = true + + // list the builds for an org + list, count, err = db.ListBuildsForOrg(resources.Repos[0].GetOrg(), nil, 1, 10) + if err != nil { + t.Errorf("unable to list builds for org %s: %v", resources.Repos[0].GetOrg(), err) + } + if int(count) != len(resources.Builds) { + t.Errorf("ListBuildsForOrg() is %v, want %v", count, len(resources.Builds)) + } + if !reflect.DeepEqual(list, resources.Builds) { + t.Errorf("ListBuildsForOrg() is %v, want %v", list, resources.Builds) + } + methods["ListBuildsForOrg"] = true + + // list the builds for a repo + list, count, err = db.ListBuildsForRepo(resources.Repos[0], nil, time.Now().UTC().Unix(), 0, 1, 10) + if err != nil { + t.Errorf("unable to list builds for repo %d: %v", resources.Repos[0].GetID(), err) + } + if int(count) != len(resources.Builds) { + t.Errorf("ListBuildsForRepo() is %v, want %v", count, len(resources.Builds)) + } + if !reflect.DeepEqual(list, []*library.Build{resources.Builds[1], resources.Builds[0]}) { + t.Errorf("ListBuildsForRepo() is %v, want %v", list, []*library.Build{resources.Builds[1], resources.Builds[0]}) + } + methods["ListBuildsForRepo"] = true + + // list the pending and running builds + queueList, err := db.ListPendingAndRunningBuilds("0") + if err != nil { + t.Errorf("unable to list pending and running builds: %v", err) + } + if !reflect.DeepEqual(queueList, queueBuilds) { + t.Errorf("ListPendingAndRunningBuilds() is %v, want %v", queueList, queueBuilds) + } + methods["ListPendingAndRunningBuilds"] = true + + // lookup the last build by repo + got, err := db.LastBuildForRepo(resources.Repos[0], "main") + if err != nil { + t.Errorf("unable to get last build for repo %d: %v", resources.Repos[0].GetID(), err) + } + if !reflect.DeepEqual(got, resources.Builds[1]) { + t.Errorf("LastBuildForRepo() is %v, want %v", got, resources.Builds[1]) + } + methods["LastBuildForRepo"] = true + + // lookup the builds by repo and number + for _, build := range resources.Builds { + repo := resources.Repos[build.GetRepoID()-1] + got, err = db.GetBuildForRepo(repo, build.GetNumber()) + if err != nil { + t.Errorf("unable to get build %d for repo %d: %v", build.GetID(), repo.GetID(), err) + } + if !reflect.DeepEqual(got, build) { + t.Errorf("GetBuildForRepo() is %v, want %v", got, build) + } + } + methods["GetBuildForRepo"] = true + + // clean the builds + count, err = db.CleanBuilds("integration testing", 1563474090) + if err != nil { + t.Errorf("unable to clean builds: %v", err) + } + if int(count) != len(resources.Builds) { + t.Errorf("CleanBuilds() is %v, want %v", count, len(resources.Builds)) + } + methods["CleanBuilds"] = true + + // update the builds + for _, build := range resources.Builds { + build.SetStatus("success") + _, err = db.UpdateBuild(build) + if err != nil { + t.Errorf("unable to update build %d: %v", build.GetID(), err) + } + + // lookup the build by ID + got, err = db.GetBuild(build.GetID()) + if err != nil { + t.Errorf("unable to get build %d by ID: %v", build.GetID(), err) + } + if !reflect.DeepEqual(got, build) { + t.Errorf("GetBuild() is %v, want %v", got, build) + } + } + methods["UpdateBuild"] = true + methods["GetBuild"] = true + + // delete the builds + for _, build := range resources.Builds { + err = db.DeleteBuild(build) + if err != nil { + t.Errorf("unable to delete build %d: %v", build.GetID(), err) + } + } + methods["DeleteBuild"] = true + + // delete the repos for build related functions + for _, repo := range resources.Repos { + err = db.DeleteRepo(repo) + if err != nil { + t.Errorf("unable to delete repo %d: %v", repo.GetID(), err) + } + } + + // ensure we called all the methods we expected to + for method, called := range methods { + if !called { + t.Errorf("method %s was not called for builds", method) + } + } +} + +func testHooks(t *testing.T, db Interface, resources *Resources) { + // create a variable to track the number of methods called for hooks + methods := make(map[string]bool) + // capture the element type of the hook interface + element := reflect.TypeOf(new(hook.HookInterface)).Elem() + // iterate through all methods found in the hook interface + for i := 0; i < element.NumMethod(); i++ { + // skip tracking the methods to create indexes and tables for hooks + // since those are already called when the database engine starts + if strings.Contains(element.Method(i).Name, "Index") || + strings.Contains(element.Method(i).Name, "Table") { + continue + } + + // add the method name to the list of functions + methods[element.Method(i).Name] = false + } + + // create the hooks + for _, hook := range resources.Hooks { + _, err := db.CreateHook(hook) + if err != nil { + t.Errorf("unable to create hook %d: %v", hook.GetID(), err) + } + } + methods["CreateHook"] = true + + // count the hooks + count, err := db.CountHooks() + if err != nil { + t.Errorf("unable to count hooks: %v", err) + } + if int(count) != len(resources.Hooks) { + t.Errorf("CountHooks() is %v, want %v", count, len(resources.Hooks)) + } + methods["CountHooks"] = true + + // count the hooks for a repo + count, err = db.CountHooksForRepo(resources.Repos[0]) + if err != nil { + t.Errorf("unable to count hooks for repo %d: %v", resources.Repos[0].GetID(), err) + } + if int(count) != len(resources.Builds) { + t.Errorf("CountHooksForRepo() is %v, want %v", count, len(resources.Builds)) + } + methods["CountHooksForRepo"] = true + + // list the hooks + list, err := db.ListHooks() + if err != nil { + t.Errorf("unable to list hooks: %v", err) + } + if !reflect.DeepEqual(list, resources.Hooks) { + t.Errorf("ListHooks() is %v, want %v", list, resources.Hooks) + } + methods["ListHooks"] = true + + // list the hooks for a repo + list, count, err = db.ListHooksForRepo(resources.Repos[0], 1, 10) + if err != nil { + t.Errorf("unable to list hooks for repo %d: %v", resources.Repos[0].GetID(), err) + } + if int(count) != len(resources.Hooks) { + t.Errorf("ListHooksForRepo() is %v, want %v", count, len(resources.Hooks)) + } + if !reflect.DeepEqual(list, []*library.Hook{resources.Hooks[1], resources.Hooks[0]}) { + t.Errorf("ListHooksForRepo() is %v, want %v", list, []*library.Hook{resources.Hooks[1], resources.Hooks[0]}) + } + methods["ListHooksForRepo"] = true + + // lookup the last build by repo + got, err := db.LastHookForRepo(resources.Repos[0]) + if err != nil { + t.Errorf("unable to get last hook for repo %d: %v", resources.Repos[0].GetID(), err) + } + if !reflect.DeepEqual(got, resources.Hooks[1]) { + t.Errorf("LastHookForRepo() is %v, want %v", got, resources.Hooks[1]) + } + methods["LastHookForRepo"] = true + + // lookup the hooks by name + for _, hook := range resources.Hooks { + repo := resources.Repos[hook.GetRepoID()-1] + got, err = db.GetHookForRepo(repo, hook.GetNumber()) + if err != nil { + t.Errorf("unable to get hook %d for repo %d: %v", hook.GetID(), repo.GetID(), err) + } + if !reflect.DeepEqual(got, hook) { + t.Errorf("GetHookForRepo() is %v, want %v", got, hook) + } + } + methods["GetHookForRepo"] = true + + // update the hooks + for _, hook := range resources.Hooks { + hook.SetStatus("success") + _, err = db.UpdateHook(hook) + if err != nil { + t.Errorf("unable to update hook %d: %v", hook.GetID(), err) + } + + // lookup the hook by ID + got, err = db.GetHook(hook.GetID()) + if err != nil { + t.Errorf("unable to get hook %d by ID: %v", hook.GetID(), err) + } + if !reflect.DeepEqual(got, hook) { + t.Errorf("GetHook() is %v, want %v", got, hook) + } + } + methods["UpdateHook"] = true + methods["GetHook"] = true + + // delete the hooks + for _, hook := range resources.Hooks { + err = db.DeleteHook(hook) + if err != nil { + t.Errorf("unable to delete hook %d: %v", hook.GetID(), err) + } + } + methods["DeleteHook"] = true + + // ensure we called all the methods we expected to + for method, called := range methods { + if !called { + t.Errorf("method %s was not called for hooks", method) + } + } +} + +func testLogs(t *testing.T, db Interface, resources *Resources) { + // create a variable to track the number of methods called for logs + methods := make(map[string]bool) + // capture the element type of the log interface + element := reflect.TypeOf(new(log.LogInterface)).Elem() + // iterate through all methods found in the log interface + for i := 0; i < element.NumMethod(); i++ { + // skip tracking the methods to create indexes and tables for logs + // since those are already called when the database engine starts + if strings.Contains(element.Method(i).Name, "Index") || + strings.Contains(element.Method(i).Name, "Table") { + continue + } + + // add the method name to the list of functions + methods[element.Method(i).Name] = false + } + + // create the logs + for _, log := range resources.Logs { + err := db.CreateLog(log) + if err != nil { + t.Errorf("unable to create log %d: %v", log.GetID(), err) + } + } + methods["CreateLog"] = true + + // count the logs + count, err := db.CountLogs() + if err != nil { + t.Errorf("unable to count logs: %v", err) + } + if int(count) != len(resources.Logs) { + t.Errorf("CountLogs() is %v, want %v", count, len(resources.Logs)) + } + methods["CountLogs"] = true + + // count the logs for a build + count, err = db.CountLogsForBuild(resources.Builds[0]) + if err != nil { + t.Errorf("unable to count logs for build %d: %v", resources.Builds[0].GetID(), err) + } + if int(count) != len(resources.Logs) { + t.Errorf("CountLogs() is %v, want %v", count, len(resources.Logs)) + } + methods["CountLogsForBuild"] = true + + // list the logs + list, err := db.ListLogs() + if err != nil { + t.Errorf("unable to list logs: %v", err) + } + if !reflect.DeepEqual(list, resources.Logs) { + t.Errorf("ListLogs() is %v, want %v", list, resources.Logs) + } + methods["ListLogs"] = true + + // list the logs for a build + list, count, err = db.ListLogsForBuild(resources.Builds[0], 1, 10) + if err != nil { + t.Errorf("unable to list logs for build %d: %v", resources.Builds[0].GetID(), err) + } + if int(count) != len(resources.Logs) { + t.Errorf("ListLogsForBuild() is %v, want %v", count, len(resources.Logs)) + } + if !reflect.DeepEqual(list, resources.Logs) { + t.Errorf("ListLogsForBuild() is %v, want %v", list, resources.Logs) + } + methods["ListLogsForBuild"] = true + + // lookup the logs by service + for _, log := range []*library.Log{resources.Logs[0], resources.Logs[1]} { + service := resources.Services[log.GetServiceID()-1] + got, err := db.GetLogForService(service) + if err != nil { + t.Errorf("unable to get log %d for service %d: %v", log.GetID(), service.GetID(), err) + } + if !reflect.DeepEqual(got, log) { + t.Errorf("GetLogForService() is %v, want %v", got, log) + } + } + methods["GetLogForService"] = true + + // lookup the logs by service + for _, log := range []*library.Log{resources.Logs[2], resources.Logs[3]} { + step := resources.Steps[log.GetStepID()-1] + got, err := db.GetLogForStep(step) + if err != nil { + t.Errorf("unable to get log %d for step %d: %v", log.GetID(), step.GetID(), err) + } + if !reflect.DeepEqual(got, log) { + t.Errorf("GetLogForStep() is %v, want %v", got, log) + } + } + methods["GetLogForStep"] = true + + // update the logs + for _, log := range resources.Logs { + log.SetData([]byte("bar")) + err = db.UpdateLog(log) + if err != nil { + t.Errorf("unable to update log %d: %v", log.GetID(), err) + } + + // lookup the log by ID + got, err := db.GetLog(log.GetID()) + if err != nil { + t.Errorf("unable to get log %d by ID: %v", log.GetID(), err) + } + if !reflect.DeepEqual(got, log) { + t.Errorf("GetLog() is %v, want %v", got, log) + } + } + methods["UpdateLog"] = true + methods["GetLog"] = true + + // delete the logs + for _, log := range resources.Logs { + err = db.DeleteLog(log) + if err != nil { + t.Errorf("unable to delete log %d: %v", log.GetID(), err) + } + } + methods["DeleteLog"] = true + + // ensure we called all the methods we expected to + for method, called := range methods { + if !called { + t.Errorf("method %s was not called for logs", method) + } + } +} + +func testPipelines(t *testing.T, db Interface, resources *Resources) { + // create a variable to track the number of methods called for pipelines + methods := make(map[string]bool) + // capture the element type of the pipeline interface + element := reflect.TypeOf(new(pipeline.PipelineInterface)).Elem() + // iterate through all methods found in the pipeline interface + for i := 0; i < element.NumMethod(); i++ { + // skip tracking the methods to create indexes and tables for pipelines + // since those are already called when the database engine starts + if strings.Contains(element.Method(i).Name, "Index") || + strings.Contains(element.Method(i).Name, "Table") { + continue + } + + // add the method name to the list of functions + methods[element.Method(i).Name] = false + } + + // create the pipelines + for _, pipeline := range resources.Pipelines { + _, err := db.CreatePipeline(pipeline) + if err != nil { + t.Errorf("unable to create pipeline %d: %v", pipeline.GetID(), err) + } + } + methods["CreatePipeline"] = true + + // count the pipelines + count, err := db.CountPipelines() + if err != nil { + t.Errorf("unable to count pipelines: %v", err) + } + if int(count) != len(resources.Pipelines) { + t.Errorf("CountPipelines() is %v, want %v", count, len(resources.Pipelines)) + } + methods["CountPipelines"] = true + + // count the pipelines for a repo + count, err = db.CountPipelinesForRepo(resources.Repos[0]) + if err != nil { + t.Errorf("unable to count pipelines for repo %d: %v", resources.Repos[0].GetID(), err) + } + if int(count) != len(resources.Pipelines) { + t.Errorf("CountPipelinesForRepo() is %v, want %v", count, len(resources.Pipelines)) + } + methods["CountPipelinesForRepo"] = true + + // list the pipelines + list, err := db.ListPipelines() + if err != nil { + t.Errorf("unable to list pipelines: %v", err) + } + if !reflect.DeepEqual(list, resources.Pipelines) { + t.Errorf("ListPipelines() is %v, want %v", list, resources.Pipelines) + } + methods["ListPipelines"] = true + + // list the pipelines for a repo + list, count, err = db.ListPipelinesForRepo(resources.Repos[0], 1, 10) + if err != nil { + t.Errorf("unable to list pipelines for repo %d: %v", resources.Repos[0].GetID(), err) + } + if int(count) != len(resources.Pipelines) { + t.Errorf("ListPipelinesForRepo() is %v, want %v", count, len(resources.Pipelines)) + } + if !reflect.DeepEqual(list, resources.Pipelines) { + t.Errorf("ListPipelines() is %v, want %v", list, resources.Pipelines) + } + methods["ListPipelinesForRepo"] = true + + // lookup the pipelines by name + for _, pipeline := range resources.Pipelines { + repo := resources.Repos[pipeline.GetRepoID()-1] + got, err := db.GetPipelineForRepo(pipeline.GetCommit(), repo) + if err != nil { + t.Errorf("unable to get pipeline %d for repo %d: %v", pipeline.GetID(), repo.GetID(), err) + } + if !reflect.DeepEqual(got, pipeline) { + t.Errorf("GetPipelineForRepo() is %v, want %v", got, pipeline) + } + } + methods["GetPipelineForRepo"] = true + + // update the pipelines + for _, pipeline := range resources.Pipelines { + pipeline.SetVersion("2") + _, err = db.UpdatePipeline(pipeline) + if err != nil { + t.Errorf("unable to update pipeline %d: %v", pipeline.GetID(), err) + } + + // lookup the pipeline by ID + got, err := db.GetPipeline(pipeline.GetID()) + if err != nil { + t.Errorf("unable to get pipeline %d by ID: %v", pipeline.GetID(), err) + } + if !reflect.DeepEqual(got, pipeline) { + t.Errorf("GetPipeline() is %v, want %v", got, pipeline) + } + } + methods["UpdatePipeline"] = true + methods["GetPipeline"] = true + + // delete the pipelines + for _, pipeline := range resources.Pipelines { + err = db.DeletePipeline(pipeline) + if err != nil { + t.Errorf("unable to delete pipeline %d: %v", pipeline.GetID(), err) + } + } + methods["DeletePipeline"] = true + + // ensure we called all the methods we expected to + for method, called := range methods { + if !called { + t.Errorf("method %s was not called for pipelines", method) + } + } +} + +func testRepos(t *testing.T, db Interface, resources *Resources) { + // create a variable to track the number of methods called for repos + methods := make(map[string]bool) + // capture the element type of the repo interface + element := reflect.TypeOf(new(repo.RepoInterface)).Elem() + // iterate through all methods found in the repo interface + for i := 0; i < element.NumMethod(); i++ { + // skip tracking the methods to create indexes and tables for repos + // since those are already called when the database engine starts + if strings.Contains(element.Method(i).Name, "Index") || + strings.Contains(element.Method(i).Name, "Table") { + continue + } + + // add the method name to the list of functions + methods[element.Method(i).Name] = false + } + + // create the repos + for _, repo := range resources.Repos { + _, err := db.CreateRepo(repo) + if err != nil { + t.Errorf("unable to create repo %d: %v", repo.GetID(), err) + } + } + methods["CreateRepo"] = true + + // count the repos + count, err := db.CountRepos() + if err != nil { + t.Errorf("unable to count repos: %v", err) + } + if int(count) != len(resources.Repos) { + t.Errorf("CountRepos() is %v, want %v", count, len(resources.Repos)) + } + methods["CountRepos"] = true + + // count the repos for an org + count, err = db.CountReposForOrg(resources.Repos[0].GetOrg(), nil) + if err != nil { + t.Errorf("unable to count repos for org %s: %v", resources.Repos[0].GetOrg(), err) + } + if int(count) != len(resources.Repos) { + t.Errorf("CountReposForOrg() is %v, want %v", count, len(resources.Repos)) + } + methods["CountReposForOrg"] = true + + // count the repos for a user + count, err = db.CountReposForUser(resources.Users[0], nil) + if err != nil { + t.Errorf("unable to count repos for user %d: %v", resources.Users[0].GetID(), err) + } + if int(count) != len(resources.Repos) { + t.Errorf("CountReposForUser() is %v, want %v", count, len(resources.Repos)) + } + methods["CountReposForUser"] = true + + // list the repos + list, err := db.ListRepos() + if err != nil { + t.Errorf("unable to list repos: %v", err) + } + if !reflect.DeepEqual(list, resources.Repos) { + t.Errorf("ListRepos() is %v, want %v", list, resources.Repos) + } + methods["ListRepos"] = true + + // list the repos for an org + list, count, err = db.ListReposForOrg(resources.Repos[0].GetOrg(), "name", nil, 1, 10) + if err != nil { + t.Errorf("unable to list repos for org %s: %v", resources.Repos[0].GetOrg(), err) + } + if int(count) != len(resources.Repos) { + t.Errorf("ListReposForOrg() is %v, want %v", count, len(resources.Repos)) + } + if !reflect.DeepEqual(list, resources.Repos) { + t.Errorf("ListReposForOrg() is %v, want %v", list, resources.Repos) + } + methods["ListReposForOrg"] = true + + // list the repos for a user + list, count, err = db.ListReposForUser(resources.Users[0], "name", nil, 1, 10) + if err != nil { + t.Errorf("unable to list repos for user %d: %v", resources.Users[0].GetID(), err) + } + if int(count) != len(resources.Repos) { + t.Errorf("ListReposForUser() is %v, want %v", count, len(resources.Repos)) + } + if !reflect.DeepEqual(list, resources.Repos) { + t.Errorf("ListReposForUser() is %v, want %v", list, resources.Repos) + } + methods["ListReposForUser"] = true + + // lookup the repos by name + for _, repo := range resources.Repos { + got, err := db.GetRepoForOrg(repo.GetOrg(), repo.GetName()) + if err != nil { + t.Errorf("unable to get repo %d by org: %v", repo.GetID(), err) + } + if !reflect.DeepEqual(got, repo) { + t.Errorf("GetRepoForOrg() is %v, want %v", got, repo) + } + } + methods["GetRepoForOrg"] = true + + // update the repos + for _, repo := range resources.Repos { + repo.SetActive(false) + _, err = db.UpdateRepo(repo) + if err != nil { + t.Errorf("unable to update repo %d: %v", repo.GetID(), err) + } + + // lookup the repo by ID + got, err := db.GetRepo(repo.GetID()) + if err != nil { + t.Errorf("unable to get repo %d by ID: %v", repo.GetID(), err) + } + if !reflect.DeepEqual(got, repo) { + t.Errorf("GetRepo() is %v, want %v", got, repo) + } + } + methods["UpdateRepo"] = true + methods["GetRepo"] = true + + // delete the repos + for _, repo := range resources.Repos { + err = db.DeleteRepo(repo) + if err != nil { + t.Errorf("unable to delete repo %d: %v", repo.GetID(), err) + } + } + methods["DeleteRepo"] = true + + // ensure we called all the methods we expected to + for method, called := range methods { + if !called { + t.Errorf("method %s was not called for repos", method) + } + } +} + +func testSchedules(t *testing.T, db Interface, resources *Resources) { + // create a variable to track the number of methods called for schedules + methods := make(map[string]bool) + // capture the element type of the schedule interface + element := reflect.TypeOf(new(schedule.ScheduleInterface)).Elem() + // iterate through all methods found in the schedule interface + for i := 0; i < element.NumMethod(); i++ { + // skip tracking the methods to create indexes and tables for schedules + // since those are already called when the database engine starts + if strings.Contains(element.Method(i).Name, "Index") || + strings.Contains(element.Method(i).Name, "Table") { + continue + } + + // add the method name to the list of functions + methods[element.Method(i).Name] = false + } + + // create the schedules + for _, schedule := range resources.Schedules { + err := db.CreateSchedule(schedule) + if err != nil { + t.Errorf("unable to create schedule %d: %v", schedule.GetID(), err) + } + } + methods["CreateSchedule"] = true + + // count the schedules + count, err := db.CountSchedules() + if err != nil { + t.Errorf("unable to count schedules: %v", err) + } + if int(count) != len(resources.Schedules) { + t.Errorf("CountSchedules() is %v, want %v", count, len(resources.Schedules)) + } + methods["CountSchedules"] = true + + // count the schedules for a repo + count, err = db.CountSchedulesForRepo(resources.Repos[0]) + if err != nil { + t.Errorf("unable to count schedules for repo %d: %v", resources.Repos[0].GetID(), err) + } + if int(count) != len(resources.Schedules) { + t.Errorf("CountSchedulesForRepo() is %v, want %v", count, len(resources.Schedules)) + } + methods["CountSchedulesForRepo"] = true + + // list the schedules + list, err := db.ListSchedules() + if err != nil { + t.Errorf("unable to list schedules: %v", err) + } + if !reflect.DeepEqual(list, resources.Schedules) { + t.Errorf("ListSchedules() is %v, want %v", list, resources.Schedules) + } + methods["ListSchedules"] = true + + // list the active schedules + list, err = db.ListActiveSchedules() + if err != nil { + t.Errorf("unable to list schedules: %v", err) + } + if !reflect.DeepEqual(list, resources.Schedules) { + t.Errorf("ListActiveSchedules() is %v, want %v", list, resources.Schedules) + } + methods["ListActiveSchedules"] = true + + // list the schedules for a repo + list, count, err = db.ListSchedulesForRepo(resources.Repos[0], 1, 10) + if err != nil { + t.Errorf("unable to count schedules for repo %d: %v", resources.Repos[0].GetID(), err) + } + if int(count) != len(resources.Schedules) { + t.Errorf("ListSchedulesForRepo() is %v, want %v", count, len(resources.Schedules)) + } + if !reflect.DeepEqual(list, []*library.Schedule{resources.Schedules[1], resources.Schedules[0]}) { + t.Errorf("ListSchedulesForRepo() is %v, want %v", list, []*library.Schedule{resources.Schedules[1], resources.Schedules[0]}) + } + methods["ListSchedulesForRepo"] = true + + // lookup the schedules by name + for _, schedule := range resources.Schedules { + repo := resources.Repos[schedule.GetRepoID()-1] + got, err := db.GetScheduleForRepo(repo, schedule.GetName()) + if err != nil { + t.Errorf("unable to get schedule %d for repo %d: %v", schedule.GetID(), repo.GetID(), err) + } + if !reflect.DeepEqual(got, schedule) { + t.Errorf("GetScheduleForRepo() is %v, want %v", got, schedule) + } + } + methods["GetScheduleForRepo"] = true + + // update the schedules + for _, schedule := range resources.Schedules { + schedule.SetUpdatedAt(time.Now().UTC().Unix()) + err = db.UpdateSchedule(schedule, true) + if err != nil { + t.Errorf("unable to update schedule %d: %v", schedule.GetID(), err) + } + + // lookup the schedule by ID + got, err := db.GetSchedule(schedule.GetID()) + if err != nil { + t.Errorf("unable to get schedule %d by ID: %v", schedule.GetID(), err) + } + if !reflect.DeepEqual(got, schedule) { + t.Errorf("GetSchedule() is %v, want %v", got, schedule) + } + } + methods["UpdateSchedule"] = true + methods["GetSchedule"] = true + + // delete the schedules + for _, schedule := range resources.Schedules { + err = db.DeleteSchedule(schedule) + if err != nil { + t.Errorf("unable to delete schedule %d: %v", schedule.GetID(), err) + } + } + methods["DeleteSchedule"] = true + + // ensure we called all the methods we expected to + for method, called := range methods { + if !called { + t.Errorf("method %s was not called for schedules", method) + } + } +} + +func testSecrets(t *testing.T, db Interface, resources *Resources) { + // create a variable to track the number of methods called for secrets + methods := make(map[string]bool) + // capture the element type of the secret interface + element := reflect.TypeOf(new(secret.SecretInterface)).Elem() + // iterate through all methods found in the secret interface + for i := 0; i < element.NumMethod(); i++ { + // skip tracking the methods to create indexes and tables for secrets + // since those are already called when the database engine starts + if strings.Contains(element.Method(i).Name, "Index") || + strings.Contains(element.Method(i).Name, "Table") { + continue + } + + // add the method name to the list of functions + methods[element.Method(i).Name] = false + } + + // create the secrets + for _, secret := range resources.Secrets { + err := db.CreateSecret(secret) + if err != nil { + t.Errorf("unable to create secret %d: %v", secret.GetID(), err) + } + } + methods["CreateSecret"] = true + + // count the secrets + count, err := db.CountSecrets() + if err != nil { + t.Errorf("unable to count secrets: %v", err) + } + if int(count) != len(resources.Secrets) { + t.Errorf("CountSecrets() is %v, want %v", count, len(resources.Secrets)) + } + methods["CountSecrets"] = true + + for _, secret := range resources.Secrets { + switch secret.GetType() { + case constants.SecretOrg: + // count the secrets for an org + count, err = db.CountSecretsForOrg(secret.GetOrg(), nil) + if err != nil { + t.Errorf("unable to count secrets for org %s: %v", secret.GetOrg(), err) + } + if int(count) != 1 { + t.Errorf("CountSecretsForOrg() is %v, want %v", count, 1) + } + methods["CountSecretsForOrg"] = true + case constants.SecretRepo: + // count the secrets for a repo + count, err = db.CountSecretsForRepo(resources.Repos[0], nil) + if err != nil { + t.Errorf("unable to count secrets for repo %d: %v", resources.Repos[0].GetID(), err) + } + if int(count) != 1 { + t.Errorf("CountSecretsForRepo() is %v, want %v", count, 1) + } + methods["CountSecretsForRepo"] = true + case constants.SecretShared: + // count the secrets for a team + count, err = db.CountSecretsForTeam(secret.GetOrg(), secret.GetTeam(), nil) + if err != nil { + t.Errorf("unable to count secrets for team %s: %v", secret.GetTeam(), err) + } + if int(count) != 1 { + t.Errorf("CountSecretsForTeam() is %v, want %v", count, 1) + } + methods["CountSecretsForTeam"] = true + + // count the secrets for a list of teams + count, err = db.CountSecretsForTeams(secret.GetOrg(), []string{secret.GetTeam()}, nil) + if err != nil { + t.Errorf("unable to count secrets for teams %s: %v", []string{secret.GetTeam()}, err) + } + if int(count) != 1 { + t.Errorf("CountSecretsForTeams() is %v, want %v", count, 1) + } + methods["CountSecretsForTeams"] = true + default: + t.Errorf("unsupported type %s for secret %d", secret.GetType(), secret.GetID()) + } + } + + // list the secrets + list, err := db.ListSecrets() + if err != nil { + t.Errorf("unable to list secrets: %v", err) + } + if !reflect.DeepEqual(list, resources.Secrets) { + t.Errorf("ListSecrets() is %v, want %v", list, resources.Secrets) + } + methods["ListSecrets"] = true + + for _, secret := range resources.Secrets { + switch secret.GetType() { + case constants.SecretOrg: + // list the secrets for an org + list, count, err = db.ListSecretsForOrg(secret.GetOrg(), nil, 1, 10) + if err != nil { + t.Errorf("unable to list secrets for org %s: %v", secret.GetOrg(), err) + } + if int(count) != 1 { + t.Errorf("ListSecretsForOrg() is %v, want %v", count, 1) + } + if !reflect.DeepEqual(list, []*library.Secret{secret}) { + t.Errorf("ListSecretsForOrg() is %v, want %v", list, []*library.Secret{secret}) + } + methods["ListSecretsForOrg"] = true + case constants.SecretRepo: + // list the secrets for a repo + list, count, err = db.ListSecretsForRepo(resources.Repos[0], nil, 1, 10) + if err != nil { + t.Errorf("unable to list secrets for repo %d: %v", resources.Repos[0].GetID(), err) + } + if int(count) != 1 { + t.Errorf("ListSecretsForRepo() is %v, want %v", count, 1) + } + if !reflect.DeepEqual(list, []*library.Secret{secret}) { + t.Errorf("ListSecretsForRepo() is %v, want %v", list, []*library.Secret{secret}) + } + methods["ListSecretsForRepo"] = true + case constants.SecretShared: + // list the secrets for a team + list, count, err = db.ListSecretsForTeam(secret.GetOrg(), secret.GetTeam(), nil, 1, 10) + if err != nil { + t.Errorf("unable to list secrets for team %s: %v", secret.GetTeam(), err) + } + if int(count) != 1 { + t.Errorf("ListSecretsForTeam() is %v, want %v", count, 1) + } + if !reflect.DeepEqual(list, []*library.Secret{secret}) { + t.Errorf("ListSecretsForTeam() is %v, want %v", list, []*library.Secret{secret}) + } + methods["ListSecretsForTeam"] = true + + // list the secrets for a list of teams + list, count, err = db.ListSecretsForTeams(secret.GetOrg(), []string{secret.GetTeam()}, nil, 1, 10) + if err != nil { + t.Errorf("unable to list secrets for teams %s: %v", []string{secret.GetTeam()}, err) + } + if int(count) != 1 { + t.Errorf("ListSecretsForTeams() is %v, want %v", count, 1) + } + if !reflect.DeepEqual(list, []*library.Secret{secret}) { + t.Errorf("ListSecretsForTeams() is %v, want %v", list, []*library.Secret{secret}) + } + methods["ListSecretsForTeams"] = true + default: + t.Errorf("unsupported type %s for secret %d", secret.GetType(), secret.GetID()) + } + } + + for _, secret := range resources.Secrets { + switch secret.GetType() { + case constants.SecretOrg: + // lookup the secret by org + got, err := db.GetSecretForOrg(secret.GetOrg(), secret.GetName()) + if err != nil { + t.Errorf("unable to get secret %d for org %s: %v", secret.GetID(), secret.GetOrg(), err) + } + if !reflect.DeepEqual(got, secret) { + t.Errorf("GetSecretForOrg() is %v, want %v", got, secret) + } + methods["GetSecretForOrg"] = true + case constants.SecretRepo: + // lookup the secret by repo + got, err := db.GetSecretForRepo(secret.GetName(), resources.Repos[0]) + if err != nil { + t.Errorf("unable to get secret %d for repo %d: %v", secret.GetID(), resources.Repos[0].GetID(), err) + } + if !reflect.DeepEqual(got, secret) { + t.Errorf("GetSecretForRepo() is %v, want %v", got, secret) + } + methods["GetSecretForRepo"] = true + case constants.SecretShared: + // lookup the secret by team + got, err := db.GetSecretForTeam(secret.GetOrg(), secret.GetTeam(), secret.GetName()) + if err != nil { + t.Errorf("unable to get secret %d for team %s: %v", secret.GetID(), secret.GetTeam(), err) + } + if !reflect.DeepEqual(got, secret) { + t.Errorf("GetSecretForTeam() is %v, want %v", got, secret) + } + methods["GetSecretForTeam"] = true + default: + t.Errorf("unsupported type %s for secret %d", secret.GetType(), secret.GetID()) + } + } + + // update the secrets + for _, secret := range resources.Secrets { + secret.SetUpdatedAt(time.Now().UTC().Unix()) + err = db.UpdateSecret(secret) + if err != nil { + t.Errorf("unable to update secret %d: %v", secret.GetID(), err) + } + + // lookup the secret by ID + got, err := db.GetSecret(secret.GetID()) + if err != nil { + t.Errorf("unable to get secret %d by ID: %v", secret.GetID(), err) + } + if !reflect.DeepEqual(got, secret) { + t.Errorf("GetSecret() is %v, want %v", got, secret) + } + } + methods["UpdateSecret"] = true + methods["GetSecret"] = true + + // delete the secrets + for _, secret := range resources.Secrets { + err = db.DeleteSecret(secret) + if err != nil { + t.Errorf("unable to delete secret %d: %v", secret.GetID(), err) + } + } + methods["DeleteSecret"] = true + + // ensure we called all the methods we expected to + for method, called := range methods { + if !called { + t.Errorf("method %s was not called for secrets", method) + } + } +} + +func testServices(t *testing.T, db Interface, resources *Resources) { + // create a variable to track the number of methods called for services + methods := make(map[string]bool) + // capture the element type of the service interface + element := reflect.TypeOf(new(service.ServiceInterface)).Elem() + // iterate through all methods found in the service interface + for i := 0; i < element.NumMethod(); i++ { + // skip tracking the methods to create indexes and tables for services + // since those are already called when the database engine starts + if strings.Contains(element.Method(i).Name, "Index") || + strings.Contains(element.Method(i).Name, "Table") { + continue + } + + // add the method name to the list of functions + methods[element.Method(i).Name] = false + } + + // create the services + for _, service := range resources.Services { + err := db.CreateService(service) + if err != nil { + t.Errorf("unable to create service %d: %v", service.GetID(), err) + } + } + methods["CreateService"] = true + + // count the services + count, err := db.CountServices() + if err != nil { + t.Errorf("unable to count services: %v", err) + } + if int(count) != len(resources.Services) { + t.Errorf("CountServices() is %v, want %v", count, len(resources.Services)) + } + methods["CountServices"] = true + + // count the services for a build + count, err = db.CountServicesForBuild(resources.Builds[0], nil) + if err != nil { + t.Errorf("unable to count services for build %d: %v", resources.Builds[0].GetID(), err) + } + if int(count) != len(resources.Services) { + t.Errorf("CountServicesForBuild() is %v, want %v", count, len(resources.Services)) + } + methods["CountServicesForBuild"] = true + + // list the services + list, err := db.ListServices() + if err != nil { + t.Errorf("unable to list services: %v", err) + } + if !reflect.DeepEqual(list, resources.Services) { + t.Errorf("ListServices() is %v, want %v", list, resources.Services) + } + methods["ListServices"] = true + + // list the services for a build + list, count, err = db.ListServicesForBuild(resources.Builds[0], nil, 1, 10) + if err != nil { + t.Errorf("unable to list services for build %d: %v", resources.Builds[0].GetID(), err) + } + if !reflect.DeepEqual(list, []*library.Service{resources.Services[1], resources.Services[0]}) { + t.Errorf("ListServicesForBuild() is %v, want %v", list, []*library.Service{resources.Services[1], resources.Services[0]}) + } + if int(count) != len(resources.Services) { + t.Errorf("ListServicesForBuild() is %v, want %v", count, len(resources.Services)) + } + methods["ListServicesForBuild"] = true + + expected := map[string]float64{ + "#init": 1, + "target/vela-git:v0.3.0": 1, + } + images, err := db.ListServiceImageCount() + if err != nil { + t.Errorf("unable to list service image count: %v", err) + } + if !reflect.DeepEqual(images, expected) { + t.Errorf("ListServiceImageCount() is %v, want %v", images, expected) + } + methods["ListServiceImageCount"] = true + + expected = map[string]float64{ + "pending": 1, + "failure": 0, + "killed": 0, + "running": 1, + "success": 0, + } + statuses, err := db.ListServiceStatusCount() + if err != nil { + t.Errorf("unable to list service status count: %v", err) + } + if !reflect.DeepEqual(statuses, expected) { + t.Errorf("ListServiceStatusCount() is %v, want %v", statuses, expected) + } + methods["ListServiceStatusCount"] = true + + // lookup the services by name + for _, service := range resources.Services { + build := resources.Builds[service.GetBuildID()-1] + got, err := db.GetServiceForBuild(build, service.GetNumber()) + if err != nil { + t.Errorf("unable to get service %d for build %d: %v", service.GetID(), build.GetID(), err) + } + if !reflect.DeepEqual(got, service) { + t.Errorf("GetServiceForBuild() is %v, want %v", got, service) + } + } + methods["GetServiceForBuild"] = true + + // clean the services + count, err = db.CleanServices("integration testing", 1563474090) + if err != nil { + t.Errorf("unable to clean services: %v", err) + } + if int(count) != len(resources.Services) { + t.Errorf("CleanServices() is %v, want %v", count, len(resources.Services)) + } + methods["CleanServices"] = true + + // update the services + for _, service := range resources.Services { + service.SetStatus("success") + err = db.UpdateService(service) + if err != nil { + t.Errorf("unable to update service %d: %v", service.GetID(), err) + } + + // lookup the service by ID + got, err := db.GetService(service.GetID()) + if err != nil { + t.Errorf("unable to get service %d by ID: %v", service.GetID(), err) + } + if !reflect.DeepEqual(got, service) { + t.Errorf("GetService() is %v, want %v", got, service) + } + } + methods["UpdateService"] = true + methods["GetService"] = true + + // delete the services + for _, service := range resources.Services { + err = db.DeleteService(service) + if err != nil { + t.Errorf("unable to delete service %d: %v", service.GetID(), err) + } + } + methods["DeleteService"] = true + + // ensure we called all the methods we expected to + for method, called := range methods { + if !called { + t.Errorf("method %s was not called for services", method) + } + } +} + +func testSteps(t *testing.T, db Interface, resources *Resources) { + // create a variable to track the number of methods called for steps + methods := make(map[string]bool) + // capture the element type of the step interface + element := reflect.TypeOf(new(step.StepInterface)).Elem() + // iterate through all methods found in the step interface + for i := 0; i < element.NumMethod(); i++ { + // skip tracking the methods to create indexes and tables for steps + // since those are already called when the database engine starts + if strings.Contains(element.Method(i).Name, "Index") || + strings.Contains(element.Method(i).Name, "Table") { + continue + } + + // add the method name to the list of functions + methods[element.Method(i).Name] = false + } + + // create the steps + for _, step := range resources.Steps { + err := db.CreateStep(step) + if err != nil { + t.Errorf("unable to create step %d: %v", step.GetID(), err) + } + } + methods["CreateStep"] = true + + // count the steps + count, err := db.CountSteps() + if err != nil { + t.Errorf("unable to count steps: %v", err) + } + if int(count) != len(resources.Steps) { + t.Errorf("CountSteps() is %v, want %v", count, len(resources.Steps)) + } + methods["CountSteps"] = true + + // count the steps for a build + count, err = db.CountStepsForBuild(resources.Builds[0], nil) + if err != nil { + t.Errorf("unable to count steps for build %d: %v", resources.Builds[0].GetID(), err) + } + if int(count) != len(resources.Steps) { + t.Errorf("CountStepsForBuild() is %v, want %v", count, len(resources.Steps)) + } + methods["CountStepsForBuild"] = true + + // list the steps + list, err := db.ListSteps() + if err != nil { + t.Errorf("unable to list steps: %v", err) + } + if !reflect.DeepEqual(list, resources.Steps) { + t.Errorf("ListSteps() is %v, want %v", list, resources.Steps) + } + methods["ListSteps"] = true + + // list the steps for a build + list, count, err = db.ListStepsForBuild(resources.Builds[0], nil, 1, 10) + if err != nil { + t.Errorf("unable to list steps for build %d: %v", resources.Builds[0].GetID(), err) + } + if !reflect.DeepEqual(list, []*library.Step{resources.Steps[1], resources.Steps[0]}) { + t.Errorf("ListStepsForBuild() is %v, want %v", list, []*library.Step{resources.Steps[1], resources.Steps[0]}) + } + if int(count) != len(resources.Steps) { + t.Errorf("ListStepsForBuild() is %v, want %v", count, len(resources.Steps)) + } + methods["ListStepsForBuild"] = true + + expected := map[string]float64{ + "#init": 1, + "target/vela-git:v0.3.0": 1, + } + images, err := db.ListStepImageCount() + if err != nil { + t.Errorf("unable to list step image count: %v", err) + } + if !reflect.DeepEqual(images, expected) { + t.Errorf("ListStepImageCount() is %v, want %v", images, expected) + } + methods["ListStepImageCount"] = true + + expected = map[string]float64{ + "pending": 1, + "failure": 0, + "killed": 0, + "running": 1, + "success": 0, + } + statuses, err := db.ListStepStatusCount() + if err != nil { + t.Errorf("unable to list step status count: %v", err) + } + if !reflect.DeepEqual(statuses, expected) { + t.Errorf("ListStepStatusCount() is %v, want %v", statuses, expected) + } + methods["ListStepStatusCount"] = true + + // lookup the steps by name + for _, step := range resources.Steps { + build := resources.Builds[step.GetBuildID()-1] + got, err := db.GetStepForBuild(build, step.GetNumber()) + if err != nil { + t.Errorf("unable to get step %d for build %d: %v", step.GetID(), build.GetID(), err) + } + if !reflect.DeepEqual(got, step) { + t.Errorf("GetStepForBuild() is %v, want %v", got, step) + } + } + methods["GetStepForBuild"] = true + + // clean the steps + count, err = db.CleanSteps("integration testing", 1563474090) + if err != nil { + t.Errorf("unable to clean steps: %v", err) + } + if int(count) != len(resources.Steps) { + t.Errorf("CleanSteps() is %v, want %v", count, len(resources.Steps)) + } + methods["CleanSteps"] = true + + // update the steps + for _, step := range resources.Steps { + step.SetStatus("success") + err = db.UpdateStep(step) + if err != nil { + t.Errorf("unable to update step %d: %v", step.GetID(), err) + } + + // lookup the step by ID + got, err := db.GetStep(step.GetID()) + if err != nil { + t.Errorf("unable to get step %d by ID: %v", step.GetID(), err) + } + if !reflect.DeepEqual(got, step) { + t.Errorf("GetStep() is %v, want %v", got, step) + } + } + methods["UpdateStep"] = true + methods["GetStep"] = true + + // delete the steps + for _, step := range resources.Steps { + err = db.DeleteStep(step) + if err != nil { + t.Errorf("unable to delete step %d: %v", step.GetID(), err) + } + } + methods["DeleteStep"] = true + + // ensure we called all the methods we expected to + for method, called := range methods { + if !called { + t.Errorf("method %s was not called for steps", method) + } + } +} + +func testUsers(t *testing.T, db Interface, resources *Resources) { + // create a variable to track the number of methods called for users + methods := make(map[string]bool) + // capture the element type of the user interface + element := reflect.TypeOf(new(user.UserInterface)).Elem() + // iterate through all methods found in the user interface + for i := 0; i < element.NumMethod(); i++ { + // skip tracking the methods to create indexes and tables for users + // since those are already called when the database engine starts + if strings.Contains(element.Method(i).Name, "Index") || + strings.Contains(element.Method(i).Name, "Table") { + continue + } + + // add the method name to the list of functions + methods[element.Method(i).Name] = false + } + + userOne := new(library.User) + userOne.SetID(1) + userOne.SetName("octocat") + userOne.SetToken("") + userOne.SetRefreshToken("") + userOne.SetHash("") + userOne.SetFavorites(nil) + userOne.SetActive(false) + userOne.SetAdmin(false) + + userTwo := new(library.User) + userTwo.SetID(2) + userTwo.SetName("octokitty") + userTwo.SetToken("") + userTwo.SetRefreshToken("") + userTwo.SetHash("") + userTwo.SetFavorites(nil) + userTwo.SetActive(false) + userTwo.SetAdmin(false) + + liteUsers := []*library.User{userOne, userTwo} + + // create the users + for _, user := range resources.Users { + err := db.CreateUser(user) + if err != nil { + t.Errorf("unable to create user %d: %v", user.GetID(), err) + } + } + methods["CreateUser"] = true + + // count the users + count, err := db.CountUsers() + if err != nil { + t.Errorf("unable to count users: %v", err) + } + if int(count) != len(resources.Users) { + t.Errorf("CountUsers() is %v, want %v", count, len(resources.Users)) + } + methods["CountUsers"] = true + + // list the users + list, err := db.ListUsers() + if err != nil { + t.Errorf("unable to list users: %v", err) + } + if !reflect.DeepEqual(list, resources.Users) { + t.Errorf("ListUsers() is %v, want %v", list, resources.Users) + } + methods["ListUsers"] = true + + // lite list the users + list, count, err = db.ListLiteUsers(1, 10) + if err != nil { + t.Errorf("unable to list lite users: %v", err) + } + if !reflect.DeepEqual(list, liteUsers) { + t.Errorf("ListLiteUsers() is %v, want %v", list, liteUsers) + } + if int(count) != len(liteUsers) { + t.Errorf("ListLiteUsers() is %v, want %v", count, len(liteUsers)) + } + methods["ListLiteUsers"] = true + + // lookup the users by name + for _, user := range resources.Users { + got, err := db.GetUserForName(user.GetName()) + if err != nil { + t.Errorf("unable to get user %d by name: %v", user.GetID(), err) + } + if !reflect.DeepEqual(got, user) { + t.Errorf("GetUserForName() is %v, want %v", got, user) + } + } + methods["GetUserForName"] = true + + // update the users + for _, user := range resources.Users { + user.SetActive(false) + err = db.UpdateUser(user) + if err != nil { + t.Errorf("unable to update user %d: %v", user.GetID(), err) + } + + // lookup the user by ID + got, err := db.GetUser(user.GetID()) + if err != nil { + t.Errorf("unable to get user %d by ID: %v", user.GetID(), err) + } + if !reflect.DeepEqual(got, user) { + t.Errorf("GetUser() is %v, want %v", got, user) + } + } + methods["UpdateUser"] = true + methods["GetUser"] = true + + // delete the users + for _, user := range resources.Users { + err = db.DeleteUser(user) + if err != nil { + t.Errorf("unable to delete user %d: %v", user.GetID(), err) + } + } + methods["DeleteUser"] = true + + // ensure we called all the methods we expected to + for method, called := range methods { + if !called { + t.Errorf("method %s was not called for users", method) + } + } +} + +func testWorkers(t *testing.T, db Interface, resources *Resources) { + // create a variable to track the number of methods called for workers + methods := make(map[string]bool) + // capture the element type of the worker interface + element := reflect.TypeOf(new(worker.WorkerInterface)).Elem() + // iterate through all methods found in the worker interface + for i := 0; i < element.NumMethod(); i++ { + // skip tracking the methods to create indexes and tables for workers + // since those are already called when the database engine starts + if strings.Contains(element.Method(i).Name, "Index") || + strings.Contains(element.Method(i).Name, "Table") { + continue + } + + // add the method name to the list of functions + methods[element.Method(i).Name] = false + } + + // create the workers + for _, worker := range resources.Workers { + err := db.CreateWorker(worker) + if err != nil { + t.Errorf("unable to create worker %d: %v", worker.GetID(), err) + } + } + methods["CreateWorker"] = true + + // count the workers + count, err := db.CountWorkers() + if err != nil { + t.Errorf("unable to count workers: %v", err) + } + if int(count) != len(resources.Workers) { + t.Errorf("CountWorkers() is %v, want %v", count, len(resources.Workers)) + } + methods["CountWorkers"] = true + + // list the workers + list, err := db.ListWorkers() + if err != nil { + t.Errorf("unable to list workers: %v", err) + } + if !reflect.DeepEqual(list, resources.Workers) { + t.Errorf("ListWorkers() is %v, want %v", list, resources.Workers) + } + methods["ListWorkers"] = true + + // lookup the workers by hostname + for _, worker := range resources.Workers { + got, err := db.GetWorkerForHostname(worker.GetHostname()) + if err != nil { + t.Errorf("unable to get worker %d by hostname: %v", worker.GetID(), err) + } + if !reflect.DeepEqual(got, worker) { + t.Errorf("GetWorkerForHostname() is %v, want %v", got, worker) + } + } + methods["GetWorkerForHostname"] = true + + // update the workers + for _, worker := range resources.Workers { + worker.SetActive(false) + err = db.UpdateWorker(worker) + if err != nil { + t.Errorf("unable to update worker %d: %v", worker.GetID(), err) + } + + // lookup the worker by ID + got, err := db.GetWorker(worker.GetID()) + if err != nil { + t.Errorf("unable to get worker %d by ID: %v", worker.GetID(), err) + } + if !reflect.DeepEqual(got, worker) { + t.Errorf("GetWorker() is %v, want %v", got, worker) + } + } + methods["UpdateWorker"] = true + methods["GetWorker"] = true + + // delete the workers + for _, worker := range resources.Workers { + err = db.DeleteWorker(worker) + if err != nil { + t.Errorf("unable to delete worker %d: %v", worker.GetID(), err) + } + } + methods["DeleteWorker"] = true + + // ensure we called all the methods we expected to + for method, called := range methods { + if !called { + t.Errorf("method %s was not called for workers", method) + } + } +} + +func newResources() *Resources { + buildOne := new(library.Build) + buildOne.SetID(1) + buildOne.SetRepoID(1) + buildOne.SetPipelineID(1) + buildOne.SetNumber(1) + buildOne.SetParent(1) + buildOne.SetEvent("push") + buildOne.SetEventAction("") + buildOne.SetStatus("running") + buildOne.SetError("") + buildOne.SetEnqueued(1563474077) + buildOne.SetCreated(1563474076) + buildOne.SetStarted(1563474078) + buildOne.SetFinished(1563474079) + buildOne.SetDeploy("") + buildOne.SetDeployPayload(raw.StringSliceMap{"foo": "test1"}) + buildOne.SetClone("https://github.com/github/octocat.git") + buildOne.SetSource("https://github.com/github/octocat/deployments/1") + buildOne.SetTitle("push received from https://github.com/github/octocat") + buildOne.SetMessage("First commit...") + buildOne.SetCommit("48afb5bdc41ad69bf22588491333f7cf71135163") + buildOne.SetSender("OctoKitty") + buildOne.SetAuthor("OctoKitty") + buildOne.SetEmail("OctoKitty@github.com") + buildOne.SetLink("https://example.company.com/github/octocat/1") + buildOne.SetBranch("main") + buildOne.SetRef("refs/heads/main") + buildOne.SetBaseRef("") + buildOne.SetHeadRef("changes") + buildOne.SetHost("example.company.com") + buildOne.SetRuntime("docker") + buildOne.SetDistribution("linux") + + buildTwo := new(library.Build) + buildTwo.SetID(2) + buildTwo.SetRepoID(1) + buildTwo.SetPipelineID(1) + buildTwo.SetNumber(2) + buildTwo.SetParent(1) + buildTwo.SetEvent("pull_request") + buildTwo.SetEventAction("") + buildTwo.SetStatus("running") + buildTwo.SetError("") + buildTwo.SetEnqueued(1563474077) + buildTwo.SetCreated(1563474076) + buildTwo.SetStarted(1563474078) + buildTwo.SetFinished(1563474079) + buildTwo.SetDeploy("") + buildTwo.SetDeployPayload(raw.StringSliceMap{"foo": "test1"}) + buildTwo.SetClone("https://github.com/github/octocat.git") + buildTwo.SetSource("https://github.com/github/octocat/deployments/1") + buildTwo.SetTitle("pull_request received from https://github.com/github/octocat") + buildTwo.SetMessage("Second commit...") + buildTwo.SetCommit("48afb5bdc41ad69bf22588491333f7cf71135164") + buildTwo.SetSender("OctoKitty") + buildTwo.SetAuthor("OctoKitty") + buildTwo.SetEmail("OctoKitty@github.com") + buildTwo.SetLink("https://example.company.com/github/octocat/2") + buildTwo.SetBranch("main") + buildTwo.SetRef("refs/heads/main") + buildTwo.SetBaseRef("") + buildTwo.SetHeadRef("changes") + buildTwo.SetHost("example.company.com") + buildTwo.SetRuntime("docker") + buildTwo.SetDistribution("linux") + + deploymentOne := new(library.Deployment) + deploymentOne.SetID(1) + deploymentOne.SetRepoID(1) + deploymentOne.SetURL("https://github.com/github/octocat/deployments/1") + deploymentOne.SetUser("octocat") + deploymentOne.SetCommit("48afb5bdc41ad69bf22588491333f7cf71135163") + deploymentOne.SetRef("refs/heads/master") + deploymentOne.SetTask("vela-deploy") + deploymentOne.SetTarget("production") + deploymentOne.SetDescription("Deployment request from Vela") + deploymentOne.SetPayload(map[string]string{"foo": "test1"}) + + deploymentTwo := new(library.Deployment) + deploymentTwo.SetID(1) + deploymentTwo.SetRepoID(1) + deploymentTwo.SetURL("https://github.com/github/octocat/deployments/2") + deploymentTwo.SetUser("octocat") + deploymentTwo.SetCommit("48afb5bdc41ad69bf22588491333f7cf71135164") + deploymentTwo.SetRef("refs/heads/master") + deploymentTwo.SetTask("vela-deploy") + deploymentTwo.SetTarget("production") + deploymentTwo.SetDescription("Deployment request from Vela") + deploymentTwo.SetPayload(map[string]string{"foo": "test1"}) + + hookOne := new(library.Hook) + hookOne.SetID(1) + hookOne.SetRepoID(1) + hookOne.SetBuildID(1) + hookOne.SetNumber(1) + hookOne.SetSourceID("c8da1302-07d6-11ea-882f-4893bca275b8") + hookOne.SetCreated(time.Now().UTC().Unix()) + hookOne.SetHost("github.com") + hookOne.SetEvent("push") + hookOne.SetEventAction("") + hookOne.SetBranch("main") + hookOne.SetError("") + hookOne.SetStatus("success") + hookOne.SetLink("https://github.com/github/octocat/settings/hooks/1") + hookOne.SetWebhookID(123456) + + hookTwo := new(library.Hook) + hookTwo.SetID(2) + hookTwo.SetRepoID(1) + hookTwo.SetBuildID(1) + hookTwo.SetNumber(2) + hookTwo.SetSourceID("c8da1302-07d6-11ea-882f-4893bca275b8") + hookTwo.SetCreated(time.Now().UTC().Unix()) + hookTwo.SetHost("github.com") + hookTwo.SetEvent("push") + hookTwo.SetEventAction("") + hookTwo.SetBranch("main") + hookTwo.SetError("") + hookTwo.SetStatus("success") + hookTwo.SetLink("https://github.com/github/octocat/settings/hooks/1") + hookTwo.SetWebhookID(123456) + + logServiceOne := new(library.Log) + logServiceOne.SetID(1) + logServiceOne.SetBuildID(1) + logServiceOne.SetRepoID(1) + logServiceOne.SetServiceID(1) + logServiceOne.SetStepID(0) + logServiceOne.SetData([]byte("foo")) + + logServiceTwo := new(library.Log) + logServiceTwo.SetID(2) + logServiceTwo.SetBuildID(1) + logServiceTwo.SetRepoID(1) + logServiceTwo.SetServiceID(2) + logServiceTwo.SetStepID(0) + logServiceTwo.SetData([]byte("foo")) + + logStepOne := new(library.Log) + logStepOne.SetID(3) + logStepOne.SetBuildID(1) + logStepOne.SetRepoID(1) + logStepOne.SetServiceID(0) + logStepOne.SetStepID(1) + logStepOne.SetData([]byte("foo")) + + logStepTwo := new(library.Log) + logStepTwo.SetID(4) + logStepTwo.SetBuildID(1) + logStepTwo.SetRepoID(1) + logStepTwo.SetServiceID(0) + logStepTwo.SetStepID(2) + logStepTwo.SetData([]byte("foo")) + + pipelineOne := new(library.Pipeline) + pipelineOne.SetID(1) + pipelineOne.SetRepoID(1) + pipelineOne.SetCommit("48afb5bdc41ad69bf22588491333f7cf71135163") + pipelineOne.SetFlavor("large") + pipelineOne.SetPlatform("docker") + pipelineOne.SetRef("refs/heads/main") + pipelineOne.SetType("yaml") + pipelineOne.SetVersion("1") + pipelineOne.SetExternalSecrets(false) + pipelineOne.SetInternalSecrets(false) + pipelineOne.SetServices(true) + pipelineOne.SetStages(false) + pipelineOne.SetSteps(true) + pipelineOne.SetTemplates(false) + pipelineOne.SetData([]byte("version: 1")) + + pipelineTwo := new(library.Pipeline) + pipelineTwo.SetID(2) + pipelineTwo.SetRepoID(1) + pipelineTwo.SetCommit("48afb5bdc41ad69bf22588491333f7cf71135164") + pipelineTwo.SetFlavor("large") + pipelineTwo.SetPlatform("docker") + pipelineTwo.SetRef("refs/heads/main") + pipelineTwo.SetType("yaml") + pipelineTwo.SetVersion("1") + pipelineTwo.SetExternalSecrets(false) + pipelineTwo.SetInternalSecrets(false) + pipelineTwo.SetServices(true) + pipelineTwo.SetStages(false) + pipelineTwo.SetSteps(true) + pipelineTwo.SetTemplates(false) + pipelineTwo.SetData([]byte("version: 1")) + + repoOne := new(library.Repo) + repoOne.SetID(1) + repoOne.SetUserID(1) + repoOne.SetHash("MzM4N2MzMDAtNmY4Mi00OTA5LWFhZDAtNWIzMTlkNTJkODMy") + repoOne.SetOrg("github") + repoOne.SetName("octocat") + repoOne.SetFullName("github/octocat") + repoOne.SetLink("https://github.com/github/octocat") + repoOne.SetClone("https://github.com/github/octocat.git") + repoOne.SetBranch("main") + repoOne.SetTopics([]string{"cloud", "security"}) + repoOne.SetBuildLimit(10) + repoOne.SetTimeout(30) + repoOne.SetCounter(0) + repoOne.SetVisibility("public") + repoOne.SetPrivate(false) + repoOne.SetTrusted(false) + repoOne.SetActive(true) + repoOne.SetAllowPull(false) + repoOne.SetAllowPush(true) + repoOne.SetAllowDeploy(false) + repoOne.SetAllowTag(false) + repoOne.SetAllowComment(false) + repoOne.SetPipelineType("") + repoOne.SetPreviousName("") + + repoTwo := new(library.Repo) + repoTwo.SetID(2) + repoTwo.SetUserID(1) + repoTwo.SetHash("MzM4N2MzMDAtNmY4Mi00OTA5LWFhZDAtNWIzMTlkNTJkODMy") + repoTwo.SetOrg("github") + repoTwo.SetName("octokitty") + repoTwo.SetFullName("github/octokitty") + repoTwo.SetLink("https://github.com/github/octokitty") + repoTwo.SetClone("https://github.com/github/octokitty.git") + repoTwo.SetBranch("main") + repoTwo.SetTopics([]string{"cloud", "security"}) + repoTwo.SetBuildLimit(10) + repoTwo.SetTimeout(30) + repoTwo.SetCounter(0) + repoTwo.SetVisibility("public") + repoTwo.SetPrivate(false) + repoTwo.SetTrusted(false) + repoTwo.SetActive(true) + repoTwo.SetAllowPull(false) + repoTwo.SetAllowPush(true) + repoTwo.SetAllowDeploy(false) + repoTwo.SetAllowTag(false) + repoTwo.SetAllowComment(false) + repoTwo.SetPipelineType("") + repoTwo.SetPreviousName("") + + scheduleOne := new(library.Schedule) + scheduleOne.SetID(1) + scheduleOne.SetRepoID(1) + scheduleOne.SetActive(true) + scheduleOne.SetName("nightly") + scheduleOne.SetEntry("0 0 * * *") + scheduleOne.SetCreatedAt(time.Now().UTC().Unix()) + scheduleOne.SetCreatedBy("octocat") + scheduleOne.SetUpdatedAt(time.Now().Add(time.Hour * 1).UTC().Unix()) + scheduleOne.SetUpdatedBy("octokitty") + scheduleOne.SetScheduledAt(time.Now().Add(time.Hour * 2).UTC().Unix()) + + scheduleTwo := new(library.Schedule) + scheduleTwo.SetID(2) + scheduleTwo.SetRepoID(1) + scheduleTwo.SetActive(true) + scheduleTwo.SetName("hourly") + scheduleTwo.SetEntry("0 * * * *") + scheduleTwo.SetCreatedAt(time.Now().UTC().Unix()) + scheduleTwo.SetCreatedBy("octocat") + scheduleTwo.SetUpdatedAt(time.Now().Add(time.Hour * 1).UTC().Unix()) + scheduleTwo.SetUpdatedBy("octokitty") + scheduleTwo.SetScheduledAt(time.Now().Add(time.Hour * 2).UTC().Unix()) + + secretOrg := new(library.Secret) + secretOrg.SetID(1) + secretOrg.SetOrg("github") + secretOrg.SetRepo("*") + secretOrg.SetTeam("") + secretOrg.SetName("foo") + secretOrg.SetValue("bar") + secretOrg.SetType("org") + secretOrg.SetImages([]string{"alpine"}) + secretOrg.SetEvents([]string{"push", "tag", "deployment"}) + secretOrg.SetAllowCommand(true) + secretOrg.SetCreatedAt(time.Now().UTC().Unix()) + secretOrg.SetCreatedBy("octocat") + secretOrg.SetUpdatedAt(time.Now().Add(time.Hour * 1).UTC().Unix()) + secretOrg.SetUpdatedBy("octokitty") + + secretRepo := new(library.Secret) + secretRepo.SetID(2) + secretRepo.SetOrg("github") + secretRepo.SetRepo("octocat") + secretRepo.SetTeam("") + secretRepo.SetName("foo") + secretRepo.SetValue("bar") + secretRepo.SetType("repo") + secretRepo.SetImages([]string{"alpine"}) + secretRepo.SetEvents([]string{"push", "tag", "deployment"}) + secretRepo.SetAllowCommand(true) + secretRepo.SetCreatedAt(time.Now().UTC().Unix()) + secretRepo.SetCreatedBy("octocat") + secretRepo.SetUpdatedAt(time.Now().Add(time.Hour * 1).UTC().Unix()) + secretRepo.SetUpdatedBy("octokitty") + + secretShared := new(library.Secret) + secretShared.SetID(3) + secretShared.SetOrg("github") + secretShared.SetRepo("") + secretShared.SetTeam("octocat") + secretShared.SetName("foo") + secretShared.SetValue("bar") + secretShared.SetType("shared") + secretShared.SetImages([]string{"alpine"}) + secretShared.SetEvents([]string{"push", "tag", "deployment"}) + secretShared.SetAllowCommand(true) + secretShared.SetCreatedAt(time.Now().UTC().Unix()) + secretShared.SetCreatedBy("octocat") + secretShared.SetUpdatedAt(time.Now().Add(time.Hour * 1).UTC().Unix()) + secretShared.SetUpdatedBy("octokitty") + + serviceOne := new(library.Service) + serviceOne.SetID(1) + serviceOne.SetBuildID(1) + serviceOne.SetRepoID(1) + serviceOne.SetNumber(1) + serviceOne.SetName("init") + serviceOne.SetImage("#init") + serviceOne.SetStatus("running") + serviceOne.SetError("") + serviceOne.SetExitCode(0) + serviceOne.SetCreated(1563474076) + serviceOne.SetStarted(1563474078) + serviceOne.SetFinished(1563474079) + serviceOne.SetHost("example.company.com") + serviceOne.SetRuntime("docker") + serviceOne.SetDistribution("linux") + + serviceTwo := new(library.Service) + serviceTwo.SetID(2) + serviceTwo.SetBuildID(1) + serviceTwo.SetRepoID(1) + serviceTwo.SetNumber(2) + serviceTwo.SetName("clone") + serviceTwo.SetImage("target/vela-git:v0.3.0") + serviceTwo.SetStatus("pending") + serviceTwo.SetError("") + serviceTwo.SetExitCode(0) + serviceTwo.SetCreated(1563474086) + serviceTwo.SetStarted(1563474088) + serviceTwo.SetFinished(1563474089) + serviceTwo.SetHost("example.company.com") + serviceTwo.SetRuntime("docker") + serviceTwo.SetDistribution("linux") + + stepOne := new(library.Step) + stepOne.SetID(1) + stepOne.SetBuildID(1) + stepOne.SetRepoID(1) + stepOne.SetNumber(1) + stepOne.SetName("init") + stepOne.SetImage("#init") + stepOne.SetStage("init") + stepOne.SetStatus("running") + stepOne.SetError("") + stepOne.SetExitCode(0) + stepOne.SetCreated(1563474076) + stepOne.SetStarted(1563474078) + stepOne.SetFinished(1563474079) + stepOne.SetHost("example.company.com") + stepOne.SetRuntime("docker") + stepOne.SetDistribution("linux") + + stepTwo := new(library.Step) + stepTwo.SetID(2) + stepTwo.SetBuildID(1) + stepTwo.SetRepoID(1) + stepTwo.SetNumber(2) + stepTwo.SetName("clone") + stepTwo.SetImage("target/vela-git:v0.3.0") + stepTwo.SetStage("init") + stepTwo.SetStatus("pending") + stepTwo.SetError("") + stepTwo.SetExitCode(0) + stepTwo.SetCreated(1563474086) + stepTwo.SetStarted(1563474088) + stepTwo.SetFinished(1563474089) + stepTwo.SetHost("example.company.com") + stepTwo.SetRuntime("docker") + stepTwo.SetDistribution("linux") + + userOne := new(library.User) + userOne.SetID(1) + userOne.SetName("octocat") + userOne.SetToken("superSecretToken") + userOne.SetRefreshToken("superSecretRefreshToken") + userOne.SetHash("MzM4N2MzMDAtNmY4Mi00OTA5LWFhZDAtNWIzMTlkNTJkODMy") + userOne.SetFavorites([]string{"github/octocat"}) + userOne.SetActive(true) + userOne.SetAdmin(false) + + userTwo := new(library.User) + userTwo.SetID(2) + userTwo.SetName("octokitty") + userTwo.SetToken("superSecretToken") + userTwo.SetRefreshToken("superSecretRefreshToken") + userTwo.SetHash("MzM4N2MzMDAtNmY4Mi00OTA5LWFhZDAtNWIzMTlkNTJkODMy") + userTwo.SetFavorites([]string{"github/octocat"}) + userTwo.SetActive(true) + userTwo.SetAdmin(false) + + workerOne := new(library.Worker) + workerOne.SetID(1) + workerOne.SetHostname("worker-1.example.com") + workerOne.SetAddress("https://worker-1.example.com") + workerOne.SetRoutes([]string{"vela"}) + workerOne.SetActive(true) + workerOne.SetStatus("available") + workerOne.SetLastStatusUpdateAt(time.Now().UTC().Unix()) + workerOne.SetRunningBuildIDs([]string{"12345"}) + workerOne.SetLastBuildStartedAt(time.Now().UTC().Unix()) + workerOne.SetLastBuildFinishedAt(time.Now().UTC().Unix()) + workerOne.SetLastCheckedIn(time.Now().UTC().Unix()) + workerOne.SetBuildLimit(1) + + workerTwo := new(library.Worker) + workerTwo.SetID(2) + workerTwo.SetHostname("worker-2.example.com") + workerTwo.SetAddress("https://worker-2.example.com") + workerTwo.SetRoutes([]string{"vela"}) + workerTwo.SetActive(true) + workerTwo.SetStatus("available") + workerTwo.SetLastStatusUpdateAt(time.Now().UTC().Unix()) + workerTwo.SetRunningBuildIDs([]string{"12345"}) + workerTwo.SetLastBuildStartedAt(time.Now().UTC().Unix()) + workerTwo.SetLastBuildFinishedAt(time.Now().UTC().Unix()) + workerTwo.SetLastCheckedIn(time.Now().UTC().Unix()) + workerTwo.SetBuildLimit(1) + + return &Resources{ + Builds: []*library.Build{buildOne, buildTwo}, + Deployments: []*library.Deployment{deploymentOne, deploymentTwo}, + Hooks: []*library.Hook{hookOne, hookTwo}, + Logs: []*library.Log{logServiceOne, logServiceTwo, logStepOne, logStepTwo}, + Pipelines: []*library.Pipeline{pipelineOne, pipelineTwo}, + Repos: []*library.Repo{repoOne, repoTwo}, + Schedules: []*library.Schedule{scheduleOne, scheduleTwo}, + Secrets: []*library.Secret{secretOrg, secretRepo, secretShared}, + Services: []*library.Service{serviceOne, serviceTwo}, + Steps: []*library.Step{stepOne, stepTwo}, + Users: []*library.User{userOne, userTwo}, + Workers: []*library.Worker{workerOne, workerTwo}, + } +} diff --git a/database/log/list_build.go b/database/log/list_build.go index 58ca12111..ab083a706 100644 --- a/database/log/list_build.go +++ b/database/log/list_build.go @@ -37,6 +37,7 @@ func (e *engine) ListLogsForBuild(b *library.Build, page, perPage int) ([]*libra err = e.client. Table(constants.TableLog). Where("build_id = ?", b.GetID()). + Order("service_id ASC NULLS LAST"). Order("step_id ASC"). Limit(perPage). Offset(offset). diff --git a/database/log/list_build_test.go b/database/log/list_build_test.go index fb08236e9..cf20fb50e 100644 --- a/database/log/list_build_test.go +++ b/database/log/list_build_test.go @@ -49,7 +49,7 @@ func TestLog_Engine_ListLogsForBuild(t *testing.T) { AddRow(1, 1, 1, 1, 0, []byte{}).AddRow(2, 1, 1, 0, 1, []byte{}) // ensure the mock expects the query - _mock.ExpectQuery(`SELECT * FROM "logs" WHERE build_id = $1 ORDER BY step_id ASC LIMIT 10`).WithArgs(1).WillReturnRows(_rows) + _mock.ExpectQuery(`SELECT * FROM "logs" WHERE build_id = $1 ORDER BY service_id ASC NULLS LAST,step_id ASC LIMIT 10`).WithArgs(1).WillReturnRows(_rows) _sqlite := testSqlite(t) defer func() { _sql, _ := _sqlite.client.DB(); _sql.Close() }() diff --git a/database/repo/count_org_test.go b/database/repo/count_org_test.go index 2ff3278f3..fd4797dad 100644 --- a/database/repo/count_org_test.go +++ b/database/repo/count_org_test.go @@ -43,12 +43,12 @@ func TestRepo_Engine_CountReposForOrg(t *testing.T) { _sqlite := testSqlite(t) defer func() { _sql, _ := _sqlite.client.DB(); _sql.Close() }() - err := _sqlite.CreateRepo(_repoOne) + _, err := _sqlite.CreateRepo(_repoOne) if err != nil { t.Errorf("unable to create test repo for sqlite: %v", err) } - err = _sqlite.CreateRepo(_repoTwo) + _, err = _sqlite.CreateRepo(_repoTwo) if err != nil { t.Errorf("unable to create test repo for sqlite: %v", err) } diff --git a/database/repo/count_test.go b/database/repo/count_test.go index f63a935e8..104cccc65 100644 --- a/database/repo/count_test.go +++ b/database/repo/count_test.go @@ -43,12 +43,12 @@ func TestRepo_Engine_CountRepos(t *testing.T) { _sqlite := testSqlite(t) defer func() { _sql, _ := _sqlite.client.DB(); _sql.Close() }() - err := _sqlite.CreateRepo(_repoOne) + _, err := _sqlite.CreateRepo(_repoOne) if err != nil { t.Errorf("unable to create test repo for sqlite: %v", err) } - err = _sqlite.CreateRepo(_repoTwo) + _, err = _sqlite.CreateRepo(_repoTwo) if err != nil { t.Errorf("unable to create test repo for sqlite: %v", err) } diff --git a/database/repo/count_user_test.go b/database/repo/count_user_test.go index 654788a69..45ea309ab 100644 --- a/database/repo/count_user_test.go +++ b/database/repo/count_user_test.go @@ -49,12 +49,12 @@ func TestRepo_Engine_CountReposForUser(t *testing.T) { _sqlite := testSqlite(t) defer func() { _sql, _ := _sqlite.client.DB(); _sql.Close() }() - err := _sqlite.CreateRepo(_repoOne) + _, err := _sqlite.CreateRepo(_repoOne) if err != nil { t.Errorf("unable to create test repo for sqlite: %v", err) } - err = _sqlite.CreateRepo(_repoTwo) + _, err = _sqlite.CreateRepo(_repoTwo) if err != nil { t.Errorf("unable to create test repo for sqlite: %v", err) } diff --git a/database/repo/create.go b/database/repo/create.go index fbfda486a..850d854aa 100644 --- a/database/repo/create.go +++ b/database/repo/create.go @@ -15,7 +15,7 @@ import ( ) // CreateRepo creates a new repo in the database. -func (e *engine) CreateRepo(r *library.Repo) error { +func (e *engine) CreateRepo(r *library.Repo) (*library.Repo, error) { e.logger.WithFields(logrus.Fields{ "org": r.GetOrg(), "repo": r.GetName(), @@ -31,7 +31,7 @@ func (e *engine) CreateRepo(r *library.Repo) error { // https://pkg.go.dev/github.com/go-vela/types/database#Repo.Validate err := repo.Validate() if err != nil { - return err + return nil, err } // encrypt the fields for the repo @@ -39,12 +39,23 @@ func (e *engine) CreateRepo(r *library.Repo) error { // https://pkg.go.dev/github.com/go-vela/types/database#Repo.Encrypt err = repo.Encrypt(e.config.EncryptionKey) if err != nil { - return fmt.Errorf("unable to encrypt repo %s: %w", r.GetFullName(), err) + return nil, fmt.Errorf("unable to encrypt repo %s: %w", r.GetFullName(), err) } // send query to the database - return e.client. - Table(constants.TableRepo). - Create(repo). - Error + err = e.client.Table(constants.TableRepo).Create(repo).Error + if err != nil { + return nil, err + } + + // decrypt the fields for the repo + err = repo.Decrypt(e.config.EncryptionKey) + if err != nil { + // only log to preserve backwards compatibility + e.logger.Errorf("unable to decrypt repo %d: %v", r.GetID(), err) + + return repo.ToLibrary(), nil + } + + return repo.ToLibrary(), nil } diff --git a/database/repo/create_test.go b/database/repo/create_test.go index ac0a86ffa..4241ce4ab 100644 --- a/database/repo/create_test.go +++ b/database/repo/create_test.go @@ -5,6 +5,7 @@ package repo import ( + "reflect" "testing" "github.com/DATA-DOG/go-sqlmock" @@ -22,6 +23,7 @@ func TestRepo_Engine_CreateRepo(t *testing.T) { _repo.SetVisibility("public") _repo.SetPipelineType("yaml") _repo.SetPreviousName("oldName") + _repo.SetTopics([]string{}) _postgres, _mock := testPostgres(t) defer func() { _sql, _ := _postgres.client.DB(); _sql.Close() }() @@ -60,7 +62,7 @@ VALUES ($1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11,$12,$13,$14,$15,$16,$17,$18,$19,$20,$ // run tests for _, test := range tests { t.Run(test.name, func(t *testing.T) { - err := test.database.CreateRepo(_repo) + got, err := test.database.CreateRepo(_repo) if test.failure { if err == nil { @@ -73,6 +75,10 @@ VALUES ($1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11,$12,$13,$14,$15,$16,$17,$18,$19,$20,$ if err != nil { t.Errorf("CreateRepo for %s returned err: %v", test.name, err) } + + if !reflect.DeepEqual(got, _repo) { + t.Errorf("CreateRepo for %s returned %s, want %s", test.name, got, _repo) + } }) } } diff --git a/database/repo/delete_test.go b/database/repo/delete_test.go index ccc50eb4a..a4504d6bc 100644 --- a/database/repo/delete_test.go +++ b/database/repo/delete_test.go @@ -32,7 +32,7 @@ func TestRepo_Engine_DeleteRepo(t *testing.T) { _sqlite := testSqlite(t) defer func() { _sql, _ := _sqlite.client.DB(); _sql.Close() }() - err := _sqlite.CreateRepo(_repo) + _, err := _sqlite.CreateRepo(_repo) if err != nil { t.Errorf("unable to create test repo for sqlite: %v", err) } diff --git a/database/repo/get_org_test.go b/database/repo/get_org_test.go index 2f1dee125..b60faefde 100644 --- a/database/repo/get_org_test.go +++ b/database/repo/get_org_test.go @@ -39,7 +39,7 @@ func TestRepo_Engine_GetRepoForOrg(t *testing.T) { _sqlite := testSqlite(t) defer func() { _sql, _ := _sqlite.client.DB(); _sql.Close() }() - err := _sqlite.CreateRepo(_repo) + _, err := _sqlite.CreateRepo(_repo) if err != nil { t.Errorf("unable to create test repo for sqlite: %v", err) } diff --git a/database/repo/get_test.go b/database/repo/get_test.go index a1b7a8485..e098626de 100644 --- a/database/repo/get_test.go +++ b/database/repo/get_test.go @@ -39,7 +39,7 @@ func TestRepo_Engine_GetRepo(t *testing.T) { _sqlite := testSqlite(t) defer func() { _sql, _ := _sqlite.client.DB(); _sql.Close() }() - err := _sqlite.CreateRepo(_repo) + _, err := _sqlite.CreateRepo(_repo) if err != nil { t.Errorf("unable to create test repo for sqlite: %v", err) } diff --git a/database/repo/interface.go b/database/repo/interface.go index a53ad3a0a..1b641da35 100644 --- a/database/repo/interface.go +++ b/database/repo/interface.go @@ -33,7 +33,7 @@ type RepoInterface interface { // CountReposForUser defines a function that gets the count of repos by user ID. CountReposForUser(*library.User, map[string]interface{}) (int64, error) // CreateRepo defines a function that creates a new repo. - CreateRepo(*library.Repo) error + CreateRepo(*library.Repo) (*library.Repo, error) // DeleteRepo defines a function that deletes an existing repo. DeleteRepo(*library.Repo) error // GetRepo defines a function that gets a repo by ID. @@ -47,5 +47,5 @@ type RepoInterface interface { // ListReposForUser defines a function that gets a list of repos by user ID. ListReposForUser(*library.User, string, map[string]interface{}, int, int) ([]*library.Repo, int64, error) // UpdateRepo defines a function that updates an existing repo. - UpdateRepo(*library.Repo) error + UpdateRepo(*library.Repo) (*library.Repo, error) } diff --git a/database/repo/list_org_test.go b/database/repo/list_org_test.go index b668aff97..e54a11bf4 100644 --- a/database/repo/list_org_test.go +++ b/database/repo/list_org_test.go @@ -87,12 +87,12 @@ func TestRepo_Engine_ListReposForOrg(t *testing.T) { _sqlite := testSqlite(t) defer func() { _sql, _ := _sqlite.client.DB(); _sql.Close() }() - err := _sqlite.CreateRepo(_repoOne) + _, err := _sqlite.CreateRepo(_repoOne) if err != nil { t.Errorf("unable to create test repo for sqlite: %v", err) } - err = _sqlite.CreateRepo(_repoTwo) + _, err = _sqlite.CreateRepo(_repoTwo) if err != nil { t.Errorf("unable to create test repo for sqlite: %v", err) } diff --git a/database/repo/list_test.go b/database/repo/list_test.go index 9e359c40f..6936406e6 100644 --- a/database/repo/list_test.go +++ b/database/repo/list_test.go @@ -57,12 +57,12 @@ func TestRepo_Engine_ListRepos(t *testing.T) { _sqlite := testSqlite(t) defer func() { _sql, _ := _sqlite.client.DB(); _sql.Close() }() - err := _sqlite.CreateRepo(_repoOne) + _, err := _sqlite.CreateRepo(_repoOne) if err != nil { t.Errorf("unable to create test repo for sqlite: %v", err) } - err = _sqlite.CreateRepo(_repoTwo) + _, err = _sqlite.CreateRepo(_repoTwo) if err != nil { t.Errorf("unable to create test repo for sqlite: %v", err) } diff --git a/database/repo/list_user_test.go b/database/repo/list_user_test.go index a65958c39..7bff6fe2c 100644 --- a/database/repo/list_user_test.go +++ b/database/repo/list_user_test.go @@ -92,12 +92,12 @@ func TestRepo_Engine_ListReposForUser(t *testing.T) { _sqlite := testSqlite(t) defer func() { _sql, _ := _sqlite.client.DB(); _sql.Close() }() - err := _sqlite.CreateRepo(_repoOne) + _, err := _sqlite.CreateRepo(_repoOne) if err != nil { t.Errorf("unable to create test repo for sqlite: %v", err) } - err = _sqlite.CreateRepo(_repoTwo) + _, err = _sqlite.CreateRepo(_repoTwo) if err != nil { t.Errorf("unable to create test repo for sqlite: %v", err) } diff --git a/database/repo/update.go b/database/repo/update.go index 4c31791db..cf7111499 100644 --- a/database/repo/update.go +++ b/database/repo/update.go @@ -15,7 +15,7 @@ import ( ) // UpdateRepo updates an existing repo in the database. -func (e *engine) UpdateRepo(r *library.Repo) error { +func (e *engine) UpdateRepo(r *library.Repo) (*library.Repo, error) { e.logger.WithFields(logrus.Fields{ "org": r.GetOrg(), "repo": r.GetName(), @@ -31,7 +31,7 @@ func (e *engine) UpdateRepo(r *library.Repo) error { // https://pkg.go.dev/github.com/go-vela/types/database#Repo.Validate err := repo.Validate() if err != nil { - return err + return nil, err } // encrypt the fields for the repo @@ -39,12 +39,23 @@ func (e *engine) UpdateRepo(r *library.Repo) error { // https://pkg.go.dev/github.com/go-vela/types/database#Repo.Encrypt err = repo.Encrypt(e.config.EncryptionKey) if err != nil { - return fmt.Errorf("unable to encrypt repo %s: %w", r.GetFullName(), err) + return nil, fmt.Errorf("unable to encrypt repo %s: %w", r.GetFullName(), err) } // send query to the database - return e.client. - Table(constants.TableRepo). - Save(repo). - Error + err = e.client.Table(constants.TableRepo).Save(repo).Error + if err != nil { + return nil, err + } + + // decrypt the fields for the repo + err = repo.Decrypt(e.config.EncryptionKey) + if err != nil { + // only log to preserve backwards compatibility + e.logger.Errorf("unable to decrypt repo %d: %v", r.GetID(), err) + + return repo.ToLibrary(), nil + } + + return repo.ToLibrary(), nil } diff --git a/database/repo/update_test.go b/database/repo/update_test.go index 35d4b74bb..66f4fa6a9 100644 --- a/database/repo/update_test.go +++ b/database/repo/update_test.go @@ -5,6 +5,7 @@ package repo import ( + "reflect" "testing" "github.com/DATA-DOG/go-sqlmock" @@ -22,6 +23,7 @@ func TestRepo_Engine_UpdateRepo(t *testing.T) { _repo.SetVisibility("public") _repo.SetPipelineType("yaml") _repo.SetPreviousName("oldName") + _repo.SetTopics([]string{}) _postgres, _mock := testPostgres(t) defer func() { _sql, _ := _postgres.client.DB(); _sql.Close() }() @@ -36,7 +38,7 @@ WHERE "id" = $24`). _sqlite := testSqlite(t) defer func() { _sql, _ := _sqlite.client.DB(); _sql.Close() }() - err := _sqlite.CreateRepo(_repo) + _, err := _sqlite.CreateRepo(_repo) if err != nil { t.Errorf("unable to create test repo for sqlite: %v", err) } @@ -62,7 +64,7 @@ WHERE "id" = $24`). // run tests for _, test := range tests { t.Run(test.name, func(t *testing.T) { - err = test.database.UpdateRepo(_repo) + got, err := test.database.UpdateRepo(_repo) if test.failure { if err == nil { @@ -75,6 +77,10 @@ WHERE "id" = $24`). if err != nil { t.Errorf("UpdateRepo for %s returned err: %v", test.name, err) } + + if !reflect.DeepEqual(got, _repo) { + t.Errorf("UpdateRepo for %s returned %s, want %s", test.name, got, _repo) + } }) } } diff --git a/go.mod b/go.mod index db4d2e25f..c21ad91c2 100644 --- a/go.mod +++ b/go.mod @@ -7,14 +7,14 @@ require ( github.com/DATA-DOG/go-sqlmock v1.5.0 github.com/Masterminds/semver/v3 v3.2.1 github.com/Masterminds/sprig/v3 v3.2.3 - github.com/adhocore/gronx v1.6.3 + github.com/adhocore/gronx v1.6.4 github.com/alicebob/miniredis/v2 v2.30.4 - github.com/aws/aws-sdk-go v1.44.298 + github.com/aws/aws-sdk-go v1.44.309 github.com/buildkite/yaml v0.0.0-20181016232759-0caa5f0796e3 github.com/drone/envsubst v1.0.3 github.com/gin-gonic/gin v1.9.1 github.com/go-playground/assert/v2 v2.2.0 - github.com/go-vela/types v0.20.0 + github.com/go-vela/types v0.20.1 github.com/golang-jwt/jwt/v5 v5.0.0 github.com/google/go-cmp v0.5.9 github.com/google/go-github/v53 v53.2.0 @@ -31,15 +31,15 @@ require ( github.com/sirupsen/logrus v1.9.3 github.com/spf13/afero v1.9.5 github.com/urfave/cli/v2 v2.25.7 - go.starlark.net v0.0.0-20230712173630-2226322290fc - golang.org/x/crypto v0.10.0 + go.starlark.net v0.0.0-20230725161458-0d7263928a74 + golang.org/x/crypto v0.11.0 golang.org/x/oauth2 v0.9.0 golang.org/x/sync v0.3.0 gopkg.in/square/go-jose.v2 v2.6.0 gorm.io/driver/postgres v1.5.2 gorm.io/driver/sqlite v1.5.2 gorm.io/gorm v1.25.2 - k8s.io/apimachinery v0.27.3 + k8s.io/apimachinery v0.27.4 ) require ( @@ -89,13 +89,14 @@ require ( github.com/jmespath/go-jmespath v0.4.0 // indirect github.com/json-iterator/go v1.1.12 // indirect github.com/klauspost/cpuid/v2 v2.2.4 // indirect + github.com/kr/text v0.2.0 // indirect github.com/leodido/go-urn v1.2.4 // indirect github.com/lib/pq v1.10.9 // indirect github.com/mattn/go-colorable v0.1.8 // indirect github.com/mattn/go-isatty v0.0.19 // indirect github.com/mattn/go-sqlite3 v1.14.17 // indirect github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect - github.com/microcosm-cc/bluemonday v1.0.24 // indirect + github.com/microcosm-cc/bluemonday v1.0.25 // indirect github.com/mitchellh/copystructure v1.0.0 // indirect github.com/mitchellh/go-homedir v1.1.0 // indirect github.com/mitchellh/mapstructure v1.5.0 // indirect @@ -116,9 +117,9 @@ require ( github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 // indirect github.com/yuin/gopher-lua v1.1.0 // indirect golang.org/x/arch v0.3.0 // indirect - golang.org/x/net v0.11.0 // indirect - golang.org/x/sys v0.9.0 // indirect - golang.org/x/text v0.10.0 // indirect + golang.org/x/net v0.12.0 // indirect + golang.org/x/sys v0.10.0 // indirect + golang.org/x/text v0.11.0 // indirect golang.org/x/time v0.0.0-20220210224613-90d013bbcef8 // indirect google.golang.org/appengine v1.6.7 // indirect google.golang.org/protobuf v1.30.0 // indirect diff --git a/go.sum b/go.sum index 978abf40d..a8eaa2a36 100644 --- a/go.sum +++ b/go.sum @@ -57,8 +57,8 @@ github.com/PuerkitoBio/purell v1.1.1 h1:WEQqlqaGbrPkxLJWfBwQmfEAE1Z7ONdDLqrN38tN github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0= github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 h1:d+Bc7a5rLufV/sSk/8dngufqelfh6jnri85riMAaF/M= github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE= -github.com/adhocore/gronx v1.6.3 h1:bnm5vieTrY3QQPpsfB0hrAaeaHDpuZTUC2LLCVMLe9c= -github.com/adhocore/gronx v1.6.3/go.mod h1:7oUY1WAU8rEJWmAxXR2DN0JaO4gi9khSgKjiRypqteg= +github.com/adhocore/gronx v1.6.4 h1:Bx5cNRVQsGquOOUJL3+2M5vlz1KCCMHrCECwb5UghNU= +github.com/adhocore/gronx v1.6.4/go.mod h1:7oUY1WAU8rEJWmAxXR2DN0JaO4gi9khSgKjiRypqteg= github.com/alicebob/gopher-json v0.0.0-20180125190556-5a6b3ba71ee6/go.mod h1:SGnFV6hVsYE877CKEZ6tDNTjaSXYUk6QqoIK6PrAtcc= github.com/alicebob/gopher-json v0.0.0-20200520072559-a9ecdc9d1d3a h1:HbKu58rmZpUGpz5+4FfNmIU+FmZg2P3Xaj2v2bfNWmk= github.com/alicebob/gopher-json v0.0.0-20200520072559-a9ecdc9d1d3a/go.mod h1:SGnFV6hVsYE877CKEZ6tDNTjaSXYUk6QqoIK6PrAtcc= @@ -66,8 +66,8 @@ github.com/alicebob/miniredis/v2 v2.11.1/go.mod h1:UA48pmi7aSazcGAvcdKcBB49z521I github.com/alicebob/miniredis/v2 v2.30.4 h1:8S4/o1/KoUArAGbGwPxcwf0krlzceva2XVOSchFS7Eo= github.com/alicebob/miniredis/v2 v2.30.4/go.mod h1:b25qWj4fCEsBeAAR2mlb0ufImGC6uH3VlUfb/HS5zKg= github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= -github.com/aws/aws-sdk-go v1.44.298 h1:5qTxdubgV7PptZJmp/2qDwD2JL187ePL7VOxsSh1i3g= -github.com/aws/aws-sdk-go v1.44.298/go.mod h1:aVsgQcEevwlmQ7qHE9I3h+dtQgpqhFB+i8Phjh7fkwI= +github.com/aws/aws-sdk-go v1.44.309 h1:IPJOFBzXekakxmEpDwd4RTKmmBR6LIAiXgNsM51bWbU= +github.com/aws/aws-sdk-go v1.44.309/go.mod h1:aVsgQcEevwlmQ7qHE9I3h+dtQgpqhFB+i8Phjh7fkwI= github.com/aymerick/douceur v0.2.0 h1:Mv+mAeH1Q+n9Fr+oyamOlAkUNPWPlA8PPGR0QAaYuPk= github.com/aymerick/douceur v0.2.0/go.mod h1:wlT5vV2O3h55X9m7iVYN0TBM0NH/MmbLnd30/FjWUq4= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= @@ -101,6 +101,7 @@ github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnht github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= github.com/cpuguy83/go-md2man/v2 v2.0.2 h1:p1EgwI/C7NhT0JmVkwCD2ZBK8j4aeHQX2pMHHBfMQ6w= github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= +github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= @@ -142,8 +143,8 @@ github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91 github.com/go-playground/validator/v10 v10.14.0 h1:vgvQWe3XCz3gIeFDm/HnTIbj6UGmg/+t63MyGU2n5js= github.com/go-playground/validator/v10 v10.14.0/go.mod h1:9iXMNT7sEkjXb0I+enO7QXmzG6QCsPWY4zveKFVRSyU= github.com/go-test/deep v1.0.2 h1:onZX1rnHT3Wv6cqNgYyFOOlgVKJrksuCMCRvJStbMYw= -github.com/go-vela/types v0.20.0 h1:u/wHwc6ElVbIEI+q9TaVl9Iai1EoEr4Lwis6mikOte8= -github.com/go-vela/types v0.20.0/go.mod h1:1ZSmKWX9MamKogwaIb53mzzRpZMV34mJFKiGfVFadFk= +github.com/go-vela/types v0.20.1 h1:hHAX0Iij2J7UZ9f3SlXbwNy481CjKzU9CBfkiLuysVE= +github.com/go-vela/types v0.20.1/go.mod h1:AXO4oQSygOBQ02fPapsKjQHkx2aQO3zTu7clpvVbXBY= github.com/goccy/go-json v0.10.2 h1:CrxCmQqYDkv1z7lO7Wbh2HN93uovUHgrECaO5ZrCXAU= github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I= github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= @@ -289,8 +290,9 @@ github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= -github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= +github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/leodido/go-urn v1.2.4 h1:XlAE/cm/ms7TE/VMVoduSpNBoyc2dOxHs5MZSwAN63Q= github.com/leodido/go-urn v1.2.4/go.mod h1:7ZrI8mTSeBSHl/UaRyKQW1qZeMgak41ANeCNaVckg+4= github.com/lib/pq v1.10.9 h1:YXG7RB+JIjhP29X+OtkiDnYaXQwpS4JEWq7dtCCRUEw= @@ -308,8 +310,8 @@ github.com/mattn/go-sqlite3 v1.14.17 h1:mCRHCLDUBXgpKAqIKsaAaAsrAlbkeomtRFKXh2L6 github.com/mattn/go-sqlite3 v1.14.17/go.mod h1:2eHXhiwb8IkHr+BDWZGa96P6+rkvnG63S2DGjv9HUNg= github.com/matttproud/golang_protobuf_extensions v1.0.4 h1:mmDVorXM7PCGKw94cs5zkfA9PSy5pEvNWRP0ET0TIVo= github.com/matttproud/golang_protobuf_extensions v1.0.4/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4= -github.com/microcosm-cc/bluemonday v1.0.24 h1:NGQoPtwGVcbGkKfvyYk1yRqknzBuoMiUrO6R7uFTPlw= -github.com/microcosm-cc/bluemonday v1.0.24/go.mod h1:ArQySAMps0790cHSkdPEJ7bGkF2VePWH773hsJNSHf8= +github.com/microcosm-cc/bluemonday v1.0.25 h1:4NEwSfiJ+Wva0VxN5B8OwMicaJvD8r9tlJWm9rtloEg= +github.com/microcosm-cc/bluemonday v1.0.25/go.mod h1:ZIOjCQp1OrzBBPIJmfX4qDYFuhU02nx4bn030ixfHLE= github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc= github.com/mitchellh/copystructure v1.0.0 h1:Laisrj+bAB6b/yJwB5Bt3ITZhGJdqmxquMKeZ+mmkFQ= github.com/mitchellh/copystructure v1.0.0/go.mod h1:SNtv71yrdKgLRyLFxmLdkAbkKEFWgYaq1OVrnRcwhnw= @@ -400,8 +402,8 @@ go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk= -go.starlark.net v0.0.0-20230712173630-2226322290fc h1:x7dWtxLF8z8E5/+KkK3MJJTK/kBZhTCLmYCk75rhKxk= -go.starlark.net v0.0.0-20230712173630-2226322290fc/go.mod h1:jxU+3+j+71eXOW14274+SmmuW82qJzl6iZSeqEtTGds= +go.starlark.net v0.0.0-20230725161458-0d7263928a74 h1:EL8MuNFlzO8vvpHgZxDGPaehP0ozoJ1j1zA768zKXUQ= +go.starlark.net v0.0.0-20230725161458-0d7263928a74/go.mod h1:jxU+3+j+71eXOW14274+SmmuW82qJzl6iZSeqEtTGds= golang.org/x/arch v0.0.0-20210923205945-b76863e36670/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8= golang.org/x/arch v0.3.0 h1:02VY4/ZcO/gBOH6PUaoiptASxtXU10jazRCP865E97k= golang.org/x/arch v0.3.0/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8= @@ -415,8 +417,8 @@ golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.3.0/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4= -golang.org/x/crypto v0.10.0 h1:LKqV2xt9+kDzSTfOhx4FrkEBcMrAgHSYgzywV9zcGmM= -golang.org/x/crypto v0.10.0/go.mod h1:o4eNf7Ede1fv+hwOwZsTHl9EsPFO6q6ZvYR8vYfY45I= +golang.org/x/crypto v0.11.0 h1:6Ewdq3tDic1mg5xRO4milcWCfMVQhI4NkqWWvqejpuA= +golang.org/x/crypto v0.11.0/go.mod h1:xgJhtzW8F9jGdVFWZESrid1U1bjeNy4zgy5cRr/CIio= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= @@ -486,8 +488,8 @@ golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qx golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco= golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY= -golang.org/x/net v0.11.0 h1:Gi2tvZIJyBtO9SDr1q9h5hEQCp/4L2RQ+ar0qjx2oNU= -golang.org/x/net v0.11.0/go.mod h1:2L/ixqYpgIVXmeoSA/4Lu7BzTG4KIyPIryS4IsOd1oQ= +golang.org/x/net v0.12.0 h1:cfawfvKITfUsFCeJIHJrbSxpeu/E81khclypR0GVT50= +golang.org/x/net v0.12.0/go.mod h1:zEVYFnQC7m/vmpQFELhcD1EWkZlX69l4oqgmer6hfKA= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -558,8 +560,8 @@ golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.9.0 h1:KS/R3tvhPqvJvwcKfnBHJwwthS11LRhmM5D59eEXa0s= -golang.org/x/sys v0.9.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.10.0 h1:SqMFp9UcQJZa+pmYuAKjd9xq1f0j5rLcDIk0mj4qAsA= +golang.org/x/sys v0.10.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.0.0-20220526004731-065cf7ba2467/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= @@ -574,8 +576,8 @@ golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= -golang.org/x/text v0.10.0 h1:UpjohKhiEgNc0CSauXmwYftY1+LlaC75SJwh0SgCX58= -golang.org/x/text v0.10.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= +golang.org/x/text v0.11.0 h1:LAntKIrcmeSKERyiOh0XMV39LXS8IE9UL2yP7+f5ij4= +golang.org/x/text v0.11.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= @@ -755,8 +757,8 @@ honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWh honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= -k8s.io/apimachinery v0.27.3 h1:Ubye8oBufD04l9QnNtW05idcOe9Z3GQN8+7PqmuVcUM= -k8s.io/apimachinery v0.27.3/go.mod h1:XNfZ6xklnMCOGGFNqXG7bUrQCoR04dh/E7FprV6pb+E= +k8s.io/apimachinery v0.27.4 h1:CdxflD4AF61yewuid0fLl6bM4a3q04jWel0IlP+aYjs= +k8s.io/apimachinery v0.27.4/go.mod h1:XNfZ6xklnMCOGGFNqXG7bUrQCoR04dh/E7FprV6pb+E= k8s.io/klog/v2 v2.90.1 h1:m4bYOKall2MmOiRaR1J+We67Do7vm9KiQVlT96lnHUw= k8s.io/klog/v2 v2.90.1/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0= k8s.io/utils v0.0.0-20230209194617-a36077c30491 h1:r0BAOLElQnnFhE/ApUsg3iHdVYYPBjNSSOMowRZxxsY= diff --git a/router/middleware/build/build_test.go b/router/middleware/build/build_test.go index d8a540b9c..d0e0733a5 100644 --- a/router/middleware/build/build_test.go +++ b/router/middleware/build/build_test.go @@ -94,7 +94,7 @@ func TestBuild_Establish(t *testing.T) { db.Close() }() - _ = db.CreateRepo(r) + _, _ = db.CreateRepo(r) _, _ = db.CreateBuild(want) // setup context @@ -176,7 +176,7 @@ func TestBuild_Establish_NoBuildParameter(t *testing.T) { db.Close() }() - _ = db.CreateRepo(r) + _, _ = db.CreateRepo(r) // setup context gin.SetMode(gin.TestMode) @@ -224,7 +224,7 @@ func TestBuild_Establish_InvalidBuildParameter(t *testing.T) { db.Close() }() - _ = db.CreateRepo(r) + _, _ = db.CreateRepo(r) // setup context gin.SetMode(gin.TestMode) @@ -272,7 +272,7 @@ func TestBuild_Establish_NoBuild(t *testing.T) { db.Close() }() - _ = db.CreateRepo(r) + _, _ = db.CreateRepo(r) // setup context gin.SetMode(gin.TestMode) diff --git a/router/middleware/org/org_test.go b/router/middleware/org/org_test.go index aa64710cc..4c98de87e 100644 --- a/router/middleware/org/org_test.go +++ b/router/middleware/org/org_test.go @@ -69,7 +69,7 @@ func TestOrg_Establish(t *testing.T) { db.Close() }() - _ = db.CreateRepo(r) + _, _ = db.CreateRepo(r) // setup context gin.SetMode(gin.TestMode) diff --git a/router/middleware/perm/perm_test.go b/router/middleware/perm/perm_test.go index 70a88fbf8..a5af1cbbe 100644 --- a/router/middleware/perm/perm_test.go +++ b/router/middleware/perm/perm_test.go @@ -447,7 +447,7 @@ func TestPerm_MustBuildAccess(t *testing.T) { db.Close() }() - _ = db.CreateRepo(r) + _, _ = db.CreateRepo(r) _, _ = db.CreateBuild(b) context.Request, _ = http.NewRequest(http.MethodGet, "/test/foo/bar/builds/1", nil) @@ -537,7 +537,7 @@ func TestPerm_MustBuildAccess_PlatAdmin(t *testing.T) { db.Close() }() - _ = db.CreateRepo(r) + _, _ = db.CreateRepo(r) _, _ = db.CreateBuild(b) _ = db.CreateUser(u) @@ -622,7 +622,7 @@ func TestPerm_MustBuildToken_WrongBuild(t *testing.T) { db.Close() }() - _ = db.CreateRepo(r) + _, _ = db.CreateRepo(r) _, _ = db.CreateBuild(b) context.Request, _ = http.NewRequest(http.MethodGet, "/test/foo/bar/builds/1", nil) @@ -706,7 +706,7 @@ func TestPerm_MustSecretAdmin_BuildToken_Repo(t *testing.T) { db.Close() }() - _ = db.CreateRepo(r) + _, _ = db.CreateRepo(r) _, _ = db.CreateBuild(b) context.Request, _ = http.NewRequest(http.MethodGet, "/test/native/repo/foo/bar/baz", nil) @@ -787,7 +787,7 @@ func TestPerm_MustSecretAdmin_BuildToken_Org(t *testing.T) { db.Close() }() - _ = db.CreateRepo(r) + _, _ = db.CreateRepo(r) _, _ = db.CreateBuild(b) context.Request, _ = http.NewRequest(http.MethodGet, "/test/native/org/foo/*/baz", nil) @@ -868,7 +868,7 @@ func TestPerm_MustSecretAdmin_BuildToken_Shared(t *testing.T) { db.Close() }() - _ = db.CreateRepo(r) + _, _ = db.CreateRepo(r) _, _ = db.CreateBuild(b) context.Request, _ = http.NewRequest(http.MethodGet, "/test/native/shared/foo/*/*", nil) @@ -949,7 +949,7 @@ func TestPerm_MustAdmin(t *testing.T) { db.Close() }() - _ = db.CreateRepo(r) + _, _ = db.CreateRepo(r) _ = db.CreateUser(u) context.Request, _ = http.NewRequest(http.MethodGet, "/test/foo/bar", nil) @@ -1047,7 +1047,7 @@ func TestPerm_MustAdmin_PlatAdmin(t *testing.T) { db.Close() }() - _ = db.CreateRepo(r) + _, _ = db.CreateRepo(r) _ = db.CreateUser(u) context.Request, _ = http.NewRequest(http.MethodGet, "/test/foo/bar", nil) @@ -1145,7 +1145,7 @@ func TestPerm_MustAdmin_NotAdmin(t *testing.T) { db.Close() }() - _ = db.CreateRepo(r) + _, _ = db.CreateRepo(r) _ = db.CreateUser(u) context.Request, _ = http.NewRequest(http.MethodGet, "/test/foo/bar", nil) @@ -1243,7 +1243,7 @@ func TestPerm_MustWrite(t *testing.T) { db.Close() }() - _ = db.CreateRepo(r) + _, _ = db.CreateRepo(r) _ = db.CreateUser(u) context.Request, _ = http.NewRequest(http.MethodGet, "/test/foo/bar", nil) @@ -1341,7 +1341,7 @@ func TestPerm_MustWrite_PlatAdmin(t *testing.T) { db.Close() }() - _ = db.CreateRepo(r) + _, _ = db.CreateRepo(r) _ = db.CreateUser(u) context.Request, _ = http.NewRequest(http.MethodGet, "/test/foo/bar", nil) @@ -1439,7 +1439,7 @@ func TestPerm_MustWrite_RepoAdmin(t *testing.T) { db.Close() }() - _ = db.CreateRepo(r) + _, _ = db.CreateRepo(r) _ = db.CreateUser(u) context.Request, _ = http.NewRequest(http.MethodGet, "/test/foo/bar", nil) @@ -1537,7 +1537,7 @@ func TestPerm_MustWrite_NotWrite(t *testing.T) { db.Close() }() - _ = db.CreateRepo(r) + _, _ = db.CreateRepo(r) _ = db.CreateUser(u) context.Request, _ = http.NewRequest(http.MethodGet, "/test/foo/bar", nil) @@ -1635,7 +1635,7 @@ func TestPerm_MustRead(t *testing.T) { db.Close() }() - _ = db.CreateRepo(r) + _, _ = db.CreateRepo(r) _ = db.CreateUser(u) context.Request, _ = http.NewRequest(http.MethodGet, "/test/foo/bar", nil) @@ -1733,7 +1733,7 @@ func TestPerm_MustRead_PlatAdmin(t *testing.T) { db.Close() }() - _ = db.CreateRepo(r) + _, _ = db.CreateRepo(r) _ = db.CreateUser(u) context.Request, _ = http.NewRequest(http.MethodGet, "/test/foo/bar", nil) @@ -1832,7 +1832,7 @@ func TestPerm_MustRead_WorkerBuildToken(t *testing.T) { }() _, _ = db.CreateBuild(b) - _ = db.CreateRepo(r) + _, _ = db.CreateRepo(r) context.Request, _ = http.NewRequest(http.MethodGet, "/test/foo/bar/builds/1", nil) context.Request.Header.Add("Authorization", fmt.Sprintf("Bearer %s", tok)) @@ -1915,7 +1915,7 @@ func TestPerm_MustRead_RepoAdmin(t *testing.T) { db.Close() }() - _ = db.CreateRepo(r) + _, _ = db.CreateRepo(r) _ = db.CreateUser(u) context.Request, _ = http.NewRequest(http.MethodGet, "/test/foo/bar", nil) @@ -2013,7 +2013,7 @@ func TestPerm_MustRead_RepoWrite(t *testing.T) { db.Close() }() - _ = db.CreateRepo(r) + _, _ = db.CreateRepo(r) _ = db.CreateUser(u) context.Request, _ = http.NewRequest(http.MethodGet, "/test/foo/bar", nil) @@ -2111,7 +2111,7 @@ func TestPerm_MustRead_RepoPublic(t *testing.T) { db.Close() }() - _ = db.CreateRepo(r) + _, _ = db.CreateRepo(r) _ = db.CreateUser(u) context.Request, _ = http.NewRequest(http.MethodGet, "/test/foo/bar", nil) @@ -2209,7 +2209,7 @@ func TestPerm_MustRead_NotRead(t *testing.T) { db.Close() }() - _ = db.CreateRepo(r) + _, _ = db.CreateRepo(r) _ = db.CreateUser(u) context.Request, _ = http.NewRequest(http.MethodGet, "/test/foo/bar", nil) diff --git a/router/middleware/pipeline/pipeline_test.go b/router/middleware/pipeline/pipeline_test.go index a7c76c892..4e7912372 100644 --- a/router/middleware/pipeline/pipeline_test.go +++ b/router/middleware/pipeline/pipeline_test.go @@ -107,7 +107,7 @@ func TestPipeline_Establish(t *testing.T) { db.Close() }() - _ = db.CreateRepo(r) + _, _ = db.CreateRepo(r) _, _ = db.CreatePipeline(want) // setup context @@ -189,7 +189,7 @@ func TestPipeline_Establish_NoPipelineParameter(t *testing.T) { db.Close() }() - _ = db.CreateRepo(r) + _, _ = db.CreateRepo(r) // setup context gin.SetMode(gin.TestMode) @@ -293,7 +293,7 @@ func TestPipeline_Establish_NoPipeline(t *testing.T) { db.Close() }() - _ = db.CreateRepo(r) + _, _ = db.CreateRepo(r) _ = db.CreateUser(u) // setup context diff --git a/router/middleware/repo/repo_test.go b/router/middleware/repo/repo_test.go index 83051c09c..50b6c8cc7 100644 --- a/router/middleware/repo/repo_test.go +++ b/router/middleware/repo/repo_test.go @@ -76,7 +76,7 @@ func TestRepo_Establish(t *testing.T) { db.Close() }() - _ = db.CreateRepo(want) + _, _ = db.CreateRepo(want) // setup context gin.SetMode(gin.TestMode) diff --git a/router/middleware/service/service_test.go b/router/middleware/service/service_test.go index cd057b471..20c84c868 100644 --- a/router/middleware/service/service_test.go +++ b/router/middleware/service/service_test.go @@ -84,7 +84,7 @@ func TestService_Establish(t *testing.T) { db.Close() }() - _ = db.CreateRepo(r) + _, _ = db.CreateRepo(r) _, _ = db.CreateBuild(b) _ = db.CreateService(want) @@ -171,7 +171,7 @@ func TestService_Establish_NoBuild(t *testing.T) { db.Close() }() - _ = db.CreateRepo(r) + _, _ = db.CreateRepo(r) // setup context gin.SetMode(gin.TestMode) @@ -225,7 +225,7 @@ func TestService_Establish_NoServiceParameter(t *testing.T) { db.Close() }() - _ = db.CreateRepo(r) + _, _ = db.CreateRepo(r) _, _ = db.CreateBuild(b) // setup context @@ -281,7 +281,7 @@ func TestService_Establish_InvalidServiceParameter(t *testing.T) { db.Close() }() - _ = db.CreateRepo(r) + _, _ = db.CreateRepo(r) _, _ = db.CreateBuild(b) // setup context @@ -337,7 +337,7 @@ func TestService_Establish_NoService(t *testing.T) { db.Close() }() - _ = db.CreateRepo(r) + _, _ = db.CreateRepo(r) _, _ = db.CreateBuild(b) // setup context diff --git a/router/middleware/step/step_test.go b/router/middleware/step/step_test.go index d0ad740c4..85aa8c246 100644 --- a/router/middleware/step/step_test.go +++ b/router/middleware/step/step_test.go @@ -86,7 +86,7 @@ func TestStep_Establish(t *testing.T) { db.Close() }() - _ = db.CreateRepo(r) + _, _ = db.CreateRepo(r) _, _ = db.CreateBuild(b) _ = db.CreateStep(want) @@ -173,7 +173,7 @@ func TestStep_Establish_NoBuild(t *testing.T) { db.Close() }() - _ = db.CreateRepo(r) + _, _ = db.CreateRepo(r) // setup context gin.SetMode(gin.TestMode) @@ -227,7 +227,7 @@ func TestStep_Establish_NoStepParameter(t *testing.T) { db.Close() }() - _ = db.CreateRepo(r) + _, _ = db.CreateRepo(r) _, _ = db.CreateBuild(b) // setup context @@ -283,7 +283,7 @@ func TestStep_Establish_InvalidStepParameter(t *testing.T) { db.Close() }() - _ = db.CreateRepo(r) + _, _ = db.CreateRepo(r) _, _ = db.CreateBuild(b) // setup context @@ -339,7 +339,7 @@ func TestStep_Establish_NoStep(t *testing.T) { db.Close() }() - _ = db.CreateRepo(r) + _, _ = db.CreateRepo(r) _, _ = db.CreateBuild(b) // setup context diff --git a/scm/github/repo.go b/scm/github/repo.go index 682a2db94..5cd3b0999 100644 --- a/scm/github/repo.go +++ b/scm/github/repo.go @@ -465,15 +465,24 @@ func (c *client) ListUserRepos(u *library.User) ([]*library.Repo, error) { // toLibraryRepo does a partial conversion of a github repo to a library repo. func toLibraryRepo(gr github.Repository) *library.Repo { + // setting the visbility to match the SCM visbility + var visibility string + if *gr.Private { + visibility = constants.VisibilityPrivate + } else { + visibility = constants.VisibilityPublic + } + return &library.Repo{ - Org: gr.GetOwner().Login, - Name: gr.Name, - FullName: gr.FullName, - Link: gr.HTMLURL, - Clone: gr.CloneURL, - Branch: gr.DefaultBranch, - Topics: &gr.Topics, - Private: gr.Private, + Org: gr.GetOwner().Login, + Name: gr.Name, + FullName: gr.FullName, + Link: gr.HTMLURL, + Clone: gr.CloneURL, + Branch: gr.DefaultBranch, + Topics: &gr.Topics, + Private: gr.Private, + Visibility: &visibility, } } diff --git a/scm/github/repo_test.go b/scm/github/repo_test.go index 7482c71ce..1fcd3bf0c 100644 --- a/scm/github/repo_test.go +++ b/scm/github/repo_test.go @@ -1028,6 +1028,7 @@ func TestGithub_GetRepo(t *testing.T) { want.SetBranch("master") want.SetPrivate(false) want.SetTopics([]string{"octocat", "atom", "electron", "api"}) + want.SetVisibility("public") client, _ := NewTest(s.URL) @@ -1191,6 +1192,7 @@ func TestGithub_ListUserRepos(t *testing.T) { r.SetBranch("master") r.SetPrivate(false) r.SetTopics([]string{"octocat", "atom", "electron", "api"}) + r.SetVisibility("public") want := []*library.Repo{r}