Skip to content

Commit

Permalink
backup
Browse files Browse the repository at this point in the history
  • Loading branch information
y3rsh committed Mar 16, 2024
1 parent 1096a6a commit 2e57ffb
Show file tree
Hide file tree
Showing 35 changed files with 1,453 additions and 581 deletions.
22 changes: 9 additions & 13 deletions app-testing/Pipfile
Original file line number Diff line number Diff line change
Expand Up @@ -5,21 +5,17 @@ verify_ssl = true

[packages]
pytest = "==7.4.3"
black = "==23.11.0"
selenium = "==4.15.2"
importlib-metadata = "==6.8.0"
black = "==24.1.1"
selenium = "==4.17.2"
importlib-metadata = "==7.0.1"
requests = "==2.31.0"
python-dotenv = "==1.0.0"
pytest-xdist = "==3.5.0"
mypy = "==1.7.1"
types-requests = "==2.31.0.10"
python-dotenv = "==1.0.1"
mypy = "==1.8.0"
types-requests = "==2.31.0.20240125"
rich = "==13.7.0"
atomicwrites = "==1.4.1"
pyreadline3 = "==3.4.1"
pydantic = "==2.5.2"
pygithub = "==2.1.1"
ruff = "==0.1.6"
docker = "==6.1.3"
pydantic = "==2.6.0"
ruff = "==0.1.15"
docker = "==7.0.0"
syrupy = "==4.6.0"
pytest-html = "==4.1.1"

Expand Down
793 changes: 251 additions & 542 deletions app-testing/Pipfile.lock

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions app-testing/automation/data/protocol.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
"""Model of a protocol for testing."""

import hashlib
import os
from pathlib import Path
Expand Down
1 change: 1 addition & 0 deletions app-testing/automation/data/protocol_files.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
"""Define the possible names of protocol files to use in testing."""

from typing import Literal

names = Literal[
Expand Down
1 change: 1 addition & 0 deletions app-testing/automation/data/protocols.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
"""Map for protocol files available for testing."""

from automation.data.protocol import Protocol


Expand Down
1 change: 1 addition & 0 deletions app-testing/automation/driver/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
Expose clear information upon failure.
"""

from __future__ import annotations

import os
Expand Down
1 change: 1 addition & 0 deletions app-testing/automation/driver/drag_drop.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
"""Inject javascript to utilize drag and drop functionality."""

from pathlib import Path

from selenium.webdriver.chrome.webdriver import WebDriver
Expand Down
1 change: 1 addition & 0 deletions app-testing/automation/driver/wait.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
https://stackoverflow.com/questions/2785821/is-there-an-easy-way-in-python-to-wait-until-certain-condition-is-true
"""

import time
from typing import Any, Callable, Optional

Expand Down
1 change: 1 addition & 0 deletions app-testing/automation/menus/left_menu.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
"""Left Menu Locators."""

from typing import Literal

from rich.console import Console
Expand Down
1 change: 1 addition & 0 deletions app-testing/automation/pages/app_settings.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
"""Model for the App Settings page that displays info and settings for the app."""

from typing import Optional

from rich.console import Console
Expand Down
1 change: 1 addition & 0 deletions app-testing/automation/pages/deck_calibrate.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
"""Model for the screens of deck calibration."""

from enum import Enum
from typing import Optional

Expand Down
1 change: 1 addition & 0 deletions app-testing/automation/pages/device_landing.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
"""Model for the App page that displays info and settings for the app."""

import time
from typing import List, Optional

Expand Down
1 change: 1 addition & 0 deletions app-testing/automation/pages/labware_landing.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
"""Model for the Labware Landing page that displays labware info for the app."""

from typing import Optional

from rich.console import Console
Expand Down
1 change: 1 addition & 0 deletions app-testing/automation/pages/labware_setup.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
"""Model for the screen of Labware Setup."""

from rich.console import Console
from selenium.webdriver.chrome.webdriver import WebDriver
from selenium.webdriver.common.action_chains import ActionChains
Expand Down
1 change: 1 addition & 0 deletions app-testing/automation/pages/modal.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
"""Model for the App page that displays info and settings for the app."""

from typing import Optional

from rich.console import Console
Expand Down
1 change: 0 additions & 1 deletion app-testing/automation/pages/module_setup.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
"""Model for the screen of module setup."""


from rich.console import Console
from selenium.webdriver.chrome.webdriver import WebDriver
from selenium.webdriver.common.action_chains import ActionChains
Expand Down
1 change: 1 addition & 0 deletions app-testing/automation/resources/ot_robot.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
"""Model the the Opentrons Robot."""

from typing import List

import requests
Expand Down
1 change: 1 addition & 0 deletions app-testing/automation/resources/robot_data.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
"""Robot data."""

from dataclasses import dataclass
from typing import Literal

Expand Down
96 changes: 72 additions & 24 deletions app-testing/citools/generate_analyses.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,13 @@

import json
import os
import signal
import time
from contextlib import contextmanager
from dataclasses import dataclass
from enum import Enum, auto
from pathlib import Path
from typing import Any, Dict, List
from typing import Any, Dict, List, Optional

import docker # type: ignore
from automation.data.protocol import Protocol
Expand All @@ -33,6 +35,21 @@
console = Console()


@contextmanager
def timeout(time):
# Signal handler function
def raise_timeout(signum, frame):
raise TimeoutError

# Set the signal handler for the alarm signal
signal.signal(signal.SIGALRM, raise_timeout)
signal.alarm(time) # Set the alarm
try:
yield
finally:
signal.alarm(0) # Disable the alarm


class ProtocolType(Enum):
PROTOCOL_DESIGNER = auto()
PYTHON = auto()
Expand All @@ -45,10 +62,10 @@ class AnalyzeProtocol:
host_analysis_file: Path
container_analysis_file: Path
tag: str
analysis_execution_time: float | None = None
exit_code: int | None = None
output: str | None = None
analysis: Dict[str, Any] | None = None
analysis_execution_time: Optional[float] = None
exit_code: Optional[int] = None
output: Optional[str] = None
analysis: Optional[Dict[str, Any]] = None

@property
def analysis_file_exists(self) -> bool:
Expand All @@ -71,25 +88,25 @@ def set_analysis_execution_time(self, analysis_execution_time: float) -> None:
self.analysis_execution_time = analysis_execution_time


def run_container(image_name: str, timeout: int = 60) -> docker.models.containers.Container:
def stop_and_restart_container(image_name: str, timeout: int = 60) -> docker.models.containers.Container:
client = docker.from_env()
volumes = {
str(HOST_LABWARE): {"bind": CONTAINER_LABWARE, "mode": "rw"},
str(HOST_RESULTS): {"bind": CONTAINER_RESULTS, "mode": "rw"},
str(HOST_PROTOCOLS_ROOT): {"bind": CONTAINER_PROTOCOLS_ROOT, "mode": "rw"},
}

# Check for running containers using the specified image
# Find the running container using the specified image
containers = client.containers.list(filters={"ancestor": image_name, "status": "running"})

if containers:
print("Container already running.")
print("Exiting, stop this container so that you may be sure to have the right volumes attached.")
exit(1)
else:
# If no running container is found, start a new one with the specified volume
print("Starting a new container.")
container = client.containers.run(image_name, detach=True, volumes=volumes)
console.print("Stopping the running container(s)...")
for container in containers:
container.stop(timeout=10)

# Start a new container with the specified volume
console.print("Starting a new container.")
container = client.containers.run(image_name, detach=True, volumes=volumes)

# Wait for the container to be ready if a readiness command is provided
start_time = time.time()
Expand Down Expand Up @@ -117,7 +134,7 @@ def stop_and_remove_containers(image_name: str) -> None:
# Stop the container if it's running
if container.status == "running":
print(f"Stopping container {container.short_id}...")
container.stop()
container.stop(timeout=10)

# Remove the container
print(f"Removing container {container.short_id}...")
Expand Down Expand Up @@ -207,7 +224,6 @@ def report(protocol: AnalyzeProtocol) -> None:
console.print(protocol.output)
else:
console.print(f"[bold red]Analysis not created for {protocol.protocol_file_name}[/bold red]")
console.print(protocol.output)


def container_custom_labware_paths() -> List[str]:
Expand All @@ -216,15 +232,38 @@ def container_custom_labware_paths() -> List[str]:
return []


def analyze(protocol: AnalyzeProtocol, container: docker.models.containers.Container) -> None:
def analyze(protocol: AnalyzeProtocol, container: docker.models.containers.Container) -> bool:
# Run the analyze command
command = f"python -I -m opentrons.cli analyze --json-output {protocol.container_analysis_file} {protocol.container_protocol_file} {' '.join(map(str, container_custom_labware_paths()))}" # noqa: E501
start_time = time.time()
exit_code, result = container.exec_run(command) # Assuming container is a defined object
protocol.output = result.decode("utf-8")
protocol.exit_code = exit_code
protocol.set_analysis()
timeout_duration = 15 # seconds
try:
with timeout(timeout_duration):
command_result = container.exec_run(cmd=command)
exit_code = command_result.exit_code
result = command_result.output
protocol.output = result.decode("utf-8")
protocol.exit_code = exit_code
protocol.set_analysis()
protocol.set_analysis_execution_time(time.time() - start_time)
return True
except TimeoutError:
console.print(f"Command execution exceeded {timeout_duration} seconds and was aborted.")
logs = container.logs()
# Decode and print the logs
console.print(f"container logs{logs.decode('utf-8')}")
except KeyboardInterrupt:
console.print("Execution was interrupted by the user.")
raise
except Exception as e:
console.error(f"An unexpected error occurred: {e}")
console.print("Out of the try block...")
protocol.output = None
protocol.exit_code = None
protocol.analysis = None
protocol.set_analysis_execution_time(time.time() - start_time)
report(protocol)
return False


def analyze_many(protocol_files: List[AnalyzeProtocol], container: docker.models.containers.Container) -> None:
Expand All @@ -241,7 +280,7 @@ def analyze_against_image(tag: str) -> List[AnalyzeProtocol]:
# protocols_to_process = protocols[:1] # For testing
try:
console.print(f"Analyzing {len(protocols_to_process)} protocol(s) against {image_name}...")
container = run_container(image_name)
container = stop_and_restart_container(image_name)
analyze_many(protocols_to_process, container)
finally:
stop_and_remove_containers(image_name)
Expand All @@ -262,7 +301,16 @@ def generate_analyses_from_test(tag: str, protocols: List[Protocol]) -> None:
)
try:
console.print(f"Analyzing {len(protocols_to_process)} protocol(s) against {tag}...")
container = run_container(image_name)
analyze_many(protocols_to_process, container)
container = stop_and_restart_container(image_name)
for protocol in protocols_to_process:
console.print(f"Analyzing {protocol.protocol_file_name}...")
analyzed = analyze(protocol, container)
if not analyzed:
console.print("Analysis failed. Exiting.")
stop_and_remove_containers(image_name)
accumulated_time = sum(
protocol.analysis_execution_time for protocol in protocols_to_process if protocol.analysis_execution_time is not None
)
console.print(f"{len(protocols_to_process)} protocols with total analysis time of {accumulated_time:.2f} seconds.\n")
finally:
stop_and_remove_containers(image_name)
1 change: 1 addition & 0 deletions app-testing/conftest.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
"""Pytest setup."""

import os
from typing import Generator, List, Optional

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
"""Smoke Test v3.0 """

from opentrons import protocol_api

metadata = {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
"""Smoke Test v3.0 """

# https://opentrons.atlassian.net/projects/RQA?selectedItem=com.atlassian.plugins.atlassian-connect-plugin:com.kanoah.test-manager__main-project-page#!/testCase/QB-T497
from opentrons import protocol_api

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
"""Smoke Test v3.0 """

# https://opentrons.atlassian.net/projects/RQA?selectedItem=com.atlassian.plugins.atlassian-connect-plugin:com.kanoah.test-manager__main-project-page#!/testCase/QB-T497
from opentrons import protocol_api

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
"""Smoke Test v3.0 """

# https://opentrons.atlassian.net/projects/RQA?selectedItem=com.atlassian.plugins.atlassian-connect-plugin:com.kanoah.test-manager__main-project-page#!/testCase/QB-T497
from opentrons import protocol_api

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
"""Smoke Test v3.0 """

# https://opentrons.atlassian.net/projects/RQA?selectedItem=com.atlassian.plugins.atlassian-connect-plugin:com.kanoah.test-manager__main-project-page#!/testCase/QB-T497
from opentrons import protocol_api

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
"""Smoke Test v3.0 """

from opentrons import protocol_api

metadata = {
Expand Down
1 change: 1 addition & 0 deletions app-testing/locators.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
pipenv run python -i locators.py
This launches the installed app.
"""

import importlib
import os

Expand Down
2 changes: 1 addition & 1 deletion app-testing/pytest.ini
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
[pytest]
generate_report_on_test = True
junit_family = legacy
addopts = --junitxml=results/results.xml --log-cli-level info --html=results/report.html --self-contained-html
addopts = -s -vv --junitxml=results/results.xml --log-cli-level info --html=results/report.html --self-contained-html
1 change: 1 addition & 0 deletions app-testing/tests/calibrate_test.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
"""Test the initial state the application with various setups."""

import time
from typing import List

Expand Down
1 change: 1 addition & 0 deletions app-testing/tests/labware_landing_test.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
"""Test the Labware Landing of the page."""

from pathlib import Path
from typing import Dict, List

Expand Down
1 change: 1 addition & 0 deletions app-testing/tests/lpc_test.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
"""todo these tests for refactoring"""

# flake8: noqa
import time
from pathlib import Path
Expand Down
1 change: 1 addition & 0 deletions app-testing/tests/protocol_analyze_test.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
"""Test the Protocol Landing of the page."""

import os

import pytest
Expand Down
1 change: 1 addition & 0 deletions app-testing/tests/protocol_landing_test.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
"""Test the Protocol Landing of the page."""

import time
from pathlib import Path
from typing import Dict
Expand Down
Loading

0 comments on commit 2e57ffb

Please sign in to comment.