
# Copyright (c) 2021-2025, PostgreSQL Global Development Group

use strict;
use warnings FATAL => 'all';
use PostgreSQL::Test::Utils;
use Test::More;

use FindBin;
use lib $FindBin::RealBin;

use RewindTest;

RewindTest::setup_cluster("local");
RewindTest::start_primary();

# Create a test table and insert a row in primary.
primary_psql("CREATE TABLE tbl1 (d text)");
primary_psql("INSERT INTO tbl1 VALUES ('in primary')");
primary_psql("CHECKPOINT");

RewindTest::create_standby("local");

# Insert additional data on primary that will be replicated to standby
primary_psql("INSERT INTO tbl1 values ('in primary, before promotion')");
primary_psql('CHECKPOINT');

RewindTest::promote_standby();

# Insert a row in the old primary. This causes the primary and standby to have
# "diverged", it's no longer possible to just apply the standby's logs over
# primary directory - you need to rewind.  Also insert a new row in the
# standby, which won't be present in the old primary.
primary_psql("INSERT INTO tbl1 VALUES ('in primary, after promotion')");
standby_psql("INSERT INTO tbl1 VALUES ('in standby, after promotion')");

# Stop the nodes before running pg_rewind
$node_standby->stop;
$node_primary->stop;

my $primary_pgdata = $node_primary->data_dir;
my $standby_pgdata = $node_standby->data_dir;

# Add an extra file that we can tamper with without interfering with the data
# directory data files.
mkdir "$standby_pgdata/tst_both_dir";
append_to_file "$standby_pgdata/tst_both_dir/file1", 'a';

# Run pg_rewind and pipe the output from the run into the extra file we want
# to copy. This will ensure that the file is continuously growing during the
# copy operation and the result will be an error.
my $ret = run_log(
	[
		'pg_rewind', '--debug',
		'--source-pgdata', $standby_pgdata,
		'--target-pgdata', $primary_pgdata,
		'--no-sync',
	],
	'2>>',
	"$standby_pgdata/tst_both_dir/file1");
ok(!$ret, 'Error out on copying growing file');

# Ensure that the files are of different size, the final error message should
# only be in one of them making them guaranteed to be different
my $primary_size = -s "$primary_pgdata/tst_both_dir/file1";
my $standby_size = -s "$standby_pgdata/tst_both_dir/file1";
isnt($standby_size, $primary_size, "File sizes should differ");

# Extract the last line from the verbose output as that should have the error
# message for the unexpected file size
my $last;
open my $f, '<', "$standby_pgdata/tst_both_dir/file1" or die $!;
$last = $_ while (<$f>);
close $f;
like($last, qr/error: size of source file/, "Check error message");

done_testing();
