Add more tests

Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
This commit is contained in:
Gabriel Adrian Samfira 2025-05-20 09:19:19 +00:00
parent b2d5609352
commit f0753eeb22
14 changed files with 1060 additions and 54 deletions

View file

@ -56,7 +56,7 @@ type OrgStore interface {
} }
type EnterpriseStore interface { type EnterpriseStore interface {
CreateEnterprise(ctx context.Context, name, credentialsName, webhookSecret string, poolBalancerType params.PoolBalancerType) (params.Enterprise, error) CreateEnterprise(ctx context.Context, name string, credentialsName params.ForgeCredentials, webhookSecret string, poolBalancerType params.PoolBalancerType) (params.Enterprise, error)
GetEnterprise(ctx context.Context, name, endpointName string) (params.Enterprise, error) GetEnterprise(ctx context.Context, name, endpointName string) (params.Enterprise, error)
GetEnterpriseByID(ctx context.Context, enterpriseID string) (params.Enterprise, error) GetEnterpriseByID(ctx context.Context, enterpriseID string) (params.Enterprise, error)
ListEnterprises(ctx context.Context) ([]params.Enterprise, error) ListEnterprises(ctx context.Context) ([]params.Enterprise, error)

View file

@ -28,10 +28,14 @@ import (
"github.com/cloudbase/garm/params" "github.com/cloudbase/garm/params"
) )
func (s *sqlDatabase) CreateEnterprise(ctx context.Context, name, credentialsName, webhookSecret string, poolBalancerType params.PoolBalancerType) (paramEnt params.Enterprise, err error) { func (s *sqlDatabase) CreateEnterprise(ctx context.Context, name string, credentials params.ForgeCredentials, webhookSecret string, poolBalancerType params.PoolBalancerType) (paramEnt params.Enterprise, err error) {
if webhookSecret == "" { if webhookSecret == "" {
return params.Enterprise{}, errors.New("creating enterprise: missing secret") return params.Enterprise{}, errors.New("creating enterprise: missing secret")
} }
if credentials.ForgeType != params.GithubEndpointType {
return params.Enterprise{}, errors.Wrap(runnerErrors.ErrBadRequest, "enterprises are not supported on this forge type")
}
secret, err := util.Seal([]byte(webhookSecret), []byte(s.cfg.Passphrase)) secret, err := util.Seal([]byte(webhookSecret), []byte(s.cfg.Passphrase))
if err != nil { if err != nil {
return params.Enterprise{}, errors.Wrap(err, "encoding secret") return params.Enterprise{}, errors.Wrap(err, "encoding secret")
@ -48,24 +52,18 @@ func (s *sqlDatabase) CreateEnterprise(ctx context.Context, name, credentialsNam
PoolBalancerType: poolBalancerType, PoolBalancerType: poolBalancerType,
} }
err = s.conn.Transaction(func(tx *gorm.DB) error { err = s.conn.Transaction(func(tx *gorm.DB) error {
creds, err := s.getGithubCredentialsByName(ctx, tx, credentialsName, false) newEnterprise.CredentialsID = &credentials.ID
if err != nil { newEnterprise.EndpointName = &credentials.Endpoint.Name
return errors.Wrap(err, "creating enterprise")
}
if creds.EndpointName == nil {
return errors.Wrap(runnerErrors.ErrUnprocessable, "credentials have no endpoint")
}
newEnterprise.CredentialsID = &creds.ID
newEnterprise.EndpointName = creds.EndpointName
q := tx.Create(&newEnterprise) q := tx.Create(&newEnterprise)
if q.Error != nil { if q.Error != nil {
return errors.Wrap(q.Error, "creating enterprise") return errors.Wrap(q.Error, "creating enterprise")
} }
newEnterprise.Credentials = creds newEnterprise, err = s.getEnterpriseByID(ctx, tx, newEnterprise.ID.String(), "Pools", "Credentials", "Endpoint", "Credentials.Endpoint")
newEnterprise.Endpoint = creds.Endpoint if err != nil {
return errors.Wrap(err, "creating enterprise")
}
return nil return nil
}) })
if err != nil { if err != nil {

View file

@ -99,7 +99,7 @@ func (s *EnterpriseTestSuite) SetupTest() {
enterprise, err := db.CreateEnterprise( enterprise, err := db.CreateEnterprise(
s.adminCtx, s.adminCtx,
fmt.Sprintf("test-enterprise-%d", i), fmt.Sprintf("test-enterprise-%d", i),
s.testCreds.Name, s.testCreds,
fmt.Sprintf("test-webhook-secret-%d", i), fmt.Sprintf("test-webhook-secret-%d", i),
params.PoolBalancerTypeRoundRobin, params.PoolBalancerTypeRoundRobin,
) )
@ -178,7 +178,7 @@ func (s *EnterpriseTestSuite) TestCreateEnterprise() {
enterprise, err := s.Store.CreateEnterprise( enterprise, err := s.Store.CreateEnterprise(
s.adminCtx, s.adminCtx,
s.Fixtures.CreateEnterpriseParams.Name, s.Fixtures.CreateEnterpriseParams.Name,
s.Fixtures.CreateEnterpriseParams.CredentialsName, s.testCreds,
s.Fixtures.CreateEnterpriseParams.WebhookSecret, s.Fixtures.CreateEnterpriseParams.WebhookSecret,
params.PoolBalancerTypeRoundRobin) params.PoolBalancerTypeRoundRobin)
@ -209,7 +209,7 @@ func (s *EnterpriseTestSuite) TestCreateEnterpriseInvalidDBPassphrase() {
_, err = sqlDB.CreateEnterprise( _, err = sqlDB.CreateEnterprise(
s.adminCtx, s.adminCtx,
s.Fixtures.CreateEnterpriseParams.Name, s.Fixtures.CreateEnterpriseParams.Name,
s.Fixtures.CreateEnterpriseParams.CredentialsName, s.testCreds,
s.Fixtures.CreateEnterpriseParams.WebhookSecret, s.Fixtures.CreateEnterpriseParams.WebhookSecret,
params.PoolBalancerTypeRoundRobin) params.PoolBalancerTypeRoundRobin)
@ -235,7 +235,7 @@ func (s *EnterpriseTestSuite) TestCreateEnterpriseDBCreateErr() {
_, err := s.StoreSQLMocked.CreateEnterprise( _, err := s.StoreSQLMocked.CreateEnterprise(
s.adminCtx, s.adminCtx,
s.Fixtures.CreateEnterpriseParams.Name, s.Fixtures.CreateEnterpriseParams.Name,
s.Fixtures.CreateEnterpriseParams.CredentialsName, s.testCreds,
s.Fixtures.CreateEnterpriseParams.WebhookSecret, s.Fixtures.CreateEnterpriseParams.WebhookSecret,
params.PoolBalancerTypeRoundRobin) params.PoolBalancerTypeRoundRobin)

View file

@ -22,7 +22,7 @@ func (s *sqlDatabase) CreateGiteaEndpoint(_ context.Context, param params.Create
var endpoint GithubEndpoint var endpoint GithubEndpoint
err = s.conn.Transaction(func(tx *gorm.DB) error { err = s.conn.Transaction(func(tx *gorm.DB) error {
if err := tx.Where("name = ?", param.Name).First(&endpoint).Error; err == nil { if err := tx.Where("name = ?", param.Name).First(&endpoint).Error; err == nil {
return errors.Wrap(runnerErrors.ErrDuplicateEntity, "github endpoint already exists") return errors.Wrap(runnerErrors.ErrDuplicateEntity, "gitea endpoint already exists")
} }
endpoint = GithubEndpoint{ endpoint = GithubEndpoint{
Name: param.Name, Name: param.Name,
@ -34,16 +34,16 @@ func (s *sqlDatabase) CreateGiteaEndpoint(_ context.Context, param params.Create
} }
if err := tx.Create(&endpoint).Error; err != nil { if err := tx.Create(&endpoint).Error; err != nil {
return errors.Wrap(err, "creating github endpoint") return errors.Wrap(err, "creating gitea endpoint")
} }
return nil return nil
}) })
if err != nil { if err != nil {
return params.ForgeEndpoint{}, errors.Wrap(err, "creating github endpoint") return params.ForgeEndpoint{}, errors.Wrap(err, "creating gitea endpoint")
} }
ghEndpoint, err = s.sqlToCommonGithubEndpoint(endpoint) ghEndpoint, err = s.sqlToCommonGithubEndpoint(endpoint)
if err != nil { if err != nil {
return params.ForgeEndpoint{}, errors.Wrap(err, "converting github endpoint") return params.ForgeEndpoint{}, errors.Wrap(err, "converting gitea endpoint")
} }
return ghEndpoint, nil return ghEndpoint, nil
} }
@ -52,14 +52,14 @@ func (s *sqlDatabase) ListGiteaEndpoints(_ context.Context) ([]params.ForgeEndpo
var endpoints []GithubEndpoint var endpoints []GithubEndpoint
err := s.conn.Where("endpoint_type = ?", params.GiteaEndpointType).Find(&endpoints).Error err := s.conn.Where("endpoint_type = ?", params.GiteaEndpointType).Find(&endpoints).Error
if err != nil { if err != nil {
return nil, errors.Wrap(err, "fetching github endpoints") return nil, errors.Wrap(err, "fetching gitea endpoints")
} }
var ret []params.ForgeEndpoint var ret []params.ForgeEndpoint
for _, ep := range endpoints { for _, ep := range endpoints {
commonEp, err := s.sqlToCommonGithubEndpoint(ep) commonEp, err := s.sqlToCommonGithubEndpoint(ep)
if err != nil { if err != nil {
return nil, errors.Wrap(err, "converting github endpoint") return nil, errors.Wrap(err, "converting gitea endpoint")
} }
ret = append(ret, commonEp) ret = append(ret, commonEp)
} }
@ -67,10 +67,6 @@ func (s *sqlDatabase) ListGiteaEndpoints(_ context.Context) ([]params.ForgeEndpo
} }
func (s *sqlDatabase) UpdateGiteaEndpoint(_ context.Context, name string, param params.UpdateGiteaEndpointParams) (ghEndpoint params.ForgeEndpoint, err error) { func (s *sqlDatabase) UpdateGiteaEndpoint(_ context.Context, name string, param params.UpdateGiteaEndpointParams) (ghEndpoint params.ForgeEndpoint, err error) {
if name == defaultGithubEndpoint {
return params.ForgeEndpoint{}, runnerErrors.NewBadRequestError("cannot update default endpoint %s", defaultGithubEndpoint)
}
defer func() { defer func() {
if err == nil { if err == nil {
s.sendNotify(common.GithubEndpointEntityType, common.UpdateOperation, ghEndpoint) s.sendNotify(common.GithubEndpointEntityType, common.UpdateOperation, ghEndpoint)
@ -118,7 +114,6 @@ func (s *sqlDatabase) UpdateGiteaEndpoint(_ context.Context, name string, param
func (s *sqlDatabase) GetGiteaEndpoint(_ context.Context, name string) (params.ForgeEndpoint, error) { func (s *sqlDatabase) GetGiteaEndpoint(_ context.Context, name string) (params.ForgeEndpoint, error) {
var endpoint GithubEndpoint var endpoint GithubEndpoint
err := s.conn.Where("name = ? and endpoint_type = ?", name, params.GiteaEndpointType).First(&endpoint).Error err := s.conn.Where("name = ? and endpoint_type = ?", name, params.GiteaEndpointType).First(&endpoint).Error
if err != nil { if err != nil {
if errors.Is(err, gorm.ErrRecordNotFound) { if errors.Is(err, gorm.ErrRecordNotFound) {
@ -150,7 +145,7 @@ func (s *sqlDatabase) DeleteGiteaEndpoint(_ context.Context, name string) (err e
} }
var credsCount int64 var credsCount int64
if err := tx.Model(&GithubCredentials{}).Where("endpoint_name = ?", endpoint.Name).Count(&credsCount).Error; err != nil { if err := tx.Model(&GiteaCredentials{}).Where("endpoint_name = ?", endpoint.Name).Count(&credsCount).Error; err != nil {
if !errors.Is(err, gorm.ErrRecordNotFound) { if !errors.Is(err, gorm.ErrRecordNotFound) {
return errors.Wrap(err, "fetching gitea credentials") return errors.Wrap(err, "fetching gitea credentials")
} }
@ -170,15 +165,8 @@ func (s *sqlDatabase) DeleteGiteaEndpoint(_ context.Context, name string) (err e
} }
} }
var entCnt int64 if credsCount > 0 || repoCnt > 0 || orgCnt > 0 {
if err := tx.Model(&Enterprise{}).Where("endpoint_name = ?", endpoint.Name).Count(&entCnt).Error; err != nil { return runnerErrors.NewBadRequestError("cannot delete endpoint with associated entities")
if !errors.Is(err, gorm.ErrRecordNotFound) {
return errors.Wrap(err, "fetching gitea enterprises")
}
}
if credsCount > 0 || repoCnt > 0 || orgCnt > 0 || entCnt > 0 {
return errors.New("cannot delete endpoint with associated entities")
} }
if err := tx.Unscoped().Delete(&endpoint).Error; err != nil { if err := tx.Unscoped().Delete(&endpoint).Error; err != nil {
@ -195,7 +183,7 @@ func (s *sqlDatabase) DeleteGiteaEndpoint(_ context.Context, name string) (err e
func (s *sqlDatabase) CreateGiteaCredentials(ctx context.Context, param params.CreateGiteaCredentialsParams) (gtCreds params.ForgeCredentials, err error) { func (s *sqlDatabase) CreateGiteaCredentials(ctx context.Context, param params.CreateGiteaCredentialsParams) (gtCreds params.ForgeCredentials, err error) {
userID, err := getUIDFromContext(ctx) userID, err := getUIDFromContext(ctx)
if err != nil { if err != nil {
return params.ForgeCredentials{}, errors.Wrap(err, "creating github credentials") return params.ForgeCredentials{}, errors.Wrap(err, "creating gitea credentials")
} }
if param.Endpoint == "" { if param.Endpoint == "" {
return params.ForgeCredentials{}, errors.Wrap(runnerErrors.ErrBadRequest, "endpoint name is required") return params.ForgeCredentials{}, errors.Wrap(runnerErrors.ErrBadRequest, "endpoint name is required")
@ -211,13 +199,13 @@ func (s *sqlDatabase) CreateGiteaCredentials(ctx context.Context, param params.C
var endpoint GithubEndpoint var endpoint GithubEndpoint
if err := tx.Where("name = ? and endpoint_type = ?", param.Endpoint, params.GiteaEndpointType).First(&endpoint).Error; err != nil { if err := tx.Where("name = ? and endpoint_type = ?", param.Endpoint, params.GiteaEndpointType).First(&endpoint).Error; err != nil {
if errors.Is(err, gorm.ErrRecordNotFound) { if errors.Is(err, gorm.ErrRecordNotFound) {
return errors.Wrap(runnerErrors.ErrNotFound, "github endpoint not found") return errors.Wrap(runnerErrors.ErrNotFound, "gitea endpoint not found")
} }
return errors.Wrap(err, "fetching github endpoint") return errors.Wrap(err, "fetching gitea endpoint")
} }
if err := tx.Where("name = ? and user_id = ?", param.Name, userID).First(&creds).Error; err == nil { if err := tx.Where("name = ? and user_id = ?", param.Name, userID).First(&creds).Error; err == nil {
return errors.Wrap(runnerErrors.ErrDuplicateEntity, "github credentials already exists") return errors.Wrap(runnerErrors.ErrDuplicateEntity, "gitea credentials already exists")
} }
var data []byte var data []byte
@ -225,8 +213,6 @@ func (s *sqlDatabase) CreateGiteaCredentials(ctx context.Context, param params.C
switch param.AuthType { switch param.AuthType {
case params.ForgeAuthTypePAT: case params.ForgeAuthTypePAT:
data, err = s.marshalAndSeal(param.PAT) data, err = s.marshalAndSeal(param.PAT)
case params.ForgeAuthTypeApp:
data, err = s.marshalAndSeal(param.App)
default: default:
return errors.Wrap(runnerErrors.ErrBadRequest, "invalid auth type") return errors.Wrap(runnerErrors.ErrBadRequest, "invalid auth type")
} }
@ -244,7 +230,7 @@ func (s *sqlDatabase) CreateGiteaCredentials(ctx context.Context, param params.C
} }
if err := tx.Create(&creds).Error; err != nil { if err := tx.Create(&creds).Error; err != nil {
return errors.Wrap(err, "creating github credentials") return errors.Wrap(err, "creating gitea credentials")
} }
// Skip making an extra query. // Skip making an extra query.
creds.Endpoint = endpoint creds.Endpoint = endpoint
@ -252,11 +238,11 @@ func (s *sqlDatabase) CreateGiteaCredentials(ctx context.Context, param params.C
return nil return nil
}) })
if err != nil { if err != nil {
return params.ForgeCredentials{}, errors.Wrap(err, "creating github credentials") return params.ForgeCredentials{}, errors.Wrap(err, "creating gitea credentials")
} }
gtCreds, err = s.sqlGiteaToCommonForgeCredentials(creds) gtCreds, err = s.sqlGiteaToCommonForgeCredentials(creds)
if err != nil { if err != nil {
return params.ForgeCredentials{}, errors.Wrap(err, "converting github credentials") return params.ForgeCredentials{}, errors.Wrap(err, "converting gitea credentials")
} }
return gtCreds, nil return gtCreds, nil
} }

793
database/sql/gitea_test.go Normal file
View file

@ -0,0 +1,793 @@
// Copyright 2024 Cloudbase Solutions SRL
//
// Licensed under the Apache License, Version 2.0 (the "License"); you may
// not use this file except in compliance with the License. You may obtain
// a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
// License for the specific language governing permissions and limitations
// under the License.
package sql
import (
"context"
"fmt"
"os"
"testing"
"github.com/stretchr/testify/suite"
runnerErrors "github.com/cloudbase/garm-provider-common/errors"
"github.com/cloudbase/garm/auth"
"github.com/cloudbase/garm/database/common"
garmTesting "github.com/cloudbase/garm/internal/testing"
"github.com/cloudbase/garm/params"
)
type GiteaTestSuite struct {
suite.Suite
giteaEndpoint params.ForgeEndpoint
db common.Store
}
func (s *GiteaTestSuite) SetupTest() {
db, err := NewSQLDatabase(context.Background(), garmTesting.GetTestSqliteDBConfig(s.T()))
if err != nil {
s.FailNow(fmt.Sprintf("failed to create db connection: %s", err))
}
s.db = db
createEpParams := params.CreateGiteaEndpointParams{
Name: testEndpointName,
Description: testEndpointDescription,
APIBaseURL: testAPIBaseURL,
BaseURL: testBaseURL,
}
endpoint, err := s.db.CreateGiteaEndpoint(context.Background(), createEpParams)
s.Require().NoError(err)
s.Require().NotNil(endpoint)
s.Require().Equal(testEndpointName, endpoint.Name)
s.giteaEndpoint = endpoint
}
func (s *GiteaTestSuite) TestCreatingEndpoint() {
ctx := garmTesting.ImpersonateAdminContext(context.Background(), s.db, s.T())
createEpParams := params.CreateGiteaEndpointParams{
Name: testEndpointName,
Description: testEndpointDescription,
APIBaseURL: testAPIBaseURL,
BaseURL: testBaseURL,
}
endpoint, err := s.db.CreateGiteaEndpoint(ctx, createEpParams)
s.Require().NoError(err)
s.Require().NotNil(endpoint)
s.Require().Equal(testEndpointName, endpoint.Name)
}
func (s *GiteaTestSuite) TestCreatingDuplicateEndpointFails() {
ctx := garmTesting.ImpersonateAdminContext(context.Background(), s.db, s.T())
createEpParams := params.CreateGiteaEndpointParams{
Name: testEndpointName,
Description: testEndpointDescription,
APIBaseURL: testAPIBaseURL,
BaseURL: testBaseURL,
}
_, err := s.db.CreateGiteaEndpoint(ctx, createEpParams)
s.Require().NoError(err)
_, err = s.db.CreateGiteaEndpoint(ctx, createEpParams)
s.Require().Error(err)
s.Require().ErrorIs(err, runnerErrors.ErrDuplicateEntity)
}
func (s *GiteaTestSuite) TestGetEndpoint() {
ctx := garmTesting.ImpersonateAdminContext(context.Background(), s.db, s.T())
createEpParams := params.CreateGiteaEndpointParams{
Name: "deleteme",
Description: testEndpointDescription,
APIBaseURL: testAPIBaseURL,
BaseURL: testBaseURL,
}
newEndpoint, err := s.db.CreateGiteaEndpoint(ctx, createEpParams)
s.Require().NoError(err)
endpoint, err := s.db.GetGiteaEndpoint(ctx, createEpParams.Name)
s.Require().NoError(err)
s.Require().NotNil(endpoint)
s.Require().Equal(newEndpoint.Name, endpoint.Name)
}
func (s *GiteaTestSuite) TestGetNonExistingEndpointFailsWithNotFoundError() {
ctx := garmTesting.ImpersonateAdminContext(context.Background(), s.db, s.T())
_, err := s.db.GetGiteaEndpoint(ctx, "non-existing")
s.Require().Error(err)
s.Require().ErrorIs(err, runnerErrors.ErrNotFound)
}
func (s *GiteaTestSuite) TestDeletingNonExistingEndpointIsANoop() {
ctx := garmTesting.ImpersonateAdminContext(context.Background(), s.db, s.T())
err := s.db.DeleteGiteaEndpoint(ctx, "non-existing")
s.Require().NoError(err)
}
func (s *GiteaTestSuite) TestDeletingEndpoint() {
ctx := garmTesting.ImpersonateAdminContext(context.Background(), s.db, s.T())
createEpParams := params.CreateGiteaEndpointParams{
Name: testEndpointName,
Description: testEndpointDescription,
APIBaseURL: testAPIBaseURL,
BaseURL: testBaseURL,
}
endpoint, err := s.db.CreateGiteaEndpoint(ctx, createEpParams)
s.Require().NoError(err)
s.Require().NotNil(endpoint)
err = s.db.DeleteGiteaEndpoint(ctx, testEndpointName)
s.Require().NoError(err)
_, err = s.db.GetGiteaEndpoint(ctx, testEndpointName)
s.Require().Error(err)
s.Require().ErrorIs(err, runnerErrors.ErrNotFound)
}
func (s *GiteaTestSuite) TestUpdateEndpoint() {
ctx := garmTesting.ImpersonateAdminContext(context.Background(), s.db, s.T())
createEpParams := params.CreateGiteaEndpointParams{
Name: "deleteme",
Description: testEndpointDescription,
APIBaseURL: testAPIBaseURL,
BaseURL: testBaseURL,
}
endpoint, err := s.db.CreateGiteaEndpoint(ctx, createEpParams)
s.Require().NoError(err)
s.Require().NotNil(endpoint)
newDescription := "new description"
newAPIBaseURL := "https://new-api.example.com"
newBaseURL := "https://new.example.com"
caCertBundle, err := os.ReadFile("../../testdata/certs/srv-pub.pem")
s.Require().NoError(err)
updateEpParams := params.UpdateGiteaEndpointParams{
Description: &newDescription,
APIBaseURL: &newAPIBaseURL,
BaseURL: &newBaseURL,
CACertBundle: caCertBundle,
}
updatedEndpoint, err := s.db.UpdateGiteaEndpoint(ctx, testEndpointName, updateEpParams)
s.Require().NoError(err)
s.Require().NotNil(updatedEndpoint)
s.Require().Equal(newDescription, updatedEndpoint.Description)
s.Require().Equal(newAPIBaseURL, updatedEndpoint.APIBaseURL)
s.Require().Equal(newBaseURL, updatedEndpoint.BaseURL)
s.Require().Equal(caCertBundle, updatedEndpoint.CACertBundle)
}
func (s *GiteaTestSuite) TestUpdatingNonExistingEndpointReturnsNotFoundError() {
ctx := garmTesting.ImpersonateAdminContext(context.Background(), s.db, s.T())
newDescription := "test"
updateEpParams := params.UpdateGiteaEndpointParams{
Description: &newDescription,
}
_, err := s.db.UpdateGiteaEndpoint(ctx, "non-existing", updateEpParams)
s.Require().Error(err)
s.Require().ErrorIs(err, runnerErrors.ErrNotFound)
}
func (s *GiteaTestSuite) TestListEndpoints() {
ctx := garmTesting.ImpersonateAdminContext(context.Background(), s.db, s.T())
createEpParams := params.CreateGiteaEndpointParams{
Name: testEndpointName,
Description: testEndpointDescription,
APIBaseURL: testAPIBaseURL,
BaseURL: testBaseURL,
}
_, err := s.db.CreateGiteaEndpoint(ctx, createEpParams)
s.Require().NoError(err)
endpoints, err := s.db.ListGiteaEndpoints(ctx)
s.Require().NoError(err)
s.Require().Len(endpoints, 1)
}
func (s *GiteaTestSuite) TestCreateCredentialsFailsWithUnauthorizedForAnonUser() {
ctx := context.Background()
_, err := s.db.CreateGiteaCredentials(ctx, params.CreateGiteaCredentialsParams{})
s.Require().Error(err)
s.Require().ErrorIs(err, runnerErrors.ErrUnauthorized)
}
func (s *GiteaTestSuite) TestCreateCredentialsFailsWhenEndpointNameIsEmpty() {
ctx := garmTesting.ImpersonateAdminContext(context.Background(), s.db, s.T())
_, err := s.db.CreateGiteaCredentials(ctx, params.CreateGiteaCredentialsParams{})
s.Require().Error(err)
s.Require().ErrorIs(err, runnerErrors.ErrBadRequest)
s.Require().Regexp("endpoint name is required", err.Error())
}
func (s *GiteaTestSuite) TestCreateCredentialsFailsWhenEndpointDoesNotExist() {
ctx := garmTesting.ImpersonateAdminContext(context.Background(), s.db, s.T())
_, err := s.db.CreateGiteaCredentials(ctx, params.CreateGiteaCredentialsParams{Endpoint: "non-existing"})
s.Require().Error(err)
s.Require().ErrorIs(err, runnerErrors.ErrNotFound)
s.Require().Regexp("endpoint not found", err.Error())
}
func (s *GiteaTestSuite) TestCreateCredentialsFailsWhenAuthTypeIsInvalid() {
ctx := garmTesting.ImpersonateAdminContext(context.Background(), s.db, s.T())
_, err := s.db.CreateGiteaCredentials(ctx, params.CreateGiteaCredentialsParams{Endpoint: s.giteaEndpoint.Name, AuthType: "invalid"})
s.Require().Error(err)
s.Require().ErrorIs(err, runnerErrors.ErrBadRequest)
s.Require().Regexp("invalid auth type", err.Error())
}
func (s *GiteaTestSuite) TestCreateCredentials() {
ctx := garmTesting.ImpersonateAdminContext(context.Background(), s.db, s.T())
credParams := params.CreateGiteaCredentialsParams{
Name: testCredsName,
Description: testCredsDescription,
Endpoint: s.giteaEndpoint.Name,
AuthType: params.ForgeAuthTypePAT,
PAT: params.GithubPAT{
OAuth2Token: "test",
},
}
creds, err := s.db.CreateGiteaCredentials(ctx, credParams)
s.Require().NoError(err)
s.Require().NotNil(creds)
s.Require().Equal(credParams.Name, creds.Name)
s.Require().Equal(credParams.Description, creds.Description)
s.Require().Equal(credParams.Endpoint, creds.Endpoint.Name)
s.Require().Equal(credParams.AuthType, creds.AuthType)
}
func (s *GiteaTestSuite) TestCreateCredentialsFailsOnDuplicateCredentials() {
ctx := garmTesting.ImpersonateAdminContext(context.Background(), s.db, s.T())
testUser := garmTesting.CreateGARMTestUser(ctx, "testuser", s.db, s.T())
testUserCtx := auth.PopulateContext(context.Background(), testUser, nil)
credParams := params.CreateGiteaCredentialsParams{
Name: testCredsName,
Description: testCredsDescription,
Endpoint: s.giteaEndpoint.Name,
AuthType: params.ForgeAuthTypePAT,
PAT: params.GithubPAT{
OAuth2Token: "test",
},
}
_, err := s.db.CreateGiteaCredentials(ctx, credParams)
s.Require().NoError(err)
// Creating creds with the same parameters should fail for the same user.
_, err = s.db.CreateGiteaCredentials(ctx, credParams)
s.Require().Error(err)
s.Require().ErrorIs(err, runnerErrors.ErrDuplicateEntity)
// Creating creds with the same parameters should work for different users.
_, err = s.db.CreateGiteaCredentials(testUserCtx, credParams)
s.Require().NoError(err)
}
func (s *GiteaTestSuite) TestNormalUsersCanOnlySeeTheirOwnCredentialsAdminCanSeeAll() {
ctx := garmTesting.ImpersonateAdminContext(context.Background(), s.db, s.T())
testUser := garmTesting.CreateGARMTestUser(ctx, "testuser1", s.db, s.T())
testUser2 := garmTesting.CreateGARMTestUser(ctx, "testuser2", s.db, s.T())
testUserCtx := auth.PopulateContext(context.Background(), testUser, nil)
testUser2Ctx := auth.PopulateContext(context.Background(), testUser2, nil)
credParams := params.CreateGiteaCredentialsParams{
Name: testCredsName,
Description: testCredsDescription,
Endpoint: s.giteaEndpoint.Name,
AuthType: params.ForgeAuthTypePAT,
PAT: params.GithubPAT{
OAuth2Token: "test",
},
}
creds, err := s.db.CreateGiteaCredentials(ctx, credParams)
s.Require().NoError(err)
s.Require().NotNil(creds)
credParams.Name = "test-creds2"
creds2, err := s.db.CreateGiteaCredentials(testUserCtx, credParams)
s.Require().NoError(err)
s.Require().NotNil(creds2)
credParams.Name = "test-creds3"
creds3, err := s.db.CreateGiteaCredentials(testUser2Ctx, credParams)
s.Require().NoError(err)
s.Require().NotNil(creds3)
credsList, err := s.db.ListGiteaCredentials(ctx)
s.Require().NoError(err)
s.Require().Len(credsList, 3)
credsList, err = s.db.ListGiteaCredentials(testUserCtx)
s.Require().NoError(err)
s.Require().Len(credsList, 1)
s.Require().Equal("test-creds2", credsList[0].Name)
credsList, err = s.db.ListGiteaCredentials(testUser2Ctx)
s.Require().NoError(err)
s.Require().Len(credsList, 1)
s.Require().Equal("test-creds3", credsList[0].Name)
}
func (s *GiteaTestSuite) TestGetGiteaCredentialsFailsWhenCredentialsDontExist() {
ctx := garmTesting.ImpersonateAdminContext(context.Background(), s.db, s.T())
_, err := s.db.GetGiteaCredentials(ctx, 1, true)
s.Require().Error(err)
s.Require().ErrorIs(err, runnerErrors.ErrNotFound)
_, err = s.db.GetGiteaCredentialsByName(ctx, "non-existing", true)
s.Require().Error(err)
s.Require().ErrorIs(err, runnerErrors.ErrNotFound)
}
func (s *GiteaTestSuite) TestGetGithubCredentialsByNameReturnsOnlyCurrentUserCredentials() {
ctx := garmTesting.ImpersonateAdminContext(context.Background(), s.db, s.T())
testUser := garmTesting.CreateGARMTestUser(ctx, "test-user1", s.db, s.T())
testUserCtx := auth.PopulateContext(context.Background(), testUser, nil)
credParams := params.CreateGiteaCredentialsParams{
Name: testCredsName,
Description: testCredsDescription,
Endpoint: s.giteaEndpoint.Name,
AuthType: params.ForgeAuthTypePAT,
PAT: params.GithubPAT{
OAuth2Token: "test",
},
}
creds, err := s.db.CreateGiteaCredentials(ctx, credParams)
s.Require().NoError(err)
s.Require().NotNil(creds)
creds2, err := s.db.CreateGiteaCredentials(testUserCtx, credParams)
s.Require().NoError(err)
s.Require().NotNil(creds2)
creds2Get, err := s.db.GetGiteaCredentialsByName(testUserCtx, testCredsName, true)
s.Require().NoError(err)
s.Require().NotNil(creds2)
s.Require().Equal(testCredsName, creds2Get.Name)
s.Require().Equal(creds2.ID, creds2Get.ID)
credsGet, err := s.db.GetGiteaCredentialsByName(ctx, testCredsName, true)
s.Require().NoError(err)
s.Require().NotNil(creds)
s.Require().Equal(testCredsName, credsGet.Name)
s.Require().Equal(creds.ID, credsGet.ID)
// Admin can get any creds by ID
credsGet, err = s.db.GetGiteaCredentials(ctx, creds2.ID, true)
s.Require().NoError(err)
s.Require().NotNil(creds2)
s.Require().Equal(creds2.ID, credsGet.ID)
// Normal user cannot get other user creds by ID
_, err = s.db.GetGiteaCredentials(testUserCtx, creds.ID, true)
s.Require().Error(err)
s.Require().ErrorIs(err, runnerErrors.ErrNotFound)
}
func (s *GiteaTestSuite) TestGetGithubCredentials() {
ctx := garmTesting.ImpersonateAdminContext(context.Background(), s.db, s.T())
credParams := params.CreateGiteaCredentialsParams{
Name: testCredsName,
Description: testCredsDescription,
Endpoint: s.giteaEndpoint.Name,
AuthType: params.ForgeAuthTypePAT,
PAT: params.GithubPAT{
OAuth2Token: "test",
},
}
creds, err := s.db.CreateGiteaCredentials(ctx, credParams)
s.Require().NoError(err)
s.Require().NotNil(creds)
creds2, err := s.db.GetGiteaCredentialsByName(ctx, testCredsName, true)
s.Require().NoError(err)
s.Require().NotNil(creds2)
s.Require().Equal(creds.Name, creds2.Name)
s.Require().Equal(creds.ID, creds2.ID)
creds2, err = s.db.GetGiteaCredentials(ctx, creds.ID, true)
s.Require().NoError(err)
s.Require().NotNil(creds2)
s.Require().Equal(creds.Name, creds2.Name)
s.Require().Equal(creds.ID, creds2.ID)
}
func (s *GiteaTestSuite) TestDeleteGiteaCredentials() {
ctx := garmTesting.ImpersonateAdminContext(context.Background(), s.db, s.T())
credParams := params.CreateGiteaCredentialsParams{
Name: testCredsName,
Description: testCredsDescription,
Endpoint: s.giteaEndpoint.Name,
AuthType: params.ForgeAuthTypePAT,
PAT: params.GithubPAT{
OAuth2Token: "test",
},
}
creds, err := s.db.CreateGiteaCredentials(ctx, credParams)
s.Require().NoError(err)
s.Require().NotNil(creds)
err = s.db.DeleteGiteaCredentials(ctx, creds.ID)
s.Require().NoError(err)
_, err = s.db.GetGiteaCredentials(ctx, creds.ID, true)
s.Require().Error(err)
s.Require().ErrorIs(err, runnerErrors.ErrNotFound)
}
func (s *GiteaTestSuite) TestDeleteGiteaCredentialsByNonAdminUser() {
ctx := garmTesting.ImpersonateAdminContext(context.Background(), s.db, s.T())
testUser := garmTesting.CreateGARMTestUser(ctx, "test-user4", s.db, s.T())
testUserCtx := auth.PopulateContext(context.Background(), testUser, nil)
credParams := params.CreateGiteaCredentialsParams{
Name: testCredsName,
Description: testCredsDescription,
Endpoint: s.giteaEndpoint.Name,
AuthType: params.ForgeAuthTypePAT,
PAT: params.GithubPAT{
OAuth2Token: "test-creds4",
},
}
// Create creds as admin
creds, err := s.db.CreateGiteaCredentials(ctx, credParams)
s.Require().NoError(err)
s.Require().NotNil(creds)
// Deleting non existent creds will return a nil error. For the test user
// the creds created by the admin should not be visible, which leads to not found
// which in turn returns no error.
err = s.db.DeleteGiteaCredentials(testUserCtx, creds.ID)
s.Require().NoError(err)
// Check that the creds created by the admin are still there.
credsGet, err := s.db.GetGiteaCredentials(ctx, creds.ID, true)
s.Require().NoError(err)
s.Require().NotNil(credsGet)
s.Require().Equal(creds.ID, credsGet.ID)
// Create the same creds with the test user.
creds2, err := s.db.CreateGiteaCredentials(testUserCtx, credParams)
s.Require().NoError(err)
s.Require().NotNil(creds2)
// Remove creds created by test user.
err = s.db.DeleteGiteaCredentials(testUserCtx, creds2.ID)
s.Require().NoError(err)
// The creds created by the test user should be gone.
_, err = s.db.GetGiteaCredentials(testUserCtx, creds2.ID, true)
s.Require().Error(err)
s.Require().ErrorIs(err, runnerErrors.ErrNotFound)
}
func (s *GiteaTestSuite) TestDeleteCredentialsFailsIfReposOrgsOrEntitiesUseIt() {
ctx := garmTesting.ImpersonateAdminContext(context.Background(), s.db, s.T())
credParams := params.CreateGiteaCredentialsParams{
Name: testCredsName,
Description: testCredsDescription,
Endpoint: s.giteaEndpoint.Name,
AuthType: params.ForgeAuthTypePAT,
PAT: params.GithubPAT{
OAuth2Token: "test",
},
}
creds, err := s.db.CreateGiteaCredentials(ctx, credParams)
s.Require().NoError(err)
s.Require().NotNil(creds)
repo, err := s.db.CreateRepository(ctx, "test-owner", "test-repo", creds, "superSecret@123BlaBla", params.PoolBalancerTypeRoundRobin)
s.Require().NoError(err)
s.Require().NotNil(repo)
err = s.db.DeleteGiteaCredentials(ctx, creds.ID)
s.Require().Error(err)
s.Require().ErrorIs(err, runnerErrors.ErrBadRequest)
err = s.db.DeleteRepository(ctx, repo.ID)
s.Require().NoError(err)
org, err := s.db.CreateOrganization(ctx, "test-org", creds, "superSecret@123BlaBla", params.PoolBalancerTypeRoundRobin)
s.Require().NoError(err)
s.Require().NotNil(org)
err = s.db.DeleteGiteaCredentials(ctx, creds.ID)
s.Require().Error(err)
s.Require().ErrorIs(err, runnerErrors.ErrBadRequest)
err = s.db.DeleteOrganization(ctx, org.ID)
s.Require().NoError(err)
enterprise, err := s.db.CreateEnterprise(ctx, "test-enterprise", creds, "superSecret@123BlaBla", params.PoolBalancerTypeRoundRobin)
s.Require().ErrorIs(err, runnerErrors.ErrBadRequest)
s.Require().Equal(params.Enterprise{}, enterprise)
err = s.db.DeleteGiteaCredentials(ctx, creds.ID)
s.Require().NoError(err)
_, err = s.db.GetGiteaCredentials(ctx, creds.ID, true)
s.Require().Error(err)
s.Require().ErrorIs(err, runnerErrors.ErrNotFound)
}
func (s *GiteaTestSuite) TestUpdateCredentials() {
ctx := garmTesting.ImpersonateAdminContext(context.Background(), s.db, s.T())
credParams := params.CreateGiteaCredentialsParams{
Name: testCredsName,
Description: testCredsDescription,
Endpoint: s.giteaEndpoint.Name,
AuthType: params.ForgeAuthTypePAT,
PAT: params.GithubPAT{
OAuth2Token: "test",
},
}
creds, err := s.db.CreateGiteaCredentials(ctx, credParams)
s.Require().NoError(err)
s.Require().NotNil(creds)
newDescription := "new description"
newName := "new-name"
newToken := "new-token"
updateCredParams := params.UpdateGiteaCredentialsParams{
Description: &newDescription,
Name: &newName,
PAT: &params.GithubPAT{
OAuth2Token: newToken,
},
}
updatedCreds, err := s.db.UpdateGiteaCredentials(ctx, creds.ID, updateCredParams)
s.Require().NoError(err)
s.Require().NotNil(updatedCreds)
s.Require().Equal(newDescription, updatedCreds.Description)
s.Require().Equal(newName, updatedCreds.Name)
}
func (s *GiteaTestSuite) TestUpdateCredentialsFailsForNonExistingCredentials() {
ctx := garmTesting.ImpersonateAdminContext(context.Background(), s.db, s.T())
updateCredParams := params.UpdateGiteaCredentialsParams{
Description: nil,
}
_, err := s.db.UpdateGiteaCredentials(ctx, 1, updateCredParams)
s.Require().Error(err)
s.Require().ErrorIs(err, runnerErrors.ErrNotFound)
}
func (s *GiteaTestSuite) TestUpdateCredentialsFailsIfCredentialsAreOwnedByNonAdminUser() {
ctx := garmTesting.ImpersonateAdminContext(context.Background(), s.db, s.T())
testUser := garmTesting.CreateGARMTestUser(ctx, "test-user5", s.db, s.T())
testUserCtx := auth.PopulateContext(context.Background(), testUser, nil)
credParams := params.CreateGiteaCredentialsParams{
Name: testCredsName,
Description: testCredsDescription,
Endpoint: s.giteaEndpoint.Name,
AuthType: params.ForgeAuthTypePAT,
PAT: params.GithubPAT{
OAuth2Token: "test-creds5",
},
}
creds, err := s.db.CreateGiteaCredentials(ctx, credParams)
s.Require().NoError(err)
s.Require().NotNil(creds)
newDescription := "new description2"
updateCredParams := params.UpdateGiteaCredentialsParams{
Description: &newDescription,
}
_, err = s.db.UpdateGiteaCredentials(testUserCtx, creds.ID, updateCredParams)
s.Require().Error(err)
s.Require().ErrorIs(err, runnerErrors.ErrNotFound)
}
func (s *GiteaTestSuite) TestAdminUserCanUpdateAnyGiteaCredentials() {
ctx := garmTesting.ImpersonateAdminContext(context.Background(), s.db, s.T())
testUser := garmTesting.CreateGARMTestUser(ctx, "test-user5", s.db, s.T())
testUserCtx := auth.PopulateContext(context.Background(), testUser, nil)
credParams := params.CreateGiteaCredentialsParams{
Name: testCredsName,
Description: testCredsDescription,
Endpoint: s.giteaEndpoint.Name,
AuthType: params.ForgeAuthTypePAT,
PAT: params.GithubPAT{
OAuth2Token: "test-creds5",
},
}
creds, err := s.db.CreateGiteaCredentials(testUserCtx, credParams)
s.Require().NoError(err)
s.Require().NotNil(creds)
newDescription := "new description2"
updateCredParams := params.UpdateGiteaCredentialsParams{
Description: &newDescription,
}
newCreds, err := s.db.UpdateGiteaCredentials(ctx, creds.ID, updateCredParams)
s.Require().NoError(err)
s.Require().Equal(newDescription, newCreds.Description)
}
func (s *GiteaTestSuite) TestDeleteCredentialsWithOrgsOrReposFails() {
ctx := garmTesting.ImpersonateAdminContext(context.Background(), s.db, s.T())
credParams := params.CreateGiteaCredentialsParams{
Name: testCredsName,
Description: testCredsDescription,
Endpoint: s.giteaEndpoint.Name,
AuthType: params.ForgeAuthTypePAT,
PAT: params.GithubPAT{
OAuth2Token: "test-creds5",
},
}
creds, err := s.db.CreateGiteaCredentials(ctx, credParams)
s.Require().NoError(err)
s.Require().NotNil(creds)
repo, err := s.db.CreateRepository(ctx, "test-owner", "test-repo", creds, "superSecret@123BlaBla", params.PoolBalancerTypeRoundRobin)
s.Require().NoError(err)
s.Require().NotNil(repo)
err = s.db.DeleteGiteaCredentials(ctx, creds.ID)
s.Require().Error(err)
s.Require().ErrorIs(err, runnerErrors.ErrBadRequest)
err = s.db.DeleteRepository(ctx, repo.ID)
s.Require().NoError(err)
org, err := s.db.CreateOrganization(ctx, "test-org", creds, "superSecret@123BlaBla", params.PoolBalancerTypeRoundRobin)
s.Require().NoError(err)
s.Require().NotNil(org)
err = s.db.DeleteGiteaCredentials(ctx, creds.ID)
s.Require().Error(err)
s.Require().ErrorIs(err, runnerErrors.ErrBadRequest)
err = s.db.DeleteOrganization(ctx, org.ID)
s.Require().NoError(err)
err = s.db.DeleteGiteaCredentials(ctx, creds.ID)
s.Require().NoError(err)
_, err = s.db.GetGiteaCredentials(ctx, creds.ID, true)
s.Require().Error(err)
s.Require().ErrorIs(err, runnerErrors.ErrNotFound)
}
func (s *GiteaTestSuite) TestDeleteGiteaEndpointFailsWithOrgsReposOrCredentials() {
ctx := garmTesting.ImpersonateAdminContext(context.Background(), s.db, s.T())
endpointParams := params.CreateGiteaEndpointParams{
Name: "deleteme",
Description: testEndpointDescription,
APIBaseURL: testAPIBaseURL,
BaseURL: testBaseURL,
}
ep, err := s.db.CreateGiteaEndpoint(ctx, endpointParams)
s.Require().NoError(err)
s.Require().NotNil(ep)
credParams := params.CreateGiteaCredentialsParams{
Name: testCredsName,
Description: testCredsDescription,
Endpoint: ep.Name,
AuthType: params.ForgeAuthTypePAT,
PAT: params.GithubPAT{
OAuth2Token: "test-creds5",
},
}
creds, err := s.db.CreateGiteaCredentials(ctx, credParams)
s.Require().NoError(err)
s.Require().NotNil(creds)
repo, err := s.db.CreateRepository(ctx, "test-owner", "test-repo", creds, "superSecret@123BlaBla", params.PoolBalancerTypeRoundRobin)
s.Require().NoError(err)
s.Require().NotNil(repo)
badRequest := &runnerErrors.BadRequestError{}
err = s.db.DeleteGiteaEndpoint(ctx, ep.Name)
s.Require().Error(err)
s.Require().ErrorAs(err, &badRequest)
err = s.db.DeleteRepository(ctx, repo.ID)
s.Require().NoError(err)
org, err := s.db.CreateOrganization(ctx, "test-org", creds, "superSecret@123BlaBla", params.PoolBalancerTypeRoundRobin)
s.Require().NoError(err)
s.Require().NotNil(org)
err = s.db.DeleteGiteaEndpoint(ctx, ep.Name)
s.Require().Error(err)
s.Require().ErrorAs(err, &badRequest)
err = s.db.DeleteOrganization(ctx, org.ID)
s.Require().NoError(err)
err = s.db.DeleteGiteaCredentials(ctx, creds.ID)
s.Require().NoError(err)
err = s.db.DeleteGiteaEndpoint(ctx, ep.Name)
s.Require().NoError(err)
_, err = s.db.GetGiteaEndpoint(ctx, ep.Name)
s.Require().Error(err)
s.Require().ErrorIs(err, runnerErrors.ErrNotFound)
}
func (s *GiteaTestSuite) TestListGiteaEndpoints() {
ctx := garmTesting.ImpersonateAdminContext(context.Background(), s.db, s.T())
createEpParams := params.CreateGiteaEndpointParams{
Name: "deleteme",
Description: testEndpointDescription,
APIBaseURL: testAPIBaseURL,
BaseURL: testBaseURL,
}
_, err := s.db.CreateGiteaEndpoint(ctx, createEpParams)
s.Require().NoError(err)
endpoints, err := s.db.ListGiteaEndpoints(ctx)
s.Require().NoError(err)
s.Require().Len(endpoints, 2)
}
func TestGiteaTestSuite(t *testing.T) {
suite.Run(t, new(GiteaTestSuite))
}

View file

@ -200,7 +200,7 @@ func (s *sqlDatabase) DeleteGithubEndpoint(_ context.Context, name string) (err
} }
if credsCount > 0 || repoCnt > 0 || orgCnt > 0 || entCnt > 0 { if credsCount > 0 || repoCnt > 0 || orgCnt > 0 || entCnt > 0 {
return errors.New("cannot delete endpoint with associated entities") return runnerErrors.NewBadRequestError("cannot delete endpoint with associated entities")
} }
if err := tx.Unscoped().Delete(&endpoint).Error; err != nil { if err := tx.Unscoped().Delete(&endpoint).Error; err != nil {

View file

@ -555,7 +555,7 @@ func (s *GithubTestSuite) TestDeleteCredentialsFailsIfReposOrgsOrEntitiesUseIt()
err = s.db.DeleteOrganization(ctx, org.ID) err = s.db.DeleteOrganization(ctx, org.ID)
s.Require().NoError(err) s.Require().NoError(err)
enterprise, err := s.db.CreateEnterprise(ctx, "test-enterprise", creds.Name, "superSecret@123BlaBla", params.PoolBalancerTypeRoundRobin) enterprise, err := s.db.CreateEnterprise(ctx, "test-enterprise", creds, "superSecret@123BlaBla", params.PoolBalancerTypeRoundRobin)
s.Require().NoError(err) s.Require().NoError(err)
s.Require().NotNil(enterprise) s.Require().NotNil(enterprise)
@ -737,6 +737,68 @@ func (s *GithubTestSuite) TestAdminUserCanUpdateAnyGithubCredentials() {
s.Require().Equal(newDescription, newCreds.Description) s.Require().Equal(newDescription, newCreds.Description)
} }
func (s *GithubTestSuite) TestDeleteGithubEndpointFailsWithOrgsReposOrCredentials() {
ctx := garmTesting.ImpersonateAdminContext(context.Background(), s.db, s.T())
endpointParams := params.CreateGithubEndpointParams{
Name: "deleteme",
Description: testEndpointDescription,
APIBaseURL: testAPIBaseURL,
BaseURL: testBaseURL,
}
ep, err := s.db.CreateGithubEndpoint(ctx, endpointParams)
s.Require().NoError(err)
s.Require().NotNil(ep)
credParams := params.CreateGithubCredentialsParams{
Name: testCredsName,
Description: testCredsDescription,
Endpoint: ep.Name,
AuthType: params.ForgeAuthTypePAT,
PAT: params.GithubPAT{
OAuth2Token: "test-creds5",
},
}
creds, err := s.db.CreateGithubCredentials(ctx, credParams)
s.Require().NoError(err)
s.Require().NotNil(creds)
repo, err := s.db.CreateRepository(ctx, "test-owner", "test-repo", creds, "superSecret@123BlaBla", params.PoolBalancerTypeRoundRobin)
s.Require().NoError(err)
s.Require().NotNil(repo)
badRequest := &runnerErrors.BadRequestError{}
err = s.db.DeleteGithubEndpoint(ctx, ep.Name)
s.Require().Error(err)
s.Require().ErrorAs(err, &badRequest)
err = s.db.DeleteRepository(ctx, repo.ID)
s.Require().NoError(err)
org, err := s.db.CreateOrganization(ctx, "test-org", creds, "superSecret@123BlaBla", params.PoolBalancerTypeRoundRobin)
s.Require().NoError(err)
s.Require().NotNil(org)
err = s.db.DeleteGithubEndpoint(ctx, ep.Name)
s.Require().Error(err)
s.Require().ErrorAs(err, &badRequest)
err = s.db.DeleteOrganization(ctx, org.ID)
s.Require().NoError(err)
err = s.db.DeleteGithubCredentials(ctx, creds.ID)
s.Require().NoError(err)
err = s.db.DeleteGithubEndpoint(ctx, ep.Name)
s.Require().NoError(err)
_, err = s.db.GetGithubEndpoint(ctx, ep.Name)
s.Require().Error(err)
s.Require().ErrorIs(err, runnerErrors.ErrNotFound)
}
func TestGithubTestSuite(t *testing.T) { func TestGithubTestSuite(t *testing.T) {
suite.Run(t, new(GithubTestSuite)) suite.Run(t, new(GithubTestSuite))
} }

View file

@ -54,8 +54,10 @@ type OrgTestSuite struct {
adminUserID string adminUserID string
testCreds params.ForgeCredentials testCreds params.ForgeCredentials
testCredsGitea params.ForgeCredentials
secondaryTestCreds params.ForgeCredentials secondaryTestCreds params.ForgeCredentials
githubEndpoint params.ForgeEndpoint githubEndpoint params.ForgeEndpoint
giteaEndpoint params.ForgeEndpoint
} }
func (s *OrgTestSuite) equalInstancesByName(expected, actual []params.Instance) { func (s *OrgTestSuite) equalInstancesByName(expected, actual []params.Instance) {
@ -91,7 +93,9 @@ func (s *OrgTestSuite) SetupTest() {
s.Require().NotEmpty(s.adminUserID) s.Require().NotEmpty(s.adminUserID)
s.githubEndpoint = garmTesting.CreateDefaultGithubEndpoint(adminCtx, db, s.T()) s.githubEndpoint = garmTesting.CreateDefaultGithubEndpoint(adminCtx, db, s.T())
s.giteaEndpoint = garmTesting.CreateDefaultGiteaEndpoint(adminCtx, db, s.T())
s.testCreds = garmTesting.CreateTestGithubCredentials(adminCtx, "new-creds", db, s.T(), s.githubEndpoint) s.testCreds = garmTesting.CreateTestGithubCredentials(adminCtx, "new-creds", db, s.T(), s.githubEndpoint)
s.testCredsGitea = garmTesting.CreateTestGiteaCredentials(adminCtx, "new-creds", db, s.T(), s.giteaEndpoint)
s.secondaryTestCreds = garmTesting.CreateTestGithubCredentials(adminCtx, "secondary-creds", db, s.T(), s.githubEndpoint) s.secondaryTestCreds = garmTesting.CreateTestGithubCredentials(adminCtx, "secondary-creds", db, s.T(), s.githubEndpoint)
// create some organization objects in the database, for testing purposes // create some organization objects in the database, for testing purposes
@ -192,6 +196,62 @@ func (s *OrgTestSuite) TestCreateOrganization() {
s.Require().Equal(storeOrg.Name, org.Name) s.Require().Equal(storeOrg.Name, org.Name)
s.Require().Equal(storeOrg.Credentials.Name, org.Credentials.Name) s.Require().Equal(storeOrg.Credentials.Name, org.Credentials.Name)
s.Require().Equal(storeOrg.WebhookSecret, org.WebhookSecret) s.Require().Equal(storeOrg.WebhookSecret, org.WebhookSecret)
entity, err := org.GetEntity()
s.Require().Nil(err)
s.Require().Equal(entity.EntityType, params.ForgeEntityTypeOrganization)
s.Require().Equal(entity.ID, org.ID)
forgeType, err := entity.GetForgeType()
s.Require().Nil(err)
s.Require().Equal(forgeType, params.GithubEndpointType)
}
func (s *OrgTestSuite) TestCreateOrgForGitea() {
// call tested function
org, err := s.Store.CreateOrganization(
s.adminCtx,
s.Fixtures.CreateOrgParams.Name,
s.testCredsGitea,
s.Fixtures.CreateOrgParams.WebhookSecret,
params.PoolBalancerTypeRoundRobin)
// assertions
s.Require().Nil(err)
storeOrg, err := s.Store.GetOrganizationByID(s.adminCtx, org.ID)
if err != nil {
s.FailNow(fmt.Sprintf("failed to get organization by id: %v", err))
}
s.Require().Equal(storeOrg.Name, org.Name)
s.Require().Equal(storeOrg.Credentials.Name, org.Credentials.Name)
s.Require().Equal(storeOrg.WebhookSecret, org.WebhookSecret)
entity, err := org.GetEntity()
s.Require().Nil(err)
s.Require().Equal(entity.EntityType, params.ForgeEntityTypeOrganization)
s.Require().Equal(entity.ID, org.ID)
forgeType, err := entity.GetForgeType()
s.Require().Nil(err)
s.Require().Equal(forgeType, params.GiteaEndpointType)
}
func (s *OrgTestSuite) TestCreateOrganizationInvalidForgeType() {
credentials := params.ForgeCredentials{
Name: "test-creds",
Endpoint: s.githubEndpoint,
ID: 99,
ForgeType: params.EndpointType("invalid-forge-type"),
}
_, err := s.Store.CreateOrganization(
s.adminCtx,
s.Fixtures.CreateOrgParams.Name,
credentials,
s.Fixtures.CreateOrgParams.WebhookSecret,
params.PoolBalancerTypeRoundRobin)
s.Require().NotNil(err)
s.Require().Equal("creating org: unsupported credentials type: invalid request", err.Error())
} }
func (s *OrgTestSuite) TestCreateOrganizationInvalidDBPassphrase() { func (s *OrgTestSuite) TestCreateOrganizationInvalidDBPassphrase() {

View file

@ -59,8 +59,10 @@ type RepoTestSuite struct {
adminUserID string adminUserID string
testCreds params.ForgeCredentials testCreds params.ForgeCredentials
testCredsGitea params.ForgeCredentials
secondaryTestCreds params.ForgeCredentials secondaryTestCreds params.ForgeCredentials
githubEndpoint params.ForgeEndpoint githubEndpoint params.ForgeEndpoint
giteaEndpoint params.ForgeEndpoint
} }
func (s *RepoTestSuite) equalReposByName(expected, actual []params.Repository) { func (s *RepoTestSuite) equalReposByName(expected, actual []params.Repository) {
@ -109,7 +111,9 @@ func (s *RepoTestSuite) SetupTest() {
s.Require().NotEmpty(s.adminUserID) s.Require().NotEmpty(s.adminUserID)
s.githubEndpoint = garmTesting.CreateDefaultGithubEndpoint(adminCtx, db, s.T()) s.githubEndpoint = garmTesting.CreateDefaultGithubEndpoint(adminCtx, db, s.T())
s.giteaEndpoint = garmTesting.CreateDefaultGiteaEndpoint(adminCtx, db, s.T())
s.testCreds = garmTesting.CreateTestGithubCredentials(adminCtx, "new-creds", db, s.T(), s.githubEndpoint) s.testCreds = garmTesting.CreateTestGithubCredentials(adminCtx, "new-creds", db, s.T(), s.githubEndpoint)
s.testCredsGitea = garmTesting.CreateTestGiteaCredentials(adminCtx, "new-creds", db, s.T(), s.giteaEndpoint)
s.secondaryTestCreds = garmTesting.CreateTestGithubCredentials(adminCtx, "secondary-creds", db, s.T(), s.githubEndpoint) s.secondaryTestCreds = garmTesting.CreateTestGithubCredentials(adminCtx, "secondary-creds", db, s.T(), s.githubEndpoint)
// create some repository objects in the database, for testing purposes // create some repository objects in the database, for testing purposes
@ -219,6 +223,68 @@ func (s *RepoTestSuite) TestCreateRepository() {
s.Require().Equal(storeRepo.Name, repo.Name) s.Require().Equal(storeRepo.Name, repo.Name)
s.Require().Equal(storeRepo.Credentials.Name, repo.Credentials.Name) s.Require().Equal(storeRepo.Credentials.Name, repo.Credentials.Name)
s.Require().Equal(storeRepo.WebhookSecret, repo.WebhookSecret) s.Require().Equal(storeRepo.WebhookSecret, repo.WebhookSecret)
entity, err := repo.GetEntity()
s.Require().Nil(err)
s.Require().Equal(s.Fixtures.CreateRepoParams.Owner, entity.ID)
s.Require().Equal(entity.EntityType, params.ForgeEntityTypeRepository)
forgeType, err := entity.GetForgeType()
s.Require().Nil(err)
s.Require().Equal(forgeType, params.GithubEndpointType)
}
func (s *RepoTestSuite) TestCreateRepositoryGitea() {
// call tested function
repo, err := s.Store.CreateRepository(
s.adminCtx,
s.Fixtures.CreateRepoParams.Owner,
s.Fixtures.CreateRepoParams.Name,
s.testCredsGitea,
s.Fixtures.CreateRepoParams.WebhookSecret,
params.PoolBalancerTypeRoundRobin,
)
// assertions
s.Require().Nil(err)
storeRepo, err := s.Store.GetRepositoryByID(s.adminCtx, repo.ID)
if err != nil {
s.FailNow(fmt.Sprintf("failed to get repository by id: %v", err))
}
s.Require().Equal(storeRepo.Owner, repo.Owner)
s.Require().Equal(storeRepo.Name, repo.Name)
s.Require().Equal(storeRepo.Credentials.Name, repo.Credentials.Name)
s.Require().Equal(storeRepo.WebhookSecret, repo.WebhookSecret)
entity, err := repo.GetEntity()
s.Require().Nil(err)
s.Require().Equal(repo.ID, entity.ID)
s.Require().Equal(entity.EntityType, params.ForgeEntityTypeRepository)
forgeType, err := entity.GetForgeType()
s.Require().Nil(err)
s.Require().Equal(forgeType, params.GiteaEndpointType)
}
func (s *RepoTestSuite) TestCreateRepositoryInvalidForgeType() {
// call tested function
_, err := s.Store.CreateRepository(
s.adminCtx,
s.Fixtures.CreateRepoParams.Owner,
s.Fixtures.CreateRepoParams.Name,
params.ForgeCredentials{
Name: "test-creds",
ForgeType: "invalid-forge-type",
Endpoint: params.ForgeEndpoint{
Name: "test-endpoint",
},
},
s.Fixtures.CreateRepoParams.WebhookSecret,
params.PoolBalancerTypeRoundRobin,
)
s.Require().NotNil(err)
s.Require().Equal("creating repository: unsupported credentials type: invalid request", err.Error())
} }
func (s *RepoTestSuite) TestCreateRepositoryInvalidDBPassphrase() { func (s *RepoTestSuite) TestCreateRepositoryInvalidDBPassphrase() {

View file

@ -58,7 +58,7 @@ func (s *ScaleSetsTestSuite) SetupTest() {
s.FailNow(fmt.Sprintf("failed to create repo: %s", err)) s.FailNow(fmt.Sprintf("failed to create repo: %s", err))
} }
s.enterprise, err = s.Store.CreateEnterprise(s.adminCtx, "test-enterprise", s.creds.Name, "test-webhookSecret", params.PoolBalancerTypeRoundRobin) s.enterprise, err = s.Store.CreateEnterprise(s.adminCtx, "test-enterprise", s.creds, "test-webhookSecret", params.PoolBalancerTypeRoundRobin)
if err != nil { if err != nil {
s.FailNow(fmt.Sprintf("failed to create enterprise: %s", err)) s.FailNow(fmt.Sprintf("failed to create enterprise: %s", err))
} }

View file

@ -646,7 +646,7 @@ func (s *WatcherStoreTestSuite) TestEnterpriseWatcher() {
creds := garmTesting.CreateTestGithubCredentials(s.ctx, "test-creds", s.store, s.T(), ep) creds := garmTesting.CreateTestGithubCredentials(s.ctx, "test-creds", s.store, s.T(), ep)
s.T().Cleanup(func() { s.store.DeleteGithubCredentials(s.ctx, creds.ID) }) s.T().Cleanup(func() { s.store.DeleteGithubCredentials(s.ctx, creds.ID) })
ent, err := s.store.CreateEnterprise(s.ctx, "test-enterprise", creds.Name, "test-secret", params.PoolBalancerTypeRoundRobin) ent, err := s.store.CreateEnterprise(s.ctx, "test-enterprise", creds, "test-secret", params.PoolBalancerTypeRoundRobin)
s.Require().NoError(err) s.Require().NoError(err)
s.Require().NotEmpty(ent.ID) s.Require().NotEmpty(ent.ID)

View file

@ -110,6 +110,30 @@ func CreateDefaultGithubEndpoint(ctx context.Context, db common.Store, s *testin
return ep return ep
} }
func CreateDefaultGiteaEndpoint(ctx context.Context, db common.Store, s *testing.T) params.ForgeEndpoint {
endpointParams := params.CreateGiteaEndpointParams{
Name: "gitea.example.com",
Description: "gitea endpoint",
APIBaseURL: "https://gitea.example.com/",
BaseURL: "https://gitea.example.com/",
}
ep, err := db.GetGithubEndpoint(ctx, endpointParams.Name)
if err != nil {
if !errors.Is(err, runnerErrors.ErrNotFound) {
s.Fatalf("failed to get database object (github.com): %v", err)
}
ep, err = db.CreateGiteaEndpoint(ctx, endpointParams)
if err != nil {
if !errors.Is(err, runnerErrors.ErrDuplicateEntity) {
s.Fatalf("failed to create database object (github.com): %v", err)
}
}
}
return ep
}
func CreateTestGithubCredentials(ctx context.Context, credsName string, db common.Store, s *testing.T, endpoint params.ForgeEndpoint) params.ForgeCredentials { func CreateTestGithubCredentials(ctx context.Context, credsName string, db common.Store, s *testing.T, endpoint params.ForgeEndpoint) params.ForgeCredentials {
newCredsParams := params.CreateGithubCredentialsParams{ newCredsParams := params.CreateGithubCredentialsParams{
Name: credsName, Name: credsName,
@ -127,6 +151,23 @@ func CreateTestGithubCredentials(ctx context.Context, credsName string, db commo
return newCreds return newCreds
} }
func CreateTestGiteaCredentials(ctx context.Context, credsName string, db common.Store, s *testing.T, endpoint params.ForgeEndpoint) params.ForgeCredentials {
newCredsParams := params.CreateGiteaCredentialsParams{
Name: credsName,
Description: "Test creds",
AuthType: params.ForgeAuthTypePAT,
Endpoint: endpoint.Name,
PAT: params.GithubPAT{
OAuth2Token: "test-token",
},
}
newCreds, err := db.CreateGiteaCredentials(ctx, newCredsParams)
if err != nil {
s.Fatalf("failed to create database object (%s): %v", credsName, err)
}
return newCreds
}
func GetTestSqliteDBConfig(t *testing.T) config.Database { func GetTestSqliteDBConfig(t *testing.T) config.Database {
dir, err := os.MkdirTemp("", "garm-config-test") dir, err := os.MkdirTemp("", "garm-config-test")
if err != nil { if err != nil {

View file

@ -39,7 +39,7 @@ func (r *Runner) CreateEnterprise(ctx context.Context, param params.CreateEnterp
return params.Enterprise{}, runnerErrors.NewConflictError("enterprise %s already exists", param.Name) return params.Enterprise{}, runnerErrors.NewConflictError("enterprise %s already exists", param.Name)
} }
enterprise, err = r.store.CreateEnterprise(ctx, param.Name, creds.Name, param.WebhookSecret, param.PoolBalancerType) enterprise, err = r.store.CreateEnterprise(ctx, param.Name, creds, param.WebhookSecret, param.PoolBalancerType)
if err != nil { if err != nil {
return params.Enterprise{}, errors.Wrap(err, "creating enterprise") return params.Enterprise{}, errors.Wrap(err, "creating enterprise")
} }

View file

@ -81,7 +81,7 @@ func (s *EnterpriseTestSuite) SetupTest() {
enterprise, err := db.CreateEnterprise( enterprise, err := db.CreateEnterprise(
adminCtx, adminCtx,
name, name,
s.testCreds.Name, s.testCreds,
fmt.Sprintf("test-webhook-secret-%v", i), fmt.Sprintf("test-webhook-secret-%v", i),
params.PoolBalancerTypeRoundRobin, params.PoolBalancerTypeRoundRobin,
) )