1+ // Copyright (c) 2020 Jon P Smith, GitHub: JonPSmith, web: http://www.thereformedprogrammer.net/
2+ // Licensed under MIT license. See License.txt in the project root for license information.
3+
4+ using System . Collections . Generic ;
5+ using System . Linq ;
6+ using System . Threading . Tasks ;
7+ using DataLayer . BookApp . EfCode ;
8+ using DataLayer . Database1 ;
9+ using DataLayer . Database2 ;
10+ using Microsoft . EntityFrameworkCore ;
11+ using Npgsql ;
12+ using Test . Helpers ;
13+ using TestSupport . EfHelpers ;
14+ using TestSupport . Helpers ;
15+ using Xunit ;
16+ using Xunit . Abstractions ;
17+ using Xunit . Extensions . AssertExtensions ;
18+
19+ namespace Test . UnitTests . TestDataLayer
20+ {
21+ public class TestEnsureCleanPostgreSql
22+ {
23+ private readonly ITestOutputHelper _output ;
24+
25+ public TestEnsureCleanPostgreSql ( ITestOutputHelper output )
26+ {
27+ _output = output ;
28+ }
29+
30+ [ Fact ]
31+ public void TestEnsureDeletedThenCreateDatabase1Ok ( )
32+ {
33+ //SETUP
34+ var logToOptions = new LogToOptions
35+ {
36+ ShowLog = false
37+ } ;
38+ var options = this . CreatePostgreSqlUniqueClassOptionsWithLogTo < DbContext1 > ( log => _output . WriteLine ( log ) , logToOptions ) ;
39+ using ( var context = new DbContext1 ( options ) )
40+ {
41+ context . Database . EnsureDeleted ( ) ;
42+
43+ //ATTEMPT
44+ logToOptions . ShowLog = true ;
45+ using ( new TimeThings ( _output , "Time to create a new database" ) )
46+ context . Database . EnsureClean ( ) ;
47+ logToOptions . ShowLog = false ;
48+
49+ //VERIFY
50+ context . Add ( new TopClass1 ( ) ) ;
51+ context . SaveChanges ( ) ;
52+ }
53+ }
54+
55+ [ Fact ]
56+ public void TestEnsureCreatedThenCreateDatabase1Ok ( )
57+ {
58+ //SETUP
59+ var options = this . CreatePostgreSqlUniqueClassOptions < DbContext1 > ( ) ;
60+ using ( var context = new DbContext1 ( options ) )
61+ {
62+ context . Database . EnsureCreated ( ) ;
63+
64+ //ATTEMPT
65+ using ( new TimeThings ( _output , "Time to update schema of a database" ) )
66+ context . Database . EnsureClean ( ) ;
67+
68+ //VERIFY
69+ context . Add ( new TopClass1 ( ) ) ;
70+ context . SaveChanges ( ) ;
71+ }
72+ }
73+
74+ [ Fact ]
75+ public void TestEnsureDeletedThenCreateDatabase2Ok ( )
76+ {
77+ //SETUP
78+ var logToOptions = new LogToOptions
79+ {
80+ ShowLog = false
81+ } ;
82+ var options = this . CreatePostgreSqlUniqueClassOptionsWithLogTo < DbContext2 > ( log => _output . WriteLine ( log ) , logToOptions ) ;
83+ using ( var context = new DbContext2 ( options ) )
84+ {
85+ context . Database . EnsureDeleted ( ) ;
86+
87+ //ATTEMPT
88+ logToOptions . ShowLog = true ;
89+ context . Database . EnsureClean ( ) ;
90+ logToOptions . ShowLog = false ;
91+
92+ //VERIFY
93+ context . Add ( new TopClass2 ( ) ) ;
94+ context . SaveChanges ( ) ;
95+ }
96+ }
97+
98+ [ Fact ]
99+ public void TestWipeDataDatabase1Ok ( )
100+ {
101+ //SETUP
102+ var options = this . CreatePostgreSqlUniqueMethodOptions < DbContext1 > ( ) ;
103+ using ( var context = new DbContext1 ( options ) )
104+ {
105+ context . Database . EnsureCreated ( ) ;
106+ context . Add ( new TopClass1 { Dependents = new List < Dependent1 > { new Dependent1 ( ) } } ) ;
107+ context . SaveChanges ( ) ;
108+ context . TopClasses . Count ( ) . ShouldEqual ( 1 ) ;
109+ context . Dependents . Count ( ) . ShouldEqual ( 1 ) ;
110+
111+ //ATTEMPT
112+ using ( new TimeThings ( _output , "Time to clean a PostgreSQL database" ) )
113+ context . Database . EnsureClean ( ) ;
114+
115+ //VERIFY
116+ context . TopClasses . Count ( ) . ShouldEqual ( 0 ) ;
117+ context . Dependents . Count ( ) . ShouldEqual ( 0 ) ;
118+ }
119+ }
120+
121+ [ Fact ]
122+ public void TestWipeDataDatabase2Ok ( )
123+ {
124+ //SETUP
125+ var options = this . CreatePostgreSqlUniqueMethodOptions < DbContext2 > ( ) ;
126+ using ( var context = new DbContext2 ( options ) )
127+ {
128+ context . Database . EnsureCreated ( ) ;
129+ context . Add ( new TopClass2 { Dependents = new List < Dependent2 > { new Dependent2 ( ) } } ) ;
130+ context . SaveChanges ( ) ;
131+ context . TopClasses . Count ( ) . ShouldEqual ( 1 ) ;
132+ context . Dependents . Count ( ) . ShouldEqual ( 1 ) ;
133+
134+ //ATTEMPT
135+ context . Database . EnsureClean ( ) ;
136+
137+ //VERIFY
138+ context . TopClasses . Count ( ) . ShouldEqual ( 0 ) ;
139+ context . Dependents . Count ( ) . ShouldEqual ( 0 ) ;
140+ }
141+ }
142+
143+ [ Fact ]
144+ public void TestDatabase1SchemaChangeToDatabase2Ok ( )
145+ {
146+ //SETUP
147+ var connectionString = this . GetUniquePostgreSqlConnectionString ( ) ;
148+ var builder1 = new DbContextOptionsBuilder < DbContext1 > ( ) ;
149+ using ( var context = new DbContext1 ( builder1 . UseNpgsql ( connectionString ) . Options ) )
150+ using ( new TimeThings ( _output , "EnsureDeleted/EnsureCreated" ) )
151+ {
152+ context . Database . EnsureDeleted ( ) ;
153+ context . Database . EnsureCreated ( ) ;
154+ }
155+ var builder2 = new DbContextOptionsBuilder < DbContext2 > ( ) ;
156+ using ( var context = new DbContext2 ( builder2 . UseNpgsql ( connectionString ) . Options ) )
157+ {
158+ //ATTEMPT
159+ using ( new TimeThings ( _output , "EnsureClean" ) )
160+ {
161+ context . Database . EnsureClean ( ) ;
162+ }
163+
164+ //VERIFY
165+ context . Add ( new TopClass2 ( ) ) ;
166+ context . SaveChanges ( ) ;
167+ }
168+ }
169+
170+ [ Fact ]
171+ public void TestEnsureCleanNotSetSchema ( )
172+ {
173+ //SETUP
174+ var connectionString = this . GetUniquePostgreSqlConnectionString ( ) ;
175+ var builder = new DbContextOptionsBuilder < DbContext1 > ( ) ;
176+ using ( var context = new DbContext1 ( builder . UseNpgsql ( connectionString ) . Options ) )
177+ {
178+ context . Database . EnsureCreated ( ) ;
179+ CountTablesInDatabase ( context ) . ShouldNotEqual ( 0 ) ;
180+
181+ //ATTEMPT-VERIFY1
182+ context . Database . EnsureClean ( false ) ;
183+ CountTablesInDatabase ( context ) . ShouldEqual ( - 1 ) ;
184+
185+ //ATTEMPT-VERIFY2
186+ context . Database . EnsureCreated ( ) ;
187+ CountTablesInDatabase ( context ) . ShouldNotEqual ( 0 ) ;
188+ }
189+ }
190+
191+ //This proves that PostgreSQL EnsureClean does delete the default named migration history table
192+ [ Fact ]
193+ public void TestEnsureCleanApplyMigrationOk ( )
194+ {
195+ //SETUP
196+ var options = this . CreatePostgreSqlUniqueClassOptions < BookContext > ( ) ;
197+ using var context = new BookContext ( options ) ;
198+
199+ //ATTEMPT
200+ context . Database . EnsureClean ( false ) ;
201+ context . Database . Migrate ( ) ;
202+
203+ //VERIFY
204+ context . Books . Count ( ) . ShouldEqual ( 0 ) ;
205+ }
206+
207+ [ Fact ]
208+ public async Task TestRespawnOk ( )
209+ {
210+ //SETUP
211+ var options = this . CreatePostgreSqlUniqueMethodOptions < BookContext > ( ) ;
212+ using var context = new BookContext ( options ) ;
213+ context . Database . EnsureCreated ( ) ;
214+
215+ //ATTEMPT
216+ using ( new TimeThings ( _output ) )
217+ await context . EnsureCreatedAndEmptyPostgreSqlAsync ( ) ;
218+
219+ //VERIFY
220+ context . Books . Count ( ) . ShouldEqual ( 0 ) ;
221+ }
222+
223+
224+ private int CountTablesInDatabase ( DbContext context )
225+ {
226+ return context . Database . ExecuteSqlRaw (
227+ $ "select count(*) from information_schema.tables;") ;
228+ }
229+ }
230+ }
0 commit comments