Skip to content

Commit

Permalink
ci: Merge pull request #6868 from ietf-tools/main
Browse files Browse the repository at this point in the history
ci: merge main to release
  • Loading branch information
rjsparks authored Jan 3, 2024
2 parents f770d7c + e15701a commit 9e0d937
Show file tree
Hide file tree
Showing 19 changed files with 326 additions and 73 deletions.
11 changes: 2 additions & 9 deletions .devcontainer/devcontainer.json
Original file line number Diff line number Diff line change
Expand Up @@ -33,23 +33,16 @@
"oderwat.indent-rainbow",
"redhat.vscode-yaml",
"spmeesseman.vscode-taskexplorer",
"visualstudioexptteam.vscodeintellicode"
"visualstudioexptteam.vscodeintellicode",
"ms-python.pylint"
],
"settings": {
"terminal.integrated.defaultProfile.linux": "zsh",
"python.pythonPath": "/usr/local/bin/python",
"python.languageServer": "Default",
"python.linting.enabled": true,
"python.linting.pylintEnabled": true,
"python.formatting.autopep8Path": "/usr/local/py-utils/bin/autopep8",
"python.formatting.blackPath": "/usr/local/py-utils/bin/black",
"python.formatting.yapfPath": "/usr/local/py-utils/bin/yapf",
"python.linting.banditPath": "/usr/local/py-utils/bin/bandit",
"python.linting.flake8Path": "/usr/local/py-utils/bin/flake8",
"python.linting.mypyPath": "/usr/local/py-utils/bin/mypy",
"python.linting.pycodestylePath": "/usr/local/py-utils/bin/pycodestyle",
"python.linting.pydocstylePath": "/usr/local/py-utils/bin/pydocstyle",
"python.linting.pylintPath": "/usr/local/py-utils/bin/pylint",
"python.testing.pytestArgs": [
"ietf"
],
Expand Down
2 changes: 1 addition & 1 deletion dev/deploy-to-container/cli.js
Original file line number Diff line number Diff line change
Expand Up @@ -245,7 +245,7 @@ async function main () {
name: `dt-app-${branch}`,
Hostname: `dt-app-${branch}`,
Env: [
`LETSENCRYPT_HOST=${hostname}`,
// `LETSENCRYPT_HOST=${hostname}`,
`VIRTUAL_HOST=${hostname}`,
`VIRTUAL_PORT=8000`,
`PGHOST=dt-db-${branch}`
Expand Down
3 changes: 0 additions & 3 deletions dev/deploy-to-container/start.sh
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,5 @@ echo "Running Datatracker checks..."
echo "Running Datatracker migrations..."
/usr/local/bin/python ./ietf/manage.py migrate --settings=settings_local

echo "Syncing with the rfc-index"
./ietf/bin/rfc-editor-index-updates -d 1969-01-01

echo "Starting Datatracker..."
./ietf/manage.py runserver 0.0.0.0:8000 --settings=settings_local
5 changes: 4 additions & 1 deletion ietf/doc/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -634,6 +634,9 @@ def pdfized(self):
)
except AssertionError:
pdf = None
except Exception as e:
log.log('weasyprint failed:'+str(e))
raise
if pdf:
cache.set(cache_key, pdf, settings.PDFIZER_CACHE_TIME)
return pdf
Expand All @@ -649,7 +652,7 @@ def referenced_by(self):
source__states__slug="active",
)
| models.Q(source__type__slug="rfc")
)
).distinct()

def referenced_by_rfcs(self):
"""Get refs to this doc from RFCs"""
Expand Down
35 changes: 33 additions & 2 deletions ietf/doc/tests.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Copyright The IETF Trust 2012-2020, All Rights Reserved
# Copyright The IETF Trust 2012-2023, All Rights Reserved
# -*- coding: utf-8 -*-


Expand Down Expand Up @@ -31,6 +31,8 @@

from tastypie.test import ResourceTestCaseMixin

from weasyprint.urls import URLFetchingError

import debug # pyflakes:ignore

from ietf.doc.models import ( Document, DocRelationshipName, RelatedDocument, State,
Expand All @@ -40,7 +42,7 @@
ConflictReviewFactory, WgDraftFactory, IndividualDraftFactory, WgRfcFactory,
IndividualRfcFactory, StateDocEventFactory, BallotPositionDocEventFactory,
BallotDocEventFactory, DocumentAuthorFactory, NewRevisionDocEventFactory,
StatusChangeFactory, DocExtResourceFactory, RgDraftFactory)
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, uppercase_std_abbreviated_name
Expand Down Expand Up @@ -156,6 +158,23 @@ def test_search(self):
self.assertEqual(r.status_code, 200)
self.assertContains(r, draft.title)

def test_search_became_rfc(self):
draft = WgDraftFactory()
rfc = WgRfcFactory()
draft.set_state(State.objects.get(type="draft", slug="rfc"))
draft.relateddocument_set.create(relationship_id="became_rfc", target=rfc)
base_url = urlreverse('ietf.doc.views_search.search')

# find by RFC
r = self.client.get(base_url + f"?rfcs=on&name={rfc.name}")
self.assertEqual(r.status_code, 200)
self.assertContains(r, rfc.title)

# find by draft
r = self.client.get(base_url + f"?activedrafts=on&rfcs=on&name={draft.name}")
self.assertEqual(r.status_code, 200)
self.assertContains(r, rfc.title)

def test_search_for_name(self):
draft = WgDraftFactory(name='draft-ietf-mars-test',group=GroupFactory(acronym='mars',parent=Group.objects.get(acronym='farfut')),authors=[PersonFactory()],ad=PersonFactory())
draft.set_state(State.objects.get(used=True, type="draft-iesg", slug="pub-req"))
Expand Down Expand Up @@ -1948,6 +1967,12 @@ def _parse_bibtex_response(self, response) -> dict:

@override_settings(RFC_EDITOR_INFO_BASE_URL='https://www.rfc-editor.ietf.org/info/')
def test_document_bibtex(self):

for factory in [CharterFactory, BcpFactory, StatusChangeFactory, ConflictReviewFactory]: # Should be extended to all other doc types
doc = factory()
url = urlreverse("ietf.doc.views_doc.document_bibtex", kwargs=dict(name=doc.name))
r = self.client.get(url)
self.assertEqual(r.status_code, 404)
rfc = WgRfcFactory.create(
time=datetime.datetime(2010, 10, 10, tzinfo=ZoneInfo(settings.TIME_ZONE))
)
Expand Down Expand Up @@ -2844,6 +2869,12 @@ def test_pdfized(self):
self.should_succeed(dict(name=draft.name,rev=f'{r:02d}',ext=ext))
self.should_404(dict(name=draft.name,rev='02'))

with mock.patch('ietf.doc.models.DocumentInfo.pdfized', side_effect=URLFetchingError):
url = urlreverse(self.view, kwargs=dict(name=rfc.name))
r = self.client.get(url)
self.assertEqual(r.status_code, 200)
self.assertContains(r, "Error while rendering PDF")

class NotifyValidationTests(TestCase):
def test_notify_validation(self):
valid_values = [
Expand Down
36 changes: 36 additions & 0 deletions ietf/doc/tests_draft.py
Original file line number Diff line number Diff line change
Expand Up @@ -1483,6 +1483,42 @@ def test_confirm_submission(self):
self.assertTrue("aread@" in outbox[-1]['To'])
self.assertTrue("iesg-secretary@" in outbox[-1]['Cc'])

def test_confirm_submission_no_doc_ad(self):
url = urlreverse('ietf.doc.views_draft.to_iesg', kwargs=dict(name=self.docname))
self.client.login(username="marschairman", password="marschairman+password")

doc = Document.objects.get(name=self.docname)
RoleFactory(name_id='ad', group=doc.group, person=doc.ad)
e = DocEvent(type="changed_document", by=doc.ad, doc=doc, rev=doc.rev, desc="Remove doc AD")
e.save()
doc.ad = None
doc.save_with_history([e])

docevents_pre = set(doc.docevent_set.all())
mailbox_before = len(outbox)

r = self.client.post(url, dict(confirm="1"))
self.assertEqual(r.status_code, 302)

doc = Document.objects.get(name=self.docname)
self.assertTrue(doc.get_state('draft-iesg').slug=='pub-req')
self.assertTrue(doc.get_state('draft-stream-ietf').slug=='sub-pub')

self.assertCountEqual(doc.action_holders.all(), [doc.ad])

new_docevents = set(doc.docevent_set.all()) - docevents_pre
self.assertEqual(len(new_docevents), 5)
new_docevent_type_count = Counter([e.type for e in new_docevents])
self.assertEqual(new_docevent_type_count['changed_state'],2)
self.assertEqual(new_docevent_type_count['started_iesg_process'],1)
self.assertEqual(new_docevent_type_count['changed_action_holders'], 1)
self.assertEqual(new_docevent_type_count['changed_document'], 1)

self.assertEqual(len(outbox), mailbox_before + 1)
self.assertTrue("Publication has been requested" in outbox[-1]['Subject'])
self.assertTrue("aread@" in outbox[-1]['To'])
self.assertTrue("iesg-secretary@" in outbox[-1]['Cc'])



class RequestPublicationTests(TestCase):
Expand Down
19 changes: 19 additions & 0 deletions ietf/doc/tests_review.py
Original file line number Diff line number Diff line change
Expand Up @@ -380,6 +380,25 @@ def test_assign_reviewer_after_reject(self):
reviewer_label = q("option[value=\"{}\"]".format(reviewer_email.address)).text().lower()
self.assertIn("rejected review of document before", reviewer_label)

def test_assign_reviewer_after_withdraw(self):
doc = WgDraftFactory()
review_team = ReviewTeamFactory()
rev_role = RoleFactory(group=review_team,person__user__username='reviewer',person__user__email='reviewer@example.com',name_id='reviewer')
RoleFactory(group=review_team,person__user__username='reviewsecretary',name_id='secr')
review_req = ReviewRequestFactory(team=review_team,doc=doc)
reviewer = rev_role.person.email_set.first()
ReviewAssignmentFactory(review_request=review_req, state_id='withdrawn', reviewer=reviewer)
req_url = urlreverse('ietf.doc.views_review.review_request', kwargs={ "name": doc.name, "request_id": review_req.pk })
assign_url = urlreverse('ietf.doc.views_review.assign_reviewer', kwargs={ "name": doc.name, "request_id": review_req.pk })

login_testing_unauthorized(self, "reviewsecretary", assign_url)
r = self.client.post(assign_url, { "action": "assign", "reviewer": reviewer.pk })
self.assertRedirects(r, req_url)
review_req = reload_db_objects(review_req)
assignment = review_req.reviewassignment_set.last()
self.assertEqual(assignment.state, ReviewAssignmentStateName.objects.get(slug='assigned'))
self.assertEqual(review_req.state, ReviewRequestStateName.objects.get(slug='assigned'))

def test_previously_reviewed_replaced_doc(self):
review_team = ReviewTeamFactory(acronym="reviewteam", name="Review Team", type_id="review", list_email="reviewteam@ietf.org", parent=Group.objects.get(acronym="farfut"))
rev_role = RoleFactory(group=review_team,person__user__username='reviewer',person__user__email='reviewer@example.com',person__name='Some Reviewer',name_id='reviewer')
Expand Down
47 changes: 39 additions & 8 deletions ietf/doc/views_doc.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,6 @@
from django import forms
from django.contrib.staticfiles import finders


import debug # pyflakes:ignore

from ietf.doc.models import ( Document, DocHistory, DocEvent, BallotDocEvent, BallotType,
Expand Down Expand Up @@ -1064,7 +1063,10 @@ def document_pdfized(request, name, rev=None, ext=None):
if not os.path.exists(doc.get_file_name()):
raise Http404("File not found: %s" % doc.get_file_name())

pdf = doc.pdfized()
try:
pdf = doc.pdfized()
except Exception:
return render(request, "doc/weasyprint_failed.html")
if pdf:
return HttpResponse(pdf,content_type='application/pdf')
else:
Expand Down Expand Up @@ -1262,6 +1264,9 @@ def document_bibtex(request, name, rev=None):

doc = get_object_or_404(Document, name=name)

if doc.type_id not in ["rfc", "draft"]:
raise Http404()

doi = None
draft_became_rfc = None
replaced_by = None
Expand Down Expand Up @@ -2185,22 +2190,48 @@ def idnits2_state(request, name, rev=None):
if doc.type_id == "rfc":
draft = doc.came_from_draft()
if draft:
zero_revision = NewRevisionDocEvent.objects.filter(doc=draft,rev='00').first()
zero_revision = NewRevisionDocEvent.objects.filter(
doc=draft, rev="00"
).first()
else:
zero_revision = NewRevisionDocEvent.objects.filter(doc=doc,rev='00').first()
zero_revision = NewRevisionDocEvent.objects.filter(doc=doc, rev="00").first()
if zero_revision:
doc.created = zero_revision.time
else:
doc.created = doc.docevent_set.order_by('-time').first().time
if doc.type_id == "draft":
if doc.became_rfc():
interesting_event = (
doc.became_rfc()
.docevent_set.filter(type="published_rfc")
.order_by("-time")
.first()
)
else:
interesting_event = doc.docevent_set.order_by(
"-time"
).first() # Is taking the most _recent_ instead of the oldest event correct?
else: # doc.type_id == "rfc"
interesting_event = (
doc.docevent_set.filter(type="published_rfc").order_by("-time").first()
)
doc.created = interesting_event.time
if doc.std_level:
doc.deststatus = doc.std_level.name
elif doc.intended_std_level:
doc.deststatus = doc.intended_std_level.name
else:
text = doc.text()
if text:
parsed_draft = PlaintextDraft(text=doc.text(), source=name, name_from_source=False)
parsed_draft = PlaintextDraft(
text=doc.text(), source=name, name_from_source=False
)
doc.deststatus = parsed_draft.get_status()
else:
doc.deststatus="Unknown"
return render(request, 'doc/idnits2-state.txt', context={'doc':doc}, content_type='text/plain;charset=utf-8')
doc.deststatus = "Unknown"
return render(
request,
"doc/idnits2-state.txt",
context={"doc": doc},
content_type="text/plain;charset=utf-8",
)

34 changes: 10 additions & 24 deletions ietf/doc/views_draft.py
Original file line number Diff line number Diff line change
Expand Up @@ -560,22 +560,19 @@ def to_iesg(request,name):
if request.method == 'POST':

if request.POST.get("confirm", ""):

by = request.user.person

events = []

changes = []
def doc_event(type, by, doc, desc):
return DocEvent.objects.create(type=type, by=by, doc=doc, rev=doc.rev, desc=desc)

if doc.get_state_slug("draft-iesg") == "idexists":
e = DocEvent()
e.type = "started_iesg_process"
e.by = by
e.doc = doc
e.rev = doc.rev
e.desc = "Document is now in IESG state <b>%s</b>" % target_state['iesg'].name
e.save()
events.append(e)
events.append(doc_event("started_iesg_process", by, doc, f"Document is now in IESG state <b>{target_state['iesg'].name}</b>"))

# do this first, so AD becomes action holder
if not doc.ad == ad :
doc.ad = ad
events.append(doc_event("changed_document", by, doc, f"Responsible AD changed to {doc.ad}"))

for state_type in ['draft-iesg','draft-stream-ietf']:
prev_state=doc.get_state(state_type)
Expand All @@ -587,25 +584,14 @@ def to_iesg(request,name):
events.append(e)
events.append(add_state_change_event(doc=doc,by=by,prev_state=prev_state,new_state=new_state))

if not doc.ad == ad :
doc.ad = ad
changes.append("Responsible AD changed to %s" % doc.ad)

if not doc.notify == notify :
doc.notify = notify
changes.append("State Change Notice email list changed to %s" % doc.notify)
events.append(doc_event("changed_document", by, doc, f"State Change Notice email list changed to {doc.notify}"))

# Get the last available writeup
previous_writeup = doc.latest_event(WriteupDocEvent,type="changed_protocol_writeup")
if previous_writeup != None:
changes.append(previous_writeup.text)

for c in changes:
e = DocEvent(doc=doc, rev=doc.rev, by=by)
e.desc = c
e.type = "changed_document"
e.save()
events.append(e)
events.append(doc_event("changed_document", by, doc, previous_writeup.text))

doc.save_with_history(events)

Expand Down
3 changes: 3 additions & 0 deletions ietf/doc/views_help.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
# Copyright The IETF Trust 2013-2023, All Rights Reserved

import debug # pyflakes: ignore

from django.shortcuts import render, get_object_or_404
from django.http import Http404

Expand All @@ -18,6 +20,7 @@ def state_help(request, type=None):
"draft-stream-irtf": ("draft-stream-irtf", "IRTF Stream States for Internet-Drafts"),
"draft-stream-ise": ("draft-stream-ise", "ISE Stream States for Internet-Drafts"),
"draft-stream-iab": ("draft-stream-iab", "IAB Stream States for Internet-Drafts"),
"draft-stream-editorial": ("draft-stream-editorial", "Editorial Stream States for Internet-Drafts"),
"charter": ("charter", "Charter States"),
"conflict-review": ("conflrev", "Conflict Review States"),
"status-change": ("statchg", "RFC Status Change States"),
Expand Down
13 changes: 8 additions & 5 deletions ietf/doc/views_search.py
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,9 @@ def retrieve_search_results(form, all_types=False):
Q(targets_related__source__title__icontains=singlespace, targets_related__relationship_id="contains"),
])

if query["rfcs"]:
queries.extend([Q(targets_related__source__name__icontains=look_for, targets_related__relationship_id="became_rfc")])

combined_query = reduce(operator.or_, queries)
docs = docs.filter(combined_query).distinct()

Expand Down Expand Up @@ -468,11 +471,11 @@ def ad_workload(request):
state = doc_state(doc)

state_events = doc.docevent_set.filter(
Q(type="started_iesg_process")
| Q(type="changed_state")
| Q(type="published_rfc")
| Q(type="closed_ballot"),
).order_by("-time")
type__in=["started_iesg_process", "changed_state", "closed_ballot"]
)
if doc.became_rfc():
state_events = state_events | doc.became_rfc().docevent_set.filter(type="published_rfc")
state_events = state_events.order_by("-time")

# compute state history for drafts
last = now
Expand Down
Loading

0 comments on commit 9e0d937

Please sign in to comment.