From cea22a12ff06f818843b616ba172d8770e20f73b Mon Sep 17 00:00:00 2001 From: Will Daly Date: Wed, 19 Aug 2015 11:35:47 -0700 Subject: [PATCH] Allow user partition version >= current version. If code is deployed that updates the user partition version, then the code is rolled back, we may see user partition versions greater than the currently deployed version. The previous behavior was to raise a TypeError when this occurred; the new behavior assumes that the newer version is backwards compatible and tries to load the partition. --- .../xmodule/xmodule/partitions/partitions.py | 6 ++++- .../partitions/tests/test_partitions.py | 25 ++++++++++++++++--- 2 files changed, 26 insertions(+), 5 deletions(-) diff --git a/common/lib/xmodule/xmodule/partitions/partitions.py b/common/lib/xmodule/xmodule/partitions/partitions.py index cd7307077c..31d8b79456 100644 --- a/common/lib/xmodule/xmodule/partitions/partitions.py +++ b/common/lib/xmodule/xmodule/partitions/partitions.py @@ -161,7 +161,11 @@ class UserPartition(namedtuple("UserPartition", "id name description groups sche if value["version"] == 1: # If no scheme was provided, set it to the default ('random') scheme_id = UserPartition.VERSION_1_SCHEME - elif value["version"] == UserPartition.VERSION: + + # Version changes should be backwards compatible in case the code + # gets rolled back. If we see a version number greater than the current + # version, we should try to read it rather than raising an exception. + elif value["version"] >= UserPartition.VERSION: if "scheme" not in value: raise TypeError("UserPartition dict {0} missing value key 'scheme'".format(value)) scheme_id = value["scheme"] diff --git a/common/lib/xmodule/xmodule/partitions/tests/test_partitions.py b/common/lib/xmodule/xmodule/partitions/tests/test_partitions.py index 66d69f9fbc..b5db22a238 100644 --- a/common/lib/xmodule/xmodule/partitions/tests/test_partitions.py +++ b/common/lib/xmodule/xmodule/partitions/tests/test_partitions.py @@ -60,7 +60,7 @@ class TestGroup(TestCase): jsonified = { "id": test_id, "name": name, - "version": 9001 + "version": -1, } with self.assertRaisesRegexp(TypeError, "has unexpected version"): Group.from_json(jsonified) @@ -241,14 +241,13 @@ class TestUserPartition(PartitionTestCase): with self.assertRaisesRegexp(UserPartitionError, "Unrecognized scheme"): UserPartition.from_json(jsonified) - # Wrong version (it's over 9000!) - # Wrong version (it's over 9000!) + # Wrong version jsonified = { 'id': self.TEST_ID, "name": self.TEST_NAME, "description": self.TEST_DESCRIPTION, "groups": [group.to_json() for group in self.TEST_GROUPS], - "version": 9001, + "version": -1, "scheme": self.TEST_SCHEME_NAME, } with self.assertRaisesRegexp(TypeError, "has unexpected version"): @@ -284,6 +283,24 @@ class TestUserPartition(PartitionTestCase): with self.assertRaises(NoSuchUserPartitionGroupError): self.user_partition.get_group(3) + def test_forward_compatibility(self): + # If the user partition version is updated in a release, + # then the release is rolled back, courses might contain + # version numbers greater than the currently deployed + # version number. + newer_version_json = { + "id": self.TEST_ID, + "name": self.TEST_NAME, + "description": self.TEST_DESCRIPTION, + "groups": [group.to_json() for group in self.TEST_GROUPS], + "version": UserPartition.VERSION + 1, + "scheme": "mock", + "additional_new_field": "foo", + } + partition = UserPartition.from_json(newer_version_json) + self.assertEqual(partition.id, self.TEST_ID) + self.assertEqual(partition.name, self.TEST_NAME) + class StaticPartitionService(PartitionService): """