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
105 changes: 97 additions & 8 deletions tests/test_cases/tests/test_cit_supported_datatypes.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,14 @@

@add_test_properties(
partially_verifies=[
"comp_req__persistency__key_naming_v2",
"comp_req__persistency__key_uniqueness_v2",
],
fully_verifies=[
"comp_req__persistency__key_encoding_v2",
"comp_req__persistency__value_data_types_v2",
"comp_req__persistency__key_length_v2",
],
description="Tests that the key-value store accepts valid key formats, enforces uniqueness, encodes keys as UTF-8, and restricts key length.",
test_type="requirements-based",
derivation_technique="interface-test",
)
Expand All @@ -41,22 +46,81 @@ def scenario_name(self) -> str:
def test_config(self) -> dict[str, Any]:
return {"kvs_parameters": {"instance_id": 1}}

def test_ok(self, results: ScenarioResult, logs_info_level: LogContainer) -> None:
@pytest.mark.xfail(
reason="KVS does not implement requirement #1: key character set (alphanumeric, underscore, dash) enforcement. It accepts space,special char,invalid keys."
)
def test_key_datatypes(self, results: ScenarioResult, logs_info_level: LogContainer) -> None:
assert results.return_code == ResultCode.SUCCESS

logs = logs_info_level.get_logs(field="key")
act_keys = set(map(lambda x: x.key, logs))
exp_keys = {"example", "emoji ✅❗😀", "greek ημα"}

assert len(act_keys) == len(exp_keys)
assert len(act_keys.symmetric_difference(exp_keys)) == 0
# Valid keys
valid_keys = {
"alphaNumeric123",
"with_underscore",
"with-dash",
"A1_b2-C3",
"a" * 32,
}
# Invalid keys (including non-ASCII, emoji, spaces, etc.)
invalid_keys = {
"has space",
"has$pecial",
"emoji✅",
"too_long_key_abcdefghijklmnopqrstuvwxyz123456",
"utf8_ключ",
"utf8_漢字",
"utf8_emoji ✅❗😀",
"utf8_greek ημα",
}
# UTF-8 keys
utf8_keys = {
"utf8_emoji_valid",
"utf8_alphaNumeric123",
"utf8_with_underscore",
"utf8-with-dash",
"utf8_A1_b2-C3",
}
# Check valid keys are present
assert valid_keys.issubset(act_keys)
# Check UTF-8 keys are present
assert utf8_keys.issubset(act_keys)
# Check invalid keys are not present
assert act_keys.isdisjoint(invalid_keys)

@pytest.mark.xfail(
reason="KVS allows duplicate keys by updating the value for an existing key instead of rejecting duplicates (requirement #2 not enforced)."
)
def test_duplicate_key(self, results: ScenarioResult, logs_info_level: LogContainer) -> None:
assert results.return_code == ResultCode.SUCCESS
# Check only one instance of duplicate key
# Uniqueness: duplicate key is currently fulfilled by allowing update to the value for an existing key (not strict rejection).
duplicate_key_logs = [x for x in logs if x.key == "unique_key"]
# TODO: Is allowing value update for an existing key compliant with the uniqueness requirement?
assert len(duplicate_key_logs) == 1, (
"Duplicate key insertion should be rejected (only one instance allowed, no update)"
)
assert len(duplicate_key_logs) == 1

@pytest.mark.xfail(reason="KVS does not enforce length limits on keys.")
def test_max_length_key(self, results: ScenarioResult, logs_info_level: LogContainer) -> None:
assert results.return_code == ResultCode.SUCCESS
logs = logs_info_level.get_logs(field="key")
act_keys = set(map(lambda x: x.key, logs))
# Max length key
max_length_key = "a" * 32
# Check max length key is present
assert max_length_key in act_keys


@add_test_properties(
partially_verifies=[
"comp_req__persistency__key_encoding_v2",
"comp_req__persistency__value_length_v2",
],
fully_verifies=[
"comp_req__persistency__value_data_types_v2",
"comp_req__persistency__value_serialize_v2",
],
description="Tests that the key-value store accepts only allowed value types, serializes values as JSON, and enforces value length limits.",
test_type="requirements-based",
derivation_technique="interface-test",
)
Expand Down Expand Up @@ -184,3 +248,28 @@ def exp_key(self) -> str:

def exp_value(self) -> Any:
return {"sub-number": {"t": "f64", "v": 789}}


class TestSupportedDatatypesValues_String1024(TestSupportedDatatypesValues):
def exp_key(self) -> str:
return "str_1024"

def exp_value(self) -> Any:
return "x" * 1024


class TestSupportedDatatypesValues_String1025(TestSupportedDatatypesValues):
def exp_key(self) -> str:
return "str_1025"

def exp_value(self) -> Any:
return "y" * 1025

@pytest.mark.xfail(reason="KVS does not yet enforce value length limit (requirement #7)")
def test_ok(self, results: ScenarioResult, logs_info_level: LogContainer) -> None:
# Requirement #7: The component shall limit the maximum length of a value to 1024 bytes.
# TODO: If this assertion fails, the KVS is not enforcing requirement #7.
# For >1024 bytes, expect error or no log
assert results.return_code != ResultCode.SUCCESS or not logs_info_level.get_logs(
field="key", value=self.exp_key()
)
8 changes: 5 additions & 3 deletions tests/test_scenarios/cpp/src/cit/default_values.cpp
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unnecessary reformat.

Original file line number Diff line number Diff line change
Expand Up @@ -55,12 +55,14 @@ static void info_log(const std::string& key,
*
* @tparam T The type of the current value to log.
* @param key The key being queried or modified in the KVS.
* @param value_is_default Boolean indicating whether the current value matches the default.
* @param value_is_default Boolean indicating whether the current value matches
* the default.
* @param current_value The current value for the key, of type T.
*
* This function emits logs in a structured format so that the Python test suite
* can parse and validate scenario output. Unlike the string overload, this version
* logs the current value as a typed parameter and omits the default value.
* can parse and validate scenario output. Unlike the string overload, this
* version logs the current value as a typed parameter and omits the default
* value.
*/
template <typename T>
static void info_log(const std::string& key, const bool value_is_default, T current_value)
Expand Down
17 changes: 9 additions & 8 deletions tests/test_scenarios/cpp/src/cit/snapshots.cpp
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unnecessary reformat.

Original file line number Diff line number Diff line change
Expand Up @@ -73,16 +73,17 @@ class SnapshotCount : public Scenario
* Issue: The test expects the final snapshot_count to be min(count,
* snapshot_max_count) (e.g., 1 for count=1, snapshot_max_count=1/3/10).
* Observed: C++ emits snapshot_count: 0 after the first flush.
* Possible Root Cause: In C++, the snapshot count is not incremented after
* the first flush because the snapshot rotation logic and counting are tied to
* the hardcoded max (not the parameter).
* Possible Root Cause: In C++, the snapshot count is not incremented
* after the first flush because the snapshot rotation logic and counting are
* tied to the hardcoded max (not the parameter).
*
* TestSnapshotCountFull
* Issue: The test expects a sequence of snapshot_count values: [0, 1] for count=2, [0, 1,
* 2, 3] for count=4, etc. Observed: C++ emits [0, 0, 1] or [0, 0, 1, 2, 3], but the first value
* is always 0, and the final value is not as expected. Possible Root Cause: The C++
* implementation may not be accumulating the count correctly, it stores or updates the count
* only after flush when MAX<3.
* Issue: The test expects a sequence of snapshot_count values: [0, 1]
* for count=2, [0, 1, 2, 3] for count=4, etc. Observed: C++ emits [0, 0, 1]
* or [0, 0, 1, 2, 3], but the first value is always 0, and the final value is
* not as expected. Possible Root Cause: The C++ implementation may not be
* accumulating the count correctly, it stores or updates the count only after
* flush when MAX<3.
*
* Raised bugs: https://github.com/eclipse-score/persistency/issues/108
* https://github.com/eclipse-score/persistency/issues/192
Expand Down
Loading
Loading