Skip to content

Commit

Permalink
Changes to support DDL Export Test Framework ( (babelfish-for-postgre…
Browse files Browse the repository at this point in the history
…sql#1402)

Adding support for DDL test framework into python framework.
We in the framework are comparing the generated exported DDL export from the BBF and to the expected exported DDL from the sql server instance.

Issues Resolved
[BABEL-3969]

Signed-off-by: Ashish Prasad [email protected]
  • Loading branch information
hash-16 authored Apr 6, 2023
1 parent 35e1d7c commit 08a8b8a
Show file tree
Hide file tree
Showing 16 changed files with 1,350 additions and 3 deletions.
4 changes: 4 additions & 0 deletions .github/workflows/python-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,10 @@ jobs:
cd ~
curl https://packages.microsoft.com/config/ubuntu/20.04/prod.list | sudo tee /etc/apt/sources.list.d/mssql-release.list
cd ~/work/babelfish_extensions/babelfish_extensions/test/python
mkdir sqltoolsservice
cd sqltoolsservice
wget https://github.com/microsoft/sqltoolsservice/releases/download/4.4.0.12/Microsoft.SqlTools.ServiceLayer-rhel-x64-net6.0.tar.gz && tar -xzvf Microsoft.SqlTools.ServiceLayer-rhel-x64-net6.0.tar.gz
cd ../
sudo ACCEPT_EULA=Y apt-get install -y msodbcsql17 python3-dev
pip3 install pyodbc==4.0.35 pymssql pytest pytest-xdist
Expand Down
82 changes: 82 additions & 0 deletions test/python/SMO_script.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
$argss = $args[0]
$paramsArray =$argss.Split("?")

$Assem = (Microsoft.SqlServer.Management.Sdk.Sfc,
Microsoft.SqlServer.Smo,
Microsoft.SqlServer.ConnectionInfo,
Microsoft.SqlServer.SqlEnum);

Add-Type -AssemblyName $Assem

$SmoServer = New-Object ('Microsoft.SqlServer.Management.Smo.Server') -argumentlist $paramsArray[0]
$SmoServer.ConnectionContext.LoginSecure = $false
$SmoServer.ConnectionContext.set_Login($paramsArray[3])
$SmoServer.ConnectionContext.set_Password($paramsArray[4])
$db = $SmoServer.Databases[$paramsArray[2]]
$script_flag = $paramsArray[5]
$schm = "sys"
$dtb = "sysdatabases"
$var_one = "1"




if($script_flag -eq $var_one)
{
$Objects = $db.Tables
$Objects += $db.Views
$Objects += $db.StoredProcedures
$Objects += $db.UserDefinedFunctions
$Objects += $db.Tables.Indexes
$Objects += $db.Tables.Triggers
foreach ($CurrentObject in $Objects)
{
if (-not $CurrentObject.IsSystemObject )
{
$Scripter = New-Object ('Microsoft.SqlServer.Management.Smo.Scripter') ($SmoServer)
$Scripter.Options.DriAll = $True;
$Scripter.Options.ScriptSchema = $True;
$Scripter.Options.ScriptData = $False;
$Scripter.Options.NoCollation = $True;
$Scripter.Script($CurrentObject);
Write-Output "GO`n"
}
}

}
else
{
$Objects = $db.Tables
$Objects += $db.Views
$Objects += $db.StoredProcedures
$Objects += $db.UserDefinedFunctions
$SubObjects += $db.Tables.Indexes
$SubObjects += $db.Tables.Triggers
foreach ($CurrentObject in $Objects)
{
if ($CurrentObject.schema -ne $schm -and $CurrentObject.schema -ne $dtb -and $CurrentObject.schema -ne $null -and -not $CurrentObject.IsSystemObject )
{
$Scripter = New-Object ('Microsoft.SqlServer.Management.Smo.Scripter') ($SmoServer)
$Scripter.Options.DriAll = $True;
$Scripter.Options.ScriptSchema = $True;
$Scripter.Options.ScriptData = $False;
$Scripter.Options.NoCollation = $True;
$Scripter.Script($CurrentObject);
Write-Output "GO`n"
}
}
foreach ($CurrentObject in $SubObjects)
{
if (-not $CurrentObject.IsSystemObject )
{
$Scripter = New-Object ('Microsoft.SqlServer.Management.Smo.Scripter') ($SmoServer)
$Scripter.Options.DriAll = $True;
$Scripter.Options.ScriptSchema = $True;
$Scripter.Options.ScriptData = $False;
$Scripter.Options.NoCollation = $True;
$Scripter.Script($CurrentObject);
Write-Output "GO`n"
}
}

}
47 changes: 44 additions & 3 deletions test/python/batch_run.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
from utils.config import config_dict as cfg
from execute_query import parse_prepared_statement, parse_stored_procedures, process_transaction_statement,process_statement_in_file_mode
from execute_query import parse_prepared_statement, parse_stored_procedures, process_transaction_statement,process_statement_in_file_mode,process_statement_in_file_mode_ddl
from python_authentication import py_authentication
if cfg['runIsolationTests'] == 'true':
from isolationtest.isolationTestHandler import isolationTestHandler
import os

from compare_results import handle_exception_in_file
from pathlib import Path
import subprocess

#categorise statements based on prefixes and accordingly process them
def batch_run(bbl_cnxn, file_handler, file, logger):
Expand All @@ -14,8 +16,47 @@ def batch_run(bbl_cnxn, file_handler, file, logger):
filename = file.name
f_type = filename.split(".")[1]

if filename.split(".")[0][:4] == 'ddl_' and cfg['ddlExport'] == 'true':
with open(file, "r") as f:
sqlbatch = ""

line = f.readline()
while line:
line = line.replace("\n", "")
#ignore empty lines
if len(line) < 1:
line = f.readline()
continue
else:
if line == "--DROP":
dest = Path.cwd().joinpath("output",cfg["driver"], filename.split(".")[0] + ".out")
f_obj = open(dest, 'a')
work_dir = Path.cwd().joinpath("sqltoolsservice")
script_path = Path.cwd().joinpath("SMO_script.ps1")
script_flag = "0"
if len(filename.split(".")[0]) >= 7 and filename.split(".")[0][:7] == 'ddl_all':
script_flag = "1"
params="?".join([cfg["fileGenerator_URL"],cfg["fileGenerator_port"],cfg["fileGenerator_databaseName"],cfg["fileGenerator_user"],cfg["fileGenerator_password"],script_flag])
args = []
args.append("pwsh -WorkingDirectory {} -File {} {}".format(work_dir,script_path,params))
p=subprocess.Popen(args, stdout=subprocess.PIPE, stderr=subprocess.PIPE,shell=True,text=True)
p_out, p_err = p.communicate()
f_obj.write(p_out)

elif line.lower() == "go" or line.lower() == "go;":
flag = True
flag = process_statement_in_file_mode_ddl(bbl_cnxn, file_handler, sqlbatch)
if flag:
passed += 1
else:
failed += 1

sqlbatch = ""
else:
sqlbatch += line + os.linesep
line = f.readline()

if f_type == "sql":
elif f_type == "sql":
with open(file, "r") as f:

sqlbatch = ""
Expand Down
2 changes: 2 additions & 0 deletions test/python/config.txt
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@ outputErrorCode = true
############################ ALLOW TO RUN ISOLATION TESTS (IF TRUE THEN RUNS ALL THE .SPEC FILES FROM INPUT DIRECTORY OTHERWISE SKIP THEM) ##################################################
runIsolationTests = false

############################ ALLOW TO RUN DDL EXPORT TESTS (IF TRUE THEN RUNS ALL THE .SQL FILES WITH PREFIX ddl_ FROM INPUT DIRECTORY OTHERWISE SKIP THEM) ##################################################
ddlExport = true
############################ MAX TIME LIMIT FOR SINGLE STEP QUERY EXECUTION IN SECONDS(FOR ISOLATION TESTS ONLY) ############################
stepTimeLimit = 30

Expand Down
15 changes: 15 additions & 0 deletions test/python/execute_query.py
Original file line number Diff line number Diff line change
Expand Up @@ -308,6 +308,21 @@ def process_statement_in_file_mode(bbl_cnxn, file_writer, query, is_sql_batch):

return True

def process_statement_in_file_mode_ddl(bbl_cnxn, file_writer, query):
try:
bbl_cursor = bbl_cnxn.get_cursor()
bbl_cursor.execute(query)
result_set_exist = bbl_cursor.description
except Exception as e:
handle_exception_in_file(e, file_writer)

try:
bbl_cursor.close()
except Exception as e:
print(str(e))

return True

#function to generate output files for prepared statements
def process_prepared_statement_in_file_mode(bbl_cnxn, file_writer, query, prep_statement, result, logger):
try:
Expand Down
160 changes: 160 additions & 0 deletions test/python/expected/pyodbc/ddl_all_objects.out
Original file line number Diff line number Diff line change
@@ -0,0 +1,160 @@
SET ANSI_NULLS ON
SET QUOTED_IDENTIFIER ON
CREATE TABLE [dbo].[babel_1654_vu_prepare_t](
[id] [int] IDENTITY(1,1) NOT NULL,
[a] [varchar](50) NULL,
[b] [varchar](50) NULL,
CONSTRAINT [babel_1654_vu_prepare_t_pkey] PRIMARY KEY NONCLUSTERED
(
[id]
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON)
) ON [PRIMARY]

GO

SET ANSI_NULLS ON
SET QUOTED_IDENTIFIER ON
CREATE TABLE [dbo].[sys_all_views_table_vu_prepare](
[a] [int] NULL
) ON [PRIMARY]

GO

SET ANSI_NULLS ON
SET QUOTED_IDENTIFIER ON
CREATE TABLE [dbo].[test_datetime](
[c_time] [time](6) NULL,
[c_date] [date] NULL,
[c_datetime] [datetime] NULL,
[c_datetime2] [datetime2](6) NULL,
[c_datetimeoffset] [datetimeoffset](6) NULL,
[c_smalldatetime] [smalldatetime] NULL
) ON [PRIMARY]

ALTER TABLE [dbo].[test_datetime] WITH CHECK ADD CONSTRAINT [test_datetime_c_date_check] CHECK (((c_date < '2001-01-01')))
ALTER TABLE [dbo].[test_datetime] CHECK CONSTRAINT [test_datetime_c_date_check]
ALTER TABLE [dbo].[test_datetime] WITH CHECK ADD CONSTRAINT [test_datetime_c_datetime_check] CHECK (((c_datetime < '2020-10-20 09:00:00')))
ALTER TABLE [dbo].[test_datetime] CHECK CONSTRAINT [test_datetime_c_datetime_check]
ALTER TABLE [dbo].[test_datetime] WITH CHECK ADD CONSTRAINT [test_datetime_c_datetime2_check] CHECK ((((c_datetime2 < '2020-10-20 09:00:00') AND (c_datetime2 < CAST('2020-10-20 09:00:00' AS datetime2(6))))))
ALTER TABLE [dbo].[test_datetime] CHECK CONSTRAINT [test_datetime_c_datetime2_check]
ALTER TABLE [dbo].[test_datetime] WITH CHECK ADD CONSTRAINT [test_datetime_c_datetimeoffset_check] CHECK ((((c_datetimeoffset < '2025-12-10 12:32:10 +01:00') AND (c_datetimeoffset < CAST('2025-12-10 12:32:10 +01:00' AS datetimeoffset(4))))))
ALTER TABLE [dbo].[test_datetime] CHECK CONSTRAINT [test_datetime_c_datetimeoffset_check]
ALTER TABLE [dbo].[test_datetime] WITH CHECK ADD CONSTRAINT [test_datetime_c_smalldatetime_check] CHECK (((c_smalldatetime < '2007-05-08 12:35:00')))
ALTER TABLE [dbo].[test_datetime] CHECK CONSTRAINT [test_datetime_c_smalldatetime_check]
ALTER TABLE [dbo].[test_datetime] WITH CHECK ADD CONSTRAINT [test_datetime_c_time_check] CHECK ((((c_time < '09:00:00') AND (c_time < CAST('09:00:00' AS time(6))))))
ALTER TABLE [dbo].[test_datetime] CHECK CONSTRAINT [test_datetime_c_time_check]
GO

SET ANSI_NULLS ON
SET QUOTED_IDENTIFIER ON
CREATE TABLE [dbo].[test_tsql_collate](
[c_varchar] [varchar](1) NULL,
[c_char] [char](1) NULL,
[c_nchar] [nchar](1) NULL
) ON [PRIMARY]

ALTER TABLE [dbo].[test_tsql_collate] WITH CHECK ADD CONSTRAINT [test_tsql_collate_c_char_check] CHECK (((c_char <> (CAST('sflkjasdlkfjf' AS char(7)) COLLATE japanese_ci_as))))
ALTER TABLE [dbo].[test_tsql_collate] CHECK CONSTRAINT [test_tsql_collate_c_char_check]
ALTER TABLE [dbo].[test_tsql_collate] WITH CHECK ADD CONSTRAINT [test_tsql_collate_c_nchar_check] CHECK (((CAST((c_nchar) AS nchar(7)) <> (CAST(('sflkjasdlkfjf') AS nchar(7)) COLLATE latin1_general_ci_as))))
ALTER TABLE [dbo].[test_tsql_collate] CHECK CONSTRAINT [test_tsql_collate_c_nchar_check]
ALTER TABLE [dbo].[test_tsql_collate] WITH CHECK ADD CONSTRAINT [test_tsql_collate_c_varchar_check] CHECK (((c_varchar <> (CAST('sflkjasdlkfjf' AS varchar(12)) COLLATE latin1_general_ci_as))))
ALTER TABLE [dbo].[test_tsql_collate] CHECK CONSTRAINT [test_tsql_collate_c_varchar_check]
GO

SET ANSI_NULLS ON
SET QUOTED_IDENTIFIER ON
CREATE TABLE [dbo].[test_tsql_const](
[c_int] [int] NOT NULL,
[c_bit] [bit] NULL,
[c_smallint] [smallint] NULL,
[c_binary] [binary](8) NULL,
[c_varbinary] [varbinary](8) NULL,
CONSTRAINT [test_tsql_const_pkey] PRIMARY KEY NONCLUSTERED
(
[c_int]
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON)
) ON [PRIMARY]

ALTER TABLE [dbo].[test_tsql_const] WITH CHECK ADD CONSTRAINT [test_tsql_const_c_binary_check] CHECK (((c_binary > CAST(('0xfe') AS binary(8)))))
ALTER TABLE [dbo].[test_tsql_const] CHECK CONSTRAINT [test_tsql_const_c_binary_check]
ALTER TABLE [dbo].[test_tsql_const] WITH CHECK ADD CONSTRAINT [test_tsql_const_c_bit_check] CHECK (((c_bit <> CAST((1) AS bit))))
ALTER TABLE [dbo].[test_tsql_const] CHECK CONSTRAINT [test_tsql_const_c_bit_check]
ALTER TABLE [dbo].[test_tsql_const] WITH CHECK ADD CONSTRAINT [test_tsql_const_c_int_check] CHECK (((c_int < 10)))
ALTER TABLE [dbo].[test_tsql_const] CHECK CONSTRAINT [test_tsql_const_c_int_check]
ALTER TABLE [dbo].[test_tsql_const] WITH CHECK ADD CONSTRAINT [test_tsql_const_c_smallint_check] CHECK (((c_smallint < CAST((CAST(('20') AS sql_variant)) AS smallint))))
ALTER TABLE [dbo].[test_tsql_const] CHECK CONSTRAINT [test_tsql_const_c_smallint_check]
ALTER TABLE [dbo].[test_tsql_const] WITH CHECK ADD CONSTRAINT [test_tsql_const_c_varbinary_check] CHECK (((c_varbinary > CAST('0xfe' AS varbinary(8)))))
ALTER TABLE [dbo].[test_tsql_const] CHECK CONSTRAINT [test_tsql_const_c_varbinary_check]
GO

SET ANSI_NULLS ON
SET QUOTED_IDENTIFIER ON
CREATE VIEW sys_all_views_select_chk_option_vu_prepare AS
SELECT * FROM sys_all_views_table_vu_prepare
WITH CHECK OPTION
GO

SET ANSI_NULLS ON
SET QUOTED_IDENTIFIER ON
CREATE VIEW sys_all_views_select_vu_prepare AS
SELECT * FROM sys_all_views_table_vu_prepare
GO

SET ANSI_NULLS ON
SET QUOTED_IDENTIFIER ON
create procedure routines_test_nvar(@test_nvar_a nvarchar , @test_nvar_b int = 8)
AS
BEGIN
SELECT @test_nvar_b=8;
END
GO

SET ANSI_NULLS ON
SET QUOTED_IDENTIFIER ON
create function routines_fc1(@fc1_a nvarchar) RETURNS nvarchar AS BEGIN return @fc1_a END;
GO

SET ANSI_NULLS ON
SET QUOTED_IDENTIFIER ON
create function routines_fc2(@fc2_a varchar) RETURNS varchar AS BEGIN return @fc2_a END;
GO

SET ANSI_NULLS ON
SET QUOTED_IDENTIFIER ON
create function routines_fc3(@fc3_a nchar) RETURNS nchar AS BEGIN return @fc3_a END;
GO

SET ANSI_NULLS ON
SET QUOTED_IDENTIFIER ON
create function routines_fc4(@fc4_a binary, @fc4_b tinyint, @fc4_c BIGINT, @fc4_d float) RETURNS binary AS BEGIN return @fc4_a END;
GO

SET ANSI_NULLS ON
SET QUOTED_IDENTIFIER ON
create function routines_fc5(@fc5_a varbinary) RETURNS varbinary AS BEGIN return @fc5_a END;
GO

SET ANSI_NULLS ON
SET QUOTED_IDENTIFIER ON
create function routines_fc6(@fc6_a char) RETURNS char AS BEGIN return @fc6_a END;
GO

ALTER TABLE [dbo].[babel_1654_vu_prepare_t] ADD CONSTRAINT [babel_1654_vu_prepare_t_pkey] PRIMARY KEY NONCLUSTERED
(
[id]
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON)
GO

ALTER TABLE [dbo].[test_tsql_const] ADD CONSTRAINT [test_tsql_const_pkey] PRIMARY KEY NONCLUSTERED
(
[c_int]
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON)
GO

SET ANSI_NULLS ON
SET QUOTED_IDENTIFIER ON
CREATE TRIGGER babel_1654_vu_prepare_trig_t on babel_1654_vu_prepare_t after update as
select COLUMNS_UPDATED();
ALTER TABLE [dbo].[babel_1654_vu_prepare_t] ENABLE TRIGGER [babel_1654_vu_prepare_trig_t]
GO

Loading

0 comments on commit 08a8b8a

Please sign in to comment.