kdbx.dart icon indicating copy to clipboard operation
kdbx.dart copied to clipboard

Unit test failed on Mac M1

Open drriguz opened this issue 1 year ago • 5 comments

When run flutter test on a Mac M1 device the unit test will fail:

To run this test again: /Users/riguz/mobile/flutter/bin/cache/dart-sdk/bin/dart test /Users/riguz/Documents/apps/kdbx.dart/test/deleted_objects_test.dart -p vm --plain-name 'delete permanently delete entry'
00:01 +6 -25: loading /Users/riguz/Documents/apps/kdbx.dart/test/deleted_objects_test.dart
2024-02-27 16:47:02.918727 FINEST argon2_ffi_base - resolving libargon2_ffi.dylib
2024-02-27 16:47:02.919057 FINE test_utils - Resolving libargon2_ffi.dylib to: /Users/riguz/Documents/apps/kdbx.dart/libargon2_ffi.dylib (file:///Users/riguz/Documents/apps/kdbx.dart/main.dart)
2024-02-27 16:47:02.919168 FINEST argon2_ffi_base - DynamicLibrary.open(/Users/riguz/Documents/apps/kdbx.dart/libargon2_ffi.dylib)
Shell: 2024-02-27 16:47:02.919406 SEVERE argon2_ffi_base - Error while loading dynamic library from /Users/riguz/Documents/apps/kdbx.dart/libargon2_ffi.dylib
(libargon2_ffi.dylib)
Shell: ### ArgumentError: Invalid argument(s): Failed to load dynamic library '/Users/riguz/Documents/apps/kdbx.dart/libargon2_ffi.dylib':
dlopen(/Users/riguz/Documents/apps/kdbx.dart/libargon2_ffi.dylib, 0x0001): tried: '/Users/riguz/Documents/apps/kdbx.dart/libargon2_ffi.dylib' (mach-o file, but is an incompatible
architecture (have 'x86_64', need 'arm64')), '/System/Volumes/Preboot/Cryptexes/OS/Users/riguz/Documents/apps/kdbx.dart/libargon2_ffi.dylib' (no such file),
'/Users/riguz/Documents/apps/kdbx.dart/libargon2_ffi.dylib' (mach-o file, but is an incompatible architecture (have 'x86_64', need 'arm64'))
Shell: #0      _open (dart:ffi-patch/ffi_dynamic_library_patch.dart:11:43)
Shell: #1      new DynamicLibrary.open (dart:ffi-patch/ffi_dynamic_library_patch.dart:22:12)
Shell: #2      Argon2FfiFlutter._loadLib (package:argon2_ffi_base/src/argon2_ffi_impl.dart:163:29)
Shell: #3      new Argon2FfiFlutter (package:argon2_ffi_base/src/argon2_ffi_impl.dart:92:23)
Shell: #4      TestUtil._kdbxFormat (file:///Users/riguz/Documents/apps/kdbx.dart/test/internal/test_utils.dart:29:23)
Shell: #5      TestUtil.kdbxFormat (file:///Users/riguz/Documents/apps/kdbx.dart/test/internal/test_utils.dart:25:27)
Shell: #6      TestUtil.kdbxFormat (file:///Users/riguz/Documents/apps/kdbx.dart/test/internal/test_utils.dart)
Shell: #7      TestUtil.createEmptyFile (file:///Users/riguz/Documents/apps/kdbx.dart/test/internal/test_utils.dart:68:18)
Shell: #8      main.<anonymous closure>.<anonymous closure> (file:///Users/riguz/Documents/apps/kdbx.dart/test/deleted_objects_test.dart:59:29)
Shell: #9      Declarer.test.<anonymous closure>.<anonymous closure> (package:test_api/src/backend/declarer.dart:215:19)
Shell: <asynchronous suspension>
Shell: #10     Declarer.test.<anonymous closure> (package:test_api/src/backend/declarer.dart:213:7)
Shell: <asynchronous suspension>
Shell: #11     Invoker._waitForOutstandingCallbacks.<anonymous closure> (package:test_api/src/backend/invoker.dart:258:9)
Shell: <asynchronous suspension>
Shell:

It seems that libargon2_ffi.dylib is compiled on Mac X86_64, and I re-compiled on M1 it works. It could be solved as following(generated by GPT):

final is64Bit = ffi.sizeOf<ffi.IntPtr>() == 8;  
if (is64Bit) {  
      // Use the x86_64 library for MacOS  
      dylib = ffi.DynamicLibrary.open('x86_64.so');  
} else {  
      // Use the arm library for MacOS  
      dylib = ffi.DynamicLibrary.open('arm.so');  
}

Since it requires to modify both kdbx.dart and argon2_ffi_base, I'm not able to file a PR directly.

drriguz avatar Feb 27 '24 09:02 drriguz

However authpass does work on the same computer, why?

image

drriguz avatar Feb 27 '24 09:02 drriguz

BTW, I found that PointyCastleArgon2 is already used in kdbx.dart:

  KdbxFormat([Argon2? argon2])
      : assert(kdbxKeyCommonAssertConsistency()),
        argon2 = argon2 == null || !argon2.isImplemented
            ? const PointyCastleArgon2()
            : argon2;

I think we can use it in unit test, which runs on dart vm and does not require any native library.

Also, have your benchmarked the performance between PointyCastleArgon2 and dragon2_ffi?

drriguz avatar Feb 28 '24 04:02 drriguz

I'm happy with the performance of argon2_ffi, and I don't think dragon2_ffi existed when I implemented it.. never tried it..

I guess we could use an environment variable or something to enforce pointy castle during unit tests 🤷🏽 I would still allow both though, so the ci uses the ffi implementation

hpoul avatar Feb 28 '24 05:02 hpoul

Got it, thanks! I'll try to use pointy castle in my fork of kdbx.dart to reduce complexity. I'm developing an encrypted note app, and I'm considering using kdbx and sqlcipher together to store passwords and notes. Anyway, thanks for your great work !

drriguz avatar Feb 28 '24 05:02 drriguz

fwiw, if you are developing a flutter app the native libraries should be loaded automatically.. just like with authpass.. for dart itself has no way to ship assets with packages yet, but that should change soon https://github.com/dart-lang/sdk/issues/50565

hpoul avatar Feb 28 '24 07:02 hpoul