2021-04-26 20:07:00 +02:00
#coding:utf-8
2022-01-23 20:41:55 +01:00
"""
ID : issue - 4782
ISSUE : 4782
TITLE : Make it possible to restore compressed . nbk files without explicitly decompressing them
DESCRIPTION :
Test uses three preliminarily created . zip files :
1. 7 zip - standalone - binary . zip - - contains standalone console utility 7 za . exe
2. zstd - standalone - binary . zip - - contains standalone console utility zstd . exe
3. standard_sample_databases . zip - - contains SQL statements for Firebird EMPLOYEE and Oracle " HR " schema .
We extract files from all of these . zip archives and do following :
* apply Firebird SQL script which creates the same DB as standard EMPLOYEE ;
* invoke " nbackup -b 0 ... " and use Python PIPE mechanism for redirecting STDOUT to 7 za . exe utility which ,
in turn , will accept data from this stream and compress them to .7 z file .
This eventually creates .7 z file with compressed . nbk0 file .
* apply SQL script from Oracle " HR " schema which adds several other tables and data ;
* invoke " nbackup -b 1 ... " and use again Python PIPE mechanism for redirecting STDOUT to 7 za . exe utility .
This will create one more .7 z file with compressed . nbk1 file .
* invoke " nbackup -decompress ... " with specifying command for running 7 za . exe which will extract every file
from those which are specified in the command , i . e :
nbackup - decompress " c: \\ path \\ 7za.exe x -y " < fdb_for_restoring > < compressed_7z_with_nbk0 > < compressed_7z_with_nbk1 >
* validate just restored database and check content of firebird . log : it should NOT contain any errors or warnings .
: : : NB : : :
This is * initial * implementation ! We use trivial database with ascii - only metadata and data .
Also , we use only 7 za . exe compressor and zstd . exe is not yet used .
Later this test may be expanded for check non - ascii metadata and / or data .
JIRA : CORE - 4462
2022-02-02 15:46:19 +01:00
FBTEST : bugs . core_4462
2022-01-23 20:41:55 +01:00
"""
2021-04-26 20:07:00 +02:00
import pytest
2022-01-23 20:41:55 +01:00
from firebird . qa import *
2021-04-26 20:07:00 +02:00
2022-01-23 20:41:55 +01:00
db = db_factory ( charset = ' UTF8 ' )
2021-04-26 20:07:00 +02:00
2022-01-23 20:41:55 +01:00
act = python_act ( ' db ' )
2021-04-26 20:07:00 +02:00
2022-01-23 20:41:55 +01:00
expected_stdout_1 = """
+ VALIDATION STARTED
+ VALIDATION FINISHED : 0 ERRORS , 0 WARNINGS , 0 FIXED
"""
2021-04-26 20:07:00 +02:00
2022-01-25 22:55:48 +01:00
@pytest.mark.skip ( ' FIXME: Not IMPLEMENTED ' )
2022-01-23 20:41:55 +01:00
@pytest.mark.version ( ' >=3.0.5 ' )
@pytest.mark.platform ( ' Windows ' )
def test_1 ( act : Action ) :
# This test should be reimplemnted in platform independent way!
2022-01-25 22:55:48 +01:00
pytest . fail ( " Not IMPLEMENTED " )
2021-04-26 20:07:00 +02:00
# test_script_1
#---
2021-12-15 22:02:07 +01:00
#
2021-04-26 20:07:00 +02:00
# import os
# import sys
# import zipfile
# import time
# import re
# import difflib
# import subprocess
# from subprocess import PIPE
# from fdb import services
2021-12-15 22:02:07 +01:00
#
2021-04-26 20:07:00 +02:00
# os.environ["ISC_USER"] = user_name
# os.environ["ISC_PASSWORD"] = user_password
2021-12-15 22:02:07 +01:00
#
2021-04-26 20:07:00 +02:00
# #--------------------------------------------
2021-12-15 22:02:07 +01:00
#
2021-04-26 20:07:00 +02:00
# def svc_get_fb_log( fb_home, f_fb_log ):
2021-12-15 22:02:07 +01:00
#
2021-04-26 20:07:00 +02:00
# global subprocess
# subprocess.call( [ fb_home + "fbsvcmgr",
# "localhost:service_mgr",
# "action_get_fb_log"
# ],
# stdout=f_fb_log, stderr=subprocess.STDOUT
# )
# return
2021-12-15 22:02:07 +01:00
#
2021-04-26 20:07:00 +02:00
# #--------------------------------------------
# def cleanup( f_names_list ):
# global os
# for i in range(len( f_names_list )):
# if os.path.isfile( f_names_list[i]):
# os.remove( f_names_list[i] )
# #--------------------------------------------
2021-12-15 22:02:07 +01:00
#
2021-04-26 20:07:00 +02:00
# fb_home = services.connect(host='localhost', user= user_name, password= user_password).get_home_directory()
# this_db = db_conn.database_name
2021-12-15 22:02:07 +01:00
#
2021-04-26 20:07:00 +02:00
# fdb_for_restore = os.path.join(context['temp_directory'],'tmp_4462_restored.fdb')
# nbk0_name = '.'.join( (os.path.splitext( this_db )[0], 'nbk0') )
# nbk1_name = '.'.join( (os.path.splitext( this_db )[0], 'nbk1') )
# zip0_name = nbk0_name + '.7z'
# zip1_name = nbk1_name + '.7z'
2021-12-15 22:02:07 +01:00
#
2021-04-26 20:07:00 +02:00
# f_list = ( fdb_for_restore, nbk0_name, nbk1_name, zip0_name, zip1_name )
# cleanup( f_list )
2021-12-15 22:02:07 +01:00
#
2021-04-26 20:07:00 +02:00
# db_conn.close()
2021-12-15 22:02:07 +01:00
#
2021-04-26 20:07:00 +02:00
# for z in ( '7zip-standalone-binary.zip', 'zstd-standalone-binary.zip', 'standard_sample_databases.zip'):
# zf = zipfile.ZipFile( os.path.join(context['files_location'], z ) )
# zf.extractall( context['temp_directory'] )
# zf.close()
2021-12-15 22:02:07 +01:00
# # Result: scripts sample-DB_-_firebird.sql, sample-DB_-_oracle.sql and
2021-04-26 20:07:00 +02:00
# # standalone binaries for 7-zip and zstd have been extracted into context['temp_directory']
2021-12-15 22:02:07 +01:00
#
2021-04-26 20:07:00 +02:00
# p7z_exe = os.path.join(context['temp_directory'],'7za.exe')
# zstd_exe = os.path.join(context['temp_directory'],'zstd.exe')
2021-12-15 22:02:07 +01:00
#
2021-04-26 20:07:00 +02:00
# ################################################################################################################
2021-12-15 22:02:07 +01:00
#
2021-04-26 20:07:00 +02:00
# f_sql_log=open( os.path.join(context['temp_directory'],'tmp_4462_init.log'), 'w', buffering = 0)
# subprocess.call( [ fb_home + 'isql', dsn, '-i', os.path.join(context['temp_directory'],'sample-DB_-_firebird.sql') ], stdout = f_sql_log, stderr = subprocess.STDOUT)
# f_sql_log.close()
2021-12-15 22:02:07 +01:00
#
2021-04-26 20:07:00 +02:00
# # https://docs.python.org/2/library/subprocess.html#replacing-shell-pipeline
# # output=`dmesg | grep hda`
# # becomes:
# # p1 = Popen(["dmesg"], stdout=PIPE)
# # p2 = Popen(["grep", "hda"], stdin=p1.stdout, stdout=PIPE)
# # p1.stdout.close() # Allow p1 to receive a SIGPIPE if p2 exits.
# # output = p2.communicate()[0]
2021-12-15 22:02:07 +01:00
#
2022-01-23 20:41:55 +01:00
# # nbackup.exe -b 0 employee stdout | 7za u -siemployee.nbk0 C:\\FB\\SS\\employee.nbk0.7z
2021-12-15 22:02:07 +01:00
#
2021-04-26 20:07:00 +02:00
# p_sender = subprocess.Popen( [ fb_home+'nbackup', '-b', '0', this_db, 'stdout' ], stdout=PIPE)
# p_getter = subprocess.Popen( [ os.path.join(context['temp_directory'],'7za.exe'), 'u', '-bb3', '-bt', '-bse2', '-si' + os.path.split(nbk0_name)[1], zip0_name ], stdin = p_sender.stdout, stdout = PIPE )
# p_sender.stdout.close()
# p_getter_stdout, p_getter_stderr = p_getter.communicate()
2021-12-15 22:02:07 +01:00
#
2021-04-26 20:07:00 +02:00
# # result: file with name = %FBT_REPO% mp\\BUGS.CORE_4462.nbk0.7z must be created at this point
2021-12-15 22:02:07 +01:00
#
2021-04-26 20:07:00 +02:00
# f_nbk0_to_7z_log = open( os.path.join(context['temp_directory'],'tmp_4462_nbk0_to_7z.log'), 'w', buffering = 0)
# f_nbk0_to_7z_log.write( p_getter_stdout if p_getter_stdout else '' )
# f_nbk0_to_7z_log.write( p_getter_stderr if p_getter_stderr else '' )
# f_nbk0_to_7z_log.close()
2021-12-15 22:02:07 +01:00
#
2021-04-26 20:07:00 +02:00
# ################################################################################################################
2021-12-15 22:02:07 +01:00
#
2021-04-26 20:07:00 +02:00
# f_sql_log=open( os.path.join(context['temp_directory'],'tmp_4462_init.log'), 'a', buffering = 0)
# subprocess.call( [ fb_home + 'isql', dsn, '-i', os.path.join(context['temp_directory'],'sample-DB_-_oracle.sql') ], stdout = f_sql_log, stderr = subprocess.STDOUT)
# f_sql_log.close()
2021-12-15 22:02:07 +01:00
#
2021-04-26 20:07:00 +02:00
# p_sender = subprocess.Popen( [ fb_home+'nbackup', '-b', '1', this_db, 'stdout' ], stdout=PIPE)
# p_getter = subprocess.Popen( [ os.path.join(context['temp_directory'],'7za.exe'), 'u', '-bb3', '-bt', '-bse2', '-si' + os.path.split(nbk1_name)[1], zip1_name ], stdin = p_sender.stdout, stdout = PIPE )
# p_sender.stdout.close()
# p_getter_stdout, p_getter_stderr = p_getter.communicate()
2021-12-15 22:02:07 +01:00
#
2021-04-26 20:07:00 +02:00
# # result: file with name = %FBT_REPO% mp\\BUGS.CORE_4462.nbk1.7z must be created at this point
2021-12-15 22:02:07 +01:00
#
#
2021-04-26 20:07:00 +02:00
# f_nbk1_to_7z_log = open( os.path.join(context['temp_directory'],'tmp_4462_nbk1_to_7z.log'), 'w', buffering = 0)
# f_nbk1_to_7z_log.write( p_getter_stdout if p_getter_stdout else '' )
# f_nbk1_to_7z_log.write( p_getter_stderr if p_getter_stderr else '' )
# f_nbk1_to_7z_log.close()
2021-12-15 22:02:07 +01:00
#
2021-04-26 20:07:00 +02:00
# ################################################################################################################
2021-12-15 22:02:07 +01:00
#
2021-04-26 20:07:00 +02:00
# # Now we can restore database from compressed .7z files by invocation of nbackup with '-de[compress]' command key:
2021-12-15 22:02:07 +01:00
# # nbackup -decompress "7za x -so" -r C:\\FB SS\\examples\\emp-restored\\employee-from-7z.fdb C:\\compressed_backup\\employee.nbk0.7z C:\\compressed_backup\\employee.nbk1.7z
#
2021-04-26 20:07:00 +02:00
# f_restore_log=open( os.path.join(context['temp_directory'],'tmp_4462_nbackup_restore_from_7z.log'), 'w', buffering = 0)
# subprocess.call( [ fb_home + 'nbackup', '-decompress', ' '.join( (p7z_exe,'x', '-y', '-so') ), '-r', fdb_for_restore, zip0_name, zip1_name ], stdout = f_restore_log, stderr = subprocess.STDOUT)
# f_restore_log.close()
2021-12-15 22:02:07 +01:00
#
#
2021-04-26 20:07:00 +02:00
# # Get firebird.log content BEFORE running validation:
# #################################
# f_fblog_before=open( os.path.join(context['temp_directory'],'tmp_4462_fblog_before.txt'), 'w', buffering = 0)
# svc_get_fb_log( fb_home, f_fblog_before )
# f_fblog_before.close()
2021-12-15 22:02:07 +01:00
#
#
2021-04-26 20:07:00 +02:00
# # Run VALIDATION of just restored database:
# ################
# f_validation_log=open( os.path.join(context['temp_directory'],'tmp_4462_gfix_validate.log'), 'w', buffering = 0)
# subprocess.call( [ fb_home + 'gfix', '-v', '-full', fdb_for_restore], stdout=f_validation_log, stderr=subprocess.STDOUT)
# f_validation_log.close()
2021-12-15 22:02:07 +01:00
#
#
2021-04-26 20:07:00 +02:00
# # Get firebird.log content AFTER running validation:
# ################################
# f_fblog_after=open( os.path.join(context['temp_directory'],'tmp_4462_fblog_after.txt'), 'w', buffering = 0)
# svc_get_fb_log( fb_home, f_fblog_after )
# f_fblog_after.close()
2021-12-15 22:02:07 +01:00
#
2021-04-26 20:07:00 +02:00
# oldfb=open(f_fblog_before.name, 'r')
# newfb=open(f_fblog_after.name, 'r')
2021-12-15 22:02:07 +01:00
#
2021-04-26 20:07:00 +02:00
# difftext = ''.join(difflib.unified_diff(
2021-12-15 22:02:07 +01:00
# oldfb.readlines(),
2021-04-26 20:07:00 +02:00
# newfb.readlines()
# ))
# oldfb.close()
# newfb.close()
2021-12-15 22:02:07 +01:00
#
2021-04-26 20:07:00 +02:00
# f_diff_fblog=open( os.path.join(context['temp_directory'],'tmp_4462_fblog_diff.txt'), 'w', buffering = 0)
# f_diff_fblog.write(difftext)
# f_diff_fblog.close()
2021-12-15 22:02:07 +01:00
#
2021-04-26 20:07:00 +02:00
# pattern = re.compile('.*VALIDATION.*|.*ERROR:.*')
2021-12-15 22:02:07 +01:00
#
# # NB: difflib.unified_diff() can show line(s) that present in both files, without marking that line(s) with "+".
2021-04-26 20:07:00 +02:00
# # Usually these are 1-2 lines that placed just BEFORE difference starts.
# # So we have to check output before display diff content: lines that are really differ must start with "+".
2021-12-15 22:02:07 +01:00
#
# # Check: difference between old and new firebird.log should contain
2021-04-26 20:07:00 +02:00
# # only lines about validation start and finish, without errors:
# ###############################################################
2021-12-15 22:02:07 +01:00
#
2021-04-26 20:07:00 +02:00
# with open( f_diff_fblog.name,'r') as f:
# for line in f:
# if line.startswith('+'):
# if pattern.match(line.upper()):
# print( ' '.join(line.split()).upper() )
2021-12-15 22:02:07 +01:00
#
2021-04-26 20:07:00 +02:00
# # Final checks:
# ###############
2021-12-15 22:02:07 +01:00
# # tmp_4462_gfix_validate.log tmp_4462_nbackup_restore_from_7z.log
2021-04-26 20:07:00 +02:00
# # Log for "nbackup -decompress -r ..." must be EMPTY:
# with open( f_restore_log.name,'r') as f:
# for line in f:
# if line:
# print('UNEXPECTED ERROR IN ' + f_restore_log.name + ': ' + line )
2021-12-15 22:02:07 +01:00
#
2021-04-26 20:07:00 +02:00
# # Log of "gfix -v -full" must be EMPTY (this means that no errors and no warning were found):
# with open( f_validation_log.name,'r') as f:
# for line in f:
# if line:
# print('UNEXPECTED ERROR IN ' + f_validation_log.name + ': ' + line )
2021-12-15 22:02:07 +01:00
#
#
2021-04-26 20:07:00 +02:00
# f_list = [
# fdb_for_restore
# ,nbk0_name
# ,nbk1_name
# ,zip0_name
# ,zip1_name
# ,p7z_exe
# ,zstd_exe
# ,os.path.join(context['temp_directory'],'sample-DB_-_firebird.sql')
2021-12-15 22:02:07 +01:00
# ,os.path.join(context['temp_directory'],'sample-DB_-_oracle.sql')
2021-04-26 20:07:00 +02:00
# ]
2021-12-15 22:02:07 +01:00
#
2021-04-26 20:07:00 +02:00
# f_list += [ i.name for i in (f_sql_log, f_nbk0_to_7z_log,f_nbk1_to_7z_log,f_restore_log,f_fblog_before,f_fblog_after,f_validation_log,f_diff_fblog) ]
2021-12-15 22:02:07 +01:00
#
2021-04-26 20:07:00 +02:00
# cleanup( f_list )
2021-12-15 22:02:07 +01:00
#
2021-04-26 20:07:00 +02:00
#---