This change updates all dependencies. Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
205 lines
7.5 KiB
Go
205 lines
7.5 KiB
Go
//go:build integration
|
|
// +build integration
|
|
|
|
// Copyright 2025 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 integration
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"time"
|
|
|
|
"github.com/google/go-github/v72/github"
|
|
|
|
commonParams "github.com/cloudbase/garm-provider-common/params"
|
|
"github.com/cloudbase/garm/params"
|
|
)
|
|
|
|
func (suite *GarmSuite) TestOrganizations() {
|
|
organization := suite.CreateOrg(orgName, suite.credentialsName, orgWebhookSecret)
|
|
org := suite.UpdateOrg(organization.ID, fmt.Sprintf("%s-clone", suite.credentialsName))
|
|
suite.NotEqual(organization, org, "organization not updated")
|
|
orgHookInfo := suite.InstallOrgWebhook(org.ID)
|
|
suite.ValidateOrgWebhookInstalled(suite.ghToken, orgHookInfo.URL, orgName)
|
|
suite.UninstallOrgWebhook(org.ID)
|
|
suite.ValidateOrgWebhookUninstalled(suite.ghToken, orgHookInfo.URL, orgName)
|
|
_ = suite.InstallOrgWebhook(org.ID)
|
|
suite.ValidateOrgWebhookInstalled(suite.ghToken, orgHookInfo.URL, orgName)
|
|
|
|
orgPoolParams := params.CreatePoolParams{
|
|
MaxRunners: 2,
|
|
MinIdleRunners: 0,
|
|
Flavor: "default",
|
|
Image: "ubuntu:24.04",
|
|
OSType: commonParams.Linux,
|
|
OSArch: commonParams.Amd64,
|
|
ProviderName: "lxd_local",
|
|
Tags: []string{"org-runner"},
|
|
Enabled: true,
|
|
}
|
|
orgPool := suite.CreateOrgPool(org.ID, orgPoolParams)
|
|
orgPoolGot := suite.GetOrgPool(org.ID, orgPool.ID)
|
|
suite.Equal(orgPool, orgPoolGot, "organization pool mismatch")
|
|
suite.DeleteOrgPool(org.ID, orgPool.ID)
|
|
|
|
orgPool = suite.CreateOrgPool(org.ID, orgPoolParams)
|
|
orgPoolUpdated := suite.UpdateOrgPool(org.ID, orgPool.ID, orgPoolParams.MaxRunners, 1)
|
|
suite.NotEqual(orgPool, orgPoolUpdated, "organization pool not updated")
|
|
|
|
suite.WaitOrgRunningIdleInstances(org.ID, 6*time.Minute)
|
|
}
|
|
|
|
func (suite *GarmSuite) CreateOrg(orgName, credentialsName, orgWebhookSecret string) *params.Organization {
|
|
t := suite.T()
|
|
t.Logf("Create org with org_name %s", orgName)
|
|
orgParams := params.CreateOrgParams{
|
|
Name: orgName,
|
|
CredentialsName: credentialsName,
|
|
WebhookSecret: orgWebhookSecret,
|
|
}
|
|
org, err := createOrg(suite.cli, suite.authToken, orgParams)
|
|
suite.NoError(err, "error creating organization")
|
|
return org
|
|
}
|
|
|
|
func (suite *GarmSuite) UpdateOrg(id, credentialsName string) *params.Organization {
|
|
t := suite.T()
|
|
t.Logf("Update org with org_id %s", id)
|
|
updateParams := params.UpdateEntityParams{
|
|
CredentialsName: credentialsName,
|
|
}
|
|
org, err := updateOrg(suite.cli, suite.authToken, id, updateParams)
|
|
suite.NoError(err, "error updating organization")
|
|
return org
|
|
}
|
|
|
|
func (suite *GarmSuite) InstallOrgWebhook(id string) *params.HookInfo {
|
|
t := suite.T()
|
|
t.Logf("Install org webhook with org_id %s", id)
|
|
webhookParams := params.InstallWebhookParams{
|
|
WebhookEndpointType: params.WebhookEndpointDirect,
|
|
}
|
|
_, err := installOrgWebhook(suite.cli, suite.authToken, id, webhookParams)
|
|
suite.NoError(err, "error installing organization webhook")
|
|
webhookInfo, err := getOrgWebhook(suite.cli, suite.authToken, id)
|
|
suite.NoError(err, "error getting organization webhook")
|
|
return webhookInfo
|
|
}
|
|
|
|
func (suite *GarmSuite) ValidateOrgWebhookInstalled(ghToken, url, orgName string) {
|
|
hook, err := getGhOrgWebhook(url, ghToken, orgName)
|
|
suite.NoError(err, "error getting github webhook")
|
|
suite.NotNil(hook, "github webhook with url %s, for org %s was not properly installed", url, orgName)
|
|
}
|
|
|
|
func getGhOrgWebhook(url, ghToken, orgName string) (*github.Hook, error) {
|
|
client := getGithubClient(ghToken)
|
|
ghOrgHooks, _, err := client.Organizations.ListHooks(context.Background(), orgName, nil)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
for _, hook := range ghOrgHooks {
|
|
hookURL := hook.Config.GetURL()
|
|
if hookURL == url {
|
|
return hook, nil
|
|
}
|
|
}
|
|
|
|
return nil, nil
|
|
}
|
|
|
|
func (suite *GarmSuite) UninstallOrgWebhook(id string) {
|
|
t := suite.T()
|
|
t.Logf("Uninstall org webhook with org_id %s", id)
|
|
err := uninstallOrgWebhook(suite.cli, suite.authToken, id)
|
|
suite.NoError(err, "error uninstalling organization webhook")
|
|
}
|
|
|
|
func (suite *GarmSuite) ValidateOrgWebhookUninstalled(ghToken, url, orgName string) {
|
|
hook, err := getGhOrgWebhook(url, ghToken, orgName)
|
|
suite.NoError(err, "error getting github webhook")
|
|
suite.Nil(hook, "github webhook with url %s, for org %s was not properly uninstalled", url, orgName)
|
|
}
|
|
|
|
func (suite *GarmSuite) CreateOrgPool(orgID string, poolParams params.CreatePoolParams) *params.Pool {
|
|
t := suite.T()
|
|
t.Logf("Create org pool with org_id %s", orgID)
|
|
pool, err := createOrgPool(suite.cli, suite.authToken, orgID, poolParams)
|
|
suite.NoError(err, "error creating organization pool")
|
|
return pool
|
|
}
|
|
|
|
func (suite *GarmSuite) GetOrgPool(orgID, orgPoolID string) *params.Pool {
|
|
t := suite.T()
|
|
t.Logf("Get org pool with org_id %s and pool_id %s", orgID, orgPoolID)
|
|
pool, err := getOrgPool(suite.cli, suite.authToken, orgID, orgPoolID)
|
|
suite.NoError(err, "error getting organization pool")
|
|
return pool
|
|
}
|
|
|
|
func (suite *GarmSuite) DeleteOrgPool(orgID, orgPoolID string) {
|
|
t := suite.T()
|
|
t.Logf("Delete org pool with org_id %s and pool_id %s", orgID, orgPoolID)
|
|
err := deleteOrgPool(suite.cli, suite.authToken, orgID, orgPoolID)
|
|
suite.NoError(err, "error deleting organization pool")
|
|
}
|
|
|
|
func (suite *GarmSuite) UpdateOrgPool(orgID, orgPoolID string, maxRunners, minIdleRunners uint) *params.Pool {
|
|
t := suite.T()
|
|
t.Logf("Update org pool with org_id %s and pool_id %s", orgID, orgPoolID)
|
|
poolParams := params.UpdatePoolParams{
|
|
MinIdleRunners: &minIdleRunners,
|
|
MaxRunners: &maxRunners,
|
|
}
|
|
pool, err := updateOrgPool(suite.cli, suite.authToken, orgID, orgPoolID, poolParams)
|
|
suite.NoError(err, "error updating organization pool")
|
|
return pool
|
|
}
|
|
|
|
func (suite *GarmSuite) WaitOrgRunningIdleInstances(orgID string, timeout time.Duration) {
|
|
t := suite.T()
|
|
orgPools, err := listOrgPools(suite.cli, suite.authToken, orgID)
|
|
suite.NoError(err, "error listing organization pools")
|
|
for _, pool := range orgPools {
|
|
err := suite.WaitPoolInstances(pool.ID, commonParams.InstanceRunning, params.RunnerIdle, timeout)
|
|
if err != nil {
|
|
suite.dumpOrgInstancesDetails(orgID)
|
|
t.Errorf("timeout waiting for organization %s instances to reach status: %s and runner status: %s", orgID, commonParams.InstanceRunning, params.RunnerIdle)
|
|
}
|
|
}
|
|
}
|
|
|
|
func (suite *GarmSuite) dumpOrgInstancesDetails(orgID string) {
|
|
t := suite.T()
|
|
// print org details
|
|
t.Logf("Dumping org details with org_id %s", orgID)
|
|
org, err := getOrg(suite.cli, suite.authToken, orgID)
|
|
suite.NoError(err, "error getting organization")
|
|
err = printJSONResponse(org)
|
|
suite.NoError(err, "error printing organization")
|
|
|
|
// print org instances details
|
|
t.Logf("Dumping org instances details for org %s", orgID)
|
|
instances, err := listOrgInstances(suite.cli, suite.authToken, orgID)
|
|
suite.NoError(err, "error listing organization instances")
|
|
for _, instance := range instances {
|
|
instance, err := getInstance(suite.cli, suite.authToken, instance.Name)
|
|
suite.NoError(err, "error getting instance")
|
|
t.Logf("Instance info for instace %s", instance.Name)
|
|
err = printJSONResponse(instance)
|
|
suite.NoError(err, "error printing instance")
|
|
}
|
|
}
|