Skip to content
quarry Artifact [421d5a4a9a]
Login

Artifact [421d5a4a9a]

Artifact 421d5a4a9a365d6e0344732202dfe6028a16af62f049f2cab63c4619779cad3a:


package oltp

import (
	"testing"
	"time"
)

// "Did my hook fire?" is answered by recording what happened, not only
// what failed: a log holding only failures cannot say "it worked".
func TestDeliveriesRecordSuccessAndFailureAlike(t *testing.T) {
	d := excDB(t)
	for _, rec := range []Delivery{
		{Sub: 1, Repo: "alpha", Event: "e1", Kind: "checkin", Status: 200, Ms: 42, Attempt: 1, Body: `{"id":"e1"}`},
		{Sub: 1, Repo: "alpha", Event: "e2", Kind: "ticket", Status: 500, Ms: 91, Attempt: 2, Err: "endpoint answered 500"},
		{Sub: 1, Repo: "alpha", Event: "e3", Kind: "checkin", Status: 0, Ms: 5000, Attempt: 3, Err: "dial tcp: timeout"},
		{Sub: 2, Repo: "alpha", Event: "e4", Kind: "checkin", Status: 200, Ms: 7, Attempt: 1},
	} {
		d.RecordDelivery(rec)
	}

	got, err := d.Deliveries(1, 10)
	if err != nil || len(got) != 3 {
		t.Fatalf("%d rows err %v — one endpoint's attempts only", len(got), err)
	}
	// Newest first: the question is what happened LAST.
	if got[0].Event != "e3" {
		t.Errorf("order starts at %q", got[0].Event)
	}
	if !got[2].OK() || got[1].OK() || got[0].OK() {
		t.Error("acceptance is not read from the status")
	}
	// A request that never completed is not a status of zero meaning
	// success — it is the absence of an answer, and the error says so.
	if got[0].Status != 0 || got[0].Err == "" {
		t.Errorf("a failed connection recorded as %+v", got[0])
	}

	// The body is kept so a redelivery replays the exact bytes that
	// produced the signature an endpoint rejected.
	one, ok := d.DeliveryByID(got[2].ID)
	if !ok || one.Body != `{"id":"e1"}` {
		t.Errorf("the sent bytes were not kept: %+v", one)
	}

	// Another endpoint's attempts are its own.
	if two, _ := d.Deliveries(2, 10); len(two) != 1 {
		t.Errorf("endpoint 2 has %d attempts", len(two))
	}

	// An oversized body is clipped rather than refused: a delivery log
	// that drops rows to protect itself defeats its own purpose.
	big := make([]byte, deliveryBodyMax+500)
	for i := range big {
		big[i] = 'x'
	}
	d.RecordDelivery(Delivery{Sub: 3, Repo: "alpha", Event: "big", Kind: "k",
		At: time.Now().UTC().Format(time.RFC3339Nano), Body: string(big)})
	rows, _ := d.Deliveries(3, 10)
	if len(rows) != 1 || len(rows[0].Body) != deliveryBodyMax {
		t.Errorf("oversized body handling: %d rows", len(rows))
	}
}