2022-12-08 13:05:19 -03:00

134 lines
4.6 KiB
Go

// Copyright (c) 2022 Gitpod GmbH. All rights reserved.
// Licensed under the GNU Affero General Public License (AGPL).
// See License.AGPL.txt in the project root for license information.
package baseserver_test
import (
"context"
"fmt"
"net/http"
"testing"
"github.com/gitpod-io/gitpod/common-go/baseserver"
"github.com/prometheus/client_golang/prometheus/testutil"
"github.com/stretchr/testify/require"
"google.golang.org/grpc"
"google.golang.org/grpc/credentials/insecure"
"google.golang.org/grpc/health/grpc_health_v1"
)
func TestServer_StartStop(t *testing.T) {
// We don't use the helper NewForTests, because we want to control stopping ourselves.
srv, err := baseserver.New("server_test",
baseserver.WithUnderTest(),
baseserver.WithHTTP(&baseserver.ServerConfiguration{Address: "localhost:8765"}),
baseserver.WithGRPC(&baseserver.ServerConfiguration{Address: "localhost:8766"}),
)
require.NoError(t, err)
baseserver.StartServerForTests(t, srv)
require.Equal(t, "http://127.0.0.1:8765", srv.HTTPAddress())
require.Equal(t, "localhost:8766", srv.GRPCAddress())
require.NoError(t, srv.Close())
}
func TestServer_ServerCombinations_StartsAndStops(t *testing.T) {
tests := []struct {
StartHTTP bool
StartGRPC bool
}{
{StartHTTP: false, StartGRPC: false},
{StartHTTP: true, StartGRPC: false},
{StartHTTP: true, StartGRPC: true},
{StartHTTP: false, StartGRPC: true},
}
for _, test := range tests {
t.Run(fmt.Sprintf("with http: %v, grpc: %v", test.StartGRPC, test.StartHTTP), func(t *testing.T) {
var opts []baseserver.Option
opts = append(opts, baseserver.WithUnderTest())
if test.StartHTTP {
opts = append(opts, baseserver.WithHTTP(&baseserver.ServerConfiguration{
Address: fmt.Sprintf("localhost:%d", baseserver.MustFindFreePort(t)),
}))
}
if test.StartGRPC {
opts = append(opts, baseserver.WithGRPC(&baseserver.ServerConfiguration{
Address: fmt.Sprintf("localhost:%d", baseserver.MustFindFreePort(t)),
}))
}
srv, err := baseserver.New("test_server", opts...)
if err != nil {
t.Fatal(err)
}
baseserver.StartServerForTests(t, srv)
require.NotEmpty(t, srv.DebugAddress(), "must serve debug endpoint")
if test.StartHTTP {
require.NotEmpty(t, srv.HTTPAddress(), "must serve http because startHTTP was set")
} else {
require.Empty(t, srv.HTTPAddress(), "must not serve http")
}
if test.StartGRPC {
require.NotEmpty(t, srv.GRPCAddress(), "must serve grpc because startGRPC was set")
} else {
require.Empty(t, srv.GRPCAddress(), "must not serve grpc")
}
})
}
}
func TestServer_Metrics_gRPC(t *testing.T) {
ctx := context.Background()
srv := baseserver.NewForTests(t, baseserver.WithGRPC(&baseserver.ServerConfiguration{
Address: fmt.Sprintf("localhost:%d", baseserver.MustFindFreePort(t)),
}))
// At this point, there must be metrics registry available for use
require.NotNil(t, srv.MetricsRegistry())
// Let's start our server up
baseserver.StartServerForTests(t, srv)
// We need a client to be able to invoke the RPC, let's construct one
conn, err := grpc.DialContext(ctx, srv.GRPCAddress(), grpc.WithTransportCredentials(insecure.NewCredentials()))
require.NoError(t, err)
client := grpc_health_v1.NewHealthClient(conn)
// By default the server runs a Health service, we can use it for our purposes
_, err = client.Check(ctx, &grpc_health_v1.HealthCheckRequest{})
require.NoError(t, err)
// Finally, we can assert that some metrics were produced.
registry := srv.MetricsRegistry()
// We expect at least the following. It's not the full set, but a good baseline to sanity check.
expected := []string{"grpc_server_handled_total", "grpc_server_handling_seconds", "grpc_server_started_total"}
count, err := testutil.GatherAndCount(registry, expected...)
require.NoError(t, err)
require.Equal(t, len(expected)*1, count, "expected 1 count for each metric")
}
func TestServer_Metrics_HTTP(t *testing.T) {
srv := baseserver.NewForTests(t, baseserver.WithHTTP(&baseserver.ServerConfiguration{
Address: fmt.Sprintf("localhost:%d", baseserver.MustFindFreePort(t)),
}))
// At this point, there must be metrics registry available for use
require.NotNil(t, srv.MetricsRegistry())
// Let's start our server up
baseserver.StartServerForTests(t, srv)
_, err := http.Get(fmt.Sprintf("%s/foo/bar", srv.HTTPAddress()))
require.NoError(t, err)
registry := srv.MetricsRegistry()
count, err := testutil.GatherAndCount(registry, "gitpod_http_request_duration_seconds", "gitpod_http_response_size_bytes", "gitpod_http_requests_inflight")
require.NoError(t, err)
require.Equal(t, 3, count, "expecting 1 count for each above metric")
}