Skip to content

Commit

Permalink
feat: add optional logFile argument for ConsumerPact/ConsumerMessageP…
Browse files Browse the repository at this point in the history
…act/VerifierOptions
  • Loading branch information
YOU54F committed Sep 6, 2024
1 parent d6f6034 commit 02c8d19
Show file tree
Hide file tree
Showing 10 changed files with 86 additions and 27 deletions.
1 change: 1 addition & 0 deletions native/addon.cc
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ Napi::Object Init(Napi::Env env, Napi::Object exports) {
exports.Set(Napi::String::New(env, "pactffiVersion"), Napi::Function::New(env, PactffiVersion));
exports.Set(Napi::String::New(env, "pactffiInit"), Napi::Function::New(env, PactffiInit));
exports.Set(Napi::String::New(env, "pactffiInitWithLogLevel"), Napi::Function::New(env, PactffiInitWithLogLevel));
exports.Set(Napi::String::New(env, "pactffiLogToFile"), Napi::Function::New(env, PactffiLogToFile));

// Consumer
exports.Set(Napi::String::New(env, "pactffiMockServerMatched"), Napi::Function::New(env, PactffiMockServerMatched));
Expand Down
58 changes: 58 additions & 0 deletions native/ffi.cc
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,64 @@ Napi::Value PactffiInitWithLogLevel(const Napi::CallbackInfo& info) {
return env.Undefined();
}

LevelFilter integerToLevelFilter(Napi::Env &env, uint32_t number) {
LevelFilter logLevel = LevelFilter::LevelFilter_Off;

switch(number) {
case 0:
logLevel = LevelFilter::LevelFilter_Off;
break;
case 1:
logLevel = LevelFilter::LevelFilter_Error;
break;
case 2:
logLevel = LevelFilter::LevelFilter_Warn;
break;
case 3:
logLevel = LevelFilter::LevelFilter_Info;
break;
case 4:
logLevel = LevelFilter::LevelFilter_Debug;
break;
case 5:
logLevel = LevelFilter::LevelFilter_Trace;
break;
default:
std::string err = "pact-js-core C integration: Unable to parse log level number: ";
err += number;

throw Napi::Error::New(env, err);
}

return logLevel;
}


Napi::Value PactffiLogToFile(const Napi::CallbackInfo& info) {
// return: int
Napi::Env env = info.Env();

if (info.Length() < 2) {
throw Napi::Error::New(env, "PactffiLogToFile(envVar) received < 2 arguments");
}

if (!info[0].IsString()) {
throw Napi::Error::New(env, "PactffiLogToFile(envVar) expected a string");
}

if (!info[1].IsNumber()) {
throw Napi::Error::New(env, "PactffiLogToFile(envVar) expected a number");
}

// Extract log level
std::string fileName = info[0].As<Napi::String>().Utf8Value();
uint32_t levelFilterNumber = info[1].As<Napi::Number>().Uint32Value();
LevelFilter levelFilter = integerToLevelFilter(env, levelFilterNumber);

int res = pactffi_log_to_file(fileName.c_str(), levelFilter);

return Napi::Number::New(env, res);
}
/*
Napi::Value Pactffi_log_message(const Napi::CallbackInfo& info) {
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@
"build": "tsc --project tsconfig.build.json",
"prerelease": "npm run snyk-protect",
"release": "commit-and-tag-version",
"test": "cross-env LOGLEVEL=debug PACT_DO_NOT_TRACK=true mocha \"{src,test}/**/*.spec.ts\"",
"test": "cross-env PACT_DO_NOT_TRACK=true mocha \"{src,test}/**/*.spec.ts\"",
"snyk-protect": "snyk-protect",
"format:base": "prettier --parser typescript",
"format:check": "npm run format:base -- --list-different \"{src,test}/**/*.{ts,tsx}\"",
Expand Down
10 changes: 6 additions & 4 deletions src/consumer/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -62,12 +62,13 @@ export const makeConsumerPact = (
consumer: string,
provider: string,
version: FfiSpecificationVersion = 3,
logLevel = getLogLevel()
logLevel = getLogLevel(),
logFile?: string
): ConsumerPact => {
const ffi = getFfiLib(logLevel);
if (logLevel) {
setLogLevel(logLevel);
}
const ffi = getFfiLib(logLevel, logFile);

const pactPtr = ffi.pactffiNewPact(consumer, provider);
if (!ffi.pactffiWithSpecification(pactPtr, version)) {
Expand Down Expand Up @@ -370,12 +371,13 @@ export const makeConsumerMessagePact = (
consumer: string,
provider: string,
version: FfiSpecificationVersion = 4,
logLevel = getLogLevel()
logLevel = getLogLevel(),
logFile?: string
): ConsumerMessagePact => {
const ffi = getFfiLib(logLevel);
if (logLevel) {
setLogLevel(logLevel);
}
const ffi = getFfiLib(logLevel, logFile);

const pactPtr = ffi.pactffiNewPact(consumer, provider);
if (!ffi.pactffiWithSpecification(pactPtr, version) || version < 4) {
Expand Down
32 changes: 17 additions & 15 deletions src/ffi/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import path from 'node:path';
import bindings = require('node-gyp-build');
import logger, { DEFAULT_LOG_LEVEL } from '../logger';
import { LogLevel } from '../logger/types';
import { Ffi } from './types';
import { Ffi, FfiLogLevelFilter } from './types';

export const PACT_FFI_VERSION = '0.4.22';

Expand Down Expand Up @@ -85,18 +85,15 @@ const renderBinaryErrorMessage = (error: unknown) => {
};

let ffi: typeof ffiLib;
let ffiLogLevel: LogLevel;

const initialiseFfi = (logLevel: LogLevel): typeof ffi => {
const initialiseFfi = (): typeof ffi => {
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
if (process.stdout._handle) {
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
process.stdout._handle.setBlocking(true);
}
logger.debug(`Initalising native core at log level '${logLevel}'`);
ffiLogLevel = logLevel;
try {
bindingPaths.every((bindingPath, i) => {
try {
Expand All @@ -114,7 +111,6 @@ const initialiseFfi = (logLevel: LogLevel): typeof ffi => {
return true;
}
});
ffiLib.pactffiInitWithLogLevel(logLevel);
} catch (error) {
renderBinaryErrorMessage(error);
throw new Error(
Expand All @@ -125,18 +121,24 @@ const initialiseFfi = (logLevel: LogLevel): typeof ffi => {
};

export const getFfiLib = (
logLevel: LogLevel = DEFAULT_LOG_LEVEL
logLevel: LogLevel = DEFAULT_LOG_LEVEL,
logFile: string | undefined = undefined
): typeof ffi => {
if (!ffi) {
logger.trace('Initiliasing ffi for the first time');
ffi = initialiseFfi(logLevel);
} else {
logger.trace('Ffi has already been initialised, no need to repeat it');
if (logLevel !== ffiLogLevel) {
logger.warn(
`The pact native core has already been initialised at log level '${ffiLogLevel}'`
logger.trace('Initialising ffi for the first time');
ffi = initialiseFfi();
logger.debug(
`Initialising native core at log level '${logLevel}'`,
logFile
);
if (logFile) {
logger.debug(
`writing log file at level ${FfiLogLevelFilter[logLevel]} to ${logFile}`
);
logger.warn(`The new requested log level '${logLevel}' will be ignored`);
const res = ffiLib.pactffiLogToFile(logFile, FfiLogLevelFilter[logLevel]);
logger.debug(`result of writing to file '${res}'`);
} else {
ffiLib.pactffiInitWithLogLevel(logLevel);
}
}
return ffi;
Expand Down
2 changes: 1 addition & 1 deletion src/verifier/nativeVerifier.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ export const verify = (opts: VerifierOptions): Promise<string> => {
if (opts.logLevel) {
setLogLevel(opts.logLevel);
}
const ffi = getFfiLib(opts.logLevel);
const ffi = getFfiLib(opts.logLevel, opts.logFile);

const handle = ffi.pactffiVerifierNewForApplication(
pkg.name.split('/')[1],
Expand Down
1 change: 1 addition & 0 deletions src/verifier/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ export interface VerifierOptions {
consumerVersionSelectors?: ConsumerVersionSelector[];
timeout?: number;
logLevel?: LogLevel;
logFile?: string;
disableSslVerification?: boolean;
buildUrl?: string;
customProviderHeaders?: CustomHeaders | string[];
Expand Down
1 change: 1 addition & 0 deletions src/verifier/validateOptions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -247,6 +247,7 @@ export const validationRules: ArgumentValidationRules<InternalPactVerifierOption
verbose: [deprecatedFunction],
monkeypatch: [deprecatedFunction],
logDir: [deprecatedFunction],
logFile: [assertNonEmptyString],
consumerFilters: [assertNonEmptyString],
failIfNoPactsFound: [assertBoolean],
transports: [],
Expand Down
3 changes: 0 additions & 3 deletions test/consumer.integration.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import zlib = require('zlib');
import FormData = require('form-data');
import fs = require('fs');
import { load } from 'protobufjs';
import { setLogLevel } from '../src/logger';
import {
ConsumerPact,
makeConsumerPact,
Expand All @@ -21,8 +20,6 @@ const { expect } = chai;
const HOST = '127.0.0.1';

describe('FFI integration test for the HTTP Consumer API', () => {
setLogLevel('trace');

let port: number;
let pact: ConsumerPact;
const bytes: Buffer = zlib.gzipSync('this is an encoded string');
Expand Down
3 changes: 0 additions & 3 deletions test/matt.consumer.integration.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import {
makeConsumerMessagePact,
makeConsumerPact,
} from '../src';
import { setLogLevel } from '../src/logger';
import { FfiSpecificationVersion } from '../src/ffi/types';

chai.use(chaiAsPromised);
Expand Down Expand Up @@ -45,8 +44,6 @@ const sendMattMessageTCP = (

const skipPluginTests = process.env['SKIP_PLUGIN_TESTS'] === 'true';
(skipPluginTests ? describe.skip : describe)('MATT protocol test', () => {
setLogLevel('trace');

let provider: ConsumerPact;
let tcpProvider: ConsumerMessagePact;
let port: number;
Expand Down

0 comments on commit 02c8d19

Please sign in to comment.