Skip to content

Commit

Permalink
Init rust api once (#228)
Browse files Browse the repository at this point in the history
* Garbage collects before exiting to avoid segfault

Signed-off-by: Pascal Heitz <pascal.heitz@absa.africa>

* Enforce initRustAPI to be called once

Signed-off-by: Pascal Heitz <pascal.heitz@absa.africa>

* enforce initRustApi once

Signed-off-by: Pascal Heitz <pascal.heitz@absa.africa>

* Removed empty spaces

Signed-off-by: Pascal Heitz <pascal.heitz@absa.africa>

* Merge fix

Signed-off-by: Pascal Heitz <pascal.heitz@absa.africa>

* Better comment

Signed-off-by: Pascal Heitz <pascal.heitz@absa.africa>

* test:aries => test

Signed-off-by: Pascal Heitz <pascal.heitz@absa.africa>

Co-authored-by: Pascal Heitz <pascal.heitz@absa.africa>
  • Loading branch information
OoDeLally and Pascal Heitz authored Dec 10, 2020
1 parent 521462e commit fcdbd68
Show file tree
Hide file tree
Showing 6 changed files with 58 additions and 26 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -644,7 +644,7 @@ jobs:
cd $HOME/wrappers/node && \
npm install && \
npm run compile && \
npm run test:aries)'
npm run test)'
# TODO: Run in parallel once https://github.com/actions/runner/issues/646 is ready
test-integration-node-wrapper:
Expand Down
27 changes: 13 additions & 14 deletions wrappers/node/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -70,20 +70,19 @@
"lint:js:fix": "standard --fix demo/*.js common/*.js client-vcx/*.js",
"doc-gen": "./node_modules/.bin/typedoc --out doc --excludePrivate --excludeProtected --ignoreCompilerErrors src",
"test": "npm run test:connection && npm run test:credentialDef && npm run test:credential && npm run test:disclosedProof && npm run test:issuerCredential && npm run test:proof && npm run test:schema && npm run test:utils && npm run test:wallet && npm run test:ffi && npm run test:logging",
"test:aries": "npm run test:aries:connection && npm run test:aries:credentialDef && npm run test:aries:credential && npm run test:aries:disclosedProof && npm run test:aries:issuerCredential && npm run test:aries:proof && npm run test:aries:schema && npm run test:aries:utils && npm run test:aries:wallet && npm run test:ffi && npm run test:logging",
"test:aries:connection": " TS_NODE_PROJECT=./test/tsconfig.json NODE_ENV=test RUST_BACKTRACE=full ./node_modules/.bin/mocha --timeout 10000 --expose-gc --exit --recursive --use_strict --require ts-node/register ./test/suite1/ariesvcx-connection.test.ts",
"test:aries:credentialDef": " TS_NODE_PROJECT=./test/tsconfig.json NODE_ENV=test RUST_BACKTRACE=full ./node_modules/.bin/mocha --timeout 10000 --expose-gc --exit --recursive --use_strict --require ts-node/register ./test/suite1/ariesvcx-credential-def.test.ts",
"test:aries:credential": " TS_NODE_PROJECT=./test/tsconfig.json NODE_ENV=test RUST_BACKTRACE=full ./node_modules/.bin/mocha --timeout 10000 --expose-gc --exit --recursive --use_strict --require ts-node/register ./test/suite1/ariesvcx-credential.test.ts",
"test:aries:disclosedProof": " TS_NODE_PROJECT=./test/tsconfig.json NODE_ENV=test RUST_BACKTRACE=full ./node_modules/.bin/mocha --timeout 10000 --expose-gc --exit --recursive --use_strict --require ts-node/register ./test/suite1/ariesvcx-disclosed-proof.test.ts",
"test:aries:issuerCredential": "TS_NODE_PROJECT=./test/tsconfig.json NODE_ENV=test RUST_BACKTRACE=full ./node_modules/.bin/mocha --timeout 10000 --expose-gc --exit --recursive --use_strict --require ts-node/register ./test/suite1/ariesvcx-issuer-credential.test.ts",
"test:aries:proof": " TS_NODE_PROJECT=./test/tsconfig.json NODE_ENV=test RUST_BACKTRACE=full ./node_modules/.bin/mocha --timeout 10000 --expose-gc --exit --recursive --use_strict --require ts-node/register ./test/suite1/ariesvcx-proof.test.ts",
"test:aries:schema": " TS_NODE_PROJECT=./test/tsconfig.json NODE_ENV=test RUST_BACKTRACE=full ./node_modules/.bin/mocha --timeout 10000 --expose-gc --exit --recursive --use_strict --require ts-node/register ./test/suite1/ariesvcx-schema.test.ts",
"test:aries:utils": " TS_NODE_PROJECT=./test/tsconfig.json NODE_ENV=test RUST_BACKTRACE=full ./node_modules/.bin/mocha --timeout 10000 --expose-gc --exit --recursive --use_strict --require ts-node/register ./test/suite1/ariesvcx-utils.test.ts",
"test:aries:wallet": " TS_NODE_PROJECT=./test/tsconfig.json NODE_ENV=test RUST_BACKTRACE=full ./node_modules/.bin/mocha --timeout 10000 --expose-gc --exit --recursive --use_strict --require ts-node/register ./test/suite1/ariesvcx-wallet.test.ts",
"test:ffi": " TS_NODE_PROJECT=./test/tsconfig.json NODE_ENV=test RUST_BACKTRACE=full ./node_modules/.bin/mocha --timeout 10000 --expose-gc --exit --recursive --use_strict --require ts-node/register ./test/suite2/ffi.test.ts",
"test:logging": " TS_NODE_PROJECT=./test/tsconfig.json NODE_ENV=test find ./test/suite3 -name '*.test.ts' -exec ./node_modules/.bin/mocha --timeout 10000 --expose-gc --exit --recursive --use_strict --require ts-node/register \\{} \\;",
"test:logging1": " TS_NODE_PROJECT=./test/tsconfig.json NODE_ENV=test RUST_BACKTRACE=full ./node_modules/.bin/mocha --timeout 10000 --expose-gc --exit --recursive --use_strict --require ts-node/register ./test/suite3/logging.1.test.ts",
"test:logging2": " TS_NODE_PROJECT=./test/tsconfig.json NODE_ENV=test RUST_BACKTRACE=full ./node_modules/.bin/mocha --timeout 10000 --expose-gc --exit --recursive --use_strict --require ts-node/register ./test/suite3/logging.2.test.ts"
"test:connection": " TS_NODE_PROJECT=./test/tsconfig.json NODE_ENV=test RUST_BACKTRACE=full ./node_modules/.bin/mocha --timeout 10000 --expose-gc --recursive --use_strict --require ts-node/register ./test/suite1/ariesvcx-connection.test.ts",
"test:credentialDef": " TS_NODE_PROJECT=./test/tsconfig.json NODE_ENV=test RUST_BACKTRACE=full ./node_modules/.bin/mocha --timeout 10000 --expose-gc --recursive --use_strict --require ts-node/register ./test/suite1/ariesvcx-credential-def.test.ts",
"test:credential": " TS_NODE_PROJECT=./test/tsconfig.json NODE_ENV=test RUST_BACKTRACE=full ./node_modules/.bin/mocha --timeout 10000 --expose-gc --recursive --use_strict --require ts-node/register ./test/suite1/ariesvcx-credential.test.ts",
"test:disclosedProof": " TS_NODE_PROJECT=./test/tsconfig.json NODE_ENV=test RUST_BACKTRACE=full ./node_modules/.bin/mocha --timeout 10000 --expose-gc --recursive --use_strict --require ts-node/register ./test/suite1/ariesvcx-disclosed-proof.test.ts",
"test:issuerCredential": "TS_NODE_PROJECT=./test/tsconfig.json NODE_ENV=test RUST_BACKTRACE=full ./node_modules/.bin/mocha --timeout 10000 --expose-gc --recursive --use_strict --require ts-node/register ./test/suite1/ariesvcx-issuer-credential.test.ts",
"test:proof": " TS_NODE_PROJECT=./test/tsconfig.json NODE_ENV=test RUST_BACKTRACE=full ./node_modules/.bin/mocha --timeout 10000 --expose-gc --recursive --use_strict --require ts-node/register ./test/suite1/ariesvcx-proof.test.ts",
"test:schema": " TS_NODE_PROJECT=./test/tsconfig.json NODE_ENV=test RUST_BACKTRACE=full ./node_modules/.bin/mocha --timeout 10000 --expose-gc --recursive --use_strict --require ts-node/register ./test/suite1/ariesvcx-schema.test.ts",
"test:utils": " TS_NODE_PROJECT=./test/tsconfig.json NODE_ENV=test RUST_BACKTRACE=full ./node_modules/.bin/mocha --timeout 10000 --expose-gc --recursive --use_strict --require ts-node/register ./test/suite1/ariesvcx-utils.test.ts",
"test:wallet": " TS_NODE_PROJECT=./test/tsconfig.json NODE_ENV=test RUST_BACKTRACE=full ./node_modules/.bin/mocha --timeout 10000 --expose-gc --recursive --use_strict --require ts-node/register ./test/suite1/ariesvcx-wallet.test.ts",
"test:ffi": " TS_NODE_PROJECT=./test/tsconfig.json NODE_ENV=test RUST_BACKTRACE=full ./node_modules/.bin/mocha --timeout 10000 --expose-gc --recursive --use_strict --require ts-node/register ./test/suite2/ffi.test.ts",
"test:logging": " TS_NODE_PROJECT=./test/tsconfig.json NODE_ENV=test find ./test/suite3 -name '*.test.ts' -exec ./node_modules/.bin/mocha --timeout 10000 --expose-gc --recursive --use_strict --require ts-node/register \\{} \\;",
"test:logging1": " TS_NODE_PROJECT=./test/tsconfig.json NODE_ENV=test RUST_BACKTRACE=full ./node_modules/.bin/mocha --timeout 10000 --expose-gc --recursive --use_strict --require ts-node/register ./test/suite3/logging.1.test.ts",
"test:logging2": " TS_NODE_PROJECT=./test/tsconfig.json NODE_ENV=test RUST_BACKTRACE=full ./node_modules/.bin/mocha --timeout 10000 --expose-gc --recursive --use_strict --require ts-node/register ./test/suite3/logging.2.test.ts"
},
"main": "dist/src/index.js",
"typings": "dist/src/index.d.ts"
Expand Down
3 changes: 1 addition & 2 deletions wrappers/node/src/api/init.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { Callback } from 'ffi-napi'

import { VCXInternalError } from '../errors'
import { initRustAPI, rustAPI } from '../rustlib'
import { rustAPI } from '../rustlib'
import { createFFICallbackPromise } from '../utils/ffi-helpers'
import { IInitVCXOptions } from './common'

Expand All @@ -28,7 +28,6 @@ import { IInitVCXOptions } from './common'
*/

export async function initVcxCore (config: string, options: IInitVCXOptions = {}) {
initRustAPI(options.libVCXPath)
const rc = rustAPI().vcx_init_core(config)
if (rc !== 0) {
throw new VCXInternalError(rc)
Expand Down
6 changes: 2 additions & 4 deletions wrappers/node/src/api/utils.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
import { Callback } from 'ffi-napi'

import { VCXInternalError } from '../errors'
import { initRustAPI, rustAPI } from '../rustlib'
import { rustAPI } from '../rustlib'
import { createFFICallbackPromise } from '../utils/ffi-helpers'
import { IInitVCXOptions } from './common'
// import { resolve } from 'url';

export async function provisionAgent (configAgent: string, options: IInitVCXOptions = {}): Promise<string> {
export async function provisionAgent (configAgent: string): Promise<string> {
/**
* Provision an agent in the agency, populate configuration and wallet for this agent.
*
Expand All @@ -24,7 +23,6 @@ export async function provisionAgent (configAgent: string, options: IInitVCXOpti
* vcxConfig = await provisionAgent(JSON.stringify(enterprise_config))
*/
try {
initRustAPI(options.libVCXPath)
return await createFFICallbackPromise<string>(
(resolve, reject, cb) => {
const rc = rustAPI().vcx_agent_provision_async(0, configAgent, cb)
Expand Down
19 changes: 17 additions & 2 deletions wrappers/node/src/rustlib.ts
Original file line number Diff line number Diff line change
Expand Up @@ -482,5 +482,20 @@ export const FFIConfiguration: { [ Key in keyof IFFIEntryPoint ]: any } = {
}

let _rustAPI: IFFIEntryPoint
export const initRustAPI = (path?: string) => _rustAPI = new VCXRuntime({ basepath: path }).ffi
export const rustAPI = () => _rustAPI
let wasInitialized = false
export const initRustAPI = (path?: string): IFFIEntryPoint => {
if (wasInitialized) {
throw new Error('initRustAPI was already initialized. Make sure you only call it once in the lifetime of the process.')
}
_rustAPI = new VCXRuntime({ basepath: path }).ffi
wasInitialized = true
return _rustAPI
}
export const rustAPI = (): IFFIEntryPoint => {
if (!_rustAPI) {
throw new Error('RustAPI not loaded. Make sure you are calling initRustAPI(...)');
}
return _rustAPI
}

export const isRustApiInitialized = (): boolean => Boolean(_rustAPI)
27 changes: 24 additions & 3 deletions wrappers/node/test/helpers/utils.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { initRustAPI } from 'src'
import { assert } from 'chai'
import { initRustAPI, isRustApiInitialized } from 'src'
import * as vcx from 'src'
import * as uuid from 'uuid'
import '../module-resolver-helper'
Expand Down Expand Up @@ -37,8 +38,11 @@ function generateTestConfig () {
return sampleConfig
}

export async function initVcxTestMode () {
initRustAPI()
export async function initVcxTestMode() {
scheduleGarbageCollectionBeforeExit();
if (!isRustApiInitialized()) {
initRustAPI()
}
const rustLogPattern = process.env.RUST_LOG || 'vcx=error'
await vcx.defaultLogger(rustLogPattern)
const useTestConfig = generateTestConfig()
Expand All @@ -55,3 +59,20 @@ export const shouldThrow = (fn: () => any): Promise<vcx.VCXInternalError> => new
})

export const sleep = (timeout: number) => new Promise((resolve, reject) => setTimeout(resolve, timeout))


let garbageCollectionBeforeExitIsScheduled = false

// For some (yet unknown) reason, The Rust library segfaults on exit if global.gc() is not called explicitly.
// To solve this issue, we call global.gc() on `beforeExit` event.
// NB: This solution only works with Mocha.
// With Jest the 'beforeExit' event doesn't seem fired, so we are instead still using --forceExit before it segfaults.
const scheduleGarbageCollectionBeforeExit = () => {
if (!garbageCollectionBeforeExitIsScheduled) {
assert(global.gc)
process.on('beforeExit', () => {
global.gc();
});
}
garbageCollectionBeforeExitIsScheduled = true;
}

0 comments on commit fcdbd68

Please sign in to comment.