Introduce Python Protobuf runtime version.
PiperOrigin-RevId: 613224059pull/15971/head
parent
03687b798b
commit
554a00c40a
|
@ -0,0 +1,123 @@
|
|||
# Protocol Buffers - Google's data interchange format
|
||||
# Copyright 2008 Google Inc. All rights reserved.
|
||||
#
|
||||
# Use of this source code is governed by a BSD-style
|
||||
# license that can be found in the LICENSE file or at
|
||||
# https://developers.google.com/open-source/licenses/bsd
|
||||
|
||||
"""Tests for google.protobuf.runtime_version."""
|
||||
|
||||
__author__ = 'shaod@google.com (Dennis Shao)'
|
||||
|
||||
import unittest
|
||||
from google.protobuf import runtime_version
|
||||
|
||||
|
||||
class RuntimeVersionTest(unittest.TestCase):
|
||||
|
||||
def test_invalid_version(self):
|
||||
with self.assertRaisesRegex(
|
||||
runtime_version.VersionError, 'Invalid gencode version: -1.-2.-3'
|
||||
):
|
||||
runtime_version.ValidateProtobufRuntimeVersion(
|
||||
runtime_version.DOMAIN, -1, -2, -3, '', 'dummy.proto'
|
||||
)
|
||||
|
||||
def test_cross_domain_disallowed(self):
|
||||
gencode_domain = runtime_version.Domain.GOOGLE_INTERNAL
|
||||
runtime_domain = runtime_version.Domain.PUBLIC
|
||||
with self.assertRaisesRegex(
|
||||
runtime_version.VersionError,
|
||||
'Detected mismatched Protobuf Gencode/Runtime domains when loading'
|
||||
f' foo.proto: gencode {gencode_domain.name} runtime'
|
||||
f' {runtime_domain.name}',
|
||||
):
|
||||
runtime_version.ValidateProtobufRuntimeVersion(
|
||||
gencode_domain, 1, 2, 3, '', 'foo.proto'
|
||||
)
|
||||
|
||||
def test_mismatched_major_disallowed(self):
|
||||
gencode_version_string = f'{1}.{runtime_version.MINOR}.{runtime_version.PATCH}{runtime_version.SUFFIX}'
|
||||
runtime_version_string = f'{runtime_version.MAJOR}.{runtime_version.MINOR}.{runtime_version.PATCH}{runtime_version.SUFFIX}'
|
||||
with self.assertRaisesRegex(
|
||||
runtime_version.VersionError,
|
||||
'Detected mismatched Protobuf Gencode/Runtime major versions when'
|
||||
f' loading foo.proto: gencode {gencode_version_string} runtime'
|
||||
f' {runtime_version_string}',
|
||||
):
|
||||
runtime_version.ValidateProtobufRuntimeVersion(
|
||||
runtime_version.DOMAIN,
|
||||
1,
|
||||
runtime_version.MINOR,
|
||||
runtime_version.PATCH,
|
||||
runtime_version.SUFFIX,
|
||||
'foo.proto',
|
||||
)
|
||||
|
||||
def test_same_version_allowed(self):
|
||||
runtime_version.ValidateProtobufRuntimeVersion(
|
||||
runtime_version.DOMAIN,
|
||||
runtime_version.MAJOR,
|
||||
runtime_version.MINOR,
|
||||
runtime_version.PATCH,
|
||||
runtime_version.SUFFIX,
|
||||
'dummy.proto',
|
||||
)
|
||||
|
||||
def test_newer_runtime_version_allowed(self):
|
||||
runtime_version.ValidateProtobufRuntimeVersion(
|
||||
runtime_version.DOMAIN,
|
||||
runtime_version.MAJOR,
|
||||
runtime_version.MINOR - 1,
|
||||
runtime_version.PATCH,
|
||||
runtime_version.SUFFIX,
|
||||
'dummy.proto',
|
||||
)
|
||||
|
||||
def test_older_runtime_version_disallowed(self):
|
||||
with self.assertRaisesRegex(
|
||||
runtime_version.VersionError,
|
||||
'Detected incompatible Protobuf Gencode/Runtime versions when'
|
||||
' loading foo.proto',
|
||||
):
|
||||
runtime_version.ValidateProtobufRuntimeVersion(
|
||||
runtime_version.DOMAIN,
|
||||
runtime_version.MAJOR,
|
||||
runtime_version.MINOR + 1,
|
||||
runtime_version.PATCH,
|
||||
runtime_version.SUFFIX,
|
||||
'foo.proto',
|
||||
)
|
||||
|
||||
with self.assertRaisesRegex(
|
||||
runtime_version.VersionError,
|
||||
'Detected incompatible Protobuf Gencode/Runtime versions when'
|
||||
' loading foo.proto',
|
||||
):
|
||||
runtime_version.ValidateProtobufRuntimeVersion(
|
||||
runtime_version.DOMAIN,
|
||||
runtime_version.MAJOR,
|
||||
runtime_version.MINOR,
|
||||
runtime_version.PATCH + 1,
|
||||
runtime_version.SUFFIX,
|
||||
'foo.proto',
|
||||
)
|
||||
|
||||
def test_different_suffix_disallowed(self):
|
||||
with self.assertRaisesRegex(
|
||||
runtime_version.VersionError,
|
||||
'Detected mismatched Protobuf Gencode/Runtime version suffixes when'
|
||||
' loading foo.proto',
|
||||
):
|
||||
runtime_version.ValidateProtobufRuntimeVersion(
|
||||
runtime_version.DOMAIN,
|
||||
runtime_version.MAJOR,
|
||||
runtime_version.MINOR,
|
||||
runtime_version.PATCH,
|
||||
'-noflag',
|
||||
'foo.proto',
|
||||
)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
|
@ -0,0 +1,97 @@
|
|||
# Protocol Buffers - Google's data interchange format
|
||||
# Copyright 2008 Google Inc. All rights reserved.
|
||||
#
|
||||
# Use of this source code is governed by a BSD-style
|
||||
# license that can be found in the LICENSE file or at
|
||||
# https://developers.google.com/open-source/licenses/bsd
|
||||
|
||||
"""Protobuf Runtime versions and validators.
|
||||
|
||||
It should only be accessed by Protobuf gencodes and tests. DO NOT USE it
|
||||
elsewhere.
|
||||
"""
|
||||
|
||||
__author__ = 'shaod@google.com (Dennis Shao)'
|
||||
|
||||
from enum import Enum
|
||||
import os
|
||||
|
||||
|
||||
class Domain(Enum):
|
||||
GOOGLE_INTERNAL = 1
|
||||
PUBLIC = 2
|
||||
|
||||
|
||||
class VersionError(Exception):
|
||||
"""Exception class for version violation."""
|
||||
|
||||
|
||||
# The versions of this Python Protobuf runtime to be changed automatically by
|
||||
# the Protobuf release process. Do not edit them manually.
|
||||
DOMAIN = Domain.PUBLIC
|
||||
MAJOR = 5
|
||||
MINOR = 27
|
||||
PATCH = 0
|
||||
SUFFIX = '-dev'
|
||||
|
||||
|
||||
def ValidateProtobufRuntimeVersion(
|
||||
gen_domain, gen_major, gen_minor, gen_patch, gen_suffix, location
|
||||
):
|
||||
"""Function to validate versions.
|
||||
|
||||
Args:
|
||||
gen_domain: The domain where the code was generated from.
|
||||
gen_major: The major version number of the gencode.
|
||||
gen_minor: The minor version number of the gencode.
|
||||
gen_patch: The patch version number of the gencode.
|
||||
gen_suffix: The version suffix e.g. '-dev', '-rc1' of the gencode.
|
||||
location: The proto location that causes the version violation.
|
||||
|
||||
Raises:
|
||||
VersionError: if gencode version is invalid or incompatible with the
|
||||
runtime.
|
||||
"""
|
||||
|
||||
disable_flag = os.getenv('TEMORARILY_DISABLE_PROTOBUF_VERSION_CHECK')
|
||||
if disable_flag is not None and disable_flag.lower() == 'true':
|
||||
return
|
||||
|
||||
version = f'{MAJOR}.{MINOR}.{PATCH}{SUFFIX}'
|
||||
gen_version = f'{gen_major}.{gen_minor}.{gen_patch}{gen_suffix}'
|
||||
|
||||
if gen_major < 0 or gen_minor < 0 or gen_patch < 0:
|
||||
raise VersionError(f'Invalid gencode version: {gen_version}')
|
||||
|
||||
error_prompt = (
|
||||
'See Protobuf version guarantees at'
|
||||
' https://protobuf.dev/support/cross-version-runtime-guarantee.'
|
||||
)
|
||||
|
||||
if gen_domain != DOMAIN:
|
||||
raise VersionError(
|
||||
'Detected mismatched Protobuf Gencode/Runtime domains when loading'
|
||||
f' {location}: gencode {gen_domain.name} runtime {DOMAIN.name}.'
|
||||
' Cross-domain usage of Protobuf is not supported.'
|
||||
)
|
||||
|
||||
if gen_major != MAJOR:
|
||||
raise VersionError(
|
||||
'Detected mismatched Protobuf Gencode/Runtime major versions when'
|
||||
f' loading {location}: gencode {gen_version} runtime {version}.'
|
||||
f' Same major version is required. {error_prompt}'
|
||||
)
|
||||
|
||||
if MINOR < gen_minor or (MINOR == gen_minor and PATCH < gen_patch):
|
||||
raise VersionError(
|
||||
'Detected incompatible Protobuf Gencode/Runtime versions when loading'
|
||||
f' {location}: gencode {gen_version} runtime {version}. Runtime version'
|
||||
f' cannot be older than the linked gencode version. {error_prompt}'
|
||||
)
|
||||
|
||||
if gen_suffix is not SUFFIX:
|
||||
raise VersionError(
|
||||
'Detected mismatched Protobuf Gencode/Runtime version suffixes when'
|
||||
f' loading {location}: gencode {gen_version} runtime {version}.'
|
||||
f' Version suffixes must be the same. {error_prompt}'
|
||||
)
|
Loading…
Reference in New Issue