1616
1717
1818from __future__ import absolute_import
19- import time
2019from io import BytesIO
20+ from threading import Thread
2121
22+ from splunklib .six .moves import BaseHTTPServer
2223from splunklib .six .moves .urllib .request import Request , urlopen
2324from splunklib .six .moves .urllib .error import HTTPError
24- from splunklib .six import StringIO
25+ import splunklib .six as six
2526from xml .etree .ElementTree import XML
2627
28+ import json
2729import logging
2830from tests import testlib
2931import unittest
@@ -104,7 +106,7 @@ def test_read_partial(self):
104106
105107 def test_readable (self ):
106108 txt = "abcd"
107- response = binding .ResponseReader (StringIO (txt ))
109+ response = binding .ResponseReader (six . StringIO (txt ))
108110 self .assertTrue (response .readable ())
109111
110112 def test_readinto_bytearray (self ):
@@ -813,8 +815,8 @@ class TestPostWithBodyParam(unittest.TestCase):
813815
814816 def test_post (self ):
815817 def handler (url , message , ** kwargs ):
816- assert url == "https://localhost:8089/servicesNS/testowner/testapp/foo/bar"
817- assert message ["body" ][ "testkey" ] == "testvalue"
818+ assert six . ensure_str ( url ) == "https://localhost:8089/servicesNS/testowner/testapp/foo/bar"
819+ assert six . ensure_str ( message ["body" ]) == "testkey= testvalue"
818820 return splunklib .data .Record ({
819821 "status" : 200 ,
820822 "headers" : [],
@@ -825,7 +827,7 @@ def handler(url, message, **kwargs):
825827 def test_post_with_params_and_body (self ):
826828 def handler (url , message , ** kwargs ):
827829 assert url == "https://localhost:8089/servicesNS/testowner/testapp/foo/bar?extrakey=extraval"
828- assert message ["body" ][ "testkey" ] == "testvalue"
830+ assert six . ensure_str ( message ["body" ]) == "testkey= testvalue"
829831 return splunklib .data .Record ({
830832 "status" : 200 ,
831833 "headers" : [],
@@ -836,18 +838,90 @@ def handler(url, message, **kwargs):
836838 def test_post_with_params_and_no_body (self ):
837839 def handler (url , message , ** kwargs ):
838840 assert url == "https://localhost:8089/servicesNS/testowner/testapp/foo/bar"
839- assert message ["body" ] == "extrakey=extraval"
841+ assert six . ensure_str ( message ["body" ]) == "extrakey=extraval"
840842 return splunklib .data .Record ({
841843 "status" : 200 ,
842844 "headers" : [],
843845 })
844846 ctx = binding .Context (handler = handler )
845847 ctx .post ("foo/bar" , extrakey = "extraval" , owner = "testowner" , app = "testapp" )
846848
847- def test_with_body_with_full_request (self ):
848- class TestRequestHandler (BaseHTTPRequestHandler ):
849+
850+ def _wrap_handler (func , response_code = 200 , body = "" ):
851+ def wrapped (handler_self ):
852+ result = func (handler_self )
853+ if result is None :
854+ handler_self .send_response (response_code )
855+ handler_self .end_headers ()
856+ handler_self .wfile .write (body )
857+ return wrapped
858+
859+
860+ class MockServer (object ):
861+ def __init__ (self , port = 9093 , ** handlers ):
862+ methods = {"do_" + k : _wrap_handler (v ) for (k , v ) in handlers .items ()}
863+
864+ def init (handler_self , socket , address , server ):
865+ BaseHTTPServer .BaseHTTPRequestHandler .__init__ (handler_self , socket , address , server )
866+
867+ def log (* args ): # To silence server access logs
849868 pass
850869
870+ methods ["__init__" ] = init
871+ methods ["log_message" ] = log
872+ Handler = type ("Handler" ,
873+ (BaseHTTPServer .BaseHTTPRequestHandler , object ),
874+ methods )
875+ self ._svr = BaseHTTPServer .HTTPServer (("localhost" , port ), Handler )
876+
877+ def run ():
878+ self ._svr .handle_request ()
879+ self ._thread = Thread (target = run )
880+ self ._thread .daemon = True
881+
882+ def __enter__ (self ):
883+ self ._thread .start ()
884+ return self ._svr
885+
886+ def __exit__ (self , typ , value , traceback ):
887+ self ._thread .join (10 )
888+ self ._svr .server_close ()
889+
890+
891+ class TestFullPost (unittest .TestCase ):
892+
893+ def test_post_with_body_urlencoded (self ):
894+ def check_response (handler ):
895+ length = int (handler .headers .get ('content-length' , 0 ))
896+ body = handler .rfile .read (length )
897+ assert six .ensure_str (body ) == "foo=bar"
898+
899+ with MockServer (POST = check_response ):
900+ ctx = binding .connect (port = 9093 , scheme = 'http' , token = "waffle" )
901+ ctx .post ("/" , foo = "bar" )
902+
903+ def test_post_with_body_string (self ):
904+ def check_response (handler ):
905+ length = int (handler .headers .get ('content-length' , 0 ))
906+ body = handler .rfile .read (length )
907+ assert six .ensure_str (handler .headers ['content-type' ]) == 'application/json'
908+ assert json .loads (body )["baz" ] == "baf"
909+
910+ with MockServer (POST = check_response ):
911+ ctx = binding .connect (port = 9093 , scheme = 'http' , token = "waffle" , headers = [("Content-Type" , "application/json" )])
912+ ctx .post ("/" , foo = "bar" , body = '{"baz": "baf"}' )
913+
914+ def test_post_with_body_dict (self ):
915+ def check_response (handler ):
916+ length = int (handler .headers .get ('content-length' , 0 ))
917+ body = handler .rfile .read (length )
918+ assert six .ensure_str (handler .headers ['content-type' ]) == 'application/x-www-form-urlencoded'
919+ assert six .ensure_str (body ) == 'baz=baf&hep=cat'
920+
921+ with MockServer (POST = check_response ):
922+ ctx = binding .connect (port = 9093 , scheme = 'http' , token = "waffle" )
923+ ctx .post ("/" , foo = "bar" , body = {"baz" : "baf" , "hep" : "cat" })
924+
851925
852926if __name__ == "__main__" :
853927 try :
0 commit comments