mirror of https://github.com/zulip/zulip.git
zilencer: Make BaseRemoteCount.remote_id field nullable.
This commit is contained in:
parent
c4fbb6319b
commit
2ecd7abc0d
|
@ -74,6 +74,8 @@ from zerver.models import (
|
||||||
get_user,
|
get_user,
|
||||||
is_cross_realm_bot_email,
|
is_cross_realm_bot_email,
|
||||||
)
|
)
|
||||||
|
from zilencer.models import RemoteInstallationCount, RemoteZulipServer
|
||||||
|
from zilencer.views import get_last_id_from_server
|
||||||
|
|
||||||
|
|
||||||
class AnalyticsTestCase(ZulipTestCase):
|
class AnalyticsTestCase(ZulipTestCase):
|
||||||
|
@ -1852,3 +1854,26 @@ class TestRealmActiveHumans(AnalyticsTestCase):
|
||||||
1,
|
1,
|
||||||
)
|
)
|
||||||
self.assertEqual(RealmCount.objects.filter(property="realm_active_humans::day").count(), 1)
|
self.assertEqual(RealmCount.objects.filter(property="realm_active_humans::day").count(), 1)
|
||||||
|
|
||||||
|
|
||||||
|
class GetLastIdFromServerTest(ZulipTestCase):
|
||||||
|
def test_get_last_id_from_server_ignores_null(self) -> None:
|
||||||
|
"""
|
||||||
|
Verifies that get_last_id_from_server ignores null remote_ids, since this goes
|
||||||
|
against the default Postgres ordering behavior, which treats nulls as the largest value.
|
||||||
|
"""
|
||||||
|
self.server_uuid = "6cde5f7a-1f7e-4978-9716-49f69ebfc9fe"
|
||||||
|
self.server = RemoteZulipServer.objects.create(
|
||||||
|
uuid=self.server_uuid,
|
||||||
|
api_key="magic_secret_api_key",
|
||||||
|
hostname="demo.example.com",
|
||||||
|
last_updated=timezone_now(),
|
||||||
|
)
|
||||||
|
first = RemoteInstallationCount.objects.create(
|
||||||
|
end_time=timezone_now(), server=self.server, property="test", value=1, remote_id=1
|
||||||
|
)
|
||||||
|
RemoteInstallationCount.objects.create(
|
||||||
|
end_time=timezone_now(), server=self.server, property="test2", value=1, remote_id=None
|
||||||
|
)
|
||||||
|
result = get_last_id_from_server(self.server, RemoteInstallationCount)
|
||||||
|
self.assertEqual(result, first.remote_id)
|
||||||
|
|
|
@ -0,0 +1,22 @@
|
||||||
|
# Generated by Django 4.2.6 on 2023-10-23 20:22
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
dependencies = [
|
||||||
|
("zilencer", "0030_alter_remoteinstallationcount_remote_id"),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name="remoteinstallationcount",
|
||||||
|
name="remote_id",
|
||||||
|
field=models.IntegerField(null=True),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name="remoterealmcount",
|
||||||
|
name="remote_id",
|
||||||
|
field=models.IntegerField(null=True),
|
||||||
|
),
|
||||||
|
]
|
|
@ -135,7 +135,7 @@ class BaseRemoteCount(BaseCount):
|
||||||
# The remote_id field is the id value of the corresponding *Count object
|
# The remote_id field is the id value of the corresponding *Count object
|
||||||
# on the remote server.
|
# on the remote server.
|
||||||
# It lets us deduplicate data from the remote server.
|
# It lets us deduplicate data from the remote server.
|
||||||
remote_id = models.IntegerField()
|
remote_id = models.IntegerField(null=True)
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
abstract = True
|
abstract = True
|
||||||
|
|
|
@ -444,6 +444,10 @@ def validate_incoming_table_data(
|
||||||
for row in rows:
|
for row in rows:
|
||||||
if is_count_stat and row["property"] not in COUNT_STATS:
|
if is_count_stat and row["property"] not in COUNT_STATS:
|
||||||
raise JsonableError(_("Invalid property {property}").format(property=row["property"]))
|
raise JsonableError(_("Invalid property {property}").format(property=row["property"]))
|
||||||
|
if row.get("id") is None:
|
||||||
|
# This shouldn't be possible, as submitting data like this should be
|
||||||
|
# prevented by our param validators.
|
||||||
|
raise AssertionError(f"Missing id field in row {row}")
|
||||||
if row["id"] <= last_id:
|
if row["id"] <= last_id:
|
||||||
raise JsonableError(_("Data is out of order."))
|
raise JsonableError(_("Data is out of order."))
|
||||||
last_id = row["id"]
|
last_id = row["id"]
|
||||||
|
@ -592,7 +596,15 @@ def remote_server_post_analytics(
|
||||||
|
|
||||||
|
|
||||||
def get_last_id_from_server(server: RemoteZulipServer, model: Any) -> int:
|
def get_last_id_from_server(server: RemoteZulipServer, model: Any) -> int:
|
||||||
last_count = model.objects.filter(server=server).order_by("remote_id").only("remote_id").last()
|
last_count = (
|
||||||
|
model.objects.filter(server=server)
|
||||||
|
# Rows with remote_id=None are managed by the bouncer service itself,
|
||||||
|
# and thus aren't meant for syncing and should be ignored here.
|
||||||
|
.exclude(remote_id=None)
|
||||||
|
.order_by("remote_id")
|
||||||
|
.only("remote_id")
|
||||||
|
.last()
|
||||||
|
)
|
||||||
if last_count is not None:
|
if last_count is not None:
|
||||||
return last_count.remote_id
|
return last_count.remote_id
|
||||||
return 0
|
return 0
|
||||||
|
|
Loading…
Reference in New Issue