Please use GitHub pull requests for new patches. Phabricator shutdown timeline
Changeset View
Changeset View
Standalone View
Standalone View
flang/unittests/Runtime/CommandTest.cpp
Show All 30 Lines | OwningPtr<Descriptor> descriptor{Descriptor::Create( | ||||
sizeof(char), n, nullptr, 0, nullptr, CFI_attribute_allocatable)}; | sizeof(char), n, nullptr, 0, nullptr, CFI_attribute_allocatable)}; | ||||
if (descriptor->Allocate() != 0) { | if (descriptor->Allocate() != 0) { | ||||
return nullptr; | return nullptr; | ||||
} | } | ||||
std::memcpy(descriptor->OffsetElement(), value, n); | std::memcpy(descriptor->OffsetElement(), value, n); | ||||
return descriptor; | return descriptor; | ||||
} | } | ||||
template <int kind = sizeof(std::int64_t)> | |||||
static OwningPtr<Descriptor> EmptyIntDescriptor() { | |||||
OwningPtr<Descriptor> descriptor{Descriptor::Create(TypeCategory::Integer, | |||||
kind, nullptr, 0, nullptr, CFI_attribute_allocatable)}; | |||||
if (descriptor->Allocate() != 0) { | |||||
return nullptr; | |||||
} | |||||
return descriptor; | |||||
} | |||||
class CommandFixture : public ::testing::Test { | class CommandFixture : public ::testing::Test { | ||||
protected: | protected: | ||||
CommandFixture(int argc, const char *argv[]) { | CommandFixture(int argc, const char *argv[]) { | ||||
RTNAME(ProgramStart)(argc, argv, {}); | RTNAME(ProgramStart)(argc, argv, {}); | ||||
} | } | ||||
std::string GetPaddedStr(const char *text, std::size_t len) const { | std::string GetPaddedStr(const char *text, std::size_t len) const { | ||||
std::string res{text}; | std::string res{text}; | ||||
assert(res.length() <= len && "No room to pad"); | assert(res.length() <= len && "No room to pad"); | ||||
res.append(len - res.length(), ' '); | res.append(len - res.length(), ' '); | ||||
return res; | return res; | ||||
} | } | ||||
void CheckDescriptorEqStr( | void CheckDescriptorEqStr( | ||||
const Descriptor *value, const std::string &expected) const { | const Descriptor *value, const std::string &expected) const { | ||||
ASSERT_NE(value, nullptr); | |||||
EXPECT_EQ(std::strncmp(value->OffsetElement(), expected.c_str(), | EXPECT_EQ(std::strncmp(value->OffsetElement(), expected.c_str(), | ||||
value->ElementBytes()), | value->ElementBytes()), | ||||
0) | 0) | ||||
<< "expected: " << expected << "\n" | << "expected: " << expected << "\n" | ||||
<< "value: " | << "value: " | ||||
<< std::string{value->OffsetElement(), value->ElementBytes()}; | << std::string{value->OffsetElement(), value->ElementBytes()}; | ||||
} | } | ||||
template <typename INT_T = std::int64_t> | |||||
void CheckDescriptorEqInt( | |||||
const Descriptor *value, const INT_T expected) const { | |||||
if (expected != -1) { | |||||
ASSERT_NE(value, nullptr); | |||||
EXPECT_EQ(*value->OffsetElement<INT_T>(), expected); | |||||
} | |||||
} | |||||
template <typename RuntimeCall> | template <typename RuntimeCall> | ||||
void CheckValue(RuntimeCall F, const char *expectedValue, | void CheckValue(RuntimeCall F, const char *expectedValue, | ||||
std::int32_t expectedStatus = 0, | std::int64_t expectedLength = -1, std::int32_t expectedStatus = 0, | ||||
const char *expectedErrMsg = "shouldn't change") const { | const char *expectedErrMsg = "shouldn't change") const { | ||||
OwningPtr<Descriptor> value{CreateEmptyCharDescriptor()}; | OwningPtr<Descriptor> value{CreateEmptyCharDescriptor()}; | ||||
ASSERT_NE(value, nullptr); | ASSERT_NE(value, nullptr); | ||||
OwningPtr<Descriptor> length{ | |||||
expectedLength == -1 ? nullptr : EmptyIntDescriptor()}; | |||||
OwningPtr<Descriptor> errmsg{CharDescriptor(expectedErrMsg)}; | OwningPtr<Descriptor> errmsg{CharDescriptor(expectedErrMsg)}; | ||||
ASSERT_NE(errmsg, nullptr); | |||||
std::string expectedValueStr{ | std::string expectedValueStr{ | ||||
GetPaddedStr(expectedValue, value->ElementBytes())}; | GetPaddedStr(expectedValue, value->ElementBytes())}; | ||||
EXPECT_EQ(F(value.get(), errmsg.get()), expectedStatus); | EXPECT_EQ(F(value.get(), length.get(), errmsg.get()), expectedStatus); | ||||
CheckDescriptorEqStr(value.get(), expectedValueStr); | CheckDescriptorEqStr(value.get(), expectedValueStr); | ||||
CheckDescriptorEqInt(length.get(), expectedLength); | |||||
CheckDescriptorEqStr(errmsg.get(), expectedErrMsg); | CheckDescriptorEqStr(errmsg.get(), expectedErrMsg); | ||||
} | } | ||||
void CheckArgumentValue(const char *expectedValue, int n) const { | void CheckArgumentValue(const char *expectedValue, int n) const { | ||||
SCOPED_TRACE(n); | SCOPED_TRACE(n); | ||||
SCOPED_TRACE("Checking argument:"); | SCOPED_TRACE("Checking argument:"); | ||||
CheckValue( | CheckValue( | ||||
[&](const Descriptor *value, const Descriptor *errmsg) { | [&](const Descriptor *value, const Descriptor *, | ||||
const Descriptor *errmsg) { | |||||
return RTNAME(ArgumentValue)(n, value, errmsg); | return RTNAME(ArgumentValue)(n, value, errmsg); | ||||
}, | }, | ||||
expectedValue); | expectedValue); | ||||
} | } | ||||
void CheckCommandValue(const char *args[], int n) const { | |||||
SCOPED_TRACE("Checking command:"); | |||||
ASSERT_GE(n, 1); | |||||
std::string expectedValue{args[0]}; | |||||
for (int i = 1; i < n; i++) { | |||||
expectedValue += " " + std::string{args[i]}; | |||||
} | |||||
CheckValue( | |||||
[&](const Descriptor *value, const Descriptor *length, | |||||
const Descriptor *errmsg) { | |||||
return RTNAME(GetCommand)(value, length, errmsg); | |||||
}, | |||||
expectedValue.c_str(), expectedValue.size()); | |||||
} | |||||
void CheckEnvVarValue( | void CheckEnvVarValue( | ||||
const char *expectedValue, const char *name, bool trimName = true) const { | const char *expectedValue, const char *name, bool trimName = true) const { | ||||
SCOPED_TRACE(name); | SCOPED_TRACE(name); | ||||
SCOPED_TRACE("Checking environment variable"); | SCOPED_TRACE("Checking environment variable"); | ||||
CheckValue( | CheckValue( | ||||
[&](const Descriptor *value, const Descriptor *errmsg) { | [&](const Descriptor *value, const Descriptor *, | ||||
const Descriptor *errmsg) { | |||||
return RTNAME(EnvVariableValue)(*CharDescriptor(name), value, | return RTNAME(EnvVariableValue)(*CharDescriptor(name), value, | ||||
trimName, errmsg, /*sourceFile=*/nullptr, /*line=*/0); | trimName, errmsg, /*sourceFile=*/nullptr, /*line=*/0); | ||||
}, | }, | ||||
expectedValue); | expectedValue); | ||||
} | } | ||||
void CheckMissingEnvVarValue(const char *name, bool trimName = true) const { | void CheckMissingEnvVarValue(const char *name, bool trimName = true) const { | ||||
SCOPED_TRACE(name); | SCOPED_TRACE(name); | ||||
SCOPED_TRACE("Checking missing environment variable"); | SCOPED_TRACE("Checking missing environment variable"); | ||||
ASSERT_EQ(nullptr, std::getenv(name)) | ASSERT_EQ(nullptr, std::getenv(name)) | ||||
<< "Environment variable " << name << " not expected to exist"; | << "Environment variable " << name << " not expected to exist"; | ||||
OwningPtr<Descriptor> nameDescriptor{CharDescriptor(name)}; | OwningPtr<Descriptor> nameDescriptor{CharDescriptor(name)}; | ||||
EXPECT_EQ(0, RTNAME(EnvVariableLength)(*nameDescriptor, trimName)); | EXPECT_EQ(0, RTNAME(EnvVariableLength)(*nameDescriptor, trimName)); | ||||
CheckValue( | CheckValue( | ||||
[&](const Descriptor *value, const Descriptor *errmsg) { | [&](const Descriptor *value, const Descriptor *, | ||||
const Descriptor *errmsg) { | |||||
return RTNAME(EnvVariableValue)(*nameDescriptor, value, trimName, | return RTNAME(EnvVariableValue)(*nameDescriptor, value, trimName, | ||||
errmsg, /*sourceFile=*/nullptr, /*line=*/0); | errmsg, /*sourceFile=*/nullptr, /*line=*/0); | ||||
}, | }, | ||||
"", 1, "Missing environment variable"); | "", -1, 1, "Missing environment variable"); | ||||
} | } | ||||
void CheckMissingArgumentValue(int n, const char *errStr = nullptr) const { | void CheckMissingArgumentValue(int n, const char *errStr = nullptr) const { | ||||
OwningPtr<Descriptor> value{CreateEmptyCharDescriptor()}; | OwningPtr<Descriptor> value{CreateEmptyCharDescriptor()}; | ||||
ASSERT_NE(value, nullptr); | ASSERT_NE(value, nullptr); | ||||
OwningPtr<Descriptor> err{errStr ? CreateEmptyCharDescriptor() : nullptr}; | OwningPtr<Descriptor> err{errStr ? CreateEmptyCharDescriptor() : nullptr}; | ||||
EXPECT_GT(RTNAME(ArgumentValue)(n, value.get(), err.get()), 0); | EXPECT_GT(RTNAME(ArgumentValue)(n, value.get(), err.get()), 0); | ||||
std::string spaces(value->ElementBytes(), ' '); | std::string spaces(value->ElementBytes(), ' '); | ||||
CheckDescriptorEqStr(value.get(), spaces); | CheckDescriptorEqStr(value.get(), spaces); | ||||
if (errStr) { | if (errStr) { | ||||
std::string paddedErrStr(GetPaddedStr(errStr, err->ElementBytes())); | std::string paddedErrStr(GetPaddedStr(errStr, err->ElementBytes())); | ||||
CheckDescriptorEqStr(err.get(), paddedErrStr); | CheckDescriptorEqStr(err.get(), paddedErrStr); | ||||
} | } | ||||
} | } | ||||
void CheckMissingCommandValue(const char *errStr = nullptr) const { | |||||
OwningPtr<Descriptor> value{CreateEmptyCharDescriptor()}; | |||||
ASSERT_NE(value, nullptr); | |||||
OwningPtr<Descriptor> length{EmptyIntDescriptor()}; | |||||
ASSERT_NE(length, nullptr); | |||||
OwningPtr<Descriptor> err{errStr ? CreateEmptyCharDescriptor() : nullptr}; | |||||
EXPECT_GT(RTNAME(GetCommand)(value.get(), length.get(), err.get()), 0); | |||||
std::string spaces(value->ElementBytes(), ' '); | |||||
CheckDescriptorEqStr(value.get(), spaces); | |||||
CheckDescriptorEqInt(length.get(), 0); | |||||
if (errStr) { | |||||
std::string paddedErrStr(GetPaddedStr(errStr, err->ElementBytes())); | |||||
CheckDescriptorEqStr(err.get(), paddedErrStr); | |||||
} | |||||
} | |||||
}; | |||||
class NoArgv : public CommandFixture { | |||||
protected: | |||||
NoArgv() : CommandFixture(0, nullptr) {} | |||||
}; | }; | ||||
// TODO: Test other intrinsics with this fixture. | |||||
TEST_F(NoArgv, GetCommand) { CheckMissingCommandValue(); } | |||||
static const char *commandOnlyArgv[]{"aProgram"}; | static const char *commandOnlyArgv[]{"aProgram"}; | ||||
class ZeroArguments : public CommandFixture { | class ZeroArguments : public CommandFixture { | ||||
protected: | protected: | ||||
ZeroArguments() : CommandFixture(1, commandOnlyArgv) {} | ZeroArguments() : CommandFixture(1, commandOnlyArgv) {} | ||||
}; | }; | ||||
TEST_F(ZeroArguments, ArgumentCount) { EXPECT_EQ(0, RTNAME(ArgumentCount)()); } | TEST_F(ZeroArguments, ArgumentCount) { EXPECT_EQ(0, RTNAME(ArgumentCount)()); } | ||||
TEST_F(ZeroArguments, ArgumentLength) { | TEST_F(ZeroArguments, ArgumentLength) { | ||||
EXPECT_EQ(0, RTNAME(ArgumentLength)(-1)); | EXPECT_EQ(0, RTNAME(ArgumentLength)(-1)); | ||||
EXPECT_EQ(8, RTNAME(ArgumentLength)(0)); | EXPECT_EQ(8, RTNAME(ArgumentLength)(0)); | ||||
EXPECT_EQ(0, RTNAME(ArgumentLength)(1)); | EXPECT_EQ(0, RTNAME(ArgumentLength)(1)); | ||||
} | } | ||||
TEST_F(ZeroArguments, ArgumentValue) { | TEST_F(ZeroArguments, ArgumentValue) { | ||||
CheckArgumentValue(commandOnlyArgv[0], 0); | CheckArgumentValue(commandOnlyArgv[0], 0); | ||||
} | } | ||||
TEST_F(ZeroArguments, GetCommand) { CheckCommandValue(commandOnlyArgv, 1); } | |||||
static const char *oneArgArgv[]{"aProgram", "anArgumentOfLength20"}; | static const char *oneArgArgv[]{"aProgram", "anArgumentOfLength20"}; | ||||
class OneArgument : public CommandFixture { | class OneArgument : public CommandFixture { | ||||
protected: | protected: | ||||
OneArgument() : CommandFixture(2, oneArgArgv) {} | OneArgument() : CommandFixture(2, oneArgArgv) {} | ||||
}; | }; | ||||
TEST_F(OneArgument, ArgumentCount) { EXPECT_EQ(1, RTNAME(ArgumentCount)()); } | TEST_F(OneArgument, ArgumentCount) { EXPECT_EQ(1, RTNAME(ArgumentCount)()); } | ||||
TEST_F(OneArgument, ArgumentLength) { | TEST_F(OneArgument, ArgumentLength) { | ||||
EXPECT_EQ(0, RTNAME(ArgumentLength)(-1)); | EXPECT_EQ(0, RTNAME(ArgumentLength)(-1)); | ||||
EXPECT_EQ(8, RTNAME(ArgumentLength)(0)); | EXPECT_EQ(8, RTNAME(ArgumentLength)(0)); | ||||
EXPECT_EQ(20, RTNAME(ArgumentLength)(1)); | EXPECT_EQ(20, RTNAME(ArgumentLength)(1)); | ||||
EXPECT_EQ(0, RTNAME(ArgumentLength)(2)); | EXPECT_EQ(0, RTNAME(ArgumentLength)(2)); | ||||
} | } | ||||
TEST_F(OneArgument, ArgumentValue) { | TEST_F(OneArgument, ArgumentValue) { | ||||
CheckArgumentValue(oneArgArgv[0], 0); | CheckArgumentValue(oneArgArgv[0], 0); | ||||
CheckArgumentValue(oneArgArgv[1], 1); | CheckArgumentValue(oneArgArgv[1], 1); | ||||
} | } | ||||
TEST_F(OneArgument, GetCommand) { CheckCommandValue(oneArgArgv, 2); } | |||||
static const char *severalArgsArgv[]{ | static const char *severalArgsArgv[]{ | ||||
"aProgram", "16-char-long-arg", "", "-22-character-long-arg", "o"}; | "aProgram", "16-char-long-arg", "", "-22-character-long-arg", "o"}; | ||||
class SeveralArguments : public CommandFixture { | class SeveralArguments : public CommandFixture { | ||||
protected: | protected: | ||||
SeveralArguments() | SeveralArguments() | ||||
: CommandFixture(sizeof(severalArgsArgv) / sizeof(*severalArgsArgv), | : CommandFixture(sizeof(severalArgsArgv) / sizeof(*severalArgsArgv), | ||||
severalArgsArgv) {} | severalArgsArgv) {} | ||||
}; | }; | ||||
Show All 28 Lines | |||||
TEST_F(SeveralArguments, MissingArguments) { | TEST_F(SeveralArguments, MissingArguments) { | ||||
CheckMissingArgumentValue(-1, "Invalid argument number"); | CheckMissingArgumentValue(-1, "Invalid argument number"); | ||||
CheckMissingArgumentValue(2, "Missing argument"); | CheckMissingArgumentValue(2, "Missing argument"); | ||||
CheckMissingArgumentValue(5, "Invalid argument number"); | CheckMissingArgumentValue(5, "Invalid argument number"); | ||||
CheckMissingArgumentValue(5); | CheckMissingArgumentValue(5); | ||||
} | } | ||||
TEST_F(SeveralArguments, ValueTooShort) { | TEST_F(SeveralArguments, ArgValueTooShort) { | ||||
OwningPtr<Descriptor> tooShort{CreateEmptyCharDescriptor<15>()}; | OwningPtr<Descriptor> tooShort{CreateEmptyCharDescriptor<15>()}; | ||||
ASSERT_NE(tooShort, nullptr); | ASSERT_NE(tooShort, nullptr); | ||||
EXPECT_EQ(RTNAME(ArgumentValue)(1, tooShort.get(), nullptr), -1); | EXPECT_EQ(RTNAME(ArgumentValue)(1, tooShort.get(), nullptr), -1); | ||||
CheckDescriptorEqStr(tooShort.get(), severalArgsArgv[1]); | CheckDescriptorEqStr(tooShort.get(), severalArgsArgv[1]); | ||||
OwningPtr<Descriptor> errMsg{CreateEmptyCharDescriptor()}; | OwningPtr<Descriptor> errMsg{CreateEmptyCharDescriptor()}; | ||||
ASSERT_NE(errMsg, nullptr); | ASSERT_NE(errMsg, nullptr); | ||||
EXPECT_EQ(RTNAME(ArgumentValue)(1, tooShort.get(), errMsg.get()), -1); | EXPECT_EQ(RTNAME(ArgumentValue)(1, tooShort.get(), errMsg.get()), -1); | ||||
std::string expectedErrMsg{ | std::string expectedErrMsg{ | ||||
GetPaddedStr("Value too short", errMsg->ElementBytes())}; | GetPaddedStr("Value too short", errMsg->ElementBytes())}; | ||||
CheckDescriptorEqStr(errMsg.get(), expectedErrMsg); | CheckDescriptorEqStr(errMsg.get(), expectedErrMsg); | ||||
} | } | ||||
TEST_F(SeveralArguments, ErrMsgTooShort) { | TEST_F(SeveralArguments, ArgErrMsgTooShort) { | ||||
OwningPtr<Descriptor> errMsg{CreateEmptyCharDescriptor<3>()}; | OwningPtr<Descriptor> errMsg{CreateEmptyCharDescriptor<3>()}; | ||||
EXPECT_GT(RTNAME(ArgumentValue)(-1, nullptr, errMsg.get()), 0); | EXPECT_GT(RTNAME(ArgumentValue)(-1, nullptr, errMsg.get()), 0); | ||||
CheckDescriptorEqStr(errMsg.get(), "Inv"); | CheckDescriptorEqStr(errMsg.get(), "Inv"); | ||||
} | } | ||||
TEST_F(SeveralArguments, GetCommand) { | |||||
CheckMissingCommandValue(); | |||||
CheckMissingCommandValue("Missing argument"); | |||||
} | |||||
TEST_F(SeveralArguments, CommandErrMsgTooShort) { | |||||
OwningPtr<Descriptor> value{CreateEmptyCharDescriptor()}; | |||||
OwningPtr<Descriptor> length{EmptyIntDescriptor()}; | |||||
OwningPtr<Descriptor> errMsg{CreateEmptyCharDescriptor<3>()}; | |||||
EXPECT_GT(RTNAME(GetCommand)(value.get(), length.get(), errMsg.get()), 0); | |||||
std::string spaces(value->ElementBytes(), ' '); | |||||
CheckDescriptorEqStr(value.get(), spaces); | |||||
CheckDescriptorEqInt(length.get(), 0); | |||||
CheckDescriptorEqStr(errMsg.get(), "Mis"); | |||||
} | |||||
TEST_F(SeveralArguments, GetCommandCanTakeNull) { | |||||
EXPECT_GT(RTNAME(GetCommand)(nullptr, nullptr, nullptr), 0); | |||||
} | |||||
static const char *onlyValidArgsArgv[]{ | |||||
"aProgram", "-f", "has/a/few/slashes", "has\\a\\few\\backslashes"}; | |||||
class OnlyValidArguments : public CommandFixture { | |||||
protected: | |||||
OnlyValidArguments() | |||||
: CommandFixture(sizeof(onlyValidArgsArgv) / sizeof(*onlyValidArgsArgv), | |||||
onlyValidArgsArgv) {} | |||||
}; | |||||
TEST_F(OnlyValidArguments, GetCommand) { | |||||
CheckCommandValue(onlyValidArgsArgv, 4); | |||||
} | |||||
TEST_F(OnlyValidArguments, CommandValueTooShort) { | |||||
OwningPtr<Descriptor> tooShort{CreateEmptyCharDescriptor<50>()}; | |||||
ASSERT_NE(tooShort, nullptr); | |||||
OwningPtr<Descriptor> length{EmptyIntDescriptor()}; | |||||
ASSERT_NE(length, nullptr); | |||||
EXPECT_EQ(RTNAME(GetCommand)(tooShort.get(), length.get(), nullptr), -1); | |||||
CheckDescriptorEqStr( | |||||
tooShort.get(), "aProgram -f has/a/few/slashes has\\a\\few\\backslashe"); | |||||
CheckDescriptorEqInt(length.get(), 51); | |||||
OwningPtr<Descriptor> errMsg{CreateEmptyCharDescriptor()}; | |||||
ASSERT_NE(errMsg, nullptr); | |||||
EXPECT_EQ(-1, RTNAME(GetCommand)(tooShort.get(), nullptr, errMsg.get())); | |||||
std::string expectedErrMsg{ | |||||
GetPaddedStr("Value too short", errMsg->ElementBytes())}; | |||||
CheckDescriptorEqStr(errMsg.get(), expectedErrMsg); | |||||
} | |||||
TEST_F(OnlyValidArguments, GetCommandCanTakeNull) { | |||||
EXPECT_EQ(0, RTNAME(GetCommand)(nullptr, nullptr, nullptr)); | |||||
OwningPtr<Descriptor> value{CreateEmptyCharDescriptor()}; | |||||
ASSERT_NE(value, nullptr); | |||||
OwningPtr<Descriptor> length{EmptyIntDescriptor()}; | |||||
ASSERT_NE(length, nullptr); | |||||
EXPECT_EQ(0, RTNAME(GetCommand)(value.get(), nullptr, nullptr)); | |||||
CheckDescriptorEqStr(value.get(), | |||||
GetPaddedStr("aProgram -f has/a/few/slashes has\\a\\few\\backslashes", | |||||
value->ElementBytes())); | |||||
EXPECT_EQ(0, RTNAME(GetCommand)(nullptr, length.get(), nullptr)); | |||||
CheckDescriptorEqInt(length.get(), 51); | |||||
} | |||||
TEST_F(OnlyValidArguments, GetCommandShortLength) { | |||||
OwningPtr<Descriptor> length{EmptyIntDescriptor<sizeof(short)>()}; | |||||
ASSERT_NE(length, nullptr); | |||||
EXPECT_EQ(0, RTNAME(GetCommand)(nullptr, length.get(), nullptr)); | |||||
CheckDescriptorEqInt<short>(length.get(), 51); | |||||
jeanPerier: This test seems to fail on windows, see the build bot:
```
Note: Google Test filter =… | |||||
Oops, I thought I had looked at the premerge checks for this one, but it must've slipped my mind 😳 Thanks for looking into it. rovka: Oops, I thought I had looked at the premerge checks for this one, but it must've slipped my… | |||||
} | |||||
class EnvironmentVariables : public CommandFixture { | class EnvironmentVariables : public CommandFixture { | ||||
protected: | protected: | ||||
EnvironmentVariables() : CommandFixture(0, nullptr) { | EnvironmentVariables() : CommandFixture(0, nullptr) { | ||||
SetEnv("NAME", "VALUE"); | SetEnv("NAME", "VALUE"); | ||||
SetEnv("EMPTY", ""); | SetEnv("EMPTY", ""); | ||||
} | } | ||||
// If we have access to setenv, we can run some more fine-grained tests. | // If we have access to setenv, we can run some more fine-grained tests. | ||||
▲ Show 20 Lines • Show All 92 Lines • Show Last 20 Lines |
This test seems to fail on windows, see the build bot:
I think the value->OffsetElement<std::int64_t>() in CheckDescriptorEqInt may be undefined behavior if the integer type in value is not an std::int64_t (like here where it is a short).