Skip to content

Commit

Permalink
Merge pull request #91 from fabiante/feat/add-ctx-to-test-driver
Browse files Browse the repository at this point in the history
  • Loading branch information
fabiante authored Sep 24, 2023
2 parents 6da1d7f + 4fed37a commit 62b5d10
Show file tree
Hide file tree
Showing 10 changed files with 64 additions and 38 deletions.
6 changes: 6 additions & 0 deletions tests/driver/driver.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package driver

type Driver interface {
// WithAuth sets the authentication context to be used by this driver.
WithAuth()
}
7 changes: 4 additions & 3 deletions tests/driver/http.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package driver

import (
"bytes"
"context"
"encoding/json"
"fmt"
"io"
Expand Down Expand Up @@ -44,7 +45,7 @@ func (driver *HTTPDriver) newRequest(method, url string, body io.Reader) (*http.
return req, nil
}

func (driver *HTTPDriver) ResolvePURL(domain string, name string) (*url.URL, error) {
func (driver *HTTPDriver) ResolvePURL(_ context.Context, domain string, name string) (*url.URL, error) {
req, err := driver.newRequest(http.MethodGet, fmt.Sprintf("%s/r/%s/%s", driver.BasePath, domain, name), nil)
if err != nil {
return nil, err
Expand Down Expand Up @@ -72,7 +73,7 @@ func (driver *HTTPDriver) ResolvePURL(domain string, name string) (*url.URL, err
return loc, nil
}

func (driver *HTTPDriver) SavePURL(purl *dsl.PURL) (string, error) {
func (driver *HTTPDriver) SavePURL(_ context.Context, purl *dsl.PURL) (string, error) {
body := bytes.NewBuffer([]byte{})
err := json.NewEncoder(body).Encode(map[string]string{
"target": purl.Target.String(),
Expand Down Expand Up @@ -107,7 +108,7 @@ func (driver *HTTPDriver) SavePURL(purl *dsl.PURL) (string, error) {
return r.Path, nil
}

func (driver *HTTPDriver) CreateDomain(name string) error {
func (driver *HTTPDriver) CreateDomain(_ context.Context, name string) error {
req, err := driver.newRequest(http.MethodPost, fmt.Sprintf("%s/a/domains/%s", driver.BasePath, name), nil)
if err != nil {
return err
Expand Down
11 changes: 7 additions & 4 deletions tests/dsl/apis.go
Original file line number Diff line number Diff line change
@@ -1,22 +1,25 @@
package dsl

import "net/url"
import (
"context"
"net/url"
)

// AdminAPI defines admin features of the application.
type AdminAPI interface {
CreateDomain(name string) error
CreateDomain(ctx context.Context, name string) error

// SavePURL creates a new or updates an existing purl.
//
// If no error occurred the returned string is the path (without host) of the created PURL.
SavePURL(purl *PURL) (string, error)
SavePURL(ctx context.Context, purl *PURL) (string, error)
}

// ResolveAPI defines features for PURL resolution.
type ResolveAPI interface {
// ResolvePURL resolves the PURL identified by domain and name, returning
// the target of the resolved PURL.
ResolvePURL(domain string, name string) (*url.URL, error)
ResolvePURL(ctx context.Context, domain string, name string) (*url.URL, error)
}

// API aggregates all apis.
Expand Down
11 changes: 6 additions & 5 deletions tests/dsl/given.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package dsl

import (
"context"
"testing"

"github.com/fabiante/persurl/app"
Expand All @@ -11,22 +12,22 @@ import (
// GivenExistingPURL ensures that a PURL is known to the application.
//
// This is done by simply creating it.
func GivenExistingPURL(t *testing.T, service AdminAPI, purl *PURL) {
path, err := service.SavePURL(purl)
func GivenExistingPURL(ctx context.Context, t *testing.T, service AdminAPI, purl *PURL) {
path, err := service.SavePURL(ctx, purl)
require.NoError(t, err, "saving purl failed")
require.NotEmpty(t, path)
}

// GivenExistingDomain ensures that a Domain is known to the application.
//
// This currently is a no-op since domains can't explicitly be created.
func GivenExistingDomain(t *testing.T, service AdminAPI, domain string) {
err := service.CreateDomain(domain)
func GivenExistingDomain(ctx context.Context, t *testing.T, service AdminAPI, domain string) {
err := service.CreateDomain(ctx, domain)
require.NoError(t, err, "creating domain failed")
}

// GivenSomeUser creates a user and returns the key for it.
func GivenSomeUser(t *testing.T, userService *app.UserService) *models.UserKey {
func GivenSomeUser(_ context.Context, t *testing.T, userService *app.UserService) *models.UserKey {
user, err := userService.CreateUser("[email protected]")
require.NoError(t, err)

Expand Down
5 changes: 4 additions & 1 deletion tests/http_load_test.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package tests

import (
"context"
"net/http"
"net/http/httptest"
"testing"
Expand All @@ -17,6 +18,8 @@ import (
)

func TestLoadWithHTTPDriver(t *testing.T) {
ctx := context.TODO()

conf := config.Get()

if !conf.TestLoad {
Expand All @@ -35,7 +38,7 @@ func TestLoadWithHTTPDriver(t *testing.T) {
service := app.NewService(database.Gorm)
userService := app.NewUserService(database.Gorm)

key := dsl.GivenSomeUser(t, userService)
key := dsl.GivenSomeUser(ctx, t, userService)

server := api.NewServer(service, service, userService)
api.SetupRouting(handler, server)
Expand Down
4 changes: 3 additions & 1 deletion tests/http_test.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package tests

import (
"context"
"net/http"
"net/http/httptest"
"testing"
Expand All @@ -17,6 +18,7 @@ import (
)

func TestWithHTTPDriver(t *testing.T) {
ctx := context.TODO()
gin.SetMode(gin.TestMode)
handler := gin.Default()

Expand All @@ -29,7 +31,7 @@ func TestWithHTTPDriver(t *testing.T) {
service := app.NewService(database.Gorm)
userService := app.NewUserService(database.Gorm)

key := dsl.GivenSomeUser(t, userService)
key := dsl.GivenSomeUser(ctx, t, userService)

server := api.NewServer(service, service, userService)
api.SetupRouting(handler, server)
Expand Down
11 changes: 7 additions & 4 deletions tests/load/agent_create.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package load

import (
"context"
"fmt"
"net/url"
"sync"
Expand Down Expand Up @@ -31,21 +32,23 @@ func NewCreateAgent(id int, domain string, createInterval time.Duration, API dsl
//
// Run ensures that the agent's Domain exists before starting to create PURLs.
//
// The agent runs until a message is sent to the done channel. It will then decrement the given wait group.
// The agent runs until the given context is cancelled. It will then decrement the given wait group.
//
// You should use this method in a dedicated goroutine as this is a blocking function.
func (a *CreateAgent) Run(t *testing.T, done <-chan struct{}, wg *sync.WaitGroup) {
func (a *CreateAgent) Run(t *testing.T, ctx context.Context, wg *sync.WaitGroup) {
defer wg.Done()

dsl.GivenExistingDomain(t, a.API, a.Domain)
done := ctx.Done()

dsl.GivenExistingDomain(ctx, t, a.API, a.Domain)

target, _ := url.Parse("https://google.com")
i := 0

for {
name := fmt.Sprintf("purl-%d", i)

path, err := a.API.SavePURL(dsl.NewPURL(a.Domain, name, target))
path, err := a.API.SavePURL(ctx, dsl.NewPURL(a.Domain, name, target))
require.NoError(t, err)
require.NotEmpty(t, path)

Expand Down
29 changes: 17 additions & 12 deletions tests/specs/admin.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package specs

import (
"context"
"fmt"
"testing"

Expand All @@ -17,6 +18,8 @@ func TestAdministration(t *testing.T, admin dsl.AdminAPI) {
}

func testPurlAdmin(t *testing.T, admin dsl.AdminAPI) {
ctx := context.TODO()

t.Run("can't create invalid PURL", func(t *testing.T) {
invalid := []*dsl.PURL{
// empty
Expand All @@ -33,11 +36,11 @@ func testPurlAdmin(t *testing.T, admin dsl.AdminAPI) {
dsl.NewPURL("valid", "`", mustParseURL("example.com")),
}

dsl.GivenExistingDomain(t, admin, "valid")
dsl.GivenExistingDomain(ctx, t, admin, "valid")

for i, purl := range invalid {
t.Run(fmt.Sprintf("invalid[%d]", i), func(t *testing.T) {
_, err := admin.SavePURL(purl)
_, err := admin.SavePURL(ctx, purl)
require.Error(t, err)
//require.ErrorIs(t, err, app.ErrBadRequest) // TODO: Some tests cause a 404 with the http driver.
})
Expand All @@ -48,13 +51,13 @@ func testPurlAdmin(t *testing.T, admin dsl.AdminAPI) {
domain := "this-domain-does-not-exist-it-should-not"
purl := dsl.NewPURL(domain, "my-name3456334654645663456", mustParseURL("https://google.com"))

_, err := admin.SavePURL(purl)
_, err := admin.SavePURL(ctx, purl)
require.ErrorIs(t, err, app.ErrBadRequest)
})

t.Run("can create new PURL", func(t *testing.T) {
domain := "my-domain-123456"
dsl.GivenExistingDomain(t, admin, domain)
dsl.GivenExistingDomain(ctx, t, admin, domain)

validPurls := []*dsl.PURL{
dsl.NewPURL(domain, "my-name3456345663456", mustParseURL("https://google.com")),
Expand All @@ -64,7 +67,7 @@ func testPurlAdmin(t *testing.T, admin dsl.AdminAPI) {
for i, purl := range validPurls {
t.Run(fmt.Sprintf("valid[%d]", i), func(t *testing.T) {
// TODO: Assert non-existence of purl to be created
path, err := admin.SavePURL(purl)
path, err := admin.SavePURL(ctx, purl)
require.NoError(t, err, "creating purl failed")
require.NotEmpty(t, path)
})
Expand All @@ -75,20 +78,22 @@ func testPurlAdmin(t *testing.T, admin dsl.AdminAPI) {
domain := "my-domain-123456789"
purl := dsl.NewPURL(domain, "my-name3458904562454564565467", mustParseURL("https://google.com"))

dsl.GivenExistingDomain(t, admin, domain)
dsl.GivenExistingPURL(t, admin, purl)
dsl.GivenExistingDomain(ctx, t, admin, domain)
dsl.GivenExistingPURL(ctx, t, admin, purl)

// modify purl's name - updating the target would be the usual case but that is harder to assert.
purl.Name = "my-new-name-updated"

path, err := admin.SavePURL(purl)
path, err := admin.SavePURL(ctx, purl)
require.NoError(t, err, "updating existing purl failed")
require.NotEmpty(t, path)
require.Contains(t, path, "my-new-name-updated")
})
}

func testDomainAdmin(t *testing.T, admin dsl.AdminAPI) {
ctx := context.TODO()

t.Run("can't create invalid domain", func(t *testing.T) {
invalid := []string{
// empty
Expand All @@ -107,7 +112,7 @@ func testDomainAdmin(t *testing.T, admin dsl.AdminAPI) {

for i, domain := range invalid {
t.Run(fmt.Sprintf("invalid[%d]", i), func(t *testing.T) {
err := admin.CreateDomain(domain)
err := admin.CreateDomain(ctx, domain)
require.Error(t, err)
//require.ErrorIs(t, err, app.ErrBadRequest) // TODO: Some tests cause a 404 with the http driver.
})
Expand All @@ -122,16 +127,16 @@ func testDomainAdmin(t *testing.T, admin dsl.AdminAPI) {

for i, v := range valid {
t.Run(fmt.Sprintf("valid[%d]", i), func(*testing.T) {
err := admin.CreateDomain(v)
err := admin.CreateDomain(ctx, v)
require.NoError(t, err)
})
}
})

t.Run("can't create duplicate domain", func(t *testing.T) {
domain := "should-exist-once-4357824758wr47895645"
dsl.GivenExistingDomain(t, admin, domain)
err := admin.CreateDomain("should-exist-once-4357824758wr47895645")
dsl.GivenExistingDomain(ctx, t, admin, domain)
err := admin.CreateDomain(ctx, "should-exist-once-4357824758wr47895645")
require.Error(t, err)
require.ErrorIs(t, err, app.ErrBadRequest)
})
Expand Down
3 changes: 1 addition & 2 deletions tests/specs/load.go
Original file line number Diff line number Diff line change
Expand Up @@ -64,13 +64,12 @@ func TestLoad(t *testing.T, api dsl.API) {
for i, test := range tests {
t.Run(fmt.Sprintf("tests[%d] create:%d", i, test.CreateAgents), func(t *testing.T) {
ctx, cancel := context.WithCancel(context.Background())
done := ctx.Done()
wg := &sync.WaitGroup{}

for j := 0; j < test.CreateAgents; j++ {
agent := load.NewCreateAgent(j, fmt.Sprintf("agent-%d-%d", i, j), test.CreateInterval, api)
wg.Add(1)
go agent.Run(t, done, wg)
go agent.Run(t, ctx, wg)
}

time.Sleep(test.Duration)
Expand Down
15 changes: 9 additions & 6 deletions tests/specs/resolve.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package specs

import (
"context"
"testing"

"github.com/fabiante/persurl/app"
Expand All @@ -9,12 +10,14 @@ import (
)

func TestResolver(t *testing.T, resolver dsl.API) {
ctx := context.TODO()

t.Run("resolver", func(t *testing.T) {
t.Run("does not resolve non-existent domain", func(t *testing.T) {
domain := "something-very-stupid-9873214356"
name := "should-not-exist"

purl, err := resolver.ResolvePURL(domain, name)
purl, err := resolver.ResolvePURL(ctx, domain, name)
require.Error(t, err)
require.ErrorIs(t, err, app.ErrNotFound)
require.Nil(t, purl)
Expand All @@ -24,9 +27,9 @@ func TestResolver(t *testing.T, resolver dsl.API) {
domain := "something-very-stupid-34563456"
name := "should-not-exist"

dsl.GivenExistingDomain(t, resolver, domain)
dsl.GivenExistingDomain(ctx, t, resolver, domain)

purl, err := resolver.ResolvePURL(domain, name)
purl, err := resolver.ResolvePURL(ctx, domain, name)
require.Error(t, err)
require.ErrorIs(t, err, app.ErrNotFound)
require.Nil(t, purl)
Expand All @@ -36,10 +39,10 @@ func TestResolver(t *testing.T, resolver dsl.API) {
domain := "my-domain"
name := "my-name"

dsl.GivenExistingDomain(t, resolver, domain)
dsl.GivenExistingPURL(t, resolver, dsl.NewPURL(domain, name, mustParseURL("https://google.com")))
dsl.GivenExistingDomain(ctx, t, resolver, domain)
dsl.GivenExistingPURL(ctx, t, resolver, dsl.NewPURL(domain, name, mustParseURL("https://google.com")))

purl, err := resolver.ResolvePURL(domain, name)
purl, err := resolver.ResolvePURL(ctx, domain, name)
require.NoError(t, err)
require.NotNil(t, purl)
})
Expand Down

0 comments on commit 62b5d10

Please sign in to comment.