Skip to content

Commit 4c6c470

Browse files
authored
ActiveModel compatibility between Rails 7 and 8 (#4189)
The internal representation of the validation context has changed between Rails 7 and 8. As we don't use validation contexts, it only has to be ensured that a newly introduced class exists.
1 parent 5247ce6 commit 4c6c470

File tree

2 files changed

+134
-5
lines changed

2 files changed

+134
-5
lines changed

lib/cloud_controller/db.rb

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -255,3 +255,11 @@ def self.logger
255255
end
256256
end
257257
end
258+
259+
if Rails::VERSION::MAJOR < 8
260+
module ActiveModel
261+
# rubocop:disable Lint/EmptyClass
262+
class ValidationContext; end
263+
# rubocop:enable Lint/EmptyClass
264+
end
265+
end

spec/unit/jobs/deserialization_spec.rb

Lines changed: 126 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,7 @@ module Jobs
118118

119119
subject(:job) { SpaceApplyManifestActionJob.new(space, app_guid_message_hash, apply_manifest_action, user_audit_info) }
120120

121-
let(:serialized_job) do
121+
let(:serialized_job_rails_7) do
122122
<<~EOS
123123
--- !ruby/object:VCAP::CloudController::Jobs::LoggingContextJob
124124
handler: !ruby/object:VCAP::CloudController::Jobs::TimeoutJob
@@ -230,21 +230,142 @@ module Jobs
230230
EOS
231231
end
232232

233+
let(:serialized_job_rails_8) do
234+
<<~EOS
235+
--- !ruby/object:VCAP::CloudController::Jobs::LoggingContextJob
236+
handler: !ruby/object:VCAP::CloudController::Jobs::TimeoutJob
237+
handler: !ruby/object:VCAP::CloudController::Jobs::SpaceApplyManifestActionJob
238+
space: !ruby/object:VCAP::CloudController::Space
239+
values:
240+
:id: #{space.id}
241+
:guid: space-guid
242+
:created_at: #{space.created_at.strftime('%F %H:%M:%S.%9N Z')}
243+
:updated_at: #{space.updated_at.strftime('%F %H:%M:%S.%9N Z')}
244+
:name: space-name
245+
:organization_id: #{org.id}
246+
:space_quota_definition_id:#{' '}
247+
:allow_ssh: true
248+
:isolation_segment_guid:#{' '}
249+
app_guid_message_hash:
250+
app-guid: &1 !ruby/object:VCAP::CloudController::AppManifestMessage
251+
requested_keys:
252+
- :name
253+
- :instances
254+
- :routes
255+
- :buildpack
256+
- :stack
257+
extra_keys: []
258+
buildpack: ruby
259+
instances: 4
260+
name: app-name
261+
routes:
262+
- :route: app.bommel
263+
stack: cflinuxfs4
264+
original_yaml:
265+
:name: app-name
266+
:instances: 4
267+
:routes:
268+
- :route: app.bommel
269+
:buildpack: ruby
270+
:stack: cflinuxfs4
271+
context_for_validation: !ruby/object:ActiveModel::ValidationContext
272+
context:#{' '}
273+
errors: !ruby/object:ActiveModel::Errors
274+
base: *1
275+
errors: []
276+
manifest_process_scale_messages:
277+
- &2 !ruby/object:VCAP::CloudController::ManifestProcessScaleMessage
278+
requested_keys:
279+
- :instances
280+
- :type
281+
extra_keys: []
282+
instances: 4
283+
type: web
284+
context_for_validation: !ruby/object:ActiveModel::ValidationContext
285+
context:#{' '}
286+
errors: !ruby/object:ActiveModel::Errors
287+
base: *2
288+
errors: []
289+
manifest_process_update_messages: []
290+
app_update_message: &3 !ruby/object:VCAP::CloudController::AppUpdateMessage
291+
requested_keys:
292+
- :lifecycle
293+
extra_keys: []
294+
lifecycle:
295+
:data:
296+
:buildpacks:
297+
- ruby
298+
:stack: cflinuxfs4
299+
context_for_validation: !ruby/object:ActiveModel::ValidationContext
300+
context:#{' '}
301+
errors: !ruby/object:ActiveModel::Errors
302+
base: *3
303+
errors: []
304+
manifest_buildpack_message: &4 !ruby/object:VCAP::CloudController::ManifestBuildpackMessage
305+
requested_keys:
306+
- :buildpack
307+
extra_keys: []
308+
buildpack: ruby
309+
context_for_validation: !ruby/object:ActiveModel::ValidationContext
310+
context:#{' '}
311+
errors: !ruby/object:ActiveModel::Errors
312+
base: *4
313+
errors: []
314+
manifest_routes_update_message: &5 !ruby/object:VCAP::CloudController::ManifestRoutesUpdateMessage
315+
requested_keys:
316+
- :routes
317+
extra_keys: []
318+
routes:
319+
- :route: app.bommel
320+
context_for_validation: !ruby/object:ActiveModel::ValidationContext
321+
context:#{' '}
322+
errors: !ruby/object:ActiveModel::Errors
323+
base: *5
324+
errors: []
325+
manifest_route_mappings:
326+
- :route: !ruby/object:VCAP::CloudController::ManifestRoute
327+
attrs:
328+
:scheme: unspecified
329+
:user:#{' '}
330+
:password:#{' '}
331+
:host: app.bommel
332+
:port:#{' '}
333+
:path: ''
334+
:query:#{' '}
335+
:fragment:#{' '}
336+
:full_route: app.bommel
337+
:options: {}
338+
:protocol:#{' '}
339+
apply_manifest_action: !ruby/object:VCAP::CloudController::AppApplyManifest
340+
user_audit_info: &6 !ruby/object:VCAP::CloudController::UserAuditInfo
341+
user_email: [email protected]
342+
user_name: user-name
343+
user_guid: user-guid
344+
user_audit_info: *6
345+
timeout: 14400
346+
request_id:#{' '}
347+
EOS
348+
end
349+
233350
it 'equals dumped job yaml' do
234351
VCAP::CloudController::Jobs::Enqueuer.new(job).enqueue
235352
jobs_in_db = Sequel::Model.db.fetch('SELECT handler FROM delayed_jobs').all
236353
expect(jobs_in_db.size).to eq(1)
237354

238355
# We are not interested in minor differences like ordering of nodes. Therefore comparing it as hash.
239-
permitted_classes = [ActiveModel::Errors, Time, Symbol, UserAuditInfo, AppApplyManifest, ManifestRoute, ManifestRoutesUpdateMessage, ManifestBuildpackMessage,
240-
AppUpdateMessage, ManifestProcessScaleMessage, AppManifestMessage, Space, SpaceApplyManifestActionJob, TimeoutJob, LoggingContextJob]
356+
permitted_classes = [ActiveModel::Errors, ActiveModel::ValidationContext, Time, Symbol, UserAuditInfo, AppApplyManifest, ManifestRoute, ManifestRoutesUpdateMessage,
357+
ManifestBuildpackMessage, AppUpdateMessage, ManifestProcessScaleMessage, AppManifestMessage, Space, SpaceApplyManifestActionJob, TimeoutJob,
358+
LoggingContextJob]
241359
db_job = YAML.safe_load(jobs_in_db[0][:handler], permitted_classes: permitted_classes, aliases: true).as_json
242-
dumped_job = YAML.safe_load(serialized_job, permitted_classes: permitted_classes, aliases: true).as_json
360+
dumped_job = YAML.safe_load(Rails::VERSION::MAJOR >= 8 ? serialized_job_rails_8 : serialized_job_rails_7, permitted_classes: permitted_classes, aliases: true).as_json
243361
expect(db_job).to eq(dumped_job)
244362
end
245363

246364
it 'can be deserialized' do
247-
object = YAML.load_dj(serialized_job)
365+
object = YAML.load_dj(serialized_job_rails_7)
366+
expect(object).not_to be_nil
367+
368+
object = YAML.load_dj(serialized_job_rails_8)
248369
expect(object).not_to be_nil
249370
end
250371
end

0 commit comments

Comments
 (0)