package registry import ( "bufio" "context" "fmt" "io/ioutil" "net" "net/http" "os" "reflect" "testing" "time" "github.com/distribution/distribution/v3/configuration" _ "github.com/distribution/distribution/v3/registry/storage/driver/inmemory" ) // Tests to ensure nextProtos returns the correct protocols when: // * config.HTTP.HTTP2.Disabled is not explicitly set => [h2 http/1.1] // * config.HTTP.HTTP2.Disabled is explicitly set to false [h2 http/1.1] // * config.HTTP.HTTP2.Disabled is explicitly set to true [http/1.1] func TestNextProtos(t *testing.T) { config := &configuration.Configuration{} protos := nextProtos(config) if !reflect.DeepEqual(protos, []string{"h2", "http/1.1"}) { t.Fatalf("expected protos to equal [h2 http/1.1], got %s", protos) } config.HTTP.HTTP2.Disabled = false protos = nextProtos(config) if !reflect.DeepEqual(protos, []string{"h2", "http/1.1"}) { t.Fatalf("expected protos to equal [h2 http/1.1], got %s", protos) } config.HTTP.HTTP2.Disabled = true protos = nextProtos(config) if !reflect.DeepEqual(protos, []string{"http/1.1"}) { t.Fatalf("expected protos to equal [http/1.1], got %s", protos) } } func setupRegistry() (*Registry, error) { config := &configuration.Configuration{} // TODO: this needs to change to something ephemeral as the test will fail if there is any server // already listening on port 5000 config.HTTP.Addr = ":5000" config.HTTP.DrainTimeout = time.Duration(10) * time.Second config.Storage = map[string]configuration.Parameters{"inmemory": map[string]interface{}{}} return NewRegistry(context.Background(), config) } func TestGracefulShutdown(t *testing.T) { registry, err := setupRegistry() if err != nil { t.Fatal(err) } // run registry server var errchan chan error go func() { errchan <- registry.ListenAndServe() }() select { case err = <-errchan: t.Fatalf("Error listening: %v", err) default: } // Wait for some unknown random time for server to start listening time.Sleep(3 * time.Second) // send incomplete request conn, err := net.Dial("tcp", "localhost:5000") if err != nil { t.Fatal(err) } fmt.Fprintf(conn, "GET /v2/ ") // send stop signal quit <- os.Interrupt time.Sleep(100 * time.Millisecond) // try connecting again. it shouldn't _, err = net.Dial("tcp", "localhost:5000") if err == nil { t.Fatal("Managed to connect after stopping.") } // make sure earlier request is not disconnected and response can be received fmt.Fprintf(conn, "HTTP/1.1\r\nHost: 127.0.0.1\r\n\r\n") resp, err := http.ReadResponse(bufio.NewReader(conn), nil) if err != nil { t.Fatal(err) } if resp.Status != "200 OK" { t.Error("response status is not 200 OK: ", resp.Status) } if body, err := ioutil.ReadAll(resp.Body); err != nil || string(body) != "{}" { t.Error("Body is not {}; ", string(body)) } }