1+ //------------------------------------------------------------
2+ // Copyright (c) Microsoft Corporation. All rights reserved.
3+ //------------------------------------------------------------
4+
5+ namespace Microsoft . Azure . Cosmos . SDK . EmulatorTests
6+ {
7+ using System ;
8+ using System . Collections . Generic ;
9+ using System . IO ;
10+ using System . Linq ;
11+ using System . Net ;
12+ using System . Text . Json ;
13+ using System . Text . Json . Serialization ;
14+ using System . Threading . Tasks ;
15+ using Microsoft . VisualStudio . TestTools . UnitTesting ;
16+ using static Microsoft . Azure . Cosmos . SDK . EmulatorTests . MultiRegionSetupHelpers ;
17+ using TestObject = MultiRegionSetupHelpers . CosmosIntegrationTestObject ;
18+
19+ [ TestClass ]
20+ public class CosmosItemThinClientTests
21+ {
22+ private string connectionString ;
23+ private CosmosClient client ;
24+ private Database database ;
25+ private Container container ;
26+ private CosmosSystemTextJsonSerializer cosmosSystemTextJsonSerializer ;
27+
28+ private const int ItemCount = 1000 ;
29+
30+ [ TestInitialize ]
31+ public async Task TestInitAsync ( )
32+ {
33+ this . connectionString = Environment . GetEnvironmentVariable ( "COSMOSDB_THINCLIENT" ) ;
34+ Environment . SetEnvironmentVariable ( ConfigurationManager . ThinClientModeEnabled , "True" ) ;
35+
36+ if ( string . IsNullOrEmpty ( this . connectionString ) )
37+ {
38+ Assert . Fail ( "Set environment variable COSMOSDB_THINCLIENT to run the tests" ) ;
39+ }
40+
41+ JsonSerializerOptions jsonSerializerOptions = new JsonSerializerOptions
42+ {
43+ PropertyNamingPolicy = null ,
44+ PropertyNameCaseInsensitive = true ,
45+ DefaultIgnoreCondition = JsonIgnoreCondition . WhenWritingNull
46+ } ;
47+ this . cosmosSystemTextJsonSerializer = new MultiRegionSetupHelpers . CosmosSystemTextJsonSerializer ( jsonSerializerOptions ) ;
48+
49+ this . client = new CosmosClient (
50+ this . connectionString ,
51+ new CosmosClientOptions ( )
52+ {
53+ ConnectionMode = ConnectionMode . Gateway ,
54+ Serializer = this . cosmosSystemTextJsonSerializer ,
55+ } ) ;
56+
57+ string uniqueDbName = "TestDb_" + Guid . NewGuid ( ) . ToString ( ) ;
58+ this . database = await this . client . CreateDatabaseIfNotExistsAsync ( uniqueDbName ) ;
59+ string uniqueContainerName = "TestContainer_" + Guid . NewGuid ( ) . ToString ( ) ;
60+ this . container = await this . database . CreateContainerIfNotExistsAsync ( uniqueContainerName , "/pk" ) ;
61+ }
62+
63+
64+ [ TestCleanup ]
65+ public async Task TestCleanupAsync ( )
66+ {
67+ Environment . SetEnvironmentVariable ( ConfigurationManager . ThinClientModeEnabled , "False" ) ;
68+
69+ if ( this . database != null )
70+ {
71+ await this . database . DeleteAsync ( ) ;
72+ }
73+
74+ this . client ? . Dispose ( ) ;
75+ }
76+
77+ private IEnumerable < TestObject > GenerateItems ( string partitionKey )
78+ {
79+ List < TestObject > items = new List < TestObject > ( ) ;
80+ for ( int i = 0 ; i < ItemCount ; i ++ )
81+ {
82+ items . Add ( new TestObject
83+ {
84+ Id = Guid . NewGuid ( ) . ToString ( ) ,
85+ Pk = partitionKey ,
86+ Other = "Test Item " + i
87+ } ) ;
88+ }
89+
90+ return items ;
91+ }
92+
93+ [ TestMethod ]
94+ [ TestCategory ( "ThinClient" ) ]
95+ public async Task CreateItemsTest ( )
96+ {
97+ string pk = "pk_create" ;
98+ IEnumerable < TestObject > items = this . GenerateItems ( pk ) ;
99+
100+ foreach ( TestObject item in items )
101+ {
102+ ItemResponse < TestObject > response = await this . container . CreateItemAsync ( item , new PartitionKey ( item . Pk ) ) ;
103+ Assert . AreEqual ( HttpStatusCode . Created , response . StatusCode ) ;
104+ }
105+ }
106+
107+ [ TestMethod ]
108+ [ TestCategory ( "ThinClient" ) ]
109+ public async Task ReadItemsTest ( )
110+ {
111+ string pk = "pk_read" ;
112+ List < TestObject > items = this . GenerateItems ( pk ) . ToList ( ) ;
113+
114+ foreach ( TestObject item in items )
115+ {
116+ await this . container . CreateItemAsync ( item , new PartitionKey ( item . Pk ) ) ;
117+ }
118+
119+ foreach ( TestObject item in items )
120+ {
121+ ItemResponse < TestObject > response = await this . container . ReadItemAsync < TestObject > ( item . Id , new PartitionKey ( item . Pk ) ) ;
122+ Assert . AreEqual ( HttpStatusCode . OK , response . StatusCode ) ;
123+ Assert . AreEqual ( item . Id , response . Resource . Id ) ;
124+ }
125+ }
126+
127+ [ TestMethod ]
128+ [ TestCategory ( "ThinClient" ) ]
129+ public async Task ReplaceItemsTest ( )
130+ {
131+ string pk = "pk_replace" ;
132+ List < TestObject > items = this . GenerateItems ( pk ) . ToList ( ) ;
133+
134+ foreach ( TestObject item in items )
135+ {
136+ await this . container . CreateItemAsync ( item , new PartitionKey ( item . Pk ) ) ;
137+ }
138+
139+ foreach ( TestObject item in items )
140+ {
141+ TestObject updatedItem = new TestObject
142+ {
143+ Id = item . Id ,
144+ Pk = item . Pk ,
145+ Other = "Updated " + item . Other
146+ } ;
147+
148+ ItemResponse < TestObject > response = await this . container . ReplaceItemAsync ( updatedItem , updatedItem . Id , new PartitionKey ( updatedItem . Pk ) ) ;
149+ Assert . AreEqual ( HttpStatusCode . OK , response . StatusCode ) ;
150+ Assert . AreEqual ( "Updated " + item . Other , response . Resource . Other ) ;
151+ }
152+ }
153+
154+ [ TestMethod ]
155+ [ TestCategory ( "ThinClient" ) ]
156+ public async Task UpsertItemsTest ( )
157+ {
158+ string pk = "pk_upsert" ;
159+ IEnumerable < TestObject > items = this . GenerateItems ( pk ) ;
160+
161+ foreach ( TestObject item in items )
162+ {
163+ ItemResponse < TestObject > response = await this . container . UpsertItemAsync ( item , new PartitionKey ( item . Pk ) ) ;
164+ Assert . IsTrue ( response . StatusCode == HttpStatusCode . Created || response . StatusCode == HttpStatusCode . OK ) ;
165+ }
166+ }
167+
168+ [ TestMethod ]
169+ [ TestCategory ( "ThinClient" ) ]
170+ public async Task DeleteItemsTest ( )
171+ {
172+ string pk = "pk_delete" ;
173+ List < TestObject > items = this . GenerateItems ( pk ) . ToList ( ) ;
174+
175+ foreach ( TestObject item in items )
176+ {
177+ await this . container . CreateItemAsync ( item , new PartitionKey ( item . Pk ) ) ;
178+ }
179+
180+ foreach ( TestObject item in items )
181+ {
182+ ItemResponse < TestObject > response = await this . container . DeleteItemAsync < TestObject > ( item . Id , new PartitionKey ( item . Pk ) ) ;
183+ Assert . AreEqual ( HttpStatusCode . NoContent , response . StatusCode ) ;
184+ }
185+ }
186+
187+ [ TestMethod ]
188+ [ TestCategory ( "ThinClient" ) ]
189+ public async Task CreateItemStreamTest ( )
190+ {
191+ string pk = "pk_create_stream" ;
192+ IEnumerable < TestObject > items = this . GenerateItems ( pk ) ;
193+
194+ foreach ( TestObject item in items )
195+ {
196+ using ( Stream stream = this . cosmosSystemTextJsonSerializer . ToStream ( item ) )
197+ {
198+ using ( ResponseMessage response = await this . container . CreateItemStreamAsync ( stream , new PartitionKey ( item . Pk ) ) )
199+ {
200+ Assert . AreEqual ( HttpStatusCode . Created , response . StatusCode ) ;
201+ }
202+ }
203+ }
204+ }
205+
206+ [ TestMethod ]
207+ [ TestCategory ( "ThinClient" ) ]
208+ public async Task ReadItemStreamTest ( )
209+ {
210+ string pk = "pk_read_stream" ;
211+ List < TestObject > items = this . GenerateItems ( pk ) . ToList ( ) ;
212+
213+ foreach ( TestObject item in items )
214+ {
215+ await this . container . CreateItemAsync ( item , new PartitionKey ( item . Pk ) ) ;
216+ }
217+
218+ foreach ( TestObject item in items )
219+ {
220+ using ( ResponseMessage response = await this . container . ReadItemStreamAsync ( item . Id , new PartitionKey ( item . Pk ) ) )
221+ {
222+ Assert . AreEqual ( HttpStatusCode . OK , response . StatusCode ) ;
223+ }
224+ }
225+ }
226+
227+ [ TestMethod ]
228+ [ TestCategory ( "ThinClient" ) ]
229+ public async Task ReplaceItemStreamTest ( )
230+ {
231+ string pk = "pk_replace_stream" ;
232+ List < TestObject > items = this . GenerateItems ( pk ) . ToList ( ) ;
233+
234+ foreach ( TestObject item in items )
235+ {
236+ await this . container . CreateItemAsync ( item , new PartitionKey ( item . Pk ) ) ;
237+ }
238+
239+ foreach ( TestObject item in items )
240+ {
241+ TestObject updatedItem = new TestObject
242+ {
243+ Id = item . Id ,
244+ Pk = item . Pk ,
245+ Other = "Updated " + item . Other
246+ } ;
247+
248+ using ( Stream stream = this . cosmosSystemTextJsonSerializer . ToStream ( updatedItem ) )
249+ {
250+ using ( ResponseMessage response = await this . container . ReplaceItemStreamAsync ( stream , updatedItem . Id , new PartitionKey ( updatedItem . Pk ) ) )
251+ {
252+ Assert . AreEqual ( HttpStatusCode . OK , response . StatusCode ) ;
253+ }
254+ }
255+ }
256+ }
257+
258+ [ TestMethod ]
259+ [ TestCategory ( "ThinClient" ) ]
260+ public async Task UpsertItemStreamTest ( )
261+ {
262+ string pk = "pk_upsert_stream" ;
263+ IEnumerable < TestObject > items = this . GenerateItems ( pk ) ;
264+
265+ foreach ( TestObject item in items )
266+ {
267+ using ( Stream stream = this . cosmosSystemTextJsonSerializer . ToStream ( item ) )
268+ {
269+ using ( ResponseMessage response = await this . container . UpsertItemStreamAsync ( stream , new PartitionKey ( item . Pk ) ) )
270+ {
271+ Assert . IsTrue ( response . StatusCode == HttpStatusCode . Created || response . StatusCode == HttpStatusCode . OK ) ;
272+ }
273+ }
274+ }
275+ }
276+
277+ [ TestMethod ]
278+ [ TestCategory ( "ThinClient" ) ]
279+ public async Task DeleteItemStreamTest ( )
280+ {
281+ string pk = "pk_delete_stream" ;
282+ List < TestObject > items = this . GenerateItems ( pk ) . ToList ( ) ;
283+
284+ foreach ( TestObject item in items )
285+ {
286+ await this . container . CreateItemAsync ( item , new PartitionKey ( item . Pk ) ) ;
287+ }
288+
289+ foreach ( TestObject item in items )
290+ {
291+ using ( ResponseMessage response = await this . container . DeleteItemStreamAsync ( item . Id , new PartitionKey ( item . Pk ) ) )
292+ {
293+ Assert . AreEqual ( HttpStatusCode . NoContent , response . StatusCode ) ;
294+ }
295+ }
296+ }
297+
298+ [ TestMethod ]
299+ [ TestCategory ( "ThinClient" ) ]
300+ public async Task QueryItemsTest ( )
301+ {
302+ string pk = "pk_query" ;
303+ List < TestObject > items = this . GenerateItems ( pk ) . ToList ( ) ;
304+
305+ foreach ( TestObject item in items )
306+ {
307+ await this . container . CreateItemAsync ( item , new PartitionKey ( item . Pk ) ) ;
308+ }
309+
310+ string query = $ "SELECT * FROM c WHERE c.partitionKey = '{ pk } '";
311+ FeedIterator < TestObject > iterator = this . container . GetItemQueryIterator < TestObject > ( query ) ;
312+
313+ int count = 0 ;
314+ while ( iterator . HasMoreResults )
315+ {
316+ FeedResponse < TestObject > response = await iterator . ReadNextAsync ( ) ;
317+ count += response . Count ;
318+ }
319+
320+ Assert . AreEqual ( ItemCount , count ) ;
321+ }
322+
323+ [ TestMethod ]
324+ [ TestCategory ( "ThinClient" ) ]
325+ public async Task QueryItemsStreamTest ( )
326+ {
327+ string pk = "pk_query_stream" ;
328+ List < TestObject > items = this . GenerateItems ( pk ) . ToList ( ) ;
329+
330+ foreach ( dynamic item in items )
331+ {
332+ await this . container . CreateItemAsync ( item , new PartitionKey ( item . partitionKey ) ) ;
333+ }
334+
335+ QueryDefinition query = new QueryDefinition ( "SELECT * FROM c WHERE c.partitionKey = @pk" ) . WithParameter ( "@pk" , pk ) ;
336+ FeedIterator iterator = this . container . GetItemQueryStreamIterator ( query ) ;
337+
338+ int count = 0 ;
339+ while ( iterator . HasMoreResults )
340+ {
341+ using ( ResponseMessage response = await iterator . ReadNextAsync ( ) )
342+ {
343+ Assert . AreEqual ( HttpStatusCode . OK , response . StatusCode ) ;
344+
345+ using ( StreamReader reader = new StreamReader ( response . Content ) )
346+ {
347+ string json = await reader . ReadToEndAsync ( ) ;
348+ using ( JsonDocument doc = JsonDocument . Parse ( json ) )
349+ {
350+ count += doc . RootElement . GetProperty ( "Documents" ) . GetArrayLength ( ) ;
351+ }
352+ }
353+ }
354+ }
355+
356+ Assert . AreEqual ( ItemCount , count ) ;
357+ }
358+ }
359+ }
0 commit comments