mirror of https://github.com/grpc/grpc.git
commit
5dec6e0e75
74 changed files with 19885 additions and 308 deletions
@ -0,0 +1,61 @@ |
||||
/* |
||||
* |
||||
* Copyright 2016, Google 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: |
||||
* |
||||
* * Redistributions of source code must retain the above copyright |
||||
* notice, this list of conditions and the following disclaimer. |
||||
* * 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. |
||||
* * Neither the name of Google Inc. nor the names of its |
||||
* contributors may be used to endorse or promote products derived from |
||||
* this software without specific prior written permission. |
||||
* |
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 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 COPYRIGHT |
||||
* OWNER 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. |
||||
* |
||||
*/ |
||||
|
||||
'use strict'; |
||||
|
||||
var grpc = require('../../..'); |
||||
|
||||
var proto = grpc.load(__dirname + '/../../proto/grpc/testing/metrics.proto'); |
||||
var metrics = proto.grpc.testing; |
||||
|
||||
function main() { |
||||
var parseArgs = require('minimist'); |
||||
var argv = parseArgs(process.argv, { |
||||
string: 'metrics_server_address', |
||||
boolean: 'total_only' |
||||
}); |
||||
var client = new metrics.MetricsService(argv.metrics_server_address, |
||||
grpc.credentials.createInsecure()); |
||||
if (argv.total_only) { |
||||
client.getGauge({name: 'qps'}, function(err, data) { |
||||
console.log(data.name + ':', data.long_value); |
||||
}); |
||||
} else { |
||||
var call = client.getAllGauges({}); |
||||
call.on('data', function(data) { |
||||
console.log(data.name + ':', data.long_value); |
||||
}); |
||||
} |
||||
} |
||||
|
||||
main(); |
@ -0,0 +1,87 @@ |
||||
/* |
||||
* |
||||
* Copyright 2016, Google 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: |
||||
* |
||||
* * Redistributions of source code must retain the above copyright |
||||
* notice, this list of conditions and the following disclaimer. |
||||
* * 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. |
||||
* * Neither the name of Google Inc. nor the names of its |
||||
* contributors may be used to endorse or promote products derived from |
||||
* this software without specific prior written permission. |
||||
* |
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 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 COPYRIGHT |
||||
* OWNER 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. |
||||
* |
||||
*/ |
||||
|
||||
'use strict'; |
||||
|
||||
var _ = require('lodash'); |
||||
|
||||
var grpc = require('../../..'); |
||||
|
||||
var proto = grpc.load(__dirname + '/../../proto/grpc/testing/metrics.proto'); |
||||
var metrics = proto.grpc.testing; |
||||
|
||||
function getGauge(call, callback) { |
||||
/* jshint validthis: true */ |
||||
// Should be bound to a MetricsServer object
|
||||
var name = call.request.name; |
||||
if (this.gauges.hasOwnProperty(name)) { |
||||
callback(null, _.assign({name: name}, this.gauges[name]())); |
||||
} else { |
||||
callback({code: grpc.status.NOT_FOUND, |
||||
details: 'No such gauge: ' + name}); |
||||
} |
||||
} |
||||
|
||||
function getAllGauges(call) { |
||||
/* jshint validthis: true */ |
||||
// Should be bound to a MetricsServer object
|
||||
_.each(this.gauges, function(getter, name) { |
||||
call.write(_.assign({name: name}, getter())); |
||||
}); |
||||
call.end(); |
||||
} |
||||
|
||||
function MetricsServer(port) { |
||||
var server = new grpc.Server(); |
||||
server.addProtoService(metrics.MetricsService.service, { |
||||
getGauge: _.bind(getGauge, this), |
||||
getAllGauges: _.bind(getAllGauges, this) |
||||
}); |
||||
server.bind('localhost:' + port, grpc.ServerCredentials.createInsecure()); |
||||
this.server = server; |
||||
this.gauges = {}; |
||||
} |
||||
|
||||
MetricsServer.prototype.start = function() { |
||||
this.server.start(); |
||||
} |
||||
|
||||
MetricsServer.prototype.registerGauge = function(name, getter) { |
||||
this.gauges[name] = getter; |
||||
}; |
||||
|
||||
MetricsServer.prototype.shutdown = function() { |
||||
this.server.forceShutdown(); |
||||
}; |
||||
|
||||
module.exports = MetricsServer; |
@ -0,0 +1,126 @@ |
||||
/* |
||||
* |
||||
* Copyright 2016, Google 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: |
||||
* |
||||
* * Redistributions of source code must retain the above copyright |
||||
* notice, this list of conditions and the following disclaimer. |
||||
* * 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. |
||||
* * Neither the name of Google Inc. nor the names of its |
||||
* contributors may be used to endorse or promote products derived from |
||||
* this software without specific prior written permission. |
||||
* |
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 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 COPYRIGHT |
||||
* OWNER 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. |
||||
* |
||||
*/ |
||||
|
||||
'use strict'; |
||||
|
||||
var _ = require('lodash'); |
||||
|
||||
var grpc = require('../../..'); |
||||
|
||||
var interop_client = require('../interop/interop_client'); |
||||
var MetricsServer = require('./metrics_server'); |
||||
|
||||
var running; |
||||
|
||||
var metrics_server; |
||||
|
||||
var start_time; |
||||
var query_count; |
||||
|
||||
function makeCall(client, test_cases) { |
||||
if (!running) { |
||||
return; |
||||
} |
||||
var test_case = test_cases[_.random(test_cases.length - 1)]; |
||||
interop_client.test_cases[test_case].run(client, function() { |
||||
query_count += 1; |
||||
makeCall(client, test_cases); |
||||
}); |
||||
} |
||||
|
||||
function makeCalls(client, test_cases, parallel_calls_per_channel) { |
||||
_.times(parallel_calls_per_channel, function() { |
||||
makeCall(client, test_cases); |
||||
}); |
||||
} |
||||
|
||||
function getQps() { |
||||
var diff = process.hrtime(start_time); |
||||
var seconds = diff[0] + diff[1] / 1e9; |
||||
return {long_value: query_count / seconds}; |
||||
} |
||||
|
||||
function start(server_addresses, test_cases, channels_per_server, |
||||
parallel_calls_per_channel, metrics_port) { |
||||
running = true; |
||||
/* Assuming that we are not calling unimplemented_method. The client class |
||||
* used by empty_unary is (currently) the client class used by every interop |
||||
* test except unimplemented_method */ |
||||
var Client = interop_client.test_cases.empty_unary.Client; |
||||
/* Make channels_per_server clients connecting to each server address */ |
||||
var channels = _.flatten(_.times( |
||||
channels_per_server, _.partial(_.map, server_addresses, function(address) { |
||||
return new Client(address, grpc.credentials.createInsecure()); |
||||
}))); |
||||
metrics_server = new MetricsServer(metrics_port); |
||||
metrics_server.registerGauge('qps', getQps); |
||||
start_time = process.hrtime(); |
||||
query_count = 0; |
||||
_.each(channels, _.partial(makeCalls, _, test_cases, |
||||
parallel_calls_per_channel)); |
||||
metrics_server.start(); |
||||
} |
||||
|
||||
function stop() { |
||||
running = false; |
||||
metrics_server.shutdown(); |
||||
console.log('QPS: ' + getQps().long_value); |
||||
} |
||||
|
||||
function main() { |
||||
var parseArgs = require('minimist'); |
||||
var argv = parseArgs(process.argv, { |
||||
string: ['server_addresses', 'test_cases', 'metrics_port'], |
||||
default: {'server_addresses': 'localhost:8080', |
||||
'test_duration-secs': -1, |
||||
'num_channels_per_server': 1, |
||||
'num_stubs_per_channel': 1, |
||||
'metrics_port': '8081'} |
||||
}); |
||||
var server_addresses = argv.server_addresses.split(','); |
||||
/* Generate an array of test cases, where the number of instances of each name |
||||
* corresponds to the number given in the argument. |
||||
* e.g. 'empty_unary:1,large_unary:2' => |
||||
* ['empty_unary', 'large_unary', 'large_unary'] */ |
||||
var test_cases = _.flatten(_.map(argv.test_cases.split(','), function(value) { |
||||
var split = value.split(':'); |
||||
return _.times(split[1], _.constant(split[0])); |
||||
})); |
||||
start(server_addresses, test_cases, argv.num_channels_per_server, |
||||
argv.num_stubs_per_channel, argv.metrics_port); |
||||
if (argv['test_duration-secs'] > -1) { |
||||
setTimeout(stop, argv['test_duration-secs'] * 1000); |
||||
} |
||||
} |
||||
|
||||
main(); |
@ -0,0 +1,164 @@ |
||||
#!/usr/bin/env ruby |
||||
|
||||
# Copyright 2016, Google 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: |
||||
# |
||||
# * Redistributions of source code must retain the above copyright |
||||
# notice, this list of conditions and the following disclaimer. |
||||
# * 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. |
||||
# * Neither the name of Google Inc. nor the names of its |
||||
# contributors may be used to endorse or promote products derived from |
||||
# this software without specific prior written permission. |
||||
# |
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 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 COPYRIGHT |
||||
# OWNER 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. |
||||
|
||||
# Worker and worker service implementation |
||||
|
||||
this_dir = File.expand_path(File.dirname(__FILE__)) |
||||
lib_dir = File.join(File.dirname(this_dir), 'lib') |
||||
$LOAD_PATH.unshift(lib_dir) unless $LOAD_PATH.include?(lib_dir) |
||||
$LOAD_PATH.unshift(this_dir) unless $LOAD_PATH.include?(this_dir) |
||||
|
||||
require 'grpc' |
||||
require 'histogram' |
||||
require 'src/proto/grpc/testing/services_services' |
||||
|
||||
class Poisson |
||||
def interarrival |
||||
@lambda_recip * (-Math.log(1.0-rand)) |
||||
end |
||||
def advance |
||||
t = @next_time |
||||
@next_time += interarrival |
||||
t |
||||
end |
||||
def initialize(lambda) |
||||
@lambda_recip = 1.0/lambda |
||||
@next_time = Time.now + interarrival |
||||
end |
||||
end |
||||
|
||||
class BenchmarkClient |
||||
def initialize(config) |
||||
opts = {} |
||||
if config.security_params |
||||
if config.security_params.use_test_ca |
||||
certs = load_test_certs |
||||
cred = GRPC::Core::ChannelCredentials.new(certs[0]) |
||||
else |
||||
cred = GRPC::Core::ChannelCredentials.new() |
||||
end |
||||
if config.security_params.server_host_override |
||||
opts[GRPC::Core::Channel::SSL_TARGET] = |
||||
config.security_params.server_host_override |
||||
end |
||||
else |
||||
cred = :this_channel_is_insecure |
||||
end |
||||
@histres = config.histogram_params.resolution |
||||
@histmax = config.histogram_params.max_possible |
||||
@start_time = Time.now |
||||
@histogram = Histogram.new(@histres, @histmax) |
||||
@done = false |
||||
|
||||
gtsr = Grpc::Testing::SimpleRequest |
||||
gtpt = Grpc::Testing::PayloadType |
||||
gtp = Grpc::Testing::Payload |
||||
simple_params = config.payload_config.simple_params |
||||
req = gtsr.new(response_type: gtpt::COMPRESSABLE, |
||||
response_size: simple_params.resp_size, |
||||
payload: gtp.new(type: gtpt::COMPRESSABLE, |
||||
body: nulls(simple_params.req_size))) |
||||
|
||||
(0..config.client_channels-1).each do |chan| |
||||
gtbss = Grpc::Testing::BenchmarkService::Stub |
||||
st = config.server_targets |
||||
stub = gtbss.new(st[chan % st.length], cred, **opts) |
||||
(0..config.outstanding_rpcs_per_channel-1).each do |r| |
||||
Thread.new { |
||||
case config.load_params.load.to_s |
||||
when 'closed_loop' |
||||
waiter = nil |
||||
when 'poisson' |
||||
waiter = Poisson.new(config.load_params.poisson.offered_load / |
||||
(config.client_channels * |
||||
config.outstanding_rpcs_per_channel)) |
||||
end |
||||
case config.rpc_type |
||||
when :UNARY |
||||
unary_ping_ponger(req,stub,config,waiter) |
||||
when :STREAMING |
||||
streaming_ping_ponger(req,stub,config,waiter) |
||||
end |
||||
} |
||||
end |
||||
end |
||||
end |
||||
def wait_to_issue(waiter) |
||||
if waiter |
||||
delay = waiter.advance-Time.now |
||||
sleep delay if delay > 0 |
||||
end |
||||
end |
||||
def unary_ping_ponger(req, stub, config,waiter) |
||||
while !@done |
||||
wait_to_issue(waiter) |
||||
start = Time.now |
||||
resp = stub.unary_call(req) |
||||
@histogram.add((Time.now-start)*1e9) |
||||
end |
||||
end |
||||
def streaming_ping_ponger(req, stub, config, waiter) |
||||
q = EnumeratorQueue.new(self) |
||||
resp = stub.streaming_call(q.each_item) |
||||
start = Time.now |
||||
q.push(req) |
||||
resp.each do |r| |
||||
@histogram.add((Time.now-start)*1e9) |
||||
if !@done |
||||
wait_to_issue(waiter) |
||||
start = Time.now |
||||
q.push(req) |
||||
else |
||||
q.push(self) |
||||
break |
||||
end |
||||
end |
||||
end |
||||
def mark(reset) |
||||
lat = Grpc::Testing::HistogramData.new( |
||||
bucket: @histogram.contents, |
||||
min_seen: @histogram.minimum, |
||||
max_seen: @histogram.maximum, |
||||
sum: @histogram.sum, |
||||
sum_of_squares: @histogram.sum_of_squares, |
||||
count: @histogram.count |
||||
) |
||||
elapsed = Time.now-@start_time |
||||
if reset |
||||
@start_time = Time.now |
||||
@histogram = Histogram.new(@histres, @histmax) |
||||
end |
||||
Grpc::Testing::ClientStats.new(latencies: lat, time_elapsed: elapsed) |
||||
end |
||||
def shutdown |
||||
@done = true |
||||
end |
||||
end |
@ -0,0 +1,88 @@ |
||||
#!/usr/bin/env ruby |
||||
|
||||
# Copyright 2016, Google 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: |
||||
# |
||||
# * Redistributions of source code must retain the above copyright |
||||
# notice, this list of conditions and the following disclaimer. |
||||
# * 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. |
||||
# * Neither the name of Google Inc. nor the names of its |
||||
# contributors may be used to endorse or promote products derived from |
||||
# this software without specific prior written permission. |
||||
# |
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 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 COPYRIGHT |
||||
# OWNER 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. |
||||
|
||||
# Histogram class for use in performance testing and measurement |
||||
|
||||
class Histogram |
||||
# Determine the bucket index for a given value |
||||
# @param {number} value The value to check |
||||
# @return {number} The bucket index |
||||
def bucket_for(value) |
||||
(Math.log(value)/Math.log(@multiplier)).to_i |
||||
end |
||||
# Initialize an empty histogram |
||||
# @param {number} resolution The resolution of the histogram |
||||
# @param {number} max_possible The maximum value for the histogram |
||||
def initialize(resolution, max_possible) |
||||
@resolution=resolution |
||||
@max_possible=max_possible |
||||
@sum=0 |
||||
@sum_of_squares=0 |
||||
@multiplier=1+resolution |
||||
@count=0 |
||||
@min_seen=max_possible |
||||
@max_seen=0 |
||||
@buckets=Array.new(bucket_for(max_possible)+1, 0) |
||||
end |
||||
# Add a value to the histogram. This updates all statistics with the new |
||||
# value. Those statistics should not be modified except with this function |
||||
# @param {number} value The value to add |
||||
def add(value) |
||||
@sum += value |
||||
@sum_of_squares += value * value |
||||
@count += 1 |
||||
if value < @min_seen |
||||
@min_seen = value |
||||
end |
||||
if value > @max_seen |
||||
@max_seen = value |
||||
end |
||||
@buckets[bucket_for(value)] += 1 |
||||
end |
||||
def minimum |
||||
@min_seen |
||||
end |
||||
def maximum |
||||
@max_seen |
||||
end |
||||
def sum |
||||
@sum |
||||
end |
||||
def sum_of_squares |
||||
@sum_of_squares |
||||
end |
||||
def count |
||||
@count |
||||
end |
||||
def contents |
||||
@buckets |
||||
end |
||||
end |
@ -0,0 +1,76 @@ |
||||
#!/usr/bin/env ruby |
||||
|
||||
# Copyright 2016, Google 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: |
||||
# |
||||
# * Redistributions of source code must retain the above copyright |
||||
# notice, this list of conditions and the following disclaimer. |
||||
# * 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. |
||||
# * Neither the name of Google Inc. nor the names of its |
||||
# contributors may be used to endorse or promote products derived from |
||||
# this software without specific prior written permission. |
||||
# |
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 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 COPYRIGHT |
||||
# OWNER 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. |
||||
|
||||
# Worker and worker service implementation |
||||
|
||||
this_dir = File.expand_path(File.dirname(__FILE__)) |
||||
lib_dir = File.join(File.dirname(this_dir), 'lib') |
||||
$LOAD_PATH.unshift(lib_dir) unless $LOAD_PATH.include?(lib_dir) |
||||
$LOAD_PATH.unshift(this_dir) unless $LOAD_PATH.include?(this_dir) |
||||
|
||||
require 'grpc' |
||||
|
||||
# produces a string of null chars (\0 aka pack 'x') of length l. |
||||
def nulls(l) |
||||
fail 'requires #{l} to be +ve' if l < 0 |
||||
[].pack('x' * l).force_encoding('ascii-8bit') |
||||
end |
||||
|
||||
# load the test-only certificates |
||||
def load_test_certs |
||||
this_dir = File.expand_path(File.dirname(__FILE__)) |
||||
data_dir = File.join(File.dirname(this_dir), 'spec/testdata') |
||||
files = ['ca.pem', 'server1.key', 'server1.pem'] |
||||
files.map { |f| File.open(File.join(data_dir, f)).read } |
||||
end |
||||
|
||||
# A EnumeratorQueue wraps a Queue yielding the items added to it via each_item. |
||||
class EnumeratorQueue |
||||
extend Forwardable |
||||
def_delegators :@q, :push |
||||
|
||||
def initialize(sentinel) |
||||
@q = Queue.new |
||||
@sentinel = sentinel |
||||
end |
||||
|
||||
def each_item |
||||
return enum_for(:each_item) unless block_given? |
||||
loop do |
||||
r = @q.pop |
||||
break if r.equal?(@sentinel) |
||||
fail r if r.is_a? Exception |
||||
yield r |
||||
end |
||||
end |
||||
end |
||||
|
||||
|
@ -0,0 +1,91 @@ |
||||
#!/usr/bin/env ruby |
||||
|
||||
# Copyright 2016, Google 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: |
||||
# |
||||
# * Redistributions of source code must retain the above copyright |
||||
# notice, this list of conditions and the following disclaimer. |
||||
# * 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. |
||||
# * Neither the name of Google Inc. nor the names of its |
||||
# contributors may be used to endorse or promote products derived from |
||||
# this software without specific prior written permission. |
||||
# |
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 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 COPYRIGHT |
||||
# OWNER 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. |
||||
|
||||
# Worker and worker service implementation |
||||
|
||||
this_dir = File.expand_path(File.dirname(__FILE__)) |
||||
lib_dir = File.join(File.dirname(this_dir), 'lib') |
||||
$LOAD_PATH.unshift(lib_dir) unless $LOAD_PATH.include?(lib_dir) |
||||
$LOAD_PATH.unshift(this_dir) unless $LOAD_PATH.include?(this_dir) |
||||
|
||||
require 'grpc' |
||||
require 'qps-common' |
||||
require 'src/proto/grpc/testing/messages' |
||||
require 'src/proto/grpc/testing/services_services' |
||||
require 'src/proto/grpc/testing/stats' |
||||
|
||||
class BenchmarkServiceImpl < Grpc::Testing::BenchmarkService::Service |
||||
def unary_call(req, _call) |
||||
sr = Grpc::Testing::SimpleResponse |
||||
pl = Grpc::Testing::Payload |
||||
sr.new(payload: pl.new(body: nulls(req.response_size))) |
||||
end |
||||
def streaming_call(reqs) |
||||
q = EnumeratorQueue.new(self) |
||||
Thread.new { |
||||
sr = Grpc::Testing::SimpleResponse |
||||
pl = Grpc::Testing::Payload |
||||
reqs.each do |req| |
||||
q.push(sr.new(payload: pl.new(body: nulls(req.response_size)))) |
||||
end |
||||
q.push(self) |
||||
} |
||||
q.each_item |
||||
end |
||||
end |
||||
|
||||
class BenchmarkServer |
||||
def initialize(config, port) |
||||
if config.security_params |
||||
certs = load_test_certs |
||||
cred = GRPC::Core::ServerCredentials.new( |
||||
nil, [{private_key: certs[1], cert_chain: certs[2]}], false) |
||||
else |
||||
cred = :this_port_is_insecure |
||||
end |
||||
@server = GRPC::RpcServer.new |
||||
@port = @server.add_http2_port("0.0.0.0:" + port.to_s, cred) |
||||
@server.handle(BenchmarkServiceImpl.new) |
||||
@start_time = Time.now |
||||
Thread.new { |
||||
@server.run |
||||
} |
||||
end |
||||
def mark(reset) |
||||
s = Grpc::Testing::ServerStats.new(time_elapsed: |
||||
(Time.now-@start_time).to_f) |
||||
@start_time = Time.now if reset |
||||
s |
||||
end |
||||
def get_port |
||||
@port |
||||
end |
||||
end |
@ -0,0 +1,129 @@ |
||||
# Generated by the protocol buffer compiler. DO NOT EDIT! |
||||
# source: src/proto/grpc/testing/control.proto |
||||
|
||||
require 'google/protobuf' |
||||
|
||||
require 'src/proto/grpc/testing/payloads' |
||||
require 'src/proto/grpc/testing/stats' |
||||
Google::Protobuf::DescriptorPool.generated_pool.build do |
||||
add_message "grpc.testing.PoissonParams" do |
||||
optional :offered_load, :double, 1 |
||||
end |
||||
add_message "grpc.testing.UniformParams" do |
||||
optional :interarrival_lo, :double, 1 |
||||
optional :interarrival_hi, :double, 2 |
||||
end |
||||
add_message "grpc.testing.DeterministicParams" do |
||||
optional :offered_load, :double, 1 |
||||
end |
||||
add_message "grpc.testing.ParetoParams" do |
||||
optional :interarrival_base, :double, 1 |
||||
optional :alpha, :double, 2 |
||||
end |
||||
add_message "grpc.testing.ClosedLoopParams" do |
||||
end |
||||
add_message "grpc.testing.LoadParams" do |
||||
oneof :load do |
||||
optional :closed_loop, :message, 1, "grpc.testing.ClosedLoopParams" |
||||
optional :poisson, :message, 2, "grpc.testing.PoissonParams" |
||||
optional :uniform, :message, 3, "grpc.testing.UniformParams" |
||||
optional :determ, :message, 4, "grpc.testing.DeterministicParams" |
||||
optional :pareto, :message, 5, "grpc.testing.ParetoParams" |
||||
end |
||||
end |
||||
add_message "grpc.testing.SecurityParams" do |
||||
optional :use_test_ca, :bool, 1 |
||||
optional :server_host_override, :string, 2 |
||||
end |
||||
add_message "grpc.testing.ClientConfig" do |
||||
repeated :server_targets, :string, 1 |
||||
optional :client_type, :enum, 2, "grpc.testing.ClientType" |
||||
optional :security_params, :message, 3, "grpc.testing.SecurityParams" |
||||
optional :outstanding_rpcs_per_channel, :int32, 4 |
||||
optional :client_channels, :int32, 5 |
||||
optional :async_client_threads, :int32, 7 |
||||
optional :rpc_type, :enum, 8, "grpc.testing.RpcType" |
||||
optional :load_params, :message, 10, "grpc.testing.LoadParams" |
||||
optional :payload_config, :message, 11, "grpc.testing.PayloadConfig" |
||||
optional :histogram_params, :message, 12, "grpc.testing.HistogramParams" |
||||
repeated :core_list, :int32, 13 |
||||
optional :core_limit, :int32, 14 |
||||
end |
||||
add_message "grpc.testing.ClientStatus" do |
||||
optional :stats, :message, 1, "grpc.testing.ClientStats" |
||||
end |
||||
add_message "grpc.testing.Mark" do |
||||
optional :reset, :bool, 1 |
||||
end |
||||
add_message "grpc.testing.ClientArgs" do |
||||
oneof :argtype do |
||||
optional :setup, :message, 1, "grpc.testing.ClientConfig" |
||||
optional :mark, :message, 2, "grpc.testing.Mark" |
||||
end |
||||
end |
||||
add_message "grpc.testing.ServerConfig" do |
||||
optional :server_type, :enum, 1, "grpc.testing.ServerType" |
||||
optional :security_params, :message, 2, "grpc.testing.SecurityParams" |
||||
optional :port, :int32, 4 |
||||
optional :async_server_threads, :int32, 7 |
||||
optional :core_limit, :int32, 8 |
||||
optional :payload_config, :message, 9, "grpc.testing.PayloadConfig" |
||||
repeated :core_list, :int32, 10 |
||||
end |
||||
add_message "grpc.testing.ServerArgs" do |
||||
oneof :argtype do |
||||
optional :setup, :message, 1, "grpc.testing.ServerConfig" |
||||
optional :mark, :message, 2, "grpc.testing.Mark" |
||||
end |
||||
end |
||||
add_message "grpc.testing.ServerStatus" do |
||||
optional :stats, :message, 1, "grpc.testing.ServerStats" |
||||
optional :port, :int32, 2 |
||||
optional :cores, :int32, 3 |
||||
end |
||||
add_message "grpc.testing.CoreRequest" do |
||||
end |
||||
add_message "grpc.testing.CoreResponse" do |
||||
optional :cores, :int32, 1 |
||||
end |
||||
add_message "grpc.testing.Void" do |
||||
end |
||||
add_enum "grpc.testing.ClientType" do |
||||
value :SYNC_CLIENT, 0 |
||||
value :ASYNC_CLIENT, 1 |
||||
end |
||||
add_enum "grpc.testing.ServerType" do |
||||
value :SYNC_SERVER, 0 |
||||
value :ASYNC_SERVER, 1 |
||||
value :ASYNC_GENERIC_SERVER, 2 |
||||
end |
||||
add_enum "grpc.testing.RpcType" do |
||||
value :UNARY, 0 |
||||
value :STREAMING, 1 |
||||
end |
||||
end |
||||
|
||||
module Grpc |
||||
module Testing |
||||
PoissonParams = Google::Protobuf::DescriptorPool.generated_pool.lookup("grpc.testing.PoissonParams").msgclass |
||||
UniformParams = Google::Protobuf::DescriptorPool.generated_pool.lookup("grpc.testing.UniformParams").msgclass |
||||
DeterministicParams = Google::Protobuf::DescriptorPool.generated_pool.lookup("grpc.testing.DeterministicParams").msgclass |
||||
ParetoParams = Google::Protobuf::DescriptorPool.generated_pool.lookup("grpc.testing.ParetoParams").msgclass |
||||
ClosedLoopParams = Google::Protobuf::DescriptorPool.generated_pool.lookup("grpc.testing.ClosedLoopParams").msgclass |
||||
LoadParams = Google::Protobuf::DescriptorPool.generated_pool.lookup("grpc.testing.LoadParams").msgclass |
||||
SecurityParams = Google::Protobuf::DescriptorPool.generated_pool.lookup("grpc.testing.SecurityParams").msgclass |
||||
ClientConfig = Google::Protobuf::DescriptorPool.generated_pool.lookup("grpc.testing.ClientConfig").msgclass |
||||
ClientStatus = Google::Protobuf::DescriptorPool.generated_pool.lookup("grpc.testing.ClientStatus").msgclass |
||||
Mark = Google::Protobuf::DescriptorPool.generated_pool.lookup("grpc.testing.Mark").msgclass |
||||
ClientArgs = Google::Protobuf::DescriptorPool.generated_pool.lookup("grpc.testing.ClientArgs").msgclass |
||||
ServerConfig = Google::Protobuf::DescriptorPool.generated_pool.lookup("grpc.testing.ServerConfig").msgclass |
||||
ServerArgs = Google::Protobuf::DescriptorPool.generated_pool.lookup("grpc.testing.ServerArgs").msgclass |
||||
ServerStatus = Google::Protobuf::DescriptorPool.generated_pool.lookup("grpc.testing.ServerStatus").msgclass |
||||
CoreRequest = Google::Protobuf::DescriptorPool.generated_pool.lookup("grpc.testing.CoreRequest").msgclass |
||||
CoreResponse = Google::Protobuf::DescriptorPool.generated_pool.lookup("grpc.testing.CoreResponse").msgclass |
||||
Void = Google::Protobuf::DescriptorPool.generated_pool.lookup("grpc.testing.Void").msgclass |
||||
ClientType = Google::Protobuf::DescriptorPool.generated_pool.lookup("grpc.testing.ClientType").enummodule |
||||
ServerType = Google::Protobuf::DescriptorPool.generated_pool.lookup("grpc.testing.ServerType").enummodule |
||||
RpcType = Google::Protobuf::DescriptorPool.generated_pool.lookup("grpc.testing.RpcType").enummodule |
||||
end |
||||
end |
@ -0,0 +1,80 @@ |
||||
# Generated by the protocol buffer compiler. DO NOT EDIT! |
||||
# source: src/proto/grpc/testing/messages.proto |
||||
|
||||
require 'google/protobuf' |
||||
|
||||
Google::Protobuf::DescriptorPool.generated_pool.build do |
||||
add_message "grpc.testing.Payload" do |
||||
optional :type, :enum, 1, "grpc.testing.PayloadType" |
||||
optional :body, :bytes, 2 |
||||
end |
||||
add_message "grpc.testing.EchoStatus" do |
||||
optional :code, :int32, 1 |
||||
optional :message, :string, 2 |
||||
end |
||||
add_message "grpc.testing.SimpleRequest" do |
||||
optional :response_type, :enum, 1, "grpc.testing.PayloadType" |
||||
optional :response_size, :int32, 2 |
||||
optional :payload, :message, 3, "grpc.testing.Payload" |
||||
optional :fill_username, :bool, 4 |
||||
optional :fill_oauth_scope, :bool, 5 |
||||
optional :response_compression, :enum, 6, "grpc.testing.CompressionType" |
||||
optional :response_status, :message, 7, "grpc.testing.EchoStatus" |
||||
end |
||||
add_message "grpc.testing.SimpleResponse" do |
||||
optional :payload, :message, 1, "grpc.testing.Payload" |
||||
optional :username, :string, 2 |
||||
optional :oauth_scope, :string, 3 |
||||
end |
||||
add_message "grpc.testing.StreamingInputCallRequest" do |
||||
optional :payload, :message, 1, "grpc.testing.Payload" |
||||
end |
||||
add_message "grpc.testing.StreamingInputCallResponse" do |
||||
optional :aggregated_payload_size, :int32, 1 |
||||
end |
||||
add_message "grpc.testing.ResponseParameters" do |
||||
optional :size, :int32, 1 |
||||
optional :interval_us, :int32, 2 |
||||
end |
||||
add_message "grpc.testing.StreamingOutputCallRequest" do |
||||
optional :response_type, :enum, 1, "grpc.testing.PayloadType" |
||||
repeated :response_parameters, :message, 2, "grpc.testing.ResponseParameters" |
||||
optional :payload, :message, 3, "grpc.testing.Payload" |
||||
optional :response_compression, :enum, 6, "grpc.testing.CompressionType" |
||||
optional :response_status, :message, 7, "grpc.testing.EchoStatus" |
||||
end |
||||
add_message "grpc.testing.StreamingOutputCallResponse" do |
||||
optional :payload, :message, 1, "grpc.testing.Payload" |
||||
end |
||||
add_message "grpc.testing.ReconnectInfo" do |
||||
optional :passed, :bool, 1 |
||||
repeated :backoff_ms, :int32, 2 |
||||
end |
||||
add_enum "grpc.testing.PayloadType" do |
||||
value :COMPRESSABLE, 0 |
||||
value :UNCOMPRESSABLE, 1 |
||||
value :RANDOM, 2 |
||||
end |
||||
add_enum "grpc.testing.CompressionType" do |
||||
value :NONE, 0 |
||||
value :GZIP, 1 |
||||
value :DEFLATE, 2 |
||||
end |
||||
end |
||||
|
||||
module Grpc |
||||
module Testing |
||||
Payload = Google::Protobuf::DescriptorPool.generated_pool.lookup("grpc.testing.Payload").msgclass |
||||
EchoStatus = Google::Protobuf::DescriptorPool.generated_pool.lookup("grpc.testing.EchoStatus").msgclass |
||||
SimpleRequest = Google::Protobuf::DescriptorPool.generated_pool.lookup("grpc.testing.SimpleRequest").msgclass |
||||
SimpleResponse = Google::Protobuf::DescriptorPool.generated_pool.lookup("grpc.testing.SimpleResponse").msgclass |
||||
StreamingInputCallRequest = Google::Protobuf::DescriptorPool.generated_pool.lookup("grpc.testing.StreamingInputCallRequest").msgclass |
||||
StreamingInputCallResponse = Google::Protobuf::DescriptorPool.generated_pool.lookup("grpc.testing.StreamingInputCallResponse").msgclass |
||||
ResponseParameters = Google::Protobuf::DescriptorPool.generated_pool.lookup("grpc.testing.ResponseParameters").msgclass |
||||
StreamingOutputCallRequest = Google::Protobuf::DescriptorPool.generated_pool.lookup("grpc.testing.StreamingOutputCallRequest").msgclass |
||||
StreamingOutputCallResponse = Google::Protobuf::DescriptorPool.generated_pool.lookup("grpc.testing.StreamingOutputCallResponse").msgclass |
||||
ReconnectInfo = Google::Protobuf::DescriptorPool.generated_pool.lookup("grpc.testing.ReconnectInfo").msgclass |
||||
PayloadType = Google::Protobuf::DescriptorPool.generated_pool.lookup("grpc.testing.PayloadType").enummodule |
||||
CompressionType = Google::Protobuf::DescriptorPool.generated_pool.lookup("grpc.testing.CompressionType").enummodule |
||||
end |
||||
end |
@ -0,0 +1,33 @@ |
||||
# Generated by the protocol buffer compiler. DO NOT EDIT! |
||||
# source: src/proto/grpc/testing/payloads.proto |
||||
|
||||
require 'google/protobuf' |
||||
|
||||
Google::Protobuf::DescriptorPool.generated_pool.build do |
||||
add_message "grpc.testing.ByteBufferParams" do |
||||
optional :req_size, :int32, 1 |
||||
optional :resp_size, :int32, 2 |
||||
end |
||||
add_message "grpc.testing.SimpleProtoParams" do |
||||
optional :req_size, :int32, 1 |
||||
optional :resp_size, :int32, 2 |
||||
end |
||||
add_message "grpc.testing.ComplexProtoParams" do |
||||
end |
||||
add_message "grpc.testing.PayloadConfig" do |
||||
oneof :payload do |
||||
optional :bytebuf_params, :message, 1, "grpc.testing.ByteBufferParams" |
||||
optional :simple_params, :message, 2, "grpc.testing.SimpleProtoParams" |
||||
optional :complex_params, :message, 3, "grpc.testing.ComplexProtoParams" |
||||
end |
||||
end |
||||
end |
||||
|
||||
module Grpc |
||||
module Testing |
||||
ByteBufferParams = Google::Protobuf::DescriptorPool.generated_pool.lookup("grpc.testing.ByteBufferParams").msgclass |
||||
SimpleProtoParams = Google::Protobuf::DescriptorPool.generated_pool.lookup("grpc.testing.SimpleProtoParams").msgclass |
||||
ComplexProtoParams = Google::Protobuf::DescriptorPool.generated_pool.lookup("grpc.testing.ComplexProtoParams").msgclass |
||||
PayloadConfig = Google::Protobuf::DescriptorPool.generated_pool.lookup("grpc.testing.PayloadConfig").msgclass |
||||
end |
||||
end |
@ -0,0 +1,14 @@ |
||||
# Generated by the protocol buffer compiler. DO NOT EDIT! |
||||
# source: src/proto/grpc/testing/services.proto |
||||
|
||||
require 'google/protobuf' |
||||
|
||||
require 'src/proto/grpc/testing/messages' |
||||
require 'src/proto/grpc/testing/control' |
||||
Google::Protobuf::DescriptorPool.generated_pool.build do |
||||
end |
||||
|
||||
module Grpc |
||||
module Testing |
||||
end |
||||
end |
@ -0,0 +1,46 @@ |
||||
# Generated by the protocol buffer compiler. DO NOT EDIT! |
||||
# Source: src/proto/grpc/testing/services.proto for package 'grpc.testing' |
||||
|
||||
require 'grpc' |
||||
require 'src/proto/grpc/testing/services' |
||||
|
||||
module Grpc |
||||
module Testing |
||||
module BenchmarkService |
||||
|
||||
# TODO: add proto service documentation here |
||||
class Service |
||||
|
||||
include GRPC::GenericService |
||||
|
||||
self.marshal_class_method = :encode |
||||
self.unmarshal_class_method = :decode |
||||
self.service_name = 'grpc.testing.BenchmarkService' |
||||
|
||||
rpc :UnaryCall, SimpleRequest, SimpleResponse |
||||
rpc :StreamingCall, stream(SimpleRequest), stream(SimpleResponse) |
||||
end |
||||
|
||||
Stub = Service.rpc_stub_class |
||||
end |
||||
module WorkerService |
||||
|
||||
# TODO: add proto service documentation here |
||||
class Service |
||||
|
||||
include GRPC::GenericService |
||||
|
||||
self.marshal_class_method = :encode |
||||
self.unmarshal_class_method = :decode |
||||
self.service_name = 'grpc.testing.WorkerService' |
||||
|
||||
rpc :RunServer, stream(ServerArgs), stream(ServerStatus) |
||||
rpc :RunClient, stream(ClientArgs), stream(ClientStatus) |
||||
rpc :CoreCount, CoreRequest, CoreResponse |
||||
rpc :QuitWorker, Void, Void |
||||
end |
||||
|
||||
Stub = Service.rpc_stub_class |
||||
end |
||||
end |
||||
end |
@ -0,0 +1,39 @@ |
||||
# Generated by the protocol buffer compiler. DO NOT EDIT! |
||||
# source: src/proto/grpc/testing/stats.proto |
||||
|
||||
require 'google/protobuf' |
||||
|
||||
Google::Protobuf::DescriptorPool.generated_pool.build do |
||||
add_message "grpc.testing.ServerStats" do |
||||
optional :time_elapsed, :double, 1 |
||||
optional :time_user, :double, 2 |
||||
optional :time_system, :double, 3 |
||||
end |
||||
add_message "grpc.testing.HistogramParams" do |
||||
optional :resolution, :double, 1 |
||||
optional :max_possible, :double, 2 |
||||
end |
||||
add_message "grpc.testing.HistogramData" do |
||||
repeated :bucket, :uint32, 1 |
||||
optional :min_seen, :double, 2 |
||||
optional :max_seen, :double, 3 |
||||
optional :sum, :double, 4 |
||||
optional :sum_of_squares, :double, 5 |
||||
optional :count, :double, 6 |
||||
end |
||||
add_message "grpc.testing.ClientStats" do |
||||
optional :latencies, :message, 1, "grpc.testing.HistogramData" |
||||
optional :time_elapsed, :double, 2 |
||||
optional :time_user, :double, 3 |
||||
optional :time_system, :double, 4 |
||||
end |
||||
end |
||||
|
||||
module Grpc |
||||
module Testing |
||||
ServerStats = Google::Protobuf::DescriptorPool.generated_pool.lookup("grpc.testing.ServerStats").msgclass |
||||
HistogramParams = Google::Protobuf::DescriptorPool.generated_pool.lookup("grpc.testing.HistogramParams").msgclass |
||||
HistogramData = Google::Protobuf::DescriptorPool.generated_pool.lookup("grpc.testing.HistogramData").msgclass |
||||
ClientStats = Google::Protobuf::DescriptorPool.generated_pool.lookup("grpc.testing.ClientStats").msgclass |
||||
end |
||||
end |
@ -0,0 +1,128 @@ |
||||
#!/usr/bin/env ruby |
||||
|
||||
# Copyright 2016, Google 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: |
||||
# |
||||
# * Redistributions of source code must retain the above copyright |
||||
# notice, this list of conditions and the following disclaimer. |
||||
# * 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. |
||||
# * Neither the name of Google Inc. nor the names of its |
||||
# contributors may be used to endorse or promote products derived from |
||||
# this software without specific prior written permission. |
||||
# |
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 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 COPYRIGHT |
||||
# OWNER 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. |
||||
|
||||
# Worker and worker service implementation |
||||
|
||||
this_dir = File.expand_path(File.dirname(__FILE__)) |
||||
lib_dir = File.join(File.dirname(this_dir), 'lib') |
||||
$LOAD_PATH.unshift(lib_dir) unless $LOAD_PATH.include?(lib_dir) |
||||
$LOAD_PATH.unshift(this_dir) unless $LOAD_PATH.include?(this_dir) |
||||
|
||||
require 'grpc' |
||||
require 'optparse' |
||||
require 'histogram' |
||||
require 'etc' |
||||
require 'facter' |
||||
require 'client' |
||||
require 'qps-common' |
||||
require 'server' |
||||
require 'src/proto/grpc/testing/services_services' |
||||
|
||||
class WorkerServiceImpl < Grpc::Testing::WorkerService::Service |
||||
def cpu_cores |
||||
Facter.value('processors')['count'] |
||||
end |
||||
def run_server(reqs) |
||||
q = EnumeratorQueue.new(self) |
||||
Thread.new { |
||||
bms = '' |
||||
gtss = Grpc::Testing::ServerStatus |
||||
reqs.each do |req| |
||||
case req.argtype.to_s |
||||
when 'setup' |
||||
bms = BenchmarkServer.new(req.setup, @server_port) |
||||
q.push(gtss.new(stats: bms.mark(false), port: bms.get_port)) |
||||
when 'mark' |
||||
q.push(gtss.new(stats: bms.mark(req.mark.reset), cores: cpu_cores)) |
||||
end |
||||
end |
||||
q.push(self) |
||||
bms.stop |
||||
} |
||||
q.each_item |
||||
end |
||||
def run_client(reqs) |
||||
q = EnumeratorQueue.new(self) |
||||
Thread.new { |
||||
client = '' |
||||
reqs.each do |req| |
||||
case req.argtype.to_s |
||||
when 'setup' |
||||
client = BenchmarkClient.new(req.setup) |
||||
q.push(Grpc::Testing::ClientStatus.new(stats: client.mark(false))) |
||||
when 'mark' |
||||
q.push(Grpc::Testing::ClientStatus.new(stats: |
||||
client.mark(req.mark.reset))) |
||||
end |
||||
end |
||||
q.push(self) |
||||
client.shutdown |
||||
} |
||||
q.each_item |
||||
end |
||||
def core_count(_args, _call) |
||||
Grpc::Testing::CoreResponse.new(cores: cpu_cores) |
||||
end |
||||
def quit_worker(_args, _call) |
||||
Thread.new { |
||||
sleep 3 |
||||
@server.stop |
||||
} |
||||
Grpc::Testing::Void.new |
||||
end |
||||
def initialize(s, sp) |
||||
@server = s |
||||
@server_port = sp |
||||
end |
||||
end |
||||
|
||||
def main |
||||
options = { |
||||
'driver_port' => 0, |
||||
'server_port' => 0 |
||||
} |
||||
OptionParser.new do |opts| |
||||
opts.banner = 'Usage: [--driver_port <port>] [--server_port <port>]' |
||||
opts.on('--driver_port PORT', '<port>') do |v| |
||||
options['driver_port'] = v |
||||
end |
||||
opts.on('--server_port PORT', '<port>') do |v| |
||||
options['server_port'] = v |
||||
end |
||||
end.parse! |
||||
s = GRPC::RpcServer.new |
||||
s.add_http2_port("0.0.0.0:" + options['driver_port'].to_s, |
||||
:this_port_is_insecure) |
||||
s.handle(WorkerServiceImpl.new(s, options['server_port'].to_i)) |
||||
s.run |
||||
end |
||||
|
||||
main |
@ -0,0 +1,301 @@ |
||||
/*
|
||||
* |
||||
* Copyright 2016, Google 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: |
||||
* |
||||
* * Redistributions of source code must retain the above copyright |
||||
* notice, this list of conditions and the following disclaimer. |
||||
* * 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. |
||||
* * Neither the name of Google Inc. nor the names of its |
||||
* contributors may be used to endorse or promote products derived from |
||||
* this software without specific prior written permission. |
||||
* |
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 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 COPYRIGHT |
||||
* OWNER 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. |
||||
* |
||||
*/ |
||||
|
||||
#include <grpc/grpc.h> |
||||
#include <grpc/support/alloc.h> |
||||
#include <grpc/support/log.h> |
||||
#include <grpc/support/string_util.h> |
||||
#include <string.h> |
||||
#include "src/core/lib/iomgr/resolve_address.h" |
||||
#include "src/core/lib/iomgr/sockaddr.h" |
||||
#include "test/core/end2end/cq_verifier.h" |
||||
#include "test/core/util/port.h" |
||||
#include "test/core/util/test_config.h" |
||||
|
||||
static void *tag(intptr_t i) { return (void *)i; } |
||||
|
||||
static gpr_mu g_mu; |
||||
static int g_resolve_port = -1; |
||||
static grpc_resolved_addresses *(*iomgr_resolve_address)( |
||||
const char *name, const char *default_port); |
||||
|
||||
static void set_resolve_port(int port) { |
||||
gpr_mu_lock(&g_mu); |
||||
g_resolve_port = port; |
||||
gpr_mu_unlock(&g_mu); |
||||
} |
||||
|
||||
static grpc_resolved_addresses *my_resolve_address(const char *name, |
||||
const char *addr) { |
||||
if (0 != strcmp(name, "test")) { |
||||
return iomgr_resolve_address(name, addr); |
||||
} |
||||
|
||||
gpr_mu_lock(&g_mu); |
||||
if (g_resolve_port < 0) { |
||||
gpr_mu_unlock(&g_mu); |
||||
return NULL; |
||||
} else { |
||||
grpc_resolved_addresses *addrs = gpr_malloc(sizeof(*addrs)); |
||||
addrs->naddrs = 1; |
||||
addrs->addrs = gpr_malloc(sizeof(*addrs->addrs)); |
||||
memset(addrs->addrs, 0, sizeof(*addrs->addrs)); |
||||
struct sockaddr_in *sa = (struct sockaddr_in *)addrs->addrs[0].addr; |
||||
sa->sin_family = AF_INET; |
||||
sa->sin_addr.s_addr = htonl(0x7f000001); |
||||
sa->sin_port = htons((uint16_t)g_resolve_port); |
||||
addrs->addrs[0].len = sizeof(*sa); |
||||
gpr_mu_unlock(&g_mu); |
||||
return addrs; |
||||
} |
||||
} |
||||
|
||||
int main(int argc, char **argv) { |
||||
grpc_completion_queue *cq; |
||||
cq_verifier *cqv; |
||||
grpc_op ops[6]; |
||||
grpc_op *op; |
||||
|
||||
grpc_test_init(argc, argv); |
||||
|
||||
gpr_mu_init(&g_mu); |
||||
iomgr_resolve_address = grpc_blocking_resolve_address; |
||||
grpc_blocking_resolve_address = my_resolve_address; |
||||
grpc_init(); |
||||
|
||||
int was_cancelled1; |
||||
int was_cancelled2; |
||||
|
||||
grpc_metadata_array trailing_metadata_recv1; |
||||
grpc_metadata_array request_metadata1; |
||||
grpc_call_details request_details1; |
||||
grpc_status_code status1; |
||||
char *details1 = NULL; |
||||
size_t details_capacity1 = 0; |
||||
grpc_metadata_array_init(&trailing_metadata_recv1); |
||||
grpc_metadata_array_init(&request_metadata1); |
||||
grpc_call_details_init(&request_details1); |
||||
|
||||
grpc_metadata_array trailing_metadata_recv2; |
||||
grpc_metadata_array request_metadata2; |
||||
grpc_call_details request_details2; |
||||
grpc_status_code status2; |
||||
char *details2 = NULL; |
||||
size_t details_capacity2 = 0; |
||||
grpc_metadata_array_init(&trailing_metadata_recv2); |
||||
grpc_metadata_array_init(&request_metadata2); |
||||
grpc_call_details_init(&request_details2); |
||||
|
||||
cq = grpc_completion_queue_create(NULL); |
||||
cqv = cq_verifier_create(cq); |
||||
|
||||
/* reserve two ports */ |
||||
int port1 = grpc_pick_unused_port_or_die(); |
||||
int port2 = grpc_pick_unused_port_or_die(); |
||||
|
||||
char *addr; |
||||
|
||||
/* create a channel that picks first amongst the servers */ |
||||
grpc_channel *chan = grpc_insecure_channel_create("test", NULL, NULL); |
||||
/* and an initial call to them */ |
||||
grpc_call *call1 = grpc_channel_create_call( |
||||
chan, NULL, GRPC_PROPAGATE_DEFAULTS, cq, "/foo", "127.0.0.1", |
||||
GRPC_TIMEOUT_SECONDS_TO_DEADLINE(20), NULL); |
||||
/* send initial metadata to probe connectivity */ |
||||
op = ops; |
||||
op->op = GRPC_OP_SEND_INITIAL_METADATA; |
||||
op->data.send_initial_metadata.count = 0; |
||||
op->flags = 0; |
||||
op->reserved = NULL; |
||||
op++; |
||||
GPR_ASSERT(GRPC_CALL_OK == grpc_call_start_batch(call1, ops, |
||||
(size_t)(op - ops), |
||||
tag(0x101), NULL)); |
||||
/* and receive status to probe termination */ |
||||
op = ops; |
||||
op->op = GRPC_OP_RECV_STATUS_ON_CLIENT; |
||||
op->data.recv_status_on_client.trailing_metadata = &trailing_metadata_recv1; |
||||
op->data.recv_status_on_client.status = &status1; |
||||
op->data.recv_status_on_client.status_details = &details1; |
||||
op->data.recv_status_on_client.status_details_capacity = &details_capacity1; |
||||
op->flags = 0; |
||||
op->reserved = NULL; |
||||
op++; |
||||
GPR_ASSERT(GRPC_CALL_OK == grpc_call_start_batch(call1, ops, |
||||
(size_t)(op - ops), |
||||
tag(0x102), NULL)); |
||||
|
||||
/* bring a server up on the first port */ |
||||
grpc_server *server1 = grpc_server_create(NULL, NULL); |
||||
gpr_asprintf(&addr, "127.0.0.1:%d", port1); |
||||
grpc_server_add_insecure_http2_port(server1, addr); |
||||
grpc_server_register_completion_queue(server1, cq, NULL); |
||||
gpr_free(addr); |
||||
grpc_server_start(server1); |
||||
|
||||
/* request a call to the server */ |
||||
grpc_call *server_call1; |
||||
GPR_ASSERT(GRPC_CALL_OK == |
||||
grpc_server_request_call(server1, &server_call1, &request_details1, |
||||
&request_metadata1, cq, cq, tag(0x301))); |
||||
|
||||
set_resolve_port(port1); |
||||
|
||||
/* first call should now start */ |
||||
cq_expect_completion(cqv, tag(0x101), 1); |
||||
cq_expect_completion(cqv, tag(0x301), 1); |
||||
cq_verify(cqv); |
||||
|
||||
GPR_ASSERT(GRPC_CHANNEL_READY == |
||||
grpc_channel_check_connectivity_state(chan, 0)); |
||||
grpc_channel_watch_connectivity_state(chan, GRPC_CHANNEL_READY, |
||||
gpr_inf_future(GPR_CLOCK_REALTIME), cq, |
||||
tag(0x9999)); |
||||
|
||||
/* listen for close on the server call to probe for finishing */ |
||||
op = ops; |
||||
op->op = GRPC_OP_RECV_CLOSE_ON_SERVER; |
||||
op->data.recv_close_on_server.cancelled = &was_cancelled1; |
||||
op->flags = 0; |
||||
op++; |
||||
GPR_ASSERT(GRPC_CALL_OK == grpc_call_start_batch(server_call1, ops, |
||||
(size_t)(op - ops), |
||||
tag(0x302), NULL)); |
||||
|
||||
/* shutdown first server:
|
||||
* we should see a connectivity change and then nothing */ |
||||
set_resolve_port(-1); |
||||
grpc_server_shutdown_and_notify(server1, cq, tag(0xdead1)); |
||||
cq_expect_completion(cqv, tag(0x9999), 1); |
||||
cq_verify(cqv); |
||||
cq_verify_empty(cqv); |
||||
|
||||
/* and a new call: should go through to server2 when we start it */ |
||||
grpc_call *call2 = grpc_channel_create_call( |
||||
chan, NULL, GRPC_PROPAGATE_DEFAULTS, cq, "/foo", "127.0.0.1", |
||||
GRPC_TIMEOUT_SECONDS_TO_DEADLINE(20), NULL); |
||||
/* send initial metadata to probe connectivity */ |
||||
op = ops; |
||||
op->op = GRPC_OP_SEND_INITIAL_METADATA; |
||||
op->data.send_initial_metadata.count = 0; |
||||
op->flags = 0; |
||||
op->reserved = NULL; |
||||
op++; |
||||
GPR_ASSERT(GRPC_CALL_OK == grpc_call_start_batch(call2, ops, |
||||
(size_t)(op - ops), |
||||
tag(0x201), NULL)); |
||||
/* and receive status to probe termination */ |
||||
op = ops; |
||||
op->op = GRPC_OP_RECV_STATUS_ON_CLIENT; |
||||
op->data.recv_status_on_client.trailing_metadata = &trailing_metadata_recv2; |
||||
op->data.recv_status_on_client.status = &status2; |
||||
op->data.recv_status_on_client.status_details = &details2; |
||||
op->data.recv_status_on_client.status_details_capacity = &details_capacity2; |
||||
op->flags = 0; |
||||
op->reserved = NULL; |
||||
op++; |
||||
GPR_ASSERT(GRPC_CALL_OK == grpc_call_start_batch(call2, ops, |
||||
(size_t)(op - ops), |
||||
tag(0x202), NULL)); |
||||
|
||||
/* and bring up second server */ |
||||
set_resolve_port(port2); |
||||
grpc_server *server2 = grpc_server_create(NULL, NULL); |
||||
gpr_asprintf(&addr, "127.0.0.1:%d", port2); |
||||
grpc_server_add_insecure_http2_port(server2, addr); |
||||
grpc_server_register_completion_queue(server2, cq, NULL); |
||||
gpr_free(addr); |
||||
grpc_server_start(server2); |
||||
|
||||
/* request a call to the server */ |
||||
grpc_call *server_call2; |
||||
GPR_ASSERT(GRPC_CALL_OK == |
||||
grpc_server_request_call(server2, &server_call2, &request_details2, |
||||
&request_metadata2, cq, cq, tag(0x401))); |
||||
|
||||
/* second call should now start */ |
||||
cq_expect_completion(cqv, tag(0x201), 1); |
||||
cq_expect_completion(cqv, tag(0x401), 1); |
||||
cq_verify(cqv); |
||||
|
||||
/* listen for close on the server call to probe for finishing */ |
||||
op = ops; |
||||
op->op = GRPC_OP_RECV_CLOSE_ON_SERVER; |
||||
op->data.recv_close_on_server.cancelled = &was_cancelled2; |
||||
op->flags = 0; |
||||
op++; |
||||
GPR_ASSERT(GRPC_CALL_OK == grpc_call_start_batch(server_call2, ops, |
||||
(size_t)(op - ops), |
||||
tag(0x402), NULL)); |
||||
|
||||
/* shutdown second server: we should see nothing */ |
||||
grpc_server_shutdown_and_notify(server2, cq, tag(0xdead2)); |
||||
cq_verify_empty(cqv); |
||||
|
||||
grpc_call_cancel(call1, NULL); |
||||
grpc_call_cancel(call2, NULL); |
||||
|
||||
/* now everything else should finish */ |
||||
cq_expect_completion(cqv, tag(0x102), 1); |
||||
cq_expect_completion(cqv, tag(0x202), 1); |
||||
cq_expect_completion(cqv, tag(0x302), 1); |
||||
cq_expect_completion(cqv, tag(0x402), 1); |
||||
cq_expect_completion(cqv, tag(0xdead1), 1); |
||||
cq_expect_completion(cqv, tag(0xdead2), 1); |
||||
cq_verify(cqv); |
||||
|
||||
grpc_call_destroy(call1); |
||||
grpc_call_destroy(call2); |
||||
grpc_call_destroy(server_call1); |
||||
grpc_call_destroy(server_call2); |
||||
grpc_server_destroy(server1); |
||||
grpc_server_destroy(server2); |
||||
grpc_channel_destroy(chan); |
||||
|
||||
grpc_metadata_array_destroy(&trailing_metadata_recv1); |
||||
grpc_metadata_array_destroy(&request_metadata1); |
||||
grpc_call_details_destroy(&request_details1); |
||||
gpr_free(details1); |
||||
grpc_metadata_array_destroy(&trailing_metadata_recv2); |
||||
grpc_metadata_array_destroy(&request_metadata2); |
||||
grpc_call_details_destroy(&request_details2); |
||||
gpr_free(details2); |
||||
|
||||
cq_verifier_destroy(cqv); |
||||
grpc_completion_queue_destroy(cq); |
||||
|
||||
grpc_shutdown(); |
||||
gpr_mu_destroy(&g_mu); |
||||
|
||||
return 0; |
||||
} |
@ -0,0 +1 @@ |
||||
{"":21} |
@ -0,0 +1 @@ |
||||
{"":21] |
@ -0,0 +1,46 @@ |
||||
/*
|
||||
* |
||||
* Copyright 2016, Google 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: |
||||
* |
||||
* * Redistributions of source code must retain the above copyright |
||||
* notice, this list of conditions and the following disclaimer. |
||||
* * 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. |
||||
* * Neither the name of Google Inc. nor the names of its |
||||
* contributors may be used to endorse or promote products derived from |
||||
* this software without specific prior written permission. |
||||
* |
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 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 COPYRIGHT |
||||
* OWNER 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. |
||||
* |
||||
*/ |
||||
|
||||
#include <grpc/support/log.h> |
||||
#include "src/core/lib/support/load_file.h" |
||||
|
||||
extern int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size); |
||||
|
||||
int main(int argc, char **argv) { |
||||
int ok = 0; |
||||
gpr_slice buffer = gpr_load_file(argv[1], 0, &ok); |
||||
GPR_ASSERT(ok); |
||||
LLVMFuzzerTestOneInput(GPR_SLICE_START_PTR(buffer), GPR_SLICE_LENGTH(buffer)); |
||||
gpr_slice_unref(buffer); |
||||
return 0; |
||||
} |
@ -0,0 +1,57 @@ |
||||
# Copyright 2016, Google 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: |
||||
# |
||||
# * Redistributions of source code must retain the above copyright |
||||
# notice, this list of conditions and the following disclaimer. |
||||
# * 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. |
||||
# * Neither the name of Google Inc. nor the names of its |
||||
# contributors may be used to endorse or promote products derived from |
||||
# this software without specific prior written permission. |
||||
# |
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 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 COPYRIGHT |
||||
# OWNER 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. |
||||
|
||||
"""Create tests for each fuzzer""" |
||||
|
||||
import copy |
||||
import glob |
||||
|
||||
def mako_plugin(dictionary): |
||||
targets = dictionary['targets'] |
||||
tests = dictionary['tests'] |
||||
for tgt in targets: |
||||
if tgt['build'] == 'fuzzer': |
||||
new_target = copy.deepcopy(tgt) |
||||
new_target['build'] = 'test' |
||||
new_target['name'] += '_one_entry' |
||||
new_target['run'] = False |
||||
new_target['deps'].insert(0, 'one_input_fuzzer') |
||||
targets.append(new_target) |
||||
for corpus in new_target['corpus_dirs']: |
||||
for fn in sorted(glob.glob('%s/*' % corpus)): |
||||
tests.append({ |
||||
'name': new_target['name'], |
||||
'args': [fn], |
||||
'exclude_configs': [], |
||||
'platforms': ['linux', 'mac', 'windows', 'posix'], |
||||
'ci_platforms': ['linux', 'mac', 'windows', 'posix'], |
||||
'flaky': False, |
||||
'language': 'c', |
||||
'cpu_cost': 0.1, |
||||
}) |
@ -0,0 +1,38 @@ |
||||
#!/bin/bash |
||||
# Copyright 2015-2016, Google 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: |
||||
# |
||||
# * Redistributions of source code must retain the above copyright |
||||
# notice, this list of conditions and the following disclaimer. |
||||
# * 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. |
||||
# * Neither the name of Google Inc. nor the names of its |
||||
# contributors may be used to endorse or promote products derived from |
||||
# this software without specific prior written permission. |
||||
# |
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 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 COPYRIGHT |
||||
# OWNER 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. |
||||
|
||||
set -ex |
||||
|
||||
cd $(dirname $0)/../../.. |
||||
|
||||
# needed to correctly locate testca |
||||
cd src/csharp/Grpc.IntegrationTesting.QpsWorker/bin/Release |
||||
|
||||
mono Grpc.IntegrationTesting.QpsWorker.exe $@ |
@ -0,0 +1,38 @@ |
||||
#!/bin/bash |
||||
# Copyright 2015-2016, Google 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: |
||||
# |
||||
# * Redistributions of source code must retain the above copyright |
||||
# notice, this list of conditions and the following disclaimer. |
||||
# * 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. |
||||
# * Neither the name of Google Inc. nor the names of its |
||||
# contributors may be used to endorse or promote products derived from |
||||
# this software without specific prior written permission. |
||||
# |
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 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 COPYRIGHT |
||||
# OWNER 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. |
||||
|
||||
source ~/.nvm/nvm.sh |
||||
nvm use 0.12 |
||||
|
||||
set -ex |
||||
|
||||
cd $(dirname $0)/../../.. |
||||
|
||||
node src/node/performance/worker.js $@ |
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,167 @@ |
||||
<?xml version="1.0" encoding="utf-8"?> |
||||
<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> |
||||
<ItemGroup Label="ProjectConfigurations"> |
||||
<ProjectConfiguration Include="Debug|Win32"> |
||||
<Configuration>Debug</Configuration> |
||||
<Platform>Win32</Platform> |
||||
</ProjectConfiguration> |
||||
<ProjectConfiguration Include="Debug|x64"> |
||||
<Configuration>Debug</Configuration> |
||||
<Platform>x64</Platform> |
||||
</ProjectConfiguration> |
||||
<ProjectConfiguration Include="Release|Win32"> |
||||
<Configuration>Release</Configuration> |
||||
<Platform>Win32</Platform> |
||||
</ProjectConfiguration> |
||||
<ProjectConfiguration Include="Release|x64"> |
||||
<Configuration>Release</Configuration> |
||||
<Platform>x64</Platform> |
||||
</ProjectConfiguration> |
||||
</ItemGroup> |
||||
<PropertyGroup Label="Globals"> |
||||
<ProjectGuid>{3589BCA3-CB0E-58FE-2F67-C4475D5CA517}</ProjectGuid> |
||||
<IgnoreWarnIntDirInTempDetected>true</IgnoreWarnIntDirInTempDetected> |
||||
<IntDir>$(SolutionDir)IntDir\$(MSBuildProjectName)\</IntDir> |
||||
</PropertyGroup> |
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> |
||||
<PropertyGroup Condition="'$(VisualStudioVersion)' == '10.0'" Label="Configuration"> |
||||
<PlatformToolset>v100</PlatformToolset> |
||||
</PropertyGroup> |
||||
<PropertyGroup Condition="'$(VisualStudioVersion)' == '11.0'" Label="Configuration"> |
||||
<PlatformToolset>v110</PlatformToolset> |
||||
</PropertyGroup> |
||||
<PropertyGroup Condition="'$(VisualStudioVersion)' == '12.0'" Label="Configuration"> |
||||
<PlatformToolset>v120</PlatformToolset> |
||||
</PropertyGroup> |
||||
<PropertyGroup Condition="'$(VisualStudioVersion)' == '14.0'" Label="Configuration"> |
||||
<PlatformToolset>v140</PlatformToolset> |
||||
</PropertyGroup> |
||||
<PropertyGroup Condition="'$(Configuration)'=='Debug'" Label="Configuration"> |
||||
<ConfigurationType>StaticLibrary</ConfigurationType> |
||||
<UseDebugLibraries>true</UseDebugLibraries> |
||||
<CharacterSet>Unicode</CharacterSet> |
||||
</PropertyGroup> |
||||
<PropertyGroup Condition="'$(Configuration)'=='Release'" Label="Configuration"> |
||||
<ConfigurationType>StaticLibrary</ConfigurationType> |
||||
<UseDebugLibraries>false</UseDebugLibraries> |
||||
<WholeProgramOptimization>true</WholeProgramOptimization> |
||||
<CharacterSet>Unicode</CharacterSet> |
||||
</PropertyGroup> |
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> |
||||
<ImportGroup Label="ExtensionSettings"> |
||||
</ImportGroup> |
||||
<ImportGroup Label="PropertySheets"> |
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> |
||||
<Import Project="$(SolutionDir)\..\vsprojects\global.props" /> |
||||
<Import Project="$(SolutionDir)\..\vsprojects\winsock.props" /> |
||||
</ImportGroup> |
||||
<PropertyGroup Label="UserMacros" /> |
||||
<PropertyGroup Condition="'$(Configuration)'=='Debug'"> |
||||
<TargetName>one_input_fuzzer</TargetName> |
||||
</PropertyGroup> |
||||
<PropertyGroup Condition="'$(Configuration)'=='Release'"> |
||||
<TargetName>one_input_fuzzer</TargetName> |
||||
</PropertyGroup> |
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> |
||||
<ClCompile> |
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader> |
||||
<WarningLevel>Level3</WarningLevel> |
||||
<Optimization>Disabled</Optimization> |
||||
<PreprocessorDefinitions>WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions> |
||||
<SDLCheck>true</SDLCheck> |
||||
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary> |
||||
<TreatWarningAsError>true</TreatWarningAsError> |
||||
<DebugInformationFormat Condition="$(Jenkins)">None</DebugInformationFormat> |
||||
<MinimalRebuild Condition="$(Jenkins)">false</MinimalRebuild> |
||||
</ClCompile> |
||||
<Link> |
||||
<SubSystem>Windows</SubSystem> |
||||
<GenerateDebugInformation Condition="!$(Jenkins)">true</GenerateDebugInformation> |
||||
<GenerateDebugInformation Condition="$(Jenkins)">false</GenerateDebugInformation> |
||||
</Link> |
||||
</ItemDefinitionGroup> |
||||
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> |
||||
<ClCompile> |
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader> |
||||
<WarningLevel>Level3</WarningLevel> |
||||
<Optimization>Disabled</Optimization> |
||||
<PreprocessorDefinitions>WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions> |
||||
<SDLCheck>true</SDLCheck> |
||||
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary> |
||||
<TreatWarningAsError>true</TreatWarningAsError> |
||||
<DebugInformationFormat Condition="$(Jenkins)">None</DebugInformationFormat> |
||||
<MinimalRebuild Condition="$(Jenkins)">false</MinimalRebuild> |
||||
</ClCompile> |
||||
<Link> |
||||
<SubSystem>Windows</SubSystem> |
||||
<GenerateDebugInformation Condition="!$(Jenkins)">true</GenerateDebugInformation> |
||||
<GenerateDebugInformation Condition="$(Jenkins)">false</GenerateDebugInformation> |
||||
</Link> |
||||
</ItemDefinitionGroup> |
||||
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> |
||||
<ClCompile> |
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader> |
||||
<WarningLevel>Level3</WarningLevel> |
||||
<Optimization>MaxSpeed</Optimization> |
||||
<PreprocessorDefinitions>WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions> |
||||
<FunctionLevelLinking>true</FunctionLevelLinking> |
||||
<IntrinsicFunctions>true</IntrinsicFunctions> |
||||
<SDLCheck>true</SDLCheck> |
||||
<RuntimeLibrary>MultiThreaded</RuntimeLibrary> |
||||
<TreatWarningAsError>true</TreatWarningAsError> |
||||
<DebugInformationFormat Condition="$(Jenkins)">None</DebugInformationFormat> |
||||
<MinimalRebuild Condition="$(Jenkins)">false</MinimalRebuild> |
||||
</ClCompile> |
||||
<Link> |
||||
<SubSystem>Windows</SubSystem> |
||||
<GenerateDebugInformation Condition="!$(Jenkins)">true</GenerateDebugInformation> |
||||
<GenerateDebugInformation Condition="$(Jenkins)">false</GenerateDebugInformation> |
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding> |
||||
<OptimizeReferences>true</OptimizeReferences> |
||||
</Link> |
||||
</ItemDefinitionGroup> |
||||
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> |
||||
<ClCompile> |
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader> |
||||
<WarningLevel>Level3</WarningLevel> |
||||
<Optimization>MaxSpeed</Optimization> |
||||
<PreprocessorDefinitions>WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions> |
||||
<FunctionLevelLinking>true</FunctionLevelLinking> |
||||
<IntrinsicFunctions>true</IntrinsicFunctions> |
||||
<SDLCheck>true</SDLCheck> |
||||
<RuntimeLibrary>MultiThreaded</RuntimeLibrary> |
||||
<TreatWarningAsError>true</TreatWarningAsError> |
||||
<DebugInformationFormat Condition="$(Jenkins)">None</DebugInformationFormat> |
||||
<MinimalRebuild Condition="$(Jenkins)">false</MinimalRebuild> |
||||
</ClCompile> |
||||
<Link> |
||||
<SubSystem>Windows</SubSystem> |
||||
<GenerateDebugInformation Condition="!$(Jenkins)">true</GenerateDebugInformation> |
||||
<GenerateDebugInformation Condition="$(Jenkins)">false</GenerateDebugInformation> |
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding> |
||||
<OptimizeReferences>true</OptimizeReferences> |
||||
</Link> |
||||
</ItemDefinitionGroup> |
||||
|
||||
<ItemGroup> |
||||
<ClCompile Include="$(SolutionDir)\..\test\core\util\one_corpus_entry_fuzzer.c"> |
||||
</ClCompile> |
||||
</ItemGroup> |
||||
<ItemGroup> |
||||
<ProjectReference Include="$(SolutionDir)\..\vsprojects\vcxproj\.\gpr\gpr.vcxproj"> |
||||
<Project>{B23D3D1A-9438-4EDA-BEB6-9A0A03D17792}</Project> |
||||
</ProjectReference> |
||||
</ItemGroup> |
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> |
||||
<ImportGroup Label="ExtensionTargets"> |
||||
</ImportGroup> |
||||
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild"> |
||||
<PropertyGroup> |
||||
<ErrorText>This project references NuGet package(s) that are missing on this computer. Enable NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText> |
||||
</PropertyGroup> |
||||
</Target> |
||||
</Project> |
||||
|
@ -0,0 +1,21 @@ |
||||
<?xml version="1.0" encoding="utf-8"?> |
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> |
||||
<ItemGroup> |
||||
<ClCompile Include="$(SolutionDir)\..\test\core\util\one_corpus_entry_fuzzer.c"> |
||||
<Filter>test\core\util</Filter> |
||||
</ClCompile> |
||||
</ItemGroup> |
||||
|
||||
<ItemGroup> |
||||
<Filter Include="test"> |
||||
<UniqueIdentifier>{178c17dc-766b-aa84-e928-d6bd0e456ff9}</UniqueIdentifier> |
||||
</Filter> |
||||
<Filter Include="test\core"> |
||||
<UniqueIdentifier>{f08c2f86-ff65-4ce8-1ae6-e40fae0cef67}</UniqueIdentifier> |
||||
</Filter> |
||||
<Filter Include="test\core\util"> |
||||
<UniqueIdentifier>{17c672ec-2cce-5636-14c8-4812cd2e1b9a}</UniqueIdentifier> |
||||
</Filter> |
||||
</ItemGroup> |
||||
</Project> |
||||
|
Loading…
Reference in new issue