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