1+ import os
2+ import subprocess
13from dataclasses import dataclass
24from itertools import combinations
5+ from tempfile import mkstemp
6+ from time import sleep
37from typing import Dict
48from urllib .parse import parse_qs , urlparse
59
610import pytest
11+ import yaml
712from requests .exceptions import ConnectionError
13+
814from suzieq .engines .rest .engineobj import SqRestEngine
15+ from suzieq .shared .utils import load_sq_config
16+ from tests .conftest import get_free_port , suzieq_rest_server_path
917
1018
1119@dataclass
1220class SqContextMock :
1321 """ SqContext rest parameters mock
1422 """
23+ cfg : dict
1524 rest_api_key : str
1625 rest_transport : str
1726 rest_server_ip : str
@@ -70,10 +79,10 @@ def req_error(param: str, exp: str, got: str) -> str:
7079
7180 # check query parameters
7281 url_query = parse_qs (url .query )
73- for query_param , query_value in url_query .items ():
74- assert len (query_value ) == 1 , \
82+ for query_param , query_values in url_query .items ():
83+ assert len (query_values ) == 1 , \
7584 f'Got more than 1 value for { query_param } '
76- query_value = query_value [0 ]
85+ query_value = query_values [0 ]
7786 if query_param == 'access_token' :
7887 # access_token needs a special validation
7988 assert query_value == engine .ctxt .rest_api_key , \
@@ -94,7 +103,7 @@ def req_error(param: str, exp: str, got: str) -> str:
94103def test_request_params ():
95104 """This test checks if parameters are set correctly in the request
96105 """
97- ctxt = SqContextMock ('key' , 'http' , 'rest-ip' , 80 )
106+ ctxt = SqContextMock ({}, 'key' , 'http' , 'rest-ip' , 80 )
98107 sqobj = SqObjMock (ctxt , 'default' , 'default' , 'default' ,
99108 'default' , 'default' , 'default' , 'default' )
100109 engine = SqRestEngine (sqobj )
@@ -109,3 +118,114 @@ def test_request_params():
109118 for sq_params in combinations (testing_params , n_sq_params ):
110119 req_params = {p : 'override' for p in sq_params }
111120 validate_args (engine , req_params )
121+
122+
123+ @pytest .mark .rest
124+ @pytest .mark .skipif (not os .environ .get ('TEST_SERVER' , None ),
125+ reason = 'causes github action hang' )
126+ def test_server_cert ():
127+ '''Can we can get a valid response with & without certificate'''
128+
129+ # We need to change the port used to avoid conflicts
130+ config = {'data-directory' : './tests/data/parquet' ,
131+ 'temp-directory' : '/tmp/suzieq' ,
132+ 'logging-level' : 'WARNING' ,
133+ 'test_set' : 'basic_dual_bgp' , # an extra field for testing
134+ 'rest' : {
135+ 'rest-certfile' : './tests/test_cert_CA/server-cert.pem' ,
136+ 'rest-keyfile' : './tests/test_cert_CA/server-key.pem' ,
137+ 'API_KEY' : '496157e6e869ef7f3d6ecb24a6f6d847b224ee4f' ,
138+ 'logging-level' : 'WARNING' ,
139+ 'address' : '0.0.0.0' ,
140+ 'port' : get_free_port (),
141+ 'no-https' : True ,
142+ 'log-stdout' : True
143+ },
144+ 'analyzer' : {'timezone' : 'GMT' },
145+ }
146+
147+ def create_config (config ):
148+ fd , tmpfname = mkstemp (suffix = '.yml' )
149+ f = os .fdopen (fd , 'w' )
150+ f .write (yaml .dump (config ))
151+ f .close ()
152+
153+ cfgfile = tmpfname
154+ sqcfg = load_sq_config (config_file = cfgfile )
155+
156+ print (f'sqcfg: { sqcfg } ' )
157+
158+ with open (cfgfile , 'w' ) as f :
159+ f .write (yaml .safe_dump (sqcfg ))
160+ return sqcfg , cfgfile
161+
162+ def open_rest_server (cfgfile ):
163+ server_cmd_args = f'{ suzieq_rest_server_path } -c { cfgfile } ' .split ()
164+ # pylint: disable=consider-using-with
165+ proc = subprocess .Popen (server_cmd_args )
166+ sleep (5 )
167+ return proc
168+
169+ def make_get_response_request (sqcfg ):
170+ ctxt = SqContextMock (
171+ rest_api_key = sqcfg ['rest' ]['API_KEY' ],
172+ rest_transport = 'http' if sqcfg ['rest' ]['no-https' ] is True
173+ else 'https' ,
174+ rest_server_ip = sqcfg ['rest' ]['address' ],
175+ rest_server_port = sqcfg ['rest' ]['port' ],
176+ cfg = {'rest' : sqcfg ['rest' ]})
177+
178+ sqobj = SqObjMock (ctxt , '' , '' , 'default' ,
179+ 'default' , 'latest' , 'device' , 'default' )
180+
181+ engine = SqRestEngine (sqobj )
182+ try :
183+ response = engine ._get_response ('show' )
184+ print (f'responsein test: { response } ' )
185+ return 200
186+ except Exception :
187+ return 400
188+
189+ def close_session (proc , cfgfile ):
190+ proc .kill ()
191+ os .remove (cfgfile )
192+
193+ # test with http verify None
194+ sqcfg , cfgfile = create_config (config )
195+ proc = open_rest_server (cfgfile )
196+ response = make_get_response_request (sqcfg )
197+ assert response == 200
198+ close_session (proc , cfgfile )
199+
200+ # test with https verify None
201+ config ['rest' ]['no-https' ] = False
202+ sqcfg , cfgfile = create_config (config )
203+ proc = open_rest_server (cfgfile )
204+ response = make_get_response_request (sqcfg )
205+ assert response == 400
206+ close_session (proc , cfgfile )
207+
208+ # test with https verify False
209+ config ['rest' ]['cert-verify' ] = False
210+ sqcfg , cfgfile = create_config (config )
211+ proc = open_rest_server (cfgfile )
212+ response = make_get_response_request (sqcfg )
213+ assert response == 200
214+ close_session (proc , cfgfile )
215+
216+ # test with https verify True
217+ config ['rest' ]['cert-verify' ] = True
218+ sqcfg , cfgfile = create_config (config )
219+ proc = open_rest_server (cfgfile )
220+ response = make_get_response_request (sqcfg )
221+ assert response == 400
222+ close_session (proc , cfgfile )
223+
224+ # test with https verify CA
225+ config ['rest' ]['cert-verify' ] = \
226+ './tests/test_cert_CA/ca-cert.pem'
227+ sqcfg , cfgfile = create_config (config )
228+ proc = open_rest_server (cfgfile )
229+ response = make_get_response_request (sqcfg )
230+ assert response == 200
231+ close_session (proc , cfgfile )
0 commit comments