log/slog — validation proof
Go’s own log/slog test suite, converted to C# by go2cs, built against the converted standard
library, run under the Go-semantics test host, and compared verdict for verdict against a clean
go test -json baseline of the same sources. This page is generated by the converter from that
comparison — it is the evidence behind the log/slog row in
Validated Test Packages.
Validated 2026-08-26 · converter 92c6a58b5
194 matched · 19 disclosed — Go 1.23.12, windows/amd64, converted package
src/core/log/slog.
Verdicts
| Test | go test |
go2cs |
|---|---|---|
TestAliasingAndClone |
pass | pass |
TestAlloc |
pass | fail (disclosed) |
TestAlloc/2_pairs |
pass | fail (disclosed) |
TestAlloc/2_pairs_disabled |
pass | pass |
TestAlloc/2_pairs_disabled_inline |
pass | fail (disclosed) |
TestAlloc/9_kvs |
pass | fail (disclosed) |
TestAlloc/Error |
pass | fail (disclosed) |
TestAlloc/Info |
pass | fail (disclosed) |
TestAlloc/attrs1 |
pass | fail (disclosed) |
TestAlloc/attrs3 |
pass | fail (disclosed) |
TestAlloc/attrs3_disabled |
pass | fail (disclosed) |
TestAlloc/attrs6 |
pass | fail (disclosed) |
TestAlloc/attrs9 |
pass | fail (disclosed) |
TestAlloc/logger.Info |
pass | fail (disclosed) |
TestAlloc/logger.Log |
pass | fail (disclosed) |
TestAlloc/pairs |
pass | fail (disclosed) |
TestAnyLevelAlloc |
pass | fail (disclosed) |
TestAnyValue |
pass | pass |
TestAppendJSONValue |
pass | pass |
TestAttrNoAlloc |
pass | fail (disclosed) |
TestAttrs |
pass | pass |
TestCallDepth |
pass | pass |
TestConcurrentWrites |
pass | pass |
TestConcurrentWrites/json |
pass | pass |
TestConcurrentWrites/text |
pass | pass |
TestConnections |
pass | pass |
TestConnections/wrap_default_handler |
pass | pass |
TestContext |
pass | pass |
TestDefaultHandle |
pass | pass |
TestDefaultHandle/attrs |
pass | pass |
TestDefaultHandle/group |
pass | pass |
TestDefaultHandle/groups |
pass | pass |
TestDefaultHandle/no_attrs |
pass | pass |
TestDefaultHandle/preformatted |
pass | pass |
TestDefaultHandle/preformatted_groups |
pass | pass |
TestDefaultHandle/two_with-groups |
pass | pass |
TestEmptyGroup |
pass | pass |
TestHandlerEnabled |
pass | pass |
TestJSONAndTextHandlers |
pass | pass |
TestJSONAndTextHandlers/GroupValue_as_Attr_value |
pass | pass |
TestJSONAndTextHandlers/GroupValue_as_Attr_value/json |
pass | pass |
TestJSONAndTextHandlers/GroupValue_as_Attr_value/text |
pass | pass |
TestJSONAndTextHandlers/LogValuer |
pass | pass |
TestJSONAndTextHandlers/LogValuer/json |
pass | pass |
TestJSONAndTextHandlers/LogValuer/text |
pass | pass |
TestJSONAndTextHandlers/Source |
pass | pass |
TestJSONAndTextHandlers/Source/json |
pass | pass |
TestJSONAndTextHandlers/Source/text |
pass | pass |
TestJSONAndTextHandlers/basic |
pass | pass |
TestJSONAndTextHandlers/basic/json |
pass | pass |
TestJSONAndTextHandlers/basic/text |
pass | pass |
TestJSONAndTextHandlers/byte_slice |
pass | pass |
TestJSONAndTextHandlers/byte_slice/json |
pass | pass |
TestJSONAndTextHandlers/byte_slice/text |
pass | pass |
TestJSONAndTextHandlers/cap_keys |
pass | pass |
TestJSONAndTextHandlers/cap_keys/json |
pass | pass |
TestJSONAndTextHandlers/cap_keys/text |
pass | pass |
TestJSONAndTextHandlers/empty_group |
pass | pass |
TestJSONAndTextHandlers/empty_group/json |
pass | pass |
TestJSONAndTextHandlers/empty_group/text |
pass | pass |
TestJSONAndTextHandlers/empty_key |
pass | pass |
TestJSONAndTextHandlers/empty_key/json |
pass | pass |
TestJSONAndTextHandlers/empty_key/text |
pass | pass |
TestJSONAndTextHandlers/empty_with-groups |
pass | pass |
TestJSONAndTextHandlers/empty_with-groups,_no_non-empty_attrs |
pass | pass |
TestJSONAndTextHandlers/empty_with-groups,_no_non-empty_attrs/json |
pass | pass |
TestJSONAndTextHandlers/empty_with-groups,_no_non-empty_attrs/text |
pass | pass |
TestJSONAndTextHandlers/empty_with-groups/json |
pass | pass |
TestJSONAndTextHandlers/empty_with-groups/text |
pass | pass |
TestJSONAndTextHandlers/escapes |
pass | pass |
TestJSONAndTextHandlers/escapes/json |
pass | pass |
TestJSONAndTextHandlers/escapes/text |
pass | pass |
TestJSONAndTextHandlers/groups |
pass | pass |
TestJSONAndTextHandlers/groups/json |
pass | pass |
TestJSONAndTextHandlers/groups/text |
pass | pass |
TestJSONAndTextHandlers/inline_group |
pass | pass |
TestJSONAndTextHandlers/inline_group/json |
pass | pass |
TestJSONAndTextHandlers/inline_group/text |
pass | pass |
TestJSONAndTextHandlers/json.RawMessage |
pass | pass |
TestJSONAndTextHandlers/json.RawMessage/json |
pass | pass |
TestJSONAndTextHandlers/json.RawMessage/text |
pass | pass |
TestJSONAndTextHandlers/nested_empty_group |
pass | pass |
TestJSONAndTextHandlers/nested_empty_group/json |
pass | pass |
TestJSONAndTextHandlers/nested_empty_group/text |
pass | pass |
TestJSONAndTextHandlers/nested_non-empty_group |
pass | pass |
TestJSONAndTextHandlers/nested_non-empty_group/json |
pass | pass |
TestJSONAndTextHandlers/nested_non-empty_group/text |
pass | pass |
TestJSONAndTextHandlers/one_empty_with-group |
pass | pass |
TestJSONAndTextHandlers/one_empty_with-group/json |
pass | pass |
TestJSONAndTextHandlers/one_empty_with-group/text |
pass | pass |
TestJSONAndTextHandlers/preformatted |
pass | pass |
TestJSONAndTextHandlers/preformatted/json |
pass | pass |
TestJSONAndTextHandlers/preformatted/text |
pass | pass |
TestJSONAndTextHandlers/preformatted_cap_keys |
pass | pass |
TestJSONAndTextHandlers/preformatted_cap_keys/json |
pass | pass |
TestJSONAndTextHandlers/preformatted_cap_keys/text |
pass | pass |
TestJSONAndTextHandlers/preformatted_remove_all |
pass | pass |
TestJSONAndTextHandlers/preformatted_remove_all/json |
pass | pass |
TestJSONAndTextHandlers/preformatted_remove_all/text |
pass | pass |
TestJSONAndTextHandlers/preformatted_remove_built-in |
pass | pass |
TestJSONAndTextHandlers/preformatted_remove_built-in/json |
pass | pass |
TestJSONAndTextHandlers/preformatted_remove_built-in/text |
pass | pass |
TestJSONAndTextHandlers/preformatted_with-groups |
pass | pass |
TestJSONAndTextHandlers/preformatted_with-groups/json |
pass | pass |
TestJSONAndTextHandlers/preformatted_with-groups/text |
pass | pass |
TestJSONAndTextHandlers/remove_all |
pass | pass |
TestJSONAndTextHandlers/remove_all/json |
pass | pass |
TestJSONAndTextHandlers/remove_all/text |
pass | pass |
TestJSONAndTextHandlers/remove_built-in |
pass | pass |
TestJSONAndTextHandlers/remove_built-in/json |
pass | pass |
TestJSONAndTextHandlers/remove_built-in/text |
pass | pass |
TestJSONAndTextHandlers/replace_built-in_with_group |
pass | pass |
TestJSONAndTextHandlers/replace_built-in_with_group/json |
pass | pass |
TestJSONAndTextHandlers/replace_built-in_with_group/text |
pass | pass |
TestJSONAndTextHandlers/replace_empty |
pass | pass |
TestJSONAndTextHandlers/replace_empty/json |
pass | pass |
TestJSONAndTextHandlers/replace_empty/text |
pass | pass |
TestJSONAndTextHandlers/replace_empty_1 |
pass | pass |
TestJSONAndTextHandlers/replace_empty_1/json |
pass | pass |
TestJSONAndTextHandlers/replace_empty_1/text |
pass | pass |
TestJSONAndTextHandlers/replace_empty_2 |
pass | pass |
TestJSONAndTextHandlers/replace_empty_2/json |
pass | pass |
TestJSONAndTextHandlers/replace_empty_2/text |
pass | pass |
TestJSONAndTextHandlers/replace_empty_3 |
pass | pass |
TestJSONAndTextHandlers/replace_empty_3/json |
pass | pass |
TestJSONAndTextHandlers/replace_empty_3/text |
pass | pass |
TestJSONAndTextHandlers/replace_empty_inline |
pass | pass |
TestJSONAndTextHandlers/replace_empty_inline/json |
pass | pass |
TestJSONAndTextHandlers/replace_empty_inline/text |
pass | pass |
TestJSONAndTextHandlers/replace_partial_empty_attrs_1 |
pass | pass |
TestJSONAndTextHandlers/replace_partial_empty_attrs_1/json |
pass | pass |
TestJSONAndTextHandlers/replace_partial_empty_attrs_1/text |
pass | pass |
TestJSONAndTextHandlers/replace_partial_empty_attrs_2 |
pass | pass |
TestJSONAndTextHandlers/replace_partial_empty_attrs_2/json |
pass | pass |
TestJSONAndTextHandlers/replace_partial_empty_attrs_2/text |
pass | pass |
TestJSONAndTextHandlers/replace_partial_empty_attrs_3 |
pass | pass |
TestJSONAndTextHandlers/replace_partial_empty_attrs_3/json |
pass | pass |
TestJSONAndTextHandlers/replace_partial_empty_attrs_3/text |
pass | pass |
TestJSONAndTextHandlers/replace_resolved_group |
pass | pass |
TestJSONAndTextHandlers/replace_resolved_group/json |
pass | pass |
TestJSONAndTextHandlers/replace_resolved_group/text |
pass | pass |
TestJSONAndTextHandlers/resolve |
pass | pass |
TestJSONAndTextHandlers/resolve/json |
pass | pass |
TestJSONAndTextHandlers/resolve/text |
pass | pass |
TestJSONAndTextHandlers/two_with-groups |
pass | pass |
TestJSONAndTextHandlers/two_with-groups/json |
pass | pass |
TestJSONAndTextHandlers/two_with-groups/text |
pass | pass |
TestJSONAndTextHandlers/with-group |
pass | pass |
TestJSONAndTextHandlers/with-group/json |
pass | pass |
TestJSONAndTextHandlers/with-group/text |
pass | pass |
TestJSONAppendAttrValueSpecial |
pass | pass |
TestJSONHandler |
pass | pass |
TestJSONHandler/none |
pass | pass |
TestJSONHandler/replace |
pass | pass |
TestKindString |
pass | pass |
TestLevelFlag |
pass | pass |
TestLevelMarshalJSON |
pass | pass |
TestLevelMarshalText |
pass | pass |
TestLevelParse |
pass | pass |
TestLevelParseError |
pass | pass |
TestLevelString |
pass | pass |
TestLevelVar |
pass | pass |
TestLevelVarFlag |
pass | pass |
TestLevelVarMarshalText |
pass | pass |
TestLevelVarString |
pass | pass |
TestLogLoggerLevelForDefaultHandler |
pass | pass |
TestLogLoggerLevelForHandlerWriter |
pass | pass |
TestLogTextHandler |
pass | pass |
TestLogValue |
pass | pass |
TestLoggerError |
pass | pass |
TestLoggerNoOps |
pass | pass |
TestNeedsQuoting |
pass | pass |
TestNewLogLogger |
pass | pass |
TestPanics |
pass | pass |
TestRecordAttrs |
pass | pass |
TestRecordSource |
pass | fail (disclosed) |
TestReplaceAttrGroups |
pass | pass |
TestSecondWith |
pass | pass |
TestSetAttrs |
pass | pass |
TestSetDefault |
pass | pass |
TestSlogtest |
pass | pass |
TestSlogtest/JSON |
pass | pass |
TestSlogtest/Text |
pass | pass |
TestTextHandler |
pass | pass |
TestTextHandler/String_method |
pass | pass |
TestTextHandler/String_method/none |
pass | pass |
TestTextHandler/String_method/replace |
pass | pass |
TestTextHandler/TextMarshaler |
pass | pass |
TestTextHandler/TextMarshaler/none |
pass | pass |
TestTextHandler/TextMarshaler/replace |
pass | pass |
TestTextHandler/TextMarshaler_error |
pass | pass |
TestTextHandler/TextMarshaler_error/none |
pass | pass |
TestTextHandler/TextMarshaler_error/replace |
pass | pass |
TestTextHandler/nil_value |
pass | pass |
TestTextHandler/nil_value/none |
pass | pass |
TestTextHandler/nil_value/replace |
pass | pass |
TestTextHandler/quoted |
pass | pass |
TestTextHandler/quoted/none |
pass | pass |
TestTextHandler/quoted/replace |
pass | pass |
TestTextHandler/struct |
pass | pass |
TestTextHandler/struct/none |
pass | pass |
TestTextHandler/struct/replace |
pass | pass |
TestTextHandler/unquoted |
pass | pass |
TestTextHandler/unquoted/none |
pass | pass |
TestTextHandler/unquoted/replace |
pass | pass |
TestTextHandlerAlloc |
pass | fail (disclosed) |
TestTextHandlerPreformatted |
pass | pass |
TestValueAny |
pass | pass |
TestValueEqual |
pass | pass |
TestValueNoAlloc |
pass | fail (disclosed) |
TestValueString |
pass | pass |
TestValueTime |
pass | pass |
TestWriteTimeRFC3339 |
pass | pass |
Disclosed divergences
A disclosed divergence is a specific Go assertion the managed CLR provably cannot satisfy — not
a skipped test and not a tolerance. Each one is pinned by exact failure signature in the package’s
hand-owned go2cs_test_disclosures.json;
a disclosed test that fails any other way is still a hard mismatch.
| Test | Class | Pinned reason |
|---|---|---|
TestAlloc |
aggregate |
no failure text of its own — the roll-up of this test’s disclosed subtests |
TestAlloc/2_pairs |
alloc-profile |
wantAllocs assert with a NONZERO Go budget (2): the managed model pays a heap shell per boxed pair on top of Go’s two budgeted allocations, so the divergence is the shell count rather than the assert’s premise |
TestAlloc/2_pairs_disabled_inline |
alloc-profile |
wantAllocs assert with a nonzero Go budget: even on the level-disabled path the ...any arguments are boxed before the level check can discard them, where Go’s interface values cost nothing to form |
TestAlloc/9_kvs |
alloc-profile |
wantAllocs assert with a nonzero Go budget (10): nine key/value pairs box into nine heap shells above Go’s budgeted slice growth |
TestAlloc/Error |
alloc-profile |
wantAllocs assert: same ...any boxing as TestAlloc/Info on the Error level path — one heap shell per argument where Go’s interface value allocates nothing |
TestAlloc/Info |
alloc-profile |
wantAllocs assert: the variadic ...any argument list boxes each value into a heap shell where Go’s interface value is two words carrying the data pointer inline (DESIGN-iface-shell-caching §2 — ‘C# has no two-word interface value; the shell IS the itab+data fused into an object’) |
TestAlloc/attrs1 |
alloc-profile |
wantAllocs assert: constructing one Attr materializes a boxed Value in the managed model where Go’s Value packs the payload into its own struct fields |
TestAlloc/attrs3 |
alloc-profile |
wantAllocs assert: three Attrs, each carrying a boxed Value shell that Go’s packed Value representation does not allocate |
TestAlloc/attrs3_disabled |
alloc-profile |
wantAllocs assert: the Attrs are constructed — and therefore boxed — before the level check discards them, so the level-disabled path allocates in the managed model exactly as the enabled one does |
TestAlloc/attrs6 |
alloc-profile |
wantAllocs assert with a nonzero Go budget (1): six Attrs box six Values above Go’s single budgeted allocation |
TestAlloc/attrs9 |
alloc-profile |
wantAllocs assert with a nonzero Go budget (1): nine Attrs box nine Values above Go’s single budgeted allocation |
TestAlloc/logger.Info |
alloc-profile |
wantAllocs assert: the Logger.Info convenience path boxes its ...any arguments into heap shells where Go passes two-word interface values |
TestAlloc/logger.Log |
alloc-profile |
wantAllocs assert: the Logger.Log path boxes its ...any arguments into heap shells where Go passes two-word interface values |
TestAlloc/pairs |
alloc-profile |
wantAllocs assert: each key/value pair boxes through any into a heap shell; Go’s escape analysis keeps the equivalent interface values off the heap entirely |
TestAnyLevelAlloc |
alloc-profile |
wantAllocs assert: passing a Level through any boxes the value type into a heap shell, which is precisely the allocation Go’s two-word interface value avoids |
TestAttrNoAlloc |
alloc-profile |
want-zero AllocsPerRun assert: each Attr constructor boxes its payload into a Value shell in the managed model, where Go’s Value stores the payload inline in the struct and allocates nothing |
TestRecordSource |
host-identity |
the depth-2 sub-case asserts that two frames above the test function sits testing.tRunner in testing.go — Go’s own test binary, whose testing package is compiled from that source. The converted host is the hand-owned structural replacement (F15b): its runner lives in go.testing_runtime, so it is not a converted-Go frame at all and never enters the projected traceback, and it carries no position-map record, so its file half could only ever be .cs. Passing would require the host to claim testing/testing.go, which the standing position-map ruling forbids. The depth-1 sub-case of this SAME test asserts log/slog.TestRecordSource and passes — that was the internal-test-variant caller-info defect, fixed 2026-08-26 rather than disclosed, which is what fixes this class’s boundary: only the host’s own frame is disclosed here |
TestTextHandlerAlloc |
alloc-profile |
wantAllocs assert: TextHandler.Handle formats through boxed Values and an interface-typed Handler, so the append-only formatting path Go performs allocation-free pays one heap shell per attribute here |
TestValueNoAlloc |
alloc-profile |
want-zero AllocsPerRun assert: every Value constructor boxes through any into a heap shell, the direct managed counterpart of Go’s inline-payload Value (DESIGN-iface-shell-caching §2 — the shell IS the interface value, and nothing short of IDynamicInterfaceCastable removes it) |
Excluded declarations
Declarations filtered from both sides of the comparison, and therefore not claimed above:
Benchmark, Fuzz and Example declarations the converted host does not execute, plus any
test requiring a capability the managed runtime does not provide — a testing member the host
has not implemented, or a platform behavior it provably cannot reproduce. Each is named with
the capability it needs.
- BenchmarkAttrString (benchmark): benchmark execution is deferred to Phase 4D
- BenchmarkDispatch (benchmark): benchmark execution is deferred to Phase 4D
- BenchmarkJSONEncoding (benchmark): benchmark execution is deferred to Phase 4D
- BenchmarkJSONHandler (benchmark): benchmark execution is deferred to Phase 4D
- BenchmarkNopLog (benchmark): benchmark execution is deferred to Phase 4D
- BenchmarkPC (benchmark): benchmark execution is deferred to Phase 4D
- BenchmarkPreformatting (benchmark): benchmark execution is deferred to Phase 4D
- BenchmarkRecord (benchmark): benchmark execution is deferred to Phase 4D
- BenchmarkUnsafeStrings (benchmark): benchmark execution is deferred to Phase 4D
- BenchmarkWriteTime (benchmark): benchmark execution is deferred to Phase 4D
- ExampleGroup (example): example execution is deferred to Phase 4D
- ExampleHandlerOptions_customLevels (example): example execution is deferred to Phase 4D
- ExampleHandler_levelHandler (example): example execution is deferred to Phase 4D
- ExampleLogValuer_group (example): example execution is deferred to Phase 4D
- ExampleLogValuer_secret (example): example execution is deferred to Phase 4D
- ExampleSetLogLoggerLevel_log (example): example execution is deferred to Phase 4D
- ExampleSetLogLoggerLevel_slog (example): example execution is deferred to Phase 4D
- Example_wrapping (example): example execution is deferred to Phase 4D