AmberDB

 view release on metacpan or  search on metacpan

t/amberdb_ramdisk_tiers.t  view on Meta::CPAN

#!/usr/bin/perl

# t/amberdb_ramdisk_tiers.t - Comprehensive tests for AmberDB RAM-Disk Tiers (0..4)
# Validates canonical string words ('none', 'index', 'dual', 'temp', 'async'),
# Tier 4 write-behind async dirty tracking and coalescing state machine,
# background ramdisk_sync() persistence, and transactional dual-write invariants.

use 5.016000;
use strict;
use warnings;
use Test::More;
use File::Temp qw(tempdir);
use File::Spec;
use File::Path qw(make_path);

use lib 'lib';
use AmberDB;

my $tmpdir = tempdir( CLEANUP => 1 );
my $mock_mount = tempdir( CLEANUP => 1 );
my $ram_root = File::Spec->catdir( $mock_mount, 'amberdb_tiers_test' );
make_path($ram_root);
$ENV{AMBERDB_TEST_RAMDISK} = 1;

# -----------------------------------------------------------------------------
# Subtest 1: Canonical String Normalization & Tier Mapping
# -----------------------------------------------------------------------------
subtest 'Canonical String Normalization' => sub {
    plan tests => 14;

    my $adb = AmberDB->new(
        database => 'tiers_test',
        cfg  => { use_ramdisk => 'dual' },
        path => {
            dbase_dir   => $tmpdir,
            ramdisk_dir => $ram_root,
        }
    );

    # 1. Constructor string normalization
    is( $adb->config('use_ramdisk'), 2, "Constructor 'dual' normalizes to 2" );

    # 2. Config string normalization
    $adb->config( use_ramdisk => 'index' );
    is( $adb->config('use_ramdisk'), 1, "config('index') normalizes to 1" );

    $adb->config( use_ramdisk => 'none' );
    is( $adb->config('use_ramdisk'), 0, "config('none') normalizes to 0" );

    $adb->config( use_ramdisk => 'async' );
    is( $adb->config('use_ramdisk'), 4, "config('async') normalizes to 4" );

    # Global Tier 3 fallback to 0
    $adb->config( use_ramdisk => 'temp' );
    is( $adb->config('use_ramdisk'), 0, "config('temp') falls back to 0 globally" );

    $adb->config( use_ramdisk => 'volatile' );
    is( $adb->config('use_ramdisk'), 0, "config('volatile') falls back to 0 globally" );

    # 3. Table attribute string normalization
    $adb->table_attr( 'tbl_none',  use_ramdisk => 'none' );
    $adb->table_attr( 'tbl_index', use_ramdisk => 'index' );
    $adb->table_attr( 'tbl_dual',  use_ramdisk => 'dual' );
    $adb->table_attr( 'tbl_temp',  use_ramdisk => 'temp' );
    $adb->table_attr( 'tbl_async', use_ramdisk => 'async' );

    is( $adb->table_attr( 'tbl_none',  'use_ramdisk' ), 0, "table_attr('none') normalizes to 0" );
    is( $adb->table_attr( 'tbl_index', 'use_ramdisk' ), 1, "table_attr('index') normalizes to 1" );
    is( $adb->table_attr( 'tbl_dual',  'use_ramdisk' ), 2, "table_attr('dual') normalizes to 2" );
    is( $adb->table_attr( 'tbl_temp',  'use_ramdisk' ), 3, "table_attr('temp') normalizes to 3" );
    is( $adb->table_attr( 'tbl_async', 'use_ramdisk' ), 4, "table_attr('async') normalizes to 4" );

    # Synonyms
    $adb->table_attr( 'tbl_syn1', use_ramdisk => 'mirror' );
    $adb->table_attr( 'tbl_syn2', use_ramdisk => 'ram_only' );
    $adb->table_attr( 'tbl_syn3', use_ramdisk => 'write_behind' );

    is( $adb->table_attr( 'tbl_syn1', 'use_ramdisk' ), 2, "table_attr('mirror') normalizes to 2" );
    is( $adb->table_attr( 'tbl_syn2', 'use_ramdisk' ), 3, "table_attr('ram_only') normalizes to 3" );
    is( $adb->table_attr( 'tbl_syn3', 'use_ramdisk' ), 4, "table_attr('write_behind') normalizes to 4" );
};

# -----------------------------------------------------------------------------
# Subtest 2: Tier 4 Event Tracking & Journal State Machine
# -----------------------------------------------------------------------------
subtest 'Tier 4 Dirty Tracking Journal & State Machine' => sub {
    plan tests => 8;

    my $adb = AmberDB->new(
        cfg  => { language => 'gb' },
        path => {
            dbase_dir   => $tmpdir,
            ramdisk_dir => $ram_root,
        }
    );

    my $dummy_file = "$tmpdir/table/test_events.db";

    # 1. Insert (1) -> Action 'add'
    $adb->ramdisk_mark_dirty( $dummy_file, 101, 1 );
    my @e1 = $adb->journal_read('sync_ramdisk');
    ok( @e1 >= 1, "Journal has entries" );
    is( $e1[-1]->{action}, 'add', "New insert event logged as action 'add'" );
    is( $e1[-1]->{key}, '101', "Key is 101" );

    # 2. Update (2) -> Action 'edit'
    $adb->ramdisk_mark_dirty( $dummy_file, 101, 2 );
    my @e2 = $adb->journal_read('sync_ramdisk');
    is( $e2[-1]->{action}, 'edit', "Update event logged as action 'edit'" );

    # 3. Delete (3) -> Action 'del'
    $adb->ramdisk_mark_dirty( $dummy_file, 101, 3 );
    my @e3 = $adb->journal_read('sync_ramdisk');
    is( $e3[-1]->{action}, 'del', "Delete event logged as action 'del'" );

    # 4. Pos testing: exact numerical offset and raw payload
    $adb->ramdisk_mark_dirty( $dummy_file, 202, 1, 'sample_payload_data', 8000000 );
    my @e4 = $adb->journal_read('sync_ramdisk');



( run in 0.501 second using v1.01-cache-2.11-cpan-4716db65a44 )