locustfile_tileImage.py

111 lines | 3.422 kB Blame History Raw Download
# Purpose: Response times from exportImage REST Endpoint

from locust import HttpLocust, TaskSet, task
import random
import json
import locustEvents
import time
import webui
import resource
import math
from random import randint
from pyproj import Proj, transform

# Host
service_host = "http://imagery.oregonexplorer.info"
# Routes for ArcGIS Server
routes = {
    "1995": "/arcgis/rest/services/NAIP_1995/NAIP_1995_WM/ImageServer/",
    "2000": "/arcgis/rest/services/NAIP_2000/NAIP_2000_WM/ImageServer/",
    "2005": "/arcgis/rest/services/NAIP_2005/NAIP_2005_WM/ImageServer/",
    "2009": "/arcgis/rest/services/NAIP_2009/NAIP_2009_WM/ImageServer/",
    "2011": "/arcgis/rest/services/NAIP_2011/NAIP_2011_WM/ImageServer/",
    "pictometry": "/arcgis/rest/services/Pictometry/BestofPictometry/ImageServer/",
    "hillshade": "/arcgis/rest/services/Derived_surfaces/Hillshade_derivedsurfaces/ImageServer/"
}

# Convert lat, lon, and zoom to tile numbers
def deg2num(lat_deg, lon_deg, zoom):
  lat_rad = math.radians(lat_deg)
  n = 2.0 ** zoom
  xtile = int((lon_deg + 180.0) / 360.0 * n)
  ytile = int((1.0 - math.log(math.tan(lat_rad) + (1 / math.cos(lat_rad))) / math.pi) / 2.0 * n)
  return (xtile, ytile)

class UserBehavior(TaskSet):

    extent=None

    def on_start(self):
        # @Assumption
        # All services are same extent
        if self.extent is None:
            with self.client.post(routes['1995'],{'f':'json'}, catch_response=True) as response:
                try:
                    params = json.loads(response.content)
                except:
                    locustEvents.reqError.fire(message='Bad Response Content - Definition')
                    response.failure('Could not parse json')
                    return

                self.extent = params['extent']


    def baseQuery(self, route):
        x1 = random.uniform(self.extent['xmin'], self.extent['xmax'])
        x2 = random.uniform(x1, self.extent['xmax'])
        y1 = random.uniform(self.extent['ymin'], self.extent['ymax'])
        y2 = y1 + (x2-x1) #create a square envelope

        #https://gis.stackexchange.com/questions/78838/converting-projected-coordinates-to-lat-lon-using-python/78944
        inProj = Proj(init='epsg:3857')
        outProj = Proj(init='epsg:4326')
        x1p,y1p = x1,y1
        x2p,y2p = transform(inProj,outProj,x1p,y1p)

        #format /tile/zoom/x/y.png
        #http://wiki.openstreetmap.org/wiki/Slippy_map_tilenames

        zoom = randint(1, 17)
        (xtile, ytile) = deg2num(y2p, x2p, zoom)

        #print route+'tile/'+ str(zoom) + "/" + str(ytile) + "/" + str(xtile)

        self.client.get(route+'tile/'+ str(zoom) + "/" + str(ytile) + "/" + str(xtile), name=route)

    @task(2)
    def service1(self):
        self.baseQuery(routes['1995'])

    @task(3)
    def service2(self):
        self.baseQuery(routes['2000'])

    @task(5)
    def service3(self):
        self.baseQuery(routes['2005'])

    @task(10)
    def service4(self):
        self.baseQuery(routes['2009'])

    @task(15)
    def service5(self):
        self.baseQuery(routes['2011'])

    @task(60)
    def service6(self):
        self.baseQuery(routes['pictometry'])

    @task(5)
    def service7(self):
        self.baseQuery(routes['hillshade'])

class WebsiteUser(HttpLocust):
    host = service_host
    task_set = UserBehavior
    # Assume most users wait about 0.1 - 2 seconds  between requests
    # when browsing imagery
    min_wait = 0.1 * 1000
    max_wait = 2 * 1000