Skip to content

Commit

Permalink
CP-51694: Add testing of C# date converter
Browse files Browse the repository at this point in the history
Signed-off-by: Danilo Del Busso <danilo.delbusso@cloud.com>
  • Loading branch information
danilo-delbusso committed Oct 1, 2024
1 parent 9e1ea63 commit 30501ad
Show file tree
Hide file tree
Showing 4 changed files with 183 additions and 5 deletions.
7 changes: 7 additions & 0 deletions .github/workflows/generate-and-build-sdks.yml
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,13 @@ jobs:
name: SDK_Source_CSharp
path: source/

- name: Test C# SDK
shell: pwsh
run: |
dotnet test source/XenServerTest `
--disable-build-servers `
--verbosity=normal
- name: Build C# SDK
shell: pwsh
run: |
Expand Down
139 changes: 139 additions & 0 deletions ocaml/sdk-gen/csharp/autogen/XenServerTest/DateTimeTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
/*
* Copyright (c) Cloud Software Group, Inc.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1) Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2) Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*/

using System.Reflection;
using Newtonsoft.Json;
using XenAPI;
using Console = System.Console;

namespace XenServerTest;

internal class DateTimeObject
{
[JsonConverter(typeof(XenDateTimeConverter))]
public DateTime Date { get; set; }
}

[TestClass]
public class DateTimeTests
{
private readonly JsonSerializerSettings _settings = new()
{
Converters = new List<JsonConverter> { new XenDateTimeConverter() }
};

[TestMethod]
[DynamicData(nameof(GetTestData), DynamicDataSourceType.Method,
DynamicDataDisplayName = nameof(GetCustomDynamicDataDisplayName))]
public void TestXenDateTimeConverter(string dateString, DateTime expectedDateTime)
{
try
{
var jsonDateString = "{ \"Date\" : \"" + dateString + "\" }";
var actualDateTime = JsonConvert.DeserializeObject<DateTimeObject>(jsonDateString, _settings);

Assert.IsNotNull(actualDateTime, $"Failed to convert '{dateString}'");
Assert.IsTrue(expectedDateTime.Equals(actualDateTime.Date),
$"Conversion of '{dateString}' resulted in an incorrect DateTime value");
}
catch (Exception ex)
{
// Log the error or mark this specific data entry as failed
Console.WriteLine($@"Error processing dateString '{dateString}': {ex.Message}");
Assert.Fail($"An error occurred while processing '{dateString}'");
}
}

public static string GetCustomDynamicDataDisplayName(MethodInfo methodInfo, object[] data)
{
return $"{methodInfo.Name}: '{data[0] as string}'";
}

public static IEnumerable<object[]> GetTestData()
{
// no dashes, no colons
yield return new object[] { "20220101T123045", new DateTime(2022, 1, 1, 12, 30, 45, DateTimeKind.Unspecified) };
yield return new object[] { "20220101T123045Z", new DateTime(2022, 1, 1, 12, 30, 45, DateTimeKind.Utc) };
yield return new object[] { "20220101T123045+03", new DateTime(2022, 1, 1, 9, 30, 45, DateTimeKind.Local) };
yield return new object[] { "20220101T123045+0300", new DateTime(2022, 1, 1, 9, 30, 45, DateTimeKind.Local) };
yield return new object[] { "20220101T123045+03:00", new DateTime(2022, 1, 1, 9, 30, 45, DateTimeKind.Local) };

yield return new object[]
{ "20220101T123045.123", new DateTime(2022, 1, 1, 12, 30, 45, 123, DateTimeKind.Unspecified) };
yield return new object[]
{ "20220101T123045.123Z", new DateTime(2022, 1, 1, 12, 30, 45, 123, DateTimeKind.Utc) };
yield return new object[]
{ "20220101T123045.123+03", new DateTime(2022, 1, 1, 9, 30, 45, 123, DateTimeKind.Local) };
yield return new object[]
{ "20220101T123045.123+0300", new DateTime(2022, 1, 1, 9, 30, 45, 123, DateTimeKind.Local) };
yield return new object[]
{ "20220101T123045.123+03:00", new DateTime(2022, 1, 1, 9, 30, 45, 123, DateTimeKind.Local) };

// no dashes, with colons
yield return new object[]
{ "20220101T12:30:45", new DateTime(2022, 1, 1, 12, 30, 45, DateTimeKind.Unspecified) };
yield return new object[] { "20220101T12:30:45Z", new DateTime(2022, 1, 1, 12, 30, 45, DateTimeKind.Utc) };
yield return new object[] { "20220101T12:30:45+03", new DateTime(2022, 1, 1, 9, 30, 45, DateTimeKind.Local) };
yield return new object[] { "20220101T12:30:45+0300", new DateTime(2022, 1, 1, 9, 30, 45, DateTimeKind.Local) };
yield return new object[]
{ "20220101T12:30:45+03:00", new DateTime(2022, 1, 1, 9, 30, 45, DateTimeKind.Local) };

yield return new object[]
{ "20220101T12:30:45.123", new DateTime(2022, 1, 1, 12, 30, 45, 123, DateTimeKind.Unspecified) };
yield return new object[]
{ "20220101T12:30:45.123Z", new DateTime(2022, 1, 1, 12, 30, 45, 123, DateTimeKind.Utc) };
yield return new object[]
{ "20220101T12:30:45.123+03", new DateTime(2022, 1, 1, 9, 30, 45, 123, DateTimeKind.Local) };
yield return new object[]
{ "20220101T12:30:45.123+0300", new DateTime(2022, 1, 1, 9, 30, 45, 123, DateTimeKind.Local) };
yield return new object[]
{ "20220101T12:30:45.123+03:00", new DateTime(2022, 1, 1, 9, 30, 45, 123, DateTimeKind.Local) };

// dashes and colons
yield return new object[]
{ "2022-01-01T12:30:45", new DateTime(2022, 1, 1, 12, 30, 45, DateTimeKind.Unspecified) };
yield return new object[] { "2022-01-01T12:30:45Z", new DateTime(2022, 1, 1, 12, 30, 45, DateTimeKind.Utc) };
yield return new object[] { "2022-01-01T12:30:45+03", new DateTime(2022, 1, 1, 9, 30, 45, DateTimeKind.Local) };
yield return new object[]
{ "2022-01-01T12:30:45+0300", new DateTime(2022, 1, 1, 9, 30, 45, DateTimeKind.Local) };
yield return new object[]
{ "2022-01-01T12:30:45+03:00", new DateTime(2022, 1, 1, 9, 30, 45, DateTimeKind.Local) };

yield return new object[]
{ "2022-01-01T12:30:45.123", new DateTime(2022, 1, 1, 12, 30, 45, 123, DateTimeKind.Unspecified) };
yield return new object[]
{ "2022-01-01T12:30:45.123Z", new DateTime(2022, 1, 1, 12, 30, 45, 123, DateTimeKind.Utc) };
yield return new object[]
{ "2022-01-01T12:30:45.123+03", new DateTime(2022, 1, 1, 9, 30, 45, 123, DateTimeKind.Local) };
yield return new object[]
{ "2022-01-01T12:30:45.123+0300", new DateTime(2022, 1, 1, 9, 30, 45, 123, DateTimeKind.Local) };
yield return new object[]
{ "2022-01-01T12:30:45.123+03:00", new DateTime(2022, 1, 1, 9, 30, 45, 123, DateTimeKind.Local) };
}
}
27 changes: 27 additions & 0 deletions ocaml/sdk-gen/csharp/autogen/XenServerTest/XenServerTest.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>

<IsPackable>false</IsPackable>
<IsTestProject>true</IsTestProject>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="coverlet.collector" Version="3.2.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.5.0" />
<PackageReference Include="MSTest.TestAdapter" Version="2.2.10" />
<PackageReference Include="MSTest.TestFramework" Version="2.2.10" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\src\XenServer.csproj" />
</ItemGroup>

<ItemGroup>
<Using Include="Microsoft.VisualStudio.TestTools.UnitTesting" />
</ItemGroup>

</Project>
15 changes: 10 additions & 5 deletions ocaml/sdk-gen/csharp/autogen/src/Converters.cs
Original file line number Diff line number Diff line change
Expand Up @@ -31,10 +31,12 @@
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Runtime.CompilerServices;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
using Newtonsoft.Json.Linq;

[assembly: InternalsVisibleTo("XenServerTest")]

namespace XenAPI
{
Expand Down Expand Up @@ -437,12 +439,16 @@ internal class XenDateTimeConverter : IsoDateTimeConverter

public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
string str = JToken.Load(reader).ToString();
// JsonReader may have already parsed the date for us
if (reader.ValueType != null && reader.ValueType == typeof(DateTime))
{
return reader.Value;
}

DateTime result;
var str = JToken.Load(reader).ToString();

if (DateTime.TryParseExact(str, DateFormatsUtc, CultureInfo.InvariantCulture,
DateTimeStyles.AssumeUniversal | DateTimeStyles.AdjustToUniversal, out result))
DateTimeStyles.AssumeUniversal | DateTimeStyles.AdjustToUniversal, out var result))
return result;

if (DateTime.TryParseExact(str, DateFormatsLocal, CultureInfo.InvariantCulture,
Expand All @@ -454,9 +460,8 @@ public override object ReadJson(JsonReader reader, Type objectType, object exist

public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
if (value is DateTime)
if (value is DateTime dateTime)
{
var dateTime = (DateTime)value;
dateTime = dateTime.ToUniversalTime();
var text = dateTime.ToString(DateFormatsUtc[0], CultureInfo.InvariantCulture);
writer.WriteValue(text);
Expand Down

0 comments on commit 30501ad

Please sign in to comment.