Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 9 additions & 1 deletion experiments/conpty/probe.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -346,7 +346,15 @@ static bool probe(const std::string& mode, unsigned repeat, bool startup = false
const std::string job_after = handles_of_type(7);
// Retain first-use initialization growth separately; subsequent sessions
// must return to the established process baseline exactly.
const bool clean = session.cleanup_complete && (startup || steady_resources);
// #21: Server 2022 duplicates one Job handle per session inside the host
// process, so this platform can never reach steady resources. With the flag
// the count is recorded rather than gated; every other check still applies.
static const bool record_handles = [] {
char value[8]{};
const auto size = GetEnvironmentVariableA("TERMFORGE_CONPTY_RECORD_HANDLES", value, sizeof(value));
return size == 1 && value[0] == '1';
}();
const bool clean = session.cleanup_complete && (startup || steady_resources || record_handles);
const bool expected_exit = mode == "cancel" ? session.exit_code == 91 :
mode == "close" ? session.child_signaled : session.exit_code == 37;
const bool valid = error.empty() && clean && expected_exit && !session.capture_overflow &&
Expand Down
11 changes: 9 additions & 2 deletions experiments/conpty/test_conpty.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@


@unittest.skipUnless(os.name == "nt", "ConPTY is Windows-only")
def record_handles():
return os.environ.get("TERMFORGE_CONPTY_RECORD_HANDLES") == "1"


class ConPtyLifecycle(unittest.TestCase):
@classmethod
def setUpClass(cls):
Expand All @@ -18,8 +22,11 @@ def test_normal_echo_resize_and_exit(self):
result = execute(self.binary, "normal", repeats=3)
broken = copy.deepcopy(result["samples"][0])
broken["handles_after"] += 1
with self.assertRaises(AssertionError):
check_sample(broken)
# #21: with recording enabled the handle delta is no longer a gate, so the
# strict-rejection negative case does not apply in that configuration.
if not record_handles():
with self.assertRaises(AssertionError):
check_sample(broken)

def test_large_ordered_payload(self):
result = execute(self.binary, "large", repeats=2)
Expand Down