From 3304ac00d665ff8babd7e8c447460bfb7ec92469 Mon Sep 17 00:00:00 2001 From: Asim R P Date: Mon, 15 Jul 2019 11:05:38 +0530 Subject: [PATCH] Unittest for writing and reading cursor snapshot Functions under test are dumpSharedLocalSnapshot_forCursor() and readSharedLocalSnapshot_forCursor(). Significant amount of global state needs to be created for the test to be able to invoke the two functions. What we are testing here is, whether correct snapshot information is included in what is written to file. Validation is performed by reading the contents of the file and compairing them with expected values. An implicit rule to run a unittest is defined in src/Makefile.mock. This patch overrides it such that the required directory for the cursor snapshot file is created before running the test. Reviewed-by: Adam Berlin and Jesse Zhang --- src/backend/utils/time/test/Makefile | 11 +++ .../utils/time/test/sharedsnapshot_test.c | 95 ++++++++++++++++++- 2 files changed, 105 insertions(+), 1 deletion(-) diff --git a/src/backend/utils/time/test/Makefile b/src/backend/utils/time/test/Makefile index c501a6090e..c132e11524 100644 --- a/src/backend/utils/time/test/Makefile +++ b/src/backend/utils/time/test/Makefile @@ -9,3 +9,14 @@ include $(top_builddir)/src/backend/mock.mk sharedsnapshot.t: \ $(MOCK_DIR)/backend/storage/ipc/shmem_mock.o \ $(MOCK_DIR)/backend/storage/lmgr/lwlock_mock.o \ + $(MOCK_DIR)/backend/utils/misc/faultinjector_mock.o + +.PHONY: +%-check: %.t + $(MKDIR_P) 'base/pgsql_tmp' + ./$*.t + +.PHONY: +%-clean: + rm -rf base + rm -f $*.t $*_test.o diff --git a/src/backend/utils/time/test/sharedsnapshot_test.c b/src/backend/utils/time/test/sharedsnapshot_test.c index 9bd628b86a..dc672f2161 100644 --- a/src/backend/utils/time/test/sharedsnapshot_test.c +++ b/src/backend/utils/time/test/sharedsnapshot_test.c @@ -5,9 +5,100 @@ #include "postgres.h" #include "utils/memutils.h" +#include "utils/resowner.h" +#include "utils/faultinjector.h" +#include "utils/snapshot.h" +#include "storage/fd.h" #include "../sharedsnapshot.c" +/* + * Write shared snapshot to file using dumpSharedLocalSnapshot_forCursor() + * first. Then read the snapshot from file using + * readSharedLocalSnapshot_forCursor(). Validate that the contents read from + * the file match what was written. + */ +void +test_write_read_shared_snapshot_for_cursor(void **state) +{ +#define XCNT 5 + TransactionId xip[XCNT] = {100, 101, 103, 105, 109}; + xipEntryCount = XCNT; + + PGPROC writer_proc; + + TopTransactionResourceOwner = ResourceOwnerCreate(NULL, "unittest resource owner"); + CurrentResourceOwner = TopTransactionResourceOwner; + TopTransactionContext = CurrentMemoryContext; + + /* create a dummy shared and local snapshot with 5 in-progress transactions */ + SharedSnapshotSlot slot; + SharedLocalSnapshotSlot = &slot; + slot.slotindex = 1; + slot.slotid = 1; + slot.pid = 1000; + slot.writer_proc = &writer_proc; + slot.writer_xact = NULL; + slot.xid = 100; + slot.cid = 1; + slot.startTimestamp = 0; + slot.QDxid = 10; + slot.QDcid = 1; + slot.ready = true; + slot.segmateSync = 1; + slot.combocidcnt = 0; + slot.snapshot.xmin = 99; + slot.snapshot.xmax = 110; + slot.snapshot.xcnt = XCNT; + slot.snapshot.xip = xip; + slot.slotLock = NULL; + + /* assume the role of a writer to write the snapshot */ + Gp_role = GP_ROLE_EXECUTE; + Gp_is_writer = true; + + expect_any(LWLockAcquire, l); + expect_any(LWLockAcquire, mode); + will_be_called(LWLockAcquire); + + expect_any_count(FaultInjector_InjectFaultIfSet, faultName, 13); + expect_any_count(FaultInjector_InjectFaultIfSet, ddlStatement, 13); + expect_any_count(FaultInjector_InjectFaultIfSet, databaseName, 13); + expect_any_count(FaultInjector_InjectFaultIfSet, tableName, 13); + will_be_called_count(FaultInjector_InjectFaultIfSet, 13); + + expect_any(LWLockRelease, l); + will_be_called(LWLockRelease); + + MyProc = &writer_proc; + MyProc->pid = 1000; + + /* write the snapshot to file */ + dumpSharedLocalSnapshot_forCursor(); + + /* assume the role of a reader to read the snapshot */ + PGPROC reader_proc; + MyProc = &reader_proc; + MyProc->pid = 1234; + lockHolderProcPtr = &writer_proc; + Gp_is_writer = false; + + QEDtxContextInfo.segmateSync = slot.segmateSync; + QEDtxContextInfo.distributedXid = slot.QDxid; + QEDtxContextInfo.curcid = slot.QDcid; + + SnapshotData snapshot; + snapshot.xip = palloc(XCNT * sizeof(TransactionId)); + + /* read snapshot from the same file */ + readSharedLocalSnapshot_forCursor(&snapshot, DTX_CONTEXT_QE_READER); + + assert_true(snapshot.xcnt == XCNT); + int i; + for (i=0; i