1
0
Fork 0

Adding upstream version 3.10.8.

Signed-off-by: Daniel Baumann <daniel@debian.org>
This commit is contained in:
Daniel Baumann 2025-05-18 09:37:23 +02:00
parent 37e9b6d587
commit 03bfe4079e
Signed by: daniel
GPG key ID: FBB4F0E80A80222F
356 changed files with 28857 additions and 0 deletions

View file

@ -0,0 +1,201 @@
// Copyright Earl Warren <contact@earl-warren.org>
// Copyright Loïc Dachary <loic@dachary.org>
// Copyright twenty-panda <twenty-panda@posteo.com>
// SPDX-License-Identifier: MIT
package hoverfly
import (
"fmt"
"io"
"os"
"os/exec"
"path"
"testing"
"github.com/stretchr/testify/require"
)
type M interface {
Run() (code int)
}
type Hoverfly interface {
Run(m M)
GetOutput() io.Writer
SetOutput(io.Writer)
GetURL() string
}
const (
modeCapture = "capture"
modeSimulate = "simulate"
)
var (
exit = os.Exit
getwd = os.Getwd
)
func Run(t testing.TB, name string) func() {
t.Helper()
if !hoverflySingleton.active {
return func() {}
}
httpProxyRestore := func() {}
if val, ok := os.LookupEnv("http_proxy"); ok {
httpProxyRestore = func() {
os.Setenv("http_proxy", val)
}
}
os.Setenv("http_proxy", hoverflySingleton.GetURL())
if *hoverflySingleton.mode == modeSimulate {
require.NoError(t, hoverflySingleton.loadSimulation(name))
require.NoError(t, hoverflySingleton.hoverctl("mode", "simulate", "--matching-strategy", "first"))
return func() { httpProxyRestore() }
}
if *hoverflySingleton.mode == modeCapture {
require.NoError(t, hoverflySingleton.hoverctl("mode", "capture", "--stateful"))
return func() {
httpProxyRestore()
require.NoError(t, hoverflySingleton.saveSimulation(name))
}
}
panic(fmt.Errorf("unknown mode %s", *hoverflySingleton.mode))
}
func MainTest(m *testing.M) {
hoverflySingleton.Run(m)
}
type hoverfly struct {
home string
httpProxy *string
output io.Writer
mode *string
active bool
}
var hoverflySingleton = &hoverfly{}
func GetSingleton() Hoverfly {
return hoverflySingleton
}
func newHoverfly() Hoverfly {
return &hoverfly{}
}
func (o *hoverfly) hoverctl(args ...string) error {
hoverctl := "hoverctl"
cmd := exec.Command(hoverctl, args...)
cmd.Env = append(
cmd.Env,
"HOME="+o.home,
)
if output := o.GetOutput(); output != nil {
cmd.Stdout = output
cmd.Stderr = output
fmt.Fprintf(output, "%v: %s %v\n", cmd.Env, hoverctl, args)
}
if err := cmd.Run(); err != nil {
return fmt.Errorf(hoverctl+"start: %w\n", err)
}
return nil
}
func (o *hoverfly) getSimulationDir() (string, error) {
pwd, err := getwd()
if err != nil {
return "", err
}
p := path.Join(pwd, "hoverfly")
if err := os.MkdirAll(p, 0o755); err != nil {
return p, err
}
return p, nil
}
func (o *hoverfly) getSimulationPath(name string) (string, error) {
dir, err := o.getSimulationDir()
if err != nil {
return "", err
}
return path.Join(dir, name+".json"), nil
}
func (o *hoverfly) loadSimulation(name string) error {
simulation, err := o.getSimulationPath(name)
if err != nil {
return err
}
return o.hoverctl("import", simulation)
}
func (o *hoverfly) saveSimulation(name string) error {
simulation, err := o.getSimulationPath(name)
if err != nil {
return err
}
return o.hoverctl("export", simulation)
}
func (o *hoverfly) setup() error {
if val, ok := os.LookupEnv("HOVERFLY"); ok {
o.active = true
o.mode = &val
} else {
return nil
}
home, err := os.MkdirTemp(os.TempDir(), "hoverfly")
if err != nil {
return fmt.Errorf("TempDir: %w", err)
}
o.home = home
return o.hoverctl("start")
}
func (o *hoverfly) teardown() error {
if !o.active {
return nil
}
if err := o.hoverctl("logs"); err != nil {
return err
}
if err := o.hoverctl("stop"); err != nil {
return err
}
if o.home != "" {
return os.RemoveAll(o.home)
}
return nil
}
func (o *hoverfly) SetOutput(output io.Writer) {
o.output = output
}
func (o *hoverfly) GetOutput() io.Writer {
return o.output
}
func (o *hoverfly) GetURL() string {
return "http://localhost:8500"
}
func (o *hoverfly) Run(m M) {
_ = o.setup()
exitCode := m.Run()
_ = o.teardown()
exit(exitCode)
}

View file

@ -0,0 +1,139 @@
// Copyright Earl Warren <contact@earl-warren.org>
// Copyright Loïc Dachary <loic@dachary.org>
// Copyright twenty-panda <twenty-panda@posteo.com>
// SPDX-License-Identifier: MIT
package hoverfly
import (
"bytes"
"fmt"
"io"
"net/http"
"net/http/httptest"
"net/url"
"os"
"testing"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
type testNothing struct{}
func (o testNothing) Run() (code int) {
return 456
}
type testSomething struct {
t *testing.T
}
func (o *testSomething) Run() (code int) {
return 123
}
type testSimulate struct {
t *testing.T
}
func (o testSimulate) Run() (code int) {
return 789
}
func verifyRequest(t *testing.T, serverURL, payload string) {
t.Helper()
proxyString, ok := os.LookupEnv("http_proxy")
require.True(t, ok)
proxyURL, err := url.Parse(proxyString)
require.NoError(t, err)
client := http.Client{}
client.Transport = &http.Transport{
Proxy: func(req *http.Request) (*url.URL, error) {
return http.ProxyURL(proxyURL)(req)
},
}
res, err := client.Get(serverURL)
require.NoError(t, err)
answer, err := io.ReadAll(res.Body)
res.Body.Close()
require.NoError(t, err)
assert.Equal(t, payload, string(answer))
}
func runServer(t *testing.T, payload string) (string, func()) {
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
fmt.Fprint(w, payload)
}))
require.NotNil(t, ts)
return ts.URL, ts.Close
}
func TestHoverfly(t *testing.T) {
hoverfly := newHoverfly()
var exitCode int
exit = func(code int) {
exitCode = code
}
saveDir := t.TempDir()
getwd = func() (string, error) {
return saveDir, nil
}
hoverfly.SetOutput(os.Stderr)
// do not run hoverfly
os.Unsetenv("HOVERFLY")
hoverfly.Run(testNothing{})
assert.Equal(t, 456, exitCode)
// run hoverfly and set the proxy
os.Setenv("HOVERFLY", modeCapture)
something := testSomething{t: t}
hoverfly.Run(&something)
assert.Equal(t, 123, exitCode)
testname := "thetest"
greeting := "Hello world"
serverURL, shutdownServer := runServer(t, greeting)
t.Run("capture requests and save them", func(t *testing.T) {
os.Setenv("HOVERFLY", modeCapture)
output := bytes.NewBuffer([]byte{})
hoverflySingleton.SetOutput(output)
require.NoError(t, hoverflySingleton.setup())
cleanup := Run(t, testname)
assert.Contains(t, output.String(), "capture mode")
verifyRequest(t, serverURL, greeting)
cleanup()
simulationPath, err := hoverflySingleton.getSimulationPath(testname)
require.NoError(t, err)
simulation, err := os.ReadFile(simulationPath)
require.NoError(t, err)
assert.Contains(t, string(simulation), greeting)
require.NoError(t, hoverflySingleton.teardown())
})
shutdownServer()
t.Run("read saved request and simulate them", func(t *testing.T) {
os.Setenv("HOVERFLY", modeSimulate)
output := bytes.NewBuffer([]byte{})
hoverflySingleton.SetOutput(output)
require.NoError(t, hoverflySingleton.setup())
cleanup := Run(t, testname)
assert.Contains(t, output.String(), "simulate mode")
verifyRequest(t, serverURL, greeting)
cleanup()
require.NoError(t, hoverflySingleton.teardown())
})
}

View file

@ -0,0 +1,23 @@
// Copyright Earl Warren <contact@earl-warren.org>
// Copyright Loïc Dachary <loic@dachary.org>
// Copyright twenty-panda <twenty-panda@posteo.com>
// SPDX-License-Identifier: MIT
package hoverfly
import (
"os"
"testing"
)
func TestMain(m *testing.M) {
if val, ok := os.LookupEnv("HOVERFLY"); ok {
defer func() {
os.Setenv("HOVERFLY", val)
}()
}
code := m.Run()
exit = os.Exit
getwd = os.Getwd
exit(code)
}