Skip to content

Commit

Permalink
refactor: idnits2 mgmt cmds -> tasks (#7421)
Browse files Browse the repository at this point in the history
* feat: tasks for generate_idnits2_rfc* mgmt cmds

* chore: create periodic tasks

* chore: remove mgmt cmds from bin/hourly

* test: test new tasks

* chore: remove now-unused scripts

* refactor: unitize Idnits2SupportTests
  • Loading branch information
jennifer-richards committed May 14, 2024
1 parent c0a12fa commit 235ac8b
Show file tree
Hide file tree
Showing 7 changed files with 101 additions and 62 deletions.
3 changes: 0 additions & 3 deletions bin/hourly
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,6 @@ ID=/a/ietfdata/doc/draft/repository
DERIVED=/a/ietfdata/derived
DOWNLOAD=/a/www/www6s/download

$DTDIR/ietf/manage.py generate_idnits2_rfc_status
$DTDIR/ietf/manage.py generate_idnits2_rfcs_obsoleted

CHARTER=/a/www/ietf-ftp/charter
wget -q https://datatracker.ietf.org/wg/1wg-charters-by-acronym.txt -O $CHARTER/1wg-charters-by-acronym.txt
wget -q https://datatracker.ietf.org/wg/1wg-charters.txt -O $CHARTER/1wg-charters.txt
Expand Down
23 changes: 0 additions & 23 deletions ietf/doc/management/commands/generate_idnits2_rfc_status.py

This file was deleted.

23 changes: 0 additions & 23 deletions ietf/doc/management/commands/generate_idnits2_rfcs_obsoleted.py

This file was deleted.

24 changes: 24 additions & 0 deletions ietf/doc/tasks.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@
import debug # pyflakes:ignore

from celery import shared_task
from pathlib import Path

from django.conf import settings

from ietf.utils import log
from ietf.utils.timezone import datetime_today
Expand All @@ -21,6 +24,7 @@
send_expire_warning_for_draft,
)
from .models import Document
from .utils import generate_idnits2_rfc_status, generate_idnits2_rfcs_obsoleted


@shared_task
Expand Down Expand Up @@ -54,3 +58,23 @@ def expire_ids_task():
def notify_expirations_task(notify_days=14):
for doc in get_soon_to_expire_drafts(notify_days):
send_expire_warning_for_draft(doc)


@shared_task
def generate_idnits2_rfc_status_task():
outpath = Path(settings.DERIVED_DIR) / "idnits2-rfc-status"
blob = generate_idnits2_rfc_status()
try:
outpath.write_text(blob, encoding="utf8")
except Exception as e:
log.log(f"failed to write idnits2-rfc-status: {e}")


@shared_task
def generate_idnits2_rfcs_obsoleted_task():
outpath = Path(settings.DERIVED_DIR) / "idnits2-rfcs-obsoleted"
blob = generate_idnits2_rfcs_obsoleted()
try:
outpath.write_text(blob, encoding="utf8")
except Exception as e:
log.log(f"failed to write idnits2-rfcs-obsoleted: {e}")
30 changes: 22 additions & 8 deletions ietf/doc/tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@
from collections import defaultdict
from zoneinfo import ZoneInfo

from django.core.management import call_command
from django.urls import reverse as urlreverse
from django.conf import settings
from django.forms import Form
Expand All @@ -45,7 +44,14 @@
StatusChangeFactory, DocExtResourceFactory, RgDraftFactory, BcpFactory)
from ietf.doc.forms import NotifyForm
from ietf.doc.fields import SearchableDocumentsField
from ietf.doc.utils import create_ballot_if_not_open, investigate_fragment, uppercase_std_abbreviated_name, DraftAliasGenerator
from ietf.doc.utils import (
create_ballot_if_not_open,
investigate_fragment,
uppercase_std_abbreviated_name,
DraftAliasGenerator,
generate_idnits2_rfc_status,
generate_idnits2_rfcs_obsoleted,
)
from ietf.group.models import Group, Role
from ietf.group.factories import GroupFactory, RoleFactory
from ietf.ipr.factories import HolderIprDisclosureFactory
Expand Down Expand Up @@ -2831,32 +2837,40 @@ def test_markdown_and_text(self):
class Idnits2SupportTests(TestCase):
settings_temp_path_overrides = TestCase.settings_temp_path_overrides + ['DERIVED_DIR']

def test_obsoleted(self):
def test_generate_idnits2_rfcs_obsoleted(self):
rfc = WgRfcFactory(rfc_number=1001)
WgRfcFactory(rfc_number=1003,relations=[('obs',rfc)])
rfc = WgRfcFactory(rfc_number=1005)
WgRfcFactory(rfc_number=1007,relations=[('obs',rfc)])
blob = generate_idnits2_rfcs_obsoleted()
self.assertEqual(blob, b'1001 1003\n1005 1007\n'.decode("utf8"))

def test_obsoleted(self):
url = urlreverse('ietf.doc.views_doc.idnits2_rfcs_obsoleted')
r = self.client.get(url)
self.assertEqual(r.status_code, 404)
call_command('generate_idnits2_rfcs_obsoleted')
# value written is arbitrary, expect it to be passed through
(Path(settings.DERIVED_DIR) / "idnits2-rfcs-obsoleted").write_bytes(b'1001 1003\n1005 1007\n')
url = urlreverse('ietf.doc.views_doc.idnits2_rfcs_obsoleted')
r = self.client.get(url)
self.assertEqual(r.status_code, 200)
self.assertEqual(r.content, b'1001 1003\n1005 1007\n')

def test_rfc_status(self):
def test_generate_idnits2_rfc_status(self):
for slug in ('bcp', 'ds', 'exp', 'hist', 'inf', 'std', 'ps', 'unkn'):
WgRfcFactory(std_level_id=slug)
blob = generate_idnits2_rfc_status().replace("\n", "")
self.assertEqual(blob[6312-1], "O")

def test_rfc_status(self):
url = urlreverse('ietf.doc.views_doc.idnits2_rfc_status')
r = self.client.get(url)
self.assertEqual(r.status_code,404)
call_command('generate_idnits2_rfc_status')
# value written is arbitrary, expect it to be passed through
(Path(settings.DERIVED_DIR) / "idnits2-rfc-status").write_bytes(b'1001 1003\n1005 1007\n')
r = self.client.get(url)
self.assertEqual(r.status_code,200)
blob = unicontent(r).replace('\n','')
self.assertEqual(blob[6312-1],'O')
self.assertEqual(r.content, b'1001 1003\n1005 1007\n')

def test_idnits2_state(self):
rfc = WgRfcFactory()
Expand Down
40 changes: 35 additions & 5 deletions ietf/doc/tests_tasks.py
Original file line number Diff line number Diff line change
@@ -1,15 +1,24 @@
# Copyright The IETF Trust 2024, All Rights Reserved
import mock

from pathlib import Path

from django.conf import settings

from ietf.utils.test_utils import TestCase
from ietf.utils.timezone import datetime_today

from .factories import DocumentFactory
from .models import Document
from .tasks import expire_ids_task, notify_expirations_task

from .tasks import (
expire_ids_task,
generate_idnits2_rfcs_obsoleted_task,
generate_idnits2_rfc_status_task,
notify_expirations_task,
)

class TaskTests(TestCase):
settings_temp_path_overrides = TestCase.settings_temp_path_overrides + ["DERIVED_DIR"]

@mock.patch("ietf.doc.tasks.in_draft_expire_freeze")
@mock.patch("ietf.doc.tasks.get_expired_drafts")
Expand All @@ -35,10 +44,10 @@ def test_expire_ids_task(
Document.objects.filter(pk=doc.pk),
Document.objects.filter(pk=other_doc.pk),
]

# call task
expire_ids_task()

# check results
self.assertTrue(in_draft_expire_freeze_mock.called)
self.assertEqual(expirable_drafts_mock.call_count, 2)
Expand All @@ -50,7 +59,7 @@ def test_expire_ids_task(

# test that an exception is raised
in_draft_expire_freeze_mock.side_effect = RuntimeError
with self.assertRaises(RuntimeError):(
with self.assertRaises(RuntimeError): (
expire_ids_task())

@mock.patch("ietf.doc.tasks.send_expire_warning_for_draft")
Expand All @@ -61,3 +70,24 @@ def test_notify_expirations_task(self, get_drafts_mock, send_warning_mock):
notify_expirations_task()
self.assertEqual(send_warning_mock.call_count, 1)
self.assertEqual(send_warning_mock.call_args[0], ("sentinel",))

@mock.patch("ietf.doc.tasks.generate_idnits2_rfc_status")
def test_generate_idnits2_rfc_status_task(self, mock_generate):
mock_generate.return_value = "dåtå"
generate_idnits2_rfc_status_task()
self.assertEqual(mock_generate.call_count, 1)
self.assertEqual(
"dåtå".encode("utf8"),
(Path(settings.DERIVED_DIR) / "idnits2-rfc-status").read_bytes(),
)

@mock.patch("ietf.doc.tasks.generate_idnits2_rfcs_obsoleted")
def test_generate_idnits2_rfcs_obsoleted_task(self, mock_generate):
mock_generate.return_value = "dåtå"
generate_idnits2_rfcs_obsoleted_task()
self.assertEqual(mock_generate.call_count, 1)
self.assertEqual(
"dåtå".encode("utf8"),
(Path(settings.DERIVED_DIR) / "idnits2-rfcs-obsoleted").read_bytes(),
)

20 changes: 20 additions & 0 deletions ietf/utils/management/commands/periodic_tasks.py
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,26 @@ def create_default_tasks(self):
)
)

PeriodicTask.objects.get_or_create(
name="Generate idnits2 rfcs-obsoleted blob",
task="ietf.doc.tasks.generate_idnits2_rfcs_obsoleted_task",
defaults=dict(
enabled=False,
crontab=self.crontabs["hourly"],
description="Generate the rfcs-obsoleted file used by idnits",
),
)

PeriodicTask.objects.get_or_create(
name="Generate idnits2 rfc-status blob",
task="ietf.doc.tasks.generate_idnits2_rfc_status_task",
defaults=dict(
enabled=False,
crontab=self.crontabs["hourly"],
description="Generate the rfc_status blob used by idnits",
),
)

def show_tasks(self):
for label, crontab in self.crontabs.items():
tasks = PeriodicTask.objects.filter(crontab=crontab).order_by(
Expand Down

0 comments on commit 235ac8b

Please sign in to comment.