1212import os
1313
1414
15+ def test_fdw (func ):
16+ """To run tests with FDW support set environment variable TEST_FDW=1"""
17+ def wrapper (* args ,** kwargs ):
18+ if os .environ .get ('TEST_FDW' ):
19+ func (* args ,** kwargs )
20+ else :
21+ print ('Warning: FDW features tests are disabled, skipping...' )
22+ return wrapper
23+
24+
1525class PartitioningTests (unittest .TestCase ):
1626
1727def setUp (self ):
1828self .setup_cmd = [
19- 'create extension pg_pathman' ,
29+ # 'create extension pg_pathman',
2030'create table abc(id serial, t text)' ,
2131'insert into abc select generate_series(1, 300000)' ,
2232'select create_hash_partitions(\' abc\' ,\' id\' , 3, partition_data := false)' ,
@@ -26,6 +36,16 @@ def tearDown(self):
2636stop_all ()
2737# clean_all()
2838
39+ def start_new_pathman_cluster (self ,name = 'test' ,allows_streaming = False ):
40+ node = get_new_node (name )
41+ node .init (allows_streaming = allows_streaming )
42+ node .append_conf (
43+ 'postgresql.conf' ,
44+ 'shared_preload_libraries=\' pg_pathman\' \n ' )
45+ node .start ()
46+ node .psql ('postgres' ,'create extension pg_pathman' )
47+ return node
48+
2949def init_test_data (self ,node ):
3050"""Initialize pg_pathman extension and test data"""
3151for cmd in self .setup_cmd :
@@ -42,17 +62,12 @@ def catchup_replica(self, master, replica):
4262def printlog (self ,logfile ):
4363with open (logfile ,'r' )as log :
4464for line in log .readlines ():
45- print line
65+ print ( line )
4666
4767def test_concurrent (self ):
4868"""Tests concurrent partitioning"""
49- node = get_new_node ('test' )
5069try :
51- node .init ()
52- node .append_conf (
53- 'postgresql.conf' ,
54- 'shared_preload_libraries=\' pg_pathman\' \n ' )
55- node .start ()
70+ node = self .start_new_pathman_cluster ()
5671self .init_test_data (node )
5772
5873node .psql (
@@ -95,11 +110,7 @@ def test_replication(self):
95110
96111try :
97112# initialize master server
98- node .init (allows_streaming = True )
99- node .append_conf (
100- 'postgresql.conf' ,
101- 'shared_preload_libraries=\' pg_pathman\' \n ' )
102- node .start ()
113+ node = self .start_new_pathman_cluster (allows_streaming = True )
103114node .backup ('my_backup' )
104115
105116# initialize replica from backup
@@ -238,8 +249,8 @@ def add_partition(node, flag, query):
238249con .commit ()
239250
240251# Now wait until each thread finishes
241- for i in range ( 3 ) :
242- threads [ i ] .join ()
252+ for thread in threads :
253+ thread .join ()
243254
244255# Check flags, it should be true which means that threads are
245256# finished
@@ -277,11 +288,11 @@ def check_tablespace(node, tablename, tablespace):
277288'postgresql.conf' ,
278289'shared_preload_libraries=\' pg_pathman\' \n ' )
279290node .start ()
280- path = os .path .join (node .data_dir ,'test_space_location' )
281- os .mkdir (path )
282291node .psql ('postgres' ,'create extension pg_pathman' )
283292
284293# create tablespace
294+ path = os .path .join (node .data_dir ,'test_space_location' )
295+ os .mkdir (path )
285296node .psql (
286297'postgres' ,
287298'create tablespace test_space location\' {}\' ' .format (path ))
@@ -330,6 +341,71 @@ def check_tablespace(node, tablename, tablespace):
330341self .assertTrue (check_tablespace (node ,'abc_prepended_2' ,'pg_default' ))
331342self .assertTrue (check_tablespace (node ,'abc_added_2' ,'pg_default' ))
332343
344+ @test_fdw
345+ def test_foreign_table (self ):
346+ """Test foreign tables"""
347+
348+ # Start master server
349+ master = get_new_node ('test' )
350+ master .init ()
351+ master .append_conf (
352+ 'postgresql.conf' ,
353+ 'shared_preload_libraries=\' pg_pathman, postgres_fdw\' \n ' )
354+ master .start ()
355+ master .psql ('postgres' ,'create extension pg_pathman' )
356+ master .psql ('postgres' ,'create extension postgres_fdw' )
357+ master .psql (
358+ 'postgres' ,
359+ '''create table abc(id serial, name text);
360+ select create_range_partitions('abc', 'id', 0, 10, 2)''' )
361+
362+ # Current user name (needed for user mapping)
363+ username = master .execute ('postgres' ,'select current_user' )[0 ][0 ]
364+
365+ # Start foreign server
366+ fserv = get_new_node ('fserv' )
367+ fserv .init ().start ()
368+ fserv .safe_psql ('postgres' ,'create table ftable(id serial, name text)' )
369+ fserv .safe_psql ('postgres' ,'insert into ftable values (25,\' foreign\' )' )
370+
371+ # Create foreign table and attach it to partitioned table
372+ master .safe_psql (
373+ 'postgres' ,
374+ '''create server fserv
375+ foreign data wrapper postgres_fdw
376+ options (dbname 'postgres', host '127.0.0.1', port '{}')''' .format (fserv .port )
377+ )
378+ master .safe_psql (
379+ 'postgres' ,
380+ '''create user mapping for {0}
381+ server fserv
382+ options (user '{0}')''' .format (username )
383+ )
384+ master .safe_psql (
385+ 'postgres' ,
386+ '''import foreign schema public limit to (ftable)
387+ from server fserv into public'''
388+ )
389+ master .safe_psql (
390+ 'postgres' ,
391+ 'select attach_range_partition(\' abc\' ,\' ftable\' , 20, 30)' )
392+
393+ # Check that table attached to partitioned table
394+ self .assertEqual (
395+ master .safe_psql ('postgres' ,'select * from ftable' ),
396+ '25|foreign\n '
397+ )
398+
399+ # Check that we can successfully insert new data into foreign partition
400+ master .safe_psql ('postgres' ,'insert into abc values (26,\' part\' )' )
401+ self .assertEqual (
402+ master .safe_psql ('postgres' ,'select * from ftable order by id' ),
403+ '25|foreign\n 26|part\n '
404+ )
405+
406+ # Testing drop partitions (including foreign partitions)
407+ master .safe_psql ('postgres' ,'select drop_partitions(\' abc\' )' )
408+
333409
334410if __name__ == "__main__" :
335411unittest .main ()