Quick Start: Git for personal use
SVN client over SSH to remote Unix server from Windows
Quick Start Grinder - Part V
Quick Start Grinder - Part IV
Quick Start Grinder - Part III
« Quick Start Grinder - Part I
» Gloomy and boring weekend
We will do a simple project of doing a Google search for Grinder. You need to have some fundamental knowledge about HTTP requests, GET, POST, headers etc.
Parts I and III of the series.
Choose a directory to setup your sources. Let us say it is c:\projects\grindersample. Now, create the following directories inside that.
# # # vim: ts=2:et:sw=2:ai:sm:nolist:foldmethod=indent: # google_search.py # standard Grinder imports from net.grinder.script import Test from net.grinder.script.Grinder import grinder from net.grinder.plugin.http import HTTPPluginControl, HTTPRequest from HTTPClient import Codecs, NVPair #add any specific modules you want to import; like regex #~ import re #### define other global variables you may need inside your script #this is the main site we are going to test. The URL should point only #to the server:port part. It should not have path within the server. #reason : we will make a request object to this and then reuse that object # for subsequent calls. url_test = "http://www.google.co.in" #if you are behind proxy, fill this up with address and port. If you don’t, #keep it as empty proxy_server = ("10.11.20.44", 80) #proxy_server = () #in general, you shouldn’t be coding your websites looking at difference in #headers; so we will use just one header. Note that this will fail if you use #values of things like Referer within your server side code for logical #decision making. common_header= ( NVPair('Accept', '*/*'), NVPair('Cache-Control', 'no-cache'), ) #### #couple of variables that will be of use to identify which agent and #process are running, within the script agentID = int(grinder.properties["grinder.agentID"]) processID = int(grinder.processName.split("-").pop()) #utility function shortcuts. Use this instead of print or system.out.println log = grinder.logger.output error = grinder.logger.error connectionDefaults = HTTPPluginControl.getConnectionDefaults() httpUtilities = HTTPPluginControl.getHTTPUtilities() if len(proxy_server)>=2: connectionDefaults.setProxyServer(proxy_server[0], proxy_server[1]) log("** Set proxy server") # we will just use default stuff connectionDefaults.defaultHeaders = ( NVPair('User-Agent', 'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 1.1.4322; .NET CLR 2.0.50727; .NET CLR 3.0.04506.30; .NET CLR 3.0.04506.648; InfoPath.1)'), NVPair('Accept-Encoding', 'gzip, deflate'), NVPair('Accept-Language', 'en-us'), ) #this is the request that we will reuse for all our testing rq_test = HTTPRequest(url=url_test, headers=common_header) class TestRunner: """A TestRunner instance is created for each worker thread.""" def __call__(self): """This method is called for every run performed by the worker thread.""" log("agentID %s, processID %s, threadID %s" % (agentID, processID, grinder.threadNumber)) #this is the first test - getting the search form self.doGetSearchPage() #this is the second one - actually searching for data self.doSearch("GRINDER") def doGetSearchPage(self): """Fetch the search form from Google""" #google page is the root level page log("**Get the search form") result = rq_test.GET("/") #now, there are a bunch of images, stylesheets etc. in this page. #Browser will get those normally, so if your intention is to test #the whole thing, we should get all that too. For now, we will just #get the logo. result = rq_test.GET("/intl/en_com/images/logo_plain.png") log("**Got the search form") def doSearch(self, search_for=''): """Send the search request too Google and get the resultant page""" if search_for.strip() == '': return #let us not bother Google unnecessarily #Google has one form that searches for a given string using GET #request is like search?hl=en&source=hp&q=GRINDER&btnG=Google+Search&meta=&aq=f&oq= log("**Sending request for %s" % search_for) result = rq_test.GET("search?hl=en&source=hp&q=%s&btnG=Google+Search&meta=&aq=f&oq=" % search_for) #now also we need to get stuff like adsense, images etc. #we will skip that because we will assume that all we are interested #is in figuring out how to test the search component and not the #paraphernalia around it. log("**Got results %s" % search_for) def instrumentMethod(test, method_name, c=TestRunner): """Instrument a method with the given Test.""" unadorned = getattr(c, method_name) import new method = new.instancemethod(test.wrap(unadorned), None, c) setattr(c, method_name, method) # Replace each method with an instrumented version. # The first parameter is a test id. I usually let it run from 100 to 1000 # That gives you enough space to insert new tests in between instrumentMethod(Test(100, 'Get Google Search Page'), 'doGetSearchPage') instrumentMethod(Test(150, 'Do Search'), 'doSearch')
#name of the script that executes the test grinder.script=google_search.py # we will run it as a single process grinder.processes=1 # and a single thread within the procesds grinder.threads=1 #run the test once and exit grinder.runs=1 #agentID, if you are running this from different agents grinder.agentID=1 #if you run into memory issues, tweak the java options grinder.jvm.arguments = -Dpython.home=c:/tools/jython -Dpython.cachedir=c:/tools/grinder/cachedir -Xms32m -Xmx32m grinder.logDirectory=log/
We need to prepare a grinder.properties file in the project folder. Here is how mine looks.
Open two console windows (Windows - Run - cmd) and navigate to the project directory
In one, run bin\startConsole.cmd. Wait for few seconds and run bin\startAgent.cmd in the other one. After some time, you can see the Grinder console open up.
In the console, go to Distribute - Set Directory and choose your project directory. Now, when you click on the Script tab, you should see your files in an Explorer like form. Double click on grinder.properties and google_search.py to open those. Now do a Distribute - Distribute Files to deploy the files to Grinder agent - you can see whether this got done or not by looking at the text that just scrolled by in the second console window.
Note : whenever you change any of the sources or properties, you need to do the Distribute again.
Now, click on the play icon and see the script executing. If things are not working, you might want to stop data collection and start again before executing the script again.
In the Graph tab, you can see how long it took to run each test. Similarly, the output of your log
and error
calls
can be seen under log sub directory. For each run, there are also