Skip to content

Commit

Permalink
[Test] Add tests for async progress queue worker (#1316)
Browse files Browse the repository at this point in the history
* test: Add tests for async progress queue worker

* Fix PR suggestions
  • Loading branch information
JckXia authored Jun 10, 2023
1 parent 665f4aa commit a198e24
Show file tree
Hide file tree
Showing 2 changed files with 289 additions and 0 deletions.
155 changes: 155 additions & 0 deletions test/async_progress_queue_worker.cc
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,158 @@ struct ProgressData {
int32_t progress;
};

class TestWorkerWithNoCb : public AsyncProgressQueueWorker<ProgressData> {
public:
static void DoWork(const CallbackInfo& info) {
switch (info.Length()) {
case 1: {
Function cb = info[0].As<Function>();
TestWorkerWithNoCb* worker = new TestWorkerWithNoCb(info.Env(), cb);
worker->Queue();
} break;

case 2: {
std::string resName = info[0].As<String>();
Function cb = info[1].As<Function>();
TestWorkerWithNoCb* worker =
new TestWorkerWithNoCb(info.Env(), resName.c_str(), cb);
worker->Queue();
} break;

case 3: {
std::string resName = info[0].As<String>();
Object resObject = info[1].As<Object>();
Function cb = info[2].As<Function>();
TestWorkerWithNoCb* worker =
new TestWorkerWithNoCb(info.Env(), resName.c_str(), resObject, cb);
worker->Queue();
} break;

default:

break;
}
}

protected:
void Execute(const ExecutionProgress& progress) override {
ProgressData data{1};
progress.Send(&data, 1);
}

void OnProgress(const ProgressData*, size_t /* count */) override {
_cb.Call({});
}

private:
TestWorkerWithNoCb(Napi::Env env, Function cb)
: AsyncProgressQueueWorker(env) {
_cb.Reset(cb, 1);
}
TestWorkerWithNoCb(Napi::Env env, const char* resourceName, Function cb)
: AsyncProgressQueueWorker(env, resourceName) {
_cb.Reset(cb, 1);
}
TestWorkerWithNoCb(Napi::Env env,
const char* resourceName,
const Object& resourceObject,
Function cb)
: AsyncProgressQueueWorker(env, resourceName, resourceObject) {
_cb.Reset(cb, 1);
}
FunctionReference _cb;
};

class TestWorkerWithRecv : public AsyncProgressQueueWorker<ProgressData> {
public:
static void DoWork(const CallbackInfo& info) {
switch (info.Length()) {
case 2: {
Object recv = info[0].As<Object>();
Function cb = info[1].As<Function>();
TestWorkerWithRecv* worker = new TestWorkerWithRecv(recv, cb);
worker->Queue();
} break;

case 3: {
Object recv = info[0].As<Object>();
Function cb = info[1].As<Function>();
std::string resName = info[2].As<String>();
TestWorkerWithRecv* worker =
new TestWorkerWithRecv(recv, cb, resName.c_str());
worker->Queue();
} break;

case 4: {
Object recv = info[0].As<Object>();
Function cb = info[1].As<Function>();
std::string resName = info[2].As<String>();
Object resObject = info[3].As<Object>();
TestWorkerWithRecv* worker =
new TestWorkerWithRecv(recv, cb, resName.c_str(), resObject);
worker->Queue();
} break;

default:

break;
}
}

protected:
void Execute(const ExecutionProgress&) override {}

void OnProgress(const ProgressData*, size_t /* count */) override {}

private:
TestWorkerWithRecv(const Object& recv, const Function& cb)
: AsyncProgressQueueWorker(recv, cb) {}
TestWorkerWithRecv(const Object& recv,
const Function& cb,
const char* resourceName)
: AsyncProgressQueueWorker(recv, cb, resourceName) {}
TestWorkerWithRecv(const Object& recv,
const Function& cb,
const char* resourceName,
const Object& resourceObject)
: AsyncProgressQueueWorker(recv, cb, resourceName, resourceObject) {}
};

class TestWorkerWithCb : public AsyncProgressQueueWorker<ProgressData> {
public:
static void DoWork(const CallbackInfo& info) {
switch (info.Length()) {
case 1: {
Function cb = info[0].As<Function>();
TestWorkerWithCb* worker = new TestWorkerWithCb(cb);
worker->Queue();
} break;

case 2: {
Function cb = info[0].As<Function>();
std::string asyncResName = info[1].As<String>();
TestWorkerWithCb* worker =
new TestWorkerWithCb(cb, asyncResName.c_str());
worker->Queue();
} break;

default:

break;
}
}

protected:
void Execute(const ExecutionProgress&) override {}

void OnProgress(const ProgressData*, size_t /* count */) override {}

private:
TestWorkerWithCb(Function cb) : AsyncProgressQueueWorker(cb) {}
TestWorkerWithCb(Function cb, const char* res_name)
: AsyncProgressQueueWorker(cb, res_name) {}
};

class TestWorker : public AsyncProgressQueueWorker<ProgressData> {
public:
static Napi::Value CreateWork(const CallbackInfo& info) {
Expand Down Expand Up @@ -87,6 +239,9 @@ Object InitAsyncProgressQueueWorker(Env env) {
Object exports = Object::New(env);
exports["createWork"] = Function::New(env, TestWorker::CreateWork);
exports["queueWork"] = Function::New(env, TestWorker::QueueWork);
exports["runWorkerNoCb"] = Function::New(env, TestWorkerWithNoCb::DoWork);
exports["runWorkerWithRecv"] = Function::New(env, TestWorkerWithRecv::DoWork);
exports["runWorkerWithCb"] = Function::New(env, TestWorkerWithCb::DoWork);
return exports;
}

Expand Down
134 changes: 134 additions & 0 deletions test/async_progress_queue_worker.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,144 @@ const common = require('./common');
const assert = require('assert');

module.exports = common.runTest(test);
const nodeVersion = process.versions.node.split('.')[0];

let asyncHooks;
function checkAsyncHooks () {
if (nodeVersion >= 8) {
if (asyncHooks === undefined) {
asyncHooks = require('async_hooks');
}
return true;
}
return false;
}

async function test ({ asyncprogressqueueworker }) {
await success(asyncprogressqueueworker);
await fail(asyncprogressqueueworker);

await asyncProgressWorkerCallbackOverloads(asyncprogressqueueworker.runWorkerWithCb);
await asyncProgressWorkerRecvOverloads(asyncprogressqueueworker.runWorkerWithRecv);
await asyncProgressWorkerNoCbOverloads(asyncprogressqueueworker.runWorkerNoCb);
}

async function asyncProgressWorkerCallbackOverloads (bindingFunction) {
bindingFunction(common.mustCall());
if (!checkAsyncHooks()) {
return;
}

const hooks = common.installAysncHooks('cbResources');

const triggerAsyncId = asyncHooks.executionAsyncId();
await new Promise((resolve, reject) => {
bindingFunction(common.mustCall(), 'cbResources');
hooks.then(actual => {
assert.deepStrictEqual(actual, [
{
eventName: 'init',
type: 'cbResources',
triggerAsyncId: triggerAsyncId,
resource: {}
},
{ eventName: 'before' },
{ eventName: 'after' },
{ eventName: 'destroy' }
]);
resolve();
}).catch((err) => reject(err));
});
}

async function asyncProgressWorkerRecvOverloads (bindingFunction) {
const recvObject = {
a: 4
};

function cb () {
assert.strictEqual(this.a, recvObject.a);
}

bindingFunction(recvObject, common.mustCall(cb));
if (!checkAsyncHooks()) {
return;
}
const asyncResources = [
{ resName: 'cbRecvResources', resObject: {} },
{ resName: 'cbRecvResourcesObject', resObject: { foo: 'bar' } }
];

for (const asyncResource of asyncResources) {
const asyncResName = asyncResource.resName;
const asyncResObject = asyncResource.resObject;

const hooks = common.installAysncHooks(asyncResource.resName);
const triggerAsyncId = asyncHooks.executionAsyncId();
await new Promise((resolve, reject) => {
if (Object.keys(asyncResObject).length === 0) {
bindingFunction(recvObject, common.mustCall(cb), asyncResName);
} else {
bindingFunction(recvObject, common.mustCall(cb), asyncResName, asyncResObject);
}

hooks.then(actual => {
assert.deepStrictEqual(actual, [
{
eventName: 'init',
type: asyncResName,
triggerAsyncId: triggerAsyncId,
resource: asyncResObject
},
{ eventName: 'before' },
{ eventName: 'after' },
{ eventName: 'destroy' }
]);
resolve();
}).catch((err) => reject(err));
});
}
}

async function asyncProgressWorkerNoCbOverloads (bindingFunction) {
bindingFunction(common.mustCall());
if (!checkAsyncHooks()) {
return;
}
const asyncResources = [
{ resName: 'noCbResources', resObject: {} },
{ resName: 'noCbResourcesObject', resObject: { foo: 'bar' } }
];

for (const asyncResource of asyncResources) {
const asyncResName = asyncResource.resName;
const asyncResObject = asyncResource.resObject;

const hooks = common.installAysncHooks(asyncResource.resName);
const triggerAsyncId = asyncHooks.executionAsyncId();
await new Promise((resolve, reject) => {
if (Object.keys(asyncResObject).length === 0) {
bindingFunction(asyncResName, common.mustCall(() => {}));
} else {
bindingFunction(asyncResName, asyncResObject, common.mustCall(() => {}));
}

hooks.then(actual => {
assert.deepStrictEqual(actual, [
{
eventName: 'init',
type: asyncResName,
triggerAsyncId: triggerAsyncId,
resource: asyncResObject
},
{ eventName: 'before' },
{ eventName: 'after' },
{ eventName: 'destroy' }
]);
resolve();
}).catch((err) => reject(err));
});
}
}

function success (binding) {
Expand Down

0 comments on commit a198e24

Please sign in to comment.