@@ -2,10 +2,14 @@ package server
22
33import (
44 "context"
5+ "io"
6+ "net"
57 "net/http"
68 "strings"
79 "testing"
10+ "time"
811
12+ "github.com/distribution/distribution/v3/configuration"
913 // Register the filesystem storage driver for the distribution registry.
1014 _ "github.com/distribution/distribution/v3/registry/storage/driver/filesystem"
1115
@@ -16,9 +20,8 @@ func TestNewTempRegistry_StartStop(t *testing.T) {
1620 ctx := context .Background ()
1721 srv := NewTempRegistry (ctx , t .TempDir ())
1822
19- // Start the httptest server directly to avoid the Start() method's
20- // retry logic which only accepts HTTP 200, while /v2 returns 401
21- // from the distribution registry.
23+ // start the httptest server directly to avoid the retry logic which only accepts HTTP 200
24+ // while /v2 returns 401 from the distribution registry.
2225 srv .Server .Start ()
2326 t .Cleanup (func () { srv .Stop () })
2427
@@ -74,6 +77,55 @@ func TestNewFile_Configuration(t *testing.T) {
7477 }
7578}
7679
80+ // this is the only test in the package allowed to enable prometheus, since it registers
81+ // on http.DefaultServeMux and a second registration would panic.
82+ func TestConfigureDebugServer_Prometheus (t * testing.T ) {
83+ // grab a free port and release it so ConfigureDebugServer can bind it
84+ l , err := net .Listen ("tcp" , "127.0.0.1:0" )
85+ if err != nil {
86+ t .Fatalf ("failed to reserve a free port: %v" , err )
87+ }
88+ addr := l .Addr ().String ()
89+ l .Close ()
90+
91+ cfg := & configuration.Configuration {}
92+ cfg .HTTP .Debug .Addr = addr
93+ cfg .HTTP .Debug .Prometheus .Enabled = true
94+ cfg .HTTP .Debug .Prometheus .Path = "/metrics"
95+
96+ ConfigureDebugServer (cfg )
97+
98+ var resp * http.Response
99+ for i := 0 ; i < 20 ; i ++ {
100+ resp , err = http .Get ("http://" + addr + "/metrics" )
101+ if err == nil {
102+ break
103+ }
104+ time .Sleep (50 * time .Millisecond )
105+ }
106+ if err != nil {
107+ t .Fatalf ("expected GET /metrics to eventually succeed, got error: %v" , err )
108+ }
109+ defer resp .Body .Close ()
110+
111+ if resp .StatusCode != http .StatusOK {
112+ t .Fatalf ("expected status 200 from the prometheus handler, got %d" , resp .StatusCode )
113+ }
114+
115+ body , err := io .ReadAll (resp .Body )
116+ if err != nil {
117+ t .Fatalf ("failed to read response body: %v" , err )
118+ }
119+ if ! strings .Contains (string (body ), "go_gc_duration_seconds" ) {
120+ t .Fatalf ("expected prometheus-formatted metrics output, got: %s" , body )
121+ }
122+ }
123+
124+ // an empty Debug.Addr should just no-op, not start a listener.
125+ func TestConfigureDebugServer_NoAddr (t * testing.T ) {
126+ ConfigureDebugServer (& configuration.Configuration {})
127+ }
128+
77129func TestNewFile_DefaultPort (t * testing.T ) {
78130 ctx := context .Background ()
79131 opts := flags.ServeFilesOpts {
0 commit comments