Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
305f4e5
Run Python in developer mode
andyleejordan Oct 1, 2020
79c875b
Add `test` to `make all`
andyleejordan Oct 2, 2020
10ad3b3
Use asyncio correctly
andyleejordan Oct 1, 2020
1e4c141
Add info on Async IO to contributing guidelines
andyleejordan Oct 2, 2020
111d17d
Clean up `parse_args`
andyleejordan Oct 2, 2020
de55e9a
Clean up `load_runbook`
andyleejordan Oct 2, 2020
3474153
Turn `status` into a property of `Action`
andyleejordan Sep 24, 2020
3fd10c8
Make `LisaRunner` not subclass `Action`
andyleejordan Oct 2, 2020
53bb89f
Delete unnecessary `Action` class
andyleejordan Oct 3, 2020
af9addf
Rename `LisaRunner` to `Runner` since we only have one
andyleejordan Oct 3, 2020
4fa6d99
Also rename the files
andyleejordan Oct 3, 2020
ac46da0
Rename `start` to `run` for `Runner`
andyleejordan Oct 3, 2020
bfaecf9
Delete fluffy `_create_test_results`
andyleejordan Oct 3, 2020
823457c
Remove useless `Runner` class
andyleejordan Oct 5, 2020
170cf1c
Simplify `generate_test_runbook`
andyleejordan Oct 6, 2020
e446320
Clean up tests
andyleejordan Oct 6, 2020
b333442
Temporarily rename `test_runner` back to `test_lisarunner`
andyleejordan Oct 6, 2020
1d78412
Fix some types in process and shell
andyleejordan Oct 7, 2020
7cbe0e6
Manually close the fds which spur leaks
andyleejordan Oct 7, 2020
806f662
Rename `TestSuite` to `LisaTestCase` to avoid confusion
andyleejordan Oct 7, 2020
c5bac19
Rename `TestCaseMetadata` to `LisaTestMetadata` for consistency
andyleejordan Oct 7, 2020
86d84e2
Rename `TestSuiteMetadata` to `LisaTestCaseMetadata` for consistency
andyleejordan Oct 7, 2020
5a914a0
Rename `_all_suites` and `_all_cases` for consistency
andyleejordan Oct 7, 2020
b220dca
Rename `self.suite` to `self.case` for consistency
andyleejordan Oct 7, 2020
e4ee0b3
Don’t subclass ABCMeta when unneeded
andyleejordan Oct 7, 2020
1967e7d
Rename `TestCaseRuntimeData` to `LisaTestRuntimeData`
andyleejordan Oct 7, 2020
cdb99b2
Simplify `LisaTestCaseMetadata` and `LisaTestRuntimeData`
andyleejordan Oct 8, 2020
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
21 changes: 20 additions & 1 deletion CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,15 @@ short summary of the most important parts:
* Always use `self` for the first argument to instance methods.
* Always use `cls` for the first argument to class methods.
* Use one leading underscore only for non-public methods and instance variables,
such as `_data`.
such as `_data`. Do not activate name mangling with `__` unless necessary.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

as pep8, _name uses to mark "subclass API". __ is for private in this case.

* If there is a pair of `get_x` and `set_x` methods, they should instead be a
proper property, which is easy to do with the built-in `@property` decorator.
* Constants should be `CAPITALIZED_SNAKE_CASE`.
* When importing a function, try to avoid renaming it with `import as` because
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's my previous experience, and can be fixed and document. for example, load function in runbook, it should be imported like from lisa.parameter_parser import runbook, and used like runbook.load. So that it doesn't need as, and clear on using.

it introduces cognitive overhead to track yet another name.
* When deriving another module’s class (such as `unittest.TestCase`), reuse the
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As my explanation in overall comments, unittest.TestCase is a mixin actually. We can raise another case to explain this point.

class name to avoid confusion, such as `LisaTestCase`, instead of introducing
a different connotation like `TestSuite`.

When in doubt, adhere to existing conventions, or check the style guide.

Expand Down Expand Up @@ -252,6 +259,18 @@ Python world. If you make it through even some of these guides, you will be well
on your way to being a “Pythonista” (a Python developer) writing “Pythonic”
(canonically correct Python) code left and right.

### Async IO

With Python 3.4, the Async IO pattern found in languages such as C# and Go is
Comment thread
andyleejordan marked this conversation as resolved.
available through the keywords `async` and `await`, along with the Python module
`asyncio`. Please read [Async IO in Python: A Complete
Walkthrough](https://realpython.com/async-io-python/) to understand at a high
level how asynchronous programming works. As of Python 3.7, One major “gotcha”
is that `asyncio.run(...)` should be used [exactly once in
`main`](https://docs.python.org/3/library/asyncio-task.html), it starts the
event loop. Everything else should be a coroutine or task which the event loop
schedules.

## Future Sections

Just a collection of reminders for the author to expand on later.
Expand Down
6 changes: 3 additions & 3 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,18 +1,18 @@
# This Makefile simply automates all our tasks. Its use is optional.

all: setup run check
all: setup run test check

# Install Python packages
setup:
@poetry install --no-ansi --remove-untracked

# Run LISAv3
run:
@poetry run python lisa/main.py --debug
@poetry run python -X dev lisa/main.py --debug

# Run unit tests
test:
@poetry run python -m unittest discover lisa
@poetry run python -X dev -m unittest discover -v lisa

# Generate coverage report (slow, reruns LISAv3 and tests)
coverage:
Expand Down
10 changes: 5 additions & 5 deletions examples/testsuites/helloworld.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
from lisa import TestCaseMetadata, TestSuite, TestSuiteMetadata
from lisa import LisaTestCase, LisaTestCaseMetadata, LisaTestMetadata
from lisa.operating_system import Linux
from lisa.tools import Echo, Uname


@TestSuiteMetadata(
@LisaTestCaseMetadata(
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Keep class -> suite, and method -> case. See my explanation in overall comments, we have different concept on them than Python ut. We're not write UT, so the concept of suite and case are heavier than Python UT.

area="demo",
category="simple",
description="""
Expand All @@ -12,8 +12,8 @@
""",
tags=["demo"],
)
class HelloWorld(TestSuite):
@TestCaseMetadata(
class HelloWorld(LisaTestCase):
@LisaTestMetadata(
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The Test is confusing. Test means much more than test case, it's hard to understand Test is subitem of Test case.

description="""
this test case use default node to
1. get system info
Expand Down Expand Up @@ -43,7 +43,7 @@ def hello(self) -> None:
self.assertEqual("", result.stderr)
self.assertEqual(0, result.exit_code)

@TestCaseMetadata(
@LisaTestMetadata(
description="""
demonstrate a simple way to run command in one line.
""",
Expand Down
10 changes: 5 additions & 5 deletions examples/testsuites/multinodes.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
from lisa import TestCaseMetadata, TestSuite, TestSuiteMetadata
from lisa import LisaTestCase, LisaTestCaseMetadata, LisaTestMetadata
from lisa.testsuite import simple_requirement
from lisa.tools import Lscpu, Ntttcp


@TestSuiteMetadata(
@LisaTestCaseMetadata(
area="demo",
category="demo",
description="""
Expand All @@ -13,8 +13,8 @@
tags=["demo", "multinode"],
requirement=simple_requirement(min_count=2),
)
class MutipleNodesDemo(TestSuite):
@TestCaseMetadata(
class MutipleNodesDemo(LisaTestCase):
@LisaTestMetadata(
description="""
This test case send and receive data by ntttcp
""",
Expand All @@ -28,7 +28,7 @@ def os_info(self) -> None:
core_count = lscpu.get_core_count()
self.log.info(f"index: {node.index}, core_count: {core_count}")

@TestCaseMetadata(
@LisaTestMetadata(
description="""
this test case send and receive data by ntttcp
""",
Expand Down
8 changes: 4 additions & 4 deletions examples/testsuites/withscript.py
Original file line number Diff line number Diff line change
@@ -1,27 +1,27 @@
from pathlib import Path

from lisa import TestCaseMetadata, TestSuite, TestSuiteMetadata
from lisa import LisaTestCase, LisaTestCaseMetadata, LisaTestMetadata
from lisa.executable import CustomScript, CustomScriptBuilder
from lisa.operating_system import Windows
from lisa.testsuite import simple_requirement
from lisa.util.perf_timer import create_timer


@TestSuiteMetadata(
@LisaTestCaseMetadata(
area="demo",
category="simple",
description="""
This test suite run a script on linux
""",
tags=["demo"],
)
class WithScript(TestSuite):
class WithScript(LisaTestCase):
def before_suite(self) -> None:
self._echo_script = CustomScriptBuilder(
Path(__file__).parent.joinpath("scripts"), ["echo.sh"]
)

@TestCaseMetadata(
@LisaTestMetadata(
description="""
this test case run script on a linux node, and demostrate
1. how to use customized script on tested node.
Expand Down
8 changes: 4 additions & 4 deletions lisa/__init__.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
from __future__ import annotations

from lisa.testsuite import TestCaseMetadata, TestSuite, TestSuiteMetadata
from lisa.testsuite import LisaTestCase, LisaTestCaseMetadata, LisaTestMetadata
from lisa.util.logger import init_loggger

__all__ = [
"TestSuiteMetadata",
"TestCaseMetadata",
"TestSuite",
"LisaTestCase",
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I need some guidances what kind of things worth to have a shortcut in __init__.

"LisaTestCaseMetadata",
"LisaTestMetadata",
]


Expand Down
82 changes: 0 additions & 82 deletions lisa/action.py

This file was deleted.

30 changes: 14 additions & 16 deletions lisa/commands.py
Original file line number Diff line number Diff line change
@@ -1,52 +1,50 @@
import asyncio
import functools
from argparse import Namespace
from typing import Iterable, Optional, cast

import lisa.runner
from lisa import notifier
from lisa.lisarunner import LisaRunner
from lisa.parameter_parser.runbook import load as load_runbook
from lisa.parameter_parser.runbook import load_runbook
from lisa.testselector import select_testcases
from lisa.testsuite import TestCaseRuntimeData
from lisa.testsuite import LisaTestRuntimeData, TestStatus
from lisa.util import LisaException, constants
from lisa.util.logger import get_logger

_get_init_logger = functools.partial(get_logger, "init")


def run(args: Namespace) -> int:
runbook = load_runbook(args)
async def run(args: Namespace) -> int:
runbook = load_runbook(args.runbook, args.variables)

if runbook.notifier:
notifier.initialize(runbooks=runbook.notifier)

try:
runner = LisaRunner(runbook)
awaitable = runner.start()
asyncio.run(awaitable)
results = await lisa.runner.run(runbook)
finally:
notifier.finalize()

return runner.exit_code
return sum(1 for x in results if x.status == TestStatus.FAILED)


# check runbook
def check(args: Namespace) -> int:
load_runbook(args)
async def check(args: Namespace) -> int:
load_runbook(args.runbook, args.variables)
return 0


def list_start(args: Namespace) -> int:
runbook = load_runbook(args)
async def list_start(args: Namespace) -> int:
runbook = load_runbook(args.runbook, args.variables)
list_all = cast(Optional[bool], args.list_all)
log = _get_init_logger("list")
if args.type == constants.LIST_CASE:
if list_all:
cases: Iterable[TestCaseRuntimeData] = select_testcases()
cases: Iterable[LisaTestRuntimeData] = select_testcases()
else:
cases = select_testcases(runbook.testcase)
for case_data in cases:
log.info(
f"case: {case_data.name}, suite: {case_data.metadata.suite.name}, "
f"test: {case_data.name}, case: {case_data.metadata.case.name}, "
f"area: {case_data.suite.area}, "
f"category: {case_data.suite.category}, "
f"tags: {','.join(case_data.suite.tags)}, "
Expand Down
Loading