Skip to content

Commit f9d5ffa

Browse files
committed
move CTFv1 to legacy
1 parent 1a0d4f9 commit f9d5ffa

29 files changed

+2832
-3
lines changed

book/src/SUMMARY.md

Lines changed: 30 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -103,12 +103,40 @@
103103
- [Debug Loki errors](./libs/wasp/how-to/debug_loki_errors.md)
104104
- [Havoc](./libs/havoc.md)
105105
- [Seth](./libs/seth.md)
106-
- [AWS Secrets Manager]()
107106
- [Sentinel](./libs/sentinel.md)
108107
---
109108

110-
- [Legacy]()
109+
- [Legacy](./legacy.md)
111110
- [Overview](./legacy.md)
111+
- [CTFv1](lib.md)
112+
- [Blockchain](lib/blockchain.md)
113+
- [Concurrency](lib/concurrency.md)
114+
- [Client](lib/client.md)
115+
- [Anvil]()
116+
- [AWS Secrets Manager](lib/client/aws_secrets_manager.md)
117+
- [Github](lib/client/github.md)
118+
- [Grafana](lib/client/grafana.md)
119+
- [Kafka](lib/client/kafka.md)
120+
- [Loki](lib/client/loki.md)
121+
- [MockServer](lib/client/mockserver.md)
122+
- [Postgres](lib/client/postgres.md)
123+
- [Prometheus](lib/client/prometheus.md)
124+
- [Kubernetes](lib/k8s_new/overview.md)
125+
- [Creating environments](lib/k8s_new/environments.md)
126+
- [Using remote runner](lib/k8s_new/remote_runner.md)
127+
- [Passing test secrets](lib/k8s_new/test_secrets.md)
128+
- [chain.link labels](lib/k8s/labels.md)
129+
- [Kubernetes (legacy docs)](lib/k8s/KUBERNETES.md)
130+
- [K8s Remote Run](lib/k8s/REMOTE_RUN.md)
131+
- [K8s Tutorial](lib/k8s/TUTORIAL.md)
132+
- [Config](lib/config/config.md)
133+
- [CRIB Connector](lib/crib.md)
134+
- [Docker](lib/docker/overview.md)
135+
- [Blockchain nodes](lib/docker/blockchain_nodes.md)
136+
- [Chainlink ecosystem](lib/docker/chainlink_ecosystem.md)
137+
- [Third party apps]()
138+
- [Test helpers](lib/docker/test_helpers.md)
139+
- [Logging](lib/logging.md)
112140
- [K8s Test Runner](k8s-test-runner/k8s-test-runner.md)
113141

114142
---

book/src/legacy.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
# Legacy
22

3-
This chapter contains legacy documentation or code examples that will be sunset in the next release
3+
This chapter contains legacy documentation or code examples that will be sunset in the next major release

book/src/lib/blockchain.md

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
# Blockchain Clients
2+
3+
<div class="warning">
4+
5+
This documentation is deprecated, we are using it in [Chainlink Integration Tests](https://github.com/smartcontractkit/chainlink/tree/develop/integration-tests)
6+
7+
If you want to test our new products use [v2](../framework/overview.md)
8+
</div>
9+
10+
This folder contains the bulk of code that handles integrating with different EVM chains. If you're looking to run tests on a new EVM chain, and are having issues with the default implementation, you've come to the right place.
11+
12+
### Some Terminology
13+
14+
- [L2 Chain](https://ethereum.org/en/layer-2/): A Layer 2 chain "branching" off Ethereum.
15+
- [EVM](https://ethereum.org/en/developers/docs/evm/): Ethereum Virtual Machine that underpins the Ethereum blockchain.
16+
- [EVM Compatible](https://blog.thirdweb.com/evm-compatible-blockchains-and-ethereum-virtual-machine/#:~:text=What%20does%20'EVM%20compatibility'%20mean,significant%20changes%20to%20their%20code.): A chain that has some large, underlying differences from how base Ethereum works, but can still be interacted with largely the same way as Ethereum.
17+
- [EIP-1559](https://eips.ethereum.org/EIPS/eip-1559): The Ethereum Improvement Proposal that changed how gas fees are calculated and paid on Ethereum
18+
- Legacy Transactions: Transactions that are sent using the old gas fee calculation method, the one used before EIP-1559.
19+
- Dynamic Fee Transaction: Transactions that are sent using the new gas fee calculation method, the one used after EIP-1559.
20+
21+
## How Client Integrations Work
22+
23+
In order to test Chainlink nodes, the `chainlink-testing-framework` needs to be able to interact with the chain that the node is running on. This is done through the `blockchain.EVMClient` interface. The `EVMClient` interface is a wrapper around [geth](https://geth.ethereum.org/) to interact with the blockchain. We conduct all our testing blockchain operations through this wrapper, like sending transactions and monitoring on-chain events. The primary implementation of this wrapper is built for [Ethereum](./ethereum.go). Most others, like the [Metis](./metis.go) and [Optimism](./optimism.go) integrations, extend and modify the base Ethereum implementation.
24+
25+
## Do I Need a New Integration?
26+
27+
If you're reading this, probably. The default EVM integration is designed to work with mainnet Ethereum, which covers most other EVM chain interactions, but it's not guaranteed to work with all of them. If you're on a new chain and the test framework is throwing errors while doing basic things like send transactions, receive new headers, or deploy contracts, you'll likely need to create a new integration. The most common issue with new chains (especially L2s) is gas estimations and lack of support for dynamic transactions.
28+
29+
## Creating a New Integration
30+
31+
Take a look at the [Metis](./metis.go) integration as an example. Metis is an L2, EVM compatible chain. It's largely the same as the base Ethereum integration, so we'll extend from that.
32+
33+
```go
34+
type MetisMultinodeClient struct {
35+
*EthereumMultinodeClient
36+
}
37+
38+
type MetisClient struct {
39+
*EthereumClient
40+
}
41+
```
42+
43+
Now we need to let other libraries (like our tests in the main Chainlink repo) that this integration exists. So we add the new implementation to the [known_networks.go](https://github.com/smartcontractkit/chainlink-testing-framework/blob/main/lib/blockchain/known_networks.go) file. We can then add that network to our tests' own [known_networks.go](https://github.com/smartcontractkit/chainlink/blob/develop/integration-tests/known_networks.go) file (it's annoying, there are plans to simplify).
44+
45+
Now our Metis integration is the exact same as our base Ethereum one, which doesn't do us too much good. I'm assuming you came here to make some changes, so first let's find out what we need to change. This is a mix of reading developer documentation on the chain you're testing and trial and error. Mostly the latter in later stages. In the case of Metis, like many L2s, they [have their own spin on gas fees](https://docs.metis.io/dev/protocol-in-detail/transaction-fees-on-the-metis-platform). They also only support Legacy transactions. So we'll need to override any methods that deal with gas estimations, `Fund`, `DeployContract`, and `ReturnFunds`.

book/src/lib/client.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
# Client
2+
3+
We support a variety of clients that ease communication with following applications:
4+
* [Anvil](./client/anvil.md)
5+
* [AWS Secrets Manager](./client/aws_secrets_manager.md)
6+
* [Github](./client/github.md)
7+
* [Kafka](./client/kafka.md)
8+
* [Loki](./client/loki.md)
9+
* [MockServer](./client/mockserver.md)
10+
* [Postgres](./client/postgres.md)
11+
* [Prometheus](./client/prometheus.md)
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
# AWS Secrets Manager
2+
3+
This simple client makes it even easier to:
4+
* read
5+
* create
6+
* remove secrets from AWS Secrets Manager.
7+
8+
Creating a new instance is straight-forward. You should either use environment variables or shared configuration and credentials.
9+
10+
> [!NOTE]
11+
> Environment variables take precedence over shared credentials.
12+
13+
## Using environment variables
14+
You can pass required configuration as following environment variables:
15+
* `AWS_ACCESS_KEY_ID`
16+
* `AWS_SECRET_ACCESS_KEY`
17+
* `AWS_REGION`
18+
19+
## Using shared credentials
20+
If you have shared credentials stored in `.aws/credentials` file, then the easiest way to configure the client is by setting
21+
`AWS_PROFILE` environment variable with the profile name. If that environment variable is not set, the SDK will try to use default profile.
22+
23+
> [!WARNING]
24+
> Remember, that most probably you will need to manually create a new session for that profile before running your application.
25+
26+
27+
> [!NOTE]
28+
> You can read more about configuring the AWS SDK [here](https://docs.aws.amazon.com/sdk-for-go/v1/developer-guide/configuring-sdk.html).
29+
30+
Once you have an instance of AWS Secrets Manager you gain access to following functions:
31+
* `CreateSecret(key string, val string, override bool) error`
32+
* `GetSecret(key string) (AWSSecret, error)`
33+
* `RemoveSecret(key string, noRecovery bool) error`

book/src/lib/client/github.md

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
# Github
2+
3+
This small client makes it easy to get `N` latest releases or tags from any Github.com repository. To use it, all you need to have
4+
is a properly scoped access token.
5+
6+
```go
7+
publicRepoClient := NewGithubClient(WITHOUT_TOKEN)
8+
9+
// "smartcontractkit", "chainlink"
10+
latestCLReleases, err := publicRepoClient.ListLatestCLCoreReleases(10)
11+
if err != nil {
12+
panic(err)
13+
}
14+
15+
// "smartcontractkit", "chainlink"
16+
latestCLTags, err := publicRepoClient.ListLatestCLCoreTags(10)
17+
if err != nil {
18+
panic(err)
19+
}
20+
21+
privateRepoClient := NewGithubClient("my-secret-PAT")
22+
myLatestReleases, err := privateRepoClient.ListLatestReleases("my-org", "my-private-repo", 5)
23+
if err != nil {
24+
panic(err)
25+
}
26+
```
27+
28+
There's really not much more to it...

book/src/lib/client/grafana.md

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
# Grafana
2+
3+
> [!NOTE]
4+
> Contrary to other clients, you will find Grafana client in a [separate package & go module](https://github.com/smartcontractkit/chainlink-testing-framework/tree/main/lib/grafana).
5+
6+
Grafana client encapsulate following functionalities:
7+
* Dashboard creation
8+
* Managing dashboard annotations (CRUD)
9+
* Checking alerts
10+
11+
# New instance
12+
In order to create a new instance you will need:
13+
* URL
14+
* API token
15+
16+
For example:
17+
```go
18+
url := "http://grafana.io"
19+
apiToken := "such-a-secret-1&11n"
20+
gc := NewGrafanaClient(url, apiToken)
21+
```
22+
23+
# Dashboard creation
24+
You can create a new dashboard defined in JSON with:
25+
```go
26+
27+
//define your dashboard here
28+
dashboardJson := ``
29+
30+
request := PostDashboardRequest {
31+
Dashboard: dashboardJson,
32+
FolderId: 5 // change to your folder id
33+
}
34+
35+
dr, rawResponse, err := gc.PostDashboard(request)
36+
if err != nil {
37+
panic(err)
38+
}
39+
40+
if rawResponse.StatusCode() != 200 {
41+
panic("response code wasn't 200, but " + rawResponse.StatusCode())
42+
}
43+
44+
fmt.Println("Dashboard slug is is " + *dr.Slug)
45+
```
46+
47+
# Posting annotations
48+
You can post annotations in a following way:
49+
```go
50+
annDetails := PostAnnotation {
51+
DashboardUID: "some-uid",
52+
Time: time.Now(),
53+
TimeEnd: time.Now().Add(1 * time.Second)
54+
Text: "my test annotation"
55+
}
56+
57+
r, rawResponse, err := gc.PostAnnotation(annDetails)
58+
if rawResponse.StatusCode() != 200 {
59+
panic("response code wasn't 200, but " + rawResponse.StatusCode())
60+
}
61+
62+
fmt.Println("Created annotation with id: " + r.Id)
63+
64+
```
65+
66+
# Checking alerts
67+
You can check alerts firing for a dashboard with UID:
68+
```go
69+
alerts, rawResponse, err := gc.AlertRulerClient.GetAlertsForDashboard("some-uid")
70+
if rawResponse.StatusCode() != 200 {
71+
panic("response code wasn't 200, but " + rawResponse.StatusCode())
72+
}
73+
74+
for name, value := range alerts {
75+
fmt.Println("Alert named " + name + "was triggered. Details: " + string(value))
76+
}
77+
```
78+
79+
# Troubleshooting
80+
To enable debug mode for the underlaying HTTP client set `RESTY_DEBUG` environment variable to `true`.

book/src/lib/client/kafka.md

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
# Kafka
2+
3+
This is a wrapper over HTTP client that can only return a list of topics from Kafka instance.
4+
5+
```go
6+
client, err := NewKafkaRestClient(&NewKafkaRestClient{URL: "my-kafka-url"})
7+
if err != nil {
8+
panic(err)
9+
}
10+
11+
topis, err := client.GetTopics()
12+
if err != nil {
13+
panic(err)
14+
}
15+
16+
for _, topic := range topics {
17+
fmt.Println("topic: " + topic)
18+
}
19+
```

book/src/lib/client/loki.md

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
# Loki
2+
3+
Loki client simplifies querying of Loki logs with `LogQL`.
4+
5+
The way it's designed now implies that:
6+
* you need to create a new client instance for each query
7+
* query results are returned as `string`
8+
9+
## New instance
10+
To create a new instance you to provide the following at the very least:
11+
* Loki URL
12+
* query to execute
13+
* time range
14+
15+
```go
16+
// scheme is required
17+
lokiUrl := "http://loki-host.io"
18+
// can be empty
19+
tenantId := "promtail"
20+
basicAuth := LokiBasicAuth{
21+
Login: "admin",
22+
Password: "oh-so-secret",
23+
}
24+
queryParams := LokiQueryParams{
25+
Query: "quantile_over_time(0.5, {name='my awesome app'} | json| unwrap duration [10s]) by name",
26+
StartTime: time.Now().Add(1 * time.Hour),
27+
EndTime: time.Now(),
28+
Limit: 1000,
29+
}
30+
lokiClient := client.NewLokiClient(lokiUrl, tenantId, basicAuth, queryParams)
31+
```
32+
33+
If your instance doesn't have basic auth you should use an empty string:
34+
```go
35+
basicAuth := LokiBasicAuth{}
36+
```
37+
38+
## Executing a query
39+
Once you have the client instance created you can execute the query with:
40+
```go
41+
ctx, cancelFn := context.WithTimeout(context.Background, 3 * time.Minute)
42+
defer cancelFn()
43+
results, err := lokiClient.QueryLogs(ctx)
44+
if err != nil {
45+
panic(err)
46+
}
47+
48+
for _, logEntry := range results {
49+
fmt.Println("At " + logEntry.Timestamp + " found following log: " + logEntry.Log)
50+
}
51+
```
52+
53+
## Log entry types
54+
Loki can return various data types in responses to queries. We will try to convert the following ones to `string`:
55+
* `int`
56+
* `float64`
57+
58+
If it's neither of these types nor a `string` the client will return an error. Same will happen if `nil` is returned.
59+
60+
# Troubleshooting
61+
If you find yourself in trouble these two environment variables might help you:
62+
* `RESTY_DEBUG` set to `true` will enable debug mode for the underlaying HTTP client
63+
* `LOKI_CLIENT_LOG_LEVEL` controls log level of Loki client (for supported log levels check [logging package](../logging.md) documentation)

0 commit comments

Comments
 (0)