diff --git a/gvm/protocols/gmp/_gmpnext.py b/gvm/protocols/gmp/_gmpnext.py
index 837689768..642a83045 100644
--- a/gvm/protocols/gmp/_gmpnext.py
+++ b/gvm/protocols/gmp/_gmpnext.py
@@ -228,6 +228,7 @@ def create_agent_group(
self,
name: str,
agent_ids: list[str],
+ scheduler_cron_time: str,
*,
comment: str | None = None,
) -> T:
@@ -236,6 +237,7 @@ def create_agent_group(
Args:
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.
comment: Optional comment for the group.
Raises:
@@ -246,12 +248,14 @@ def create_agent_group(
name=name,
comment=comment,
agent_ids=agent_ids,
+ scheduler_cron_time=scheduler_cron_time,
)
)
def modify_agent_group(
self,
agent_group_id: EntityID,
+ scheduler_cron_time: str,
*,
name: str | None = None,
comment: str | None = None,
@@ -262,6 +266,7 @@ def modify_agent_group(
Args:
agent_group_id: UUID of the group to modify.
name: Optional new name for the 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.
@@ -274,6 +279,7 @@ def modify_agent_group(
name=name,
comment=comment,
agent_ids=agent_ids,
+ scheduler_cron_time=scheduler_cron_time,
)
)
diff --git a/gvm/protocols/gmp/requests/next/_agent_groups.py b/gvm/protocols/gmp/requests/next/_agent_groups.py
index 1d93f6d99..c817364e6 100644
--- a/gvm/protocols/gmp/requests/next/_agent_groups.py
+++ b/gvm/protocols/gmp/requests/next/_agent_groups.py
@@ -16,6 +16,7 @@ def create_agent_group(
cls,
name: str,
agent_ids: list[str],
+ scheduler_cron_time: str,
*,
comment: str | None = None,
) -> Request:
@@ -24,6 +25,7 @@ def create_agent_group(
Args:
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).
comment: Optional comment for the group.
Raises:
@@ -38,9 +40,15 @@ def create_agent_group(
raise RequiredArgument(
function=cls.create_agent_group.__name__, argument="agent_ids"
)
+ if not scheduler_cron_time:
+ raise RequiredArgument(
+ function=cls.create_agent_group.__name__,
+ argument="scheduler_cron_time",
+ )
cmd = XmlCommand("create_agent_group")
cmd.add_element("name", name)
+ cmd.add_element("scheduler_cron_time", scheduler_cron_time)
if comment:
cmd.add_element("comment", comment)
@@ -76,6 +84,7 @@ def clone_agent_group(cls, agent_group_id: EntityID) -> Request:
def modify_agent_group(
cls,
agent_group_id: EntityID,
+ scheduler_cron_time: str,
*,
name: str | None = None,
comment: str | None = None,
@@ -85,6 +94,7 @@ def modify_agent_group(
Args:
agent_group_id: UUID of the group to modify.
+ scheduler_cron_time: Cron-like time to schedule the agent groups.
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.
@@ -98,9 +108,15 @@ def modify_agent_group(
argument="agent_group_id",
)
+ if not scheduler_cron_time:
+ raise RequiredArgument(
+ function=cls.modify_agent_group.__name__,
+ argument="scheduler_cron_time",
+ )
+
cmd = XmlCommand("modify_agent_group")
cmd.set_attribute("agent_group_id", str(agent_group_id))
-
+ cmd.add_element("scheduler_cron_time", scheduler_cron_time)
if name:
cmd.add_element("name", name)
diff --git a/tests/connections/test_debug_connection.py b/tests/connections/test_debug_connection.py
index efe051228..d3735a460 100644
--- a/tests/connections/test_debug_connection.py
+++ b/tests/connections/test_debug_connection.py
@@ -8,12 +8,12 @@
from gvm.connections._connection import AbstractGvmConnection
-class TestConnection(AbstractGvmConnection):
+class DummyConnection(AbstractGvmConnection):
def connect(self) -> None:
pass
class DebugConnectionTestCase(unittest.TestCase):
def test_is_gvm_connection(self):
- connection = DebugConnection(TestConnection())
+ connection = DebugConnection(DummyConnection())
self.assertTrue(isinstance(connection, GvmConnection))
diff --git a/tests/connections/test_gvm_connection.py b/tests/connections/test_gvm_connection.py
index 041a24f8d..b3aecfe9d 100644
--- a/tests/connections/test_gvm_connection.py
+++ b/tests/connections/test_gvm_connection.py
@@ -14,7 +14,7 @@
from gvm.errors import GvmError
-class TestConnection(AbstractGvmConnection):
+class DummyConnection(AbstractGvmConnection):
def connect(self) -> None:
pass
@@ -22,13 +22,13 @@ def connect(self) -> None:
class GvmConnectionTestCase(unittest.TestCase):
# pylint: disable=protected-access
def test_init_no_args(self):
- connection = TestConnection()
+ connection = DummyConnection()
self.assertIsNone(connection._socket)
self.assertEqual(connection._timeout, DEFAULT_TIMEOUT)
def test_init_with_none(self):
- connection = TestConnection(timeout=None)
+ connection = DummyConnection(timeout=None)
self.assertIsNone(connection._socket)
self.assertEqual(connection._timeout, DEFAULT_TIMEOUT)
@@ -37,7 +37,7 @@ def test_read_no_data(self):
read_mock = MagicMock()
read_mock.return_value = None
- connection = TestConnection()
+ connection = DummyConnection()
connection._read = read_mock
with self.assertRaises(GvmError, msg="Remote closed the connection"):
@@ -49,7 +49,7 @@ def test_read_trigger_timeout(self):
read_mock = MagicMock()
read_mock.side_effect = [b"xyz", b""]
- connection = TestConnection(timeout=0)
+ connection = DummyConnection(timeout=0)
connection._read = read_mock
with self.assertRaises(
@@ -58,5 +58,5 @@ def test_read_trigger_timeout(self):
connection.read()
def test_is_gvm_connection(self):
- connection = TestConnection()
+ connection = DummyConnection()
self.assertTrue(isinstance(connection, GvmConnection))
diff --git a/tests/connections/test_unix_socket_connection.py b/tests/connections/test_unix_socket_connection.py
index d64883a62..127c3ebd5 100644
--- a/tests/connections/test_unix_socket_connection.py
+++ b/tests/connections/test_unix_socket_connection.py
@@ -23,6 +23,15 @@
class DummyRequestHandler(socketserver.BaseRequestHandler):
def handle(self):
response = b''
+
+ self.request.settimeout(0.2)
+ try:
+ self.request.recv(16 * 1024)
+ except (TimeoutError, OSError):
+ # In tests, receiving request data is optional; on timeout/socket read
+ # issues we still return the canned response to keep behavior deterministic.
+ _ = None
+
self.request.sendall(response)
@@ -47,29 +56,33 @@ def setUp(self):
self.server_thread.start()
def tearDown(self):
- self.socket_server.server_close()
self.socket_server.shutdown()
self.server_thread.join(60.0)
+ self.socket_server.server_close()
self.socket_path.unlink(missing_ok=True)
def test_unix_socket_connection_connect_read(self):
connection = UnixSocketConnection(
path=self.socket_name, timeout=DEFAULT_TIMEOUT
)
+ self.addCleanup(connection.disconnect)
+
connection.connect()
resp = connection.read()
+
self.assertEqual(resp, b'')
- connection.disconnect()
def test_unix_socket_connection_connect_send_bytes_read(self):
connection = UnixSocketConnection(
path=self.socket_name, timeout=DEFAULT_TIMEOUT
)
+ self.addCleanup(connection.disconnect)
+
connection.connect()
connection.send(b"")
resp = connection.read()
+
self.assertEqual(resp, b'')
- connection.disconnect()
def test_unix_socket_connect_file_not_found(self):
connection = UnixSocketConnection(path="foo", timeout=DEFAULT_TIMEOUT)
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 a6b9d1f53..80bf2c747 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
@@ -11,11 +11,13 @@ def test_create_agent_group(self):
name="ExampleGroup",
agent_ids=["agent-1", "agent-2"],
comment="Sample comment",
+ scheduler_cron_time="0 */5 * * *",
)
self.connection.send.has_been_called_with(
b""
b"ExampleGroup"
+ b"0 */5 * * *"
b"Sample comment"
b''
b""
@@ -23,18 +25,35 @@ def test_create_agent_group(self):
def test_create_agent_group_without_name(self):
with self.assertRaises(RequiredArgument):
- self.gmp.create_agent_group(name="", agent_ids=["agent-1"])
+ self.gmp.create_agent_group(
+ name="",
+ agent_ids=["agent-1"],
+ scheduler_cron_time="0 */5 * * *",
+ )
def test_create_agent_group_without_agents(self):
with self.assertRaises(RequiredArgument):
- self.gmp.create_agent_group(name="Group", agent_ids=[])
+ self.gmp.create_agent_group(
+ name="Group", agent_ids=[], scheduler_cron_time="0 */5 * * *"
+ )
+
+ def test_create_agent_group_without_scheduler_cron_time(self):
+ with self.assertRaises(RequiredArgument):
+ self.gmp.create_agent_group(
+ name="Group", agent_ids=["agent-1"], scheduler_cron_time=None
+ )
def test_create_agent_group_without_comment(self):
- self.gmp.create_agent_group(name="GroupX", agent_ids=["a1", "a2"])
+ self.gmp.create_agent_group(
+ name="GroupX",
+ agent_ids=["a1", "a2"],
+ 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 83aa3dbd0..c7f809eaa 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
@@ -11,11 +11,13 @@ def test_modify_agent_group(self):
agent_group_id="group-1",
name="NewName",
comment="Updated comment",
+ scheduler_cron_time="0 */5 * * *",
agent_ids=["agent-1", "agent-2"],
)
self.connection.send.has_been_called_with(
b''
+ b"0 */5 * * *"
b"NewName"
b"Updated comment"
b''
@@ -24,17 +26,27 @@ def test_modify_agent_group(self):
def test_modify_agent_group_without_id(self):
with self.assertRaises(RequiredArgument):
- self.gmp.modify_agent_group(agent_group_id=None)
+ self.gmp.modify_agent_group(
+ agent_group_id=None, scheduler_cron_time="0 */5 * * *"
+ )
+
+ def test_modify_agent_group_without_scheduler_cron_time(self):
+ with self.assertRaises(RequiredArgument):
+ self.gmp.modify_agent_group(
+ agent_group_id="group-1", scheduler_cron_time=None
+ )
def test_modify_agent_group_without_name(self):
self.gmp.modify_agent_group(
agent_group_id="group-1",
comment="Updated comment",
+ scheduler_cron_time="0 */5 * * *",
agent_ids=["agent-1", "agent-2"],
)
self.connection.send.has_been_called_with(
b''
+ b"0 */5 * * *"
b"Updated comment"
b''
b""
@@ -44,11 +56,13 @@ def test_modify_agent_group_without_comment(self):
self.gmp.modify_agent_group(
agent_group_id="group-1",
name="NewName",
+ scheduler_cron_time="0 */5 * * *",
agent_ids=["agent-1", "agent-2"],
)
self.connection.send.has_been_called_with(
b''
+ b"0 */5 * * *"
b"NewName"
b''
b""
@@ -59,10 +73,12 @@ def test_modify_agent_group_without_agent_ids(self):
agent_group_id="group-1",
name="NewName",
comment="Updated comment",
+ scheduler_cron_time="0 */5 * * *",
)
self.connection.send.has_been_called_with(
b''
+ b"0 */5 * * *"
b"NewName"
b"Updated comment"
b""