From 6fb6b86349f216200613575784c97c3c27d886d0 Mon Sep 17 00:00:00 2001 From: porosnicuadrian Date: Fri, 22 Jan 2021 18:41:14 +0200 Subject: [PATCH] Cover + integration tests for server --- cores/server.go | 2 - cores/server_it_test.go | 357 ++++++++++++++++++++++++++++++++++++++++ cores/server_test.go | 39 ++--- 3 files changed, 368 insertions(+), 30 deletions(-) diff --git a/cores/server.go b/cores/server.go index 579c8dd7c..fd67c0913 100644 --- a/cores/server.go +++ b/cores/server.go @@ -403,9 +403,7 @@ func (s *Server) ServeGOBTLS(addr, serverCrt, serverKey, caCert string, if !enabled { return } - fmt.Println("am intrat aici") config, err := loadTLSConfig(serverCrt, serverKey, caCert, serverPolicy, serverName) - fmt.Println("am iesit de aici") if err != nil { shdChan.CloseOnce() return diff --git a/cores/server_it_test.go b/cores/server_it_test.go index 131a7b385..5fd9be8b3 100644 --- a/cores/server_it_test.go +++ b/cores/server_it_test.go @@ -1 +1,358 @@ +/* +Real-time Online/Offline Charging System (OCS) for Telecom & ISP environments +Copyright (C) ITsysCOM GmbH + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see +*/ + package cores + +import ( + "net" + "net/rpc/jsonrpc" + "runtime" + "testing" + + sessions2 "github.com/cgrates/cgrates/sessions" + + "github.com/cenkalti/rpc2" + + "github.com/cgrates/cgrates/config" + + "github.com/cgrates/cgrates/engine" + + "github.com/cgrates/cgrates/utils" +) + +var ( + server *Server + + sTestsServer = []func(t *testing.T){ + testServeJSONPass, + testServeJSONFail, + testServeJSONFailRpcEnabled, + testServeGOBPass, + testServeHHTPPass, + testServeHHTPPassUseBasicAuth, + testServeHHTPEnableHttp, + testServeHHTPFail, + testServeHHTPFailEnableRpc, + testServeBiJSON, + testServeBiJSONEmptyBiRPCServer, + testServeBiJSONInvalidPort, + } +) + +func TestServerIT(t *testing.T) { + for _, test := range sTestsServer { + t.Run("Running IT serve tests", test) + } +} + +type mockRegister struct{} + +func (robj *mockRegister) Ping(in string, out *string) error { + *out = utils.Pong + return nil +} + +type mockListener struct{} + +func (mkL *mockListener) Accept() (net.Conn, error) { return nil, utils.ErrDisconnected } +func (mkL *mockListener) Close() error { return nil } +func (mkL *mockListener) Addr() net.Addr { return nil } + +func testServeJSONPass(t *testing.T) { + caps := engine.NewCaps(100, utils.MetaBusy) + server = NewServer(caps) + server.RpcRegister(new(mockRegister)) + shdChan := utils.NewSyncedChan() + + go server.ServeJSON(":2016", shdChan) + runtime.Gosched() + _, err := jsonrpc.Dial(utils.TCP, ":2016") + if err != nil { + t.Error(err) + } + + shdChan.CloseOnce() +} + +func testServeJSONFail(t *testing.T) { + caps := engine.NewCaps(100, utils.MetaBusy) + server = NewServer(caps) + server.RpcRegister(new(mockRegister)) + shdChan := utils.NewSyncedChan() + + l := &mockListener{} + go server.accept(l, utils.JSONCaps, newCapsJSONCodec, shdChan) + runtime.Gosched() + _, err := jsonrpc.Dial(utils.TCP, ":9999") + expected := "dial tcp :9999: connect: connection refused" + if err == nil || err.Error() != expected { + t.Errorf("Expected %+v, received %+v", expected, err) + } + + _, ok := <-shdChan.Done() + if ok { + t.Errorf("Expected to be close") + } +} + +func testServeJSONFailRpcEnabled(t *testing.T) { + caps := engine.NewCaps(100, utils.MetaBusy) + server = NewServer(caps) + server.RpcRegister(new(mockRegister)) + shdChan := utils.NewSyncedChan() + server.rpcEnabled = false + + go server.serveCodec(":9999", utils.JSONCaps, newCapsJSONCodec, shdChan) + + shdChan.CloseOnce() +} + +func testServeGOBPass(t *testing.T) { + caps := engine.NewCaps(100, utils.MetaBusy) + server = NewServer(caps) + server.RpcRegister(new(mockRegister)) + shdChan := utils.NewSyncedChan() + + go server.ServeGOB(":2019", shdChan) + runtime.Gosched() + _, err := jsonrpc.Dial(utils.TCP, ":2019") + if err != nil { + t.Error(err) + } + + shdChan.CloseOnce() +} + +func testServeHHTPPass(t *testing.T) { + cfgDflt := config.NewDefaultCGRConfig() + caps := engine.NewCaps(100, utils.MetaBusy) + server = NewServer(caps) + server.RpcRegister(new(mockRegister)) + shdChan := utils.NewSyncedChan() + + go server.ServeHTTP( + ":2021", + cfgDflt.HTTPCfg().HTTPJsonRPCURL, + cfgDflt.HTTPCfg().HTTPWSURL, + cfgDflt.HTTPCfg().HTTPUseBasicAuth, + cfgDflt.HTTPCfg().HTTPAuthUsers, + shdChan) + + runtime.Gosched() + _, err := jsonrpc.Dial(utils.TCP, ":2021") + if err != nil { + t.Error(err) + } + + shdChan.CloseOnce() +} + +func testServeHHTPPassUseBasicAuth(t *testing.T) { + cfgDflt := config.NewDefaultCGRConfig() + caps := engine.NewCaps(100, utils.MetaBusy) + server = NewServer(caps) + server.RpcRegister(new(mockRegister)) + shdChan := utils.NewSyncedChan() + + go server.ServeHTTP( + ":2075", + cfgDflt.HTTPCfg().HTTPJsonRPCURL, + cfgDflt.HTTPCfg().HTTPWSURL, + !cfgDflt.HTTPCfg().HTTPUseBasicAuth, + cfgDflt.HTTPCfg().HTTPAuthUsers, + shdChan) + + runtime.Gosched() + _, err := jsonrpc.Dial(utils.TCP, ":2075") + if err != nil { + t.Error(err) + } + + shdChan.CloseOnce() +} + +func testServeHHTPEnableHttp(t *testing.T) { + cfgDflt := config.NewDefaultCGRConfig() + caps := engine.NewCaps(100, utils.MetaBusy) + server = NewServer(caps) + server.RpcRegister(new(mockRegister)) + shdChan := utils.NewSyncedChan() + + go server.ServeHTTP( + ":2077", + utils.EmptyString, + utils.EmptyString, + !cfgDflt.HTTPCfg().HTTPUseBasicAuth, + cfgDflt.HTTPCfg().HTTPAuthUsers, + shdChan) + + runtime.Gosched() + _, err := jsonrpc.Dial(utils.TCP, ":2077") + expected := "dial tcp :2077: connect: connection refused" + if err == nil || err.Error() != expected { + t.Errorf("Expected %+v, received %+v", expected, err) + } + + shdChan.CloseOnce() +} + +func testServeHHTPFail(t *testing.T) { + cfgDflt := config.NewDefaultCGRConfig() + caps := engine.NewCaps(100, utils.MetaBusy) + server = NewServer(caps) + server.RpcRegister(new(mockRegister)) + shdChan := utils.NewSyncedChan() + + go server.ServeHTTP( + "invalid_portt_format", + cfgDflt.HTTPCfg().HTTPJsonRPCURL, + cfgDflt.HTTPCfg().HTTPWSURL, + cfgDflt.HTTPCfg().HTTPUseBasicAuth, + cfgDflt.HTTPCfg().HTTPAuthUsers, + shdChan) + + runtime.Gosched() + _, err := jsonrpc.Dial(utils.TCP, ":2037") + expected := "dial tcp :2037: connect: connection refused" + if err == nil || err.Error() != expected { + t.Errorf("Expected %+v, received %+v", expected, err) + } + + _, ok := <-shdChan.Done() + if ok { + t.Errorf("Expected to be close") + } +} + +func testServeHHTPFailEnableRpc(t *testing.T) { + cfgDflt := config.NewDefaultCGRConfig() + caps := engine.NewCaps(100, utils.MetaBusy) + server = NewServer(caps) + server.RpcRegister(new(mockRegister)) + shdChan := utils.NewSyncedChan() + server.rpcEnabled = false + + go server.ServeHTTP(":1000", + cfgDflt.HTTPCfg().HTTPJsonRPCURL, + cfgDflt.HTTPCfg().HTTPWSURL, + cfgDflt.HTTPCfg().HTTPUseBasicAuth, + cfgDflt.HTTPCfg().HTTPAuthUsers, + shdChan) + + shdChan.CloseOnce() +} + +func testServeBiJSON(t *testing.T) { + cfgDflt := config.NewDefaultCGRConfig() + caps := engine.NewCaps(100, utils.MetaBusy) + server = NewServer(caps) + server.RpcRegister(new(mockRegister)) + server.birpcSrv = rpc2.NewServer() + + data := engine.NewInternalDB(nil, nil, true) + dm := engine.NewDataManager(data, cfgDflt.CacheCfg(), nil) + + sessions := sessions2.NewSessionS(cfgDflt, dm, nil) + + go func() { + if err := server.ServeBiJSON(":3434", sessions.OnBiJSONConnect, sessions.OnBiJSONDisconnect); err != nil { + t.Error(err) + } + }() + + runtime.Gosched() + _, err := jsonrpc.Dial(utils.TCP, ":3434") + if err != nil { + t.Error(err) + } +} + +func testServeBiJSONEmptyBiRPCServer(t *testing.T) { + cfgDflt := config.NewDefaultCGRConfig() + caps := engine.NewCaps(100, utils.MetaBusy) + server = NewServer(caps) + server.RpcRegister(new(mockRegister)) + + data := engine.NewInternalDB(nil, nil, true) + dm := engine.NewDataManager(data, cfgDflt.CacheCfg(), nil) + + sessions := sessions2.NewSessionS(cfgDflt, dm, nil) + + expectedErr := "BiRPCServer should not be nil" + go func() { + + if err := server.ServeBiJSON(":3430", sessions.OnBiJSONConnect, sessions.OnBiJSONDisconnect); err == nil || err.Error() != "BiRPCServer should not be nil" { + t.Errorf("Expected %+v, received %+v", expectedErr, err) + } + }() + + runtime.Gosched() + expected := "dial tcp :3430: connect: connection refused" + _, err := jsonrpc.Dial(utils.TCP, ":3430") + if err == nil || err.Error() != expected { + t.Errorf("Expected %+v, received %+v", expected, err) + } +} + +func testServeBiJSONInvalidPort(t *testing.T) { + cfgDflt := config.NewDefaultCGRConfig() + caps := engine.NewCaps(100, utils.MetaBusy) + server = NewServer(caps) + server.RpcRegister(new(mockRegister)) + server.birpcSrv = rpc2.NewServer() + + data := engine.NewInternalDB(nil, nil, true) + dm := engine.NewDataManager(data, cfgDflt.CacheCfg(), nil) + + sessions := sessions2.NewSessionS(cfgDflt, dm, nil) + + expectedErr := "listen tcp: address invalid_port_format: missing port in address" + if err := server.ServeBiJSON("invalid_port_format", sessions.OnBiJSONConnect, + sessions.OnBiJSONDisconnect); err == nil || err.Error() != expectedErr { + t.Errorf("Expected %+v, received %+v", expectedErr, err) + } +} + +/* +func testServeGOBTLS(t *testing.T) { + cfgDflt := config.NewDefaultCGRConfig() + caps := engine.NewCaps(100, utils.MetaBusy) + server = NewServer(caps) + server.RpcRegister(new(randomObj)) + + shdChan := utils.NewSyncedChan() + + go server.ServeGOBTLS( + ":1256", + cfgDflt.TLSCfg().ServerCerificate, + cfgDflt.TLSCfg().ServerKey, + cfgDflt.TLSCfg().CaCertificate, + cfgDflt.TLSCfg().ServerPolicy, + cfgDflt.TLSCfg().ServerName, + shdChan, + ) + + _, err := jsonrpc.Dial(utils.TCP, ":1256") + if err != nil { + t.Error(err) + } + + shdChan.CloseOnce() +} + +*/ diff --git a/cores/server_test.go b/cores/server_test.go index 129c3dd47..bd7c9e843 100644 --- a/cores/server_test.go +++ b/cores/server_test.go @@ -19,10 +19,11 @@ along with this program. If not, see package cores import ( + "bytes" "net/http" + "net/http/httptest" "os" "reflect" - "strings" "testing" "github.com/cenkalti/rpc2" @@ -203,43 +204,25 @@ func TestRegisterProfiler(t *testing.T) { rcv.StopBiRPC() } -type mockWriteResponse struct{} - -func (mk *mockWriteResponse) Header() http.Header { return http.Header{} } -func (mk *mockWriteResponse) Write([]byte) (int, error) { return 0, nil } -func (mk *mockWriteResponse) WriteHeader(statusCode int) {} - func TestHandleRequest(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.rpcEnabled = true - req, err := http.NewRequest("POST", "http://www.google.com/search?q=foo&q=bar&both=x&prio=1&orphan=nope&empty=not", - strings.NewReader("z=post&both=y&prio=2&=nokey&orphan;empty=&")) + req, err := http.NewRequest(http.MethodPost, "https://raw.githubusercontent.com/cgrates/cgrates/master/data/tariffplans/oldtutorial/ActionPlans.csv", + bytes.NewBuffer([]byte("1"))) if err != nil { - t.Error(err) - } - - mkRespWriter := &mockWriteResponse{} - rcv.handleRequest(mkRespWriter, req) - - if err := os.RemoveAll(cfgDflt.AnalyzerSCfg().DBPath); err != nil { t.Fatal(err) } + + w := httptest.NewRecorder() + rcv.handleRequest(w, req) + if w.Body.String() != utils.EmptyString { + t.Errorf("Expected: %q ,received: %q", utils.EmptyString, w.Body.String()) + } + rcv.StopBiRPC() }