diff --git a/ChangeLog.txt b/ChangeLog.txt index 38eac376ef8d..c9af47f03db2 100644 --- a/ChangeLog.txt +++ b/ChangeLog.txt @@ -1,3 +1,10 @@ +2012-12-17 Version 0.6.1 + * Fixes for bugs: + #69 _get_readable_id doesn't support queues with slashes in their names + #68 Service bus cache of tokens doesn't support multiple creds in same app + #66 Need to change the default timeout for httprequest on windows + * Improved support for unicode data + 2012-10-16 Version 0.6.0 * Added service management API * Added ability to specify custom hosts diff --git a/src/azure.pyproj b/src/azure.pyproj index c76335724cb3..fc124380af94 100644 --- a/src/azure.pyproj +++ b/src/azure.pyproj @@ -6,8 +6,7 @@ {25b2c65a-0553-4452-8907-8b5b17544e68} - - + azure\storage\blobservice.py .. . . diff --git a/src/azure/__init__.py b/src/azure/__init__.py index 7ede4ce9b1c3..94a5ab1765eb 100644 --- a/src/azure/__init__.py +++ b/src/azure/__init__.py @@ -95,15 +95,23 @@ class HeaderDict(dict): def __getitem__(self, index): return super(HeaderDict, self).__getitem__(index.lower()) -def _get_readable_id(id_name): +def _get_readable_id(id_name, id_prefix_to_skip): """simplified an id to be more friendly for us people""" - pos = id_name.rfind('/') + # id_name is in the form 'https://namespace.host.suffix/name' + # where name may contain a forward slash! + pos = id_name.find('//') if pos != -1: - return id_name[pos+1:] - else: - return id_name - -def _get_entry_properties(xmlstr, include_id): + pos += 2 + if id_prefix_to_skip: + pos = id_name.find(id_prefix_to_skip, pos) + if pos != -1: + pos += len(id_prefix_to_skip) + pos = id_name.find('/', pos) + if pos != -1: + return id_name[pos+1:] + return id_name + +def _get_entry_properties(xmlstr, include_id, id_prefix_to_skip=None): ''' get properties from entry xml ''' xmldoc = minidom.parseString(xmlstr) properties = {} @@ -120,7 +128,7 @@ def _get_entry_properties(xmlstr, include_id): if include_id: for id in _get_child_nodes(entry, 'id'): - properties['name'] = _get_readable_id(id.firstChild.nodeValue) + properties['name'] = _get_readable_id(id.firstChild.nodeValue, id_prefix_to_skip) return properties @@ -207,7 +215,16 @@ def _get_serialization_name(element_name): return ''.join(name.capitalize() for name in element_name.split('_')) +def _str(value): + if isinstance(value, unicode): + return value.encode('utf-8') + + return str(value) + def _str_or_none(value): + if isinstance(value, unicode): + return value.encode('utf-8') + if value is None: return None @@ -375,9 +392,8 @@ def _fill_dict_of(xmldoc, parent_xml_element_name, pair_xml_element_name, key_xm keys = _get_child_nodes(pair, key_xml_element_name) values = _get_child_nodes(pair, value_xml_element_name) if keys and values: - key = str(keys[0].firstChild.nodeValue) - value = str(values[0].firstChild.nodeValue) - + key = keys[0].firstChild.nodeValue + value = values[0].firstChild.nodeValue return_obj[key] = value return return_obj @@ -436,7 +452,7 @@ def _get_request_body(request_body): elif isinstance(request_body, WindowsAzureData): return _convert_class_to_xml(request_body) - return request_body + return _str(request_body) def _parse_enum_results_list(response, return_type, resp_type, item_type): """resp_body is the XML we received @@ -514,6 +530,9 @@ def _fill_data_to_return_object(node, return_obj): value = _fill_data_minidom(node, name, '') if value is not None: value = base64.b64decode(value) + try: + value = value.decode('utf-8') + except: pass #always set the attribute, so we don't end up returning an object with type _Base64String setattr(return_obj, name, value) else: diff --git a/src/azure/http/winhttp.py b/src/azure/http/winhttp.py index 139654f9cf53..6c67ef69a3a4 100644 --- a/src/azure/http/winhttp.py +++ b/src/azure/http/winhttp.py @@ -163,6 +163,7 @@ def open(self, method, url): method: the request VERB 'GET', 'POST', etc. url: the url to connect ''' + _WinHttpRequest._SetTimeouts(self, 0, 65000, 65000, 65000) flag = VARIANT() flag.vt = VT_BOOL @@ -321,11 +322,12 @@ def putrequest(self, method, uri): #sets certificate for the connection if cert_file is set. if self.cert_file is not None: - self._httprequest.set_client_certificate(BSTR(unicode(self.cert_file))) + self._httprequest.set_client_certificate(unicode(self.cert_file)) def putheader(self, name, value): ''' Sends the headers of request. ''' - self._httprequest.set_request_header(unicode(name), unicode(value)) + self._httprequest.set_request_header(str(name).decode('utf-8'), + str(value).decode('utf-8')) def endheaders(self): ''' No operation. Exists only to provide the same interface of httplib HTTPConnection.''' diff --git a/src/azure/servicebus/__init__.py b/src/azure/servicebus/__init__.py index a42a19a99c5d..d10e26dba380 100644 --- a/src/azure/servicebus/__init__.py +++ b/src/azure/servicebus/__init__.py @@ -190,7 +190,9 @@ def add_headers(self, request): # Adds custom properties if self.custom_properties: for name, value in self.custom_properties.iteritems(): - if isinstance(value, str): + if isinstance(value, unicode): + request.headers.append((name, '"' + value.encode('utf-8') + '"')) + elif isinstance(value, str): request.headers.append((name, '"' + str(value) + '"')) elif isinstance(value, datetime): request.headers.append((name, '"' + value.strftime('%a, %d %b %Y %H:%M:%S GMT') + '"')) @@ -248,8 +250,8 @@ def _get_token(request, account_key, issuer): account_key: service bus access key issuer: service bus issuer ''' - wrap_scope = 'http://' + request.host + request.path - + wrap_scope = 'http://' + request.host + request.path + issuer + account_key + # Check whether has unexpired cache, return cached token if it is still usable. if _tokens.has_key(wrap_scope): token = _tokens[wrap_scope] @@ -371,7 +373,7 @@ def _convert_xml_to_rule(xmlstr): setattr(rule, 'action_expression', action_expression.nodeValue) #extract id, updated and name value from feed entry and set them of rule. - for name, value in _get_entry_properties(xmlstr, True).iteritems(): + for name, value in _get_entry_properties(xmlstr, True, '/rules').iteritems(): setattr(rule, name, value) return rule @@ -565,7 +567,7 @@ def _convert_xml_to_subscription(xmlstr): if node_value is not None: subscription.message_count = int(node_value) - for name, value in _get_entry_properties(xmlstr, True).iteritems(): + for name, value in _get_entry_properties(xmlstr, True, '/subscriptions').iteritems(): setattr(subscription, name, value) return subscription diff --git a/src/azure/servicebus/servicebusservice.py b/src/azure/servicebus/servicebusservice.py index 81f6ed1bba8b..79353f00156e 100644 --- a/src/azure/servicebus/servicebusservice.py +++ b/src/azure/servicebus/servicebusservice.py @@ -29,7 +29,7 @@ AZURE_SERVICEBUS_ACCESS_KEY, AZURE_SERVICEBUS_ISSUER) from azure.http import HTTPRequest, HTTP_RESPONSE_NO_CONTENT from azure import (_validate_not_none, Feed, - _convert_response_to_feeds, _str_or_none, _int_or_none, + _convert_response_to_feeds, _str, _str_or_none, _int_or_none, _get_request_body, _update_request_uri_query, _dont_fail_on_exist, _dont_fail_not_exist, WindowsAzureConflictError, WindowsAzureError, _parse_response, _convert_class_to_xml, @@ -52,7 +52,7 @@ def create_queue(self, queue_name, queue=None, fail_on_exist=False): request = HTTPRequest() request.method = 'PUT' request.host = self._get_host() - request.path = '/' + str(queue_name) + '' + request.path = '/' + _str(queue_name) + '' request.body = _get_request_body(convert_queue_to_xml(queue)) request.path, request.query = _update_request_uri_query(request) request.headers = _update_service_bus_header(request, self.account_key, self.issuer) @@ -78,7 +78,7 @@ def delete_queue(self, queue_name, fail_not_exist=False): request = HTTPRequest() request.method = 'DELETE' request.host = self._get_host() - request.path = '/' + str(queue_name) + '' + request.path = '/' + _str(queue_name) + '' request.path, request.query = _update_request_uri_query(request) request.headers = _update_service_bus_header(request, self.account_key, self.issuer) if not fail_not_exist: @@ -102,7 +102,7 @@ def get_queue(self, queue_name): request = HTTPRequest() request.method = 'GET' request.host = self._get_host() - request.path = '/' + str(queue_name) + '' + request.path = '/' + _str(queue_name) + '' request.path, request.query = _update_request_uri_query(request) request.headers = _update_service_bus_header(request, self.account_key, self.issuer) response = self._perform_request(request) @@ -135,7 +135,7 @@ def create_topic(self, topic_name, topic=None, fail_on_exist=False): request = HTTPRequest() request.method = 'PUT' request.host = self._get_host() - request.path = '/' + str(topic_name) + '' + request.path = '/' + _str(topic_name) + '' request.body = _get_request_body(convert_topic_to_xml(topic)) request.path, request.query = _update_request_uri_query(request) request.headers = _update_service_bus_header(request, self.account_key, self.issuer) @@ -162,7 +162,7 @@ def delete_topic(self, topic_name, fail_not_exist=False): request = HTTPRequest() request.method = 'DELETE' request.host = self._get_host() - request.path = '/' + str(topic_name) + '' + request.path = '/' + _str(topic_name) + '' request.path, request.query = _update_request_uri_query(request) request.headers = _update_service_bus_header(request, self.account_key, self.issuer) if not fail_not_exist: @@ -186,7 +186,7 @@ def get_topic(self, topic_name): request = HTTPRequest() request.method = 'GET' request.host = self._get_host() - request.path = '/' + str(topic_name) + '' + request.path = '/' + _str(topic_name) + '' request.path, request.query = _update_request_uri_query(request) request.headers = _update_service_bus_header(request, self.account_key, self.issuer) response = self._perform_request(request) @@ -222,7 +222,7 @@ def create_rule(self, topic_name, subscription_name, rule_name, rule=None, fail_ request = HTTPRequest() request.method = 'PUT' request.host = self._get_host() - request.path = '/' + str(topic_name) + '/subscriptions/' + str(subscription_name) + '/rules/' + str(rule_name) + '' + request.path = '/' + _str(topic_name) + '/subscriptions/' + _str(subscription_name) + '/rules/' + _str(rule_name) + '' request.body = _get_request_body(convert_rule_to_xml(rule)) request.path, request.query = _update_request_uri_query(request) request.headers = _update_service_bus_header(request, self.account_key, self.issuer) @@ -253,7 +253,7 @@ def delete_rule(self, topic_name, subscription_name, rule_name, fail_not_exist=F request = HTTPRequest() request.method = 'DELETE' request.host = self._get_host() - request.path = '/' + str(topic_name) + '/subscriptions/' + str(subscription_name) + '/rules/' + str(rule_name) + '' + request.path = '/' + _str(topic_name) + '/subscriptions/' + _str(subscription_name) + '/rules/' + _str(rule_name) + '' request.path, request.query = _update_request_uri_query(request) request.headers = _update_service_bus_header(request, self.account_key, self.issuer) if not fail_not_exist: @@ -281,7 +281,7 @@ def get_rule(self, topic_name, subscription_name, rule_name): request = HTTPRequest() request.method = 'GET' request.host = self._get_host() - request.path = '/' + str(topic_name) + '/subscriptions/' + str(subscription_name) + '/rules/' + str(rule_name) + '' + request.path = '/' + _str(topic_name) + '/subscriptions/' + _str(subscription_name) + '/rules/' + _str(rule_name) + '' request.path, request.query = _update_request_uri_query(request) request.headers = _update_service_bus_header(request, self.account_key, self.issuer) response = self._perform_request(request) @@ -300,7 +300,7 @@ def list_rules(self, topic_name, subscription_name): request = HTTPRequest() request.method = 'GET' request.host = self._get_host() - request.path = '/' + str(topic_name) + '/subscriptions/' + str(subscription_name) + '/rules/' + request.path = '/' + _str(topic_name) + '/subscriptions/' + _str(subscription_name) + '/rules/' request.path, request.query = _update_request_uri_query(request) request.headers = _update_service_bus_header(request, self.account_key, self.issuer) response = self._perform_request(request) @@ -321,7 +321,7 @@ def create_subscription(self, topic_name, subscription_name, subscription=None, request = HTTPRequest() request.method = 'PUT' request.host = self._get_host() - request.path = '/' + str(topic_name) + '/subscriptions/' + str(subscription_name) + '' + request.path = '/' + _str(topic_name) + '/subscriptions/' + _str(subscription_name) + '' request.body = _get_request_body(convert_subscription_to_xml(subscription)) request.path, request.query = _update_request_uri_query(request) request.headers = _update_service_bus_header(request, self.account_key, self.issuer) @@ -349,7 +349,7 @@ def delete_subscription(self, topic_name, subscription_name, fail_not_exist=Fals request = HTTPRequest() request.method = 'DELETE' request.host = self._get_host() - request.path = '/' + str(topic_name) + '/subscriptions/' + str(subscription_name) + '' + request.path = '/' + _str(topic_name) + '/subscriptions/' + _str(subscription_name) + '' request.path, request.query = _update_request_uri_query(request) request.headers = _update_service_bus_header(request, self.account_key, self.issuer) if not fail_not_exist: @@ -375,7 +375,7 @@ def get_subscription(self, topic_name, subscription_name): request = HTTPRequest() request.method = 'GET' request.host = self._get_host() - request.path = '/' + str(topic_name) + '/subscriptions/' + str(subscription_name) + '' + request.path = '/' + _str(topic_name) + '/subscriptions/' + _str(subscription_name) + '' request.path, request.query = _update_request_uri_query(request) request.headers = _update_service_bus_header(request, self.account_key, self.issuer) response = self._perform_request(request) @@ -392,7 +392,7 @@ def list_subscriptions(self, topic_name): request = HTTPRequest() request.method = 'GET' request.host = self._get_host() - request.path = '/' + str(topic_name) + '/subscriptions/' + request.path = '/' + _str(topic_name) + '/subscriptions/' request.path, request.query = _update_request_uri_query(request) request.headers = _update_service_bus_header(request, self.account_key, self.issuer) response = self._perform_request(request) @@ -413,7 +413,7 @@ def send_topic_message(self, topic_name, message=None): request = HTTPRequest() request.method = 'POST' request.host = self._get_host() - request.path = '/' + str(topic_name) + '/messages' + request.path = '/' + _str(topic_name) + '/messages' request.headers = message.add_headers(request) request.body = _get_request_body(message.body) request.path, request.query = _update_request_uri_query(request) @@ -441,7 +441,7 @@ def peek_lock_subscription_message(self, topic_name, subscription_name, timeout= request = HTTPRequest() request.method = 'POST' request.host = self._get_host() - request.path = '/' + str(topic_name) + '/subscriptions/' + str(subscription_name) + '/messages/head' + request.path = '/' + _str(topic_name) + '/subscriptions/' + _str(subscription_name) + '/messages/head' request.query = [('timeout', _int_or_none(timeout))] request.path, request.query = _update_request_uri_query(request) request.headers = _update_service_bus_header(request, self.account_key, self.issuer) @@ -470,7 +470,7 @@ def unlock_subscription_message(self, topic_name, subscription_name, sequence_nu request = HTTPRequest() request.method = 'PUT' request.host = self._get_host() - request.path = '/' + str(topic_name) + '/subscriptions/' + str(subscription_name) + '/messages/' + str(sequence_number) + '/' + str(lock_token) + '' + request.path = '/' + _str(topic_name) + '/subscriptions/' + _str(subscription_name) + '/messages/' + _str(sequence_number) + '/' + _str(lock_token) + '' request.path, request.query = _update_request_uri_query(request) request.headers = _update_service_bus_header(request, self.account_key, self.issuer) response = self._perform_request(request) @@ -490,7 +490,7 @@ def read_delete_subscription_message(self, topic_name, subscription_name, timeou request = HTTPRequest() request.method = 'DELETE' request.host = self._get_host() - request.path = '/' + str(topic_name) + '/subscriptions/' + str(subscription_name) + '/messages/head' + request.path = '/' + _str(topic_name) + '/subscriptions/' + _str(subscription_name) + '/messages/head' request.query = [('timeout', _int_or_none(timeout))] request.path, request.query = _update_request_uri_query(request) request.headers = _update_service_bus_header(request, self.account_key, self.issuer) @@ -518,7 +518,7 @@ def delete_subscription_message(self, topic_name, subscription_name, sequence_nu request = HTTPRequest() request.method = 'DELETE' request.host = self._get_host() - request.path = '/' + str(topic_name) + '/subscriptions/' + str(subscription_name) + '/messages/' + str(sequence_number) + '/' + str(lock_token) + '' + request.path = '/' + _str(topic_name) + '/subscriptions/' + _str(subscription_name) + '/messages/' + _str(sequence_number) + '/' + _str(lock_token) + '' request.path, request.query = _update_request_uri_query(request) request.headers = _update_service_bus_header(request, self.account_key, self.issuer) response = self._perform_request(request) @@ -537,7 +537,7 @@ def send_queue_message(self, queue_name, message=None): request = HTTPRequest() request.method = 'POST' request.host = self._get_host() - request.path = '/' + str(queue_name) + '/messages' + request.path = '/' + _str(queue_name) + '/messages' request.headers = message.add_headers(request) request.body = _get_request_body(message.body) request.path, request.query = _update_request_uri_query(request) @@ -562,7 +562,7 @@ def peek_lock_queue_message(self, queue_name, timeout='60'): request = HTTPRequest() request.method = 'POST' request.host = self._get_host() - request.path = '/' + str(queue_name) + '/messages/head' + request.path = '/' + _str(queue_name) + '/messages/head' request.query = [('timeout', _int_or_none(timeout))] request.path, request.query = _update_request_uri_query(request) request.headers = _update_service_bus_header(request, self.account_key, self.issuer) @@ -589,7 +589,7 @@ def unlock_queue_message(self, queue_name, sequence_number, lock_token): request = HTTPRequest() request.method = 'PUT' request.host = self._get_host() - request.path = '/' + str(queue_name) + '/messages/' + str(sequence_number) + '/' + str(lock_token) + '' + request.path = '/' + _str(queue_name) + '/messages/' + _str(sequence_number) + '/' + _str(lock_token) + '' request.path, request.query = _update_request_uri_query(request) request.headers = _update_service_bus_header(request, self.account_key, self.issuer) response = self._perform_request(request) @@ -607,7 +607,7 @@ def read_delete_queue_message(self, queue_name, timeout='60'): request = HTTPRequest() request.method = 'DELETE' request.host = self._get_host() - request.path = '/' + str(queue_name) + '/messages/head' + request.path = '/' + _str(queue_name) + '/messages/head' request.query = [('timeout', _int_or_none(timeout))] request.path, request.query = _update_request_uri_query(request) request.headers = _update_service_bus_header(request, self.account_key, self.issuer) @@ -633,7 +633,7 @@ def delete_queue_message(self, queue_name, sequence_number, lock_token): request = HTTPRequest() request.method = 'DELETE' request.host = self._get_host() - request.path = '/' + str(queue_name) + '/messages/' + str(sequence_number) + '/' + str(lock_token) + '' + request.path = '/' + _str(queue_name) + '/messages/' + _str(sequence_number) + '/' + _str(lock_token) + '' request.path, request.query = _update_request_uri_query(request) request.headers = _update_service_bus_header(request, self.account_key, self.issuer) response = self._perform_request(request) diff --git a/src/azure/servicemanagement/__init__.py b/src/azure/servicemanagement/__init__.py index 5fe33fb49858..23c31aae4f41 100644 --- a/src/azure/servicemanagement/__init__.py +++ b/src/azure/servicemanagement/__init__.py @@ -15,11 +15,7 @@ import base64 from azure.http import HTTPError from azure import (WindowsAzureError, WindowsAzureData, _general_error_handler, - _create_entry, _get_entry_properties, xml_escape, - _get_child_nodes, WindowsAzureMissingResourceError, - WindowsAzureConflictError, _get_serialization_name, - _list_of, _scalar_list_of, _dict_of, _Base64String, - _get_children_from_path, _get_first_child_node_value) + _str, _list_of, _scalar_list_of, _dict_of, _Base64String) import azure #----------------------------------------------------------------------------- @@ -57,23 +53,23 @@ def __init__(self): class StorageAccountProperties(WindowsAzureData): def __init__(self): - self.description = '' - self.affinity_group = '' - self.location = '' + self.description = u'' + self.affinity_group = u'' + self.location = u'' self.label = _Base64String() - self.status = '' + self.status = u'' self.endpoints = _scalar_list_of(str, 'Endpoint') self.geo_replication_enabled = False - self.geo_primary_region = '' - self.status_of_primary = '' - self.geo_secondary_region = '' - self.status_of_secondary = '' - self.last_geo_failover_time = '' + self.geo_primary_region = u'' + self.status_of_primary = u'' + self.geo_secondary_region = u'' + self.status_of_secondary = u'' + self.last_geo_failover_time = u'' class StorageServiceKeys(WindowsAzureData): def __init__(self): - self.primary = '' - self.secondary = '' + self.primary = u'' + self.secondary = u'' class Locations(WindowsAzureData): def __init__(self): @@ -90,16 +86,16 @@ def __getitem__(self, index): class Location(WindowsAzureData): def __init__(self): - self.name = '' - self.display_name = '' + self.name = u'' + self.display_name = u'' self.available_services = _scalar_list_of(str, 'AvailableService') class AffinityGroup(WindowsAzureData): def __init__(self): self.name = '' self.label = _Base64String() - self.description = '' - self.location = '' + self.description = u'' + self.location = u'' self.hosted_services = HostedServices() self.storage_services = StorageServices() self.capabilities = _scalar_list_of(str, 'Capability') @@ -132,20 +128,20 @@ def __getitem__(self, index): class HostedService(WindowsAzureData): def __init__(self): - self.url = '' - self.service_name = '' + self.url = u'' + self.service_name = u'' self.hosted_service_properties = HostedServiceProperties() self.deployments = Deployments() class HostedServiceProperties(WindowsAzureData): def __init__(self): - self.description = '' - self.location = '' - self.affinity_group = '' + self.description = u'' + self.location = u'' + self.affinity_group = u'' self.label = _Base64String() - self.status = '' - self.date_created = '' - self.date_last_modified = '' + self.status = u'' + self.date_created = u'' + self.date_last_modified = u'' self.extended_properties = _dict_of('ExtendedProperty', 'Name', 'Value') class Deployments(WindowsAzureData): @@ -163,24 +159,24 @@ def __getitem__(self, index): class Deployment(WindowsAzureData): def __init__(self): - self.name = '' - self.deployment_slot = '' - self.private_id = '' - self.status = '' + self.name = u'' + self.deployment_slot = u'' + self.private_id = u'' + self.status = u'' self.label = _Base64String() - self.url = '' + self.url = u'' self.configuration = _Base64String() self.role_instance_list = RoleInstanceList() self.upgrade_status = UpgradeStatus() - self.upgrade_domain_count = '' + self.upgrade_domain_count = u'' self.role_list = RoleList() - self.sdk_version = '' + self.sdk_version = u'' self.input_endpoint_list = InputEndpoints() self.locked = False self.rollback_allowed = False self.persistent_vm_downtime_info = PersistentVMDowntimeInfo() - self.created_time = '' - self.last_modified_time = '' + self.created_time = u'' + self.last_modified_time = u'' self.extended_properties = _dict_of('ExtendedProperty', 'Name', 'Value') class RoleInstanceList(WindowsAzureData): @@ -198,23 +194,23 @@ def __getitem__(self, index): class RoleInstance(WindowsAzureData): def __init__(self): - self.role_name = '' - self.instance_name = '' - self.instance_status = '' + self.role_name = u'' + self.instance_name = u'' + self.instance_status = u'' self.instance_upgrade_domain = 0 self.instance_fault_domain = 0 - self.instance_size = '' - self.instance_state_details = '' - self.instance_error_code = '' - self.ip_address = '' - self.power_state = '' - self.fqdn = '' + self.instance_size = u'' + self.instance_state_details = u'' + self.instance_error_code = u'' + self.ip_address = u'' + self.power_state = u'' + self.fqdn = u'' class UpgradeStatus(WindowsAzureData): def __init__(self): - self.upgrade_type = '' - self.current_upgrade_domain_state = '' - self.current_upgrade_domain = '' + self.upgrade_type = u'' + self.current_upgrade_domain_state = u'' + self.current_upgrade_domain = u'' class InputEndpoints(WindowsAzureData): def __init__(self): @@ -231,9 +227,9 @@ def __getitem__(self, index): class InputEndpoint(WindowsAzureData): def __init__(self): - self.role_name = '' - self.vip = '' - self.port = '' + self.role_name = u'' + self.vip = u'' + self.port = u'' class RoleList(WindowsAzureData): def __init__(self): @@ -250,14 +246,14 @@ def __getitem__(self, index): class Role(WindowsAzureData): def __init__(self): - self.role_name = '' - self.os_version = '' + self.role_name = u'' + self.os_version = u'' class PersistentVMDowntimeInfo(WindowsAzureData): def __init__(self): - self.start_time = '' - self.end_time = '' - self.status = '' + self.start_time = u'' + self.end_time = u'' + self.status = u'' class Certificates(WindowsAzureData): def __init__(self): @@ -274,26 +270,26 @@ def __getitem__(self, index): class Certificate(WindowsAzureData): def __init__(self): - self.certificate_url = '' - self.thumbprint = '' - self.thumbprint_algorithm = '' - self.data = '' + self.certificate_url = u'' + self.thumbprint = u'' + self.thumbprint_algorithm = u'' + self.data = u'' class OperationError(WindowsAzureData): def __init__(self): - self.code = '' - self.message = '' + self.code = u'' + self.message = u'' class Operation(WindowsAzureData): def __init__(self): - self.id = '' - self.status = '' - self.http_status_code = '' + self.id = u'' + self.status = u'' + self.http_status_code = u'' self.error = OperationError() class OperatingSystem(WindowsAzureData): def __init__(self): - self.version = '' + self.version = u'' self.label = _Base64String() self.is_default = True self.is_active = True @@ -315,7 +311,7 @@ def __getitem__(self, index): class OperatingSystemFamily(WindowsAzureData): def __init__(self): - self.name = '' + self.name = u'' self.label = _Base64String() self.operating_systems = OperatingSystems() @@ -334,11 +330,11 @@ def __getitem__(self, index): class Subscription(WindowsAzureData): def __init__(self): - self.subscription_id = '' - self.subscription_name = '' - self.subscription_status = '' - self.account_admin_live_email_id = '' - self.service_admin_live_email_id = '' + self.subscription_id = u'' + self.subscription_name = u'' + self.subscription_status = u'' + self.account_admin_live_email_id = u'' + self.service_admin_live_email_id = u'' self.max_core_count = 0 self.max_storage_accounts = 0 self.max_hosted_services = 0 @@ -368,10 +364,10 @@ def __getitem__(self, index): class SubscriptionCertificate(WindowsAzureData): def __init__(self): - self.subscription_certificate_public_key = '' - self.subscription_certificate_thumbprint = '' - self.subscription_certificate_data = '' - self.created = '' + self.subscription_certificate_public_key = u'' + self.subscription_certificate_thumbprint = u'' + self.subscription_certificate_data = u'' + self.created = u'' class Images(WindowsAzureData): def __init__(self): @@ -388,16 +384,16 @@ def __getitem__(self, index): class OSImage(WindowsAzureData): def __init__(self): - self.affinity_group = '' - self.category = '' - self.location = '' + self.affinity_group = u'' + self.category = u'' + self.location = u'' self.logical_size_in_gb = 0 - self.label = '' - self.media_link = '' - self.name = '' - self.os = '' - self.eula = '' - self.description = '' + self.label = u'' + self.media_link = u'' + self.name = u'' + self.os = u'' + self.eula = u'' + self.description = u'' class Disks(WindowsAzureData): def __init__(self): @@ -414,34 +410,34 @@ def __getitem__(self, index): class Disk(WindowsAzureData): def __init__(self): - self.affinity_group = '' + self.affinity_group = u'' self.attached_to = AttachedTo() - self.has_operating_system = '' - self.is_corrupted = '' - self.location = '' + self.has_operating_system = u'' + self.is_corrupted = u'' + self.location = u'' self.logical_disk_size_in_gb = 0 - self.label = '' - self.media_link= '' - self.name = '' - self.os = '' - self.source_image_name = '' + self.label = u'' + self.media_link = u'' + self.name = u'' + self.os = u'' + self.source_image_name = u'' class AttachedTo(WindowsAzureData): def __init__(self): - self.hosted_service_name = '' - self.deployment_name = '' - self.role_name = '' + self.hosted_service_name = u'' + self.deployment_name = u'' + self.role_name = u'' class PersistentVMRole(WindowsAzureData): def __init__(self): - self.role_name = '' - self.role_type= '' - self.os_version = '' # undocumented + self.role_name = u'' + self.role_type= u'' + self.os_version = u'' # undocumented self.configuration_sets = ConfigurationSets() - self.availability_set_name = '' + self.availability_set_name = u'' self.data_virtual_hard_disks = DataVirtualHardDisks() self.os_virtual_hard_disk = OSVirtualHardDisk() - self.role_size = '' + self.role_size = u'' class ConfigurationSets(WindowsAzureData): def __init__(self): @@ -458,8 +454,8 @@ def __getitem__(self, index): class ConfigurationSet(WindowsAzureData): def __init__(self): - self.configuration_set_type = '' - self.role_type= '' + self.configuration_set_type = u'' + self.role_type= u'' self.input_endpoints = ConfigurationSetInputEndpoints() self.subnet_names = _scalar_list_of(str, 'SubnetName') @@ -487,7 +483,7 @@ class ConfigurationSetInputEndpoint(WindowsAzureData): load_balanced_endpoint_set_name: Specifies a name for a set of load-balanced endpoints. Specifying this element for a given endpoint adds it to the set. If you are setting an endpoint to use to connect to the virtual machine via the Remote Desktop, do not set this property. enable_direct_server_return: Specifies whether direct server return load balancing is enabled. ''' - def __init__(self, name='', protocol='', port='', local_port='', load_balanced_endpoint_set_name='', enable_direct_server_return=False): + def __init__(self, name=u'', protocol=u'', port=u'', local_port=u'', load_balanced_endpoint_set_name=u'', enable_direct_server_return=False): self.enable_direct_server_return = enable_direct_server_return self.load_balanced_endpoint_set_name = load_balanced_endpoint_set_name self.local_port = local_port @@ -498,7 +494,7 @@ def __init__(self, name='', protocol='', port='', local_port='', load_balanced_e class WindowsConfigurationSet(WindowsAzureData): def __init__(self, computer_name=None, admin_password=None, reset_password_on_first_logon=None, enable_automatic_updates=None, time_zone=None): - self.configuration_set_type = 'WindowsProvisioningConfiguration' + self.configuration_set_type = u'WindowsProvisioningConfiguration' self.computer_name = computer_name self.admin_password = admin_password self.reset_password_on_first_logon = reset_password_on_first_logon @@ -510,14 +506,14 @@ def __init__(self, computer_name=None, admin_password=None, reset_password_on_fi class DomainJoin(WindowsAzureData): def __init__(self): self.credentials = Credentials() - self.join_domain = '' - self.machine_object_ou = '' + self.join_domain = u'' + self.machine_object_ou = u'' class Credentials(WindowsAzureData): def __init(self): - self.domain = '' - self.username = '' - self.password = '' + self.domain = u'' + self.username = u'' + self.password = u'' class StoredCertificateSettings(WindowsAzureData): def __init__(self): @@ -540,14 +536,14 @@ class CertificateSetting(WindowsAzureData): store_name: Specifies the name of the certificate store from which retrieve certificate. store_location: Specifies the target certificate store location on the virtual machine. The only supported value is LocalMachine. ''' - def __init__(self, thumbprint='', store_name='', store_location=''): + def __init__(self, thumbprint=u'', store_name=u'', store_location=u''): self.thumbprint = thumbprint self.store_name = store_name self.store_location = store_location class LinuxConfigurationSet(WindowsAzureData): def __init__(self, host_name=None, user_name=None, user_password=None, disable_ssh_password_authentication=None): - self.configuration_set_type = 'LinuxProvisioningConfiguration' + self.configuration_set_type = u'LinuxProvisioningConfiguration' self.host_name = host_name self.user_name = user_name self.user_password = user_password @@ -592,14 +588,14 @@ def __getitem__(self, index): class KeyPair(WindowsAzureData): def __init__(self): - self.finger_print = '' - self.path = '' + self.finger_print = u'' + self.path = u'' class LoadBalancerProbe(WindowsAzureData): def __init__(self): - self.path = '' - self.port = '' - self.protocol = '' + self.path = u'' + self.port = u'' + self.protocol = u'' class DataVirtualHardDisks(WindowsAzureData): def __init__(self): @@ -616,12 +612,12 @@ def __getitem__(self, index): class DataVirtualHardDisk(WindowsAzureData): def __init__(self): - self.host_caching = '' - self.disk_label = '' - self.disk_name = '' + self.host_caching = u'' + self.disk_label = u'' + self.disk_name = u'' self.lun = 0 self.logical_disk_size_in_gb = 0 - self.media_link = '' + self.media_link = u'' class OSVirtualHardDisk(WindowsAzureData): def __init__(self, source_image_name=None, media_link=None, host_caching=None, disk_label=None, disk_name=None): @@ -630,7 +626,7 @@ def __init__(self, source_image_name=None, media_link=None, host_caching=None, d self.host_caching = host_caching self.disk_label = disk_label self.disk_name = disk_name - self.os = '' # undocumented, not used when adding a role + self.os = u'' # undocumented, not used when adding a role class AsynchronousOperationResult(WindowsAzureData): def __init__(self, request_id=None): @@ -1033,9 +1029,9 @@ def data_to_xml(data): if val is not None: if converter is not None: - text = converter(str(val)) + text = converter(_str(val)) else: - text = str(val) + text = _str(val) xml += ''.join(['<', name, '>', text, '']) return xml @@ -1060,7 +1056,7 @@ def extended_properties_dict_to_xml_fragment(extended_properties): if extended_properties is not None and len(extended_properties) > 0: xml += '' for key, val in extended_properties.items(): - xml += ''.join(['', '', str(key), '', '', str(val), '', '']) + xml += ''.join(['', '', _str(key), '', '', _str(val), '', '']) xml += '' return xml diff --git a/src/azure/servicemanagement/servicemanagementservice.py b/src/azure/servicemanagement/servicemanagementservice.py index c9f287f45a7e..0a7bab088415 100644 --- a/src/azure/servicemanagement/servicemanagementservice.py +++ b/src/azure/servicemanagement/servicemanagementservice.py @@ -24,7 +24,7 @@ _parse_response_for_async_op, _XmlSerializer) from azure.http import HTTPRequest -from azure import (_validate_not_none, +from azure import (_validate_not_none, _str, _get_request_body, _update_request_uri_query, WindowsAzureError, _parse_response, MANAGEMENT_HOST) @@ -208,7 +208,7 @@ def check_storage_account_name_availability(self, service_name): service_name: Name of the storage service account. ''' _validate_not_none('service_name', service_name) - return self._perform_get(self._get_storage_service_path() + '/operations/isavailable/' + str(service_name) + '', + return self._perform_get(self._get_storage_service_path() + '/operations/isavailable/' + _str(service_name) + '', AvailabilityResponse) #--Operations for hosted services ------------------------------------ @@ -234,7 +234,7 @@ def get_hosted_service_properties(self, service_name, embed_detail=False): ''' _validate_not_none('service_name', service_name) _validate_not_none('embed_detail', embed_detail) - return self._perform_get(self._get_hosted_service_path(service_name) + '?embed-detail=' + str(embed_detail).lower(), + return self._perform_get(self._get_hosted_service_path(service_name) + '?embed-detail=' + _str(embed_detail).lower(), HostedService) def create_hosted_service(self, service_name, label, description=None, location=None, affinity_group=None, extended_properties=None): @@ -572,7 +572,7 @@ def reboot_role_instance(self, service_name, deployment_name, role_instance_name _validate_not_none('service_name', service_name) _validate_not_none('deployment_name', deployment_name) _validate_not_none('role_instance_name', role_instance_name) - return self._perform_post(self._get_deployment_path_using_name(service_name, deployment_name) + '/roleinstances/' + str(role_instance_name) + '?comp=reboot', + return self._perform_post(self._get_deployment_path_using_name(service_name, deployment_name) + '/roleinstances/' + _str(role_instance_name) + '?comp=reboot', '', async=True) @@ -587,7 +587,7 @@ def reimage_role_instance(self, service_name, deployment_name, role_instance_nam _validate_not_none('service_name', service_name) _validate_not_none('deployment_name', deployment_name) _validate_not_none('role_instance_name', role_instance_name) - return self._perform_post(self._get_deployment_path_using_name(service_name, deployment_name) + '/roleinstances/' + str(role_instance_name) + '?comp=reimage', + return self._perform_post(self._get_deployment_path_using_name(service_name, deployment_name) + '/roleinstances/' + _str(role_instance_name) + '?comp=reimage', '', async=True) @@ -599,7 +599,7 @@ def check_hosted_service_name_availability(self, service_name): service_name: Name of the hosted service. ''' _validate_not_none('service_name', service_name) - return self._perform_get('/' + self.subscription_id + '/services/hostedservices/operations/isavailable/' + str(service_name) + '', + return self._perform_get('/' + self.subscription_id + '/services/hostedservices/operations/isavailable/' + _str(service_name) + '', AvailabilityResponse) #--Operations for service certificates ------------------------------- @@ -611,7 +611,7 @@ def list_service_certificates(self, service_name): service_name: Name of the hosted service. ''' _validate_not_none('service_name', service_name) - return self._perform_get('/' + self.subscription_id + '/services/hostedservices/' + str(service_name) + '/certificates', + return self._perform_get('/' + self.subscription_id + '/services/hostedservices/' + _str(service_name) + '/certificates', Certificates) def get_service_certificate(self, service_name, thumbalgorithm, thumbprint): @@ -626,7 +626,7 @@ def get_service_certificate(self, service_name, thumbalgorithm, thumbprint): _validate_not_none('service_name', service_name) _validate_not_none('thumbalgorithm', thumbalgorithm) _validate_not_none('thumbprint', thumbprint) - return self._perform_get('/' + self.subscription_id + '/services/hostedservices/' + str(service_name) + '/certificates/' + str(thumbalgorithm) + '-' + str(thumbprint) + '', + return self._perform_get('/' + self.subscription_id + '/services/hostedservices/' + _str(service_name) + '/certificates/' + _str(thumbalgorithm) + '-' + _str(thumbprint) + '', Certificate) def add_service_certificate(self, service_name, data, certificate_format, password): @@ -643,7 +643,7 @@ def add_service_certificate(self, service_name, data, certificate_format, passwo _validate_not_none('data', data) _validate_not_none('certificate_format', certificate_format) _validate_not_none('password', password) - return self._perform_post('/' + self.subscription_id + '/services/hostedservices/' + str(service_name) + '/certificates', + return self._perform_post('/' + self.subscription_id + '/services/hostedservices/' + _str(service_name) + '/certificates', _XmlSerializer.certificate_file_to_xml(data, certificate_format, password), async=True) @@ -659,7 +659,7 @@ def delete_service_certificate(self, service_name, thumbalgorithm, thumbprint): _validate_not_none('service_name', service_name) _validate_not_none('thumbalgorithm', thumbalgorithm) _validate_not_none('thumbprint', thumbprint) - return self._perform_delete('/' + self.subscription_id + '/services/hostedservices/' + str(service_name) + '/certificates/' + str(thumbalgorithm) + '-' + str(thumbprint), + return self._perform_delete('/' + self.subscription_id + '/services/hostedservices/' + _str(service_name) + '/certificates/' + _str(thumbalgorithm) + '-' + _str(thumbprint), async=True) #--Operations for management certificates ---------------------------- @@ -685,7 +685,7 @@ def get_management_certificate(self, thumbprint): thumbprint: The thumbprint value of the certificate. ''' _validate_not_none('thumbprint', thumbprint) - return self._perform_get('/' + self.subscription_id + '/certificates/' + str(thumbprint), + return self._perform_get('/' + self.subscription_id + '/certificates/' + _str(thumbprint), SubscriptionCertificate) def add_management_certificate(self, public_key, thumbprint, data): @@ -719,7 +719,7 @@ def delete_management_certificate(self, thumbprint): thumbprint: The thumb print that uniquely identifies the management certificate. ''' _validate_not_none('thumbprint', thumbprint) - return self._perform_delete('/' + self.subscription_id + '/certificates/' + str(thumbprint)) + return self._perform_delete('/' + self.subscription_id + '/certificates/' + _str(thumbprint)) #--Operations for affinity groups ------------------------------------ def list_affinity_groups(self): @@ -737,7 +737,7 @@ def get_affinity_group_properties(self, affinity_group_name): affinity_group_name: The name of the affinity group. ''' _validate_not_none('affinity_group_name', affinity_group_name) - return self._perform_get('/' + self.subscription_id + '/affinitygroups/' + str(affinity_group_name) + '', + return self._perform_get('/' + self.subscription_id + '/affinitygroups/' + _str(affinity_group_name) + '', AffinityGroup) def create_affinity_group(self, name, label, location, description=None): @@ -772,7 +772,7 @@ def update_affinity_group(self, affinity_group_name, label, description=None): ''' _validate_not_none('affinity_group_name', affinity_group_name) _validate_not_none('label', label) - return self._perform_put('/' + self.subscription_id + '/affinitygroups/' + str(affinity_group_name), + return self._perform_put('/' + self.subscription_id + '/affinitygroups/' + _str(affinity_group_name), _XmlSerializer.update_affinity_group_to_xml(label, description)) def delete_affinity_group(self, affinity_group_name): @@ -782,7 +782,7 @@ def delete_affinity_group(self, affinity_group_name): affinity_group_name: The name of the affinity group. ''' _validate_not_none('affinity_group_name', affinity_group_name) - return self._perform_delete('/' + self.subscription_id + '/affinitygroups/' + str(affinity_group_name)) + return self._perform_delete('/' + self.subscription_id + '/affinitygroups/' + _str(affinity_group_name)) #--Operations for locations ------------------------------------------ def list_locations(self): @@ -803,7 +803,7 @@ def get_operation_status(self, request_id): request_id: The request ID for the request you wish to track. ''' _validate_not_none('request_id', request_id) - return self._perform_get('/' + self.subscription_id + '/operations/' + str(request_id), + return self._perform_get('/' + self.subscription_id + '/operations/' + _str(request_id), Operation) #--Operations for retrieving operating system information ------------ @@ -1437,7 +1437,7 @@ def _perform_delete(self, path, async=False): def _get_path(self, resource, name): path = '/' + self.subscription_id + '/' + resource if name is not None: - path += '/' + str(name) + path += '/' + _str(name) return path def _get_storage_service_path(self, service_name=None): @@ -1447,19 +1447,19 @@ def _get_hosted_service_path(self, service_name=None): return self._get_path('services/hostedservices', service_name) def _get_deployment_path_using_slot(self, service_name, slot=None): - return self._get_path('services/hostedservices/' + str(service_name) + '/deploymentslots', slot) + return self._get_path('services/hostedservices/' + _str(service_name) + '/deploymentslots', slot) def _get_deployment_path_using_name(self, service_name, deployment_name=None): - return self._get_path('services/hostedservices/' + str(service_name) + '/deployments', deployment_name) + return self._get_path('services/hostedservices/' + _str(service_name) + '/deployments', deployment_name) def _get_role_path(self, service_name, deployment_name, role_name=None): - return self._get_path('services/hostedservices/' + str(service_name) + '/deployments/' + deployment_name + '/roles', role_name) + return self._get_path('services/hostedservices/' + _str(service_name) + '/deployments/' + deployment_name + '/roles', role_name) def _get_role_instance_operations_path(self, service_name, deployment_name, role_name=None): - return self._get_path('services/hostedservices/' + str(service_name) + '/deployments/' + deployment_name + '/roleinstances', role_name) + '/Operations' + return self._get_path('services/hostedservices/' + _str(service_name) + '/deployments/' + deployment_name + '/roleinstances', role_name) + '/Operations' def _get_data_disk_path(self, service_name, deployment_name, role_name, lun=None): - return self._get_path('services/hostedservices/' + str(service_name) + '/deployments/' + str(deployment_name) + '/roles/' + str(role_name) + '/DataDisks', lun) + return self._get_path('services/hostedservices/' + _str(service_name) + '/deployments/' + _str(deployment_name) + '/roles/' + _str(role_name) + '/DataDisks', lun) def _get_disk_path(self, disk_name=None): return self._get_path('services/disks', disk_name) diff --git a/src/azure/storage/__init__.py b/src/azure/storage/__init__.py index a82660709323..fd4a33d0e21e 100644 --- a/src/azure/storage/__init__.py +++ b/src/azure/storage/__init__.py @@ -40,10 +40,10 @@ class EnumResultsBase: ''' base class for EnumResults. ''' def __init__(self): - self.prefix = '' - self.marker = '' + self.prefix = u'' + self.marker = u'' self.max_results = 0 - self.next_marker = '' + self.next_marker = u'' class ContainerEnumResults(EnumResultsBase): ''' Blob Container list. ''' @@ -65,8 +65,8 @@ class Container(WindowsAzureData): ''' Blob container class. ''' def __init__(self): - self.name = '' - self.url = '' + self.name = u'' + self.url = u'' self.properties = Properties() self.metadata = {} @@ -74,8 +74,8 @@ class Properties(WindowsAzureData): ''' Blob container's properties class. ''' def __init__(self): - self.last_modified = '' - self.etag = '' + self.last_modified = u'' + self.etag = u'' class RetentionPolicy(WindowsAzureData): ''' RetentionPolicy in service properties. ''' @@ -98,7 +98,7 @@ class Logging(WindowsAzureData): ''' Logging class in service properties. ''' def __init__(self): - self.version = '1.0' + self.version = u'1.0' self.delete = False self.read = False self.write = False @@ -108,7 +108,7 @@ class Metrics(WindowsAzureData): ''' Metrics class in service properties. ''' def __init__(self): - self.version = '1.0' + self.version = u'1.0' self.enabled = False self.include_apis = None self.retention_policy = RetentionPolicy() @@ -124,15 +124,15 @@ class AccessPolicy(WindowsAzureData): ''' Access Policy class in service properties. ''' def __init__(self): - self.start = '' - self.expiry = '' - self.permission = '' + self.start = u'' + self.expiry = u'' + self.permission = u'' class SignedIdentifier(WindowsAzureData): ''' Signed Identifier class for service properties. ''' def __init__(self): - self.id = '' + self.id = u'' self.access_policy = AccessPolicy() class SignedIdentifiers(WindowsAzureData): @@ -178,9 +178,9 @@ class Blob(WindowsAzureData): ''' Blob class. ''' def __init__(self): - self.name = '' - self.snapshot = '' - self.url = '' + self.name = u'' + self.snapshot = u'' + self.url = u'' self.properties = BlobProperties() self.metadata = {} self.blob_prefix = BlobPrefix() @@ -189,16 +189,16 @@ class BlobProperties(WindowsAzureData): ''' Blob Properties ''' def __init__(self): - self.last_modified = '' - self.etag = '' + self.last_modified = u'' + self.etag = u'' self.content_length = 0 - self.content_type = '' - self.content_encoding = '' - self.content_language = '' - self.content_md5 = '' + self.content_type = u'' + self.content_encoding = u'' + self.content_language = u'' + self.content_md5 = u'' self.xms_blob_sequence_number = 0 - self.blob_type = '' - self.lease_status = '' + self.blob_type = u'' + self.lease_status = u'' class BlobPrefix(WindowsAzureData): ''' BlobPrefix in Blob. ''' @@ -262,8 +262,8 @@ class Queue(WindowsAzureData): ''' Queue class ''' def __init__(self): - self.name = '' - self.url = '' + self.name = u'' + self.url = u'' self.metadata = {} class QueueMessagesList(WindowsAzureData): @@ -285,13 +285,13 @@ class QueueMessage(WindowsAzureData): ''' Queue message class. ''' def __init__(self): - self.message_id = '' - self.insertion_time = '' - self.expiration_time = '' - self.pop_receipt = '' - self.time_next_visible = '' - self.dequeue_count = '' - self.message_text = '' + self.message_id = u'' + self.insertion_time = u'' + self.expiration_time = u'' + self.pop_receipt = u'' + self.time_next_visible = u'' + self.dequeue_count = u'' + self.message_text = u'' class Entity(WindowsAzureData): ''' Entity class. The attributes of entity will be created dynamically. ''' @@ -686,7 +686,7 @@ def _convert_xml_to_entity(xmlstr): #if not isnull and no type info, then it is a string and we just need the str type to hold the property. if not isnull and not mtype: - setattr(entity, name, value) + _set_entity_attr(entity, name, value) elif isnull == 'true': if mtype: property = EntityProperty(mtype, None) @@ -698,15 +698,23 @@ def _convert_xml_to_entity(xmlstr): property = conv(value) else: property = EntityProperty(mtype, value) - setattr(entity, name, property) + _set_entity_attr(entity, name, property) #extract id, updated and name value from feed entry and set them of rule. for name, value in _get_entry_properties(xmlstr, True).iteritems(): if name in ['etag']: - setattr(entity, name, value) + _set_entity_attr(entity, name, value) return entity +def _set_entity_attr(entity, name, value): + try: + setattr(entity, name, value) + except UnicodeEncodeError: + # Python 2 doesn't support unicode attribute names, so we'll + # add them and access them directly through the dictionary + entity.__dict__[name] = value + def _convert_xml_to_table(xmlstr): ''' Converts the xml response to table class Simply call convert_xml_to_entity and extract the table name, and add updated and author info diff --git a/src/azure/storage/blobservice.py b/src/azure/storage/blobservice.py index b79dfa420795..b25aa26c8642 100644 --- a/src/azure/storage/blobservice.py +++ b/src/azure/storage/blobservice.py @@ -22,7 +22,7 @@ convert_block_list_to_xml, convert_response_to_block_list) from azure.http import HTTPRequest, HTTP_RESPONSE_NO_CONTENT from azure import (_validate_not_none, Feed, - _convert_response_to_feeds, _str_or_none, _int_or_none, + _convert_response_to_feeds, _str, _str_or_none, _int_or_none, _get_request_body, _update_request_uri_query, _dont_fail_on_exist, _dont_fail_not_exist, WindowsAzureConflictError, WindowsAzureError, _parse_response, _convert_class_to_xml, @@ -84,7 +84,7 @@ def create_container(self, container_name, x_ms_meta_name_values=None, x_ms_blob request = HTTPRequest() request.method = 'PUT' request.host = self._get_host() - request.path = '/' + str(container_name) + '?restype=container' + request.path = '/' + _str(container_name) + '?restype=container' request.headers = [ ('x-ms-meta-name-values', x_ms_meta_name_values), ('x-ms-blob-public-access', _str_or_none(x_ms_blob_public_access)) @@ -110,7 +110,7 @@ def get_container_properties(self, container_name): request = HTTPRequest() request.method = 'GET' request.host = self._get_host() - request.path = '/' + str(container_name) + '?restype=container' + request.path = '/' + _str(container_name) + '?restype=container' request.path, request.query = _update_request_uri_query_local_storage(request, self.use_local_storage) request.headers = _update_storage_blob_header(request, self.account_name, self.account_key) response = self._perform_request(request) @@ -126,7 +126,7 @@ def get_container_metadata(self, container_name): request = HTTPRequest() request.method = 'GET' request.host = self._get_host() - request.path = '/' + str(container_name) + '?restype=container&comp=metadata' + request.path = '/' + _str(container_name) + '?restype=container&comp=metadata' request.path, request.query = _update_request_uri_query_local_storage(request, self.use_local_storage) request.headers = _update_storage_blob_header(request, self.account_name, self.account_key) response = self._perform_request(request) @@ -143,7 +143,7 @@ def set_container_metadata(self, container_name, x_ms_meta_name_values=None): request = HTTPRequest() request.method = 'PUT' request.host = self._get_host() - request.path = '/' + str(container_name) + '?restype=container&comp=metadata' + request.path = '/' + _str(container_name) + '?restype=container&comp=metadata' request.headers = [('x-ms-meta-name-values', x_ms_meta_name_values)] request.path, request.query = _update_request_uri_query_local_storage(request, self.use_local_storage) request.headers = _update_storage_blob_header(request, self.account_name, self.account_key) @@ -157,7 +157,7 @@ def get_container_acl(self, container_name): request = HTTPRequest() request.method = 'GET' request.host = self._get_host() - request.path = '/' + str(container_name) + '?restype=container&comp=acl' + request.path = '/' + _str(container_name) + '?restype=container&comp=acl' request.path, request.query = _update_request_uri_query_local_storage(request, self.use_local_storage) request.headers = _update_storage_blob_header(request, self.account_name, self.account_key) response = self._perform_request(request) @@ -175,7 +175,7 @@ def set_container_acl(self, container_name, signed_identifiers=None, x_ms_blob_p request = HTTPRequest() request.method = 'PUT' request.host = self._get_host() - request.path = '/' + str(container_name) + '?restype=container&comp=acl' + request.path = '/' + _str(container_name) + '?restype=container&comp=acl' request.headers = [('x-ms-blob-public-access', _str_or_none(x_ms_blob_public_access))] request.body = _get_request_body(_convert_class_to_xml(signed_identifiers)) request.path, request.query = _update_request_uri_query_local_storage(request, self.use_local_storage) @@ -192,7 +192,7 @@ def delete_container(self, container_name, fail_not_exist=False): request = HTTPRequest() request.method = 'DELETE' request.host = self._get_host() - request.path = '/' + str(container_name) + '?restype=container' + request.path = '/' + _str(container_name) + '?restype=container' request.path, request.query = _update_request_uri_query_local_storage(request, self.use_local_storage) request.headers = _update_storage_blob_header(request, self.account_name, self.account_key) if not fail_not_exist: @@ -214,7 +214,7 @@ def list_blobs(self, container_name, prefix=None, marker=None, maxresults=None, request = HTTPRequest() request.method = 'GET' request.host = self._get_host() - request.path = '/' + str(container_name) + '?restype=container&comp=list' + request.path = '/' + _str(container_name) + '?restype=container&comp=list' request.query = [ ('prefix', _str_or_none(prefix)), ('marker', _str_or_none(marker)), @@ -278,7 +278,7 @@ def get_blob_properties(self, container_name, blob_name, x_ms_lease_id=None): request = HTTPRequest() request.method = 'HEAD' request.host = self._get_host() - request.path = '/' + str(container_name) + '/' + str(blob_name) + '' + request.path = '/' + _str(container_name) + '/' + _str(blob_name) + '' request.headers = [('x-ms-lease-id', _str_or_none(x_ms_lease_id))] request.path, request.query = _update_request_uri_query_local_storage(request, self.use_local_storage) request.headers = _update_storage_blob_header(request, self.account_name, self.account_key) @@ -302,7 +302,7 @@ def set_blob_properties(self, container_name, blob_name, x_ms_blob_cache_control request = HTTPRequest() request.method = 'PUT' request.host = self._get_host() - request.path = '/' + str(container_name) + '/' + str(blob_name) + '?comp=properties' + request.path = '/' + _str(container_name) + '/' + _str(blob_name) + '?comp=properties' request.headers = [ ('x-ms-blob-cache-control', _str_or_none(x_ms_blob_cache_control)), ('x-ms-blob-content-type', _str_or_none(x_ms_blob_content_type)), @@ -333,7 +333,7 @@ def put_blob(self, container_name, blob_name, blob, x_ms_blob_type, content_enco request = HTTPRequest() request.method = 'PUT' request.host = self._get_host() - request.path = '/' + str(container_name) + '/' + str(blob_name) + '' + request.path = '/' + _str(container_name) + '/' + _str(blob_name) + '' request.headers = [ ('x-ms-blob-type', _str_or_none(x_ms_blob_type)), ('Content-Encoding', _str_or_none(content_encoding)), @@ -368,7 +368,7 @@ def get_blob(self, container_name, blob_name, snapshot=None, x_ms_range=None, x_ request = HTTPRequest() request.method = 'GET' request.host = self._get_host() - request.path = '/' + str(container_name) + '/' + str(blob_name) + '' + request.path = '/' + _str(container_name) + '/' + _str(blob_name) + '' request.headers = [ ('x-ms-range', _str_or_none(x_ms_range)), ('x-ms-lease-id', _str_or_none(x_ms_lease_id)), @@ -393,7 +393,7 @@ def get_blob_metadata(self, container_name, blob_name, snapshot=None, x_ms_lease request = HTTPRequest() request.method = 'GET' request.host = self._get_host() - request.path = '/' + str(container_name) + '/' + str(blob_name) + '?comp=metadata' + request.path = '/' + _str(container_name) + '/' + _str(blob_name) + '?comp=metadata' request.headers = [('x-ms-lease-id', _str_or_none(x_ms_lease_id))] request.query = [('snapshot', _str_or_none(snapshot))] request.path, request.query = _update_request_uri_query_local_storage(request, self.use_local_storage) @@ -415,7 +415,7 @@ def set_blob_metadata(self, container_name, blob_name, x_ms_meta_name_values=Non request = HTTPRequest() request.method = 'PUT' request.host = self._get_host() - request.path = '/' + str(container_name) + '/' + str(blob_name) + '?comp=metadata' + request.path = '/' + _str(container_name) + '/' + _str(blob_name) + '?comp=metadata' request.headers = [ ('x-ms-meta-name-values', x_ms_meta_name_values), ('x-ms-lease-id', _str_or_none(x_ms_lease_id)) @@ -439,7 +439,7 @@ def lease_blob(self, container_name, blob_name, x_ms_lease_action, x_ms_lease_id request = HTTPRequest() request.method = 'PUT' request.host = self._get_host() - request.path = '/' + str(container_name) + '/' + str(blob_name) + '?comp=lease' + request.path = '/' + _str(container_name) + '/' + _str(blob_name) + '?comp=lease' request.headers = [ ('x-ms-lease-id', _str_or_none(x_ms_lease_id)), ('x-ms-lease-action', _str_or_none(x_ms_lease_action)) @@ -471,7 +471,7 @@ def snapshot_blob(self, container_name, blob_name, x_ms_meta_name_values=None, i request = HTTPRequest() request.method = 'PUT' request.host = self._get_host() - request.path = '/' + str(container_name) + '/' + str(blob_name) + '?comp=snapshot' + request.path = '/' + _str(container_name) + '/' + _str(blob_name) + '?comp=snapshot' request.headers = [ ('x-ms-meta-name-values', x_ms_meta_name_values), ('If-Modified-Since', _str_or_none(if_modified_since)), @@ -518,7 +518,7 @@ def copy_blob(self, container_name, blob_name, x_ms_copy_source, x_ms_meta_name_ request = HTTPRequest() request.method = 'PUT' request.host = self._get_host() - request.path = '/' + str(container_name) + '/' + str(blob_name) + '' + request.path = '/' + _str(container_name) + '/' + _str(blob_name) + '' request.headers = [ ('x-ms-copy-source', _str_or_none(x_ms_copy_source)), ('x-ms-meta-name-values', x_ms_meta_name_values), @@ -557,7 +557,7 @@ def delete_blob(self, container_name, blob_name, snapshot=None, x_ms_lease_id=No request = HTTPRequest() request.method = 'DELETE' request.host = self._get_host() - request.path = '/' + str(container_name) + '/' + str(blob_name) + '' + request.path = '/' + _str(container_name) + '/' + _str(blob_name) + '' request.headers = [('x-ms-lease-id', _str_or_none(x_ms_lease_id))] request.query = [('snapshot', _str_or_none(snapshot))] request.path, request.query = _update_request_uri_query_local_storage(request, self.use_local_storage) @@ -583,7 +583,7 @@ def put_block(self, container_name, blob_name, block, blockid, content_md5=None, request = HTTPRequest() request.method = 'PUT' request.host = self._get_host() - request.path = '/' + str(container_name) + '/' + str(blob_name) + '?comp=block' + request.path = '/' + _str(container_name) + '/' + _str(blob_name) + '?comp=block' request.headers = [ ('Content-MD5', _str_or_none(content_md5)), ('x-ms-lease-id', _str_or_none(x_ms_lease_id)) @@ -627,7 +627,7 @@ def put_block_list(self, container_name, blob_name, block_list, content_md5=None request = HTTPRequest() request.method = 'PUT' request.host = self._get_host() - request.path = '/' + str(container_name) + '/' + str(blob_name) + '?comp=blocklist' + request.path = '/' + _str(container_name) + '/' + _str(blob_name) + '?comp=blocklist' request.headers = [ ('Content-MD5', _str_or_none(content_md5)), ('x-ms-blob-cache-control', _str_or_none(x_ms_blob_cache_control)), @@ -659,7 +659,7 @@ def get_block_list(self, container_name, blob_name, snapshot=None, blocklisttype request = HTTPRequest() request.method = 'GET' request.host = self._get_host() - request.path = '/' + str(container_name) + '/' + str(blob_name) + '?comp=blocklist' + request.path = '/' + _str(container_name) + '/' + _str(blob_name) + '?comp=blocklist' request.headers = [('x-ms-lease-id', _str_or_none(x_ms_lease_id))] request.query = [ ('snapshot', _str_or_none(snapshot)), @@ -700,7 +700,7 @@ def put_page(self, container_name, blob_name, page, x_ms_range, x_ms_page_write, request = HTTPRequest() request.method = 'PUT' request.host = self._get_host() - request.path = '/' + str(container_name) + '/' + str(blob_name) + '?comp=page' + request.path = '/' + _str(container_name) + '/' + _str(blob_name) + '?comp=page' request.headers = [ ('x-ms-range', _str_or_none(x_ms_range)), ('Content-MD5', _str_or_none(content_md5)), @@ -739,7 +739,7 @@ def get_page_ranges(self, container_name, blob_name, snapshot=None, range=None, request = HTTPRequest() request.method = 'GET' request.host = self._get_host() - request.path = '/' + str(container_name) + '/' + str(blob_name) + '?comp=pagelist' + request.path = '/' + _str(container_name) + '/' + _str(blob_name) + '?comp=pagelist' request.headers = [ ('Range', _str_or_none(range)), ('x-ms-range', _str_or_none(x_ms_range)), diff --git a/src/azure/storage/queueservice.py b/src/azure/storage/queueservice.py index 778dcc776f0d..f665fca37132 100644 --- a/src/azure/storage/queueservice.py +++ b/src/azure/storage/queueservice.py @@ -21,7 +21,7 @@ from azure.storage import (_update_storage_queue_header) from azure.http import HTTPRequest, HTTP_RESPONSE_NO_CONTENT from azure import (_validate_not_none, Feed, - _convert_response_to_feeds, _str_or_none, _int_or_none, + _convert_response_to_feeds, _str, _str_or_none, _int_or_none, _get_request_body, _update_request_uri_query, _dont_fail_on_exist, _dont_fail_not_exist, WindowsAzureConflictError, WindowsAzureError, _parse_response, _convert_class_to_xml, @@ -92,7 +92,7 @@ def create_queue(self, queue_name, x_ms_meta_name_values=None, fail_on_exist=Fal request = HTTPRequest() request.method = 'PUT' request.host = self._get_host() - request.path = '/' + str(queue_name) + '' + request.path = '/' + _str(queue_name) + '' request.headers = [('x-ms-meta-name-values', x_ms_meta_name_values)] request.path, request.query = _update_request_uri_query_local_storage(request, self.use_local_storage) request.headers = _update_storage_queue_header(request, self.account_name, self.account_key) @@ -122,7 +122,7 @@ def delete_queue(self, queue_name, fail_not_exist=False): request = HTTPRequest() request.method = 'DELETE' request.host = self._get_host() - request.path = '/' + str(queue_name) + '' + request.path = '/' + _str(queue_name) + '' request.path, request.query = _update_request_uri_query_local_storage(request, self.use_local_storage) request.headers = _update_storage_queue_header(request, self.account_name, self.account_key) if not fail_not_exist: @@ -147,7 +147,7 @@ def get_queue_metadata(self, queue_name): request = HTTPRequest() request.method = 'GET' request.host = self._get_host() - request.path = '/' + str(queue_name) + '?comp=metadata' + request.path = '/' + _str(queue_name) + '?comp=metadata' request.path, request.query = _update_request_uri_query_local_storage(request, self.use_local_storage) request.headers = _update_storage_queue_header(request, self.account_name, self.account_key) response = self._perform_request(request) @@ -167,7 +167,7 @@ def set_queue_metadata(self, queue_name, x_ms_meta_name_values=None): request = HTTPRequest() request.method = 'PUT' request.host = self._get_host() - request.path = '/' + str(queue_name) + '?comp=metadata' + request.path = '/' + _str(queue_name) + '?comp=metadata' request.headers = [('x-ms-meta-name-values', x_ms_meta_name_values)] request.path, request.query = _update_request_uri_query_local_storage(request, self.use_local_storage) request.headers = _update_storage_queue_header(request, self.account_name, self.account_key) @@ -193,14 +193,14 @@ def put_message(self, queue_name, message_text, visibilitytimeout=None, messaget request = HTTPRequest() request.method = 'POST' request.host = self._get_host() - request.path = '/' + str(queue_name) + '/messages' + request.path = '/' + _str(queue_name) + '/messages' request.query = [ ('visibilitytimeout', _str_or_none(visibilitytimeout)), ('messagettl', _str_or_none(messagettl)) ] request.body = _get_request_body(' \ \ - ' + xml_escape(str(message_text)) + ' \ + ' + xml_escape(_str(message_text)) + ' \ ') request.path, request.query = _update_request_uri_query_local_storage(request, self.use_local_storage) request.headers = _update_storage_queue_header(request, self.account_name, self.account_key) @@ -225,7 +225,7 @@ def get_messages(self, queue_name, numofmessages=None, visibilitytimeout=None): request = HTTPRequest() request.method = 'GET' request.host = self._get_host() - request.path = '/' + str(queue_name) + '/messages' + request.path = '/' + _str(queue_name) + '/messages' request.query = [ ('numofmessages', _str_or_none(numofmessages)), ('visibilitytimeout', _str_or_none(visibilitytimeout)) @@ -250,7 +250,7 @@ def peek_messages(self, queue_name, numofmessages=None): request = HTTPRequest() request.method = 'GET' request.host = self._get_host() - request.path = '/' + str(queue_name) + '/messages?peekonly=true' + request.path = '/' + _str(queue_name) + '/messages?peekonly=true' request.query = [('numofmessages', _str_or_none(numofmessages))] request.path, request.query = _update_request_uri_query_local_storage(request, self.use_local_storage) request.headers = _update_storage_queue_header(request, self.account_name, self.account_key) @@ -272,7 +272,7 @@ def delete_message(self, queue_name, message_id, popreceipt): request = HTTPRequest() request.method = 'DELETE' request.host = self._get_host() - request.path = '/' + str(queue_name) + '/messages/' + str(message_id) + '' + request.path = '/' + _str(queue_name) + '/messages/' + _str(message_id) + '' request.query = [('popreceipt', _str_or_none(popreceipt))] request.path, request.query = _update_request_uri_query_local_storage(request, self.use_local_storage) request.headers = _update_storage_queue_header(request, self.account_name, self.account_key) @@ -288,7 +288,7 @@ def clear_messages(self, queue_name): request = HTTPRequest() request.method = 'DELETE' request.host = self._get_host() - request.path = '/' + str(queue_name) + '/messages' + request.path = '/' + _str(queue_name) + '/messages' request.path, request.query = _update_request_uri_query_local_storage(request, self.use_local_storage) request.headers = _update_storage_queue_header(request, self.account_name, self.account_key) response = self._perform_request(request) @@ -315,14 +315,14 @@ def update_message(self, queue_name, message_id, message_text, popreceipt, visib request = HTTPRequest() request.method = 'PUT' request.host = self._get_host() - request.path = '/' + str(queue_name) + '/messages/' + str(message_id) + '' + request.path = '/' + _str(queue_name) + '/messages/' + _str(message_id) + '' request.query = [ ('popreceipt', _str_or_none(popreceipt)), ('visibilitytimeout', _str_or_none(visibilitytimeout)) ] request.body = _get_request_body(' \ \ - ' + xml_escape(str(message_text)) + ' \ + ' + xml_escape(_str(message_text)) + ' \ ') request.path, request.query = _update_request_uri_query_local_storage(request, self.use_local_storage) request.headers = _update_storage_queue_header(request, self.account_name, self.account_key) diff --git a/src/azure/storage/tableservice.py b/src/azure/storage/tableservice.py index 4240009385fc..adc62d93ad37 100644 --- a/src/azure/storage/tableservice.py +++ b/src/azure/storage/tableservice.py @@ -25,7 +25,7 @@ from azure.http.batchclient import _BatchClient from azure.http import HTTPRequest, HTTP_RESPONSE_NO_CONTENT from azure import (_validate_not_none, Feed, - _convert_response_to_feeds, _str_or_none, _int_or_none, + _convert_response_to_feeds, _str, _str_or_none, _int_or_none, _get_request_body, _update_request_uri_query, _dont_fail_on_exist, _dont_fail_not_exist, WindowsAzureConflictError, WindowsAzureError, _parse_response, _convert_class_to_xml, @@ -155,7 +155,7 @@ def delete_table(self, table_name, fail_not_exist=False): request = HTTPRequest() request.method = 'DELETE' request.host = self._get_host() - request.path = '/Tables(\'' + str(table_name) + '\')' + request.path = '/Tables(\'' + _str(table_name) + '\')' request.path, request.query = _update_request_uri_query_local_storage(request, self.use_local_storage) request.headers = _update_storage_table_header(request) if not fail_not_exist: @@ -184,7 +184,7 @@ def get_entity(self, table_name, partition_key, row_key, select=''): request = HTTPRequest() request.method = 'GET' request.host = self._get_host() - request.path = '/' + str(table_name) + '(PartitionKey=\'' + str(partition_key) + '\',RowKey=\'' + str(row_key) + '\')?$select=' + str(select) + '' + request.path = '/' + _str(table_name) + '(PartitionKey=\'' + _str(partition_key) + '\',RowKey=\'' + _str(row_key) + '\')?$select=' + _str(select) + '' request.path, request.query = _update_request_uri_query_local_storage(request, self.use_local_storage) request.headers = _update_storage_table_header(request) response = self._perform_request(request) @@ -204,7 +204,7 @@ def query_entities(self, table_name, filter=None, select=None, top=None, next_pa request = HTTPRequest() request.method = 'GET' request.host = self._get_host() - request.path = '/' + str(table_name) + '()' + request.path = '/' + _str(table_name) + '()' request.query = [ ('$filter', _str_or_none(filter)), ('$select', _str_or_none(select)), @@ -231,7 +231,7 @@ def insert_entity(self, table_name, entity, content_type='application/atom+xml') request = HTTPRequest() request.method = 'POST' request.host = self._get_host() - request.path = '/' + str(table_name) + '' + request.path = '/' + _str(table_name) + '' request.headers = [('Content-Type', _str_or_none(content_type))] request.body = _get_request_body(convert_entity_to_xml(entity)) request.path, request.query = _update_request_uri_query_local_storage(request, self.use_local_storage) @@ -258,7 +258,7 @@ def update_entity(self, table_name, partition_key, row_key, entity, content_type request = HTTPRequest() request.method = 'PUT' request.host = self._get_host() - request.path = '/' + str(table_name) + '(PartitionKey=\'' + str(partition_key) + '\',RowKey=\'' + str(row_key) + '\')' + request.path = '/' + _str(table_name) + '(PartitionKey=\'' + _str(partition_key) + '\',RowKey=\'' + _str(row_key) + '\')' request.headers = [ ('Content-Type', _str_or_none(content_type)), ('If-Match', _str_or_none(if_match)) @@ -288,7 +288,7 @@ def merge_entity(self, table_name, partition_key, row_key, entity, content_type= request = HTTPRequest() request.method = 'MERGE' request.host = self._get_host() - request.path = '/' + str(table_name) + '(PartitionKey=\'' + str(partition_key) + '\',RowKey=\'' + str(row_key) + '\')' + request.path = '/' + _str(table_name) + '(PartitionKey=\'' + _str(partition_key) + '\',RowKey=\'' + _str(row_key) + '\')' request.headers = [ ('Content-Type', _str_or_none(content_type)), ('If-Match', _str_or_none(if_match)) @@ -318,7 +318,7 @@ def delete_entity(self, table_name, partition_key, row_key, content_type='applic request = HTTPRequest() request.method = 'DELETE' request.host = self._get_host() - request.path = '/' + str(table_name) + '(PartitionKey=\'' + str(partition_key) + '\',RowKey=\'' + str(row_key) + '\')' + request.path = '/' + _str(table_name) + '(PartitionKey=\'' + _str(partition_key) + '\',RowKey=\'' + _str(row_key) + '\')' request.headers = [ ('Content-Type', _str_or_none(content_type)), ('If-Match', _str_or_none(if_match)) @@ -346,7 +346,7 @@ def insert_or_replace_entity(self, table_name, partition_key, row_key, entity, c request = HTTPRequest() request.method = 'PUT' request.host = self._get_host() - request.path = '/' + str(table_name) + '(PartitionKey=\'' + str(partition_key) + '\',RowKey=\'' + str(row_key) + '\')' + request.path = '/' + _str(table_name) + '(PartitionKey=\'' + _str(partition_key) + '\',RowKey=\'' + _str(row_key) + '\')' request.headers = [('Content-Type', _str_or_none(content_type))] request.body = _get_request_body(convert_entity_to_xml(entity)) request.path, request.query = _update_request_uri_query_local_storage(request, self.use_local_storage) @@ -374,7 +374,7 @@ def insert_or_merge_entity(self, table_name, partition_key, row_key, entity, con request = HTTPRequest() request.method = 'MERGE' request.host = self._get_host() - request.path = '/' + str(table_name) + '(PartitionKey=\'' + str(partition_key) + '\',RowKey=\'' + str(row_key) + '\')' + request.path = '/' + _str(table_name) + '(PartitionKey=\'' + _str(partition_key) + '\',RowKey=\'' + _str(row_key) + '\')' request.headers = [('Content-Type', _str_or_none(content_type))] request.body = _get_request_body(convert_entity_to_xml(entity)) request.path, request.query = _update_request_uri_query_local_storage(request, self.use_local_storage) diff --git a/src/setup.py b/src/setup.py index 3f38f1e8c237..6219854e80be 100644 --- a/src/setup.py +++ b/src/setup.py @@ -18,7 +18,7 @@ from distutils.core import setup setup(name='azure', - version='0.6', + version='0.6.1', description='Windows Azure client APIs', url='https://github.com/WindowsAzure/azure-sdk-for-python', packages=['azure', diff --git a/test/azuretest.pyproj b/test/azuretest.pyproj index 507971137014..5660c45bb3a6 100644 --- a/test/azuretest.pyproj +++ b/test/azuretest.pyproj @@ -6,7 +6,7 @@ {c0742a2d-4862-40e4-8a28-036eecdbc614} - azuretest\test_servicemanagementservice.py + azuretest\test_servicebusservice.py . . azuretest @@ -51,8 +51,8 @@ - + diff --git a/test/azuretest/test_blobservice.py b/test/azuretest/test_blobservice.py index 087068c67c5b..e298d1cb3846 100644 --- a/test/azuretest/test_blobservice.py +++ b/test/azuretest/test_blobservice.py @@ -1,4 +1,4 @@ -#------------------------------------------------------------------------- +#------------------------------------------------------------------------- # Copyright (c) Microsoft. All rights reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -1279,6 +1279,53 @@ def filter_b(request, next): self.assertEqual(called, ['b', 'a', 'b', 'a']) + def test_unicode_create_container_unicode_name(self): + # Arrange + self.container_name = unicode(self.container_name) + u'啊齄丂狛狜' + + # Act + with self.assertRaises(WindowsAzureError): + # not supported - container name must be alphanumeric, lowercase + self.bc.create_container(self.container_name) + + # Assert + + def test_unicode_get_blob_unicode_name(self): + # Arrange + self._create_container_and_block_blob(self.container_name, '啊齄丂狛狜', 'hello world') + + # Act + blob = self.bc.get_blob(self.container_name, '啊齄丂狛狜') + + # Assert + self.assertIsInstance(blob, BlobResult) + self.assertEquals(blob, 'hello world') + + def test_unicode_get_blob_unicode_data(self): + # Arrange + self._create_container_and_block_blob(self.container_name, 'blob1', u'hello world啊齄丂狛狜') + + # Act + blob = self.bc.get_blob(self.container_name, 'blob1') + + # Assert + self.assertIsInstance(blob, BlobResult) + self.assertEquals(blob, 'hello world啊齄丂狛狜') + + def test_unicode_get_blob_binary_data(self): + # Arrange + base64_data = 'AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8gISIjJCUmJygpKissLS4vMDEyMzQ1Njc4OTo7PD0+P0BBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWltcXV5fYGFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6e3x9fn+AgYKDhIWGh4iJiouMjY6PkJGSk5SVlpeYmZqbnJ2en6ChoqOkpaanqKmqq6ytrq+wsbKztLW2t7i5uru8vb6/wMHCw8TFxsfIycrLzM3Oz9DR0tPU1dbX2Nna29zd3t/g4eLj5OXm5+jp6uvs7e7v8PHy8/T19vf4+fr7/P3+/wABAgMEBQYHCAkKCwwNDg8QERITFBUWFxgZGhscHR4fICEiIyQlJicoKSorLC0uLzAxMjM0NTY3ODk6Ozw9Pj9AQUJDREVGR0hJSktMTU5PUFFSU1RVVldYWVpbXF1eX2BhYmNkZWZnaGlqa2xtbm9wcXJzdHV2d3h5ent8fX5/gIGCg4SFhoeIiYqLjI2Oj5CRkpOUlZaXmJmam5ydnp+goaKjpKWmp6ipqqusra6vsLGys7S1tre4ubq7vL2+v8DBwsPExcbHyMnKy8zNzs/Q0dLT1NXW19jZ2tvc3d7f4OHi4+Tl5ufo6err7O3u7/Dx8vP09fb3+Pn6+/z9/v8AAQIDBAUGBwgJCgsMDQ4PEBESExQVFhcYGRobHB0eHyAhIiMkJSYnKCkqKywtLi8wMTIzNDU2Nzg5Ojs8PT4/QEFCQ0RFRkdISUpLTE1OT1BRUlNUVVZXWFlaW1xdXl9gYWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXp7fH1+f4CBgoOEhYaHiImKi4yNjo+QkZKTlJWWl5iZmpucnZ6foKGio6SlpqeoqaqrrK2ur7CxsrO0tba3uLm6u7y9vr/AwcLDxMXGx8jJysvMzc7P0NHS09TV1tfY2drb3N3e3+Dh4uPk5ebn6Onq6+zt7u/w8fLz9PX29/j5+vv8/f7/AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8gISIjJCUmJygpKissLS4vMDEyMzQ1Njc4OTo7PD0+P0BBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWltcXV5fYGFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6e3x9fn+AgYKDhIWGh4iJiouMjY6PkJGSk5SVlpeYmZqbnJ2en6ChoqOkpaanqKmqq6ytrq+wsbKztLW2t7i5uru8vb6/wMHCw8TFxsfIycrLzM3Oz9DR0tPU1dbX2Nna29zd3t/g4eLj5OXm5+jp6uvs7e7v8PHy8/T19vf4+fr7/P3+/w==' + binary_data = base64.b64decode(base64_data) + + self._create_container_and_block_blob(self.container_name, 'blob1', binary_data) + + # Act + blob = self.bc.get_blob(self.container_name, 'blob1') + + # Assert + self.assertIsInstance(blob, BlobResult) + self.assertEquals(blob, binary_data) + #------------------------------------------------------------------------------ if __name__ == '__main__': unittest.main() diff --git a/test/azuretest/test_queueservice.py b/test/azuretest/test_queueservice.py index c058b6c8a364..594b10d59715 100644 --- a/test/azuretest/test_queueservice.py +++ b/test/azuretest/test_queueservice.py @@ -1,4 +1,4 @@ -#------------------------------------------------------------------------- +#------------------------------------------------------------------------- # Copyright (c) Microsoft. All rights reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -375,7 +375,53 @@ def filter_b(request, next): self.assertEqual(called, ['b', 'a']) - + def test_unicode_create_queue_unicode_name(self): + #Action + self.creatable_queues[0] = u'啊齄丂狛狜' + + with self.assertRaises(WindowsAzureError): + # not supported - queue name must be alphanumeric, lowercase + self.queue_client.create_queue(self.creatable_queues[0]) + + #Asserts + + def test_unicode_get_messages_unicode_data(self): + #Action + self.queue_client.put_message(self.test_queues[1], u'message1㚈') + result = self.queue_client.get_messages(self.test_queues[1]) + + #Asserts + self.assertIsNotNone(result) + self.assertEqual(1, len(result)) + message = result[0] + self.assertIsNotNone(message) + self.assertNotEqual('', message.message_id) + self.assertEqual(u'message1㚈', message.message_text) + self.assertNotEqual('', message.pop_receipt) + self.assertEqual('1', message.dequeue_count) + self.assertNotEqual('', message.insertion_time) + self.assertNotEqual('', message.expiration_time) + self.assertNotEqual('', message.time_next_visible) + + def test_unicode_update_message_unicode_data(self): + #Action + self.queue_client.put_message(self.test_queues[7], 'message1') + list_result1 = self.queue_client.get_messages(self.test_queues[7]) + self.queue_client.update_message(self.test_queues[7], list_result1[0].message_id, u'啊齄丂狛狜', list_result1[0].pop_receipt, visibilitytimeout=0) + list_result2 = self.queue_client.get_messages(self.test_queues[7]) + + #Asserts + self.assertIsNotNone(list_result2) + message = list_result2[0] + self.assertIsNotNone(message) + self.assertNotEqual('', message.message_id) + self.assertEqual(u'啊齄丂狛狜', message.message_text) + self.assertNotEqual('', message.pop_receipt) + self.assertEqual('2', message.dequeue_count) + self.assertNotEqual('', message.insertion_time) + self.assertNotEqual('', message.expiration_time) + self.assertNotEqual('', message.time_next_visible) + #------------------------------------------------------------------------------ if __name__ == '__main__': unittest.main() diff --git a/test/azuretest/test_servicebusservice.py b/test/azuretest/test_servicebusservice.py index d5a6ca0dd053..a24762d1c331 100644 --- a/test/azuretest/test_servicebusservice.py +++ b/test/azuretest/test_servicebusservice.py @@ -1,4 +1,4 @@ -#------------------------------------------------------------------------- +#------------------------------------------------------------------------- # Copyright (c) Microsoft. All rights reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -17,6 +17,8 @@ from azure.servicebus import * from azuretest.util import * +import random +import time import unittest #------------------------------------------------------------------------------ @@ -39,6 +41,9 @@ def setUp(self): self.queue_name = getUniqueNameBasedOnCurrentTime(queue_base_name) self.topic_name = getUniqueNameBasedOnCurrentTime(topic_base_name) + self.additional_queue_names = [] + self.additional_topic_names = [] + def tearDown(self): self.cleanup() return super(ServiceBusTest, self).tearDown() @@ -48,10 +53,20 @@ def cleanup(self): self.sbs.delete_queue(self.queue_name) except: pass + for name in self.additional_queue_names: + try: + self.sbs.delete_queue(name) + except: pass + try: self.sbs.delete_topic(self.topic_name) except: pass + for name in self.additional_topic_names: + try: + self.sbs.delete_topic(name) + except: pass + #--Helpers----------------------------------------------------------------- def _create_queue(self, queue_name): self.sbs.create_queue(queue_name, None, True) @@ -215,6 +230,21 @@ def test_list_queues(self): self.assertIsNotNone(queues) self.assertNamedItemInContainer(queues, self.queue_name) + def test_list_queues_with_special_chars(self): + # Arrange + # Name must start and end with an alphanumeric and can only contain + # letters, numbers, periods, hyphens, forward slashes and underscores. + other_queue_name = self.queue_name + 'foo/.-_123' + self.additional_queue_names = [other_queue_name] + self._create_queue(other_queue_name) + + # Act + queues = self.sbs.list_queues() + + # Assert + self.assertIsNotNone(queues) + self.assertNamedItemInContainer(queues, other_queue_name) + def test_delete_queue_with_existing_queue(self): # Arrange self._create_queue(self.queue_name) @@ -386,6 +416,34 @@ def test_send_queue_message_with_custom_message_properties(self): self.assertEquals(received_msg.custom_properties['floating'], 3.14) self.assertEquals(received_msg.custom_properties['dob'], datetime(2011, 12, 14)) + def test_receive_queue_message_timeout_5(self): + # Arrange + self._create_queue(self.queue_name) + + # Act + start = time.clock() + received_msg = self.sbs.receive_queue_message(self.queue_name, True, 5) + duration = time.clock() - start + + # Assert + self.assertTrue(duration > 3 and duration < 7) + self.assertIsNotNone(received_msg) + self.assertIsNone(received_msg.body) + + def test_receive_queue_message_timeout_50(self): + # Arrange + self._create_queue(self.queue_name) + + # Act + start = time.clock() + received_msg = self.sbs.receive_queue_message(self.queue_name, True, 50) + duration = time.clock() - start + + # Assert + self.assertTrue(duration > 48 and duration < 52) + self.assertIsNotNone(received_msg) + self.assertIsNone(received_msg.body) + #--Test cases for topics/subscriptions ------------------------------------ def test_create_topic_no_options(self): # Arrange @@ -501,6 +559,21 @@ def test_list_topics(self): self.assertIsNotNone(topics) self.assertNamedItemInContainer(topics, self.topic_name) + def test_list_topics_with_special_chars(self): + # Arrange + # Name must start and end with an alphanumeric and can only contain + # letters, numbers, periods, hyphens, forward slashes and underscores. + other_topic_name = self.topic_name + 'foo/.-_123' + self.additional_topic_names = [other_topic_name] + self._create_topic(other_topic_name) + + # Act + topics = self.sbs.list_topics() + + # Assert + self.assertIsNotNone(topics) + self.assertNamedItemInContainer(topics, other_topic_name) + def test_delete_topic_with_existing_topic(self): # Arrange self._create_topic(self.topic_name) @@ -1063,6 +1136,148 @@ def filter_b(request, next): self.assertEqual(called, ['b', 'a', 'b', 'a']) + def test_two_identities(self): + # In order to run this test, 2 service bus service identities are created using + # the sbaztool available at: + # http://code.msdn.microsoft.com/windowsazure/Authorization-SBAzTool-6fd76d93 + # + # Use the following commands to create 2 identities and grant access rights. + # Replace with the namespace specified in the test .json file + # Replace with the key specified in the test .json file + # This only needs to be executed once, after the service bus namespace is created. + # + # sbaztool makeid user1 NoHEoD6snlvlhZm7yek9Etxca3l0CYjfc19ICIJZoUg= -n -k + # sbaztool grant Send /path1 user1 -n -k + # sbaztool grant Listen /path1 user1 -n -k + # sbaztool grant Manage /path1 user1 -n -k + + # sbaztool makeid user2 Tb6K5qEgstyRBwp86JEjUezKj/a+fnkLFnibfgvxvdg= -n -k + # sbaztool grant Send /path2 user2 -n -k + # sbaztool grant Listen /path2 user2 -n -k + # sbaztool grant Manage /path2 user2 -n -k + + sbs1 = ServiceBusService(credentials.getServiceBusNamespace(), + 'NoHEoD6snlvlhZm7yek9Etxca3l0CYjfc19ICIJZoUg=', + 'user1') + sbs2 = ServiceBusService(credentials.getServiceBusNamespace(), + 'Tb6K5qEgstyRBwp86JEjUezKj/a+fnkLFnibfgvxvdg=', + 'user2') + + queue1_name = 'path1/queue' + str(random.randint(1, 10000000)) + queue2_name = 'path2/queue' + str(random.randint(1, 10000000)) + + try: + # Create queues, success + sbs1.create_queue(queue1_name) + sbs2.create_queue(queue2_name) + + # Receive messages, success + msg = sbs1.receive_queue_message(queue1_name, True, 1) + self.assertIsNone(msg.body) + msg = sbs1.receive_queue_message(queue1_name, True, 1) + self.assertIsNone(msg.body) + msg = sbs2.receive_queue_message(queue2_name, True, 1) + self.assertIsNone(msg.body) + msg = sbs2.receive_queue_message(queue2_name, True, 1) + self.assertIsNone(msg.body) + + # Receive messages, failure + with self.assertRaises(HTTPError): + msg = sbs1.receive_queue_message(queue2_name, True, 1) + with self.assertRaises(HTTPError): + msg = sbs2.receive_queue_message(queue1_name, True, 1) + finally: + try: + sbs1.delete_queue(queue1_name) + except: pass + try: + sbs2.delete_queue(queue2_name) + except: pass + + def test_unicode_create_queue_unicode_name(self): + # Arrange + self.queue_name = self.queue_name + u'啊齄丂狛狜' + + # Act + with self.assertRaises(WindowsAzureError): + created = self.sbs.create_queue(self.queue_name) + + # Assert + + def test_unicode_receive_queue_message_unicode_data(self): + # Assert + sent_msg = Message('receive message啊齄丂狛狜') + self._create_queue_and_send_msg(self.queue_name, sent_msg) + + # Act + received_msg = self.sbs.receive_queue_message(self.queue_name, False) + + # Assert + self.assertIsNotNone(received_msg) + self.assertEquals(sent_msg.body, received_msg.body) + + def test_unicode_receive_queue_message_binary_data(self): + # Assert + base64_data = 'AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8gISIjJCUmJygpKissLS4vMDEyMzQ1Njc4OTo7PD0+P0BBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWltcXV5fYGFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6e3x9fn+AgYKDhIWGh4iJiouMjY6PkJGSk5SVlpeYmZqbnJ2en6ChoqOkpaanqKmqq6ytrq+wsbKztLW2t7i5uru8vb6/wMHCw8TFxsfIycrLzM3Oz9DR0tPU1dbX2Nna29zd3t/g4eLj5OXm5+jp6uvs7e7v8PHy8/T19vf4+fr7/P3+/wABAgMEBQYHCAkKCwwNDg8QERITFBUWFxgZGhscHR4fICEiIyQlJicoKSorLC0uLzAxMjM0NTY3ODk6Ozw9Pj9AQUJDREVGR0hJSktMTU5PUFFSU1RVVldYWVpbXF1eX2BhYmNkZWZnaGlqa2xtbm9wcXJzdHV2d3h5ent8fX5/gIGCg4SFhoeIiYqLjI2Oj5CRkpOUlZaXmJmam5ydnp+goaKjpKWmp6ipqqusra6vsLGys7S1tre4ubq7vL2+v8DBwsPExcbHyMnKy8zNzs/Q0dLT1NXW19jZ2tvc3d7f4OHi4+Tl5ufo6err7O3u7/Dx8vP09fb3+Pn6+/z9/v8AAQIDBAUGBwgJCgsMDQ4PEBESExQVFhcYGRobHB0eHyAhIiMkJSYnKCkqKywtLi8wMTIzNDU2Nzg5Ojs8PT4/QEFCQ0RFRkdISUpLTE1OT1BRUlNUVVZXWFlaW1xdXl9gYWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXp7fH1+f4CBgoOEhYaHiImKi4yNjo+QkZKTlJWWl5iZmpucnZ6foKGio6SlpqeoqaqrrK2ur7CxsrO0tba3uLm6u7y9vr/AwcLDxMXGx8jJysvMzc7P0NHS09TV1tfY2drb3N3e3+Dh4uPk5ebn6Onq6+zt7u/w8fLz9PX29/j5+vv8/f7/AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8gISIjJCUmJygpKissLS4vMDEyMzQ1Njc4OTo7PD0+P0BBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWltcXV5fYGFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6e3x9fn+AgYKDhIWGh4iJiouMjY6PkJGSk5SVlpeYmZqbnJ2en6ChoqOkpaanqKmqq6ytrq+wsbKztLW2t7i5uru8vb6/wMHCw8TFxsfIycrLzM3Oz9DR0tPU1dbX2Nna29zd3t/g4eLj5OXm5+jp6uvs7e7v8PHy8/T19vf4+fr7/P3+/w==' + binary_data = base64.b64decode(base64_data) + sent_msg = Message(binary_data) + self._create_queue_and_send_msg(self.queue_name, sent_msg) + + # Act + received_msg = self.sbs.receive_queue_message(self.queue_name, False) + + # Assert + self.assertIsNotNone(received_msg) + self.assertEquals(sent_msg.body, received_msg.body) + + def test_unicode_create_subscription_unicode_name(self): + # Arrange + self._create_topic(self.topic_name) + + # Act + with self.assertRaises(WindowsAzureError): + created = self.sbs.create_subscription(self.topic_name, u'MySubscription啊齄丂狛狜') + + # Assert + + def test_unicode_create_rule_unicode_name(self): + # Arrange + self._create_topic_and_subscription(self.topic_name, 'MySubscription') + + # Act + with self.assertRaises(WindowsAzureError): + created = self.sbs.create_rule(self.topic_name, 'MySubscription', 'MyRule啊齄丂狛狜') + + # Assert + + def test_unicode_receive_subscription_message_unicode_data(self): + # Arrange + self._create_topic_and_subscription(self.topic_name, 'MySubscription') + sent_msg = Message('subscription message啊齄丂狛狜') + self.sbs.send_topic_message(self.topic_name, sent_msg) + + # Act + received_msg = self.sbs.receive_subscription_message(self.topic_name, 'MySubscription', False) + + # Assert + self.assertIsNotNone(received_msg) + self.assertEquals(sent_msg.body, received_msg.body) + + def test_unicode_receive_subscription_message_binary_data(self): + # Arrange + base64_data = 'AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8gISIjJCUmJygpKissLS4vMDEyMzQ1Njc4OTo7PD0+P0BBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWltcXV5fYGFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6e3x9fn+AgYKDhIWGh4iJiouMjY6PkJGSk5SVlpeYmZqbnJ2en6ChoqOkpaanqKmqq6ytrq+wsbKztLW2t7i5uru8vb6/wMHCw8TFxsfIycrLzM3Oz9DR0tPU1dbX2Nna29zd3t/g4eLj5OXm5+jp6uvs7e7v8PHy8/T19vf4+fr7/P3+/wABAgMEBQYHCAkKCwwNDg8QERITFBUWFxgZGhscHR4fICEiIyQlJicoKSorLC0uLzAxMjM0NTY3ODk6Ozw9Pj9AQUJDREVGR0hJSktMTU5PUFFSU1RVVldYWVpbXF1eX2BhYmNkZWZnaGlqa2xtbm9wcXJzdHV2d3h5ent8fX5/gIGCg4SFhoeIiYqLjI2Oj5CRkpOUlZaXmJmam5ydnp+goaKjpKWmp6ipqqusra6vsLGys7S1tre4ubq7vL2+v8DBwsPExcbHyMnKy8zNzs/Q0dLT1NXW19jZ2tvc3d7f4OHi4+Tl5ufo6err7O3u7/Dx8vP09fb3+Pn6+/z9/v8AAQIDBAUGBwgJCgsMDQ4PEBESExQVFhcYGRobHB0eHyAhIiMkJSYnKCkqKywtLi8wMTIzNDU2Nzg5Ojs8PT4/QEFCQ0RFRkdISUpLTE1OT1BRUlNUVVZXWFlaW1xdXl9gYWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXp7fH1+f4CBgoOEhYaHiImKi4yNjo+QkZKTlJWWl5iZmpucnZ6foKGio6SlpqeoqaqrrK2ur7CxsrO0tba3uLm6u7y9vr/AwcLDxMXGx8jJysvMzc7P0NHS09TV1tfY2drb3N3e3+Dh4uPk5ebn6Onq6+zt7u/w8fLz9PX29/j5+vv8/f7/AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8gISIjJCUmJygpKissLS4vMDEyMzQ1Njc4OTo7PD0+P0BBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWltcXV5fYGFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6e3x9fn+AgYKDhIWGh4iJiouMjY6PkJGSk5SVlpeYmZqbnJ2en6ChoqOkpaanqKmqq6ytrq+wsbKztLW2t7i5uru8vb6/wMHCw8TFxsfIycrLzM3Oz9DR0tPU1dbX2Nna29zd3t/g4eLj5OXm5+jp6uvs7e7v8PHy8/T19vf4+fr7/P3+/w==' + binary_data = base64.b64decode(base64_data) + self._create_topic_and_subscription(self.topic_name, 'MySubscription') + sent_msg = Message(binary_data) + self.sbs.send_topic_message(self.topic_name, sent_msg) + + # Act + received_msg = self.sbs.receive_subscription_message(self.topic_name, 'MySubscription', False) + + # Assert + self.assertIsNotNone(received_msg) + self.assertEquals(sent_msg.body, received_msg.body) + #------------------------------------------------------------------------------ if __name__ == '__main__': unittest.main() diff --git a/test/azuretest/test_servicemanagementservice.py b/test/azuretest/test_servicemanagementservice.py index d3382dae9c5d..09bae9df8cd3 100644 --- a/test/azuretest/test_servicemanagementservice.py +++ b/test/azuretest/test_servicemanagementservice.py @@ -1,4 +1,4 @@ -#------------------------------------------------------------------------- +#------------------------------------------------------------------------- # Copyright (c) Microsoft. All rights reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -52,8 +52,10 @@ CSPKG_PATH = 'azuretest/data/WindowsAzure1.cspkg' DATA_VHD_PATH = 'azuretest/data/test.vhd' +# Note that available os images on Azure change regularly +# If these images get removed, replace with a similar OS image LINUX_IMAGE_NAME = 'OpenLogic__OpenLogic-CentOS-62-20120531-en-us-30GB.vhd' -WINDOWS_IMAGE_NAME = 'MSFT__Win2K8R2SP1-Datacenter-201208.01-en.us-30GB.vhd' +WINDOWS_IMAGE_NAME = 'MSFT__Win2K8R2SP1-Datacenter-201210.01-en.us-30GB.vhd' # This blob must be created manually before running the unit tests, # they must be present in the storage account listed in the credentials file. @@ -1749,6 +1751,49 @@ def test_delete_disk(self): self.assertIsNone(result) self.assertFalse(self._disk_exists(self.disk_name)) + def test_unicode_create_storage_account_unicode_name(self): + # Arrange + self.storage_account_name = unicode(self.storage_account_name) + u'啊齄丂狛狜' + description = 'description' + label = 'label' + + # Act + with self.assertRaises(WindowsAzureError): + # not supported - queue name must be alphanumeric, lowercase + result = self.sms.create_storage_account(self.storage_account_name, description, label, None, 'West US', True, {'ext1':'val1', 'ext2':42}) + self._wait_for_async(result.request_id) + + # Assert + + def test_unicode_create_storage_account_unicode_description_label(self): + # Arrange + description = u'啊齄丂狛狜' + label = u'丂狛狜' + + # Act + result = self.sms.create_storage_account(self.storage_account_name, description, label, None, 'West US', True, {'ext1':'val1', 'ext2':42}) + self._wait_for_async(result.request_id) + + # Assert + result = self.sms.get_storage_account_properties(self.storage_account_name) + self.assertEqual(result.storage_service_properties.description, description) + self.assertEqual(result.storage_service_properties.label, label) + + def test_unicode_create_storage_account_unicode_property_value(self): + # Arrange + description = 'description' + label = 'label' + + # Act + result = self.sms.create_storage_account(self.storage_account_name, description, label, None, 'West US', True, {'ext1':u'丂狛狜', 'ext2':42}) + self._wait_for_async(result.request_id) + + # Assert + result = self.sms.get_storage_account_properties(self.storage_account_name) + self.assertEqual(result.storage_service_properties.description, description) + self.assertEqual(result.storage_service_properties.label, label) + self.assertEqual(result.extended_properties['ext1'], u'丂狛狜') + #------------------------------------------------------------------------------ if __name__ == '__main__': unittest.main() diff --git a/test/azuretest/test_tableservice.py b/test/azuretest/test_tableservice.py index 49be76c057ff..649344d1289d 100644 --- a/test/azuretest/test_tableservice.py +++ b/test/azuretest/test_tableservice.py @@ -34,7 +34,7 @@ MAX_RETRY = 60 #------------------------------------------------------------------------------ -class StorageTest(AzureTestCase): +class TableServiceTest(AzureTestCase): def setUp(self): self.tc = TableService(account_name=credentials.getStorageServicesName(), @@ -52,7 +52,7 @@ def setUp(self): def tearDown(self): self.cleanup() - return super(StorageTest, self).tearDown() + return super(TableServiceTest, self).tearDown() def cleanup(self): try: @@ -1043,7 +1043,7 @@ def test_batch_different_table_operations_fail(self): self.tc.cancel_batch() - def test_unicode_xml_encoding(self): + def test_unicode_property_value(self): ''' regression test for github issue #57''' # Act self._create_table(self.table_name) @@ -1054,7 +1054,29 @@ def test_unicode_xml_encoding(self): self.assertEquals(len(resp), 2) self.assertEquals(resp[0].Description, u'ꀕ') self.assertEquals(resp[1].Description, u'ꀕ') - + + def test_unicode_property_name(self): + # Act + self._create_table(self.table_name) + self.tc.insert_entity(self.table_name, {'PartitionKey': 'test', 'RowKey': 'test1', u'啊齄丂狛狜': u'ꀕ'}) + self.tc.insert_entity(self.table_name, {'PartitionKey': 'test', 'RowKey': 'test2', u'啊齄丂狛狜': 'hello'}) + resp = self.tc.query_entities(self.table_name, "PartitionKey eq 'test'") + # Assert + self.assertEquals(len(resp), 2) + self.assertEquals(resp[0].__dict__[u'啊齄丂狛狜'], u'ꀕ') + self.assertEquals(resp[1].__dict__[u'啊齄丂狛狜'], u'hello') + + def test_unicode_create_table_unicode_name(self): + # Arrange + self.table_name = unicode(self.table_name) + u'啊齄丂狛狜' + + # Act + with self.assertRaises(WindowsAzureError): + # not supported - table name must be alphanumeric, lowercase + self.tc.create_table(self.table_name) + + # Assert + #------------------------------------------------------------------------------ if __name__ == '__main__': unittest.main()