@@ -130,6 +130,43 @@ TEST_F(ClockTrackerTest, ClockDomainConversions) {
130130 static_cast <int64_t >(100000 - 1000 + 1e6 ));
131131}
132132
133+ // Merging independent traces from a remote machine deduplicates them onto one
134+ // machine: the first is the primary, the rest are non-primary. A non-primary
135+ // trace isolates its builtin clocks onto its own file tag so its snapshots
136+ // cannot corrupt the others' conversions. But a remote machine's only route to
137+ // trace time is the cross-machine REALTIME rendezvous (its BOOTTIME belongs to
138+ // a different machine), so a remote non-primary trace's REALTIME must stay on
139+ // the machine-canonical tag to join that rendezvous. Otherwise every one of its
140+ // events is dropped (clock_sync_failure_no_path).
141+ TEST_F (ClockTrackerTest, RemoteNonPrimaryFileResolvesThroughSharedRealtime) {
142+ // Host machine (trace time == its BOOTTIME): relate REALTIME to BOOTTIME so
143+ // the cross-machine REALTIME rendezvous can reach trace time.
144+ ct_->AddSnapshot ({{REALTIME , 1000 }, {BOOTTIME , 1000 }});
145+
146+ // Remote machine, primary trace: its own REALTIME<->BOOTTIME plus the
147+ // deferred BOOTTIME->trace-time sync the remote reader registers. This builds
148+ // the REALTIME(remote)<->REALTIME(host) rendezvous.
149+ auto remote_primary = MakeRemoteTracker (/* raw_machine_id=*/ 1 );
150+ remote_primary->AddSnapshot ({{REALTIME , 2000 }, {BOOTTIME , 200000 }});
151+ remote_primary->AddDeferredClockSync (BOOTTIME );
152+ ASSERT_TRUE (remote_primary->ToTraceTime (BOOTTIME , 200000 ).has_value ());
153+
154+ // Remote machine, non-primary trace: a distinct file id but the SAME machine
155+ // as remote_primary (reuse its machine_tracker; a real merge dedups files
156+ // with the same raw machine id onto one machine row). Only its own
157+ // REALTIME<->BOOTTIME. Its REALTIME must join the shared machine-canonical
158+ // REALTIME to reach trace time via the rendezvous.
159+ context_.trace_state =
160+ TraceProcessorContextPtr<TraceProcessorContext::TraceState>::MakeRoot (
161+ TraceProcessorContext::TraceState{TraceId (9 )});
162+ ClockTracker remote_np (&context_, primary_sync_.get (), /* is_primary=*/ false );
163+ remote_np.AddSnapshot ({{REALTIME , 3000 }, {BOOTTIME , 300000 }});
164+
165+ // A BOOTTIME event on the non-primary trace reaches trace time only because
166+ // its REALTIME is the shared machine-canonical node feeding the rendezvous.
167+ EXPECT_TRUE (remote_np.ToTraceTime (BOOTTIME , 300000 ).has_value ());
168+ }
169+
133170// When a clock moves backwards conversions *from* that clock are forbidden
134171// but conversions *to* that clock should still work.
135172// Think to the case of REALTIME going backwards from 3AM to 2AM during DST day.
0 commit comments