Skip to content

Commit

Permalink
catchup: into long_lived/datalayer_merkle_blob from main @ 49354dc (#…
Browse files Browse the repository at this point in the history
…19074)

Source hash: 49354dc
Remaining commits: 0
  • Loading branch information
altendky authored Dec 20, 2024
2 parents 1ebf518 + 4e6546c commit 3d4ce9d
Show file tree
Hide file tree
Showing 50 changed files with 953 additions and 257 deletions.
2 changes: 2 additions & 0 deletions .github/workflows/conflict-check.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ name: 🩹 Conflict Check
on:
# So that PRs touching the same files as the push are updated
push:
branches-ignore:
- "tmp/**"
# So that the `dirtyLabel` is removed if conflicts are resolve
# We recommend `pull_request_target` so that github secrets are available.
# In `pull_request` we wouldn't be able to change labels of fork PRs
Expand Down
18 changes: 9 additions & 9 deletions chia/_tests/blockchain/test_blockchain.py
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,7 @@ async def test_long_chain(self, empty_blockchain: Blockchain, default_1000_block
block_bad = recursive_replace(
block, "finished_sub_slots", [new_finished_ss] + block.finished_sub_slots[1:]
)
header_block_bad = get_block_header(block_bad, [], [])
header_block_bad = get_block_header(block_bad)
# TODO: Inspect these block values as they are currently None
expected_difficulty = block.finished_sub_slots[0].challenge_chain.new_difficulty or uint64(0)
expected_sub_slot_iters = block.finished_sub_slots[0].challenge_chain.new_sub_slot_iters or uint64(0)
Expand All @@ -195,7 +195,7 @@ async def test_long_chain(self, empty_blockchain: Blockchain, default_1000_block
block, "finished_sub_slots", [new_finished_ss_2] + block.finished_sub_slots[1:]
)

header_block_bad_2 = get_block_header(block_bad_2, [], [])
header_block_bad_2 = get_block_header(block_bad_2)
# TODO: Inspect these block values as they are currently None
expected_difficulty = block.finished_sub_slots[0].challenge_chain.new_difficulty or uint64(0)
expected_sub_slot_iters = block.finished_sub_slots[0].challenge_chain.new_sub_slot_iters or uint64(0)
Expand Down Expand Up @@ -225,7 +225,7 @@ async def test_long_chain(self, empty_blockchain: Blockchain, default_1000_block
log.warning(f"Number of slots: {len(block.finished_sub_slots)}")
block_bad_3 = recursive_replace(block, "finished_sub_slots", [new_finished_ss_3])

header_block_bad_3 = get_block_header(block_bad_3, [], [])
header_block_bad_3 = get_block_header(block_bad_3)
# TODO: Inspect these block values as they are currently None
expected_difficulty = block.finished_sub_slots[0].challenge_chain.new_difficulty or uint64(0)
expected_sub_slot_iters = block.finished_sub_slots[0].challenge_chain.new_sub_slot_iters or uint64(0)
Expand Down Expand Up @@ -254,7 +254,7 @@ async def test_long_chain(self, empty_blockchain: Blockchain, default_1000_block
)
block_bad_4 = recursive_replace(block, "finished_sub_slots", [new_finished_ss_4])

header_block_bad_4 = get_block_header(block_bad_4, [], [])
header_block_bad_4 = get_block_header(block_bad_4)
# TODO: Inspect these block values as they are currently None
expected_difficulty = block.finished_sub_slots[0].challenge_chain.new_difficulty or uint64(0)
expected_sub_slot_iters = block.finished_sub_slots[0].challenge_chain.new_sub_slot_iters or uint64(0)
Expand Down Expand Up @@ -510,7 +510,7 @@ async def test_invalid_sub_slot_challenge_hash_genesis(self, empty_blockchain: B
blocks[0], "finished_sub_slots", [new_finished_ss] + blocks[0].finished_sub_slots[1:]
)

header_block_bad = get_block_header(block_0_bad, [], [])
header_block_bad = get_block_header(block_0_bad)
expected_vs = ValidationState(
empty_blockchain.constants.SUB_SLOT_ITERS_STARTING, empty_blockchain.constants.DIFFICULTY_STARTING, None
)
Expand Down Expand Up @@ -539,7 +539,7 @@ async def test_invalid_sub_slot_challenge_hash_non_genesis(
)

await _validate_and_add_block(empty_blockchain, blocks[0])
header_block_bad = get_block_header(block_1_bad, [], [])
header_block_bad = get_block_header(block_1_bad)
# TODO: Inspect these block values as they are currently None
expected_difficulty = blocks[1].finished_sub_slots[0].challenge_chain.new_difficulty or uint64(0)
expected_sub_slot_iters = blocks[1].finished_sub_slots[0].challenge_chain.new_sub_slot_iters or uint64(0)
Expand All @@ -566,7 +566,7 @@ async def test_invalid_sub_slot_challenge_hash_empty_ss(self, empty_blockchain:
)
await _validate_and_add_block(empty_blockchain, blocks[0])

header_block_bad = get_block_header(block_1_bad, [], [])
header_block_bad = get_block_header(block_1_bad)
# TODO: Inspect these block values as they are currently None
expected_difficulty = blocks[1].finished_sub_slots[0].challenge_chain.new_difficulty or uint64(0)
expected_sub_slot_iters = blocks[1].finished_sub_slots[0].challenge_chain.new_sub_slot_iters or uint64(0)
Expand Down Expand Up @@ -721,7 +721,7 @@ async def test_invalid_icc_into_cc(self, empty_blockchain: Blockchain, bt: Block
block, "finished_sub_slots", block.finished_sub_slots[:-1] + [new_finished_ss]
)

header_block_bad = get_block_header(block_bad, [], [])
header_block_bad = get_block_header(block_bad)
# TODO: Inspect these block values as they are currently None
expected_difficulty = block.finished_sub_slots[0].challenge_chain.new_difficulty or uint64(0)
expected_sub_slot_iters = block.finished_sub_slots[0].challenge_chain.new_sub_slot_iters or uint64(0)
Expand Down Expand Up @@ -792,7 +792,7 @@ async def test_empty_slot_no_ses(self, empty_blockchain: Blockchain, bt: BlockTo
blocks[-1], "finished_sub_slots", blocks[-1].finished_sub_slots[:-1] + [new_finished_ss]
)

header_block_bad = get_block_header(block_bad, [], [])
header_block_bad = get_block_header(block_bad)
expected_vs = ValidationState(
empty_blockchain.constants.SUB_SLOT_ITERS_STARTING, empty_blockchain.constants.DIFFICULTY_STARTING, None
)
Expand Down
28 changes: 17 additions & 11 deletions chia/_tests/cmds/test_click_types.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
from __future__ import annotations

from dataclasses import dataclass, field
from decimal import Decimal
from pathlib import Path
from typing import Any, cast

import click
import pytest
from click import BadParameter, Context
from click import BadParameter

from chia.cmds.cmd_classes import ChiaCliContext
from chia.cmds.param_types import (
AddressParamType,
AmountParamType,
Expand Down Expand Up @@ -38,9 +38,9 @@
overflow_decimal = Decimal(overflow_decimal_str)


@dataclass
class FakeContext:
obj: dict[Any, Any] = field(default_factory=dict)
@click.command()
def a_command_for_testing() -> None:
pass # pragma: no cover


def test_click_tx_fee_type() -> None:
Expand Down Expand Up @@ -114,7 +114,11 @@ def test_click_amount_type() -> None:


def test_click_address_type() -> None:
context = cast(Context, FakeContext(obj={"expected_prefix": "xch"})) # this makes us not have to use a config file
context = click.Context(command=a_command_for_testing)
chia_context = ChiaCliContext.set_default(context)
# this makes us not have to use a config file
chia_context.expected_prefix = "xch"

std_cli_address = CliAddress(burn_ph, burn_address, AddressType.XCH)
nft_cli_address = CliAddress(burn_ph, burn_nft_addr, AddressType.DID)
# Test CliAddress (Generally is not used)
Expand All @@ -132,7 +136,7 @@ def test_click_address_type() -> None:
# check error handling
with pytest.raises(BadParameter):
AddressParamType().convert("test", None, None)
with pytest.raises(AttributeError): # attribute error because the context does not have a real error handler
with pytest.raises(click.BadParameter):
AddressParamType().convert(burn_address_txch, None, context)
with pytest.raises(BadParameter):
AddressParamType().convert(burn_bad_prefix, None, None)
Expand All @@ -148,13 +152,15 @@ def test_click_address_type() -> None:


def test_click_address_type_config(root_path_populated_with_config: Path) -> None:
context = click.Context(command=a_command_for_testing)
chia_context = ChiaCliContext.set_default(context)
# set a root path in context.
context = cast(Context, FakeContext(obj={"root_path": root_path_populated_with_config}))
chia_context.root_path = root_path_populated_with_config
# run test that should pass
assert AddressParamType().convert(burn_address, None, context) == CliAddress(burn_ph, burn_address, AddressType.XCH)
assert context.obj["expected_prefix"] == "xch" # validate that the prefix was set correctly
assert ChiaCliContext.set_default(context).expected_prefix == "xch" # validate that the prefix was set correctly
# use txch address
with pytest.raises(AttributeError): # attribute error because the context does not have a real error handler
with pytest.raises(click.BadParameter):
AddressParamType().convert(burn_address_txch, None, context)


Expand Down
18 changes: 11 additions & 7 deletions chia/_tests/cmds/test_cmd_framework.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
from __future__ import annotations

import pathlib
import textwrap
from collections.abc import Sequence
from dataclasses import asdict
Expand All @@ -12,7 +13,7 @@

from chia._tests.environments.wallet import STANDARD_TX_ENDPOINT_ARGS, WalletTestFramework
from chia._tests.wallet.conftest import * # noqa
from chia.cmds.cmd_classes import ChiaCommand, Context, chia_command, option
from chia.cmds.cmd_classes import ChiaCliContext, ChiaCommand, chia_command, option
from chia.cmds.cmd_helpers import (
_TRANSACTION_ENDPOINT_DECORATOR_APPLIED,
NeedsCoinSelectionConfig,
Expand All @@ -31,7 +32,7 @@
from chia.wallet.util.tx_config import CoinSelectionConfig, TXConfig


def check_click_parsing(cmd: ChiaCommand, *args: str, obj: Optional[Any] = None) -> None:
def check_click_parsing(cmd: ChiaCommand, *args: str, context: Optional[ChiaCliContext] = None) -> None:
@click.group()
def _cmd() -> None:
pass
Expand All @@ -57,8 +58,11 @@ def new_run(self: Any) -> None:
setattr(mock_type, "run", new_run)
chia_command(group=_cmd, name="_", short_help="", help="")(mock_type)

if context is None:
context = ChiaCliContext()

runner = CliRunner()
result = runner.invoke(_cmd, ["_", *args], catch_exceptions=False, obj=obj)
result = runner.invoke(_cmd, ["_", *args], catch_exceptions=False, obj=context.to_click())
assert result.output == ""


Expand Down Expand Up @@ -162,14 +166,14 @@ def test_context_requirement() -> None:
@click.group()
@click.pass_context
def cmd(ctx: click.Context) -> None:
ctx.obj = {"foo": "bar"}
ctx.obj = ChiaCliContext(root_path=pathlib.Path("foo", "bar")).to_click()

@chia_command(group=cmd, name="temp_cmd", short_help="blah", help="n/a")
class TempCMD:
context: Context
context: ChiaCliContext

def run(self) -> None:
assert self.context["foo"] == "bar"
assert self.context.root_path == pathlib.Path("foo", "bar")

runner = CliRunner()
result = runner.invoke(
Expand Down Expand Up @@ -404,7 +408,7 @@ def run(self) -> None:

expected_command = TempCMD(
rpc_info=NeedsWalletRPC(
context={"root_path": wallet_environments.environments[0].node.root_path},
context=ChiaCliContext(root_path=wallet_environments.environments[0].node.root_path),
wallet_rpc_port=port,
fingerprint=fingerprint,
),
Expand Down
131 changes: 131 additions & 0 deletions chia/_tests/cmds/test_dev_gh.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
from __future__ import annotations

import re
from dataclasses import dataclass
from pathlib import Path

import aiohttp
import anyio
import click
import pytest

# TODO: update after resolution in https://github.com/pytest-dev/pytest/issues/7469
from _pytest.capture import CaptureFixture

import chia._tests
from chia._tests.util.misc import Marks, datacases
from chia.cmds.gh import Per, TestCMD, get_gh_token

test_root = Path(chia._tests.__file__).parent


@dataclass
class InvalidOnlyCase:
only: Path
per: Per
exists: bool
marks: Marks = ()

@property
def id(self) -> str:
return f"{self.per}: {self.only}"


@datacases(
InvalidOnlyCase(only=Path("does_not_exist.py"), per="directory", exists=False),
InvalidOnlyCase(only=Path("pools/test_pool_rpc.py"), per="directory", exists=True),
InvalidOnlyCase(only=Path("does_not_exist/"), per="file", exists=False),
InvalidOnlyCase(only=Path("pools/"), per="file", exists=True),
)
@pytest.mark.anyio
async def test_invalid_only(case: InvalidOnlyCase) -> None:
cmd = TestCMD(only=case.only, per=case.per)

if case.exists:
assert test_root.joinpath(case.only).exists()
explanation = "wrong type"
if case.per == "directory":
assert test_root.joinpath(case.only).is_file()
else:
assert test_root.joinpath(case.only).is_dir()
else:
assert not test_root.joinpath(case.only).exists()
explanation = "does not exist"

with pytest.raises(click.ClickException, match=rf"\bto be a {re.escape(case.per)}\b.*\b{re.escape(explanation)}\b"):
await cmd.run()


@pytest.mark.skip("considering inclusion, but not yet")
@pytest.mark.anyio
async def test_successfully_dispatches(
capsys: CaptureFixture[str],
) -> None:
cmd = TestCMD(
# TODO: stop hardcoding here
owner="chia-network",
repository="chia-blockchain",
per="file",
only=Path("util/test_errors.py"),
duplicates=2,
oses=["linux", "macos-arm"],
full_python_matrix=True,
open_browser=False,
)

capsys.readouterr()
await cmd.run()
stdout, stderr = capsys.readouterr()

assert len(stderr.strip()) == 0
for line in stdout.splitlines():
match = re.search(r"(?<=\brun api url: )(?P<url>.*)", line)
if match is None:
continue
url = match.group("url")
break
else:
pytest.fail(f"Failed to find run url in: {stdout}")

token = await get_gh_token()
headers = {"Authorization": f"Bearer {token}"}

async with aiohttp.ClientSession(raise_for_status=True, headers=headers) as client:
while True:
async with client.get(url) as response:
d = await response.json()
jobs_url = d["jobs_url"]
conclusion = d["conclusion"]

print("conclusion:", conclusion)
if conclusion is None:
await anyio.sleep(5)
continue

break

async with client.get(jobs_url) as response:
d = await response.json()
jobs = d["jobs"]

by_name = {job["name"]: job for job in jobs}

assert by_name["Configure matrix"]["conclusion"] == "success"
assert by_name["macos-intel"]["conclusion"] == "skipped"
assert by_name["windows"]["conclusion"] == "skipped"

versions = ["3.9", "3.10", "3.11", "3.12"]
runs_by_name: dict[str, list[str]] = {name: [] for name in ["ubuntu", "macos-arm"]}
for name in by_name:
platform, _, rest = name.partition(" / ")

jobs = runs_by_name.get(platform)
if jobs is None:
continue

jobs.append(rest)

expected = len(versions) * cmd.duplicates
print("expected:", expected)
print("runs_by_name:", runs_by_name)
assert len({expected, *(len(runs) for runs in runs_by_name.values())}) == 1
10 changes: 5 additions & 5 deletions chia/_tests/pools/test_pool_cli_parsing.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
from __future__ import annotations

from chia._tests.cmds.test_cmd_framework import check_click_parsing
from chia.cmds.cmd_classes import ChiaCliContext
from chia.cmds.cmd_helpers import NeedsWalletRPC
from chia.cmds.param_types import CliAddress
from chia.cmds.plotnft import (
Expand All @@ -22,7 +23,7 @@
def test_plotnft_command_default_parsing() -> None:
launcher_id = bytes32([1] * 32)
check_click_parsing(
GetLoginLinkCMD(context=dict(), launcher_id=launcher_id),
GetLoginLinkCMD(launcher_id=launcher_id),
"--launcher_id",
launcher_id.hex(),
)
Expand All @@ -37,7 +38,8 @@ def test_plotnft_command_default_parsing() -> None:
launcher_id.hex(),
"--address",
burn_address,
obj={"expected_prefix": "xch"}, # Needed for AddressParamType to work correctly without config
# Needed for AddressParamType to work correctly without config
context=ChiaCliContext(expected_prefix="xch"),
)

check_click_parsing(
Expand Down Expand Up @@ -120,9 +122,7 @@ def test_plotnft_command_default_parsing() -> None:
)

check_click_parsing(
ShowPlotNFTCMD(
context=dict(), rpc_info=NeedsWalletRPC(client_info=None, wallet_rpc_port=None, fingerprint=None), id=5
),
ShowPlotNFTCMD(rpc_info=NeedsWalletRPC(client_info=None, wallet_rpc_port=None, fingerprint=None), id=5),
"--id",
"5",
)
Loading

0 comments on commit 3d4ce9d

Please sign in to comment.