Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(248)

Unified Diff: tools/telemetry/third_party/gsutilz/third_party/protorpc/protorpc/protojson_test.py

Issue 1264873003: Add gsutil/third_party to telemetry/third_party/gsutilz/third_party. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Remove httplib2 Created 5 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: tools/telemetry/third_party/gsutilz/third_party/protorpc/protorpc/protojson_test.py
diff --git a/tools/telemetry/third_party/gsutilz/third_party/protorpc/protorpc/protojson_test.py b/tools/telemetry/third_party/gsutilz/third_party/protorpc/protorpc/protojson_test.py
new file mode 100755
index 0000000000000000000000000000000000000000..1ed23e201a3dd8a02c40f9b0ac0fe8485c78c2ff
--- /dev/null
+++ b/tools/telemetry/third_party/gsutilz/third_party/protorpc/protorpc/protojson_test.py
@@ -0,0 +1,554 @@
+#!/usr/bin/env python
+#
+# Copyright 2010 Google Inc.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+"""Tests for protorpc.protojson."""
+
+__author__ = 'rafek@google.com (Rafe Kaplan)'
+
+
+import datetime
+import imp
+import sys
+import unittest
+
+from protorpc import message_types
+from protorpc import messages
+from protorpc import protojson
+from protorpc import test_util
+
+import simplejson
+
+
+class CustomField(messages.MessageField):
+ """Custom MessageField class."""
+
+ type = int
+ message_type = message_types.VoidMessage
+
+ def __init__(self, number, **kwargs):
+ super(CustomField, self).__init__(self.message_type, number, **kwargs)
+
+ def value_to_message(self, value):
+ return self.message_type()
+
+
+class MyMessage(messages.Message):
+ """Test message containing various types."""
+
+ class Color(messages.Enum):
+
+ RED = 1
+ GREEN = 2
+ BLUE = 3
+
+ class Nested(messages.Message):
+
+ nested_value = messages.StringField(1)
+
+ a_string = messages.StringField(2)
+ an_integer = messages.IntegerField(3)
+ a_float = messages.FloatField(4)
+ a_boolean = messages.BooleanField(5)
+ an_enum = messages.EnumField(Color, 6)
+ a_nested = messages.MessageField(Nested, 7)
+ a_repeated = messages.IntegerField(8, repeated=True)
+ a_repeated_float = messages.FloatField(9, repeated=True)
+ a_datetime = message_types.DateTimeField(10)
+ a_repeated_datetime = message_types.DateTimeField(11, repeated=True)
+ a_custom = CustomField(12)
+ a_repeated_custom = CustomField(13, repeated=True)
+
+
+class ModuleInterfaceTest(test_util.ModuleInterfaceTest,
+ test_util.TestCase):
+
+ MODULE = protojson
+
+
+# TODO(rafek): Convert this test to the compliance test in test_util.
+class ProtojsonTest(test_util.TestCase,
+ test_util.ProtoConformanceTestBase):
+ """Test JSON encoding and decoding."""
+
+ PROTOLIB = protojson
+
+ def CompareEncoded(self, expected_encoded, actual_encoded):
+ """JSON encoding will be laundered to remove string differences."""
+ self.assertEquals(simplejson.loads(expected_encoded),
+ simplejson.loads(actual_encoded))
+
+ encoded_empty_message = '{}'
+
+ encoded_partial = """{
+ "double_value": 1.23,
+ "int64_value": -100000000000,
+ "int32_value": 1020,
+ "string_value": "a string",
+ "enum_value": "VAL2"
+ }
+ """
+
+ encoded_full = """{
+ "double_value": 1.23,
+ "float_value": -2.5,
+ "int64_value": -100000000000,
+ "uint64_value": 102020202020,
+ "int32_value": 1020,
+ "bool_value": true,
+ "string_value": "a string\u044f",
+ "bytes_value": "YSBieXRlc//+",
+ "enum_value": "VAL2"
+ }
+ """
+
+ encoded_repeated = """{
+ "double_value": [1.23, 2.3],
+ "float_value": [-2.5, 0.5],
+ "int64_value": [-100000000000, 20],
+ "uint64_value": [102020202020, 10],
+ "int32_value": [1020, 718],
+ "bool_value": [true, false],
+ "string_value": ["a string\u044f", "another string"],
+ "bytes_value": ["YSBieXRlc//+", "YW5vdGhlciBieXRlcw=="],
+ "enum_value": ["VAL2", "VAL1"]
+ }
+ """
+
+ encoded_nested = """{
+ "nested": {
+ "a_value": "a string"
+ }
+ }
+ """
+
+ encoded_repeated_nested = """{
+ "repeated_nested": [{"a_value": "a string"},
+ {"a_value": "another string"}]
+ }
+ """
+
+ unexpected_tag_message = '{"unknown": "value"}'
+
+ encoded_default_assigned = '{"a_value": "a default"}'
+
+ encoded_nested_empty = '{"nested": {}}'
+
+ encoded_repeated_nested_empty = '{"repeated_nested": [{}, {}]}'
+
+ encoded_extend_message = '{"int64_value": [400, 50, 6000]}'
+
+ encoded_string_types = '{"string_value": "Latin"}'
+
+ encoded_invalid_enum = '{"enum_value": "undefined"}'
+
+ def testConvertIntegerToFloat(self):
+ """Test that integers passed in to float fields are converted.
+
+ This is necessary because JSON outputs integers for numbers with 0 decimals.
+ """
+ message = protojson.decode_message(MyMessage, '{"a_float": 10}')
+
+ self.assertTrue(isinstance(message.a_float, float))
+ self.assertEquals(10.0, message.a_float)
+
+ def testConvertStringToNumbers(self):
+ """Test that strings passed to integer fields are converted."""
+ message = protojson.decode_message(MyMessage,
+ """{"an_integer": "10",
+ "a_float": "3.5",
+ "a_repeated": ["1", "2"],
+ "a_repeated_float": ["1.5", "2", 10]
+ }""")
+
+ self.assertEquals(MyMessage(an_integer=10,
+ a_float=3.5,
+ a_repeated=[1, 2],
+ a_repeated_float=[1.5, 2.0, 10.0]),
+ message)
+
+ def testWrongTypeAssignment(self):
+ """Test when wrong type is assigned to a field."""
+ self.assertRaises(messages.ValidationError,
+ protojson.decode_message,
+ MyMessage, '{"a_string": 10}')
+ self.assertRaises(messages.ValidationError,
+ protojson.decode_message,
+ MyMessage, '{"an_integer": 10.2}')
+ self.assertRaises(messages.ValidationError,
+ protojson.decode_message,
+ MyMessage, '{"an_integer": "10.2"}')
+
+ def testNumericEnumeration(self):
+ """Test that numbers work for enum values."""
+ message = protojson.decode_message(MyMessage, '{"an_enum": 2}')
+
+ expected_message = MyMessage()
+ expected_message.an_enum = MyMessage.Color.GREEN
+
+ self.assertEquals(expected_message, message)
+
+ def testNumericEnumerationNegativeTest(self):
+ """Test with an invalid number for the enum value."""
+ self.assertRaisesRegexp(
+ messages.DecodeError,
+ 'Invalid enum value "89"',
+ protojson.decode_message,
+ MyMessage,
+ '{"an_enum": 89}')
+
+ def testAlphaEnumeration(self):
+ """Test that alpha enum values work."""
+ message = protojson.decode_message(MyMessage, '{"an_enum": "RED"}')
+
+ expected_message = MyMessage()
+ expected_message.an_enum = MyMessage.Color.RED
+
+ self.assertEquals(expected_message, message)
+
+ def testAlphaEnumerationNegativeTest(self):
+ """The alpha enum value is invalid."""
+ self.assertRaisesRegexp(
+ messages.DecodeError,
+ 'Invalid enum value "IAMINVALID"',
+ protojson.decode_message,
+ MyMessage,
+ '{"an_enum": "IAMINVALID"}')
+
+ def testEnumerationNegativeTestWithEmptyString(self):
+ """The enum value is an empty string."""
+ self.assertRaisesRegexp(
+ messages.DecodeError,
+ 'Invalid enum value ""',
+ protojson.decode_message,
+ MyMessage,
+ '{"an_enum": ""}')
+
+ def testNullValues(self):
+ """Test that null values overwrite existing values."""
+ self.assertEquals(MyMessage(),
+ protojson.decode_message(MyMessage,
+ ('{"an_integer": null,'
+ ' "a_nested": null,'
+ ' "an_enum": null'
+ '}')))
+
+ def testEmptyList(self):
+ """Test that empty lists are ignored."""
+ self.assertEquals(MyMessage(),
+ protojson.decode_message(MyMessage,
+ '{"a_repeated": []}'))
+
+ def testNotJSON(self):
+ """Test error when string is not valid JSON."""
+ self.assertRaises(ValueError,
+ protojson.decode_message, MyMessage, '{this is not json}')
+
+ def testDoNotEncodeStrangeObjects(self):
+ """Test trying to encode a strange object.
+
+ The main purpose of this test is to complete coverage. It ensures that
+ the default behavior of the JSON encoder is preserved when someone tries to
+ serialized an unexpected type.
+ """
+ class BogusObject(object):
+
+ def check_initialized(self):
+ pass
+
+ self.assertRaises(TypeError,
+ protojson.encode_message,
+ BogusObject())
+
+ def testMergeEmptyString(self):
+ """Test merging the empty or space only string."""
+ message = protojson.decode_message(test_util.OptionalMessage, '')
+ self.assertEquals(test_util.OptionalMessage(), message)
+
+ message = protojson.decode_message(test_util.OptionalMessage, ' ')
+ self.assertEquals(test_util.OptionalMessage(), message)
+
+ def testProtojsonUnrecognizedFieldName(self):
+ """Test that unrecognized fields are saved and can be accessed."""
+ decoded = protojson.decode_message(MyMessage,
+ ('{"an_integer": 1, "unknown_val": 2}'))
+ self.assertEquals(decoded.an_integer, 1)
+ self.assertEquals(1, len(decoded.all_unrecognized_fields()))
+ self.assertEquals('unknown_val', decoded.all_unrecognized_fields()[0])
+ self.assertEquals((2, messages.Variant.INT64),
+ decoded.get_unrecognized_field_info('unknown_val'))
+
+ def testProtojsonUnrecognizedFieldNumber(self):
+ """Test that unrecognized fields are saved and can be accessed."""
+ decoded = protojson.decode_message(
+ MyMessage,
+ '{"an_integer": 1, "1001": "unknown", "-123": "negative", '
+ '"456_mixed": 2}')
+ self.assertEquals(decoded.an_integer, 1)
+ self.assertEquals(3, len(decoded.all_unrecognized_fields()))
+ self.assertTrue(1001 in decoded.all_unrecognized_fields())
+ self.assertEquals(('unknown', messages.Variant.STRING),
+ decoded.get_unrecognized_field_info(1001))
+ self.assertTrue('-123' in decoded.all_unrecognized_fields())
+ self.assertEquals(('negative', messages.Variant.STRING),
+ decoded.get_unrecognized_field_info('-123'))
+ self.assertTrue('456_mixed' in decoded.all_unrecognized_fields())
+ self.assertEquals((2, messages.Variant.INT64),
+ decoded.get_unrecognized_field_info('456_mixed'))
+
+ def testProtojsonUnrecognizedNull(self):
+ """Test that unrecognized fields that are None are skipped."""
+ decoded = protojson.decode_message(
+ MyMessage,
+ '{"an_integer": 1, "unrecognized_null": null}')
+ self.assertEquals(decoded.an_integer, 1)
+ self.assertEquals(decoded.all_unrecognized_fields(), [])
+
+ def testUnrecognizedFieldVariants(self):
+ """Test that unrecognized fields are mapped to the right variants."""
+ for encoded, expected_variant in (
+ ('{"an_integer": 1, "unknown_val": 2}', messages.Variant.INT64),
+ ('{"an_integer": 1, "unknown_val": 2.0}', messages.Variant.DOUBLE),
+ ('{"an_integer": 1, "unknown_val": "string value"}',
+ messages.Variant.STRING),
+ ('{"an_integer": 1, "unknown_val": [1, 2, 3]}', messages.Variant.INT64),
+ ('{"an_integer": 1, "unknown_val": [1, 2.0, 3]}',
+ messages.Variant.DOUBLE),
+ ('{"an_integer": 1, "unknown_val": [1, "foo", 3]}',
+ messages.Variant.STRING),
+ ('{"an_integer": 1, "unknown_val": true}', messages.Variant.BOOL)):
+ decoded = protojson.decode_message(MyMessage, encoded)
+ self.assertEquals(decoded.an_integer, 1)
+ self.assertEquals(1, len(decoded.all_unrecognized_fields()))
+ self.assertEquals('unknown_val', decoded.all_unrecognized_fields()[0])
+ _, decoded_variant = decoded.get_unrecognized_field_info('unknown_val')
+ self.assertEquals(expected_variant, decoded_variant)
+
+ def testDecodeDateTime(self):
+ for datetime_string, datetime_vals in (
+ ('2012-09-30T15:31:50.262', (2012, 9, 30, 15, 31, 50, 262000)),
+ ('2012-09-30T15:31:50', (2012, 9, 30, 15, 31, 50, 0))):
+ message = protojson.decode_message(
+ MyMessage, '{"a_datetime": "%s"}' % datetime_string)
+ expected_message = MyMessage(
+ a_datetime=datetime.datetime(*datetime_vals))
+
+ self.assertEquals(expected_message, message)
+
+ def testDecodeInvalidDateTime(self):
+ self.assertRaises(messages.DecodeError, protojson.decode_message,
+ MyMessage, '{"a_datetime": "invalid"}')
+
+ def testEncodeDateTime(self):
+ for datetime_string, datetime_vals in (
+ ('2012-09-30T15:31:50.262000', (2012, 9, 30, 15, 31, 50, 262000)),
+ ('2012-09-30T15:31:50.262123', (2012, 9, 30, 15, 31, 50, 262123)),
+ ('2012-09-30T15:31:50', (2012, 9, 30, 15, 31, 50, 0))):
+ decoded_message = protojson.encode_message(
+ MyMessage(a_datetime=datetime.datetime(*datetime_vals)))
+ expected_decoding = '{"a_datetime": "%s"}' % datetime_string
+ self.CompareEncoded(expected_decoding, decoded_message)
+
+ def testDecodeRepeatedDateTime(self):
+ message = protojson.decode_message(
+ MyMessage,
+ '{"a_repeated_datetime": ["2012-09-30T15:31:50.262", '
+ '"2010-01-21T09:52:00", "2000-01-01T01:00:59.999999"]}')
+ expected_message = MyMessage(
+ a_repeated_datetime=[
+ datetime.datetime(2012, 9, 30, 15, 31, 50, 262000),
+ datetime.datetime(2010, 1, 21, 9, 52),
+ datetime.datetime(2000, 1, 1, 1, 0, 59, 999999)])
+
+ self.assertEquals(expected_message, message)
+
+ def testDecodeCustom(self):
+ message = protojson.decode_message(MyMessage, '{"a_custom": 1}')
+ self.assertEquals(MyMessage(a_custom=1), message)
+
+ def testDecodeInvalidCustom(self):
+ self.assertRaises(messages.ValidationError, protojson.decode_message,
+ MyMessage, '{"a_custom": "invalid"}')
+
+ def testEncodeCustom(self):
+ decoded_message = protojson.encode_message(MyMessage(a_custom=1))
+ self.CompareEncoded('{"a_custom": 1}', decoded_message)
+
+ def testDecodeRepeatedCustom(self):
+ message = protojson.decode_message(
+ MyMessage, '{"a_repeated_custom": [1, 2, 3]}')
+ self.assertEquals(MyMessage(a_repeated_custom=[1, 2, 3]), message)
+
+ def testDecodeBadBase64BytesField(self):
+ """Test decoding improperly encoded base64 bytes value."""
+ self.assertRaisesWithRegexpMatch(
+ messages.DecodeError,
+ 'Base64 decoding error: Incorrect padding',
+ protojson.decode_message,
+ test_util.OptionalMessage,
+ '{"bytes_value": "abcdefghijklmnopq"}')
+
+
+class CustomProtoJson(protojson.ProtoJson):
+
+ def encode_field(self, field, value):
+ return '{encoded}' + value
+
+ def decode_field(self, field, value):
+ return '{decoded}' + value
+
+
+class CustomProtoJsonTest(test_util.TestCase):
+ """Tests for serialization overriding functionality."""
+
+ def setUp(self):
+ self.protojson = CustomProtoJson()
+
+ def testEncode(self):
+ self.assertEqual('{"a_string": "{encoded}xyz"}',
+ self.protojson.encode_message(MyMessage(a_string='xyz')))
+
+ def testDecode(self):
+ self.assertEqual(
+ MyMessage(a_string='{decoded}xyz'),
+ self.protojson.decode_message(MyMessage, '{"a_string": "xyz"}'))
+
+ def testDecodeEmptyMessage(self):
+ self.assertEqual(
+ MyMessage(a_string='{decoded}'),
+ self.protojson.decode_message(MyMessage, '{"a_string": ""}'))
+
+ def testDefault(self):
+ self.assertTrue(protojson.ProtoJson.get_default(),
+ protojson.ProtoJson.get_default())
+
+ instance = CustomProtoJson()
+ protojson.ProtoJson.set_default(instance)
+ self.assertTrue(instance is protojson.ProtoJson.get_default())
+
+
+class InvalidJsonModule(object):
+ pass
+
+
+class ValidJsonModule(object):
+ class JSONEncoder(object):
+ pass
+
+
+class TestJsonDependencyLoading(test_util.TestCase):
+ """Test loading various implementations of json."""
+
+ def get_import(self):
+ """Get __import__ method.
+
+ Returns:
+ The current __import__ method.
+ """
+ if isinstance(__builtins__, dict):
+ return __builtins__['__import__']
+ else:
+ return __builtins__.__import__
+
+ def set_import(self, new_import):
+ """Set __import__ method.
+
+ Args:
+ new_import: Function to replace __import__.
+ """
+ if isinstance(__builtins__, dict):
+ __builtins__['__import__'] = new_import
+ else:
+ __builtins__.__import__ = new_import
+
+ def setUp(self):
+ """Save original import function."""
+ self.simplejson = sys.modules.pop('simplejson', None)
+ self.json = sys.modules.pop('json', None)
+ self.original_import = self.get_import()
+ def block_all_jsons(name, *args, **kwargs):
+ if 'json' in name:
+ if name in sys.modules:
+ module = sys.modules[name]
+ module.name = name
+ return module
+ raise ImportError('Unable to find %s' % name)
+ else:
+ return self.original_import(name, *args, **kwargs)
+ self.set_import(block_all_jsons)
+
+ def tearDown(self):
+ """Restore original import functions and any loaded modules."""
+
+ def reset_module(name, module):
+ if module:
+ sys.modules[name] = module
+ else:
+ sys.modules.pop(name, None)
+ reset_module('simplejson', self.simplejson)
+ reset_module('json', self.json)
+ imp.reload(protojson)
+
+ def testLoadProtojsonWithValidJsonModule(self):
+ """Test loading protojson module with a valid json dependency."""
+ sys.modules['json'] = ValidJsonModule
+
+ # This will cause protojson to reload with the default json module
+ # instead of simplejson.
+ imp.reload(protojson)
+ self.assertEquals('json', protojson.json.name)
+
+ def testLoadProtojsonWithSimplejsonModule(self):
+ """Test loading protojson module with simplejson dependency."""
+ sys.modules['simplejson'] = ValidJsonModule
+
+ # This will cause protojson to reload with the default json module
+ # instead of simplejson.
+ imp.reload(protojson)
+ self.assertEquals('simplejson', protojson.json.name)
+
+ def testLoadProtojsonWithInvalidJsonModule(self):
+ """Loading protojson module with an invalid json defaults to simplejson."""
+ sys.modules['json'] = InvalidJsonModule
+ sys.modules['simplejson'] = ValidJsonModule
+
+ # Ignore bad module and default back to simplejson.
+ imp.reload(protojson)
+ self.assertEquals('simplejson', protojson.json.name)
+
+ def testLoadProtojsonWithInvalidJsonModuleAndNoSimplejson(self):
+ """Loading protojson module with invalid json and no simplejson."""
+ sys.modules['json'] = InvalidJsonModule
+
+ # Bad module without simplejson back raises errors.
+ self.assertRaisesWithRegexpMatch(
+ ImportError,
+ 'json library "json" is not compatible with ProtoRPC',
+ imp.reload,
+ protojson)
+
+ def testLoadProtojsonWithNoJsonModules(self):
+ """Loading protojson module with invalid json and no simplejson."""
+ # No json modules raise the first exception.
+ self.assertRaisesWithRegexpMatch(
+ ImportError,
+ 'Unable to find json',
+ imp.reload,
+ protojson)
+
+
+if __name__ == '__main__':
+ unittest.main()

Powered by Google App Engine
This is Rietveld 408576698