summaryrefslogtreecommitdiffhomepage
path: root/benchmarks/suites/http.py
blob: ea9024e431ee898d6c598e50f70961557a5ff13d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
# python3
# Copyright 2019 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""HTTP benchmarks."""

from benchmarks import suites
from benchmarks.harness import machine
from benchmarks.workloads import ab


# pylint: disable=too-many-arguments
def http(server: machine.Machine,
         client: machine.Machine,
         workload: str,
         requests: int = 5000,
         connections: int = 10,
         port: int = 80,
         path: str = "notfound",
         **kwargs) -> str:
  """Run apachebench (ab) against an http server.

  Args:
    server: A machine object.
    client: A machine object.
    workload: The http-serving workload.
    requests: Number of requests to send the server. Default is 5000.
    connections: Number of concurent connections to use. Default is 10.
    port: The port to access in benchmarking.
    path: File to download, generally workload-specific.
    **kwargs: Additional container options.

  Returns:
    The full apachebench output.
  """
  # Pull the client & server.
  apachebench = client.pull("ab")
  netcat = client.pull("netcat")
  image = server.pull(workload)

  with server.container(image, port=port, **kwargs).detach() as container:
    (host, port) = container.address()
    # Wait for the server to come up.
    client.container(netcat).run(host=host, port=port)
    # Run the benchmark, no arguments.
    return client.container(apachebench).run(
        host=host,
        port=port,
        requests=requests,
        connections=connections,
        path=path)


# pylint: disable=too-many-arguments
# pylint: disable=too-many-locals
def http_app(server: machine.Machine,
             client: machine.Machine,
             workload: str,
             requests: int = 5000,
             connections: int = 10,
             port: int = 80,
             path: str = "notfound",
             **kwargs) -> str:
  """Run apachebench (ab) against an http application.

  Args:
    server: A machine object.
    client: A machine object.
    workload: The http-serving workload.
    requests: Number of requests to send the server. Default is 5000.
    connections: Number of concurent connections to use. Default is 10.
    port: The port to use for benchmarking.
    path: File to download, generally workload-specific.
    **kwargs: Additional container options.

  Returns:
    The full apachebench output.
  """
  # Pull the client & server.
  apachebench = client.pull("ab")
  netcat = client.pull("netcat")
  server_netcat = server.pull("netcat")
  redis = server.pull("redis")
  image = server.pull(workload)
  redis_port = 6379
  redis_name = "redis_server"

  with server.container(redis, name=redis_name).detach():
    server.container(server_netcat, links={redis_name: redis_name})\
        .run(host=redis_name, port=redis_port)
    with server.container(image, port=port, links={redis_name: redis_name}, **kwargs)\
            .detach(host=redis_name) as container:
      (host, port) = container.address()
      # Wait for the server to come up.
      client.container(netcat).run(host=host, port=port)
      # Run the benchmark, no arguments.
      return client.container(apachebench).run(
          host=host,
          port=port,
          requests=requests,
          connections=connections,
          path=path)


@suites.benchmark(metrics=[ab.transfer_rate, ab.latency], machines=2)
def httpd(*args, **kwargs) -> str:
  """Apache2 benchmark."""
  return http(*args, workload="httpd", port=80, **kwargs)


@suites.benchmark(
    metrics=[ab.transfer_rate, ab.latency, ab.requests_per_second], machines=2)
def nginx(*args, **kwargs) -> str:
  """Nginx benchmark."""
  return http(*args, workload="nginx", port=80, **kwargs)


@suites.benchmark(
    metrics=[ab.transfer_rate, ab.latency, ab.requests_per_second], machines=2)
def node(*args, **kwargs) -> str:
  """Node benchmark."""
  return http_app(*args, workload="node_template", path="", port=8080, **kwargs)


@suites.benchmark(
    metrics=[ab.transfer_rate, ab.latency, ab.requests_per_second], machines=2)
def ruby(*args, **kwargs) -> str:
  """Ruby benchmark."""
  return http_app(*args, workload="ruby_template", path="", port=9292, **kwargs)