Skip to content

Commit

Permalink
test: add unary clinet test samples
Browse files Browse the repository at this point in the history
Signed-off-by: LingKa <cnfty786@gmail.com>
  • Loading branch information
LingKa28 authored and Phoenix500526 committed Feb 18, 2024
1 parent 17f8649 commit e511f84
Show file tree
Hide file tree
Showing 2 changed files with 287 additions and 1 deletion.
51 changes: 50 additions & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,56 @@ jobs:
files: ./coverage.xml
fail_ci_if_error: true
verbose: true


mock:
name: Test Mock Sample Validation
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
path: py-xline

- name: Checkout mock xline
uses: actions/checkout@v4
with:
repository: xline-kv/mock-xline
path: mock-xline

- name: Setup Python
uses: actions/setup-python@v4
with:
python-version: '3.10'

- name: Install Pip
run: sudo apt install pip

- name: Setup Go
uses: actions/setup-go@v4
with:
go-version: 1.21

- name: Generate API
run: |
cd py-xline
python3 -m pip install grpcio grpcio-tools
git submodule init
git submodule update
make
- name: Install Hatch
run: pip install hatch==1.7.0

- name: Start the cluster
run: |
cd mock-xline
./scripts/quick_start.sh
- name: Run tests
run: |
cd py-xline
hatch run test ./src/curp/ -v
commit:
name: Commit Message Validation
runs-on: ubuntu-latest
Expand Down
237 changes: 237 additions & 0 deletions src/curp/curp_test.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,237 @@
"""
Test for curp client
"""

import pytest
from src.curp.unary import UnaryBuilder, UnaryConfig
from src.rpc.type import CurpError
from curp_command_pb2 import ProposeId
from api.xline.xline_command_pb2 import Command, CommandResponse, SyncResponse
from api.xline.rpc_pb2 import RangeResponse


@pytest.mark.asyncio
async def test_unary_fetch_clusters():
"""
Test unary fetch clusters
"""
all_members = {
0: ["127.0.0.1:48081"],
1: ["127.0.0.1:48082"],
2: ["127.0.0.1:48083"],
3: ["127.0.0.1:48084"],
4: ["127.0.0.1:48085"],
}
config = UnaryConfig(1, 2)
unary = UnaryBuilder(all_members, config).build()
res = await unary.fetch_cluster()
assert len(res.members) == 5
assert res.members[0].addrs == ["A0"]
assert res.members[1].addrs == ["A1"]
assert res.members[2].addrs == ["A2"]
assert res.members[3].addrs == ["A3"]
assert res.members[4].addrs == ["A4"]


@pytest.mark.asyncio
async def test_unary_fetch_clusters_failed():
"""
Test unary fetch clusters failed
"""
all_members = {
0: ["127.0.0.1:48081"],
1: ["127.0.0.1:48082"],
2: ["127.0.0.1:48083"],
3: ["127.0.0.1:48084"],
4: ["127.0.0.1:48085"],
}
config = UnaryConfig(1, 2)
unary = UnaryBuilder(all_members, config).build()
try:
await unary.fetch_cluster()
except CurpError as e:
assert isinstance(e, CurpError)


@pytest.mark.asyncio
async def test_fast_round_works():
"""
Test fast round works
"""
all_members = {
0: ["127.0.0.1:48081"],
1: ["127.0.0.1:48082"],
2: ["127.0.0.1:48083"],
3: ["127.0.0.1:48084"],
4: ["127.0.0.1:48085"],
}
config = UnaryConfig(1, 2)
unary = UnaryBuilder(all_members, config).build()
er, err = await unary.fast_round(ProposeId(seq_num=1), Command())
assert er is not None
assert er == CommandResponse(range_response=RangeResponse(count=1))
assert err is None

@pytest.mark.asyncio
async def test_fast_round_return_early_err():
"""
Test fast round return early error
"""
all_members = {
0: ["127.0.0.1:48081"],
1: ["127.0.0.1:48082"],
2: ["127.0.0.1:48083"],
}
config = UnaryConfig(1, 2)
unary = UnaryBuilder(all_members, config).build()
try:
await unary.fast_round(ProposeId(seq_num=2), Command())
except CurpError as e:
assert isinstance(e, CurpError)

@pytest.mark.asyncio
async def test_fast_round_less_quorum():
"""
Test fast round less quorum
"""
all_members = {
0: ["127.0.0.1:48081"],
1: ["127.0.0.1:48082"],
2: ["127.0.0.1:48083"],
3: ["127.0.0.1:48084"],
4: ["127.0.0.1:48085"],
}
config = UnaryConfig(1, 2)
unary = UnaryBuilder(all_members, config).build()
try:
await unary.fast_round(ProposeId(seq_num=3), Command())
except CurpError as e:
assert isinstance(e, CurpError)

@pytest.mark.asyncio
async def test_fast_round_with_two_leader():
"""
Test fast round with two leader
"""
all_members = {
0: ["127.0.0.1:48081"],
1: ["127.0.0.1:48082"],
2: ["127.0.0.1:48083"],
3: ["127.0.0.1:48084"],
4: ["127.0.0.1:48085"],
}
config = UnaryConfig(1, 2)
unary = UnaryBuilder(all_members, config).build()
try:
await unary.fast_round(ProposeId(seq_num=4), Command())
except RuntimeError as e:
assert isinstance(e, RuntimeError)

@pytest.mark.asyncio
async def test_fast_round_without_leader():
"""
Test fast round without leader
"""
all_members = {
0: ["127.0.0.1:48081"],
1: ["127.0.0.1:48082"],
2: ["127.0.0.1:48083"],
3: ["127.0.0.1:48084"],
4: ["127.0.0.1:48085"],
}
config = UnaryConfig(1, 2)
unary = UnaryBuilder(all_members, config).build()
try:
await unary.fast_round(ProposeId(seq_num=5), Command())
except RuntimeError as e:
assert isinstance(e, RuntimeError)


@pytest.mark.asyncio
async def test_unary_slow_round_fetch_leader_first():
"""
Test unary slow round fetch leader first
"""
all_members = {
0: ["127.0.0.1:48081"],
1: ["127.0.0.1:48082"],
2: ["127.0.0.1:48083"],
3: ["127.0.0.1:48084"],
4: ["127.0.0.1:48085"],
}
config = UnaryConfig(1, 2)
unary = UnaryBuilder(all_members, config).build()
(er, asr), _ = await unary.slow_round(ProposeId(seq_num=6))
assert er == CommandResponse(range_response=RangeResponse(count=1))
assert asr == SyncResponse(revision=1)


@pytest.mark.asyncio
async def test_unary_propose_fast_path_works():
"""
Test unary propose fast path works
"""
all_members = {
0: ["127.0.0.1:48081"],
1: ["127.0.0.1:48082"],
2: ["127.0.0.1:48083"],
3: ["127.0.0.1:48084"],
4: ["127.0.0.1:48085"],
}
config = UnaryConfig(1, 2)

unary = UnaryBuilder(all_members, config).set_leader_state(0, 1).build()
er, asr = await unary.repeatable_propose(ProposeId(seq_num=7), Command())
assert er == CommandResponse(range_response=RangeResponse(count=1))
assert asr is None

@pytest.mark.asyncio
async def test_unary_propose_slow_path_works():
"""
Test unary propose slow path works
"""
all_members = {
0: ["127.0.0.1:48081"],
1: ["127.0.0.1:48082"],
2: ["127.0.0.1:48083"],
3: ["127.0.0.1:48084"],
4: ["127.0.0.1:48085"],
}
config = UnaryConfig(1, 2)
unary = UnaryBuilder(all_members, config).set_leader_state(0, 1).build()
er, asr = await unary.repeatable_propose(ProposeId(seq_num=7), Command(), use_fast_path=False)
assert er == CommandResponse(range_response=RangeResponse(count=1))
assert asr == SyncResponse(revision=1)


@pytest.mark.asyncio
async def test_unary_propose_fast_path_fallback_slow_path():
"""
Test unary propose fast path fallback slow path
"""
all_members = {
0: ["127.0.0.1:48081"],
1: ["127.0.0.1:48082"],
2: ["127.0.0.1:48083"],
3: ["127.0.0.1:48084"],
4: ["127.0.0.1:48085"],
}
config = UnaryConfig(1, 2)
unary = UnaryBuilder(all_members, config).set_leader_state(0, 1).build()
er, asr = await unary.repeatable_propose(ProposeId(seq_num=8), Command())
assert er == CommandResponse(range_response=RangeResponse(count=1))
assert asr == SyncResponse(revision=1)


@pytest.mark.asyncio
async def test_unary_propose_return_early_err():
"""
Test unary propose return early error
"""
all_members = {0: ["127.0.0.1:48081"]}
config = UnaryConfig(1, 2)
unary = UnaryBuilder(all_members, config).set_leader_state(0, 1).build()
try:
await unary.repeatable_propose(ProposeId(seq_num=9), Command())
except CurpError as e:
assert isinstance(e, CurpError)

0 comments on commit e511f84

Please sign in to comment.