1
0
mirror of https://github.com/netbox-community/netbox.git synced 2024-05-10 07:54:54 +00:00

fix tests and cleanup

This commit is contained in:
John Anderson
2020-06-29 14:34:42 -04:00
parent 1681dbfa39
commit f48a079ae6
11 changed files with 29 additions and 111 deletions

View File

@ -284,21 +284,12 @@ class ScriptSerializer(serializers.Serializer):
lookup_field='full_name',
lookup_url_kwarg='pk'
)
id = serializers.SerializerMethodField(read_only=True)
name = serializers.SerializerMethodField(read_only=True)
description = serializers.SerializerMethodField(read_only=True)
id = serializers.CharField(read_only=True, source="full_name")
name = serializers.CharField(read_only=True)
description = serializers.CharField(read_only=True)
vars = serializers.SerializerMethodField(read_only=True)
result = NestedJobResultSerializer()
def get_id(self, instance):
return '{}.{}'.format(instance.__module__, instance.__name__)
def get_name(self, instance):
return getattr(instance.Meta, 'name', instance.__name__)
def get_description(self, instance):
return getattr(instance.Meta, 'description', '')
def get_vars(self, instance):
return {
k: v.__class__.__name__ for k, v in instance._get_vars().items()

View File

@ -17,6 +17,7 @@ from extras.models import (
from extras.reports import get_report, get_reports
from extras.scripts import get_script, get_scripts, run_script
from utilities.api import IsAuthenticatedOrLoginNotRequired, ModelViewSet
from utilities.utils import copy_safe_request
from . import serializers
@ -304,12 +305,12 @@ class ScriptViewSet(ViewSet):
script.full_name,
script_content_type,
request.user,
data=form.cleaned_data,
data=data,
request=copy_safe_request(request),
commit=commit
)
script.result = job_result
serializer = serializers.ScriptDetailSerializer(script)
serializer = serializers.ScriptDetailSerializer(script, context={'request': request})
return Response(serializer.data)

View File

@ -573,25 +573,6 @@ class Script(models.Model):
class Meta:
managed = False
@classmethod
def get_absolute_url_from_job_result(cls, job_result):
"""
Given a JobResult that links to this content type, return URL to an instance which corresponds to that job
result, i.e. for historical records
"""
if job_result.obj_type.model_class() != cls:
return None
module, script_name = job_result.name.split('.')
return reverse(
'extras:script_history_detail',
kwargs={
'module': module,
'script_name': script_name,
'job_id': job_result.job_id
}
)
#
# Reports
@ -606,23 +587,6 @@ class Report(models.Model):
class Meta:
managed = False
@classmethod
def get_absolute_url_from_job_result(cls, job_result):
"""
Given a JobResult that links to this content type, return URL to an instance which corresponds to that job
result, i.e. for historical records
"""
if job_result.obj_type.model_class() != cls:
return None
return reverse(
'extras:report_history_detail',
kwargs={
'name': job_result.name,
'job_id': job_result.job_id
}
)
#
# Job results
@ -676,12 +640,6 @@ class JobResult(models.Model):
def __str__(self):
return str(self.job_id)
def get_absolute_url(self):
"""
Job results are accessed only under the context of the content type they link to
"""
return self.obj_type.model_class().get_absolute_url_from_job_result(self)
@property
def duration(self):
if not self.completed:
@ -692,7 +650,6 @@ class JobResult(models.Model):
return f"{int(minutes)} minutes, {seconds:.2f} seconds"
@classmethod
def enqueue_job(cls, func, name, obj_type, user, *args, **kwargs):
"""

View File

@ -273,12 +273,20 @@ class BaseScript:
self.source = inspect.getsource(self.__class__)
def __str__(self):
return self.name
@classproperty
def name(self):
return getattr(self.Meta, 'name', self.__class__.__name__)
@classproperty
def full_name(self):
return '.'.join([self.__module__, self.__name__])
@classproperty
def description(self):
return getattr(self.Meta, 'description', '')
@classmethod
def module(cls):
return cls.__module__

View File

@ -61,28 +61,6 @@ OBJECTCHANGE_REQUEST_ID = """
<a href="{% url 'extras:objectchange_list' %}?request_id={{ value }}">{{ value }}</a>
"""
JOB_RESULT_CREATED = """
<a href="{{ record.get_absolute_url }}">{{ value|date:"SHORT_DATETIME_FORMAT" }}</a>
"""
JOB_RESULT_COMPLETED = """
<span>{% if value %}{{ value|date:"SHORT_DATETIME_FORMAT" }}{% else %}—{% endif %}</span>
"""
JOB_RESULT_STATUS = """
{% if record.status == 'failed' %}
<label class="label label-danger">Failed</label>
{% elif record.status == 'pending' %}
<label class="label label-default">Pending</label>
{% elif record.status == 'running' %}
<label class="label label-warning">Running</label>
{% elif record.status == 'completed' %}
<label class="label label-success">Passed</label>
{% else %}
<label class="label label-default">N/A</label>
{% endif %}
"""
class TagTable(BaseTable):
pk = ToggleColumn()
@ -155,21 +133,3 @@ class ObjectChangeTable(BaseTable):
class Meta(BaseTable.Meta):
model = ObjectChange
fields = ('time', 'user_name', 'action', 'changed_object_type', 'object_repr', 'request_id')
class JobResultHistoryTable(BaseTable):
created = tables.TemplateColumn(
template_code=JOB_RESULT_CREATED,
verbose_name='Run'
)
completed = tables.TemplateColumn(
template_code=JOB_RESULT_COMPLETED
)
status = tables.TemplateColumn(
template_code=JOB_RESULT_STATUS
)
class Meta(BaseTable.Meta):
model = JobResult
fields = ('created', 'completed', 'status')

View File

@ -10,6 +10,7 @@ from extras.api.views import ScriptViewSet
from extras.models import ConfigContext, Graph, ExportTemplate, Tag
from extras.scripts import BooleanVar, IntegerVar, Script, StringVar
from utilities.testing import APITestCase, APIViewTestCases
from utilities.utils import copy_safe_request
class AppTest(APITestCase):
@ -263,13 +264,7 @@ class ScriptTest(APITestCase):
response = self.client.post(url, data, format='json', **self.header)
self.assertHttpStatus(response, status.HTTP_200_OK)
self.assertEqual(response.data['log'][0]['status'], 'info')
self.assertEqual(response.data['log'][0]['message'], script_data['var1'])
self.assertEqual(response.data['log'][1]['status'], 'success')
self.assertEqual(response.data['log'][1]['message'], script_data['var2'])
self.assertEqual(response.data['log'][2]['status'], 'failure')
self.assertEqual(response.data['log'][2]['message'], script_data['var3'])
self.assertEqual(response.data['output'], 'Script complete')
self.assertEqual(response.data['result']['status']['value'], 'pending')
class CreatedUpdatedFilterTest(APITestCase):

View File

@ -501,7 +501,6 @@ class ScriptView(ContentTypePermissionRequiredMixin, GetScriptMixin, View):
if form.is_valid():
commit = form.cleaned_data.pop('_commit')
#output, execution_time = run_script(script, form.cleaned_data, request, commit)
script_content_type = ContentType.objects.get(app_label='extras', model='script')
job_result = JobResult.enqueue_job(

View File

@ -1,6 +1,7 @@
from collections import OrderedDict
from django.conf import settings
from django.contrib.contenttypes.models import ContentType
from django.db.models import Count, F
from django.shortcuts import render
from django.views.generic import View
@ -24,6 +25,7 @@ from dcim.tables import (
CableTable, DeviceTable, DeviceTypeTable, PowerFeedTable, RackTable, RackGroupTable, SiteTable,
VirtualChassisTable,
)
from extras.choices import JobResultStatusChoices
from extras.models import ObjectChange, JobResult
from ipam.filters import AggregateFilterSet, IPAddressFilterSet, PrefixFilterSet, VLANFilterSet, VRFFilterSet
from ipam.models import Aggregate, IPAddress, Prefix, VLAN, VRF
@ -187,6 +189,13 @@ class HomeView(View):
pk__lt=F('_connected_interface')
)
# Report Results
report_content_type = ContentType.objects.get(app_label='extras', model='report')
report_results = JobResult.objects.filter(
obj_type=report_content_type,
status__in=JobResultStatusChoices.TERMINAL_STATE_CHOICES
).defer('data')[:10]
stats = {
# Organization
@ -241,7 +250,7 @@ class HomeView(View):
return render(request, self.template_name, {
'search_form': SearchForm(),
'stats': stats,
'report_results': [],#ReportResult.objects.order_by('-created')[:10],
'report_results': report_results,
'changelog': changelog[:15],
'new_release': new_release,
})

View File

@ -30,9 +30,6 @@ $(document).ready(function(){
url: url + pending_result_id + '/',
method: 'GET',
dataType: 'json',
beforeSend: function(xhr, settings) {
xhr.setRequestHeader("X-CSRFToken", "{{ csrf_token }}");
},
context: this,
success: function(data) {
updatePendingStatusLabel(data.status);

View File

@ -280,8 +280,8 @@
<table class="table table-hover panel-body">
{% for result in report_results %}
<tr>
<td><a href="{% url 'extras:report' name=result.report %}">{{ result.report }}</a></td>
<td class="text-right"><span title="{{ result.created }}">{% include 'extras/inc/report_label.html' %}</span></td>
<td><a href="{% url 'extras:report' name=result.name %}">{{ result.name }}</a></td>
<td class="text-right"><span title="{{ result.created }}">{% include 'extras/inc/job_label.html' %}</span></td>
</tr>
{% endfor %}
</table>

View File

@ -12,6 +12,7 @@ from dcim.choices import CableLengthUnitChoices
from extras.utils import is_taggable
from utilities.constants import HTTP_REQUEST_META_SAFE_COPY
def csv_format(data):
"""
Encapsulate any data which contains a comma within double quotes.