-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
ebb5185
commit cd6ef63
Showing
2 changed files
with
168 additions
and
0 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,68 @@ | ||
"""This package is for holding classes relevant to managing swarm sessions. | ||
It should allow the state of a swarm to be restored from the point of failure""" | ||
|
||
from iotswarm.swarm import Swarm | ||
import uuid | ||
|
||
|
||
class Session: | ||
"""Represents the current session. Holds configuration necessary to the | ||
SessionWriter.""" | ||
|
||
swarm: Swarm | ||
"""The swarm object in use.""" | ||
|
||
session_id: str | ||
"""Unique ID for the session""" | ||
|
||
def __init__(self, swarm: Swarm, session_id: str | None = None): | ||
"""Initialises the class. | ||
Args: | ||
swarm: A Swarm object to track the state of. | ||
session_id: A unique identifier of the session. Automatically assigned if not provided. | ||
""" | ||
|
||
if not isinstance(swarm, Swarm): | ||
raise TypeError(f'"swarm" must be a Swarm, not "{type(swarm)}".') | ||
|
||
self.swarm = swarm | ||
|
||
if session_id is not None: | ||
self.session_id = str(session_id) | ||
else: | ||
self.session_id = self._build_session_id(swarm.name) | ||
|
||
def __repr__(self): | ||
|
||
return f'{self.__class__.__name__}({self.swarm}, "{self.session_id}")' | ||
|
||
def __str__(self): | ||
|
||
return f'{self.__class__.__name__}: "{self.session_id}"' | ||
|
||
@staticmethod | ||
def _build_session_id(prefix: str | None = None): | ||
"""Builds a session ID with a prefix if requested. | ||
Args: | ||
prefix: Adds a prefix to the ID for readability. | ||
Returns: | ||
str: A session ID string. | ||
""" | ||
|
||
session_id = str(uuid.uuid4()) | ||
|
||
if prefix is not None: | ||
session_id = f"{prefix}-{session_id}" | ||
|
||
return session_id | ||
|
||
|
||
class SessionWriter: | ||
"""Handles writing of the session state to file.""" | ||
|
||
|
||
class SessionLoader: | ||
"""Loads a session, instantiates the swarm and devices.""" |
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,100 @@ | ||
import unittest | ||
import pytest | ||
from parameterized import parameterized | ||
from iotswarm.session import Session | ||
from iotswarm.swarm import Swarm | ||
from iotswarm.devices import BaseDevice | ||
from iotswarm.messaging.core import MockMessageConnection | ||
from iotswarm.db import LoopingSQLite3, MockDB | ||
|
||
|
||
class TestSession(unittest.TestCase): | ||
"""Tests the Session class""" | ||
|
||
@classmethod | ||
def setUpClass(cls) -> None: | ||
cls.devices = [ | ||
BaseDevice(x, MockDB(), MockMessageConnection()) | ||
for x in ["MORLY", "ALIC1", "SPENF", "RISEH"] | ||
] | ||
|
||
cls.swarm = Swarm(cls.devices, "test-swarm") | ||
cls.maxDiff = None | ||
|
||
def test_instantiation(self): | ||
"""Tests that the class can be instantiated under normal conditions.""" | ||
|
||
session = Session(self.swarm) | ||
|
||
print(session) | ||
|
||
self.assertIsInstance(session.swarm, Swarm) | ||
self.assertIsInstance(session.session_id, str) | ||
|
||
def test_error_if_bad_swarm_type(self): | ||
|
||
with self.assertRaises(TypeError): | ||
Session("swarm?") | ||
|
||
def test_session_id_set_if_given(self): | ||
"""Tests that the session_id attribute is set when the argument is supplied.""" | ||
session_id = "this-is-my-session" | ||
session = Session(self.swarm, session_id=session_id) | ||
|
||
self.assertEqual(session.session_id, session_id) | ||
|
||
def test_session_id_assigned_if_not_given(self): | ||
"""Tests that an id is generated if not given.""" | ||
|
||
session = Session(self.swarm) | ||
|
||
self.assertTrue(session.session_id.startswith(self.swarm.name)) | ||
|
||
def test_session_id_method(self): | ||
"""Tests the _build_session_id method returns an ID""" | ||
|
||
value = Session._build_session_id() | ||
|
||
self.assertIsInstance(value, str) | ||
self.assertEqual(len(value), 36) | ||
|
||
# string prefix | ||
prefix = "my-swarm" | ||
value = Session._build_session_id(prefix) | ||
|
||
self.assertTrue(value.startswith(f"my-swarm-")) | ||
self.assertEqual(len(value), 36 + len(prefix) + 1) | ||
|
||
# number prefix | ||
prefix = 12345 | ||
value = Session._build_session_id(prefix) | ||
|
||
self.assertTrue(value.startswith(f"12345-")) | ||
self.assertEqual(len(value), 36 + 6) | ||
|
||
@parameterized.expand([None, "my-swarm"]) | ||
def test_repr(self, session_id): | ||
|
||
session = Session(self.swarm, session_id=session_id) | ||
|
||
if session_id is not None: | ||
expected_start = ( | ||
f'{session.__class__.__name__}({self.swarm}, "{session_id}"' | ||
) | ||
else: | ||
expected_start = expected_start = ( | ||
f'{session.__class__.__name__}({self.swarm}, "{self.swarm.name}-' | ||
) | ||
self.assertTrue(session.__repr__().startswith(expected_start)) | ||
|
||
@parameterized.expand([None, "my-swarm"]) | ||
def test_str(self, session_id): | ||
|
||
session = Session(self.swarm, session_id=session_id) | ||
|
||
if session_id is not None: | ||
expected_start = f'Session: "{session_id}"' | ||
else: | ||
expected_start = expected_start = f'Session: "{self.swarm.name}-' | ||
|
||
self.assertTrue(str(session).startswith(expected_start)) |