Skip to content

Commit

Permalink
Implemented session object
Browse files Browse the repository at this point in the history
  • Loading branch information
lewis-chambers committed Jun 25, 2024
1 parent ebb5185 commit cd6ef63
Show file tree
Hide file tree
Showing 2 changed files with 168 additions and 0 deletions.
68 changes: 68 additions & 0 deletions src/iotswarm/session.py
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."""
100 changes: 100 additions & 0 deletions src/tests/test_sessions.py
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))

0 comments on commit cd6ef63

Please sign in to comment.