Skip to content

Commit

Permalink
reasonable text for ops.testing
Browse files Browse the repository at this point in the history
  • Loading branch information
dimaqq committed Sep 10, 2024
1 parent d055d3e commit 4d9234f
Show file tree
Hide file tree
Showing 3 changed files with 38 additions and 113 deletions.
115 changes: 10 additions & 105 deletions docs/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -3,19 +3,18 @@ ops library API reference
=========================

The `ops` library is a Python framework for writing and testing Juju charms.
It is the recommended way to write charms for both Kubernetes and machines.

The `ops` library provides powerful constructs for charm developers: FIXME fixme fixme the ops library provides structure that makes blah blah easier to reason.
Easier to write charms, read other charms, and reuse aspects like individual integration handling via charm libs.

- ``ops`` offers the API to respond to Juju events and manage application units, relations, storage, secrets and resources.
It is the recommended way to write charms for both Kubernetes and machines.
The framework encapsulates the best charming practice and helps you write
consistent readable charms, reuse code via charm libs, and separate typical charm
concerns, such as application state management from integration management and
lifecycle management from testability.

- **Interact with Juju**: `ops` offers the API to respond to Juju events
and manage application units, relations, storage, secrets and resources.
- **Manage workloads**: For Kubernetes charms, `ops.pebble`
provides an interface to control services inside the workload containers.
- **Write unit tests**: `ops.testing` is the unit testing framework for
your charm.
- ``ops`` is the API to respond to Juju events and manage the application
[units, relations, storage, secrets and resources].
- ``ops.pebble`` is the interface to control services and respond to their
events in the workload container for Kubernetes charms.
- ``ops.testing`` is the unit testing framework for your charm.

.. toctree::
:maxdepth: 2
Expand All @@ -24,38 +23,6 @@ Easier to write charms, read other charms, and reuse aspects like individual int
ops module
==========

Provides APIs for managing the given Juju application, focusing on:

- Lifecycle
- State management and event response
- Handling of units, relations, and resources

Here’s a simple charm example using the `ops` library:

.. code-block:: python
#!/usr/bin/env python3
import ops
class FastAPIDemoCharm(ops.CharmBase):
"""Charm the service."""
def __init__(self, framework):
super().__init__(framework)
# let's try to on.started...
self.framework.observe(self.on.demo_server_pebble_ready, self._on_demo_server_pebble_ready)
def _on_demo_server_pebble_ready(self, event):
event.workload.container.add_layer(...)
event.workload.container.replan()
self.unit.status = ops.ActiveStatus()
if __name__ == "__main__": # pragma: nocover
ops.main(FastAPIDemoCharm)
.. automodule:: ops
:exclude-members: main

Expand All @@ -75,74 +42,12 @@ legacy main module
ops.pebble module
=================

An example of configuring workload container using pebble.

.. code-block:: python
def _on_demo_server_pebble_ready(self, event):
event.workload.container.add_layer(self._pebble_layer())
event.workload.container.replan()
self.unit.status = ops.ActiveStatus()
def _pebble_layer(self) -> ops.pebble.Layer:
return ops.pebble.Layer({
"services": {
"demo_service": {
"override": "replace",
"startup": "enabled",
"command": ["/some/command", "--some-arg"],
"environment": {
"SOME_ENV_VAR": "some value",
},
# Let the container die if things go wrong
"on-success": "shutdown",
"on-failure": "shutdown",
"on-check-failure": {
"online": "shutdown"
}
}
},
"checks": {
# A custom check called "online"
"online": {
"override": "replace",
"exec": {
"command": ["/another/command", "--another-arg"],
},
"period": "3s"
}
},
})
.. automodule:: ops.pebble


ops.testing module
==================

Framework for unit testing charms in a simulated environment, enabling:

- Testing against mocked Juju events and states
- Validation of charm behavior prior to live deployment

An example testing a charm using the Harness framework.

.. code-block:: python
@pytest.fixture
def harness():
harness = ops.testing.Harness(FastAPIDemoCharm)
harness.begin()
yield harness
harness.cleanup()
def test_pebble_ready(harness):
assert harness.model.unit.status == ops.MaintenanceStatus("")
harness.container_pebble_ready("demo_server")
assert harness.model.unit.status == ops.ActiveStatus()
.. automodule:: ops.testing


Expand Down
11 changes: 5 additions & 6 deletions ops/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,12 @@
# See the License for the specific language governing permissions and
# limitations under the License.

"""The ops library: a Python framework for writing Juju charms.
"""The API for managing a Juju application.
The ops library is a Python framework (`available on PyPI`_) for developing
and testing Juju charms in a consistent way, using standard Python constructs
to allow for clean, maintainable, and reusable code.
- lifecycle fixme fixme
- state managment
- responding to events
- handling of units, relatiuons and resources
A charm is an operator -- business logic encapsulated in a reusable software
package that automates every aspect of an application's life.
Expand All @@ -35,8 +36,6 @@
https://juju.is/docs/sdk.
To learn more about Juju, visit https://juju.is/docs/olm.
.. _available on PyPI: https://pypi.org/project/ops/
"""

# The "from .X import Y" imports below don't explicitly tell Pyright (or MyPy)
Expand Down
25 changes: 23 additions & 2 deletions ops/testing.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,29 @@
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

"""Infrastructure to build unit tests for charms using the ops library."""
"""Framework for unit testing charms in a simulated environment.
The recommended structure delineates three kinds of tests:
- **Unit Tests**: Test charm code against mock Juju APIs and mocked-out
workloads using this module, ``ops.testing``. Validate isolated behavior
without external interactions.
- **Interface Tests**: Validate charm library behavior without individual
charm code against mock Juju APIs. For more information, see
`Interface Tests <https://juju.is/docs/sdk/interface-tests>`_.
- **Integration Tests**: Spin up several charms in a test model in a real Juju
controller, set up the integrations between the charms, and validate the
workload behavior and connections between the integrated workloads. See
`Integration Tests <https://juju.is/docs/sdk/write-integration-tests-for-a-charm>`_.
The key elements of this module are the :class:`ops.testing.Harness` class, the
convenience entrypoint :meth:`~ops.testing.Harness.begin_with_initial_hooks` as
well as individual lifecycle methods :meth:`~ops.testing.Harness.begin` and
:meth:`~ops.testing.Harness.cleanup`; collection functionality via
:meth:`~ops.testing.Harness.evaluate_status`, along with individual Model properties
like :attr:`~ops.Model.unit` exposed via :attr:`~ops.testing.Harness.model` that's
driven by Harness.
"""

import dataclasses
import datetime
Expand Down

0 comments on commit 4d9234f

Please sign in to comment.