未验证 提交 8386f644 编写于 作者: J Jose Perez Rodriguez 提交者: GitHub

Adding Helix testing infrastructure (#267)

* Adding Helix testing infrastructure

* Update arcade and address feedback

* Fixing tests and cancellation token source issue
上级 b9fd0e3f
......@@ -15,5 +15,9 @@
<Uri>https://github.com/dotnet/arcade</Uri>
<Sha>86e674361bdcefecbd8199ab62d0b1a6cb25703d</Sha>
</Dependency>
<Dependency Name="Microsoft.DotNet.Helix.Sdk" Version="2.0.0-beta.19272.13">
<Uri>https://github.com/dotnet/arcade</Uri>
<Sha>86e674361bdcefecbd8199ab62d0b1a6cb25703d</Sha>
</Dependency>
</ToolsetDependencies>
</Dependencies>
<Project Sdk="Microsoft.DotNet.Helix.Sdk">
<PropertyGroup>
<HelixSource>pr/dotnet/iot/$(BUILD_SOURCEBRANCH)/</HelixSource>
<HelixType>test/product/</HelixType>
<HelixBuild>$(BUILD_BUILDNUMBER)</HelixBuild>
<HelixBuild Condition="'$(HelixBuild)' == ''">123460.01</HelixBuild>
<IncludeDotNetCli>true</IncludeDotNetCli>
<DotNetCliPackageType>sdk</DotNetCliPackageType>
<EnableAzurePipelinesReporter Condition="'$(SYSTEM_ACCESSTOKEN)' != ''">true</EnableAzurePipelinesReporter>
<TestRunNamePrefix>$(AGENT_JOBNAME)</TestRunNamePrefix>
<EnableXUnitReporter>true</EnableXUnitReporter>
<FailOnMissionControlTestFailure>true</FailOnMissionControlTestFailure>
</PropertyGroup>
<ItemGroup>
<!-- For now we only have a queue for Linux. Once we have a queue for Windows we will run
those tests too. -->
<XUnitProject Include="..\src\System.Device.Gpio.Tests\System.Device.Gpio.Tests.csproj">
<TargetFramework>netcoreapp2.1</TargetFramework>
<RuntimeTargetFramework>netcoreapp2.0</RuntimeTargetFramework>
<AdditionalProperties>RuntimeIdentifier=linux-arm</AdditionalProperties>
</XUnitProject>
</ItemGroup>
<ItemGroup Condition=" '$(HelixAccessToken)' != '' And '$(HelixTargetQueue)' == ''">
<HelixTargetQueue Include="Raspbian.9.Arm32.IoT"/>
</ItemGroup>
<ItemGroup Condition="'$(HelixTargetQueue)' != ''">
<HelixTargetQueue Include="$(HelixTargetQueue)"/>
</ItemGroup>
<PropertyGroup Condition=" '$(HelixAccessToken)' == '' ">
<IsExternal>true</IsExternal>
<Creator>$(BUILD_SOURCEVERSIONAUTHOR)</Creator>
<Creator Condition=" '$(Creator)' == ''">dotnet-bot</Creator>
</PropertyGroup>
<ItemGroup Condition=" '$(HelixAccessToken)' == '' And '$(HelixTargetQueue)' == ''">
<HelixTargetQueue Include="Raspbian.9.Arm32.IoT.open"/>
</ItemGroup>
<!-- Our tests require to run as elevated. -->
<Target Name="AppendSudoToHelixWorkItems"
Inputs="%(HelixWorkItem.Identity)%(HelixWorkItem.Command)"
Outputs="unused"
AfterTargets="CreateXUnitWorkItems">
<PropertyGroup>
<!-- Because our tests need to run as sudo, PATH environment variable is reset so we need to set
a different variable to the full path of dotnet -->
<HelixPreCommands>$(HelixPreCommands);export _dotnet="%24(which dotnet)"</HelixPreCommands>
<!-- Pre append sudo and the full path to dotnet to the command, along with a dollarsign throwAway
which will remove the initial dotnet from the helix command as it will be interpreted as a
variable -->
<_newCommand>sudo -E $_dotnet $throwAway%(HelixWorkItem.Command) -verbose -serialize -maxthreads 1</_newCommand>
</PropertyGroup>
<ItemGroup>
<HelixWorkItem>
<Command>$(_newCommand)</Command>
</HelixWorkItem>
</ItemGroup>
</Target>
<!-- Useless stuff to make Arcade SDK happy -->
<PropertyGroup>
<Language>msbuild</Language>
</PropertyGroup>
</Project>
\ No newline at end of file
......@@ -11,6 +11,7 @@
"version": "3.0.100-preview5-011568"
},
"msbuild-sdks": {
"Microsoft.DotNet.Arcade.Sdk": "1.0.0-beta.19272.13"
"Microsoft.DotNet.Arcade.Sdk": "1.0.0-beta.19272.13",
"Microsoft.DotNet.Helix.Sdk": "2.0.0-beta.19272.13"
}
}
......@@ -15,7 +15,7 @@ namespace System.Device.Gpio.Tests
private const int LedPin = 18;
private const int OutputPin = 16;
private const int InputPin = 12;
private static readonly int WaitMilliSeconds = 10;
private static readonly int WaitMilliSeconds = 1000;
[Fact]
public void ControllerCanTurnOnLEDs()
......@@ -137,6 +137,7 @@ namespace System.Device.Gpio.Tests
{
controller.OpenPin(InputPin, PinMode.Input);
controller.OpenPin(OutputPin, PinMode.Output);
controller.Write(OutputPin, PinValue.Low);
controller.RegisterCallbackForPinValueChangedEvent(InputPin, PinEventTypes.Rising, callback);
controller.Write(OutputPin, PinValue.High);
Thread.Sleep(WaitMilliSeconds);
......@@ -166,6 +167,7 @@ namespace System.Device.Gpio.Tests
void callback(object sender, PinValueChangedEventArgs pinValueChangedEventArgs)
{
Debug.WriteLine("Oops I was called!");
wasCalled = true;
}
}
......
......@@ -6,7 +6,9 @@ using System.Device.Gpio.Drivers;
namespace System.Device.Gpio.Tests
{
public class LibGpiodDriverTests : GpioControllerTestBase
// TODO: Uncomment making public once the LibGpiodTests stop crashing with SegFault.
// public
class LibGpiodDriverTests : GpioControllerTestBase
{
protected override GpioDriver GetTestDriver() => new LibGpiodDriver();
......
......@@ -13,4 +13,4 @@ namespace System.Device.Gpio.Tests
protected override PinNumberingScheme GetTestNumberingScheme() => PinNumberingScheme.Logical;
}
}
\ No newline at end of file
}
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netcoreapp2.1</TargetFramework>
<RuntimeIdentifiers>win-arm;linux-arm</RuntimeIdentifiers>
......@@ -23,4 +22,15 @@
<Compile Remove="**\*.Linux.cs" />
</ItemGroup>
<!-- Make sure that we copy the native shim to the publish directory before sending the tests to Helix -->
<Target Name="AddNativeShimToCopyToPublishDirectory" BeforeTargets="_ComputeResolvedFilesToPublishTypes">
<ItemGroup>
<_nativeShimFiles Include="$(ArtifactsBinDir)Native\$(Configuration)\*.*" />
<ResolvedFileToPublish Include="@(_nativeShimFiles)">
<RelativePath>%(_nativeShimFiles.Filename)%(_nativeShimFiles.Extension)</RelativePath>
<CopyToPublishDirectory>Always</CopyToPublishDirectory>
</ResolvedFileToPublish>
</ItemGroup>
</Target>
</Project>
......@@ -6,7 +6,7 @@ using System.Device.Gpio.Drivers;
namespace System.Device.Gpio.Tests
{
public class WindowsDriverTests : GpioControllerTestBase
class WindowsDriverTests : GpioControllerTestBase
{
protected override GpioDriver GetTestDriver() => new Windows10Driver();
......
......@@ -23,7 +23,7 @@ namespace System.Device.Gpio.Drivers
private int _pollFileDescriptor = -1;
private Thread _eventDetectionThread;
private int _pinsToDetectEventsCount;
private readonly static CancellationTokenSource s_eventThreadCancellationTokenSource = new CancellationTokenSource();
private readonly CancellationTokenSource s_eventThreadCancellationTokenSource;
private readonly List<int> _exportedPins = new List<int>();
private readonly Dictionary<int, UnixDriverDevicePin> _devicePins = new Dictionary<int, UnixDriverDevicePin>();
private readonly int _pollingTimeoutInMilliseconds = Convert.ToInt32(TimeSpan.FromMilliseconds(1).TotalMilliseconds);
......@@ -52,6 +52,11 @@ namespace System.Device.Gpio.Drivers
return 0;
}
public SysFsDriver()
{
s_eventThreadCancellationTokenSource = new CancellationTokenSource();
}
/// <summary>
/// The number of pins provided by the driver.
/// </summary>
......@@ -445,7 +450,10 @@ namespace System.Device.Gpio.Drivers
{
if (cancelEventDetectionThread)
{
s_eventThreadCancellationTokenSource.Cancel();
try
{
s_eventThreadCancellationTokenSource.Cancel();
} catch (ObjectDisposedException) { }
while (_eventDetectionThread != null && _eventDetectionThread.IsAlive)
{
Thread.Sleep(TimeSpan.FromMilliseconds(10)); // Wait until the event detection thread is aborted.
......@@ -462,8 +470,11 @@ namespace System.Device.Gpio.Drivers
_pinsToDetectEventsCount = 0;
if (_eventDetectionThread != null && _eventDetectionThread.IsAlive)
{
s_eventThreadCancellationTokenSource.Cancel();
s_eventThreadCancellationTokenSource.Dispose();
try
{
s_eventThreadCancellationTokenSource.Cancel();
s_eventThreadCancellationTokenSource.Dispose();
} catch (ObjectDisposedException) { } //The Cancellation Token source may already be disposed.
while (_eventDetectionThread != null && _eventDetectionThread.IsAlive)
{
Thread.Sleep(TimeSpan.FromMilliseconds(10)); // Wait until the event detection thread is aborted.
......@@ -528,12 +539,19 @@ namespace System.Device.Gpio.Drivers
{
while (_pinsToDetectEventsCount > 0)
{
bool eventDetected = WasEventDetected(_pollFileDescriptor, -1, out int pinNumber, s_eventThreadCancellationTokenSource.Token);
if (eventDetected)
try
{
bool eventDetected = WasEventDetected(_pollFileDescriptor, -1, out int pinNumber, s_eventThreadCancellationTokenSource.Token);
if (eventDetected)
{
Thread.Sleep(1); // Adding some delay to make sure that the value of the File has been updated so that we will get the right event type.
PinEventTypes eventTypes = (Read(pinNumber) == PinValue.High) ? PinEventTypes.Rising : PinEventTypes.Falling;
var args = new PinValueChangedEventArgs(eventTypes, pinNumber);
_devicePins[pinNumber]?.OnPinValueChanged(args);
}
} catch (ObjectDisposedException)
{
PinEventTypes eventTypes = (Read(pinNumber) == PinValue.High) ? PinEventTypes.Rising : PinEventTypes.Falling;
var args = new PinValueChangedEventArgs(eventTypes, pinNumber);
_devicePins[pinNumber]?.OnPinValueChanged(args, GetPinEventsToDetect(pinNumber));
break; //If cancellation token source is dispossed then we need to exit this thread.
}
}
......
......@@ -16,13 +16,13 @@ namespace System.Device.Gpio.Drivers
public int FileDescriptor;
public void OnPinValueChanged(PinValueChangedEventArgs args, PinEventTypes detectionOfEventTypes)
public void OnPinValueChanged(PinValueChangedEventArgs args)
{
if (detectionOfEventTypes.HasFlag(PinEventTypes.Rising) && args.ChangeType == PinEventTypes.Rising)
if (ValueRising != null && args.ChangeType == PinEventTypes.Rising)
{
ValueRising?.Invoke(this, args);
}
if (detectionOfEventTypes.HasFlag(PinEventTypes.Falling) && args.ChangeType == PinEventTypes.Falling)
if (ValueFalling != null && args.ChangeType == PinEventTypes.Falling)
{
ValueFalling?.Invoke(this, args);
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册