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

DevContainer: Unable to load shared library 'pact_ffi' or one of its dependencies #500

Closed
franvivas opened this issue May 21, 2024 · 1 comment · May be fixed by #502
Closed

DevContainer: Unable to load shared library 'pact_ffi' or one of its dependencies #500

franvivas opened this issue May 21, 2024 · 1 comment · May be fixed by #502
Labels
bug Indicates an unexpected problem or unintended behavior triage This issue is yet to be triaged by a maintainer

Comments

@franvivas
Copy link

Previous issues

Version information:
*** Do Not Work ***

  • OS: MacOS ARM M2 / Sonoma
  • PactNet Version: 4.5.0
  • .Net Version: 7.0

*** Do Work ***

  • OS: x64
  • PactNet Version: 4.5.0
  • .Net Version: 7.0

Describe the bug
I work with devcontainer. If I use the devcontainer below i get this error:

System.DllNotFoundException : Unable to load shared library 'pact_ffi' or one of its dependencies. In order to help diagnose loading problems, consider using a tool like strace. If you're using glibc, consider setting the LD_DEBUG environment variable:
/usr/share/dotnet/shared/Microsoft.NETCore.App/7.0.19/pact_ffi.so: cannot open shared object file: No such file or directory

Stack Trace:
at PactNet.Interop.NativeInterop.LogToBuffer(LevelFilter levelFilter)
at PactNet.PactExtensions.InitialiseLogging(PactLogLevel level)
at PactNet.PactExtensions.WithHttpInteractions(IPactV3 pact, Nullable1 port, IPAddress host) at PactNet.PactExtensions.UsingNativeBackend(IPactV3 pact, Nullable1 port, IPAddress host)
at pact_test.xunit.tests.UnitTest1..ctor() in /workspaces/pact_ffi/pact-test.xunit.tests/UnitTest1.cs:line 13
at System.RuntimeType.CreateInstanceDefaultCtor(Boolean publicOnly, Boolean wrapExceptions)

Steps To Reproduce
devcontainer.son

{
  "name": "My Test Dev Container",
  // Or use a Dockerfile or Docker Compose file. More info: https://containers.dev/guide/dockerfile
  "dockerComposeFile": "docker-compose.yml",
  "service": "app",
  "workspaceFolder": "/workspaces/${localWorkspaceFolderBasename}",
  "features": {
    "ghcr.io/devcontainers/features/dotnet:2": {
      "version": "8.0",
      "additionalVersions": "7.0"
    },
    "ghcr.io/devcontainers/features/docker-in-docker:2": {}
  },
  "containerEnv": {},
  "customizations": {
    "vscode": {
      "extensions": [
        "ms-dotnettools.csdevkit",
        "fernandoescolar.vscode-solution-explorer"
      ]
    }
  }
}

docker-compose.yaml

version: "3.8"
services:
  app:
    image: mcr.microsoft.com/devcontainers/base:bullseye
    volumes:
      - ../..:/workspaces:cached
    command: sleep infinity
    networks:
      - pactnetwork

networks:
  pactnetwork:
namespace pact_test.xunit.tests;

using System.Net;
using PactNet;

public class UnitTest1
{
    private readonly IPactBuilderV3 _pactBuilder;

    public UnitTest1()
    {
        var pact = Pact.V3("Something API Consumer", "Something API");
        _pactBuilder = pact.UsingNativeBackend();
    }

    [Fact]
    public async Task Test()
    {
        // Arrange
        _pactBuilder
            .UponReceiving("a request")
                .WithRequest(HttpMethod.Get, "/")
            .WillRespond()
                .WithStatus(HttpStatusCode.OK);

        await _pactBuilder.VerifyAsync(async ctx =>
        {
            var client = new HttpClient { BaseAddress = ctx.MockServerUri };

            var response = await client.GetAsync("/");

            response.EnsureSuccessStatusCode();
        });
    }
}

Expected behavior
Pass the test and create the pact file

Log Output
Starting test execution, please wait...
A total of 1 test files matched the specified pattern.
[xUnit.net 00:00:00.29] pact_test.xunit.tests.UnitTest1.Test [FAIL]
Failed pact_test.xunit.tests.UnitTest1.Test [1 ms]
Error Message:
System.DllNotFoundException : Unable to load shared library 'pact_ffi' or one of its dependencies. In order to help diagnose loading problems, consider using a tool like strace. If you're using glibc, consider setting the LD_DEBUG environment variable:
/usr/share/dotnet/shared/Microsoft.NETCore.App/7.0.19/pact_ffi.so: cannot open shared object file: No such file or directory
/workspaces/pact_ffi/pact-test.xunit.tests/bin/Debug/net7.0/pact_ffi.so: cannot open shared object file: No such file or directory
/usr/share/dotnet/shared/Microsoft.NETCore.App/7.0.19/libpact_ffi.so: cannot open shared object file: No such file or directory
/workspaces/pact_ffi/pact-test.xunit.tests/bin/Debug/net7.0/libpact_ffi.so: cannot open shared object file: No such file or directory
/usr/share/dotnet/shared/Microsoft.NETCore.App/7.0.19/pact_ffi: cannot open shared object file: No such file or directory
/workspaces/pact_ffi/pact-test.xunit.tests/bin/Debug/net7.0/pact_ffi: cannot open shared object file: No such file or directory
/usr/share/dotnet/shared/Microsoft.NETCore.App/7.0.19/libpact_ffi: cannot open shared object file: No such file or directory
/workspaces/pact_ffi/pact-test.xunit.tests/bin/Debug/net7.0/libpact_ffi: cannot open shared object file: No such file or directory

Stack Trace:
at PactNet.Interop.NativeInterop.LogToBuffer(LevelFilter levelFilter)
at PactNet.PactExtensions.InitialiseLogging(PactLogLevel level)
at PactNet.PactExtensions.WithHttpInteractions(IPactV3 pact, Nullable1 port, IPAddress host) at PactNet.PactExtensions.UsingNativeBackend(IPactV3 pact, Nullable1 port, IPAddress host)
at pact_test.xunit.tests.UnitTest1..ctor() in /workspaces/pact_ffi/pact-test.xunit.tests/UnitTest1.cs:line 13
at System.RuntimeType.CreateInstanceDefaultCtor(Boolean publicOnly, Boolean wrapExceptions)

Failed! - Failed: 1, Passed: 0, Skipped: 0, Total: 1, Duration: < 1 ms - pact-test.xunit.tests.dll (net7.0)

Additional context
If I launch this devcontainer in a Mac with Intel x64, it works.
If I launch this devcontainer in a Mac with ARM M2, it does not work.
If I launch this test locally in a Mac with ARM M2, it works.

@franvivas franvivas added bug Indicates an unexpected problem or unintended behavior triage This issue is yet to be triaged by a maintainer labels May 21, 2024
@adamrodger
Copy link
Contributor

Mac ARM isn't supported in 4.x. Support is added from 5.0.0-beta.2 onwards. See #451 (comment)

YOU54F added a commit to YOU54F/pact-net that referenced this issue May 29, 2024
## Rationale

pact-reference has introduced musl and arm64 based ffi libraries for linux

- pact-foundation/pact-reference#416

Tracking Issue

- pact-foundation/roadmap#30

## Issues Resolved

fixes pact-foundation#498
fixes pact-foundation#496
fixes pact-foundation#500
fixes pact-foundation#374
fixes pact-foundation#387

## Backwards Compatibility

Linux glibc based hosts take precedence, so if any error occurs during musl
detection. I do not anticipate breaking changes for users

## Implementation notes

### .NET notes

- Docs
  - [Uses MSBuild Exec task](https://learn.microsoft.com/en-us/visualstudio/msbuild/exec-task?view=vs-2022)
- MSBuild Blog Posts
  - [Cross-Platform Build Events in .NET Core using MSBuild](https://jeremybytes.blogspot.com/2020/05/cross-platform-build-events-in-net-core.html)
  - [MSBuild 101: Using the exit code from a command](https://www.creepingcoder.com/2020/06/01/msbuild-101-using-the-exit-code-from-a-command/)
- Stack OverFlow
  - [Set PropertyGroup property to Exec output](https://stackoverflow.com/questions/76583824/set-propertygroup-property-to-exec-output)
- .NET runtime musl detection code
  - https://github.com/dotnet/runtime/blob/a50ba0669353893ca8ade8568b0a7d210b5a425f/src/mono/llvm/llvm-init.proj\#L7
  - https://github.com/dotnet/runtime/blob/a50ba0669353893ca8ade8568b0a7d210b5a425f/src/libraries/Common/tests/TestUtilities/System/PlatformDetection.Unix.cs\#L78t

### Conditions for execution

musl detection will run if

- if linux
- if /lib/ld-musl-(x86_64|aarch64).so.1 exists
- if ldd bin/sh | grep musl is true (musl lib is loaded, rather than glibc)

will continue on error, reverting back to glibc based libaries.

### Supported musl targets

should work for multiple musl based distroes if

- /lib/ld-musl-(x86_64|aarch64).so.1 exists
- ldd is available (available by default in alpine images)

Tested on Alpine ARM64 / AMD64.

## Caveats

- [.NET does not run under QEMU](https://github.com/dotnet/core/blob/main/release-notes/8.0/supported-os.md#qemu) affecting the ability to test multi-arch from a single system
- .NET restore can take a long time when running under containers.
  - [Workaround](NuGet/Home#13062 (comment)): Set `DOTNET_NUGET_SIGNATURE_VERIFICATION` to `false`

## Compatibility

### Operating System

Due to using a shared native library instead of C# for the main Pact logic only certain OSs are supported:

| OS           | Arch        | Support                                                            |
| ------------ | ----------- | -------------------------------------------------------------------|
| Windows      | x86         | ❌ No                                                              |
| Windows      | x64         | ✔️ Yes                                                              |
| Linux (libc) | x86         | ❌ No                                                              |
| Linux (libc) | x64         | ✔️ Yes                                                              |
| Linux (musl) | x64         | ✔️ Yes (Tier 2)*                                                    |
| Linux (libc) | ARM         | ✔️ Yes (Tier 3)*                                                    |
| Linux (musl) | ARM         | ✔️ Yes (Tier 3)*                                                    |
| OSX          | x64         | ✔️ Yes                                                              |
| OSX          | ARM (M1/M2) | ✔️ Yes                                                              |

#### Support

- Tier 1
  - Established
  - Full CI/CD support.
  - Users should not encounter issues
  - Full reproducible examples running in CI, should be provided by users raising issues
  - If using musl targets, users should attempt the same test on a libc target (such as debian)
- Tier 2
  - Recently introduced
  - Full CI/CD support.
  - Users may encounter issues
  - Full reproducible examples running in CI, should be provided by users raising issues
  - If using musl targets, users should attempt the same test on a libc target (such as debian)
- Tier 3
  - Recently introduced, No/limited CI/CD support.
  - Users may encounter issues
  - Full reproducible examples which can be run by maintainers locally, should be provided by users raising issues
YOU54F added a commit to YOU54F/pact-net that referenced this issue Sep 24, 2024
## Rationale

pact-reference has introduced musl and arm64 based ffi libraries for linux

- pact-foundation/pact-reference#416

Tracking Issue

- pact-foundation/roadmap#30

## Issues Resolved

fixes pact-foundation#498
fixes pact-foundation#496
fixes pact-foundation#500
fixes pact-foundation#374
fixes pact-foundation#387

## Backwards Compatibility

Linux glibc based hosts take precedence, so if any error occurs during musl
detection. I do not anticipate breaking changes for users

## Implementation notes

### .NET notes

- Docs
  - [Uses MSBuild Exec task](https://learn.microsoft.com/en-us/visualstudio/msbuild/exec-task?view=vs-2022)
- MSBuild Blog Posts
  - [Cross-Platform Build Events in .NET Core using MSBuild](https://jeremybytes.blogspot.com/2020/05/cross-platform-build-events-in-net-core.html)
  - [MSBuild 101: Using the exit code from a command](https://www.creepingcoder.com/2020/06/01/msbuild-101-using-the-exit-code-from-a-command/)
- Stack OverFlow
  - [Set PropertyGroup property to Exec output](https://stackoverflow.com/questions/76583824/set-propertygroup-property-to-exec-output)
- .NET runtime musl detection code
  - https://github.com/dotnet/runtime/blob/a50ba0669353893ca8ade8568b0a7d210b5a425f/src/mono/llvm/llvm-init.proj\#L7
  - https://github.com/dotnet/runtime/blob/a50ba0669353893ca8ade8568b0a7d210b5a425f/src/libraries/Common/tests/TestUtilities/System/PlatformDetection.Unix.cs\#L78t

### Conditions for execution

musl detection will run if

- if linux
- if /lib/ld-musl-(x86_64|aarch64).so.1 exists
- if ldd bin/sh | grep musl is true (musl lib is loaded, rather than glibc)

will continue on error, reverting back to glibc based libaries.

### Supported musl targets

should work for multiple musl based distroes if

- /lib/ld-musl-(x86_64|aarch64).so.1 exists
- ldd is available (available by default in alpine images)

Tested on Alpine ARM64 / AMD64.
YOU54F added a commit to YOU54F/pact-net that referenced this issue Feb 17, 2025
## Rationale

pact-reference has introduced musl and arm64 based ffi libraries for linux

- pact-foundation/pact-reference#416

Tracking Issue

- pact-foundation/roadmap#30

## Issues Resolved

fixes pact-foundation#498
fixes pact-foundation#496
fixes pact-foundation#500
fixes pact-foundation#374
fixes pact-foundation#387

## Backwards Compatibility

Linux glibc based hosts take precedence, so if any error occurs during musl
detection. I do not anticipate breaking changes for users

## Implementation notes

### .NET notes

- Docs
  - [Uses MSBuild Exec task](https://learn.microsoft.com/en-us/visualstudio/msbuild/exec-task?view=vs-2022)
- MSBuild Blog Posts
  - [Cross-Platform Build Events in .NET Core using MSBuild](https://jeremybytes.blogspot.com/2020/05/cross-platform-build-events-in-net-core.html)
  - [MSBuild 101: Using the exit code from a command](https://www.creepingcoder.com/2020/06/01/msbuild-101-using-the-exit-code-from-a-command/)
- Stack OverFlow
  - [Set PropertyGroup property to Exec output](https://stackoverflow.com/questions/76583824/set-propertygroup-property-to-exec-output)
- .NET runtime musl detection code
  - https://github.com/dotnet/runtime/blob/a50ba0669353893ca8ade8568b0a7d210b5a425f/src/mono/llvm/llvm-init.proj\#L7
  - https://github.com/dotnet/runtime/blob/a50ba0669353893ca8ade8568b0a7d210b5a425f/src/libraries/Common/tests/TestUtilities/System/PlatformDetection.Unix.cs\#L78t

### Conditions for execution

musl detection will run if

- if linux
- if /lib/ld-musl-(x86_64|aarch64).so.1 exists
- if ldd bin/sh | grep musl is true (musl lib is loaded, rather than glibc)

will continue on error, reverting back to glibc based libaries.

### Supported musl targets

should work for multiple musl based distroes if

- /lib/ld-musl-(x86_64|aarch64).so.1 exists
- ldd is available (available by default in alpine images)

Tested on Alpine ARM64 / AMD64.
YOU54F added a commit to YOU54F/pact-net that referenced this issue Feb 17, 2025
pact-reference has introduced musl and arm64 based ffi libraries for linux

- pact-foundation/pact-reference#416

Tracking Issue

- pact-foundation/roadmap#30

fixes pact-foundation#498
fixes pact-foundation#496
fixes pact-foundation#500
fixes pact-foundation#374
fixes pact-foundation#387

Linux glibc based hosts take precedence, so if any error occurs during musl
detection. I do not anticipate breaking changes for users

- Docs
  - [Uses MSBuild Exec task](https://learn.microsoft.com/en-us/visualstudio/msbuild/exec-task?view=vs-2022)
- MSBuild Blog Posts
  - [Cross-Platform Build Events in .NET Core using MSBuild](https://jeremybytes.blogspot.com/2020/05/cross-platform-build-events-in-net-core.html)
  - [MSBuild 101: Using the exit code from a command](https://www.creepingcoder.com/2020/06/01/msbuild-101-using-the-exit-code-from-a-command/)
- Stack OverFlow
  - [Set PropertyGroup property to Exec output](https://stackoverflow.com/questions/76583824/set-propertygroup-property-to-exec-output)
- .NET runtime musl detection code
  - https://github.com/dotnet/runtime/blob/a50ba0669353893ca8ade8568b0a7d210b5a425f/src/mono/llvm/llvm-init.proj\#L7
  - https://github.com/dotnet/runtime/blob/a50ba0669353893ca8ade8568b0a7d210b5a425f/src/libraries/Common/tests/TestUtilities/System/PlatformDetection.Unix.cs\#L78t

musl detection will run if

- if linux
- if /lib/ld-musl-(x86_64|aarch64).so.1 exists
- if ldd bin/sh | grep musl is true (musl lib is loaded, rather than glibc)

will continue on error, reverting back to glibc based libaries.

should work for multiple musl based distroes if

- /lib/ld-musl-(x86_64|aarch64).so.1 exists
- ldd is available (available by default in alpine images)

Tested on Alpine ARM64 / AMD64.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Indicates an unexpected problem or unintended behavior triage This issue is yet to be triaged by a maintainer
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants