Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
194 commits
Select commit Hold shift + click to select a range
ec2fbba
Move first prototype into ‘.archive’
andyleejordan Nov 20, 2020
37756a1
Demo LISAv3 as simply pytest
andyleejordan Oct 10, 2020
b94555b
Make Node fixture more reusable
andyleejordan Oct 10, 2020
8727317
Add 300 second timeout to all tests
andyleejordan Oct 10, 2020
c7564d1
Move node implementation to custom plugin
andyleejordan Oct 12, 2020
9246b0e
Shorten tracebacks
andyleejordan Oct 12, 2020
5204a1c
Demo connecting to host based on mark
andyleejordan Oct 12, 2020
790f224
Add considered early alternatives
andyleejordan Oct 12, 2020
9f31ce1
Allow untyped decorators
andyleejordan Oct 12, 2020
fe596b2
Setup markers for generation from XML
andyleejordan Oct 12, 2020
3a1ea7f
Add libvirt note
andyleejordan Oct 12, 2020
d1688f5
Add pytest-azurepipelines note
andyleejordan Oct 12, 2020
b6f4e91
Add skeleton to parse deploy marker
andyleejordan Oct 12, 2020
2ffda5f
Create and delete VM resource
andyleejordan Oct 12, 2020
f65940f
Move semantic analysis testing to separate target
andyleejordan Oct 14, 2020
6f4ed26
Cache deployed VM
andyleejordan Oct 14, 2020
3f52e5c
Enable boot diagnostics when creating a VM
andyleejordan Oct 15, 2020
6b4d8f0
Include /usr/bin etc. in remote path
andyleejordan Oct 15, 2020
779c617
Add node functions to restart and get boot diagnostics
andyleejordan Oct 15, 2020
7f8aa96
Add a basic smoke test
andyleejordan Oct 15, 2020
0fba2a8
Set default node command timeout to 1 minute
andyleejordan Oct 15, 2020
aadd9f6
Clean up Invoke configuration
andyleejordan Oct 15, 2020
9bd0d70
Create boot storage account and resource group automatically
andyleejordan Oct 15, 2020
c39badb
Check that az cli is logged in with a default subscription
andyleejordan Oct 15, 2020
bd363c3
Set default node command timeout to 5 minutes instead
andyleejordan Oct 15, 2020
3c41920
Display logged stderr/stdout as it happens
andyleejordan Oct 15, 2020
e95420f
Fix subtle break in Fabric
andyleejordan Oct 15, 2020
ef234b9
Note use of az CLI instead of Azure Python APIs
andyleejordan Oct 15, 2020
c865846
Add a basic self test
andyleejordan Oct 15, 2020
f251499
Make az CLI check compatible with Windows
andyleejordan Oct 15, 2020
8220a60
Only set PATH for SSH commands
andyleejordan Oct 15, 2020
d10825e
Make ‘ping’ cross-platform
andyleejordan Oct 15, 2020
a4d5f49
Fix types
andyleejordan Oct 16, 2020
cbbbcbd
Add tenacity package
andyleejordan Oct 16, 2020
bbc4c17
Add retry to get boot diagnostics with exponential wait
andyleejordan Oct 16, 2020
bf14056
Ignore unclosed file/socket resource warnings
andyleejordan Oct 16, 2020
b31ec91
Fix VM caching
andyleejordan Oct 16, 2020
d6d0198
Clean up types
andyleejordan Oct 16, 2020
b29ac6a
Enable all junit logging
andyleejordan Oct 16, 2020
4cd522d
Add logging to node plugin
andyleejordan Oct 16, 2020
52bd621
Split Node scopes to function and class fixtures
andyleejordan Oct 16, 2020
778c97c
Split smoke test into component tests with less verbose output
andyleejordan Oct 16, 2020
0a0e8b3
Add a ‘clean’ make target to clear the cache and show the setup plan
andyleejordan Oct 16, 2020
49b0edf
Don’t wait for deletion of resource group
andyleejordan Oct 16, 2020
33fcb31
Better output
andyleejordan Oct 17, 2020
27db854
Enable ICMP on deployed Azure VMs
andyleejordan Oct 17, 2020
b62eff0
Add retry with exponential backoff after reboot
andyleejordan Oct 17, 2020
7be7425
Replace tenacity with pytest-rerunfailures
andyleejordan Oct 18, 2020
e1c3c03
Generate HTML report instead of JUnit (XML)
andyleejordan Oct 18, 2020
788fa16
Add reports to gitignore
andyleejordan Oct 18, 2020
1e7b0e9
Revert "Replace tenacity with pytest-rerunfailures"
andyleejordan Oct 18, 2020
1a10501
Document use of Tenacity over pytest-rerunfailures
andyleejordan Oct 18, 2020
b4e8ad9
Add `ping()` to Node
andyleejordan Oct 20, 2020
f9bc739
Redo smoke test using single function
andyleejordan Oct 20, 2020
e94f06a
Demo test parameterization using smoke test
andyleejordan Oct 20, 2020
ae339c6
Change SSH test to just connecting
andyleejordan Oct 20, 2020
6e0b5cd
Fix timeout of reboot command
andyleejordan Oct 21, 2020
753e83f
Improve retry logic and increase command timeouts
andyleejordan Oct 21, 2020
9d3713d
Use pytest-rerunfailures in addition to Tenacity
andyleejordan Oct 21, 2020
0a87e60
Use East US 2 Azure region by default
andyleejordan Oct 21, 2020
3441b76
Move pytest/Makefile to root directory
andyleejordan Oct 21, 2020
7618b50
Add PyYAML package
andyleejordan Oct 22, 2020
df78c88
Add proof-of-concept YAML playbook parsing
andyleejordan Oct 22, 2020
8dbb8f6
Add basic user modes
andyleejordan Oct 27, 2020
cb0a21a
Draft the Technical Specification Document
andyleejordan Oct 27, 2020
0dcb30c
Basic automatic grouping of tests based on feature requirement
andyleejordan Nov 3, 2020
d3e088e
Slightly extended example which removes instead of skips tests
andyleejordan Nov 4, 2020
ed25509
Add pytest-xdist
andyleejordan Nov 4, 2020
c200847
Add filelock package
andyleejordan Nov 4, 2020
8be09cb
Demonstrate parallelism with shared feature fixture
andyleejordan Nov 4, 2020
1c972a0
Proof-of-concept redux with dynamic feature requests
andyleejordan Nov 6, 2020
72dfe08
Use schema to massively simplify playbook
andyleejordan Nov 7, 2020
75a52c1
Add schema package
andyleejordan Nov 7, 2020
199458a
Fix up tests for schema validation
andyleejordan Nov 7, 2020
9aff173
Move LISA marker and update tests
andyleejordan Nov 10, 2020
9fc8d17
Cleanup types in Target and Azure modules
andyleejordan Nov 10, 2020
16e30d7
Handle LISA marker being optional
andyleejordan Nov 10, 2020
9a199b9
Load platforms dynamically with their own parameters schema
andyleejordan Nov 10, 2020
af47815
Move smoke test targets to smoke.yaml
andyleejordan Nov 10, 2020
2edf257
Move playbooks and fix self tests to use “Custom” platform
andyleejordan Nov 11, 2020
6c1c746
Small cleanups found during update of design document
andyleejordan Nov 12, 2020
03125ce
Write version 0.2 of design document
andyleejordan Nov 12, 2020
0120bae
Write version 0.3 of design document
andyleejordan Nov 18, 2020
ed42f7a
Add initial Pytest plugin trees
andyleejordan Nov 18, 2020
55aa90c
Update Python packages
andyleejordan Nov 19, 2020
16ef4e7
Create pytest-playbook plugin
andyleejordan Nov 19, 2020
02beaf0
Settle on plugin source code layout
andyleejordan Nov 19, 2020
886aa12
Create pytest-target plugin
andyleejordan Nov 20, 2020
bb476b3
Fix tests for target plugin refactor
andyleejordan Nov 20, 2020
a72559c
Make `Target.schema()` an abstract classmethod
andyleejordan Nov 20, 2020
81718d3
Handle schema, yaml, and OS errors in playbook
andyleejordan Nov 20, 2020
3b44e89
Rename top-level package to ‘LISA’ so we can make pytest-lisa
andyleejordan Nov 20, 2020
a573d0a
Move `lisa.config` into `Target` to break coupling
andyleejordan Nov 20, 2020
af043cb
Create pytest-lisa plugin
andyleejordan Nov 20, 2020
635b0aa
Improve `target.plugin` documentation
andyleejordan Nov 20, 2020
66bc2c8
Use self.conn directly instead of forwarding
andyleejordan Nov 20, 2020
32b2c76
Update .gitignore
andyleejordan Nov 20, 2020
b9b62ed
Remove filelock, drop Python to 3.7, and test it
andyleejordan Nov 20, 2020
d06a425
Programmatically register LISA marker
andyleejordan Nov 20, 2020
47c8845
Add `lisa` binary
andyleejordan Nov 20, 2020
db2d17b
Update readme, CI, license, etc.
andyleejordan Nov 21, 2020
b5f3274
Remove references to LINUX_SCRIPTS and unnecessary CLI options
andyleejordan Nov 21, 2020
03d5a2f
Fix Azure.deploy() (forgot to finish ‘internal_address’)
andyleejordan Nov 24, 2020
8b064b0
Build as a Python package (so we can take a dependency on it)
andyleejordan Nov 24, 2020
776fcfe
Add demo-like Pytest options
andyleejordan Dec 7, 2020
f4fb61f
Add a TODO to the design doc
andyleejordan Dec 7, 2020
00d8556
Downgrade schema package to 0.7.2 manually
andyleejordan Dec 8, 2020
fa75c67
Setup module and class target fixtures
andyleejordan Dec 9, 2020
6f1bef4
Add second smoke test example using multiple small tests
andyleejordan Dec 9, 2020
17854c5
Update playbooks for demo and add module as criteria field
andyleejordan Dec 9, 2020
1fd4cb1
Implement custom `LisaScheduler` to scope tests by parameterization
andyleejordan Dec 10, 2020
7a3f3a7
Move pytest-xdist dependency to pytest-lisa
andyleejordan Dec 10, 2020
3380c86
Use priority less likely to conflict in rules to allow ICMP on Azure
andyleejordan Dec 10, 2020
d032bfa
Prefix target parameter with `Target=<Name>`
andyleejordan Dec 12, 2020
46bcc26
Adjust scheduler to split on target parameter, and add tests
andyleejordan Dec 12, 2020
1f49365
Rename `parameters` to `params` because of its use frequency
andyleejordan Dec 12, 2020
13232ea
Rename `Local` platform to `SSH` and accept `host` param
andyleejordan Dec 12, 2020
61fbce9
Setup assertion rewriting for `azure` and `target` modules
andyleejordan Dec 12, 2020
700ae22
Rename `playbook.playbook` to `playbook.data`
andyleejordan Dec 12, 2020
8d3005a
Flatten the playbook schema
andyleejordan Dec 12, 2020
42e4953
Fix scheduler to handle whitespace in target names
andyleejordan Dec 12, 2020
51a29e3
Add basic schema printing option to playbook
andyleejordan Dec 12, 2020
8f4b042
Simplify logic for generating target schema
andyleejordan Dec 14, 2020
915aef8
Enable mutable platform defaults in the playbook
andyleejordan Dec 15, 2020
9937d37
Add descriptions to pytest-lisa schemata
andyleejordan Dec 15, 2020
d207d73
Add `pytest.mark.target` to `pytest-target` to finish decoupling
andyleejordan Dec 15, 2020
0585ab6
Forward `pytest.mark.lisa(features=...)` to `pytest.mark.target`
andyleejordan Dec 15, 2020
0cda8c3
Stop matching `Target.params` when searching for targets
andyleejordan Dec 15, 2020
26a78f9
Add `reuse` parameter to `pytest.mark.target`
andyleejordan Dec 15, 2020
d4fe7f9
Add defaults to `get()` to make type checking happy
andyleejordan Dec 15, 2020
86d37bf
Reference nested schemata with definitions
andyleejordan Dec 15, 2020
a054136
Add logging
andyleejordan Dec 15, 2020
c6bd423
Check that matching targets have the same parameterization name
andyleejordan Dec 15, 2020
8b9e289
Suppress warning caused by earlier xdist import
andyleejordan Dec 15, 2020
61c7c24
Add basic `targets` fixture which gets N target instances
andyleejordan Dec 15, 2020
f98c116
Rename `Azure` to `AzureCLI` in preparation for more implementations
andyleejordan Dec 15, 2020
89ef35b
Hide some `az` output
andyleejordan Dec 15, 2020
b45e658
Clean up of `pytest_playbook_schema` by moving code to `Target`
andyleejordan Dec 16, 2020
4e0faa0
Make `name` for `Target.__init__` non-optional
andyleejordan Dec 16, 2020
e724522
Print schema to a file, not just stdout
andyleejordan Dec 16, 2020
ba5a8a9
Document how to lint playbooks against JSON Schema
andyleejordan Dec 17, 2020
4674d5a
Add `self.data` as field to `Target` (used for cache)
andyleejordan Dec 17, 2020
cff1069
Implement caching of targets between runs
andyleejordan Dec 18, 2020
731def1
Update readme
andyleejordan Dec 18, 2020
37a1e89
Skip `targets` test until cache key is fixed
andyleejordan Dec 18, 2020
b9672ce
Rename `Target.name` to `group` and add `number`
andyleejordan Dec 18, 2020
be86c87
Add `free` property to `Target` to indicate in-use state
andyleejordan Dec 22, 2020
4e76b06
Add basic JSON serialization to `Target`
andyleejordan Dec 22, 2020
9ac98ea
Implement caching of target groups
andyleejordan Dec 22, 2020
2be9b90
Implement `--delete-targets`
andyleejordan Dec 22, 2020
92a3d0a
Refactor cache access into pair of functions
andyleejordan Dec 22, 2020
6116b0f
Add FileLock package to `pytest-target`
andyleejordan Dec 22, 2020
45dbbdf
Rename `Target.free` to `Target.locked`
andyleejordan Dec 22, 2020
d5239f2
Move `name` to base `Target` class
andyleejordan Dec 22, 2020
6797fcf
Use dataclass as serializable container for target data
andyleejordan Dec 22, 2020
f876c7c
Refactor to use locking context manager instead of session fixture
andyleejordan Dec 23, 2020
6df423d
Emit full flake8/mypy errors in CI
andyleejordan Dec 23, 2020
45bb5c5
Properly report deselected items
andyleejordan Jan 5, 2021
ec8e757
Update Python packages
andyleejordan Jan 6, 2021
80b44a6
Add Sphinx as developer dependency
andyleejordan Jan 6, 2021
aa38bbc
Add recommonmark as developer dependency
andyleejordan Jan 6, 2021
c7c4b6c
Add basic Sphinx configuration
andyleejordan Jan 6, 2021
c9faf5c
Enable built-in extensions
andyleejordan Jan 6, 2021
c5dcd7c
Create Table of Contents
andyleejordan Jan 6, 2021
4fdda97
Documentation updates
andyleejordan Jan 6, 2021
a36530e
Convert readme to reStructuredText for proper documentation
andyleejordan Jan 7, 2021
c0283cd
Add CI workflow to build documentation
andyleejordan Jan 7, 2021
4536ba4
Setup autosummary to generate API documentation
andyleejordan Jan 7, 2021
7296e66
Note use of Sphinx for documentation generation
andyleejordan Jan 7, 2021
2d7519a
Fix links to source in documentation
andyleejordan Jan 7, 2021
626a215
Setup autodoc to document class members
andyleejordan Jan 7, 2021
0f988cf
Make a couple members private to avoid documentation generation
andyleejordan Jan 7, 2021
0f84dca
Generate TODO lists in documentation
andyleejordan Jan 7, 2021
48f6ad8
Keep CLA and Legal notices only in readme
andyleejordan Jan 7, 2021
0fe3ea7
Update `plugin.py` docstrings
andyleejordan Jan 8, 2021
17f4358
Ignore long lines (they’re inevitable with links)
andyleejordan Jan 8, 2021
3dcb7c6
Update `target.py` docstrings
andyleejordan Jan 8, 2021
9f037c0
Add copyright headers and notice to documentation website
andyleejordan Jan 11, 2021
856705c
Update index
andyleejordan Jan 11, 2021
12c7050
Convert design from markdown to reStructuredText
andyleejordan Jan 12, 2021
fe1f0cb
Move `pytest-target` dependency from `pytest-lisa` to `LISA`
andyleejordan Jan 12, 2021
df1084f
Update TSD to 0.4
andyleejordan Jan 13, 2021
da6fce7
Make deploy and cache logic more robust
andyleejordan Jan 14, 2021
6559c4d
Fix up smoke test retry logic
andyleejordan Jan 15, 2021
44b6cac
Add README files and info to plugins
andyleejordan Jan 16, 2021
3b22578
Update `pytest-playbook` and `pytest-lisa` documentation
andyleejordan Jan 16, 2021
2d10e24
Use `tmp_path` fixture in smoke test for boot diagnostics
andyleejordan Jan 20, 2021
d552019
Hide output of commands to allow ping in the AzureCLI’s NSG
andyleejordan Jan 20, 2021
50fe160
Display summary of all tests
andyleejordan Jan 20, 2021
56739e9
Write usage document
andyleejordan Jan 20, 2021
6ab5edc
Use default capture mode and short traceback
andyleejordan Jan 21, 2021
3a4e95d
Setup plugins to depend on pytest-playbook from PyPI
andyleejordan Jan 21, 2021
b9a67b9
Document steps to publish packages
andyleejordan Jan 21, 2021
7bbdbda
Add smoke test code as example to usage document
andyleejordan Jan 21, 2021
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
5 changes: 5 additions & 0 deletions .archive/.flake8
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
[flake8]
max-line-length = 88
select = B,BLK,C90,E,F,I,W
max-complexity = 15
extend-ignore = E203
File renamed without changes.
File renamed without changes.
18 changes: 18 additions & 0 deletions .archive/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# IDE Settings
/.vscode

# lisa runtime folder
/runtime/*

# python cache
__pycache__

# you can have your own command alias on Windows
lisa.cmd

# it's auto generated by poetry
lisa.egg-info

# code coverage result
.coverage
htmlcov
9 changes: 9 additions & 0 deletions .archive/CODE_OF_CONDUCT.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# Microsoft Open Source Code of Conduct

This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/).

Resources:

- [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/)
- [Microsoft Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/)
- Contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with questions or concerns
284 changes: 284 additions & 0 deletions .archive/CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,284 @@
# Contributing Guidelines

This document describes the existing developer tooling we have in place (and what to
expect of it), as well as our design and development philosophy.

## Naming Conventions

Naming conventions are not automatically enforced, so please read the [naming
conventions](https://www.python.org/dev/peps/pep-0008/#naming-conventions)
section of PEP 8, which describes what each of the different styles means. A
short summary of the most important parts:

* Modules (and hence files) should have short, all-lowercase names.
* Class (and exception) names should normally use the `CapWords` convention
(also known as `CamelCase`).
* Function and variable names should be lowercase, with words separated by
underscores as necessary to improve readability (also known as `snake_case`).
* To avoid collisions with the standard library, an underscore can be appended,
such as `id_`.
* Always use `self` for the first argument to instance methods.
* Always use `cls` for the first argument to class methods.
* One leading underscore like `_data` is for non-public methods and instance
variables. And it can be used by sub-classes. If it won't be used in
sub-classes, use like `__data`.
* 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
it introduces cognitive overhead to track yet another name.

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

## Automated Tooling

If you have ran LISAv3 already, then you have installed and used the `poetry`
tool. [Poetry][] is a [PEP 518][] compliant and cross-platform build system
which handles our Python dependencies and environment.

This project’s dependencies are found in the [`pyproject.toml`](pyproject.toml)
file. This is similar to but more powerful than the familiar `requirements.txt`.
With [PEP 518][] and [PEP 621][].

[Poetry]: https://python-poetry.org/docs/
[PEP 518]: https://www.python.org/dev/peps/pep-0518/
[PEP 621]: https://www.python.org/dev/peps/pep-0621/

### Metadata

The first section, `tool.poetry`, defines the project’s metadata (name, version,
description, authors, and license) which will be embedded in the final built
package.

The chosen version follows [Semantic Versioning][], with the [Python specific
pre-release versioning suffix][pre-release] ‘.dev1’. Since this is “LISAv3” it
seemed appropriate to set our version to ‘3.0.0.dev1’, that is, “the first
development release of LISAv3.”

[Semantic Versioning]: https://semver.org/
[pre-release]: https://packaging.python.org/guides/distributing-packages-using-setuptools/#choosing-a-versioning-scheme

### Package Dependencies

The next section, `tool.poetry.dependencies`, is where `poetry add
<package_name>` records our required packages.

Poetry automatically creates and manages [isolated
environments](https://python-poetry.org/docs/managing-environments/).

From the documentation:

> Poetry will first check if it’s currently running inside a virtual
> environment. If it is, it will use it directly without creating a new one. But
> if it’s not, it will use one that it has already created or create a brand new
> one for you.

On Linux, your initial run of `poetry install` will cause Poetry to
automatically setup a new [virtualenv][] using [pyenv][]. If you are developing
on Windows, you will want to setup your own, perhaps using [Conda][].

[virtualenv]: https://docs.python-guide.org/dev/virtualenvs/
[pyenv]: https://github.com/pyenv/pyenv
[Conda]: https://docs.conda.io/en/latest/

* python: We pinned Python to version 3.8 so everyone uses the same version.

* psutil: TODO @squirrelsc will document

* pyyaml: TODO @squirrelsc will document

* retry: TODO @squirrelsc will document

* paramiko: TODO @squirrelsc will document

* spurplus: TODO @squirrelsc will document

* dataclasses-json: TODO @squirrelsc will document (brings in `usjon` which
requires `gcc` and `libpython`)

* portalocker: TODO @squirrelsc will document

* azure-*: TODO @squirrelsc will document

### Developer Dependencies

Similar to the previous section, `tool.poetry.dev-dependencies` is where `poetry
add --dev <package_name>` records our _developer_ packages. These are not
necessary for LISAv3 to execute, but are used by developers to automatically
adhere to our coding standards.

* [Black](https://github.com/psf/black), the opinionated code formatter which
settles all debates as to how our Python files should be formatted. It follows
[PEP 8](https://www.python.org/dev/peps/pep-0008/), the official Python style
guide, and where ambiguous makes the decision for us.

* [Flake8](https://flake8.pycqa.org/en/latest/) (and integrations), the semantic
analyzer, used to coordinate most of the other tools.

* [isort](https://timothycrosley.github.io/isort/), the `import` sorter, which
automatically splits imports into the expected, alphabetized sections.

* [mypy](http://mypy-lang.org/), the static type checker, which coupled with
type annotations allows us to avoid the pitfalls of Python being a dynamically
typed language.

* [python-language-server](https://github.com/palantir/python-language-server)
(and integrations), the de facto LSP server. While Microsoft is developing
their own LSP servers, they do not integrate with the existing ecosystem of
tools, and their latest tool, Pyright, simply does not support
`pyproject.toml`. Since pyls is used far more widely, and supports every
editor, we use it.

* [rope](https://github.com/python-rope/rope), to provide completions and
renaming support to pyls.

With these packages installed and a correctly setup editor (see the readme and
feel free to reach out to us), your code should automatically follow all the
standards which we could automate.

The final sections, `tool.black`, `tool.isort`, `build-system`, and the
`.flake8` file (Flake8 does not yet support `pyproject.toml`) configure the
tools per their recommendations.

## Type Annotations

We are using [mypy][] to enforce static type checking of our Python code. This
may surprise you as Python is not a statically typed language. While dynamic
typing can be useful, for a complex tool such as LISA it is more likely to
introduce bugs that are found only at runtime (which the user experiences as a
crash). For more information on why we (and others) do this, see [Dropbox’s
journey to type checking 4 million lines of Python][dropbox]. [PEP 484][] and
[PEP 526][] (among others) introduced and defined [type hints][] for the Python
language. You can probably figuring out the syntax based on the surrounding
code, but you can also see this [Intro to Using Python Type Hints][intro] and
mypy’s [cheat sheet][].

[mypy]: http://mypy-lang.org/
[dropbox]: https://dropbox.tech/application/our-journey-to-type-checking-4-million-lines-of-python
[PEP 484]: https://www.python.org/dev/peps/pep-0484/
[PEP 526]: https://www.python.org/dev/peps/pep-0526/
[type hints]: https://docs.python.org/3/library/typing.html
[intro]: https://kishstats.com/python/2019/01/07/python-type-hinting.html
[cheat sheet]: https://mypy.readthedocs.io/en/latest/cheat_sheet_py3.html

## Runbook schema

Some plugins like Platform need follow this section to extend runbook schema. Runbook is the configurations of LISA runs. Every LISA run need a runbook.

The runbook uses [dataclass](https://docs.python.org/3/library/dataclasses.html) to define, [dataclass-json](https://github.com/lidatong/dataclasses-json/) to deserialize, and [marshmallow](https://marshmallow.readthedocs.io/en/3.0/api_reference.html) to validate the schema.

See more examples in [schema.py](lisa/schema.py), if you need to extend runbook schema.

## Committing Guidelines

A best practice when using [Git](https://git-scm.com/book/en/v2) is to create a
series of independent and well-documented commits. Each commit should “do one
thing” and do it correctly. If a mistake is made (you need to fix a bug or
adjust formatting), you should amend it (or use an [interactive
rebase](https://thoughtbot.com/blog/git-interactive-rebase-squash-amend-rewriting-history)
to edit it). If you’re using Emacs, the [Magit](https://magit.vc/) package makes
all of this easy. Some of the reasons for making each commit polished is that it
aids immensely in future debugging. It lets us use tools like [`git
bisect`](https://git-scm.com/docs/git-bisect) to automatically find bugs, and
understand why prior code was written. Although some of it has gone out of date,
see this otherwise great essay on [Git best
practices](http://sethrobertson.github.io/GitBestPractices/). For how Git works,
read [Git from the Bottom
Up](https://jwiegley.github.io/git-from-the-bottom-up/).

For writing your commit messages, see this modification of [Tim Pope’s
example](https://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html):

> Capitalized, short (72 chars or less) summary
>
> More detailed explanatory text, if necessary. Wrap it to about 72
> characters or so. In some contexts, the first line is treated as the
> subject of an email and the rest of the text as the body. The blank line
> separating the summary from the body is critical (unless you omit the
> body entirely); tools like rebase can get confused if you run the two
> together.
>
> Write your commit message in the imperative: “Fix bug” and not “Fixed
> bug” or “Fixes bug.” This convention matches up with commit messages
> generated by commands like git merge and git revert.
>
> Further paragraphs come after blank lines.
>
> * Bullet points are okay, too
>
> * Typically a hyphen or asterisk is used for the bullet, followed by a
> single space, with blank lines in between, but conventions vary here
>
> * Use a hanging indent

You should also feel free to use Markdown in the commit messages, as our project
is hosted on GitHub which renders it (and Markdown is human readable).

## Design Patterns

The most important goal we are attempting to accomplish with LISAv3 is for it to
be “simple, clean, and with a low maintenance cost.”

We should use caution when using Object Oriented Design, because when it is used
without critical analysis, it creates unmaintainable code. A great talk on this
subject is [Stop Writing Classes](https://www.youtube.com/watch?v=o9pEzgHorH0),
by Jack Diederich. As he says, “classes are great but they are also overused.”

This [Python Design Patterns](https://python-patterns.guide/) is a fantastic
collection of material for writing maintainable Python code. It specifically
details many of the common “Object Oriented” patterns from the Gang of Four book
(which, in fact, were patterns geared toward languages like C++, and no longer
apply to modern languages like Python), what lessons can be learned from them,
and how to apply them (or their modern alternatives) today. It also serves as an
easy-to-read guide to the Gang of Four book itself, as its principles still
serve us well today.

Every time a developer chooses to use a design pattern, that person needs to
reason through and document why it was chosen, and what alternatives were
considered. We will recreate the problems with LISAv2 unless we take our time to
carefully create a well-designed and maintainable framework.

Several popular patterns that actually _do not_ work well in Python are:

* [The Abstract Factory Pattern](https://python-patterns.guide/gang-of-four/abstract-factory/)
* [The Factory Method Pattern](https://python-patterns.guide/gang-of-four/factory-method/)
* [The Prototype Pattern](https://python-patterns.guide/gang-of-four/prototype/)
* [The Singleton Pattern](https://python-patterns.guide/gang-of-four/singleton/)

Conversely, patterns that are a natural fit to Python include:

* [The Composite Pattern](https://python-patterns.guide/gang-of-four/composite/)
* [The Iterator Pattern](https://python-patterns.guide/gang-of-four/iterator/)
(caution: it is actually better to implement these with `yield`!)

Finally, a high-level guide to all things Python is [The Hitchhiker’s Guide to
Python](https://docs.python-guide.org/). It covers just about everything in the
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
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.

* [unittest](https://docs.python.org/3/library/unittest.html)
* [doctest](https://docs.python.org/3/library/doctest.html)
* [subprocess](https://pymotw.com/3/subprocess/index.html)
* [GitHub Actions](https://github.com/LIS/LISAv2/actions)
* [ShellCheck](https://www.shellcheck.net/)
* [Governance](https://opensource.guide/leadership-and-governance/)
* [Maintenance Cost](https://web.archive.org/web/20120313070806/http://users.jyu.fi/~koskinen/smcosts.htm)
* Parallelism and multi-plexing
* Versioned inputs and outputs
File renamed without changes.
File renamed without changes.
Loading