Files
pve-purestorage-plugin/tests/unit/test_retry_logic.t
T
Timur Kumakbayev f9f8eed94b Active Cluster Support, Pod Quota Fixes,Token Cache and CI Improvements (#81)
feat: add Active Cluster support and improve plugin stability

## Major Features

### Active Cluster Support (Experimental) (#42)
- Add support for multiple PureStorage arrays in Active Cluster configuration
- Automatic volume connection on all arrays for high availability
- Configure via comma-separated addresses and tokens

### Pod Quota Limit Support (#69)
- Add proper handling of pod quota_limit parameter
- Use quota_limit when set, fall back to array capacity when unlimited
- Fix capacity reporting for pods with quotas

### Session Token Caching
- Implement session token caching in /etc/pve/priv/purestorage/
- Automatic token refresh at 80% of TTL to prevent expiration
- In-memory and file-based caching with jitter to prevent thundering herd

### Debug Logging
- Add configurable debug logging with 4 levels (0-3)
- Support both config parameter and PURESTORAGE_DEBUG environment variable

## Bug Fixes
- Fix volume deletion when connected to multiple hosts
- Query all connections before destroy
- Disconnect from all hosts on all arrays
- Prevents "Cannot destroy volume because it is currently connected" error

## CI/CD Improvements
- Add workflow_dispatch trigger to checks workflow
- Add option to check all files or only changed files
- Add comprehensive markdown linting with markdownlint-cli2

## Testing
- Add token caching tests (tests/token_cache_test.pl)
- Test token validation, expiration, and race conditions
- Test cleanup of expired cache files

## Refactoring (#72)
- Refactor volume removal logic to handle multiple host connections
- Improve device cleanup sequence (LVM, partitions, multipath)
- Extract connection querying logic before volume destruction
- Refactor CI/CD workflows for better maintainability and flexibility
- Improve error handling and logging throughout the plugin
- Enhance Active Cluster support with proper multi-array operations

## Code Formatting
- Format all Perl files with perltidy using .perltidyrc configuration
- Ensure consistent code style across the codebase
- Fix formatting issues in PureStoragePlugin.pm and test files

## Documentation
- Update README with new functionality
2026-01-17 17:20:28 +05:00

142 lines
2.9 KiB
Perl

#!/usr/bin/env perl
use strict;
use warnings;
use Test::More tests => 8;
# Mock HTTP response
package MockHTTPResponse {
sub new {
my ( $class, $code, $success ) = @_;
return bless { code => $code, success => $success }, $class;
}
sub code { $_[0]->{code} }
sub is_success { $_[0]->{success} }
}
# Test retry counter logic
my $retry_count = 0;
my $max_retries = 1;
my @responses;
sub simulate_request {
my $response = shift @responses;
return $response;
}
# Test 1: Success on first try (no retry)
@responses = ( MockHTTPResponse->new(200, 1) );
$retry_count = 0;
while ( $retry_count <= $max_retries ) {
my $response = simulate_request();
if ( $response->code == 401 ) {
$retry_count++;
if ( $retry_count <= $max_retries ) {
next; # Retry
}
}
last; # Success or max retries
}
is( $retry_count, 0, 'No retry on successful response' );
# Test 2: One retry on 401, then success
@responses = (
MockHTTPResponse->new(401, 0),
MockHTTPResponse->new(200, 1)
);
$retry_count = 0;
while ( $retry_count <= $max_retries ) {
my $response = simulate_request();
if ( $response->code == 401 ) {
$retry_count++;
if ( $retry_count <= $max_retries ) {
next;
}
}
last;
}
is( $retry_count, 1, 'One retry on 401 response' );
# Test 3: Max retries reached (401 twice)
@responses = (
MockHTTPResponse->new(401, 0),
MockHTTPResponse->new(401, 0)
);
$retry_count = 0;
while ( $retry_count <= $max_retries ) {
my $response = simulate_request();
if ( $response->code == 401 ) {
$retry_count++;
if ( $retry_count <= $max_retries ) {
next;
} else {
last; # Max retries
}
}
last;
}
is( $retry_count, 2, 'Max retries (2) attempted on repeated 401' );
# Test 4: Loop exits after max retries
ok( $retry_count > $max_retries, 'Retry count exceeds max_retries after exhausting' );
# Test 5: No retry on non-401 errors
@responses = ( MockHTTPResponse->new(500, 0) );
$retry_count = 0;
while ( $retry_count <= $max_retries ) {
my $response = simulate_request();
if ( $response->code == 401 ) {
$retry_count++;
if ( $retry_count <= $max_retries ) {
next;
}
}
last;
}
is( $retry_count, 0, 'No retry on 500 error' );
# Test 6: Retry counter increments correctly
my @counts;
@responses = (
MockHTTPResponse->new(401, 0),
MockHTTPResponse->new(401, 0),
MockHTTPResponse->new(200, 1)
);
$retry_count = 0;
while ( $retry_count <= $max_retries ) {
push @counts, $retry_count;
my $response = simulate_request();
if ( $response->code == 401 ) {
$retry_count++;
if ( $retry_count <= $max_retries ) {
next;
}
}
last;
}
is_deeply( \@counts, [0, 1], 'Retry counter increments: 0, 1' );
# Test 7: Max retries = 1 allows exactly 1 retry
is( $max_retries, 1, 'Max retries configured to 1' );
# Test 8: Total attempts = max_retries + 1
my $total_attempts = $max_retries + 1;
is( $total_attempts, 2, 'Total attempts = 2 (initial + 1 retry)' );
done_testing();