canvas_sync 0.23.4 → 0.24.0.beta1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (206) hide show
  1. checksums.yaml +4 -4
  2. data/Rakefile +2 -4
  3. data/lib/canvas_sync/processors/provisioning_report_processor.rb +1 -0
  4. data/lib/canvas_sync/version.rb +1 -1
  5. data/lib/canvas_sync.rb +6 -4
  6. data/spec/canvas_sync/canvas_sync_spec.rb +11 -11
  7. data/spec/canvas_sync/live_events/process_event_job_spec.rb +1 -0
  8. data/spec/{dummy → internal}/app/models/application_record.rb +1 -0
  9. data/spec/{dummy → internal}/app/models/content_migration.rb +0 -0
  10. data/spec/{dummy → internal}/app/models/course.rb +0 -1
  11. data/spec/{dummy → internal}/app/models/course_nickname.rb +0 -0
  12. data/spec/{dummy → internal}/app/models/learning_outcome.rb +0 -0
  13. data/spec/{dummy → internal}/app/services/live_events/assignment_event.rb +0 -0
  14. data/spec/{dummy → internal}/app/services/live_events/course_event.rb +0 -0
  15. data/spec/{dummy → internal}/app/services/live_events/course_section_event.rb +0 -0
  16. data/spec/{dummy → internal}/app/services/live_events/enrollment_event.rb +0 -0
  17. data/spec/{dummy → internal}/app/services/live_events/grade_event.rb +0 -0
  18. data/spec/{dummy → internal}/app/services/live_events/module_event.rb +0 -0
  19. data/spec/{dummy → internal}/app/services/live_events/module_item_event.rb +0 -0
  20. data/spec/{dummy → internal}/app/services/live_events/submission_event.rb +0 -0
  21. data/spec/{dummy → internal}/app/services/live_events/syllabus_event.rb +0 -0
  22. data/spec/{dummy → internal}/app/services/live_events/user_event.rb +0 -0
  23. data/spec/internal/bin/rails +9 -0
  24. data/spec/internal/config/database.yml +5 -0
  25. data/spec/internal/config/routes.rb +5 -0
  26. data/spec/internal/config/storage.yml +3 -0
  27. data/spec/{dummy/db/migrate/20220926221926_create_users.rb → internal/db/migrate/20250912205136_create_users.rb} +0 -0
  28. data/spec/{dummy/db/migrate/20201016181346_create_pseudonyms.rb → internal/db/migrate/20250912205137_create_pseudonyms.rb} +0 -0
  29. data/spec/{dummy/db/migrate/20200415171620_create_groups.rb → internal/db/migrate/20250912205139_create_groups.rb} +0 -0
  30. data/spec/{dummy/db/migrate/20200416214248_create_group_memberships.rb → internal/db/migrate/20250912205140_create_group_memberships.rb} +0 -0
  31. data/spec/{dummy/db/migrate/20190702203622_create_accounts.rb → internal/db/migrate/20250912205141_create_accounts.rb} +0 -0
  32. data/spec/{dummy/db/migrate/20190702203623_create_terms.rb → internal/db/migrate/20250912205142_create_terms.rb} +0 -0
  33. data/spec/{dummy/db/migrate/20190702203625_create_sections.rb → internal/db/migrate/20250912205144_create_sections.rb} +0 -0
  34. data/spec/{dummy/db/migrate/20190702203626_create_assignments.rb → internal/db/migrate/20250912205145_create_assignments.rb} +0 -0
  35. data/spec/{dummy/db/migrate/20190702203627_create_submissions.rb → internal/db/migrate/20250912205146_create_submissions.rb} +0 -0
  36. data/spec/{dummy/db/migrate/20190927204545_create_roles.rb → internal/db/migrate/20250912205147_create_roles.rb} +2 -2
  37. data/spec/{dummy/db/migrate/20190927204546_create_admins.rb → internal/db/migrate/20250912205148_create_admins.rb} +0 -0
  38. data/spec/{dummy/db/migrate/20190702203630_create_assignment_groups.rb → internal/db/migrate/20250912205149_create_assignment_groups.rb} +0 -0
  39. data/spec/{dummy/db/migrate/20190702203631_create_context_modules.rb → internal/db/migrate/20250912205150_create_context_modules.rb} +0 -0
  40. data/spec/{dummy/db/migrate/20190702203632_create_context_module_items.rb → internal/db/migrate/20250912205151_create_context_module_items.rb} +0 -0
  41. data/spec/{dummy/db/migrate/20210907233329_create_user_observers.rb → internal/db/migrate/20250912205152_create_user_observers.rb} +0 -0
  42. data/spec/{dummy/db/migrate/20210907233330_create_grading_periods.rb → internal/db/migrate/20250912205153_create_grading_periods.rb} +0 -0
  43. data/spec/{dummy/db/migrate/20211001184920_create_grading_period_groups.rb → internal/db/migrate/20250912205154_create_grading_period_groups.rb} +0 -0
  44. data/spec/{dummy/db/migrate/20220308072643_create_content_migrations.rb → internal/db/migrate/20250912205155_create_content_migrations.rb} +0 -0
  45. data/spec/{dummy/db/migrate/20220712210559_create_learning_outcomes.rb → internal/db/migrate/20250912205156_create_learning_outcomes.rb} +0 -0
  46. data/spec/{dummy/db/migrate/20240523101010_create_learning_outcome_results.rb → internal/db/migrate/20250912205157_create_learning_outcome_results.rb} +0 -0
  47. data/spec/{dummy/db/migrate/20240510094100_create_rubric_associations.rb → internal/db/migrate/20250912205160_create_rubric_associations.rb} +0 -0
  48. data/spec/{dummy/db/migrate/20240510101100_create_rubric_assessments.rb → internal/db/migrate/20250912205161_create_rubric_assessments.rb} +0 -0
  49. data/spec/{dummy/db/migrate/20240828161300_create_course_progresses.rb → internal/db/migrate/20250912205162_create_course_progresses.rb} +0 -0
  50. data/spec/internal/db/schema.rb +6 -0
  51. data/spec/spec_helper.rb +8 -4
  52. metadata +182 -372
  53. data/lib/canvas_sync/job_batches/batch.rb +0 -595
  54. data/lib/canvas_sync/job_batches/callback.rb +0 -135
  55. data/lib/canvas_sync/job_batches/chain_builder.rb +0 -247
  56. data/lib/canvas_sync/job_batches/compat/active_job.rb +0 -108
  57. data/lib/canvas_sync/job_batches/compat/sidekiq/web/batches_assets/css/styles.less +0 -182
  58. data/lib/canvas_sync/job_batches/compat/sidekiq/web/batches_assets/js/batch_tree.js +0 -108
  59. data/lib/canvas_sync/job_batches/compat/sidekiq/web/batches_assets/js/util.js +0 -2
  60. data/lib/canvas_sync/job_batches/compat/sidekiq/web/helpers.rb +0 -41
  61. data/lib/canvas_sync/job_batches/compat/sidekiq/web/views/_batch_tree.erb +0 -6
  62. data/lib/canvas_sync/job_batches/compat/sidekiq/web/views/_batches_table.erb +0 -44
  63. data/lib/canvas_sync/job_batches/compat/sidekiq/web/views/_common.erb +0 -13
  64. data/lib/canvas_sync/job_batches/compat/sidekiq/web/views/_jobs_table.erb +0 -21
  65. data/lib/canvas_sync/job_batches/compat/sidekiq/web/views/_pagination.erb +0 -26
  66. data/lib/canvas_sync/job_batches/compat/sidekiq/web/views/batch.erb +0 -81
  67. data/lib/canvas_sync/job_batches/compat/sidekiq/web/views/batches.erb +0 -23
  68. data/lib/canvas_sync/job_batches/compat/sidekiq/web/views/pool.erb +0 -137
  69. data/lib/canvas_sync/job_batches/compat/sidekiq/web/views/pools.erb +0 -47
  70. data/lib/canvas_sync/job_batches/compat/sidekiq/web.rb +0 -218
  71. data/lib/canvas_sync/job_batches/compat/sidekiq.rb +0 -149
  72. data/lib/canvas_sync/job_batches/compat.rb +0 -20
  73. data/lib/canvas_sync/job_batches/context_hash.rb +0 -157
  74. data/lib/canvas_sync/job_batches/hier_batch_ids.lua +0 -25
  75. data/lib/canvas_sync/job_batches/jobs/base_job.rb +0 -5
  76. data/lib/canvas_sync/job_batches/jobs/concurrent_batch_job.rb +0 -20
  77. data/lib/canvas_sync/job_batches/jobs/managed_batch_job.rb +0 -175
  78. data/lib/canvas_sync/job_batches/jobs/serial_batch_job.rb +0 -20
  79. data/lib/canvas_sync/job_batches/pool.rb +0 -254
  80. data/lib/canvas_sync/job_batches/pool_refill.lua +0 -47
  81. data/lib/canvas_sync/job_batches/redis_model.rb +0 -67
  82. data/lib/canvas_sync/job_batches/redis_script.rb +0 -161
  83. data/lib/canvas_sync/job_batches/schedule_callback.lua +0 -14
  84. data/lib/canvas_sync/job_batches/status.rb +0 -89
  85. data/lib/canvas_sync/job_uniqueness/compat/active_job.rb +0 -75
  86. data/lib/canvas_sync/job_uniqueness/compat/sidekiq.rb +0 -135
  87. data/lib/canvas_sync/job_uniqueness/compat.rb +0 -20
  88. data/lib/canvas_sync/job_uniqueness/configuration.rb +0 -25
  89. data/lib/canvas_sync/job_uniqueness/job_uniqueness.rb +0 -47
  90. data/lib/canvas_sync/job_uniqueness/lock_context.rb +0 -199
  91. data/lib/canvas_sync/job_uniqueness/locksmith.rb +0 -92
  92. data/lib/canvas_sync/job_uniqueness/on_conflict/base.rb +0 -32
  93. data/lib/canvas_sync/job_uniqueness/on_conflict/log.rb +0 -13
  94. data/lib/canvas_sync/job_uniqueness/on_conflict/null_strategy.rb +0 -9
  95. data/lib/canvas_sync/job_uniqueness/on_conflict/raise.rb +0 -11
  96. data/lib/canvas_sync/job_uniqueness/on_conflict/reject.rb +0 -21
  97. data/lib/canvas_sync/job_uniqueness/on_conflict/reschedule.rb +0 -20
  98. data/lib/canvas_sync/job_uniqueness/on_conflict.rb +0 -62
  99. data/lib/canvas_sync/job_uniqueness/strategy/base.rb +0 -107
  100. data/lib/canvas_sync/job_uniqueness/strategy/until_and_while_executing.rb +0 -35
  101. data/lib/canvas_sync/job_uniqueness/strategy/until_executed.rb +0 -20
  102. data/lib/canvas_sync/job_uniqueness/strategy/until_executing.rb +0 -20
  103. data/lib/canvas_sync/job_uniqueness/strategy/until_expired.rb +0 -16
  104. data/lib/canvas_sync/job_uniqueness/strategy/while_executing.rb +0 -26
  105. data/lib/canvas_sync/job_uniqueness/strategy.rb +0 -27
  106. data/lib/canvas_sync/job_uniqueness/unique_job_common.rb +0 -79
  107. data/spec/dummy/README.rdoc +0 -1
  108. data/spec/dummy/Rakefile +0 -6
  109. data/spec/dummy/app/services/live_events/assignment_created_event.rb +0 -12
  110. data/spec/dummy/app/services/live_events/assignment_updated_event.rb +0 -12
  111. data/spec/dummy/app/services/live_events/base_event.rb +0 -52
  112. data/spec/dummy/app/services/live_events/course_created_event.rb +0 -12
  113. data/spec/dummy/app/services/live_events/course_section_created_event.rb +0 -12
  114. data/spec/dummy/app/services/live_events/course_section_updated_event.rb +0 -12
  115. data/spec/dummy/app/services/live_events/course_updated_event.rb +0 -12
  116. data/spec/dummy/app/services/live_events/enrollment_created_event.rb +0 -12
  117. data/spec/dummy/app/services/live_events/enrollment_updated_event.rb +0 -12
  118. data/spec/dummy/app/services/live_events/grade_changed_event.rb +0 -12
  119. data/spec/dummy/app/services/live_events/module_created_event.rb +0 -12
  120. data/spec/dummy/app/services/live_events/module_item_created_event.rb +0 -12
  121. data/spec/dummy/app/services/live_events/module_item_updated_event.rb +0 -12
  122. data/spec/dummy/app/services/live_events/module_updated_event.rb +0 -12
  123. data/spec/dummy/app/services/live_events/submission_created_event.rb +0 -12
  124. data/spec/dummy/app/services/live_events/submission_updated_event.rb +0 -12
  125. data/spec/dummy/app/services/live_events/syllabus_updated_event.rb +0 -12
  126. data/spec/dummy/app/services/live_events/user_created_event.rb +0 -12
  127. data/spec/dummy/app/services/live_events/user_updated_event.rb +0 -12
  128. data/spec/dummy/bin/rails +0 -4
  129. data/spec/dummy/config/application.rb +0 -39
  130. data/spec/dummy/config/boot.rb +0 -5
  131. data/spec/dummy/config/database.yml +0 -25
  132. data/spec/dummy/config/environment.rb +0 -5
  133. data/spec/dummy/config/environments/development.rb +0 -41
  134. data/spec/dummy/config/environments/test.rb +0 -44
  135. data/spec/dummy/config/initializers/assets.rb +0 -11
  136. data/spec/dummy/config/initializers/session_store.rb +0 -3
  137. data/spec/dummy/config/initializers/wrap_parameters.rb +0 -14
  138. data/spec/dummy/config/routes.rb +0 -3
  139. data/spec/dummy/config/secrets.yml +0 -22
  140. data/spec/dummy/config.ru +0 -4
  141. data/spec/dummy/db/schema.rb +0 -563
  142. data/spec/job_batching/batch_spec.rb +0 -531
  143. data/spec/job_batching/callback_spec.rb +0 -38
  144. data/spec/job_batching/compat/active_job_spec.rb +0 -107
  145. data/spec/job_batching/compat/sidekiq_spec.rb +0 -127
  146. data/spec/job_batching/context_hash_spec.rb +0 -54
  147. data/spec/job_batching/flow_spec.rb +0 -82
  148. data/spec/job_batching/integration/fail_then_succeed.rb +0 -42
  149. data/spec/job_batching/integration/integration.rb +0 -57
  150. data/spec/job_batching/integration/nested.rb +0 -88
  151. data/spec/job_batching/integration/simple.rb +0 -47
  152. data/spec/job_batching/integration/workflow.rb +0 -134
  153. data/spec/job_batching/integration_helper.rb +0 -50
  154. data/spec/job_batching/pool_spec.rb +0 -161
  155. data/spec/job_batching/status_spec.rb +0 -76
  156. data/spec/job_batching/support/base_job.rb +0 -14
  157. data/spec/job_batching/support/sample_callback.rb +0 -2
  158. data/spec/job_uniqueness/compat/active_job_spec.rb +0 -49
  159. data/spec/job_uniqueness/compat/sidekiq_spec.rb +0 -68
  160. data/spec/job_uniqueness/lock_context_spec.rb +0 -106
  161. data/spec/job_uniqueness/on_conflict/log_spec.rb +0 -11
  162. data/spec/job_uniqueness/on_conflict/raise_spec.rb +0 -10
  163. data/spec/job_uniqueness/on_conflict/reschedule_spec.rb +0 -63
  164. data/spec/job_uniqueness/on_conflict_spec.rb +0 -16
  165. data/spec/job_uniqueness/spec_helper.rb +0 -17
  166. data/spec/job_uniqueness/strategy/base_spec.rb +0 -100
  167. data/spec/job_uniqueness/strategy/until_and_while_executing_spec.rb +0 -48
  168. data/spec/job_uniqueness/strategy/until_executed_spec.rb +0 -23
  169. data/spec/job_uniqueness/strategy/until_executing_spec.rb +0 -23
  170. data/spec/job_uniqueness/strategy/until_expired_spec.rb +0 -23
  171. data/spec/job_uniqueness/strategy/while_executing_spec.rb +0 -33
  172. data/spec/job_uniqueness/support/lock_strategy.rb +0 -28
  173. data/spec/job_uniqueness/support/on_conflict.rb +0 -24
  174. data/spec/job_uniqueness/support/test_worker.rb +0 -19
  175. data/spec/job_uniqueness/unique_job_common_spec.rb +0 -45
  176. /data/spec/{dummy → internal}/app/models/account.rb +0 -0
  177. /data/spec/{dummy → internal}/app/models/admin.rb +0 -0
  178. /data/spec/{dummy → internal}/app/models/assignment.rb +0 -0
  179. /data/spec/{dummy → internal}/app/models/assignment_group.rb +0 -0
  180. /data/spec/{dummy → internal}/app/models/assignment_override.rb +0 -0
  181. /data/spec/{dummy → internal}/app/models/context_module.rb +0 -0
  182. /data/spec/{dummy → internal}/app/models/context_module_item.rb +0 -0
  183. /data/spec/{dummy → internal}/app/models/course_progress.rb +0 -0
  184. /data/spec/{dummy → internal}/app/models/enrollment.rb +0 -0
  185. /data/spec/{dummy → internal}/app/models/grading_period.rb +0 -0
  186. /data/spec/{dummy → internal}/app/models/grading_period_group.rb +0 -0
  187. /data/spec/{dummy → internal}/app/models/group.rb +0 -0
  188. /data/spec/{dummy → internal}/app/models/group_membership.rb +0 -0
  189. /data/spec/{dummy → internal}/app/models/learning_outcome_result.rb +0 -0
  190. /data/spec/{dummy → internal}/app/models/pseudonym.rb +0 -0
  191. /data/spec/{dummy → internal}/app/models/role.rb +0 -0
  192. /data/spec/{dummy → internal}/app/models/rubric.rb +0 -0
  193. /data/spec/{dummy → internal}/app/models/rubric_assessment.rb +0 -0
  194. /data/spec/{dummy → internal}/app/models/rubric_association.rb +0 -0
  195. /data/spec/{dummy → internal}/app/models/score.rb +0 -0
  196. /data/spec/{dummy → internal}/app/models/section.rb +0 -0
  197. /data/spec/{dummy → internal}/app/models/submission.rb +0 -0
  198. /data/spec/{dummy → internal}/app/models/term.rb +0 -0
  199. /data/spec/{dummy → internal}/app/models/user.rb +0 -0
  200. /data/spec/{dummy → internal}/app/models/user_observer.rb +0 -0
  201. /data/spec/{dummy/db/migrate/20190702203621_create_courses.rb → internal/db/migrate/20250912205138_create_courses.rb} +0 -0
  202. /data/spec/{dummy/db/migrate/20190702203624_create_enrollments.rb → internal/db/migrate/20250912205143_create_enrollments.rb} +0 -0
  203. /data/spec/{dummy/db/migrate/20250319194134_create_course_nicknames.rb → internal/db/migrate/20250912205158_create_course_nicknames.rb} +0 -0
  204. /data/spec/{dummy/db/migrate/20250319194135_create_rubrics.rb → internal/db/migrate/20250912205159_create_rubrics.rb} +0 -0
  205. /data/spec/{dummy/db/migrate/20241223080202_create_assignment_overrides.rb → internal/db/migrate/20250912205163_create_assignment_overrides.rb} +0 -0
  206. /data/spec/{dummy/db/migrate/20250626194330_create_scores.rb → internal/db/migrate/20250912205164_create_scores.rb} +0 -0
@@ -1,161 +0,0 @@
1
- require 'spec_helper'
2
-
3
- RSpec.describe CanvasSync::JobBatches::Pool do
4
- include ActiveJob::TestHelper
5
-
6
- subject { described_class.new(order: pool_order, concurrency: pool_concurrency) }
7
-
8
- let(:pool) { subject }
9
-
10
- let(:pool_order) { :fifo }
11
- let(:pool_concurrency) { 2 }
12
-
13
- describe '#initialize' do
14
- subject { described_class }
15
-
16
- it 'creates pid when called without it' do
17
- expect(subject.new.pid).not_to be_nil
18
- end
19
-
20
- it 'reuses pid when called with it' do
21
- batch = subject.new('dayPO5KxuRXXxw')
22
- expect(batch.pid).to eq('dayPO5KxuRXXxw')
23
- end
24
- end
25
-
26
- def load_pool(count = 3)
27
- jobs = count.times.map do |i|
28
- { job: "BatchTestJobBase", args: [1] }
29
- end
30
- subject.add_jobs(jobs, skip_refill: true)
31
- end
32
-
33
- describe "#job_checked_in" do
34
- it "gets called" do
35
- expect(CanvasSync::JobBatches::Pool).to receive(:job_checked_in).twice
36
- load_pool
37
- perform_enqueued_jobs do
38
- pool.send :refill_allotment
39
- Sidekiq::Worker.drain_all
40
- end
41
- end
42
-
43
- it "refills the pool" do
44
- expect(CanvasSync::JobBatches::Pool).to receive(:job_checked_in).and_call_original.exactly(3).times
45
-
46
- load_pool
47
- perform_enqueued_jobs do
48
- pool.send :refill_allotment
49
- Sidekiq::Worker.drain_all
50
- end
51
- end
52
- end
53
-
54
- describe "#cleanup_if_empty" do
55
- it "cleans if pool is empty and allowed to close" do
56
- expect(pool).to receive(:cleanup_redis)
57
- pool.cleanup_if_empty
58
- end
59
-
60
- it "doesn't clean if pool has pending" do
61
- load_pool
62
- expect(pool).to_not receive(:cleanup_redis)
63
- pool.cleanup_if_empty
64
- end
65
-
66
- it "doesn't clean if pool has active" do
67
- subject.redis.hset("#{subject.send(:redis_key)}-active", "blocked", "{}")
68
- expect(pool).to_not receive(:cleanup_redis)
69
- pool.cleanup_if_empty
70
- end
71
-
72
- it "doesn't clean if pool has activating" do
73
- subject.redis.hincrby(subject.send(:redis_key), "_active_count", 1)
74
- expect(pool).to_not receive(:cleanup_redis)
75
- pool.cleanup_if_empty
76
- end
77
-
78
- it "doesn't clean if pool is empty but is kept open" do
79
- pool.keep_open!
80
- expect(pool).to_not receive(:cleanup_redis)
81
- pool.cleanup_if_empty
82
- end
83
-
84
- it "doesn't clean if pool is empty but clean_when_empty is false" do
85
- subject.redis.hset(subject.send(:redis_key), "clean_when_empty", "false")
86
- expect(pool).to_not receive(:cleanup_redis)
87
- pool.cleanup_if_empty
88
- end
89
- end
90
-
91
- shared_examples "basic pool tests" do
92
- describe "#push_job_to_pool" do
93
- it "adds a job to the pool" do
94
- subject.send(:push_job_to_pool, { job: 'job1' })
95
- expect(subject.pending_count).to eq(1)
96
- end
97
- end
98
-
99
- describe "#refill_allotment" do
100
- it "refills the pool with jobs" do
101
- load_pool
102
- expect(CanvasSync::JobBatches::ChainBuilder).to receive(:enqueue_job).twice
103
- subject.send(:refill_allotment)
104
- end
105
-
106
- it "limits to the concurrency count" do
107
- load_pool
108
- expect(CanvasSync::JobBatches::ChainBuilder).to receive(:enqueue_job).twice
109
- expect(subject.send(:refill_allotment)).to eql 2
110
- expect(subject.pending_count).to eql 1
111
- end
112
-
113
- it "considers already active jobs against concurrency" do
114
- load_pool
115
- subject.redis.hset("#{subject.send(:redis_key)}-active", "blocked", "{}")
116
- expect(CanvasSync::JobBatches::ChainBuilder).to receive(:enqueue_job).once
117
- expect(subject.send(:refill_allotment)).to eql 2
118
- expect(subject.pending_count).to eql 2
119
- end
120
-
121
- it "considers activating jobs against concurrency" do
122
- load_pool
123
- subject.redis.hincrby(subject.send(:redis_key), "_active_count", 1)
124
- expect(CanvasSync::JobBatches::ChainBuilder).to receive(:enqueue_job).once
125
- expect(subject.send(:refill_allotment)).to eql 2
126
- expect(subject.pending_count).to eql 2
127
- end
128
-
129
- it "doesn't fail if the pool is gone" do
130
- load_pool
131
- subject.cleanup_redis
132
- expect(CanvasSync::JobBatches::ChainBuilder).not_to receive(:enqueue_job)
133
- expect(subject.send(:refill_allotment)).to eql -1
134
- end
135
-
136
- it "doesn't fail if the pool is empty" do
137
- expect(subject.send(:refill_allotment)).to eql 0
138
- end
139
- end
140
- end
141
-
142
- context "FIFO Pool" do
143
- let(:pool_order) { :fifo }
144
- it_behaves_like "basic pool tests"
145
- end
146
-
147
- context "LIFO Pool" do
148
- let(:pool_order) { :lifo }
149
- it_behaves_like "basic pool tests"
150
- end
151
-
152
- context "Random Pool" do
153
- let(:pool_order) { :random }
154
- it_behaves_like "basic pool tests"
155
- end
156
-
157
- context "Priority Pool" do
158
- let(:pool_order) { :priority }
159
- it_behaves_like "basic pool tests"
160
- end
161
- end
@@ -1,76 +0,0 @@
1
- require 'spec_helper'
2
-
3
- RSpec.describe CanvasSync::JobBatches::Batch::Status do
4
- let(:batch) { CanvasSync::JobBatches::Batch.new() }
5
- let(:bid) { batch.bid }
6
- subject { described_class.new(bid) }
7
-
8
- describe '#join' do
9
- it 'raises info' do
10
- expect { subject.join }.to raise_error('Not supported')
11
- end
12
- end
13
-
14
- describe '#pending' do
15
- context 'when not initalized' do
16
- it 'returns 0 pending jobs' do
17
- expect(subject.pending).to eq(0)
18
- end
19
- end
20
-
21
- context 'when more than 0' do
22
- before { batch.jobs do BatchTestWorker.perform_async end }
23
- it 'returns pending jobs' do
24
- expect(subject.pending).to eq(1)
25
- end
26
- end
27
- end
28
-
29
- describe '#failures' do
30
- context 'when not initalized' do
31
- it 'returns 0 failed jobs' do
32
- expect(subject.failures).to eq(0)
33
- end
34
- end
35
-
36
- context 'when more than 0' do
37
- before { batch.append_jobs(bid) }
38
- before { CanvasSync::JobBatches::Batch.process_failed_job(bid, 'FAILEDID') }
39
-
40
- it 'returns failed jobs' do
41
- expect(subject.failures).to eq(1)
42
- end
43
- end
44
- end
45
-
46
- describe '#failure_info' do
47
- context 'when not initalized' do
48
- it 'returns empty array' do
49
- expect(subject.failure_info).to eq([])
50
- end
51
- end
52
-
53
- context 'when with error' do
54
- before { batch.jobs{}; CanvasSync::JobBatches::Batch.process_failed_job(bid, 'jid123') }
55
-
56
- it 'returns array with failed jids' do
57
- expect(subject.failure_info).to eq(['jid123'])
58
- end
59
- end
60
- end
61
-
62
- describe '#data' do
63
- it 'returns batch description' do
64
- expect(subject.data).to include(failures: 0, pending: 0, created_at: nil, complete: false, failure_info: [], parent_bid: nil)
65
- end
66
- end
67
-
68
- describe '#created_at' do
69
- it 'returns time' do
70
- batch = CanvasSync::JobBatches::Batch.new
71
- batch.jobs do BatchTestWorker.perform_async end
72
- status = described_class.new(batch.bid)
73
- expect(status.created_at).not_to be_nil
74
- end
75
- end
76
- end
@@ -1,14 +0,0 @@
1
- class BatchTestJobBase < ActiveJob::Base
2
- def perform(*args, **kwargs)
3
- end
4
-
5
- def self.perform_async(*args)
6
- perform_later(*args)
7
- end
8
- end
9
-
10
- class FailingBatchTestJobBase < BatchTestJobBase
11
- def perform
12
- raise "Foo"
13
- end
14
- end
@@ -1,2 +0,0 @@
1
- class SampleCallback; end
2
- class SampleCallback2; end
@@ -1,49 +0,0 @@
1
- require 'job_uniqueness/spec_helper'
2
-
3
- RSpec.describe CanvasSync::JobUniqueness::Compat::ActiveJob do
4
- context 'Job Extension' do
5
- it 'includes UniqueJobExtension' do
6
- expect(ActiveJob::Base < CanvasSync::JobUniqueness::Compat::ActiveJob::JobExtension).to be true
7
- end
8
-
9
- it 'has the ensure_uniqueness method' do
10
- expect(ActiveJob::Base.method(:ensure_uniqueness)).to be_present
11
- end
12
- end
13
-
14
- context 'Job' do
15
- let(:test_job) do
16
- Class.new(ActiveJob::Base) do
17
- ensure_uniqueness(
18
- strategy: :until_executed,
19
- )
20
- def perform; end
21
- end
22
- end
23
-
24
- before(:each) do
25
- stub_const('TestJob', test_job)
26
- ActiveJob::Base.queue_adapter = :sidekiq
27
- end
28
-
29
- it 'runs as expected' do
30
- strategy = CanvasSync::JobUniqueness::Strategy::UntilExecuted.new(nil)
31
- allow_any_instance_of(CanvasSync::JobUniqueness::LockContext).to receive(:lock_strategy) do |lock_context|
32
- strategy.instance_variable_set(:@lock_context, lock_context)
33
- strategy
34
- end
35
- allow(CanvasSync::JobUniqueness::Strategy::UntilExecuted).to receive(:new).and_return(strategy)
36
-
37
- expect(strategy).to receive(:on_enqueue).and_call_original
38
- expect(strategy).to receive(:on_perform).and_call_original
39
- expect(strategy).to receive(:batch_callback).with(:complete, anything).and_call_original
40
- expect(strategy).to receive(:batch_callback).with(:success, anything).and_call_original
41
-
42
- expect_any_instance_of(test_job).to receive(:perform)
43
-
44
- Sidekiq::Testing.inline! do
45
- test_job.perform_later
46
- end
47
- end
48
- end
49
- end
@@ -1,68 +0,0 @@
1
- require 'job_uniqueness/spec_helper'
2
-
3
- RSpec.describe CanvasSync::JobUniqueness::Compat::Sidekiq do
4
- let(:config) { defined?(Sidekiq::Config) ? double(Sidekiq::Config) : class_double(Sidekiq) }
5
- let(:client_middleware) { double(Sidekiq::Middleware::Chain) }
6
-
7
- context 'client' do
8
- it 'adds client middleware' do
9
- allow(Sidekiq).to receive(:configure_client).and_yield(config)
10
- expect(config).to receive(:client_middleware).and_yield(client_middleware)
11
- expect(client_middleware).to receive(:insert_before).with(anything, CanvasSync::JobUniqueness::Compat::Sidekiq::ClientMiddleware)
12
- CanvasSync::JobUniqueness::Compat::Sidekiq.configure
13
- end
14
- end
15
-
16
- context 'server' do
17
- let(:server_middleware) { double(Sidekiq::Middleware::Chain) }
18
-
19
- it 'adds client and server middleware' do
20
- allow(Sidekiq).to receive(:configure_server).and_yield(config)
21
- expect(config).to receive(:client_middleware).and_yield(client_middleware)
22
- expect(config).to receive(:server_middleware).and_yield(server_middleware)
23
- expect(client_middleware).to receive(:insert_before).with(anything, CanvasSync::JobUniqueness::Compat::Sidekiq::ClientMiddleware)
24
- expect(server_middleware).to receive(:insert_after).with(anything, CanvasSync::JobUniqueness::Compat::Sidekiq::ServerMiddleware)
25
- CanvasSync::JobUniqueness::Compat::Sidekiq.configure
26
- end
27
- end
28
-
29
- context 'Job Extension' do
30
- let!(:dummy_worker) do
31
- Class.new do
32
- include Sidekiq::Worker
33
- end
34
- end
35
-
36
- it 'includes UniqueJobExtension' do
37
- expect(dummy_worker < CanvasSync::JobUniqueness::Compat::Sidekiq::WorkerExtension).to be true
38
- end
39
-
40
- it 'has the ensure_uniqueness method' do
41
- expect(dummy_worker.method(:ensure_uniqueness)).to be_present
42
- end
43
- end
44
-
45
- context 'Job' do
46
- include_context 'with TestWorker'
47
-
48
- it 'runs as expected' do
49
- strategy = CanvasSync::JobUniqueness::Strategy::UntilExecuted.new(nil)
50
- allow_any_instance_of(CanvasSync::JobUniqueness::LockContext).to receive(:lock_strategy) do |lock_context|
51
- strategy.instance_variable_set(:@lock_context, lock_context)
52
- strategy
53
- end
54
- allow(CanvasSync::JobUniqueness::Strategy::UntilExecuted).to receive(:new).and_return(strategy)
55
-
56
- expect(strategy).to receive(:on_enqueue).and_call_original
57
- expect(strategy).to receive(:on_perform).and_call_original
58
- expect(strategy).to receive(:batch_callback).with(:complete, anything).and_call_original
59
- expect(strategy).to receive(:batch_callback).with(:success, anything).and_call_original
60
-
61
- expect_any_instance_of(TestWorker).to receive(:perform)
62
-
63
- Sidekiq::Testing.inline! do
64
- worker.perform_async
65
- end
66
- end
67
- end
68
- end
@@ -1,106 +0,0 @@
1
- require 'job_uniqueness/spec_helper'
2
-
3
- RSpec.describe CanvasSync::JobUniqueness::LockContext do
4
- let!(:worker) do
5
- Class.new do
6
- include Sidekiq::Worker
7
-
8
- ensure_uniqueness(
9
- strategy: :until_executed,
10
- )
11
-
12
- def perform; end
13
- end
14
- end
15
-
16
- before(:each) { stub_const('TestWorker', worker) }
17
-
18
- let(:lock_context) { described_class.new(context_data) }
19
- let(:context_data) { { queue: 'default', job_clazz: 'TestWorker', args: [1,2,3], kwargs: { foo: 'bar' } } }
20
-
21
- describe '#base_key' do
22
- let(:scope) { :per_queue }
23
- before(:each) do
24
- TestWorker.unique_job_options[:scope] = scope
25
- end
26
-
27
- it 'returns matching keys for equal hashes' do
28
- context_data[:args] = [{ foo: 'bar', bar: 'foo' }]
29
- key1 = lock_context.base_key
30
- lock_context.instance_variable_set(:@base_key, nil)
31
-
32
- context_data[:args] = [{ bar: 'foo', foo: 'bar' }]
33
- key2 = lock_context.base_key
34
-
35
- expect(key1).to eq key2
36
- end
37
-
38
- context 'when scope is a Proc' do
39
- let(:scope) { ->(queue:) { "blob" } }
40
-
41
- it 'returns the base key' do
42
- expect(lock_context.base_key).to match /^uniquejob:blob:.*/
43
- end
44
- end
45
-
46
- context 'when scope is :global' do
47
- let(:scope) { :global }
48
-
49
- it 'returns the base key' do
50
- expect(lock_context.base_key).to match /^uniquejob:TestWorker:.*/
51
- end
52
- end
53
-
54
- context 'when scope is :per_queue' do
55
- let(:scope) { :per_queue }
56
-
57
- it 'returns the base key' do
58
- expect(lock_context.base_key).to match /^uniquejob:TestWorker:default:.*/
59
- end
60
- end
61
-
62
- context 'when scope is not a Proc, :global, or :per_queue' do
63
- let(:scope) { 'foo' }
64
-
65
- it 'returns the base key' do
66
- expect(lock_context.base_key).to match /^uniquejob:foo:.*/
67
- end
68
- end
69
- end
70
-
71
- describe '#call_conflict_strategy' do
72
- before(:each) do
73
- worker.unique_job_options[:on_conflict] = :raise
74
- end
75
-
76
- it 'invokes the conflict strategy' do
77
- expect_any_instance_of(CanvasSync::JobUniqueness::OnConflict::Raise).to receive(:call)
78
- lock_context.send(:call_conflict_strategy, :perform)
79
- end
80
- end
81
-
82
- describe '#conflict_strategy_for' do
83
- before(:each) do
84
- worker.unique_job_options[:on_conflict] = :raise
85
- end
86
-
87
- it 'resolves a united conflict strategy' do
88
- expect(lock_context.send(:conflict_strategy_for, :perform)).to be_a CanvasSync::JobUniqueness::OnConflict::Raise
89
- end
90
-
91
- it 'resolves enqueue strategy' do
92
- worker.unique_job_options[:on_conflict] = { enqueue: :log, perform: :raise }
93
- expect(lock_context.send(:conflict_strategy_for, :enqueue)).to be_a CanvasSync::JobUniqueness::OnConflict::Log
94
- end
95
-
96
- it 'resolves perform strategy' do
97
- worker.unique_job_options[:on_conflict] = { enqueue: :log, perform: :reject }
98
- expect(lock_context.send(:conflict_strategy_for, :perform)).to be_a CanvasSync::JobUniqueness::OnConflict::Reject
99
- end
100
-
101
- it 'resolves null strategy' do
102
- worker.unique_job_options[:on_conflict] = { enqueue: :log }
103
- expect(lock_context.send(:conflict_strategy_for, :perform)).to be_a CanvasSync::JobUniqueness::OnConflict::NullStrategy
104
- end
105
- end
106
- end
@@ -1,11 +0,0 @@
1
- require 'job_uniqueness/spec_helper'
2
-
3
- RSpec.describe CanvasSync::JobUniqueness::OnConflict::Log do
4
- include_context "on_conflict specs"
5
- include_examples "OnConflict is compatible with", %i[until_executing while_executing until_executed until_and_while_executing until_expired]
6
-
7
- it "logs" do
8
- expect(CanvasSync::JobUniqueness.logger).to receive(:info)
9
- on_conflict.call
10
- end
11
- end
@@ -1,10 +0,0 @@
1
- require 'job_uniqueness/spec_helper'
2
-
3
- RSpec.describe CanvasSync::JobUniqueness::OnConflict::Raise do
4
- include_context "on_conflict specs"
5
- include_examples "OnConflict is compatible with", %i[until_executing while_executing until_executed until_and_while_executing until_expired]
6
-
7
- it "raises an error" do
8
- expect { on_conflict.call }.to raise_error(CanvasSync::JobUniqueness::Conflict)
9
- end
10
- end
@@ -1,63 +0,0 @@
1
- require 'job_uniqueness/spec_helper'
2
-
3
- RSpec.describe CanvasSync::JobUniqueness::OnConflict::Reschedule do
4
- include_context "on_conflict specs"
5
- include_examples "OnConflict is compatible with", %i[while_executing]
6
-
7
- it "calls reenqueue" do
8
- expect(lock_context).to receive(:reenqueue) do |*args, **kwargs|
9
- expect(Thread.current[:unique_jobs_previous_context]).to be_present
10
- end
11
- on_conflict.call
12
- end
13
-
14
- it "reschedules successfully" do
15
- TestWorker.unique_job_options.merge!({ strategy: :until_and_while_executing, on_conflict: { enqueue: :raise, perform: :reschedule }})
16
-
17
- lock_context.handle_lifecycle!(:enqueue) {}
18
- lock_context.handle_lifecycle!(:perform) {}
19
-
20
- lock_context2 = CanvasSync::JobUniqueness::Compat::Sidekiq::SidekiqLockContext.new({ jid: 'j2', queue: 'default', job_clazz: 'TestWorker'}, job_instance: {})
21
- lock_context2.handle_lifecycle!(:enqueue) {}
22
- lock_context2.handle_lifecycle!(:perform) {}
23
- end
24
-
25
- it "maintains a consistent lock_id" do
26
- TestWorker.clear
27
- TestWorker.unique_job_options.merge!({ strategy: :while_executing, on_conflict: :reschedule })
28
-
29
- lock_context.handle_lifecycle!(:enqueue) {}
30
- lock_context.handle_lifecycle!(:perform) {}
31
-
32
- TestWorker.perform_async
33
- j1 = TestWorker.jobs[0]
34
- TestWorker.perform_one
35
- j2 = TestWorker.jobs[0]
36
-
37
- expect(j1).not_to eq(j2)
38
- expect(j1['uniqueness_cache_data']['lid']).to be_present
39
- expect(j1['uniqueness_cache_data']['lid']).to eq(j2['uniqueness_cache_data']['lid'])
40
- end
41
-
42
- it "unlocks after rescheduling" do
43
- TestWorker.clear
44
- TestWorker.unique_job_options.merge!({ strategy: :while_executing, on_conflict: :reschedule })
45
-
46
- lock_context.handle_lifecycle!(:enqueue) {}
47
- lock_context.handle_lifecycle!(:perform) {}
48
-
49
- TestWorker.perform_async
50
- expect(TestWorker.jobs.size).to eq(1)
51
- TestWorker.perform_one
52
- expect(TestWorker.jobs.size).to eq(1)
53
-
54
- lock_context.lock_strategy.send(:unlock)
55
- Sidekiq::Worker.drain_all
56
- expect(TestWorker.jobs.size).to eq(0)
57
-
58
- # Run another worker to validate that the lock was released
59
- TestWorker.perform_async
60
- TestWorker.perform_one
61
- expect(TestWorker.jobs.size).to eq(0)
62
- end
63
- end
@@ -1,16 +0,0 @@
1
- require 'job_uniqueness/spec_helper'
2
-
3
- RSpec.describe CanvasSync::JobUniqueness::OnConflict do
4
-
5
- describe ".validate!" do
6
- it "passes a valid pair" do
7
- described_class.validate!(:reject, :while_executing)
8
- end
9
-
10
- it "raises an error if the strategy is not valid for the given action" do
11
- expect do
12
- described_class.validate!(:reject, :until_executed)
13
- end.to raise_error(ArgumentError)
14
- end
15
- end
16
- end
@@ -1,17 +0,0 @@
1
- require_relative "../spec_helper"
2
- require "canvas_sync/job_uniqueness/job_uniqueness"
3
-
4
- require 'redis'
5
- Redis.silence_deprecations = true
6
-
7
- Dir[File.join(File.dirname(__FILE__), "./support/**/*.rb")].sort.each { |f| require f }
8
-
9
- Sidekiq::Testing.server_middleware do |chain|
10
- chain.insert_after CanvasSync::JobBatches::Compat::Sidekiq::ServerMiddleware, CanvasSync::JobUniqueness::Compat::Sidekiq::ServerMiddleware
11
- end
12
-
13
- RSpec.configure do |config|
14
- config.before(:each) do
15
- CanvasSync.redis.flushdb
16
- end
17
- end