Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions .agents/skills/acknowledg-client/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,17 @@ Auth header: `X-AcknowlEDG-API-Key` (never put the key in query strings).
`RoleOccupied`: discard that handler / stop reconnecting that section; keep
other sections running.

Batch subscribe / unsubscribe answers are not timed: the server answers at
once, and a lost connection (keepalive pings notice) fails what is pending
as `NotConnectedError`; `add_section` keeps the section registered, and the
next session restores it.

`IncompatibleProtocolVersion` carries the peer's `revision` (the server's
`outdated-proto` says its own) and `peer_is_newer`. It stops a session;
`BatchClient(wait_for_server_update=True)` instead waits out an older
server, reconnecting every `SERVER_UPDATE_RETRY_S` (5 s) with its sections
still registered. A newer server still stops it: the client must be updated.

## Batch subscription maps

`_BatchClientReview` tracks:
Expand Down
40 changes: 34 additions & 6 deletions dev_tools/bin/edgy
Original file line number Diff line number Diff line change
Expand Up @@ -255,15 +255,43 @@ def load_edgy_config(args: argparse.Namespace, test_home: Path) -> EdgyConfig:
)

test_suites = config_file_dict.get('test_suites', {})
primary_test_suites = test_suites.get('primary', [])
secondary_test_suites = test_suites.get('secondary', [])
_validate_configured_suites(
config_file_path,
{'primary': primary_test_suites, 'secondary': secondary_test_suites}
)
config_sets = config_file_dict.get('config_sets', {})
return EdgyConfig(
test_home,
loaded_configs,
config_sets,
test_suites.get('primary', []),
test_suites.get('secondary', [])
primary_test_suites,
secondary_test_suites
)

def _validate_configured_suites(config_file_path: Path,
test_suites: Dict[str, Any]) -> None:
'''Exit unless each list of suites ``config_file_path`` gives is a list of
valid names.'''
invalid_test_suite_encountered = False
for kind, test_suite_names in test_suites.items():
if not isinstance(test_suite_names, list):
edgutil.eprint(f"Invalid {kind} test suites {test_suite_names!r} in "
f"{config_file_path} (expected a list of names).")
invalid_test_suite_encountered = True
continue
for test_suite in test_suite_names:
if not (isinstance(test_suite, str) and
edgtest.is_valid_suite_name(test_suite)):
edgutil.eprint(f"Invalid test suite name {test_suite!r} in "
f"{config_file_path} (expected 1-64 of A-Z, a-z, "
"0-9, _ and -).")
invalid_test_suite_encountered = True

if invalid_test_suite_encountered:
sys.exit(1)

def get_expectation_path(run_config: TestRunConfig,
test_suite_name: str) -> Path:
return Path(run_config.expectations_dir, f"{test_suite_name}.log")
Expand Down Expand Up @@ -627,7 +655,7 @@ def _diagnose_bad_expectations_file(file_path: Path) -> None:
line_ctr += 1
try:
parse_test_status(line_text)
except:
except Exception:
if len(line_text) != 0:
edgutil.eprint(
f"{file_path_str}, line {line_ctr}: "
Expand Down Expand Up @@ -668,7 +696,7 @@ def _construct_replay_filters(
)
for key in comparison:
desired_tests.add(parsed_test_status_key_to_name(key))
except:
except Exception:
edgutil.eprint(
f"Failed to compare the previous run of the {test_suite.name} "
'suite to its expectations.'
Expand All @@ -691,7 +719,7 @@ def _construct_replay_filters(
elif (args.replay == 'output-mismatch' and
parsed_test_status.is_output_mismatch()):
desired_tests.add(parsed_test_status_key_to_name(key))
except:
except Exception:
edgutil.eprint(
f"Failed to parse test statuses in previous run of {test_suite.name}."
)
Expand Down Expand Up @@ -1246,7 +1274,7 @@ class TestStatusChecker:
encountered_lines: List[str]) -> Optional['TestStatusChecker']:
try:
return TestStatusChecker(expected_lines, encountered_lines)
except:
except Exception:
return None

def _get_status_for_comparison(
Expand Down
10 changes: 7 additions & 3 deletions dev_tools/bin/ifc-qt
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,11 @@ import edgifc.decoration
from enum import IntEnum
from pathlib import Path

from PySide6 import QtCore, QtWidgets, QtGui # type: ignore[import-not-found,import]
from PySide6 import ( # type: ignore[import-not-found,import]
QtCore,
QtWidgets,
QtGui
)

from edgifc import (
IFCReader,
Expand Down Expand Up @@ -383,7 +387,7 @@ class PartitionNodeFormatter:
values.append(template_string.format(value.description))
else:
values.append(format_fn(value))
except:
except Exception:
traceback.print_exc()
values.append(edgifc.decoration.UNKNOWN_VALUE)

Expand Down Expand Up @@ -428,7 +432,7 @@ class PartitionNodeFormatter:
stream_reader,
tacit_field.name()
)
except:
except Exception:
traceback.print_exc()
field_value = 0

Expand Down
21 changes: 19 additions & 2 deletions dev_tools/pylibs/edgacknowledg/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -330,7 +330,7 @@ def _parse_envelope(response_message: DecodableMessage) -> ProtocolMessage:
revision = response_json.get('r')

if revision != PROTOCOL_REVISION:
raise IncompatibleProtocolVersion()
raise IncompatibleProtocolVersion(revision)
return response_json

def decode_response(
Expand All @@ -347,7 +347,24 @@ def decode_response(
return (tag, value, response_json.get('s'))

class IncompatibleProtocolVersion(Exception):
pass
'''The peer speaks another protocol revision: ``revision``, as it said
(the server's ``outdated-proto`` carries its own), if it said.
'''

def __init__(self, revision: Any = None) -> None:
self.revision = revision
super().__init__(
f"the peer speaks protocol revision {revision!r}, not "
f"{PROTOCOL_REVISION}"
)

@property
def peer_is_newer(self) -> bool:
'''Whether the peer is newer (this side must be updated), rather than
older, or saying no revision it could be compared by.
'''
return (isinstance(self.revision, int) and
self.revision > PROTOCOL_REVISION)

class UnexpectedResponseTag(Exception):
pass
Expand Down
Loading
Loading