-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathSetTSTDatabase.sql
More file actions
5433 lines (4600 loc) · 229 KB
/
SetTSTDatabase.sql
File metadata and controls
5433 lines (4600 loc) · 229 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
--===================================================================
-- FILE: SetTSTDatabase.sql
-- This is the SQL script that will setup the TST support
-- database. It must be invoked by TST.bat
-- Licence:
-- This project is released under the
-- "Eclipse Public License - v 1.0"
-- See http://www.eclipse.org/legal/epl-v10.html
-- History:
-- ------------------------------------------------------------------
-- 02/28/2009 - Ladislau Molnar
-- Version 1.0 is finalized
-- 03/01/2009 - Ladislau Molnar
-- The project is released on Codeplex:
-- http://www.codeplex.com/
-- 04/19/2009 - Ladislau Molnar
-- Version 1.1 is finalized
-- Support for writing test sprocs in their own schema.
-- Test results are in alphabetical order of Suites/Tests.
-- 05/17/2009 - Ladislau Molnar
-- Version 1.2 is finalized
-- Allow Assert.TableEquals to ignore columns as specified
-- in an optional parameter.
-- 07/22/2009 - Ladislau Molnar
-- Version 1.3 is finalized
-- Add a new view: Data.TSTResultsEx to facilitate the integration
-- with http://www.codeplex.com/MCI4TST.
-- Data.TSTResultsEx provides more details about the results of a
-- test session compared with the existing view: Data.TSTResults.
-- 09/23/2009 - Ladislau Molnar
-- Version 1.4 is finalized
-- V 1.3 or earlier will not install on a SQL Server with a case sensitive collation.
-- The V1.4 release fixes all known issues related to case sensitive collations
-- 03/17/2010 - Ladislau Molnar
-- Version 1.5 is finalized
-- Bug fix. In V1.4 and earlier table comparison failed if the tables that
-- were compared had columns with names that contained spaces.
-- 08/15/2010 - Ladislau Molnar
-- Version 1.6 is finalized
-- Adding Setup and Teardown at the Test Session level. One can provide a stored procedure
-- to be run at the beginning of each test session or another stored procedure to be run
-- at the end of each test session.
-- Fix a bug: “Not well-formed xml result generated for some failed test cases”.
-- Add a new Assert API: Assert.IsTableNotEmpty.
-- 05/28/2011 Ladislau Molnar
-- Version 1.7 is finalized
-- Bug fix. In V1.6 and earlier a RAISERROR in a TRIGGER cannot be tested by
-- registering an expected error.
-- 11/13/2011 Ladislau Molnar
-- Version 1.8 is finalized
-- Alow users to customize the prefix "SQLTest_".
-- Introduce Assert.Ignore.
-- Fix bug: A test session is reported as passing even when the test session setup or teardown failed.
-- Improve the text and Xml output when test session setup/teardown are present.
-- 03/29/2012 Ladislau Molnar
-- Version 1.9 is finalized
-- Fix bug: When using XML output the overall status is incorrectly reported as Failed.
-- Add support for new types for Assert.TableEquals
-- Introduce Assert.NVarCharMaxEquals and Assert.NVarCharMaxNotEquals
-- Add new parameters to Assert.RegisterExpectedError: @ExpectedErrorLikeMessage, @LikeEscapeCharacter
-- Improve the output of RegisterExpectedError. Add info about the expected error in the output of RegisterExpectedError.
-- Change the declaration of parameter @ExpectedLikeValue in Assert.IsLike from nvarchar(max) to nvarchar(4000)
-- Change the declaration of parameter @ExpectedNotLikeValue in Assert.IsNotLike from nvarchar(max) to nvarchar(4000)
-- Add the name of the TST SQL Server and the name of the tested SQL database to the XML output.
-- ==================================================================
/*
General comments
=====================================================================
SECTION 'Results Format'
Several stored procedures have a parameter named @ResultsFormat. This
indicates the format in which the results are printed. The valid values are:
'Text' - The results will be printed in plain text format. The output
contains a line showing the passed/failed status in the format:
TST Status: XXXX
where XXXX is Passed or Failed.
'XML' - The results will be printed in an XML format.
'Batch' - The same as 'Text' and additionally it prints the testSessionId
in the format:
TST TestSessionId: X
where X is the TestSessionId
'None' - Nothing will be printed
=====================================================================
*/
USE tempdb
-- =======================================================================
-- Creates the TST Database. If already exists then drops it first.
-- =======================================================================
IF EXISTS (SELECT [name] FROM sys.databases WHERE [name] = 'TST')
BEGIN
DROP DATABASE TST
END
CREATE DATABASE TST
GO
USE TST
GO
-- =======================================================================
-- TST Schemas
-- =======================================================================
CREATE SCHEMA Assert
GO
CREATE SCHEMA Runner
GO
CREATE SCHEMA Utils
GO
CREATE SCHEMA Internal
GO
CREATE SCHEMA Data
GO
-- =======================================================================
-- START TST Tables and views.
-- =======================================================================
-- =======================================================================
-- TABLE: TSTVersion
-- This table will contain a signature and version information.
-- Note: The signature is used to make sure during the automated setup
-- that if a TST database already exists is not an unrelated TST
-- database that by chance has the same name.
-- =======================================================================
CREATE TABLE Data.TSTVersion(
TSTSignature varchar(100) NOT NULL,
MajorVersion int NOT NULL,
MinorVersion int NOT NULL,
SetupDate datetime NOT NULL DEFAULT(GETDATE())
)
-- Get the MajorVersion and MinorVersion from the caller (this script is invoked using SQLCMD)
DECLARE @TST_MajorVersion int
DECLARE @TST_MinorVersion int
SET @TST_MajorVersion = $(MajorVersion)
SET @TST_MinorVersion = $(MinorVersion)
INSERT INTO Data.TSTVersion(TSTSignature, MajorVersion, MinorVersion) VALUES ('TST-{6C57D85A-CE44-49ba-9286-A5227961DF02}', @TST_MajorVersion, @TST_MinorVersion)
GO
-- =======================================================================
-- TABLE: TSTVariables
-- This table will contain TST variables defined per test database.
-- =======================================================================
CREATE TABLE Data.TSTVariables(
VariableId int NOT NULL IDENTITY(1,1), -- Identifies the variable.
DatabaseName sysname NULL, -- Identifies the database for which the variable is set.
-- If NULL then the variable is global.
VariableName varchar(32) NOT NULL, -- Name of the variable.
VariableValue varchar(100) NOT NULL, -- Value of the variable.
)
ALTER TABLE Data.TSTVariables ADD CONSTRAINT PK_TSTVariables PRIMARY KEY CLUSTERED (VariableId)
-- The same variable cannot be specified twice for the same database scope
ALTER TABLE Data.TSTVariables ADD CONSTRAINT UK_TSTVariables_DatabaseName_VariableName UNIQUE(DatabaseName, VariableName)
ALTER TABLE Data.TSTVariables ADD CONSTRAINT CK_TSTVariables_VariableName CHECK (
VariableName = 'SqlTestPrefix' -- Indicates the prefix used to identify the test procedures. See SFN_GetTestProcedurePrefix
)
GO
-- =======================================================================
-- TABLE: TSTParameters
-- This table will contain TST parameters per test session
-- They will direct different aspects of the test session.
-- Note: Transitory data. The row describing one test session will be
-- deleted after the test session is completed.
-- =======================================================================
CREATE TABLE Data.TSTParameters(
ParameterId int NOT NULL IDENTITY(1,1), -- Identifies the parameter.
TestSessionId int NOT NULL, -- Identifies the test session.
ParameterName varchar(32) NOT NULL, -- See CK_TSTParameters_ParameterName
ParameterValue varchar(100)NOT NULL, -- The parameter value. Depends on the ParameterName.
-- See CK_TSTParameters_ParameterName.
Scope sysname NOT NULL, -- See CK_TSTParameters_Scope
ScopeValue sysname NULL, -- Depends on Scope. see CK_TSTParameters_Scope
)
ALTER TABLE Data.TSTParameters ADD CONSTRAINT PK_TSTParameters PRIMARY KEY CLUSTERED (ParameterId)
-- The same parameter cannot be specified twice in the same scope
ALTER TABLE Data.TSTParameters ADD CONSTRAINT UK_TSTParameters_TestSessionId_ParameterName_Scope_ScopeValue UNIQUE(TestSessionId, ParameterName, Scope, ScopeValue)
ALTER TABLE Data.TSTParameters ADD CONSTRAINT CK_TSTParameters_ParameterName CHECK (
ParameterName = 'UseTSTRollback' -- Indicates if the TST runners (the TST.Runner.RunXXX APIs) use transactions to rollback changes
-- In this case the ParameterValue can be:
-- 0 - Do NOT use transactions.
-- any other value - Use transactions.
-- If 'UseTSTRollback' is not specified the default value is '1'
)
ALTER TABLE Data.TSTParameters ADD CONSTRAINT CK_TSTParameters_Scope CHECK (
Scope = 'All' -- Indicates that the parameter applies to the entire test session.
-- In this case the ScopeValue is ignored
OR Scope = 'Suite' -- Indicates that the parameter applies during the scope of one suite.
-- In this case the ScopeValue is the name of the suite.
-- Parameters set in the suite scope overwrite ones set in the 'All' scope.
OR Scope = 'Test' -- Indicates that the parameter applies during the scope of one test.
-- In this case the ScopeValue is the name of the stored procedure
-- that implements the test.
-- Parameters set in the test scope overwrite ones set in the 'All' and 'Suite' scope.
)
-- =======================================================================
-- TABLE: TestSession
-- This table will contain summary information about test sessions.
-- Note: Transitory data. The row describing one test session will be
-- deleted after the test session is completed.
-- =======================================================================
CREATE TABLE Data.TestSession(
TestSessionId int NOT NULL IDENTITY(1,1), -- Identifies the test session.
-- Multiple clients can simultaneously execute their own test runs.
DatabaseName sysname NOT NULL, -- Identifies the database that is the subject of the current run.
TestSessionStart datetime NOT NULL, -- The time when the current run started.
TestSessionFinish datetime -- The time when the current run finished.
-- NULL while the run is in progress
)
ALTER TABLE Data.TestSession ADD CONSTRAINT PK_TestSession PRIMARY KEY CLUSTERED (TestSessionId)
GO
-- =======================================================================
-- Table: Suite
-- This table associates a suite name with a suite ID.
-- Note: Transitory data. The rows describing suites that are part of
-- a test session will be deleted after the test
-- session is completed.
-- =======================================================================
CREATE TABLE Data.Suite(
SuiteId int NOT NULL IDENTITY(1,1),
TestSessionId int NOT NULL, -- Identifies the test session that this suite belongs to.
SchemaName sysname NULL, -- NULL will be reserved for the Anonymous suite
-- All tests that are not grouped to a suite are considered to belong to an anonymous suite.
-- That anonymous suite has an entry in this table where SchemaName and SuiteName are NULL.
SuiteName sysname NULL, -- NULL will be reserved for the Anonymous suite.
-- (see the comments on SchemaName).
)
ALTER TABLE Data.Suite ADD CONSTRAINT PK_Suite PRIMARY KEY CLUSTERED (SuiteId)
ALTER TABLE Data.Suite ADD CONSTRAINT UK_Suite_TestSessionId_SuiteName UNIQUE(TestSessionId, SchemaName, SuiteName)
ALTER TABLE Data.Suite ADD CONSTRAINT FK_Suite_TestSessionId FOREIGN KEY(TestSessionId) REFERENCES Data.TestSession(TestSessionId)
CREATE NONCLUSTERED INDEX IX_Suite_TestSessionId_SuiteId ON Data.Suite(TestSessionId, SuiteId)
GO
-- =======================================================================
-- TABLE: Test
-- This table stores information about every test that has to be run in
-- the current test session.
-- Note: Transitory data. The rows describing tests that are part of
-- a test session will be deleted after the test
-- session is completed.
-- =======================================================================
CREATE TABLE Data.Test(
TestId int NOT NULL IDENTITY(1,1), -- Identifies the test
TestSessionId int NOT NULL, -- Identifies the test session that this test belongs to.
-- Note: this is a denormalization. TestSessionId could have been determined
-- having SuiteId known. TestSessionId is present here for convenience.
SuiteId int NOT NULL, -- Identifies the suite that this test belongs to.
SchemaName sysname NOT NULL, -- The schema name of the procedures that implements the test (like 'dbo')
SProcName sysname NOT NULL, -- The name of the procedures that implements the test
SProcType varchar(10) NOT NULL -- Indicates the type of procedure and can be:
-- 'SetupS'
-- 'TeardownS'
-- 'Setup'
-- 'Teardown'
-- 'Test'
)
ALTER TABLE Data.Test ADD CONSTRAINT PK_Test PRIMARY KEY CLUSTERED (TestId)
ALTER TABLE Data.Test ADD CONSTRAINT UK_Test_SuiteId_SchemaName_SProcName UNIQUE(SuiteId, SchemaName, SProcName)
ALTER TABLE Data.Test ADD CONSTRAINT UK_Test_TestSessionId_SchemaName_SProcName UNIQUE(TestSessionId, SchemaName, SProcName)
ALTER TABLE Data.Test ADD CONSTRAINT CK_Test_SProcType CHECK (SProcType = 'SetupS' OR SProcType = 'TeardownS' OR SProcType = 'Setup' OR SProcType = 'Teardown' OR SProcType = 'Test')
ALTER TABLE Data.Test ADD CONSTRAINT FK_Test_SuiteId FOREIGN KEY(SuiteId) REFERENCES Data.Suite(SuiteId)
CREATE NONCLUSTERED INDEX IX_Test_SuiteId_SProcName ON Data.Test(SuiteId, SProcName)
CREATE NONCLUSTERED INDEX IX_Test_TestSessionId_SProcName ON Data.Test(TestSessionId, SProcName)
GO
-- =======================================================================
-- TABLE: TestLog
-- This table collects all the log entries.
-- Note: Transitory data. The rows describing entries saved as part of
-- a test session will be deleted after the test
-- session is completed.
-- =======================================================================
CREATE TABLE Data.TestLog(
LogEntryId int NOT NULL IDENTITY(1,1), -- Identifies the log entry
TestSessionId int NOT NULL, -- Identifies the test session that this log entry belongs to.
-- Note: there is a little denormalization here. TestSessionId
-- is here for convinience. It could be determined based on TestId.
TestId int NOT NULL, -- Identifies the test that this log entry belongs to.
EntryType char NOT NULL, -- Indicates the type of log entry:
-- 'P' - Pass
-- 'I' - Ignore
-- 'L' - Log
-- 'F' - Fail
-- 'E' - Error
CreatedTime DateTime NOT NULL DEFAULT(GETDATE()), -- The datetime when this entry was created.
LogMessage nvarchar(max) NOT NULL
)
ALTER TABLE Data.TestLog ADD CONSTRAINT PK_TestLog PRIMARY KEY CLUSTERED (LogEntryId)
ALTER TABLE Data.TestLog ADD CONSTRAINT FK_TestLog_TestSessionId FOREIGN KEY(TestSessionId) REFERENCES Data.TestSession(TestSessionId)
ALTER TABLE Data.TestLog ADD CONSTRAINT FK_TestLog_TestId FOREIGN KEY(TestId) REFERENCES Data.Test(TestId)
CREATE NONCLUSTERED INDEX IX_TestLog_TestSessionId ON Data.TestLog(TestSessionId)
CREATE NONCLUSTERED INDEX IX_TestLog_TestId ON Data.TestLog(TestId)
ALTER TABLE Data.TestLog ADD CONSTRAINT CK_TestLog_EntryType CHECK (EntryType = 'P' OR EntryType = 'I' OR EntryType = 'L' OR EntryType = 'F' OR EntryType = 'E')
GO
-- =======================================================================
-- TABLE: SystemErrorLog
-- This table collects log entries regarding errors that occured outside
-- of any test. Normally these logs corespond to issues that occured
-- in the preparatory phase before any test is executed.
-- Note: Transitory data. The rows describing entries saved as part of
-- a test session will be deleted after the test
-- session is completed.
-- =======================================================================
CREATE TABLE Data.SystemErrorLog(
LogEntryId int NOT NULL IDENTITY(1,1), -- Identifies the log entry
TestSessionId int NOT NULL, -- Identifies the test session that this log entry belongs to.
CreatedTime DateTime NOT NULL DEFAULT(GETDATE()), -- The datetime when this entry was created.
LogMessage nvarchar(max) NOT NULL
)
ALTER TABLE Data.SystemErrorLog ADD CONSTRAINT PK_SystemErrorLog PRIMARY KEY CLUSTERED (LogEntryId)
ALTER TABLE Data.SystemErrorLog ADD CONSTRAINT FK_SystemErrorLog_TestSessionId FOREIGN KEY(TestSessionId) REFERENCES Data.TestSession(TestSessionId)
CREATE NONCLUSTERED INDEX IX_SystemErrorLog_TestSessionId ON Data.SystemErrorLog(TestSessionId)
GO
-- =======================================================================
-- VIEW: TSTResults
-- Aggregates data from several tables to facilitate results reporting
-- =======================================================================
CREATE VIEW Data.TSTResults AS
SELECT
TestLog.LogEntryId,
TestLog.TestSessionId,
Suite.SuiteId,
Suite.SuiteName,
Test.TestId,
Test.SProcName,
Test.SProcType,
TestLog.EntryType,
TestLog.CreatedTime,
TestLog.LogMessage
FROM Data.TestLog
INNER JOIN Data.Test ON TestLog.TestId = Test.TestId
INNER JOIN Data.Suite ON Suite.SuiteId = Test.SuiteId
GO
-- =======================================================================
-- VIEW: TSTResultsEx
-- Aggregates data from several tables to facilitate results reporting
-- Adds more info compared with TSTResults. Specifically test status and suite status
-- =======================================================================
CREATE VIEW Data.TSTResultsEx AS
SELECT
LogEntries.LogEntryId,
LogEntries.TestSessionId,
Suite.SuiteId,
ISNULL(Suite.SuiteName, 'Anonymous') AS SuiteName,
SuiteStatus = CASE WHEN SuiteFailInfo.FailuresOrErrorsCount > 0 THEN 'F' ELSE 'P' END,
Test.TestId,
Test.SProcName,
TestStatus = CASE WHEN TestFailInfo.FailuresOrErrorsCount > 0 THEN 'F' ELSE 'P' END,
LogEntries.EntryType,
LogEntries.LogMessage,
LogEntries.CreatedTime
FROM Data.TestLog AS LogEntries
INNER JOIN Data.Test ON LogEntries.TestId = Test.TestId
INNER JOIN Data.Suite ON Suite.SuiteId = Test.SuiteId
INNER JOIN ( SELECT
TestId,
( SELECT COUNT(*) FROM Data.TestLog AS L1
WHERE
(L1.EntryType = 'E' OR L1.EntryType = 'F' )
AND L1.TestId = T1.TestId
) AS FailuresOrErrorsCount
FROM TST.Data.Test AS T1
) AS TestFailInfo ON TestFailInfo.TestId = Test.TestId
INNER JOIN ( SELECT
SuiteId,
( SELECT COUNT(*) FROM Data.TestLog L2
INNER JOIN Data.Test AS T2 ON L2.TestId = T2.TestId
WHERE
(L2.EntryType = 'E' OR L2.EntryType = 'F' )
AND T2.SuiteId = S1.SuiteId
) AS FailuresOrErrorsCount
FROM TST.Data.Suite AS S1
) AS SuiteFailInfo ON SuiteFailInfo.SuiteId = Suite.SuiteId
GO
-- =======================================================================
-- END TST Tables and views.
-- =======================================================================
-- =======================================================================
-- START TST Internals.
-- These are functions and stored procedures internal to the TST framework.
-- =======================================================================
-- Early declaration. This sproc is declared to avoid a warning (Cannot add rows to sys.sql_dependencies ...)
-- It will be properly defined later.
CREATE PROCEDURE Assert.Pass
@Message nvarchar(max) = ''
AS
BEGIN
RAISERROR ('Early declaration of Assert.Pass', 16, 1)
END
GO
-- Early declaration. This sproc is declared to avoid a warning (Cannot add rows to sys.sql_dependencies ...)
-- It will be properly defined later.
CREATE PROCEDURE Assert.Fail
@ErrorMessage nvarchar(max)
AS
BEGIN
RAISERROR ('Early declaration of Assert.Fail', 16, 1)
END
GO
-- Early declaration. This sproc is declared to avoid a warning (Cannot add rows to sys.sql_dependencies ...)
-- It will be properly defined later.
CREATE PROCEDURE Internal.ClearExpectedError
AS
BEGIN
RAISERROR ('Early declaration of Internal.ClearExpectedError', 16, 1)
END
GO
-- =======================================================================
-- FUNCTION SFN_GetListToTable
-- Takes a list with items separated by semicolons and returns a table
-- where each row contains one item. Each item is max 500 characters otherwise
-- a truncation error occurs.
-- =======================================================================
CREATE FUNCTION Internal.SFN_GetListToTable(@List varchar(max))
RETURNS @ListToTable TABLE (ListItem varchar(500) )
AS
BEGIN
IF (@List IS NULL) RETURN
DECLARE @IndexStart int
DECLARE @IndexEnd int
DECLARE @CrtItem varchar(500)
SET @IndexStart = 1;
WHILE (@IndexStart <= DATALENGTH(@List) + 1)
BEGIN
SET @IndexEnd = CHARINDEX(';', @List, @IndexStart)
IF (@IndexEnd = 0) SET @IndexEnd = DATALENGTH(@List) + 1
IF (@IndexEnd > @IndexStart)
BEGIN
SET @CrtItem = SUBSTRING(@List, @IndexStart, @IndexEnd - @IndexStart)
INSERT INTO @ListToTable(ListItem) VALUES (@CrtItem)
END
SET @IndexStart = @IndexEnd + 1
END
RETURN
END
GO
-- =======================================================================
-- FUNCTION SFN_EscapeForXml
-- Returns the given string after escaping characters that have a special
-- role in an XML file.
-- =======================================================================
CREATE FUNCTION Internal.SFN_EscapeForXml(@TextString nvarchar(max)) RETURNS nvarchar(max)
AS
BEGIN
SET @TextString = REPLACE (@TextString, '"', '"')
SET @TextString = REPLACE (@TextString, '&', '&')
SET @TextString = REPLACE (@TextString, '>', '>')
SET @TextString = REPLACE (@TextString, '<', '<')
RETURN @TextString
END
GO
-- =======================================================================
-- FUNCTION SFN_GetEntryTypeName
-- Returns the name corresponding to the @EntryType. See TestLog.EntryType
-- =======================================================================
CREATE FUNCTION Internal.SFN_GetEntryTypeName(@EntryType char) RETURNS varchar(10)
AS
BEGIN
IF @EntryType = 'P' RETURN 'Pass'
IF @EntryType = 'I' RETURN 'Ignore'
IF @EntryType = 'L' RETURN 'Log'
IF @EntryType = 'F' RETURN 'Failure'
IF @EntryType = 'E' RETURN 'Error'
RETURN '???'
END
GO
-- =======================================================================
-- FUNCTION SFN_GetFullSprocName
-- Returns the full name of the sproc identified by @TestId
-- The full name has the format: Database.Schema.Name
-- =======================================================================
CREATE FUNCTION Internal.SFN_GetFullSprocName(@TestId int) RETURNS nvarchar(1000)
AS
BEGIN
DECLARE @DatabaseName sysname
DECLARE @SchemaName sysname
DECLARE @SProcName sysname
DECLARE @FullSprocName nvarchar(1000)
SELECT
@DatabaseName = TestSession.DatabaseName,
@SchemaName = Test.SchemaName,
@SProcName = Test.SProcName
FROM Data.Test
INNER JOIN Data.TestSession ON TestSession.TestSessionId = Test.TestSessionId
WHERE TestId = @TestId
SET @FullSprocName = QUOTENAME(@DatabaseName) + '.' + QUOTENAME(ISNULL(@SchemaName, '')) + '.' + QUOTENAME(@SProcName)
RETURN @FullSprocName
END
GO
-- =======================================================================
-- PROCEDURE SuiteExists
-- Determines if the suite with the name given by @TestName exists
-- in the database with the name given by @TestDatabaseName.
-- =======================================================================
CREATE PROCEDURE Internal.SuiteExists
@TestDatabaseName sysname,
@SuiteName sysname,
@TestProcedurePrefix varchar(100),
@SuiteExists bit OUT
AS
BEGIN
DECLARE @SqlCommand nvarchar(1000)
DECLARE @Params nvarchar(100)
DECLARE @TestInSuiteCount int
SET @SqlCommand = 'SELECT @TestInSuiteCountOUT = COUNT(*) ' +
'FROM ' + QUOTENAME(@TestDatabaseName) + '.sys.procedures ' +
'WHERE name LIKE ''' + @TestProcedurePrefix + @SuiteName + '#%'''
SET @Params = '@TestInSuiteCountOUT int OUT'
EXEC sp_executesql @SqlCommand, @Params, @TestInSuiteCountOUT=@TestInSuiteCount OUT
SET @SuiteExists = 0
IF (@TestInSuiteCount >= 1) SET @SuiteExists = 1
END
GO
-- =======================================================================
-- FUNCTION SFN_SProcExists
-- Determines if the procedure with the name given by @TestName exists
-- in database with the name given by @TestDatabaseName.
-- =======================================================================
CREATE FUNCTION Internal.SFN_SProcExists(@TestDatabaseName sysname, @SProcNameName sysname) RETURNS bit
AS
BEGIN
DECLARE @ObjectName nvarchar(1000)
SET @ObjectName = @TestDatabaseName + '..' + @SProcNameName
IF (object_id(@ObjectName, 'P') IS NOT NULL)
BEGIN
RETURN 1
END
RETURN 0
END
GO
-- =======================================================================
-- FUNCTION SFN_UseTSTRollbackForTest
-- Determins if transactions can be used for the given test.
-- =======================================================================
CREATE FUNCTION Internal.SFN_UseTSTRollbackForTest(@TestSessionId int, @TestId int) RETURNS bit
AS
BEGIN
DECLARE @UseTSTRollback varchar(100)
SET @UseTSTRollback = '1' -- Default value
SELECT @UseTSTRollback = TSTParameters.ParameterValue
FROM Data.TSTParameters
WHERE
TestSessionId = @TestSessionId
AND ParameterName = 'UseTSTRollback'
AND Scope = 'All'
-- The 'Suite' scope will overwrite the 'All' scope
SELECT @UseTSTRollback = TSTParameters.ParameterValue
FROM Data.TSTParameters
INNER JOIN Data.Suite ON
Suite.TestSessionId = TSTParameters.TestSessionId
AND TSTParameters.Scope = 'Suite'
AND Suite.SuiteName = TSTParameters.ScopeValue
INNER JOIN Data.Test ON
Test.SuiteId = Suite.SuiteId
WHERE
TSTParameters.TestSessionId = @TestSessionId
AND TSTParameters.ParameterName = 'UseTSTRollback'
AND Test.TestId = @TestId
-- The 'Test' scope will overwrite the 'Suite' and 'All' scope
SELECT @UseTSTRollback = TSTParameters.ParameterValue
FROM Data.TSTParameters
INNER JOIN Data.Test ON
Test.TestSessionId = TSTParameters.TestSessionId
AND TSTParameters.Scope = 'Test'
AND Test.SProcName = TSTParameters.ScopeValue
WHERE
TSTParameters.TestSessionId = @TestSessionId
AND TSTParameters.ParameterName = 'UseTSTRollback'
AND Test.TestId = @TestId
IF @UseTSTRollback = '0' RETURN 0
RETURN 1
END
GO
-- =======================================================================
-- FUNCTION: SFN_GetCountOfPassEntriesForTest
-- Returns the number of log entries indicating pass for the given test.
-- =======================================================================
CREATE FUNCTION Internal.SFN_GetCountOfPassEntriesForTest(@TestId int) RETURNS int
AS
BEGIN
DECLARE @PassEntries int
SELECT @PassEntries = COUNT(1)
FROM Data.TestLog
WHERE
TestLog.TestId = @TestId
AND EntryType = 'P'
RETURN ISNULL(@PassEntries, 0)
END
GO
-- =======================================================================
-- FUNCTION: SFN_GetCountOfFailOrErrorEntriesForTest
-- Returns the number of log entries indicating failures or
-- errors for the given test.
-- =======================================================================
CREATE FUNCTION Internal.SFN_GetCountOfFailOrErrorEntriesForTest(@TestId int) RETURNS int
AS
BEGIN
DECLARE @FailOrErrorEntries int
SELECT @FailOrErrorEntries = COUNT(1)
FROM Data.TestLog
WHERE
TestLog.TestId = @TestId
AND EntryType IN ('F', 'E')
RETURN ISNULL(@FailOrErrorEntries, 0)
END
GO
-- =======================================================================
-- FUNCTION: SFN_GetCountOfIgnoreEntriesForTest
-- Returns the number of log entries indicating 'Ignore' for the given test.
-- =======================================================================
CREATE FUNCTION Internal.SFN_GetCountOfIgnoreEntriesForTest(@TestId int) RETURNS int
AS
BEGIN
DECLARE @IgnoreEntries int
SELECT @IgnoreEntries = COUNT(1)
FROM Data.TestLog
WHERE
TestLog.TestId = @TestId
AND EntryType = 'I'
RETURN ISNULL(@IgnoreEntries, 0)
END
GO
-- =======================================================================
-- FUNCTION SFN_GetCountOfSuitesInSession
-- Returns the number of suites in the given session
-- =======================================================================
CREATE FUNCTION Internal.SFN_GetCountOfSuitesInSession(@TestSessionId int) RETURNS int
AS
BEGIN
DECLARE @CountOfSuitesInSession int
SELECT @CountOfSuitesInSession = COUNT(1)
FROM Data.Suite WHERE TestSessionId = @TestSessionId AND ISNULL(SuiteName, 'Anonymous') != '#SessionSetup#' AND ISNULL(SuiteName, 'Anonymous') != '#SessionTeardown#'
RETURN ISNULL(@CountOfSuitesInSession, 0)
END
GO
-- =======================================================================
-- FUNCTION SFN_GetCountOfTestsInSession
-- Returns the number of tests in the given session
-- =======================================================================
CREATE FUNCTION Internal.SFN_GetCountOfTestsInSession(@TestSessionId int) RETURNS int
AS
BEGIN
DECLARE @CountOfTestsInSession int
SELECT @CountOfTestsInSession = COUNT(1)
FROM Data.Test
WHERE
Test.TestSessionId = @TestSessionId
AND Test.SProcType = 'Test'
RETURN ISNULL(@CountOfTestsInSession, 0)
END
GO
-- =======================================================================
-- FUNCTION SFN_GetCountOfPassedTestsInSession
-- Returns the number of tests that have passed in the given session
-- =======================================================================
CREATE FUNCTION Internal.SFN_GetCountOfPassedTestsInSession(@TestSessionId int) RETURNS int
AS
BEGIN
DECLARE @CountOfPassedTestsInSession int
SELECT @CountOfPassedTestsInSession = COUNT(1)
FROM Data.Test
WHERE
Test.TestSessionId = @TestSessionId
AND Test.SProcType = 'Test'
AND Internal.SFN_GetCountOfPassEntriesForTest(Test.TestId) >= 1
AND Internal.SFN_GetCountOfIgnoreEntriesForTest(Test.TestId) = 0
AND Internal.SFN_GetCountOfFailOrErrorEntriesForTest(Test.TestId) = 0
RETURN ISNULL(@CountOfPassedTestsInSession, 0)
END
GO
-- =======================================================================
-- FUNCTION SFN_GetCountOfIgnoredTestsInSession
-- Returns the number of tests that have passed in the given session
-- =======================================================================
CREATE FUNCTION Internal.SFN_GetCountOfIgnoredTestsInSession(@TestSessionId int) RETURNS int
AS
BEGIN
DECLARE @CountOfIgnoredTestsInSession int
SELECT @CountOfIgnoredTestsInSession = COUNT(1)
FROM Data.Test
WHERE
Test.TestSessionId = @TestSessionId
AND Test.SProcType = 'Test'
AND Internal.SFN_GetCountOfIgnoreEntriesForTest(Test.TestId) >= 1
AND Internal.SFN_GetCountOfFailOrErrorEntriesForTest(Test.TestId) = 0
RETURN ISNULL(@CountOfIgnoredTestsInSession, 0)
END
GO
-- =======================================================================
-- FUNCTION SFN_GetCountOfFailedTestsInSession
-- Returns the number of failed tests in the given test session
-- =======================================================================
CREATE FUNCTION Internal.SFN_GetCountOfFailedTestsInSession(@TestSessionId int) RETURNS int
AS
BEGIN
DECLARE @CountOfFailedTestsInSession int
SELECT @CountOfFailedTestsInSession = COUNT(1)
FROM (
SELECT DISTINCT Test.TestId
FROM Data.TestLog
INNER JOIN Data.Test ON Test.TestId = TestLog.TestId
WHERE
TestLog.TestSessionId = @TestSessionId
AND TestLog.EntryType IN ('F', 'E')
AND Test.SProcType = 'Test'
) AS FailedTestsList
RETURN ISNULL(@CountOfFailedTestsInSession, 0)
END
GO
-- =======================================================================
-- FUNCTION SFN_SystemErrorsExistInSession
-- Returns a flag indicating if any system errors exist
-- in the given test session.
-- =======================================================================
CREATE FUNCTION Internal.SFN_SystemErrorsExistInSession(@TestSessionId int) RETURNS int
AS
BEGIN
IF EXISTS (SELECT * FROM Data.SystemErrorLog WHERE TestSessionId = @TestSessionId)
BEGIN
RETURN 1
END
RETURN 0
END
GO
-- =======================================================================
-- FUNCTION SFN_GetSessionStatus
-- Returns a flag indicating if the test session passed or failed.
-- 1 - The test session passed.
-- 0 - The test session failed.
-- in the given test session.
-- =======================================================================
CREATE FUNCTION Internal.SFN_GetSessionStatus(@TestSessionId int) RETURNS int
AS
BEGIN
DECLARE @ErrorOrFailuresExistInSession bit
DECLARE @SystemErrorsExistInSession bit
SET @ErrorOrFailuresExistInSession = Internal.SFN_ErrorOrFailuresExistInSession(@TestSessionId)
SET @SystemErrorsExistInSession = Internal.SFN_SystemErrorsExistInSession(@TestSessionId)
IF (@ErrorOrFailuresExistInSession = 1 OR @SystemErrorsExistInSession = 1) RETURN 0
RETURN 1
END
GO
-- =======================================================================
-- FUNCTION SFN_ErrorOrFailuresExistInSession
-- Returns a flag indicating if any errors or failures exist
-- in the given test session.
-- =======================================================================
CREATE FUNCTION Internal.SFN_ErrorOrFailuresExistInSession(@TestSessionId int) RETURNS int
AS
BEGIN
IF EXISTS (SELECT * FROM Data.TestLog WHERE TestLog.TestSessionId = @TestSessionId AND TestLog.EntryType IN ('F', 'E'))
BEGIN
RETURN 1
END
RETURN 0
END
GO
-- =======================================================================
-- FUNCTION SFN_GetSuiteTypeId
-- Returns an ID that can be used to order suites based on their type:
-- 0: Session Setup suite.
-- 1: The anonymous suite.
-- 2: A regular suite.
-- 3: Session Setup teardown.
-- =======================================================================
CREATE FUNCTION Internal.SFN_GetSuiteTypeId(@SuiteName sysname) RETURNS int
AS
BEGIN
IF (@SuiteName = '#SessionSetup#') RETURN 0
IF (@SuiteName = '#SessionTeardown#') RETURN 3
ELSE IF (@SuiteName IS NULL ) RETURN 1
RETURN 2
END
GO
-- =======================================================================
-- FUNCTION SFN_GetCountOfTestsInSuite
-- Returns the number of passed tests in the given suite
-- =======================================================================
CREATE FUNCTION Internal.SFN_GetCountOfTestsInSuite(@SuiteId int) RETURNS int
AS
BEGIN
DECLARE @CountOfTestInSuite int
SELECT @CountOfTestInSuite = COUNT(1)
FROM Data.Test
WHERE
Test.SuiteId = @SuiteId
AND Test.SProcType = 'Test'
RETURN ISNULL(@CountOfTestInSuite, 0)
END
GO
-- =======================================================================
-- FUNCTION SFN_GetCountOfFailedTestsInSuite
-- Returns the number of failed tests in the given suite
-- =======================================================================
CREATE FUNCTION Internal.SFN_GetCountOfFailedTestsInSuite(@SuiteId int) RETURNS int
AS
BEGIN
DECLARE @CountOfFailedTestInSuite int
SELECT @CountOfFailedTestInSuite = COUNT(1)
FROM (
SELECT DISTINCT Test.TestId
FROM Data.TestLog
INNER JOIN Data.Test ON TestLog.TestId = Test.TestId
WHERE
Test.SuiteId = @SuiteId
AND TestLog.EntryType IN ('F', 'E')
AND Test.SProcType = 'Test'
) AS FailedTestsList
RETURN ISNULL(@CountOfFailedTestInSuite, 0)
END
GO
-- =======================================================================
-- FUNCTION SFN_GetCountOfIgnoredTestsInSuite
-- Returns the number of ignored tests in the given suite
-- =======================================================================
CREATE FUNCTION Internal.SFN_GetCountOfIgnoredTestsInSuite(@SuiteId int) RETURNS int
AS
BEGIN
DECLARE @CountOfIgnoredTestInSuite int
SELECT @CountOfIgnoredTestInSuite = COUNT(1)
FROM Data.Test
WHERE
Test.SuiteId = @SuiteId
AND Test.SProcType = 'Test'
AND Internal.SFN_GetCountOfIgnoreEntriesForTest(Test.TestId) >= 1
AND Internal.SFN_GetCountOfFailOrErrorEntriesForTest(Test.TestId) = 0
RETURN ISNULL(@CountOfIgnoredTestInSuite, 0)
END
GO
-- =======================================================================
-- FUNCTION SFN_GetCountOfPassedTestsInSuite
-- Returns the number of passed tests in the given suite
-- =======================================================================
CREATE FUNCTION Internal.SFN_GetCountOfPassedTestsInSuite(@SuiteId int) RETURNS int
AS
BEGIN
DECLARE @CountOfPassedTestInSuite int
SELECT @CountOfPassedTestInSuite = COUNT(1)
FROM Data.Test
WHERE
Test.SuiteId = @SuiteId
AND Test.SProcType = 'Test'
AND Internal.SFN_GetCountOfPassEntriesForTest(Test.TestId) >= 1
AND Internal.SFN_GetCountOfIgnoreEntriesForTest(Test.TestId) = 0
AND Internal.SFN_GetCountOfFailOrErrorEntriesForTest(Test.TestId) = 0