Path: blob/main/components/ws-manager-mk2/grpcpool/pool_test.go
2496 views
// Copyright (c) 2020 Gitpod GmbH. All rights reserved.1// Licensed under the GNU Affero General Public License (AGPL).2// See License-AGPL.txt in the project root for license information.34package grpcpool_test56import (7"fmt"8"net"9"testing"10"time"1112"google.golang.org/grpc"13"google.golang.org/grpc/connectivity"1415"github.com/gitpod-io/gitpod/ws-manager-mk2/grpcpool"16)1718// go tests does execute tests concurrently (each test a goroutine)19// To avoid clashes, we20var lastPort = 220002122var falseConnectionValidationFunc = func(hostIP string) (valid bool) { return false }2324func getTestAddr() string {25// No need to lock() as we do not execute in _parallel_ but _concurrently_26port := lastPort + 127lastPort = port28return fmt.Sprintf("localhost:%d", port)29}3031func getFactory(address string) func(host string) (*grpc.ClientConn, error) {32return func(host string) (*grpc.ClientConn, error) {33return grpc.Dial(address, grpc.WithInsecure())34}35}3637func startServer(address string, stop chan struct{}) error {38server := grpc.NewServer()3940go func() {41lis, err := net.Listen("tcp", address)42if err != nil {43panic(err)44}45err = server.Serve(lis)46if err != nil && err != grpc.ErrServerStopped {47panic(err)48}49}()50go func() {51<-stop52server.Stop()53stop <- struct{}{}54}()55return nil56}5758func stopServer(stop chan struct{}) {59stop <- struct{}{}60select {61case <-stop:62return63case <-time.After(4 * time.Second):64panic("stopServer took too long!")65}66}6768func TestFirstGet(t *testing.T) {69address := getTestAddr()70stopTest := make(chan struct{}, 1)71err := startServer(address, stopTest)72if err != nil {73t.Skipf("cannot start server: %v", err)74return75}76defer stopServer(stopTest)7778pool := grpcpool.New(getFactory(address), falseConnectionValidationFunc)7980conn, err := pool.Get("foo")81if err != nil {82t.Errorf("Get returned error when it shouldn't have: %v", err)83return84}85if conn == nil {86t.Errorf("Get returned conn == nil")87}8889connB, err := pool.Get("foo")90if err != nil {91t.Errorf("Get returned error when it shouldn't have: %v", err)92return93}94if connB == nil {95t.Errorf("Get returned conn == nil")96}97if connB != conn {98t.Errorf("Get did not return the same connection")99}100}101102func TestGetShutDown(t *testing.T) {103address := getTestAddr()104stopTest := make(chan struct{}, 1)105err := startServer(address, stopTest)106if err != nil {107t.Skipf("cannot start server: %v", err)108return109}110defer stopServer(stopTest)111112pool := grpcpool.New(getFactory(address), falseConnectionValidationFunc)113114conn, err := pool.Get("foo")115if err != nil {116t.Errorf("Get returned error when it shouldn't have: %v", err)117return118}119if conn == nil {120t.Errorf("Get returned conn == nil")121}122123conn.Close()124connB, err := pool.Get("foo")125if err != nil {126t.Errorf("Get returned error when it shouldn't have: %v", err)127return128}129if connB == nil {130t.Errorf("Get returned conn == nil")131}132if connB == conn {133t.Errorf("Get returned the same connection although it was closed")134}135}136137func TestClosed(t *testing.T) {138address := getTestAddr()139stopTest := make(chan struct{}, 1)140err := startServer(address, stopTest)141if err != nil {142t.Skipf("cannot start server: %v", err)143return144}145defer stopServer(stopTest)146147pool := grpcpool.New(getFactory(address), falseConnectionValidationFunc)148149conn, err := pool.Get("foo")150if conn == nil || err != nil {151t.Errorf("Get returned an error or no connection: %v", err)152return153}154155err = pool.Close()156if err != nil {157t.Errorf("Close returned an error: %v", err)158}159160if conn.GetState() != connectivity.Shutdown {161t.Errorf("Close did not close connections in the pool")162}163164conn, err = pool.Get("foo")165if err != grpcpool.ErrPoolClosed {166t.Errorf("Get did not return ErrPoolClosed even though pool was closed")167}168if conn != nil {169t.Errorf("Get returned a connection even though pool was closed")170}171}172173func TestValidateConnections(t *testing.T) {174address := getTestAddr()175stopTest := make(chan struct{}, 1)176err := startServer(address, stopTest)177if err != nil {178t.Skipf("cannot start server: %v", err)179return180}181defer stopServer(stopTest)182183checkFn := func(checkAddress string) bool {184if address != checkAddress {185t.Errorf("check address is invalid, expected %v, but returned %v", address, checkAddress)186return false187}188189return true190}191192pool := grpcpool.New(getFactory(address), checkFn)193194conn, err := pool.Get(address)195if err != nil {196t.Errorf("Get returned error when it shouldn't have: %v", err)197return198}199if conn == nil {200t.Errorf("Get returned conn == nil")201}202203pool.ValidateConnections()204}205206207