1# 2# Copyright (C) 2016 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 logging 18 19from vts.proto import ComponentSpecificationMessage_pb2 as CompSpecMsg 20import logging 21 22 23def PyValue2PbEnum(message, pb_spec, py_value): 24 """Converts Python value to VTS VariableSecificationMessage (Enum). 25 26 Args: 27 message: VariableSpecificationMessage is the current and result 28 value message. 29 pb_spec: VariableSpecificationMessage which captures the 30 specification of a target attribute. 31 py_value: Python value provided by a test case. 32 33 Returns: 34 Converted VariableSpecificationMessage if found, None otherwise 35 """ 36 if pb_spec.name: 37 message.name = pb_spec.name 38 message.type = CompSpecMsg.TYPE_ENUM 39 # TODO(yim): derive the type by looking up its predefined_type. 40 setattr(message.scalar_value, "int32_t", py_value) 41 42 43def PyValue2PbScalar(message, pb_spec, py_value): 44 """Converts Python value to VTS VariableSecificationMessage (Scalar). 45 46 Args: 47 message: VariableSpecificationMessage is the current and result 48 value message. 49 pb_spec: VariableSpecificationMessage which captures the 50 specification of a target attribute. 51 py_value: Python value provided by a test case. 52 53 Returns: 54 Converted VariableSpecificationMessage if found, None otherwise 55 """ 56 if pb_spec.name: 57 message.name = pb_spec.name 58 message.type = CompSpecMsg.TYPE_SCALAR 59 message.scalar_type = pb_spec.scalar_type 60 setattr(message.scalar_value, pb_spec.scalar_type, py_value) 61 62 63def PyString2PbString(message, pb_spec, py_value): 64 """Converts Python string to VTS VariableSecificationMessage (String). 65 66 Args: 67 message: VariableSpecificationMessage is the current and result 68 value message. 69 pb_spec: VariableSpecificationMessage which captures the 70 specification of a target attribute. 71 py_value: Python value provided by a test case. 72 73 Returns: 74 Converted VariableSpecificationMessage if found, None otherwise 75 """ 76 if pb_spec.name: 77 message.name = pb_spec.name 78 message.type = CompSpecMsg.TYPE_STRING 79 message.string_value.message = py_value 80 message.string_value.length = len(py_value) 81 82 83def PyList2PbVector(message, pb_spec, py_value): 84 """Converts Python list value to VTS VariableSecificationMessage (Vector). 85 86 Args: 87 message: VariableSpecificationMessage is the current and result 88 value message. 89 pb_spec: VariableSpecificationMessage which captures the 90 specification of a target attribute. 91 py_value: Python value provided by a test case. 92 93 Returns: 94 Converted VariableSpecificationMessage if found, None otherwise 95 """ 96 if pb_spec.name: 97 message.name = pb_spec.name 98 message.type = CompSpecMsg.TYPE_VECTOR 99 if len(py_value) == 0: 100 return message 101 102 vector_spec = pb_spec.vector_value[0] 103 for curr_value in py_value: 104 new_vector_message = message.vector_value.add() 105 if vector_spec.type == CompSpecMsg.TYPE_SCALAR: 106 PyValue2PbScalar(new_vector_message, vector_spec, curr_value) 107 else: 108 logging.error("unsupported type %s", message.type) 109 sys.exit(-1) 110 message.vector_size = len(py_value) 111 return message 112 113 114def FindSubStructType(pb_spec, sub_struct_name): 115 """Finds a specific sub_struct type. 116 117 Args: 118 pb_spec: VariableSpecificationMessage which captures the 119 specification of a target attribute. 120 sub_struct_name: string, the name of a sub struct to look up. 121 122 Returns: 123 VariableSpecificationMessage if found or None otherwise. 124 """ 125 for sub_struct in pb_spec.sub_struct: 126 if sub_struct.name == sub_struct_name: 127 return sub_struct 128 return None 129 130 131def PyDict2PbStruct(message, pb_spec, py_value): 132 """Converts Python dict to VTS VariableSecificationMessage (struct). 133 134 Args: 135 pb_spec: VariableSpecificationMessage which captures the 136 specification of a target attribute. 137 py_value: Python value provided by a test case. 138 139 Returns: 140 Converted VariableSpecificationMessage if found, None otherwise 141 """ 142 if pb_spec.name: 143 message.name = pb_spec.name 144 message.type = CompSpecMsg.TYPE_STRUCT 145 provided_attrs = set(py_value.keys()) 146 for attr in pb_spec.struct_value: 147 if attr.name in py_value: 148 provided_attrs.remove(attr.name) 149 curr_value = py_value[attr.name] 150 attr_msg = message.struct_value.add() 151 if attr.type == CompSpecMsg.TYPE_ENUM: 152 PyValue2PbEnum(attr_msg, attr, curr_value) 153 elif attr.type == CompSpecMsg.TYPE_SCALAR: 154 PyValue2PbScalar(attr_msg, attr, curr_value) 155 elif attr.type == CompSpecMsg.TYPE_STRING: 156 PyString2PbString(attr_msg, attr, curr_value) 157 elif attr.type == CompSpecMsg.TYPE_VECTOR: 158 PyList2PbVector(attr_msg, attr, curr_value) 159 elif attr.type == CompSpecMsg.TYPE_STRUCT: 160 sub_attr = FindSubStructType(pb_spec, attr.predefined_type) 161 if sub_attr: 162 PyDict2PbStruct(attr_msg, sub_attr, curr_value) 163 else: 164 logging.error("PyDict2PbStruct: substruct not found.") 165 sys.exit(-1) 166 else: 167 logging.error("PyDict2PbStruct: unsupported type %s", 168 attr.type) 169 sys.exit(-1) 170 if len(provided_attrs) > 0: 171 logging.error("PyDict2PbStruct: provided dictionary included elements" + 172 " not part of the type being converted to: %s", 173 provided_attrs) 174 sys.exit(-1) 175 return message 176 177 178def Convert(pb_spec, py_value): 179 """Converts Python native data structure to VTS VariableSecificationMessage. 180 181 Args: 182 pb_spec: VariableSpecificationMessage which captures the 183 specification of a target attribute. 184 py_value: Python value provided by a test case. 185 186 Returns: 187 Converted VariableSpecificationMessage if found, None otherwise 188 """ 189 if not pb_spec: 190 logging.error("py2pb.Convert: ProtoBuf spec is None", pb_spec) 191 return None 192 193 message = CompSpecMsg.VariableSpecificationMessage() 194 message.name = pb_spec.name 195 196 if pb_spec.type == CompSpecMsg.TYPE_STRUCT: 197 PyDict2PbStruct(message, pb_spec, py_value) 198 elif pb_spec.type == CompSpecMsg.TYPE_ENUM: 199 PyValue2PbEnum(message, pb_spec, py_value) 200 elif pb_spec.type == CompSpecMsg.TYPE_SCALAR: 201 PyValue2PbScalar(message, pb_spec, py_value) 202 elif pb_spec.type == CompSpecMsg.TYPE_STRING: 203 PyString2PbString(attr_msg, attr, curr_value) 204 elif pb_spec.type == CompSpecMsg.TYPE_VECTOR: 205 PyList2PbVector(message, pb_spec, py_value) 206 else: 207 logging.error("py2pb.Convert: unsupported type %s", 208 pb_spec.type) 209 sys.exit(-1) 210 211 return message 212