Skip to content

Libpostal.zip not correctly unzip when included in Test project #58

@bard83

Description

@bard83

Executing the test the below error is returned:

$ dotnet test

  MyProject -> XXX\MyProject\bin\Debug\net8.0\MyProject.dll
  Checking for LibpostalData.zip
  Unzipping LibpostalData.zip
  Unzipped LibpostalData.zip
  Copying libpostal library files to output directory
  MyProjectTests -> XXX\MyProjectTests\bin\Debug\net8.0\MyProjectTests.dll
Test run for XXX\MyProjectTests\bin\Debug\net8.0\MyProjectTests.dll (.NETCoreApp,Version=v8.0)
Microsoft (R) Test Execution Command Line Tool Version 17.8.0 (x64)
Copyright (c) Microsoft Corporation.  All rights reserved.

Starting test execution, please wait...
A total of 1 test files matched the specified pattern.
Setup failed for test fixture MyProjectTests.LibpostalClientTests
System.DllNotFoundException : Unable to load DLL 'libpostal-1' or one of its dependencies: The specified module could not be found. (0x8007007E)
StackTrace:    at LibPostalNet.libpostal.__Internal.LibpostalSetupDatadir(String datadir)
   at LibPostalNet.libpostal.LibpostalSetupDatadir(String datadir)
   at NHSISL.LibPostalClient.Brokers.LibPostal.LibPostalBroker..ctor(LibPostalConfiguration libPostalConfiguration)
   at System.RuntimeMethodHandle.InvokeMethod(Object target, Void** arguments, Signature sig, Boolean isConstructor)
   at System.Reflection.MethodBaseInvoker.InvokeDirectByRefWithFewArgs(Object obj, Span`1 copyOfArgs, BindingFlags invokeAttr)
   at System.Reflection.MethodBaseInvoker.InvokeWithOneArg(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
   at System.Reflection.RuntimeConstructorInfo.Invoke(BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitConstructor(ConstructorCallSite constructorCallSite, RuntimeResolverContext context)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitCallSiteMain(ServiceCallSite callSite, TArgument argument)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitDisposeCache(ServiceCallSite transientCallSite, RuntimeResolverContext context)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitCallSite(ServiceCallSite callSite, TArgument argument)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitConstructor(ConstructorCallSite constructorCallSite, RuntimeResolverContext context)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitCallSiteMain(ServiceCallSite callSite, TArgument argument)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitDisposeCache(ServiceCallSite transientCallSite, RuntimeResolverContext context)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitCallSite(ServiceCallSite callSite, TArgument argument)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.Resolve(ServiceCallSite callSite, ServiceProviderEngineScope scope)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.DynamicServiceProviderEngine.<>c__DisplayClass2_0.<RealizeService>b__0(ServiceProviderEngineScope scope)
   at Microsoft.Extensions.DependencyInjection.ServiceProvider.GetService(ServiceIdentifier serviceIdentifier, ServiceProviderEngineScope serviceProviderEngineScope)
   at Microsoft.Extensions.DependencyInjection.ServiceProvider.GetService(Type serviceType)
   at Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(IServiceProvider provider, Type serviceType)
   at Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService[T](IServiceProvider provider)
   at NHSISL.LibPostalClient.Clients.LibPostalClient..ctor(LibPostalConfiguration config)
   at MyProjectTests.LibpostalClientTests..ctor() in XXX\MyProjectTests\LibpostalClientTests.cs:line 25
   at System.RuntimeMethodHandle.InvokeMethod(Object target, Void** arguments, Signature sig, Boolean isConstructor)
   at System.Reflection.MethodBaseInvoker.InvokeWithNoArgs(Object obj, BindingFlags invokeAttr)
  Failed GivenShortAddress_ParseAddressAsync_ReturnsExpectedResult [157 ms]
  Error Message:
   OneTimeSetUp: System.DllNotFoundException : Unable to load DLL 'libpostal-1' or one of its dependencies: The specified module could not be found. (0x8007007E)


Failed!  - Failed:     1, Passed:     0, Skipped:     0, Total:     1, Duration: 157 ms - MyProjectTests.dll (net8.0)

My program is really simple.

$ cat MyProject/Program.cs
using System.Reflection;
using NHSISL.LibPostalClient.Clients;
using NHSISL.LibPostalClient.Models.Brokers.LibPostal;

Console.WriteLine("Hello, World!");
var assembly = Assembly.GetExecutingAssembly().Location;
var dataFolderPath = Path.Combine(
    Path.GetDirectoryName(assembly) ?? throw new InvalidOperationException("Assembly path null"),
    @"Data"
);

var config = new LibPostalConfiguration {
    DataDirectory = dataFolderPath,
    ParserDataDirectory = dataFolderPath,
    LanguageClassifierDataDirectory = dataFolderPath
};

var libPostalClient = new LibPostalClient(config);
var inputAddress = "123 Main St";
var outputParsedAddress =
    new List<KeyValuePair<string, string>> { new("road", "main st"), new("house_number", "123"), };
var expectedParsedAddress = outputParsedAddress.ToList();

// Act
var actualParsedAddress = await libPostalClient.ParseAddressAsync(inputAddress);

foreach (var parsedAddress in actualParsedAddress)
{
        Console.WriteLine(parsedAddress.Value);
}

The csproj is below:

$ cat MyProject/MyProject.csproj
<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>net8.0</TargetFramework>
    <ImplicitUsings>enable</ImplicitUsings>
    <Nullable>enable</Nullable>
  </PropertyGroup>

  <ItemGroup>
          <PackageReference Include="NHSISL.LibPostalClient" Version="1.0.0.8"/>
  </ItemGroup>

</Project>

The test csproj is below:

$ cat MyProjectTests.csproj
<Project Sdk="Microsoft.NET.Sdk">

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

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

        <ItemGroup>
                <Using Include="FluentAssertions" />
                <Using Include="Moq" />
                <Using Include="NUnit.Framework" />
        </ItemGroup>

  <ItemGroup>
        <PackageReference Include="FluentAssertions" Version="6.12.0" />
    <PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.6.0" />
        <PackageReference Include="Moq" Version="4.20.70" />
    <PackageReference Include="NUnit" Version="3.13.3" />
    <PackageReference Include="NUnit3TestAdapter" Version="4.2.1" />
    <PackageReference Include="NUnit.Analyzers" Version="3.6.1" />
    <PackageReference Include="coverlet.collector" Version="6.0.0" />
  </ItemGroup>

  <ItemGroup>
    <ProjectReference Include="..\MyProject\MyProject.csproj" />
  </ItemGroup>

</Project>

The unit test

$ cat LibpostalClientTests.cs
using System.Reflection;
using NHSISL.LibPostalClient.Clients;
using NHSISL.LibPostalClient.Models.Brokers.LibPostal;

namespace MyProjectTests;

public class LibpostalClientTests
{
        private readonly ILibPostalClient _libPostalClient;

        public LibpostalClientTests()
        {
                var assembly = Assembly.GetExecutingAssembly().Location;
                var dataFolderPath = Path.Combine(
                    Path.GetDirectoryName(assembly) ?? throw new InvalidOperationException("Assembly path null"),
                    @"Data"
                );

                var config = new LibPostalConfiguration {
                    DataDirectory = dataFolderPath,
                    ParserDataDirectory = dataFolderPath,
                    LanguageClassifierDataDirectory = dataFolderPath
                };

                _libPostalClient = new LibPostalClient(config);
        }

        [Test]
        public async Task GivenShortAddress_ParseAddressAsync_ReturnsExpectedResult()
        {
                // Arrange
                const string inputAddress = "123 Main St";
                var outputParsedAddress =
                    new List<KeyValuePair<string, string>> { new("road", "main st"), new("house_number", "123"), };
                var expectedParsedAddress = outputParsedAddress.ToList();

                // Act
                var actualParsedAddress = await _libPostalClient.ParseAddressAsync(inputAddress);

                // Assert
                actualParsedAddress.Should().BeEquivalentTo(expectedParsedAddress);
        }
}

Expected Behavior

The Libpost data files are copied under the MyprojectTests/bin/(Debug|Release)/net8.0 folder instead of MyProject folder.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions