begin adding httphi tests

This commit is contained in:
Patricio Whittingslow
2026-07-25 19:46:42 -03:00
parent 7b17218f26
commit c25bedcb2a
2 changed files with 129 additions and 2 deletions
+2 -2
View File
@@ -41,7 +41,7 @@ type job struct {
}
type Mux interface {
Handler(get Method, uri []byte) HandlerFunc
LookupHandler(get Method, uri []byte) HandlerFunc
}
type RouterConfig struct {
@@ -196,7 +196,7 @@ func (r *Router) goroHandle(exch *Exchange, backoff lneto.BackoffStrategy, mux M
// Mux URI.
uri := reqhdr.RequestURI()
meth := reqhdr.Method()
handler := mux.Handler(MethodFromBytes(meth), uri)
handler := mux.LookupHandler(MethodFromBytes(meth), uri)
if handler != nil {
handler(exch)
}
+127
View File
@@ -0,0 +1,127 @@
package httphi
import (
"bytes"
"context"
"io"
"net"
"strings"
"testing"
"time"
"github.com/soypat/lneto"
"github.com/soypat/lneto/internal"
)
type rwconn struct {
readable bytes.Buffer
written bytes.Buffer
closed bool
deadline time.Time
}
func (r *rwconn) Close() error {
r.closed = true
return nil
}
func (r *rwconn) Read(b []byte) (int, error) {
if r.closed {
return 0, net.ErrClosed
} else if r.deadlineExceeded() {
return 0, context.DeadlineExceeded
}
return r.readable.Read(b)
}
func (r *rwconn) Write(b []byte) (int, error) {
if r.closed {
return 0, net.ErrClosed
} else if r.deadlineExceeded() {
return 0, context.DeadlineExceeded
}
return r.written.Write(b)
}
func (r *rwconn) deadlineExceeded() bool {
return !r.deadline.IsZero() && time.Since(r.deadline) > 0
}
func (r *rwconn) AddReadable(b []byte) { r.readable.Write(b) }
func (r *rwconn) ViewWritten() []byte { return r.written.Bytes() }
var _ Mux = (*sliceMux)(nil)
type sliceMux struct {
_handlers []struct {
method Method
uri string
handler HandlerFunc
}
}
func (sm *sliceMux) LookupHandler(method Method, uri []byte) HandlerFunc {
for _, endpoint := range sm._handlers {
if endpoint.method != MethUndefined && endpoint.method != method {
continue
}
// Method matches.
if b2s(uri) == endpoint.uri {
return endpoint.handler
}
}
return nil
}
func (sm *sliceMux) Handle(reg string, handler HandlerFunc) {
v := internal.SliceReclaim(&sm._handlers)
method := MethUndefined
methodOrURL, url, methodFound := strings.Cut(reg, " ")
if methodFound {
method = MethodFromBytes([]byte(methodOrURL))
} else {
url = methodOrURL
}
v.method = method
v.uri = url
v.handler = handler
}
func configSynchronousRouter(t *testing.T, router *Router, bufferSize int, mux Mux) {
err := router.Configure(RouterConfig{
FixedNumGoroutines: -1,
Mux: mux,
RequestBufferSize: bufferSize,
ResponseMinBufferSize: bufferSize,
Backoff: func(consecutiveBackoffs uint) (sleepOrFlag time.Duration) {
return lneto.BackoffFlagNop
},
})
if err != nil {
t.Fatal(err)
}
}
func TestRouterGet(t *testing.T) {
const bufferSize = 1024
const expectResponse = "its time"
var (
sm sliceMux
router Router
conn rwconn
)
conn.deadline = time.Now().Add(10 * time.Millisecond) // TODO: remove after tests run without blocking forever.
sm.Handle("GET /", staticPage(t, expectResponse))
configSynchronousRouter(t, &router, bufferSize, &sm)
err := router.Handle(&conn)
if err != nil {
t.Fatal(err)
}
}
func staticPage(t *testing.T, page string) HandlerFunc {
return func(ex *Exchange) {
n, err := io.WriteString(ex, page)
if err != nil {
t.Fatal(err)
} else if n != len(page) {
t.Fatal("expected written ", len(page), "got", n)
}
}
}