diff options
| author | Charles Cabergs <me@cacharle.xyz> | 2020-09-27 16:58:35 +0200 |
|---|---|---|
| committer | Charles Cabergs <me@cacharle.xyz> | 2020-09-27 16:58:35 +0200 |
| commit | 20e0b28ec3c8e9e0a63759116a32438c18941a59 (patch) | |
| tree | ee426189825867a0d98358154da3660c48ca5957 /src | |
| parent | 861621b9bdbdc7336183597b3ffd4ee161be19f3 (diff) | |
| download | philosophers_test-20e0b28ec3c8e9e0a63759116a32438c18941a59.tar.gz philosophers_test-20e0b28ec3c8e9e0a63759116a32438c18941a59.tar.bz2 philosophers_test-20e0b28ec3c8e9e0a63759116a32438c18941a59.zip | |
Added log checking
Diffstat (limited to 'src')
| -rw-r--r-- | src/__pycache__/config.cpython-38.pyc | bin | 462 -> 0 bytes | |||
| -rw-r--r-- | src/__pycache__/test.cpython-38.pyc | bin | 980 -> 0 bytes | |||
| -rw-r--r-- | src/philo/__init__.py (renamed from src/test/table.py) | 21 | ||||
| -rw-r--r-- | src/philo/event.py (renamed from src/test/philo.py) | 22 | ||||
| -rw-r--r-- | src/philo/log.py | 53 | ||||
| -rw-r--r-- | src/philo/philo.py | 50 | ||||
| -rw-r--r-- | src/philo/table.py | 40 | ||||
| -rw-r--r-- | src/test/__pycache__/__init__.cpython-38.pyc | bin | 185 -> 0 bytes | |||
| -rw-r--r-- | src/test/__pycache__/test.cpython-38.pyc | bin | 1876 -> 0 bytes | |||
| -rw-r--r-- | src/test/test.py | 56 |
10 files changed, 183 insertions, 59 deletions
diff --git a/src/__pycache__/config.cpython-38.pyc b/src/__pycache__/config.cpython-38.pyc Binary files differdeleted file mode 100644 index 0dd6446..0000000 --- a/src/__pycache__/config.cpython-38.pyc +++ /dev/null diff --git a/src/__pycache__/test.cpython-38.pyc b/src/__pycache__/test.cpython-38.pyc Binary files differdeleted file mode 100644 index aec2223..0000000 --- a/src/__pycache__/test.cpython-38.pyc +++ /dev/null diff --git a/src/test/table.py b/src/philo/__init__.py index 6aa1b15..f8cb07f 100644 --- a/src/test/table.py +++ b/src/philo/__init__.py @@ -1,23 +1,16 @@ # ############################################################################ # # # # ::: :::::::: # -# table.py :+: :+: :+: # +# __init__.py :+: :+: :+: # # +:+ +:+ +:+ # # By: charles <me@cacharle.xyz> +#+ +:+ +#+ # # +#+#+#+#+#+ +#+ # -# Created: 2020/09/27 12:44:48 by charles #+# #+# # -# Updated: 2020/09/27 12:54:01 by charles ### ########.fr # +# Created: 2020/09/27 16:06:28 by charles #+# #+# # +# Updated: 2020/09/27 16:11:04 by charles ### ########.fr # # # # ############################################################################ # -class Table: - def __init__(self, philo_num): - self._philos = [Philo(id_) for id_ in range(1, philo_num + 1)] - - def update(self, match): - philo = itertools.first_true(self._philos, pred = lambda x: x.id == match.id) - philo.add_log(match) - - def check(self): - return True - +from philo.table import Table +from philo.philo import Philo +from philo.log import Log +from philo.event import Event diff --git a/src/test/philo.py b/src/philo/event.py index c103bec..62f7ca6 100644 --- a/src/test/philo.py +++ b/src/philo/event.py @@ -1,23 +1,21 @@ # ############################################################################ # # # # ::: :::::::: # -# philo.py :+: :+: :+: # +# event.py :+: :+: :+: # # +:+ +:+ +:+ # # By: charles <me@cacharle.xyz> +#+ +:+ +#+ # # +#+#+#+#+#+ +#+ # -# Created: 2020/09/27 12:54:12 by charles #+# #+# # -# Updated: 2020/09/27 12:59:50 by charles ### ########.fr # +# Created: 2020/09/27 16:04:04 by charles #+# #+# # +# Updated: 2020/09/27 16:28:43 by charles ### ########.fr # # # # ############################################################################ # -class Philo: - def __init__(id_: int): - self.id = id_ - self.last_event = None - self.last_eat_date = None +from enum import Enum - def add_log(self, match): - pass - def check(self): - return True +class Event(Enum): + EATING = 1 + SLEEPING = 2 + THINKING = 3 + DIED = 4 + NONE = 5 diff --git a/src/philo/log.py b/src/philo/log.py new file mode 100644 index 0000000..cc4347e --- /dev/null +++ b/src/philo/log.py @@ -0,0 +1,53 @@ +# ############################################################################ # +# # +# ::: :::::::: # +# log.py :+: :+: :+: # +# +:+ +:+ +:+ # +# By: charles <me@cacharle.xyz> +#+ +:+ +#+ # +# +#+#+#+#+#+ +#+ # +# Created: 2020/09/27 16:04:18 by charles #+# #+# # +# Updated: 2020/09/27 16:05:21 by charles ### ########.fr # +# # +# ############################################################################ # + +import re +import time + +import philo + + +class Log: + def __init__(self, log, philo_num): + match = re.match( + "^(?P<timestamp>\d+) " + "(?P<id>\d+) " + "(?P<event>is thinking|is eating|is sleeping|died)$", + log + ) + if match is None: + raise ValueError("Bad line format |{}|".format(log)) + + curr = int(time.time() * 1000) + self.timestamp = Log._parse_ranged_int(match.group("timestamp"), curr - 100, curr + 100) + self.id = Log._parse_ranged_int(match.group("id"), 1, philo_num) + + self.event = { + "is thinking": philo.Event.THINKING, + "is eating": philo.Event.EATING, + "is sleeping": philo.Event.SLEEPING, + "died": philo.Event.DIED, + }[match.group('event')] + + @staticmethod + def _parse_ranged_int(s, lo, hi): + try: + value = int(s) + if not (lo <= value <= hi): + raise ValueError("Invalid value range {}".format(s)) + except ValueError: + raise ValueError("Invalid value {}".format(s)) + return value + + + def __repr__(self): + return "{} {} {}".format(self.timestamp, self.id, self.event) diff --git a/src/philo/philo.py b/src/philo/philo.py new file mode 100644 index 0000000..e7e2e1d --- /dev/null +++ b/src/philo/philo.py @@ -0,0 +1,50 @@ +# ############################################################################ # +# # +# ::: :::::::: # +# philo.py :+: :+: :+: # +# +:+ +:+ +:+ # +# By: charles <me@cacharle.xyz> +#+ +:+ +#+ # +# +#+#+#+#+#+ +#+ # +# Created: 2020/09/27 12:54:12 by charles #+# #+# # +# Updated: 2020/09/27 16:50:22 by charles ### ########.fr # +# # +# ############################################################################ # + +import itertools +from philo.event import Event + +class Philo: + def __init__(self, id_: int, meal_num: int = 1): + self._logs = [] + self.id = id_ + self.meal_num = meal_num + + def add_log(self, log): + self._logs.append(log) + + def check(self): + grouped = [(e, list(g)) for e, g in itertools.groupby(self._logs, (lambda x: x.event))] + for e, g in grouped: + if e is Event.EATING: + if len(g) != self.meal_num: + raise RuntimeError("lala") + else: + if len(g) != 1: + raise RuntimeError("1lala") + + events = [e for e, _ in grouped] + for e1, e2 in zip(events, events[1:]): + if e2 is Event.DIED: + break + if e1 is Event.THINKING and e2 is not Event.EATING: + raise RuntimeError("2lala") + elif e1 is Event.EATING and e2 is not Event.SLEEPING: + raise RuntimeError("2lala") + elif e1 is Event.SLEEPING and e2 is not Event.EATING: + raise RuntimeError("2lala") + + @property + def last_event(self): + if len(self._logs) == 0: + return Event.NONE + return self._logs[-1].event diff --git a/src/philo/table.py b/src/philo/table.py new file mode 100644 index 0000000..8214ffb --- /dev/null +++ b/src/philo/table.py @@ -0,0 +1,40 @@ +# ############################################################################ # +# # +# ::: :::::::: # +# table.py :+: :+: :+: # +# +:+ +:+ +:+ # +# By: charles <me@cacharle.xyz> +#+ +:+ +#+ # +# +#+#+#+#+#+ +#+ # +# Created: 2020/09/27 12:44:48 by charles #+# #+# # +# Updated: 2020/09/27 16:54:52 by charles ### ########.fr # +# # +# ############################################################################ # + +from philo.philo import Philo +from philo.event import Event + + +class Table: + def __init__(self, philo_num): + self._philos = [Philo(id_) for id_ in range(1, philo_num + 1)] + self._logs = [] + self._philo_num = philo_num + + def add_log(self, log): + self._logs.append(log) + philo = next(p for p in self._philos if p.id == log.id) + philo.add_log(log) + + def check(self): + died_count = len([p for p in self._philos if p.last_event == Event.DIED]) + if died_count > 1: + raise RuntimeError("died") + fork_used = 2 * len([p for p in self._philos if p.last_event == Event.EATING]) + if fork_used > self._philo_num: + raise RuntimeError("too much fork") + for p in self._philos: + p.check() + for l1, l2 in zip(self._logs, self._logs[1:]): + if l1.timestamp > l2.timestamp: + raise RuntimeError("timestamp not ordered") + diff --git a/src/test/__pycache__/__init__.cpython-38.pyc b/src/test/__pycache__/__init__.cpython-38.pyc Binary files differdeleted file mode 100644 index 37cb896..0000000 --- a/src/test/__pycache__/__init__.cpython-38.pyc +++ /dev/null diff --git a/src/test/__pycache__/test.cpython-38.pyc b/src/test/__pycache__/test.cpython-38.pyc Binary files differdeleted file mode 100644 index ce4b3b7..0000000 --- a/src/test/__pycache__/test.cpython-38.pyc +++ /dev/null diff --git a/src/test/test.py b/src/test/test.py index 7be1d18..14ee097 100644 --- a/src/test/test.py +++ b/src/test/test.py @@ -6,16 +6,21 @@ # By: charles <me@cacharle.xyz> +#+ +:+ +#+ # # +#+#+#+#+#+ +#+ # # Created: 2020/09/27 11:36:32 by charles #+# #+# # -# Updated: 2020/09/27 13:28:15 by charles ### ########.fr # +# Updated: 2020/09/27 16:25:37 by charles ### ########.fr # # # # ############################################################################ # import re +import time import subprocess # import threading # from result import Result +import philo +# from test.table import Table + + class Test: #(threading.Thread): _tests = [] @@ -59,44 +64,35 @@ class Test: #(threading.Thread): if self._meal_num is not None: argv.append(str(self._meal_num)) # try: - process_result = subprocess.run( + process = subprocess.Popen( argv, stdout=subprocess.PIPE, stderr=subprocess.STDOUT ) - output = process_result.stdout.decode() - print(output) + # output = process_result.stdout.decode() + # print(output) # timeout=1, # except subprocess.TimeoutExpered as err: # return Result(err) # except subprocess.CalledProcessError as err: # return Result(err) - self._check_output(output) - # return Result() + self._check_output(process.stdout) + process.wait() def _check_output(self, stream): - # table = Table(self._philo_num) - - for line in stream.split('\n'): - match = re.match( - "^(?P<timestamp>\d+) " - "(?P<id>\d+) " - "(?P<event>is thinking|is eating|is sleeping|died)$", - line - ) - if match is None: - print("Bad line format |{}|".format(line)) - return - - print(match.group('event')) - try: - timestamp = int(match.group("timestamp")) - # if timestamp < 0 - except ValueError: - print("Invalid timestamp value {}".format(match.group("timestamp"))) - - table.add_log(match) + table = philo.Table(self._philo_num) + + for line in stream: + line = line.decode()[:-1] + # print(">", line) + l = philo.Log(line, self._philo_num) + print(l) + table.add_log(l) + table.check() + + # print(timestamp, id_, event) + # philo_states.append(Philo) @@ -104,9 +100,3 @@ class Test: #(threading.Thread): # Test._stdout_lock.aquire() # print(*args) # Test._stdout_lock.release() - -# from enum import Enum -# class PhiloEvent(Enum): -# EATING = 1 -# SLEEPING = 2 -# THINKING = 3 |
