mirror of
https://git.anonymousland.org/anonymousland/synapse.git
synced 2025-05-05 07:25:05 -04:00
Add an admin API to run background jobs. (#11352)
Instead of having admins poke into the database directly. Can currently run jobs to populate stats and to populate the user directory.
This commit is contained in:
parent
7ae559944a
commit
ea20937084
9 changed files with 280 additions and 43 deletions
|
@ -11,8 +11,13 @@
|
|||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
from http import HTTPStatus
|
||||
from typing import Collection
|
||||
|
||||
from parameterized import parameterized
|
||||
|
||||
import synapse.rest.admin
|
||||
from synapse.api.errors import Codes
|
||||
from synapse.rest.client import login
|
||||
from synapse.server import HomeServer
|
||||
|
||||
|
@ -30,6 +35,60 @@ class BackgroundUpdatesTestCase(unittest.HomeserverTestCase):
|
|||
self.admin_user = self.register_user("admin", "pass", admin=True)
|
||||
self.admin_user_tok = self.login("admin", "pass")
|
||||
|
||||
@parameterized.expand(
|
||||
[
|
||||
("GET", "/_synapse/admin/v1/background_updates/enabled"),
|
||||
("POST", "/_synapse/admin/v1/background_updates/enabled"),
|
||||
("GET", "/_synapse/admin/v1/background_updates/status"),
|
||||
("POST", "/_synapse/admin/v1/background_updates/start_job"),
|
||||
]
|
||||
)
|
||||
def test_requester_is_no_admin(self, method: str, url: str):
|
||||
"""
|
||||
If the user is not a server admin, an error 403 is returned.
|
||||
"""
|
||||
|
||||
self.register_user("user", "pass", admin=False)
|
||||
other_user_tok = self.login("user", "pass")
|
||||
|
||||
channel = self.make_request(
|
||||
method,
|
||||
url,
|
||||
content={},
|
||||
access_token=other_user_tok,
|
||||
)
|
||||
|
||||
self.assertEqual(HTTPStatus.FORBIDDEN, channel.code, msg=channel.json_body)
|
||||
self.assertEqual(Codes.FORBIDDEN, channel.json_body["errcode"])
|
||||
|
||||
def test_invalid_parameter(self):
|
||||
"""
|
||||
If parameters are invalid, an error is returned.
|
||||
"""
|
||||
url = "/_synapse/admin/v1/background_updates/start_job"
|
||||
|
||||
# empty content
|
||||
channel = self.make_request(
|
||||
"POST",
|
||||
url,
|
||||
content={},
|
||||
access_token=self.admin_user_tok,
|
||||
)
|
||||
|
||||
self.assertEqual(HTTPStatus.BAD_REQUEST, channel.code, msg=channel.json_body)
|
||||
self.assertEqual(Codes.MISSING_PARAM, channel.json_body["errcode"])
|
||||
|
||||
# job_name invalid
|
||||
channel = self.make_request(
|
||||
"POST",
|
||||
url,
|
||||
content={"job_name": "unknown"},
|
||||
access_token=self.admin_user_tok,
|
||||
)
|
||||
|
||||
self.assertEqual(HTTPStatus.BAD_REQUEST, channel.code, msg=channel.json_body)
|
||||
self.assertEqual(Codes.UNKNOWN, channel.json_body["errcode"])
|
||||
|
||||
def _register_bg_update(self):
|
||||
"Adds a bg update but doesn't start it"
|
||||
|
||||
|
@ -60,7 +119,7 @@ class BackgroundUpdatesTestCase(unittest.HomeserverTestCase):
|
|||
"/_synapse/admin/v1/background_updates/status",
|
||||
access_token=self.admin_user_tok,
|
||||
)
|
||||
self.assertEqual(200, int(channel.result["code"]), msg=channel.result["body"])
|
||||
self.assertEqual(HTTPStatus.OK, channel.code, msg=channel.json_body)
|
||||
|
||||
# Background updates should be enabled, but none should be running.
|
||||
self.assertDictEqual(
|
||||
|
@ -82,7 +141,7 @@ class BackgroundUpdatesTestCase(unittest.HomeserverTestCase):
|
|||
"/_synapse/admin/v1/background_updates/status",
|
||||
access_token=self.admin_user_tok,
|
||||
)
|
||||
self.assertEqual(200, int(channel.result["code"]), msg=channel.result["body"])
|
||||
self.assertEqual(HTTPStatus.OK, channel.code, msg=channel.json_body)
|
||||
|
||||
# Background updates should be enabled, and one should be running.
|
||||
self.assertDictEqual(
|
||||
|
@ -114,7 +173,7 @@ class BackgroundUpdatesTestCase(unittest.HomeserverTestCase):
|
|||
"/_synapse/admin/v1/background_updates/enabled",
|
||||
access_token=self.admin_user_tok,
|
||||
)
|
||||
self.assertEqual(200, int(channel.result["code"]), msg=channel.result["body"])
|
||||
self.assertEqual(HTTPStatus.OK, channel.code, msg=channel.json_body)
|
||||
self.assertDictEqual(channel.json_body, {"enabled": True})
|
||||
|
||||
# Disable the BG updates
|
||||
|
@ -124,7 +183,7 @@ class BackgroundUpdatesTestCase(unittest.HomeserverTestCase):
|
|||
content={"enabled": False},
|
||||
access_token=self.admin_user_tok,
|
||||
)
|
||||
self.assertEqual(200, int(channel.result["code"]), msg=channel.result["body"])
|
||||
self.assertEqual(HTTPStatus.OK, channel.code, msg=channel.json_body)
|
||||
self.assertDictEqual(channel.json_body, {"enabled": False})
|
||||
|
||||
# Advance a bit and get the current status, note this will finish the in
|
||||
|
@ -137,7 +196,7 @@ class BackgroundUpdatesTestCase(unittest.HomeserverTestCase):
|
|||
"/_synapse/admin/v1/background_updates/status",
|
||||
access_token=self.admin_user_tok,
|
||||
)
|
||||
self.assertEqual(200, int(channel.result["code"]), msg=channel.result["body"])
|
||||
self.assertEqual(HTTPStatus.OK, channel.code, msg=channel.json_body)
|
||||
self.assertDictEqual(
|
||||
channel.json_body,
|
||||
{
|
||||
|
@ -162,7 +221,7 @@ class BackgroundUpdatesTestCase(unittest.HomeserverTestCase):
|
|||
"/_synapse/admin/v1/background_updates/status",
|
||||
access_token=self.admin_user_tok,
|
||||
)
|
||||
self.assertEqual(200, int(channel.result["code"]), msg=channel.result["body"])
|
||||
self.assertEqual(HTTPStatus.OK, channel.code, msg=channel.json_body)
|
||||
|
||||
# There should be no change from the previous /status response.
|
||||
self.assertDictEqual(
|
||||
|
@ -188,7 +247,7 @@ class BackgroundUpdatesTestCase(unittest.HomeserverTestCase):
|
|||
content={"enabled": True},
|
||||
access_token=self.admin_user_tok,
|
||||
)
|
||||
self.assertEqual(200, int(channel.result["code"]), msg=channel.result["body"])
|
||||
self.assertEqual(HTTPStatus.OK, channel.code, msg=channel.json_body)
|
||||
|
||||
self.assertDictEqual(channel.json_body, {"enabled": True})
|
||||
|
||||
|
@ -199,7 +258,7 @@ class BackgroundUpdatesTestCase(unittest.HomeserverTestCase):
|
|||
"/_synapse/admin/v1/background_updates/status",
|
||||
access_token=self.admin_user_tok,
|
||||
)
|
||||
self.assertEqual(200, int(channel.result["code"]), msg=channel.result["body"])
|
||||
self.assertEqual(HTTPStatus.OK, channel.code, msg=channel.json_body)
|
||||
|
||||
# Background updates should be enabled and making progress.
|
||||
self.assertDictEqual(
|
||||
|
@ -216,3 +275,82 @@ class BackgroundUpdatesTestCase(unittest.HomeserverTestCase):
|
|||
"enabled": True,
|
||||
},
|
||||
)
|
||||
|
||||
@parameterized.expand(
|
||||
[
|
||||
("populate_stats_process_rooms", ["populate_stats_process_rooms"]),
|
||||
(
|
||||
"regenerate_directory",
|
||||
[
|
||||
"populate_user_directory_createtables",
|
||||
"populate_user_directory_process_rooms",
|
||||
"populate_user_directory_process_users",
|
||||
"populate_user_directory_cleanup",
|
||||
],
|
||||
),
|
||||
]
|
||||
)
|
||||
def test_start_backround_job(self, job_name: str, updates: Collection[str]):
|
||||
"""
|
||||
Test that background updates add to database and be processed.
|
||||
|
||||
Args:
|
||||
job_name: name of the job to call with API
|
||||
updates: collection of background updates to be started
|
||||
"""
|
||||
|
||||
# no background update is waiting
|
||||
self.assertTrue(
|
||||
self.get_success(
|
||||
self.store.db_pool.updates.has_completed_background_updates()
|
||||
)
|
||||
)
|
||||
|
||||
channel = self.make_request(
|
||||
"POST",
|
||||
"/_synapse/admin/v1/background_updates/start_job",
|
||||
content={"job_name": job_name},
|
||||
access_token=self.admin_user_tok,
|
||||
)
|
||||
|
||||
self.assertEqual(HTTPStatus.OK, channel.code, msg=channel.json_body)
|
||||
|
||||
# test that each background update is waiting now
|
||||
for update in updates:
|
||||
self.assertFalse(
|
||||
self.get_success(
|
||||
self.store.db_pool.updates.has_completed_background_update(update)
|
||||
)
|
||||
)
|
||||
|
||||
self.wait_for_background_updates()
|
||||
|
||||
# background updates are done
|
||||
self.assertTrue(
|
||||
self.get_success(
|
||||
self.store.db_pool.updates.has_completed_background_updates()
|
||||
)
|
||||
)
|
||||
|
||||
def test_start_backround_job_twice(self):
|
||||
"""Test that add a background update twice return an error."""
|
||||
|
||||
# add job to database
|
||||
self.get_success(
|
||||
self.store.db_pool.simple_insert(
|
||||
table="background_updates",
|
||||
values={
|
||||
"update_name": "populate_stats_process_rooms",
|
||||
"progress_json": "{}",
|
||||
},
|
||||
)
|
||||
)
|
||||
|
||||
channel = self.make_request(
|
||||
"POST",
|
||||
"/_synapse/admin/v1/background_updates/start_job",
|
||||
content={"job_name": "populate_stats_process_rooms"},
|
||||
access_token=self.admin_user_tok,
|
||||
)
|
||||
|
||||
self.assertEqual(HTTPStatus.BAD_REQUEST, channel.code, msg=channel.json_body)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue