diff --git a/action.yml b/action.yml
index d755f62..2c6a87c 100644
--- a/action.yml
+++ b/action.yml
@@ -1,6 +1,6 @@
-name: Generate gas diff
-author: TomAFrench
-description: Easily compare circuit size reports generated by Nargo!
+name: Generate report
+author: guipublic
+description: Easily compare json reports
branding:
icon: info
color: purple
@@ -11,11 +11,11 @@ inputs:
default: ${{ github.token }}
required: false
base:
- description: The gates diff reference branch name.
+ description: The report reference branch name.
default: ${{ github.base_ref || github.ref_name }}
required: false
head:
- description: The gates diff target branch name.
+ description: The report target branch name.
default: ${{ github.head_ref || github.ref_name }}
required: false
report:
@@ -27,36 +27,16 @@ inputs:
default: |
# Changes to circuit sizes
required: false
- summaryQuantile:
- description: The quantile threshold to filter avg gas cost diffs to display in the summary top section.
- default: 0.8
- required: false
- brillig_report:
- description: States whether we want to generate a report of ACIR opcodes or Brillig opcodes.
- default: false
- brillig_report_bytes:
- description: States whether the Brillig report is done with bytecode sizes rather than opcodes.
- default: false
- # sortCriteria:
- # description: The list of criteria to order diff rows by in the report (name | min | avg | median | max | calls), separated by a comma. Must have the same length as sortOrders.
- # required: false
- # default: name
- # sortOrders:
- # description: The list of directions to order diff rows in the report, according to order criteria (asc | desc), separated by a comma. Must have the same length as sortCriteria.
- # required: false
- # default: asc
- # ignore:
- # description: The list of contract paths from which to ignore gates reports, separated by a comma.
- # required: false
- # match:
- # description: The list of contract paths of which only to keep gates reports, separated by a comma.
- # required: false
+ memory_report:
+ description: States whether we want to generate a report of memory usage.
+ default: false
+ required: false
outputs:
shell:
- description: The gates diff between the base gates report and the freshly generated gates report, specifically formatted for shell display
+ description: The diff between the base report and the freshly generated report, specifically formatted for shell display
markdown:
- description: The gates diff between the base gates report and the freshly generated gates report, specifically formatted for markdown display
+ description: The diff between the base report and the freshly generated report, specifically formatted for markdown display
runs:
using: node16
diff --git a/src/format/contract.ts b/src/format/contract.ts
deleted file mode 100644
index 440ed48..0000000
--- a/src/format/contract.ts
+++ /dev/null
@@ -1,307 +0,0 @@
-import colors from "colors";
-import _sortBy from "lodash/sortBy";
-
-import { ContractDiffReport, DiffCell } from "../types";
-
-import {
- alignPattern,
- center,
- generateCommitInfo,
- parenthesized,
- plusSign,
- TextAlign,
-} from "./utils";
-
-export const formatShellCell = (cell: DiffCell, length = 10) => {
- const format = colors[cell.delta > 0 ? "red" : cell.delta < 0 ? "green" : "reset"];
-
- return [
- cell.current.toLocaleString().padStart(length) +
- " " +
- format(parenthesized(plusSign(cell.delta) + cell.delta.toLocaleString()).padEnd(length)),
- colors.bold(
- format(
- (
- plusSign(cell.percentage) +
- (cell.percentage === Infinity ? "โ" : cell.percentage.toFixed(2)) +
- "%"
- ).padStart(9)
- )
- ),
- ];
-};
-
-const selectSummaryDiffs = (
- diffs: ContractDiffReport[],
- minCircuitChangePercentage: number
-): ContractDiffReport[] =>
- diffs
- .map(({ functions, ...diff }) => ({
- ...diff,
- functions: functions.filter(
- (method) =>
- Math.abs(method.circuit_size.percentage) >= minCircuitChangePercentage &&
- (method.opcodes.delta !== 0 || method.circuit_size.delta !== 0)
- ),
- }))
- .filter((diff) => diff.functions.length > 0);
-
-export const formatShellDiff = (diffs: ContractDiffReport[], summaryQuantile = 0.8) => {
- const maxContractLength = Math.max(8, ...diffs.map(({ name }) => name.length));
- const maxMethodLength = Math.max(
- 7,
- ...diffs.flatMap(({ functions }) => functions.map(({ name }) => name.length))
- );
-
- const SHELL_SUMMARY_COLS = [
- { txt: "", length: 0 },
- { txt: "Contract", length: maxContractLength },
- { txt: "Method", length: maxMethodLength },
- { txt: "ACIR opcodes (+/-)", length: 33 },
- { txt: "Circuit size (+/-)", length: 33 },
- { txt: "", length: 0 },
- ];
-
- const SHELL_DIFF_COLS = [
- { txt: "", length: 0 },
- { txt: "Contract", length: maxContractLength },
- { txt: "Method", length: maxMethodLength },
- { txt: "ACIR opcodes (+/-)", length: 33 },
- { txt: "Circuit size (+/-)", length: 33 },
- { txt: "", length: 0 },
- ];
-
- const summaryHeader = SHELL_SUMMARY_COLS.map((entry) =>
- colors.bold(center(entry.txt, entry.length || 0))
- )
- .join(" | ")
- .trim();
- const summarySeparator = SHELL_SUMMARY_COLS.map(({ length }) =>
- length > 0 ? "-".repeat(length + 2) : ""
- )
- .join("|")
- .trim();
-
- const diffHeader = SHELL_DIFF_COLS.map((entry) =>
- colors.bold(center(entry.txt, entry.length || 0))
- )
- .join(" | ")
- .trim();
- const diffSeparator = SHELL_DIFF_COLS.map(({ length }) =>
- length > 0 ? "-".repeat(length + 2) : ""
- )
- .join("|")
- .trim();
-
- const sortedMethods = _sortBy(
- diffs.flatMap((diff) => diff.functions),
- (method) => Math.abs(method.circuit_size.percentage)
- );
- const circuitChangeQuantile = Math.abs(
- sortedMethods[Math.floor((sortedMethods.length - 1) * summaryQuantile)]?.circuit_size
- .percentage ?? 0
- );
-
- const summaryRows = selectSummaryDiffs(diffs, circuitChangeQuantile).flatMap((diff) =>
- diff.functions
- .map((method, methodIndex) =>
- [
- "",
- colors.bold(colors.grey((methodIndex === 0 ? diff.name : "").padEnd(maxContractLength))),
- colors.italic(method.name.padEnd(maxMethodLength)),
- ...formatShellCell(method.opcodes),
- ...formatShellCell(method.circuit_size),
- "",
- ]
- .join(" | ")
- .trim()
- )
- .join("\n")
- .trim()
- );
-
- const fullReportRows = diffs.map((diff) =>
- diff.functions
- .map((method, methodIndex) =>
- [
- "",
- colors.bold(colors.grey((methodIndex === 0 ? diff.name : "").padEnd(maxContractLength))),
- colors.italic(method.name.padEnd(maxMethodLength)),
- ...formatShellCell(method.opcodes),
- ...formatShellCell(method.circuit_size),
- "",
- ]
- .join(" | ")
- .trim()
- )
- .join("\n")
- .trim()
- );
-
- return (
- colors.underline(
- colors.bold(
- colors.yellow(
- `๐งพ Summary (${Math.round((1 - summaryQuantile) * 100)}% most significant diffs)\n\n`
- )
- )
- ) +
- ["", summaryHeader, ...summaryRows, ""].join(`\n${summarySeparator}\n`).trim() +
- colors.underline(colors.bold(colors.yellow("\n\nFull diff report ๐\n\n"))) +
- ["", diffHeader, ...fullReportRows, ""].join(`\n${diffSeparator}\n`).trim()
- );
-};
-
-const formatMarkdownSummaryCell = (rows: DiffCell[]) => [
- rows
- .map(
- (row) =>
- plusSign(row.delta) +
- row.delta.toLocaleString() +
- " " +
- (row.delta > 0 ? "โ" : row.delta < 0 ? "โ
" : "โ")
- )
- .join("
"),
- rows
- .map(
- (row) =>
- "**" +
- plusSign(row.percentage) +
- (row.percentage === Infinity ? "โ" : row.percentage.toFixed(2)) +
- "%**"
- )
- .join("
"),
-];
-
-const formatMarkdownFullCell = (rows: DiffCell[]) => [
- rows
- .map(
- (row) =>
- row.current.toLocaleString() +
- " (" +
- plusSign(row.delta) +
- row.delta.toLocaleString() +
- ")"
- )
- .join("
"),
- rows
- .map(
- (row) =>
- "**" +
- plusSign(row.percentage) +
- (row.percentage === Infinity ? "โ" : row.percentage.toFixed(2)) +
- "%**"
- )
- .join("
"),
-];
-
-const MARKDOWN_SUMMARY_COLS = [
- { txt: "" },
- { txt: "Contract", align: TextAlign.LEFT },
- { txt: "Method", align: TextAlign.LEFT },
- { txt: "ACIR opcodes (+/-)", align: TextAlign.RIGHT },
- { txt: "%", align: TextAlign.RIGHT },
- { txt: "Circuit size (+/-)", align: TextAlign.RIGHT },
- { txt: "%", align: TextAlign.RIGHT },
- { txt: "" },
-];
-
-const MARKDOWN_DIFF_COLS = [
- { txt: "" },
- { txt: "Contract", align: TextAlign.LEFT },
- { txt: "Method", align: TextAlign.LEFT },
- { txt: "ACIR opcodes (+/-)", align: TextAlign.RIGHT },
- { txt: "%", align: TextAlign.RIGHT },
- { txt: "Circuit size (+/-)", align: TextAlign.RIGHT },
- { txt: "%", align: TextAlign.RIGHT },
- { txt: "" },
-];
-
-export const formatMarkdownDiff = (
- header: string,
- diffs: ContractDiffReport[],
- repository: string,
- commitHash: string,
- refCommitHash?: string,
- summaryQuantile = 0.8
-) => {
- const diffReport = [header, "", generateCommitInfo(repository, commitHash, refCommitHash)];
- if (diffs.length === 0)
- return diffReport.concat(["", "### There are no changes in circuit sizes"]).join("\n").trim();
-
- const summaryHeader = MARKDOWN_SUMMARY_COLS.map((entry) => entry.txt)
- .join(" | ")
- .trim();
- const summaryHeaderSeparator = MARKDOWN_SUMMARY_COLS.map((entry) =>
- entry.txt ? alignPattern(entry.align) : ""
- )
- .join("|")
- .trim();
-
- const diffHeader = MARKDOWN_DIFF_COLS.map((entry) => entry.txt)
- .join(" | ")
- .trim();
- const diffHeaderSeparator = MARKDOWN_DIFF_COLS.map((entry) =>
- entry.txt ? alignPattern(entry.align) : ""
- )
- .join("|")
- .trim();
-
- const sortedMethods = _sortBy(
- diffs.flatMap((diff) => diff.functions),
- (method) => Math.abs(method.circuit_size.percentage)
- );
- const circuitChangeQuantile = Math.abs(
- sortedMethods[Math.floor((sortedMethods.length - 1) * summaryQuantile)]?.circuit_size
- .percentage ?? 0
- );
-
- const summaryRows = selectSummaryDiffs(diffs, circuitChangeQuantile).flatMap((diff) =>
- [
- "",
- `**${diff.name}**`,
- diff.functions.map((method) => `_${method.name}_`).join("
"),
- ...formatMarkdownSummaryCell(diff.functions.map((method) => method.opcodes)),
- ...formatMarkdownSummaryCell(diff.functions.map((method) => method.circuit_size)),
- "",
- ]
- .join(" | ")
- .trim()
- );
-
- const fullReportRows = diffs.flatMap((diff) =>
- [
- "",
- `**${diff.name}**`,
- diff.functions.map((method) => `_${method.name}_`).join("
"),
- ...formatMarkdownFullCell(diff.functions.map((method) => method.opcodes)),
- ...formatMarkdownFullCell(diff.functions.map((method) => method.circuit_size)),
- "",
- ]
- .join(" | ")
- .trim()
- );
-
- return diffReport
- .concat([
- "",
- `### ๐งพ Summary (${Math.round((1 - summaryQuantile) * 100)}% most significant diffs)`,
- "",
- summaryHeader,
- summaryHeaderSeparator,
- ...summaryRows,
- "---",
- "",
- "",
- "Full diff report ๐
",
- "
",
- "",
- diffHeader,
- diffHeaderSeparator,
- ...fullReportRows,
- " ",
- "",
- ])
- .join("\n")
- .trim();
-};
diff --git a/src/format/program.ts b/src/format/program.ts
deleted file mode 100644
index dadd360..0000000
--- a/src/format/program.ts
+++ /dev/null
@@ -1,460 +0,0 @@
-import colors from "colors";
-import _sortBy from "lodash/sortBy";
-
-import { DiffBrillig, DiffCell, DiffCircuit } from "../types";
-
-import {
- alignPattern,
- center,
- generateCommitInfo,
- parenthesized,
- plusSign,
- TextAlign,
-} from "./utils";
-
-export const formatShellCell = (cell: DiffCell, length = 10) => {
- const format = colors[cell.delta > 0 ? "red" : cell.delta < 0 ? "green" : "reset"];
-
- return [
- cell.current.toLocaleString().padStart(length) +
- " " +
- format(parenthesized(plusSign(cell.delta) + cell.delta.toLocaleString()).padEnd(length)),
- colors.bold(
- format(
- (
- plusSign(cell.percentage) +
- (cell.percentage === Infinity ? "โ" : cell.percentage.toFixed(2)) +
- "%"
- ).padStart(9)
- )
- ),
- ];
-};
-
-const selectSummaryDiffs = (
- diffs: DiffCircuit[],
- minCircuitChangePercentage: number
-): DiffCircuit[] =>
- diffs.filter(
- (method) =>
- Math.abs(method.circuit_size.percentage) >= minCircuitChangePercentage &&
- (method.opcodes.delta !== 0 || method.circuit_size.delta !== 0)
- );
-
-const selectSummaryDiffsBrillig = (
- diffs: DiffBrillig[],
- minCircuitChangePercentage: number
-): DiffBrillig[] =>
- diffs.filter(
- (method) =>
- Math.abs(method.opcodes.percentage) >= minCircuitChangePercentage &&
- method.opcodes.delta !== 0
- );
-
-export const formatShellCircuitRows = (
- diffs: DiffCircuit[],
- summaryQuantile = 0.8
-): [string[], string[]] => {
- const maxProgramLength = Math.max(8, ...diffs.map(({ name }) => name.length));
-
- const sortedPrograms = _sortBy(diffs, (method) => Math.abs(method.circuit_size.percentage));
- const circuitChangeQuantile = Math.abs(
- sortedPrograms[Math.floor((sortedPrograms.length - 1) * summaryQuantile)]?.circuit_size
- .percentage ?? 0
- );
-
- const summaryRows = selectSummaryDiffs(diffs, circuitChangeQuantile).map((diff) =>
- [
- "",
- colors.bold(colors.grey(diff.name.padEnd(maxProgramLength))),
- ...formatShellCell(diff.opcodes),
- ...formatShellCell(diff.circuit_size),
- "",
- ]
- .join(" | ")
- .trim()
- );
-
- const fullReportRows = diffs.map((diff) =>
- [
- "",
- colors.bold(colors.grey(diff.name.padEnd(maxProgramLength))),
- ...formatShellCell(diff.opcodes),
- ...formatShellCell(diff.circuit_size),
- "",
- ]
- .join(" | ")
- .trim()
- );
-
- return [summaryRows, fullReportRows];
-};
-
-export const formatShellDiff = (
- diffs: DiffCircuit[],
- summaryRows: string[],
- fullReportRows: string[],
- summaryQuantile = 0.8
-) => {
- const maxProgramLength = Math.max(8, ...diffs.map(({ name }) => name.length));
-
- const SHELL_SUMMARY_COLS = [
- { txt: "", length: 0 },
- { txt: "Program", length: maxProgramLength },
- { txt: "ACIR opcodes (+/-)", length: 33 },
- { txt: "Circuit size (+/-)", length: 33 },
- { txt: "", length: 0 },
- ];
-
- const SHELL_DIFF_COLS = [
- { txt: "", length: 0 },
- { txt: "Program", length: maxProgramLength },
- { txt: "ACIR opcodes (+/-)", length: 33 },
- { txt: "Circuit size (+/-)", length: 33 },
- { txt: "", length: 0 },
- ];
-
- const summaryHeader = SHELL_SUMMARY_COLS.map((entry) =>
- colors.bold(center(entry.txt, entry.length || 0))
- )
- .join(" | ")
- .trim();
- const summarySeparator = SHELL_SUMMARY_COLS.map(({ length }) =>
- length > 0 ? "-".repeat(length + 2) : ""
- )
- .join("|")
- .trim();
-
- const diffHeader = SHELL_DIFF_COLS.map((entry) =>
- colors.bold(center(entry.txt, entry.length || 0))
- )
- .join(" | ")
- .trim();
- const diffSeparator = SHELL_DIFF_COLS.map(({ length }) =>
- length > 0 ? "-".repeat(length + 2) : ""
- )
- .join("|")
- .trim();
-
- return (
- colors.underline(
- colors.bold(
- colors.yellow(
- `๐งพ Summary (${Math.round((1 - summaryQuantile) * 100)}% most significant diffs)\n\n`
- )
- )
- ) +
- ["", summaryHeader, ...summaryRows, ""].join(`\n${summarySeparator}\n`).trim() +
- colors.underline(colors.bold(colors.yellow("\n\nFull diff report ๐\n\n"))) +
- ["", diffHeader, ...fullReportRows, ""].join(`\n${diffSeparator}\n`).trim()
- );
-};
-
-export const formatShellBrilligRows = (
- diffs: DiffBrillig[],
- summaryQuantile = 0.8
-): [string[], string[]] => {
- const maxProgramLength = Math.max(8, ...diffs.map(({ name }) => name.length));
-
- const sortedPrograms = _sortBy(diffs, (method) => Math.abs(method.opcodes.percentage));
- const circuitChangeQuantile = Math.abs(
- sortedPrograms[Math.floor((sortedPrograms.length - 1) * summaryQuantile)]?.opcodes.percentage ??
- 0
- );
-
- const summaryRows = selectSummaryDiffsBrillig(diffs, circuitChangeQuantile).map((diff) =>
- [
- "",
- colors.bold(colors.grey(diff.name.padEnd(maxProgramLength))),
- ...formatShellCell(diff.opcodes),
- "",
- ]
- .join(" | ")
- .trim()
- );
-
- const fullReportRows = diffs.map((diff) =>
- [
- "",
- colors.bold(colors.grey(diff.name.padEnd(maxProgramLength))),
- ...formatShellCell(diff.opcodes),
- "",
- ]
- .join(" | ")
- .trim()
- );
-
- return [summaryRows, fullReportRows];
-};
-
-export const formatShellDiffBrillig = (
- diffs: DiffBrillig[],
- summaryRows: string[],
- fullReportRows: string[],
- brillig_report_bytes: boolean,
- summaryQuantile = 0.8
-) => {
- const maxProgramLength = Math.max(8, ...diffs.map(({ name }) => name.length));
-
- const SHELL_SUMMARY_COLS = [
- { txt: "", length: 0 },
- { txt: "Program", length: maxProgramLength },
- { txt: "Brillig opcodes (+/-)", length: 33 },
- { txt: "", length: 0 },
- ];
-
- const SHELL_DIFF_COLS = [
- { txt: "", length: 0 },
- { txt: "Program", length: maxProgramLength },
- { txt: "Brillig opcodes (+/-)", length: 33 },
- { txt: "", length: 0 },
- ];
-
- if (brillig_report_bytes) {
- SHELL_SUMMARY_COLS[2].txt = "Bytecode size in bytes (+/-)";
- SHELL_DIFF_COLS[2].txt = "Bytecode size in bytes (+/-)";
- }
-
- const summaryHeader = SHELL_SUMMARY_COLS.map((entry) =>
- colors.bold(center(entry.txt, entry.length || 0))
- )
- .join(" | ")
- .trim();
- const summarySeparator = SHELL_SUMMARY_COLS.map(({ length }) =>
- length > 0 ? "-".repeat(length + 2) : ""
- )
- .join("|")
- .trim();
-
- const diffHeader = SHELL_DIFF_COLS.map((entry) =>
- colors.bold(center(entry.txt, entry.length || 0))
- )
- .join(" | ")
- .trim();
- const diffSeparator = SHELL_DIFF_COLS.map(({ length }) =>
- length > 0 ? "-".repeat(length + 2) : ""
- )
- .join("|")
- .trim();
-
- return (
- colors.underline(
- colors.bold(
- colors.yellow(
- `๐งพ Summary (${Math.round((1 - summaryQuantile) * 100)}% most significant diffs)\n\n`
- )
- )
- ) +
- ["", summaryHeader, ...summaryRows, ""].join(`\n${summarySeparator}\n`).trim() +
- colors.underline(colors.bold(colors.yellow("\n\nFull diff report ๐\n\n"))) +
- ["", diffHeader, ...fullReportRows, ""].join(`\n${diffSeparator}\n`).trim()
- );
-};
-
-const formatMarkdownSummaryCell = (rows: DiffCell[]) => [
- rows
- .map(
- (row) =>
- plusSign(row.delta) +
- row.delta.toLocaleString() +
- " " +
- (row.delta > 0 ? "โ" : row.delta < 0 ? "โ
" : "โ")
- )
- .join("
"),
- rows
- .map(
- (row) =>
- "**" +
- plusSign(row.percentage) +
- (row.percentage === Infinity ? "โ" : row.percentage.toFixed(2)) +
- "%**"
- )
- .join("
"),
-];
-
-const formatMarkdownFullCell = (rows: DiffCell[]): string[] => [
- rows
- .map(
- (row) =>
- row.current.toLocaleString() +
- " (" +
- plusSign(row.delta) +
- row.delta.toLocaleString() +
- ")"
- )
- .join("
"),
- rows
- .map(
- (row) =>
- "**" +
- plusSign(row.percentage) +
- (row.percentage === Infinity ? "โ" : row.percentage.toFixed(2)) +
- "%**"
- )
- .join("
"),
-];
-
-const MARKDOWN_SUMMARY_COLS_CIRCUIT = [
- { txt: "" },
- { txt: "Program", align: TextAlign.LEFT },
- { txt: "ACIR opcodes (+/-)", align: TextAlign.RIGHT },
- { txt: "%", align: TextAlign.RIGHT },
- { txt: "Circuit size (+/-)", align: TextAlign.RIGHT },
- { txt: "%", align: TextAlign.RIGHT },
- { txt: "" },
-];
-
-const MARKDOWN_DIFF_COLS_CIRCUIT = [
- { txt: "" },
- { txt: "Program", align: TextAlign.LEFT },
- { txt: "ACIR opcodes (+/-)", align: TextAlign.RIGHT },
- { txt: "%", align: TextAlign.RIGHT },
- { txt: "Circuit size (+/-)", align: TextAlign.RIGHT },
- { txt: "%", align: TextAlign.RIGHT },
- { txt: "" },
-];
-
-const MARKDOWN_SUMMARY_COLS_BRILLIG = [
- { txt: "" },
- { txt: "Program", align: TextAlign.LEFT },
- { txt: "Brillig opcodes (+/-)", align: TextAlign.RIGHT },
- { txt: "%", align: TextAlign.RIGHT },
- { txt: "" },
-];
-
-const MARKDOWN_DIFF_COLS_BRILLIG = [
- { txt: "" },
- { txt: "Program", align: TextAlign.LEFT },
- { txt: "Brillig opcodes (+/-)", align: TextAlign.RIGHT },
- { txt: "%", align: TextAlign.RIGHT },
- { txt: "" },
-];
-
-export const formatCircuitRows = (
- diffs: DiffCircuit[],
- summaryQuantile = 0.8
-): [string[], string[]] => {
- const sortedMethods = _sortBy(diffs, (program) => Math.abs(program.circuit_size.percentage));
- const circuitChangeQuantile = Math.abs(
- sortedMethods[Math.floor((sortedMethods.length - 1) * summaryQuantile)]?.circuit_size
- .percentage ?? 0
- );
-
- const summaryRows = selectSummaryDiffs(diffs, circuitChangeQuantile).flatMap((diff) =>
- [
- "",
- `**${diff.name}**`,
- ...formatMarkdownSummaryCell([diff.opcodes]),
- ...formatMarkdownSummaryCell([diff.circuit_size]),
- "",
- ]
- .join(" | ")
- .trim()
- );
-
- const fullReportRows = diffs.flatMap((diff) =>
- [
- "",
- `**${diff.name}**`,
- ...formatMarkdownFullCell([diff.opcodes]),
- ...formatMarkdownFullCell([diff.circuit_size]),
- "",
- ]
- .join(" | ")
- .trim()
- );
-
- return [summaryRows, fullReportRows];
-};
-
-export const formatBrilligRows = (
- diffs: DiffBrillig[],
- summaryQuantile = 0.8
-): [string[], string[]] => {
- const sortedMethods = _sortBy(diffs, (program) => Math.abs(program.opcodes.percentage));
- const circuitChangeQuantile = Math.abs(
- sortedMethods[Math.floor((sortedMethods.length - 1) * summaryQuantile)]?.opcodes.percentage ?? 0
- );
-
- const summaryRows = selectSummaryDiffsBrillig(diffs, circuitChangeQuantile).flatMap((diff) =>
- ["", `**${diff.name}**`, ...formatMarkdownSummaryCell([diff.opcodes]), ""].join(" | ").trim()
- );
-
- const fullReportRows = diffs.flatMap((diff) =>
- ["", `**${diff.name}**`, ...formatMarkdownFullCell([diff.opcodes]), ""].join(" | ").trim()
- );
-
- return [summaryRows, fullReportRows];
-};
-
-export const formatMarkdownDiff = (
- header: string,
- repository: string,
- commitHash: string,
- summaryRows: string[],
- fullReportRows: string[],
- // Flag to distinguish the markdown columns that should be used
- circuitReport: boolean,
- brillig_report_bytes: boolean,
- refCommitHash?: string,
- summaryQuantile = 0.8
-) => {
- const diffReport = [header, "", generateCommitInfo(repository, commitHash, refCommitHash)];
- if (fullReportRows.length === 0)
- return diffReport.concat(["", "### There are no changes in sizes"]).join("\n").trim();
-
- let MARKDOWN_SUMMARY_COLS;
- let MARKDOWN_DIFF_COLS;
- if (circuitReport) {
- MARKDOWN_SUMMARY_COLS = MARKDOWN_SUMMARY_COLS_CIRCUIT;
- MARKDOWN_DIFF_COLS = MARKDOWN_DIFF_COLS_CIRCUIT;
- } else {
- MARKDOWN_SUMMARY_COLS = MARKDOWN_SUMMARY_COLS_BRILLIG;
- MARKDOWN_DIFF_COLS = MARKDOWN_DIFF_COLS_BRILLIG;
- if (brillig_report_bytes) {
- MARKDOWN_SUMMARY_COLS[2].txt = "Bytecode size in bytes (+/-)";
- MARKDOWN_DIFF_COLS[2].txt = "Bytecode size in bytes (+/-)";
- }
- }
-
- const summaryHeader = MARKDOWN_SUMMARY_COLS.map((entry) => entry.txt)
- .join(" | ")
- .trim();
- const summaryHeaderSeparator = MARKDOWN_SUMMARY_COLS.map((entry) =>
- entry.txt ? alignPattern(entry.align) : ""
- )
- .join("|")
- .trim();
-
- const diffHeader = MARKDOWN_DIFF_COLS.map((entry) => entry.txt)
- .join(" | ")
- .trim();
- const diffHeaderSeparator = MARKDOWN_DIFF_COLS.map((entry) =>
- entry.txt ? alignPattern(entry.align) : ""
- )
- .join("|")
- .trim();
-
- return diffReport
- .concat([
- "",
- `### ๐งพ Summary (${Math.round((1 - summaryQuantile) * 100)}% most significant diffs)`,
- "",
- summaryHeader,
- summaryHeaderSeparator,
- ...summaryRows,
- "---",
- "",
- "",
- "Full diff report ๐
",
- "
",
- "",
- diffHeader,
- diffHeaderSeparator,
- ...fullReportRows,
- " ",
- "",
- ])
- .join("\n")
- .trim();
-};
diff --git a/src/index.ts b/src/index.ts
index d25dd1c..b042ae4 100755
--- a/src/index.ts
+++ b/src/index.ts
@@ -6,25 +6,13 @@ import * as artifact from "@actions/artifact";
import * as core from "@actions/core";
import { context, getOctokit } from "@actions/github";
-import {
- formatBrilligRows,
- formatCircuitRows,
- formatMarkdownDiff,
- formatShellBrilligRows,
- formatShellCircuitRows,
- formatShellDiff,
- formatShellDiffBrillig,
-} from "./format/program";
-import { loadReports, computeProgramDiffs } from "./report";
+import { memoryReports, computeMemoryDiff } from "./report";
const token = process.env.GITHUB_TOKEN || core.getInput("token");
const report = core.getInput("report");
const header = core.getInput("header");
-const brillig_report = core.getInput("brillig_report");
-const brillig_report_bytes = core.getInput("brillig_report_bytes");
-const summaryQuantile = parseFloat(core.getInput("summaryQuantile"));
-// const sortCriteria = core.getInput("sortCriteria").split(",");
-// const sortOrders = core.getInput("sortOrders").split(",");
+const memory_report = core.getInput("memory_report");
+
const baseBranch = core.getInput("base");
const headBranch = core.getInput("head");
@@ -39,15 +27,15 @@ const { owner, repo } = context.repo;
const repository = owner + "/" + repo;
let referenceContent: string;
+let compareContent: string;
let refCommitHash: string | undefined;
async function run() {
- // if (!isSortCriteriaValid(sortCriteria)) return;
- // if (!isSortOrdersValid(sortOrders)) return;
-
try {
// Upload the gates report to be used as a reference in later runs.
await uploadArtifact();
+ core.info(`Loading reports from "${localReportPath}"`);
+ compareContent = fs.readFileSync(localReportPath, "utf8");
} catch (error) {
return core.setFailed((error as Error).message);
}
@@ -59,17 +47,20 @@ async function run() {
core.startGroup(
`Searching artifact "${baseReport}" on repository "${repository}", on branch "${baseBranch}"`
);
-
+ let count = 100;
let artifactId: number | null = null;
// Artifacts are returned in most recent first order.
for await (const res of octokit.paginate.iterator(octokit.rest.actions.listArtifactsForRepo, {
owner,
repo,
})) {
+ if (count == 0) {
+ break;
+ }
const artifact = res.data.find(
(artifact) => !artifact.expired && artifact.name === baseReport
);
-
+ count = count - 1;
if (!artifact) {
await new Promise((resolve) => setTimeout(resolve, 900)); // avoid reaching the API rate limit
@@ -98,7 +89,7 @@ async function run() {
const zip = new Zip(Buffer.from(res.data as ArrayBuffer));
for (const entry of zip.getEntries()) {
- core.info(`Loading gas reports from "${entry.entryName}"`);
+ core.info(`Loading reports from "${entry.entryName}"`);
referenceContent = zip.readAsText(entry);
}
core.endGroup();
@@ -109,89 +100,18 @@ async function run() {
}
try {
- core.startGroup("Load gas reports");
- core.info(`Loading gas reports from "${localReportPath}"`);
- const compareContent = fs.readFileSync(localReportPath, "utf8");
- referenceContent ??= compareContent; // if no source gas reports were loaded, defaults to the current gas reports
-
- core.info(`Mapping compared gas reports`);
- const compareReports = loadReports(compareContent);
- core.info(`Got ${compareReports.programs.length} compare programs`);
-
- core.info(`Mapping reference gas reports`);
- const referenceReports = loadReports(referenceContent);
- core.info(`Got ${compareReports.programs.length} reference programs`);
- core.endGroup();
-
- core.startGroup("Compute gas diff");
- const [diffCircuitRows, diffBrilligRows] = computeProgramDiffs(
- referenceReports.programs,
- compareReports.programs
- );
-
- let numDiffs = diffCircuitRows.length;
- let summaryRows;
- let fullReportRows;
- if (brillig_report) {
- numDiffs = diffBrilligRows.length;
- core.info(`Format Brillig markdown rows`);
- [summaryRows, fullReportRows] = formatBrilligRows(diffBrilligRows, summaryQuantile);
- } else {
- core.info(`Format ACIR markdown rows`);
- [summaryRows, fullReportRows] = formatCircuitRows(diffCircuitRows, summaryQuantile);
- }
-
- core.info(`Format markdown of ${numDiffs} diffs`);
- // const [summaryRows, fullReportRows] = formatCircuitRows(diffCircuitRows, summaryQuantile);
- const markdown = formatMarkdownDiff(
- header,
- repository,
- context.sha,
- summaryRows,
- fullReportRows,
- !brillig_report,
- brillig_report_bytes == "true",
- refCommitHash,
- summaryQuantile
- );
- core.info(`Format shell of ${numDiffs} diffs`);
-
- let shell;
- if (brillig_report) {
- core.info(`Format Brillig diffs`);
- const [summaryRowsShell, fullReportRowsShell] = formatShellBrilligRows(
- diffBrilligRows,
- summaryQuantile
- );
- shell = formatShellDiffBrillig(
- diffCircuitRows,
- summaryRowsShell,
- fullReportRowsShell,
- brillig_report_bytes == "true",
- summaryQuantile
- );
- } else {
- core.info(`Format ACIR diffs`);
- const [summaryRowsShell, fullReportRowsShell] = formatShellCircuitRows(
- diffCircuitRows,
- summaryQuantile
- );
- shell = formatShellDiff(
- diffCircuitRows,
- summaryRowsShell,
- fullReportRowsShell,
- summaryQuantile
- );
+ core.startGroup("Load reports");
+ referenceContent ??= compareContent; // if no source reports were loaded, defaults to the current reports
+
+ if (memory_report) {
+ core.info(`Format Memory markdown rows`);
+ const memoryContent = memoryReports(compareContent);
+ const referenceReports = memoryReports(referenceContent);
+ const markdown = computeMemoryDiff(referenceReports, memoryContent);
+ core.setOutput("markdown", markdown);
}
core.endGroup();
-
- console.log(shell);
-
- if (numDiffs > 0) {
- core.setOutput("shell", shell);
- core.setOutput("markdown", markdown);
- }
} catch (error) {
core.setFailed((error as Error).message);
}
diff --git a/src/report.ts b/src/report.ts
index 6509fb8..0339237 100644
--- a/src/report.ts
+++ b/src/report.ts
@@ -1,16 +1,6 @@
import _orderBy from "lodash/orderBy";
-import {
- ContractDiffReport,
- ContractReport,
- DiffCircuit,
- CircuitReport,
- WorkspaceDiffReport,
- WorkspaceReport,
- ProgramReport,
- BrilligReport,
- DiffBrillig,
-} from "./types";
+import { MemoryReport } from "./types";
export const variation = (current: number, previous: number) => {
const delta = current - previous;
@@ -23,173 +13,70 @@ export const variation = (current: number, previous: number) => {
};
};
-export const loadReports = (content: string): WorkspaceReport => {
- return JSON.parse(content);
+export const memoryReports = (content: string): MemoryReport[] => {
+ return JSON.parse(content).memory_reports;
};
-export const computedWorkspaceDiff = (
- sourceReport: WorkspaceReport,
- compareReport: WorkspaceReport
-): WorkspaceDiffReport => {
- const [diffCircuits, diffBrilligs] = computeProgramDiffs(
- sourceReport.programs,
- compareReport.programs
- );
- return {
- programs: diffCircuits,
- unconstrained_functions: diffBrilligs,
- contracts: computeContractDiffs(sourceReport.contracts, compareReport.contracts),
- };
-};
-
-export const computeProgramDiffs = (
- sourceReports: ProgramReport[],
- compareReports: ProgramReport[]
-): [DiffCircuit[], DiffBrillig[]] => {
- const sourceReportNames = sourceReports.map((report) => report.package_name);
- const commonReportNames = compareReports
- .map((report) => report.package_name)
- .filter((name) => sourceReportNames.includes(name));
-
- const diffCircuits = commonReportNames
- .map((reportName) => {
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
- const srcReport = sourceReports.find((report) => report.package_name == reportName)!;
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
- const cmpReport = compareReports.find((report) => report.package_name == reportName)!;
-
- // For now we fetch just the main of each program
- return computeCircuitDiff(srcReport.functions[0], cmpReport.functions[0], reportName);
- })
- .filter((diff) => !isEmptyDiff(diff))
- .sort(
- (diff1, diff2) =>
- Math.max(diff2.circuit_size.percentage) - Math.max(diff1.circuit_size.percentage)
+export const formatMemoryReport = (memReports: MemoryReport[]): string => {
+ let markdown = "## Peak Memory Sample\n | Program | Peak Memory |\n | --- | --- |\n";
+ for (let i = 0; i < memReports.length; i++) {
+ markdown = markdown.concat(
+ " | ",
+ memReports[i].artifact_name,
+ " | ",
+ memReports[i].peak_memory,
+ " |\n"
);
+ }
+ return markdown;
+};
- const diffBrilligs = commonReportNames
- .map((reportName) => {
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
- const srcReport = sourceReports.find((report) => report.package_name == reportName)!;
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
- const cmpReport = compareReports.find((report) => report.package_name == reportName)!;
-
- if (
- srcReport.unconstrained_functions.length === 0 ||
- cmpReport.unconstrained_functions.length === 0
- ) {
- return {
- name: "",
- opcodes: {
- previous: 0,
- current: 0,
- delta: 0,
- percentage: 0,
- },
- };
+export const computeMemoryDiff = (
+ refReports: MemoryReport[],
+ memReports: MemoryReport[]
+): string => {
+ let markdown = "";
+ const diff_percentage = [];
+ let diff_column = false;
+ if (refReports.length === memReports.length) {
+ for (let i = 0; i < refReports.length; i++) {
+ let diff_str = "N/A";
+ if (refReports[i].artifact_name === memReports[i].artifact_name) {
+ const compPeak = memReports[i].peak_memory;
+ const refPeak = refReports[i].peak_memory;
+ let diff = 0;
+ if (compPeak[compPeak.length - 1] == refPeak[refPeak.length - 1]) {
+ const compPeakValue = parseInt(compPeak.substring(0, compPeak.length - 1));
+ const refPeakValue = parseInt(refPeak.substring(0, refPeak.length - 1));
+ diff = Math.floor(((compPeakValue - refPeakValue) / refPeakValue) * 100);
+ } else {
+ diff = 100;
+ }
+ if (diff != 0) {
+ diff_column = true;
+ }
+ diff_str = diff.toString() + "%";
}
- // For now we fetch just the main of each program
- return computeUnconstrainedDiff(
- srcReport.unconstrained_functions[0],
- cmpReport.unconstrained_functions[0],
- reportName
+ diff_percentage.push(diff_str);
+ }
+ }
+
+ if (diff_column == true) {
+ markdown = "## Peak Memory Sample\n | Program | Peak Memory | % |\n | --- | --- | --- |\n";
+ for (let i = 0; i < memReports.length; i++) {
+ markdown = markdown.concat(
+ " | ",
+ memReports[i].artifact_name,
+ " | ",
+ memReports[i].peak_memory,
+ " | ",
+ diff_percentage[i],
+ " |\n"
);
- })
- .filter((diff) => !isEmptyDiffBrillig(diff))
- .sort(
- (diff1, diff2) => Math.max(diff2.opcodes.percentage) - Math.max(diff1.opcodes.percentage)
- );
-
- return [diffCircuits, diffBrilligs];
-};
-
-const computeCircuitDiff = (
- sourceReport: CircuitReport,
- compareReport: CircuitReport,
- // We want the name of the package that represents the entire program in our report
- reportName: string
-): DiffCircuit => {
- return {
- name: reportName,
- opcodes: variation(compareReport.opcodes, sourceReport.opcodes),
- circuit_size: variation(compareReport.circuit_size, sourceReport.circuit_size),
- };
-};
+ }
+ } else {
+ markdown = formatMemoryReport(memReports);
+ }
-const computeUnconstrainedDiff = (
- sourceReport: BrilligReport,
- compareReport: BrilligReport,
- // We want the name of the package that represents the entire program in our report
- reportName: string
-): DiffBrillig => {
- return {
- name: reportName,
- opcodes: variation(compareReport.opcodes, sourceReport.opcodes),
- };
-};
-
-const isEmptyDiff = (diff: DiffCircuit): boolean =>
- diff.opcodes.delta === 0 && diff.circuit_size.delta === 0;
-
-const isEmptyDiffBrillig = (diff: DiffBrillig): boolean => diff.opcodes.delta === 0;
-
-export const computeContractDiffs = (
- sourceReports: ContractReport[],
- compareReports: ContractReport[]
-): ContractDiffReport[] => {
- const sourceReportNames = sourceReports.map((report) => report.name);
- const commonReportNames = compareReports
- .map((report) => report.name)
- .filter((name) => sourceReportNames.includes(name));
-
- return commonReportNames
- .map((reportName) => {
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
- const srcReport = sourceReports.find((report) => report.name == reportName)!;
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
- const cmpReport = compareReports.find((report) => report.name == reportName)!;
-
- return computeContractDiff(srcReport, cmpReport);
- })
- .filter((diff) => diff.functions.length > 0)
- .sort(
- (diff1, diff2) =>
- Math.max(
- ...diff2.functions.map((functionDiff) => Math.abs(functionDiff.circuit_size.percentage))
- ) -
- Math.max(
- ...diff1.functions.map((functionDiff) => Math.abs(functionDiff.circuit_size.percentage))
- )
- );
-};
-
-const computeContractDiff = (
- sourceReport: ContractReport,
- compareReport: ContractReport
-): ContractDiffReport => {
- // TODO(https://github.com/noir-lang/noir/issues/4720): Settle on how to display contract functions with non-inlined Acir calls
- // Right now we assume each contract function does not have non-inlined functions.
- // Thus, we simply re-assign each `CircuitReport` to a `ProgramReport` to easily reuse `computeProgramDiffs`
- const sourceFunctionsAsProgram = sourceReport.functions.map((func) => {
- const programReport: ProgramReport = {
- package_name: func.name,
- functions: [func],
- unconstrained_functions: [],
- };
- return programReport;
- });
- const compareFunctionsAsProgram = compareReport.functions.map((func) => {
- const programReport: ProgramReport = {
- package_name: func.name,
- functions: [func],
- unconstrained_functions: [],
- };
- return programReport;
- });
- const [functionDiffs] = computeProgramDiffs(sourceFunctionsAsProgram, compareFunctionsAsProgram);
-
- return {
- name: sourceReport.name,
- functions: functionDiffs,
- };
+ return markdown;
};
diff --git a/src/types.ts b/src/types.ts
index 6927651..2f9018f 100644
--- a/src/types.ts
+++ b/src/types.ts
@@ -1,83 +1,10 @@
import * as core from "@actions/core";
-export interface CircuitReport {
- name: string;
- opcodes: number;
- circuit_size: number;
+export interface MemoryReport {
+ artifact_name: string;
+ peak_memory: string;
}
-export interface BrilligReport {
- name: string;
- opcodes: number;
+export interface MemoryReports {
+ memory_reports: MemoryReport[];
}
-
-export interface ProgramReport {
- // Name of the program package
- package_name: string;
- functions: CircuitReport[];
- unconstrained_functions: BrilligReport[];
-}
-
-export interface ContractReport {
- name: string;
- // TODO(https://github.com/noir-lang/noir/issues/4720): Settle on how to display contract functions with non-inlined Acir calls
- functions: CircuitReport[];
-}
-
-export interface WorkspaceReport {
- programs: ProgramReport[];
- contracts: ContractReport[];
-}
-
-export interface WorkspaceDiffReport {
- programs: DiffCircuit[];
- unconstrained_functions: DiffBrillig[];
- contracts: ContractDiffReport[];
-}
-
-export interface ContractDiffReport {
- name: string;
- functions: DiffCircuit[];
-}
-
-export interface DiffCircuit {
- name: string;
- opcodes: DiffCell;
- circuit_size: DiffCell;
-}
-
-export interface DiffBrillig {
- name: string;
- opcodes: DiffCell;
-}
-
-export interface DiffCell {
- previous: number;
- current: number;
- delta: number;
- percentage: number;
-}
-
-export type SortCriterion = keyof DiffCircuit;
-export type SortOrder = "asc" | "desc";
-
-const validSortCriteria = ["name", "opcodes", "circuit_size"] as SortCriterion[];
-const validSortOrders = ["asc", "desc"] as SortOrder[];
-
-export const isSortCriteriaValid = (sortCriteria: string[]): sortCriteria is SortCriterion[] => {
- const invalidSortCriterion = sortCriteria.find(
- (criterion) => !validSortCriteria.includes(criterion as SortCriterion)
- );
- if (invalidSortCriterion) core.setFailed(`Invalid sort criterion "${invalidSortCriterion}"`);
-
- return !invalidSortCriterion;
-};
-
-export const isSortOrdersValid = (sortOrders: string[]): sortOrders is SortOrder[] => {
- const invalidSortOrder = sortOrders.find(
- (order) => !validSortOrders.includes(order as SortOrder)
- );
- if (invalidSortOrder) core.setFailed(`Invalid sort order "${invalidSortOrder}"`);
-
- return !invalidSortOrder;
-};
diff --git a/tests/contract_report.test.ts b/tests/contract_report.test.ts
deleted file mode 100644
index f69cbbc..0000000
--- a/tests/contract_report.test.ts
+++ /dev/null
@@ -1,87 +0,0 @@
-import * as fs from "fs";
-
-import { formatMarkdownDiff, formatShellDiff } from "../src/format/contract";
-import { loadReports, computeContractDiffs } from "../src/report";
-
-const srcContent = fs.readFileSync("tests/mocks/gas_report.2.json", "utf8");
-const cmpContent = fs.readFileSync("tests/mocks/gas_report.1.json", "utf8");
-
-const srcContractReports = loadReports(srcContent).contracts;
-const cmpContractReports = loadReports(cmpContent).contracts;
-
-describe("Markdown format", () => {
- // shows how the runner will run a javascript action with env / stdout protocol
- // it("should run action", () => {
- // const np = process.execPath;
- // const ip = path.join(__dirname, "..", "dist", "index.js");
- // console.log(
- // cp
- // .execFileSync(np, [ip], {
- // env: {
- // ...process.env,
- // INPUT_WORKFLOWID: "test",
- // INPUT_BASE: "base",
- // INPUT_HEAD: "head",
- // GITHUB_TOKEN: "token",
- // INPUT_REPORT: "report",
- // },
- // })
- // .toString()
- // );
- // });
-
- it("should compare 1 to 2 with markdown format", () => {
- const contractDiffs = computeContractDiffs(srcContractReports, cmpContractReports);
- expect(contractDiffs.length).toBeGreaterThan(0);
-
- fs.writeFileSync(
- "tests/mocks/1-2-contract.md",
- formatMarkdownDiff(
- "# Changes to gas cost",
- contractDiffs,
- "Rubilmax/foundry-gas-diff",
- "d62d23148ca73df77cd4378ee1b3c17f1f303dbf",
- undefined,
- 0.8
- )
- );
- });
-
- it("should compare 1 to 1 with markdown format", () => {
- const contractDiffs = computeContractDiffs(srcContractReports, srcContractReports);
- expect(contractDiffs.length).toBe(0);
-
- fs.writeFileSync(
- "tests/mocks/1-1-contract.md",
- formatMarkdownDiff(
- "# Changes to gas cost",
- contractDiffs,
- "Rubilmax/foundry-gas-diff",
- "d62d23148ca73df77cd4378ee1b3c17f1f303dbf"
- )
- );
- });
-});
-
-describe("Shell format", () => {
- it("should compare 1 to 1", () => {
- const contractDiffs = computeContractDiffs(srcContractReports, srcContractReports);
- expect(contractDiffs.length).toBe(0);
-
- console.log(formatShellDiff(contractDiffs));
- });
-
- it("should compare 1 to 2", () => {
- const contractDiffs = computeContractDiffs(srcContractReports, cmpContractReports);
- expect(contractDiffs.length).toBeGreaterThan(0);
-
- console.log(formatShellDiff(contractDiffs));
- });
-
- it("should compare 2 to 1", () => {
- const contractDiffs = computeContractDiffs(cmpContractReports, srcContractReports);
- expect(contractDiffs.length).toBeGreaterThan(0);
-
- console.log(formatShellDiff(contractDiffs));
- });
-});
diff --git a/tests/diff.test.ts b/tests/diff.test.ts
deleted file mode 100644
index d942187..0000000
--- a/tests/diff.test.ts
+++ /dev/null
@@ -1,55 +0,0 @@
-import * as fs from "fs";
-
-import { computeProgramDiffs, loadReports } from "../src/report";
-import { DiffBrillig, DiffCircuit } from "../src/types";
-
-const srcContent = fs.readFileSync("tests/mocks/gas_report.2.json", "utf8");
-const cmpContent = fs.readFileSync("tests/mocks/gas_report.1.json", "utf8");
-
-describe("Program diffs", () => {
- const srcProgramReports = loadReports(srcContent).programs;
- const cmpProgramReports = loadReports(cmpContent).programs;
-
- it("should diff 1 and 2 successfully", () => {
- const expectedDiffCircuits: DiffCircuit[] = [
- {
- name: "c",
- opcodes: { previous: 2, current: 4, delta: 2, percentage: 100 },
- circuit_size: { previous: 2, current: 8, delta: 6, percentage: 300 },
- },
- {
- name: "d",
- opcodes: { previous: 3, current: 4, delta: 1, percentage: 33.333333333333336 },
- circuit_size: { previous: 5, current: 8, delta: 3, percentage: 60 },
- },
- {
- name: "b",
- opcodes: { previous: 5, current: 4, delta: -1, percentage: -20 },
- circuit_size: { previous: 10, current: 8, delta: -2, percentage: -20 },
- },
- ];
-
- const expectedDiffBrilligs: DiffBrillig[] = [
- {
- name: "c",
- opcodes: { previous: 2, current: 4, delta: 2, percentage: 100 },
- },
- {
- name: "d",
- opcodes: { previous: 3, current: 4, delta: 1, percentage: 33.333333333333336 },
- },
- {
- name: "b",
- opcodes: { previous: 5, current: 4, delta: -1, percentage: -20 },
- },
- ];
-
- const expectedDiff = [expectedDiffCircuits, expectedDiffBrilligs];
-
- expect(computeProgramDiffs(srcProgramReports, cmpProgramReports)).toStrictEqual(expectedDiff);
- });
-
- it("should return zero diff for identical reports", () => {
- expect(computeProgramDiffs(srcProgramReports, srcProgramReports)).toStrictEqual([[], []]);
- });
-});
diff --git a/tests/loading.test.ts b/tests/loading.test.ts
deleted file mode 100644
index 4f3618d..0000000
--- a/tests/loading.test.ts
+++ /dev/null
@@ -1,16 +0,0 @@
-import * as fs from "fs";
-
-import { loadReports } from "../src/report";
-
-const srcContent = fs.readFileSync("tests/mocks/gas_report.2.json", "utf8");
-const cmpContent = fs.readFileSync("tests/mocks/gas_report.1.json", "utf8");
-
-describe("Report Loading", () => {
- it("should load 1 successfully", () => {
- console.log(loadReports(srcContent));
- });
-
- it("should load 2 successfully", () => {
- console.log(loadReports(cmpContent));
- });
-});
diff --git a/tests/memory_report.test.ts b/tests/memory_report.test.ts
new file mode 100644
index 0000000..0184c0b
--- /dev/null
+++ b/tests/memory_report.test.ts
@@ -0,0 +1,26 @@
+import * as fs from "fs";
+
+import { memoryReports, formatMemoryReport, computeMemoryDiff } from "../src/report";
+
+const srcContent = fs.readFileSync("tests/mocks/mem_report.json", "utf8");
+const ref_1_Content = fs.readFileSync("tests/mocks/1-1-mem_report.json", "utf8");
+const ref_2_Content = fs.readFileSync("tests/mocks/1-2-mem_report.json", "utf8");
+
+const memReports = memoryReports(srcContent);
+
+describe("Markdown format", () => {
+ it("should generate markdown format", () => {
+ expect(memReports.length).toBeGreaterThan(0);
+ const markdown = formatMemoryReport(memReports);
+ expect(markdown.length).toBeGreaterThan(0);
+ });
+
+ it("should generate diff report format", () => {
+ const ref_1_Reports = memoryReports(ref_1_Content);
+ const ref_2_Reports = memoryReports(ref_2_Content);
+ expect(ref_1_Reports.length).toBeGreaterThan(0);
+ expect(ref_1_Reports.length).toBe(ref_2_Reports.length);
+ const markdown = computeMemoryDiff(ref_1_Reports, ref_2_Reports);
+ expect(markdown.length).toBeGreaterThan(0);
+ });
+});
diff --git a/tests/mocks/1-1-mem_report.json b/tests/mocks/1-1-mem_report.json
new file mode 100644
index 0000000..c5d09c2
--- /dev/null
+++ b/tests/mocks/1-1-mem_report.json
@@ -0,0 +1,16 @@
+{"memory_reports": [
+ {
+ "artifact_name":"keccak256",
+ "peak_memory":"85.19M"
+ }
+ ,
+ {
+ "artifact_name":"workspace",
+ "peak_memory":"123.04M"
+ }
+ ,
+ {
+ "artifact_name":"regression_4709",
+ "peak_memory":"349.30M"
+ }
+]}
\ No newline at end of file
diff --git a/tests/mocks/1-2-mem_report.json b/tests/mocks/1-2-mem_report.json
new file mode 100644
index 0000000..da0d914
--- /dev/null
+++ b/tests/mocks/1-2-mem_report.json
@@ -0,0 +1,16 @@
+{"memory_reports": [
+ {
+ "artifact_name":"keccak256",
+ "peak_memory":"95.19M"
+ }
+ ,
+ {
+ "artifact_name":"workspace",
+ "peak_memory":"103.04M"
+ }
+ ,
+ {
+ "artifact_name":"regression_4709",
+ "peak_memory":"749.30M"
+ }
+]}
\ No newline at end of file
diff --git a/tests/mocks/mem_report.json b/tests/mocks/mem_report.json
new file mode 100644
index 0000000..6715774
--- /dev/null
+++ b/tests/mocks/mem_report.json
@@ -0,0 +1,338 @@
+{
+ "memory_reports": [
+ {
+ "artifact_name":"1327_concrete_in_generic",
+ "peak_memory":78.51
+ }
+ ,
+ {
+ "artifact_name":"1_mul",
+ "peak_memory":132.60
+ }
+ ,
+ {
+ "artifact_name":"2_div",
+ "peak_memory":78.45
+ }
+ ,
+ {
+ "artifact_name":"3_add",
+ "peak_memory":78.43
+ }
+ ,
+ {
+ "artifact_name":"4_sub",
+ "peak_memory":78.43
+ }
+ ,
+ {
+ "artifact_name":"5_over",
+ "peak_memory":78.44
+ }
+ ,
+ {
+ "artifact_name":"6",
+ "peak_memory":80.70
+ }
+ ,
+ {
+ "artifact_name":"6_array",
+ "peak_memory":78.82
+ }
+ ,
+ {
+ "artifact_name":"7",
+ "peak_memory":78.45
+ }
+ ,
+ {
+ "artifact_name":"7_function",
+ "peak_memory":78.89
+ }
+ ,
+ {
+ "artifact_name":"acir_inside_brillig_recursion",
+ "peak_memory":78.44
+ }
+ ,
+ {
+ "artifact_name":"aes128_encrypt",
+ "peak_memory":78.68
+ }
+ ,
+ {
+ "artifact_name":"arithmetic_binary_operations",
+ "peak_memory":78.44
+ }
+ ,
+ {
+ "artifact_name":"array_dynamic",
+ "peak_memory":78.57
+ }
+ ,
+ {
+ "artifact_name":"array_dynamic_blackbox_input",
+ "peak_memory":86.68
+ }
+ ,
+ {
+ "artifact_name":"array_dynamic_main_output",
+ "peak_memory":78.43
+ }
+ ,
+ {
+ "artifact_name":"array_dynamic_nested_blackbox_input",
+ "peak_memory":80.22
+ }
+ ,
+ {
+ "artifact_name":"array_eq",
+ "peak_memory":78.43
+ }
+ ,
+ {
+ "artifact_name":"array_if_cond_simple",
+ "peak_memory":78.47
+ }
+ ,
+ {
+ "artifact_name":"array_len",
+ "peak_memory":78.50
+ }
+ ,
+ {
+ "artifact_name":"array_neq",
+ "peak_memory":78.52
+ }
+ ,
+ {
+ "artifact_name":"array_sort",
+ "peak_memory":78.60
+ }
+ ,
+ {
+ "artifact_name":"array_to_slice",
+ "peak_memory":78.66
+ }
+ ,
+ {
+ "artifact_name":"array_to_slice_constant_length",
+ "peak_memory":78.43
+ }
+ ,
+ {
+ "artifact_name":"as_witness",
+ "peak_memory":78.41
+ }
+ ,
+ {
+ "artifact_name":"assert",
+ "peak_memory":78.43
+ }
+ ,
+ {
+ "artifact_name":"assert_statement",
+ "peak_memory":78.42
+ }
+ ,
+ {
+ "artifact_name":"assign_ex",
+ "peak_memory":78.45
+ }
+ ,
+ {
+ "artifact_name":"bench_ecdsa_secp256k1",
+ "peak_memory":78.48
+ }
+ ,
+ {
+ "artifact_name":"bigint",
+ "peak_memory":81.40
+ }
+ ,
+ {
+ "artifact_name":"binary_operator_overloading",
+ "peak_memory":79.03
+ }
+ ,
+ {
+ "artifact_name":"bit_and",
+ "peak_memory":78.47
+ }
+ ,
+ {
+ "artifact_name":"bit_not",
+ "peak_memory":78.42
+ }
+ ,
+ {
+ "artifact_name":"bit_shifts_comptime",
+ "peak_memory":78.49
+ }
+ ,
+ {
+ "artifact_name":"bit_shifts_runtime",
+ "peak_memory":79.50
+ }
+ ,
+ {
+ "artifact_name":"blake3",
+ "peak_memory":78.45
+ }
+ ,
+ {
+ "artifact_name":"bool_not",
+ "peak_memory":78.41
+ }
+ ,
+ {
+ "artifact_name":"bool_or",
+ "peak_memory":78.42
+ }
+ ,
+ {
+ "artifact_name":"break_and_continue",
+ "peak_memory":78.44
+ }
+ ,
+ {
+ "artifact_name":"brillig_acir_as_brillig",
+ "peak_memory":78.54
+ }
+ ,
+ {
+ "artifact_name":"brillig_arrays",
+ "peak_memory":78.51
+ }
+ ,
+ {
+ "artifact_name":"brillig_blake2s",
+ "peak_memory":78.48
+ }
+ ,
+ {
+ "artifact_name":"brillig_block_parameter_liveness",
+ "peak_memory":98.25
+ }
+ ,
+ {
+ "artifact_name":"brillig_calls",
+ "peak_memory":78.59
+ }
+ ,
+ {
+ "artifact_name":"brillig_calls_array",
+ "peak_memory":78.55
+ }
+ ,
+ {
+ "artifact_name":"brillig_calls_conditionals",
+ "peak_memory":78.49
+ }
+ ,
+ {
+ "artifact_name":"brillig_conditional",
+ "peak_memory":78.44
+ }
+ ,
+ {
+ "artifact_name":"brillig_constant_reference_regression",
+ "peak_memory":78.45
+ }
+ ,
+ {
+ "artifact_name":"brillig_cow",
+ "peak_memory":78.59
+ }
+ ,
+ {
+ "artifact_name":"brillig_cow_assign",
+ "peak_memory":78.47
+ }
+ ,
+ {
+ "artifact_name":"brillig_cow_regression",
+ "peak_memory":79.76
+ }
+ ,
+ {
+ "artifact_name":"brillig_fns_as_values",
+ "peak_memory":78.55
+ }
+ ,
+ {
+ "artifact_name":"brillig_identity_function",
+ "peak_memory":78.51
+ }
+ ,
+ {
+ "artifact_name":"brillig_loop_size_regression",
+ "peak_memory":78.45
+ }
+ ,
+ {
+ "artifact_name":"brillig_nested_arrays",
+ "peak_memory":78.67
+ }
+ ,
+ {
+ "artifact_name":"brillig_not",
+ "peak_memory":78.45
+ }
+ ,
+ {
+ "artifact_name":"brillig_oracle",
+ "peak_memory":78.57
+ }
+ ,
+ {
+ "artifact_name":"brillig_pedersen",
+ "peak_memory":78.65
+ }
+ ,
+ {
+ "artifact_name":"brillig_rc_regression_6123",
+ "peak_memory":78.56
+ }
+ ,
+ {
+ "artifact_name":"brillig_recursion",
+ "peak_memory":78.45
+ }
+ ,
+ {
+ "artifact_name":"brillig_uninitialized_arrays",
+ "peak_memory":78.45
+ }
+ ,
+ {
+ "artifact_name":"cast_and_shift_global",
+ "peak_memory":78.42
+ }
+ ,
+ {
+ "artifact_name":"cast_bool",
+ "peak_memory":78.42
+ }
+ ,
+ {
+ "artifact_name":"check_large_field_bits",
+ "peak_memory":78.55
+ }
+ ,
+ {
+ "artifact_name":"closures_mut_ref",
+ "peak_memory":78.49
+ }
+ ,
+ {
+ "artifact_name":"comptime_println",
+ "peak_memory":78.44
+ }
+ ,
+ {
+ "artifact_name":"comptime_slice_equality",
+ "peak_memory":78.41
+ }
+]
+}
\ No newline at end of file
diff --git a/tests/program_report.test.ts b/tests/program_report.test.ts
deleted file mode 100644
index b8b1578..0000000
--- a/tests/program_report.test.ts
+++ /dev/null
@@ -1,196 +0,0 @@
-import * as fs from "fs";
-
-import {
- formatBrilligRows,
- formatCircuitRows,
- formatMarkdownDiff,
- formatShellBrilligRows,
- formatShellCircuitRows,
- formatShellDiff,
- formatShellDiffBrillig,
-} from "../src/format/program";
-import { computeProgramDiffs, loadReports } from "../src/report";
-
-const srcContent = fs.readFileSync("tests/mocks/gas_report.2.json", "utf8");
-const cmpContent = fs.readFileSync("tests/mocks/gas_report.1.json", "utf8");
-
-const srcContractReports = loadReports(srcContent).programs;
-const cmpContractReports = loadReports(cmpContent).programs;
-
-describe("Markdown format", () => {
- // shows how the runner will run a javascript action with env / stdout protocol
- // it("should run action", () => {
- // const np = process.execPath;
- // const ip = path.join(__dirname, "..", "dist", "index.js");
- // console.log(
- // cp
- // .execFileSync(np, [ip], {
- // env: {
- // ...process.env,
- // INPUT_WORKFLOWID: "test",
- // INPUT_BASE: "base",
- // INPUT_HEAD: "head",
- // GITHUB_TOKEN: "token",
- // INPUT_REPORT: "report",
- // },
- // })
- // .toString()
- // );
- // });
-
- it("should compare 1 to 2 with markdown format", () => {
- const [circuitDiffs, brilligDiffs] = computeProgramDiffs(
- srcContractReports,
- cmpContractReports
- );
- expect(circuitDiffs.length).toBeGreaterThan(0);
-
- const [summaryRows, fullReportRows] = formatCircuitRows(circuitDiffs, 0.8);
- fs.writeFileSync(
- "tests/mocks/1-2-program-acir.md",
- formatMarkdownDiff(
- "# Changes to gas cost",
- "Rubilmax/foundry-gas-diff",
- "d62d23148ca73df77cd4378ee1b3c17f1f303dbf",
- summaryRows,
- fullReportRows,
- true,
- false,
- undefined,
- 0.8
- )
- );
-
- const [summaryRowsBrillig, fullReportRowsBrillig] = formatBrilligRows(brilligDiffs, 0.8);
- fs.writeFileSync(
- "tests/mocks/1-2-program-brillig.md",
- formatMarkdownDiff(
- "# Changes to gas cost",
- "Rubilmax/foundry-gas-diff",
- "d62d23148ca73df77cd4378ee1b3c17f1f303dbf",
- summaryRowsBrillig,
- fullReportRowsBrillig,
- false,
- false,
- undefined,
- 0.8
- )
- );
- });
-
- it("should compare 1 to 1 with markdown format", () => {
- const [circuitDiffs, brilligDiffs] = computeProgramDiffs(
- srcContractReports,
- srcContractReports
- );
- expect(circuitDiffs.length).toBe(0);
-
- const [summaryRows, fullReportRows] = formatCircuitRows(circuitDiffs, 0.8);
- fs.writeFileSync(
- "tests/mocks/1-1-program-acir.md",
- formatMarkdownDiff(
- "# Changes to gas cost",
- "Rubilmax/foundry-gas-diff",
- "d62d23148ca73df77cd4378ee1b3c17f1f303dbf",
- summaryRows,
- fullReportRows,
- true,
- false
- )
- );
-
- const [summaryRowsBrillig, fullReportRowsBrillig] = formatBrilligRows(brilligDiffs, 0.8);
- fs.writeFileSync(
- "tests/mocks/1-1-program-brillig.md",
- formatMarkdownDiff(
- "# Changes to gas cost",
- "Rubilmax/foundry-gas-diff",
- "d62d23148ca73df77cd4378ee1b3c17f1f303dbf",
- summaryRowsBrillig,
- fullReportRowsBrillig,
- false,
- false,
- undefined,
- 0.8
- )
- );
- });
-});
-
-describe("Shell format", () => {
- it("should compare 1 to 1", () => {
- const [circuitDiffs, brilligDiffs] = computeProgramDiffs(
- srcContractReports,
- srcContractReports
- );
- expect(circuitDiffs.length).toBe(0);
-
- const [summaryRows, fullReportRows] = formatShellCircuitRows(circuitDiffs);
- console.log(formatShellDiff(circuitDiffs, summaryRows, fullReportRows));
-
- const [summaryRowsBrillig, fullReportRowsBrillig] = formatShellBrilligRows(brilligDiffs);
- console.log(
- formatShellDiffBrillig(brilligDiffs, summaryRowsBrillig, fullReportRowsBrillig, false)
- );
- });
-
- it("should compare 1 to 2", () => {
- const [circuitDiffs, brilligDiffs] = computeProgramDiffs(
- srcContractReports,
- cmpContractReports
- );
- expect(circuitDiffs.length).toBeGreaterThan(0);
-
- const [summaryRows, fullReportRows] = formatShellCircuitRows(circuitDiffs);
- console.log(formatShellDiff(circuitDiffs, summaryRows, fullReportRows));
-
- const [summaryRowsBrillig, fullReportRowsBrillig] = formatShellBrilligRows(brilligDiffs);
- console.log(
- formatShellDiffBrillig(brilligDiffs, summaryRowsBrillig, fullReportRowsBrillig, false)
- );
- });
-
- // This test is just to make sure that we are accurately resetting our reference
- // report in case it gets malformed
- it("should compare fresh report", () => {
- const srcContractReports = cmpContractReports.map((program) => {
- const circuitReport = { name: "main", opcodes: 1, circuit_size: 1 };
- const unconstrainedReport = { name: "main", opcodes: 1 };
- const programReport = {
- package_name: program.package_name,
- functions: [circuitReport],
- unconstrained_functions: [unconstrainedReport],
- };
- return programReport;
- });
- const [circuitDiffs, brilligDiffs] = computeProgramDiffs(
- srcContractReports,
- cmpContractReports
- );
- expect(circuitDiffs.length).toBeGreaterThan(0);
-
- const [summaryRows, fullReportRows] = formatShellCircuitRows(circuitDiffs);
- console.log(formatShellDiff(circuitDiffs, summaryRows, fullReportRows));
-
- const [summaryRowsBrillig, fullReportRowsBrillig] = formatShellBrilligRows(brilligDiffs);
- console.log(
- formatShellDiffBrillig(brilligDiffs, summaryRowsBrillig, fullReportRowsBrillig, false)
- );
- });
-
- it("should compare 2 to 1", () => {
- const [circuitDiffs, brilligDiffs] = computeProgramDiffs(
- cmpContractReports,
- srcContractReports
- );
- expect(circuitDiffs.length).toBeGreaterThan(0);
-
- const [summaryRows, fullReportRows] = formatShellCircuitRows(circuitDiffs);
- console.log(formatShellDiff(circuitDiffs, summaryRows, fullReportRows));
-
- const [summaryRowsBrillig, fullReportRowsBrillig] = formatShellBrilligRows(brilligDiffs);
- console.log(
- formatShellDiffBrillig(brilligDiffs, summaryRowsBrillig, fullReportRowsBrillig, false)
- );
- });
-});