Skip to content

Commit a9bf05b

Browse files
authored
Fix XmlSqlBinaryReader and introduce a corpus of SqlXml tests (#81878)
* Fix XmlSqlBinaryReader and introduce a corpus of SqlXml tests * Revert solution file changes made by VS * Use runtime-assets test files for Text and SQL Binary XML tests * Remove System.Data.Common.TestData package reference * Reference the System.Data.Common.TestData package for SqlXml tests * Add System.Common.Data.TestData to Version.Details.xml for automated dependency flow
1 parent e1edb16 commit a9bf05b

File tree

5 files changed

+100
-38
lines changed

5 files changed

+100
-38
lines changed

eng/Version.Details.xml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -164,6 +164,10 @@
164164
<Uri>https://github.com/dotnet/runtime-assets</Uri>
165165
<Sha>758d8a04223a3238863dd28bce0ec2e20b3bb960</Sha>
166166
</Dependency>
167+
<Dependency Name="System.Data.Common.TestData" Version="8.0.0-beta.23110.1">
168+
<Uri>https://github.com/dotnet/runtime-assets</Uri>
169+
<Sha>758d8a04223a3238863dd28bce0ec2e20b3bb960</Sha>
170+
</Dependency>
167171
<Dependency Name="System.Drawing.Common.TestData" Version="8.0.0-beta.23110.1">
168172
<Uri>https://github.com/dotnet/runtime-assets</Uri>
169173
<Sha>758d8a04223a3238863dd28bce0ec2e20b3bb960</Sha>

eng/Versions.props

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,7 @@
149149
<!-- Runtime-Assets dependencies -->
150150
<SystemRuntimeNumericsTestDataVersion>8.0.0-beta.23110.1</SystemRuntimeNumericsTestDataVersion>
151151
<SystemComponentModelTypeConverterTestDataVersion>8.0.0-beta.23110.1</SystemComponentModelTypeConverterTestDataVersion>
152+
<SystemDataCommonTestDataVersion>8.0.0-beta.23110.1</SystemDataCommonTestDataVersion>
152153
<SystemDrawingCommonTestDataVersion>8.0.0-beta.23110.1</SystemDrawingCommonTestDataVersion>
153154
<SystemFormatsTarTestDataVersion>8.0.0-beta.23110.1</SystemFormatsTarTestDataVersion>
154155
<SystemIOCompressionTestDataVersion>8.0.0-beta.23110.1</SystemIOCompressionTestDataVersion>

src/libraries/System.Data.Common/tests/System.Data.Common.Tests.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,7 @@
121121
</ItemGroup>
122122
<!-- S.D.SqlClient isn't live built anymore. -->
123123
<ItemGroup>
124+
<PackageReference Include="System.Data.Common.TestData" Version="$(SystemDataCommonTestDataVersion)" />
124125
<PackageReference Include="System.Data.SqlClient" Version="$(SystemDataSqlClientVersion)" />
125126
</ItemGroup>
126127
</Project>

src/libraries/System.Data.Common/tests/System/Data/SqlTypes/SqlXmlTest.cs

Lines changed: 91 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,11 @@
11
// Licensed to the .NET Foundation under one or more agreements.
22
// The .NET Foundation licenses this file to you under the MIT license.
33

4-
//
5-
// Permission is hereby granted, free of charge, to any person obtaining
6-
// a copy of this software and associated documentation files (the
7-
// "Software"), to deal in the Software without restriction, including
8-
// without limitation the rights to use, copy, modify, merge, publish,
9-
// distribute, sublicense, and/or sell copies of the Software, and to
10-
// permit persons to whom the Software is furnished to do so, subject to
11-
// the following conditions:
12-
//
13-
// The above copyright notice and this permission notice shall be
14-
// included in all copies or substantial portions of the Software.
15-
//
16-
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17-
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18-
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19-
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20-
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21-
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22-
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23-
4+
using System.Collections;
5+
using System.Collections.Generic;
246
using System.Data.SqlTypes;
257
using System.IO;
8+
using System.Linq;
269
using System.Text;
2710
using System.Xml;
2811

@@ -32,10 +15,8 @@ namespace System.Data.Tests.SqlTypes
3215
{
3316
public class SqlXmlTest
3417
{
35-
// Test constructor
36-
[Fact] // .ctor (Stream)
37-
//[Category ("NotDotNet")] // Name cannot begin with the '.' character, hexadecimal value 0x00. Line 1, position 2
38-
public void Constructor2_Stream_Unicode()
18+
[Fact]
19+
public void Constructor_Stream_Unicode()
3920
{
4021
string xmlStr = "<Employee><FirstName>Varadhan</FirstName><LastName>Veerapuram</LastName></Employee>";
4122
MemoryStream stream = new MemoryStream(Encoding.Unicode.GetBytes(xmlStr));
@@ -44,8 +25,8 @@ public void Constructor2_Stream_Unicode()
4425
Assert.Equal(xmlStr, xmlSql.Value);
4526
}
4627

47-
[Fact] // .ctor (Stream)
48-
public void Constructor2_Stream_Empty()
28+
[Fact]
29+
public void Constructor_Stream_Empty()
4930
{
5031
MemoryStream ms = new MemoryStream();
5132
SqlXml xmlSql = new SqlXml(ms);
@@ -54,16 +35,16 @@ public void Constructor2_Stream_Empty()
5435
}
5536

5637
[Fact]
57-
public void Constructor2_Stream_Null()
38+
public void Constructor_Stream_Null()
5839
{
5940
SqlXml xmlSql = new SqlXml((Stream)null);
6041
Assert.True(xmlSql.IsNull);
6142

6243
Assert.Throws<SqlNullValueException>(() => xmlSql.Value);
6344
}
6445

65-
[Fact] // .ctor (XmlReader)
66-
public void Constructor3()
46+
[Fact]
47+
public void Constructor_StringReader()
6748
{
6849
string xmlStr = "<Employee><FirstName>Varadhan</FirstName><LastName>Veerapuram</LastName></Employee>";
6950
XmlReader xrdr = new XmlTextReader(new StringReader(xmlStr));
@@ -72,8 +53,8 @@ public void Constructor3()
7253
Assert.Equal(xmlStr, xmlSql.Value);
7354
}
7455

75-
[Fact] // .ctor (XmlReader)
76-
public void Constructor3_XmlReader_Empty()
56+
[Fact]
57+
public void Constructor_XmlReader_Empty()
7758
{
7859
XmlReaderSettings xs = new XmlReaderSettings();
7960
xs.ConformanceLevel = ConformanceLevel.Fragment;
@@ -84,7 +65,7 @@ public void Constructor3_XmlReader_Empty()
8465
}
8566

8667
[Fact]
87-
public void Constructor3_XmlReader_Null()
68+
public void Constructor_XmlReader_Null()
8869
{
8970
SqlXml xmlSql = new SqlXml((XmlReader)null);
9071
Assert.True(xmlSql.IsNull);
@@ -93,7 +74,6 @@ public void Constructor3_XmlReader_Null()
9374
}
9475

9576
[Fact]
96-
//[Category ("NotDotNet")] // Name cannot begin with the '.' character, hexadecimal value 0x00. Line 1, position 2
9777
public void CreateReader_Stream_Unicode()
9878
{
9979
string xmlStr = "<Employee><FirstName>Varadhan</FirstName><LastName>Veerapuram</LastName></Employee>";
@@ -107,7 +87,7 @@ public void CreateReader_Stream_Unicode()
10787
}
10888

10989
[Fact]
110-
public void SqlXml_fromXmlReader_CreateReaderTest()
90+
public void CreateReader_XmlTextReader_CanReadContent()
11191
{
11292
string xmlStr = "<Employee><FirstName>Varadhan</FirstName><LastName>Veerapuram</LastName></Employee>";
11393
XmlReader rdr = new XmlTextReader(new StringReader(xmlStr));
@@ -119,8 +99,82 @@ public void SqlXml_fromXmlReader_CreateReaderTest()
11999
Assert.Equal(xmlStr, xrdr.ReadOuterXml());
120100
}
121101

102+
public static class CreateReader_TestFiles
103+
{
104+
private static TheoryData<string, string> _filesAndBaselines;
105+
106+
// The test files are made available through the System.Data.Common.TestData package included in dotnet/runtime-assets
107+
private static void EnsureFileList()
108+
{
109+
if (_filesAndBaselines is null)
110+
{
111+
IEnumerable<string> text = Directory.EnumerateFiles(Path.Combine("SqlXml.CreateReader", "Baseline-Text"), "*.xml");
112+
IEnumerable<string> binary = Directory.EnumerateFiles(Path.Combine("SqlXml.CreateReader", "SqlBinaryXml"), "*.bmx");
113+
114+
// Make sure that we found our test files; otherwise the theories would succeed without validating anything
115+
Assert.NotEmpty(text);
116+
Assert.NotEmpty(binary);
117+
118+
TheoryData<string, string> filesAndBaselines = new TheoryData<string, string>();
119+
120+
// Use the Text XML files as their own baselines
121+
filesAndBaselines.Append(text.Select(f => new string[] { TextXmlFileName(f), TextXmlFileName(f) }).ToArray());
122+
123+
// Use the matching Text XML files as the baselines for the SQL Binary XML files
124+
filesAndBaselines.Append(binary
125+
.Select(Path.GetFileNameWithoutExtension)
126+
.Intersect(text.Select(Path.GetFileNameWithoutExtension))
127+
.Select(f => new string[] { SqlBinaryXmlFileName(f), TextXmlFileName(f) }).ToArray());
128+
129+
_filesAndBaselines = filesAndBaselines;
130+
131+
string TextXmlFileName(string name) => Path.Combine("SqlXml.CreateReader", "Baseline-Text", $"{name}.xml");
132+
string SqlBinaryXmlFileName(string name) => Path.Combine("SqlXml.CreateReader", "SqlBinaryXml", $"{name}.bmx");
133+
}
134+
}
135+
136+
public static TheoryData<string, string> FilesAndBaselines
137+
{
138+
get
139+
{
140+
EnsureFileList();
141+
return _filesAndBaselines;
142+
}
143+
}
144+
145+
public static string ReadAllXml(XmlReader reader)
146+
{
147+
using StringWriter writer = new StringWriter();
148+
using XmlWriter xmlWriter = new XmlTextWriter(writer);
149+
150+
while (reader.Read()) xmlWriter.WriteNode(reader, false);
151+
152+
return writer.ToString();
153+
}
154+
}
155+
156+
[Theory]
157+
[MemberData(nameof(CreateReader_TestFiles.FilesAndBaselines), MemberType = typeof(CreateReader_TestFiles))]
158+
public void CreateReader_TestAgainstBaseline(string testFile, string baselineFile)
159+
{
160+
// Get our expected output by using XmlReader directly
161+
using XmlReader baselineReader = XmlReader.Create(baselineFile);
162+
string expected = CreateReader_TestFiles.ReadAllXml(baselineReader);
163+
164+
// Now produce the actual output through SqlXml.CreateReader
165+
using FileStream xmlStream = new FileStream(testFile, FileMode.Open);
166+
SqlXml sqlXml = new SqlXml(xmlStream);
167+
168+
// When the input is text, an XmlTextReader will be returned
169+
// When the input is SQL Binary XML, an XmlSqlBinaryReader will be returned
170+
using XmlReader actualReader = sqlXml.CreateReader();
171+
string actual = CreateReader_TestFiles.ReadAllXml(actualReader);
172+
173+
Assert.Equal(expected, actual);
174+
}
175+
122176
[Fact]
123-
public void SqlXml_fromZeroLengthStream_CreateReaderTest()
177+
public void SqlXml_FromZeroLengthStream_CreateReaderTest()
124178
{
125179
MemoryStream stream = new MemoryStream();
126180
SqlXml xmlSql = new SqlXml(stream);
@@ -131,7 +185,7 @@ public void SqlXml_fromZeroLengthStream_CreateReaderTest()
131185
}
132186

133187
[Fact]
134-
public void SqlXml_fromZeroLengthXmlReader_CreateReaderTest_withFragment()
188+
public void SqlXml_FromZeroLengthXmlReader_CreateReaderTest_withFragment()
135189
{
136190
XmlReaderSettings xs = new XmlReaderSettings();
137191
xs.ConformanceLevel = ConformanceLevel.Fragment;
@@ -145,7 +199,7 @@ public void SqlXml_fromZeroLengthXmlReader_CreateReaderTest_withFragment()
145199
}
146200

147201
[Fact]
148-
public void SqlXml_fromZeroLengthXmlReader_CreateReaderTest()
202+
public void SqlXml_FromZeroLengthXmlReader_CreateReaderTest()
149203
{
150204
XmlReader rdr = new XmlTextReader(new StringReader(string.Empty));
151205

src/libraries/System.Private.Xml/src/System/Xml/BinaryXml/XmlBinaryReader.cs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3489,7 +3489,9 @@ private XmlNodeType CheckText(bool attr)
34893489
Debug.Assert(_checkCharacters, "this.checkCharacters");
34903490
// grab local copy (perf)
34913491

3492-
ReadOnlySpan<byte> data = _data.AsSpan(_tokDataPos, _end - _tokDataPos);
3492+
// Get the bytes for the current token. _tokDataPos is the beginning position,
3493+
// and _pos has advanced to the next token (1 past the end of this token).
3494+
ReadOnlySpan<byte> data = _data.AsSpan(_tokDataPos, _pos - _tokDataPos);
34933495
Debug.Assert(data.Length % 2 == 0, "Data size should not be odd");
34943496

34953497
if (!attr)

0 commit comments

Comments
 (0)