Skip to content

Commit 359ea26

Browse files
committed
add chaosmesh debug example with Havoc for local and stage
1 parent 6be35b8 commit 359ea26

File tree

8 files changed

+467
-1
lines changed

8 files changed

+467
-1
lines changed

framework/components/jd/jd.go

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,21 @@ func NewJD(in *Input) (*Output, error) {
104104
WaitingFor: tcwait.ForAll(
105105
tcwait.ForListeningPort(nat.Port(fmt.Sprintf("%s/tcp", in.GRPCPort))),
106106
),
107+
LifecycleHooks: []tc.ContainerLifecycleHooks{
108+
{
109+
PostStarts: []tc.ContainerHook{
110+
func(ctx context.Context, c tc.Container) error {
111+
_, _, err := c.Exec(ctx, []string{
112+
"sh", "-c", `iptables -A OUTPUT -d 10.0.0.0/8 -j ACCEPT && \
113+
iptables -A OUTPUT -d 172.16.0.0/12 -j ACCEPT && \
114+
iptables -A OUTPUT -d 192.168.0.0/16 -j ACCEPT && \
115+
iptables -A OUTPUT -j DROP`,
116+
})
117+
return err
118+
},
119+
},
120+
},
121+
},
107122
}
108123
if req.Image == "" {
109124
req.Image = TmpImageName
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
package networktest
2+
3+
import (
4+
"context"
5+
"fmt"
6+
7+
"github.com/docker/docker/api/types/container"
8+
"github.com/testcontainers/testcontainers-go"
9+
"github.com/testcontainers/testcontainers-go/wait"
10+
11+
"github.com/smartcontractkit/chainlink-testing-framework/framework"
12+
)
13+
14+
type AlpineInput struct {
15+
Privileged bool // Whether to run in privileged mode
16+
BlockInternet bool // Whether to block internet access
17+
Labels map[string]string // Container labels
18+
}
19+
20+
type AlpineOutput struct{}
21+
22+
// NewNetworkTest creates a minimal Alpine Linux container for network testing
23+
func NewNetworkTest(in AlpineInput) (*AlpineOutput, error) {
24+
req := testcontainers.ContainerRequest{
25+
Name: "networktest",
26+
Image: "alpine:latest",
27+
Networks: []string{framework.DefaultNetworkName},
28+
NetworkAliases: map[string][]string{
29+
framework.DefaultNetworkName: {"networktest"},
30+
},
31+
Labels: framework.DefaultTCLabels(),
32+
WaitingFor: wait.ForLog(""),
33+
Cmd: []string{"/bin/sh", "-c", "while true; do sleep 30; done;"},
34+
}
35+
36+
if in.BlockInternet {
37+
req.HostConfigModifier = func(hc *container.HostConfig) {
38+
hc.DNS = []string{"127.0.0.1"}
39+
hc.CapAdd = []string{"NET_ADMIN"}
40+
if in.Privileged {
41+
hc.Privileged = true
42+
}
43+
}
44+
45+
req.LifecycleHooks = []testcontainers.ContainerLifecycleHooks{{
46+
PostStarts: []testcontainers.ContainerHook{
47+
func(ctx context.Context, c testcontainers.Container) error {
48+
// Block all internet traffic while allowing local network
49+
_, _, err := c.Exec(ctx, []string{
50+
"sh", "-c", `iptables -A OUTPUT -d 10.0.0.0/8 -j ACCEPT &&
51+
iptables -A OUTPUT -d 172.16.0.0/12 -j ACCEPT &&
52+
iptables -A OUTPUT -d 192.168.0.0/16 -j ACCEPT &&
53+
iptables -A OUTPUT -j DROP`,
54+
})
55+
return err
56+
},
57+
},
58+
}}
59+
}
60+
61+
_, err := testcontainers.GenericContainer(context.Background(), testcontainers.GenericContainerRequest{
62+
ContainerRequest: req,
63+
Started: true,
64+
})
65+
if err != nil {
66+
return nil, fmt.Errorf("failed to start alpine container: %w", err)
67+
}
68+
69+
return &AlpineOutput{}, nil
70+
}

framework/examples/myproject/smoke.toml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,9 @@
66
[data_provider]
77
port = 9111
88

9+
[jd]
10+
image = "job-distributor:0.9.0"
11+
912
[[nodesets]]
1013
name = "don"
1114
nodes = 5

framework/examples/myproject/smoke_test.go

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package examples
22

33
import (
4+
"fmt"
45
"testing"
56

67
"github.com/davecgh/go-spew/spew"
@@ -9,13 +10,16 @@ import (
910
"github.com/smartcontractkit/chainlink-testing-framework/framework"
1011
"github.com/smartcontractkit/chainlink-testing-framework/framework/components/blockchain"
1112
"github.com/smartcontractkit/chainlink-testing-framework/framework/components/fake"
13+
"github.com/smartcontractkit/chainlink-testing-framework/framework/components/jd"
14+
"github.com/smartcontractkit/chainlink-testing-framework/framework/components/networktest"
1215
ns "github.com/smartcontractkit/chainlink-testing-framework/framework/components/simple_node_set"
1316
)
1417

1518
type Cfg struct {
1619
BlockchainA *blockchain.Input `toml:"blockchain_a" validate:"required"`
1720
MockerDataProvider *fake.Input `toml:"data_provider" validate:"required"`
1821
NodeSets []*ns.Input `toml:"nodesets" validate:"required"`
22+
JD *jd.Input `toml:"jd" validate:"required"`
1923
}
2024

2125
func TestSmoke(t *testing.T) {
@@ -28,7 +32,16 @@ func TestSmoke(t *testing.T) {
2832
require.NoError(t, err)
2933
out, err := ns.NewSharedDBNodeSet(in.NodeSets[0], bc)
3034
require.NoError(t, err)
35+
_, err = jd.NewJD(in.JD)
36+
require.NoError(t, err)
3137
spew.Dump(in.NodeSets[0])
38+
_, err = networktest.NewNetworkTest(networktest.AlpineInput{Privileged: true, BlockInternet: true})
39+
require.NoError(t, err)
40+
dc, err := framework.NewDockerClient()
41+
require.NoError(t, err)
42+
sOut, err := dc.ExecContainer("networktest", []string{"ping", "-c", "2", "google.com"})
43+
require.NoError(t, err)
44+
fmt.Println(sOut)
3245

3346
t.Run("test something", func(t *testing.T) {
3447
for _, n := range out.CLNodes {

infra/chaosmesh-playground/README.md

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,4 +23,20 @@ Debug `ChaosMesh` using `k9s`, check daemon logs.
2323
Remove the environment
2424
```
2525
devbox run down
26-
```
26+
```
27+
28+
## Using Havoc
29+
30+
To use our chaos testing framework and apply a single experiment either locally or remotely use
31+
```
32+
// main.stage
33+
aws sso login --profile=staging-crib
34+
kubectl config use-context main-stage-cluster-crib
35+
36+
// OR local chaosmesh-playground
37+
kubectl config use-context kind-cm-playground
38+
39+
go test -v -run TestChaosSample
40+
```
41+
42+
Open `k9s` and search your namespace for `networkchaos`
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
package main_test
2+
3+
import (
4+
"context"
5+
"os"
6+
"testing"
7+
"time"
8+
9+
"github.com/rs/zerolog"
10+
"github.com/rs/zerolog/log"
11+
"github.com/stretchr/testify/require"
12+
13+
"github.com/smartcontractkit/chainlink-testing-framework/havoc"
14+
)
15+
16+
func TestChaosSample(t *testing.T) {
17+
l := log.Output(zerolog.ConsoleWriter{Out: os.Stderr}).Level(zerolog.DebugLevel)
18+
c, err := havoc.NewChaosMeshClient()
19+
require.NoError(t, err)
20+
r := havoc.NewNamespaceRunner(l, c, false)
21+
dur := 1 * time.Minute
22+
23+
// choose any experiment type
24+
_, err = r.RunPodDelay(context.Background(),
25+
havoc.PodDelayCfg{
26+
// fill your target here
27+
Namespace: "crib-aw-remote",
28+
LabelKey: "app.kubernetes.io/instance",
29+
LabelValues: []string{"ccip-15"},
30+
Latency: 200 * time.Millisecond,
31+
Jitter: 200 * time.Millisecond,
32+
Correlation: "0",
33+
InjectionDuration: dur,
34+
})
35+
require.NoError(t, err)
36+
time.Sleep(dur)
37+
}

infra/chaosmesh-playground/go.mod

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
module github.com/smartcontractkit/chainlink-testing-framework/k8s-test
2+
3+
go 1.24.2
4+
5+
replace github.com/smartcontractkit/chainlink-testing-framework/havoc => ../../havoc
6+
7+
require (
8+
github.com/rs/zerolog v1.34.0
9+
github.com/smartcontractkit/chainlink-testing-framework/havoc v0.0.0-00010101000000-000000000000
10+
github.com/stretchr/testify v1.10.0
11+
)
12+
13+
require (
14+
github.com/alecthomas/units v0.0.0-20211218093645-b94a6e3cc137 // indirect
15+
github.com/beorn7/perks v1.0.1 // indirect
16+
github.com/cespare/xxhash/v2 v2.3.0 // indirect
17+
github.com/chaos-mesh/chaos-mesh/api v0.0.0-20240821051457-da69c6d9617a // indirect
18+
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
19+
github.com/docker/go-units v0.5.0 // indirect
20+
github.com/emicklei/go-restful/v3 v3.11.0 // indirect
21+
github.com/evanphx/json-patch/v5 v5.9.0 // indirect
22+
github.com/fsnotify/fsnotify v1.7.0 // indirect
23+
github.com/fxamacker/cbor/v2 v2.7.0 // indirect
24+
github.com/go-logr/logr v1.4.2 // indirect
25+
github.com/go-openapi/jsonpointer v0.20.0 // indirect
26+
github.com/go-openapi/jsonreference v0.20.2 // indirect
27+
github.com/go-openapi/swag v0.22.4 // indirect
28+
github.com/go-resty/resty/v2 v2.15.3 // indirect
29+
github.com/gogo/protobuf v1.3.2 // indirect
30+
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
31+
github.com/golang/protobuf v1.5.4 // indirect
32+
github.com/google/gnostic-models v0.6.8 // indirect
33+
github.com/google/go-cmp v0.6.0 // indirect
34+
github.com/google/gofuzz v1.2.0 // indirect
35+
github.com/google/uuid v1.6.0 // indirect
36+
github.com/grafana/grafana-foundation-sdk/go v0.0.0-20240326122733-6f96a993222b // indirect
37+
github.com/imdario/mergo v0.3.16 // indirect
38+
github.com/josharian/intern v1.0.0 // indirect
39+
github.com/json-iterator/go v1.1.12 // indirect
40+
github.com/klauspost/compress v1.17.9 // indirect
41+
github.com/mailru/easyjson v0.7.7 // indirect
42+
github.com/mattn/go-colorable v0.1.13 // indirect
43+
github.com/mattn/go-isatty v0.0.20 // indirect
44+
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
45+
github.com/modern-go/reflect2 v1.0.2 // indirect
46+
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
47+
github.com/pkg/errors v0.9.1 // indirect
48+
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
49+
github.com/prometheus/client_golang v1.20.4 // indirect
50+
github.com/prometheus/client_model v0.6.1 // indirect
51+
github.com/prometheus/common v0.62.0 // indirect
52+
github.com/prometheus/procfs v0.15.1 // indirect
53+
github.com/robfig/cron/v3 v3.0.1 // indirect
54+
github.com/smartcontractkit/chainlink-testing-framework/lib/grafana v1.50.0 // indirect
55+
github.com/spf13/pflag v1.0.5 // indirect
56+
github.com/x448/float16 v0.8.4 // indirect
57+
golang.org/x/exp v0.0.0-20240112132812-db7319d0e0e3 // indirect
58+
golang.org/x/net v0.34.0 // indirect
59+
golang.org/x/oauth2 v0.24.0 // indirect
60+
golang.org/x/sys v0.31.0 // indirect
61+
golang.org/x/term v0.28.0 // indirect
62+
golang.org/x/text v0.21.0 // indirect
63+
golang.org/x/time v0.6.0 // indirect
64+
gomodules.xyz/jsonpatch/v2 v2.4.0 // indirect
65+
google.golang.org/protobuf v1.36.1 // indirect
66+
gopkg.in/inf.v0 v0.9.1 // indirect
67+
gopkg.in/yaml.v2 v2.4.0 // indirect
68+
gopkg.in/yaml.v3 v3.0.1 // indirect
69+
k8s.io/api v0.31.2 // indirect
70+
k8s.io/apiextensions-apiserver v0.31.0 // indirect
71+
k8s.io/apimachinery v0.31.2 // indirect
72+
k8s.io/client-go v0.31.2 // indirect
73+
k8s.io/klog/v2 v2.130.1 // indirect
74+
k8s.io/kube-openapi v0.0.0-20240228011516-70dd3763d340 // indirect
75+
k8s.io/utils v0.0.0-20240711033017-18e509b52bc8 // indirect
76+
sigs.k8s.io/controller-runtime v0.19.0 // indirect
77+
sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect
78+
sigs.k8s.io/structured-merge-diff/v4 v4.4.1 // indirect
79+
sigs.k8s.io/yaml v1.4.0 // indirect
80+
)

0 commit comments

Comments
 (0)