-
Notifications
You must be signed in to change notification settings - Fork 6
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #255 from simonsobs/develop
Release v0.9.1
- Loading branch information
Showing
17 changed files
with
372 additions
and
202 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -34,4 +34,4 @@ RUN pip3 install -r requirements.txt | |
COPY . /app/ocs/ | ||
|
||
# Install ocs | ||
RUN pip3 install -e . | ||
RUN pip3 install . |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
Testing | ||
======= | ||
|
||
Writing tests for your OCS Agents is important for the long term maintanence of | ||
your Agent. Tests allow other developers to contribute to your Agent and easily | ||
confirm that their changes did not break functionality within the Agent. With | ||
some setup, tests can also allow you to test your Agent without access to the | ||
hardware that it controls. | ||
|
||
Testing within OCS comes in two forms, unit tests and integration tests. Unit | ||
tests test functionality of the Agent code directly, without running the Agent | ||
itself (or any supporting parts, such as the crossbar server, or a piece of | ||
hardware to connect to.) | ||
|
||
Integration tests run a small OCS network, starting up the crossbar server, | ||
your Agent, and any supporting programs that your Agent might need (for | ||
instance, a program accepting serial connections for you Agent to connect to). | ||
As a result, integration tests are more involved than unit tests, requiring | ||
more setup and thus taking longer to execute. | ||
|
||
Both types of testing can be important for fully testing the functionality of | ||
your Agent. | ||
|
||
Running Tests | ||
------------- | ||
|
||
.. include:: ../../tests/README.rst | ||
:start-line: 2 | ||
|
||
Testing API | ||
----------- | ||
|
||
This section details the helper functions within OCS for assisting with testing | ||
your Agents. | ||
|
||
.. automodule:: ocs.testing | ||
:members: |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,126 @@ | ||
import os | ||
import time | ||
import pytest | ||
import signal | ||
import subprocess | ||
import coverage.data | ||
import urllib.request | ||
|
||
from urllib.error import URLError | ||
|
||
from ocs.ocs_client import OCSClient | ||
|
||
|
||
def create_agent_runner_fixture(agent_path, agent_name, args=None): | ||
"""Create a pytest fixture for running a given OCS Agent. | ||
Parameters: | ||
agent_path (str): Relative path to Agent, | ||
i.e. '../agents/fake_data/fake_data_agent.py' | ||
agent_name (str): Short, unique name for the agent | ||
args (list): Additional CLI arguments to add when starting the Agent | ||
""" | ||
@pytest.fixture() | ||
def run_agent(cov): | ||
env = os.environ.copy() | ||
env['COVERAGE_FILE'] = f'.coverage.agent.{agent_name}' | ||
env['OCS_CONFIG_DIR'] = os.getcwd() | ||
cmd = ['coverage', 'run', | ||
'--rcfile=./.coveragerc', | ||
agent_path, | ||
'--site-file', | ||
'./default.yaml'] | ||
if args is not None: | ||
cmd.extend(args) | ||
agentproc = subprocess.Popen(cmd, | ||
env=env, | ||
stdout=subprocess.PIPE, | ||
stderr=subprocess.PIPE, | ||
preexec_fn=os.setsid) | ||
|
||
# wait for Agent to startup | ||
time.sleep(1) | ||
|
||
yield | ||
|
||
# shutdown Agent | ||
agentproc.send_signal(signal.SIGINT) | ||
time.sleep(1) | ||
|
||
# report coverage | ||
agentcov = coverage.data.CoverageData( | ||
basename=f'.coverage.agent.{agent_name}') | ||
agentcov.read() | ||
# protect against missing --cov flag | ||
if cov is not None: | ||
cov.get_data().update(agentcov) | ||
|
||
return run_agent | ||
|
||
|
||
def create_client_fixture(instance_id, timeout=30): | ||
"""Create the fixture that provides tests a Client object. | ||
Parameters: | ||
instance_id (str): Agent instance-id to connect the Client to | ||
timeout (int): Approximate timeout in seconds for the connection. | ||
Connection attempts will be made X times, with a 1 second pause | ||
between attempts. This is useful if it takes some time for the | ||
Agent to start accepting connections, which varies depending on the | ||
Agent. | ||
""" | ||
@pytest.fixture() | ||
def client_fixture(): | ||
# Set the OCS_CONFIG_DIR so we read the local default.yaml file | ||
os.environ['OCS_CONFIG_DIR'] = os.getcwd() | ||
print(os.environ['OCS_CONFIG_DIR']) | ||
attempts = 0 | ||
|
||
while attempts < timeout: | ||
try: | ||
client = OCSClient(instance_id) | ||
break | ||
except RuntimeError as e: | ||
print(f"Caught error: {e}") | ||
print("Attempting to reconnect.") | ||
|
||
time.sleep(1) | ||
attempts += 1 | ||
|
||
return client | ||
|
||
return client_fixture | ||
|
||
|
||
def check_crossbar_connection(port=18001, interval=5, max_attempts=6): | ||
"""Check that the crossbar server is up and available for an Agent to | ||
connect to. | ||
Parameters: | ||
port (int): Port the crossbar server is configured to run on for | ||
testing. | ||
interval (float): Amount of time in seconds to wait between checks. | ||
max_attempts (int): Maximum number of attempts before giving up. | ||
Notes: | ||
For this check to work the crossbar server needs the `Node Info Service | ||
<https://crossbar.io/docs/Node-Info-Service/>`_ running at the path | ||
/info. | ||
""" | ||
attempts = 0 | ||
|
||
while attempts < max_attempts: | ||
try: | ||
url = f"http://localhost:{port}/info" | ||
code = urllib.request.urlopen(url).getcode() | ||
except (URLError, ConnectionResetError): | ||
print("Crossbar server not online yet, waiting 5 seconds.") | ||
time.sleep(interval) | ||
|
||
attempts += 1 | ||
|
||
assert code == 200 | ||
print("Crossbar server online.") |
Oops, something went wrong.