Skip to content

Commit f757918

Browse files
committed
Support dot-path keyby and fix CI junit upload
- Resolve dotted attribute paths in DefaultState/DuckDBState insert so keyby can reference nested struct members (e.g. keyby='sub.id') - Make --junitxml explicit in Makefile and switch upload-artifact/publish paths to 'junit.xml' so CI test results are reported (previously '**/junit.xml' produced 0 tests in the PR comment) Signed-off-by: Tim Paine <3105306+timkpaine@users.noreply.github.com>
1 parent 7414947 commit f757918

4 files changed

Lines changed: 31 additions & 5 deletions

File tree

.github/workflows/build.yaml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -111,13 +111,13 @@ jobs:
111111
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7
112112
with:
113113
name: test-results-${{ matrix.os }}-${{ matrix.python-version }}
114-
path: '**/junit.xml'
114+
path: junit.xml
115115
if: matrix.os == 'ubuntu-latest' && matrix.python-version == '3.11'
116116

117117
- name: Publish Unit Test Results
118118
uses: EnricoMi/publish-unit-test-result-action@c950f6fb443cb5af20a377fd0dfaa78838901040 # v2
119119
with:
120-
files: '**/junit.xml'
120+
files: junit.xml
121121
if: matrix.os == 'ubuntu-latest' && matrix.python-version == '3.11'
122122

123123
- name: Upload coverage

Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@ test-py: ## run python tests
9797
tests-py: test-py
9898

9999
coverage-py: ## run python tests and collect test coverage
100-
python -m pytest -v csp_gateway/tests --cov=csp_gateway --cov-report term-missing --cov-report xml
100+
python -m pytest -v csp_gateway/tests --junitxml=junit.xml --cov=csp_gateway --cov-report term-missing --cov-report xml
101101

102102
.PHONY: test-js tests-js coverage-js
103103
test-js: ## run js tests

csp_gateway/server/gateway/csp/state.py

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,16 @@ def disable_duckdb_state() -> None:
7575
_USE_DUCKDB_STATE = False
7676

7777

78+
def _resolve_keyby_attr(record: Any, path: str) -> Any:
79+
"""Resolve a (possibly dotted) attribute path on ``record``, returning ``None`` if any segment is missing."""
80+
obj = record
81+
for segment in path.split("."):
82+
if obj is None:
83+
return None
84+
obj = getattr(obj, segment, None)
85+
return obj
86+
87+
7888
class StateType(CoreEnum):
7989
UNKNOWN = 0
8090
DEFAULT = 1
@@ -149,7 +159,7 @@ def insert(self, record: Any) -> None:
149159

150160
for subkey in self._keyby:
151161
# extract the key from the record
152-
subkey_to_use = getattr(record, subkey, None)
162+
subkey_to_use = _resolve_keyby_attr(record, subkey)
153163

154164
if subkey == self._keyby[-1]:
155165
# Put the element there if last
@@ -408,7 +418,7 @@ def insert(self, record: Struct) -> None:
408418
obj_id = None
409419
for subkey in self._keyby:
410420
# extract the key from the record
411-
subkey_to_use = getattr(record, subkey, None)
421+
subkey_to_use = _resolve_keyby_attr(record, subkey)
412422

413423
if subkey == self._keyby[-1]:
414424
if subkey_to_use not in place.keys():

csp_gateway/tests/server/gateway/csp/test_state.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,22 @@ def test_state_keyby_unset():
9494
assert res == [ts]
9595

9696

97+
def test_state_keyby_dot_path():
98+
for specialization, struct_type in zip(_STATES, _STRUCTS):
99+
s = State[struct_type](keyby="g.suba")
100+
assert s.state_type() == specialization
101+
ts1 = struct_type(a=0, b="hello", g=CspSubStruct(suba=1))
102+
ts2 = struct_type(a=1, b="world", g=CspSubStruct(suba=2))
103+
s.insert(ts1)
104+
s.insert(ts2)
105+
assert sorted(s.query(), key=lambda r: r.g.suba) == [ts1, ts2]
106+
107+
# Overwriting with same nested key replaces the record.
108+
ts3 = struct_type(a=2, b="again", g=CspSubStruct(suba=1))
109+
s.insert(ts3)
110+
assert sorted(s.query(), key=lambda r: r.g.suba) == [ts3, ts2]
111+
112+
97113
def test_state_keyby_two():
98114
for specialization, struct_type in zip(_STATES, _STRUCTS):
99115
s = State[struct_type](keyby=("a", "b"))

0 commit comments

Comments
 (0)