Compare commits
1
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
42cd423e39 |
+4
-4
@@ -24,8 +24,8 @@ RUN --mount=type=cache,target=/root/.cache/go-build \
|
|||||||
# image ships and the alpine one does not. -count=1 because the mounted
|
# image ships and the alpine one does not. -count=1 because the mounted
|
||||||
# cache also holds test results, which go test would otherwise replay.
|
# cache also holds test results, which go test would otherwise replay.
|
||||||
# -short skips the live RIS Live feed test, so the suite needs no network.
|
# -short skips the live RIS Live feed test, so the suite needs no network.
|
||||||
# golang:1.27.2-bookworm, 2026-10-19
|
# golang:1.24-bookworm, 2026-09-21
|
||||||
FROM golang@sha256:5cf287a799e6b94384bad13d16b14904c531f51ba65792237e122ce42b392f61 AS test
|
FROM golang@sha256:1a6d4452c65dea36aac2e2d606b01b4a029ec90cc1ae53890540ce6173ea77ac AS test
|
||||||
WORKDIR /src
|
WORKDIR /src
|
||||||
COPY go.mod go.sum ./
|
COPY go.mod go.sum ./
|
||||||
RUN go mod download
|
RUN go mod download
|
||||||
@@ -39,8 +39,8 @@ RUN --mount=type=cache,target=/root/.cache/go-build \
|
|||||||
# Build stage. Nothing is wanted from either phase above; the copies
|
# Build stage. Nothing is wanted from either phase above; the copies
|
||||||
# are what make BuildKit build them first, so nothing after them can
|
# are what make BuildKit build them first, so nothing after them can
|
||||||
# run unless lint and test passed.
|
# run unless lint and test passed.
|
||||||
# golang:1.27.2-bookworm, 2026-10-19
|
# golang:1.24-bookworm, 2026-09-21
|
||||||
FROM golang@sha256:5cf287a799e6b94384bad13d16b14904c531f51ba65792237e122ce42b392f61 AS builder
|
FROM golang@sha256:1a6d4452c65dea36aac2e2d606b01b4a029ec90cc1ae53890540ce6173ea77ac AS builder
|
||||||
|
|
||||||
# Install build dependencies (zstd for archive, gcc for CGO/sqlite3)
|
# Install build dependencies (zstd for archive, gcc for CGO/sqlite3)
|
||||||
RUN apt-get update && apt-get install -y --no-install-recommends \
|
RUN apt-get update && apt-get install -y --no-install-recommends \
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
module git.eeqj.de/sneak/routewatch
|
module git.eeqj.de/sneak/routewatch
|
||||||
|
|
||||||
go 1.27.1
|
go 1.24.4
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/dustin/go-humanize v1.0.1
|
github.com/dustin/go-humanize v1.0.1
|
||||||
|
|||||||
@@ -564,8 +564,11 @@ func TestBatchWriteDuringCheckpoint(t *testing.T) {
|
|||||||
ctx, cancel := context.WithCancel(context.Background())
|
ctx, cancel := context.WithCancel(context.Background())
|
||||||
|
|
||||||
var wg sync.WaitGroup
|
var wg sync.WaitGroup
|
||||||
|
wg.Add(1)
|
||||||
|
|
||||||
|
go func() {
|
||||||
|
defer wg.Done()
|
||||||
|
|
||||||
wg.Go(func() {
|
|
||||||
for {
|
for {
|
||||||
select {
|
select {
|
||||||
case <-ctx.Done():
|
case <-ctx.Done():
|
||||||
@@ -574,7 +577,7 @@ func TestBatchWriteDuringCheckpoint(t *testing.T) {
|
|||||||
_ = db.Checkpoint(ctx) // errors are the checkpoint's own to absorb
|
_ = db.Checkpoint(ctx) // errors are the checkpoint's own to absorb
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
}()
|
||||||
|
|
||||||
ts := time.Now().UTC()
|
ts := time.Now().UTC()
|
||||||
for i := range contentionIterations {
|
for i := range contentionIterations {
|
||||||
|
|||||||
@@ -597,11 +597,11 @@ func (s *firstPeerDeleteFailsStore) DeleteLiveRoutesOfPeer(
|
|||||||
// after another: a peer's announcement, then its session going down and a new
|
// after another: a peer's announcement, then its session going down and a new
|
||||||
// announcement from the peer, then nothing. The failed delete must be retried
|
// announcement from the peer, then nothing. The failed delete must be retried
|
||||||
// on the next flush, and the announcement the peer sent after the down written
|
// on the next flush, and the announcement the peer sent after the down written
|
||||||
// only after that retry, so it is kept. In the other cases the peer's session
|
// only after that retry, so it is kept. In the second case the peer's session
|
||||||
// goes down again, and the peer announces another prefix, while the delete
|
// goes down again, and the peer announces another prefix, while the delete
|
||||||
// fails or after the flush whose delete failed: the announcement sent between
|
// fails: the announcement sent between the two downs must not be written, and
|
||||||
// the two downs must not be written, and the next flush must delete the peer's
|
// the next flush must delete the peer's routes once, not once for the retry and
|
||||||
// routes once, not once for the retry and once for the down.
|
// once for the down.
|
||||||
func TestPrefixHandlerRetriesAFailedDeleteOfAPeersRoutes(t *testing.T) {
|
func TestPrefixHandlerRetriesAFailedDeleteOfAPeersRoutes(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
@@ -610,42 +610,37 @@ func TestPrefixHandlerRetriesAFailedDeleteOfAPeersRoutes(t *testing.T) {
|
|||||||
afterDown = "198.51.100.0/24"
|
afterDown = "198.51.100.0/24"
|
||||||
afterSecondDown = "203.0.113.0/24"
|
afterSecondDown = "203.0.113.0/24"
|
||||||
maskLength = 24
|
maskLength = 24
|
||||||
// The delete that fails and its retry, which is also the delete for
|
|
||||||
// a second down.
|
|
||||||
wantDeletes = 2
|
|
||||||
)
|
)
|
||||||
|
|
||||||
tests := []struct {
|
tests := []struct {
|
||||||
name string
|
name string
|
||||||
// Handled while the delete fails, if not nil.
|
// Handled while the delete fails, if not nil.
|
||||||
whileFailing []*ristypes.RISMessage
|
whileFailing []*ristypes.RISMessage
|
||||||
// Handled after the flush whose delete fails, if not nil.
|
wantDeletes int
|
||||||
afterFailing []*ristypes.RISMessage
|
|
||||||
// The peers left with a live route for each prefix.
|
// The peers left with a live route for each prefix.
|
||||||
wantPeers map[string][]string
|
wantPeers map[string][]string
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
name: "the delete fails once",
|
name: "the delete fails once",
|
||||||
|
wantDeletes: 2,
|
||||||
wantPeers: map[string][]string{
|
wantPeers: map[string][]string{
|
||||||
beforeDown: nil, afterDown: {testPeerIP}, afterSecondDown: nil,
|
beforeDown: nil,
|
||||||
|
afterDown: {testPeerIP},
|
||||||
|
afterSecondDown: nil,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "the session goes down again while the delete fails",
|
name: "the session goes down again while the delete fails",
|
||||||
whileFailing: []*ristypes.RISMessage{
|
whileFailing: []*ristypes.RISMessage{
|
||||||
sessionDown(), peerAnnouncement(testPeerIP, afterSecondDown),
|
sessionDown(),
|
||||||
|
peerAnnouncement(testPeerIP, afterSecondDown),
|
||||||
},
|
},
|
||||||
|
// One retry, which is also the delete for the second down.
|
||||||
|
wantDeletes: 2,
|
||||||
wantPeers: map[string][]string{
|
wantPeers: map[string][]string{
|
||||||
beforeDown: nil, afterDown: nil, afterSecondDown: {testPeerIP},
|
beforeDown: nil,
|
||||||
},
|
afterDown: nil,
|
||||||
},
|
afterSecondDown: {testPeerIP},
|
||||||
{
|
|
||||||
name: "the session goes down again after the delete failed",
|
|
||||||
afterFailing: []*ristypes.RISMessage{
|
|
||||||
sessionDown(), peerAnnouncement(testPeerIP, afterSecondDown),
|
|
||||||
},
|
|
||||||
wantPeers: map[string][]string{
|
|
||||||
beforeDown: nil, afterDown: nil, afterSecondDown: {testPeerIP},
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
@@ -671,16 +666,11 @@ func TestPrefixHandlerRetriesAFailedDeleteOfAPeersRoutes(t *testing.T) {
|
|||||||
h.HandleMessage(sessionDown())
|
h.HandleMessage(sessionDown())
|
||||||
h.HandleMessage(peerAnnouncement(testPeerIP, afterDown))
|
h.HandleMessage(peerAnnouncement(testPeerIP, afterDown))
|
||||||
h.flushBatch() // the delete fails
|
h.flushBatch() // the delete fails
|
||||||
|
|
||||||
for _, msg := range tt.afterFailing {
|
|
||||||
h.HandleMessage(msg)
|
|
||||||
}
|
|
||||||
|
|
||||||
h.flushBatch()
|
h.flushBatch()
|
||||||
|
|
||||||
if store.deletes != wantDeletes {
|
if store.deletes != tt.wantDeletes {
|
||||||
t.Errorf("the store was asked for %d deletes of the peer's "+
|
t.Errorf("the store was asked for %d deletes of the peer's "+
|
||||||
"routes, want %d", store.deletes, wantDeletes)
|
"routes, want %d", store.deletes, tt.wantDeletes)
|
||||||
}
|
}
|
||||||
|
|
||||||
assertPeers(t, db, tt.wantPeers)
|
assertPeers(t, db, tt.wantPeers)
|
||||||
|
|||||||
Reference in New Issue
Block a user