Skip to content
Draft
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
34 changes: 34 additions & 0 deletions Makefile.mock
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
MOCK_DIR=unit/mock
CMOCKERY_DIR=unit/cmockery
CMOCKERY_OBJS=$(CMOCKERY_DIR)/cmockery.o
override CFLAGS+=$(PTHREAD_CFLAGS)

override CPPFLAGS+= -I$(CMOCKERY_DIR)

$(MOCK_DIR)/%_mock.c: $(abs_top_srcdir)/src/%.c
@echo mocking $<
PYTHONPATH=$(python_libdir) $(MOCK_DIR)/mocker.py $<

# For some reason, mock.o files are intermediate files sometimes.
# Mark them as secondary in order not to be deleted automatically.
.SECONDARY:
$(MOCK_DIR)/%_mock.o: CFLAGS+= -Wno-unused-function -Wno-unused-variable
$(MOCK_DIR)/%_mock.o: $(MOCK_DIR)/%_mock.c


all: $(patsubst %,%.t,$(TARGETS))


.PHONY:
check: $(patsubst %,%-check,$(TARGETS))

.PHONY:
%-check: %.t
./$*.t

.PHONY:
clean: $(patsubst %,%-clean,$(TARGETS))

.PHONY:
%-clean:
rm -f $*.t $*_test.o
30 changes: 21 additions & 9 deletions external-table/test/Makefile
Original file line number Diff line number Diff line change
@@ -1,16 +1,28 @@
subdir=gpcontrib/pxf
top_builddir=../../..
include $(top_builddir)/src/Makefile.global
PG_CONFIG ?= pg_config
PGXS := $(shell $(PG_CONFIG) --pgxs)
ifndef PGXS
$(error Make sure the Greenplum installation binaries are in your PATH. i.e. export PATH=<path to your Greenplum installation>/bin:$$PATH)
endif
# include $(PGXS)

TARGETS= libchurl pxfprotocol pxfbridge pxfheaders pxfuriparser pxfutils pxffragment pxffilters
subdir=external-table/test
top_builddir=$(GPHOME)/lib/postgresql/pgxs
include $(top_builddir)/src/Makefile.global

include $(top_builddir)/src/backend/mock.mk
PXF_API_VERSION := $(shell cat ../../api_version)
CFLAGS += -DPXF_API_VERSION=\"$(PXF_API_VERSION)\"

pxfheaders.t: $(MOCK_DIR)/backend/access/external/fileam_mock.o $(MOCK_DIR)/backend/catalog/pg_exttable_mock.o
LD_FLAGS += postgres

pxffragment.t: $(MOCK_DIR)/backend/cdb/cdbtm_mock.o $(top_builddir)/src/backend/utils/adt/json.o $(MOCK_DIR)/backend/cdb/cdbutil_mock.o
# The test target depends on $(OBJFILES) which would update files including mocks.
%.t: $(OBJFILES) $(CMOCKERY_OBJS) $(MOCK_OBJS) %_test.o
$(CXX) $(CFLAGS) $(LDFLAGS) \
$(call WRAP_FUNCS, $*_test.c) $(call BACKEND_OBJS, $(top_srcdir)/$(subdir)/$*.o $(patsubst $(MOCK_DIR)/%_mock.o,$(top_builddir)/src/%.o, $^)) \
$(filter-out %/objfiles.txt, $^) \
$(OBJFILES) $(CMOCKERY_OBJS) $(MOCK_OBJS) \
$(MOCK_LIBS) -o $@

TARGETS= libchurl pxfprotocol pxfbridge pxfheaders pxfuriparser pxfutils pxffilters

pxfbridge.t: $(MOCK_DIR)/backend/cdb/cdbtm_mock.o
include mock.mk

pxffilters.t: $(MOCK_DIR)/backend/utils/cache/lsyscache_mock.o $(MOCK_DIR)/backend/utils/fmgr/fmgr_mock.o $(MOCK_DIR)/backend/utils/adt/arrayfuncs_mock.o
12 changes: 9 additions & 3 deletions external-table/test/libchurl_test.c
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,12 @@

/* include mock files */
#include "mock/curl_mock.c"
#include "mock/pg_mock.c"
#include "mock/pg_json_mock.c"
#include "mock/pg_cache_mock.c"
#include "mock/pg_formatting_mock.c"
#include "mock/pg_memutils_mock.c"
#include "mock/pg_resowner_mock.c"

/* test strings */
const char *uri_param = "pxf://localhost:5888/tmp/dummy1";
Expand Down Expand Up @@ -271,9 +277,9 @@ main(int argc, char *argv[])

const UnitTest tests[] = {
unit_test(test_set_curl_option),
unit_test(test_churl_init_upload),
unit_test(test_churl_init_download),
unit_test(test_churl_read)
// unit_test(test_churl_init_upload),
// unit_test(test_churl_init_download),
// unit_test(test_churl_read)
};

MemoryContextInit();
Expand Down
132 changes: 132 additions & 0 deletions external-table/test/mock.mk
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
#
# Rules for backend mock test programs.
#
# We have a mechanism where every test program is automatically linked with
# mock versions of every backend file, except for those listed in
# <testname>_REAL_OBJS variable.

include ../../Makefile.mock

override CPPFLAGS+= -I$(top_srcdir)/src/backend/libpq \
-I$(libpq_srcdir) \
-I$(top_srcdir)/src/backend/postmaster \
-I. -I$(top_builddir)/src/port \
-DDLSUFFIX=$(DLSUFFIX) \
-I$(top_srcdir)/src/backend/utils/stat

# TODO: add ldl for quick hack; we need to figure out why
# postgres in src/backend/Makefile doesn't need this and -pthread.
MOCK_LIBS := -ldl $(filter-out -ledit, $(LIBS)) $(LDAP_LIBS_BE)

# These files are not linked into test programs.
EXCL_OBJS=\
src/backend/main/main.o \
src/backend/access/transam/rmgr.o \
src/backend/utils/fmgrtab.o \
src/backend/gpopt/%.o \
src/backend/gpopt/config/%.o \
src/backend/gpopt/relcache/%.o \
src/backend/gpopt/translate/%.o \
src/backend/gpopt/utils/%.o \

# More files that are not linked into test programs. There's no particular
# reason these couldn't be linked into, if necessary, but currently none of
# the tests need these, so better to leave them out to cut down on the size
# of the test programs. Feel free to link them back (i.e. remove them from
# this exclusion list) as needed.
EXCL_OBJS+=\
src/backend/access/hash/hash.o \
src/backend/access/hash/hashsearch.o \
\
src/backend/utils/adt/cash.o \
src/backend/utils/adt/char.o \
src/backend/utils/adt/complex_type.o \
src/backend/utils/adt/enum.o \
src/backend/utils/adt/geo_selfuncs.o \
src/backend/utils/adt/gp_optimizer_functions.o \
src/backend/utils/adt/interpolate.o \
src/backend/utils/adt/jsonfuncs.o \
src/backend/utils/adt/like.o \
src/backend/utils/adt/like_match.o \
src/backend/utils/adt/lockfuncs.o \
src/backend/utils/adt/mac.o \
src/backend/utils/adt/matrix.o \
src/backend/utils/adt/oracle_compat.o \
src/backend/utils/adt/pgstatfuncs.o \
src/backend/utils/adt/pivot.o \
src/backend/utils/adt/pseudotypes.o \
src/backend/utils/adt/rowtypes.o \
src/backend/utils/adt/tsginidx.o \
src/backend/utils/adt/tsgistidx.o \
src/backend/utils/adt/tsquery.o \
src/backend/utils/adt/tsquery_cleanup.o \
src/backend/utils/adt/tsquery_gist.o \
src/backend/utils/adt/tsquery_op.o \
src/backend/utils/adt/tsquery_rewrite.o \
src/backend/utils/adt/tsquery_util.o \
src/backend/utils/adt/tsrank.o \
src/backend/utils/adt/tsvector.o \
src/backend/utils/adt/tsvector_op.o \
src/backend/utils/adt/tsvector_parser.o \
src/backend/utils/adt/txid.o \
src/backend/utils/adt/uuid.o \
src/backend/tsearch/dict.o \
src/backend/tsearch/dict_ispell.o \
src/backend/tsearch/dict_simple.o \
src/backend/tsearch/dict_synonym.o \
src/backend/tsearch/dict_thesaurus.o \
src/backend/tsearch/regis.o \
src/backend/tsearch/spell.o \
src/backend/tsearch/to_tsany.o \
src/backend/tsearch/ts_locale.o \
src/backend/tsearch/ts_parse.o \
src/backend/tsearch/ts_utils.o \
src/backend/tsearch/wparser.o \
src/backend/tsearch/wparser_def.o \

# These files are linked into every test program.
MOCK_OBJS=\
unit/mock/fmgrtab_mock.o \
unit/mock/rmgr_mock.o \
unit/mock/main_mock.o
# No test programs currently exercise the ORCA translator library, so
# mock that instead of linking with the real library.
# ifeq ($(enable_orca),yes)
# # MOCK_OBJS+=unit/mock/gpopt_mock.o
# endif

# $(OBJFILES) contains %/objfiles.txt, because src/backend/Makefile will
# create it with rule=objfiles.txt, which is not expected in postgres rule.
# It actually uses expand_subsys to obtain the .o file list. But here we
# don't include common.mk so just clear out objfiles.txt from the list for
# $(TARGET_OBJS)
# OBJFILES=$(top_srcdir)/src/backend/objfiles.txt
# OBJFILES=
# ALL_OBJS=$(addprefix $(top_srcdir)/, \
# # $(filter-out $(EXCL_OBJS) %/objfiles.txt, \
# $(shell test -f $(OBJFILES) && cat $(OBJFILES))))

# A function that generates a list of backend .o files that should be included
# in a test program.
#
# The argument is a list of backend object files that should *not* be included
BACKEND_OBJS=$(filter-out $(1), $(ALL_OBJS))

# If we are using linker's wrap feature in unit test, add wrap flags for
# those mocked functions
WRAP_FLAGS=-Wl,--wrap=
WRAP_SED_REGEXP='s/.*__wrap_\(\w*\)(.*/\1/p'
WRAP_FUNCS=$(addprefix $(WRAP_FLAGS), \
$(sort $(shell sed -n $(WRAP_SED_REGEXP) $(1))))

# The test target depends on $(OBJFILES) which would update files including mocks.
# %.t: $(OBJFILES) $(CMOCKERY_OBJS) $(MOCK_OBJS) %_test.o
# $(CXX) $(CFLAGS) $(LDFLAGS) $(call WRAP_FUNCS, $(top_srcdir)/$(subdir)/test/$*_test.c) $(call BACKEND_OBJS, $(top_srcdir)/$(subdir)/$*.o $(patsubst $(MOCK_DIR)/%_mock.o,$(top_builddir)/src/%.o, $^)) $(filter-out %/objfiles.txt, $^) $(MOCK_LIBS) -o $@

# We'd like to call only src/backend, but it seems we should build src/port and
# src/timezone before src/backend. This is not the case when main build has finished,
# but this makes sure a simple make works fine in this directory any time.
# With PARTIAL_LINKING it will generate objfiles.txt
$(OBJFILES): $(ALL_OBJS)
$(MAKE) -C $(top_srcdir)/src
$(MAKE) PARTIAL_LINKING= -C $(top_srcdir)/src/backend objfiles.txt
23 changes: 16 additions & 7 deletions external-table/test/mock/libchurl_mock.c
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,22 @@ churl_init_upload(const char* url, CHURL_HEADERS headers)
return (CHURL_HANDLE) mock();
}

CHURL_HANDLE
churl_init_upload_timeout(const char *url, CHURL_HEADERS headers, long timeout)
{
check_expected(url);
check_expected(headers);
check_expected(timeout);
return (CHURL_HANDLE) mock();
}

int
churl_get_local_port(CHURL_HANDLE handle)
{
check_expected(handle);
return (int)mock();
}

CHURL_HANDLE
churl_init_download(const char* url, CHURL_HEADERS headers)
{
Expand Down Expand Up @@ -96,10 +112,3 @@ churl_cleanup(CHURL_HANDLE handle, bool after_error)
check_expected(after_error);
mock();
}

void
print_http_headers(CHURL_HEADERS headers)
{
check_expected(headers);
mock();
}
7 changes: 7 additions & 0 deletions external-table/test/mock/pg_array_mock.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
void
deconstruct_array(ArrayType *array,
Oid elmtype,
int elmlen, bool elmbyval, char elmalign,
Datum **elemsp, bool **nullsp, int *nelemsp)
{
}
16 changes: 16 additions & 0 deletions external-table/test/mock/pg_bitmapset_mock.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
Bitmapset *
bms_add_member(Bitmapset *a, int x)
{
return NULL;
}

bool
bms_is_member(int x, const Bitmapset *a)
{
return false;
}

void
bms_free(Bitmapset *a)
{
}
22 changes: 22 additions & 0 deletions external-table/test/mock/pg_cache_mock.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
HeapTuple
SearchSysCache(int cacheId,
Datum key1,
Datum key2,
Datum key3,
Datum key4)
{
return NULL;
}

void
ReleaseSysCache(HeapTuple tuple)
{
}

Datum
SysCacheGetAttr(int cacheId, HeapTuple tup,
AttrNumber attributeNumber,
bool *isNull)
{
return 0;
}
5 changes: 5 additions & 0 deletions external-table/test/mock/pg_exttable_mock.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
ExtTableEntry*
GetExtTableEntry(Oid relid)
{
return NULL;
}
55 changes: 55 additions & 0 deletions external-table/test/mock/pg_fileam_mock.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
List *
parseCopyFormatString(Relation rel, char *fmtstr, char fmttype)
{
return NULL;
}

void
external_set_env_vars(extvar_t *extvar, char *uri, bool csv, char *escape, char *quote, bool header, uint32 scancounter)
{

}

/*
The following is from different places, but to used together with above functions,
To keep file smaller put it there.
*/

/* lmgr/proc.c */
PGPROC *MyProc = NULL;

/* defrem */
char *
defGetString(DefElem *def)
{
return NULL;
}

DefElem *
makeDefElem(char *name, Node *arg)
{
return NULL;
}

/* nodefuncs */
bool
expression_tree_walker(Node *node,
bool (*walker) (),
void *context)
{
return false;
}

/* mbutils */
const char *
GetDatabaseEncodingName(void)
{
return NULL;
}

const char *
pg_encoding_to_char(int encoding)
{
return NULL;
}

5 changes: 5 additions & 0 deletions external-table/test/mock/pg_fmgr_mock.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
char *
OidOutputFunctionCall(Oid functionId, Datum val)
{
return NULL;
}
5 changes: 5 additions & 0 deletions external-table/test/mock/pg_formatting_mock.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
char *
asc_toupper(const char *buff, size_t nbytes)
{
return NULL;
}
5 changes: 5 additions & 0 deletions external-table/test/mock/pg_gpid_mock.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
#if !defined(UNINITIALIZED_GP_IDENTITY_VALUE)
#define UNINITIALIZED_GP_IDENTITY_VALUE (-10000)
#endif

GpId GpIdentity = {UNINITIALIZED_GP_IDENTITY_VALUE, UNINITIALIZED_GP_IDENTITY_VALUE};
Loading