Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 26 additions & 14 deletions src/differences.ts
Original file line number Diff line number Diff line change
Expand Up @@ -68,17 +68,23 @@ export class Differences {
}
/** Extract info from diffkemp-out.yaml loaded to JSON as object (yaml). */
static fromDiffKempOut(yaml: DiffKempOutputFormat) {
// Extracting results for compared functions
let results = Array<ComparedFunctionOutputFormat>();
if (yaml.results.length > 0 && "function" in yaml.results[0]) {
// Results for normal comparison
results = yaml.results as ResultNormalComparisonFormat;
} else {
// Results for sysctl comparison
(yaml.results as ResultSysctlComparisonFormat).forEach((result) => {
results.push(...result.results);
// Extracting results for compared functions. The `results` structure can be nested and may
// contain direct `function` entries or grouped entries (e.g. `sysctl`, `glob_var`) at 'any'
// depth — collect them recursively.
const results: ComparedFunctionOutputFormat[] = [];
const collect = (arr: ResultNormalComparisonFormat[] | ResultSysctlComparisonFormat[]) => {
if (!arr) return;
arr.forEach((item) => {
if ("function" in item && "diffs" in item && Array.isArray(item.diffs)) {
results.push(item);
}
// If this node groups other results, recurse into them.
if ("results" in item) {
collect(item.results);
}
});
}
};
collect(yaml.results);
results.sort((result1, result2) => result1.function.localeCompare(result2.function));
const comparedDiffering = new Map<string, string[]>();
results.forEach((result) => {
Expand Down Expand Up @@ -300,17 +306,17 @@ export interface DifferingInfo {
export interface DiffKempOutputFormat {
"old-snapshot"?: string;
"new-snapshot"?: string;
results: ResultNormalComparisonFormat | ResultSysctlComparisonFormat;
results: ResultNormalComparisonFormat[] | ResultSysctlComparisonFormat[];
definitions?: DKOutDefinitions;
}

/** Format for results when running compare command without --sysctl parameters. */
type ResultNormalComparisonFormat = ComparedFunctionOutputFormat[];
type ResultNormalComparisonFormat = ComparedFunctionOutputFormat | GlobalVarOutputFormat;
/** Format for results when running compare command with `--sysctl` parameters. */
type ResultSysctlComparisonFormat = {
interface ResultSysctlComparisonFormat {
sysctl: string;
results: ComparedFunctionOutputFormat[];
}[];
}

/** Format of subpart of `diffkemp-out.yaml` file describing compared function. */
interface ComparedFunctionOutputFormat {
Expand All @@ -324,6 +330,12 @@ interface ComparedFunctionOutputFormat {
}[];
}

/** Format of subpart of `diffkemp-out.yaml` file describing compared global variable. */
interface GlobalVarOutputFormat {
glob_var: string;
results: ComparedFunctionOutputFormat[];
}

/** Format of definitions of functions from diffkemp-out.yaml. */
type DKOutDefinitions = Record<string, DKOutDefinition>;
/** Format of definition of old/new function from diffkemp-out.yaml. */
Expand Down
37 changes: 37 additions & 0 deletions tests/differences.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -132,3 +132,40 @@ test("it should be possible to extract differences from diffkemp-out.yaml for sy
);
expect(differences.getDiffering()).toEqual(["RECLAIM_UNMAP"]);
});

const EXAMPLE_GLOB_VAR_AND_FUN: DiffKempOutputFormat = {
"old-snapshot": "/old/",
"new-snapshot": "/new/",
results: [
{ function: "a_fun", diffs: [{ function: "X", "old-callstack": [], "new-callstack": [] }] },
{
glob_var: "g",
results: [
{ function: "b_fun", diffs: [{ function: "Y", "old-callstack": [], "new-callstack": [] }] },
],
},
{ function: "c_fun", diffs: [{ function: "Z", "old-callstack": [], "new-callstack": [] }] },
],
};

test("it should be able to parse output glob_var + functions", () => {
const differences = Differences.fromDiffKempOut(EXAMPLE_GLOB_VAR_AND_FUN);
expect(differences.oldSrcPath).toBe("/old/");
expect(differences.newSrcPath).toBe("/new/");
expect(differences.getCompared()).toEqual(["a_fun", "b_fun", "c_fun"]);
expect(differences.comparedDiffering).toEqual(
new Map([
["a_fun", ["X"]],
["b_fun", ["Y"]],
["c_fun", ["Z"]],
]),
);
expect(differences.getDifferingCompared()).toEqual(
new Map([
["X", new Set(["a_fun"])],
["Y", new Set(["b_fun"])],
["Z", new Set(["c_fun"])],
]),
);
expect(differences.getDiffering()).toEqual(["X", "Y", "Z"]);
});
Loading