Skip to content

Commit

Permalink
feat: add test config to the solidity config
Browse files Browse the repository at this point in the history
  • Loading branch information
galargh committed Oct 21, 2024
1 parent 9d1eb8b commit 2f8b6d9
Show file tree
Hide file tree
Showing 6 changed files with 78 additions and 44 deletions.
Original file line number Diff line number Diff line change
@@ -1,20 +1,12 @@
import type { HardhatPlugin } from "../../../types/plugins.js";

import { ArgumentType } from "../../../types/arguments.js";
import { task } from "../../core/config.js";

const hardhatPlugin: HardhatPlugin = {
id: "builtin:solidity-test",
tasks: [
task(["test:solidity"], "Run the Solidity tests")
.setAction(import.meta.resolve("./task-action.js"))
.addOption({
name: "timeout",
description:
"The maximum time in milliseconds to wait for all the test suites to finish",
type: ArgumentType.INT,
defaultValue: 60 * 60 * 1000,
})
.build(),
],
};
Expand Down
37 changes: 15 additions & 22 deletions v-next/hardhat/src/internal/builtin-plugins/solidity-test/runner.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import type { TestEvent, TestsStream } from "./types.js";
import type { RunOptions, TestEvent, TestsStream } from "./types.js";
import type {
ArtifactId,
Artifact,
Expand All @@ -12,15 +12,6 @@ import { HardhatError } from "@ignored/hardhat-vnext-errors";

import { formatArtifactId } from "./formatters.js";

export interface RunOptions {
/**
* The maximum time in milliseconds to wait for all the test suites to finish.
*
* If not provided, the default is 1 hour.
*/
timeout?: number;
}

/**
* Run all the given solidity tests and returns the stream of results.
*
Expand Down Expand Up @@ -52,18 +43,20 @@ export function run(

const remainingSuites = new Set(testSuiteIds.map(formatArtifactId));

// NOTE: The timeout prevents the situation in which the stream is never
// closed. This can happen if we receive fewer suite results than the
// number of test suites. The timeout is set to 1 hour.
const duration = options?.timeout ?? 60 * 60 * 1000;
const timeout = setTimeout(() => {
controller.error(
new HardhatError(HardhatError.ERRORS.SOLIDITY_TESTS.RUNNER_TIMEOUT, {
duration,
suites: Array.from(remainingSuites).join(", "),
}),
);
}, duration);
let timeout: NodeJS.Timeout | undefined;
if (options?.timeout !== undefined) {
timeout = setTimeout(() => {
controller.error(
new HardhatError(
HardhatError.ERRORS.SOLIDITY_TESTS.RUNNER_TIMEOUT,
{
duration: options.timeout,
suites: Array.from(remainingSuites).join(", "),
},
),
);
}, options.timeout);
}

runSolidityTests(
artifacts,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import type { RunOptions } from "./runner.js";
import type { TestEvent } from "./types.js";
import type { RunOptions, TestEvent } from "./types.js";
import type { NewTaskActionFunction } from "../../../types/tasks.js";

import { finished } from "node:stream/promises";
Expand All @@ -8,7 +7,7 @@ import { getArtifacts, isTestArtifact } from "./helpers.js";
import { testReporter } from "./reporter.js";
import { run } from "./runner.js";

const runSolidityTests: NewTaskActionFunction = async ({ timeout }, hre) => {
const runSolidityTests: NewTaskActionFunction = async (_taskArguments, hre) => {
await hre.tasks.getTask("compile").run({ quiet: false });

console.log("\nRunning Solidity tests...\n");
Expand All @@ -31,7 +30,11 @@ const runSolidityTests: NewTaskActionFunction = async ({ timeout }, hre) => {
let includesFailures = false;
let includesErrors = false;

const options: RunOptions = { timeout };
const profileName = hre.globalOptions.buildProfile;
const profile = hre.config.solidity.profiles[profileName];
const testOptions = profile.test;

const options: RunOptions = { timeout: testOptions.timeout };

const runStream = run(artifacts, testSuiteIds, config, options);

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,13 @@
import type { SuiteResult } from "@ignored/edr";
import type { Readable } from "node:stream";

export interface RunOptions {
/**
* The maximum time in milliseconds to wait for all the test suites to finish.
*/
timeout?: number;
}

export type TestStatus = "Success" | "Failure" | "Skipped";

export type TestsStream = Readable;
Expand Down
40 changes: 32 additions & 8 deletions v-next/hardhat/src/internal/builtin-plugins/solidity/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,22 +34,38 @@ const solcUserConfigType = z.object({
profiles: incompatibleFieldType("This field is incompatible with `version`"),
});

const solidityTestUserConfigType = z.object({
timeout: z.number().optional(),
});

const singleVersionSolcUserConfigType = solcUserConfigType.extend({
test: solidityTestUserConfigType.optional(),
});

const multiVersionSolcUserConfigType = z.object({
compilers: z.array(solcUserConfigType).nonempty(),
overrides: z.record(z.string(), solcUserConfigType).optional(),
test: solidityTestUserConfigType.optional(),
version: incompatibleFieldType("This field is incompatible with `compilers`"),
settings: incompatibleFieldType(
"This field is incompatible with `compilers`",
),
});

const singleVersionSolidityUserConfigType = solcUserConfigType.extend({
dependenciesToCompile: z.array(z.string()).optional(),
remappings: z.array(z.string()).optional(),
compilers: incompatibleFieldType("This field is incompatible with `version`"),
overrides: incompatibleFieldType("This field is incompatible with `version`"),
profiles: incompatibleFieldType("This field is incompatible with `version`"),
});
const singleVersionSolidityUserConfigType =
singleVersionSolcUserConfigType.extend({
dependenciesToCompile: z.array(z.string()).optional(),
remappings: z.array(z.string()).optional(),
compilers: incompatibleFieldType(
"This field is incompatible with `version`",
),
overrides: incompatibleFieldType(
"This field is incompatible with `version`",
),
profiles: incompatibleFieldType(
"This field is incompatible with `version`",
),
});

const multiVersionSolidityUserConfigType =
multiVersionSolcUserConfigType.extend({
Expand All @@ -68,7 +84,10 @@ const buildProfilesSolidityUserConfigType = z.object({
z.string(),
conditionalUnionType(
[
[(data) => isObject(data) && "version" in data, solcUserConfigType],
[
(data) => isObject(data) && "version" in data,
singleVersionSolcUserConfigType,
],
[
(data) => isObject(data) && "compilers" in data,
multiVersionSolcUserConfigType,
Expand Down Expand Up @@ -196,6 +215,7 @@ function resolveSolidityConfig(
settings: {},
})),
overrides: {},
test: {},
},
},
dependenciesToCompile: [],
Expand All @@ -214,6 +234,7 @@ function resolveSolidityConfig(
},
],
overrides: {},
test: solidityConfig.test ?? {},
},
},
dependenciesToCompile: solidityConfig.dependenciesToCompile ?? [],
Expand Down Expand Up @@ -242,6 +263,7 @@ function resolveSolidityConfig(
},
),
),
test: solidityConfig.test ?? {},
},
},
dependenciesToCompile: solidityConfig.dependenciesToCompile ?? [],
Expand All @@ -264,6 +286,7 @@ function resolveSolidityConfig(
},
],
overrides: {},
test: {},
};
continue;
}
Expand All @@ -286,6 +309,7 @@ function resolveSolidityConfig(
},
),
),
test: profile.test ?? {},
};
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,20 @@ declare module "../../../types/config.js" {
settings?: any;
}

export type SolidityTestUserConfig = RunOptions;

export interface SingleVersionSolcUserConfig extends SolcUserConfig {
test?: SolidityTestUserConfig;
}

export interface MultiVersionSolcUserConfig {
compilers: SolcUserConfig[];
overrides?: Record<string, SolcUserConfig>;
test?: SolidityTestUserConfig;
}

export interface SingleVersionSolidityUserConfig extends SolcUserConfig {
export interface SingleVersionSolidityUserConfig
extends SingleVersionSolcUserConfig {
dependenciesToCompile?: string[];
remappings?: string[];
}
Expand All @@ -30,7 +38,10 @@ declare module "../../../types/config.js" {
}

export interface BuildProfilesSolidityUserConfig {
profiles: Record<string, SolcUserConfig | MultiVersionSolcUserConfig>;
profiles: Record<
string,
SingleVersionSolcUserConfig | MultiVersionSolcUserConfig
>;
dependenciesToCompile?: string[];
remappings?: string[];
}
Expand All @@ -44,9 +55,12 @@ declare module "../../../types/config.js" {
settings: any;
}

export type SolidityTestConfig = RunOptions;

export interface SolidityBuildProfileConfig {
compilers: SolcConfig[];
overrides: Record<string, SolcConfig>;
test: SolidityTestConfig;
}

export interface SolidityConfig {
Expand All @@ -70,6 +84,7 @@ declare module "../../../types/config.js" {

import "../../../types/hre.js";
import type { SolidityBuildSystem } from "../../../types/solidity/build-system.js";
import type { RunOptions } from "../solidity-test/types.js";

declare module "../../../types/hre.js" {
export interface HardhatRuntimeEnvironment {
Expand Down

0 comments on commit 2f8b6d9

Please sign in to comment.