chore: import upstream snapshot with attribution
cffconvert / validate (push) Has been skipped
License Check / license-check (push) Failing after 2s

This commit is contained in:
wehub-resource-sync
2026-07-13 12:14:16 +08:00
commit 8a852e4b4e
36502 changed files with 9277225 additions and 0 deletions
+161
View File
@@ -0,0 +1,161 @@
# Tests of tf.io.*proto.
load("@rules_python//python:proto.bzl", "py_proto_library")
load("@xla//third_party/rules_python/python:py_library.bzl", "py_library")
load("//tensorflow:tensorflow.bzl", "if_oss", "tf_cc_shared_object")
load("//tensorflow:tensorflow.default.bzl", "stripped_cc_info", "tf_py_strict_test")
load("//tensorflow/core/platform:build_config.bzl", "tf_additional_all_protos", "tf_proto_library")
load("//tensorflow/core/platform:build_config_root.bzl", "if_pywrap")
package(
# copybara:uncomment default_applicable_licenses = ["//tensorflow:license"],
default_visibility = ["//visibility:public"],
licenses = ["notice"],
)
exports_files([
"test_example.proto",
])
tf_py_strict_test(
name = "decode_proto_op_test",
size = "small",
srcs = ["decode_proto_op_test.py"],
data = if_oss([":libtestexample.so"]),
tags = [
"no_pip", # TODO(b/78026780)
"no_windows", # TODO(b/78028010)
],
deps = [
":decode_proto_op_test_base",
":py_test_deps",
"//tensorflow/python/ops:proto_ops",
"//tensorflow/python/platform:client_testlib",
],
)
tf_py_strict_test(
name = "encode_proto_op_test",
size = "small",
srcs = ["encode_proto_op_test.py"],
data = if_oss([":libtestexample.so"]),
tags = [
"no_pip", # TODO(b/78026780)
"no_windows", # TODO(b/78028010)
],
deps = [
":encode_proto_op_test_base",
":py_test_deps",
"//tensorflow/python/ops:proto_ops",
"//tensorflow/python/platform:client_testlib",
],
)
py_library(
name = "proto_op_test_base",
testonly = 1,
srcs = ["proto_op_test_base.py"],
strict_deps = True,
deps = [
":test_example_proto_py",
"//tensorflow/core:protos_all_py",
"//tensorflow/python/platform:client_testlib",
],
)
py_library(
name = "decode_proto_op_test_base",
testonly = 1,
srcs = ["decode_proto_op_test_base.py"],
strict_deps = True,
deps = [
":proto_op_test_base",
":test_example_proto_py",
"//tensorflow/python/framework:dtypes",
"//tensorflow/python/framework:errors",
"//third_party/py/numpy",
"@absl_py//absl/testing:parameterized",
],
)
py_library(
name = "encode_proto_op_test_base",
testonly = 1,
srcs = ["encode_proto_op_test_base.py"],
strict_deps = True,
deps = [
":proto_op_test_base",
":test_example_proto_py",
"//tensorflow/python/eager:context",
"//tensorflow/python/framework:dtypes",
"//tensorflow/python/framework:errors",
"//tensorflow/python/ops:array_ops",
"//third_party/py/numpy",
"@absl_py//absl/testing:parameterized",
],
)
py_library(
name = "py_test_deps",
strict_deps = True,
)
tf_proto_library(
name = "test_example_proto",
srcs = ["test_example.proto"],
protodeps = tf_additional_all_protos(),
)
tf_cc_shared_object(
name = "libtestexample.so",
linkstatic = 1,
deps = if_pywrap(
if_false = [
":test_example_proto_cc",
],
if_true = [
"//tensorflow/python:tensorflow_common_framework",
":test_example_proto_cc_stripped",
],
),
)
stripped_cc_info(
name = "test_example_proto_cc_stripped",
deps = [":test_example_proto_cc"],
)
py_library(
name = "descriptor_source_test_base",
testonly = 1,
srcs = ["descriptor_source_test_base.py"],
strict_deps = True,
deps = [
":proto_op_test_base",
"//tensorflow/python/framework:dtypes",
"//tensorflow/python/platform:client_testlib",
"//third_party/py/numpy",
"@com_google_protobuf//:protobuf_python",
],
)
tf_py_strict_test(
name = "descriptor_source_test",
size = "small",
srcs = ["descriptor_source_test.py"],
tags = [
"no_pip",
],
deps = [
":descriptor_source_test_base",
"//tensorflow/python/ops:proto_ops",
"//tensorflow/python/platform:client_testlib",
],
)
# copybara:uncomment_begin(google-only)
# py_proto_library(
# name = "test_example_proto_py",
# deps = [":test_example_proto"],
# )
# copybara:uncomment_end
@@ -0,0 +1,31 @@
# =============================================================================
# Copyright 2018 The TensorFlow Authors. All Rights Reserved.
#
# 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 decode_proto op."""
# Python3 preparedness imports.
from tensorflow.python.kernel_tests.proto import decode_proto_op_test_base as test_base
from tensorflow.python.ops import proto_ops as proto_ops
from tensorflow.python.platform import test
class DecodeProtoOpTest(test_base.DecodeProtoOpTestBase):
def __init__(self, methodName='runTest'): # pylint: disable=invalid-name
super(DecodeProtoOpTest, self).__init__(proto_ops, methodName)
if __name__ == '__main__':
test.main()
@@ -0,0 +1,379 @@
# =============================================================================
# Copyright 2018 The TensorFlow Authors. All Rights Reserved.
#
# 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 decode_proto op."""
# Python3 preparedness imports.
import itertools
from absl.testing import parameterized
import numpy as np
from google.protobuf import text_format
from tensorflow.python.framework import dtypes
from tensorflow.python.framework import errors
from tensorflow.python.kernel_tests.proto import proto_op_test_base as test_base
from tensorflow.python.kernel_tests.proto import test_example_pb2
class DecodeProtoOpTestBase(test_base.ProtoOpTestBase, parameterized.TestCase):
"""Base class for testing proto decoding ops."""
def __init__(self, decode_module, methodName='runTest'): # pylint: disable=invalid-name
"""DecodeProtoOpTestBase initializer.
Args:
decode_module: a module containing the `decode_proto_op` method
methodName: the name of the test method (same as for test.TestCase)
"""
super(DecodeProtoOpTestBase, self).__init__(methodName)
self._decode_module = decode_module
def _compareValues(self, fd, vs, evs):
"""Compare lists/arrays of field values."""
if len(vs) != len(evs):
self.fail('Field %s decoded %d outputs, expected %d' %
(fd.name, len(vs), len(evs)))
for i, ev in enumerate(evs):
# Special case fuzzy match for float32. TensorFlow seems to mess with
# MAX_FLT slightly and the test doesn't work otherwise.
# TODO(nix): ask on TF list about why MAX_FLT doesn't pass through.
if fd.cpp_type == fd.CPPTYPE_FLOAT:
# Numpy isclose() is better than assertIsClose() which uses an absolute
# value comparison.
self.assertTrue(
np.isclose(vs[i], ev), 'expected %r, actual %r' % (ev, vs[i]))
elif fd.cpp_type == fd.CPPTYPE_STRING:
# In Python3 string tensor values will be represented as bytes, so we
# reencode the proto values to match that.
self.assertEqual(vs[i], ev.encode('ascii'))
else:
# Doubles and other types pass through unscathed.
self.assertEqual(vs[i], ev)
def _compareProtos(self, batch_shape, sizes, fields, field_dict):
"""Compare protos of type TestValue.
Args:
batch_shape: the shape of the input tensor of serialized messages.
sizes: int matrix of repeat counts returned by decode_proto
fields: list of test_example_pb2.FieldSpec (types and expected values)
field_dict: map from field names to decoded numpy tensors of values
"""
# Check that expected values match.
for field in fields:
values = field_dict[field.name]
self.assertEqual(dtypes.as_dtype(values.dtype), field.dtype)
if 'ext_value' in field.name:
fd = test_example_pb2.PrimitiveValue()
else:
fd = field.value.DESCRIPTOR.fields_by_name[field.name]
# Values has the same shape as the input plus an extra
# dimension for repeats.
self.assertEqual(list(values.shape)[:-1], batch_shape)
# Nested messages are represented as TF strings, requiring
# some special handling.
if field.name == 'message_value' or 'ext_value' in field.name:
vs = []
for buf in values.flat:
msg = test_example_pb2.PrimitiveValue()
msg.ParseFromString(buf)
vs.append(msg)
if 'ext_value' in field.name:
evs = field.value.Extensions[test_example_pb2.ext_value]
else:
evs = getattr(field.value, field.name)
if len(vs) != len(evs):
self.fail('Field %s decoded %d outputs, expected %d' %
(fd.name, len(vs), len(evs)))
for v, ev in zip(vs, evs):
self.assertEqual(v, ev)
continue
tf_type_to_primitive_value_field = {
dtypes.bool:
'bool_value',
dtypes.float32:
'float_value',
dtypes.float64:
'double_value',
dtypes.int8:
'int8_value',
dtypes.int32:
'int32_value',
dtypes.int64:
'int64_value',
dtypes.string:
'string_value',
dtypes.uint8:
'uint8_value',
dtypes.uint32:
'uint32_value',
dtypes.uint64:
'uint64_value',
}
if field.name in ['enum_value', 'enum_value_with_default']:
tf_field_name = 'enum_value'
else:
tf_field_name = tf_type_to_primitive_value_field.get(field.dtype)
if tf_field_name is None:
self.fail('Unhandled tensorflow type %d' % field.dtype)
self._compareValues(fd, values.flat,
getattr(field.value, tf_field_name))
def _runDecodeProtoTests(self, fields, case_sizes, batch_shape, batch,
message_type, message_format, sanitize,
force_disordered=False):
"""Run decode tests on a batch of messages.
Args:
fields: list of test_example_pb2.FieldSpec (types and expected values)
case_sizes: expected sizes array
batch_shape: the shape of the input tensor of serialized messages
batch: list of serialized messages
message_type: descriptor name for messages
message_format: format of messages, 'text' or 'binary'
sanitize: whether to sanitize binary protobuf inputs
force_disordered: whether to force fields encoded out of order.
"""
if force_disordered:
# Exercise code path that handles out-of-order fields by prepending extra
# fields with tag numbers higher than any real field. Note that this won't
# work with sanitization because that forces reserialization using a
# trusted decoder and encoder.
assert not sanitize
extra_fields = test_example_pb2.ExtraFields()
extra_fields.string_value = 'IGNORE ME'
extra_fields.bool_value = False
extra_msg = extra_fields.SerializeToString()
batch = [extra_msg + msg for msg in batch]
# Numpy silently truncates the strings if you don't specify dtype=object.
batch = np.array(batch, dtype=object)
batch = np.reshape(batch, batch_shape)
field_names = [f.name for f in fields]
output_types = [f.dtype for f in fields]
with self.cached_session() as sess:
sizes, vtensor = self._decode_module.decode_proto(
batch,
message_type=message_type,
field_names=field_names,
output_types=output_types,
message_format=message_format,
sanitize=sanitize)
vlist = sess.run([sizes] + vtensor)
sizes = vlist[0]
# Values is a list of tensors, one for each field.
value_tensors = vlist[1:]
# Check that the repeat sizes are correct.
self.assertTrue(
np.all(np.array(sizes.shape) == batch_shape + [len(field_names)]))
# Check that the decoded sizes match the expected sizes.
self.assertEqual(len(sizes.flat), len(case_sizes))
self.assertTrue(
np.all(sizes.flat == np.array(
case_sizes, dtype=np.int32)))
field_dict = dict(zip(field_names, value_tensors))
self._compareProtos(batch_shape, sizes, fields, field_dict)
@parameterized.named_parameters(*test_base.ProtoOpTestBase.named_parameters())
def testBinary(self, case):
batch = [value.SerializeToString() for value in case.values]
self._runDecodeProtoTests(
case.fields,
case.sizes,
list(case.shapes),
batch,
'tensorflow.contrib.proto.TestValue',
'binary',
sanitize=False)
@parameterized.named_parameters(*test_base.ProtoOpTestBase.named_parameters())
def testBinaryDisordered(self, case):
batch = [value.SerializeToString() for value in case.values]
self._runDecodeProtoTests(
case.fields,
case.sizes,
list(case.shapes),
batch,
'tensorflow.contrib.proto.TestValue',
'binary',
sanitize=False,
force_disordered=True)
@parameterized.named_parameters(
*test_base.ProtoOpTestBase.named_parameters(extension=False))
def testPacked(self, case):
# Now try with the packed serialization.
#
# We test the packed representations by loading the same test case using
# PackedTestValue instead of TestValue. To do this we rely on the text
# format being the same for packed and unpacked fields, and reparse the
# test message using the packed version of the proto.
packed_batch = [
text_format.Parse(
text_format.MessageToString(value),
test_example_pb2.PackedTestValue(),
).SerializeToString()
for value in case.values
]
self._runDecodeProtoTests(
case.fields,
case.sizes,
list(case.shapes),
packed_batch,
'tensorflow.contrib.proto.PackedTestValue',
'binary',
sanitize=False)
@parameterized.named_parameters(*test_base.ProtoOpTestBase.named_parameters())
def testText(self, case):
text_batch = [text_format.MessageToString(value) for value in case.values]
self._runDecodeProtoTests(
case.fields,
case.sizes,
list(case.shapes),
text_batch,
'tensorflow.contrib.proto.TestValue',
'text',
sanitize=False)
@parameterized.named_parameters(*test_base.ProtoOpTestBase.named_parameters())
def testSanitizerGood(self, case):
batch = [value.SerializeToString() for value in case.values]
self._runDecodeProtoTests(
case.fields,
case.sizes,
list(case.shapes),
batch,
'tensorflow.contrib.proto.TestValue',
'binary',
sanitize=True)
@parameterized.parameters((False), (True))
def testCorruptProtobuf(self, sanitize):
corrupt_proto = 'This is not a binary protobuf'
# Numpy silently truncates the strings if you don't specify dtype=object.
batch = np.array(corrupt_proto, dtype=object)
msg_type = 'tensorflow.contrib.proto.TestCase'
field_names = ['sizes']
field_types = [dtypes.int32]
with self.assertRaisesRegex(
errors.DataLossError, 'Unable to parse binary protobuf'
'|Failed to consume entire buffer'):
self.evaluate(
self._decode_module.decode_proto(
batch,
message_type=msg_type,
field_names=field_names,
output_types=field_types,
sanitize=sanitize))
def testUnexpectedType(self):
with self.assertRaisesRegex(
errors.InvalidArgumentError,
'Unexpected output type.*int64 to DT_STRING'):
msg = test_example_pb2.TestValue(
int64_value_with_default=3
).SerializeToString()
msg_type = 'tensorflow.contrib.proto.TestValue'
field_names = ['int64_value_with_default']
field_types = [dtypes.string]
self.evaluate(
self._decode_module.decode_proto(
msg,
message_type=msg_type,
field_names=field_names,
output_types=field_types,
)
)
def testOutOfOrderRepeated(self):
fragments = [
test_example_pb2.TestValue(double_value=[1.0]).SerializeToString(),
test_example_pb2.TestValue(
message_value=[test_example_pb2.PrimitiveValue(
string_value='abc')]).SerializeToString(),
test_example_pb2.TestValue(
message_value=[test_example_pb2.PrimitiveValue(
string_value='def')]).SerializeToString()
]
all_fields_to_parse = ['double_value', 'message_value']
field_types = {
'double_value': dtypes.double,
'message_value': dtypes.string,
}
# Test against all 3! permutations of fragments, and for each permutation
# test parsing all possible combination of 2 fields.
for indices in itertools.permutations(range(len(fragments))):
proto = b''.join(fragments[i] for i in indices)
for i in indices:
if i == 1:
expected_message_values = [
test_example_pb2.PrimitiveValue(
string_value='abc').SerializeToString(),
test_example_pb2.PrimitiveValue(
string_value='def').SerializeToString(),
]
break
if i == 2:
expected_message_values = [
test_example_pb2.PrimitiveValue(
string_value='def').SerializeToString(),
test_example_pb2.PrimitiveValue(
string_value='abc').SerializeToString(),
]
break
expected_field_values = {
'double_value': [[1.0]],
'message_value': [expected_message_values],
}
for num_fields_to_parse in range(len(all_fields_to_parse)):
for comb in itertools.combinations(
all_fields_to_parse, num_fields_to_parse):
parsed_values = self.evaluate(
self._decode_module.decode_proto(
[proto],
message_type='tensorflow.contrib.proto.TestValue',
field_names=comb,
output_types=[field_types[f] for f in comb],
sanitize=False)).values
self.assertLen(parsed_values, len(comb))
for field_name, parsed in zip(comb, parsed_values):
self.assertAllEqual(parsed, expected_field_values[field_name],
'perm: {}, comb: {}'.format(indices, comb))
@@ -0,0 +1,32 @@
# =============================================================================
# Copyright 2018 The TensorFlow Authors. All Rights Reserved.
#
# 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 proto ops reading descriptors from other sources."""
# Python3 preparedness imports.
from tensorflow.python.kernel_tests.proto import descriptor_source_test_base as test_base
from tensorflow.python.ops import proto_ops
from tensorflow.python.platform import test
class DescriptorSourceTest(test_base.DescriptorSourceTestBase):
def __init__(self, methodName='runTest'): # pylint: disable=invalid-name
super(DescriptorSourceTest, self).__init__(decode_module=proto_ops,
encode_module=proto_ops,
methodName=methodName)
if __name__ == '__main__':
test.main()
@@ -0,0 +1,177 @@
# =============================================================================
# Copyright 2018 The TensorFlow Authors. All Rights Reserved.
#
# 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 proto ops reading descriptors from other sources."""
# Python3 preparedness imports.
import os
import numpy as np
from google.protobuf.descriptor_pb2 import FieldDescriptorProto
from google.protobuf.descriptor_pb2 import FileDescriptorSet
from tensorflow.python.framework import dtypes
from tensorflow.python.kernel_tests.proto import proto_op_test_base as test_base
from tensorflow.python.platform import test
class DescriptorSourceTestBase(test.TestCase):
"""Base class for testing descriptor sources."""
def __init__(self, decode_module, encode_module, methodName='runTest'): # pylint: disable=invalid-name
"""DescriptorSourceTestBase initializer.
Args:
decode_module: a module containing the `decode_proto_op` method
encode_module: a module containing the `encode_proto_op` method
methodName: the name of the test method (same as for test.TestCase)
"""
super(DescriptorSourceTestBase, self).__init__(methodName)
self._decode_module = decode_module
self._encode_module = encode_module
# NOTE: We generate the descriptor programmatically instead of via a compiler
# because of differences between different versions of the compiler.
#
# The generated descriptor should capture the subset of `test_example.proto`
# used in `test_base.simple_test_case()`.
def _createDescriptorProto(self):
proto = FileDescriptorSet()
file_proto = proto.file.add(
name='types.proto', package='tensorflow', syntax='proto3')
enum_proto = file_proto.enum_type.add(name='DataType')
enum_proto.value.add(name='DT_DOUBLE', number=0)
enum_proto.value.add(name='DT_BOOL', number=1)
file_proto = proto.file.add(
name='test_example.proto',
package='tensorflow.contrib.proto',
dependency=['types.proto'])
message_proto = file_proto.message_type.add(name='TestCase')
message_proto.field.add(
name='values',
number=1,
type=FieldDescriptorProto.TYPE_MESSAGE,
type_name='.tensorflow.contrib.proto.TestValue',
label=FieldDescriptorProto.LABEL_REPEATED)
message_proto.field.add(
name='shapes',
number=2,
type=FieldDescriptorProto.TYPE_INT32,
label=FieldDescriptorProto.LABEL_REPEATED)
message_proto.field.add(
name='sizes',
number=3,
type=FieldDescriptorProto.TYPE_INT32,
label=FieldDescriptorProto.LABEL_REPEATED)
message_proto.field.add(
name='fields',
number=4,
type=FieldDescriptorProto.TYPE_MESSAGE,
type_name='.tensorflow.contrib.proto.FieldSpec',
label=FieldDescriptorProto.LABEL_REPEATED)
message_proto = file_proto.message_type.add(
name='TestValue')
message_proto.field.add(
name='double_value',
number=1,
type=FieldDescriptorProto.TYPE_DOUBLE,
label=FieldDescriptorProto.LABEL_REPEATED)
message_proto.field.add(
name='bool_value',
number=2,
type=FieldDescriptorProto.TYPE_BOOL,
label=FieldDescriptorProto.LABEL_REPEATED)
message_proto = file_proto.message_type.add(
name='FieldSpec')
message_proto.field.add(
name='name',
number=1,
type=FieldDescriptorProto.TYPE_STRING,
label=FieldDescriptorProto.LABEL_OPTIONAL)
message_proto.field.add(
name='dtype',
number=2,
type=FieldDescriptorProto.TYPE_ENUM,
type_name='.tensorflow.DataType',
label=FieldDescriptorProto.LABEL_OPTIONAL)
message_proto.field.add(
name='value',
number=3,
type=FieldDescriptorProto.TYPE_MESSAGE,
type_name='.tensorflow.contrib.proto.TestValue',
label=FieldDescriptorProto.LABEL_OPTIONAL)
return proto
def _writeProtoToFile(self, proto):
fn = os.path.join(self.get_temp_dir(), 'descriptor.pb')
with open(fn, 'wb') as f:
f.write(proto.SerializeToString())
return fn
def _testRoundtrip(self, descriptor_source):
# Numpy silently truncates the strings if you don't specify dtype=object.
in_bufs = np.array(
[test_base.ProtoOpTestBase.simple_test_case().SerializeToString()],
dtype=object)
message_type = 'tensorflow.contrib.proto.TestCase'
field_names = ['values', 'shapes', 'sizes', 'fields']
tensor_types = [dtypes.string, dtypes.int32, dtypes.int32, dtypes.string]
with self.cached_session() as sess:
sizes, field_tensors = self._decode_module.decode_proto(
in_bufs,
message_type=message_type,
field_names=field_names,
output_types=tensor_types,
descriptor_source=descriptor_source)
out_tensors = self._encode_module.encode_proto(
sizes,
field_tensors,
message_type=message_type,
field_names=field_names,
descriptor_source=descriptor_source)
out_bufs, = sess.run([out_tensors])
# Check that the re-encoded tensor has the same shape.
self.assertEqual(in_bufs.shape, out_bufs.shape)
# Compare the input and output.
for in_buf, out_buf in zip(in_bufs.flat, out_bufs.flat):
# Check that the input and output serialized messages are identical.
# If we fail here, there is a difference in the serialized
# representation but the new serialization still parses. This could
# be harmless (a change in map ordering?) or it could be bad (e.g.
# loss of packing in the encoding).
self.assertEqual(in_buf, out_buf)
def testWithFileDescriptorSet(self):
# First try parsing with a local proto db, which should fail.
with self.assertRaisesOpError('No descriptor found for message type'):
self._testRoundtrip(b'local://')
# Now try parsing with a FileDescriptorSet which contains the test proto.
proto = self._createDescriptorProto()
proto_file = self._writeProtoToFile(proto)
self._testRoundtrip(proto_file)
# Finally, try parsing the descriptor as a serialized string.
self._testRoundtrip(b'bytes://' + proto.SerializeToString())
@@ -0,0 +1,33 @@
# =============================================================================
# Copyright 2018 The TensorFlow Authors. All Rights Reserved.
#
# 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 encode_proto op."""
# Python3 readiness boilerplate
from tensorflow.python.kernel_tests.proto import encode_proto_op_test_base as test_base
from tensorflow.python.ops import proto_ops
from tensorflow.python.platform import test
class EncodeProtoOpTest(test_base.EncodeProtoOpTestBase):
def __init__(self, methodName='runTest'): # pylint: disable=invalid-name
super(EncodeProtoOpTest, self).__init__(encode_module=proto_ops,
decode_module=proto_ops,
methodName=methodName)
if __name__ == '__main__':
test.main()
@@ -0,0 +1,202 @@
# =============================================================================
# Copyright 2018 The TensorFlow Authors. All Rights Reserved.
#
# 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.
# =============================================================================
"""Table-driven test for encode_proto op.
It tests that encode_proto is a lossless inverse of decode_proto
(for the specified fields).
"""
# Python3 readiness boilerplate
from absl.testing import parameterized
import numpy as np
from google.protobuf import text_format
from tensorflow.python.eager import context
from tensorflow.python.framework import dtypes
from tensorflow.python.framework import errors
from tensorflow.python.kernel_tests.proto import proto_op_test_base as test_base
from tensorflow.python.kernel_tests.proto import test_example_pb2
from tensorflow.python.ops import array_ops
class EncodeProtoOpTestBase(test_base.ProtoOpTestBase, parameterized.TestCase):
"""Base class for testing proto encoding ops."""
def __init__(self, decode_module, encode_module, methodName='runTest'): # pylint: disable=invalid-name
"""EncodeProtoOpTestBase initializer.
Args:
decode_module: a module containing the `decode_proto_op` method
encode_module: a module containing the `encode_proto_op` method
methodName: the name of the test method (same as for test.TestCase)
"""
super(EncodeProtoOpTestBase, self).__init__(methodName)
self._decode_module = decode_module
self._encode_module = encode_module
def testBadSizesShape(self):
if context.executing_eagerly():
expected_error = (errors.InvalidArgumentError,
r'Invalid shape for field double_value.')
else:
expected_error = (ValueError,
r'Shape must be at least rank 2 but is rank 0')
with self.assertRaisesRegex(*expected_error):
self.evaluate(
self._encode_module.encode_proto(
sizes=1,
values=[np.double(1.0)],
message_type='tensorflow.contrib.proto.TestValue',
field_names=['double_value']))
def testBadInputs(self):
# Invalid field name
with self.assertRaisesOpError('Unknown field: non_existent_field'):
self.evaluate(
self._encode_module.encode_proto(
sizes=[[1]],
values=[np.array([[0.0]], dtype=np.int32)],
message_type='tensorflow.contrib.proto.TestValue',
field_names=['non_existent_field']))
# Incorrect types.
with self.assertRaisesOpError('Incompatible type for field double_value.'):
self.evaluate(
self._encode_module.encode_proto(
sizes=[[1]],
values=[np.array([[0.0]], dtype=np.int32)],
message_type='tensorflow.contrib.proto.TestValue',
field_names=['double_value']))
# Incorrect shapes of sizes.
for sizes_value in 1, np.array([[[0, 0]]]):
with self.assertRaisesOpError(
r'sizes should be batch_size \+ \[len\(field_names\)\]'):
if context.executing_eagerly():
self.evaluate(
self._encode_module.encode_proto(
sizes=sizes_value,
values=[np.array([[0.0]])],
message_type='tensorflow.contrib.proto.TestValue',
field_names=['double_value']))
else:
with self.cached_session():
sizes = array_ops.placeholder(dtypes.int32)
values = array_ops.placeholder(dtypes.float64)
self._encode_module.encode_proto(
sizes=sizes,
values=[values],
message_type='tensorflow.contrib.proto.TestValue',
field_names=['double_value']).eval(feed_dict={
sizes: sizes_value,
values: [[0.0]]
})
# Inconsistent shapes of values.
with self.assertRaisesOpError('Values must match up to the last dimension'):
if context.executing_eagerly():
self.evaluate(
self._encode_module.encode_proto(
sizes=[[1, 1]],
values=[np.array([[0.0]]),
np.array([[0], [0]])],
message_type='tensorflow.contrib.proto.TestValue',
field_names=['double_value', 'int32_value']))
else:
with self.cached_session():
values1 = array_ops.placeholder(dtypes.float64)
values2 = array_ops.placeholder(dtypes.int32)
(self._encode_module.encode_proto(
sizes=[[1, 1]],
values=[values1, values2],
message_type='tensorflow.contrib.proto.TestValue',
field_names=['double_value', 'int32_value']).eval(feed_dict={
values1: [[0.0]],
values2: [[0], [0]]
}))
def _testRoundtrip(self, in_bufs, message_type, fields):
field_names = [f.name for f in fields]
out_types = [f.dtype for f in fields]
with self.cached_session() as sess:
sizes, field_tensors = self._decode_module.decode_proto(
in_bufs,
message_type=message_type,
field_names=field_names,
output_types=out_types)
out_tensors = self._encode_module.encode_proto(
sizes,
field_tensors,
message_type=message_type,
field_names=field_names)
out_bufs, = sess.run([out_tensors])
# Check that the re-encoded tensor has the same shape.
self.assertEqual(in_bufs.shape, out_bufs.shape)
# Compare the input and output.
for in_buf, out_buf in zip(in_bufs.flat, out_bufs.flat):
in_obj = test_example_pb2.TestValue()
in_obj.ParseFromString(in_buf)
out_obj = test_example_pb2.TestValue()
out_obj.ParseFromString(out_buf)
# Check that the deserialized objects are identical.
self.assertEqual(in_obj, out_obj)
# Check that the input and output serialized messages are identical.
# If we fail here, there is a difference in the serialized
# representation but the new serialization still parses. This could
# be harmless (a change in map ordering?) or it could be bad (e.g.
# loss of packing in the encoding).
self.assertEqual(in_buf, out_buf)
@parameterized.named_parameters(
*test_base.ProtoOpTestBase.named_parameters(extension=False))
def testRoundtrip(self, case):
in_bufs = [value.SerializeToString() for value in case.values]
# np.array silently truncates strings if you don't specify dtype=object.
in_bufs = np.reshape(np.array(in_bufs, dtype=object), list(case.shapes))
return self._testRoundtrip(
in_bufs, 'tensorflow.contrib.proto.TestValue', case.fields)
@parameterized.named_parameters(
*test_base.ProtoOpTestBase.named_parameters(extension=False))
def testRoundtripPacked(self, case):
# Now try with the packed serialization.
# We test the packed representations by loading the same test cases using
# PackedTestValue instead of TestValue. To do this we rely on the text
# format being the same for packed and unpacked fields, and reparse the test
# message using the packed version of the proto.
in_bufs = [
text_format.Parse(
text_format.MessageToString(value),
test_example_pb2.PackedTestValue(),
).SerializeToString()
for value in case.values
]
# np.array silently truncates strings if you don't specify dtype=object.
in_bufs = np.reshape(np.array(in_bufs, dtype=object), list(case.shapes))
return self._testRoundtrip(
in_bufs, 'tensorflow.contrib.proto.PackedTestValue', case.fields)
@@ -0,0 +1,442 @@
# =============================================================================
# Copyright 2018 The TensorFlow Authors. All Rights Reserved.
#
# 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.
# =============================================================================
"""Test case base for testing proto operations."""
# Python3 preparedness imports.
import ctypes as ct
import os
from tensorflow.core.framework import types_pb2
from tensorflow.python.kernel_tests.proto import test_example_pb2
from tensorflow.python.platform import test
class ProtoOpTestBase(test.TestCase):
"""Base class for testing proto decoding and encoding ops."""
def __init__(self, methodName="runTest"): # pylint: disable=invalid-name
super(ProtoOpTestBase, self).__init__(methodName)
lib = os.path.join(os.path.dirname(__file__), "libtestexample.so")
if os.path.isfile(lib):
ct.cdll.LoadLibrary(lib)
@staticmethod
def named_parameters(extension=True):
parameters = [("defaults", ProtoOpTestBase.defaults_test_case()),
("minmax", ProtoOpTestBase.minmax_test_case()),
("nested", ProtoOpTestBase.nested_test_case()),
("optional", ProtoOpTestBase.optional_test_case()),
("promote", ProtoOpTestBase.promote_test_case()),
("ragged", ProtoOpTestBase.ragged_test_case()),
("shaped_batch", ProtoOpTestBase.shaped_batch_test_case()),
("simple", ProtoOpTestBase.simple_test_case())]
if extension:
parameters.append(("extension", ProtoOpTestBase.extension_test_case()))
return parameters
@staticmethod
def defaults_test_case():
test_case = test_example_pb2.TestCase()
test_case.values.add() # No fields specified, so we get all defaults.
test_case.shapes.append(1)
test_case.sizes.append(0)
field = test_case.fields.add()
field.name = "double_value_with_default"
field.dtype = types_pb2.DT_DOUBLE
field.value.double_value.append(1.0)
test_case.sizes.append(0)
field = test_case.fields.add()
field.name = "float_value_with_default"
field.dtype = types_pb2.DT_FLOAT
field.value.float_value.append(2.0)
test_case.sizes.append(0)
field = test_case.fields.add()
field.name = "int64_value_with_default"
field.dtype = types_pb2.DT_INT64
field.value.int64_value.append(3)
test_case.sizes.append(0)
field = test_case.fields.add()
field.name = "sfixed64_value_with_default"
field.dtype = types_pb2.DT_INT64
field.value.int64_value.append(11)
test_case.sizes.append(0)
field = test_case.fields.add()
field.name = "sint64_value_with_default"
field.dtype = types_pb2.DT_INT64
field.value.int64_value.append(13)
test_case.sizes.append(0)
field = test_case.fields.add()
field.name = "uint64_value_with_default"
field.dtype = types_pb2.DT_UINT64
field.value.uint64_value.append(4)
test_case.sizes.append(0)
field = test_case.fields.add()
field.name = "fixed64_value_with_default"
field.dtype = types_pb2.DT_UINT64
field.value.uint64_value.append(6)
test_case.sizes.append(0)
field = test_case.fields.add()
field.name = "int32_value_with_default"
field.dtype = types_pb2.DT_INT32
field.value.int32_value.append(5)
test_case.sizes.append(0)
field = test_case.fields.add()
field.name = "sfixed32_value_with_default"
field.dtype = types_pb2.DT_INT32
field.value.int32_value.append(10)
test_case.sizes.append(0)
field = test_case.fields.add()
field.name = "sint32_value_with_default"
field.dtype = types_pb2.DT_INT32
field.value.int32_value.append(12)
test_case.sizes.append(0)
field = test_case.fields.add()
field.name = "uint32_value_with_default"
field.dtype = types_pb2.DT_UINT32
field.value.uint32_value.append(9)
test_case.sizes.append(0)
field = test_case.fields.add()
field.name = "fixed32_value_with_default"
field.dtype = types_pb2.DT_UINT32
field.value.uint32_value.append(7)
test_case.sizes.append(0)
field = test_case.fields.add()
field.name = "bool_value_with_default"
field.dtype = types_pb2.DT_BOOL
field.value.bool_value.append(True)
test_case.sizes.append(0)
field = test_case.fields.add()
field.name = "string_value_with_default"
field.dtype = types_pb2.DT_STRING
field.value.string_value.append("a")
test_case.sizes.append(0)
field = test_case.fields.add()
field.name = "bytes_value_with_default"
field.dtype = types_pb2.DT_STRING
field.value.string_value.append("a longer default string")
test_case.sizes.append(0)
field = test_case.fields.add()
field.name = "enum_value_with_default"
field.dtype = types_pb2.DT_INT32
field.value.enum_value.append(test_example_pb2.Color.GREEN)
return test_case
@staticmethod
def minmax_test_case():
test_case = test_example_pb2.TestCase()
value = test_case.values.add()
value.double_value.append(-1.7976931348623158e+308)
value.double_value.append(2.2250738585072014e-308)
value.double_value.append(1.7976931348623158e+308)
value.float_value.append(-3.402823466e+38)
value.float_value.append(1.175494351e-38)
value.float_value.append(3.402823466e+38)
value.int64_value.append(-9223372036854775808)
value.int64_value.append(9223372036854775807)
value.sfixed64_value.append(-9223372036854775808)
value.sfixed64_value.append(9223372036854775807)
value.sint64_value.append(-9223372036854775808)
value.sint64_value.append(9223372036854775807)
value.uint64_value.append(0)
value.uint64_value.append(18446744073709551615)
value.fixed64_value.append(0)
value.fixed64_value.append(18446744073709551615)
value.int32_value.append(-2147483648)
value.int32_value.append(2147483647)
value.sfixed32_value.append(-2147483648)
value.sfixed32_value.append(2147483647)
value.sint32_value.append(-2147483648)
value.sint32_value.append(2147483647)
value.uint32_value.append(0)
value.uint32_value.append(4294967295)
value.fixed32_value.append(0)
value.fixed32_value.append(4294967295)
value.bool_value.append(False)
value.bool_value.append(True)
value.string_value.append("")
value.string_value.append("I refer to the infinite.")
test_case.shapes.append(1)
test_case.sizes.append(3)
field = test_case.fields.add()
field.name = "double_value"
field.dtype = types_pb2.DT_DOUBLE
field.value.double_value.append(-1.7976931348623158e+308)
field.value.double_value.append(2.2250738585072014e-308)
field.value.double_value.append(1.7976931348623158e+308)
test_case.sizes.append(3)
field = test_case.fields.add()
field.name = "float_value"
field.dtype = types_pb2.DT_FLOAT
field.value.float_value.append(-3.402823466e+38)
field.value.float_value.append(1.175494351e-38)
field.value.float_value.append(3.402823466e+38)
test_case.sizes.append(2)
field = test_case.fields.add()
field.name = "int64_value"
field.dtype = types_pb2.DT_INT64
field.value.int64_value.append(-9223372036854775808)
field.value.int64_value.append(9223372036854775807)
test_case.sizes.append(2)
field = test_case.fields.add()
field.name = "sfixed64_value"
field.dtype = types_pb2.DT_INT64
field.value.int64_value.append(-9223372036854775808)
field.value.int64_value.append(9223372036854775807)
test_case.sizes.append(2)
field = test_case.fields.add()
field.name = "sint64_value"
field.dtype = types_pb2.DT_INT64
field.value.int64_value.append(-9223372036854775808)
field.value.int64_value.append(9223372036854775807)
test_case.sizes.append(2)
field = test_case.fields.add()
field.name = "uint64_value"
field.dtype = types_pb2.DT_UINT64
field.value.uint64_value.append(0)
field.value.uint64_value.append(18446744073709551615)
test_case.sizes.append(2)
field = test_case.fields.add()
field.name = "fixed64_value"
field.dtype = types_pb2.DT_UINT64
field.value.uint64_value.append(0)
field.value.uint64_value.append(18446744073709551615)
test_case.sizes.append(2)
field = test_case.fields.add()
field.name = "int32_value"
field.dtype = types_pb2.DT_INT32
field.value.int32_value.append(-2147483648)
field.value.int32_value.append(2147483647)
test_case.sizes.append(2)
field = test_case.fields.add()
field.name = "sfixed32_value"
field.dtype = types_pb2.DT_INT32
field.value.int32_value.append(-2147483648)
field.value.int32_value.append(2147483647)
test_case.sizes.append(2)
field = test_case.fields.add()
field.name = "sint32_value"
field.dtype = types_pb2.DT_INT32
field.value.int32_value.append(-2147483648)
field.value.int32_value.append(2147483647)
test_case.sizes.append(2)
field = test_case.fields.add()
field.name = "uint32_value"
field.dtype = types_pb2.DT_UINT32
field.value.uint32_value.append(0)
field.value.uint32_value.append(4294967295)
test_case.sizes.append(2)
field = test_case.fields.add()
field.name = "fixed32_value"
field.dtype = types_pb2.DT_UINT32
field.value.uint32_value.append(0)
field.value.uint32_value.append(4294967295)
test_case.sizes.append(2)
field = test_case.fields.add()
field.name = "bool_value"
field.dtype = types_pb2.DT_BOOL
field.value.bool_value.append(False)
field.value.bool_value.append(True)
test_case.sizes.append(2)
field = test_case.fields.add()
field.name = "string_value"
field.dtype = types_pb2.DT_STRING
field.value.string_value.append("")
field.value.string_value.append("I refer to the infinite.")
return test_case
@staticmethod
def nested_test_case():
test_case = test_example_pb2.TestCase()
value = test_case.values.add()
message_value = value.message_value.add()
message_value.double_value = 23.5
test_case.shapes.append(1)
test_case.sizes.append(1)
field = test_case.fields.add()
field.name = "message_value"
field.dtype = types_pb2.DT_STRING
message_value = field.value.message_value.add()
message_value.double_value = 23.5
return test_case
@staticmethod
def optional_test_case():
test_case = test_example_pb2.TestCase()
value = test_case.values.add()
value.bool_value.append(True)
test_case.shapes.append(1)
test_case.sizes.append(1)
field = test_case.fields.add()
field.name = "bool_value"
field.dtype = types_pb2.DT_BOOL
field.value.bool_value.append(True)
test_case.sizes.append(0)
field = test_case.fields.add()
field.name = "double_value"
field.dtype = types_pb2.DT_DOUBLE
field.value.double_value.append(0.0)
return test_case
@staticmethod
def promote_test_case():
test_case = test_example_pb2.TestCase()
value = test_case.values.add()
value.sint32_value.append(2147483647)
value.sfixed32_value.append(2147483647)
value.int32_value.append(2147483647)
value.fixed32_value.append(4294967295)
value.uint32_value.append(4294967295)
test_case.shapes.append(1)
test_case.sizes.append(1)
field = test_case.fields.add()
field.name = "sint32_value"
field.dtype = types_pb2.DT_INT64
field.value.int64_value.append(2147483647)
test_case.sizes.append(1)
field = test_case.fields.add()
field.name = "sfixed32_value"
field.dtype = types_pb2.DT_INT64
field.value.int64_value.append(2147483647)
test_case.sizes.append(1)
field = test_case.fields.add()
field.name = "int32_value"
field.dtype = types_pb2.DT_INT64
field.value.int64_value.append(2147483647)
test_case.sizes.append(1)
field = test_case.fields.add()
field.name = "fixed32_value"
field.dtype = types_pb2.DT_UINT64
field.value.uint64_value.append(4294967295)
test_case.sizes.append(1)
field = test_case.fields.add()
field.name = "uint32_value"
field.dtype = types_pb2.DT_UINT64
field.value.uint64_value.append(4294967295)
return test_case
@staticmethod
def ragged_test_case():
test_case = test_example_pb2.TestCase()
value = test_case.values.add()
value.double_value.append(23.5)
value.double_value.append(123.0)
value.bool_value.append(True)
value = test_case.values.add()
value.double_value.append(3.1)
value.bool_value.append(False)
test_case.shapes.append(2)
test_case.sizes.append(2)
test_case.sizes.append(1)
test_case.sizes.append(1)
test_case.sizes.append(1)
field = test_case.fields.add()
field.name = "double_value"
field.dtype = types_pb2.DT_DOUBLE
field.value.double_value.append(23.5)
field.value.double_value.append(123.0)
field.value.double_value.append(3.1)
field.value.double_value.append(0.0)
field = test_case.fields.add()
field.name = "bool_value"
field.dtype = types_pb2.DT_BOOL
field.value.bool_value.append(True)
field.value.bool_value.append(False)
return test_case
@staticmethod
def shaped_batch_test_case():
test_case = test_example_pb2.TestCase()
value = test_case.values.add()
value.double_value.append(23.5)
value.bool_value.append(True)
value = test_case.values.add()
value.double_value.append(44.0)
value.bool_value.append(False)
value = test_case.values.add()
value.double_value.append(3.14159)
value.bool_value.append(True)
value = test_case.values.add()
value.double_value.append(1.414)
value.bool_value.append(True)
value = test_case.values.add()
value.double_value.append(-32.2)
value.bool_value.append(False)
value = test_case.values.add()
value.double_value.append(0.0001)
value.bool_value.append(True)
test_case.shapes.append(3)
test_case.shapes.append(2)
for _ in range(12):
test_case.sizes.append(1)
field = test_case.fields.add()
field.name = "double_value"
field.dtype = types_pb2.DT_DOUBLE
field.value.double_value.append(23.5)
field.value.double_value.append(44.0)
field.value.double_value.append(3.14159)
field.value.double_value.append(1.414)
field.value.double_value.append(-32.2)
field.value.double_value.append(0.0001)
field = test_case.fields.add()
field.name = "bool_value"
field.dtype = types_pb2.DT_BOOL
field.value.bool_value.append(True)
field.value.bool_value.append(False)
field.value.bool_value.append(True)
field.value.bool_value.append(True)
field.value.bool_value.append(False)
field.value.bool_value.append(True)
return test_case
@staticmethod
def extension_test_case():
test_case = test_example_pb2.TestCase()
value = test_case.values.add()
message_value = value.Extensions[test_example_pb2.ext_value].add()
message_value.double_value = 23.5
test_case.shapes.append(1)
test_case.sizes.append(1)
field = test_case.fields.add()
field.name = test_example_pb2.ext_value.full_name
field.dtype = types_pb2.DT_STRING
message_value = field.value.Extensions[test_example_pb2.ext_value].add()
message_value.double_value = 23.5
return test_case
@staticmethod
def simple_test_case():
test_case = test_example_pb2.TestCase()
value = test_case.values.add()
value.double_value.append(23.5)
value.bool_value.append(True)
value.enum_value.append(test_example_pb2.Color.INDIGO)
test_case.shapes.append(1)
test_case.sizes.append(1)
field = test_case.fields.add()
field.name = "double_value"
field.dtype = types_pb2.DT_DOUBLE
field.value.double_value.append(23.5)
test_case.sizes.append(1)
field = test_case.fields.add()
field.name = "bool_value"
field.dtype = types_pb2.DT_BOOL
field.value.bool_value.append(True)
test_case.sizes.append(1)
field = test_case.fields.add()
field.name = "enum_value"
field.dtype = types_pb2.DT_INT32
field.value.enum_value.append(test_example_pb2.Color.INDIGO)
return test_case
@@ -0,0 +1,195 @@
// Copyright 2026 The TensorFlow Authors. All Rights Reserved.
//
// 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.
// ==============================================================================
// Test description and protos to work with it.
syntax = "proto2";
package tensorflow.contrib.proto;
import "tensorflow/core/framework/types.proto";
// A TestCase holds a proto and assertions about how it should decode.
message TestCase {
// Batches of primitive values.
repeated TestValue values = 1;
// The batch shapes.
repeated int32 shapes = 2;
// Expected sizes for each field.
repeated int32 sizes = 3;
// Expected values for each field.
repeated FieldSpec fields = 4;
}
// FieldSpec describes the expected output for a single field.
message FieldSpec {
optional string name = 1;
optional tensorflow.DataType dtype = 2;
optional TestValue value = 3;
}
enum Color {
RED = 0;
ORANGE = 1;
YELLOW = 2;
GREEN = 3;
BLUE = 4;
INDIGO = 5;
VIOLET = 6;
}
// NOTE: This definition must be kept in sync with PackedTestValue.
message TestValue {
repeated double double_value = 1;
repeated float float_value = 2;
repeated int64 int64_value = 3;
repeated uint64 uint64_value = 4;
repeated int32 int32_value = 5;
repeated fixed64 fixed64_value = 6;
repeated fixed32 fixed32_value = 7;
repeated bool bool_value = 8;
repeated string string_value = 9;
repeated bytes bytes_value = 12;
repeated uint32 uint32_value = 13;
repeated sfixed32 sfixed32_value = 15;
repeated sfixed64 sfixed64_value = 16;
repeated sint32 sint32_value = 17;
repeated sint64 sint64_value = 18;
repeated PrimitiveValue message_value = 19;
repeated Color enum_value = 35;
// Optional fields with explicitly-specified defaults.
optional double double_value_with_default = 20 [default = 1.0];
optional float float_value_with_default = 21 [default = 2.0];
optional int64 int64_value_with_default = 22 [default = 3];
optional uint64 uint64_value_with_default = 23 [default = 4];
optional int32 int32_value_with_default = 24 [default = 5];
optional fixed64 fixed64_value_with_default = 25 [default = 6];
optional fixed32 fixed32_value_with_default = 26 [default = 7];
optional bool bool_value_with_default = 27 [default = true];
optional string string_value_with_default = 28 [default = "a"];
optional bytes bytes_value_with_default = 29
[default = "a longer default string"];
optional uint32 uint32_value_with_default = 30 [default = 9];
optional sfixed32 sfixed32_value_with_default = 31 [default = 10];
optional sfixed64 sfixed64_value_with_default = 32 [default = 11];
optional sint32 sint32_value_with_default = 33 [default = 12];
optional sint64 sint64_value_with_default = 34 [default = 13];
optional Color enum_value_with_default = 36 [default = GREEN];
extensions 100 to 199;
}
// A PackedTestValue looks exactly the same as a TestValue in the text format,
// but the binary serializion is different. We test the packed representations
// by loading the same test cases using this definition instead of TestValue.
//
// NOTE: This definition must be kept in sync with TestValue in every way except
// the packed=true declaration and the lack of extensions.
message PackedTestValue {
repeated double double_value = 1 [packed = true];
repeated float float_value = 2 [packed = true];
repeated int64 int64_value = 3 [packed = true];
repeated uint64 uint64_value = 4 [packed = true];
repeated int32 int32_value = 5 [packed = true];
repeated fixed64 fixed64_value = 6 [packed = true];
repeated fixed32 fixed32_value = 7 [packed = true];
repeated bool bool_value = 8 [packed = true];
repeated string string_value = 9;
repeated bytes bytes_value = 12;
repeated uint32 uint32_value = 13 [packed = true];
repeated sfixed32 sfixed32_value = 15 [packed = true];
repeated sfixed64 sfixed64_value = 16 [packed = true];
repeated sint32 sint32_value = 17 [packed = true];
repeated sint64 sint64_value = 18 [packed = true];
repeated PrimitiveValue message_value = 19;
repeated Color enum_value = 35 [packed = true];
optional double double_value_with_default = 20 [default = 1.0];
optional float float_value_with_default = 21 [default = 2.0];
optional int64 int64_value_with_default = 22 [default = 3];
optional uint64 uint64_value_with_default = 23 [default = 4];
optional int32 int32_value_with_default = 24 [default = 5];
optional fixed64 fixed64_value_with_default = 25 [default = 6];
optional fixed32 fixed32_value_with_default = 26 [default = 7];
optional bool bool_value_with_default = 27 [default = true];
optional string string_value_with_default = 28 [default = "a"];
optional bytes bytes_value_with_default = 29
[default = "a longer default string"];
optional uint32 uint32_value_with_default = 30 [default = 9];
optional sfixed32 sfixed32_value_with_default = 31 [default = 10];
optional sfixed64 sfixed64_value_with_default = 32 [default = 11];
optional sint32 sint32_value_with_default = 33 [default = 12];
optional sint64 sint64_value_with_default = 34 [default = 13];
optional Color enum_value_with_default = 36 [default = GREEN];
}
message PrimitiveValue {
optional double double_value = 1;
optional float float_value = 2;
optional int64 int64_value = 3;
optional uint64 uint64_value = 4;
optional int32 int32_value = 5;
optional fixed64 fixed64_value = 6;
optional fixed32 fixed32_value = 7;
optional bool bool_value = 8;
optional string string_value = 9;
optional bytes bytes_value = 12;
optional uint32 uint32_value = 13;
optional sfixed32 sfixed32_value = 15;
optional sfixed64 sfixed64_value = 16;
optional sint32 sint32_value = 17;
optional sint64 sint64_value = 18;
}
// Message containing fields with field numbers higher than any field above.
// An instance of this message is prepended to each binary message in the test
// to exercise the code path that handles fields encoded out of order of field
// number.
message ExtraFields {
optional string string_value = 1776;
optional bool bool_value = 1777;
}
extend TestValue {
repeated PrimitiveValue ext_value = 100;
}
// The messages below are for yet-to-be created tests.
message InnerMessageValue {
optional float float_value = 2;
repeated bytes bytes_values = 8;
}
message MiddleMessageValue {
repeated int32 int32_values = 5;
optional InnerMessageValue message_value = 11;
optional uint32 uint32_value = 13;
}
message MessageValue {
optional double double_value = 1;
optional MiddleMessageValue message_value = 11;
}
message RepeatedMessageValue {
message NestedMessageValue {
optional float float_value = 2;
repeated bytes bytes_values = 8;
}
repeated NestedMessageValue message_values = 11;
}