Skip to content

Commit

Permalink
Add Active Record Marshal forward compatibility tests
Browse files Browse the repository at this point in the history
This is following a recent discussion on Basecamp.

So far Rails haven't tried to preserve Marshal compatibilty of Active Record instances,
and it probably shouldn't as it isn't as controllable as other serialization formats.

However it's common to store ActiveRecord instances in Rails.cache, and when the
Marshal format changes, it causes problems during Rails upgrade. Process using the new Rails
version might not be able to deserialize the existing cache, and also older process that
weren't restarted yet my fail to load the cache entries written by newer processes.

The goal of this PR is not to freeze the Marshal format, but to have a better visibility
when it changes, so that's it's done on purpose with good reasons rather than accidentally.

Note that this only test forward compatibility (AR vN reading entries written by AR vN-1),
ideally we'd also test backward compatibility (AR vN-1 reading entries written by AR vN),
but it means installing and loading and older Active Record as part of the test suite.
  • Loading branch information
byroot committed Jul 2, 2020
1 parent 4fe1452 commit 617f990
Show file tree
Hide file tree
Showing 7 changed files with 39 additions and 0 deletions.
39 changes: 39 additions & 0 deletions activerecord/test/cases/marshal_serialization_test.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
# frozen_string_literal: true

require "cases/helper"
require "models/topic"
require "models/reply"

class MarshalSerializationTest < ActiveRecord::TestCase
fixtures :topics

def test_deserializing_rails_6_0_marshal_basic
topic = Marshal.load(marshal_fixture("rails_6_0_topic"))

assert_not_predicate topic, :new_record?
assert_equal 1, topic.id
assert_equal "The First Topic", topic.title
assert_equal "Have a nice day", topic.content
end

def test_deserializing_rails_6_0_marshal_with_loaded_association_cache
topic = Marshal.load(marshal_fixture("rails_6_0_topic_associations"))

assert_not_predicate topic, :new_record?
assert_equal 1, topic.id
assert_equal "The First Topic", topic.title
assert_equal "Have a nice day", topic.content
end

private
def marshal_fixture(file_name)
File.binread(marshal_fixture_path(file_name))
end

def marshal_fixture_path(file_name)
File.expand_path(
"support/marshal_compatibility_fixtures/#{ActiveRecord::Base.connection.adapter_name}/#{file_name}.dump",
TEST_ROOT
)
end
end
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.

0 comments on commit 617f990

Please sign in to comment.