Skip to content

Commit 08ec73e

Browse files
committed
more docs
1 parent b3e84a8 commit 08ec73e

18 files changed

+542
-178
lines changed

book/src/SUMMARY.md

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,17 @@
22

33
- [Overview](./overview.md)
44
- [Framework](./framework/overview.md)
5-
- [Overview](./framework/overview.md)
65
- [Getting Started](./framework/getting_started.md)
76
- [First Test](./framework/first_test.md)
87
- [Connecting Chainlink Node](./framework/connecting_chainlink_node.md)
98
- [Connecting Chainlink Node (Multiple networks)]()
10-
- [Basic NodeSet Environment](./framework/basic_environment.md)
9+
- [NodeSet Environment](./framework/nodeset_environment.md)
10+
- [NodeSet with External Blockchain](./framework/nodeset_external.md)
11+
- [NodeSet (Local Docker builds)](./framework/nodeset_docker_rebuild.md)
12+
- [NodeSet Compat Environment](./framework/nodeset_compatibility.md)
1113
- [CLI](./framework/cli.md)
1214
- [Configuration](./framework/configuration.md)
15+
- [Test Configuration](./framework/test_configuration_overrides.md)
1316
- [Secrets]()
1417
- [Observability Stack](framework/observability/observability_stack.md)
1518
- [Metrics]()
@@ -31,5 +34,6 @@
3134

3235
---
3336

34-
- [Developing](./developing.md)
35-
- [Releasing modules](./releasing_modules.md)
37+
- [Developing](developing.md)
38+
- [Components](developing/developing_components.md)
39+
- [Releasing modules](releasing_modules.md)

book/src/developing.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,8 @@
11
# Developing
2+
3+
Here we describe good practices for developing components for our framework.
4+
5+
Rules for components are simple:
6+
- Component should declare some `Input` and an optional `Output` (we use that so we can skip or cache any component results)
7+
- Components should be isolated, they should not return anything except basic types like `int`, `string`, `maps` or `structs`
8+
- Component **must** have documentation under [Components](./framework/components/overview.md), here is an [example](./framework/components/blockchains/anvil.md)
Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
## Developing Components
2+
3+
To build a scalable framework that enables the reuse of our product deployments (contracts or services in Docker), we need to establish a clear component structure.
4+
5+
```golang
6+
package mycomponent
7+
8+
import (
9+
"fmt"
10+
"github.com/smartcontractkit/chainlink-testing-framework/framework"
11+
)
12+
13+
type Input struct {
14+
// inputs fields that component exposes for configuration
15+
...
16+
// outputs are embedded into inputs so framework can automatically save them
17+
Out *Output `toml:"out"`
18+
}
19+
20+
type Output struct {
21+
UseCache bool `toml:"use_cache"`
22+
// outputs that will be dumped to config and cached
23+
}
24+
25+
26+
func NewComponent(input *Input) (*Output, error) {
27+
if input.Out != nil && input.Out.UseCache {
28+
return input.Out, nil
29+
}
30+
31+
// component logic here
32+
// deploy a docker container(s)
33+
// or deploy a set of smart contracts
34+
35+
input.Out = &Output{
36+
UseCache: true,
37+
// other fields
38+
...
39+
}
40+
return out, nil
41+
}
42+
```
43+
44+
Each component can define inputs and outputs, following these rules:
45+
46+
- Outputs should be included within inputs.
47+
- If your component is used for side effects output can be omitted.
48+
- `input.Out.UseCache` should be added if you'd like to use caching, see more [here](caching)
49+
50+
### Docker components good practices for [testcontainers-go](https://golang.testcontainers.org/):
51+
52+
An example [simple component](../../../../framework/components/blockchain/anvil.go)
53+
54+
An example of [complex component](../../../../framework/components/clnode/clnode.go)
55+
56+
An example of [composite component](../../../../framework/components/simple_node_set/node_set.go)
57+
58+
- Inputs should include at least `image`, `tag` and `pull_image` field
59+
```golang
60+
Image string `toml:"image" validate:"required"`
61+
Tag string `toml:"tag" validate:"required"`
62+
PullImage bool `toml:"pull_image" validate:"required"`
63+
```
64+
65+
- `ContainerRequest` must contain labels, network and alias required for local observability stack and deployment isolation
66+
```golang
67+
Labels: framework.DefaultTCLabels(),
68+
Networks: []string{framework.DefaultNetworkName},
69+
NetworkAliases: map[string][]string{
70+
framework.DefaultNetworkName: {containerName},
71+
},
72+
```
73+
- In order to copy files into container use `framework.WriteTmpFile(data string, fileName string)`
74+
```golang
75+
userSecretsOverridesFile, err := WriteTmpFile(in.Node.UserSecretsOverrides, "user-secrets-overrides.toml")
76+
if err != nil {
77+
return nil, err
78+
}
79+
```
80+
- Output of docker component must contain all the URLs component exposes for access, both for internal docker usage and external test (host) usage
81+
```golang
82+
host, err := framework.GetHost(c)
83+
if err != nil {
84+
return nil, err
85+
}
86+
mp, err := c.MappedPort(ctx, nat.Port(bindPort))
87+
if err != nil {
88+
return nil, err
89+
}
90+
91+
return &NodeOut{
92+
UseCache: true,
93+
DockerURL: fmt.Sprintf("http://%s:%s", containerName, in.Node.Port),
94+
HostURL: fmt.Sprintf("http://%s:%s", host, mp.Port()),
95+
}, nil
96+
```

book/src/framework/components/components.md renamed to book/src/framework/components/developing_components.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ type Output struct {
2323
2424
2525
func NewComponent(input *Input) (*Output, error) {
26-
if input.Out.UseCache {
26+
if input.Out != nil && input.Out.UseCache {
2727
return input.Out, nil
2828
}
2929
@@ -47,11 +47,11 @@ Each component can define inputs and outputs, following these rules:
4747

4848
### Docker components good practices for [testcontainers-go](https://golang.testcontainers.org/):
4949

50-
An example [simple component](components/blockchain/anvil.go)
50+
An example [simple component](../../../../framework/components/blockchain/anvil.go)
5151

52-
An example of [complex component](components/clnode/clnode.go)
52+
An example of [complex component](../../../../framework/components/clnode/clnode.go)
5353

54-
An example of [composite component](components/node_set_extended/don.go)
54+
An example of [composite component](../../../../framework/components/simple_node_set/node_set.go)
5555

5656
- Inputs should include at least `image`, `tag` and `pull_image` field
5757
```
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,8 @@
11
# Components
2+
3+
CTF contains a lot of useful components, some of them are off-chain services like `Chainlink Node`, `NodeSet`
4+
5+
CTF contains three groups of components:
6+
- Off-chain services like `CL Node`, `NodeSet`, `JobDistributor`, etc.
7+
- On-chain wrappers for [chainlink-deployments](https://github.com/smartcontractkit/chainlink-deployments) repository
8+
- Test components, blockchain simulators, fakes, etc

book/src/framework/connecting_chainlink_node.md

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,6 @@
11
# Connecting Chainlink Node
22

3-
The Chainlink Testing Framework (CTF) is a modular, data-driven tool that lets you explicitly define and configure various Chainlink components.
4-
5-
Let's spin up a simple component.
6-
3+
Now let's have an example of Chainlink node connected to some local blockchain.
74

85
Create your configuration in `smoke.toml`
96
```toml
@@ -72,9 +69,15 @@ Select your configuration by setting `CTF_CONFIGS=smoke.toml` and run it
7269
go test -v -run TestNode
7370
```
7471

72+
Check `node url: ...` in logs, open it and login using default credentials:
73+
```
74+
75+
fj293fbBnlQ!f9vNs
76+
```
77+
7578
Summary:
7679
- We defined configuration for `BlockchainNetwork` and `NodeWithDB` (Chainlink + PostgreSQL)
7780
- We connected them together by creating common network config in `NewNetworkCfgOneNetworkAllNodes`
78-
- We have a Chainlink node running, check `node url: ...` messages in logs to open UI
81+
- We explored the Chainlink node UI
7982

80-
You can learn more about [component design](./components/overview.md) or proceed with another example of [connecting Chainlink node](./connecting_chainlink_node.md)
83+
Let's proceed with another example of [using node sets](./nodeset_environment)
Lines changed: 2 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -1,80 +1,14 @@
1-
# Writing your first test
2-
3-
The Chainlink Testing Framework (CTF) is a modular, data-driven tool that lets you explicitly define and configure various Chainlink components.
4-
5-
Let's spin up a simple component.
1+
# Connecting Multiple Blockchain Nodes
62

73

84
Create your configuration in `smoke.toml`
95
```toml
10-
[blockchain_a]
11-
chain_id = "31337"
12-
image = "ghcr.io/gakonst/foundry:latest"
13-
port = "8545"
14-
type = "anvil"
15-
16-
[cl_node]
17-
data_provider_url = "http://example.com"
18-
19-
[cl_node.db]
20-
image = "postgres:15.6"
21-
pull_image = true
22-
23-
[cl_node.node]
24-
image = "public.ecr.aws/chainlink/chainlink:v2.17.0"
25-
pull_image = true
266
```
277

288
Create your test in `smoke_test.go`
299
```golang
30-
31-
package capabilities_test
32-
33-
import (
34-
"fmt"
35-
"github.com/smartcontractkit/chainlink-testing-framework/framework"
36-
"github.com/smartcontractkit/chainlink-testing-framework/framework/components/blockchain"
37-
"github.com/smartcontractkit/chainlink-testing-framework/framework/components/clnode"
38-
"github.com/stretchr/testify/require"
39-
"testing"
40-
)
41-
42-
type Config struct {
43-
BlockchainA *blockchain.Input `toml:"blockchain_a" validate:"required"`
44-
CLNode *clnode.Input `toml:"cl_node" validate:"required"`
45-
}
46-
47-
func TestNode(t *testing.T) {
48-
in, err := framework.Load[Config](t)
49-
require.NoError(t, err)
50-
51-
bc, err := blockchain.NewBlockchainNetwork(in.BlockchainA)
52-
require.NoError(t, err)
53-
54-
networkCfg, err := clnode.NewNetworkCfgOneNetworkAllNodes(bc)
55-
require.NoError(t, err)
56-
in.CLNode.Node.TestConfigOverrides = networkCfg
57-
58-
output, err := clnode.NewNodeWithDB(in.CLNode)
59-
require.NoError(t, err)
60-
61-
t.Run("test something", func(t *testing.T) {
62-
fmt.Printf("node url: %s\n", output.Node.HostURL)
63-
require.NotEmpty(t, output.Node.HostURL)
64-
})
65-
}
66-
67-
6810
```
6911

7012
Select your configuration by setting `CTF_CONFIGS=smoke.toml` and run it
7113
```bash
72-
go test -v -run TestNode
73-
```
74-
75-
Summary:
76-
- We defined configuration for `BlockchainNetwork` and `NodeWithDB` (Chainlink + PostgreSQL)
77-
- We connected them together by creating common network config in `NewNetworkCfgOneNetworkAllNodes`
78-
- We have a Chainlink node running, check `node url: ...` messages in logs to open UI
79-
80-
You can learn more about [component design](./components/overview.md) or proceed with another example of [connecting Chainlink node](./connecting_chainlink_node.md)
14+
```

0 commit comments

Comments
 (0)