decision_agent 0.3.0 → 1.0.1

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 (115) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +272 -7
  3. data/lib/decision_agent/agent.rb +72 -1
  4. data/lib/decision_agent/context.rb +1 -0
  5. data/lib/decision_agent/data_enrichment/cache/memory_adapter.rb +86 -0
  6. data/lib/decision_agent/data_enrichment/cache_adapter.rb +49 -0
  7. data/lib/decision_agent/data_enrichment/circuit_breaker.rb +135 -0
  8. data/lib/decision_agent/data_enrichment/client.rb +220 -0
  9. data/lib/decision_agent/data_enrichment/config.rb +78 -0
  10. data/lib/decision_agent/data_enrichment/errors.rb +36 -0
  11. data/lib/decision_agent/decision.rb +102 -2
  12. data/lib/decision_agent/dmn/feel/evaluator.rb +28 -6
  13. data/lib/decision_agent/dsl/condition_evaluator.rb +982 -839
  14. data/lib/decision_agent/dsl/schema_validator.rb +51 -13
  15. data/lib/decision_agent/evaluators/dmn_evaluator.rb +106 -19
  16. data/lib/decision_agent/evaluators/json_rule_evaluator.rb +69 -9
  17. data/lib/decision_agent/explainability/condition_trace.rb +83 -0
  18. data/lib/decision_agent/explainability/explainability_result.rb +52 -0
  19. data/lib/decision_agent/explainability/rule_trace.rb +39 -0
  20. data/lib/decision_agent/explainability/trace_collector.rb +24 -0
  21. data/lib/decision_agent/monitoring/alert_manager.rb +5 -1
  22. data/lib/decision_agent/simulation/errors.rb +18 -0
  23. data/lib/decision_agent/simulation/impact_analyzer.rb +498 -0
  24. data/lib/decision_agent/simulation/monte_carlo_simulator.rb +635 -0
  25. data/lib/decision_agent/simulation/replay_engine.rb +486 -0
  26. data/lib/decision_agent/simulation/scenario_engine.rb +318 -0
  27. data/lib/decision_agent/simulation/scenario_library.rb +163 -0
  28. data/lib/decision_agent/simulation/shadow_test_engine.rb +287 -0
  29. data/lib/decision_agent/simulation/what_if_analyzer.rb +1002 -0
  30. data/lib/decision_agent/simulation.rb +17 -0
  31. data/lib/decision_agent/version.rb +1 -1
  32. data/lib/decision_agent/versioning/activerecord_adapter.rb +23 -8
  33. data/lib/decision_agent/web/public/app.js +119 -0
  34. data/lib/decision_agent/web/public/index.html +49 -0
  35. data/lib/decision_agent/web/public/simulation.html +130 -0
  36. data/lib/decision_agent/web/public/simulation_impact.html +478 -0
  37. data/lib/decision_agent/web/public/simulation_replay.html +551 -0
  38. data/lib/decision_agent/web/public/simulation_shadow.html +546 -0
  39. data/lib/decision_agent/web/public/simulation_whatif.html +532 -0
  40. data/lib/decision_agent/web/public/styles.css +65 -0
  41. data/lib/decision_agent/web/server.rb +594 -23
  42. data/lib/decision_agent.rb +60 -2
  43. metadata +53 -73
  44. data/spec/ab_testing/ab_test_assignment_spec.rb +0 -253
  45. data/spec/ab_testing/ab_test_manager_spec.rb +0 -612
  46. data/spec/ab_testing/ab_test_spec.rb +0 -270
  47. data/spec/ab_testing/ab_testing_agent_spec.rb +0 -655
  48. data/spec/ab_testing/storage/adapter_spec.rb +0 -64
  49. data/spec/ab_testing/storage/memory_adapter_spec.rb +0 -485
  50. data/spec/activerecord_thread_safety_spec.rb +0 -553
  51. data/spec/advanced_operators_spec.rb +0 -3150
  52. data/spec/agent_spec.rb +0 -289
  53. data/spec/api_contract_spec.rb +0 -430
  54. data/spec/audit_adapters_spec.rb +0 -92
  55. data/spec/auth/access_audit_logger_spec.rb +0 -394
  56. data/spec/auth/authenticator_spec.rb +0 -112
  57. data/spec/auth/password_reset_spec.rb +0 -294
  58. data/spec/auth/permission_checker_spec.rb +0 -207
  59. data/spec/auth/permission_spec.rb +0 -73
  60. data/spec/auth/rbac_adapter_spec.rb +0 -778
  61. data/spec/auth/rbac_config_spec.rb +0 -82
  62. data/spec/auth/role_spec.rb +0 -51
  63. data/spec/auth/session_manager_spec.rb +0 -172
  64. data/spec/auth/session_spec.rb +0 -112
  65. data/spec/auth/user_spec.rb +0 -130
  66. data/spec/comprehensive_edge_cases_spec.rb +0 -1777
  67. data/spec/context_spec.rb +0 -127
  68. data/spec/decision_agent_spec.rb +0 -96
  69. data/spec/decision_spec.rb +0 -423
  70. data/spec/dmn/decision_graph_spec.rb +0 -282
  71. data/spec/dmn/decision_tree_spec.rb +0 -203
  72. data/spec/dmn/feel/errors_spec.rb +0 -18
  73. data/spec/dmn/feel/functions_spec.rb +0 -400
  74. data/spec/dmn/feel/simple_parser_spec.rb +0 -274
  75. data/spec/dmn/feel/types_spec.rb +0 -176
  76. data/spec/dmn/feel_parser_spec.rb +0 -489
  77. data/spec/dmn/hit_policy_spec.rb +0 -202
  78. data/spec/dmn/integration_spec.rb +0 -226
  79. data/spec/dsl/condition_evaluator_spec.rb +0 -774
  80. data/spec/dsl_validation_spec.rb +0 -648
  81. data/spec/edge_cases_spec.rb +0 -353
  82. data/spec/evaluation_spec.rb +0 -364
  83. data/spec/evaluation_validator_spec.rb +0 -165
  84. data/spec/examples/feedback_aware_evaluator_spec.rb +0 -460
  85. data/spec/examples.txt +0 -1909
  86. data/spec/fixtures/dmn/complex_decision.dmn +0 -81
  87. data/spec/fixtures/dmn/invalid_structure.dmn +0 -31
  88. data/spec/fixtures/dmn/simple_decision.dmn +0 -40
  89. data/spec/issue_verification_spec.rb +0 -759
  90. data/spec/json_rule_evaluator_spec.rb +0 -587
  91. data/spec/monitoring/alert_manager_spec.rb +0 -378
  92. data/spec/monitoring/metrics_collector_spec.rb +0 -501
  93. data/spec/monitoring/monitored_agent_spec.rb +0 -225
  94. data/spec/monitoring/prometheus_exporter_spec.rb +0 -242
  95. data/spec/monitoring/storage/activerecord_adapter_spec.rb +0 -498
  96. data/spec/monitoring/storage/base_adapter_spec.rb +0 -61
  97. data/spec/monitoring/storage/memory_adapter_spec.rb +0 -247
  98. data/spec/performance_optimizations_spec.rb +0 -493
  99. data/spec/replay_edge_cases_spec.rb +0 -699
  100. data/spec/replay_spec.rb +0 -210
  101. data/spec/rfc8785_canonicalization_spec.rb +0 -215
  102. data/spec/scoring_spec.rb +0 -225
  103. data/spec/spec_helper.rb +0 -60
  104. data/spec/testing/batch_test_importer_spec.rb +0 -693
  105. data/spec/testing/batch_test_runner_spec.rb +0 -307
  106. data/spec/testing/test_coverage_analyzer_spec.rb +0 -292
  107. data/spec/testing/test_result_comparator_spec.rb +0 -392
  108. data/spec/testing/test_scenario_spec.rb +0 -113
  109. data/spec/thread_safety_spec.rb +0 -490
  110. data/spec/thread_safety_spec.rb.broken +0 -878
  111. data/spec/versioning/adapter_spec.rb +0 -156
  112. data/spec/versioning_spec.rb +0 -1030
  113. data/spec/web/middleware/auth_middleware_spec.rb +0 -133
  114. data/spec/web/middleware/permission_middleware_spec.rb +0 -247
  115. data/spec/web_ui_rack_spec.rb +0 -2134
@@ -1,485 +0,0 @@
1
- require "spec_helper"
2
- require "decision_agent/ab_testing/storage/memory_adapter"
3
- require "decision_agent/ab_testing/ab_test"
4
- require "decision_agent/ab_testing/ab_test_assignment"
5
-
6
- RSpec.describe DecisionAgent::ABTesting::Storage::MemoryAdapter do
7
- let(:adapter) { described_class.new }
8
-
9
- describe "#initialize" do
10
- it "initializes with empty storage" do
11
- expect(adapter.test_count).to eq(0)
12
- expect(adapter.assignment_count).to eq(0)
13
- end
14
- end
15
-
16
- describe "#save_test" do
17
- it "saves a test and assigns an ID" do
18
- test = DecisionAgent::ABTesting::ABTest.new(
19
- name: "Test 1",
20
- champion_version_id: "v1",
21
- challenger_version_id: "v2"
22
- )
23
-
24
- saved = adapter.save_test(test)
25
- expect(saved.id).to eq(1)
26
- expect(saved.name).to eq("Test 1")
27
- end
28
-
29
- it "increments the test counter" do
30
- test1 = DecisionAgent::ABTesting::ABTest.new(
31
- name: "Test 1",
32
- champion_version_id: "v1",
33
- challenger_version_id: "v2"
34
- )
35
- test2 = DecisionAgent::ABTesting::ABTest.new(
36
- name: "Test 2",
37
- champion_version_id: "v1",
38
- challenger_version_id: "v2"
39
- )
40
-
41
- adapter.save_test(test1)
42
- adapter.save_test(test2)
43
-
44
- expect(adapter.test_count).to eq(2)
45
- end
46
- end
47
-
48
- describe "#get_test" do
49
- it "returns nil for non-existent test" do
50
- expect(adapter.get_test(999)).to be_nil
51
- end
52
-
53
- it "returns the saved test" do
54
- test = DecisionAgent::ABTesting::ABTest.new(
55
- name: "Test 1",
56
- champion_version_id: "v1",
57
- challenger_version_id: "v2"
58
- )
59
- saved = adapter.save_test(test)
60
-
61
- retrieved = adapter.get_test(saved.id)
62
- expect(retrieved).to be_a(DecisionAgent::ABTesting::ABTest)
63
- expect(retrieved.id).to eq(saved.id)
64
- expect(retrieved.name).to eq("Test 1")
65
- end
66
-
67
- it "converts string IDs to integers" do
68
- test = DecisionAgent::ABTesting::ABTest.new(
69
- name: "Test 1",
70
- champion_version_id: "v1",
71
- challenger_version_id: "v2"
72
- )
73
- saved = adapter.save_test(test)
74
-
75
- retrieved = adapter.get_test(saved.id.to_s)
76
- expect(retrieved).not_to be_nil
77
- expect(retrieved.id).to eq(saved.id)
78
- end
79
- end
80
-
81
- describe "#update_test" do
82
- let(:saved_test) do
83
- test = DecisionAgent::ABTesting::ABTest.new(
84
- name: "Original Name",
85
- champion_version_id: "v1",
86
- challenger_version_id: "v2",
87
- status: "scheduled"
88
- )
89
- adapter.save_test(test)
90
- end
91
-
92
- it "updates test attributes" do
93
- updated = adapter.update_test(saved_test.id, { status: "running" })
94
- expect(updated.status).to eq("running")
95
- expect(updated.name).to eq("Original Name") # Other attributes unchanged
96
- end
97
-
98
- it "raises error when test not found" do
99
- expect do
100
- adapter.update_test(999, { status: "running" })
101
- end.to raise_error(DecisionAgent::ABTesting::TestNotFoundError, /Test not found: 999/)
102
- end
103
-
104
- it "persists the update" do
105
- adapter.update_test(saved_test.id, { status: "running" })
106
- retrieved = adapter.get_test(saved_test.id)
107
- expect(retrieved.status).to eq("running")
108
- end
109
- end
110
-
111
- describe "#list_tests" do
112
- before do
113
- adapter.save_test(DecisionAgent::ABTesting::ABTest.new(
114
- name: "Scheduled Test",
115
- champion_version_id: "v1",
116
- challenger_version_id: "v2",
117
- status: "scheduled"
118
- ))
119
- adapter.save_test(DecisionAgent::ABTesting::ABTest.new(
120
- name: "Running Test",
121
- champion_version_id: "v1",
122
- challenger_version_id: "v2",
123
- status: "running"
124
- ))
125
- adapter.save_test(DecisionAgent::ABTesting::ABTest.new(
126
- name: "Another Running",
127
- champion_version_id: "v1",
128
- challenger_version_id: "v2",
129
- status: "running"
130
- ))
131
- end
132
-
133
- it "returns all tests when no filters" do
134
- tests = adapter.list_tests
135
- expect(tests.size).to eq(3)
136
- end
137
-
138
- it "filters by status" do
139
- tests = adapter.list_tests(status: "running")
140
- expect(tests.size).to eq(2)
141
- expect(tests.all? { |t| t.status == "running" }).to be true
142
- end
143
-
144
- it "returns empty array when no tests match status" do
145
- tests = adapter.list_tests(status: "completed")
146
- expect(tests).to eq([])
147
- end
148
-
149
- it "respects limit parameter" do
150
- tests = adapter.list_tests(limit: 2)
151
- expect(tests.size).to eq(2)
152
- end
153
-
154
- it "returns last N tests when limit specified" do
155
- tests = adapter.list_tests(limit: 2)
156
- # Should return the last 2 tests (most recently added)
157
- expect(tests.map(&:name)).to include("Running Test", "Another Running")
158
- end
159
-
160
- it "filters by status and limit together" do
161
- tests = adapter.list_tests(status: "running", limit: 1)
162
- expect(tests.size).to eq(1)
163
- expect(tests.first.status).to eq("running")
164
- end
165
- end
166
-
167
- describe "#save_assignment" do
168
- it "saves an assignment and assigns an ID" do
169
- assignment = DecisionAgent::ABTesting::ABTestAssignment.new(
170
- ab_test_id: 1,
171
- variant: :champion,
172
- version_id: "v1"
173
- )
174
-
175
- saved = adapter.save_assignment(assignment)
176
- expect(saved.id).to eq(1)
177
- expect(saved.ab_test_id).to eq(1)
178
- expect(saved.variant).to eq(:champion)
179
- end
180
-
181
- it "increments the assignment counter" do
182
- assignment1 = DecisionAgent::ABTesting::ABTestAssignment.new(
183
- ab_test_id: 1,
184
- variant: :champion,
185
- version_id: "v1"
186
- )
187
- assignment2 = DecisionAgent::ABTesting::ABTestAssignment.new(
188
- ab_test_id: 1,
189
- variant: :challenger,
190
- version_id: "v2"
191
- )
192
-
193
- adapter.save_assignment(assignment1)
194
- adapter.save_assignment(assignment2)
195
-
196
- expect(adapter.assignment_count).to eq(2)
197
- end
198
- end
199
-
200
- describe "#update_assignment" do
201
- let(:saved_assignment) do
202
- assignment = DecisionAgent::ABTesting::ABTestAssignment.new(
203
- ab_test_id: 1,
204
- variant: :champion,
205
- version_id: "v1"
206
- )
207
- adapter.save_assignment(assignment)
208
- end
209
-
210
- it "updates assignment attributes" do
211
- updated = adapter.update_assignment(saved_assignment.id, {
212
- decision_result: "approve",
213
- confidence: 0.85
214
- })
215
- expect(updated.decision_result).to eq("approve")
216
- expect(updated.confidence).to eq(0.85)
217
- end
218
-
219
- it "raises error when assignment not found" do
220
- expect do
221
- adapter.update_assignment(999, { decision_result: "approve" })
222
- end.to raise_error(StandardError, /Assignment not found: 999/)
223
- end
224
-
225
- it "persists the update" do
226
- adapter.update_assignment(saved_assignment.id, { decision_result: "reject" })
227
- # Get via get_assignments to verify persistence
228
- assignments = adapter.get_assignments(1)
229
- updated = assignments.find { |a| a.id == saved_assignment.id }
230
- expect(updated.decision_result).to eq("reject")
231
- end
232
- end
233
-
234
- describe "#get_assignments" do
235
- before do
236
- test1 = adapter.save_test(DecisionAgent::ABTesting::ABTest.new(
237
- name: "Test 1",
238
- champion_version_id: "v1",
239
- challenger_version_id: "v2"
240
- ))
241
- test2 = adapter.save_test(DecisionAgent::ABTesting::ABTest.new(
242
- name: "Test 2",
243
- champion_version_id: "v1",
244
- challenger_version_id: "v2"
245
- ))
246
-
247
- adapter.save_assignment(DecisionAgent::ABTesting::ABTestAssignment.new(
248
- ab_test_id: test1.id,
249
- variant: :champion,
250
- version_id: "v1"
251
- ))
252
- adapter.save_assignment(DecisionAgent::ABTesting::ABTestAssignment.new(
253
- ab_test_id: test1.id,
254
- variant: :challenger,
255
- version_id: "v2"
256
- ))
257
- adapter.save_assignment(DecisionAgent::ABTesting::ABTestAssignment.new(
258
- ab_test_id: test2.id,
259
- variant: :champion,
260
- version_id: "v1"
261
- ))
262
- end
263
-
264
- it "returns assignments for a specific test" do
265
- assignments = adapter.get_assignments(1)
266
- expect(assignments.size).to eq(2)
267
- expect(assignments.all? { |a| a.ab_test_id == 1 }).to be true
268
- end
269
-
270
- it "returns empty array when no assignments for test" do
271
- assignments = adapter.get_assignments(999)
272
- expect(assignments).to eq([])
273
- end
274
- end
275
-
276
- describe "#delete_test" do
277
- let(:test) do
278
- adapter.save_test(DecisionAgent::ABTesting::ABTest.new(
279
- name: "Test 1",
280
- champion_version_id: "v1",
281
- challenger_version_id: "v2"
282
- ))
283
- end
284
-
285
- before do
286
- adapter.save_assignment(DecisionAgent::ABTesting::ABTestAssignment.new(
287
- ab_test_id: test.id,
288
- variant: :champion,
289
- version_id: "v1"
290
- ))
291
- adapter.save_assignment(DecisionAgent::ABTesting::ABTestAssignment.new(
292
- ab_test_id: test.id,
293
- variant: :challenger,
294
- version_id: "v2"
295
- ))
296
- # Assignment for another test
297
- other_test = adapter.save_test(DecisionAgent::ABTesting::ABTest.new(
298
- name: "Test 2",
299
- champion_version_id: "v1",
300
- challenger_version_id: "v2"
301
- ))
302
- adapter.save_assignment(DecisionAgent::ABTesting::ABTestAssignment.new(
303
- ab_test_id: other_test.id,
304
- variant: :champion,
305
- version_id: "v1"
306
- ))
307
- end
308
-
309
- it "deletes the test" do
310
- expect(adapter.get_test(test.id)).not_to be_nil
311
- adapter.delete_test(test.id)
312
- expect(adapter.get_test(test.id)).to be_nil
313
- end
314
-
315
- it "deletes all assignments for the test" do
316
- expect(adapter.get_assignments(test.id).size).to eq(2)
317
- adapter.delete_test(test.id)
318
- expect(adapter.get_assignments(test.id).size).to eq(0)
319
- end
320
-
321
- it "does not delete assignments for other tests" do
322
- other_assignments_count = adapter.assignment_count - adapter.get_assignments(test.id).size
323
- adapter.delete_test(test.id)
324
- expect(adapter.assignment_count).to eq(other_assignments_count)
325
- end
326
-
327
- it "returns true" do
328
- result = adapter.delete_test(test.id)
329
- expect(result).to be true
330
- end
331
-
332
- it "converts string IDs to integers" do
333
- adapter.delete_test(test.id.to_s)
334
- expect(adapter.get_test(test.id)).to be_nil
335
- end
336
- end
337
-
338
- describe "#clear!" do
339
- before do
340
- adapter.save_test(DecisionAgent::ABTesting::ABTest.new(
341
- name: "Test 1",
342
- champion_version_id: "v1",
343
- challenger_version_id: "v2"
344
- ))
345
- adapter.save_assignment(DecisionAgent::ABTesting::ABTestAssignment.new(
346
- ab_test_id: 1,
347
- variant: :champion,
348
- version_id: "v1"
349
- ))
350
- end
351
-
352
- it "clears all tests" do
353
- expect(adapter.test_count).to eq(1)
354
- adapter.clear!
355
- expect(adapter.test_count).to eq(0)
356
- end
357
-
358
- it "clears all assignments" do
359
- expect(adapter.assignment_count).to eq(1)
360
- adapter.clear!
361
- expect(adapter.assignment_count).to eq(0)
362
- end
363
-
364
- it "resets test counter" do
365
- adapter.clear!
366
- test = adapter.save_test(DecisionAgent::ABTesting::ABTest.new(
367
- name: "New Test",
368
- champion_version_id: "v1",
369
- challenger_version_id: "v2"
370
- ))
371
- expect(test.id).to eq(1)
372
- end
373
-
374
- it "resets assignment counter" do
375
- adapter.clear!
376
- assignment = adapter.save_assignment(DecisionAgent::ABTesting::ABTestAssignment.new(
377
- ab_test_id: 1,
378
- variant: :champion,
379
- version_id: "v1"
380
- ))
381
- expect(assignment.id).to eq(1)
382
- end
383
- end
384
-
385
- describe "#test_count" do
386
- it "returns zero initially" do
387
- expect(adapter.test_count).to eq(0)
388
- end
389
-
390
- it "returns correct count after saving tests" do
391
- adapter.save_test(DecisionAgent::ABTesting::ABTest.new(
392
- name: "Test 1",
393
- champion_version_id: "v1",
394
- challenger_version_id: "v2"
395
- ))
396
- expect(adapter.test_count).to eq(1)
397
-
398
- adapter.save_test(DecisionAgent::ABTesting::ABTest.new(
399
- name: "Test 2",
400
- champion_version_id: "v1",
401
- challenger_version_id: "v2"
402
- ))
403
- expect(adapter.test_count).to eq(2)
404
- end
405
-
406
- it "reflects deletions" do
407
- test = adapter.save_test(DecisionAgent::ABTesting::ABTest.new(
408
- name: "Test 1",
409
- champion_version_id: "v1",
410
- challenger_version_id: "v2"
411
- ))
412
- adapter.save_test(DecisionAgent::ABTesting::ABTest.new(
413
- name: "Test 2",
414
- champion_version_id: "v1",
415
- challenger_version_id: "v2"
416
- ))
417
- adapter.delete_test(test.id)
418
- expect(adapter.test_count).to eq(1)
419
- end
420
- end
421
-
422
- describe "#assignment_count" do
423
- it "returns zero initially" do
424
- expect(adapter.assignment_count).to eq(0)
425
- end
426
-
427
- it "returns correct count after saving assignments" do
428
- adapter.save_assignment(DecisionAgent::ABTesting::ABTestAssignment.new(
429
- ab_test_id: 1,
430
- variant: :champion,
431
- version_id: "v1"
432
- ))
433
- expect(adapter.assignment_count).to eq(1)
434
-
435
- adapter.save_assignment(DecisionAgent::ABTesting::ABTestAssignment.new(
436
- ab_test_id: 1,
437
- variant: :challenger,
438
- version_id: "v2"
439
- ))
440
- expect(adapter.assignment_count).to eq(2)
441
- end
442
-
443
- it "reflects deletions" do
444
- test = adapter.save_test(DecisionAgent::ABTesting::ABTest.new(
445
- name: "Test 1",
446
- champion_version_id: "v1",
447
- challenger_version_id: "v2"
448
- ))
449
- adapter.save_assignment(DecisionAgent::ABTesting::ABTestAssignment.new(
450
- ab_test_id: test.id,
451
- variant: :champion,
452
- version_id: "v1"
453
- ))
454
- adapter.save_assignment(DecisionAgent::ABTesting::ABTestAssignment.new(
455
- ab_test_id: test.id,
456
- variant: :challenger,
457
- version_id: "v2"
458
- ))
459
- adapter.delete_test(test.id) # This deletes all assignments for the test
460
- expect(adapter.assignment_count).to eq(0)
461
- end
462
- end
463
-
464
- describe "thread safety" do
465
- it "handles concurrent access safely" do
466
- threads = []
467
- 10.times do
468
- threads << Thread.new do
469
- 10.times do
470
- test = adapter.save_test(DecisionAgent::ABTesting::ABTest.new(
471
- name: "Test",
472
- champion_version_id: "v1",
473
- challenger_version_id: "v2"
474
- ))
475
- adapter.get_test(test.id)
476
- adapter.list_tests
477
- end
478
- end
479
- end
480
-
481
- threads.each(&:join)
482
- expect(adapter.test_count).to eq(100)
483
- end
484
- end
485
- end