Skip to content

Commit

Permalink
Validation of DeviceConfiguration. Tests on this validation. More tes…
Browse files Browse the repository at this point in the history
…ts on Image class. Minor improvements.
  • Loading branch information
bibigone committed Aug 2, 2019
1 parent 15bcfe6 commit f4c2a77
Show file tree
Hide file tree
Showing 10 changed files with 403 additions and 61 deletions.
18 changes: 18 additions & 0 deletions K4AdotNet.Samples.Wpf.Common/AppBase.cs
Original file line number Diff line number Diff line change
@@ -1,16 +1,34 @@
using System;
using System.Globalization;
using System.Linq;
using System.Threading;
using System.Windows;

namespace K4AdotNet.Samples.Wpf
{
public abstract class AppBase : Application, IApp
{
protected AppBase()
{
SetDefaultCulture();
}

protected static void SetDefaultCulture()
{
// Set default culture to en-US because UI is in English
// and it is also a default culture for formatting values in bindings.
// https://social.msdn.microsoft.com/Forums/vstudio/en-US/dd94f1f8-4213-49c3-903f-780b901a30d0/data-binding-ignores-local-culture-settings?forum=wpf
var defaultCulture = CultureInfo.GetCultureInfo("en-US");
Thread.CurrentThread.CurrentCulture = defaultCulture;
CultureInfo.DefaultThreadCurrentCulture = defaultCulture;
}

protected abstract Window CreateMainWindow(StartupEventArgs e);

protected override void OnStartup(StartupEventArgs e)
{
base.OnStartup(e);

ShutdownMode = ShutdownMode.OnExplicitShutdown;
var mainWindow = CreateMainWindow(e);
if (mainWindow == null)
Expand Down
86 changes: 86 additions & 0 deletions K4AdotNet.Tests.SensorTypesUnitTests/DeviceConfigurationTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
using Microsoft.VisualStudio.TestTools.UnitTesting;
using K4AdotNet.Sensor;

namespace K4AdotNet.Tests.SensorTypesUnitTests
{
[TestClass]
public class DeviceConfigurationTests
{
[TestMethod]
public void TestThatDisableAllConfigIsValid()
{
var config = DeviceConfiguration.DisableAll;

Assert.IsTrue(config.IsValid(out var message));
Assert.IsNull(message);
}

[TestMethod]
public void TestValidConfig()
{
var config = new DeviceConfiguration
{
CameraFps = FrameRate.Thirty,
ColorFormat = ImageFormat.ColorMjpg,
ColorResolution = ColorResolution.R720p,
DepthMode = DepthMode.NarrowViewUnbinned,
WiredSyncMode = WiredSyncMode.Standalone,
};

Assert.IsTrue(config.IsValid(out var message));
Assert.IsNull(message);
}

[TestMethod]
public void TestInvalidConfigs()
{
var config = new DeviceConfiguration
{
CameraFps = FrameRate.Thirty,
ColorFormat = ImageFormat.ColorMjpg,
ColorResolution = ColorResolution.R720p,
DepthMode = DepthMode.WideViewUnbinned, // this mode is not compatible with 30 FPS
WiredSyncMode = WiredSyncMode.Standalone,
};

Assert.IsFalse(config.IsValid(out var message));
Assert.IsNotNull(message);

config = new DeviceConfiguration
{
CameraFps = FrameRate.Thirty,
ColorFormat = ImageFormat.ColorMjpg,
ColorResolution = ColorResolution.R3072p, // this resolution is not compatible with 30 FPS
DepthMode = DepthMode.Off,
WiredSyncMode = WiredSyncMode.Standalone,
};

Assert.IsFalse(config.IsValid(out message));
Assert.IsNotNull(message);

config = new DeviceConfiguration
{
CameraFps = FrameRate.Fifteen,
ColorFormat = ImageFormat.ColorNV12,
ColorResolution = ColorResolution.R1080p, // this resolution is not compatible with NV12
DepthMode = DepthMode.Off,
WiredSyncMode = WiredSyncMode.Standalone,
};

Assert.IsFalse(config.IsValid(out message));
Assert.IsNotNull(message);

config = new DeviceConfiguration
{
CameraFps = FrameRate.Fifteen,
ColorFormat = ImageFormat.IR16, // <- oops!
ColorResolution = ColorResolution.Off,
DepthMode = DepthMode.Off,
WiredSyncMode = WiredSyncMode.Standalone,
};

Assert.IsFalse(config.IsValid(out message));
Assert.IsNotNull(message);
}
}
}
164 changes: 133 additions & 31 deletions K4AdotNet.Tests.SensorTypesUnitTests/ImageTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -50,45 +50,18 @@ private void TestImageCreationWithNoSizeSpecified(ImageFormat format, int? strid
var stride = strideOrNull ?? format.StrideBytes(testWidth);
var expectedSize = stride * testHeight;

var image = new Image(format, testWidth, testHeight, stride);
var image = strideOrNull.HasValue
? new Image(format, testWidth, testHeight, strideOrNull.Value)
: new Image(format, testWidth, testHeight);

Assert.AreNotEqual(IntPtr.Zero, image.Buffer);

// Check common properties
// Check common (readonly) properties
Assert.AreEqual(format, image.Format);
Assert.AreEqual(testWidth, image.WidthPixels);
Assert.AreEqual(testHeight, image.HeightPixels);
Assert.AreEqual(stride, image.StrideBytes);
Assert.AreEqual(expectedSize, image.SizeBytes);

// Check Timestamp property
Assert.AreEqual(Microseconds64.Zero, image.Timestamp);
image.Timestamp = testTimestamp;
Assert.AreEqual(testTimestamp, image.Timestamp);

// Check WhiteBalance property
Assert.AreEqual(0, image.WhiteBalance);
image.WhiteBalance = testWhiteBalance;
Assert.AreEqual(testWhiteBalance, image.WhiteBalance);

// Check IsoSpeed property
Assert.AreEqual(0, image.IsoSpeed);
image.IsoSpeed = testIsoSpeed;
Assert.AreEqual(testIsoSpeed, image.IsoSpeed);

// Check disposing
Assert.IsFalse(image.IsDisposed);
var disposedEventCounter = 0;
image.Disposed += (_, __) => disposedEventCounter++;
image.Dispose();
Assert.IsTrue(image.IsDisposed);
Assert.AreEqual(1, disposedEventCounter);

// We can call Dispose() multiple times
image.Dispose();
Assert.IsTrue(image.IsDisposed);
// But Disposed event must be invoked only once
Assert.AreEqual(1, disposedEventCounter);
}

#endregion
Expand Down Expand Up @@ -144,5 +117,134 @@ public void TestCreationFromArray()
}

#endregion

#region Testing of IsDisposed property, Dispose() method and Disposed event

[TestMethod]
public void TestDisposing()
{
var image = new Image(ImageFormat.Depth16, testWidth, testHeight);

// Check disposing
Assert.IsFalse(image.IsDisposed);
var disposedEventCounter = 0;
image.Disposed += (_, __) => disposedEventCounter++;
image.Dispose();
Assert.IsTrue(image.IsDisposed);
Assert.AreEqual(1, disposedEventCounter);

// We can call Dispose() multiple times
image.Dispose();
Assert.IsTrue(image.IsDisposed);
// But Disposed event must be invoked only once
Assert.AreEqual(1, disposedEventCounter);
}

private Image CreateImageFromArray(out WeakReference<byte[]> weakReferenceToArray)
{
var format = ImageFormat.ColorBgra32;
var strideBytes = format.StrideBytes(1);
var array = new byte[strideBytes];
weakReferenceToArray = new WeakReference<byte[]>(array);
return Image.CreateFromArray(array, format, 1, 1, strideBytes);
}

[TestMethod]
public void TestArrayUnpinningOnDispose()
{
var image = CreateImageFromArray(out var weakReferenceToArray);
image.Dispose();

// Force collecting of array
GC.Collect();

Assert.IsFalse(weakReferenceToArray.TryGetTarget(out var notUsed));

// Nothing bad if we call dispose second time
image.Dispose();
}

[TestMethod]
[ExpectedException(typeof(ObjectDisposedException))]
public void TestObjectDisposedException()
{
var image = new Image(ImageFormat.Depth16, testWidth, testHeight);
image.Dispose();
var buffer = image.Buffer; // <- ObjectDisposedException
}

#endregion

#region Test setting of properties

[TestMethod]
public void TestMutableProperties()
{
using (var image = new Image(ImageFormat.Depth16, testWidth, testHeight))
{
// Check Timestamp property
Assert.AreEqual(Microseconds64.Zero, image.Timestamp);
image.Timestamp = testTimestamp;
Assert.AreEqual(testTimestamp, image.Timestamp);

// Check WhiteBalance property
Assert.AreEqual(0, image.WhiteBalance);
image.WhiteBalance = testWhiteBalance;
Assert.AreEqual(testWhiteBalance, image.WhiteBalance);

// Check IsoSpeed property
Assert.AreEqual(0, image.IsoSpeed);
image.IsoSpeed = testIsoSpeed;
Assert.AreEqual(testIsoSpeed, image.IsoSpeed);
}
}

#endregion

#region Test duplicate reference

[TestMethod]
public void TestDuplicateReference()
{
var image = CreateImageFromArray(out var weakReferenceToArray);
var refImage = image.DuplicateReference();

Assert.AreEqual(image.Buffer, refImage.Buffer);
Assert.AreEqual(image.SizeBytes, refImage.SizeBytes);
Assert.AreEqual(image.WidthPixels, refImage.WidthPixels);
Assert.AreEqual(image.HeightPixels, refImage.HeightPixels);
Assert.AreEqual(image.StrideBytes, refImage.StrideBytes);
Assert.AreEqual(image.Format, refImage.Format);

// Check that when we change property of image,
// then property of refImage is also synchronously changed
image.Timestamp = testTimestamp;
Assert.AreEqual(testTimestamp, refImage.Timestamp);

// And vice versa
refImage.WhiteBalance = testWhiteBalance;
Assert.AreEqual(testWhiteBalance, image.WhiteBalance);

// And for one more property
image.IsoSpeed = testIsoSpeed;
Assert.AreEqual(testIsoSpeed, refImage.IsoSpeed);

// Dispose source image
image.Dispose();

// But refImage must be still alive
Assert.IsFalse(refImage.IsDisposed);
Assert.AreNotEqual(IntPtr.Zero, refImage.Buffer);

// Force GC
GC.Collect();

// But array is still alive because refImage keeps it
Assert.IsTrue(weakReferenceToArray.TryGetTarget(out var notUsed));

refImage.Dispose();
}

#endregion
}
}
Loading

0 comments on commit f4c2a77

Please sign in to comment.