aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar Jie Luo <jieluo@google.com>2017-01-23 15:11:00 -0800
committerGravatar Jie Luo <jieluo@google.com>2017-01-26 11:05:16 -0800
commitea511491009a40360b4891cdc58d2c3f9bdf4481 (patch)
tree4609dbf4b5729075cf066d6bcc77a10c90b6f3c9
parent140e28d12e5eee856cbe1cac3313399542ec7a5b (diff)
Add python compatibility tests against v2.5.0 amd run on Travis.
-rw-r--r--.travis.yml4
-rwxr-xr-xpython/compatibility_tests/v2.5.0/setup.py87
-rwxr-xr-xpython/compatibility_tests/v2.5.0/test.sh110
-rwxr-xr-xpython/compatibility_tests/v2.5.0/tests/google/protobuf/internal/test_util.py4
-rwxr-xr-xpython/compatibility_tests/v2.5.0/tests/google/protobuf/internal/text_format_test.py5
-rwxr-xr-xtests.sh14
6 files changed, 220 insertions, 4 deletions
diff --git a/.travis.yml b/.travis.yml
index a34cb83b..77662993 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -63,6 +63,10 @@ matrix:
# fetch pre-built Linux protoc binaries in the test.
- os: linux
env: CONFIG=java_compatibility
+ # The Python compatibility test currently only runs on Linux because it will
+ # fetch pre-built Linux protoc binaries in the test.
+ - os: linux
+ env: CONFIG=python_compatibility
allow_failures:
# These currently do not work on OS X but are being worked on by @haberman.
- os: osx
diff --git a/python/compatibility_tests/v2.5.0/setup.py b/python/compatibility_tests/v2.5.0/setup.py
new file mode 100755
index 00000000..d8e34bc0
--- /dev/null
+++ b/python/compatibility_tests/v2.5.0/setup.py
@@ -0,0 +1,87 @@
+#! /usr/bin/env python
+#
+import glob
+import os
+import subprocess
+import sys
+
+from setuptools import setup, Extension, find_packages
+
+if sys.version_info[0] == 3:
+ # Python 3
+ from distutils.command.build_py import build_py_2to3 as _build_py
+else:
+ # Python 2
+ from distutils.command.build_py import build_py as _build_py
+from distutils.spawn import find_executable
+
+def generate_proto(source, code_gen):
+ """Invokes the Protocol Compiler to generate a _pb2.py from the given
+ .proto file."""
+ output = source.replace(".proto", "_pb2.py").replace("protos/src/proto/", "").replace("protos/python/", "")
+
+ if not os.path.exists(source):
+ sys.stderr.write("Can't find required file: %s\n" % source)
+ sys.exit(-1)
+
+ protoc_command = [ code_gen, "-Iprotos/src/proto", "-Iprotos/python", "--python_out=.", source ]
+ if subprocess.call(protoc_command) != 0:
+ sys.exit(-1)
+
+class build_py(_build_py):
+ def run(self):
+ # generate .proto file
+ protoc_1 = "./protoc_1"
+ protoc_2 = "./protoc_2"
+ generate_proto("protos/src/proto/google/protobuf/unittest.proto", protoc_2)
+ generate_proto("protos/src/proto/google/protobuf/unittest_custom_options.proto", protoc_1)
+ generate_proto("protos/src/proto/google/protobuf/unittest_import.proto", protoc_1)
+ generate_proto("protos/src/proto/google/protobuf/unittest_import_public.proto", protoc_1)
+ generate_proto("protos/src/proto/google/protobuf/unittest_mset.proto", protoc_1)
+ generate_proto("protos/src/proto/google/protobuf/unittest_no_generic_services.proto", protoc_1)
+ generate_proto("protos/python/google/protobuf/internal/factory_test1.proto", protoc_1)
+ generate_proto("protos/python/google/protobuf/internal/factory_test2.proto", protoc_1)
+ generate_proto("protos/python/google/protobuf/internal/more_extensions.proto", protoc_1)
+ generate_proto("protos/python/google/protobuf/internal/more_extensions_dynamic.proto", protoc_1)
+ generate_proto("protos/python/google/protobuf/internal/more_messages.proto", protoc_1)
+ generate_proto("protos/python/google/protobuf/internal/test_bad_identifiers.proto", protoc_1)
+
+ # _build_py is an old-style class, so super() doesn't work.
+ _build_py.run(self)
+
+if __name__ == '__main__':
+ # Keep this list of dependencies in sync with tox.ini.
+ install_requires = ['six>=1.9', 'setuptools']
+ if sys.version_info <= (2,7):
+ install_requires.append('ordereddict')
+ install_requires.append('unittest2')
+
+ setup(
+ name='protobuf',
+ description='Protocol Buffers',
+ download_url='https://github.com/google/protobuf/releases',
+ long_description="Protocol Buffers are Google's data interchange format",
+ url='https://developers.google.com/protocol-buffers/',
+ maintainer='protobuf@googlegroups.com',
+ maintainer_email='protobuf@googlegroups.com',
+ license='New BSD License',
+ classifiers=[
+ "Programming Language :: Python",
+ "Programming Language :: Python :: 2",
+ "Programming Language :: Python :: 2.6",
+ "Programming Language :: Python :: 2.7",
+ "Programming Language :: Python :: 3",
+ "Programming Language :: Python :: 3.3",
+ "Programming Language :: Python :: 3.4",
+ ],
+ packages=find_packages(
+ exclude=[
+ 'import_test_package',
+ ],
+ ),
+ test_suite='tests.google.protobuf.internal',
+ cmdclass={
+ 'build_py': build_py,
+ },
+ install_requires=install_requires,
+ )
diff --git a/python/compatibility_tests/v2.5.0/test.sh b/python/compatibility_tests/v2.5.0/test.sh
new file mode 100755
index 00000000..c640da80
--- /dev/null
+++ b/python/compatibility_tests/v2.5.0/test.sh
@@ -0,0 +1,110 @@
+#!/bin/bash
+
+set -ex
+
+# Change to the script's directory.
+cd $(dirname $0)
+
+# Version of the tests (i.e., the version of protobuf from where we extracted
+# these tests).
+TEST_VERSION=2.5.0
+
+# The old version of protobuf that we are testing compatibility against. This
+# is usually the same as TEST_VERSION (i.e., we use the tests extracted from
+# that version to test compatibility of the newest runtime against it), but it
+# is also possible to use this same test set to test the compatibiilty of the
+# latest version against other versions.
+case "$1" in
+ ""|2.5.0)
+ OLD_VERSION=2.5.0
+ OLD_VERSION_PROTOC=https://github.com/xfxyjwf/protobuf-compiler-release/raw/master/v2.5.0/linux/protoc
+ ;;
+ 2.6.1)
+ OLD_VERSION=2.6.1
+ OLD_VERSION_PROTOC=http://repo1.maven.org/maven2/com/google/protobuf/protoc/2.6.1-build2/protoc-2.6.1-build2-linux-x86_64.exe
+ ;;
+ 3.0.0-beta-1)
+ OLD_VERSION=3.0.0-beta-1
+ OLD_VERSION_PROTOC=http://repo1.maven.org/maven2/com/google/protobuf/protoc/3.0.0-beta-1/protoc-3.0.0-beta-1-linux-x86_64.exe
+ ;;
+ 3.0.0-beta-2)
+ OLD_VERSION=3.0.0-beta-2
+ OLD_VERSION_PROTOC=http://repo1.maven.org/maven2/com/google/protobuf/protoc/3.0.0-beta-2/protoc-3.0.0-beta-2-linux-x86_64.exe
+ ;;
+ 3.0.0-beta-3)
+ OLD_VERSION=3.0.0-beta-3
+ OLD_VERSION_PROTOC=http://repo1.maven.org/maven2/com/google/protobuf/protoc/3.0.0-beta-3/protoc-3.0.0-beta-3-linux-x86_64.exe
+ ;;
+ 3.0.0-beta-4)
+ OLD_VERSION=3.0.0-beta-4
+ OLD_VERSION_PROTOC=http://repo1.maven.org/maven2/com/google/protobuf/protoc/3.0.0-beta-4/protoc-3.0.0-beta-4-linux-x86_64.exe
+ ;;
+ *)
+ echo "[ERROR]: Unknown version number: $1"
+ exit 1
+ ;;
+esac
+
+# Extract the latest protobuf version number.
+VERSION_NUMBER=`grep "^__version__ = '.*'" ../../google/protobuf/__init__.py | sed "s|__version__ = '\(.*\)'|\1|"`
+
+echo "Running compatibility tests between $VERSION_NUMBER and $OLD_VERSION"
+
+# Check protoc
+[ -f ../../../src/protoc ] || {
+ echo "[ERROR]: Please build protoc first."
+ exit 1
+}
+
+# Test source compatibility. In these tests we recompile everything against
+# the new runtime (including old version generated code).
+rm google -f -r
+mkdir -p google/protobuf/internal
+# Build and copy the new runtime
+cd ../../
+python setup.py build
+cp google/protobuf/*.py compatibility_tests/v2.5.0/google/protobuf/
+cp google/protobuf/internal/*.py compatibility_tests/v2.5.0/google/protobuf/internal/
+cd compatibility_tests/v2.5.0
+cp tests/google/protobuf/internal/test_util.py google/protobuf/internal/
+cp google/protobuf/__init__.py google/
+
+# Download old version protoc compiler (for linux)
+wget $OLD_VERSION_PROTOC -O old_protoc
+chmod +x old_protoc
+
+# Test A.1:
+# proto set 1: use old version
+# proto set 2 which may import protos in set 1: use old version
+cp old_protoc protoc_1
+cp old_protoc protoc_2
+python setup.py build
+python setup.py test
+
+# Test A.2:
+# proto set 1: use new version
+# proto set 2 which may import protos in set 1: use old version
+cp ../../../src/protoc protoc_1
+cp old_protoc protoc_2
+python setup.py build
+python setup.py test
+
+# Test A.3:
+# proto set 1: use old version
+# proto set 2 which may import protos in set 1: use new version
+# Compatiblility test fail if the old verison is less than 3.0.0-alpha-1.
+# Because module name aliases was added in v3.0.0-alpha-1 instead of
+# fully-qualified module names to refer to dependencies: dot was replaced
+# with _dot_.
+if [ "$(printf "$OLD_VERSION\n3.0.0" | sort -V | head -n 1 )" = "3.0.0" ]; then
+ cp old_protoc protoc_1
+ cp ../../../src/protoc protoc_2
+ python setup.py build
+ python setup.py test
+fi
+
+rm google -r -f
+rm build -r -f
+rm protoc_1
+rm protoc_2
+rm old_protoc
diff --git a/python/compatibility_tests/v2.5.0/tests/google/protobuf/internal/test_util.py b/python/compatibility_tests/v2.5.0/tests/google/protobuf/internal/test_util.py
index be8ae7be..e2c9db03 100755
--- a/python/compatibility_tests/v2.5.0/tests/google/protobuf/internal/test_util.py
+++ b/python/compatibility_tests/v2.5.0/tests/google/protobuf/internal/test_util.py
@@ -567,9 +567,9 @@ def GoldenFile(filename):
# Search up the directory tree looking for the C++ protobuf source code.
path = '.'
while os.path.exists(path):
- if os.path.exists(os.path.join(path, 'src/google/protobuf')):
+ if os.path.exists(os.path.join(path, 'tests/google/protobuf/internal')):
# Found it. Load the golden file from the testdata directory.
- full_path = os.path.join(path, 'src/google/protobuf/testdata', filename)
+ full_path = os.path.join(path, 'tests/google/protobuf/internal', filename)
return open(full_path, 'rb')
path = os.path.join(path, '..')
diff --git a/python/compatibility_tests/v2.5.0/tests/google/protobuf/internal/text_format_test.py b/python/compatibility_tests/v2.5.0/tests/google/protobuf/internal/text_format_test.py
index 4b1b4f59..6bf7befb 100755
--- a/python/compatibility_tests/v2.5.0/tests/google/protobuf/internal/text_format_test.py
+++ b/python/compatibility_tests/v2.5.0/tests/google/protobuf/internal/text_format_test.py
@@ -94,6 +94,7 @@ class TextFormatTest(unittest.TestCase):
' }\n'
'}\n')
+ """
def testPrintBadEnumValue(self):
message = unittest_pb2.TestAllTypes()
message.optional_nested_enum = 100
@@ -115,6 +116,7 @@ class TextFormatTest(unittest.TestCase):
'[protobuf_unittest.optional_nested_enum_extension]: 100\n'
'[protobuf_unittest.optional_foreign_enum_extension]: 101\n'
'[protobuf_unittest.optional_import_enum_extension]: 102\n')
+ """
def testPrintExotic(self):
message = unittest_pb2.TestAllTypes()
@@ -470,7 +472,7 @@ class TextFormatTest(unittest.TestCase):
class TokenizerTest(unittest.TestCase):
-
+ """
def testSimpleTokenCases(self):
text = ('identifier1:"string1"\n \n\n'
'identifier2 : \n \n123 \n identifier3 :\'string\'\n'
@@ -585,6 +587,7 @@ class TokenizerTest(unittest.TestCase):
self.assertEqual(0, tokenizer.ConsumeUint32())
self.assertEqual(0, tokenizer.ConsumeUint64())
self.assertTrue(tokenizer.AtEnd())
+ """
def testConsumeByteString(self):
text = '"string1\''
diff --git a/tests.sh b/tests.sh
index ce149bc9..9e04bd66 100755
--- a/tests.sh
+++ b/tests.sh
@@ -62,7 +62,8 @@ build_cpp_distcheck() {
# List all files that should be included in the distribution package.
git ls-files | grep "^\(java\|python\|objectivec\|csharp\|js\|ruby\|php\|cmake\|examples\)" |\
- grep -v ".gitignore" | grep -v "java/compatibility_tests" > dist.lst
+ grep -v ".gitignore" | grep -v "java/compatibility_tests" |\
+ grep -v "python/compatibility_tests" > dist.lst
# Unzip the dist tar file.
DIST=`ls *.tar.gz`
tar -xf $DIST
@@ -311,6 +312,16 @@ build_python_cpp() {
cd ..
}
+build_python_compatibility() {
+ internal_build_cpp
+ # Use the unit-tests extraced from 2.5.0 to test the compatibilty.
+ cd python/compatibility_tests/v2.5.0
+ # Test between 2.5.0 and the current version.
+ ./test.sh 2.5.0
+ # Test between 3.0.0-beta-1 and the current version.
+ ./test.sh 3.0.0-beta-1
+}
+
build_ruby21() {
internal_build_cpp # For conformance tests.
cd ruby && bash travis-test.sh ruby-2.1 && cd ..
@@ -513,6 +524,7 @@ Usage: $0 { cpp |
objectivec_cocoapods_integration |
python |
python_cpp |
+ python_compatibility |
ruby21 |
ruby22 |
jruby |