|
@@ -330,14 +330,60 @@ class SimulationTest extends TestCase
|
|
|
|
|
|
|
|
$this->assertSame($before, $this->realView(), 'the task run did not leak either');
|
|
$this->assertSame($before, $this->realView(), 'the task run did not leak either');
|
|
|
|
|
|
|
|
|
|
+ // 一键启动:按模拟设置的默认任务参数跑完整流程
|
|
|
|
|
+ SimulationSettings::save(['simulation_task_members' => 2, 'simulation_task_recharge' => 500, 'simulation_task_bet_amount' => 50,
|
|
|
|
|
+ 'simulation_task_bet_count' => 2, 'simulation_task_withdraw' => 100, 'simulation_task_interval' => 0]);
|
|
|
|
|
+ $quickId = SimulationTaskService::quickStart(1);
|
|
|
|
|
+ for ($i = 0; $i < 60 && in_array(DB::table('simulation_task_runs')->where('id', $quickId)->value('status'), ['queued', 'running'], true); $i++) SimulationRunner::tick();
|
|
|
|
|
+ $quick = DB::table('simulation_task_runs')->where('id', $quickId)->first();
|
|
|
|
|
+ $this->assertSame(['completed', 16, 16, 0], [$quick->status, (int) $quick->total, (int) $quick->completed, (int) $quick->failed], (string) $quick->last_error);
|
|
|
|
|
+ $this->assertSame(['register', 'login', 'recharge', 'bet', 'settle', 'withdraw', 'logout'], array_column(json_decode($quick->steps, true), 'type'));
|
|
|
|
|
+ SimulationSettings::save(['simulation_task_recharge' => 20000]);
|
|
|
|
|
+ try { SimulationTaskService::quickStart(1); $this->fail('defaults above the amount cap are refused'); }
|
|
|
|
|
+ catch (\Exception $e) { $this->assertStringContainsString('单次金额上限', $e->getMessage()); }
|
|
|
|
|
+ $this->assertSame($before, $this->realView());
|
|
|
|
|
+
|
|
|
|
|
+ // 持续运行:日期区间内一轮接一轮;区间外、间隔未到、上一轮没结束时都不启动
|
|
|
|
|
+ SimulationSettings::save(['simulation_task_recharge' => 500]);
|
|
|
|
|
+ try { SimulationSettings::save(['simulation_schedule_enabled' => 1, 'simulation_schedule_start' => '', 'simulation_schedule_end' => '']); $this->fail('dates are required'); }
|
|
|
|
|
+ catch (\Exception $e) { $this->assertStringContainsString('开始和结束日期', $e->getMessage()); }
|
|
|
|
|
+ $this->assertSame('0', SimulationSettings::get('simulation_schedule_enabled'), 'a refused save changes nothing');
|
|
|
|
|
+ $today = now()->toDateString();
|
|
|
|
|
+ SimulationSettings::save(['simulation_schedule_enabled' => 1, 'simulation_schedule_start' => now()->addDay()->toDateString(), 'simulation_schedule_end' => now()->addDays(30)->toDateString(), 'simulation_schedule_gap_minutes' => 10]);
|
|
|
|
|
+ $this->assertNull(SimulationTaskService::scheduleNext(), 'not started before the range');
|
|
|
|
|
+ SimulationSettings::save(['simulation_schedule_start' => $today]);
|
|
|
|
|
+ $runsBefore = DB::table('simulation_task_runs')->count();
|
|
|
|
|
+ SimulationRunner::tick();
|
|
|
|
|
+ $first = DB::table('simulation_task_runs')->orderByDesc('id')->first();
|
|
|
|
|
+ $this->assertSame([$runsBefore + 1, true], [DB::table('simulation_task_runs')->count(), str_starts_with($first->name, '持续任务 ')]);
|
|
|
|
|
+ $this->assertNull(SimulationTaskService::scheduleNext(), 'one round at a time');
|
|
|
|
|
+ for ($i = 0; $i < 60 && DB::table('simulation_task_runs')->where('id', $first->id)->value('status') === 'running'; $i++) SimulationRunner::tick();
|
|
|
|
|
+ $this->assertSame('completed', DB::table('simulation_task_runs')->where('id', $first->id)->value('status'));
|
|
|
|
|
+ $this->assertNull(SimulationTaskService::scheduleNext(), 'waits for the gap after a round');
|
|
|
|
|
+ \Carbon\Carbon::setTestNow(now()->addMinutes(11));
|
|
|
|
|
+ // 会员数到上限后不再注册,改用已有模拟会员
|
|
|
|
|
+ SimulationSettings::save(['simulation_max_members_total' => DB::table('users')->where('user_type', 2)->count()]);
|
|
|
|
|
+ $second = SimulationTaskService::scheduleNext();
|
|
|
|
|
+ $this->assertNotNull($second);
|
|
|
|
|
+ $secondRun = DB::table('simulation_task_runs')->where('id', $second)->first();
|
|
|
|
|
+ $this->assertNotContains('register', array_column(json_decode($secondRun->steps, true), 'type'));
|
|
|
|
|
+ $this->assertCount(2, json_decode($secondRun->member_ids, true));
|
|
|
|
|
+ \Carbon\Carbon::setTestNow(now()->addDays(40));
|
|
|
|
|
+ SimulationTaskService::setStatus($second, 'stop');
|
|
|
|
|
+ $this->assertNull(SimulationTaskService::scheduleNext(), 'not started after the range');
|
|
|
|
|
+ \Carbon\Carbon::setTestNow();
|
|
|
|
|
+ SimulationSettings::save(['simulation_schedule_enabled' => 0]);
|
|
|
|
|
+ $this->assertSame($before, $this->realView());
|
|
|
|
|
+ $simulatedMembers = DB::table('users')->where('user_type', 2)->count();
|
|
|
|
|
+
|
|
|
// 重置:只删模拟数据
|
|
// 重置:只删模拟数据
|
|
|
$preview = SimulationResetService::preview();
|
|
$preview = SimulationResetService::preview();
|
|
|
- $this->assertSame(3, $preview['counts']['users']);
|
|
|
|
|
|
|
+ $this->assertSame([7, 7], [$simulatedMembers, $preview['counts']['users']]);
|
|
|
try { SimulationResetService::reset('wrong', SimulationResetService::CONFIRM_TEXT); $this->fail('wrong token must be refused'); }
|
|
try { SimulationResetService::reset('wrong', SimulationResetService::CONFIRM_TEXT); $this->fail('wrong token must be refused'); }
|
|
|
catch (\Exception $e) { $this->assertStringContainsString('失效', $e->getMessage()); }
|
|
catch (\Exception $e) { $this->assertStringContainsString('失效', $e->getMessage()); }
|
|
|
$preview = SimulationResetService::preview();
|
|
$preview = SimulationResetService::preview();
|
|
|
$deleted = SimulationResetService::reset($preview['confirm_token'], $preview['confirm_text']);
|
|
$deleted = SimulationResetService::reset($preview['confirm_token'], $preview['confirm_text']);
|
|
|
- $this->assertSame(3, $deleted['users']);
|
|
|
|
|
|
|
+ $this->assertSame(7, $deleted['users']);
|
|
|
$this->assertSame(0, DB::table('users')->where('user_type', 2)->count());
|
|
$this->assertSame(0, DB::table('users')->where('user_type', 2)->count());
|
|
|
$this->assertSame([2, 2, 4, 2, 2], [DB::table('users')->count(), DB::table('wallets')->count(), DB::table('balance_logs')->count(),
|
|
$this->assertSame([2, 2, 4, 2, 2], [DB::table('users')->count(), DB::table('wallets')->count(), DB::table('balance_logs')->count(),
|
|
|
DB::table('payment_orders')->count(), DB::table('lhc_order')->count()], 'real and guest rows are untouched');
|
|
DB::table('payment_orders')->count(), DB::table('lhc_order')->count()], 'real and guest rows are untouched');
|