fix(regression test): fix in shutdown and replication pytests (#1530)

* fix(regression_test): fix in shutdown and replication pytests

- skip test_gracefull_shutdown test
- fix test_take_over_seeder test:
    bug: the dbfilename was not unique, therefore between different runs the server reload
    the snapshot of the last test run and this failed the test.
    fix: use random dbfilename
- fix test_take_over_timeout test:
    bug: REPLTAKEOVER timeout was not small enough for opt dfly build
    fix: decrease timeout

Signed-off-by: adi_holden <adi@dragonflydb.io>
This commit is contained in:
adiholden 2023-07-11 09:56:20 +03:00 committed by GitHub
parent 77a223d36d
commit c27fa8d674
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 20 additions and 12 deletions

View file

@ -359,7 +359,7 @@ void DflyCmd::TakeOver(CmdArgList args, ConnectionContext* cntx) {
return (*cntx)->SendError("timeout is negative"); return (*cntx)->SendError("timeout is negative");
} }
VLOG(1) << "Got DFLY TAKEOVER " << sync_id_str; VLOG(1) << "Got DFLY TAKEOVER " << sync_id_str << " time out:" << timeout;
auto [sync_id, replica_ptr] = GetReplicaInfoOrReply(sync_id_str, rb); auto [sync_id, replica_ptr] = GetReplicaInfoOrReply(sync_id_str, rb);
if (!sync_id) if (!sync_id)
@ -412,6 +412,8 @@ void DflyCmd::TakeOver(CmdArgList args, ConnectionContext* cntx) {
status = OpStatus::CANCELLED; status = OpStatus::CANCELLED;
return; return;
} }
VLOG(1) << "Replica lsn:" << flow->last_acked_lsn
<< " master lsn:" << shard->journal()->GetLsn();
ThisFiber::SleepFor(1ms); ThisFiber::SleepFor(1ms);
} }
}; };

View file

@ -1142,10 +1142,11 @@ async def test_take_over_counters(df_local_factory, master_threads, replica_thre
@pytest.mark.parametrize("master_threads, replica_threads", take_over_cases) @pytest.mark.parametrize("master_threads, replica_threads", take_over_cases)
@pytest.mark.asyncio @pytest.mark.asyncio
async def test_take_over_seeder(df_local_factory, df_seeder_factory, master_threads, replica_threads): async def test_take_over_seeder(request, df_local_factory, df_seeder_factory, master_threads, replica_threads):
tmp_file_name = ''.join(random.choices(string.ascii_letters, k=10))
master = df_local_factory.create(proactor_threads=master_threads, master = df_local_factory.create(proactor_threads=master_threads,
port=BASE_PORT, port=BASE_PORT,
dbfilename=f"dump_{master_threads}_{replica_threads}", dbfilename=f"dump_{tmp_file_name}",
logtostderr=True) logtostderr=True)
replica = df_local_factory.create( replica = df_local_factory.create(
port=BASE_PORT+1, proactor_threads=replica_threads) port=BASE_PORT+1, proactor_threads=replica_threads)
@ -1203,15 +1204,12 @@ async def test_take_over_timeout(df_local_factory, df_seeder_factory):
await c_replica.execute_command(f"REPLICAOF localhost {master.port}") await c_replica.execute_command(f"REPLICAOF localhost {master.port}")
await wait_available_async(c_replica) await wait_available_async(c_replica)
async def seed(): fill_task = asyncio.create_task(seeder.run(target_ops=3000))
await seeder.run(target_ops=3000)
fill_task = asyncio.create_task(seed())
# Give the seeder a bit of time. # Give the seeder a bit of time.
await asyncio.sleep(1) await asyncio.sleep(1)
try: try:
await c_replica.execute_command(f"REPLTAKEOVER 0.0001") await c_replica.execute_command(f"REPLTAKEOVER 0.00001")
except redis.exceptions.ResponseError as e: except redis.exceptions.ResponseError as e:
assert str(e) == "Couldn't execute takeover" assert str(e) == "Couldn't execute takeover"
else: else:
@ -1229,11 +1227,14 @@ async def test_take_over_timeout(df_local_factory, df_seeder_factory):
# 2. Number of threads for each replica # 2. Number of threads for each replica
replication_cases = [(8, 8)] replication_cases = [(8, 8)]
@pytest.mark.asyncio @pytest.mark.asyncio
@pytest.mark.parametrize("t_master, t_replica", replication_cases) @pytest.mark.parametrize("t_master, t_replica", replication_cases)
async def test_no_tls_on_admin_port(df_local_factory, df_seeder_factory, t_master, t_replica, with_tls_server_args): async def test_no_tls_on_admin_port(df_local_factory, df_seeder_factory, t_master, t_replica, with_tls_server_args):
# 1. Spin up dragonfly without tls, debug populate # 1. Spin up dragonfly without tls, debug populate
master = df_local_factory.create(no_tls_on_admin_port="true", admin_port=ADMIN_PORT, **with_tls_server_args, port=BASE_PORT, proactor_threads=t_master)
master = df_local_factory.create(
no_tls_on_admin_port="true", admin_port=ADMIN_PORT, **with_tls_server_args, port=BASE_PORT, proactor_threads=t_master)
master.start() master.start()
c_master = aioredis.Redis(port=master.admin_port) c_master = aioredis.Redis(port=master.admin_port)
await c_master.execute_command("DEBUG POPULATE 100") await c_master.execute_command("DEBUG POPULATE 100")
@ -1241,7 +1242,9 @@ async def test_no_tls_on_admin_port(df_local_factory, df_seeder_factory, t_maste
assert 100 == db_size assert 100 == db_size
# 2. Spin up a replica and initiate a REPLICAOF # 2. Spin up a replica and initiate a REPLICAOF
replica = df_local_factory.create(no_tls_on_admin_port="true", admin_port=ADMIN_PORT + 1, **with_tls_server_args, port=BASE_PORT + 1, proactor_threads=t_replica)
replica = df_local_factory.create(
no_tls_on_admin_port="true", admin_port=ADMIN_PORT + 1, **with_tls_server_args, port=BASE_PORT + 1, proactor_threads=t_replica)
replica.start() replica.start()
c_replica = aioredis.Redis(port=replica.admin_port) c_replica = aioredis.Redis(port=replica.admin_port)
res = await c_replica.execute_command("REPLICAOF localhost " + str(master.admin_port)) res = await c_replica.execute_command("REPLICAOF localhost " + str(master.admin_port))

View file

@ -9,10 +9,13 @@ from . import dfly_args
BASIC_ARGS = {"dir": "{DRAGONFLY_TMP}/"} BASIC_ARGS = {"dir": "{DRAGONFLY_TMP}/"}
@pytest.mark.skip(reason='Currently we can not guarantee that on shutdown if command is executed and value is written we response before breaking the connection')
@dfly_args({"proactor_threads": "4"}) @dfly_args({"proactor_threads": "4"})
class TestDflyAutoLoadSnapshot(): class TestDflyAutoLoadSnapshot():
"""Test automatic loading of dump files on startup with timestamp""" """
Test automatic loading of dump files on startup with timestamp.
When command is executed if a value is written we should send the response before shutdown
"""
@pytest.mark.asyncio @pytest.mark.asyncio
async def test_gracefull_shutdown(self, df_local_factory): async def test_gracefull_shutdown(self, df_local_factory):
df_args = {"dbfilename": "dump", **BASIC_ARGS, "port": 1111} df_args = {"dbfilename": "dump", **BASIC_ARGS, "port": 1111}