Skip to content

Commit

Permalink
feat: check the installed valgrind version
Browse files Browse the repository at this point in the history
  • Loading branch information
art049 committed Apr 14, 2023
1 parent c2f2a80 commit 2e24a7d
Show file tree
Hide file tree
Showing 5 changed files with 152 additions and 14 deletions.
20 changes: 10 additions & 10 deletions dist/index.js

Large diffs are not rendered by default.

8 changes: 4 additions & 4 deletions dist/index.js.map

Large diffs are not rendered by default.

51 changes: 51 additions & 0 deletions src/helpers/valgrind.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import {exec} from "@actions/exec";

const MIN_VALGRIND_VERSION = [3, 16, 0]; // Below 3.16.0, --collect-systime=nsec is not supported

export const checkValgrindVersion = async (): Promise<void> => {
let versionOutput = "";
try {
await exec("valgrind", ["--version"], {
silent: true,
listeners: {
stdout: (data: Buffer) => {
versionOutput += data.toString();
},
},
});
} catch (error) {
throw new Error("valgrind is not installed");
}
versionOutput = versionOutput.trim();
const version = parseValgrindVersion(versionOutput);
if (!isVersionValid(version)) {
throw new Error(
`valgrind version ${version.join(
"."
)} is not supported, please upgrade to at least ${MIN_VALGRIND_VERSION.join(
"."
)}. Upgrading to Ubuntu 22.04+ will allow you to have a valid version.`
);
}
};

export const parseValgrindVersion = (versionOutput: string): number[] => {
// versionOutput is something like "valgrind-3.16.0"
const versionString = versionOutput.match(/valgrind-(.*)/)?.[1];
if (!versionString) {
throw new Error("Failed to get valgrind version");
}
const version = versionString.split(".").map(Number);
if (version.length !== 3) {
throw new Error(`valgrind version ${versionString} is not valid`);
}
return version;
};

export const isVersionValid = (version: number[]): boolean =>
version[0] >= MIN_VALGRIND_VERSION[0] &&
(version[0] > MIN_VALGRIND_VERSION[0] ||
version[1] >= MIN_VALGRIND_VERSION[1]) &&
(version[0] > MIN_VALGRIND_VERSION[0] ||
version[1] > MIN_VALGRIND_VERSION[1] ||
version[2] >= MIN_VALGRIND_VERSION[2]);
2 changes: 2 additions & 0 deletions src/prepare.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
import * as core from "@actions/core";
import {exec} from "@actions/exec";
import {checkValgrindVersion} from "./helpers/valgrind";

const prepare = async (): Promise<void> => {
core.startGroup("Prepare environment");
try {
await exec("sudo apt-get install -y valgrind", [], {
silent: true,
});
await checkValgrindVersion();
try {
await exec("pip show pytest-codspeed", [], {
silent: true,
Expand Down
85 changes: 85 additions & 0 deletions tests/valgrind.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
import {
isVersionValid,
parseValgrindVersion,
checkValgrindVersion,
} from "../src/helpers/valgrind";
import {exec} from "@actions/exec";

jest.mock("@actions/exec");
const execMock = exec as unknown as jest.Mock;

describe("valgrind helpers", () => {
describe("isVersionValid", () => {
test("should return true when version is greater than or equal to minimum version", () => {
expect(isVersionValid([3, 16, 0])).toBe(true);
expect(isVersionValid([3, 16, 1])).toBe(true);
expect(isVersionValid([3, 17, 0])).toBe(true);
expect(isVersionValid([4, 0, 0])).toBe(true);
});

test("should return false when version is less than minimum version", () => {
expect(isVersionValid([3, 15, 0])).toBe(false);
expect(isVersionValid([2, 0, 0])).toBe(false);
expect(isVersionValid([3, 15, 5])).toBe(false);
expect(isVersionValid([3, 14, 0])).toBe(false);
});
});

describe("parseValgrindVersion", () => {
test("should parse version string correctly", () => {
const versionString = "valgrind-3.16.0";
const version = parseValgrindVersion(versionString);
expect(version).toEqual([3, 16, 0]);
});

test("should throw an error if version string is not found", () => {
const versionString = "some random string";
expect(() => parseValgrindVersion(versionString)).toThrow(
"Failed to get valgrind version"
);
});

test("should throw an error if version string is invalid", () => {
const versionString = "valgrind-3.16.0.1";
expect(() => parseValgrindVersion(versionString)).toThrow(
"valgrind version 3.16.0.1 is not valid"
);
});
});
describe("checkValgrindVersion", () => {
beforeEach(() => {
jest.clearAllMocks();
jest.resetAllMocks();
});
test("should throw an error if valgrind is not installed", async () => {
execMock.mockRejectedValueOnce(
new Error("Error: Unable to locate executable file")
);
await expect(checkValgrindVersion()).rejects.toThrow(
"valgrind is not installed"
);
});
test("should throw an error if parseValgrindVersion returns a non-version value", async () => {
execMock.mockImplementationOnce(async (_, __, {listeners}) => {
listeners.stdout?.(Buffer.from("valgrind-foo"));
});
await expect(checkValgrindVersion()).rejects.toThrow(
"valgrind version foo is not valid"
);
});
test("should throw an error if installed valgrind version is too old", async () => {
execMock.mockImplementationOnce(async (_, __, {listeners}) => {
listeners.stdout?.(Buffer.from("valgrind-3.15.0"));
});
await expect(checkValgrindVersion()).rejects.toThrow(
"valgrind version 3.15.0 is not supported, please upgrade to at least 3.16.0. Upgrading to Ubuntu 22.04+ will allow you to have a valid version."
);
});
test("should not throw an error when the Valgrind version is valid", async () => {
execMock.mockImplementationOnce(async (_, __, {listeners}) => {
listeners.stdout?.(Buffer.from("valgrind-3.16.0"));
});
await expect(checkValgrindVersion()).resolves.not.toThrow();
});
});
});

0 comments on commit 2e24a7d

Please sign in to comment.