mirror of
https://github.com/FEX-Emu/FEX.git
synced 2026-10-29 04:01:27 +01:00
Merge pull request #1586 from Sonicadvance1/testharness_env
TestHarnessRunner: Wire up environment variable option setting
This commit is contained in:
3 files changed
+96
-2
No files matched your search
@@ -148,7 +148,7 @@ def parse_json(json_text, output_file):
|
||||
OptionRegData = {}
|
||||
OptionMemoryRegions = {}
|
||||
OptionMemoryData = {}
|
||||
|
||||
OptionEnvironmentVariables = {}
|
||||
|
||||
json_object = json.loads(json_text)
|
||||
json_object = {k.upper(): v for k, v in json_object.items()}
|
||||
@@ -242,6 +242,14 @@ def parse_json(json_text, output_file):
|
||||
length, byte_data = parse_hexstring(data_val)
|
||||
OptionMemoryData[int(data_key, 0)] = (length, byte_data)
|
||||
|
||||
if ("ENV" in json_object):
|
||||
data = json_object["ENV"]
|
||||
if not (type(data) is dict):
|
||||
sys.exit("Environment variables value must be list of key:value pairs")
|
||||
|
||||
for data_key, data_val in data.items():
|
||||
OptionEnvironmentVariables[data_key] = data_val
|
||||
|
||||
# If Match option wasn't touched then set it to the default
|
||||
if (OptionMatch == Regs.REG_INVALID):
|
||||
OptionMatch = Regs.REG_NONE
|
||||
@@ -250,6 +258,7 @@ def parse_json(json_text, output_file):
|
||||
memRegions = bytes()
|
||||
regData = bytes()
|
||||
memData = bytes()
|
||||
envData = bytes()
|
||||
|
||||
# Write memory regions
|
||||
for key, val in OptionMemoryRegions.items():
|
||||
@@ -271,6 +280,13 @@ def parse_json(json_text, output_file):
|
||||
for byte in data:
|
||||
memData += struct.pack('B', byte)
|
||||
|
||||
# Write environment variables
|
||||
for key, val in OptionEnvironmentVariables.items():
|
||||
envData += key.encode()
|
||||
envData += struct.pack('B', 0)
|
||||
envData += val.encode()
|
||||
envData += struct.pack('B', 0)
|
||||
|
||||
config_file = open(output_file, "wb")
|
||||
config_file.write(struct.pack('Q', OptionMatch.value))
|
||||
config_file.write(struct.pack('Q', OptionIgnore.value))
|
||||
@@ -280,7 +296,7 @@ def parse_json(json_text, output_file):
|
||||
config_file.write(struct.pack('I', OptionMode.value))
|
||||
|
||||
# Total length of header, including offsets/counts below
|
||||
headerLength = (8 * 4) + (4 * 2) + (4 * 6)
|
||||
headerLength = (8 * 4) + (4 * 2) + (4 * 8)
|
||||
offset = headerLength
|
||||
|
||||
# memory regions offset/count
|
||||
@@ -298,10 +314,16 @@ def parse_json(json_text, output_file):
|
||||
config_file.write(struct.pack('I', len(OptionMemoryData)))
|
||||
offset += len(memData)
|
||||
|
||||
# environment data offset/count
|
||||
config_file.write(struct.pack('I', offset))
|
||||
config_file.write(struct.pack('I', len(OptionEnvironmentVariables)))
|
||||
offset += len(envData)
|
||||
|
||||
# write out the actual data for memory regions, reg data and memory data
|
||||
config_file.write(memRegions)
|
||||
config_file.write(regData)
|
||||
config_file.write(memData)
|
||||
config_file.write(envData)
|
||||
|
||||
config_file.close()
|
||||
|
||||
@@ -161,6 +161,21 @@ namespace FEX::HarnessHelper {
|
||||
void Init(std::string const &ConfigFilename) {
|
||||
ReadFile(ConfigFilename, &RawConfigFile);
|
||||
memcpy(&BaseConfig, RawConfigFile.data(), sizeof(ConfigStructBase));
|
||||
GetEnvironmentOptions();
|
||||
}
|
||||
|
||||
std::vector<std::pair<std::string_view, std::string_view>> GetEnvironmentOptions() {
|
||||
std::vector<std::pair<std::string_view, std::string_view>> Env{};
|
||||
|
||||
uintptr_t DataOffset = BaseConfig.OptionEnvOptionOffset;
|
||||
for (unsigned i = 0; i < BaseConfig.OptionEnvOptionCount; ++i) {
|
||||
// Environment variables are null terminated strings
|
||||
std::string_view Key = RawConfigFile.data() + DataOffset;
|
||||
std::string_view Value = RawConfigFile.data() + DataOffset + Key.size() + 1;
|
||||
DataOffset += Key.size() + Value.size() + 2;
|
||||
Env.emplace_back(Key, Value);
|
||||
}
|
||||
return Env;
|
||||
}
|
||||
|
||||
bool CompareStates(FEXCore::Core::CPUState const* State1, FEXCore::Core::CPUState const* State2) {
|
||||
@@ -316,6 +331,8 @@ namespace FEX::HarnessHelper {
|
||||
uint32_t OptionRegDataCount;
|
||||
uint32_t OptionMemDataOffset;
|
||||
uint32_t OptionMemDataCount;
|
||||
uint32_t OptionEnvOptionOffset;
|
||||
uint32_t OptionEnvOptionCount;
|
||||
uint8_t AdditionalData[];
|
||||
} FEX_PACKED;
|
||||
|
||||
@@ -424,6 +441,9 @@ namespace FEX::HarnessHelper {
|
||||
Config.LoadMemory();
|
||||
}
|
||||
|
||||
std::vector<std::pair<std::string_view, std::string_view>> GetEnvironmentOptions() {
|
||||
return Config.GetEnvironmentOptions();
|
||||
}
|
||||
|
||||
bool CompareStates(FEXCore::Core::CPUState const* State1, FEXCore::Core::CPUState const* State2) {
|
||||
return Config.CompareStates(State1, State2);
|
||||
|
||||
@@ -64,6 +64,53 @@ void AssertHandler(char const *Message) {
|
||||
fmt::print("[ASSERT] {}\n", Message);
|
||||
}
|
||||
|
||||
namespace {
|
||||
static const std::vector<std::pair<const char*, FEXCore::Config::ConfigOption>> EnvConfigLookup = {{
|
||||
#define OPT_BASE(type, group, enum, json, default) {"FEX_" #enum, FEXCore::Config::ConfigOption::CONFIG_##enum},
|
||||
#include <FEXCore/Config/ConfigValues.inl>
|
||||
}};
|
||||
|
||||
// Claims to be a local application config layer
|
||||
class TestEnvLoader final : public FEXCore::Config::Layer {
|
||||
public:
|
||||
explicit TestEnvLoader(std::vector<std::pair<std::string_view, std::string_view>> _Env)
|
||||
: FEXCore::Config::Layer(FEXCore::Config::LayerType::LAYER_LOCAL_APP)
|
||||
, Env {std::move(_Env)} {
|
||||
Load();
|
||||
}
|
||||
|
||||
void Load() override {
|
||||
std::unordered_map<std::string_view, std::string_view> EnvMap;
|
||||
for (auto &Option : Env) {
|
||||
std::string_view Key = Option.first;
|
||||
std::string_view Value = Option.second;
|
||||
|
||||
#define ENVLOADER
|
||||
#include <FEXCore/Config/ConfigOptions.inl>
|
||||
|
||||
EnvMap.insert_or_assign(Key, Value);
|
||||
}
|
||||
|
||||
auto GetVar = [&](const std::string_view id) -> std::optional<std::string_view> {
|
||||
const auto it = EnvMap.find(id);
|
||||
if (it == EnvMap.end())
|
||||
return std::nullopt;
|
||||
|
||||
return it->second;
|
||||
};
|
||||
|
||||
for (auto &it : EnvConfigLookup) {
|
||||
if (auto Value = GetVar(it.first); Value) {
|
||||
Set(it.second, *Value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
std::vector<std::pair<std::string_view, std::string_view>> Env;
|
||||
};
|
||||
}
|
||||
|
||||
int main(int argc, char **argv, char **const envp) {
|
||||
LogMan::Throw::InstallHandler(AssertHandler);
|
||||
LogMan::Msg::InstallHandler(MsgHandler);
|
||||
@@ -80,6 +127,11 @@ int main(int argc, char **argv, char **const envp) {
|
||||
}
|
||||
|
||||
FEX::HarnessHelper::HarnessCodeLoader Loader{Args[0], Args[1].c_str()};
|
||||
|
||||
// Adds in environment options from the test harness config
|
||||
FEXCore::Config::AddLayer(std::make_unique<TestEnvLoader>(Loader.GetEnvironmentOptions()));
|
||||
FEXCore::Config::ReloadMetaLayer();
|
||||
|
||||
FEXCore::Config::Set(FEXCore::Config::CONFIG_IS64BIT_MODE, Loader.Is64BitMode() ? "1" : "0");
|
||||
|
||||
FEXCore::Context::InitializeStaticTables(Loader.Is64BitMode() ? FEXCore::Context::MODE_64BIT : FEXCore::Context::MODE_32BIT);
|
||||
|
||||
Reference in new issue
Block a user