4
0

+ Fixed Floating test suite.

This commit is contained in:
SAVELIY BAKTURIN
2026-03-08 18:08:25 +00:00
parent 351b7fb8c5
commit 885757f752
4 changed files with 129 additions and 14 deletions

View File

@@ -31,9 +31,10 @@
Ниже представлена таблица доступных для тестирования (как локально, так и автоматически в репозиториях) лабораторных работ с названием набора тестов для тестера (`suite`). Ниже представлена таблица доступных для тестирования (как локально, так и автоматически в репозиториях) лабораторных работ с названием набора тестов для тестера (`suite`).
| № | Лабораторная работа | Набор тестов | | № | Лабораторная работа | Набор тестов |
|:--:|:--------------------|:-------------| |:--:|:--------------------|:-----------------|
| 0 | Интро | `intro` | | 0 | Интро | `intro` |
| 1 | Представление чисел | `fixed_floating` |
## Скрипт запуска ## Скрипт запуска

View File

@@ -4,12 +4,13 @@ import argparse
import platform import platform
import testsuites.intro as intro import testsuites.intro as intro
import testsuites.fixed_floating as fixed_floating
from testsuites import Testsuite, DynamicWrapper from testsuites import Testsuite, DynamicWrapper
from typing import Dict, Any, List from typing import Dict, Any, List
__TESTSUITES: List[Testsuite] = [ __TESTSUITES: List[Testsuite] = [
intro.instance intro.instance, fixed_floating.instance
] ]
__SUITENAMES: List[str] = [t.name() for t in __TESTSUITES] __SUITENAMES: List[str] = [t.name() for t in __TESTSUITES]

View File

@@ -0,0 +1,110 @@
from .suite import Run, Runned, Verdict
from testsuites import *
from enum import Enum
class __FixedFloating(Testsuite):
__SUITE_NAME = "fixed_floating"
__TIMEOUT = 1
__CATEGORIES_TO_ENVNAMES = {"fixed": "FIXED", "floating": "FLOATING"}
def __init__(self):
super().__init__(self.__SUITE_NAME, PREFIX_ENVIRONMENT_NAME, self.__CATEGORIES_TO_ENVNAMES)
def get_tester(self) -> Tester:
tester = Tester(self.name())
class Policy(Enum):
FIXED = 1
FLOATING = 2
class __Expected(Expected):
def __init__(self, ref: str, policy: Policy):
super().__init__()
self.__ref = ref
self.__policy = policy
def test(self, run: Run, runned: Runned) -> Verdict:
output = runned.get_stdout()
if not output.endswith("\n"):
return Verdict(VerdictErrno.ERROR_INVALID_FORMAT, f"newline at stdout's end expected")
lines = output.splitlines()
if len(lines) != 1:
return Verdict(VerdictErrno.ERROR_INVALID_FORMAT, f"single line expected")
line = lines[0]
if line != line.lstrip() or line != line.rstrip():
return Verdict(VerdictErrno.ERROR_INVALID_FORMAT, f"found unexpected space characters in stdout")
actuals = line.split(" ")
if len(actuals) != self.__policy.value:
return Verdict(VerdictErrno.ERROR_INVALID_FORMAT, f"expected {self.__policy.value} elements on single line, but found {len(actuals)}")
expecteds = self.__ref.split(" ")
if any(a != e for a, e in zip(actuals, expecteds)):
return Verdict(VerdictErrno.ERROR_ASSERTION, f"expected '{self.__ref}', but actual is '{line}'")
return ok()
def __single_test(args: str, ref: str, policy: Policy) -> SingleTest:
run = Run(c_timeout = self.__TIMEOUT, c_stdin = None, c_args = args.split(" "), t_returncode_policy = ReturnCodePolicy.ShouldBeZero)
expected = __Expected(ref, policy)
return (run, expected)
def __sequence(args: str, ref: str, policy: Policy) -> List[SingleTest]:
return [__single_test(args, ref, policy)]
def __test(name: str, categories: List[str], args: str, ref: str, policy: Policy) -> Test:
return Test(name, categories, __sequence(args, ref, policy))
def __t(name: str, categories: List[str], args: str, ref: str, policy: Policy):
tester.add(__test(name, categories, args, ref, policy))
def fixed(name: str, argv: str, ref: str):
categories = ["fixed"]
__t(name, categories, argv, ref, Policy.FIXED)
def floating(name: str, argv: str, ref: str):
categories = ["floating"]
__t(name, categories, argv, ref, Policy.FLOATING)
fixed(name = "print with rounding A 0", argv = "16.12 0 0x17360", ref = "23.210")
fixed(name = "print with rounding A 1", argv = "16.12 1 0x17360", ref = "23.211")
fixed(name = "print with rounding A 2", argv = "16.12 2 0x17360", ref = "23.211")
fixed(name = "print with rounding A 3", argv = "16.12 3 0x17360", ref = "23.210")
fixed(name = "print with rounding B 0", argv = "8.8 0 0x9c9f", ref = "-99.378")
fixed(name = "print with rounding B 1", argv = "8.8 1 0x9c9F", ref = "-99.379")
fixed(name = "print with rounding B 2", argv = "8.8 2 0x9C9f", ref = "-99.378")
fixed(name = "print with rounding B 3", argv = "8.8 3 0x9c9f", ref = "-99.379")
fixed(name = "+ with rounding 0", argv = "8.8 0 + 0xdc9f 0xD736", ref = "-76.167")
fixed(name = "+ with rounding 1", argv = "8.8 1 + 0xDc9f 0xd736", ref = "-76.168")
fixed(name = "+ with rounding 2", argv = "8.8 2 + 0xdC9f 0xd736", ref = "-76.167")
fixed(name = "+ with rounding 3", argv = "8.8 3 + 0xdc9F 0xd736", ref = "-76.168")
floating(name = "single pres.: print with rounding 0", argv = "s 0 0xB9CD542", ref = "0x1.39aa84p-104 0x0B9CD542")
floating(name = "single pres.: print with rounding 1", argv = "s 1 0xB9Cd542", ref = "0x1.39aa84p-104 0x0B9CD542")
floating(name = "single pres.: print with rounding 2", argv = "s 2 0xb9CD542", ref = "0x1.39aa84p-104 0x0B9CD542")
floating(name = "single pres.: print with rounding 3", argv = "s 3 0xB9cD542", ref = "0x1.39aa84p-104 0x0B9CD542")
floating(name = "half pres.: * with rounding 0", argv = "h 0 * 0x4145 0x142EB", ref = "0x1.238p+3 0x488E")
floating(name = "half pres.: * with rounding 1", argv = "h 1 * 0x4145 0x142eB", ref = "0x1.23cp+3 0x488F")
floating(name = "half pres.: * with rounding 2", argv = "h 2 * 0x4145 0x142eb", ref = "0x1.23cp+3 0x488F")
floating(name = "half pres.: * with rounding 3", argv = "h 3 * 0x4145 0x142Eb", ref = "0x1.238p+3 0x488E")
floating(name = "half pres.: special with rounding 0", argv = "h 0 / 0x1 0x0", ref = "inf 0x7C00")
floating(name = "single pres.: special with rounding 1", argv = "s 1 + 0xFFC10000 0x7F800001", ref = "nan 0xFFC10000")
floating(name = "single pres.: special with rounding 2", argv = "s 2 / 0x1 0x0", ref = "inf 0x7F800000")
floating(name = "half pres.: special with rounding 3", argv = "h 3 + 0xFF10 0x7F01", ref = "nan 0xFF10")
floating(name = "low pres.: fp4 with rounding 0", argv = "e2m1 0 0xf", ref = "-0x1.8p+2 0xF")
floating(name = "low pres.: fp4 with rounding 1", argv = "e2m1 0 0xf", ref = "-0x1.8p+2 0xF")
floating(name = "low pres.: fp4 with rounding 2", argv = "e2m1 0 0xf", ref = "-0x1.8p+2 0xF")
floating(name = "low pres.: fp4 with rounding 3", argv = "e2m1 0 0xf", ref = "-0x1.8p+2 0xF")
return tester
instance = __FixedFloating()

View File

@@ -6,6 +6,7 @@ import enum
import signal import signal
from typing import List, Optional, Tuple, Union, Callable, TypeVar, Any, Dict, Set, Iterable from typing import List, Optional, Tuple, Union, Callable, TypeVar, Any, Dict, Set, Iterable
from decimal import Decimal
from abc import abstractmethod, ABC from abc import abstractmethod, ABC
T = TypeVar('T') T = TypeVar('T')
@@ -398,31 +399,33 @@ class Result:
def __get_total_by_category(self, category: str) -> int: def __get_total_by_category(self, category: str) -> int:
total = 0 total = 0
for test, verdict in zip(self.__tests, self.__verdicts): for test, _ in zip(self.__tests, self.__verdicts):
if category in test.categories(): if category in test.categories():
total += 1 total += 1
return total return total
def __get_result_by_category(self, category: str) -> float: def __get_result_by_category(self, category: str) -> Decimal:
total = self.__get_total_by_category(category) total = self.__get_total_by_category(category)
passed = self.__get_passed_by_category(category) passed = self.__get_passed_by_category(category)
return passed / total if total == 0:
return Decimal(0.0)
return Decimal(passed) / Decimal(total)
def __calculate_total(self, coefficients: Dict[str, float]) -> float: def __calculate_total(self, coefficients: Dict[str, float]) -> Decimal:
total = 0.0 total = Decimal(0.0)
for category, coefficient in coefficients.items(): for category, coefficient in coefficients.items():
result = self.__get_result_by_category(category) result = self.__get_result_by_category(category)
total += result * coefficient total += result * Decimal(coefficient)
return total return total
def __get_results_by_categories(self, categories: Iterable[str]) -> Dict[str, float]: def __get_results_by_categories(self, categories: Iterable[str]) -> Dict[str, str]:
results: Dict[str, float] = {} results: Dict[str, str] = {}
for category in categories: for category in categories:
results[category] = self.__get_result_by_category(category) results[category] = str(self.__get_result_by_category(category))
return results return results
@@ -464,7 +467,7 @@ class Result:
j: Dict[str, Any] = {} j: Dict[str, Any] = {}
j["result"] = self.__calculate_total(coefficients) j["result"] = str(self.__calculate_total(coefficients))
j["categories"] = self.__get_results_by_categories(categories) j["categories"] = self.__get_results_by_categories(categories)
j["tests"] = self.__get_results() j["tests"] = self.__get_results()