From ac29af6eff6721d51d748ab4d8a063802b5a3ff9 Mon Sep 17 00:00:00 2001 From: Gabriel Adrian Samfira Date: Fri, 15 Mar 2024 14:35:05 +0000 Subject: [PATCH] Add some unit tests Signed-off-by: Gabriel Adrian Samfira --- params/requests.go | 6 +- runner/enterprises.go | 4 - runner/organizations.go | 4 - runner/pool/util.go | 2 +- runner/pool/util_test.go | 228 +++++++++++++++++++++++++++++++++++++++ runner/repositories.go | 4 - 6 files changed, 232 insertions(+), 16 deletions(-) create mode 100644 runner/pool/util_test.go diff --git a/params/requests.go b/params/requests.go index 81108493..885ed678 100644 --- a/params/requests.go +++ b/params/requests.go @@ -55,7 +55,7 @@ func (c *CreateRepoParams) Validate() error { } switch c.PoolBalancerType { - case PoolBalancerTypeRoundRobin, PoolBalancerTypePack: + case PoolBalancerTypeRoundRobin, PoolBalancerTypePack, PoolBalancerTypeNone: default: return errors.NewBadRequestError("invalid pool balancer type") } @@ -83,7 +83,7 @@ func (c *CreateOrgParams) Validate() error { } switch c.PoolBalancerType { - case PoolBalancerTypeRoundRobin, PoolBalancerTypePack: + case PoolBalancerTypeRoundRobin, PoolBalancerTypePack, PoolBalancerTypeNone: default: return errors.NewBadRequestError("invalid pool balancer type") } @@ -109,7 +109,7 @@ func (c *CreateEnterpriseParams) Validate() error { } switch c.PoolBalancerType { - case PoolBalancerTypeRoundRobin, PoolBalancerTypePack: + case PoolBalancerTypeRoundRobin, PoolBalancerTypePack, PoolBalancerTypeNone: default: return errors.NewBadRequestError("invalid pool balancer type") } diff --git a/runner/enterprises.go b/runner/enterprises.go index 01c5a8d0..c76d3973 100644 --- a/runner/enterprises.go +++ b/runner/enterprises.go @@ -20,10 +20,6 @@ func (r *Runner) CreateEnterprise(ctx context.Context, param params.CreateEnterp return enterprise, runnerErrors.ErrUnauthorized } - if param.PoolBalancerType == "" { - param.PoolBalancerType = params.PoolBalancerTypeRoundRobin - } - err = param.Validate() if err != nil { return params.Enterprise{}, errors.Wrap(err, "validating params") diff --git a/runner/organizations.go b/runner/organizations.go index 2d837fd0..3d24dcda 100644 --- a/runner/organizations.go +++ b/runner/organizations.go @@ -34,10 +34,6 @@ func (r *Runner) CreateOrganization(ctx context.Context, param params.CreateOrgP return org, runnerErrors.ErrUnauthorized } - if param.PoolBalancerType == "" { - param.PoolBalancerType = params.PoolBalancerTypeRoundRobin - } - if err := param.Validate(); err != nil { return params.Organization{}, errors.Wrap(err, "validating params") } diff --git a/runner/pool/util.go b/runner/pool/util.go index 8769fe0b..5a3a3c8c 100644 --- a/runner/pool/util.go +++ b/runner/pool/util.go @@ -61,7 +61,7 @@ func (p *poolsForTags) Get(tags []string) (poolCacheStore, bool) { return poolCache, true } -func (p *poolsForTags) Add(tags []string, pools []params.Pool) *poolRoundRobin { +func (p *poolsForTags) Add(tags []string, pools []params.Pool) poolCacheStore { sort.Slice(pools, func(i, j int) bool { return pools[i].Priority > pools[j].Priority }) diff --git a/runner/pool/util_test.go b/runner/pool/util_test.go new file mode 100644 index 00000000..bcfea879 --- /dev/null +++ b/runner/pool/util_test.go @@ -0,0 +1,228 @@ +package pool + +import ( + "sync" + "testing" + + runnerErrors "github.com/cloudbase/garm-provider-common/errors" + "github.com/cloudbase/garm/params" +) + +func TestPoolRoundRobinRollsOver(t *testing.T) { + p := &poolRoundRobin{ + pools: []params.Pool{ + { + ID: "1", + }, + { + ID: "2", + }, + }, + } + + pool, err := p.Next() + if err != nil { + t.Fatalf("unexpected error: %s", err) + } + if pool.ID != "1" { + t.Fatalf("expected pool 1, got %s", pool.ID) + } + + pool, err = p.Next() + if err != nil { + t.Fatalf("unexpected error: %s", err) + } + if pool.ID != "2" { + t.Fatalf("expected pool 2, got %s", pool.ID) + } + + pool, err = p.Next() + if err != nil { + t.Fatalf("unexpected error: %s", err) + } + if pool.ID != "1" { + t.Fatalf("expected pool 1, got %s", pool.ID) + } +} + +func TestPoolRoundRobinEmptyPoolErrorsOut(t *testing.T) { + p := &poolRoundRobin{} + + _, err := p.Next() + if err == nil { + t.Fatalf("expected error, got nil") + } + if err != runnerErrors.ErrNoPoolsAvailable { + t.Fatalf("expected ErrNoPoolsAvailable, got %s", err) + } +} + +func TestPoolRoundRobinLen(t *testing.T) { + p := &poolRoundRobin{ + pools: []params.Pool{ + { + ID: "1", + }, + { + ID: "2", + }, + }, + } + + if p.Len() != 2 { + t.Fatalf("expected 2, got %d", p.Len()) + } +} + +func TestPoolRoundRobinReset(t *testing.T) { + p := &poolRoundRobin{ + pools: []params.Pool{ + { + ID: "1", + }, + { + ID: "2", + }, + }, + } + + p.Next() + p.Reset() + if p.next != 0 { + t.Fatalf("expected 0, got %d", p.next) + } +} + +func TestPoolsForTagsPackGet(t *testing.T) { + p := &poolsForTags{ + poolCacheType: params.PoolBalancerTypePack, + } + + pools := []params.Pool{ + { + ID: "1", + Priority: 0, + }, + { + ID: "2", + Priority: 100, + }, + } + _ = p.Add([]string{"key"}, pools) + cache, ok := p.Get([]string{"key"}) + if !ok { + t.Fatalf("expected true, got false") + } + if cache.Len() != 2 { + t.Fatalf("expected 2, got %d", cache.Len()) + } + + poolRR, ok := cache.(*poolRoundRobin) + if !ok { + t.Fatalf("expected poolRoundRobin, got %v", cache) + } + if poolRR.next != 0 { + t.Fatalf("expected 0, got %d", poolRR.next) + } + pool, err := poolRR.Next() + if err != nil { + t.Fatalf("unexpected error: %s", err) + } + if pool.ID != "2" { + t.Fatalf("expected pool 2, got %s", pool.ID) + } + + if poolRR.next != 1 { + t.Fatalf("expected 1, got %d", poolRR.next) + } + // Getting the pool cache again should reset next + cache, ok = p.Get([]string{"key"}) + if !ok { + t.Fatalf("expected true, got false") + } + poolRR, ok = cache.(*poolRoundRobin) + if !ok { + t.Fatalf("expected poolRoundRobin, got %v", cache) + } + if poolRR.next != 0 { + t.Fatalf("expected 0, got %d", poolRR.next) + } +} + +func TestPoolsForTagsRoundRobinGet(t *testing.T) { + p := &poolsForTags{ + poolCacheType: params.PoolBalancerTypeRoundRobin, + } + + pools := []params.Pool{ + { + ID: "1", + Priority: 0, + }, + { + ID: "2", + Priority: 100, + }, + } + _ = p.Add([]string{"key"}, pools) + cache, ok := p.Get([]string{"key"}) + if !ok { + t.Fatalf("expected true, got false") + } + if cache.Len() != 2 { + t.Fatalf("expected 2, got %d", cache.Len()) + } + + pool, err := cache.Next() + if err != nil { + t.Fatalf("unexpected error: %s", err) + } + if pool.ID != "2" { + t.Fatalf("expected pool 2, got %s", pool.ID) + } + // Getting the pool cache again should not reset next, and + // should return the next pool. + cache, ok = p.Get([]string{"key"}) + if !ok { + t.Fatalf("expected true, got false") + } + pool, err = cache.Next() + if err != nil { + t.Fatalf("unexpected error: %s", err) + } + if pool.ID != "1" { + t.Fatalf("expected pool 1, got %s", pool.ID) + } +} + +func TestPoolsForTagsNoPoolsForTag(t *testing.T) { + p := &poolsForTags{ + pools: sync.Map{}, + } + + _, ok := p.Get([]string{"key"}) + if ok { + t.Fatalf("expected false, got true") + } +} + +func TestPoolsForTagsBalancerTypePack(t *testing.T) { + p := &poolsForTags{ + pools: sync.Map{}, + poolCacheType: params.PoolBalancerTypePack, + } + + poolCache := &poolRoundRobin{} + p.pools.Store("key", poolCache) + + cache, ok := p.Get([]string{"key"}) + if !ok { + t.Fatalf("expected true, got false") + } + if cache != poolCache { + t.Fatalf("expected poolCache, got %v", cache) + } + if poolCache.next != 0 { + t.Fatalf("expected 0, got %d", poolCache.next) + } +} diff --git a/runner/repositories.go b/runner/repositories.go index d5b4db77..c71fab39 100644 --- a/runner/repositories.go +++ b/runner/repositories.go @@ -34,10 +34,6 @@ func (r *Runner) CreateRepository(ctx context.Context, param params.CreateRepoPa return repo, runnerErrors.ErrUnauthorized } - if param.PoolBalancerType == "" { - param.PoolBalancerType = params.PoolBalancerTypeRoundRobin - } - if err := param.Validate(); err != nil { return params.Repository{}, errors.Wrap(err, "validating params") }