mirror of
https://github.com/pion/stun.git
synced 2025-09-26 20:01:18 +08:00
136 lines
3.9 KiB
Go
136 lines
3.9 KiB
Go
// SPDX-FileCopyrightText: 2023 The Pion community <https://pion.ly>
|
|
// SPDX-License-Identifier: MIT
|
|
|
|
package stun
|
|
|
|
import (
|
|
"errors"
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/stretchr/testify/assert"
|
|
)
|
|
|
|
func TestAgent_ProcessInTransaction(t *testing.T) {
|
|
msg := New()
|
|
agent := NewAgent(func(e Event) {
|
|
assert.NoError(t, e.Error, "got error")
|
|
assert.True(t, e.Message.Equal(msg), "%s (got) != %s (expected)", e.Message, msg)
|
|
})
|
|
assert.NoError(t, msg.NewTransactionID())
|
|
assert.NoError(t, agent.Start(msg.TransactionID, time.Time{}))
|
|
assert.NoError(t, agent.Process(msg))
|
|
assert.NoError(t, agent.Close())
|
|
}
|
|
|
|
func TestAgent_Process(t *testing.T) {
|
|
msg := New()
|
|
agent := NewAgent(func(e Event) {
|
|
assert.NoError(t, e.Error, "got error")
|
|
assert.True(t, e.Message.Equal(msg), "%s (got) != %s (expected)", e.Message, msg)
|
|
})
|
|
assert.NoError(t, msg.NewTransactionID())
|
|
assert.NoError(t, agent.Process(msg))
|
|
assert.NoError(t, agent.Close())
|
|
assert.ErrorIs(t, agent.Process(msg), ErrAgentClosed)
|
|
}
|
|
|
|
func TestAgent_Start(t *testing.T) {
|
|
agent := NewAgent(nil)
|
|
id := NewTransactionID()
|
|
deadline := time.Now().AddDate(0, 0, 1)
|
|
assert.NoError(t, agent.Start(id, deadline), "failed to start transaction")
|
|
assert.ErrorIs(t, agent.Start(id, deadline), ErrTransactionExists)
|
|
assert.NoError(t, agent.Close())
|
|
id = NewTransactionID()
|
|
assert.ErrorIs(t, agent.Start(id, deadline), ErrAgentClosed)
|
|
assert.ErrorIs(t, agent.SetHandler(nil), ErrAgentClosed)
|
|
}
|
|
|
|
func TestAgent_Stop(t *testing.T) {
|
|
called := make(chan Event, 1)
|
|
agent := NewAgent(func(e Event) {
|
|
called <- e
|
|
})
|
|
assert.ErrorIs(t, agent.Stop(transactionID{}), ErrTransactionNotExists)
|
|
id := NewTransactionID()
|
|
timeout := time.Millisecond * 200
|
|
assert.NoError(t, agent.Start(id, time.Now().Add(timeout)))
|
|
assert.NoError(t, agent.Stop(id))
|
|
select {
|
|
case e := <-called:
|
|
assert.ErrorIs(t, e.Error, ErrTransactionStopped)
|
|
case <-time.After(timeout * 2):
|
|
assert.Fail(t, "timed out")
|
|
}
|
|
assert.NoError(t, agent.Close())
|
|
assert.ErrorIs(t, agent.Close(), ErrAgentClosed)
|
|
assert.ErrorIs(t, agent.Stop(transactionID{}), ErrAgentClosed)
|
|
}
|
|
|
|
func TestAgent_GC(t *testing.T) { //nolint:cyclop
|
|
agent := NewAgent(nil)
|
|
shouldTimeOutID := make(map[transactionID]bool)
|
|
deadline := time.Date(2027, time.November, 21,
|
|
23, 0, 0, 0,
|
|
time.UTC,
|
|
)
|
|
gcDeadline := deadline.Add(-time.Second)
|
|
deadlineNotGC := gcDeadline.AddDate(0, 0, -1)
|
|
agent.SetHandler(func(e Event) { //nolint:errcheck,gosec
|
|
id := e.TransactionID
|
|
shouldTimeOut, found := shouldTimeOutID[id]
|
|
assert.True(t, found, "unexpected transaction ID")
|
|
if shouldTimeOut {
|
|
assert.ErrorIs(t, e.Error, ErrTransactionTimeOut, "%x should time out", id)
|
|
} else {
|
|
assert.False(t, errors.Is(e.Error, ErrTransactionTimeOut), "%x should not time out", id)
|
|
}
|
|
})
|
|
for i := 0; i < 5; i++ {
|
|
id := NewTransactionID()
|
|
shouldTimeOutID[id] = false
|
|
assert.NoError(t, agent.Start(id, deadline))
|
|
}
|
|
for i := 0; i < 5; i++ {
|
|
id := NewTransactionID()
|
|
shouldTimeOutID[id] = true
|
|
assert.NoError(t, agent.Start(id, deadlineNotGC))
|
|
}
|
|
assert.NoError(t, agent.Collect(gcDeadline))
|
|
assert.NoError(t, agent.Close())
|
|
assert.ErrorIs(t, agent.Collect(gcDeadline), ErrAgentClosed)
|
|
}
|
|
|
|
func BenchmarkAgent_GC(b *testing.B) {
|
|
agent := NewAgent(nil)
|
|
deadline := time.Now().AddDate(0, 0, 1)
|
|
for i := 0; i < agentCollectCap; i++ {
|
|
assert.NoError(b, agent.Start(NewTransactionID(), deadline))
|
|
}
|
|
defer func() {
|
|
assert.NoError(b, agent.Close())
|
|
}()
|
|
b.ReportAllocs()
|
|
gcDeadline := deadline.Add(-time.Second)
|
|
for i := 0; i < b.N; i++ {
|
|
assert.NoError(b, agent.Collect(gcDeadline))
|
|
}
|
|
}
|
|
|
|
func BenchmarkAgent_Process(b *testing.B) {
|
|
agent := NewAgent(nil)
|
|
deadline := time.Now().AddDate(0, 0, 1)
|
|
for i := 0; i < 1000; i++ {
|
|
assert.NoError(b, agent.Start(NewTransactionID(), deadline))
|
|
}
|
|
defer func() {
|
|
assert.NoError(b, agent.Close())
|
|
}()
|
|
b.ReportAllocs()
|
|
m := MustBuild(TransactionID)
|
|
for i := 0; i < b.N; i++ {
|
|
assert.NoError(b, agent.Process(m))
|
|
}
|
|
}
|