From 81f2fed5ced8ed74517836657d15a42dd21dd4fd Mon Sep 17 00:00:00 2001
From: Dilip Kumar <dilip.kumar@enterprisedb.com>
Date: Mon, 5 Nov 2018 02:46:43 -0800
Subject: [PATCH 2/2] undo-interface-test

---
 src/test/modules/Makefile                          |  1 +
 src/test/modules/test_undo_api/Makefile            | 21 ++++++
 .../test_undo_api/expected/test_undo_api.out       | 12 ++++
 .../modules/test_undo_api/sql/test_undo_api.sql    |  8 +++
 .../modules/test_undo_api/test_undo_api--1.0.sql   |  8 +++
 src/test/modules/test_undo_api/test_undo_api.c     | 84 ++++++++++++++++++++++
 .../modules/test_undo_api/test_undo_api.control    |  4 ++
 7 files changed, 138 insertions(+)
 create mode 100644 src/test/modules/test_undo_api/Makefile
 create mode 100644 src/test/modules/test_undo_api/expected/test_undo_api.out
 create mode 100644 src/test/modules/test_undo_api/sql/test_undo_api.sql
 create mode 100644 src/test/modules/test_undo_api/test_undo_api--1.0.sql
 create mode 100644 src/test/modules/test_undo_api/test_undo_api.c
 create mode 100644 src/test/modules/test_undo_api/test_undo_api.control

diff --git a/src/test/modules/Makefile b/src/test/modules/Makefile
index 43323a6..e05fd00 100644
--- a/src/test/modules/Makefile
+++ b/src/test/modules/Makefile
@@ -19,6 +19,7 @@ SUBDIRS = \
 		  test_rls_hooks \
 		  test_shm_mq \
 		  test_undo \
+		  test_undo_api \
 		  worker_spi
 
 $(recurse)
diff --git a/src/test/modules/test_undo_api/Makefile b/src/test/modules/test_undo_api/Makefile
new file mode 100644
index 0000000..deb3816
--- /dev/null
+++ b/src/test/modules/test_undo_api/Makefile
@@ -0,0 +1,21 @@
+# src/test/modules/test_undo/Makefile
+
+MODULE_big = test_undo_api
+OBJS = test_undo_api.o
+PGFILEDESC = "test_undo_api - a test module for the undo api layer"
+
+EXTENSION = test_undo_api
+DATA = test_undo_api--1.0.sql
+
+REGRESS = test_undo_api
+
+ifdef USE_PGXS
+PG_CONFIG = pg_config
+PGXS := $(shell $(PG_CONFIG) --pgxs)
+include $(PGXS)
+else
+subdir = src/test/modules/test_undo_api
+top_builddir = ../../../..
+include $(top_builddir)/src/Makefile.global
+include $(top_srcdir)/contrib/contrib-global.mk
+endif
diff --git a/src/test/modules/test_undo_api/expected/test_undo_api.out b/src/test/modules/test_undo_api/expected/test_undo_api.out
new file mode 100644
index 0000000..995b517
--- /dev/null
+++ b/src/test/modules/test_undo_api/expected/test_undo_api.out
@@ -0,0 +1,12 @@
+CREATE EXTENSION test_undo_api;
+--
+-- This test will insert the data in the undo using undo api and after that
+-- it will fetch the data and verify that whether we have got the same data
+-- back or not.
+--
+SELECT test_undo_api(txid_current()::text::xid, 'permanent');
+ test_undo_api 
+---------------
+ 
+(1 row)
+
diff --git a/src/test/modules/test_undo_api/sql/test_undo_api.sql b/src/test/modules/test_undo_api/sql/test_undo_api.sql
new file mode 100644
index 0000000..4fb40ff
--- /dev/null
+++ b/src/test/modules/test_undo_api/sql/test_undo_api.sql
@@ -0,0 +1,8 @@
+CREATE EXTENSION test_undo_api;
+
+--
+-- This test will insert the data in the undo using undo api and after that
+-- it will fetch the data and verify that whether we have got the same data
+-- back or not.
+--
+SELECT test_undo_api(txid_current()::text::xid, 'permanent');
diff --git a/src/test/modules/test_undo_api/test_undo_api--1.0.sql b/src/test/modules/test_undo_api/test_undo_api--1.0.sql
new file mode 100644
index 0000000..3dd134b
--- /dev/null
+++ b/src/test/modules/test_undo_api/test_undo_api--1.0.sql
@@ -0,0 +1,8 @@
+\echo Use "CREATE EXTENSION test_undo_api" to load this file. \quit
+
+CREATE FUNCTION test_undo_api(xid xid, persistence text)
+RETURNS void
+AS 'MODULE_PATHNAME'
+LANGUAGE C;
+
+
diff --git a/src/test/modules/test_undo_api/test_undo_api.c b/src/test/modules/test_undo_api/test_undo_api.c
new file mode 100644
index 0000000..6026582
--- /dev/null
+++ b/src/test/modules/test_undo_api/test_undo_api.c
@@ -0,0 +1,84 @@
+#include "postgres.h"
+
+#include "access/transam.h"
+#include "access/undoinsert.h"
+#include "catalog/pg_class.h"
+#include "fmgr.h"
+#include "funcapi.h"
+#include "miscadmin.h"
+#include "pgstat.h"
+#include "storage/bufmgr.h"
+#include "utils/builtins.h"
+
+#include <stdlib.h>
+#include <unistd.h>
+
+PG_MODULE_MAGIC;
+
+PG_FUNCTION_INFO_V1(test_undo_api);
+
+static UndoPersistence
+undo_persistence_from_text(text *t)
+{
+	char *str = text_to_cstring(t);
+
+	if (strcmp(str, "permanent") == 0)
+		return UNDO_PERMANENT;
+	else if (strcmp(str, "temporary") == 0)
+		return UNDO_TEMP;
+	else if (strcmp(str, "unlogged") == 0)
+		return UNDO_UNLOGGED;
+	else
+		elog(ERROR, "unknown undo persistence level: %s", str);
+}
+
+/*
+ * Prepare and insert data in undo storage and fetch it back to verify.
+ */
+Datum
+test_undo_api(PG_FUNCTION_ARGS)
+{
+	TransactionId xid = DatumGetTransactionId(PG_GETARG_DATUM(0));
+	UndoPersistence persistence = undo_persistence_from_text(PG_GETARG_TEXT_PP(1));
+	char	*data = "test_data";
+	int		 len = strlen(data);
+	UnpackedUndoRecord	undorecord;
+	UnpackedUndoRecord *undorecord_out;
+	int	header_size = offsetof(UnpackedUndoRecord, uur_next) + sizeof(uint64);
+	UndoRecPtr	undo_ptr;
+
+	undorecord.uur_type = 0;
+	undorecord.uur_info = 0;
+	undorecord.uur_prevlen = 0;
+	undorecord.uur_prevxid = FrozenTransactionId;
+	undorecord.uur_xid = xid;
+	undorecord.uur_cid = 0;
+	undorecord.uur_tsid = 100;
+	undorecord.uur_fork = MAIN_FORKNUM;
+	undorecord.uur_blkprev = 0;
+	undorecord.uur_block = 1;
+	undorecord.uur_offset = 100;
+	initStringInfo(&undorecord.uur_tuple);
+	
+	appendBinaryStringInfo(&undorecord.uur_tuple,
+						   (char *) data,
+						   len);
+	undo_ptr = PrepareUndoInsert(&undorecord, persistence, xid, NULL);
+	InsertPreparedUndo();
+	UnlockReleaseUndoBuffers();
+	
+	undorecord_out = UndoFetchRecord(undo_ptr, InvalidBlockNumber,
+									 InvalidOffsetNumber,
+									 InvalidTransactionId, NULL,
+									 NULL);
+
+	if (strncmp((char *) &undorecord, (char *) undorecord_out, header_size) != 0)
+		elog(ERROR, "undo header did not match");
+	if (strncmp(undorecord_out->uur_tuple.data, data, len) != 0)
+		elog(ERROR, "undo data did not match");
+
+	UndoRecordRelease(undorecord_out);
+	pfree(undorecord.uur_tuple.data);
+
+	PG_RETURN_VOID();
+}
diff --git a/src/test/modules/test_undo_api/test_undo_api.control b/src/test/modules/test_undo_api/test_undo_api.control
new file mode 100644
index 0000000..09df344
--- /dev/null
+++ b/src/test/modules/test_undo_api/test_undo_api.control
@@ -0,0 +1,4 @@
+comment = 'test_undo_api'
+default_version = '1.0'
+module_pathname = '$libdir/test_undo_api'
+relocatable = true
-- 
1.8.3.1

