Commits

Bryan O'Sullivan  committed f82a1f8

Initial commit

  • Participants

Comments (0)

Files changed (6)

+.*\.(?:aux|h[ip]|o|orig|out|pdf|prof|ps|rej)$
+^(?:dist|\.DS_Store)$
+^benchmarks/(?:AesonParse|AesonEncode|JsonParse|.*_p)$
+^tests/(?:qc)
+
+syntax: glob
+cabal-dev
+*~
+.*.swp
+.\#*
+\#*
+Copyright (c) 2011, MailRank, Inc.
+
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+
+1. Redistributions of source code must retain the above copyright
+   notice, this list of conditions and the following disclaimer.
+
+2. Redistributions in binary form must reproduce the above copyright
+   notice, this list of conditions and the following disclaimer in the
+   documentation and/or other materials provided with the distribution.
+
+3. Neither the name of the author nor the names of his contributors
+   may be used to endorse or promote products derived from this software
+   without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS ``AS IS'' AND ANY EXPRESS
+OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED.  IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR
+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.

File README.markdown

+# Welcome to http-load-tester
+
+`http-load-tester` is a small command line application for load
+testing web servers.  You can think of it as similar to `httperf` or
+`ab`, only it's more modern and simpler to deal with.
+
+# Join in!
+
+We are happy to receive bug reports, fixes, documentation enhancements,
+and other improvements.
+
+Please report bugs via the
+[github issue tracker](http://github.com/mailrank/http-load-tester/issues).
+
+Master [git repository](http://github.com/mailrank/http-load-tester):
+
+* `git clone git://github.com/mailrank/http-load-tester.git`
+
+There's also a [Mercurial mirror](http://bitbucket.org/bos/http-load-tester):
+
+* `hg clone http://bitbucket.org/bos/http-load-tester`
+
+(You can create and contribute changes using either git or Mercurial.)
+
+Authors
+-------
+
+This application is written and maintained by Bryan O'Sullivan,
+<bos@mailrank.com>.
+#!/usr/bin/env runhaskell
+> import Distribution.Simple
+> main = defaultMain

File http-load-tester.cabal

+name:                http-load-tester
+version:             0
+synopsis:            A small command line app for HTTP load testing
+description:
+  A small command line app for HTTP load testing.  You can think of it
+  as similar to `httperf` or `ab`, only it's more modern and simpler
+  to deal with.
+homepage:            https://github.com/mailrank/http-load-tester
+license:             BSD3
+license-file:        LICENSE
+author:              Bryan O'Sullivan <bos@mailrank.com>
+maintainer:          Bryan O'Sullivan <bos@mailrank.com>
+copyright:           2011 MailRank, Inc.
+category:            Network
+build-type:          Simple
+cabal-version:       >=1.8
+extra-source-files:  
+    README.markdown
+
+executable http-load-tester
+  hs-source-dirs: src
+  main-is:        LoadTester.hs
+
+  ghc-options: -threaded -rtsopts -Wall
+
+  build-depends:
+    base < 5,
+    bytestring,
+    cmdargs >= 0.7,
+    http-enumerator,
+    network,
+    time
+
+source-repository head
+  type:     git
+  location: git://github.com/mailrank/http-load-tester
+
+source-repository head
+  type:     mercurial
+  location: https://bitbucket.org/bos/http-load-tester

File src/LoadTester.hs

+{-# LANGUAGE BangPatterns, DeriveDataTypeable, RecordWildCards #-}
+
+module Main (main) where
+
+import Control.Concurrent
+import Control.Monad
+import Data.Time.Clock.POSIX
+import Network.HTTP.Enumerator
+import Network.Socket (withSocketsDo)
+import System.Console.CmdArgs
+
+data Args = Args {
+      concurrency :: Int
+    , num_requests :: Int
+    , requests_per_second :: Int
+    , url :: String
+    } deriving (Eq, Show, Typeable, Data)
+
+defaultArgs :: Args
+defaultArgs = Args {
+                concurrency = 1
+              , num_requests = 1
+              , requests_per_second = def
+              , url = def &= argPos 0
+              }
+
+main :: IO ()
+main = withSocketsDo $ do
+  Args{..} <- cmdArgs defaultArgs
+  req <- parseUrl url
+  let !interval | requests_per_second == 0 = 0
+                | otherwise = 1 / fromIntegral requests_per_second
+  withManager $ \mgr -> do
+    let loop !n now
+            | n == num_requests = return ()
+            | otherwise = do
+          httpLbs req mgr
+          now' <- getPOSIXTime
+          let elapsed = now' - now
+          when (elapsed < interval) $
+            threadDelay . truncate $ (interval - elapsed) * 1000000
+          loop (n+1) =<< getPOSIXTime
+    loop 0 =<< getPOSIXTime