1#
2# Copyright (C) 2017 The Android Open Source Project
3#
4# Licensed under the Apache License, Version 2.0 (the "License");
5# you may not use this file except in compliance with the License.
6# You may obtain a copy of the License at
7#
8#      http://www.apache.org/licenses/LICENSE-2.0
9#
10# Unless required by applicable law or agreed to in writing, software
11# distributed under the License is distributed on an "AS IS" BASIS,
12# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13# See the License for the specific language governing permissions and
14# limitations under the License.
15#
16
17import time
18
19from host_controller.tfc import api_message
20
21
22class EventType(object):
23    """The types of command events."""
24    ALLOCATION_FAILED = "AllocationFailed"
25    CONFIGURATION_ERROR = "ConfigurationError"
26    EXECUTE_FAILED = "ExecuteFailed"
27    FETCH_FAILED = "FetchFailed"
28    INVOCATION_COMPLETED = "InvocationCompleted"
29    INVOCATION_STARTED = "InvocationStarted"
30    TEST_RUN_IN_PROGRESS = "TestRunInProgress"
31
32
33class CommandAttempt(api_message.ApiMessage):
34    """The command attempt defined by TFC API.
35
36    Attributes:
37        _COMMAND_EVENT: The parameters of command_events.submit.
38        _COMMAND_EVENT_DATA: The fields in "data" parameter of command_events.
39        _LIST_ATTEMPT: The fields returned by commandAttempts.list.
40    """
41    _COMMAND_EVENT = {
42            "attempt_id",
43            "data",
44            "device_serial",
45            "hostname",
46            "task_id",
47            "time",
48            "type"}
49    _COMMAND_EVENT_DATA = {
50            "error",
51            "failed_test_count",
52            "summary",
53            "test_run_name",
54            "total_test_count"}
55    _LIST_ATTEMPT = {
56            "attempt_id",
57            "command_id",
58            "create_time",
59            "end_time",
60            "error",
61            "device_serial",
62            "failed_test_count",
63            "hostname",
64            "request_id",
65            "start_time",
66            "state",
67            "status",
68            "summary",
69            "task_id",
70            "total_test_count",
71            "update_time"}
72
73    def __init__(self, task_id, attempt_id, hostname, device_serial, **kwargs):
74        """Initializes the attributes.
75
76        Args:
77            task_id: A string, the task id assigned by the server.
78            attempt_id: A string or UUID, the attempt id generated by the host.
79            hostname: The name of the TradeFed host.
80            device_serial: The serial number of the device.
81            **kwargs: The optional attributes.
82        """
83        super(CommandAttempt, self).__init__(self._LIST_ATTEMPT,
84                                             task_id=task_id,
85                                             attempt_id=str(attempt_id),
86                                             hostname=hostname,
87                                             device_serial=device_serial,
88                                             **kwargs)
89
90    def CreateCommandEvent(self, event_type, error=None, event_time=None):
91        """Creates an event defined by command_events.submit.
92
93        Args:
94            event_type: A string in EventType.
95            error: A string, the error message for *Failed, *Error, and
96                   *Completed events.
97            event_time: A float, Unix timestamp of the event in seconds.
98
99        Returns:
100            A JSON object.
101        """
102        obj = self.ToJson(self._COMMAND_EVENT)
103        obj["type"] = event_type
104        obj["time"] = int(event_time if event_time is not None else time.time())
105        data_obj = self.ToJson(self._COMMAND_EVENT_DATA)
106        if error is not None:
107            data_obj["error"] = error
108        if data_obj:
109            obj["data"] = data_obj
110        return obj
111
112    def CreateInvocationCompletedEvent(self,
113                                       summary,
114                                       total_test_count,
115                                       failed_test_count,
116                                       error=None,
117                                       event_time=None):
118        """Creates an InvocationCompleted event.
119
120        Args:
121            summary: A string, the result of the command.
122            total_test_count: Number of test cases.
123            failed_test_count: Number of failed test cases.
124            error: A string, the error message.
125            event_time: A float, Unix timestamp of the event in seconds.
126
127        Returns:
128            A JSON object.
129        """
130        obj = self.CreateCommandEvent(EventType.INVOCATION_COMPLETED,
131                                      error, event_time)
132        if "data" not in obj:
133            obj["data"] = dict()
134        obj["data"].update({"summary": summary,
135                            "total_test_count": total_test_count,
136                            "failed_test_count": failed_test_count})
137        return obj
138