Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 40 additions & 0 deletions .github/workflows/test-rpc-template.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
name: test-rpc-template

on:
workflow_call:
inputs:
namespace:
required: true
type: string
script:
required: true
type: string

jobs:
run-tests:
runs-on: ubuntu-latest
steps:
- name: Check out repository
uses: actions/checkout@v4

- name: Install wrk
run: |
git clone https://github.com/wg/wrk.git
cd wrk
make
sudo cp wrk /usr/local/bin

- name: Run wrk
run: chmod u+x ${{ inputs.script }} && bash ${{ inputs.script }}
working-directory: tests/stress-testing/scripts/${{ inputs.namespace }}

- name: Install wrk2
run: |
git clone https://github.com/giltene/wrk2.git
cd wrk2
make
sudo cp wrk /usr/local/bin/wrk2

- name: Run wrk2
run: chmod u+x ${{ inputs.script }} && bash ${{ inputs.script }}
working-directory: tests/stress-testing/scripts/${{ inputs.namespace }}
25 changes: 25 additions & 0 deletions .github/workflows/test-rpc.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
name: test-rpc

on:
push:
branches:
- ns/wrk-rpc-test
# schedule:
# - cron: '*/5 * * * *'
workflow_dispatch:
with:
ref: ns/wrk-rpc-test


jobs:
eth:
uses: ./.github/workflows/test-rpc-template.yml
with:
namespace: eth
script: eth.sh

zkevm:
uses: ./.github/workflows/test-rpc-template.yml
with:
namespace: zkevm
script: zkevm.sh
30 changes: 30 additions & 0 deletions tests/stress-testing/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
FROM ubuntu:22.04 AS builder

RUN apt-get update && apt-get install -y \
build-essential \
libssl-dev \
git \
zlib1g-dev \
&& rm -rf /var/lib/apt/lists/*

WORKDIR /build

#https://github.com/giltene/wrk2.git
#https://github.com/kinvolk/wrk2.git
#https://github.com/AmpereTravis/wrk2-aarch64
RUN git clone https://github.com/AmpereTravis/wrk2-aarch64 && \
cd wrk2-aarch64 && \
make

FROM ubuntu:22.04

RUN apt-get update && apt-get install -y \
libssl3 \
netbase \
&& rm -rf /var/lib/apt/lists/*

COPY --from=builder /build/wrk2-aarch64/wrk /usr/local/bin/wrk2

WORKDIR /scripts

ENTRYPOINT ["/bin/sh"]
12 changes: 12 additions & 0 deletions tests/stress-testing/docker-compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
version: '3.8'

services:
eth:
build:
context: .
dockerfile: Dockerfile
container_name: eth
volumes:
- ./scripts:/scripts
command: ["-c", "cd /scripts/eth && /bin/bash eth.sh"]
network_mode: "host"
32 changes: 32 additions & 0 deletions tests/stress-testing/scripts/eth/accounts.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
dofile("common.lua")
methodName = "eth_accounts"
wrk.method = "POST"
wrk.headers["Content-Type"] = "application/json"

threads = {}
counter = 1

setup = function(thread)
thread:set("t_id",counter)
counter = counter + 1
thread:set("counter_invalid", 0)
thread:set("counter_valid", 0)
thread:set("counter_failed", 0)
table.insert(threads,thread)
math.randomseed(os.time()+counter)
end

request = function()
local filter = "0xc9000000000000000fff66454582cd83"
local body = string.format('{"jsonrpc":"2.0","method":"%s","params":["%s"],"id":1}', methodName, filter)
--print(body)
headers = {}
headers["Content-Type"] = "application/json"
return wrk.format("POST",nil,headers,body)
end

response = handle_response

done = function(summary, latency, requests)
print_summary(summary, latency, requests, threads, methodName)
end
31 changes: 31 additions & 0 deletions tests/stress-testing/scripts/eth/blockNumber.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
dofile("common.lua")
methodName = "eth_blockNumber"
wrk.method = "POST"
wrk.headers["Content-Type"] = "application/json"

threads = {}
counter = 1

setup = function(thread)
thread:set("t_id",counter)
counter = counter + 1
thread:set("counter_invalid", 0)
thread:set("counter_valid", 0)
thread:set("counter_failed", 0)
table.insert(threads,thread)
math.randomseed(os.time()+counter)
end

request = function()
local body = string.format('{"jsonrpc":"2.0","method":"%s","params":[],"id":1}', methodName)
-- print(body)
headers = {}
headers["Content-Type"] = "application/json"
return wrk.format("POST",nil,headers,body)
end

response = handle_response

done = function(summary, latency, requests)
print_summary(summary, latency, requests, threads, methodName)
end
35 changes: 35 additions & 0 deletions tests/stress-testing/scripts/eth/call.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
dofile("common.lua")
methodName = "eth_call"
wrk.method = "POST"
wrk.headers["Content-Type"] = "application/json"

threads = {}
counter = 1

setup = function(thread)
thread:set("t_id",counter)
counter = counter + 1
thread:set("counter_invalid", 0)
thread:set("counter_valid", 0)
thread:set("counter_failed", 0)
table.insert(threads,thread)
math.randomseed(os.time()+counter)
end

request = function()
local from = "0x5075ff68a0efb54db13423ad924bd680327d305e"
local to = "0xcd5f731b3b77737743f80a3d4b0722b710f549cb"
local gasPrice = "0x0"
local data = "0x3a4b66f1"
local body = string.format('{"jsonrpc":"2.0","method":"%s","params":[{"from":"%s","to":"%s","gasPrice":"%s", "data":"%s"},"latest"],"id":1}', methodName, from, to,gasPrice, data)
-- print(body)
headers = {}
headers["Content-Type"] = "application/json"
return wrk.format("POST",nil,headers,body)
end

response = handle_response

done = function(summary, latency, requests)
print_summary(summary, latency, requests, threads, methodName)
end
31 changes: 31 additions & 0 deletions tests/stress-testing/scripts/eth/chainId.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
dofile("common.lua")
methodName = "eth_chainId"
wrk.method = "POST"
wrk.headers["Content-Type"] = "application/json"

threads = {}
counter = 1

setup = function(thread)
thread:set("t_id",counter)
counter = counter + 1
thread:set("counter_invalid", 0)
thread:set("counter_valid", 0)
thread:set("counter_failed", 0)
table.insert(threads,thread)
math.randomseed(os.time()+counter)
end

request = function()
local body = string.format('{"jsonrpc":"2.0","method":"%s","params":[],"id":1}', methodName)
-- print(body)
headers = {}
headers["Content-Type"] = "application/json"
return wrk.format("POST",nil,headers,body)
end

response = handle_response

done = function(summary, latency, requests)
print_summary(summary, latency, requests, threads, methodName)
end
77 changes: 77 additions & 0 deletions tests/stress-testing/scripts/eth/common.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
function print_summary(summary, latency, requests, threads, methodName)
local x4 = 0
failTotal = 0
sucTotal = 0
if (threads ~= nil) then
for index, thread in pairs(threads) do
local counter_invalid = thread:get("counter_invalid")
local counter_valid = thread:get("counter_valid")
local counter_failed = thread:get("counter_failed")
print(string.format("thread%d counter: %d", index, counter_failed))
failTotal = failTotal + counter_invalid
sucTotal = sucTotal + counter_valid
x4 = x4 + counter_failed
end
end

local durations = summary.duration / 1000000 -- Execution time in seconds
local errors = summary.errors.status -- HTTP status codes not starting with 200 or 300
local requests = summary.requests -- Total number of requests
local valid = requests - x4 -- Valid requests = total - failed
local connect = summary.errors.connect
local read1 = summary.errors.read
local write1 = summary.errors.write
local timeout = summary.errors.timeout
local errorRate = (x4/requests)*100
errorRate = string.format("%.1f",errorRate)

io.write("+++++++++++++++++++++++++++++++++++++\n")
io.write(" "..string.format("%s",methodName).."\n")
io.write(" Test duration: "..string.format("%.2f",durations).."s".."\n")
io.write(" Avg response time: "..string.format("%.2f",latency.mean / 1000).."ms".."\n")
io.write(" Min response time: "..(latency.min / 1000).."ms".."\n")
io.write(" Max response time: "..(latency.max / 1000).."ms".."\n")
io.write(" Total requests: "..summary.requests.."\n")
io.write(" Failed requests: "..x4.."\n")
io.write(" Valid requests: "..valid.."\n")
io.write(" Error rate: "..errorRate.."%\n")
io.write(" Queries per second: "..string.format("%.2f",valid / durations).."\n")
io.write(" Response assert failed: "..failTotal.."\n")
io.write(" Response assert success: "..sucTotal.."\n")
io.write("+++++++++++++++++++++++++++++++++++++\n")
end

function handle_response(status, headers, body)
local counter_invalid = wrk.thread:get("counter_invalid")
local counter_valid = wrk.thread:get("counter_valid")
local counter_failed = wrk.thread:get("counter_failed")
if string.find(body,'"error":') then
counter_invalid = counter_invalid + 1
-- print("Error response")
-- print("Status: " .. status)
-- print("Body: " .. body)
-- print(1,body," ", "SET ",counter)
elseif string.find(body,'"result":') then
counter_valid = counter_valid + 1
-- print(2,body)
elseif not string.find(body,'"jsonrpc":') then
counter_failed = counter_failed + 1
-- print("RPC call failed")
-- print("Status: " .. status)
-- print("Body: " .. body)
end
wrk.thread:set("counter_invalid", counter_invalid)
wrk.thread:set("counter_valid", counter_valid)
wrk.thread:set("counter_failed", counter_failed)
end


function initialize(thread, threads, counter)
thread:set("t_id", counter)
counter = counter + 1
thread:set("counter_invalid", 0)
thread:set("counter_valid", 0)
thread:set("counter_failed", 0)
table.insert(threads, thread)
math.randomseed(os.time() + counter)
end
36 changes: 36 additions & 0 deletions tests/stress-testing/scripts/eth/createAccessList.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
dofile("common.lua")
methodName = "eth_createAccessList"
wrk.method = "POST"
wrk.headers["Content-Type"] = "application/json"

threads = {}
counter = 1

setup = function(thread)
thread:set("t_id",counter)
counter = counter + 1
thread:set("counter_invalid", 0)
thread:set("counter_valid", 0)
thread:set("counter_failed", 0)
table.insert(threads,thread)
math.randomseed(os.time()+counter)
end

request = function()
local from = "0x100d1b939151598373E4BbAAc7435eE9C4dec7A1"
local to = "0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D"
local gas = "0x4c4b40"
local gasPrice = "0xba43b7400"
local data = "0x18cbafe500000000000000000000000000000000000000000000000000000000000186a0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000009aFc51c7867f369371F238674ee4459556c5D2b50000000000000000000000000000000000000000000000000000000061d133750000000000000000000000000000000000000000000000000000000000000002000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2"
local body = string.format('{"jsonrpc":"2.0","method":"%s","params":[{"from":"%s","to":"%s","gasPrice":"%s","gas":"%s", "data":"%s"},"latest", true],"id":1}', methodName, from, to,gasPrice, gas, data)
-- print(body)
headers = {}
headers["Content-Type"] = "application/json"
return wrk.format("POST",nil,headers,body)
end

response = handle_response

done = function(summary, latency, requests)
print_summary(summary, latency, requests, threads, methodName)
end
Loading