2023-04-24 20:52:12 +02:00
|
|
|
package testsuite
|
|
|
|
|
|
|
|
import (
|
|
|
|
"context"
|
|
|
|
"reflect"
|
2024-06-27 17:03:50 +02:00
|
|
|
"sync"
|
2023-04-24 20:52:12 +02:00
|
|
|
"testing"
|
|
|
|
|
|
|
|
"forge.cadoles.com/cadoles/bouncer/internal/store"
|
|
|
|
"github.com/pkg/errors"
|
|
|
|
)
|
|
|
|
|
|
|
|
type proxyRepositoryTestCase struct {
|
|
|
|
Name string
|
|
|
|
Do func(repo store.ProxyRepository) error
|
|
|
|
}
|
|
|
|
|
|
|
|
var proxyRepositoryTestCases = []proxyRepositoryTestCase{
|
|
|
|
{
|
|
|
|
Name: "Create proxy",
|
|
|
|
Do: func(repo store.ProxyRepository) error {
|
|
|
|
ctx := context.Background()
|
|
|
|
|
|
|
|
to := "http://example.com"
|
|
|
|
|
|
|
|
proxy, err := repo.CreateProxy(ctx, "create_proxy", to, "*:*")
|
|
|
|
if err != nil {
|
|
|
|
return errors.WithStack(err)
|
|
|
|
}
|
|
|
|
|
|
|
|
if proxy == nil {
|
|
|
|
return errors.Errorf("proxy should not be nil")
|
|
|
|
}
|
|
|
|
|
|
|
|
if proxy.Name == "" {
|
|
|
|
return errors.Errorf("proxy.Name should not be empty")
|
|
|
|
}
|
|
|
|
|
|
|
|
if proxy.To == "" {
|
|
|
|
return errors.Errorf("proxy.To should not be empty")
|
|
|
|
}
|
|
|
|
|
|
|
|
if e, g := to, proxy.To; e != g {
|
|
|
|
return errors.Errorf("proxy.To: expected '%v', got '%v'", to, proxy.To)
|
|
|
|
}
|
|
|
|
|
|
|
|
if proxy.CreatedAt.IsZero() {
|
|
|
|
return errors.Errorf("proxy.CreatedAt should not be zero value")
|
|
|
|
}
|
|
|
|
|
|
|
|
if proxy.UpdatedAt.IsZero() {
|
|
|
|
return errors.Errorf("proxy.UpdatedAt should not be zero value")
|
|
|
|
}
|
|
|
|
|
2024-06-27 17:03:50 +02:00
|
|
|
if proxy.Revision != 0 {
|
|
|
|
return errors.Errorf("proxy.Revision should be zero")
|
|
|
|
}
|
|
|
|
|
2023-04-24 20:52:12 +02:00
|
|
|
return nil
|
|
|
|
},
|
|
|
|
},
|
|
|
|
{
|
|
|
|
Name: "Create then get proxy",
|
|
|
|
Do: func(repo store.ProxyRepository) error {
|
|
|
|
ctx := context.Background()
|
|
|
|
|
|
|
|
to := "http://example.com"
|
|
|
|
|
|
|
|
createdProxy, err := repo.CreateProxy(ctx, "create_then_get_proxy", to, "127.0.0.1:*", "localhost:*")
|
|
|
|
if err != nil {
|
|
|
|
return errors.WithStack(err)
|
|
|
|
}
|
|
|
|
|
|
|
|
foundProxy, err := repo.GetProxy(ctx, createdProxy.Name)
|
|
|
|
if err != nil {
|
|
|
|
return errors.WithStack(err)
|
|
|
|
}
|
|
|
|
|
|
|
|
if e, g := createdProxy.Name, foundProxy.Name; e != g {
|
|
|
|
return errors.Errorf("foundProxy.Name: expected '%v', got '%v'", createdProxy.Name, foundProxy.Name)
|
|
|
|
}
|
|
|
|
|
|
|
|
if e, g := createdProxy.From, foundProxy.From; !reflect.DeepEqual(e, g) {
|
|
|
|
return errors.Errorf("foundProxy.From: expected '%v', got '%v'", createdProxy.From, foundProxy.From)
|
|
|
|
}
|
|
|
|
|
|
|
|
if e, g := createdProxy.To, foundProxy.To; e != g {
|
|
|
|
return errors.Errorf("foundProxy.To: expected '%v', got '%v'", createdProxy.To, foundProxy.To)
|
|
|
|
}
|
|
|
|
|
2023-07-07 20:22:31 +02:00
|
|
|
if e, g := createdProxy.Enabled, foundProxy.Enabled; e != g {
|
|
|
|
return errors.Errorf("foundProxy.Enabled: expected '%v', got '%v'", createdProxy.Enabled, foundProxy.Enabled)
|
|
|
|
}
|
|
|
|
|
|
|
|
if e, g := createdProxy.Weight, foundProxy.Weight; e != g {
|
|
|
|
return errors.Errorf("foundProxy.Weight: expected '%v', got '%v'", createdProxy.Weight, foundProxy.Weight)
|
|
|
|
}
|
|
|
|
|
2023-04-24 20:52:12 +02:00
|
|
|
if e, g := createdProxy.CreatedAt, foundProxy.CreatedAt; e != g {
|
|
|
|
return errors.Errorf("foundProxy.CreatedAt: expected '%v', got '%v'", createdProxy.CreatedAt, foundProxy.CreatedAt)
|
|
|
|
}
|
|
|
|
|
|
|
|
if e, g := createdProxy.UpdatedAt, foundProxy.UpdatedAt; e != g {
|
|
|
|
return errors.Errorf("foundProxy.UpdatedAt: expected '%v', got '%v'", createdProxy.UpdatedAt, foundProxy.UpdatedAt)
|
|
|
|
}
|
|
|
|
|
2024-06-27 17:03:50 +02:00
|
|
|
if foundProxy.Revision != 0 {
|
|
|
|
return errors.Errorf("foundProxy.Revision should be zero")
|
|
|
|
}
|
|
|
|
|
2023-04-24 20:52:12 +02:00
|
|
|
return nil
|
|
|
|
},
|
|
|
|
},
|
|
|
|
{
|
|
|
|
Name: "Create then delete proxy",
|
|
|
|
Do: func(repo store.ProxyRepository) error {
|
|
|
|
ctx := context.Background()
|
|
|
|
|
|
|
|
to := "http://example.com"
|
|
|
|
|
|
|
|
createdProxy, err := repo.CreateProxy(ctx, "create_then_delete_proxy", to, "127.0.0.1:*", "localhost:*")
|
|
|
|
if err != nil {
|
|
|
|
return errors.WithStack(err)
|
|
|
|
}
|
|
|
|
|
|
|
|
if err := repo.DeleteProxy(ctx, createdProxy.Name); err != nil {
|
|
|
|
return errors.WithStack(err)
|
|
|
|
}
|
|
|
|
|
|
|
|
foundProxy, err := repo.GetProxy(ctx, createdProxy.Name)
|
|
|
|
if err == nil {
|
|
|
|
return errors.New("err should not be nil")
|
|
|
|
}
|
|
|
|
|
|
|
|
if !errors.Is(err, store.ErrNotFound) {
|
|
|
|
return errors.Errorf("err should be store.ErrNotFound, got '%+v'", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
if foundProxy != nil {
|
|
|
|
return errors.Errorf("foundProxy should be nil, got '%v'", foundProxy)
|
|
|
|
}
|
|
|
|
|
|
|
|
return nil
|
|
|
|
},
|
|
|
|
},
|
|
|
|
{
|
2023-07-07 20:22:31 +02:00
|
|
|
Name: "Create then query layer",
|
2023-04-24 20:52:12 +02:00
|
|
|
Do: func(repo store.ProxyRepository) error {
|
|
|
|
ctx := context.Background()
|
|
|
|
|
|
|
|
to := "http://example.com"
|
|
|
|
|
|
|
|
createdProxy, err := repo.CreateProxy(ctx, "create_then_query", to, "127.0.0.1:*", "localhost:*")
|
|
|
|
if err != nil {
|
|
|
|
return errors.WithStack(err)
|
|
|
|
}
|
|
|
|
|
|
|
|
headers, err := repo.QueryProxy(ctx)
|
|
|
|
if err != nil {
|
|
|
|
return errors.WithStack(err)
|
|
|
|
}
|
|
|
|
|
|
|
|
if len(headers) < 1 {
|
|
|
|
return errors.Errorf("len(headers): expected value > 1, got '%v'", len(headers))
|
|
|
|
}
|
|
|
|
|
|
|
|
found := false
|
|
|
|
|
|
|
|
for _, h := range headers {
|
|
|
|
if h.Name == createdProxy.Name {
|
|
|
|
found = true
|
|
|
|
break
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if !found {
|
|
|
|
return errors.New("could not find created proxy in query results")
|
|
|
|
}
|
|
|
|
|
|
|
|
return nil
|
|
|
|
},
|
|
|
|
},
|
|
|
|
{
|
|
|
|
Name: "Create already existing proxy",
|
|
|
|
Do: func(repo store.ProxyRepository) error {
|
|
|
|
ctx := context.Background()
|
|
|
|
|
|
|
|
to := "http://example.com"
|
|
|
|
|
|
|
|
var name store.ProxyName = "create_already_existing_proxy"
|
|
|
|
|
|
|
|
_, err := repo.CreateProxy(ctx, name, to, "127.0.0.1:*", "localhost:*")
|
|
|
|
if err != nil {
|
|
|
|
return errors.WithStack(err)
|
|
|
|
}
|
|
|
|
|
|
|
|
_, err = repo.CreateProxy(ctx, name, to, "127.0.0.1:*")
|
|
|
|
if err == nil {
|
|
|
|
return errors.New("err should not be nil")
|
|
|
|
}
|
|
|
|
|
|
|
|
if !errors.Is(err, store.ErrAlreadyExist) {
|
|
|
|
return errors.Errorf("err: expected store.ErrAlreadyExists, got '%+v'", err)
|
|
|
|
}
|
|
|
|
|
2024-06-27 17:03:50 +02:00
|
|
|
return nil
|
|
|
|
},
|
|
|
|
},
|
|
|
|
{
|
|
|
|
Name: "Create then update proxy",
|
|
|
|
Do: func(repo store.ProxyRepository) error {
|
|
|
|
ctx := context.Background()
|
|
|
|
|
|
|
|
to := "http://example.com"
|
|
|
|
|
|
|
|
var name store.ProxyName = "create_then_update_proxy"
|
|
|
|
|
|
|
|
createdProxy, err := repo.CreateProxy(ctx, name, to, "127.0.0.1:*", "localhost:*")
|
|
|
|
if err != nil {
|
|
|
|
return errors.Wrap(err, "err should be nil")
|
|
|
|
}
|
|
|
|
|
|
|
|
if createdProxy.Revision != 0 {
|
|
|
|
return errors.Errorf("createdProxy.Revision should be zero")
|
|
|
|
}
|
|
|
|
|
|
|
|
updatedProxy, err := repo.UpdateProxy(ctx, name)
|
|
|
|
if err != nil {
|
|
|
|
return errors.Wrap(err, "err should be nil")
|
|
|
|
}
|
|
|
|
|
|
|
|
if e, g := 1, updatedProxy.Revision; e != g {
|
|
|
|
return errors.Errorf("updatedProxy.Revision: expected '%v', got '%v'", e, g)
|
|
|
|
}
|
|
|
|
|
|
|
|
return nil
|
|
|
|
},
|
|
|
|
},
|
|
|
|
{
|
|
|
|
Name: "Update proxy concurrently",
|
|
|
|
Do: func(repo store.ProxyRepository) error {
|
|
|
|
ctx := context.Background()
|
|
|
|
|
|
|
|
to := "http://example.com"
|
|
|
|
|
|
|
|
var name store.ProxyName = "update_proxy_concurrently"
|
|
|
|
|
|
|
|
createdProxy, err := repo.CreateProxy(ctx, name, to, "127.0.0.1:*", "localhost:*")
|
|
|
|
if err != nil {
|
|
|
|
return errors.Wrap(err, "err should be nil")
|
|
|
|
}
|
|
|
|
|
|
|
|
if createdProxy.Revision != 0 {
|
|
|
|
return errors.Errorf("createdProxy.Revision should be zero")
|
|
|
|
}
|
|
|
|
|
|
|
|
var wg sync.WaitGroup
|
|
|
|
|
|
|
|
total := 100
|
|
|
|
|
|
|
|
wg.Add(total)
|
|
|
|
|
|
|
|
for i := 0; i < total; i++ {
|
|
|
|
go func(i int) {
|
|
|
|
defer wg.Done()
|
|
|
|
|
|
|
|
if _, err := repo.UpdateProxy(ctx, name); err != nil {
|
|
|
|
panic(errors.Wrap(err, "err should be nil"))
|
|
|
|
}
|
|
|
|
}(i)
|
|
|
|
}
|
|
|
|
|
|
|
|
wg.Wait()
|
|
|
|
|
|
|
|
proxy, err := repo.GetProxy(ctx, name)
|
|
|
|
if err != nil {
|
|
|
|
return errors.Wrap(err, "err should be nil")
|
|
|
|
}
|
|
|
|
|
|
|
|
if e, g := total, proxy.Revision; e != g {
|
|
|
|
return errors.Errorf("proxy.Revision: expected '%v', got '%v'", e, g)
|
|
|
|
}
|
|
|
|
|
2023-04-24 20:52:12 +02:00
|
|
|
return nil
|
|
|
|
},
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestProxyRepository(t *testing.T, repo store.ProxyRepository) {
|
|
|
|
for _, tc := range proxyRepositoryTestCases {
|
|
|
|
func(tc proxyRepositoryTestCase) {
|
|
|
|
t.Run(tc.Name, func(t *testing.T) {
|
|
|
|
if err := tc.Do(repo); err != nil {
|
|
|
|
t.Fatalf("%+v", errors.WithStack(err))
|
|
|
|
}
|
|
|
|
})
|
|
|
|
}(tc)
|
|
|
|
}
|
|
|
|
}
|