1#!/usr/bin/env python
2#
3# Copyright (C) 2017 The Android Open Source Project
4#
5# Licensed under the Apache License, Version 2.0 (the "License");
6# you may not use this file except in compliance with the License.
7# You may obtain a copy of the License at
8#
9#      http://www.apache.org/licenses/LICENSE-2.0
10#
11# Unless required by applicable law or agreed to in writing, software
12# distributed under the License is distributed on an "AS IS" BASIS,
13# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14# See the License for the specific language governing permissions and
15# limitations under the License.
16#
17
18from google.appengine.ext import ndb
19
20from protorpc import messages
21from protorpc import message_types
22
23
24class BuildModel(ndb.Model):
25    """A model for representing an individual build entry."""
26    manifest_branch = ndb.StringProperty()
27    build_id = ndb.StringProperty()
28    build_target = ndb.StringProperty()
29    build_type = ndb.StringProperty()
30    artifact_type = ndb.StringProperty()
31    artifacts = ndb.StringProperty(repeated=True)
32    timestamp = ndb.DateTimeProperty(auto_now=False)
33    signed = ndb.BooleanProperty()
34
35
36class BuildInfoMessage(messages.Message):
37    """A message for representing an individual build entry."""
38    manifest_branch = messages.StringField(1)
39    build_id = messages.StringField(2)
40    build_target = messages.StringField(3)
41    build_type = messages.StringField(4)
42    artifact_type = messages.StringField(5)
43    artifacts = messages.StringField(6, repeated=True)
44    signed = messages.BooleanField(7)
45    timestamp = message_types.DateTimeField(8)
46
47
48class ScheduleControlModel(ndb.Model):
49    """A model for representing a schedule control data entry."""
50    enabled = ndb.BooleanProperty()
51    # "global" or empty string to enable/disable all schedules.
52    schedule_name = ndb.StringProperty()
53
54
55class ScheduleModel(ndb.Model):
56    """A model for representing an individual schedule entry."""
57    # schedule name for green build schedule, optional.
58    name = ndb.StringProperty()
59    schedule_type = ndb.StringProperty()
60
61    # device image information
62    build_storage_type = ndb.IntegerProperty()
63    manifest_branch = ndb.StringProperty()
64    build_target = ndb.StringProperty()  # type:name
65    device_pab_account_id = ndb.StringProperty()
66    require_signed_device_build = ndb.BooleanProperty()
67    has_bootloader_img = ndb.BooleanProperty(default=True)
68    has_radio_img = ndb.BooleanProperty(default=True)
69
70    # GSI information
71    gsi_storage_type = ndb.IntegerProperty()
72    gsi_branch = ndb.StringProperty()
73    gsi_build_target = ndb.StringProperty()
74    gsi_pab_account_id = ndb.StringProperty()
75    gsi_vendor_version = ndb.StringProperty()
76
77    # test suite information
78    test_storage_type = ndb.IntegerProperty()
79    test_branch = ndb.StringProperty()
80    test_build_target = ndb.StringProperty()
81    test_pab_account_id = ndb.StringProperty()
82
83    test_name = ndb.StringProperty()
84    period = ndb.IntegerProperty()
85    schedule = ndb.StringProperty()
86    priority = ndb.StringProperty()
87    priority_value = ndb.IntegerProperty()
88    device = ndb.StringProperty(repeated=True)
89    shards = ndb.IntegerProperty()
90    param = ndb.StringProperty(repeated=True)
91    timestamp = ndb.DateTimeProperty(auto_now=False)
92    retry_count = ndb.IntegerProperty()
93
94    children_jobs = ndb.KeyProperty(kind="JobModel", repeated=True)
95    error_count = ndb.IntegerProperty()
96    suspended = ndb.BooleanProperty()
97    image_package_repo_base = ndb.StringProperty()
98
99    required_host_equipment = ndb.StringProperty(repeated=True)
100    required_device_equipment = ndb.StringProperty(repeated=True)
101
102    report_bucket = ndb.StringProperty(repeated=True)
103    report_spreadsheet_id = ndb.StringProperty(repeated=True)
104    report_persistent_url = ndb.StringProperty(repeated=True)
105    report_reference_url = ndb.StringProperty(repeated=True)
106
107    owner = ndb.StringProperty(repeated=True)
108
109
110class ScheduleControlInfoMessage(messages.Message):
111    """A message for representing a schedule control data entry."""
112    enabled = messages.BooleanField(1)
113    schedule_name = messages.StringField(2)
114
115
116class ScheduleInfoMessage(messages.Message):
117    """A message for representing an individual schedule entry."""
118    # Next ID = 39
119    # schedule name for green build schedule, optional.
120    name = messages.StringField(16)
121    schedule_type = messages.StringField(19)
122
123    # device image information
124    build_storage_type = messages.IntegerField(21)
125    manifest_branch = messages.StringField(1)
126    build_target = messages.StringField(2)
127    device_pab_account_id = messages.StringField(17)
128    require_signed_device_build = messages.BooleanField(20)
129    has_bootloader_img = messages.BooleanField(27)
130    has_radio_img = messages.BooleanField(28)
131
132    # GSI information
133    gsi_storage_type = messages.IntegerField(22)
134    gsi_branch = messages.StringField(9)
135    gsi_build_target = messages.StringField(10)
136    gsi_pab_account_id = messages.StringField(11)
137    gsi_vendor_version = messages.StringField(24)
138
139    # test suite information
140    test_storage_type = messages.IntegerField(23)
141    test_branch = messages.StringField(12)
142    test_build_target = messages.StringField(13)
143    test_pab_account_id = messages.StringField(14)
144
145    test_name = messages.StringField(3)
146    period = messages.IntegerField(4)
147    schedule = messages.StringField(18)
148    priority = messages.StringField(5)
149    device = messages.StringField(6, repeated=True)
150    shards = messages.IntegerField(7)
151    param = messages.StringField(8, repeated=True)
152    retry_count = messages.IntegerField(15)
153
154    required_host_equipment = messages.StringField(25, repeated=True)
155    required_device_equipment = messages.StringField(26, repeated=True)
156
157    report_bucket = messages.StringField(29, repeated=True)
158    report_spreadsheet_id = messages.StringField(30, repeated=True)
159    report_persistent_url = messages.StringField(32, repeated=True)
160    report_reference_url = messages.StringField(33, repeated=True)
161
162    image_package_repo_base = messages.StringField(31)
163    timestamp = message_types.DateTimeField(34)
164    owner = messages.StringField(35, repeated=True)
165
166    suspended = messages.BooleanField(36)
167    urlsafe_key = messages.StringField(37)
168    error_count = messages.IntegerField(38)
169
170
171class LabModel(ndb.Model):
172    """A model for representing an individual lab entry."""
173    name = ndb.StringProperty()
174    owner = ndb.StringProperty()
175    admin = ndb.StringProperty(repeated=True)
176    hostname = ndb.StringProperty()
177    ip = ndb.StringProperty()
178    # devices is a comma-separated list of serial=product pairs
179    devices = ndb.StringProperty()
180    timestamp = ndb.DateTimeProperty(auto_now=False)
181    vtslab_version = ndb.StringProperty()
182    host_equipment = ndb.StringProperty(repeated=True)
183
184
185class LabDeviceInfoMessage(messages.Message):
186    """A message for representing an individual lab host's device entry."""
187    serial = messages.StringField(1, repeated=False)
188    product = messages.StringField(2, repeated=False)
189    device_equipment = messages.StringField(3, repeated=True)
190
191
192class LabHostInfoMessage(messages.Message):
193    """A message for representing an individual lab's host entry."""
194    hostname = messages.StringField(1, repeated=False)
195    ip = messages.StringField(2, repeated=False)
196    script = messages.StringField(3)
197    device = messages.MessageField(LabDeviceInfoMessage, 4, repeated=True)
198    vtslab_version = messages.StringField(5)
199    host_equipment = messages.StringField(6, repeated=True)
200
201
202class LabInfoMessage(messages.Message):
203    """A message for representing an individual lab entry."""
204    name = messages.StringField(1)
205    owner = messages.StringField(2)
206    admin = messages.StringField(4, repeated=True)
207    host = messages.MessageField(LabHostInfoMessage, 3, repeated=True)
208
209
210class LabMessage(messages.Message):
211    """A model for representing a LabModel entity."""
212    name = messages.StringField(1)
213    owner = messages.StringField(2)
214    admin = messages.StringField(3, repeated=True)
215    hostname = messages.StringField(4)
216    ip = messages.StringField(5)
217    devices = messages.StringField(6)
218    vtslab_version = messages.StringField(7)
219    host_equipment = messages.StringField(8, repeated=True)
220
221
222class DeviceModel(ndb.Model):
223    """A model for representing an individual device entry."""
224    hostname = ndb.StringProperty()
225    product = ndb.StringProperty()
226    serial = ndb.StringProperty()
227    status = ndb.IntegerProperty()
228    scheduling_status = ndb.IntegerProperty()
229    timestamp = ndb.DateTimeProperty(auto_now=False)
230    device_equipment = ndb.StringProperty(repeated=True)
231
232
233class DeviceInfoMessage(messages.Message):
234    """A message for representing an individual host's device entry."""
235    serial = messages.StringField(1)
236    product = messages.StringField(2)
237    status = messages.IntegerField(3)
238    scheduling_status = messages.IntegerField(4)
239    hostname = messages.StringField(5)
240    device_equipment = messages.StringField(6, repeated=True)
241    timestamp = message_types.DateTimeField(7)
242
243
244class HostInfoMessage(messages.Message):
245    """A message for representing an individual host entry."""
246    hostname = messages.StringField(1)
247    devices = messages.MessageField(DeviceInfoMessage, 2, repeated=True)
248
249
250class JobModel(ndb.Model):
251    """A model for representing an individual job entry."""
252    test_type = ndb.IntegerProperty()
253
254    hostname = ndb.StringProperty()
255    priority = ndb.StringProperty()
256    test_name = ndb.StringProperty()
257    require_signed_device_build = ndb.BooleanProperty()
258    has_bootloader_img = ndb.BooleanProperty()
259    has_radio_img = ndb.BooleanProperty()
260    device = ndb.StringProperty()
261    serial = ndb.StringProperty(repeated=True)
262
263    # device image information
264    build_storage_type = ndb.IntegerProperty()
265    manifest_branch = ndb.StringProperty()
266    build_target = ndb.StringProperty()
267    build_id = ndb.StringProperty()
268    pab_account_id = ndb.StringProperty()
269
270    shards = ndb.IntegerProperty()
271    param = ndb.StringProperty(repeated=True)
272    status = ndb.IntegerProperty()
273    period = ndb.IntegerProperty()
274
275    # GSI information
276    gsi_storage_type = ndb.IntegerProperty()
277    gsi_branch = ndb.StringProperty()
278    gsi_build_target = ndb.StringProperty()
279    gsi_build_id = ndb.StringProperty()
280    gsi_pab_account_id = ndb.StringProperty()
281    gsi_vendor_version = ndb.StringProperty()
282
283    # test suite information
284    test_storage_type = ndb.IntegerProperty()
285    test_branch = ndb.StringProperty()
286    test_build_target = ndb.StringProperty()
287    test_build_id = ndb.StringProperty()
288    test_pab_account_id = ndb.StringProperty()
289
290    timestamp = ndb.DateTimeProperty(auto_now=False)
291    heartbeat_stamp = ndb.DateTimeProperty(auto_now=False)
292    retry_count = ndb.IntegerProperty()
293
294    infra_log_url = ndb.StringProperty()
295
296    parent_schedule = ndb.KeyProperty(kind="ScheduleModel")
297
298    image_package_repo_base = ndb.StringProperty()
299
300    report_bucket = ndb.StringProperty(repeated=True)
301    report_spreadsheet_id = ndb.StringProperty(repeated=True)
302    report_persistent_url = ndb.StringProperty(repeated=True)
303    report_reference_url = ndb.StringProperty(repeated=True)
304
305
306class JobMessage(messages.Message):
307    """A message for representing an individual job entry."""
308    # Next ID = 39
309    test_type = messages.IntegerField(29)
310
311    hostname = messages.StringField(1)
312    priority = messages.StringField(2)
313    test_name = messages.StringField(3)
314    require_signed_device_build = messages.BooleanField(23)
315    has_bootloader_img = messages.BooleanField(31)
316    has_radio_img = messages.BooleanField(32)
317    device = messages.StringField(4)
318    serial = messages.StringField(5, repeated=True)
319
320    # device image information
321    build_storage_type = messages.IntegerField(25)
322    manifest_branch = messages.StringField(6)
323    build_target = messages.StringField(7)
324    build_id = messages.StringField(10)
325    pab_account_id = messages.StringField(20)
326
327    shards = messages.IntegerField(8)
328    param = messages.StringField(9, repeated=True)
329    status = messages.IntegerField(11)
330    period = messages.IntegerField(12)
331
332    # GSI information
333    gsi_storage_type = messages.IntegerField(26)
334    gsi_branch = messages.StringField(13)
335    gsi_build_target = messages.StringField(14)
336    gsi_build_id = messages.StringField(21)
337    gsi_pab_account_id = messages.StringField(15)
338    gsi_vendor_version = messages.StringField(28)
339
340    # test suite information
341    test_storage_type = messages.IntegerField(27)
342    test_branch = messages.StringField(16)
343    test_build_target = messages.StringField(17)
344    test_build_id = messages.StringField(22)
345    test_pab_account_id = messages.StringField(18)
346
347    retry_count = messages.IntegerField(19)
348
349    infra_log_url = messages.StringField(24)
350
351    image_package_repo_base = messages.StringField(30)
352
353    report_bucket = messages.StringField(33, repeated=True)
354    report_spreadsheet_id = messages.StringField(34, repeated=True)
355    report_persistent_url = messages.StringField(35, repeated=True)
356    report_reference_url = messages.StringField(36, repeated=True)
357
358    timestamp = message_types.DateTimeField(37)
359    heartbeat_stamp = message_types.DateTimeField(38)
360
361
362class ReturnCodeMessage(messages.Enum):
363    """Enum for default return code."""
364    SUCCESS = 0
365    FAIL = 1
366
367
368class DefaultResponse(messages.Message):
369    """A default response proto message."""
370    return_code = messages.EnumField(ReturnCodeMessage, 1)
371
372
373class JobLeaseResponse(messages.Message):
374    """A job lease response proto message."""
375    return_code = messages.EnumField(ReturnCodeMessage, 1)
376    jobs = messages.MessageField(JobMessage, 2, repeated=True)
377
378
379class KeyValueModel(ndb.Model):
380    """A simple key-value model.
381
382    This class uses name as key and store one value or more than one values
383    to store values which require continuous monitoring such as counters,
384    or flags.
385    """
386    name = ndb.StringProperty()
387    string_value = ndb.StringProperty()
388    integer_value = ndb.IntegerProperty()
389    boolean_value = ndb.BooleanProperty()
390
391
392class GetRequestMessage(messages.Message):
393    """A message to request entities through /get endpoints."""
394    size = messages.IntegerField(1)
395    offset = messages.IntegerField(2)
396    filter = messages.StringField(3)
397    sort = messages.StringField(4)
398    direction = messages.StringField(5)
399
400
401class BuildResponseMessage(messages.Message):
402    """A message containing build entities to respond to /get endpoints."""
403    builds = messages.MessageField(BuildInfoMessage, 1, repeated=True)
404    has_next = messages.BooleanField(2)
405
406
407class DeviceResponseMessage(messages.Message):
408    """A message containing device entities to respond to /get endpoints."""
409    devices = messages.MessageField(DeviceInfoMessage, 1, repeated=True)
410    has_next = messages.BooleanField(2)
411
412
413class JobResponseMessage(messages.Message):
414    """A message containing job entities to respond to /get endpoints."""
415    jobs = messages.MessageField(JobMessage, 1, repeated=True)
416    has_next = messages.BooleanField(2)
417
418
419class LabResponseMessage(messages.Message):
420    """A message containing lab entities to respond to /get endpoints."""
421    labs = messages.MessageField(LabMessage, 1, repeated=True)
422    has_next = messages.BooleanField(2)
423
424
425class ScheduleResponseMessage(messages.Message):
426    """A message containing schedule entities to respond to /get endpoints."""
427    schedules = messages.MessageField(ScheduleInfoMessage, 1, repeated=True)
428    has_next = messages.BooleanField(2)
429
430
431class CountRequestMessage(messages.Message):
432    """A message to request a count of entities through /count endpoints."""
433    filter = messages.StringField(1)
434
435
436class CountResponseMessage(messages.Message):
437    """A message of a count of entities to respond to /count endpoints."""
438    count = messages.IntegerField(1)
439
440
441class ScheduleSuspendMessage(messages.Message):
442    """A response message to schedule endpoint API's /suspend method."""
443
444    class SingleScheduleSuspendMessage(messages.Message):
445        urlsafe_key = messages.StringField(1)
446        suspend = messages.BooleanField(2)
447
448    schedules = messages.MessageField(
449        SingleScheduleSuspendMessage, 1, repeated=True)
450