microsoft/openvmm

Public

mirrored fromhttps://github.com/microsoft/openvmmAvailable

CodeCommitsIssuesPull requestsActionsInsightsSecurity
copilot/apply-async-process-wait-functionality

Branches

Tags

  • No tags available.
0Branches0Tags
Go to file
Add file
Code

Clone

HTTPS

Download ZIP

.github/scripts/dep-review.test.js

412lines · modecode

1// Copyright (c) Microsoft Corporation.
2// Licensed under the MIT License.
3
4// Tests for dep-review.js — run with: node --test .github/scripts/dep-review.test.js
5
6"use strict";
7
8const { describe, it } = require("node:test");
9const assert = require("node:assert/strict");
10
11const {
12 parseExternalDeps,
13 fmtSource,
14 diffDeps,
15 buildSummary,
16 parseCratePathMap,
17 parseInternalDepGraph,
18 checkContainment,
19 diffContainmentViolations,
20 buildPolicySummary,
21} = require("./dep-review.js");
22
23// -- fixtures --
24
25const LOCK_MINIMAL = `
26# This file is automatically @generated by Cargo.
27version = 4
28
29[[package]]
30name = "my_crate"
31version = "0.0.0"
32dependencies = [
33 "serde",
34 "helper",
35]
36
37[[package]]
38name = "helper"
39version = "0.0.0"
40
41[[package]]
42name = "serde"
43version = "1.0.200"
44source = "registry+https://github.com/rust-lang/crates.io-index"
45checksum = "abc"
46
47[[package]]
48name = "serde_derive"
49version = "1.0.200"
50source = "registry+https://github.com/rust-lang/crates.io-index"
51checksum = "def"
52`;
53
54const MANIFEST_MINIMAL = `
55[workspace]
56members = ["my_crate", "helper", "lib_a", "lib_b"]
57
58[workspace.dependencies]
59my_crate = { path = "app/my_crate" }
60helper = { path = "support/helper" }
61lib_a = { path = "support/lib_a" }
62lib_b = { path = "vm/lib_b" }
63serde = "1.0"
64`;
65
66const POLICY = {
67 containment: [
68 {
69 prefix: "support/",
70 description: "support/ crates must not depend on crates outside support/",
71 },
72 ],
73};
74
75// -- parseExternalDeps --
76
77describe("parseExternalDeps", () => {
78 it("extracts external packages (those with source)", () => {
79 const deps = parseExternalDeps(LOCK_MINIMAL);
80 assert.equal(deps.size, 2);
81 assert.ok(
82 deps.has("serde\t1.0.200\tregistry+https://github.com/rust-lang/crates.io-index")
83 );
84 assert.ok(
85 deps.has("serde_derive\t1.0.200\tregistry+https://github.com/rust-lang/crates.io-index")
86 );
87 });
88
89 it("ignores internal packages (no source)", () => {
90 const deps = parseExternalDeps(LOCK_MINIMAL);
91 for (const key of deps) {
92 assert.ok(!key.startsWith("my_crate\t"));
93 assert.ok(!key.startsWith("helper\t"));
94 }
95 });
96
97 it("handles empty lockfile", () => {
98 const deps = parseExternalDeps("version = 4\n");
99 assert.equal(deps.size, 0);
100 });
101
102 it("handles git sources", () => {
103 const lock = `
104[[package]]
105name = "foo"
106version = "0.1.0"
107source = "git+https://github.com/org/foo?branch=main#abc123"
108`;
109 const deps = parseExternalDeps(lock);
110 assert.equal(deps.size, 1);
111 const key = [...deps][0];
112 assert.ok(key.startsWith("foo\t0.1.0\tgit+"));
113 });
114
115 it("tracks multiple versions of the same crate", () => {
116 const lock = `
117[[package]]
118name = "windows-sys"
119version = "0.48.0"
120source = "registry+https://github.com/rust-lang/crates.io-index"
121checksum = "aaa"
122
123[[package]]
124name = "windows-sys"
125version = "0.52.0"
126source = "registry+https://github.com/rust-lang/crates.io-index"
127checksum = "bbb"
128`;
129 const deps = parseExternalDeps(lock);
130 assert.equal(deps.size, 2);
131 assert.ok(
132 deps.has("windows-sys\t0.48.0\tregistry+https://github.com/rust-lang/crates.io-index")
133 );
134 assert.ok(
135 deps.has("windows-sys\t0.52.0\tregistry+https://github.com/rust-lang/crates.io-index")
136 );
137 });
138});
139
140// -- fmtSource --
141
142describe("fmtSource", () => {
143 it("returns empty for registry source", () => {
144 assert.equal(fmtSource("registry+https://github.com/rust-lang/crates.io-index"), "");
145 });
146
147 it("formats git source with URL", () => {
148 const result = fmtSource("git+https://github.com/org/repo?branch=main#abc123");
149 assert.equal(result, " (https://github.com/org/repo?branch=main)");
150 });
151
152 it("passes through unknown sources", () => {
153 assert.equal(fmtSource("something-else"), " (something-else)");
154 });
155});
156
157// -- diffDeps --
158
159describe("diffDeps", () => {
160 it("detects added crates", () => {
161 const base = new Set();
162 const pr = new Set(["foo\t1.0.0\tsrc"]);
163 const { added } = diffDeps(base, pr);
164 assert.equal(added.length, 1);
165 assert.equal(added[0].name, "foo");
166 });
167
168 it("detects version changes as additions", () => {
169 const base = new Set(["foo\t1.0.0\tsrc"]);
170 const pr = new Set(["foo\t2.0.0\tsrc"]);
171 const { added } = diffDeps(base, pr);
172 assert.equal(added.length, 1);
173 assert.equal(added[0].name, "foo");
174 assert.equal(added[0].version, "2.0.0");
175 });
176
177 it("does not report removals", () => {
178 const base = new Set(["foo\t1.0.0\tsrc"]);
179 const pr = new Set();
180 const { added } = diffDeps(base, pr);
181 assert.equal(added.length, 0);
182 });
183
184 it("reports nothing when identical", () => {
185 const base = new Set(["foo\t1.0.0\tsrc"]);
186 const pr = new Set(["foo\t1.0.0\tsrc"]);
187 const { added } = diffDeps(base, pr);
188 assert.equal(added.length, 0);
189 });
190
191 it("detects new version alongside existing version", () => {
192 const base = new Set(["foo\t1.0.0\tsrc"]);
193 const pr = new Set(["foo\t1.0.0\tsrc", "foo\t2.0.0\tsrc"]);
194 const { added } = diffDeps(base, pr);
195 assert.equal(added.length, 1);
196 assert.equal(added[0].version, "2.0.0");
197 });
198});
199
200// -- buildSummary --
201
202describe("buildSummary", () => {
203 it("includes added crates", () => {
204 const summary = buildSummary({
205 added: [{ name: "foo", version: "1.0.0", source: "registry+x" }],
206 });
207 assert.ok(summary.includes("**New external crate versions:**"));
208 assert.ok(summary.includes("`foo` 1.0.0"));
209 });
210});
211
212// -- parseCratePathMap --
213
214describe("parseCratePathMap", () => {
215 it("extracts path-based dependencies", () => {
216 const map = parseCratePathMap(MANIFEST_MINIMAL);
217 assert.equal(map.get("my_crate"), "app/my_crate");
218 assert.equal(map.get("helper"), "support/helper");
219 assert.equal(map.get("lib_a"), "support/lib_a");
220 assert.equal(map.get("lib_b"), "vm/lib_b");
221 });
222
223 it("ignores non-path dependencies", () => {
224 const map = parseCratePathMap(MANIFEST_MINIMAL);
225 assert.ok(!map.has("serde"));
226 });
227
228 it("handles complex inline tables", () => {
229 const toml = `foo = { path = "a/b", features = ["x"], default-features = false }`;
230 const map = parseCratePathMap(toml);
231 assert.equal(map.get("foo"), "a/b");
232 });
233});
234
235// -- parseInternalDepGraph --
236
237describe("parseInternalDepGraph", () => {
238 it("extracts internal crates and their dependencies", () => {
239 const { graph, internalCrates } = parseInternalDepGraph(LOCK_MINIMAL);
240 assert.ok(internalCrates.has("my_crate"));
241 assert.ok(internalCrates.has("helper"));
242 assert.ok(!internalCrates.has("serde"));
243 assert.deepEqual(graph.get("my_crate"), ["serde", "helper"]);
244 assert.deepEqual(graph.get("helper"), []);
245 });
246});
247
248// -- checkContainment --
249
250describe("checkContainment", () => {
251 it("flags violations when support/ crate depends on non-support/ crate", () => {
252 // helper (support/helper) depends on lib_b (vm/lib_b)
253 const lock = `
254[[package]]
255name = "helper"
256version = "0.0.0"
257dependencies = [
258 "lib_b",
259]
260
261[[package]]
262name = "lib_b"
263version = "0.0.0"
264`;
265 const { graph, internalCrates } = parseInternalDepGraph(lock);
266 const pathMap = parseCratePathMap(MANIFEST_MINIMAL);
267 const violations = checkContainment(graph, internalCrates, pathMap, POLICY);
268 assert.equal(violations.length, 1);
269 assert.equal(violations[0].crate, "helper");
270 assert.equal(violations[0].dep, "lib_b");
271 });
272
273 it("allows support/ crate depending on other support/ crate", () => {
274 const lock = `
275[[package]]
276name = "helper"
277version = "0.0.0"
278dependencies = [
279 "lib_a",
280]
281
282[[package]]
283name = "lib_a"
284version = "0.0.0"
285`;
286 const { graph, internalCrates } = parseInternalDepGraph(lock);
287 const pathMap = parseCratePathMap(MANIFEST_MINIMAL);
288 const violations = checkContainment(graph, internalCrates, pathMap, POLICY);
289 assert.equal(violations.length, 0);
290 });
291
292 it("ignores non-support/ crates depending on anything", () => {
293 const lock = `
294[[package]]
295name = "my_crate"
296version = "0.0.0"
297dependencies = [
298 "helper",
299 "lib_b",
300]
301
302[[package]]
303name = "helper"
304version = "0.0.0"
305
306[[package]]
307name = "lib_b"
308version = "0.0.0"
309`;
310 const { graph, internalCrates } = parseInternalDepGraph(lock);
311 const pathMap = parseCratePathMap(MANIFEST_MINIMAL);
312 const violations = checkContainment(graph, internalCrates, pathMap, POLICY);
313 assert.equal(violations.length, 0);
314 });
315});
316
317// -- diffContainmentViolations --
318
319describe("diffContainmentViolations", () => {
320 const v1 = { crate: "a", dep: "b", cratePath: "support/a", depPath: "vm/b", rule: "test" };
321 const v2 = { crate: "c", dep: "d", cratePath: "support/c", depPath: "vm/d", rule: "test" };
322
323 it("returns only new violations", () => {
324 const result = diffContainmentViolations([v1], [v1, v2]);
325 assert.equal(result.length, 1);
326 assert.equal(result[0].crate, "c");
327 });
328
329 it("returns empty when no new violations", () => {
330 const result = diffContainmentViolations([v1, v2], [v1]);
331 assert.equal(result.length, 0);
332 });
333
334 it("returns empty when identical", () => {
335 const result = diffContainmentViolations([v1], [v1]);
336 assert.equal(result.length, 0);
337 });
338});
339
340// -- buildPolicySummary --
341
342describe("buildPolicySummary", () => {
343 it("returns empty for no violations", () => {
344 assert.equal(buildPolicySummary([]), "");
345 });
346
347 it("formats violations", () => {
348 const summary = buildPolicySummary([
349 { crate: "a", cratePath: "support/a", dep: "b", depPath: "vm/b", rule: "no cross" },
350 ]);
351 assert.ok(summary.includes("`a` (support/a) → `b` (vm/b)"));
352 assert.ok(summary.includes("no cross"));
353 });
354});
355
356// -- integration: full lockfile round-trip --
357
358describe("integration", () => {
359 it("no issues when base and PR are identical", () => {
360 const baseDeps = parseExternalDeps(LOCK_MINIMAL);
361 const prDeps = parseExternalDeps(LOCK_MINIMAL);
362 const diff = diffDeps(baseDeps, prDeps);
363 assert.equal(diff.added.length, 0);
364
365 const pathMap = parseCratePathMap(MANIFEST_MINIMAL);
366 const baseGraph = parseInternalDepGraph(LOCK_MINIMAL);
367 const prGraph = parseInternalDepGraph(LOCK_MINIMAL);
368 const baseV = checkContainment(baseGraph.graph, baseGraph.internalCrates, pathMap, POLICY);
369 const prV = checkContainment(prGraph.graph, prGraph.internalCrates, pathMap, POLICY);
370 const newV = diffContainmentViolations(baseV, prV);
371 assert.equal(newV.length, 0);
372 });
373
374 it("detects added external dep + new containment violation together", () => {
375 const prLock = LOCK_MINIMAL + `
376[[package]]
377name = "new_ext"
378version = "0.5.0"
379source = "registry+https://github.com/rust-lang/crates.io-index"
380checksum = "xyz"
381
382[[package]]
383name = "lib_a"
384version = "0.0.0"
385dependencies = [
386 "lib_b",
387]
388
389[[package]]
390name = "lib_b"
391version = "0.0.0"
392`;
393
394 // External diff
395 const baseDeps = parseExternalDeps(LOCK_MINIMAL);
396 const prDeps = parseExternalDeps(prLock);
397 const diff = diffDeps(baseDeps, prDeps);
398 assert.equal(diff.added.length, 1);
399 assert.equal(diff.added[0].name, "new_ext");
400
401 // Containment
402 const pathMap = parseCratePathMap(MANIFEST_MINIMAL);
403 const baseGraph = parseInternalDepGraph(LOCK_MINIMAL);
404 const prGraph = parseInternalDepGraph(prLock);
405 const baseV = checkContainment(baseGraph.graph, baseGraph.internalCrates, pathMap, POLICY);
406 const prV = checkContainment(prGraph.graph, prGraph.internalCrates, pathMap, POLICY);
407 const newV = diffContainmentViolations(baseV, prV);
408 assert.equal(newV.length, 1);
409 assert.equal(newV[0].crate, "lib_a");
410 assert.equal(newV[0].dep, "lib_b");
411 });
412});
413