ping/rust: introduce rust cross-version test (#26)
* ping/go: fix composition name * ping/rust: introduce the ping/rust test * Showcase version selection through features Can be run with `cargo check --features libp2pv0450` or `cargo check --features libp2pv0440`. * Peer programming session * ping/rust: experiment with master & current groups * ping/rust/src/main: Simplify import across versions * ping/rust/src/main: Remove commented out code * ping/rust/src/main: Clean up * ping/rust/Dockerfile: Update crates.io index in separate step Potentially allows caching. * ping/rust/Dockerfile: Don't both build and install Building the binary in release mode is enough. * ping/rust/src/main: Clean up log lines * ping/rust: Implement iterations with latency * ping/rust/src/main: Extract signal and wait logic into fn * ping/rust/Dockerfile: import caching fixes * ping/: add cross-version composition * ping/rust: add json payloads fix * ping/rust: match iterations id with go * ping/rust/Dockerfile: improve caching * ci: introduce workflow ping-interop-rust * ping/interop: update latest versions * ping/_compositions: add full ping interop * ci: resolve git reference to sha * ping/rust/Dockerfile: drop cargo output * ping/rust: drop version indirection * ping/rust/Dockerfile: fix features to support caching * ping/rust/Dockerfile: do not cache the rewritten package * ping/_compositions/*: use concurrent_builds * ping/_compositions/*: drop test_instances count * ci: build composition then run * ping: introduce InteropTarget option * ci: fix interop target & build * ping/_compositions/*: introduce load_resource * ci: 10 minutes timeout for the run step * README: add update instruction for rust & clean go * ping/rust/Dockerfile: add protocol buffer compiler * ping/rust/Cargo.lock: cargo update packages * .github: increase testground timeout Co-authored-by: Max Inden <mail@max-inden.de>
This commit is contained in:
parent
3f6b90969d
commit
072d351a5f
|
@ -35,7 +35,7 @@ runs:
|
|||
cat <<EOF >> ~/testground/.env.toml
|
||||
|
||||
[daemon.scheduler]
|
||||
task_timeout_min = 30
|
||||
task_timeout_min = 60
|
||||
EOF
|
||||
testground daemon > testground.out 2> testground.err &
|
||||
fi;
|
|
@ -26,5 +26,5 @@ jobs:
|
|||
with:
|
||||
composition_file: "ping/_compositions/go-cross-versions.toml"
|
||||
custom_git_target: ${{ github.event.inputs.custom_git_target }} # nothing or "some-fork/go-libp2p"
|
||||
custom_git_reference: ${{ github.event.inputs.custom_git_reference }} # a git reference
|
||||
custom_git_reference: ${{ github.event.inputs.custom_git_reference }} # a git branch
|
||||
testground_endpoint: ${{ github.event.inputs.testground_endpoint }}
|
||||
|
|
|
@ -0,0 +1,30 @@
|
|||
on:
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
testground_endpoint:
|
||||
type: string
|
||||
required: false
|
||||
description: testground endpoint
|
||||
custom_git_reference:
|
||||
type: string
|
||||
required: false
|
||||
description: rust ref
|
||||
custom_git_target:
|
||||
type: string
|
||||
required: false
|
||||
description: repository to use as replace target
|
||||
default: github.com/libp2p/rust-libp2p
|
||||
|
||||
name: rust-libp2p ping - rust test with testground.
|
||||
|
||||
jobs:
|
||||
run-libp2p-test-plans:
|
||||
# If you intend to use this workflow from another repo,
|
||||
# you need to pass the repo and the version:
|
||||
# uses: "libp2p/test-plans/.github/workflows/run-composition.yml@master"
|
||||
uses: "./.github/workflows/run-composition.yml"
|
||||
with:
|
||||
composition_file: "ping/_compositions/rust-cross-versions.toml"
|
||||
custom_git_target: ${{ github.event.inputs.custom_git_target }} # nothing or "some-fork/go-libp2p"
|
||||
custom_git_reference: ${{ github.event.inputs.custom_git_reference }} # a git reference
|
||||
testground_endpoint: ${{ github.event.inputs.testground_endpoint }}
|
|
@ -0,0 +1,39 @@
|
|||
on:
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
testground_endpoint:
|
||||
type: string
|
||||
required: false
|
||||
description: testground endpoint
|
||||
custom_git_reference:
|
||||
description: the git commit or branch we're going to use for the custom target
|
||||
required: false
|
||||
type: string
|
||||
custom_git_target:
|
||||
description: the custom git fork url we're going to use for the custom target (github.com/some-fork/rust-libp2p)
|
||||
required: false
|
||||
type: string
|
||||
custom_interop_target:
|
||||
description: in the case of cross-implementation testing, the implementation target (go | rust | ...)
|
||||
required: false
|
||||
type: string
|
||||
|
||||
name: libp2p ping - go and rust test with testground.
|
||||
|
||||
jobs:
|
||||
run-ping-latest:
|
||||
uses: "./.github/workflows/run-composition.yml"
|
||||
with:
|
||||
composition_file: "ping/_compositions/go-rust-interop-latest.toml"
|
||||
custom_git_target: ${{ github.event.inputs.custom_git_target }} # nothing or "some-fork/go-libp2p"
|
||||
custom_git_reference: ${{ github.event.inputs.custom_git_reference }} # a git reference
|
||||
custom_interop_target: ${{ github.event.inputs.custom_interop_target }} # go | rust
|
||||
testground_endpoint: ${{ github.event.inputs.testground_endpoint }}
|
||||
run-ping-all:
|
||||
uses: "./.github/workflows/run-composition.yml"
|
||||
with:
|
||||
composition_file: "ping/_compositions/go-rust-interop.toml"
|
||||
custom_git_target: ${{ github.event.inputs.custom_git_target }} # nothing or "some-fork/go-libp2p"
|
||||
custom_git_reference: ${{ github.event.inputs.custom_git_reference }} # a git reference
|
||||
custom_interop_target: ${{ github.event.inputs.custom_interop_target }} # go | rust
|
||||
testground_endpoint: ${{ github.event.inputs.testground_endpoint }}
|
|
@ -4,12 +4,19 @@ on:
|
|||
workflow_call:
|
||||
inputs:
|
||||
composition_file:
|
||||
description: the workflow we're going to run
|
||||
required: true
|
||||
type: string
|
||||
custom_git_reference:
|
||||
description: the git commit or branch we're going to use for the custom target
|
||||
required: false
|
||||
type: string
|
||||
custom_git_target:
|
||||
description: the custom git fork url we're going to use for the custom target (github.com/some-fork/rust-libp2p)
|
||||
required: false
|
||||
type: string
|
||||
custom_interop_target:
|
||||
description: in the case of cross-implementation testing, the implementation target (go | rust | ...)
|
||||
required: false
|
||||
type: string
|
||||
testground_endpoint:
|
||||
|
@ -39,11 +46,28 @@ jobs:
|
|||
working-directory: ./test-plans
|
||||
run: |
|
||||
testground plan import --from ./ --name libp2p
|
||||
- name: Run the composition file
|
||||
- name: Resolve the git references
|
||||
if: ${{ inputs.custom_git_reference && inputs.custom_git_target }}
|
||||
id: resolve_reference
|
||||
working-directory: ./test-plans
|
||||
run: |
|
||||
GitReference=${{ inputs.custom_git_reference }} \
|
||||
GitTarget=${{ inputs.custom_git_target }} \
|
||||
git fetch https://${{ inputs.custom_git_target }} ${{ inputs.custom_git_reference }}
|
||||
SHA=`git log FETCH_HEAD -n 1 --pretty=format:"%H"`
|
||||
echo "::set-output name=custom_git_sha::${SHA}"
|
||||
- name: Build the composition file
|
||||
working-directory: ./test-plans
|
||||
run: |
|
||||
testground build composition \
|
||||
-f ${{ inputs.composition_file }} \
|
||||
--wait
|
||||
env:
|
||||
GitReference: ${{ steps.resolve_reference.outputs.custom_git_sha || inputs.custom_git_reference }}
|
||||
GitTarget: ${{ inputs.custom_git_target }}
|
||||
InteropTarget: ${{ inputs.custom_interop_target }}
|
||||
- name: Run the composition file
|
||||
working-directory: ./test-plans
|
||||
timeout-minutes: 10
|
||||
run: |
|
||||
testground run composition \
|
||||
-f ${{ inputs.composition_file }} \
|
||||
--metadata-repo "${GITHUB_REPOSITORY}" \
|
||||
|
@ -52,7 +76,9 @@ jobs:
|
|||
--collect-file ./result.tgz \
|
||||
--collect --wait
|
||||
env:
|
||||
GitReference: ${{ inputs.custom_git_reference }}
|
||||
GitReference: ${{ steps.resolve_reference.outputs.custom_git_sha || inputs.custom_git_reference }}
|
||||
GitTarget: ${{ inputs.custom_git_target }}
|
||||
InteropTarget: ${{ inputs.custom_interop_target }}
|
||||
- uses: actions/upload-artifact@v3
|
||||
if: ${{ failure() }}
|
||||
with:
|
||||
|
|
26
README.md
26
README.md
|
@ -9,10 +9,9 @@ This repository contains Testground test plans for libp2p components.
|
|||
|
||||
When a new version of libp2p is released, we want to make it permanent in the `ping/go` test folder.
|
||||
|
||||
1. In the `ping/_compositions/go-cross-versions.toml` file,
|
||||
- Find the group for the latest version (`v0.20` for example) and copy it into a new group (`v0.21` for example).
|
||||
- Update the `selectors` (go tags) and `modfile` options. Update the `build_base_image` if needed.
|
||||
- Increment the `total_instances` flag (near line 7).
|
||||
1. In the `ping/_compositions/go.toml` file,
|
||||
- copy the `[master]` section and turn it into a `[[groups]]` item
|
||||
- update the `[master]` section with the future version
|
||||
2. In the `ping/go` folder,
|
||||
- Add a new compatibility shim in `compat/` if needed, or add your new selector to the latest shim (see `compat/libp2p.v0.17.go` for example).
|
||||
- Create the new mod and sum files (`go.v0.21.mod` for example). Assuming you're updating from `v$A` to `v$B`, a simple way to do this is to:
|
||||
|
@ -21,8 +20,23 @@ When a new version of libp2p is released, we want to make it permanent in the `p
|
|||
- update the `go-libp2p` version, go version, and update the code if needed.
|
||||
- then `go get -tags v$B && go mod tidy`
|
||||
3. Run the test on your machine
|
||||
- Import the test-plans with `testground plan import ./ --name libp2p` (once, from the test-plans root)
|
||||
- Run with `testground run composition -f ping/_compositions/go-cross-versions.toml --wait`
|
||||
- Do once, from the test-plans root: import the test-plans with `testground plan import ./ --name libp2p`
|
||||
- Run the test with `testground run composition -f ping/_compositions/go-cross-versions.toml --wait`
|
||||
|
||||
## How to add a new version to ping/rust
|
||||
|
||||
When a new version of libp2p is released, we want to make it permanent in the `ping/rust` test folder.
|
||||
|
||||
1. In the `ping/_compositions/rust.toml` file,
|
||||
- Copy the `[master]` section and turn it into a item in the `[[groups]]` array
|
||||
- Update the `[master]` section with the new master version
|
||||
2. In the `ping/rust` folder,
|
||||
- `Cargo.toml`: update the feature flags `libp2pvxxx` to fix the released version and add the new `master`
|
||||
- `src/main.rs`: Update the `mod libp2p` definition with the new master
|
||||
- Run `cargo update` if needed. Try to build with `cargo build --features libp2pvxxx`
|
||||
3. Run the test on your machine
|
||||
- Do once, from the test-plans root: import the test-plans with `testground plan import ./ --name libp2p`
|
||||
- Run the test with `testground run composition -f ping/_compositions/rust-cross-versions.toml --wait`
|
||||
|
||||
## License
|
||||
|
||||
|
|
|
@ -1,10 +1,9 @@
|
|||
[metadata]
|
||||
name = "go-cross-versions {{ .Env.Reference }}"
|
||||
name = "go-cross-versions {{ .Env.GitReference }}"
|
||||
|
||||
[global]
|
||||
plan = "libp2p/ping/go"
|
||||
case = "ping"
|
||||
total_instances = {{ if .Env.GitReference }}7{{ else }}6{{ end }}
|
||||
builder = "docker:go"
|
||||
runner = "local:docker"
|
||||
|
||||
|
@ -14,108 +13,72 @@
|
|||
go_proxy_mode = "remote"
|
||||
go_proxy_url = "https://proxy.golang.org"
|
||||
|
||||
{{ with (load_resource "./go.toml" ) }}
|
||||
{{ range .groups }}
|
||||
[[groups]]
|
||||
id = "v0.11"
|
||||
id = "{{ .Id }}"
|
||||
instances = { count = 1 }
|
||||
|
||||
[groups.build]
|
||||
selectors = ['v0.11']
|
||||
selectors = ['{{ .Selector }}']
|
||||
|
||||
[groups.build_config]
|
||||
build_base_image = 'golang:1.14-buster'
|
||||
modfile = "go.v0.11.mod"
|
||||
|
||||
[[groups]]
|
||||
id = "v0.17"
|
||||
instances = { count = 1 }
|
||||
|
||||
[groups.build]
|
||||
selectors = ['v0.17']
|
||||
|
||||
[groups.build_config]
|
||||
build_base_image = 'golang:1.16-buster'
|
||||
modfile = "go.v0.17.mod"
|
||||
|
||||
[[groups]]
|
||||
id = "v0.19"
|
||||
instances = { count = 1 }
|
||||
|
||||
[groups.build]
|
||||
selectors = ['v0.19']
|
||||
|
||||
[groups.build_config]
|
||||
build_base_image = 'golang:1.17-buster'
|
||||
modfile = "go.v0.19.mod"
|
||||
|
||||
[[groups]]
|
||||
id = "v0.20"
|
||||
instances = { count = 1 }
|
||||
|
||||
[groups.build]
|
||||
selectors = ['v0.20']
|
||||
|
||||
[groups.build_config]
|
||||
build_base_image = 'golang:1.18-buster'
|
||||
modfile = "go.v0.20.mod"
|
||||
|
||||
[[groups]]
|
||||
id = "v0.21"
|
||||
instances = { count = 1 }
|
||||
|
||||
[groups.build]
|
||||
selectors = ['v0.21']
|
||||
|
||||
[groups.build_config]
|
||||
build_base_image = 'golang:1.18-buster'
|
||||
modfile = "go.v0.21.mod"
|
||||
build_base_image = 'golang:{{ .GoVersion }}-buster'
|
||||
modfile = "{{ .Modfile }}"
|
||||
{{ end }}
|
||||
|
||||
{{ with .master }}
|
||||
[[groups]]
|
||||
id = "master"
|
||||
instances = { count = 1 }
|
||||
|
||||
[groups.build]
|
||||
selectors = ['v0.21']
|
||||
selectors = ['{{ .Selector }}']
|
||||
|
||||
[[groups.build.dependencies]]
|
||||
module = "github.com/libp2p/go-libp2p"
|
||||
version = "master"
|
||||
|
||||
[groups.build_config]
|
||||
build_base_image = 'golang:1.18-buster'
|
||||
modfile = "go.v0.21.mod"
|
||||
build_base_image = 'golang:{{ .GoVersion }}-buster'
|
||||
modfile = "{{ .Modfile }}"
|
||||
|
||||
[groups.build_config.dockerfile_extensions]
|
||||
# deal with dependency changes in master until we create the new vx.y.z instance
|
||||
pre_build = """
|
||||
RUN cd ${PLAN_DIR} && \
|
||||
go mod download github.com/libp2p/go-libp2p && \
|
||||
go mod tidy -compat=1.18
|
||||
go mod tidy -compat={{ .GoVersion }}
|
||||
"""
|
||||
{{ end }}
|
||||
|
||||
{{ if .Env.GitReference }}
|
||||
{{ if $.Env.GitReference }}
|
||||
{{ with .custom }}
|
||||
[[groups]]
|
||||
id = "custom"
|
||||
instances = { count = 1 }
|
||||
|
||||
[groups.build]
|
||||
selectors = ['v0.20']
|
||||
selectors = ['{{ .Selector }}']
|
||||
|
||||
[[groups.build.dependencies]]
|
||||
module = "github.com/libp2p/go-libp2p"
|
||||
version = "{{ .Env.GitReference }}"
|
||||
{{ if .Env.GitTarget }}
|
||||
target = "{{ .Env.GitTarget }}"
|
||||
version = "{{ $.Env.GitReference }}"
|
||||
{{ if $.Env.GitTarget }}
|
||||
target = "{{ $.Env.GitTarget }}"
|
||||
{{ end }}
|
||||
|
||||
[groups.build_config]
|
||||
build_base_image = 'golang:1.18-buster'
|
||||
modfile = "go.v0.20.mod"
|
||||
build_base_image = 'golang:{{ .GoVersion }}-buster'
|
||||
modfile = "{{ .Modfile }}"
|
||||
|
||||
[groups.build_config.dockerfile_extensions]
|
||||
# deal with dependency changes in master until we create the new vx.y.z instance
|
||||
pre_build = """
|
||||
RUN cd ${PLAN_DIR} && \
|
||||
go mod download github.com/libp2p/go-libp2p && \
|
||||
go mod tidy -compat=1.18
|
||||
go mod tidy -compat={{ .GoVersion }}
|
||||
"""
|
||||
{{ end }}
|
||||
{{ end }}
|
||||
{{ end }}
|
|
@ -0,0 +1,113 @@
|
|||
[metadata]
|
||||
name = "go-rust-cross-version"
|
||||
|
||||
[global]
|
||||
plan = "libp2p/ping"
|
||||
case = "ping"
|
||||
runner = "local:docker"
|
||||
concurrent_builds = 1
|
||||
|
||||
[global.build_config]
|
||||
enable_go_build_cache = false # see https://github.com/testground/testground/issues/1361
|
||||
# disable testground's goproxy which hangs on github runners.
|
||||
go_proxy_mode = "remote"
|
||||
go_proxy_url = "https://proxy.golang.org"
|
||||
|
||||
{{ with (load_resource "./go.toml") }}
|
||||
{{ with .master }}
|
||||
[[groups]]
|
||||
id = "go-master"
|
||||
instances = { count = 1 }
|
||||
builder = "docker:go"
|
||||
|
||||
[groups.build]
|
||||
selectors = ['{{ .Selector }}']
|
||||
|
||||
[[groups.build.dependencies]]
|
||||
module = "github.com/libp2p/go-libp2p"
|
||||
version = "master"
|
||||
|
||||
[groups.build_config]
|
||||
path = "./go/"
|
||||
build_base_image = 'golang:{{ .GoVersion }}-buster'
|
||||
modfile = "{{ .Modfile }}"
|
||||
|
||||
[groups.build_config.dockerfile_extensions]
|
||||
# deal with dependency changes in master until we create the new vx.y.z instance
|
||||
pre_build = """
|
||||
RUN cd ${PLAN_DIR} && \
|
||||
go mod download github.com/libp2p/go-libp2p && \
|
||||
go mod tidy -compat={{ .GoVersion }}
|
||||
"""
|
||||
{{ end }}
|
||||
|
||||
{{ if eq $.Env.InteropTarget "go" }}
|
||||
{{ if $.Env.GitReference }}
|
||||
{{ with .custom }}
|
||||
[[groups]]
|
||||
id = "custom-go"
|
||||
instances = { count = 1 }
|
||||
builder = "docker:go"
|
||||
|
||||
[groups.build]
|
||||
selectors = ['{{ .Selector }}']
|
||||
|
||||
[[groups.build.dependencies]]
|
||||
module = "github.com/libp2p/go-libp2p"
|
||||
version = "{{ $.Env.GitReference }}"
|
||||
{{ if $.Env.GitTarget }}
|
||||
target = "{{ $.Env.GitTarget }}"
|
||||
{{ end }}
|
||||
|
||||
[groups.build_config]
|
||||
path = "./go/"
|
||||
build_base_image = 'golang:{{ .GoVersion }}-buster'
|
||||
modfile = "{{ .Modfile }}"
|
||||
|
||||
[groups.build_config.dockerfile_extensions]
|
||||
# deal with dependency changes in master until we create the new vx.y.z instance
|
||||
pre_build = """
|
||||
RUN cd ${PLAN_DIR} && \
|
||||
go mod download github.com/libp2p/go-libp2p && \
|
||||
go mod tidy -compat={{ .GoVersion }}
|
||||
"""
|
||||
{{ end }}
|
||||
{{ end }}
|
||||
{{ end }}
|
||||
{{ end }}
|
||||
|
||||
{{ with (load_resource "./rust.toml") }}
|
||||
{{ with .master }}
|
||||
[[groups]]
|
||||
id = "rust-master"
|
||||
instances = { count = 1 }
|
||||
builder = "docker:generic"
|
||||
|
||||
[groups.build_config]
|
||||
path = "./rust/"
|
||||
|
||||
[groups.build_config.build_args]
|
||||
CARGO_FEATURES = '{{ .CargoFeatures }}'
|
||||
{{ end }}
|
||||
|
||||
{{ if eq $.Env.InteropTarget "rust" }}
|
||||
{{ if $.Env.GitReference }}
|
||||
{{ with .custom }}
|
||||
[[groups]]
|
||||
id = "custom-rust"
|
||||
instances = { count = 1 }
|
||||
builder = "docker:generic"
|
||||
|
||||
[groups.build_config]
|
||||
path = "./rust/"
|
||||
|
||||
[groups.build_config.build_args]
|
||||
CARGO_FEATURES = '{{ .CargoFeatures }}'
|
||||
CARGO_REMOVE = '{{ .CargoFeatures }}'
|
||||
CARGO_PATCH = """
|
||||
{{ .CargoFeatures }} = {package = "libp2p", git = "https://{{ or $.Env.GitTarget "github.com/libp2p/rust-libp2p" }}", rev = "{{ $.Env.GitReference }}", default_features = false, features = [ "websocket", "mplex", "yamux", "tcp-async-io", "ping", "noise", "dns-async-std" ], version = "0.47.0", optional = true}
|
||||
"""
|
||||
{{ end }}
|
||||
{{ end }}
|
||||
{{ end }}
|
||||
{{ end }}
|
|
@ -0,0 +1,141 @@
|
|||
[metadata]
|
||||
name = "go-rust-cross-version"
|
||||
|
||||
[global]
|
||||
plan = "libp2p/ping"
|
||||
case = "ping"
|
||||
runner = "local:docker"
|
||||
concurrent_builds = 1
|
||||
|
||||
[global.build_config]
|
||||
enable_go_build_cache = false # see https://github.com/testground/testground/issues/1361
|
||||
# disable testground's goproxy which hangs on github runners.
|
||||
go_proxy_mode = "remote"
|
||||
go_proxy_url = "https://proxy.golang.org"
|
||||
|
||||
{{ with (load_resource "./go.toml") }}
|
||||
{{ range .groups }}
|
||||
[[groups]]
|
||||
id = "{{ .Id }}"
|
||||
instances = { count = 1 }
|
||||
builder = "docker:go"
|
||||
|
||||
[groups.build]
|
||||
selectors = ['{{ .Selector }}']
|
||||
|
||||
[groups.build_config]
|
||||
path = "./go/"
|
||||
build_base_image = 'golang:{{ .GoVersion }}-buster'
|
||||
modfile = "{{ .Modfile }}"
|
||||
{{ end }}
|
||||
|
||||
{{ with .master }}
|
||||
[[groups]]
|
||||
id = "master"
|
||||
instances = { count = 1 }
|
||||
builder = "docker:go"
|
||||
|
||||
[groups.build]
|
||||
selectors = ['{{ .Selector }}']
|
||||
|
||||
[[groups.build.dependencies]]
|
||||
module = "github.com/libp2p/go-libp2p"
|
||||
version = "master"
|
||||
|
||||
[groups.build_config]
|
||||
path = "./go/"
|
||||
build_base_image = 'golang:{{ .GoVersion }}-buster'
|
||||
modfile = "{{ .Modfile }}"
|
||||
|
||||
[groups.build_config.dockerfile_extensions]
|
||||
# deal with dependency changes in master until we create the new vx.y.z instance
|
||||
pre_build = """
|
||||
RUN cd ${PLAN_DIR} && \
|
||||
go mod download github.com/libp2p/go-libp2p && \
|
||||
go mod tidy -compat={{ .GoVersion }}
|
||||
"""
|
||||
{{ end }}
|
||||
|
||||
{{ if eq $.Env.InteropTarget "go" }}
|
||||
{{ if $.Env.GitReference }}
|
||||
{{ with .custom }}
|
||||
[[groups]]
|
||||
id = "custom-go"
|
||||
instances = { count = 1 }
|
||||
builder = "docker:go"
|
||||
|
||||
[groups.build]
|
||||
selectors = ['{{ .Selector }}']
|
||||
|
||||
[[groups.build.dependencies]]
|
||||
module = "github.com/libp2p/go-libp2p"
|
||||
version = "{{ $.Env.GitReference }}"
|
||||
{{ if $.Env.GitTarget }}
|
||||
target = "{{ $.Env.GitTarget }}"
|
||||
{{ end }}
|
||||
|
||||
[groups.build_config]
|
||||
path = "./go/"
|
||||
build_base_image = 'golang:{{ .GoVersion }}-buster'
|
||||
modfile = "{{ .Modfile }}"
|
||||
|
||||
[groups.build_config.dockerfile_extensions]
|
||||
# deal with dependency changes in master until we create the new vx.y.z instance
|
||||
pre_build = """
|
||||
RUN cd ${PLAN_DIR} && \
|
||||
go mod download github.com/libp2p/go-libp2p && \
|
||||
go mod tidy -compat={{ .GoVersion }}
|
||||
"""
|
||||
{{ end }}
|
||||
{{ end }}
|
||||
{{ end }}
|
||||
{{ end }}
|
||||
|
||||
{{ with (load_resource "./rust.toml") }}
|
||||
{{ range .groups }}
|
||||
[[groups]]
|
||||
id = "rust-{{ .Id }}"
|
||||
instances = { count = 1 }
|
||||
builder = "docker:generic"
|
||||
|
||||
[groups.build_config]
|
||||
path = "./rust/"
|
||||
|
||||
[groups.build_config.build_args]
|
||||
CARGO_FEATURES = '{{ .CargoFeatures }}'
|
||||
{{ end }}
|
||||
|
||||
{{ with .master }}
|
||||
[[groups]]
|
||||
id = "rust-master"
|
||||
instances = { count = 1 }
|
||||
builder = "docker:generic"
|
||||
|
||||
[groups.build_config]
|
||||
path = "./rust/"
|
||||
|
||||
[groups.build_config.build_args]
|
||||
CARGO_FEATURES = '{{ .CargoFeatures }}'
|
||||
{{ end }}
|
||||
|
||||
{{ if eq $.Env.InteropTarget "rust" }}
|
||||
{{ if $.Env.GitReference }}
|
||||
{{ with .custom }}
|
||||
[[groups]]
|
||||
id = "custom-rust"
|
||||
instances = { count = 1 }
|
||||
builder = "docker:generic"
|
||||
|
||||
[groups.build_config]
|
||||
path = "./rust/"
|
||||
|
||||
[groups.build_config.build_args]
|
||||
CARGO_FEATURES = '{{ .CargoFeatures }}'
|
||||
CARGO_REMOVE = '{{ .CargoFeatures }}'
|
||||
CARGO_PATCH = """
|
||||
{{ .CargoFeatures }} = {package = "libp2p", git = "https://{{ or $.Env.GitTarget "github.com/libp2p/rust-libp2p" }}", rev = "{{ $.Env.GitReference }}", default_features = false, features = [ "websocket", "mplex", "yamux", "tcp-async-io", "ping", "noise", "dns-async-std" ], version = "0.47.0", optional = true}
|
||||
"""
|
||||
{{ end }}
|
||||
{{ end }}
|
||||
{{ end }}
|
||||
{{ end }}
|
|
@ -0,0 +1,39 @@
|
|||
[master]
|
||||
GoVersion = '1.18'
|
||||
Modfile = "go.v0.21.mod"
|
||||
Selector = 'v0.21'
|
||||
|
||||
[custom]
|
||||
GoVersion = '1.18'
|
||||
Modfile = "go.v0.21.mod"
|
||||
Selector = 'v0.21'
|
||||
|
||||
[[groups]]
|
||||
Id = "v0.11"
|
||||
GoVersion = '1.14'
|
||||
Modfile = "go.v0.11.mod"
|
||||
Selector = 'v0.11'
|
||||
|
||||
[[groups]]
|
||||
Id = "v0.17"
|
||||
GoVersion = '1.16'
|
||||
Modfile = "go.v0.17.mod"
|
||||
Selector = 'v0.17'
|
||||
|
||||
[[groups]]
|
||||
Id = "v0.19"
|
||||
GoVersion = '1.17'
|
||||
Modfile = "go.v0.19.mod"
|
||||
Selector = 'v0.19'
|
||||
|
||||
[[groups]]
|
||||
Id = "v0.20"
|
||||
GoVersion = '1.18'
|
||||
Modfile = "go.v0.20.mod"
|
||||
Selector = 'v0.20'
|
||||
|
||||
[[groups]]
|
||||
Id = "v0.21"
|
||||
GoVersion = '1.18'
|
||||
Modfile = "go.v0.21.mod"
|
||||
Selector = 'v0.21'
|
|
@ -0,0 +1,44 @@
|
|||
[metadata]
|
||||
name = "rust-cross-versions-{{ $.Env.GitReference }}"
|
||||
|
||||
[global]
|
||||
plan = "libp2p/ping/rust"
|
||||
case = "ping"
|
||||
builder = "docker:generic"
|
||||
runner = "local:docker"
|
||||
concurrent_builds = 1
|
||||
|
||||
{{ with (load_resource "./rust.toml" ) }}
|
||||
{{ range .groups }}
|
||||
[[groups]]
|
||||
id = "{{ .Id }}"
|
||||
instances = { count = 1 }
|
||||
|
||||
[groups.build_config.build_args]
|
||||
CARGO_FEATURES = '{{ .CargoFeatures }}'
|
||||
{{ end }}
|
||||
|
||||
{{ with .master }}
|
||||
[[groups]]
|
||||
id = "master"
|
||||
instances = { count = 1 }
|
||||
|
||||
[groups.build_config.build_args]
|
||||
CARGO_FEATURES = '{{ .CargoFeatures }}'
|
||||
{{ end }}
|
||||
|
||||
{{ if $.Env.GitReference }}
|
||||
{{ with .custom }}
|
||||
[[groups]]
|
||||
id = "custom"
|
||||
instances = { count = 1 }
|
||||
|
||||
[groups.build_config.build_args]
|
||||
CARGO_FEATURES = '{{ .CargoFeatures }}'
|
||||
CARGO_REMOVE = '{{ .CargoFeatures }}'
|
||||
CARGO_PATCH = """
|
||||
{{ .CargoFeatures }} = {package = "libp2p", git = "https://{{ or $.Env.GitTarget "github.com/libp2p/rust-libp2p" }}", rev = "{{ $.Env.GitReference }}", default_features = false, features = [ "websocket", "mplex", "yamux", "tcp-async-io", "ping", "noise", "dns-async-std" ], version = "0.47.0", optional = true}
|
||||
"""
|
||||
{{ end }}
|
||||
{{ end }}
|
||||
{{ end }}
|
|
@ -0,0 +1,17 @@
|
|||
[[groups]]
|
||||
Id = "v0.44.0"
|
||||
CargoFeatures = 'libp2pv0440'
|
||||
|
||||
[[groups]]
|
||||
Id = "v0.45.1"
|
||||
CargoFeatures = 'libp2pv0450'
|
||||
|
||||
[[groups]]
|
||||
Id = "v0.46.0"
|
||||
CargoFeatures = 'libp2pv0460'
|
||||
|
||||
[master]
|
||||
CargoFeatures = 'libp2pv0470'
|
||||
|
||||
[custom]
|
||||
CargoFeatures = 'libp2pv0470'
|
|
@ -0,0 +1,23 @@
|
|||
name = "compatibility-rust-and-go"
|
||||
|
||||
[defaults]
|
||||
builder = "docker:generic"
|
||||
runner = "local:docker"
|
||||
|
||||
[builders."docker:generic"]
|
||||
enabled = true
|
||||
|
||||
[builders."docker:go"]
|
||||
enabled = true
|
||||
|
||||
[runners."local:docker"]
|
||||
enabled = true
|
||||
|
||||
[[testcases]]
|
||||
name = "ping"
|
||||
instances = { min = 2, max = 10000, default = 5 }
|
||||
|
||||
[testcases.params]
|
||||
secure_channel = { type = "enum", desc = "secure channel used", values = ["noise"], default = "noise" }
|
||||
max_latency_ms = { type = "int", desc = "maximum value for random local link latency", unit = "ms", default = 1000 }
|
||||
iterations = { type = "int", desc = "number of ping iterations we'll run against each peer", unit = "count", default = 5 }
|
|
@ -0,0 +1 @@
|
|||
/target
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,26 @@
|
|||
[package]
|
||||
edition = "2021"
|
||||
name = "testplan"
|
||||
version = "0.1.0"
|
||||
|
||||
[dependencies]
|
||||
async-std = {version = "1.10", features = ["attributes", "tokio1"]}
|
||||
env_logger = "0.9.0"
|
||||
if-addrs = "0.7.0"
|
||||
ipnetwork = {version = "0.19.0", default-features = false, features = ["serde"]}
|
||||
log = "0.4"
|
||||
rand = "0.8"
|
||||
serde = {version = "1", features = ["derive"]}
|
||||
serde_json = "1"
|
||||
soketto = "0.7.1"
|
||||
testground = {git = "https://github.com/testground/sdk-rust", branch = "master", version = "0.4.0"}
|
||||
thiserror = "1"
|
||||
tokio = { version = "1", default-features = false, features = ["sync", "rt-multi-thread", "macros", "net"] }
|
||||
tokio-stream = { version = "0.1", default-features = false, features = [] }
|
||||
tokio-util = { version = "0.7", default-features = false, features = ["compat"] }
|
||||
futures = "0.3.1"
|
||||
|
||||
libp2pv0440 = {package = "libp2p", default_features = false, features = [ "websocket", "mplex", "yamux", "tcp-async-io", "ping", "noise", "dns-async-std" ], version = "0.44.0", optional = true}
|
||||
libp2pv0450 = {package = "libp2p", default_features = false, features = [ "websocket", "mplex", "yamux", "tcp-async-io", "ping", "noise", "dns-async-std" ], version = "0.45.0", optional = true}
|
||||
libp2pv0460 = {package = "libp2p", default_features = false, features = [ "websocket", "mplex", "yamux", "tcp-async-io", "ping", "noise", "dns-async-std" ], version = "0.46.0", optional = true}
|
||||
libp2pv0470 = {package = "libp2p", git = "https://github.com/libp2p/rust-libp2p", branch = "master", default_features = false, features = [ "websocket", "mplex", "yamux", "tcp-async-io", "ping", "noise", "dns-async-std" ], version = "0.47.0", optional = true}
|
|
@ -0,0 +1,46 @@
|
|||
FROM rust:1.62-bullseye as builder
|
||||
WORKDIR /usr/src/testplan
|
||||
|
||||
RUN apt-get update && apt-get install -y cmake protobuf-compiler
|
||||
|
||||
ARG PLAN_PATH="./"
|
||||
|
||||
# Cache dependencies between test runs, see testground examples.
|
||||
RUN mkdir -p ./plan/src/
|
||||
RUN echo "fn main() { println!(\"If you see this message, you may want to clean up the target directory or the Docker build cache.\") }" > ./plan/src/main.rs
|
||||
COPY ./plan/${PLAN_PATH}/Cargo.lock ./plan/${PLAN_PATH}/Cargo.toml ./plan/
|
||||
|
||||
RUN cd ./plan/ && \
|
||||
cargo update --dry-run && \
|
||||
cargo fetch && \
|
||||
# use a default feature to rely on docker caching.
|
||||
cargo build --release --features "libp2pv0450"
|
||||
|
||||
ARG CARGO_PATCH=""
|
||||
ARG CARGO_REMOVE=""
|
||||
|
||||
RUN if [ ! -z "${CARGO_REMOVE}" ]; then sed -i "s/^${CARGO_REMOVE}.*//" ./plan/Cargo.toml; fi
|
||||
RUN echo "${CARGO_PATCH}" >> ./plan/Cargo.toml
|
||||
|
||||
# Backup Cargo file to preserve patches.
|
||||
RUN cp ./plan/Cargo.toml ./plan/Cargo.lock /tmp/
|
||||
|
||||
COPY ./plan/${PLAN_PATH} ./plan
|
||||
|
||||
# This is in order to make sure `main.rs`s mtime timestamp is updated to avoid the dummy `main`
|
||||
# remaining in the release binary.
|
||||
# https://github.com/rust-lang/cargo/issues/9598
|
||||
RUN touch ./plan/src/main.rs
|
||||
|
||||
RUN mv /tmp/Cargo.toml /tmp/Cargo.lock ./plan
|
||||
|
||||
ARG CARGO_FEATURES=""
|
||||
|
||||
RUN cd ./plan/ && \
|
||||
cargo build --release --features="${CARGO_FEATURES}"
|
||||
|
||||
FROM debian:bullseye-slim
|
||||
COPY --from=builder /usr/src/testplan/plan/target/release/testplan /usr/local/bin/testplan
|
||||
EXPOSE 6060
|
||||
ENV RUST_BACKTRACE=1
|
||||
ENTRYPOINT ["testplan"]
|
|
@ -0,0 +1,19 @@
|
|||
name = "compatibility-rust"
|
||||
|
||||
[defaults]
|
||||
builder = "docker:generic"
|
||||
runner = "local:docker"
|
||||
|
||||
[builders."docker:generic"]
|
||||
enabled = true
|
||||
|
||||
[runners."local:docker"]
|
||||
enabled = true
|
||||
|
||||
[[testcases]]
|
||||
name = "ping"
|
||||
instances = { min = 2, max = 10000, default = 5 }
|
||||
|
||||
[testcases.params]
|
||||
max_latency_ms = { type = "int", desc = "maximum value for random local link latency", unit = "ms", default = 1000 }
|
||||
iterations = { type = "int", desc = "number of ping iterations we'll run against each peer", unit = "count", default = 5 }
|
|
@ -0,0 +1,230 @@
|
|||
use std::borrow::Cow;
|
||||
use std::collections::HashSet;
|
||||
use std::str::FromStr;
|
||||
use std::time::Duration;
|
||||
|
||||
use env_logger::Env;
|
||||
use log::info;
|
||||
use rand::Rng;
|
||||
use testground::network_conf::{
|
||||
FilterAction, LinkShape, NetworkConfiguration, RoutingPolicyType, DEFAULT_DATA_NETWORK,
|
||||
};
|
||||
|
||||
pub mod libp2p {
|
||||
#[cfg(all(feature = "libp2pv0470",))]
|
||||
pub use libp2pv0470::*;
|
||||
|
||||
#[cfg(all(feature = "libp2pv0460",))]
|
||||
pub use libp2pv0460::*;
|
||||
|
||||
#[cfg(all(feature = "libp2pv0450",))]
|
||||
pub use libp2pv0450::*;
|
||||
|
||||
#[cfg(all(feature = "libp2pv0440",))]
|
||||
pub use libp2pv0440::*;
|
||||
}
|
||||
|
||||
use libp2p::futures::future::ready;
|
||||
use libp2p::futures::{FutureExt, StreamExt};
|
||||
use libp2p::swarm::{Swarm, SwarmEvent};
|
||||
use libp2p::{development_transport, identity, multiaddr::Protocol, ping, Multiaddr, PeerId};
|
||||
|
||||
const LISTENING_PORT: u16 = 1234;
|
||||
|
||||
#[async_std::main]
|
||||
async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
env_logger::Builder::from_env(Env::default().default_filter_or("info")).init();
|
||||
|
||||
let client = testground::client::Client::new_and_init().await?;
|
||||
|
||||
let mut swarm = {
|
||||
let local_key = identity::Keypair::generate_ed25519();
|
||||
let local_peer_id = PeerId::from(local_key.public());
|
||||
info!("Local peer id: {:?}", local_peer_id);
|
||||
|
||||
Swarm::new(
|
||||
development_transport(local_key).await?,
|
||||
ping::Behaviour::new(
|
||||
ping::Config::new()
|
||||
.with_interval(Duration::from_secs(10))
|
||||
.with_keep_alive(true),
|
||||
),
|
||||
local_peer_id,
|
||||
)
|
||||
};
|
||||
|
||||
let local_addr: Multiaddr = {
|
||||
let ip_addr = match if_addrs::get_if_addrs()
|
||||
.unwrap()
|
||||
.into_iter()
|
||||
.find(|iface| iface.name == "eth1")
|
||||
.unwrap()
|
||||
.addr
|
||||
.ip()
|
||||
{
|
||||
std::net::IpAddr::V4(addr) => addr,
|
||||
std::net::IpAddr::V6(_) => unimplemented!(),
|
||||
};
|
||||
|
||||
Multiaddr::empty()
|
||||
.with(Protocol::Ip4(ip_addr))
|
||||
.with(Protocol::Tcp(LISTENING_PORT))
|
||||
};
|
||||
|
||||
info!(
|
||||
"Test instance, listening for incoming connections on: {:?}.",
|
||||
local_addr
|
||||
);
|
||||
swarm.listen_on(local_addr.clone())?;
|
||||
match swarm.next().await.unwrap() {
|
||||
SwarmEvent::NewListenAddr { address, .. } if address == local_addr => {}
|
||||
e => panic!("Unexpected event {:?}", e),
|
||||
}
|
||||
|
||||
let mut address_stream = client
|
||||
.subscribe("peers")
|
||||
.await
|
||||
.take(client.run_parameters().test_instance_count as usize)
|
||||
.map(|a| {
|
||||
let value = a.unwrap();
|
||||
let addr = value["Addrs"][0].as_str().unwrap();
|
||||
Multiaddr::from_str(addr).unwrap()
|
||||
})
|
||||
// Note: we sidestep simultaneous connect issues by ONLY connecting to peers
|
||||
// who published their addresses before us (this is enough to dedup and avoid
|
||||
// two peers dialling each other at the same time).
|
||||
//
|
||||
// We can do this because sync service pubsub is ordered.
|
||||
.take_while(|a| ready(a != &local_addr));
|
||||
|
||||
let payload = serde_json::json!({
|
||||
"ID": swarm.local_peer_id().to_string(),
|
||||
"Addrs": [
|
||||
local_addr.to_string(),
|
||||
],
|
||||
});
|
||||
|
||||
client.publish("peers", Cow::Owned(payload)).await?;
|
||||
|
||||
while let Some(addr) = address_stream.next().await {
|
||||
swarm.dial(addr).unwrap();
|
||||
}
|
||||
|
||||
// Otherwise the testground background task gets blocked sending
|
||||
// subscription upgrades to the backpressured channel.
|
||||
drop(address_stream);
|
||||
|
||||
info!("Wait to connect to each peer.");
|
||||
let mut connected = HashSet::new();
|
||||
while connected.len() < client.run_parameters().test_instance_count as usize - 1 {
|
||||
let event = swarm.next().await.unwrap();
|
||||
info!("Event: {:?}", event);
|
||||
if let SwarmEvent::ConnectionEstablished { peer_id, .. } = event {
|
||||
connected.insert(peer_id);
|
||||
}
|
||||
}
|
||||
|
||||
signal_wait_and_drive_swarm(&client, &mut swarm, "connected".to_string()).await?;
|
||||
|
||||
ping(&client, &mut swarm, "initial".to_string()).await?;
|
||||
|
||||
let iterations: usize = client
|
||||
.run_parameters()
|
||||
.test_instance_params
|
||||
.get("iterations")
|
||||
.unwrap()
|
||||
.parse()
|
||||
.unwrap();
|
||||
let max_latency_ms: u64 = client
|
||||
.run_parameters()
|
||||
.test_instance_params
|
||||
.get("max_latency_ms")
|
||||
.unwrap()
|
||||
.parse()
|
||||
.unwrap();
|
||||
|
||||
for i in 1..iterations + 1 {
|
||||
client.record_message(format!("⚡️ ITERATION ROUND {}", i));
|
||||
|
||||
let latency = Duration::from_millis(rand::thread_rng().gen_range(0..max_latency_ms))
|
||||
.as_nanos()
|
||||
.try_into()
|
||||
.unwrap();
|
||||
|
||||
let network_conf = NetworkConfiguration {
|
||||
network: DEFAULT_DATA_NETWORK.to_owned(),
|
||||
ipv4: None,
|
||||
ipv6: None,
|
||||
enable: true,
|
||||
default: LinkShape {
|
||||
latency,
|
||||
jitter: 0,
|
||||
bandwidth: 0,
|
||||
filter: FilterAction::Accept,
|
||||
loss: 0.0,
|
||||
corrupt: 0.0,
|
||||
corrupt_corr: 0.0,
|
||||
reorder: 0.0,
|
||||
reorder_corr: 0.0,
|
||||
duplicate: 0.0,
|
||||
duplicate_corr: 0.0,
|
||||
},
|
||||
rules: None,
|
||||
callback_state: format!("network-configured-{}", i),
|
||||
callback_target: Some(client.run_parameters().test_instance_count),
|
||||
routing_policy: RoutingPolicyType::AllowAll,
|
||||
};
|
||||
|
||||
client.configure_network(network_conf).await.unwrap();
|
||||
|
||||
ping(&client, &mut swarm, format!("done-{}", i)).await?;
|
||||
}
|
||||
|
||||
client.record_success().await?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn ping(
|
||||
client: &testground::client::Client,
|
||||
swarm: &mut Swarm<ping::Behaviour>,
|
||||
tag: String,
|
||||
) -> Result<(), Box<dyn std::error::Error>> {
|
||||
info!("Wait to receive ping from each peer.");
|
||||
let mut pinged = HashSet::new();
|
||||
while pinged.len() < client.run_parameters().test_instance_count as usize - 1 {
|
||||
let event = swarm.next().await.unwrap();
|
||||
info!("Event: {:?}", event);
|
||||
if let SwarmEvent::Behaviour(ping::PingEvent {
|
||||
peer,
|
||||
result: Ok(ping::PingSuccess::Ping { .. }),
|
||||
}) = event
|
||||
{
|
||||
pinged.insert(peer);
|
||||
}
|
||||
}
|
||||
|
||||
signal_wait_and_drive_swarm(client, swarm, tag).await
|
||||
}
|
||||
|
||||
async fn signal_wait_and_drive_swarm(
|
||||
client: &testground::client::Client,
|
||||
swarm: &mut Swarm<ping::Behaviour>,
|
||||
tag: String,
|
||||
) -> Result<(), Box<dyn std::error::Error>> {
|
||||
info!(
|
||||
"Signal and wait for all peers to signal being done with \"{}\".",
|
||||
tag
|
||||
);
|
||||
swarm
|
||||
.take_until(
|
||||
client
|
||||
.signal_and_wait(tag, client.run_parameters().test_instance_count)
|
||||
.boxed_local(),
|
||||
)
|
||||
.map(|event| info!("Event: {:?}", event))
|
||||
.collect::<Vec<()>>()
|
||||
.await;
|
||||
|
||||
Ok(())
|
||||
}
|
Loading…
Reference in New Issue