Skip to content

Commit

Permalink
Adapt bug box for the GNAT release
Browse files Browse the repository at this point in the history
Ref. eng/recordflux/RecordFlux#1620
  • Loading branch information
andrestt committed Aug 7, 2024
1 parent b597640 commit 825da89
Show file tree
Hide file tree
Showing 9 changed files with 156 additions and 18 deletions.
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -480,7 +480,7 @@ endif
$(BUILD_DIR)/venv/bin/pip install $(PIP_ARGS) $(PACKAGE) pytest
$(BUILD_DIR)/venv/bin/rflx --version
mkdir -p $(BUILD_DIR)/tests
cp -r tests/{__init__.py,const.py,end_to_end,data} $(BUILD_DIR)/tests/
cp -r tests/{__init__.py,const.py,utils.py,end_to_end,data} $(BUILD_DIR)/tests/
cd $(BUILD_DIR) && source venv/bin/activate && rflx --version && venv/bin/pytest -vv tests/end_to_end
$(RM) -r $(BUILD_DIR)/{venv,tests}

Expand Down
24 changes: 18 additions & 6 deletions rflx/fatal_error.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,23 @@
import sys
import traceback
import types
from typing import Callable, Optional
from typing import Callable, Final, Optional

from rflx.version import version
from rflx.version import is_gnat_tracker_release, version

BUG_BOX_MSG_GITHUB: Final = """
A bug was detected. Please report this issue on GitHub:
https://github.com/AdaCore/RecordFlux/issues/new?labels=bug
"""

BUG_BOX_MSG_GNAT_TRACKER: Final = """
A bug was detected. Please submit a bug report using GNATtracker at
https://support.adacore.com/csm by logging in and clicking the
'Create A New Case' button. Alternatively, submit a bug report by email to
[email protected], including your account number #xxxx in the subject line.
Use a subject line meaningful to you and us to track the bug.
"""


class FatalErrorHandler:
Expand Down Expand Up @@ -47,10 +61,8 @@ def fatal_error_message(unsafe: bool) -> str:
{traceback.format_exc()}
----------------------------------------------------------------------------
A bug was detected. Please report this issue on GitHub:
https://github.com/AdaCore/RecordFlux/issues/new?labels=bug
{BUG_BOX_MSG_GNAT_TRACKER if is_gnat_tracker_release() else BUG_BOX_MSG_GITHUB}
Include the complete content of the bug box shown above and all input files
in the report."""
in the report. Use plain ASCII or MIME attachment(s)."""
return result
24 changes: 24 additions & 0 deletions rflx/version.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
from importlib import metadata
from typing import Optional

import rflx
from rflx import __version__
from rflx.error import fatal_fail

Expand All @@ -25,6 +26,29 @@ def dependencies() -> list[str]:
]


def is_gnat_tracker_release() -> bool:
"""
Return True iff the current instance of the tool is part of the GNATtracker release track.
RecordFlux has two release tracks: PyPI and GNATtracker. This function
determines the active track indirectly from the version number. The PyPI
track uses semantic versioning while the GNATtracker track does not.
"""
# Note: The regex below is from https://semver.org/ with one slight
# difference: the prerelease section is allowed to start also with a '.'
# instead of '-'. This allows for the intermediate version numbers, such as
# "0.22.1.dev13+1ef4d7163" that are generated by Poetry Dynamic Versioning
# also to be categorized as being on the PyPI release track.
semver_regex = (
r"^(?P<major>0|[1-9]\d*)\.(?P<minor>0|[1-9]\d*)\.(?P<patch>0|[1-9]\d*)"
r"(?:[-\.](?P<prerelease>(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)"
r"(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?"
r"(?:\+(?P<buildmetadata>[0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?$"
)
match = re.match(semver_regex, rflx.__version__)
return not bool(match)


class Requirement:
def __init__(self, string: str) -> None:
self.name: str
Expand Down
6 changes: 6 additions & 0 deletions tests/const.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
from pathlib import Path
from typing import Final

TEST_DIR = Path("tests")
DATA_DIR = TEST_DIR / "data"
Expand All @@ -12,3 +13,8 @@

EX_SPEC_DIR = Path("examples/specs")
MAIN = "main.adb"

GITHUB_TRACKER_REF_PATTERN: Final = (
r".*GitHub.*https://github.com/AdaCore/RecordFlux/issues/new\?labels=bug.*"
)
GNAT_TRACKER_REF_PATTERN: Final = r".*GNATtracker.*https://support.adacore.com/csm.*"
38 changes: 37 additions & 1 deletion tests/end_to_end/cli_test.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,22 @@
import re
import subprocess
import textwrap
from pathlib import Path

from tests.const import DATA_DIR, SPEC_DIR, VALIDATOR_DIR
import pytest

from rflx import cli
from tests.const import (
DATA_DIR,
GITHUB_TRACKER_REF_PATTERN,
GNAT_TRACKER_REF_PATTERN,
SPEC_DIR,
VALIDATOR_DIR,
)
from tests.utils import is_gnat_tracker_release_testing, raise_fatal_error

MESSAGE_SPEC_FILE = str(SPEC_DIR / "tlv.rflx")
SESSION_SPEC_FILE = str(SPEC_DIR / "session.rflx")


def test_check() -> None:
Expand Down Expand Up @@ -312,3 +326,25 @@ def test_run_ls() -> None:
Closing the event loop.
""", # noqa: E501
)


def test_unexpected_exception(
monkeypatch: pytest.MonkeyPatch,
tmp_path: Path,
capfd: pytest.CaptureFixture[str],
) -> None:
monkeypatch.setattr(cli, "generate", lambda _: raise_fatal_error())
with pytest.raises(SystemExit, match="^2$"):
cli.main(
["rflx", "generate", "-d", str(tmp_path), MESSAGE_SPEC_FILE, SESSION_SPEC_FILE],
)
tracker_ref_pattern = (
GNAT_TRACKER_REF_PATTERN
if is_gnat_tracker_release_testing()
else GITHUB_TRACKER_REF_PATTERN
)
assert re.fullmatch(
rf"\n-* RecordFlux Bug -*.*Traceback.*-*.*{tracker_ref_pattern}.*",
capfd.readouterr().err,
re.DOTALL,
)
24 changes: 15 additions & 9 deletions tests/unit/cli_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,14 @@
import pytest

import rflx.specification
from rflx import cli, generator, validator
from rflx import cli, fatal_error, generator, validator
from rflx.converter import iana
from rflx.error import fail, fatal_fail
from rflx.error import fail
from rflx.ls.server import server
from rflx.pyrflx import PyRFLXError
from rflx.rapidflux import ErrorEntry, Location, RecordFluxError, Severity, logging
from tests.const import DATA_DIR, SPEC_DIR
from tests.utils import assert_stderr_regex
from tests.const import DATA_DIR, GITHUB_TRACKER_REF_PATTERN, GNAT_TRACKER_REF_PATTERN, SPEC_DIR
from tests.utils import assert_stderr_regex, raise_fatal_error

MESSAGE_SPEC_FILE = str(SPEC_DIR / "tlv.rflx")
SESSION_SPEC_FILE = str(SPEC_DIR / "session.rflx")
Expand Down Expand Up @@ -53,10 +53,6 @@ def raise_unexpected_exception() -> None:
raise NotImplementedError("Not implemented")


def raise_fatal_error() -> None:
fatal_fail("TEST")


def test_run(monkeypatch: pytest.MonkeyPatch) -> None:
expected = ["rflx", "foo", "bar"]
monkeypatch.setattr(sys, "argv", expected)
Expand Down Expand Up @@ -651,18 +647,28 @@ def test_main_validate_fatal_error(
assert "RecordFlux Bug" in capfd.readouterr().err


@pytest.mark.parametrize(
("gnat_tracker_release", "tracker_ref_pattern"),
[
(False, GITHUB_TRACKER_REF_PATTERN),
(True, GNAT_TRACKER_REF_PATTERN),
],
)
def test_main_unexpected_exception(
gnat_tracker_release: bool,
tracker_ref_pattern: str,
monkeypatch: pytest.MonkeyPatch,
tmp_path: Path,
capfd: pytest.CaptureFixture[str],
) -> None:
monkeypatch.setattr(cli, "generate", lambda _: raise_fatal_error())
monkeypatch.setattr(fatal_error, "is_gnat_tracker_release", lambda: gnat_tracker_release)
with pytest.raises(SystemExit, match="^2$"):
cli.main(
["rflx", "generate", "-d", str(tmp_path), MESSAGE_SPEC_FILE, SESSION_SPEC_FILE],
)
assert re.fullmatch(
r"\n-* RecordFlux Bug -*.*Traceback.*-*.*RecordFlux/issues.*",
rf"\n-* RecordFlux Bug -*.*Traceback.*-*.*{tracker_ref_pattern}.*",
capfd.readouterr().err,
re.DOTALL,
)
Expand Down
23 changes: 22 additions & 1 deletion tests/unit/fatal_error_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,12 @@

import pytest

from rflx.fatal_error import FatalErrorHandler
from rflx import fatal_error
from rflx.fatal_error import (
FatalErrorHandler,
fatal_error_message,
)
from tests.const import GITHUB_TRACKER_REF_PATTERN, GNAT_TRACKER_REF_PATTERN


def test_fatal_error_handler() -> None:
Expand Down Expand Up @@ -41,3 +46,19 @@ def store(msg: str) -> None:
result[0],
re.DOTALL,
)


@pytest.mark.parametrize(
("gnat_tracker_release", "expected"),
[
(False, GITHUB_TRACKER_REF_PATTERN),
(True, GNAT_TRACKER_REF_PATTERN),
],
)
def test_fatal_error_message(
gnat_tracker_release: bool,
expected: str,
monkeypatch: pytest.MonkeyPatch,
) -> None:
monkeypatch.setattr(fatal_error, "is_gnat_tracker_release", lambda: gnat_tracker_release)
assert re.match(expected, fatal_error_message(unsafe=False), re.DOTALL)
24 changes: 24 additions & 0 deletions tests/unit/version_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,38 @@

import pytest

import rflx
from rflx import __version__, version
from rflx.error import FatalError
from rflx.version import is_gnat_tracker_release


def test_version() -> None:
assert version.version().startswith(f"RecordFlux {__version__}")


@pytest.mark.parametrize(
("rflx_version", "expected"),
[
("0.22.1", False),
("0.22.1.dev13+1ef4d7163", False),
("0.22.1-dev13+1ef4d7163", False),
("25.1.0", False),
("25.0", True),
("25.dev20240804", True),
("27.1", True),
("27.2", True),
],
)
def test_is_gnat_tracker_release(
rflx_version: str,
expected: bool,
monkeypatch: pytest.MonkeyPatch,
) -> None:
monkeypatch.setattr(rflx, "__version__", rflx_version)
assert is_gnat_tracker_release() == expected


@pytest.mark.parametrize(
("requirement", "name", "extra"),
[
Expand Down
9 changes: 9 additions & 0 deletions tests/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@

from rflx import ada, lang
from rflx.common import STDIN
from rflx.error import fatal_fail
from rflx.expr import Expr
from rflx.generator import Debug, Generator, const
from rflx.identifier import ID, StrID
Expand Down Expand Up @@ -1246,6 +1247,10 @@ def parse_expression(data: str, rule: str = lang.GrammarRule.extended_expression
return expression


def raise_fatal_error() -> None:
fatal_fail("TEST")


def get_test_model(name: str) -> Model:
parser = Parser()
parser.parse(SPEC_DIR / f"{name}.rflx")
Expand All @@ -1268,3 +1273,7 @@ def assert_stderr_regex(
check_regex(expected_regex)
capture = capfd.readouterr()
assert re.match(expected_regex, capture.err) is not None


def is_gnat_tracker_release_testing() -> bool:
return "RFLX_GNAT_TRACKER_RELEASE_TEST" in os.environ

0 comments on commit 825da89

Please sign in to comment.