['driver' => 'sqlite', 'database' => ':memory:', 'prefix' => ''], 'upstream_mirrors.connection' => 'business_mirror', 'upstream_mirrors.datasets' => [ 'source.schema.fact' => ['source_key' => 'source', 'schema' => 'schema', 'object' => 'fact', 'target' => 'fact_rows', 'keys' => ['id']], 'source.schema.unused' => ['source_key' => 'source', 'schema' => 'schema', 'object' => 'unused', 'target' => 'unused_rows', 'keys' => ['id']], ], 'business_data.datasets' => [ 'source.schema.fact' => ['role' => 'fact', 'target_store' => 'clickhouse', 'sync' => 'after_columnar_activation'], 'source.schema.unused' => ['role' => 'archive_only', 'target_store' => 'parquet', 'sync' => 'disabled'], ], ]); DB::purge('business_mirror'); Schema::connection('business_mirror')->create('business_data_placements', function (Blueprint $table): void { $table->string('dataset_key')->primary(); $table->string('target_store'); $table->string('phase')->default('planned'); $table->string('active_generation')->nullable(); $table->timestamps(); }); } protected function tearDown(): void { DB::purge('business_mirror'); parent::tearDown(); } public function test_it_stops_unused_data_and_enables_columnar_sync_only_after_activation(): void { $placement = new BusinessDataPlacement(app('db')); $this->assertFalse($placement->shouldSchedule('source.schema.unused')); $this->assertFalse($placement->shouldSchedule('source.schema.fact')); DB::connection('business_mirror')->table('business_data_placements')->insert([ 'dataset_key' => 'source.schema.fact', 'target_store' => 'clickhouse', 'phase' => 'active', 'active_generation' => '11111111-1111-4111-8111-111111111111', 'created_at' => now(), 'updated_at' => now(), ]); $this->assertTrue($placement->shouldSchedule('source.schema.fact')); $this->assertTrue($placement->isActive('source.schema.fact', 'clickhouse')); } public function test_runtime_registered_dataset_defaults_to_a_mariadb_dimension(): void { $policy = (new BusinessDataPlacement(app('db')))->policy('database_4.accounts_v1'); $this->assertSame('external_dimension', $policy['role']); $this->assertSame('mariadb', $policy['target_store']); $this->assertSame('always', $policy['sync']); } public function test_every_fixed_upstream_dataset_has_exactly_one_storage_policy(): void { $upstream = require base_path('config/upstream_mirrors.php'); $businessData = require base_path('config/business_data.php'); $this->assertCount(56, $upstream['datasets']); $upstreamKeys = array_keys($upstream['datasets']); $policyKeys = array_keys($businessData['datasets']); sort($upstreamKeys); sort($policyKeys); $this->assertSame($upstreamKeys, $policyKeys); } public function test_original_bills_keep_refreshing_for_the_current_alipay_reader(): void { $businessData = require base_path('config/business_data.php'); config(['business_data.datasets' => $businessData['datasets']]); $placement = new BusinessDataPlacement(app('db')); $this->assertFalse($placement->isActive('operations_replica.rpt.jst_originalBillInfo', 'clickhouse')); $this->assertTrue($placement->shouldSchedule('operations_replica.rpt.jst_originalBillInfo')); } }