Add a simple test for the CreateProcess NewConsole standard handle case.
Simplify checkModernConsoleHandleInit usage; it isn't necessary to build a list of potential console handles. We can just scan for them.
This commit is contained in:
parent
7ad3f28f48
commit
45a38be9e4
56
misc/buffer-tests/HandleTests/CreateProcess_NewConsole.cc
Executable file
56
misc/buffer-tests/HandleTests/CreateProcess_NewConsole.cc
Executable file
@ -0,0 +1,56 @@
|
||||
#include <TestCommon.h>
|
||||
|
||||
//
|
||||
// Test CreateProcess when called with these parameters:
|
||||
// - STARTF_USESTDHANDLES is not specified
|
||||
// - bInheritHandles=FALSE or bInheritHandles=TRUE
|
||||
// - CreationConsoleMode=NewConsole
|
||||
//
|
||||
|
||||
template <typename T>
|
||||
static void extend(std::vector<T> &base, const std::vector<T> &to_add) {
|
||||
base.insert(base.end(), to_add.begin(), to_add.end());
|
||||
}
|
||||
|
||||
REGISTER(Test_CreateProcess_NewConsole, always);
|
||||
static void Test_CreateProcess_NewConsole() {
|
||||
auto check = [](Worker &p, bool inheritHandles) {
|
||||
auto c = p.child({ inheritHandles, CREATE_NEW_CONSOLE });
|
||||
if (isTraditionalConio()) {
|
||||
checkInitConsoleHandleSet(c);
|
||||
} else {
|
||||
checkModernConsoleHandleInit(c, true, true, true);
|
||||
}
|
||||
return c;
|
||||
};
|
||||
{
|
||||
Worker p;
|
||||
check(p, true);
|
||||
check(p, false);
|
||||
}
|
||||
{
|
||||
Worker p;
|
||||
p.openConin(false).setStdin();
|
||||
p.newBuffer(false).setStdout().dup(true).setStderr();
|
||||
check(p, true);
|
||||
check(p, false);
|
||||
}
|
||||
|
||||
if (isModernConio()) {
|
||||
// The default Unbound console handles should be inheritable, so with
|
||||
// bInheritHandles=TRUE, the child process should have six console
|
||||
// handles, all usable.
|
||||
Worker p;
|
||||
auto c = check(p, true);
|
||||
|
||||
std::vector<uint64_t> expected;
|
||||
extend(expected, handleInts(stdHandles(p)));
|
||||
extend(expected, handleInts(stdHandles(c)));
|
||||
std::sort(expected.begin(), expected.end());
|
||||
|
||||
auto correct = handleInts(c.scanForConsoleHandles());
|
||||
std::sort(correct.begin(), correct.end());
|
||||
|
||||
CHECK(expected == correct);
|
||||
}
|
||||
}
|
@ -147,9 +147,6 @@ static void Test_CreateProcess_UseStdHandles() {
|
||||
}
|
||||
}
|
||||
} else {
|
||||
auto nonReuseCheck = stdHandles(p);
|
||||
nonReuseCheck.insert(nonReuseCheck.end(),
|
||||
newHandles.begin(), newHandles.end());
|
||||
ObjectSnap snap;
|
||||
bool consoleOpened[3] = {false, false, false};
|
||||
for (int i = 0; i < 3; ++i) {
|
||||
@ -176,8 +173,7 @@ static void Test_CreateProcess_UseStdHandles() {
|
||||
checkModernConsoleHandleInit(c,
|
||||
consoleOpened[0],
|
||||
consoleOpened[1],
|
||||
consoleOpened[2],
|
||||
nonReuseCheck);
|
||||
consoleOpened[2]);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -45,6 +45,7 @@ HANDLETESTS_OBJECTS = \
|
||||
build/obj/HandleTests/CreateProcess_DefaultInherit.o \
|
||||
build/obj/HandleTests/CreateProcess_DefaultInherit_PseudoHandleBug.o \
|
||||
build/obj/HandleTests/CreateProcess_DefaultInherit_XPPipeBug.o \
|
||||
build/obj/HandleTests/CreateProcess_NewConsole.o \
|
||||
build/obj/HandleTests/CreateProcess_UseStdHandles.o \
|
||||
build/obj/HandleTests/MiscTests.o \
|
||||
build/obj/HandleTests/Modern.o \
|
||||
|
@ -225,16 +225,26 @@ bool isUnboundConsoleObject(RemoteHandle h) {
|
||||
}
|
||||
|
||||
void checkModernConsoleHandleInit(RemoteWorker &proc,
|
||||
bool in, bool out, bool err,
|
||||
std::vector<RemoteHandle> nonReuseCheck) {
|
||||
bool in, bool out, bool err) {
|
||||
// List all the usable console handles that weren't just opened.
|
||||
std::vector<RemoteHandle> preExistingHandles;
|
||||
for (auto h : proc.scanForConsoleHandles()) {
|
||||
if ((in && h.value() == proc.getStdin().value()) ||
|
||||
(out && h.value() == proc.getStdout().value()) ||
|
||||
(err && h.value() == proc.getStderr().value())) {
|
||||
continue;
|
||||
}
|
||||
preExistingHandles.push_back(h);
|
||||
}
|
||||
ObjectSnap snap;
|
||||
auto checkNonReuse = [&](RemoteHandle h) {
|
||||
// The new Unbound console objects should not be inherited from
|
||||
// anywhere else -- they should be brand new objects.
|
||||
for (auto other : nonReuseCheck) {
|
||||
// The Unbound console objects that were just opened should not be
|
||||
// inherited from anywhere else -- they should be brand new objects.
|
||||
for (auto other : preExistingHandles) {
|
||||
CHECK(!snap.eq(h, other));
|
||||
}
|
||||
};
|
||||
|
||||
if (in) {
|
||||
CHECK(isUsableConsoleInputHandle(proc.getStdin()));
|
||||
CHECK(isUnboundConsoleObject(proc.getStdin()));
|
||||
|
@ -78,5 +78,4 @@ bool isUsableConsoleInputHandle(RemoteHandle h);
|
||||
bool isUsableConsoleOutputHandle(RemoteHandle h);
|
||||
bool isUnboundConsoleObject(RemoteHandle h);
|
||||
void checkModernConsoleHandleInit(RemoteWorker &proc,
|
||||
bool in, bool out, bool err,
|
||||
std::vector<RemoteHandle> nonReuseCheck);
|
||||
bool in, bool out, bool err);
|
||||
|
Loading…
Reference in New Issue
Block a user