@@ -1172,6 +1172,179 @@ def test_external_dir_is_symlink(self):
1172
1172
# Clean after yourself
1173
1173
self .del_test_dir (module_name ,fname )
1174
1174
1175
+ # @unittest.expectedFailure
1176
+ # @unittest.skip("skip")
1177
+ def test_external_dir_contain_symlink_on_dir (self ):
1178
+ """
1179
+ Check that backup works correctly if external dir is symlink,
1180
+ symlink pointing to external dir should be followed,
1181
+ but restored as directory
1182
+ """
1183
+ fname = self .id ().split ('.' )[3 ]
1184
+ backup_dir = os .path .join (self .tmp_path ,module_name ,fname ,'backup' )
1185
+ core_dir = os .path .join (self .tmp_path ,module_name ,fname )
1186
+ shutil .rmtree (core_dir ,ignore_errors = True )
1187
+ node = self .make_simple_node (
1188
+ base_dir = os .path .join (module_name ,fname ,'node' ),
1189
+ set_replication = True ,
1190
+ initdb_params = ['--data-checksums' ])
1191
+
1192
+ self .init_pb (backup_dir )
1193
+ self .add_instance (backup_dir ,'node' ,node )
1194
+ node .slow_start ()
1195
+
1196
+ external_dir = self .get_tblspace_path (node ,'external_dir' )
1197
+ dir_in_external_dir = os .path .join (external_dir ,'dir' )
1198
+
1199
+ node .pgbench_init (scale = 3 )
1200
+
1201
+ # temp FULL backup
1202
+ backup_id = self .backup_node (
1203
+ backup_dir ,'node' ,node ,options = ["-j" ,"4" ,"--stream" ])
1204
+
1205
+ # fill some directory with data
1206
+ core_dir = os .path .join (self .tmp_path ,module_name ,fname )
1207
+ symlinked_dir = os .path .join (core_dir ,'symlinked' )
1208
+
1209
+ self .restore_node (
1210
+ backup_dir ,'node' ,node ,
1211
+ data_dir = symlinked_dir ,options = ["-j" ,"4" ])
1212
+
1213
+ # drop temp FULL backup
1214
+ self .delete_pb (backup_dir ,'node' ,backup_id = backup_id )
1215
+
1216
+ # create symlink to directory in external directory
1217
+ print (symlinked_dir )
1218
+ print (dir_in_external_dir )
1219
+ os .mkdir (external_dir )
1220
+ os .symlink (symlinked_dir ,dir_in_external_dir )
1221
+
1222
+ # FULL backup with external directories
1223
+ backup_id = self .backup_node (
1224
+ backup_dir ,'node' ,node ,
1225
+ options = [
1226
+ "-j" ,"4" ,"--stream" ,
1227
+ "-E" ,"{0}" .format (
1228
+ external_dir )])
1229
+
1230
+ pgdata = self .pgdata_content (
1231
+ node .base_dir ,exclude_dirs = ['logs' ])
1232
+
1233
+ node_restored = self .make_simple_node (
1234
+ base_dir = os .path .join (module_name ,fname ,'node_restored' ))
1235
+
1236
+ # RESTORE
1237
+ node_restored .cleanup ()
1238
+
1239
+ external_dir_new = self .get_tblspace_path (
1240
+ node_restored ,'external_dir' )
1241
+
1242
+ self .restore_node (
1243
+ backup_dir ,'node' ,node_restored ,
1244
+ options = [
1245
+ "-j" ,"4" ,"--external-mapping={0}={1}" .format (
1246
+ external_dir ,external_dir_new )])
1247
+
1248
+ pgdata_restored = self .pgdata_content (
1249
+ node_restored .base_dir ,exclude_dirs = ['logs' ])
1250
+
1251
+ self .compare_pgdata (pgdata ,pgdata_restored )
1252
+
1253
+ self .assertEqual (
1254
+ external_dir ,
1255
+ self .show_pb (
1256
+ backup_dir ,'node' ,
1257
+ backup_id = backup_id )['external-dirs' ])
1258
+
1259
+ # Clean after yourself
1260
+ self .del_test_dir (module_name ,fname )
1261
+
1262
+ # @unittest.expectedFailure
1263
+ # @unittest.skip("skip")
1264
+ def test_external_dir_contain_symlink_on_file (self ):
1265
+ """
1266
+ Check that backup works correctly if external dir is symlink,
1267
+ symlink pointing to external dir should be followed,
1268
+ but restored as directory
1269
+ """
1270
+ fname = self .id ().split ('.' )[3 ]
1271
+ backup_dir = os .path .join (self .tmp_path ,module_name ,fname ,'backup' )
1272
+ core_dir = os .path .join (self .tmp_path ,module_name ,fname )
1273
+ shutil .rmtree (core_dir ,ignore_errors = True )
1274
+ node = self .make_simple_node (
1275
+ base_dir = os .path .join (module_name ,fname ,'node' ),
1276
+ set_replication = True ,
1277
+ initdb_params = ['--data-checksums' ])
1278
+
1279
+ self .init_pb (backup_dir )
1280
+ self .add_instance (backup_dir ,'node' ,node )
1281
+ node .slow_start ()
1282
+
1283
+ external_dir = self .get_tblspace_path (node ,'external_dir' )
1284
+ file_in_external_dir = os .path .join (external_dir ,'file' )
1285
+
1286
+ node .pgbench_init (scale = 3 )
1287
+
1288
+ # temp FULL backup
1289
+ backup_id = self .backup_node (
1290
+ backup_dir ,'node' ,node ,options = ["-j" ,"4" ,"--stream" ])
1291
+
1292
+ # fill some directory with data
1293
+ core_dir = os .path .join (self .tmp_path ,module_name ,fname )
1294
+ symlinked_dir = os .path .join (core_dir ,'symlinked' )
1295
+
1296
+ self .restore_node (
1297
+ backup_dir ,'node' ,node ,
1298
+ data_dir = symlinked_dir ,options = ["-j" ,"4" ])
1299
+
1300
+ # drop temp FULL backup
1301
+ self .delete_pb (backup_dir ,'node' ,backup_id = backup_id )
1302
+
1303
+ # create symlink to directory in external directory
1304
+ src_file = os .path .join (symlinked_dir ,'postgresql.conf' )
1305
+ os .mkdir (external_dir )
1306
+ os .symlink (src_file ,file_in_external_dir )
1307
+
1308
+ # FULL backup with external directories
1309
+ backup_id = self .backup_node (
1310
+ backup_dir ,'node' ,node ,
1311
+ options = [
1312
+ "-j" ,"4" ,"--stream" ,
1313
+ "-E" ,"{0}" .format (
1314
+ external_dir )])
1315
+
1316
+ pgdata = self .pgdata_content (
1317
+ node .base_dir ,exclude_dirs = ['logs' ])
1318
+
1319
+ node_restored = self .make_simple_node (
1320
+ base_dir = os .path .join (module_name ,fname ,'node_restored' ))
1321
+
1322
+ # RESTORE
1323
+ node_restored .cleanup ()
1324
+
1325
+ external_dir_new = self .get_tblspace_path (
1326
+ node_restored ,'external_dir' )
1327
+
1328
+ self .restore_node (
1329
+ backup_dir ,'node' ,node_restored ,
1330
+ options = [
1331
+ "-j" ,"4" ,"--external-mapping={0}={1}" .format (
1332
+ external_dir ,external_dir_new )])
1333
+
1334
+ pgdata_restored = self .pgdata_content (
1335
+ node_restored .base_dir ,exclude_dirs = ['logs' ])
1336
+
1337
+ self .compare_pgdata (pgdata ,pgdata_restored )
1338
+
1339
+ self .assertEqual (
1340
+ external_dir ,
1341
+ self .show_pb (
1342
+ backup_dir ,'node' ,
1343
+ backup_id = backup_id )['external-dirs' ])
1344
+
1345
+ # Clean after yourself
1346
+ self .del_test_dir (module_name ,fname )
1347
+
1175
1348
# @unittest.expectedFailure
1176
1349
# @unittest.skip("skip")
1177
1350
def test_external_dir_is_tablespace (self ):