(t *testing.T)
| 375 | func (r *recordingPush) OnTracerouteHop(string, string, []byte) {} |
| 376 | |
| 377 | func TestUsagePushAck(t *testing.T) { |
| 378 | rp := &recordingPush{failOn: map[uint64]bool{7: true}} |
| 379 | hub := New(Options{PeerExtractor: mdPeerExtractor, PushHandler: rp}) |
| 380 | env := newTestEnv(t, hub) |
| 381 | cc := env.dial(t) |
| 382 | mock := startNodeMock(t, cc, "n") |
| 383 | waitOnline(t, hub, "n") |
| 384 | |
| 385 | mock.pushUsage(1, []byte(`{"a":1}`)) |
| 386 | mock.pushUsage(7, []byte(`{"a":7}`)) // handler 失败 → 不应 ack |
| 387 | mock.pushUsage(2, []byte(`{"a":2}`)) |
| 388 | |
| 389 | // 期望收到 seq=1 和 seq=2 的 ack(顺序不强求) |
| 390 | got := map[uint64]bool{} |
| 391 | deadline := time.After(2 * time.Second) |
| 392 | for len(got) < 2 { |
| 393 | select { |
| 394 | case body := <-mock.acks: |
| 395 | var v struct{ Seq uint64 } |
| 396 | if err := json.Unmarshal(body, &v); err != nil { |
| 397 | t.Fatalf("ack body parse: %v / %s", err, body) |
| 398 | } |
| 399 | got[v.Seq] = true |
| 400 | case <-deadline: |
| 401 | t.Fatalf("timed out waiting for acks; got=%v", got) |
| 402 | } |
| 403 | } |
| 404 | if !got[1] || !got[2] { |
| 405 | t.Fatalf("missing acks; got=%v", got) |
| 406 | } |
| 407 | // seq=7 不应收到 ack;再等一小段确保没多发 |
| 408 | select { |
| 409 | case body := <-mock.acks: |
| 410 | var v struct{ Seq uint64 } |
| 411 | _ = json.Unmarshal(body, &v) |
| 412 | if v.Seq == 7 { |
| 413 | t.Fatalf("unexpected ack for failing seq 7") |
| 414 | } |
| 415 | case <-time.After(150 * time.Millisecond): |
| 416 | // good |
| 417 | } |
| 418 | } |
| 419 | |
| 420 | // 防止 io 未使用警告(部分平台) |
| 421 | var _ = io.EOF |
nothing calls this directly
no test coverage detected