blob: c146a2445772c895183f1617cd0a934aa781563c [file] [log] [blame]
#
# Copyright (C) 2017 The Android Open Source Project
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
"""UI classes for test output."""
from __future__ import absolute_import
from __future__ import print_function
import os
from typing import List
from ndk.ansi import AnsiConsole, Console, font_bold, font_faint, font_reset
from ndk.ui import Ui, UiRenderer, AnsiUiRenderer, NonAnsiUiRenderer, columnate
from ndk.test.devices import DeviceShardingGroup
from ndk.workqueue import LoadRestrictingWorkQueue, ShardingWorkQueue, Worker
class TestProgressUi(Ui):
NUM_TESTS_DIGITS = 6
def __init__(self, ui_renderer: UiRenderer, show_worker_status: bool,
show_device_groups: bool,
workqueue: ShardingWorkQueue) -> None:
super().__init__(ui_renderer)
self.show_worker_status = show_worker_status
self.show_device_groups = show_device_groups
self.workqueue = workqueue
def get_ui_lines(self) -> List[str]:
lines = []
if self.show_worker_status:
for group, group_queues in self.workqueue.work_queues.items():
for device, work_queue in group_queues.items():
style = font_bold()
if all([
w.status == Worker.IDLE_STATUS
for w in work_queue.workers
]):
style = font_faint()
lines.append(f'{style}{device}{font_reset()}')
for worker in work_queue.workers:
style = ''
if worker.status == Worker.IDLE_STATUS:
style = font_faint()
lines.append(f' {style}{worker.status}{font_reset()}')
lines.append('{: >{width}} tests remaining'.format(
self.workqueue.num_tasks, width=self.NUM_TESTS_DIGITS))
if self.show_device_groups:
for group in sorted(self.workqueue.task_queues.keys()):
assert isinstance(group, DeviceShardingGroup)
group_id = f'{len(group.devices)} devices {group}'
lines.append('{: >{width}} {}'.format(
self.workqueue.task_queues[group].qsize(), group_id,
width=self.NUM_TESTS_DIGITS))
return lines
def get_test_progress_ui(console: Console,
workqueue: ShardingWorkQueue) -> TestProgressUi:
ui_renderer: UiRenderer
if console.smart_console:
ui_renderer = AnsiUiRenderer(console)
show_worker_status = True
show_device_groups = True
elif os.name == 'nt':
ui_renderer = NonAnsiUiRenderer(console)
show_worker_status = False
show_device_groups = False
else:
ui_renderer = NonAnsiUiRenderer(console)
show_worker_status = False
show_device_groups = True
return TestProgressUi(
ui_renderer, show_worker_status, show_device_groups, workqueue)
class TestBuildProgressUi(Ui):
NUM_TESTS_DIGITS = 6
def __init__(self, ui_renderer: UiRenderer, show_worker_status: bool,
workqueue: LoadRestrictingWorkQueue):
super().__init__(ui_renderer)
self.show_worker_status = show_worker_status
self.workqueue = workqueue
def get_ui_lines(self) -> List[str]:
lines = []
if self.show_worker_status:
for worker in self.workqueue.main_work_queue.workers:
lines.append(worker.status)
for worker in self.workqueue.restricted_work_queue.workers:
lines.append(worker.status)
if self.ui_renderer.console.smart_console:
assert isinstance(self.ui_renderer.console, AnsiConsole)
# Keep some space at the top of the UI so we can see messages.
ui_height = self.ui_renderer.console.height - 10
if ui_height > 0:
lines = columnate(lines, self.ui_renderer.console.width,
ui_height)
lines.append('{: >{width}} tests remaining'.format(
self.workqueue.num_tasks, width=self.NUM_TESTS_DIGITS))
return lines
def get_test_build_progress_ui(
console: Console,
workqueue: LoadRestrictingWorkQueue) -> TestBuildProgressUi:
ui_renderer: UiRenderer
if console.smart_console:
ui_renderer = AnsiUiRenderer(console)
show_worker_status = True
else:
ui_renderer = NonAnsiUiRenderer(console)
show_worker_status = False
return TestBuildProgressUi(ui_renderer, show_worker_status, workqueue)