blob: 0b05d38c6f728cda987fb56d7eb3dd3646b4ea95 [file] [log] [blame]
Alex Miller0516e4c2013-06-03 18:07:48 -07001# Copyright (c) 2013 The Chromium OS Authors. All rights reserved.
2# Use of this source code is governed by a BSD-style license that can be
3# found in the LICENSE file.
4
5
6import logging
7
8import common
9from autotest_lib.frontend.afe.json_rpc import proxy
10from autotest_lib.server import frontend
11
12
13### Constants for label prefixes
14CROS_VERSION_PREFIX = 'cros-version'
15
16
17### Helpers to convert value to label
18def cros_version_to_label(image):
19 """
20 Returns the proper label name for a ChromeOS build of |image|.
21
22 @param image: A string of the form 'lumpy-release/R28-3993.0.0'
23 @returns: A string that is the appropriate label name.
24
25 """
26 return CROS_VERSION_PREFIX + ':' + image
27
28
29# TODO(milleral): http://crbug.com/249555
30# Create some way to discover and register provisioning tests so that we don't
31# need to hand-maintain a list of all of them.
32_provision_types = {
33 CROS_VERSION_PREFIX:'provision_AutoUpdate',
34}
35
36
37def can_provision(label):
38 """
39 Returns True if the label is a label that we recognize as something we
40 know how to provision.
41
42 @param label: The label as a string.
43 @returns: True if there exists a test to provision the label.
44
45 """
46 return label.split(':')[0] in _provision_types
47
48
49def provisioner_for(name):
50 """
51 Returns the provisioning class associated with the given (string) name.
52
53 @param name: The name of the provision type being requested.
54 @returns: The subclass of Provisioner that was requested.
55 @raises KeyError: If the name was not recognized as a provision type.
56
57 """
58 return _provision_types[name]
59
60
61def filter_labels(labels):
62 """
63 Filter a list of labels into two sets: those labels that we know how to
64 change and those that we don't. For the ones we know how to change, split
65 them apart into the name of configuration type and its value.
66
67 @param labels: A list of strings of labels.
68 @returns: A tuple where the first element is a set of unprovisionable
69 labels, and the second element is a set of the provisionable
70 labels.
71
72 >>> filter_labels(['bluetooth', 'cros-version:lumpy-release/R28-3993.0.0'])
73 (set(['bluetooth']), set(['cros-version:lumpy-release/R28-3993.0.0']))
74
75 """
76 capabilities = set()
77 configurations = set()
78
79 for label in labels:
80 if can_provision(label):
81 configurations.add(label)
82 else:
83 capabilities.add(label)
84
85 return capabilities, configurations
86
87
88def split_labels(labels):
89 """
90 Split a list of labels into a dict mapping name to value. All labels must
91 be provisionable labels, or else a ValueError
92
93 @param labels: list of strings of label names
94 @returns: A dict of where the key is the configuration name, and the value
95 is the configuration value.
96 @raises: ValueError if a label is not a provisionable label.
97
98 >>> split_labels(['cros-version:lumpy-release/R28-3993.0.0'])
99 {'cros-version': 'lumpy-release/R28-3993.0.0'}
100 >>> split_labels(['bluetooth'])
101 Traceback (most recent call last):
102 ...
103 ValueError: Unprovisionable label bluetooth
104
105 """
106 configurations = dict()
107
108 for label in labels:
109 if can_provision(label):
110 name, value = label.split(':', 1)
111 configurations[name] = value
112 else:
113 raise ValueError('Unprovisionable label %s' % label)
114
115 return configurations
116
117
118# This has been copied out of dynamic_suite's reimager.py, which will be killed
119# off in a future CL. I'd prefer if this would go away by doing
120# http://crbug.com/249424, so that labels are just automatically made when we
121# try to add them to a host.
122def ensure_label_exists(name):
123 """
124 Ensure that a label called |name| exists in the autotest DB.
125
126 @param name: the label to check for/create.
127 @raises ValidationError: There was an error in the response that was
128 not because the label already existed.
129
130 """
131 afe = frontend.AFE()
132 try:
133 afe.create_label(name=name)
134 except proxy.ValidationError as ve:
135 if ('name' in ve.problem_keys and
136 'This value must be unique' in ve.problem_keys['name']):
137 logging.debug('Version label %s already exists', name)
138 else:
139 raise ve