// 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: alternetTestEndpointName, Description: testEndpointDescription, APIBaseURL: testAPIBaseURL, BaseURL: testBaseURL, } endpoint, err := s.db.CreateGiteaEndpoint(ctx, createEpParams) s.Require().NoError(err) s.Require().NotNil(endpoint) s.Require().Equal(alternetTestEndpointName, endpoint.Name) } func (s *GiteaTestSuite) TestCreatingDuplicateEndpointFails() { ctx := garmTesting.ImpersonateAdminContext(context.Background(), s.db, s.T()) createEpParams := params.CreateGiteaEndpointParams{ Name: alternetTestEndpointName, 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: alternetTestEndpointName, 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: alternetTestEndpointName, 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, alternetTestEndpointName) s.Require().NoError(err) _, err = s.db.GetGiteaEndpoint(ctx, alternetTestEndpointName) 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 := "another description" newAPIBaseURL := "https://updated.example.com" newBaseURL := "https://updated.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 desc" 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: alternetTestEndpointName, 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 (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 := "just a description" newName := "new-name" newToken := "new-token" updateCredParams := params.UpdateGiteaCredentialsParams{ Description: &newDescription, Name: &newName, PAT: ¶ms.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 params desc" 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 := "another new description" 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) TestUpdateEndpointURLsFailsIfCredentialsAreAssociated() { 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) credParams := params.CreateGiteaCredentialsParams{ Name: testCredsName, Description: testCredsDescription, Endpoint: testEndpointName, AuthType: params.ForgeAuthTypePAT, PAT: params.GithubPAT{ OAuth2Token: "test", }, } _, err = s.db.CreateGiteaCredentials(ctx, credParams) s.Require().NoError(err) newDescription := "new gitea description" newBaseURL := "https://new-gitea.example.com" newAPIBaseURL := "https://new-gotea.example.com" updateEpParams := params.UpdateGiteaEndpointParams{ BaseURL: &newBaseURL, } _, err = s.db.UpdateGiteaEndpoint(ctx, testEndpointName, updateEpParams) s.Require().Error(err) s.Require().ErrorIs(err, runnerErrors.ErrBadRequest) s.Require().EqualError(err, "updating gitea endpoint: cannot update endpoint URLs with existing credentials: invalid request") updateEpParams = params.UpdateGiteaEndpointParams{ APIBaseURL: &newAPIBaseURL, } _, err = s.db.UpdateGiteaEndpoint(ctx, testEndpointName, updateEpParams) s.Require().Error(err) s.Require().ErrorIs(err, runnerErrors.ErrBadRequest) s.Require().EqualError(err, "updating gitea endpoint: cannot update endpoint URLs with existing credentials: invalid request") updateEpParams = params.UpdateGiteaEndpointParams{ Description: &newDescription, } ret, err := s.db.UpdateGiteaEndpoint(ctx, testEndpointName, updateEpParams) s.Require().NoError(err) s.Require().Equal(newDescription, ret.Description) } 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)) }