Skip to content

Commit

Permalink
feat(dockertestx): Support Prism
Browse files Browse the repository at this point in the history
  • Loading branch information
rxnew committed Feb 18, 2024
1 parent d7a1c9f commit a3f7bb7
Show file tree
Hide file tree
Showing 3 changed files with 147 additions and 0 deletions.
84 changes: 84 additions & 0 deletions dockertestx/prism.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
package dockertestx

import (
"errors"
"fmt"
"io"
"net/http"
"net/url"
"os"
"path/filepath"

"github.com/ory/dockertest/v3"
)

type PrismFactory struct {
// SpecURI is a file path or URL of the OpenAPI Specification.
SpecURI string

// HealthCheckPath is the path accessed to verify that the stub server has started.
// The response status code is ignored.
// The default is to use the base path.
HealthCheckPath string
}

func (f *PrismFactory) repository() string {
return "stoplight/prism"
}

func (f *PrismFactory) create(p *Pool, opt ContainerOption) (*state, error) {
if opt.Tag == "latest" {
opt.Tag = "4"
}

rOpt := &dockertest.RunOptions{
Name: opt.Name,
Repository: f.repository(),
Tag: opt.Tag,
Env: []string{},
Cmd: []string{"mock", "-h", "0.0.0.0"},
}

if u, err := url.Parse(f.SpecURI); err == nil && (u.Scheme == "http" || u.Scheme == "https") {
rOpt.Cmd = append(rOpt.Cmd, f.SpecURI)
} else {
fp, err := filepath.Abs(f.SpecURI)
if err != nil {
return nil, fmt.Errorf("could not resolve abstract path of the definition file: %w", err)
}
if _, err := os.Stat(fp); errors.Is(err, os.ErrNotExist) {
return nil, fmt.Errorf("could not stat the definition file: %w", err)
}
rOpt.Mounts = []string{fp + ":/tmp/oas.yml:ro"}
rOpt.Cmd = append(rOpt.Cmd, "/tmp/oas.yml")
}

resource, err := p.Pool.RunWithOptions(rOpt)
if err != nil {
return nil, fmt.Errorf("could not start resource: %w", err)
}
return &state{
ContainerName: opt.Name,
Repository: f.repository(),
Tag: opt.Tag,
Env: rOpt.Env,
DSN: fmt.Sprintf("http://localhost:%s", resource.GetPort("4010/tcp")),
r: resource,
}, nil
}

func (f *PrismFactory) ready(p *Pool, s *state) error {
u, err := url.JoinPath(s.DSN, f.HealthCheckPath)
if err != nil {
return fmt.Errorf("invalid heath check path: %w", err)
}
return p.Pool.Retry(func() error {
out, err := http.Get(u)
if err != nil {
return err
}
defer out.Body.Close()
_, _ = io.ReadAll(out.Body)
return nil
})
}
35 changes: 35 additions & 0 deletions dockertestx/prism_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package dockertestx_test

import (
"net/http"
"net/url"
"testing"

"github.com/stretchr/testify/assert"

"github.com/stretchr/testify/require"

"github.com/tier4/x-go/dockertestx"
)

func TestPool_NewPrism(t *testing.T) {
t.Parallel()

p, err := dockertestx.New(dockertestx.PoolOption{})
require.NoError(t, err)
t.Cleanup(func() {
require.NoError(t, p.Purge())
})

endpoint, err := p.NewResource(&dockertestx.PrismFactory{
SpecURI: "testdata/oas.yml",
HealthCheckPath: "/health",
}, dockertestx.ContainerOption{})
require.NoError(t, err)

u, err := url.JoinPath(endpoint, "books")
require.NoError(t, err)
resp, err := http.Get(u)
require.NoError(t, err)
assert.Equal(t, http.StatusOK, resp.StatusCode)
}
28 changes: 28 additions & 0 deletions dockertestx/testdata/oas.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
openapi: 3.0.0
info:
title: test
version: 1.0.0
components:
schemas:
book:
type: object
properties:
id:
type: integer
format: int64
example: 1
paths:
/books:
get:
responses:
'200':
content:
application/json:
schema:
type: array
items:
$ref: '#/components/schemas/book'
/health:
get:
responses:
'204':

0 comments on commit a3f7bb7

Please sign in to comment.