Lib-Pepper
view release on metacpan or search on metacpan
t/05-stress-test.t view on Meta::CPAN
use strict;
use warnings;
use Test::More;
use File::Spec;
use Time::HiRes qw(time);
# Test module loading
BEGIN {
use_ok('Lib::Pepper::Simple');
use_ok('Lib::Pepper::Constants', qw(:all));
}
# Author-only test: requires PEPPER_LICENSE environment variable
# Usage: PEPPER_LICENSE=/path/to/license.xml make test
my $licenseFile = $ENV{PEPPER_LICENSE};
my $configFile = File::Spec->catfile('examples', 'config', 'pepper_config.xml');
my $libraryPath = (-f 'libpepcore.so' ? File::Spec->rel2abs('libpepcore.so') : '');
my $haveLicense = 0;
my $license_xml;
my $config_xml;
if(defined $licenseFile && -f $licenseFile && -f $configFile) {
# Read files into XML strings (like working examples do)
open(my $fh, '<', $licenseFile) or die "Cannot open license file: $!";
$license_xml = do { local $/; <$fh> };
close($fh);
open($fh, '<', $configFile) or die "Cannot open config file: $!";
$config_xml = do { local $/; <$fh> };
close($fh);
$haveLicense = 1;
diag("License file: $licenseFile");
diag("Config file: $configFile");
diag("Library path: $libraryPath");
}
SKIP: {
skip 'Author-only test: Set PEPPER_LICENSE=/path/to/license.xml to run stress tests', 20 unless $haveLicense;
diag("");
diag("=" x 70);
diag("STRESS TEST: 100 instances - Create/Destroy cycles");
diag("=" x 70);
diag("");
# Verify initial state (never-finalize design: library may be initialized from previous tests)
my $initialStatus = Lib::Pepper::Simple->library_status();
# With never-finalize design, library stays initialized across tests
ok($initialStatus->{initialized} >= 0, 'Library status checked before stress test');
is($initialStatus->{instance_count}, 0, 'Instance count is 0 before stress test');
# Test 1: Sequential create/destroy (100 iterations)
diag("Test 1: Sequential create/destroy (100 iterations)");
my $startTime = time();
my $iterations = 100;
my $errors = 0;
my $warnings = 0;
# Capture warnings
local $SIG{__WARN__} = sub {
my $warning = shift;
# Ignore expected warnings from destructor
unless($warning =~ /Lib::Pepper finalization failed during DESTROY/) {
diag("WARNING: $warning");
$warnings++;
}
};
for my $i (1..$iterations) {
my $terminal;
eval {
$terminal = Lib::Pepper::Simple->new(
terminal_type => PEP_TERMINAL_TYPE_GENERIC_ZVT,
terminal_address => '192.168.1.163:20008',
license_xml => $license_xml,
config_xml => $config_xml,
library_path => $libraryPath,
);
};
if($@) {
diag("Iteration $i FAILED: $@");
$errors++;
last; # Stop on first error
}
# Verify library state during iteration
if($i == 1) {
my $status = Lib::Pepper::Simple->library_status();
is($status->{initialized}, 1, "Library initialized on first iteration");
is($status->{instance_count}, 1, "Instance count is 1 on first iteration");
}
# Destroy terminal
undef $terminal;
# Every 10 iterations, verify cleanup
if($i % 10 == 0) {
my $status = Lib::Pepper::Simple->library_status();
is($status->{instance_count}, 0, "Instance count is 0 after iteration $i");
is($status->{initialized}, 1, "Library STAYS initialized after iteration $i (never-finalize design)");
diag("Progress: $i/$iterations iterations complete");
}
}
my $elapsed = time() - $startTime;
diag(sprintf("Sequential test completed in %.2f seconds (%.0f ms per iteration)",
$elapsed, ($elapsed / $iterations) * 1000));
is($errors, 0, "No errors during $iterations sequential iterations");
is($warnings, 0, "No unexpected warnings during sequential test");
# Verify final cleanup (never-finalize design: library STAYS initialized)
my $finalStatus = Lib::Pepper::Simple->library_status();
is($finalStatus->{initialized}, 1, 'Library STAYS initialized after sequential stress test (never-finalize design)');
is($finalStatus->{instance_count}, 0, 'Instance count is 0 after sequential stress test');
# Test 2: Multiple simultaneous instances (stress test cleanup)
diag("");
diag("Test 2: Multiple simultaneous instances (10 at a time, 10 cycles)");
$startTime = time();
$errors = 0;
for my $cycle (1..10) {
my @terminals;
# Create 10 terminals
for my $i (1..10) {
my $terminal;
eval {
$terminal = Lib::Pepper::Simple->new(
terminal_type => PEP_TERMINAL_TYPE_GENERIC_ZVT,
terminal_address => '192.168.1.163:20008',
license_xml => $license_xml,
config_xml => $config_xml,
library_path => $libraryPath,
);
};
if($@) {
diag("Cycle $cycle, terminal $i FAILED: $@");
$errors++;
last;
}
push @terminals, $terminal;
}
# Verify instance count
my $status = Lib::Pepper::Simple->library_status();
is($status->{instance_count}, 10, "Cycle $cycle: 10 instances active");
# Destroy all terminals
@terminals = ();
# Verify cleanup (never-finalize design: library STAYS initialized)
$status = Lib::Pepper::Simple->library_status();
is($status->{instance_count}, 0, "Cycle $cycle: All instances cleaned up");
is($status->{initialized}, 1, "Cycle $cycle: Library STAYS initialized (never-finalize design)");
diag("Cycle $cycle complete");
}
$elapsed = time() - $startTime;
diag(sprintf("Multi-instance test completed in %.2f seconds", $elapsed));
is($errors, 0, "No errors during multi-instance stress test");
# Verify final state (never-finalize design: library STAYS initialized)
my $veryFinalStatus = Lib::Pepper::Simple->library_status();
( run in 0.699 second using v1.01-cache-2.11-cpan-71847e10f99 )