Skip to content

Commit

Permalink
fix luxos cli script (#34)
Browse files Browse the repository at this point in the history
* clean up validate_message

* fix luxos script

* fix test
  • Loading branch information
cav71 authored Jun 24, 2024
1 parent 333c59e commit b4e242f
Show file tree
Hide file tree
Showing 6 changed files with 72 additions and 55 deletions.
4 changes: 2 additions & 2 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ build-backend = "setuptools.build_meta"

[project]
name = "luxos"
version = "0.1.1"
version = "0.1.2"
description = "The all encompassing LuxOS python library."
readme = "README.md"
license = { text = "MIT" } # TODO I don't think this is a MIT??
Expand Down Expand Up @@ -39,7 +39,7 @@ Source = "https://github.com/LuxorLabs/firmware-biz-tools"
Issues = "https://github.com/LuxorLabs/firmware-biz-tools/issues"

[project.scripts]
luxos = "luxos.scripts.luxos:main"
luxos = "luxos.scripts.luxos:run"
health-checker = "luxos.scripts.health_checker:main"

[tool.setuptools.package-data]
Expand Down
39 changes: 32 additions & 7 deletions src/luxos/asyncops.py
Original file line number Diff line number Diff line change
Expand Up @@ -131,22 +131,46 @@ def validate_message(
maxfields: None | int = 1,
) -> Any:
# all miner message comes with a STATUS
for key in ["STATUS", "id", *([extrakey] if extrakey else [])]:
for key in ["STATUS", "id"]:
if key in res:
continue
raise exceptions.MinerCommandMalformedMessageError(
host, port, f"missing {key} from logon message", res
host, port, f"missing {key} from message STATUS", res
)

if not extrakey or not (minfields or maxfields):
# no further validation here
if not extrakey:
return res

# TODO if minfield is 0, there might not be extrakey
if minfields == 0 and extrakey not in res:
return []

if extrakey not in res:
if not minfields:
return []
raise exceptions.MinerCommandMalformedMessageError(
host, port, f"missing {extrakey} from message", res
)

n = len(res[extrakey])
msg = None

cond = ""
if minfields is not None and maxfields is None:
cond = f" ({n} < {minfields})"
elif minfields is None and maxfields is not None:
cond = f" ({n} > {maxfields})"
elif minfields is not None and maxfields is not None:
if n > maxfields:
cond = f" ({n} > {maxfields})"
else:
cond = f" ({n} < {minfields})"

if (minfields is not None) and (n < minfields):
msg = f"found {n} fields for {extrakey} invalid: " f"{n} <= {minfields}"
msg = f"found too few items for '{extrakey}' {cond}"
elif (maxfields is not None) and (n > maxfields):
msg = f"found {n} fields for {extrakey} invalid: " f"{n} >= {maxfields}"
msg = f"found too many items for '{extrakey}' {cond}"
if msg is None:
return res[extrakey]
raise exceptions.MinerCommandMalformedMessageError(host, port, msg, res)
Expand Down Expand Up @@ -187,7 +211,7 @@ async def logoff(


def parameters_to_list(
parameters: str | list[Any] | dict[str, Any] | None = None,
parameters: str | int | float | bool | list[Any] | dict[str, Any] | None = None,
) -> list[str]:
if isinstance(parameters, dict):
data = []
Expand All @@ -211,7 +235,7 @@ async def rexec(
host: str,
port: int,
cmd: str,
parameters: str | list[Any] | dict[str, Any] | None = None,
parameters: str | int | float | bool | list[Any] | dict[str, Any] | None = None,
timeout: float | None = None,
retry: int | None = None,
retry_delay: float | None = None,
Expand Down Expand Up @@ -295,5 +319,6 @@ async def with_atm(host, port, enabled: bool, timeout: float | None = None):
raise exceptions.MinerConnectionError(host, port, "cannot check atm")
current = validate_message(host, port, res, "ATM")[0]["Enabled"]
await rexec(host, port, "atmset", {"enabled": enabled}, timeout=timeout)
# TODO
yield current
await rexec(host, port, "atmset", {"enabled": current}, timeout=timeout)
6 changes: 5 additions & 1 deletion src/luxos/scripts/luxos.py
Original file line number Diff line number Diff line change
Expand Up @@ -119,5 +119,9 @@ async def main(args: argparse.Namespace):
)


if __name__ == "__main__":
def run():
asyncio.run(main())


if __name__ == "__main__":
run()
Empty file added src/luxos/scripts/luxos_run.py
Empty file.
76 changes: 32 additions & 44 deletions tests/test_asyncops.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,60 +26,48 @@ def test_parameters_to_list():


def test_validate_message():
pytest.raises(
exceptions.MinerCommandMalformedMessageError, aapi.validate_message, "a", 0, {}
)
host, port = "a", 0
# TODO add more cases
# 1. when res is not present and limit is 0,None
# 2. check limits like None/value value/None None/None

# Avoid to repeat the same code over and over
def validate(res, extrakey=None, minfields=1, maxfields=1):
return aapi.validate_message("a-host", 0, res, extrakey, minfields, maxfields)

res = {}
pytest.raises(exceptions.MinerCommandMalformedMessageError, validate, res)

assert aapi.validate_message(host, port, {"STATUS": 1, "id": 2})
res = {"STATUS": 1, "id": 2}
assert validate(res)
assert validate(res, "A-MISSING-KEY", 0, None) == []
assert validate(res, "A-MISSING-KEY", None, None) == []

pytest.raises(
exceptions.MinerCommandMalformedMessageError,
aapi.validate_message,
host,
port,
{
"STATUS": 1,
"id": 2,
},
"wooow",
exceptions.MinerCommandMalformedMessageError, validate, res, "A-MISSING-KEY"
)

assert aapi.validate_message(
host, port, {"STATUS": 1, "id": 2, "wooow": [1, 2]}, "wooow", 2, 2
pytest.raises(
exceptions.MinerCommandMalformedMessageError,
validate,
res,
"A-MISSING-KEY",
1,
None,
)

with pytest.raises(exceptions.MinerCommandMalformedMessageError) as excinfo:
aapi.validate_message(
host, port, {"STATUS": 1, "id": 2, "wooow": [1, 2]}, "wooow", minfields=9
)
assert excinfo.value.args[2] == "found 2 fields for wooow invalid: 2 <= 9"
res = {"STATUS": 1, "id": 2, "KEY": [1, 2, 3]}
assert validate(res)
assert validate(res, "KEY", 0, None) == [1, 2, 3]
assert validate(res, "KEY", None, None) == [1, 2, 3]
assert validate(res, "KEY", None, 5) == [1, 2, 3]
assert validate(res, "KEY", 1, 5) == [1, 2, 3]

with pytest.raises(exceptions.MinerCommandMalformedMessageError) as excinfo:
aapi.validate_message(
host, port, {"STATUS": 1, "id": 2, "wooow": [1, 2]}, "wooow", maxfields=1
)
assert excinfo.value.args[2] == "found 2 fields for wooow invalid: 2 >= 1"
validate(res, "KEY", 4, None)
assert excinfo.value.args[2] == "found too few items for 'KEY' (3 < 4)"

with pytest.raises(exceptions.MinerCommandMalformedMessageError) as excinfo:
aapi.validate_message(
host,
port,
{"STATUS": 1, "id": 2, "wooow": [1, 2]},
"wooow",
minfields=9,
maxfields=10,
)
assert excinfo.value.args[2] == "found 2 fields for wooow invalid: 2 <= 9"

assert aapi.validate_message(
host,
port,
{"STATUS": 1, "id": 2, "wooow": [1, 2]},
"wooow",
minfields=2,
maxfields=10,
)
validate(res, "KEY", 1, 2)
assert excinfo.value.args[2] == "found too many items for 'KEY' (3 > 2)"


@pytest.mark.asyncio
Expand Down
2 changes: 1 addition & 1 deletion tests/test_syncops.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ def test_miner_double_logon_cycle(miner_host_port):
def test_miner_version(miner_host_port):
host, port = miner_host_port

res = syncops.rexec_command(host, port, None, "version")
res = syncops.rexec(host, port, "version")
assert "VERSION" in res
assert len(res["VERSION"]) == 1
assert "API" in res["VERSION"][0]
Expand Down

0 comments on commit b4e242f

Please sign in to comment.