Skip to content

Commit 66d23ca

Browse files
authored
tests: add tests for configuration related output files (gem5#2613)
This commit adds tests to check that `config.ini`, `config.json`, and `config.dot` are correctly generated in the `m5out` directory when running a gem5 simulation. Note: a large portion of `test-output-files.py` was written using Claude.
1 parent 2cdb524 commit 66d23ca

File tree

3 files changed

+308
-0
lines changed

3 files changed

+308
-0
lines changed
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
# Configuration related output files
2+
3+
These tests check if output files in the `m5out` directory related to the
4+
simulation's configuration (config.ini, config.json, config.dot) are
5+
correctly generated.
6+
7+
To run these tests, use the following command:
8+
9+
```bash
10+
./main.py run gem5/config_output_files
11+
```
Lines changed: 152 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,152 @@
1+
# Copyright (c) 2021-2025 The Regents of the University of California
2+
# All rights reserved.
3+
#
4+
# Redistribution and use in source and binary forms, with or without
5+
# modification, are permitted provided that the following conditions are
6+
# met: redistributions of source code must retain the above copyright
7+
# notice, this list of conditions and the following disclaimer;
8+
# redistributions in binary form must reproduce the above copyright
9+
# notice, this list of conditions and the following disclaimer in the
10+
# documentation and/or other materials provided with the distribution;
11+
# neither the name of the copyright holders nor the names of its
12+
# contributors may be used to endorse or promote products derived from
13+
# this software without specific prior written permission.
14+
#
15+
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
16+
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
17+
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
18+
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
19+
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
20+
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
21+
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22+
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23+
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24+
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
25+
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26+
27+
"""
28+
This gem5 configuation script creates a simple board to run an ARM
29+
"hello world" binary.
30+
31+
This setup is close to the simplest setup possible using the gem5
32+
library. It does not contain any kind of caching, IO, or any non-essential
33+
components.
34+
35+
Usage
36+
-----
37+
38+
```
39+
scons build/ALL/gem5.opt
40+
./build/ALL/gem5.opt configs/example/gem5_library/arm-hello.py
41+
```
42+
"""
43+
44+
import argparse
45+
import os
46+
47+
import m5
48+
49+
from gem5.components.boards.simple_board import SimpleBoard
50+
from gem5.components.cachehierarchies.classic.no_cache import NoCache
51+
from gem5.components.memory import SingleChannelDDR3_1600
52+
from gem5.components.processors.cpu_types import CPUTypes
53+
from gem5.components.processors.simple_processor import SimpleProcessor
54+
from gem5.isas import ISA
55+
from gem5.resources.resource import obtain_resource
56+
from gem5.simulate.simulator import Simulator
57+
from gem5.utils.requires import requires
58+
59+
parser = argparse.ArgumentParser()
60+
61+
parser.add_argument("--dump-config", action="store_true")
62+
63+
parser.add_argument("--json-config", action="store_true")
64+
65+
parser.add_argument("--dot-config", action="store_true")
66+
67+
args = parser.parse_args()
68+
69+
# This check ensures the gem5 binary contains the ARM ISA target. If not, an
70+
# exception will be thrown.
71+
requires(isa_required=ISA.ARM)
72+
73+
# In this setup we don't have a cache. `NoCache` can be used for such setups.
74+
cache_hierarchy = NoCache()
75+
76+
# We use a single channel DDR3_1600 memory system
77+
memory = SingleChannelDDR3_1600(size="32MiB")
78+
79+
# We use a simple Timing processor with one core.
80+
processor = SimpleProcessor(cpu_type=CPUTypes.TIMING, isa=ISA.ARM, num_cores=1)
81+
82+
# The gem5 library simple board which can be used to run SE-mode simulations.
83+
board = SimpleBoard(
84+
clk_freq="3GHz",
85+
processor=processor,
86+
memory=memory,
87+
cache_hierarchy=cache_hierarchy,
88+
)
89+
90+
# Here we set the workload. In this case we want to run a simple "Hello World!"
91+
# program compiled to the ARM ISA. The `obtain_resource` function will
92+
# automatically download the binary from the gem5 Resources cloud bucket if
93+
# it's not already present.
94+
board.set_se_binary_workload(
95+
obtain_resource("arm-hello64-static", resource_version="1.0.0")
96+
)
97+
98+
# Lastly we run the simulation.
99+
simulator = Simulator(board=board)
100+
simulator.run()
101+
102+
103+
def check_file_exists(file_name: str):
104+
return os.path.isfile(f"{m5.options.outdir}/{file_name}")
105+
106+
107+
if args.dump_config and args.json_config and args.dot_config:
108+
if (
109+
not check_file_exists("combined_config.ini")
110+
or not check_file_exists("combined_config.json")
111+
or not check_file_exists("combined_config.dot")
112+
):
113+
print(
114+
"At least one of combined_config.ini, combined_config.json or "
115+
"combined_config.dot isn't in m5out!"
116+
)
117+
exit(1)
118+
119+
elif args.dump_config:
120+
if not check_file_exists("custom_config.ini"):
121+
print("custom_config.ini isn't in m5out!")
122+
exit(1)
123+
124+
elif args.json_config:
125+
if not check_file_exists("custom_config.json"):
126+
print("custom_config.json isn't in m5out!")
127+
exit(1)
128+
elif args.dot_config:
129+
if (
130+
not check_file_exists("custom_config.dot")
131+
or not check_file_exists("custom_config.dot.pdf")
132+
or not check_file_exists("custom_config.dot.svg")
133+
):
134+
print(
135+
"At least one of custom_config.dot, custom_config.dot.pdf or "
136+
"custom_config.dot.svg isn't in m5out!"
137+
)
138+
exit(1)
139+
140+
else:
141+
if (
142+
not check_file_exists("config.ini")
143+
or not check_file_exists("config.json")
144+
or not check_file_exists("config.dot")
145+
or not check_file_exists("config.dot.pdf")
146+
or not check_file_exists("config.dot.svg")
147+
):
148+
print(
149+
"At least one of config.ini, config.json, config.dot, "
150+
"config.dot.pdf, or config.dot.svg is missing!"
151+
)
152+
exit(1)
Lines changed: 145 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,145 @@
1+
# Copyright (c) 2025 The Regents of the University of California
2+
# All rights reserved.
3+
#
4+
# Redistribution and use in source and binary forms, with or without
5+
# modification, are permitted provided that the following conditions are
6+
# met: redistributions of source code must retain the above copyright
7+
# notice, this list of conditions and the following disclaimer;
8+
# redistributions in binary form must reproduce the above copyright
9+
# notice, this list of conditions and the following disclaimer in the
10+
# documentation and/or other materials provided with the distribution;
11+
# neither the name of the copyright holders nor the names of its
12+
# contributors may be used to endorse or promote products derived from
13+
# this software without specific prior written permission.
14+
#
15+
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
16+
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
17+
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
18+
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
19+
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
20+
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
21+
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22+
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23+
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24+
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
25+
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26+
27+
"""
28+
This runs tests to verify that configuration output files are generated
29+
correctly when using various dump-config options.
30+
"""
31+
32+
from testlib import *
33+
from testlib.helper import joinpath
34+
35+
# Test the --dump-config option. `arm-hello.py` checks for `custom_config.ini`
36+
# in the `m5out` directory after the simulation finishes.
37+
gem5_verify_config(
38+
name="arm_hello_dump_config",
39+
verifiers=(),
40+
fixtures=(),
41+
gem5_args=[
42+
"--dump-config=custom_config.ini",
43+
],
44+
config=joinpath(
45+
config.base_dir,
46+
"tests",
47+
"gem5",
48+
"config_output_files",
49+
"configs",
50+
"arm-hello.py",
51+
),
52+
config_args=["--dump-config"],
53+
valid_isas=(constants.all_compiled_tag,),
54+
valid_hosts=constants.supported_hosts,
55+
length=constants.quick_tag,
56+
)
57+
58+
# Test the --json-config option. Checks for `custom_config.json`.
59+
gem5_verify_config(
60+
name="arm_hello_json_config",
61+
verifiers=(),
62+
fixtures=(),
63+
gem5_args=[
64+
"--json-config=custom_config.json",
65+
],
66+
config=joinpath(
67+
config.base_dir,
68+
"tests",
69+
"gem5",
70+
"config_output_files",
71+
"configs",
72+
"arm-hello.py",
73+
),
74+
config_args=["--json-config"],
75+
valid_isas=(constants.all_compiled_tag,),
76+
valid_hosts=constants.supported_hosts,
77+
length=constants.quick_tag,
78+
)
79+
80+
# Test the --dot-config option. Checks for `custom_config.dot`,
81+
# `custom_config.dot.pdf` and `custom_config.dot.svg`.
82+
gem5_verify_config(
83+
name="arm_hello_dot_config",
84+
verifiers=(),
85+
fixtures=(),
86+
gem5_args=[
87+
"--dot-config=custom_config.dot",
88+
],
89+
config=joinpath(
90+
config.base_dir,
91+
"tests",
92+
"gem5",
93+
"config_output_files",
94+
"configs",
95+
"arm-hello.py",
96+
),
97+
config_args=["--dot-config"],
98+
valid_isas=(constants.all_compiled_tag,),
99+
valid_hosts=constants.supported_hosts,
100+
length=constants.quick_tag,
101+
)
102+
103+
# Test with all three options together.
104+
gem5_verify_config(
105+
name="arm_hello_all_config_options",
106+
verifiers=(),
107+
fixtures=(),
108+
gem5_args=[
109+
"--dump-config=combined_config.ini",
110+
"--json-config=combined_config.json",
111+
"--dot-config=combined_config.dot",
112+
],
113+
config=joinpath(
114+
config.base_dir,
115+
"tests",
116+
"gem5",
117+
"config_output_files",
118+
"configs",
119+
"arm-hello.py",
120+
),
121+
config_args=["--dump-config", "--json-config", "--dot-config"],
122+
valid_isas=(constants.all_compiled_tag,),
123+
valid_hosts=constants.supported_hosts,
124+
length=constants.quick_tag,
125+
)
126+
127+
# Test without passing any options in.
128+
gem5_verify_config(
129+
name="arm_hello_default_config_names",
130+
verifiers=(),
131+
fixtures=(),
132+
gem5_args=[],
133+
config=joinpath(
134+
config.base_dir,
135+
"tests",
136+
"gem5",
137+
"config_output_files",
138+
"configs",
139+
"arm-hello.py",
140+
),
141+
config_args=[],
142+
valid_isas=(constants.all_compiled_tag,),
143+
valid_hosts=constants.supported_hosts,
144+
length=constants.quick_tag,
145+
)

0 commit comments

Comments
 (0)