I'm trying to test my application using python Locust, but I can't get a basic version to work. My locustfile.py file:
from locust import HttpLocust, TaskSet, task
class UserBehavior(TaskSet):
#task(1)
def test_get(self):
self.client.get("/")
class WebsiteUser(HttpLocust):
task_set = UserBehavior
min_wait=5000
max_wait=9000
I ran
locust --host=http://example.com
And got this error:
[2015-08-04 23:10:11,734] my-macbook-pro.local/ERROR/stderr: herror: [Errno 1] Unknown host
Wondering if it's just me putting in the wrong host, I tried facebook, google, and other hosts with no success either.
What am I doing wrong here?
You need to give -f locustfile.py parameters for running a file: locust -f locustfile.py --host=http://www.example.com
Alternatively, you can also declerate the host in locust class like in the below and run it locust -f locustfile.py:
from locust import HttpLocust, TaskSet, task
class UserBehavior(TaskSet):
#task(1)
def test_get(self):
self.client.get("/")
class WebsiteUser(HttpLocust):
task_set = UserBehavior
host = "http://www.example.com"
min_wait=5000
max_wait=9000
Related
I am very new to wsdl, asmx, client, zeep and other topics related to SOAP APIs, and I have to fix a system of "REST, SOAP APIs - service", made in Python by others.
Currently I am working only on my local machine. This is the main context:
In my project main folder myservice there are:
a service made with Tornado, myservice > myserviceSrv.py, and
a set of APIs whose logic is split into two scripts:
myservice > handlers > myservice_api.py: containing classes inerithing from tornado.web.RequestHandler, which contain posts methods calling the SOAP APIs in the externalcompany_myservice_api.py script.
myservice > handlers > externalcompany_myservice_api.py: containing a single class which contains the SOAP APIs methods that will call the externalcompany service SOAP APIs.
One of these methods is ping, and my aim is to make it work, that is, I want it to get the correct response when I launch a post with Postman.
In particular, the POST request from Postman should trigger the ping method of my service that should trigger the ping SOAP API that should trigger the corresponding SOAP API of the externalcompany service, which should answer back and in the end give me the post response.
A module containing some configurations myservice > config.py, mainly the ones bound to tornado.options, the wsdl files path, and the APIs urls.
This is the problem:
I start my server(/service) and then I lauch the POST with Postman to http://localhost:30205/service/ping (with no inputs), but this is the log and traceback that I get:
[I 2021-11-15 10:37:20.964 myserviceSrv:76] **************************************************
[I 2021-11-15 10:37:20.964 myserviceSrv:77] Starting externalcompany service 2021-11-15 10:37:20 on port 30205 for destination externalcompany
[I 2021-11-15 10:37:20.964 myserviceSrv:78] **************************************************
[I 2021-11-15 10:33:21.354 myserver_api:154] S - post Ping Handler
[I 2021-11-15 10:33:21.354 myserver_api:158] Destination Ping Handler: externalcompany
[I 2021-11-15 10:33:21.354 externalcompany_myserver_api:23] S - initialise wsdl
[W 2021-11-15 10:33:22.833 soap:218] Forcing soap:address location to HTTPS
[W 2021-11-15 10:33:22.833 soap:218] Forcing soap:address location to HTTPS
[I 2021-11-15 10:33:22.834 externalcompany_myserver_api:26] Created wsdl externalcompany connection
[I 2021-11-15 10:33:22.834 externalcompany_myserver_api:27] E - initialise wsdl
[E 2021-11-15 10:35:33.348 externalcompany_myserver_api:216] Exception error ping: HTTPSConnectionPool(host='10.90.XXX.YY', port=8080): Max retries exceeded with url: /WebServices/Api/SalesApi.asmx (Caused by NewConnectionError('<urllib3.connection.HTTPSConnection object at 0x7f3a5dfc4cd0>: Failed to establish a new connection: [Errno 110] Connection timed out'))
[I 2021-11-15 10:35:33.348 web:2239] 200 POST /service/ping (::1) 131994.51ms
and here are my questions:
I don't understand where that IP address 10.90.XXX.YY comes from. I can't find a reference to it into my entire project folder.
It looks like the code manages to initialize the wsdl, but then it cannot establish a connection. But why? What am I doing wrong, and how can I fix it?
Here is the content of:
myservice_api.py:
import tornado.web
from tornado import gen
import json
import logging
import config as config
class Ping(tornado.web.RequestHandler):
def initialize(self, **kwargs):
self.destination = kwargs["destination"]
#gen.coroutine
def post(self):
logging.info('S - post Ping Handler')
response = {}
# Data received
logging.info("Destination Ping Handler: {}".format(self.destination))
# Init module with correct destination - start specific method ping()
try:
# calls the class associated to key "destination" -> the class ("externalcompanymyserviceApi") is initialized
# init_wsdl is passed the wsdl sales file for settings
destination_object_init = config.destination_schema[self.destination]()
response = yield destination_object_init.ping()
except Exception as e:
logging.error("Error Ping Handler: {}".format(e))
raise gen.Return(self.write(response))
externalcompany_myservice_api.py:
import logging
import config as config
import json
import os
from tornado import gen
from zeep import Client, Settings, helpers
from zeep.exceptions import Fault, Error
from utils import utilities as utils
class externalcompanymyserviceApi:
def __init__(self):
# Init wsdl object for all methods in class externalcompany - utilities object
self.wsdl_object_sales = self.init_wsdl(config.WSDL_SALES)
# wsdl object
#staticmethod
def init_wsdl(type_wsdl):
logging.info("S - initialise wsdl")
settings = Settings(strict=False, xml_huge_tree=True)
wsdl_externalcompany = Client(wsdl=type_wsdl, settings=settings)
logging.info("Created wsdl externalcompany connection")
logging.info("E - initialise wsdl")
return wsdl_externalcompany
config.py
from tornado.options import define, parse_command_line
import logging
from handlers.externalcompany_myservice_api import externalcompanymyserviceApi
# LOGGING
logging.basicConfig(format='[%(levelname)1.1s %(asctime)s.%(msecs)03d %(module)s:%(lineno)d] %(message)s',
datefmt='%F %T')
# OPTIONS
# default: ip address of externalcompany (alias of externalcompany)
define("destination", default="externalcompany", help="destination of service", type=str)
# default: port of cash service intermediating with externalcompany
define("http_port", default=30205, help="run on the given port", type=int)
parse_command_line()
# SERVICE SETTINGS
DEBUG = True
######
# WSDL
######
# links to externalcompany test server
WSDL_PRODUCTS = "https://externalcompanyapi.vendorcompany.com/webservices/productservice_v1.asmx?WSDL"
WSDL_SALES = "https://externalcompanyapi.vendorcompany.com/WebServices/Api/SalesApi.asmx?WSDL"
# HANDLERS
PING = r"/service/ping"
# ...
destination_schema = {
"externalcompany": externalcompanymyserviceApi,
"John": "init class John"
}
myserviceSrv.py:
import config as cf
from config import PING
import logging
import tornado.web
from datetime import datetime
from tornado.log import enable_pretty_logging
from tornado.options import options
from tornado.ioloop import IOLoop
from tornado import httpserver
from handlers.myservice_api import Ping
#...
enable_pretty_logging()
class Destination_Service_Srv:
def __init__(self):
app = self.make_app()
self.http_server = self.make_server(app)
#staticmethod
def make_app():
settings = {
"debug": cf.DEBUG
}
return tornado.web.Application([
# ...
(PING, Ping, {"destination": options.destination})
], **settings)
#staticmethod
def make_server(app):
http_server = httpserver.HTTPServer(app, decompress_request=True)
http_server.listen(options.http_port)
return http_server
def start(self):
io_loop = IOLoop.current()
io_loop.start()
def stop(self):
io_loop = IOLoop.current()
io_loop.stop()
if __name__ == "__main__":
today = datetime.today().strftime("%Y-%m-%d %H:%M:%S")
myservice_server = Destination_Service_Srv()
try:
logging.info('**************************************************')
logging.info('Starting myservice service {} on port {} for destination {}'.format(today, options.http_port,
options.destination))
logging.info('**************************************************')
myservice_server.start()
except KeyboardInterrupt:
myservice_server.stop()
SOLVED
Turns out that the URLs stored inside variables WSDL_PRODUCTS and WSDL_SALES are wrong, because I can't access the corresponding wsdl files from my browser.
So I found out that the correct URLs are HTTP:// and not HTTPS://
WSDL_PRODUCTS = "http://externalcompanyapi.vendorcompany.com/webservices/productservice_v1.asmx?WSDL"
WSDL_SALES = "http://externalcompanyapi.vendorcompany.com/WebServices/Api/SalesApi.asmx?WSDL"
Now my post gets the corrrect response:
{"ping": {"MessageNo": 1001, "MessageText": "Ping Response", "MessageInfo": "Response from 'START' on '16/11/2021
10:20:31'", "IsSuccess": true, "Content": null}}
So, to answer my own questions:
The IP address 10.90.XXX.YY comes from the wsdl file whose URL is saved in WSDL_SALES.
If I get it right, zeep initialized the wsdl, but it did it following the HTTPS protocol, so that the traceback indicated
[W 2021-11-15 10:33:22.833 soap:218] Forcing soap:address location to HTTPS
[W 2021-11-15 10:33:22.833 soap:218] Forcing soap:address location to HTTPS
and so the connection was configured for the invalid wsdl URL.
This was the line failing
zeep_response = helpers.serialize_object(self.wsdl_object_sales.service.Ping())
because the POST could not get a response, so the zeep serializer could not process an empty response.
I need to test some APIs having different addresses, I have created locustfile for Locust Tool as mentioned below, but only api1 is working, endpoints in api2 are not being called
from locust import HttpUser, task, between
class api1(HttpUser):
host = 'http://localhost:6001'
wait_time = between(2, 4)
#task()
def api1_ep1(self):
self.client.post('/ep1')
#task()
def api1_ep2(self):
self.client.post('/ep2')
class api2(HttpUser):
host = 'http://localhost:6002'
wait_time = between(2, 4)
#task()
def api2_ep1(self):
self.client.post('/ep1')
#task()
def api2_ep2(self):
self.client.post('/ep2')
I tried suggestions from issue: 150 and put full path as self.client.post('http://localhost:6001/ep1') but the same problem persists
I was spawning single user, spawning more users fixed the probem
I wanted to test Locust for my Project on Windows 10.
The Script seems to run properly (no Errors in CMD), but i can't connect to the web interface http://127.0.0.1:8089 (ERR_CONNECTION_REFUSED).
I am guessing, that this has to do with Browser/Windows config, but i can't find the problem. I have no Proxy set up in Lan settings, i get my ip from DNS, and i have no changes in my hosts file.
locustfile.py
from locust import HttpLocust, TaskSet, task
class UserBehavior(TaskSet):
def on_start(self):
""" on_start is called when a Locust start before any task is scheduled """
self.login()
def on_stop(self):
""" on_stop is called when the TaskSet is stopping """
self.logout()
def login(self):
self.client.post("/login", {"username":"tester", "password":"abcd1234"})
def logout(self):
self.client.post("/logout", {"username":"ellen_key", "password":"education"})
#task(2)
def index(self):
self.client.get("/")
#task(1)
def profile(self):
self.client.get("/profile")
class WebsiteUser(HttpLocust):
task_set = UserBehavior
min_wait = 5000
max_wait = 9000
host="http://google.com"
CMD
D:\workspace\WebTesting>locust
CMD result :
[2019-05-13 09:49:45,069] LB6-001-DTMH/INFO/locust.main: Starting web monitor at *:8089
[2019-05-13 09:49:45,070] LB6-001-DTMH/INFO/locust.main: Starting Locust 0.11.0
When i interrupt the script in the command line i get the "KeyboardInterrupt" message and some statistics without data
python -m http.server 8089 seems to work
Try going to http://localhost:8089/
I am not quite sure why, but I can't reach the Locust webinterface through http://127.0.0.1 either (other webservers run fine locally with this address), but going to localhost does work for me.
I faced a similar issue. Instead of using IP address, try using localhost.
http://localhost:portnumber -> http://localhost:8089. This solved the issue for me.
When trying to test the admin login using the following code, I found the self.live_server_url returns something like http://localhost:39346, where the port number is different on each running.
from django.test import LiveServerTestCase
from selenium import webdriver
class AdminLoginTests(LiveServerTestCase):
def setUp(self):
self.selenium = webdriver.Firefox()
super(AdminLoginTests, self).setUp()
def tearDown(self):
self.selenium.quit()
super(AdminLoginTests, self).tearDown()
def test_admin_login(self):
# ...
print('url: %s' %self.live_server_url)
How do I get the correct port number 8000 of the running server? Suppose I run the server through python manage.py runserver 0.0.0.0:8000. Thanks!
LiveServerTestCase spawns a new instance with that port on purpose. That way you can test a production environment without having to shutdown the production server (which by default runs on 8000).
However if you want to change the port that the debug is running on you can initialize to a different port number.
class TempTest(LiveServerTestCase):
def __init__(self):
super(TempTest, self).__init__()
self.port = 8910
def setUp(self)
# ....
This is what works for me under Django version 1.11.26
class TempTest(LiveServerTestCase):
port = 8888
host = "0.0.0.0" # If you want your test server to be public
I am using the following script from the Twisted tutorial (with slight modification):
from twisted.application import internet, service
from twisted.internet import reactor, protocol, defer
from twisted.protocols import basic
from twisted.web import client
class FingerProtocol(basic.LineReceiver):
def lineReceived(self, user):
d = self.factory.getUser(user)
def onError(err):
return "Internal server error"
d.addErrback(onError)
def writeResponse(message):
self.transport.write(message + "\r\n")
self.transport.loseConnection()
d.addCallback(writeResponse)
class FingerFactory(protocol.ServerFactory):
protocol = FingerProtocol
def __init__(self, prefix):
self.prefix = prefix
def getUser(self, user):
return client.getPage(self.prefix + user)
application = service.Application('finger', uid=1, gid=1)
factory = FingerFactory(prefix="http://livejournal.com/~")
internet.TCPServer(7979, factory).setServiceParent(
service.IServiceCollection(application))
which I save as finger_daemon.tac and run with
twistd -y finger_daemon.tac \
-l /home/me/twisted/finger.log \
--pidfile=/home/me/twisted/finger.pid
but of course it won't bind to 79, since it's a privileged port. I tried also running with sudo, no difference there.
I then tried changing the TCPServer port to 7979 and then connecting to the daemon once running with
telnet 127.0.0.1 7979
and I get Connection Refused error. What's going on here specifically? How is daemonizing supposed to work in Twisted?
When I run this code, I see the following log message:
2013-10-02 23:50:34-0700 [-] failed to set uid/gid 1/1 (are you root?) -- exiting.
and then twistd exits. So you'd need to do sudo twistd and then that adds a whole bunch of python path management problems...
Why are you setting the uid and gid arguments? You're trying to run it as the daemon user? You don't need to do that in order to daemonize. Just removing the uid=1, gid=1 arguments to Application makes it work for me.