1 // Licensed to the .NET Foundation under one or more agreements.
2 // The .NET Foundation licenses this file to you under the MIT license.
3 // See the LICENSE file in the project root for more information.
4 
5 using OLEDB.Test.ModuleCore;
6 using System.IO;
7 using System.Text;
8 using XmlCoreTest.Common;
9 
10 namespace System.Xml.Tests
11 {
12     public partial class CReaderFactory : CFactory
13     {
14         //Enum defined for different API calls. This is superset of the actual reader types.
15         protected enum ReaderOverload
16         {
17             StreamReader,
18             StringReader,
19             FileStream,
20             MemoryStream,
21             CoreReader,
22             CustomReader
23         };
24 
25         public enum ReadThru
26         {
27             XmlReader,
28             TextReader,
29             Stream
30         };
31 
32         //The required objects that will be used during the variation processing.
33         private XmlReaderSettings _settings = new XmlReaderSettings();
34         private XmlReaderSettings _underlyingSettings = new XmlReaderSettings();
35 
36         private Encoding _enc = null;
37         private Stream _stream = null;
38         private string _baseUri = null;
39         private TextReader _textReader = null;
40         private ReaderOverload _overload;
41         private XmlReader _factoryReader = null;
42         private XmlReader _underlyingReader = null;
43         protected short numEventHandlers = 0;
44 
45         // Parse Optional data specific to reader tests.
PreTest()46         protected override void PreTest()
47         {
48             SetupSettings();
49             Log("--Setup Settings Done");
50             SetupReadOverload();
51             Log("--Setup ReadOverload Done");
52             SetupEncoding();
53             Log("--Setup Encoding Done");
54             SetupBaseUri();
55             Log("--Setup BaseUri Done");
56             pstate = TestState.PreTest;
57         }
58 
PostTest()59         protected override void PostTest()
60         {
61             //Cleanup and release files you may hold.
62             if (_stream != null)
63                 _stream.Dispose();
64 
65             if (_textReader != null)
66                 _textReader.Dispose();
67 
68             if (_underlyingReader != null)
69                 _underlyingReader.Dispose();
70 
71             if (_factoryReader != null)
72                 _factoryReader.Dispose();
73 
74             pstate = TestState.Complete;
75         }
76 
77         /// <summary>
78         /// This method will test the read based on different settings.
79         /// It will call the correct overload and set the state properly.
80         /// </summary>
Test()81         protected override void Test()
82         {
83             CError.WriteLine("Testing : " + TestFileName);
84             string tempStr = null;
85 
86             switch (_overload)
87             {
88                 case ReaderOverload.StreamReader:
89                     _textReader = new StreamReader(FilePathUtil.getStream(GetFile(TestFileName)));
90                     CreateReader(ReadThru.TextReader);
91                     break;
92 
93                 case ReaderOverload.StringReader:
94                     StreamReader sr = new StreamReader(FilePathUtil.getStream(GetFile(TestFileName)));
95                     tempStr = sr.ReadToEnd();
96                     sr.Dispose();
97                     _textReader = new StringReader(tempStr);
98                     CreateReader(ReadThru.TextReader);
99                     break;
100 
101                 case ReaderOverload.FileStream:
102                     _stream = FilePathUtil.getStream(TestFileName);
103                     CreateReader(ReadThru.Stream);
104                     break;
105 
106                 case ReaderOverload.MemoryStream:
107                     StreamReader sr1 = new StreamReader(FilePathUtil.getStream(GetFile(TestFileName)));
108                     tempStr = sr1.ReadToEnd();
109                     sr1.Dispose();
110                     byte[] bits = _enc.GetBytes(tempStr);
111                     _stream = new MemoryStream(bits);
112                     CreateReader(ReadThru.Stream);
113                     break;
114                 case ReaderOverload.CoreReader:
115                     _underlyingSettings.DtdProcessing = DtdProcessing.Ignore;
116                     _underlyingSettings.ConformanceLevel = _settings.ConformanceLevel;
117                     StringReader strr = new StringReader(new StreamReader(FilePathUtil.getStream(GetFile(TestFileName))).ReadToEnd());
118                     _underlyingReader = ReaderHelper.CreateReader(_overload.ToString(),
119                                                                 strr,
120                                                                 false,
121                                                                 null,
122                                                                 _underlyingSettings,
123                                                                 (_settings.ConformanceLevel == ConformanceLevel.Fragment)); //should this be settings or underlyingSettings?
124                     CError.Compare(_underlyingReader != null, "ReaderHelper returned null Reader");
125                     CreateReader(ReadThru.XmlReader);
126                     break;
127                 case ReaderOverload.CustomReader:
128                     if (AsyncUtil.IsAsyncEnabled)
129                     {
130                         pstate = TestState.Skip;
131                         return;
132                     }
133                     if (_settings.ConformanceLevel != ConformanceLevel.Fragment)
134                         _underlyingReader = new CustomReader(FilePathUtil.getStream(GetFile(TestFileName)), false);
135                     else
136                         _underlyingReader = new CustomReader(FilePathUtil.getStream(GetFile(TestFileName)), true);
137 
138                     CError.Compare(_underlyingReader != null, "ReaderHelper returned null Reader");
139                     CreateReader(ReadThru.XmlReader);
140                     break;
141 
142                 default:
143                     throw new CTestFailedException("Unknown ReaderOverload: " + _overload);
144             }
145 
146             if (_underlyingReader != null)
147                 CError.WriteLineIgnore("Type of Reader : " + _underlyingReader.GetType());
148 
149             if (pstate == TestState.Pass) return;
150             CError.Compare(pstate, TestState.CreateSuccess, "Invalid State after Create: " + pstate);
151 
152             //By this time the factory Reader is already set up correctly. So we must go Consume it now.
153             CError.Compare(pstate != TestState.Pass && pstate == TestState.CreateSuccess, "Invalid state before Consuming Reader: " + pstate);
154 
155             //Call TestReader to Consume Reader;
156             TestReader();
157 
158             if (pstate == TestState.Pass) return;
159             CError.Compare(pstate != TestState.Pass && pstate == TestState.Consume, "Invalid state after Consuming Reader: " + pstate);
160         }
161 
TestReader()162         protected void TestReader()
163         {
164             pstate = TestState.Consume;
165             try
166             {
167                 ConsumeReader(_factoryReader);
168 
169                 if (!IsVariationValid)
170                 {
171                     //Invalid Case didn't throw exception.
172                     pstate = TestState.Error;
173                     DumpVariationInfo();
174                     throw new CTestFailedException("Invalid Variation didn't throw exception");
175                 }
176                 else
177                 {
178                     pstate = TestState.Pass;
179                 }
180             }
181             finally
182             {
183                 if (_factoryReader != null)
184                     _factoryReader.Dispose();
185             }
186 
187             //If you are not in PASS state at this point you are in Error.
188             if (pstate != TestState.Pass)
189                 pstate = TestState.Error;
190         }
191 
CompareSettings()192         protected void CompareSettings()
193         {
194             Log("Comparing ErrorSettings");
195             XmlReaderSettings actual = _factoryReader.Settings;
196             if (actual == null)
197                 throw new CTestFailedException("Factory Reader Settings returned null");
198 
199             CError.Compare(actual.CheckCharacters, _settings.CheckCharacters, "CheckCharacters");
200             CError.Compare(actual.IgnoreComments, _settings.IgnoreComments, "IgnoreComments");
201             CError.Compare(actual.IgnoreProcessingInstructions, _settings.IgnoreProcessingInstructions, "IgnorePI");
202             CError.Compare(actual.IgnoreWhitespace, _settings.IgnoreWhitespace, "IgnoreWhitespace");
203             CError.Compare(actual.LineNumberOffset, _settings.LineNumberOffset, "LinenumberOffset");
204             CError.Compare(actual.LinePositionOffset, _settings.LinePositionOffset, "LinePositionOffset");
205         }
206 
ConsumeReader(XmlReader reader)207         protected void ConsumeReader(XmlReader reader)
208         {
209             while (reader.Read())
210             {
211                 string x = reader.Name + reader.NodeType + reader.Value;
212                 if (reader.NodeType == XmlNodeType.Element)
213                 {
214                     if (reader.HasAttributes)
215                     {
216                         reader.MoveToFirstAttribute();
217                         int index = 0;
218                         reader.MoveToAttribute(index);
219                         index++;
220                         while (reader.MoveToNextAttribute())
221                         {
222                             string name = reader.Name;
223                             string value;
224 
225                             value = reader.GetAttribute(index);
226                             value = reader.GetAttribute(name);
227                             value = reader.GetAttribute(name, null);
228 
229                             reader.ReadAttributeValue();
230                             reader.MoveToAttribute(index);
231                             reader.MoveToAttribute(name, null);
232                             index++;
233                         }
234                     }
235                 }
236                 if (reader.NodeType == XmlNodeType.EndElement)
237                 {
238                     reader.Skip();
239                 }
240             }
241         }
242 
243 
244         /// <summary>
245         /// This method calls the Create Method on the XmlReader and puts the state in CreateSuccess or TestPass.
246         /// It goes in PASS also if the reader threw an expected error. In all other cases it should throw
247         /// TestFailedException.
248         /// </summary>
249         /// <param name="readThru">This param determines which overload to call.
250         /// In future on multiple overloads we can make this param
251         /// an enum which can be set using the spec file data</param>
CreateReader(ReadThru readThru)252         protected void CreateReader(ReadThru readThru)
253         {
254             // Assumption is that the Create method doesn't throw NullReferenceException and
255             // it is not the goal of this framework to test if they are thrown anywhere.
256             // but if they are thrown that's a problem and they shouldn't be caught but exposed.
257             try
258             {
259                 switch (readThru)
260                 {
261                     case ReadThru.TextReader:
262                         _factoryReader = ReaderHelper.Create(_textReader, _settings, _baseUri);
263                         break;
264                     case ReadThru.XmlReader:
265                         _factoryReader = ReaderHelper.Create(_underlyingReader, _settings);
266                         break;
267                     case ReadThru.Stream:
268                         _factoryReader = ReaderHelper.Create(_stream, _settings);
269                         break;
270                     default:
271                         throw new CTestFailedException("Unknown ReadThru type: " + readThru);
272                 }
273 
274                 pstate = TestState.CreateSuccess;
275             }
276             catch (ArgumentNullException ane)
277             {
278                 Log(ane.Message);
279                 Log(ane.StackTrace);
280                 if (!IsVariationValid)
281                 {
282                     if (!CheckException(ane))
283                     {
284                         pstate = TestState.Error;
285                         DumpVariationInfo();
286                         throw new CTestFailedException(
287                                 "Argument Null Exception Thrown in CreateMethod, is your variation data correct?");
288                     }
289                     else
290                     {
291                         //This means that the Exception was checked and everything is fine.
292                         pstate = TestState.Pass;
293                     }
294                 }
295                 else
296                 {
297                     pstate = TestState.Error;
298                     DumpVariationInfo();
299                     throw new CTestFailedException(
300                             "Argument Null Exception Thrown in CreateMethod, is your variation data correct?");
301                 }
302             }
303         }
304 
305         /// <summary>
306         /// Setup Settings basically reads the variation info and populates the info block.
307         ///    <ConformanceLevel>Fragment</ConformanceLevel>
308         ///    <CheckCharacters>true</CheckCharacters>
309         ///    <ReaderType>Dtd</ReaderType>
310         ///    <NameTable>new</NameTable>
311         ///    <LineNumberOffset>1</LineNumberOffset>
312         ///		 <LinePositionOffset>0</LinePositionOffset>
313         ///    <IgnoreInlineSchema>false</IgnoreInlineSchema>
314         ///    <IgnoreSchemaLocation>true</IgnoreSchemaLocation>
315         ///    <IgnoreIdentityConstraints>false</IgnoreIdentityConstraints>
316         ///		 <IgnoreValidationWarnings>true</IgnoreValidationWarnings>
317         ///    <Schemas>2</Schemas>
318         ///    <ValidationEventHandler>0</ValidationEventHandler>
319         ///    <ProhibitDtd>true</ProhibitDtd>
320         ///    <IgnoreWS>false</IgnoreWS>
321         ///    <IgnorePI>true</IgnorePI>
322         ///    <IgnoreCS>true</IgnoreCS>
323         /// </summary>
SetupSettings()324         private void SetupSettings()
325         {
326             _settings = new XmlReaderSettings();
327             _callbackWarningCount1 = 0;
328             _callbackWarningCount2 = 0;
329             _callbackErrorCount1 = 0;
330             _callbackErrorCount2 = 0;
331 
332             //Conformance Level
333             _settings.ConformanceLevel = (ConformanceLevel)Enum.Parse(typeof(ConformanceLevel), ReadFilterCriteria("ConformanceLevel", true));
334 
335             //CheckCharacters
336             _settings.CheckCharacters = Boolean.Parse(ReadFilterCriteria("CheckCharacters", true));
337 
338             //Reader Type : Parse and then set the Xsd or Dtd validation accordingly.
339             string readertype = ReadFilterCriteria("ReaderType", true);
340             switch (readertype)
341             {
342                 case "Dtd":
343                 case "Xsd":
344                 case "Binary":
345                     throw new CTestSkippedException("Skipped: ReaderType " + readertype);
346                 case "Core":
347                     break;
348                 default:
349                     throw new CTestFailedException("Unexpected ReaderType Criteria");
350             }
351 
352             //Nametable
353             string nt = ReadFilterCriteria("NameTable", true);
354             switch (nt)
355             {
356                 case "new":
357                     _settings.NameTable = new NameTable();
358                     break;
359                 case "null":
360                     _settings.NameTable = null;
361                     break;
362                 case "custom":
363                     _settings.NameTable = new MyNameTable();
364                     break;
365                 default:
366                     throw new CTestFailedException("Unexpected Nametable Criteria : " + nt);
367             }
368 
369             //Line number
370             _settings.LineNumberOffset = Int32.Parse(ReadFilterCriteria("LineNumberOffset", true));
371             //Line position
372             _settings.LinePositionOffset = Int32.Parse(ReadFilterCriteria("LinePositionOffset", true));
373 
374             _settings.IgnoreProcessingInstructions = Boolean.Parse(ReadFilterCriteria("IgnorePI", true));
375             _settings.IgnoreComments = Boolean.Parse(ReadFilterCriteria("IgnoreComments", true));
376             _settings.IgnoreWhitespace = Boolean.Parse(ReadFilterCriteria("IgnoreWhiteSpace", true));
377         }//End of SetupSettings
378 
379         //Validation Event Handlers and their Counts for Reader to verify
380         private int _callbackWarningCount1 = 0;
381         private int _callbackWarningCount2 = 0;
382         private int _callbackErrorCount1 = 0;
383         private int _callbackErrorCount2 = 0;
384 
385         public int EventWarningCount1
386         {
387             get { return _callbackWarningCount1; }
388         }
389 
390         public int EventWarningCount2
391         {
392             get { return _callbackWarningCount2; }
393         }
394 
395         public int EventErrorCount1
396         {
397             get { return _callbackErrorCount1; }
398         }
399 
400         public int EventErrorCount2
401         {
402             get { return _callbackErrorCount2; }
403         }
404 
405         /// <summary>
406         /// Sets up the Correct Read Overload Method to be called.
407         /// </summary>
SetupReadOverload()408         public void SetupReadOverload()
409         {
410             string ol = ReadFilterCriteria("Load", true);
411             if (ol == "HTTPStream" || ol == "FileName" || ol == "XmlTextReader" || ol == "XmlValidatingReader" || ol == "CoreValidatingReader"
412                 || ol == "CoreXsdReader" || ol == "XmlBinaryReader" || ol == "XPathNavigatorReader" || ol == "XmlNodeReader" || ol == "XmlNodeReaderDD"
413                 || ol == "XsltReader")
414             {
415                 throw new CTestSkippedException("Skipped: OverLoad " + ol);
416             }
417             _overload = (ReaderOverload)Enum.Parse(typeof(ReaderOverload), ol);
418         }
419 
SetupBaseUri()420         public void SetupBaseUri()
421         {
422             string bUri = ReadFilterCriteria("BaseUri", true);
423             switch (bUri)
424             {
425                 case "valid":
426                     _baseUri = GetPath(TestFileName, false);
427                     Log("Setting baseuri = " + _baseUri);
428                     break;
429                 case "~null":
430                     break;
431                 default:
432                     _baseUri = "";
433                     break;
434             }
435         }
436 
SetupEncoding()437         public void SetupEncoding()
438         {
439             string strEnc = ReadFilterCriteria("Encoding", true);
440             if (strEnc != "~null")
441                 _enc = Encoding.GetEncoding(strEnc);
442         }
443 
444         //Custom Nametable
445         public class MyNameTable : XmlNameTable
446         {
447             private NameTable _nt = new NameTable();
Get(string array)448             public override string Get(string array)
449             {
450                 return _nt.Get(array);
451             }
452 
Get(char[] array, int offset, int length)453             public override string Get(char[] array, int offset, int length)
454             {
455                 return _nt.Get(array, offset, length);
456             }
457 
Add(string array)458             public override string Add(string array)
459             {
460                 return _nt.Add(array);
461             }
462 
Add(char[] array, int offset, int length)463             public override string Add(char[] array, int offset, int length)
464             {
465                 return _nt.Add(array, offset, length);
466             }
467         }
468     }
469 }
470