Skip to content

Commit 9e76309

Browse files
committed
WIP: docs
1 parent bccdbd6 commit 9e76309

File tree

10 files changed

+203
-65
lines changed

10 files changed

+203
-65
lines changed
Lines changed: 52 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,67 @@
1-
# Mocking Services
1+
# Faking Services
22

3-
The framework aims to equip you with all the necessary tools to write end-to-end system-level tests, while still allowing the flexibility to mock third-party services that are not critical to your testing scope.
3+
The framework aims to equip you with all the necessary tools to write end-to-end system-level tests, while still allowing the flexibility to fake third-party services that are not critical to your testing scope.
44

5-
## Configuration
5+
## Local Usage without Docker (Go runtime)
66
```toml
77
[fake]
88
# port to start Gin server
99
port = 9111
1010
```
1111

12-
## Usage
13-
1412
See [full](https://github.com/smartcontractkit/chainlink-testing-framework/blob/main/framework/examples/myproject/fake_test.go) example.
1513

14+
Run it
15+
```
16+
CTF_CONFIGS=fake.toml go test -v -run TestFakes
17+
```
18+
1619
<div class="warning">
1720

18-
`host.docker.internal` is docker platform dependent!
21+
`host.docker.internal` is Docker platform dependent!
1922

2023
Use `framework.HostDockerInternal()` to reference `host.docker.internal` in your tests, so they can work in GHA CI
2124
</div>
25+
26+
## Dockerized Usage
27+
28+
Copy this example into your project, write the logic of fake, build and upload it and run.
29+
30+
## Install
31+
32+
To handle some utility command please install `Taskfile`
33+
```
34+
brew install go-task
35+
```
36+
37+
## Private Repositories (Optional)
38+
39+
If your tests are in a private repository please generate a new SSH key and add it on [GitHub](https://github.com/settings/keys). Don't forget to click `Configure SSO` in UI
40+
```
41+
task new-ssh
42+
```
43+
44+
## Usage
45+
46+
Build it and run locally when developing fakes
47+
```
48+
task build -- ${product-name}-${tag} # ex. myproduct-1.0
49+
task run
50+
```
51+
52+
Test it
53+
```
54+
curl "http://localhost:9111/static-fake"
55+
curl "http://localhost:9111/dynamic-fake"
56+
```
57+
Publish it
58+
```
59+
task publish -- $tag
60+
```
61+
62+
See full [example](https://github.com/smartcontractkit/chainlink-testing-framework/blob/main/framework/examples/myproject/fake_docker_test.go)
63+
64+
Run it
65+
```
66+
CTF_CONFIGS=fake_docker.toml go test -v -run TestDockerFakes
67+
```

framework/components/fake/container.go

Lines changed: 13 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -8,45 +8,29 @@ import (
88
"github.com/docker/go-connections/nat"
99
tc "github.com/testcontainers/testcontainers-go"
1010
tcwait "github.com/testcontainers/testcontainers-go/wait"
11-
)
12-
13-
type Input struct {
14-
Image string `toml:"image"`
15-
Port int `toml:"port" validate:"required"`
16-
Out *Output `toml:"out"`
17-
}
18-
19-
type Output struct {
20-
UseCache bool `toml:"use_cache"`
21-
BaseURLHost string `toml:"base_url_host"`
22-
BaseURLDocker string `toml:"base_url_docker"`
23-
}
2411

25-
func defaults(in *Input) {
26-
}
12+
"github.com/smartcontractkit/chainlink-testing-framework/framework"
13+
)
2714

28-
// NewFakeDataProvider creates new fake data provider
29-
func NewFakeDataProvider(in *Input) (*Output, error) {
15+
// NewDockerFakeDataProvider creates new fake data provider in Docker using testcontainers-go
16+
func NewDockerFakeDataProvider(in *Input) (*Output, error) {
3017
if in.Out != nil && in.Out.UseCache {
3118
return in.Out, nil
3219
}
3320
ctx := context.Background()
34-
defaults(in)
3521
bindPort := fmt.Sprintf("%d/tcp", in.Port)
22+
containerName := framework.DefaultTCName("fake")
3623
req := tc.ContainerRequest{
37-
Name: in.Image,
38-
Image: in.Image,
39-
//Labels: framework.DefaultTCLabels(),
40-
//Networks: []string{framework.DefaultNetworkName},
41-
//NetworkAliases: map[string][]string{
42-
// framework.DefaultNetworkName: {containerName},
43-
//},
24+
Name: containerName,
25+
Image: in.Image,
26+
Labels: framework.DefaultTCLabels(),
27+
Networks: []string{framework.DefaultNetworkName},
28+
NetworkAliases: map[string][]string{
29+
framework.DefaultNetworkName: {containerName},
30+
},
4431
ExposedPorts: []string{bindPort},
4532
HostConfigModifier: func(h *container.HostConfig) {
46-
//h.PortBindings = framework.MapTheSamePort(bindPort)
47-
},
48-
Env: map[string]string{
49-
//"DATABASE_URL": pgOut.JDInternalURL,
33+
h.PortBindings = framework.MapTheSamePort(bindPort)
5034
},
5135
WaitingFor: tcwait.ForAll(
5236
tcwait.ForListeningPort(nat.Port(fmt.Sprintf("%d/tcp", in.Port))),
@@ -64,15 +48,5 @@ func NewFakeDataProvider(in *Input) (*Output, error) {
6448
BaseURLDocker: fmt.Sprintf("%s:%d", HostDockerInternal(), in.Port),
6549
}
6650
in.Out = out
67-
//out := &Output{
68-
// UseCache: true,
69-
// ContainerName: containerName,
70-
// DBContainerName: pgOut.ContainerName,
71-
// ExternalGRPCUrl: fmt.Sprintf("%s:%s", host, in.GRPCPort),
72-
// InternalGRPCUrl: fmt.Sprintf("%s:%s", containerName, in.GRPCPort),
73-
// ExternalWSRPCUrl: fmt.Sprintf("%s:%s", host, in.WSRPCPort),
74-
// InternalWSRPCUrl: fmt.Sprintf("%s:%s", containerName, in.WSRPCPort),
75-
//}
76-
//in.Out = out
7751
return out, nil
7852
}

framework/components/fake/fake.go

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,46 @@ import (
66
"regexp"
77

88
"github.com/gin-gonic/gin"
9+
10+
"github.com/smartcontractkit/chainlink-testing-framework/framework"
11+
)
12+
13+
const (
14+
DefaultFakeServicePort = 9111
915
)
1016

17+
type Input struct {
18+
Image string `toml:"image"`
19+
Port int `toml:"port" validate:"required"`
20+
Out *Output `toml:"out"`
21+
}
22+
23+
type Output struct {
24+
UseCache bool `toml:"use_cache"`
25+
BaseURLHost string `toml:"base_url_host"`
26+
BaseURLDocker string `toml:"base_url_docker"`
27+
}
28+
1129
var (
1230
Service *gin.Engine
1331
validMethod = regexp.MustCompile("GET|POST|PATCH|PUT|DELETE")
1432
)
1533

34+
// NewFakeDataProvider creates new fake data provider
35+
func NewFakeDataProvider(in *Input) (*Output, error) {
36+
Service = gin.Default()
37+
Service.Use(recordMiddleware())
38+
go func() {
39+
_ = Service.Run(fmt.Sprintf(":%d", in.Port))
40+
}()
41+
out := &Output{
42+
BaseURLHost: fmt.Sprintf("http://localhost:%d", in.Port),
43+
BaseURLDocker: fmt.Sprintf("%s:%d", framework.HostDockerInternal(), in.Port),
44+
}
45+
in.Out = out
46+
return out, nil
47+
}
48+
1649
// validate validates method and path, does not allow to override mock
1750
func validate(method, path string) error {
1851
if Service == nil {

framework/components/fake/go.mod

Lines changed: 36 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -2,51 +2,69 @@ module github.com/smartcontractkit/chainlink-testing-framework/framework/compone
22

33
go 1.24.4
44

5+
replace github.com/smartcontractkit/chainlink-testing-framework/framework => ../../../framework
6+
57
require (
68
github.com/docker/docker v28.3.1+incompatible
79
github.com/docker/go-connections v0.5.0
810
github.com/gin-gonic/gin v1.10.1
911
github.com/go-resty/resty/v2 v2.16.5
12+
github.com/smartcontractkit/chainlink-testing-framework/framework v0.0.0-00010101000000-000000000000
1013
github.com/stretchr/testify v1.10.0
1114
github.com/testcontainers/testcontainers-go v0.37.0
1215
)
1316

1417
require (
1518
dario.cat/mergo v1.0.1 // indirect
16-
github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 // indirect
19+
github.com/Azure/go-ansiterm v0.0.0-20250102033503-faa5f7b0171c // indirect
1720
github.com/Microsoft/go-winio v0.6.2 // indirect
18-
github.com/bytedance/sonic v1.11.6 // indirect
19-
github.com/bytedance/sonic/loader v0.1.1 // indirect
20-
github.com/cenkalti/backoff/v4 v4.2.1 // indirect
21+
github.com/aws/aws-sdk-go-v2 v1.31.0 // indirect
22+
github.com/aws/aws-sdk-go-v2/config v1.27.39 // indirect
23+
github.com/aws/aws-sdk-go-v2/credentials v1.17.37 // indirect
24+
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.14 // indirect
25+
github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.18 // indirect
26+
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.18 // indirect
27+
github.com/aws/aws-sdk-go-v2/internal/ini v1.8.1 // indirect
28+
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.11.5 // indirect
29+
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.11.20 // indirect
30+
github.com/aws/aws-sdk-go-v2/service/secretsmanager v1.33.3 // indirect
31+
github.com/aws/aws-sdk-go-v2/service/sso v1.23.3 // indirect
32+
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.27.3 // indirect
33+
github.com/aws/aws-sdk-go-v2/service/sts v1.31.3 // indirect
34+
github.com/aws/smithy-go v1.21.0 // indirect
35+
github.com/bytedance/sonic v1.12.3 // indirect
36+
github.com/bytedance/sonic/loader v0.2.0 // indirect
37+
github.com/cenkalti/backoff/v4 v4.3.0 // indirect
2138
github.com/cloudwego/base64x v0.1.4 // indirect
2239
github.com/cloudwego/iasm v0.2.0 // indirect
2340
github.com/containerd/errdefs v1.0.0 // indirect
2441
github.com/containerd/errdefs/pkg v0.3.0 // indirect
2542
github.com/containerd/log v0.1.0 // indirect
26-
github.com/containerd/platforms v0.2.1 // indirect
43+
github.com/containerd/platforms v1.0.0-rc.1 // indirect
2744
github.com/cpuguy83/dockercfg v0.3.2 // indirect
28-
github.com/davecgh/go-spew v1.1.1 // indirect
45+
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
2946
github.com/distribution/reference v0.6.0 // indirect
3047
github.com/docker/go-units v0.5.0 // indirect
3148
github.com/ebitengine/purego v0.8.2 // indirect
3249
github.com/felixge/httpsnoop v1.0.4 // indirect
33-
github.com/gabriel-vasile/mimetype v1.4.3 // indirect
50+
github.com/gabriel-vasile/mimetype v1.4.6 // indirect
3451
github.com/gin-contrib/sse v0.1.0 // indirect
3552
github.com/go-logr/logr v1.4.3 // indirect
3653
github.com/go-logr/stdr v1.2.2 // indirect
37-
github.com/go-ole/go-ole v1.2.6 // indirect
54+
github.com/go-ole/go-ole v1.3.0 // indirect
3855
github.com/go-playground/locales v0.14.1 // indirect
3956
github.com/go-playground/universal-translator v0.18.1 // indirect
40-
github.com/go-playground/validator/v10 v10.20.0 // indirect
41-
github.com/goccy/go-json v0.10.2 // indirect
57+
github.com/go-playground/validator/v10 v10.22.1 // indirect
58+
github.com/goccy/go-json v0.10.3 // indirect
4259
github.com/gogo/protobuf v1.3.2 // indirect
4360
github.com/google/uuid v1.6.0 // indirect
4461
github.com/json-iterator/go v1.1.12 // indirect
4562
github.com/klauspost/compress v1.18.0 // indirect
46-
github.com/klauspost/cpuid/v2 v2.2.7 // indirect
63+
github.com/klauspost/cpuid/v2 v2.2.8 // indirect
4764
github.com/leodido/go-urn v1.4.0 // indirect
4865
github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 // indirect
4966
github.com/magiconair/properties v1.8.10 // indirect
67+
github.com/mattn/go-colorable v0.1.13 // indirect
5068
github.com/mattn/go-isatty v0.0.20 // indirect
5169
github.com/moby/docker-image-spec v1.3.1 // indirect
5270
github.com/moby/go-archive v0.1.0 // indirect
@@ -55,16 +73,17 @@ require (
5573
github.com/moby/sys/sequential v0.6.0 // indirect
5674
github.com/moby/sys/user v0.4.0 // indirect
5775
github.com/moby/sys/userns v0.1.0 // indirect
58-
github.com/moby/term v0.5.0 // indirect
76+
github.com/moby/term v0.5.2 // indirect
5977
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
6078
github.com/modern-go/reflect2 v1.0.2 // indirect
6179
github.com/morikuni/aec v1.0.0 // indirect
6280
github.com/opencontainers/go-digest v1.0.0 // indirect
6381
github.com/opencontainers/image-spec v1.1.1 // indirect
64-
github.com/pelletier/go-toml/v2 v2.2.2 // indirect
82+
github.com/pelletier/go-toml/v2 v2.2.3 // indirect
6583
github.com/pkg/errors v0.9.1 // indirect
66-
github.com/pmezard/go-difflib v1.0.0 // indirect
84+
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
6785
github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c // indirect
86+
github.com/rs/zerolog v1.33.0 // indirect
6887
github.com/shirou/gopsutil/v4 v4.25.1 // indirect
6988
github.com/sirupsen/logrus v1.9.3 // indirect
7089
github.com/tklauser/go-sysconf v0.3.12 // indirect
@@ -73,16 +92,17 @@ require (
7392
github.com/ugorji/go/codec v1.2.12 // indirect
7493
github.com/yusufpapurcu/wmi v1.2.4 // indirect
7594
go.opentelemetry.io/auto/sdk v1.1.0 // indirect
76-
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.49.0 // indirect
95+
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.56.0 // indirect
7796
go.opentelemetry.io/otel v1.37.0 // indirect
7897
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.37.0 // indirect
7998
go.opentelemetry.io/otel/metric v1.37.0 // indirect
8099
go.opentelemetry.io/otel/sdk v1.37.0 // indirect
81100
go.opentelemetry.io/otel/trace v1.37.0 // indirect
82101
go.opentelemetry.io/proto/otlp v1.7.0 // indirect
83-
golang.org/x/arch v0.8.0 // indirect
102+
golang.org/x/arch v0.11.0 // indirect
84103
golang.org/x/crypto v0.38.0 // indirect
85104
golang.org/x/net v0.40.0 // indirect
105+
golang.org/x/sync v0.14.0 // indirect
86106
golang.org/x/sys v0.33.0 // indirect
87107
golang.org/x/text v0.25.0 // indirect
88108
google.golang.org/genproto/googleapis/rpc v0.0.0-20250603155806-513f23925822 // indirect
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
2+
[blockchain_a]
3+
type = "anvil"
4+
5+
[fake]
6+
image = "test-fakes:myproduct-1.0"
7+
port = 9111
8+
9+
[[nodesets]]
10+
name = "don"
11+
nodes = 5
12+
override_mode = "all"
13+
14+
[nodesets.db]
15+
image = "postgres:12.0"
16+
17+
[[nodesets.node_specs]]
18+
19+
[nodesets.node_specs.node]
20+
image = "public.ecr.aws/chainlink/chainlink:v2.17.0"
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
package examples
2+
3+
import (
4+
"fmt"
5+
"testing"
6+
7+
"github.com/go-resty/resty/v2"
8+
"github.com/stretchr/testify/require"
9+
10+
"github.com/smartcontractkit/chainlink-testing-framework/framework"
11+
"github.com/smartcontractkit/chainlink-testing-framework/framework/components/blockchain"
12+
"github.com/smartcontractkit/chainlink-testing-framework/framework/components/fake"
13+
ns "github.com/smartcontractkit/chainlink-testing-framework/framework/components/simple_node_set"
14+
components "github.com/smartcontractkit/chainlink-testing-framework/framework/examples/example_components"
15+
)
16+
17+
type CfgDockerFake struct {
18+
BlockchainA *blockchain.Input `toml:"blockchain_a" validate:"required"`
19+
Fake *fake.Input `toml:"fake" validate:"required"`
20+
NodeSets []*ns.Input `toml:"nodesets" validate:"required"`
21+
}
22+
23+
func TestDockerFakes(t *testing.T) {
24+
in, err := framework.Load[CfgDockerFake](t)
25+
require.NoError(t, err)
26+
27+
bc, err := blockchain.NewBlockchainNetwork(in.BlockchainA)
28+
require.NoError(t, err)
29+
fakeOut, err := fake.NewDockerFakeDataProvider(in.Fake)
30+
require.NoError(t, err)
31+
_, err = ns.NewSharedDBNodeSet(in.NodeSets[0], bc)
32+
require.NoError(t, err)
33+
34+
t.Run("test fake on host machine", func(t *testing.T) {
35+
myFakeAPI := "/static-fake"
36+
resp, err := resty.New().SetBaseURL(fakeOut.BaseURLHost).R().Get(myFakeAPI)
37+
require.NoError(t, err)
38+
require.Equal(t, 200, resp.StatusCode())
39+
})
40+
41+
t.Run("test fake inside Docker network", func(t *testing.T) {
42+
myFakeAPI := "/static-fake"
43+
err := components.NewDockerFakeTester(fmt.Sprintf("%s%s", fakeOut.BaseURLDocker, myFakeAPI))
44+
require.NoError(t, err)
45+
})
46+
}

framework/examples/myproject/fake_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ func TestFakes(t *testing.T) {
7272
_ = fmt.Sprintf("%s%s", fakeOut.BaseURLDocker, myFakeAPI)
7373
})
7474

75-
t.Run("verify that containers can access internally both locally and in CI", func(t *testing.T) {
75+
t.Run("test fake inside Docker network", func(t *testing.T) {
7676
myFakeAPI := "/fake/api/internal"
7777
// use fake.Func if you need full control over response
7878
err = fake.JSON(

0 commit comments

Comments
 (0)