Commit fa0bd6d7 authored by ale's avatar ale

Add go.mod, update internal dependencies, build on Bullseye

parent 998aa7f1
Pipeline #10500 passed with stages
in 1 minute and 54 seconds
include: "https://git.autistici.org/ai3/build-deb/raw/master/ci-common.yml"
include: "https://git.autistici.org/ai3/build-deb/raw/master/ci-nextstable.yml"
......@@ -2,7 +2,7 @@ Source: auth-server
Section: net
Priority: extra
Maintainer: Autistici/Inventati <debian@autistici.org>
Build-Depends: debhelper (>= 8.0.0), golang-any (>= 1.11), dh-golang, dh-systemd
Build-Depends: debhelper (>= 8.0.0), golang-any (>= 1.11), dh-golang
Standards-Version: 3.9.4
Package: auth-server
......
module git.autistici.org/id/auth
go 1.15
require (
git.autistici.org/ai3/go-common v0.0.0-20210109170950-49f8d26bcc81
git.autistici.org/id/usermetadb v0.0.0-20190209105239-61e5a7b24130
github.com/boombuler/barcode v0.0.0-20170618053812-56ef0af91246 // indirect
github.com/bradfitz/gomemcache v0.0.0-20180710155616-bc664df96737
github.com/cenkalti/backoff v2.2.1+incompatible
github.com/coreos/go-systemd v0.0.0-20191104093116-d3cd4ed1dbcf
github.com/go-ldap/ldap/v3 v3.2.4
github.com/go-sql-driver/mysql v1.4.0
github.com/google/go-cmp v0.5.4
github.com/lib/pq v0.0.0-20190326042056-d6156e141ac6
github.com/mattn/go-sqlite3 v0.0.0-20180926090220-0a88db3545c4
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
github.com/patrickmn/go-cache v0.0.0-20180815053127-5633e0862627
github.com/pierrec/lz4 v2.0.5+incompatible // indirect
github.com/pquerna/otp v1.0.0
github.com/prometheus/client_golang v1.9.0
github.com/theckman/go-flock v0.8.0
github.com/tstranex/u2f v1.0.0
go.opencensus.io v0.22.5
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421 // indirect
golang.org/x/sync v0.0.0-20201207232520-09787c993a3a
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 // indirect
gopkg.in/yaml.v2 v2.3.0
)
This diff is collapsed.
stages:
- test
run_tests:
stage: test
image: "debian:bullseye"
script:
- "apt update"
- "env DEBIAN_FRONTEND=noninteractive apt -y install golang git"
- "go test -v ./..."
package clientutil
import (
"context"
"io"
"log"
"math/rand"
"net"
"net/http"
"net/http/httptest"
"net/url"
"testing"
"time"
)
type tcpHandler interface {
Handle(net.Conn)
}
type tcpHandlerFunc func(net.Conn)
func (f tcpHandlerFunc) Handle(c net.Conn) { f(c) }
// Base TCP server type (to build fake LDAP servers).
type tcpServer struct {
l net.Listener
handler tcpHandler
}
func newTCPServer(t testing.TB, handler tcpHandler) *tcpServer {
l, err := net.Listen("tcp", "localhost:0")
if err != nil {
t.Fatal("Listen():", err)
}
log.Printf("started new tcp server on %s", l.Addr().String())
s := &tcpServer{l: l, handler: handler}
go s.serve()
return s
}
func (s *tcpServer) serve() {
for {
conn, err := s.l.Accept()
if err != nil {
return
}
go func(c net.Conn) {
s.handler.Handle(c)
c.Close()
}(conn)
}
}
func (s *tcpServer) Addr() string {
return s.l.Addr().String()
}
func (s *tcpServer) Close() {
s.l.Close()
}
// A test server that will close all incoming connections right away.
func newConnFailServer(t testing.TB) *tcpServer {
return newTCPServer(t, tcpHandlerFunc(func(c net.Conn) {}))
}
// A test server that will close all connections after a 1s delay.
func newConnFailDelayServer(t testing.TB) *tcpServer {
return newTCPServer(t, tcpHandlerFunc(func(c net.Conn) { time.Sleep(1 * time.Second) }))
}
type httpServer struct {
*httptest.Server
}
func (s *httpServer) Addr() string {
u, _ := url.Parse(s.Server.URL)
return u.Host
}
// An HTTP server that will always return a specific HTTP status using
// http.Error().
func newErrorHTTPServer(statusCode int) *httpServer {
return &httpServer{httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
w.Header().Set("Connection", "close")
http.Error(w, "oh no", statusCode)
}))}
}
func newJSONHTTPServer() *httpServer {
return &httpServer{httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json")
io.WriteString(w, "{\"value\": 42}") // nolint
}))}
}
func newHostCountingJSONHTTPServer() (*httpServer, map[string]int) {
counters := make(map[string]int)
return &httpServer{httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
counters[r.Host]++
w.Header().Set("Content-Type", "application/json")
io.WriteString(w, "{\"value\": 42}") // nolint
}))}, counters
}
type testServer interface {
Addr() string
Close()
}
type testBackends struct {
servers []testServer
addrs []string
}
func newTestBackends(servers ...testServer) *testBackends {
b := new(testBackends)
for _, s := range servers {
b.servers = append(b.servers, s)
b.addrs = append(b.addrs, s.Addr())
}
return b
}
func (b *testBackends) ResolveIP(_ string) []string {
return b.addrs
}
func (b *testBackends) stop(i int) {
b.servers[i].Close()
}
func (b *testBackends) close() {
for _, s := range b.servers {
s.Close()
}
}
// Do a number of fake requests to a test JSONHTTPServer. If shards is
// not nil, set up a fake sharded service and pick one of the given
// shards randomly on every request.
func doJSONRequests(backends *testBackends, u string, n int, shards []string) (int, int) {
b, err := newBalancedBackend(&BackendConfig{
URL: u,
Debug: true,
Sharded: len(shards) > 0,
}, backends)
if err != nil {
panic(err)
}
defer b.Close()
var errs, oks int
for i := 0; i < n; i++ {
ctx, cancel := context.WithTimeout(context.Background(), 500*time.Millisecond)
var resp struct {
Value int `json:"value"`
}
var shard string
if len(shards) > 0 {
shard = shards[rand.Intn(len(shards))]
}
err = b.Call(ctx, shard, "/", struct{}{}, &resp)
cancel()
if err != nil {
errs++
log.Printf("request error: %v", err)
} else if resp.Value != 42 {
errs++
} else {
oks++
}
}
return oks, errs
}
func TestBackend_TargetsDown(t *testing.T) {
b := newTestBackends(newJSONHTTPServer(), newJSONHTTPServer(), newJSONHTTPServer())
defer b.close()
oks, errs := doJSONRequests(b, "http://test/", 10, nil)
if errs > 0 {
t.Fatalf("errs=%d", errs)
}
if oks == 0 {
t.Fatal("oks=0")
}
// Stop the first two backends, request should still succeed.
b.stop(0)
b.stop(1)
oks, errs = doJSONRequests(b, "http://test/", 10, nil)
if errs > 0 {
t.Fatalf("errs=%d", errs)
}
if oks < 10 {
t.Fatalf("oks=%d", oks)
}
}
func TestBackend_OverloadedTargets(t *testing.T) {
b := newTestBackends(newErrorHTTPServer(http.StatusTooManyRequests), newJSONHTTPServer())
defer b.close()
oks, errs := doJSONRequests(b, "http://test/", 10, nil)
if errs > 0 {
t.Fatalf("errs=%d", errs)
}
if oks < 10 {
t.Fatalf("oks=%d", oks)
}
}
func TestBackend_BrokenTarget(t *testing.T) {
b := newTestBackends(newConnFailServer(t), newJSONHTTPServer())
defer b.close()