Skip to content

Commit

Permalink
Add a warning for gencode that is one major version older than runtime
Browse files Browse the repository at this point in the history
PiperOrigin-RevId: 646598896
  • Loading branch information
protobuf-github-bot authored and copybara-github committed Jul 2, 2024
1 parent 5bb8c51 commit fa0b78a
Show file tree
Hide file tree
Showing 4 changed files with 107 additions and 10 deletions.
28 changes: 23 additions & 5 deletions java/core/src/main/java/com/google/protobuf/RuntimeVersion.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@

package com.google.protobuf;

import java.util.logging.Logger;

/**
* Provides the version of this Protobuf Java runtime, and methods for Protobuf Java gencode to
* validate that versions are compatible. Fields and methods in this class should be only accessed
Expand Down Expand Up @@ -36,6 +38,7 @@ public enum RuntimeDomain {
public static final String SUFFIX = OSS_SUFFIX;

private static final String VERSION_STRING = versionString(MAJOR, MINOR, PATCH, SUFFIX);
private static final Logger logger = Logger.getLogger(RuntimeVersion.class.getName());

/**
* Validates that the gencode version is compatible with this runtime version according to
Expand Down Expand Up @@ -83,11 +86,20 @@ private static void validateProtobufGencodeVersionImpl(

// Check that runtime major version is the same as the gencode major version.
if (major != MAJOR) {
throw new ProtobufRuntimeVersionException(
String.format(
"Detected mismatched Protobuf Gencode/Runtime major versions when loading %s: gencode"
+ " %s, runtime %s. Same major version is required.",
location, gencodeVersionString, VERSION_STRING));
if (major == MAJOR - 1) {
logger.warning(
String.format(
" Protobuf gencode version %s is exactly one major version older than the runtime"
+ " version %s at %s. Please update the gencode to avoid compatibility"
+ " violations in the next runtime release.",
gencodeVersionString, VERSION_STRING, location));
} else {
throw new ProtobufRuntimeVersionException(
String.format(
"Detected mismatched Protobuf Gencode/Runtime major versions when loading %s:"
+ " gencode %s, runtime %s. Same major version is required.",
location, gencodeVersionString, VERSION_STRING));
}
}

// Check that runtime version is newer than the gencode version.
Expand All @@ -97,6 +109,12 @@ private static void validateProtobufGencodeVersionImpl(
"Detected incompatible Protobuf Gencode/Runtime versions when loading %s: gencode %s,"
+ " runtime %s. Runtime version cannot be older than the linked gencode version.",
location, gencodeVersionString, VERSION_STRING));
} else if (MINOR > minor || PATCH > patch) {
logger.warning(
String.format(
" Protobuf gencode version %s is older than the runtime version %s at %s. Please"
+ " avoid checked-in Protobuf gencode that can be obsolete.",
gencodeVersionString, VERSION_STRING, location));
}

// Check that runtime version suffix is the same as the gencode version suffix.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import static com.google.common.truth.Truth.assertThat;
import static org.junit.Assert.assertThrows;

import java.util.logging.Logger;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
Expand Down Expand Up @@ -144,4 +145,38 @@ public void versionValidation_differentVesionSuffixDisallowed() {
"Detected mismatched Protobuf Gencode/Runtime version suffixes when loading"
+ " testing.Foo");
}

@Test
public void versionValidation_warnOlderGencodeVersion() {
TestUtil.TestLogHandler logHandler = new TestUtil.TestLogHandler();
Logger logger = Logger.getLogger(RuntimeVersion.class.getName());
logger.addHandler(logHandler);
RuntimeVersion.validateProtobufGencodeVersion(
RuntimeVersion.DOMAIN,
RuntimeVersion.MAJOR,
RuntimeVersion.MINOR - 1,
RuntimeVersion.PATCH,
RuntimeVersion.SUFFIX,
"dummy");
assertThat(logHandler.getStoredLogRecords()).hasSize(1);
assertThat(logHandler.getStoredLogRecords().get(0).getMessage())
.contains("Please avoid checked-in Protobuf gencode that can be obsolete.");
}

@Test
public void versionValidation_gencodeOneMajorVersionOlderWarning() {
TestUtil.TestLogHandler logHandler = new TestUtil.TestLogHandler();
Logger logger = Logger.getLogger(RuntimeVersion.class.getName());
logger.addHandler(logHandler);
RuntimeVersion.validateProtobufGencodeVersion(
RuntimeVersion.DOMAIN,
RuntimeVersion.MAJOR - 1,
RuntimeVersion.MINOR,
RuntimeVersion.PATCH,
RuntimeVersion.SUFFIX,
"dummy");
assertThat(logHandler.getStoredLogRecords()).hasSize(1);
assertThat(logHandler.getStoredLogRecords().get(0).getMessage())
.contains("is exactly one major version older than the runtime version");
}
}
29 changes: 29 additions & 0 deletions python/google/protobuf/internal/runtime_version_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,35 @@ def test_different_suffix_disallowed(self):
'foo.proto',
)

def test_gencode_older_than_runtime_version_warning(self):
with self.assertWarnsRegex(
Warning,
expected_regex=(
'Please avoid checked-in Protobuf gencode that can be obsolete.'
),
):
runtime_version.ValidateProtobufRuntimeVersion(
runtime_version.DOMAIN,
runtime_version.MAJOR,
runtime_version.MINOR - 1,
runtime_version.PATCH,
runtime_version.SUFFIX,
'foo.proto',
)

def test_gencode_one_major_version_older_warning(self):
with self.assertWarnsRegex(
Warning, expected_regex='is exactly one major version older'
):
runtime_version.ValidateProtobufRuntimeVersion(
runtime_version.DOMAIN,
runtime_version.MAJOR - 1,
runtime_version.MINOR,
runtime_version.PATCH,
runtime_version.SUFFIX,
'foo.proto',
)


if __name__ == '__main__':
unittest.main()
25 changes: 20 additions & 5 deletions python/google/protobuf/runtime_version.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@

from enum import Enum
import os
import warnings


class Domain(Enum):
Expand Down Expand Up @@ -87,18 +88,32 @@ def ValidateProtobufRuntimeVersion(
)

if gen_major != MAJOR:
_ReportVersionError(
'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 gen_major == MAJOR - 1:
warnings.warn(
'Protobuf gencode version %s is exactly one major version older than'
' the runtime version %s at %s. Please update the gencode to avoid'
' compatibility violations in the next runtime release.'
% (gen_version, version, location)
)
else:
_ReportVersionError(
'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):
_ReportVersionError(
'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}'
)
elif MINOR > gen_minor or PATCH > gen_patch:
warnings.warn(
'Protobuf gencode version %s is older than the runtime version %s at'
' %s. Please avoid checked-in Protobuf gencode that can be obsolete.'
% (gen_version, version, location)
)

if gen_suffix != SUFFIX:
_ReportVersionError(
Expand Down

0 comments on commit fa0b78a

Please sign in to comment.