Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 34 additions & 15 deletions run-tests.pl
Original file line number Diff line number Diff line change
Expand Up @@ -415,26 +415,45 @@ sub delay
$loop->delay_future( after => $secs * $TIMEOUT_FACTOR );
}

# Handy utility wrapper around Future::Utils::try_repeat_until_success which
# includes a delay on retry (and logs the reason for failure)
sub retry_until_success(&)

# Retries a code block until it returns a successful Future.
#
# Includes a delay between each call, and logs the reason for failure.
#
# The code block is called with the iteration number.
#
# Example:
#
# retry_until_success {
# my ( $iter ) = @_;
# ...
# }, max_iterations => 20,
# initial_delay => 0.01;
#
# Will fail if the code block fails `max_iterations` (default 7) times.
#
sub retry_until_success(&%)
{
my ( $code ) = @_;
my ( $code, %params ) = @_;

my $delay = 0.1;
my $delay = $params{initial_delay} // 0.1;

# 7 iterations means a total delay of
# 0.1 * (1 + 1.5 + 1.5^2 + ... + 1.5^5 )
# =~ 2.0 seconds.
my $max_iter = $params{max_iterations} // 7;
my $iter = 0;

try_repeat {
( $iter++ ?
delay( $delay *= 1.5 ) :
Future->done )
->then( $code )
->on_fail( sub {
my ( $exc ) = @_;
chomp $exc;
log_if_fail("Iteration $iter: not ready yet: $exc");
});
} until => sub { !$_[0]->failure };
( $iter ? delay( $delay *= 1.5 ) : Future->done )
->then( sub {
Future->call( $code, $iter++ );
})->on_fail( sub {
my ( $exc ) = @_;
chomp $exc;
log_if_fail("Iteration $iter++: not ready yet: $exc");
});
} until => sub { $iter > $max_iter || !$_[0]->failure };
}

# Another wrapper which repeats (with delay) until the block returns a true
Expand Down
34 changes: 20 additions & 14 deletions tests/10apidoc/32room-alias.pl
Original file line number Diff line number Diff line change
Expand Up @@ -63,11 +63,11 @@
do_request_json_for(
$user,
method => "GET",
uri => "/unstable/org.matrix.msc2432/rooms/$room_id/aliases",
uri => "/r0/rooms/$room_id/aliases",
);
})->then( sub {
my ( $res ) = @_;
log_if_fail "response from /aliases", $res;
log_if_fail "response from /aliases before change:", $res;

assert_json_keys( $res, qw( aliases ));
assert_json_empty_list( $res->{aliases} );
Expand All @@ -79,19 +79,25 @@
uri => "/r0/directory/room/$room_alias",
content => { room_id => $room_id },
);
})->then( sub {
# ... and recheck
do_request_json_for(
$user,
method => "GET",
uri => "/unstable/org.matrix.msc2432/rooms/$room_id/aliases",
);
})->then( sub {
my ( $res ) = @_;
log_if_fail "response from /aliases", $res;

assert_json_keys( $res, qw( aliases ));
assert_deeply_eq($res->{aliases}, [ $room_alias ]);
Future->done;
log_if_fail "response from PUT /directory:", $res;

# ... and recheck. Might need to try this a few times while the caches
# get flushed.
retry_until_success {
my ( $iter ) = @_;
return do_request_json_for(
$user,
method => "GET",
uri => "/r0/rooms/$room_id/aliases",
)->then( sub {
my ( $res ) = @_;
log_if_fail "$iter: response from /aliases", $res;
assert_json_keys( $res, qw( aliases ));
assert_deeply_eq($res->{aliases}, [ $room_alias ]);
Future->done;
});
}
});
};