aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/args.py31
-rw-r--r--src/helper.py7
-rw-r--r--src/philo/__init__.py12
-rw-r--r--src/philo/error.py12
-rw-r--r--src/philo/event.py3
-rw-r--r--src/philo/log.py17
-rw-r--r--src/philo/philo.py68
-rw-r--r--src/philo/table.py5
-rw-r--r--src/suite.py3
-rw-r--r--src/test.py9
10 files changed, 95 insertions, 72 deletions
diff --git a/src/args.py b/src/args.py
index 899ef3f..2cb5749 100644
--- a/src/args.py
+++ b/src/args.py
@@ -6,27 +6,44 @@
# By: cacharle <me@cacharle.xyz> +#+ +:+ +#+ #
# +#+#+#+#+#+ +#+ #
# Created: 2020/10/01 10:23:09 by cacharle #+# #+# #
-# Updated: 2020/10/01 10:33:00 by cacharle ### ########.fr #
+# Updated: 2020/10/05 14:03:42 by cacharle ### ########.fr #
# #
# ############################################################################ #
import argparse
+import textwrap
import config
+
def parse_args():
parser = argparse.ArgumentParser(
description="Philosophers test",
- formatter_class=argparse.RawTextHelpFormatter
+ formatter_class=argparse.RawTextHelpFormatter,
+ epilog=textwrap.dedent("""\
+ Tested:
+ - Take 2 forks before eating
+ - State switch in the correct order
+ think -> fork -> fork -> eat n times -> sleep
+ - Almost 0 delay between second fork taken and eat
+ - Die if the death timeout is expired
+ - No output after death
+ - Timestamp in order
+ - Only take existing fork
+ - Error message and status != 0 on argument error
+ (not asked by subject but easy to do and cleanner)
+ """)
)
parser.add_argument(
"-p", "--philo",
- help="Id of the philosopher program to test \n"
- "- 1: philo_one\n"
- "- 2: philo_two\n"
- "- 3: philo_three\n"
- "- 0: all programs\n",
+ help=textwrap.dedent("""\
+ Number of the philosopher program to test
+ - 1: philo_one
+ - 2: philo_two
+ - 3: philo_three
+ - 0: all programs
+ """),
required=True,
type=int,
choices=[0, 1, 2, 3]
diff --git a/src/helper.py b/src/helper.py
index bc211c9..ff96638 100644
--- a/src/helper.py
+++ b/src/helper.py
@@ -6,25 +6,30 @@
# By: cacharle <me@cacharle.xyz> +#+ +:+ +#+ #
# +#+#+#+#+#+ +#+ #
# Created: 2020/09/29 11:19:32 by cacharle #+# #+# #
-# Updated: 2020/10/01 11:27:48 by cacharle ### ########.fr #
+# Updated: 2020/10/05 13:49:25 by cacharle ### ########.fr #
# #
# ############################################################################ #
import time
+
def current_ms():
return int(time.time() * 1000)
+
RED_CHARS = "\033[31m"
GREEN_CHARS = "\033[32m"
BLUE_CHARS = "\033[34m"
CLOSE_CHARS = "\033[0m"
+
def red(string):
return RED_CHARS + string + CLOSE_CHARS
+
def green(string):
return GREEN_CHARS + string + CLOSE_CHARS
+
def blue(string):
return BLUE_CHARS + string + CLOSE_CHARS
diff --git a/src/philo/__init__.py b/src/philo/__init__.py
index 5915e2b..5d7024a 100644
--- a/src/philo/__init__.py
+++ b/src/philo/__init__.py
@@ -6,12 +6,12 @@
# By: cacharle <me@cacharle.xyz> +#+ +:+ +#+ #
# +#+#+#+#+#+ +#+ #
# Created: 2020/10/01 10:50:41 by cacharle #+# #+# #
-# Updated: 2020/10/01 11:08:00 by cacharle ### ########.fr #
+# Updated: 2020/10/05 13:50:41 by cacharle ### ########.fr #
# #
# ############################################################################ #
-from philo.philo import Philo
-from philo.table import Table
-from philo.log import Log
-from philo.event import Event
-import philo.error as error
+from philo.philo import Philo # noqa: F401
+from philo.table import Table # noqa: F401
+from philo.log import Log # noqa: F401
+from philo.event import Event # noqa: F401
+import philo.error as error # noqa: F401
diff --git a/src/philo/error.py b/src/philo/error.py
index 51c3f7b..96a0723 100644
--- a/src/philo/error.py
+++ b/src/philo/error.py
@@ -6,10 +6,13 @@
# By: cacharle <me@cacharle.xyz> +#+ +:+ +#+ #
# +#+#+#+#+#+ +#+ #
# Created: 2020/09/29 09:09:31 by cacharle #+# #+# #
-# Updated: 2020/09/29 11:14:08 by cacharle ### ########.fr #
+# Updated: 2020/10/05 13:51:40 by cacharle ### ########.fr #
# #
# ############################################################################ #
+import textwrap
+
+
class Philo(Exception):
pass
@@ -53,9 +56,10 @@ class Log(Philo):
@property
def full_summary(self):
- return """LOG ERROR: {}
-{}
-""".format(self._msg, '\n'.join([str(l) for l in self._logs]))
+ return textwrap.dedent("""\
+ LOG ERROR: {}
+ {}
+ """).format(self._msg, '\n'.join([str(log) for log in self._logs]))
@property
def summary(self):
diff --git a/src/philo/event.py b/src/philo/event.py
index ddcbe59..c589a97 100644
--- a/src/philo/event.py
+++ b/src/philo/event.py
@@ -6,12 +6,13 @@
# By: cacharle <me@cacharle.xyz> +#+ +:+ +#+ #
# +#+#+#+#+#+ +#+ #
# Created: 2020/10/01 10:51:13 by cacharle #+# #+# #
-# Updated: 2020/10/01 11:21:00 by cacharle ### ########.fr #
+# Updated: 2020/10/05 13:51:48 by cacharle ### ########.fr #
# #
# ############################################################################ #
import enum
+
class Event(enum.Enum):
FORK = 1
EAT = 2
diff --git a/src/philo/log.py b/src/philo/log.py
index 14bdd75..a07b734 100644
--- a/src/philo/log.py
+++ b/src/philo/log.py
@@ -6,14 +6,15 @@
# By: cacharle <me@cacharle.xyz> +#+ +:+ +#+ #
# +#+#+#+#+#+ +#+ #
# Created: 2020/10/01 10:51:39 by cacharle #+# #+# #
-# Updated: 2020/10/01 14:19:29 by cacharle ### ########.fr #
+# Updated: 2020/10/05 13:52:51 by cacharle ### ########.fr #
# #
# ############################################################################ #
import re
-from .event import Event
-from . import error
+from philo.event import Event
+import philo
+
class Log:
def __init__(self, line: str, philo_num, start_time, end_time):
@@ -24,7 +25,7 @@ class Log:
line
)
if match is None:
- raise error.Format(line, "wrong format")
+ raise philo.error.Format(line, "wrong format")
self._line = line
self.id = self._parse_ranged_int(match.group("id"), 1, philo_num)
@@ -37,10 +38,12 @@ class Log:
try:
value = int(s)
if not (lo <= value <= hi):
- raise error.Format(self._line,
- "{} should be between {} - {}".format(s, lo, hi))
+ raise philo.error.Format(
+ self._line,
+ "{} should be between {} - {}".format(s, lo, hi)
+ )
except ValueError:
- raise error.Format(self._line, "{} sould be an integer".format(s))
+ raise philo.error.Format(self._line, "{} sould be an integer".format(s))
return value
def __repr__(self):
diff --git a/src/philo/philo.py b/src/philo/philo.py
index 0f75589..3319a0b 100644
--- a/src/philo/philo.py
+++ b/src/philo/philo.py
@@ -6,13 +6,13 @@
# By: cacharle <me@cacharle.xyz> +#+ +:+ +#+ #
# +#+#+#+#+#+ +#+ #
# Created: 2020/10/01 10:52:56 by cacharle #+# #+# #
-# Updated: 2020/10/01 16:39:30 by cacharle ### ########.fr #
+# Updated: 2020/10/05 14:03:07 by cacharle ### ########.fr #
# #
# ############################################################################ #
import itertools
-from . import error
+from philo import error
from philo.event import Event
@@ -32,20 +32,6 @@ class Philo:
self._timeout_sleep = timeout_sleep
self._meal_num = meal_num
- @property
- def used_forks(self):
- """ The number of forks currently used by the philosopher """
- if len(self.logs) < 1:
- return 0
- if self.logs[-1].event is Event.EAT:
- return 2
- if self.logs[-1].event is Event.FORK:
- if len(self.logs) > 1 and self.logs[-2].event is Event.FORK:
- return 2
- else:
- return 1
- return 0
-
def check(self):
""" Check log for errors
@@ -104,32 +90,40 @@ class Philo:
if e1 is Event.EAT:
self._check_time_range(t1, t2, self._timeout_eat, "Ate")
-
- # if l1.event is Event.EATING and l2.event is Event.EATING:
- # if l2.timestamp - l1.timestamp > self._timeout_eat:
- # raise ValueError
- # if timeout is not None and l2.timestamp - l1.timestamp > timeout:
- # raise ValueError
-
# check if should be dead
- # last_eat = None
- # for log in reversed(self.logs):
- # if log.event is Event.EATING:
- # last_eat = log
- # break
- # last = self.logs[-1]
- # if last_eat is not None and last_eat is not last:
- # if last.timestamp - last_eat.timestamp > self._timeout_die + 10:
- # self._raise("{} should be dead {} - {} > {}".format(self.id, last.timestamp, last_eat.timestamp, self._timeout_die + 10))
+ last_eat = next(
+ (log for log in reversed(self.logs) if log.event is Event.EAT),
+ None
+ )
+ last = self.logs[-1]
+ if last_eat is not None and last_eat is not last:
+ if last.timestamp - last_eat.timestamp > self._timeout_die + 10:
+ self._raise(
+ "{} should be dead {} - {} > {}"
+ .format(self.id, last.timestamp,
+ last_eat.timestamp, self._timeout_die + 10)
+ )
def _check_time_range(self, t1, t2, timeout, verb):
- lo = timeout - 10
- hi = timeout + 10
- if not (lo <= t2 - t1 <= hi):
- self._raise("{} {}ms expected {}-{}ms".format(verb, t2 - t1, lo, hi))
-
+ start = timeout - 10
+ end = timeout + 10
+ if not (start <= t2 - t1 <= end):
+ self._raise("{} {}ms expected {}-{}ms".format(verb, t2 - t1, start, end))
def _raise(self, msg):
""" Helper to raise Log errrors"""
raise error.Log(self.logs, msg)
+ @property
+ def used_forks(self):
+ """ The number of forks currently used by the philosopher """
+ if len(self.logs) < 1:
+ return 0
+ if self.logs[-1].event is Event.EAT:
+ return 2
+ if self.logs[-1].event is Event.FORK:
+ if len(self.logs) > 1 and self.logs[-2].event is Event.FORK:
+ return 2
+ else:
+ return 1
+ return 0
diff --git a/src/philo/table.py b/src/philo/table.py
index 56ed331..66eaa9d 100644
--- a/src/philo/table.py
+++ b/src/philo/table.py
@@ -6,7 +6,7 @@
# By: cacharle <me@cacharle.xyz> +#+ +:+ +#+ #
# +#+#+#+#+#+ +#+ #
# Created: 2020/10/01 10:53:29 by cacharle #+# #+# #
-# Updated: 2020/10/01 14:15:09 by cacharle ### ########.fr #
+# Updated: 2020/10/05 14:03:35 by cacharle ### ########.fr #
# #
# ############################################################################ #
@@ -17,6 +17,7 @@ from philo import Philo
from philo import error
from philo.event import Event
+
class Table:
def __init__(
self,
@@ -55,10 +56,8 @@ class Table:
if self.dead:
return
-
for p in self._philos:
p.check()
-
fork_used = sum([p.used_forks for p in self._philos])
if fork_used > self._philo_num:
raise error.Log(self._logs, "Using nonexistant forks")
diff --git a/src/suite.py b/src/suite.py
index 07b2432..dd087e6 100644
--- a/src/suite.py
+++ b/src/suite.py
@@ -6,13 +6,14 @@
# By: cacharle <me@cacharle.xyz> +#+ +:+ +#+ #
# +#+#+#+#+#+ +#+ #
# Created: 2020/10/01 10:41:43 by cacharle #+# #+# #
-# Updated: 2020/10/01 12:08:18 by cacharle ### ########.fr #
+# Updated: 2020/10/05 13:49:30 by cacharle ### ########.fr #
# #
# ############################################################################ #
import config
from test import Test
+
def suite():
Test.new_error([])
Test.new_error(["a", "a", "a", "a"])
diff --git a/src/test.py b/src/test.py
index 8aafc57..4312858 100644
--- a/src/test.py
+++ b/src/test.py
@@ -6,12 +6,11 @@
# By: charles <me@cacharle.xyz> +#+ +:+ +#+ #
# +#+#+#+#+#+ +#+ #
# Created: 2020/09/27 11:36:32 by charles #+# #+# #
-# Updated: 2020/10/01 16:27:21 by cacharle ### ########.fr #
+# Updated: 2020/10/05 13:50:01 by cacharle ### ########.fr #
# #
# ############################################################################ #
import os
-import time
import subprocess
import config
@@ -113,11 +112,11 @@ class Test:
try:
_, err = process.communicate(timeout=config.TIMEOUT_ERROR)
except subprocess.TimeoutExpired:
- raise error.ShouldFail("no error message")
+ raise philo.error.ShouldFail("no error message")
if process.returncode == 0:
- raise error.ShouldFail("non zero status code: {}".format(process.returncode))
+ raise philo.error.ShouldFail("non zero status code: {}".format(process.returncode))
if err.decode().count('\n') != 1:
- raise error.ShouldFail("no error message on stderr")
+ raise philo.error.ShouldFail("no error message on stderr")
def _argv(self, basename=False):
exec_path = os.path.basename(Test._exec_path) if basename else Test._exec_path