Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Thread Unsafe XUnit Testing #40

Open
theodoreOnzGit opened this issue Aug 25, 2022 · 0 comments
Open

Thread Unsafe XUnit Testing #40

theodoreOnzGit opened this issue Aug 25, 2022 · 0 comments

Comments

@theodoreOnzGit
Copy link
Contributor

theodoreOnzGit commented Aug 25, 2022

Hi MadsKirkFoged,

As promised, here is a bug report demonstrating thread unsafe-ness of coolprop using sharpfluids.

I made an xunit test:

dotnet new xunit --output threadSafetyTestSharpFluids

and i made two identical unit tests and placed them under two files:
UnitTest1.cs
UnitTest2.cs

Here are the codes for each unit test respectively.

using EngineeringUnits;
using EngineeringUnits.Units;
using SharpFluids;
using Xunit;
using System;
using Xunit.Abstractions;


namespace therminolPipeTest;

public class UnitTest1 
{

	[Theory]
	[InlineData(20,1064)]
	[InlineData(30,1056)]
	[InlineData(40,1048)]
	[InlineData(50,1040)]
	[InlineData(60,1032)]
	[InlineData(70,1024)]
	[InlineData(80,1015)]
	[InlineData(90,1007)]
	[InlineData(100,999)]
	[InlineData(110,991)]
	[InlineData(120,982)]
	[InlineData(130,974)]
	[InlineData(140,965)]
	[InlineData(150,957)]
	[InlineData(160,948)]
	[InlineData(180,931)]
	public void WhenTherminolObjectTestedExpectVendorDensityValue(
			double temperatureC, double densityValueKgPerM3){

		//Setup


		// set temperature and pressure for dowtherm and Therminol
		Pressure referencePressure = new Pressure(1.1013e5, PressureUnit.Pascal);
		EngineeringUnits.Temperature testTemperature 
			= new EngineeringUnits.Temperature(temperatureC, 
					TemperatureUnit.DegreeCelsius);

		// get therminol VP-1 fluid object
		Fluid therminol = new Fluid(FluidList.InCompTherminolVP1);

		// Act
		therminol.UpdatePT(referencePressure, testTemperature);

		Density resultDensity = therminol.Density;

		// Assert 
		//
		// Check if densities are equal to within 0.2% of vendor data
	
		double errorMax = 0.2/100;
		double resultDensityValueKgPerM3 = resultDensity.
			As(DensityUnit.KilogramPerCubicMeter);
		double error = Math.Abs(resultDensityValueKgPerM3 - 
				densityValueKgPerM3)/densityValueKgPerM3;

		if (error < errorMax){
			return;
		}
		if (error > errorMax){

		Assert.Equal(densityValueKgPerM3, 
				resultDensity.As(DensityUnit.KilogramPerCubicMeter),
				0);
		}
		
	}


}

And,

using EngineeringUnits;
using EngineeringUnits.Units;
using SharpFluids;
using Xunit;
using System;
using Xunit.Abstractions;


namespace therminolPipeTest;

public class UnitTest2 
{

	[Theory]
	[InlineData(20,1064)]
	[InlineData(30,1056)]
	[InlineData(40,1048)]
	[InlineData(50,1040)]
	[InlineData(60,1032)]
	[InlineData(70,1024)]
	[InlineData(80,1015)]
	[InlineData(90,1007)]
	[InlineData(100,999)]
	[InlineData(110,991)]
	[InlineData(120,982)]
	[InlineData(130,974)]
	[InlineData(140,965)]
	[InlineData(150,957)]
	[InlineData(160,948)]
	[InlineData(180,931)]
	public void WhenTherminolObjectTestedExpectVendorDensityValue(
			double temperatureC, double densityValueKgPerM3){

		//Setup


		// set temperature and pressure for dowtherm and Therminol
		Pressure referencePressure = new Pressure(1.1013e5, PressureUnit.Pascal);
		EngineeringUnits.Temperature testTemperature 
			= new EngineeringUnits.Temperature(temperatureC, 
					TemperatureUnit.DegreeCelsius);

		// get therminol VP-1 fluid object
		Fluid therminol = new Fluid(FluidList.InCompTherminolVP1);

		// Act
		therminol.UpdatePT(referencePressure, testTemperature);

		Density resultDensity = therminol.Density;

		// Assert 
		//
		// Check if densities are equal to within 0.2% of vendor data
	
		double errorMax = 0.2/100;
		double resultDensityValueKgPerM3 = resultDensity.
			As(DensityUnit.KilogramPerCubicMeter);
		double error = Math.Abs(resultDensityValueKgPerM3 - 
				densityValueKgPerM3)/densityValueKgPerM3;

		if (error < errorMax){
			return;
		}
		if (error > errorMax){

		Assert.Equal(densityValueKgPerM3, 
				resultDensity.As(DensityUnit.KilogramPerCubicMeter),
				0);
		}
		
	}


}

Now running both of these using dotnet watch test yields:

Starting test execution, please wait...
A total of 1 test files matched the specified pattern.
The active test run was aborted. Reason: Test host process crashed : Unhandled exception. System.ApplicationException: FATAL: An earlier pending exception from unmanaged code was missed and thus not thrown (System.ApplicationException: This backend does not implement calc_phase function)
 ---> System.ApplicationException: calc_compressibility_factor is not implemented for this backend
   --- End of inner exception stack trace ---
   at CoolPropPINVOKE64.SWIGPendingException.Set(Exception e)
   at CoolPropPINVOKE64.SWIGExceptionHelper.SetPendingApplicationException(String message)


Test Run Aborted with error System.Exception: One or more errors occurred.
 ---> System.Exception: Unable to read beyond the end of the stream.
   at System.IO.BinaryReader.ReadByte()
   at System.IO.BinaryReader.Read7BitEncodedInt()
   at System.IO.BinaryReader.ReadString()
   at Microsoft.VisualStudio.TestPlatform.CommunicationUtilities.LengthPrefixCommunicationChannel.NotifyDataAvailable()
   at Microsoft.VisualStudio.TestPlatform.CommunicationUtilities.TcpClientExtensions.MessageLoopAsync(TcpClient client, ICommunicationChannel channel, Action`1 errorHandler, CancellationToken cancellationToken)
   --- End of inner exception stack trace ---.
watch : Exited with error code 1
watch : Waiting for a file to change before restarting dotnet...

This happens with almost absolute certainty.

If you put the same classes in the same unit test, it will also throw some sort of race condition like error.

In fat i've gotten

Test host process crashed: malloc(): unaligned tcache chunk detected

So this can show that coolprop is definitely not thread safe.

How to solve it? I haven't quite thought of it lol... It's just quite the headache now.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant