diff --git a/gvm/protocols/gmp/_gmpnext.py b/gvm/protocols/gmp/_gmpnext.py
index 8ce40027..e9a1ccd3 100644
--- a/gvm/protocols/gmp/_gmpnext.py
+++ b/gvm/protocols/gmp/_gmpnext.py
@@ -218,6 +218,7 @@ def create_agent_group(
agent_ids: list[str],
scheduler_cron_time: str,
*,
+ max_delay_seconds: int | None = None,
comment: str | None = None,
) -> T:
"""Create a new agent group.
@@ -226,6 +227,7 @@ def create_agent_group(
name: Name of the new agent group.
agent_ids: List of agent UUIDs to include in the group (required).
scheduler_cron_time: Scheduler cron to use.
+ max_delay_seconds: Max delay seconds to use.
comment: Optional comment for the group.
Raises:
@@ -237,6 +239,7 @@ def create_agent_group(
comment=comment,
agent_ids=agent_ids,
scheduler_cron_time=scheduler_cron_time,
+ max_delay_seconds=max_delay_seconds,
)
)
@@ -248,6 +251,7 @@ def modify_agent_group(
name: str | None = None,
comment: str | None = None,
agent_ids: list[str] | None = None,
+ max_delay_seconds: int | None = None,
) -> T:
"""Modify an existing agent group.
@@ -257,6 +261,7 @@ def modify_agent_group(
scheduler_cron_time: Scheduler cron to use.
comment: Optional comment for the group.
agent_ids: Optional list of agent UUIDs to set for the group.
+ max_delay_seconds: Optional maximum delay for agent groups.
Raises:
RequiredArgument: If agent_group_id is not provided.
@@ -268,6 +273,7 @@ def modify_agent_group(
comment=comment,
agent_ids=agent_ids,
scheduler_cron_time=scheduler_cron_time,
+ max_delay_seconds=max_delay_seconds,
)
)
diff --git a/gvm/protocols/gmp/requests/next/_agent_groups.py b/gvm/protocols/gmp/requests/next/_agent_groups.py
index c817364e..fb9eca5b 100644
--- a/gvm/protocols/gmp/requests/next/_agent_groups.py
+++ b/gvm/protocols/gmp/requests/next/_agent_groups.py
@@ -18,6 +18,7 @@ def create_agent_group(
agent_ids: list[str],
scheduler_cron_time: str,
*,
+ max_delay_seconds: int | None = None,
comment: str | None = None,
) -> Request:
"""Create a new agent group.
@@ -26,6 +27,7 @@ def create_agent_group(
name: Name of the new agent group.
agent_ids: List of agent UUIDs to include in the group (required).
scheduler_cron_time: Cron-like time to schedule new agent groups (required).
+ max_delay_seconds: Max delay seconds to schedule the new agent group (optional).
comment: Optional comment for the group.
Raises:
@@ -50,6 +52,9 @@ def create_agent_group(
cmd.add_element("name", name)
cmd.add_element("scheduler_cron_time", scheduler_cron_time)
+ if max_delay_seconds is not None:
+ cmd.add_element("max_delay_seconds", str(max_delay_seconds))
+
if comment:
cmd.add_element("comment", comment)
@@ -89,6 +94,7 @@ def modify_agent_group(
name: str | None = None,
comment: str | None = None,
agent_ids: list[str] | None = None,
+ max_delay_seconds: int | None = None,
) -> Request:
"""Modify an existing agent group.
@@ -98,6 +104,7 @@ def modify_agent_group(
name: Optional new name for the group.
comment: Optional comment for the group.
agent_ids: Optional list of agent UUIDs to set for the group.
+ max_delay_seconds: Max delay seconds to schedule the new agent group.
Raises:
RequiredArgument: If agent_group_id is not provided.
@@ -127,6 +134,8 @@ def modify_agent_group(
agents_element = cmd.add_element("agents")
for agent_id in agent_ids:
agents_element.add_element("agent", attrs={"id": agent_id})
+ if max_delay_seconds is not None:
+ cmd.add_element("max_delay_seconds", str(max_delay_seconds))
return cmd
diff --git a/gvm/protocols/gmp/requests/next/_agents.py b/gvm/protocols/gmp/requests/next/_agents.py
index e0571567..c8434a76 100644
--- a/gvm/protocols/gmp/requests/next/_agents.py
+++ b/gvm/protocols/gmp/requests/next/_agents.py
@@ -73,20 +73,40 @@ def valid_value(d: Mapping[str, Any], key: str, path: str) -> Any:
valid_value(se, "indexer_dir_depth", "agent_script_executor.")
sched = se.get("scheduler_cron_time")
- if isinstance(sched, str):
- items = [sched]
- elif isinstance(sched, Sequence) and not isinstance(
- sched, (str, bytes)
+
+ if (
+ not isinstance(sched, Sequence)
+ or isinstance(sched, (str, bytes))
+ or not sched
):
- items = [str(x) for x in sched]
- else:
- items = []
- if not items or any(not str(x).strip() for x in items):
raise RequiredArgument(
function=caller,
argument="config.agent_script_executor.scheduler_cron_time",
)
+ for item in sched:
+ if not isinstance(item, Mapping):
+ raise InvalidArgumentType(
+ function=caller,
+ argument="config.agent_script_executor.scheduler_cron_time",
+ arg_type="Mapping",
+ )
+
+ cron = item.get("cron")
+ max_delay_seconds = item.get("max_delay_seconds")
+
+ if not isinstance(cron, str) or not cron.strip():
+ raise RequiredArgument(
+ function=caller,
+ argument="config.agent_script_executor.scheduler_cron_time.cron",
+ )
+
+ if type(max_delay_seconds) is not int or max_delay_seconds < 0:
+ raise InvalidArgumentType(
+ function=caller,
+ argument="config.agent_script_executor.scheduler_cron_time.max_delay_seconds",
+ arg_type="non-negative integer",
+ )
# heartbeat
hb = valid_map(config, "heartbeat", "")
valid_value(hb, "interval_in_seconds", "heartbeat.")
@@ -162,7 +182,12 @@ def _append_agent_config(
"bulk_size": 2,
"bulk_throttle_time_in_ms": 300,
"indexer_dir_depth": 100,
- "scheduler_cron_time": ["0 */12 * * *"],
+ "scheduler_cron_time": [
+ {
+ "cron": "0 */12 * * *",
+ "max_delay_seconds": 30,
+ },
+ ],
},
"heartbeat": {
"interval_in_seconds": 300,
@@ -212,18 +237,21 @@ def _append_agent_config(
xml_se, "indexer_dir_depth", se.get("indexer_dir_depth")
)
sched = se.get("scheduler_cron_time")
- if isinstance(sched, str):
- sched_items = [sched]
- else:
- sched_items = list(sched or [])
- if sched_items:
+ if sched:
xml_sched = xml_se.add_element(
"scheduler_cron_time",
attrs={"is_list": "1"},
)
- for item in sched_items:
- xml_sched.add_element("item", str(item))
+
+ for item in sched:
+ xml_item = xml_sched.add_element("item")
+ cls._add_element(xml_item, "cron", item["cron"])
+ cls._add_element(
+ xml_item,
+ "max_delay_seconds",
+ item["max_delay_seconds"],
+ )
# heartbeat
hb = config["heartbeat"]
@@ -311,7 +339,12 @@ def modify_agents(
"bulk_size": 2,
"bulk_throttle_time_in_ms": 300,
"indexer_dir_depth": 100,
- "scheduler_cron_time": ["0 */12 * * *"], # str or list[str]
+ "scheduler_cron_time": [
+ {
+ "cron": "0 */12 * * *",
+ "max_delay_seconds": 30,
+ },
+ ],
},
"heartbeat": {
"interval_in_seconds": 300,
@@ -393,7 +426,16 @@ def modify_agent_control_scan_config(
"bulk_size": 2,
"bulk_throttle_time_in_ms": 300,
"indexer_dir_depth": 100,
- "scheduler_cron_time": ["0 */12 * * *"],
+ "scheduler_cron_time": [
+ {
+ "cron": "0 */12 * * *",
+ "max_delay_seconds": 30,
+ },
+ {
+ "cron": "0 23 * * *",
+ "max_delay_seconds": 60,
+ },
+ ],
},
"heartbeat": {
"interval_in_seconds": 300,
@@ -410,6 +452,7 @@ def modify_agent_control_scan_config(
function=cls.modify_agent_control_scan_config.__name__,
argument="agent_control_id",
)
+
if not config_defaults:
raise RequiredArgument(
function=cls.modify_agent_control_scan_config.__name__,
diff --git a/tests/protocols/gmpnext/entities/agent_groups/test_create_agent_group.py b/tests/protocols/gmpnext/entities/agent_groups/test_create_agent_group.py
index 80bf2c74..95a0291a 100644
--- a/tests/protocols/gmpnext/entities/agent_groups/test_create_agent_group.py
+++ b/tests/protocols/gmpnext/entities/agent_groups/test_create_agent_group.py
@@ -12,12 +12,14 @@ def test_create_agent_group(self):
agent_ids=["agent-1", "agent-2"],
comment="Sample comment",
scheduler_cron_time="0 */5 * * *",
+ max_delay_seconds=30,
)
self.connection.send.has_been_called_with(
b""
b"ExampleGroup"
b"0 */5 * * *"
+ b"30"
b"Sample comment"
b''
b""
@@ -57,3 +59,35 @@ def test_create_agent_group_without_comment(self):
b''
b""
)
+
+ def test_create_agent_group_with_zero_max_delay(self):
+ self.gmp.create_agent_group(
+ name="GroupX",
+ agent_ids=["a1"],
+ scheduler_cron_time="0 */5 * * *",
+ max_delay_seconds=0,
+ )
+
+ self.connection.send.has_been_called_with(
+ b""
+ b"GroupX"
+ b"0 */5 * * *"
+ b"0"
+ b''
+ b""
+ )
+
+ def test_create_agent_group_without_max_delay(self):
+ self.gmp.create_agent_group(
+ name="GroupX",
+ agent_ids=["a1"],
+ scheduler_cron_time="0 */5 * * *",
+ )
+
+ self.connection.send.has_been_called_with(
+ b""
+ b"GroupX"
+ b"0 */5 * * *"
+ b''
+ b""
+ )
diff --git a/tests/protocols/gmpnext/entities/agent_groups/test_modify_agent_group.py b/tests/protocols/gmpnext/entities/agent_groups/test_modify_agent_group.py
index c7f809ea..e179ba14 100644
--- a/tests/protocols/gmpnext/entities/agent_groups/test_modify_agent_group.py
+++ b/tests/protocols/gmpnext/entities/agent_groups/test_modify_agent_group.py
@@ -12,6 +12,7 @@ def test_modify_agent_group(self):
name="NewName",
comment="Updated comment",
scheduler_cron_time="0 */5 * * *",
+ max_delay_seconds=30,
agent_ids=["agent-1", "agent-2"],
)
@@ -21,6 +22,7 @@ def test_modify_agent_group(self):
b"NewName"
b"Updated comment"
b''
+ b"30"
b""
)
@@ -83,3 +85,29 @@ def test_modify_agent_group_without_agent_ids(self):
b"Updated comment"
b""
)
+
+ def test_modify_agent_group_with_zero_max_delay(self):
+ self.gmp.modify_agent_group(
+ agent_group_id="group-1",
+ scheduler_cron_time="0 */5 * * *",
+ max_delay_seconds=0,
+ )
+
+ self.connection.send.has_been_called_with(
+ b''
+ b"0 */5 * * *"
+ b"0"
+ b""
+ )
+
+ def test_modify_agent_group_without_max_delay(self):
+ self.gmp.modify_agent_group(
+ agent_group_id="group-1",
+ scheduler_cron_time="0 */5 * * *",
+ )
+
+ self.connection.send.has_been_called_with(
+ b''
+ b"0 */5 * * *"
+ b""
+ )
diff --git a/tests/protocols/gmpnext/entities/agents/test_modify_agent_controller_scan_config.py b/tests/protocols/gmpnext/entities/agents/test_modify_agent_controller_scan_config.py
index 5e293bae..0d9d3b7a 100644
--- a/tests/protocols/gmpnext/entities/agents/test_modify_agent_controller_scan_config.py
+++ b/tests/protocols/gmpnext/entities/agents/test_modify_agent_controller_scan_config.py
@@ -21,8 +21,8 @@ def test_modify_agent_control_scan_config_full(self):
"bulk_throttle_time_in_ms": 100,
"indexer_dir_depth": 10,
"scheduler_cron_time": [
- "0 23 * * *",
- "0 22 * * *",
+ {"cron": "0 23 * * *", "max_delay_seconds": 30},
+ {"cron": "0 22 * * *", "max_delay_seconds": 60},
],
},
"heartbeat": {
@@ -56,8 +56,10 @@ def test_modify_agent_control_scan_config_full(self):
b"100"
b"10"
b''
- b"- 0 23 * * *
"
- b"- 0 22 * * *
"
+ b"- 0 23 * * *"
+ b"30
"
+ b"- 0 22 * * *"
+ b"60
"
b""
b""
b""
@@ -72,32 +74,85 @@ def test_modify_agent_control_scan_config_full(self):
b""
)
+ def test_modify_agent_control_scan_config_zero_max_delay(self):
+ config = {
+ "agent_defaults": {
+ "agent_control": {
+ "retry": {
+ "attempts": 6,
+ "delay_in_seconds": 60,
+ "max_jitter_in_seconds": 10,
+ }
+ },
+ "agent_script_executor": {
+ "bulk_size": 1,
+ "bulk_throttle_time_in_ms": 100,
+ "indexer_dir_depth": 10,
+ "scheduler_cron_time": [
+ {"cron": "0 23 * * *", "max_delay_seconds": 0},
+ ],
+ },
+ "heartbeat": {
+ "interval_in_seconds": 600,
+ "miss_until_inactive": 1,
+ },
+ },
+ "agent_control_defaults": {"update_to_latest": True},
+ }
+
+ self.gmp.modify_agent_control_scan_config(
+ "3b4be213-281f-49ee-b457-5a5f34f71510",
+ config=config,
+ )
+
+ self.connection.send.has_been_called_with(
+ b''
+ b""
+ b"6"
+ b"60"
+ b"10"
+ b""
+ b"1"
+ b"100"
+ b"10"
+ b''
+ b"- 0 23 * * *"
+ b"0
"
+ b""
+ b"600"
+ b"1"
+ b""
+ b"1"
+ b""
+ b""
+ )
+
def test_modify_agent_control_scan_config_with_missing_element_raises(self):
cfg = {
- "config_defaults": {
- "agent_defaults": {
- "agent_control": {
- "retry": {
- "attempts": 6,
- "delay_in_seconds": 60,
- # max_jitter_in_seconds is missing
- }
- },
- "agent_script_executor": {
- "bulk_size": 2,
- "bulk_throttle_time_in_ms": 300,
- "indexer_dir_depth": 100,
- "scheduler_cron_time": ["0 */12 * * *"],
- },
- "heartbeat": {
- "interval_in_seconds": 300,
- "miss_until_inactive": 1,
- },
+ "agent_defaults": {
+ "agent_control": {
+ "retry": {
+ "attempts": 6,
+ "delay_in_seconds": 60,
+ # max_jitter_in_seconds is missing
+ }
+ },
+ "agent_script_executor": {
+ "bulk_size": 2,
+ "bulk_throttle_time_in_ms": 300,
+ "indexer_dir_depth": 100,
+ "scheduler_cron_time": [
+ {"cron": "0 */12 * * *", "max_delay_seconds": 30}
+ ],
},
- "agent_control_defaults": {
- "update_to_latest": True,
+ "heartbeat": {
+ "interval_in_seconds": 300,
+ "miss_until_inactive": 1,
},
- }
+ },
+ "agent_control_defaults": {
+ "update_to_latest": True,
+ },
}
with self.assertRaises(RequiredArgument):
@@ -111,30 +166,33 @@ def test_modify_agent_control_scan_config_missing_id_raises(self):
self.gmp.modify_agent_control_scan_config(
"", # missing id
config={
- "config_defaults": {
- "agent_defaults": {
- "agent_control": {
- "retry": {
- "attempts": 6,
- "delay_in_seconds": 60,
- "max_jitter_in_seconds": 10,
+ "agent_defaults": {
+ "agent_control": {
+ "retry": {
+ "attempts": 6,
+ "delay_in_seconds": 60,
+ "max_jitter_in_seconds": 10,
+ }
+ },
+ "agent_script_executor": {
+ "bulk_size": 2,
+ "bulk_throttle_time_in_ms": 300,
+ "indexer_dir_depth": 100,
+ "scheduler_cron_time": [
+ {
+ "cron": "0 */12 * * *",
+ "max_delay_seconds": 30,
}
- },
- "agent_script_executor": {
- "bulk_size": 2,
- "bulk_throttle_time_in_ms": 300,
- "indexer_dir_depth": 100,
- "scheduler_cron_time": ["0 */12 * * *"],
- },
- "heartbeat": {
- "interval_in_seconds": 300,
- "miss_until_inactive": 1,
- },
+ ],
},
- "agent_control_defaults": {
- "update_to_latest": True,
+ "heartbeat": {
+ "interval_in_seconds": 300,
+ "miss_until_inactive": 1,
},
- }
+ },
+ "agent_control_defaults": {
+ "update_to_latest": True,
+ },
},
)
@@ -155,24 +213,24 @@ def test_modify_agent_control_scan_config_agent_control_not_mapping_raises(
self,
):
cfg = {
- "config_defaults": {
- "agent_defaults": {
- "agent_control": "oops-not-a-mapping",
- "agent_script_executor": {
- "bulk_size": 2,
- "bulk_throttle_time_in_ms": 300,
- "indexer_dir_depth": 100,
- "scheduler_cron_time": ["0 */12 * * *"],
- },
- "heartbeat": {
- "interval_in_seconds": 300,
- "miss_until_inactive": 1,
- },
+ "agent_defaults": {
+ "agent_control": "oops-not-a-mapping",
+ "agent_script_executor": {
+ "bulk_size": 2,
+ "bulk_throttle_time_in_ms": 300,
+ "indexer_dir_depth": 100,
+ "scheduler_cron_time": [
+ {"cron": "0 */12 * * *", "max_delay_seconds": 30}
+ ],
},
- "agent_control_defaults": {
- "update_to_latest": True,
+ "heartbeat": {
+ "interval_in_seconds": 300,
+ "miss_until_inactive": 1,
},
- }
+ },
+ "agent_control_defaults": {
+ "update_to_latest": True,
+ },
}
with self.assertRaises(RequiredArgument):
self.gmp.modify_agent_control_scan_config(
@@ -181,30 +239,28 @@ def test_modify_agent_control_scan_config_agent_control_not_mapping_raises(
def test_modify_agent_control_scan_config_scheduler_empty_list_raises(self):
cfg = {
- "config_defaults": {
- "agent_defaults": {
- "agent_control": {
- "retry": {
- "attempts": 6,
- "delay_in_seconds": 60,
- "max_jitter_in_seconds": 10,
- }
- },
- "agent_script_executor": {
- "bulk_size": 2,
- "bulk_throttle_time_in_ms": 300,
- "indexer_dir_depth": 100,
- "scheduler_cron_time": [],
- },
- "heartbeat": {
- "interval_in_seconds": 300,
- "miss_until_inactive": 1,
- },
+ "agent_defaults": {
+ "agent_control": {
+ "retry": {
+ "attempts": 6,
+ "delay_in_seconds": 60,
+ "max_jitter_in_seconds": 10,
+ }
},
- "agent_control_defaults": {
- "update_to_latest": True,
+ "agent_script_executor": {
+ "bulk_size": 2,
+ "bulk_throttle_time_in_ms": 300,
+ "indexer_dir_depth": 100,
+ "scheduler_cron_time": [],
},
- }
+ "heartbeat": {
+ "interval_in_seconds": 300,
+ "miss_until_inactive": 1,
+ },
+ },
+ "agent_control_defaults": {
+ "update_to_latest": True,
+ },
}
with self.assertRaises(RequiredArgument):
self.gmp.modify_agent_control_scan_config(
@@ -215,30 +271,31 @@ def test_modify_agent_control_scan_config_scheduler_with_empty_item_raises(
self,
):
cfg = {
- "config_defaults": {
- "agent_defaults": {
- "agent_control": {
- "retry": {
- "attempts": 6,
- "delay_in_seconds": 60,
- "max_jitter_in_seconds": 10,
- }
- },
- "agent_script_executor": {
- "bulk_size": 2,
- "bulk_throttle_time_in_ms": 300,
- "indexer_dir_depth": 100,
- "scheduler_cron_time": ["", " "],
- },
- "heartbeat": {
- "interval_in_seconds": 300,
- "miss_until_inactive": 1,
- },
+ "agent_defaults": {
+ "agent_control": {
+ "retry": {
+ "attempts": 6,
+ "delay_in_seconds": 60,
+ "max_jitter_in_seconds": 10,
+ }
},
- "agent_control_defaults": {
- "update_to_latest": True,
+ "agent_script_executor": {
+ "bulk_size": 2,
+ "bulk_throttle_time_in_ms": 300,
+ "indexer_dir_depth": 100,
+ "scheduler_cron_time": [
+ {"cron": "", "max_delay_seconds": 30},
+ {"cron": " ", "max_delay_seconds": 30},
+ ],
+ },
+ "heartbeat": {
+ "interval_in_seconds": 300,
+ "miss_until_inactive": 1,
},
- }
+ },
+ "agent_control_defaults": {
+ "update_to_latest": True,
+ },
}
with self.assertRaises(RequiredArgument):
self.gmp.modify_agent_control_scan_config(
@@ -249,24 +306,24 @@ def test_modify_agent_control_scan_config_missing_agent_control_raises(
self,
):
cfg = {
- "config_defaults": {
- "agent_defaults": {
- # "agent_control": missing
- "agent_script_executor": {
- "bulk_size": 2,
- "bulk_throttle_time_in_ms": 300,
- "indexer_dir_depth": 100,
- "scheduler_cron_time": ["0 */12 * * *"],
- },
- "heartbeat": {
- "interval_in_seconds": 300,
- "miss_until_inactive": 1,
- },
+ "agent_defaults": {
+ # "agent_control": missing
+ "agent_script_executor": {
+ "bulk_size": 2,
+ "bulk_throttle_time_in_ms": 300,
+ "indexer_dir_depth": 100,
+ "scheduler_cron_time": [
+ {"cron": "0 */12 * * *", "max_delay_seconds": 30}
+ ],
},
- "agent_control_defaults": {
- "update_to_latest": True,
+ "heartbeat": {
+ "interval_in_seconds": 300,
+ "miss_until_inactive": 1,
},
- }
+ },
+ "agent_control_defaults": {
+ "update_to_latest": True,
+ },
}
with self.assertRaises(RequiredArgument):
self.gmp.modify_agent_control_scan_config(
@@ -275,26 +332,26 @@ def test_modify_agent_control_scan_config_missing_agent_control_raises(
def test_modify_agent_control_scan_config_missing_retry_block_raises(self):
cfg = {
- "config_defaults": {
- "agent_defaults": {
- "agent_control": {
- # "retry": {}
- },
- "agent_script_executor": {
- "bulk_size": 2,
- "bulk_throttle_time_in_ms": 300,
- "indexer_dir_depth": 100,
- "scheduler_cron_time": ["0 */12 * * *"],
- },
- "heartbeat": {
- "interval_in_seconds": 300,
- "miss_until_inactive": 1,
- },
+ "agent_defaults": {
+ "agent_control": {
+ # "retry": {}
},
- "agent_control_defaults": {
- "update_to_latest": True,
+ "agent_script_executor": {
+ "bulk_size": 2,
+ "bulk_throttle_time_in_ms": 300,
+ "indexer_dir_depth": 100,
+ "scheduler_cron_time": [
+ {"cron": "0 */12 * * *", "max_delay_seconds": 30}
+ ],
},
- }
+ "heartbeat": {
+ "interval_in_seconds": 300,
+ "miss_until_inactive": 1,
+ },
+ },
+ "agent_control_defaults": {
+ "update_to_latest": True,
+ },
}
with self.assertRaises(RequiredArgument):
self.gmp.modify_agent_control_scan_config(
@@ -305,30 +362,30 @@ def test_modify_agent_control_scan_config_missing_retry_attempts_raises(
self,
):
cfg = {
- "config_defaults": {
- "agent_defaults": {
- "agent_control": {
- "retry": {
- # "attempts": 6,
- "delay_in_seconds": 60,
- "max_jitter_in_seconds": 10,
- }
- },
- "agent_script_executor": {
- "bulk_size": 2,
- "bulk_throttle_time_in_ms": 300,
- "indexer_dir_depth": 100,
- "scheduler_cron_time": ["0 */12 * * *"],
- },
- "heartbeat": {
- "interval_in_seconds": 300,
- "miss_until_inactive": 1,
- },
+ "agent_defaults": {
+ "agent_control": {
+ "retry": {
+ # "attempts": 6,
+ "delay_in_seconds": 60,
+ "max_jitter_in_seconds": 10,
+ }
},
- "agent_control_defaults": {
- "update_to_latest": True,
+ "agent_script_executor": {
+ "bulk_size": 2,
+ "bulk_throttle_time_in_ms": 300,
+ "indexer_dir_depth": 100,
+ "scheduler_cron_time": [
+ {"cron": "0 */12 * * *", "max_delay_seconds": 30}
+ ],
+ },
+ "heartbeat": {
+ "interval_in_seconds": 300,
+ "miss_until_inactive": 1,
},
- }
+ },
+ "agent_control_defaults": {
+ "update_to_latest": True,
+ },
}
with self.assertRaises(RequiredArgument):
self.gmp.modify_agent_control_scan_config(
@@ -337,30 +394,30 @@ def test_modify_agent_control_scan_config_missing_retry_attempts_raises(
def test_modify_agent_control_scan_config_missing_retry_delay_raises(self):
cfg = {
- "config_defaults": {
- "agent_defaults": {
- "agent_control": {
- "retry": {
- "attempts": 6,
- # "delay_in_seconds": 60,
- "max_jitter_in_seconds": 10,
- }
- },
- "agent_script_executor": {
- "bulk_size": 2,
- "bulk_throttle_time_in_ms": 300,
- "indexer_dir_depth": 100,
- "scheduler_cron_time": ["0 */12 * * *"],
- },
- "heartbeat": {
- "interval_in_seconds": 300,
- "miss_until_inactive": 1,
- },
+ "agent_defaults": {
+ "agent_control": {
+ "retry": {
+ "attempts": 6,
+ # "delay_in_seconds": 60,
+ "max_jitter_in_seconds": 10,
+ }
},
- "agent_control_defaults": {
- "update_to_latest": True,
+ "agent_script_executor": {
+ "bulk_size": 2,
+ "bulk_throttle_time_in_ms": 300,
+ "indexer_dir_depth": 100,
+ "scheduler_cron_time": [
+ {"cron": "0 */12 * * *", "max_delay_seconds": 30}
+ ],
},
- }
+ "heartbeat": {
+ "interval_in_seconds": 300,
+ "miss_until_inactive": 1,
+ },
+ },
+ "agent_control_defaults": {
+ "update_to_latest": True,
+ },
}
with self.assertRaises(RequiredArgument):
self.gmp.modify_agent_control_scan_config(
@@ -371,30 +428,30 @@ def test_modify_agent_control_scan_config_missing_retry_max_jitter_raises(
self,
):
cfg = {
- "config_defaults": {
- "agent_defaults": {
- "agent_control": {
- "retry": {
- "attempts": 6,
- "delay_in_seconds": 60,
- # "max_jitter_in_seconds": 10,
- }
- },
- "agent_script_executor": {
- "bulk_size": 2,
- "bulk_throttle_time_in_ms": 300,
- "indexer_dir_depth": 100,
- "scheduler_cron_time": ["0 */12 * * *"],
- },
- "heartbeat": {
- "interval_in_seconds": 300,
- "miss_until_inactive": 1,
- },
+ "agent_defaults": {
+ "agent_control": {
+ "retry": {
+ "attempts": 6,
+ "delay_in_seconds": 60,
+ # "max_jitter_in_seconds": 10,
+ }
+ },
+ "agent_script_executor": {
+ "bulk_size": 2,
+ "bulk_throttle_time_in_ms": 300,
+ "indexer_dir_depth": 100,
+ "scheduler_cron_time": [
+ {"cron": "0 */12 * * *", "max_delay_seconds": 30}
+ ],
},
- "agent_control_defaults": {
- "update_to_latest": True,
+ "heartbeat": {
+ "interval_in_seconds": 300,
+ "miss_until_inactive": 1,
},
- }
+ },
+ "agent_control_defaults": {
+ "update_to_latest": True,
+ },
}
with self.assertRaises(RequiredArgument):
self.gmp.modify_agent_control_scan_config(
@@ -405,25 +462,23 @@ def test_modify_agent_control_scan_config_missing_agent_script_executor_raises(
self,
):
cfg = {
- "config_defaults": {
- "agent_defaults": {
- "agent_control": {
- "retry": {
- "attempts": 6,
- "delay_in_seconds": 60,
- "max_jitter_in_seconds": 10,
- }
- },
- # "agent_script_executor": missing,
- "heartbeat": {
- "interval_in_seconds": 300,
- "miss_until_inactive": 1,
- },
+ "agent_defaults": {
+ "agent_control": {
+ "retry": {
+ "attempts": 6,
+ "delay_in_seconds": 60,
+ "max_jitter_in_seconds": 10,
+ }
},
- "agent_control_defaults": {
- "update_to_latest": True,
+ # "agent_script_executor": missing,
+ "heartbeat": {
+ "interval_in_seconds": 300,
+ "miss_until_inactive": 1,
},
- }
+ },
+ "agent_control_defaults": {
+ "update_to_latest": True,
+ },
}
with self.assertRaises(RequiredArgument):
self.gmp.modify_agent_control_scan_config(
@@ -432,30 +487,30 @@ def test_modify_agent_control_scan_config_missing_agent_script_executor_raises(
def test_modify_agent_control_scan_config_missing_bulk_size_raises(self):
cfg = {
- "config_defaults": {
- "agent_defaults": {
- "agent_control": {
- "retry": {
- "attempts": 6,
- "delay_in_seconds": 60,
- "max_jitter_in_seconds": 10,
- }
- },
- "agent_script_executor": {
- # "bulk_size": 2,
- "bulk_throttle_time_in_ms": 300,
- "indexer_dir_depth": 100,
- "scheduler_cron_time": ["0 */12 * * *"],
- },
- "heartbeat": {
- "interval_in_seconds": 300,
- "miss_until_inactive": 1,
- },
+ "agent_defaults": {
+ "agent_control": {
+ "retry": {
+ "attempts": 6,
+ "delay_in_seconds": 60,
+ "max_jitter_in_seconds": 10,
+ }
},
- "agent_control_defaults": {
- "update_to_latest": True,
+ "agent_script_executor": {
+ # "bulk_size": 2,
+ "bulk_throttle_time_in_ms": 300,
+ "indexer_dir_depth": 100,
+ "scheduler_cron_time": [
+ {"cron": "0 */12 * * *", "max_delay_seconds": 30}
+ ],
},
- }
+ "heartbeat": {
+ "interval_in_seconds": 300,
+ "miss_until_inactive": 1,
+ },
+ },
+ "agent_control_defaults": {
+ "update_to_latest": True,
+ },
}
with self.assertRaises(RequiredArgument):
self.gmp.modify_agent_control_scan_config(
@@ -466,30 +521,30 @@ def test_modify_agent_control_scan_config_missing_bulk_throttle_time_in_ms_raise
self,
):
cfg = {
- "config_defaults": {
- "agent_defaults": {
- "agent_control": {
- "retry": {
- "attempts": 6,
- "delay_in_seconds": 60,
- "max_jitter_in_seconds": 10,
- }
- },
- "agent_script_executor": {
- "bulk_size": 2,
- # "bulk_throttle_time_in_ms": 300,
- "indexer_dir_depth": 100,
- "scheduler_cron_time": ["0 */12 * * *"],
- },
- "heartbeat": {
- "interval_in_seconds": 300,
- "miss_until_inactive": 1,
- },
+ "agent_defaults": {
+ "agent_control": {
+ "retry": {
+ "attempts": 6,
+ "delay_in_seconds": 60,
+ "max_jitter_in_seconds": 10,
+ }
},
- "agent_control_defaults": {
- "update_to_latest": True,
+ "agent_script_executor": {
+ "bulk_size": 2,
+ # "bulk_throttle_time_in_ms": 300,
+ "indexer_dir_depth": 100,
+ "scheduler_cron_time": [
+ {"cron": "0 */12 * * *", "max_delay_seconds": 30}
+ ],
},
- }
+ "heartbeat": {
+ "interval_in_seconds": 300,
+ "miss_until_inactive": 1,
+ },
+ },
+ "agent_control_defaults": {
+ "update_to_latest": True,
+ },
}
with self.assertRaises(RequiredArgument):
self.gmp.modify_agent_control_scan_config(
@@ -500,30 +555,30 @@ def test_modify_agent_control_scan_config_missing_indexer_dir_depth_raises(
self,
):
cfg = {
- "config_defaults": {
- "agent_defaults": {
- "agent_control": {
- "retry": {
- "attempts": 6,
- "delay_in_seconds": 60,
- "max_jitter_in_seconds": 10,
- }
- },
- "agent_script_executor": {
- "bulk_size": 2,
- "bulk_throttle_time_in_ms": 300,
- # "indexer_dir_depth": 100,
- "scheduler_cron_time": ["0 */12 * * *"],
- },
- "heartbeat": {
- "interval_in_seconds": 300,
- "miss_until_inactive": 1,
- },
+ "agent_defaults": {
+ "agent_control": {
+ "retry": {
+ "attempts": 6,
+ "delay_in_seconds": 60,
+ "max_jitter_in_seconds": 10,
+ }
},
- "agent_control_defaults": {
- "update_to_latest": True,
+ "agent_script_executor": {
+ "bulk_size": 2,
+ "bulk_throttle_time_in_ms": 300,
+ # "indexer_dir_depth": 100,
+ "scheduler_cron_time": [
+ {"cron": "0 */12 * * *", "max_delay_seconds": 30}
+ ],
+ },
+ "heartbeat": {
+ "interval_in_seconds": 300,
+ "miss_until_inactive": 1,
},
- }
+ },
+ "agent_control_defaults": {
+ "update_to_latest": True,
+ },
}
with self.assertRaises(RequiredArgument):
self.gmp.modify_agent_control_scan_config(
@@ -534,27 +589,27 @@ def test_modify_agent_control_scan_config_missing_heartbeat_block_raises(
self,
):
cfg = {
- "config_defaults": {
- "agent_defaults": {
- "agent_control": {
- "retry": {
- "attempts": 6,
- "delay_in_seconds": 60,
- "max_jitter_in_seconds": 10,
- }
- },
- "agent_script_executor": {
- "bulk_size": 2,
- "bulk_throttle_time_in_ms": 300,
- "indexer_dir_depth": 100,
- "scheduler_cron_time": ["0 */12 * * *"],
- },
- # "heartbeat": missing,
+ "agent_defaults": {
+ "agent_control": {
+ "retry": {
+ "attempts": 6,
+ "delay_in_seconds": 60,
+ "max_jitter_in_seconds": 10,
+ }
},
- "agent_control_defaults": {
- "update_to_latest": True,
+ "agent_script_executor": {
+ "bulk_size": 2,
+ "bulk_throttle_time_in_ms": 300,
+ "indexer_dir_depth": 100,
+ "scheduler_cron_time": [
+ {"cron": "0 */12 * * *", "max_delay_seconds": 30}
+ ],
},
- }
+ # "heartbeat": missing,
+ },
+ "agent_control_defaults": {
+ "update_to_latest": True,
+ },
}
with self.assertRaises(RequiredArgument):
self.gmp.modify_agent_control_scan_config(
@@ -565,30 +620,30 @@ def test_modify_agent_control_scan_config_missing_heartbeat_interval_raises(
self,
):
cfg = {
- "config_defaults": {
- "agent_defaults": {
- "agent_control": {
- "retry": {
- "attempts": 6,
- "delay_in_seconds": 60,
- "max_jitter_in_seconds": 10,
- }
- },
- "agent_script_executor": {
- "bulk_size": 2,
- "bulk_throttle_time_in_ms": 300,
- "indexer_dir_depth": 100,
- "scheduler_cron_time": ["0 */12 * * *"],
- },
- "heartbeat": {
- # "interval_in_seconds": 300,
- "miss_until_inactive": 1,
- },
+ "agent_defaults": {
+ "agent_control": {
+ "retry": {
+ "attempts": 6,
+ "delay_in_seconds": 60,
+ "max_jitter_in_seconds": 10,
+ }
},
- "agent_control_defaults": {
- "update_to_latest": True,
+ "agent_script_executor": {
+ "bulk_size": 2,
+ "bulk_throttle_time_in_ms": 300,
+ "indexer_dir_depth": 100,
+ "scheduler_cron_time": [
+ {"cron": "0 */12 * * *", "max_delay_seconds": 30}
+ ],
+ },
+ "heartbeat": {
+ # "interval_in_seconds": 300,
+ "miss_until_inactive": 1,
},
- }
+ },
+ "agent_control_defaults": {
+ "update_to_latest": True,
+ },
}
with self.assertRaises(RequiredArgument):
self.gmp.modify_agent_control_scan_config(
@@ -599,30 +654,30 @@ def test_modify_agent_control_scan_config_missing_heartbeat_miss_until_inactive_
self,
):
cfg = {
- "config_defaults": {
- "agent_defaults": {
- "agent_control": {
- "retry": {
- "attempts": 6,
- "delay_in_seconds": 60,
- "max_jitter_in_seconds": 10,
- }
- },
- "agent_script_executor": {
- "bulk_size": 2,
- "bulk_throttle_time_in_ms": 300,
- "indexer_dir_depth": 100,
- "scheduler_cron_time": ["0 */12 * * *"],
- },
- "heartbeat": {
- "interval_in_seconds": 300,
- # "miss_until_inactive": 1,
- },
+ "agent_defaults": {
+ "agent_control": {
+ "retry": {
+ "attempts": 6,
+ "delay_in_seconds": 60,
+ "max_jitter_in_seconds": 10,
+ }
},
- "agent_control_defaults": {
- "update_to_latest": True,
+ "agent_script_executor": {
+ "bulk_size": 2,
+ "bulk_throttle_time_in_ms": 300,
+ "indexer_dir_depth": 100,
+ "scheduler_cron_time": [
+ {"cron": "0 */12 * * *", "max_delay_seconds": 30}
+ ],
},
- }
+ "heartbeat": {
+ "interval_in_seconds": 300,
+ # "miss_until_inactive": 1,
+ },
+ },
+ "agent_control_defaults": {
+ "update_to_latest": True,
+ },
}
with self.assertRaises(RequiredArgument):
self.gmp.modify_agent_control_scan_config(
@@ -633,28 +688,28 @@ def test_modify_agent_control_scan_config_agent_control_defaults_raises(
self,
):
cfg = {
- "config_defaults": {
- "agent_defaults": {
- "agent_control": {
- "retry": {
- "attempts": 6,
- "delay_in_seconds": 60,
- "max_jitter_in_seconds": 10,
- }
- },
- "agent_script_executor": {
- "bulk_size": 2,
- "bulk_throttle_time_in_ms": 300,
- "indexer_dir_depth": 100,
- "scheduler_cron_time": ["0 */12 * * *"],
- },
- "heartbeat": {
- "interval_in_seconds": 300,
- "miss_until_inactive": 1,
- },
+ "agent_defaults": {
+ "agent_control": {
+ "retry": {
+ "attempts": 6,
+ "delay_in_seconds": 60,
+ "max_jitter_in_seconds": 10,
+ }
+ },
+ "agent_script_executor": {
+ "bulk_size": 2,
+ "bulk_throttle_time_in_ms": 300,
+ "indexer_dir_depth": 100,
+ "scheduler_cron_time": [
+ {"cron": "0 */12 * * *", "max_delay_seconds": 30}
+ ],
+ },
+ "heartbeat": {
+ "interval_in_seconds": 300,
+ "miss_until_inactive": 1,
},
- # "agent_control_defaults": missing,
- }
+ },
+ # "agent_control_defaults": missing,
}
with self.assertRaises(RequiredArgument):
self.gmp.modify_agent_control_scan_config(
@@ -665,32 +720,32 @@ def test_modify_agent_control_scan_config_missing_update_to_latest_raises(
self,
):
cfg = {
- "config_defaults": {
- "agent_defaults": {
- "agent_control": {
- "retry": {
- "attempts": 6,
- "delay_in_seconds": 60,
- "max_jitter_in_seconds": 10,
- }
- },
- "agent_script_executor": {
- "bulk_size": 2,
- "bulk_throttle_time_in_ms": 300,
- "indexer_dir_depth": 100,
- "scheduler_cron_time": ["0 */12 * * *"],
- },
- "heartbeat": {
- "interval_in_seconds": 300,
- "miss_until_inactive": 1,
- },
+ "agent_defaults": {
+ "agent_control": {
+ "retry": {
+ "attempts": 6,
+ "delay_in_seconds": 60,
+ "max_jitter_in_seconds": 10,
+ }
},
- "agent_control_defaults": {
- # "update_to_latest": True,
+ "agent_script_executor": {
+ "bulk_size": 2,
+ "bulk_throttle_time_in_ms": 300,
+ "indexer_dir_depth": 100,
+ "scheduler_cron_time": [
+ {"cron": "0 */12 * * *", "max_delay_seconds": 30}
+ ],
+ },
+ "heartbeat": {
+ "interval_in_seconds": 300,
+ "miss_until_inactive": 1,
},
- }
+ },
+ "agent_control_defaults": {
+ # "update_to_latest": True,
+ },
}
- with self.assertRaises(RequiredArgument):
+ with self.assertRaises(InvalidArgumentType):
self.gmp.modify_agent_control_scan_config(
"fb6451bf-ec5a-45a8-8bab-5cf4b862e51b", config=cfg
)
@@ -712,8 +767,8 @@ def test_modify_agent_control_scan_config_wrong_update_to_latest_raises(
"bulk_throttle_time_in_ms": 100,
"indexer_dir_depth": 10,
"scheduler_cron_time": [
- "0 23 * * *",
- "0 22 * * *",
+ {"cron": "0 23 * * *", "max_delay_seconds": 30},
+ {"cron": "0 22 * * *", "max_delay_seconds": 60},
],
},
"heartbeat": {
diff --git a/tests/protocols/gmpnext/entities/agents/test_modify_agents.py b/tests/protocols/gmpnext/entities/agents/test_modify_agents.py
index d2db4d00..544282ba 100644
--- a/tests/protocols/gmpnext/entities/agents/test_modify_agents.py
+++ b/tests/protocols/gmpnext/entities/agents/test_modify_agents.py
@@ -2,7 +2,7 @@
#
# SPDX-License-Identifier: GPL-3.0-or-later
-from gvm.errors import RequiredArgument
+from gvm.errors import InvalidArgumentType, RequiredArgument
class GmpModifyAgentsTestMixin:
@@ -52,7 +52,9 @@ def test_modify_agents_with_full_config_and_comment(self):
"bulk_size": 2,
"bulk_throttle_time_in_ms": 300,
"indexer_dir_depth": 100,
- "scheduler_cron_time": ["0 */12 * * *"],
+ "scheduler_cron_time": [
+ {"cron": "0 */12 * * *", "max_delay_seconds": 30}
+ ],
},
"heartbeat": {"interval_in_seconds": 300, "miss_until_inactive": 1},
}
@@ -83,7 +85,10 @@ def test_modify_agents_with_full_config_and_comment(self):
b"300"
b"100"
b''
- b"- 0 */12 * * *
"
+ b"- "
+ b"0 */12 * * *"
+ b"30"
+ b"
"
b""
b""
b""
@@ -108,7 +113,9 @@ def test_modify_agents_omits_optional_elements_when_none(self):
"bulk_size": 2,
"bulk_throttle_time_in_ms": 300,
"indexer_dir_depth": 100,
- "scheduler_cron_time": ["0 */12 * * *"],
+ "scheduler_cron_time": [
+ {"cron": "0 */12 * * *", "max_delay_seconds": 30}
+ ],
},
"heartbeat": {
"interval_in_seconds": 300,
@@ -140,7 +147,10 @@ def test_modify_agents_omits_optional_elements_when_none(self):
b"300"
b"100"
b''
- b"- 0 */12 * * *
"
+ b"- "
+ b"0 */12 * * *"
+ b"30"
+ b"
"
b""
b""
b""
@@ -214,7 +224,10 @@ def test_modify_agents_scheduler_with_empty_item_raises(self):
"bulk_size": 2,
"bulk_throttle_time_in_ms": 300,
"indexer_dir_depth": 100,
- "scheduler_cron_time": ["", " "],
+ "scheduler_cron_time": [
+ {"cron": "", "max_delay_seconds": 30},
+ {"cron": " ", "max_delay_seconds": 30},
+ ],
},
"heartbeat": {"interval_in_seconds": 300, "miss_until_inactive": 1},
}
@@ -228,7 +241,9 @@ def test_modify_agents_missing_agent_control_raises(self):
"bulk_size": 2,
"bulk_throttle_time_in_ms": 300,
"indexer_dir_depth": 100,
- "scheduler_cron_time": ["0 */12 * * *"],
+ "scheduler_cron_time": [
+ {"cron": "0 */12 * * *", "max_delay_seconds": 30}
+ ],
},
"heartbeat": {"interval_in_seconds": 300, "miss_until_inactive": 1},
}
@@ -244,7 +259,9 @@ def test_modify_agents_missing_retry_block_raises(self):
"bulk_size": 2,
"bulk_throttle_time_in_ms": 300,
"indexer_dir_depth": 100,
- "scheduler_cron_time": ["0 */12 * * *"],
+ "scheduler_cron_time": [
+ {"cron": "0 */12 * * *", "max_delay_seconds": 30}
+ ],
},
"heartbeat": {"interval_in_seconds": 300, "miss_until_inactive": 1},
}
@@ -264,7 +281,9 @@ def test_modify_agents_missing_retry_attempts_raises(self):
"bulk_size": 2,
"bulk_throttle_time_in_ms": 300,
"indexer_dir_depth": 100,
- "scheduler_cron_time": ["0 */12 * * *"],
+ "scheduler_cron_time": [
+ {"cron": "0 */12 * * *", "max_delay_seconds": 30}
+ ],
},
"heartbeat": {"interval_in_seconds": 300, "miss_until_inactive": 1},
}
@@ -284,7 +303,9 @@ def test_modify_agents_missing_retry_delay_raises(self):
"bulk_size": 2,
"bulk_throttle_time_in_ms": 300,
"indexer_dir_depth": 100,
- "scheduler_cron_time": ["0 */12 * * *"],
+ "scheduler_cron_time": [
+ {"cron": "0 */12 * * *", "max_delay_seconds": 30}
+ ],
},
"heartbeat": {"interval_in_seconds": 300, "miss_until_inactive": 1},
}
@@ -304,7 +325,9 @@ def test_modify_agents_missing_retry_max_jitter_raises(self):
"bulk_size": 2,
"bulk_throttle_time_in_ms": 300,
"indexer_dir_depth": 100,
- "scheduler_cron_time": ["0 */12 * * *"],
+ "scheduler_cron_time": [
+ {"cron": "0 */12 * * *", "max_delay_seconds": 30}
+ ],
},
"heartbeat": {"interval_in_seconds": 300, "miss_until_inactive": 1},
}
@@ -339,7 +362,9 @@ def test_modify_agents_missing_bulk_size_raises(self):
# "bulk_size": 2,
"bulk_throttle_time_in_ms": 300,
"indexer_dir_depth": 100,
- "scheduler_cron_time": ["0 */12 * * *"],
+ "scheduler_cron_time": [
+ {"cron": "0 */12 * * *", "max_delay_seconds": 30}
+ ],
},
"heartbeat": {"interval_in_seconds": 300, "miss_until_inactive": 1},
}
@@ -359,7 +384,9 @@ def test_modify_agents_missing_bulk_throttle_time_in_ms_raises(self):
"bulk_size": 2,
# "bulk_throttle_time_in_ms": 300,
"indexer_dir_depth": 100,
- "scheduler_cron_time": ["0 */12 * * *"],
+ "scheduler_cron_time": [
+ {"cron": "0 */12 * * *", "max_delay_seconds": 30}
+ ],
},
"heartbeat": {"interval_in_seconds": 300, "miss_until_inactive": 1},
}
@@ -379,7 +406,9 @@ def test_modify_agents_missing_indexer_dir_depth_raises(self):
"bulk_size": 2,
"bulk_throttle_time_in_ms": 300,
# "indexer_dir_depth": 100,
- "scheduler_cron_time": ["0 */12 * * *"],
+ "scheduler_cron_time": [
+ {"cron": "0 */12 * * *", "max_delay_seconds": 30}
+ ],
},
"heartbeat": {"interval_in_seconds": 300, "miss_until_inactive": 1},
}
@@ -399,7 +428,9 @@ def test_modify_agents_missing_heartbeat_block_raises(self):
"bulk_size": 2,
"bulk_throttle_time_in_ms": 300,
"indexer_dir_depth": 100,
- "scheduler_cron_time": ["0 */12 * * *"],
+ "scheduler_cron_time": [
+ {"cron": "0 */12 * * *", "max_delay_seconds": 30}
+ ],
},
# "heartbeat": missing
}
@@ -419,7 +450,9 @@ def test_modify_agents_missing_heartbeat_interval_raises(self):
"bulk_size": 2,
"bulk_throttle_time_in_ms": 300,
"indexer_dir_depth": 100,
- "scheduler_cron_time": ["0 */12 * * *"],
+ "scheduler_cron_time": [
+ {"cron": "0 */12 * * *", "max_delay_seconds": 30}
+ ],
},
"heartbeat": {
# "interval_in_seconds": 300,
@@ -442,7 +475,9 @@ def test_modify_agents_missing_heartbeat_miss_until_inactive_raises(self):
"bulk_size": 2,
"bulk_throttle_time_in_ms": 300,
"indexer_dir_depth": 100,
- "scheduler_cron_time": ["0 */12 * * *"],
+ "scheduler_cron_time": [
+ {"cron": "0 */12 * * *", "max_delay_seconds": 30}
+ ],
},
"heartbeat": {
"interval_in_seconds": 300,
@@ -465,9 +500,132 @@ def test_modify_agents_agent_control_not_mapping_raises(self):
"bulk_size": 2,
"bulk_throttle_time_in_ms": 300,
"indexer_dir_depth": 100,
- "scheduler_cron_time": ["0 */12 * * *"],
+ "scheduler_cron_time": [
+ {"cron": "0 */12 * * *", "max_delay_seconds": 30}
+ ],
},
"heartbeat": {"interval_in_seconds": 300, "miss_until_inactive": 1},
}
with self.assertRaises(RequiredArgument):
self.gmp.modify_agents(agent_ids=["agent-123"], config=cfg)
+
+ def test_modify_agents_scheduler_zero_max_delay(self):
+ cfg = {
+ "agent_control": {
+ "retry": {
+ "attempts": 6,
+ "delay_in_seconds": 60,
+ "max_jitter_in_seconds": 10,
+ }
+ },
+ "agent_script_executor": {
+ "bulk_size": 2,
+ "bulk_throttle_time_in_ms": 300,
+ "indexer_dir_depth": 100,
+ "scheduler_cron_time": [
+ {"cron": "0 */12 * * *", "max_delay_seconds": 0}
+ ],
+ },
+ "heartbeat": {"interval_in_seconds": 300, "miss_until_inactive": 1},
+ }
+
+ self.gmp.modify_agents(agent_ids=["agent-123"], config=cfg)
+
+ self.connection.send.has_been_called_with(
+ b""
+ b''
+ b""
+ b""
+ b""
+ b"6"
+ b"60"
+ b"10"
+ b""
+ b""
+ b""
+ b"2"
+ b"300"
+ b"100"
+ b''
+ b"- 0 */12 * * *"
+ b"0
"
+ b""
+ b""
+ b""
+ b"300"
+ b"1"
+ b""
+ b""
+ b""
+ )
+
+ def test_modify_agents_scheduler_missing_max_delay_raises(self):
+ cfg = {
+ "agent_control": {
+ "retry": {
+ "attempts": 6,
+ "delay_in_seconds": 60,
+ "max_jitter_in_seconds": 10,
+ }
+ },
+ "agent_script_executor": {
+ "bulk_size": 2,
+ "bulk_throttle_time_in_ms": 300,
+ "indexer_dir_depth": 100,
+ "scheduler_cron_time": [{"cron": "0 */12 * * *"}],
+ },
+ "heartbeat": {"interval_in_seconds": 300, "miss_until_inactive": 1},
+ }
+
+ with self.assertRaises(InvalidArgumentType):
+ self.gmp.modify_agents(agent_ids=["agent-123"], config=cfg)
+
+ def test_modify_agents_scheduler_negative_max_delay_raises(self):
+ cfg = {
+ "agent_control": {
+ "retry": {
+ "attempts": 6,
+ "delay_in_seconds": 60,
+ "max_jitter_in_seconds": 10,
+ }
+ },
+ "agent_script_executor": {
+ "bulk_size": 2,
+ "bulk_throttle_time_in_ms": 300,
+ "indexer_dir_depth": 100,
+ "scheduler_cron_time": [
+ {"cron": "0 */12 * * *", "max_delay_seconds": -1}
+ ],
+ },
+ "heartbeat": {"interval_in_seconds": 300, "miss_until_inactive": 1},
+ }
+
+ with self.assertRaises(InvalidArgumentType):
+ self.gmp.modify_agents(agent_ids=["agent-123"], config=cfg)
+
+ def test_modify_agents_scheduler_item_not_mapping_raises(self):
+ cfg = {
+ "agent_control": {
+ "retry": {
+ "attempts": 6,
+ "delay_in_seconds": 60,
+ "max_jitter_in_seconds": 10,
+ }
+ },
+ "agent_script_executor": {
+ "bulk_size": 2,
+ "bulk_throttle_time_in_ms": 300,
+ "indexer_dir_depth": 100,
+ "scheduler_cron_time": [
+ {"cron": "0 23 * * *", "max_delay_seconds": 30},
+ "0 22 * * *",
+ ],
+ },
+ "heartbeat": {
+ "interval_in_seconds": 300,
+ "miss_until_inactive": 1,
+ },
+ }
+
+ with self.assertRaises(InvalidArgumentType):
+ self.gmp.modify_agents(agent_ids=["agent-123"], config=cfg)