Replace d3-queue with native async/await across test infrastructure#7458
Replace d3-queue with native async/await across test infrastructure#7458DennisOSRM merged 6 commits intomasterfrom
Conversation
Remove the stale d3-queue dependency and replace all usages with native async/await and Promise.all across the test infrastructure: - features/lib/hash.js: convert hashOfFiles/hashOfFile to async, use Promise.all + fs.promises.readFile - features/support/data.js: convert processRowsAndDiff to async sequential loop; simplify buildWaysFromTable to plain forEach - features/step_definitions/data.js: remove queue wrappers from synchronous steps (shortcuts, ways, relations) - features/step_definitions/routing.js: replace queue(1) serial loop with async for-loop - features/step_definitions/routability.js: replace queue(1) forw/backw sequential run and synchronous parseRes queue with async/await Closes #7453
There was a problem hiding this comment.
Pull request overview
This PR removes the d3-queue dependency from the Cucumber test infrastructure and rewrites affected helpers/step-definitions to use native Promises (async/await, Promise.all) instead.
Changes:
- Drop
d3-queuefrom npm devDependencies and refactor usages across feature support + step definitions. - Convert serial
queue(1)patterns to explicitawaitloops for deterministic sequencing. - Switch file hashing helpers to
fs.promises.readFileand Promise-based APIs.
Reviewed changes
Copilot reviewed 6 out of 7 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| package.json | Removes d3-queue; adds an eslint-specific AJV override. |
| package-lock.json | Removes d3-queue and updates lockfile resolution/metadata (incl. engines + transitive updates). |
| features/support/data.js | Removes d3-queue; simplifies synchronous table-to-OSM building; rewrites row processing to sequential await. |
| features/lib/hash.js | Refactors hashing helpers to async Promise-based functions. |
| features/step_definitions/data.js | Removes d3-queue wrappers from synchronous setup steps (shortcuts/ways/relations). |
| features/step_definitions/routing.js | Replaces serial queue(1) routing loop with an await-driven loop. |
| features/step_definitions/routability.js | Replaces sequential queue(1) direction tests and result comparison with async/await. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 6 out of 7 changed files in this pull request and generated 2 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
|
@copilot apply changes based on the comments in this thread. Make it async/await all the way and remove the callback. The functions should be a promise and callsites should await |
… pure async/await, remove all callbacks Agent-Logs-Url: https://github.com/Project-OSRM/osrm-backend/sessions/37a703d6-0f13-4686-8bd1-53c2cef81981 Co-authored-by: DennisOSRM <1067895+DennisOSRM@users.noreply.github.com>
Done in commit 03a5db9. Converted both |
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 12 out of 13 changed files in this pull request and generated 5 comments.
Comments suppressed due to low confidence (2)
features/step_definitions/trip.js:29
afterRequestwrites intoparams[...], butparamsis only declared inside the non-request branch later in the function, so it is out of scope here and will throw a ReferenceError as soon as aparam:*column is present. Declareparamsin the outertestRowscope (e.g.,let params = this.queryParams) and ensure both branches use that same variable (or pass it intoafterRequest).
for (const k in row) {
const match = k.match(/param:(.*)/);
if (match) {
if (row[k] === '(nil)') {
params[match[1]] = null;
} else if (row[k]) {
params[match[1]] = [row[k]];
}
got[k] = row[k];
}
features/step_definitions/trip.js:135
- In the
row.requestbranch,gotis used before being initialized (got.request = ...), which will throw a TypeError. Initializegot(e.g.,got = { request: row.request }) before assigning fields in this branch.
if (row.request) {
got.request = row.request;
this.requestUrl(row.request, afterRequest);
} else {
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| if (!row.time.match(/\d+s/)) | ||
| return cb( | ||
| return reject( | ||
| new Error('*** Time must be specied in seconds. (ex: 60s)'), | ||
| ); |
There was a problem hiding this comment.
Typo in error message: "specied" should be "specified" (this message is user-facing when tests fail).
| if (!row.speed.match(/\d+ km\/h/)) | ||
| cb( | ||
| return reject( | ||
| new Error( | ||
| '*** Speed must be specied in km/h. (ex: 50 km/h)', | ||
| ), |
There was a problem hiding this comment.
Typo in error message: "specied" should be "specified" (this message is user-facing when tests fail).
| if (k.match(/^a:/)) { | ||
| const a_type = k.slice(2); | ||
| if (whitelist.indexOf(a_type) == -1) | ||
| return cb(new Error('Unrecognized annotation field', a_type)); | ||
| return reject(new Error('Unrecognized annotation field', a_type)); | ||
| if (annotation && !annotation[a_type]) | ||
| return cb( | ||
| return reject( | ||
| new Error('Annotation not found in response', a_type), | ||
| ); |
There was a problem hiding this comment.
new Error('Unrecognized annotation field', a_type) ignores the second argument, so the annotation type is lost from the error message. Include a_type in the message (e.g., via template string / util.format) so failures are actionable.
| } else if (k.match(/^am:/)) { | ||
| const a_type = k.slice(3); | ||
| if (metadata_whitelist.indexOf(a_type) == -1) | ||
| return cb(new Error('Unrecognized annotation field', a_type)); | ||
| return reject(new Error('Unrecognized annotation field', a_type)); | ||
| if ( | ||
| annotation && | ||
| (!annotation.metadata || !annotation.metadata[a_type]) | ||
| ) | ||
| return cb( | ||
| return reject( | ||
| new Error('Annotation not found in response', a_type), | ||
| ); |
There was a problem hiding this comment.
Same issue here: new Error('Unrecognized annotation field', a_type) / new Error('Annotation not found in response', a_type) drop a_type because Error doesn't accept a second message argument. Format the message to include the field name.
|
|
||
| if (!testedHeaders.some((k) => !!headers.has(k))) { | ||
| throw new Error( | ||
| '*** routability table must contain either "forw", "backw", "bothw", "forw_rate" or "backw_mode" column', |
There was a problem hiding this comment.
The validation error mentions a "backw_mode" column, but this step actually checks for backw / backw_rate / bothw_rate (see testedHeaders). Update the message so it reflects the accepted columns.
| '*** routability table must contain either "forw", "backw", "bothw", "forw_rate" or "backw_mode" column', | |
| '*** routability table must contain at least one of the following columns: "forw", "backw", "bothw", "forw_rate", "backw_rate", or "bothw_rate"', |
- Fix 'specied' typos in time and speed error messages - Include annotation field name in Unrecognized/NotFound error messages - Fix routability error message to list correct column names - Rename unused 'ri' param to '_ri' to satisfy ESLint Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Removes
d3-queuedependency and replaces all usages with nativeasync/awaitandPromise-based patterns. Follow-up to review feedback requiring fully promise-based APIs with no callback mixing.Core changes
features/support/data.js:processRowsAndDiff,reprocessAndLoadData, andbuildWaysFromTabledrop theircallbackparameters entirely — errors throw, callersawaitfeatures/step_definitions/routability.js:testRoutabilityRowreturns aPromiseinstead of callingcb;testRowis nowasync; step function isasyncmatching.js,nearest.js,trip.js,distance_matrix.js,shared_steps.js,routing.js,requests.js): step functions converted toasync, innertestRow/requestRowfunctions wrap callback-based HTTP APIs innew Promise()and return results directlyBefore / After