diff options
author | Michael Wood <michael.g.wood@intel.com> | 2016-05-26 16:12:22 +0100 |
---|---|---|
committer | Richard Purdie <richard.purdie@linuxfoundation.org> | 2016-06-15 08:35:04 +0100 |
commit | b2a68f55110b39aaf0b0d47bf533251a59a40a41 (patch) | |
tree | 7791ed85141e07f01c228619047740b235ee02dc /bitbake/lib/toaster/toastergui/buildtables.py | |
parent | 32d1e2dd25f288790450db48766cf115854712ba (diff) | |
download | poky-b2a68f55110b39aaf0b0d47bf533251a59a40a41.tar.gz |
bitbake: toaster: port Task tables to ToasterTables widget
Port the Task based tables to ToasterTable. This is the Task, Time, CPU
usage and Disk I/O tables.
(Bitbake rev: bebcef7a4bf08b10e472475435ddc7a524364adb)
Signed-off-by: Michael Wood <michael.g.wood@intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
Diffstat (limited to 'bitbake/lib/toaster/toastergui/buildtables.py')
-rw-r--r-- | bitbake/lib/toaster/toastergui/buildtables.py | 227 |
1 files changed, 225 insertions, 2 deletions
diff --git a/bitbake/lib/toaster/toastergui/buildtables.py b/bitbake/lib/toaster/toastergui/buildtables.py index dc742b9fe5..51c136f988 100644 --- a/bitbake/lib/toaster/toastergui/buildtables.py +++ b/bitbake/lib/toaster/toastergui/buildtables.py | |||
@@ -19,10 +19,13 @@ | |||
19 | # with this program; if not, write to the Free Software Foundation, Inc., | 19 | # with this program; if not, write to the Free Software Foundation, Inc., |
20 | # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. | 20 | # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. |
21 | 21 | ||
22 | from orm.models import Build | 22 | from orm.models import Build, Task |
23 | import toastergui.tables as tables | 23 | from django.db.models import Q |
24 | 24 | ||
25 | import toastergui.tables as tables | ||
25 | from toastergui.widgets import ToasterTable | 26 | from toastergui.widgets import ToasterTable |
27 | from toastergui.tablefilter import TableFilter | ||
28 | from toastergui.tablefilter import TableFilterActionToggle | ||
26 | 29 | ||
27 | 30 | ||
28 | class BuildTablesMixin(ToasterTable): | 31 | class BuildTablesMixin(ToasterTable): |
@@ -279,3 +282,223 @@ class BuiltRecipesTable(BuildTablesMixin): | |||
279 | self.add_column(title="Layer commit", | 282 | self.add_column(title="Layer commit", |
280 | static_data_name="commit", | 283 | static_data_name="commit", |
281 | static_data_template=git_rev_template) | 284 | static_data_template=git_rev_template) |
285 | |||
286 | |||
287 | class BuildTasksTable(BuildTablesMixin): | ||
288 | """ Table to show the tasks that run in this build """ | ||
289 | |||
290 | def __init__(self, *args, **kwargs): | ||
291 | super(BuildTasksTable, self).__init__(*args, **kwargs) | ||
292 | self.title = "Tasks" | ||
293 | self.default_orderby = "order" | ||
294 | |||
295 | # Toggle these columns on off for Time/CPU usage/Disk I/O tables | ||
296 | self.toggle_columns = {} | ||
297 | |||
298 | def setup_queryset(self, *args, **kwargs): | ||
299 | build = Build.objects.get(pk=kwargs['build_id']) | ||
300 | self.static_context_extra['build'] = build | ||
301 | self.queryset = build.task_build.filter(~Q(order=None)) | ||
302 | self.queryset = self.queryset.order_by(self.default_orderby) | ||
303 | |||
304 | def setup_filters(self, *args, **kwargs): | ||
305 | # Execution outcome types filter | ||
306 | executed_outcome = TableFilter(name="execution_outcome", | ||
307 | title="Filter Tasks by 'Executed") | ||
308 | |||
309 | exec_outcome_action_exec = TableFilterActionToggle( | ||
310 | "executed", | ||
311 | "Executed Tasks", | ||
312 | Q(task_executed=True)) | ||
313 | |||
314 | exec_outcome_action_not_exec = TableFilterActionToggle( | ||
315 | "not_executed", | ||
316 | "Not Executed Tasks", | ||
317 | Q(task_executed=False)) | ||
318 | |||
319 | executed_outcome.add_action(exec_outcome_action_exec) | ||
320 | executed_outcome.add_action(exec_outcome_action_not_exec) | ||
321 | |||
322 | # Task outcome types filter | ||
323 | task_outcome = TableFilter(name="task_outcome", | ||
324 | title="Filter Task by 'Outcome'") | ||
325 | |||
326 | for outcome_enum, title in Task.TASK_OUTCOME: | ||
327 | action = TableFilterActionToggle( | ||
328 | title.replace(" ", "_").lower(), | ||
329 | "%s Tasks" % title, | ||
330 | Q(outcome=outcome_enum)) | ||
331 | |||
332 | task_outcome.add_action(action) | ||
333 | |||
334 | # SSTATE outcome types filter | ||
335 | sstate_outcome = TableFilter(name="sstate_outcome", | ||
336 | title="Filter Task by 'Cache attempt'") | ||
337 | |||
338 | for sstate_result_enum, title in Task.SSTATE_RESULT: | ||
339 | action = TableFilterActionToggle( | ||
340 | title.replace(" ", "_").lower(), | ||
341 | "Tasks with '%s' attempts" % title, | ||
342 | Q(sstate_result=sstate_result_enum)) | ||
343 | |||
344 | sstate_outcome.add_action(action) | ||
345 | |||
346 | self.add_filter(sstate_outcome) | ||
347 | self.add_filter(executed_outcome) | ||
348 | self.add_filter(task_outcome) | ||
349 | |||
350 | def setup_columns(self, *args, **kwargs): | ||
351 | self.toggle_columns['order'] = len(self.columns) | ||
352 | |||
353 | recipe_name_tmpl =\ | ||
354 | '<a href="{% url "recipe" extra.build.pk data.recipe.pk %}">'\ | ||
355 | '{{data.recipe.name}}'\ | ||
356 | '</a>' | ||
357 | |||
358 | recipe_version_tmpl =\ | ||
359 | '<a href="{% url "recipe" extra.build.pk data.recipe.pk %}">'\ | ||
360 | '{{data.recipe.version}}'\ | ||
361 | '</a>' | ||
362 | |||
363 | def task_link_tmpl(val): | ||
364 | return ('<a name="task-{{data.order}}"' | ||
365 | 'href="{%% url "task" extra.build.pk data.pk %%}">' | ||
366 | '%s' | ||
367 | '</a>') % str(val) | ||
368 | |||
369 | self.add_column(title="Order", | ||
370 | static_data_name="order", | ||
371 | static_data_template=task_link_tmpl('{{data.order}}'), | ||
372 | orderable=True) | ||
373 | |||
374 | self.add_column(title="Recipe", | ||
375 | static_data_name='recipe__name', | ||
376 | static_data_template=recipe_name_tmpl, | ||
377 | orderable=True) | ||
378 | |||
379 | self.add_column(title="Recipe version", | ||
380 | static_data_name='recipe__version', | ||
381 | static_data_template=recipe_version_tmpl) | ||
382 | |||
383 | self.add_column(title="Task", | ||
384 | static_data_name="task_name", | ||
385 | static_data_template=task_link_tmpl( | ||
386 | "{{data.task_name}}"), | ||
387 | orderable=True) | ||
388 | |||
389 | self.add_column(title="Executed", | ||
390 | static_data_name="task_executed", | ||
391 | static_data_template=task_link_tmpl( | ||
392 | "{{data.get_executed_display}}"), | ||
393 | filter_name='execution_outcome', | ||
394 | orderable=True) | ||
395 | |||
396 | self.static_context_extra['OUTCOME_FAILED'] = Task.OUTCOME_FAILED | ||
397 | outcome_tmpl = task_link_tmpl("{{data.outcome_text}}") | ||
398 | outcome_tmpl = ('%s ' | ||
399 | '{%% if data.outcome = extra.OUTCOME_FAILED %%}' | ||
400 | '<a href="{%% url "build_artifact" extra.build.pk ' | ||
401 | ' "tasklogfile" data.pk %%}">' | ||
402 | ' <i class="icon-download-alt" ' | ||
403 | ' title="Download task log file"></i>' | ||
404 | '</a> {%% endif %%}' | ||
405 | '<i class="icon-question-sign get-help ' | ||
406 | 'hover-help" style="visibility: hidden;" ' | ||
407 | 'title="{{data.get_outcome_help}}"></i>' | ||
408 | ) % outcome_tmpl | ||
409 | |||
410 | self.add_column(title="Outcome", | ||
411 | static_data_name="outcome", | ||
412 | static_data_template=outcome_tmpl, | ||
413 | filter_name="task_outcome", | ||
414 | orderable=True) | ||
415 | |||
416 | self.add_column(title="Cache attempt", | ||
417 | static_data_name="sstate_result", | ||
418 | static_data_template=task_link_tmpl( | ||
419 | "{{data.sstate_text}}"), | ||
420 | filter_name="sstate_outcome", | ||
421 | orderable=True) | ||
422 | |||
423 | self.toggle_columns['elapsed_time'] = len(self.columns) | ||
424 | |||
425 | self.add_column( | ||
426 | title="Time (secs)", | ||
427 | static_data_name="elapsed_time", | ||
428 | static_data_template='{% load projecttags %}{% load humanize %}' | ||
429 | '{{data.elapsed_time|format_none_and_zero|floatformat:2}}', | ||
430 | orderable=True, | ||
431 | hidden=True) | ||
432 | |||
433 | self.toggle_columns['cpu_time_sys'] = len(self.columns) | ||
434 | |||
435 | self.add_column( | ||
436 | title="System CPU time (secs)", | ||
437 | static_data_name="cpu_time_system", | ||
438 | static_data_template='{% load projecttags %}{% load humanize %}' | ||
439 | '{{data.cpu_time_system|format_none_and_zero|floatformat:2}}', | ||
440 | hidden=True, | ||
441 | orderable=True) | ||
442 | |||
443 | self.toggle_columns['cpu_time_user'] = len(self.columns) | ||
444 | |||
445 | self.add_column( | ||
446 | title="User CPU time (secs)", | ||
447 | static_data_name="cpu_time_user", | ||
448 | static_data_template='{% load projecttags %}{% load humanize %}' | ||
449 | '{{data.cpu_time_user|format_none_and_zero|floatformat:2}}', | ||
450 | hidden=True, | ||
451 | orderable=True) | ||
452 | |||
453 | self.toggle_columns['disk_io'] = len(self.columns) | ||
454 | |||
455 | self.add_column( | ||
456 | title="Disk I/O (ms)", | ||
457 | static_data_name="disk_io", | ||
458 | static_data_template='{% load projecttags %}{% load humanize %}' | ||
459 | '{{data.disk_io|format_none_and_zero|filtered_filesizeformat}}', | ||
460 | hidden=True, | ||
461 | orderable=True) | ||
462 | |||
463 | |||
464 | class BuildTimeTable(BuildTasksTable): | ||
465 | """ Same as tasks table but the Time column is default displayed""" | ||
466 | |||
467 | def __init__(self, *args, **kwargs): | ||
468 | super(BuildTimeTable, self).__init__(*args, **kwargs) | ||
469 | self.default_orderby = "-elapsed_time" | ||
470 | |||
471 | def setup_columns(self, *args, **kwargs): | ||
472 | super(BuildTimeTable, self).setup_columns(**kwargs) | ||
473 | |||
474 | self.columns[self.toggle_columns['order']]['hidden'] = True | ||
475 | self.columns[self.toggle_columns['elapsed_time']]['hidden'] = False | ||
476 | |||
477 | |||
478 | class BuildCPUTimeTable(BuildTasksTable): | ||
479 | """ Same as tasks table but the CPU usage columns are default displayed""" | ||
480 | |||
481 | def __init__(self, *args, **kwargs): | ||
482 | super(BuildCPUTimeTable, self).__init__(*args, **kwargs) | ||
483 | self.default_orderby = "-cpu_time_system" | ||
484 | |||
485 | def setup_columns(self, *args, **kwargs): | ||
486 | super(BuildCPUTimeTable, self).setup_columns(**kwargs) | ||
487 | |||
488 | self.columns[self.toggle_columns['order']]['hidden'] = True | ||
489 | self.columns[self.toggle_columns['cpu_time_sys']]['hidden'] = False | ||
490 | self.columns[self.toggle_columns['cpu_time_user']]['hidden'] = False | ||
491 | |||
492 | |||
493 | class BuildIOTable(BuildTasksTable): | ||
494 | """ Same as tasks table but the Disk IO column is default displayed""" | ||
495 | |||
496 | def __init__(self, *args, **kwargs): | ||
497 | super(BuildIOTable, self).__init__(*args, **kwargs) | ||
498 | self.default_orderby = "-disk_io" | ||
499 | |||
500 | def setup_columns(self, *args, **kwargs): | ||
501 | super(BuildIOTable, self).setup_columns(**kwargs) | ||
502 | |||
503 | self.columns[self.toggle_columns['order']]['hidden'] = True | ||
504 | self.columns[self.toggle_columns['disk_io']]['hidden'] = False | ||