From 37bac585edc3fd0a7c88acd657787cc64425da94 Mon Sep 17 00:00:00 2001 From: porosnicuadrian Date: Wed, 27 Jan 2021 16:12:10 +0200 Subject: [PATCH] Tests for cores package --- cores/server.go | 58 +++++++++---------------- cores/server_it_test.go | 93 ++++++++++++++++++++++++++++++++++++++++- cores/server_test.go | 33 --------------- 3 files changed, 111 insertions(+), 73 deletions(-) diff --git a/cores/server.go b/cores/server.go index 8e13632de..c71c035a4 100644 --- a/cores/server.go +++ b/cores/server.go @@ -31,7 +31,6 @@ import ( "net/http" "net/http/pprof" "net/rpc" - "reflect" "strings" "sync" "time" @@ -123,24 +122,6 @@ func (s *Server) BiRPCRegisterName(method string, handlerFunc interface{}) { s.birpcSrv.Handle(method, handlerFunc) } -func (s *Server) BiRPCRegister(rcvr interface{}) { - s.RLock() - isNil := s.birpcSrv == nil - s.RUnlock() - if isNil { - s.Lock() - s.birpcSrv = rpc2.NewServer() - s.Unlock() - } - rcvType := reflect.TypeOf(rcvr) - for i := 0; i < rcvType.NumMethod(); i++ { - method := rcvType.Method(i) - if method.Name != "Call" { - s.birpcSrv.Handle("SMGenericV1."+method.Name, method.Func.Interface()) - } - } -} - func (s *Server) serveCodec(addr, codecName string, newCodec func(conn conn, caps *engine.Caps, anz *analyzers.AnalyzerService) rpc.ServerCodec, shdChan *utils.SyncedChan) { s.RLock() @@ -270,7 +251,7 @@ func (s *Server) ServeHTTP(addr string, jsonRPCURL string, wsRPCURL string, } } -// ServeBiJSON create a gorutine to listen and serve as BiRPC server +// ServeBiJSON create a goroutine to listen and serve as BiRPC server func (s *Server) ServeBiJSON(addr string, onConn func(*rpc2.Client), onDis func(*rpc2.Client)) (err error) { s.RLock() isNil := s.birpcSrv == nil @@ -287,26 +268,28 @@ func (s *Server) ServeBiJSON(addr string, onConn func(*rpc2.Client), onDis func( s.birpcSrv.OnConnect(onConn) s.birpcSrv.OnDisconnect(onDis) utils.Logger.Info(fmt.Sprintf("Starting CGRateS BiJSON server at <%s>", addr)) - go func(l net.Listener) { - for { - conn, err := l.Accept() - if err != nil { - if strings.Contains(err.Error(), "use of closed network connection") { // if closed by us do not log - return - } - s.stopbiRPCServer <- struct{}{} - log.Fatal(err) - return // stop if we get Accept error - } - go s.birpcSrv.ServeCodec(rpc2_jsonrpc.NewJSONCodec(conn)) - } - }(lBiJSON) + go s.acceptBiRPC(lBiJSON) <-s.stopbiRPCServer // wait until server is stoped to close the listener lBiJSON.Close() return } -// StopBiRPC stops the go rutine create with ServeBiJSON +func (s *Server) acceptBiRPC(l net.Listener) { + for { + conn, err := l.Accept() + if err != nil { + if strings.Contains(err.Error(), "use of closed network connection") { // if closed by us do not log + return + } + s.stopbiRPCServer <- struct{}{} + utils.Logger.Crit(fmt.Sprintf("Stoped BiRPC server beacause %s", err)) + return // stop if we get Accept error + } + go s.birpcSrv.ServeCodec(rpc2_jsonrpc.NewJSONCodec(conn)) + } +} + +// StopBiRPC stops the go routine create with ServeBiJSON func (s *Server) StopBiRPC() { s.stopbiRPCServer <- struct{}{} } @@ -364,14 +347,13 @@ func loadTLSConfig(serverCrt, serverKey, caCert string, serverPolicy int, utils.Logger.Crit(fmt.Sprintf("Error: %s when load server keys", err)) return nil, err } + rootCAs, err := x509.SystemCertPool() + //This will only happen on windows if err != nil { utils.Logger.Crit(fmt.Sprintf("Error: %s when load SystemCertPool", err)) return nil, err } - if rootCAs == nil { - rootCAs = x509.NewCertPool() - } if caCert != "" { ca, err := ioutil.ReadFile(caCert) diff --git a/cores/server_it_test.go b/cores/server_it_test.go index 1bb95bbfc..852834311 100644 --- a/cores/server_it_test.go +++ b/cores/server_it_test.go @@ -30,6 +30,7 @@ import ( "net/rpc/jsonrpc" "os" "path" + "reflect" "runtime" "strings" "testing" @@ -73,6 +74,9 @@ var ( testServeHTTPTLSHttpNotEnabled, testHandleRequest, testBiRPCRegisterName, + testAcceptBiRPC, + testRpcRegisterActions, + testWebSocket, } ) @@ -84,7 +88,11 @@ func TestServerIT(t *testing.T) { } } -type mockRegister struct{} +type mockRegister string + +func (x *mockRegister) ForTest(method *rpc2.Client, args *interface{}, reply *interface{}) error { + return nil +} func (robj *mockRegister) Ping(in string, out *string) error { *out = utils.Pong @@ -272,7 +280,7 @@ func testServeHHTPFail(t *testing.T) { shdChan := utils.NewSyncedChan() go server.ServeHTTP( - "invalid_portt_format", + "invalid_port_format", cfgDflt.HTTPCfg().HTTPJsonRPCURL, cfgDflt.HTTPCfg().HTTPWSURL, cfgDflt.HTTPCfg().HTTPUseBasicAuth, @@ -669,3 +677,84 @@ func testBiRPCRegisterName(t *testing.T) { server.StopBiRPC() } + +func testAcceptBiRPC(t *testing.T) { + caps := engine.NewCaps(0, utils.MetaBusy) + server := NewServer(caps) + server.RpcRegister(new(mockRegister)) + server.birpcSrv = rpc2.NewServer() + + p1, p2 := net.Pipe() + l := &mockListener{ + p1: p1, + } + go server.acceptBiRPC(l) + rpc := jsonrpc.NewClient(p2) + var reply string + expected := "rpc2: can't find method AttributeSv1.Ping" + if err := rpc.Call(utils.AttributeSv1Ping, utils.CGREvent{}, &reply); err == nil || err.Error() != expected { + t.Errorf("Expected %+v, received %+v", expected, err) + } + + p2.Close() + runtime.Gosched() +} + +func testRpcRegisterActions(t *testing.T) { + caps := engine.NewCaps(0, utils.MetaBusy) + server := NewServer(caps) + + r, err := http.NewRequest(http.MethodPost, "http://127.0.0.1:2080/json_rpc", + bytes.NewBuffer([]byte("1"))) + if err != nil { + t.Fatal(err) + } + rmtIP, _ := utils.GetRemoteIP(r) + rmtAddr, _ := net.ResolveIPAddr(utils.EmptyString, rmtIP) + + rpcReq := newRPCRequest(r.Body, rmtAddr, server.caps, nil) + rpcReq.remoteAddr = utils.NewNetAddr("network", "127.0.0.1:2012") + + if n, err := rpcReq.Write([]byte(`TEST`)); err != nil { + t.Error(err) + } else if n != 4 { + t.Errorf("Expected 4, received %+v", n) + } + + if rcv := rpcReq.LocalAddr(); !reflect.DeepEqual(rcv, utils.LocalAddr()) { + t.Errorf("Received %+v, expected %+v", utils.ToJSON(rcv), utils.ToJSON(utils.LocalAddr())) + } + + exp := utils.NewNetAddr("network", "127.0.0.1:2012") + if rcv := rpcReq.RemoteAddr(); !reflect.DeepEqual(rcv, exp) { + t.Errorf("Received %+v, expected %+v", utils.ToJSON(rcv), utils.ToJSON(exp)) + } +} + +func testWebSocket(t *testing.T) { + cfgDflt := config.NewDefaultCGRConfig() + caps := engine.NewCaps(100, utils.MetaBusy) + server = NewServer(caps) + server.RpcRegister(new(mockRegister)) + + shdChan := utils.NewSyncedChan() + + authUsers := map[string]string{ + "admin": "password", + } + + //Invalid port address + go server.ServeHTTPTLS( + "57235", + "/usr/share/cgrates/tls/inexisting_file", + "/usr/share/cgrates/tls/server.key", + "/usr/share/cgrates/tls/ca.crt", + cfgDflt.TLSCfg().ServerPolicy, + cfgDflt.TLSCfg().ServerName, + utils.EmptyString, + cfgDflt.HTTPCfg().HTTPWSURL, + true, + authUsers, + shdChan) + runtime.Gosched() +} diff --git a/cores/server_test.go b/cores/server_test.go index e6b53cb3a..34230c5d9 100644 --- a/cores/server_test.go +++ b/cores/server_test.go @@ -26,7 +26,6 @@ import ( "reflect" "testing" - "github.com/cenkalti/rpc2" "github.com/cgrates/cgrates/agents" "github.com/cgrates/cgrates/analyzers" @@ -97,38 +96,6 @@ func TestRegisterHttpFunc(t *testing.T) { rcv.StopBiRPC() } -func TestBiRPCRegisterName(t *testing.T) { - cfgDflt := config.NewDefaultCGRConfig() - cfgDflt.CoreSCfg().CapsStatsInterval = 1 - caps := engine.NewCaps(0, utils.MetaBusy) - rcv := NewServer(caps) - - cfgDflt.AnalyzerSCfg().DBPath = "/tmp/analyzers" - if err := os.RemoveAll(cfgDflt.AnalyzerSCfg().DBPath); err != nil { - t.Fatal(err) - } - if err := os.MkdirAll(cfgDflt.AnalyzerSCfg().DBPath, 0700); err != nil { - t.Fatal(err) - } - analz, err := analyzers.NewAnalyzerService(cfgDflt) - if err != nil { - t.Error(err) - } - rcv.SetAnalyzer(analz) - - rcv.birpcSrv = &rpc2.Server{} - - rcv.BiRPCRegister(mockReadWriteCloserErrorNilResponse{}) - - rcv.birpcSrv = nil - rcv.BiRPCRegister(gobServerCodec{}) - - if err := os.RemoveAll(cfgDflt.AnalyzerSCfg().DBPath); err != nil { - t.Fatal(err) - } - rcv.StopBiRPC() -} - func TestRegisterProfiler(t *testing.T) { cfgDflt := config.NewDefaultCGRConfig() cfgDflt.CoreSCfg().CapsStatsInterval = 1