mirror of https://github.com/grpc/grpc.git
commit
1900ca157f
172 changed files with 5901 additions and 3512 deletions
@ -1,189 +1,3 @@ |
||||
#OAuth2 on gRPC: Objective-C |
||||
|
||||
This example application demostrates how to use OAuth2 on gRPC to make authenticated API calls on |
||||
behalf of a user. By walking through it you'll learn how to use the Objective-C gRPC API to: |
||||
|
||||
- Initialize and configure a remote call object before the RPC is started. |
||||
- Set request metadata elements on a call, which are semantically equivalent to HTTP request |
||||
headers. |
||||
- Read response metadata from a call, which is equivalent to HTTP response headers and trailers. |
||||
|
||||
It assumes you know the basics on how to make gRPC API calls using the Objective-C client library, |
||||
as shown in the [Hello World](../helloworld) |
||||
or [Route Guide](../route_guide) tutorials, |
||||
and are familiar with OAuth2 concepts like _access token_. |
||||
|
||||
- [Example code and setup](#setup) |
||||
- [Try it out!](#try) |
||||
- [Create an RPC object and start it later](#rpc-object) |
||||
- [Set request metadata of a call: Authorization header with an access token](#request-metadata) |
||||
- [Get response metadata of a call: Auth challenge header](#response-metadata) |
||||
|
||||
<a name="setup"></a> |
||||
## Example code and setup |
||||
|
||||
The example code for our tutorial is in [examples/objective-c/auth_sample](.). |
||||
To download the example, clone this repository by running the following command: |
||||
```shell |
||||
$ git clone https://github.com/grpc/grpc.git |
||||
``` |
||||
|
||||
Then change your current directory to `examples/objective-c/auth_sample`: |
||||
```shell |
||||
$ cd examples/objective-c/auth_sample |
||||
``` |
||||
|
||||
Our example is a simple application with two views. The first one lets a user sign in and out using |
||||
the OAuth2 flow of Google's [iOS SignIn library](https://developers.google.com/identity/sign-in/ios/). |
||||
(Google's library is used in this example because the test gRPC service we are going to call expects |
||||
Google account credentials, but neither gRPC nor the Objective-C client library is tied to any |
||||
specific OAuth2 provider). The second view makes a gRPC request to the test server, using the |
||||
access token obtained by the first view. |
||||
|
||||
Note: OAuth2 libraries need the application to register and obtain an ID from the identity provider |
||||
(in the case of this example app, Google). The app's XCode project is configured using that ID, so |
||||
you shouldn't copy this project "as is" for your own app: it would result in your app being |
||||
identified in the consent screen as "gRPC-AuthSample", and not having access to real Google |
||||
services. Instead, configure your own XCode project following the [instructions here](https://developers.google.com/identity/sign-in/ios/). |
||||
|
||||
As with the other examples, you also should have [Cocoapods](https://cocoapods.org/#install) |
||||
installed, as well as the relevant tools to generate the client library code. You can obtain the |
||||
latter by following [these setup instructions](https://github.com/grpc/homebrew-grpc). |
||||
|
||||
|
||||
<a name="try"></a> |
||||
## Try it out! |
||||
|
||||
To try the sample app, first have Cocoapods generate and install the client library for our .proto |
||||
files: |
||||
|
||||
```shell |
||||
$ pod install |
||||
``` |
||||
|
||||
(This might have to compile OpenSSL, which takes around 15 minutes if Cocoapods doesn't have it yet |
||||
on your computer's cache). |
||||
|
||||
Finally, open the XCode workspace created by Cocoapods, and run the app. |
||||
|
||||
The first view, `SelectUserViewController.h/m`, asks you to sign in with your Google account, and to |
||||
give the "gRPC-AuthSample" app the following permissions: |
||||
|
||||
- View your email address. |
||||
- View your basic profile info. |
||||
- "Test scope for access to the Zoo service". |
||||
|
||||
This last permission, corresponding to the scope `https://www.googleapis.com/auth/xapi.zoo` doesn't |
||||
grant any real capability: it's only used for testing. You can log out at any time. |
||||
|
||||
The second view, `MakeRPCViewController.h/m`, makes a gRPC request to a test server at |
||||
https://grpc-test.sandbox.google.com, sending the access token along with the request. The test |
||||
service simply validates the token and writes in its response which user it belongs to, and which |
||||
scopes it gives access to. (The client application already knows those two values; it's a way to |
||||
verify that everything went as expected). |
||||
|
||||
The next sections guide you step-by-step through how the gRPC call in `MakeRPCViewController` is |
||||
performed. |
||||
|
||||
<a name="rpc-object"></a> |
||||
## Create an RPC object and start it later |
||||
|
||||
The other basic tutorials show how to invoke an RPC by calling an asynchronous method in a generated |
||||
client object. This shows how to initialize an object that represents the RPC, and configure it |
||||
before starting the network request. |
||||
|
||||
Assume you have a proto service definition like this: |
||||
|
||||
```protobuf |
||||
option objc_class_prefix = "AUTH"; |
||||
|
||||
service TestService { |
||||
rpc UnaryCall(Request) returns (Response); |
||||
} |
||||
``` |
||||
|
||||
A `unaryCallWithRequest:handler:` method, with which you're already familiar, is generated for the |
||||
`AUTHTestService` class: |
||||
|
||||
```objective-c |
||||
[client unaryCallWithRequest:request handler:^(AUTHResponse *response, NSError *error) { |
||||
... |
||||
}]; |
||||
``` |
||||
|
||||
In addition, an `RPCToUnaryCallWithRequest:handler:` method is generated, which returns a |
||||
not-yet-started RPC object: |
||||
|
||||
```objective-c |
||||
#import <ProtoRPC/ProtoRPC.h> |
||||
|
||||
ProtoRPC *call = |
||||
[client RPCToUnaryCallWithRequest:request handler:^(AUTHResponse *response, NSError *error) { |
||||
... |
||||
}]; |
||||
``` |
||||
|
||||
The RPC represented by this object can be started at any later time like this: |
||||
|
||||
```objective-c |
||||
[call start]; |
||||
``` |
||||
|
||||
<a name="request-metadata"></a> |
||||
## Set request metadata of a call: Authorization header with an access token |
||||
|
||||
The `ProtoRPC` class has a `requestMetadata` property (inherited from `GRPCCall`) defined like this: |
||||
|
||||
```objective-c |
||||
- (NSMutableDictionary *)requestMetadata; // nonatomic |
||||
- (void)setRequestMetadata:(NSDictionary *)requestMetadata; // nonatomic, copy |
||||
``` |
||||
|
||||
Setting it to a dictionary of metadata keys and values will have them sent on the wire when the call |
||||
is started. gRPC metadata are pieces of information about the call sent by the client to the server |
||||
(and vice versa). They take the form of key-value pairs and are essentially opaque to gRPC itself. |
||||
|
||||
```objective-c |
||||
call.requestMetadata = @{@"My-Header": @"Value for this header", |
||||
@"Another-Header": @"Its value"}; |
||||
``` |
||||
|
||||
For convenience, the property is initialized with an empty `NSMutableDictionary`, so that request |
||||
metadata elements can be set like this: |
||||
|
||||
```objective-c |
||||
call.requestMetadata[@"My-Header"] = @"Value for this header"; |
||||
``` |
||||
|
||||
If you have an access token, OAuth2 specifies it is to be sent in this format: |
||||
|
||||
```objective-c |
||||
call.requestMetadata[@"Authorization"] = [@"Bearer " stringByAppendingString:accessToken]; |
||||
``` |
||||
|
||||
<a name="response-metadata"></a> |
||||
## Get response metadata of a call: Auth challenge header |
||||
|
||||
The `ProtoRPC` class also inherits a `responseMetadata` property, analogous to the request metadata |
||||
we just looked at. It's defined like this: |
||||
|
||||
```objective-c |
||||
@property(atomic, readonly) NSDictionary *responseMetadata; |
||||
``` |
||||
|
||||
To access OAuth2's authentication challenge header you write: |
||||
|
||||
```objective-c |
||||
call.responseMetadata[@"www-authenticate"] |
||||
``` |
||||
|
||||
Note that, as gRPC metadata elements are mapped to HTTP/2 headers (or trailers), the keys of the |
||||
response metadata are always ASCII strings in lowercase. |
||||
|
||||
Many uses cases of response metadata are getting more details about an RPC error. For convenience, |
||||
when a `NSError` instance is passed to an RPC handler block, the response metadata dictionary can |
||||
also be accessed this way: |
||||
|
||||
```objective-c |
||||
error.userInfo[kGRPCStatusMetadataKey] |
||||
``` |
||||
This is the supporting code for the tutorial "[OAuth2 on gRPC: Objective-C](http://www.grpc.io/docs/tutorials/auth/oauth2-objective-c.html)." |
||||
|
@ -0,0 +1,99 @@ |
||||
#region Copyright notice and license |
||||
|
||||
// Copyright 2015, 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. |
||||
|
||||
#endregion |
||||
|
||||
using System; |
||||
using System.Diagnostics; |
||||
using System.Linq; |
||||
using System.Threading; |
||||
using System.Threading.Tasks; |
||||
using Grpc.Core; |
||||
using Grpc.Core.Internal; |
||||
using Grpc.Core.Profiling; |
||||
using Grpc.Core.Utils; |
||||
using NUnit.Framework; |
||||
|
||||
namespace Grpc.Core.Tests |
||||
{ |
||||
public class PerformanceTest |
||||
{ |
||||
const string Host = "127.0.0.1"; |
||||
|
||||
MockServiceHelper helper; |
||||
Server server; |
||||
Channel channel; |
||||
|
||||
[SetUp] |
||||
public void Init() |
||||
{ |
||||
helper = new MockServiceHelper(Host); |
||||
server = helper.GetServer(); |
||||
server.Start(); |
||||
channel = helper.GetChannel(); |
||||
} |
||||
|
||||
[TearDown] |
||||
public void Cleanup() |
||||
{ |
||||
channel.ShutdownAsync().Wait(); |
||||
server.ShutdownAsync().Wait(); |
||||
} |
||||
|
||||
// Test attribute commented out to prevent running as part of the default test suite. |
||||
//[Test] |
||||
//[Category("Performance")] |
||||
public void UnaryCallPerformance() |
||||
{ |
||||
var profiler = new BasicProfiler(); |
||||
Profilers.SetForCurrentThread(profiler); |
||||
|
||||
helper.UnaryHandler = new UnaryServerMethod<string, string>(async (request, context) => |
||||
{ |
||||
return request; |
||||
}); |
||||
|
||||
var callDetails = helper.CreateUnaryCall(); |
||||
for(int i = 0; i < 3000; i++) |
||||
{ |
||||
Calls.BlockingUnaryCall(callDetails, "ABC"); |
||||
} |
||||
|
||||
profiler.Reset(); |
||||
|
||||
for(int i = 0; i < 3000; i++) |
||||
{ |
||||
Calls.BlockingUnaryCall(callDetails, "ABC"); |
||||
} |
||||
profiler.Dump("latency_trace_csharp.txt"); |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,47 @@ |
||||
#region Copyright notice and license |
||||
|
||||
// Copyright 2015, 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. |
||||
|
||||
#endregion |
||||
|
||||
using System; |
||||
using System.IO; |
||||
using System.Threading; |
||||
using Grpc.Core.Internal; |
||||
|
||||
namespace Grpc.Core.Profiling |
||||
{ |
||||
internal interface IProfiler |
||||
{ |
||||
void Begin(string tag); |
||||
void End(string tag); |
||||
void Mark(string tag); |
||||
} |
||||
} |
@ -0,0 +1,87 @@ |
||||
#region Copyright notice and license |
||||
|
||||
// Copyright 2015, 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. |
||||
|
||||
#endregion |
||||
|
||||
using System; |
||||
using System.IO; |
||||
using System.Threading; |
||||
using Grpc.Core.Internal; |
||||
|
||||
namespace Grpc.Core.Profiling |
||||
{ |
||||
internal struct ProfilerEntry |
||||
{ |
||||
public enum Type { |
||||
BEGIN, |
||||
END, |
||||
MARK |
||||
} |
||||
|
||||
public ProfilerEntry(Timespec timespec, Type type, string tag) |
||||
{ |
||||
this.timespec = timespec; |
||||
this.type = type; |
||||
this.tag = tag; |
||||
} |
||||
|
||||
public Timespec timespec; |
||||
public Type type; |
||||
public string tag; |
||||
|
||||
public override string ToString() |
||||
{ |
||||
// mimic the output format used by C core. |
||||
return string.Format( |
||||
"{{\"t\": {0}.{1}, \"thd\":\"unknown\", \"type\": \"{2}\", \"tag\": \"{3}\", " + |
||||
"\"file\": \"unknown\", \"line\": 0, \"imp\": 0}}", |
||||
timespec.TimevalSeconds, timespec.TimevalNanos.ToString("D9"), |
||||
GetTypeAbbreviation(type), tag); |
||||
} |
||||
|
||||
internal static string GetTypeAbbreviation(Type type) |
||||
{ |
||||
switch (type) |
||||
{ |
||||
case Type.BEGIN: |
||||
return "{"; |
||||
|
||||
case Type.END: |
||||
return "}"; |
||||
|
||||
case Type.MARK: |
||||
return "."; |
||||
default: |
||||
throw new ArgumentException("Unknown type"); |
||||
} |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,60 @@ |
||||
#region Copyright notice and license |
||||
|
||||
// Copyright 2015, 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. |
||||
|
||||
#endregion |
||||
|
||||
using System; |
||||
using System.IO; |
||||
using System.Threading; |
||||
using Grpc.Core.Internal; |
||||
|
||||
namespace Grpc.Core.Profiling |
||||
{ |
||||
// Allows declaring Begin and End of a profiler scope with a using statement. |
||||
// declared as struct for better performance. |
||||
internal struct ProfilerScope : IDisposable |
||||
{ |
||||
readonly IProfiler profiler; |
||||
readonly string tag; |
||||
|
||||
public ProfilerScope(IProfiler profiler, string tag) |
||||
{ |
||||
this.profiler = profiler; |
||||
this.tag = tag; |
||||
this.profiler.Begin(this.tag); |
||||
} |
||||
|
||||
public void Dispose() |
||||
{ |
||||
profiler.End(tag); |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,131 @@ |
||||
#region Copyright notice and license |
||||
|
||||
// Copyright 2015, 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. |
||||
|
||||
#endregion |
||||
|
||||
using System; |
||||
using System.IO; |
||||
using System.Threading; |
||||
using Grpc.Core.Internal; |
||||
|
||||
namespace Grpc.Core.Profiling |
||||
{ |
||||
internal static class Profilers |
||||
{ |
||||
static readonly NopProfiler defaultProfiler = new NopProfiler(); |
||||
static readonly ThreadLocal<IProfiler> profilers = new ThreadLocal<IProfiler>(); |
||||
|
||||
public static IProfiler ForCurrentThread() |
||||
{ |
||||
return profilers.Value ?? defaultProfiler; |
||||
} |
||||
|
||||
public static void SetForCurrentThread(IProfiler profiler) |
||||
{ |
||||
profilers.Value = profiler; |
||||
} |
||||
|
||||
public static ProfilerScope NewScope(this IProfiler profiler, string tag) |
||||
{ |
||||
return new ProfilerScope(profiler, tag); |
||||
} |
||||
} |
||||
|
||||
internal class NopProfiler : IProfiler |
||||
{ |
||||
public void Begin(string tag) |
||||
{ |
||||
} |
||||
|
||||
public void End(string tag) |
||||
{ |
||||
} |
||||
|
||||
public void Mark(string tag) |
||||
{ |
||||
} |
||||
} |
||||
|
||||
// Profiler using Timespec.PreciseNow |
||||
internal class BasicProfiler : IProfiler |
||||
{ |
||||
ProfilerEntry[] entries; |
||||
int count; |
||||
|
||||
public BasicProfiler() : this(1024*1024) |
||||
{ |
||||
} |
||||
|
||||
public BasicProfiler(int capacity) |
||||
{ |
||||
this.entries = new ProfilerEntry[capacity]; |
||||
} |
||||
|
||||
public void Begin(string tag) { |
||||
AddEntry(new ProfilerEntry(Timespec.PreciseNow, ProfilerEntry.Type.BEGIN, tag)); |
||||
} |
||||
|
||||
public void End(string tag) { |
||||
AddEntry(new ProfilerEntry(Timespec.PreciseNow, ProfilerEntry.Type.END, tag)); |
||||
} |
||||
|
||||
public void Mark(string tag) { |
||||
AddEntry(new ProfilerEntry(Timespec.PreciseNow, ProfilerEntry.Type.MARK, tag)); |
||||
} |
||||
|
||||
public void Reset() |
||||
{ |
||||
count = 0; |
||||
} |
||||
|
||||
public void Dump(string filepath) |
||||
{ |
||||
using (var stream = new StreamWriter(filepath)) |
||||
{ |
||||
Dump(stream); |
||||
} |
||||
} |
||||
|
||||
public void Dump(TextWriter stream) |
||||
{ |
||||
for (int i = 0; i < count; i++) |
||||
{ |
||||
var entry = entries[i]; |
||||
stream.WriteLine(entry.ToString()); |
||||
} |
||||
} |
||||
|
||||
// NOT THREADSAFE! |
||||
void AddEntry(ProfilerEntry entry) { |
||||
entries[count++] = entry; |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,128 @@ |
||||
#!/usr/bin/env python2.7 |
||||
# Copyright 2015, 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. |
||||
|
||||
"""Change comments style of source files from // to /** */""" |
||||
|
||||
import re |
||||
import sys |
||||
|
||||
|
||||
if len(sys.argv) < 2: |
||||
print("Please provide at least one source file name as argument.") |
||||
sys.exit() |
||||
|
||||
for file_name in sys.argv[1:]: |
||||
|
||||
print("Modifying format of {file} comments in place...".format( |
||||
file=file_name, |
||||
)) |
||||
|
||||
|
||||
# Input |
||||
|
||||
with open(file_name, "r") as input_file: |
||||
lines = input_file.readlines() |
||||
|
||||
def peek(): |
||||
return lines[0] |
||||
|
||||
def read_line(): |
||||
return lines.pop(0) |
||||
|
||||
def more_input_available(): |
||||
return lines |
||||
|
||||
|
||||
# Output |
||||
|
||||
output_lines = [] |
||||
|
||||
def write(line): |
||||
output_lines.append(line) |
||||
|
||||
def flush_output(): |
||||
with open(file_name, "w") as output_file: |
||||
for line in output_lines: |
||||
output_file.write(line) |
||||
|
||||
|
||||
# Pattern matching |
||||
|
||||
comment_regex = r'^(\s*)//\s(.*)$' |
||||
|
||||
def is_comment(line): |
||||
return re.search(comment_regex, line) |
||||
|
||||
def isnt_comment(line): |
||||
return not is_comment(line) |
||||
|
||||
def next_line(predicate): |
||||
return more_input_available() and predicate(peek()) |
||||
|
||||
|
||||
# Transformation |
||||
|
||||
def indentation_of(line): |
||||
match = re.search(comment_regex, line) |
||||
return match.group(1) |
||||
|
||||
def content(line): |
||||
match = re.search(comment_regex, line) |
||||
return match.group(2) |
||||
|
||||
def format_as_block(comment_block): |
||||
if len(comment_block) == 0: |
||||
return [] |
||||
|
||||
indent = indentation_of(comment_block[0]) |
||||
|
||||
if len(comment_block) == 1: |
||||
return [indent + "/** " + content(comment_block[0]) + " */\n"] |
||||
|
||||
block = ["/**"] + [" * " + content(line) for line in comment_block] + [" */"] |
||||
return [indent + line.rstrip() + "\n" for line in block] |
||||
|
||||
|
||||
# Main algorithm |
||||
|
||||
while more_input_available(): |
||||
while next_line(isnt_comment): |
||||
write(read_line()) |
||||
|
||||
comment_block = [] |
||||
# Get all lines in the same comment block. We could restrict the indentation |
||||
# to be the same as the first line of the block, but it's probably ok. |
||||
while (next_line(is_comment)): |
||||
comment_block.append(read_line()) |
||||
|
||||
for line in format_as_block(comment_block): |
||||
write(line) |
||||
|
||||
flush_output() |
@ -0,0 +1,31 @@ |
||||
#!/bin/bash |
||||
# Copyright 2015, 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. |
||||
|
||||
find . -type f -name "*.h" ! -path "*/Pods/*" ! -path "./generated_libraries/*" ! -path "./examples/*" ! -path "./tests/*" | xargs ./change-comments.py |
@ -0,0 +1,50 @@ |
||||
/* |
||||
* |
||||
* Copyright 2015, 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. |
||||
* |
||||
*/ |
||||
|
||||
#import <GRPCClient/GRPCCall+Tests.h> |
||||
|
||||
#import "InteropTests.h" |
||||
|
||||
static NSString * const kRemoteSSLHost = @"grpc-test.sandbox.google.com"; |
||||
|
||||
/** Tests in InteropTests.m, sending the RPCs to a remote SSL server. */ |
||||
@interface InteropTestsRemote : InteropTests |
||||
@end |
||||
|
||||
@implementation InteropTestsRemote |
||||
|
||||
+ (NSString *)host { |
||||
return kRemoteSSLHost; |
||||
} |
||||
|
||||
@end |
@ -1,164 +0,0 @@ |
||||
/* |
||||
* |
||||
* Copyright 2015, 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. |
||||
* |
||||
*/ |
||||
|
||||
#import <UIKit/UIKit.h> |
||||
#import <XCTest/XCTest.h> |
||||
|
||||
#import <GRPCClient/GRPCCall.h> |
||||
#import <ProtoRPC/ProtoMethod.h> |
||||
#import <RouteGuide/RouteGuide.pbobjc.h> |
||||
#import <RouteGuide/RouteGuide.pbrpc.h> |
||||
#import <RxLibrary/GRXWriteable.h> |
||||
#import <RxLibrary/GRXWriter+Immediate.h> |
||||
|
||||
// These tests require a gRPC "RouteGuide" sample server to be running locally. You can compile and |
||||
// run one by following the instructions here: https://github.com/grpc/grpc/blob/master/examples/cpp/cpptutorial.md#try-it-out |
||||
// Be sure to have the C gRPC library installed in your system (for example, by having followed the |
||||
// instructions at https://github.com/grpc/homebrew-grpc |
||||
|
||||
static NSString * const kRouteGuideHost = @"http://localhost:50051"; |
||||
static NSString * const kPackage = @"routeguide"; |
||||
static NSString * const kService = @"RouteGuide"; |
||||
|
||||
@interface LocalClearTextTests : XCTestCase |
||||
@end |
||||
|
||||
@implementation LocalClearTextTests |
||||
|
||||
// This test currently fails: see Issue #1907. |
||||
//- (void)testConnectionToLocalServer { |
||||
// __weak XCTestExpectation *expectation = [self expectationWithDescription:@"Server reachable."]; |
||||
// |
||||
// // This method isn't implemented by the local server. |
||||
// GRPCMethodName *method = [[GRPCMethodName alloc] initWithPackage:kPackage |
||||
// interface:kService |
||||
// method:@"EmptyCall"]; |
||||
// |
||||
// GRXWriter *requestsWriter = [GRXWriter writerWithValue:[NSData data]]; |
||||
// |
||||
// GRPCCall *call = [[GRPCCall alloc] initWithHost:kRouteGuideHost |
||||
// method:method |
||||
// requestsWriter:requestsWriter]; |
||||
// |
||||
// id<GRXWriteable> responsesWriteable = [[GRXWriteable alloc] initWithValueHandler:^(NSData *value) { |
||||
// XCTFail(@"Received unexpected response: %@", value); |
||||
// } completionHandler:^(NSError *errorOrNil) { |
||||
// XCTAssertNotNil(errorOrNil, @"Finished without error!"); |
||||
// XCTAssertEqual(errorOrNil.code, 12, @"Finished with unexpected error: %@", errorOrNil); |
||||
// [expectation fulfill]; |
||||
// }]; |
||||
// |
||||
// [call startWithWriteable:responsesWriteable]; |
||||
// |
||||
// [self waitForExpectationsWithTimeout:8.0 handler:nil]; |
||||
//} |
||||
|
||||
- (void)testEmptyRPC { |
||||
__weak XCTestExpectation *response = [self expectationWithDescription:@"Empty response received."]; |
||||
__weak XCTestExpectation *completion = [self expectationWithDescription:@"Empty RPC completed."]; |
||||
|
||||
ProtoMethod *method = [[ProtoMethod alloc] initWithPackage:kPackage |
||||
service:kService |
||||
method:@"RecordRoute"]; |
||||
|
||||
GRXWriter *requestsWriter = [GRXWriter emptyWriter]; |
||||
|
||||
GRPCCall *call = [[GRPCCall alloc] initWithHost:kRouteGuideHost |
||||
path:method.HTTPPath |
||||
requestsWriter:requestsWriter]; |
||||
|
||||
id<GRXWriteable> responsesWriteable = [[GRXWriteable alloc] initWithValueHandler:^(NSData *value) { |
||||
XCTAssertNotNil(value, @"nil value received as response."); |
||||
XCTAssertEqual([value length], 0, @"Non-empty response received: %@", value); |
||||
[response fulfill]; |
||||
} completionHandler:^(NSError *errorOrNil) { |
||||
XCTAssertNil(errorOrNil, @"Finished with unexpected error: %@", errorOrNil); |
||||
[completion fulfill]; |
||||
}]; |
||||
|
||||
[call startWithWriteable:responsesWriteable]; |
||||
|
||||
[self waitForExpectationsWithTimeout:2.0 handler:nil]; |
||||
} |
||||
|
||||
- (void)testSimpleProtoRPC { |
||||
__weak XCTestExpectation *response = [self expectationWithDescription:@"Response received."]; |
||||
__weak XCTestExpectation *completion = [self expectationWithDescription:@"RPC completed."]; |
||||
|
||||
ProtoMethod *method = [[ProtoMethod alloc] initWithPackage:kPackage |
||||
service:kService |
||||
method:@"GetFeature"]; |
||||
|
||||
RGDPoint *point = [RGDPoint message]; |
||||
point.latitude = 28E7; |
||||
point.longitude = -15E7; |
||||
GRXWriter *requestsWriter = [GRXWriter writerWithValue:[point data]]; |
||||
|
||||
GRPCCall *call = [[GRPCCall alloc] initWithHost:kRouteGuideHost |
||||
path:method.HTTPPath |
||||
requestsWriter:requestsWriter]; |
||||
|
||||
id<GRXWriteable> responsesWriteable = [[GRXWriteable alloc] initWithValueHandler:^(NSData *value) { |
||||
XCTAssertNotNil(value, @"nil value received as response."); |
||||
RGDFeature *feature = [RGDFeature parseFromData:value error:NULL]; |
||||
XCTAssertEqualObjects(point, feature.location); |
||||
XCTAssertNotNil(feature.name, @"Response's name is nil."); |
||||
[response fulfill]; |
||||
} completionHandler:^(NSError *errorOrNil) { |
||||
XCTAssertNil(errorOrNil, @"Finished with unexpected error: %@", errorOrNil); |
||||
[completion fulfill]; |
||||
}]; |
||||
|
||||
[call startWithWriteable:responsesWriteable]; |
||||
|
||||
[self waitForExpectationsWithTimeout:2.0 handler:nil]; |
||||
} |
||||
|
||||
- (void)testSimpleProtoRPCUsingGeneratedService { |
||||
__weak XCTestExpectation *completion = [self expectationWithDescription:@"RPC completed."]; |
||||
|
||||
RGDPoint *point = [RGDPoint message]; |
||||
point.latitude = 28E7; |
||||
point.longitude = -15E7; |
||||
|
||||
RGDRouteGuide *service = [[RGDRouteGuide alloc] initWithHost:kRouteGuideHost]; |
||||
[service getFeatureWithRequest:point handler:^(RGDFeature *response, NSError *error) { |
||||
XCTAssertNil(error, @"Finished with unexpected error: %@", error); |
||||
XCTAssertEqualObjects(point, response.location); |
||||
XCTAssertNotNil(response.name, @"Response's name is nil."); |
||||
[completion fulfill]; |
||||
}]; |
||||
|
||||
[self waitForExpectationsWithTimeout:2.0 handler:nil]; |
||||
} |
||||
@end |
@ -0,0 +1,101 @@ |
||||
<?xml version="1.0" encoding="UTF-8"?> |
||||
<Scheme |
||||
LastUpgradeVersion = "0700" |
||||
version = "1.3"> |
||||
<BuildAction |
||||
parallelizeBuildables = "YES" |
||||
buildImplicitDependencies = "YES"> |
||||
<BuildActionEntries> |
||||
<BuildActionEntry |
||||
buildForTesting = "YES" |
||||
buildForRunning = "YES" |
||||
buildForProfiling = "NO" |
||||
buildForArchiving = "NO" |
||||
buildForAnalyzing = "YES"> |
||||
<BuildableReference |
||||
BuildableIdentifier = "primary" |
||||
BlueprintIdentifier = "63DC84421BE152B5000708E8" |
||||
BuildableName = "InteropTestsLocalCleartext.xctest" |
||||
BlueprintName = "InteropTestsLocalCleartext" |
||||
ReferencedContainer = "container:Tests.xcodeproj"> |
||||
</BuildableReference> |
||||
</BuildActionEntry> |
||||
</BuildActionEntries> |
||||
</BuildAction> |
||||
<TestAction |
||||
buildConfiguration = "Debug" |
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB" |
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" |
||||
shouldUseLaunchSchemeArgsEnv = "YES"> |
||||
<Testables> |
||||
<TestableReference |
||||
skipped = "NO"> |
||||
<BuildableReference |
||||
BuildableIdentifier = "primary" |
||||
BlueprintIdentifier = "63DC84421BE152B5000708E8" |
||||
BuildableName = "InteropTestsLocalCleartext.xctest" |
||||
BlueprintName = "InteropTestsLocalCleartext" |
||||
ReferencedContainer = "container:Tests.xcodeproj"> |
||||
</BuildableReference> |
||||
<SkippedTests> |
||||
<Test |
||||
Identifier = "GRPCClientTests/testConnectionToRemoteServer"> |
||||
</Test> |
||||
<Test |
||||
Identifier = "GRPCClientTests/testMetadata"> |
||||
</Test> |
||||
<Test |
||||
Identifier = "InteropTests"> |
||||
</Test> |
||||
</SkippedTests> |
||||
</TestableReference> |
||||
</Testables> |
||||
<AdditionalOptions> |
||||
</AdditionalOptions> |
||||
</TestAction> |
||||
<LaunchAction |
||||
buildConfiguration = "Debug" |
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB" |
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" |
||||
launchStyle = "0" |
||||
useCustomWorkingDirectory = "NO" |
||||
ignoresPersistentStateOnLaunch = "NO" |
||||
debugDocumentVersioning = "YES" |
||||
debugServiceExtension = "internal" |
||||
allowLocationSimulation = "YES"> |
||||
<MacroExpansion> |
||||
<BuildableReference |
||||
BuildableIdentifier = "primary" |
||||
BlueprintIdentifier = "63DC84421BE152B5000708E8" |
||||
BuildableName = "InteropTestsLocalCleartext.xctest" |
||||
BlueprintName = "InteropTestsLocalCleartext" |
||||
ReferencedContainer = "container:Tests.xcodeproj"> |
||||
</BuildableReference> |
||||
</MacroExpansion> |
||||
<AdditionalOptions> |
||||
</AdditionalOptions> |
||||
</LaunchAction> |
||||
<ProfileAction |
||||
buildConfiguration = "Release" |
||||
shouldUseLaunchSchemeArgsEnv = "YES" |
||||
savedToolIdentifier = "" |
||||
useCustomWorkingDirectory = "NO" |
||||
debugDocumentVersioning = "YES"> |
||||
<MacroExpansion> |
||||
<BuildableReference |
||||
BuildableIdentifier = "primary" |
||||
BlueprintIdentifier = "63DC84421BE152B5000708E8" |
||||
BuildableName = "InteropTestsLocalCleartext.xctest" |
||||
BlueprintName = "InteropTestsLocalCleartext" |
||||
ReferencedContainer = "container:Tests.xcodeproj"> |
||||
</BuildableReference> |
||||
</MacroExpansion> |
||||
</ProfileAction> |
||||
<AnalyzeAction |
||||
buildConfiguration = "Debug"> |
||||
</AnalyzeAction> |
||||
<ArchiveAction |
||||
buildConfiguration = "Release" |
||||
revealArchiveInOrganizer = "YES"> |
||||
</ArchiveAction> |
||||
</Scheme> |
@ -0,0 +1,95 @@ |
||||
<?xml version="1.0" encoding="UTF-8"?> |
||||
<Scheme |
||||
LastUpgradeVersion = "0700" |
||||
version = "1.3"> |
||||
<BuildAction |
||||
parallelizeBuildables = "YES" |
||||
buildImplicitDependencies = "YES"> |
||||
<BuildActionEntries> |
||||
<BuildActionEntry |
||||
buildForTesting = "YES" |
||||
buildForRunning = "YES" |
||||
buildForProfiling = "NO" |
||||
buildForArchiving = "NO" |
||||
buildForAnalyzing = "YES"> |
||||
<BuildableReference |
||||
BuildableIdentifier = "primary" |
||||
BlueprintIdentifier = "63DC84331BE15294000708E8" |
||||
BuildableName = "InteropTestsLocalSSL.xctest" |
||||
BlueprintName = "InteropTestsLocalSSL" |
||||
ReferencedContainer = "container:Tests.xcodeproj"> |
||||
</BuildableReference> |
||||
</BuildActionEntry> |
||||
</BuildActionEntries> |
||||
</BuildAction> |
||||
<TestAction |
||||
buildConfiguration = "Debug" |
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB" |
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" |
||||
shouldUseLaunchSchemeArgsEnv = "YES"> |
||||
<Testables> |
||||
<TestableReference |
||||
skipped = "NO"> |
||||
<BuildableReference |
||||
BuildableIdentifier = "primary" |
||||
BlueprintIdentifier = "63DC84331BE15294000708E8" |
||||
BuildableName = "InteropTestsLocalSSL.xctest" |
||||
BlueprintName = "InteropTestsLocalSSL" |
||||
ReferencedContainer = "container:Tests.xcodeproj"> |
||||
</BuildableReference> |
||||
<SkippedTests> |
||||
<Test |
||||
Identifier = "InteropTests"> |
||||
</Test> |
||||
</SkippedTests> |
||||
</TestableReference> |
||||
</Testables> |
||||
<MacroExpansion> |
||||
<BuildableReference |
||||
BuildableIdentifier = "primary" |
||||
BlueprintIdentifier = "63DC84331BE15294000708E8" |
||||
BuildableName = "InteropTestsLocalSSL.xctest" |
||||
BlueprintName = "InteropTestsLocalSSL" |
||||
ReferencedContainer = "container:Tests.xcodeproj"> |
||||
</BuildableReference> |
||||
</MacroExpansion> |
||||
<AdditionalOptions> |
||||
</AdditionalOptions> |
||||
</TestAction> |
||||
<LaunchAction |
||||
buildConfiguration = "Debug" |
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB" |
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" |
||||
launchStyle = "0" |
||||
useCustomWorkingDirectory = "NO" |
||||
ignoresPersistentStateOnLaunch = "NO" |
||||
debugDocumentVersioning = "YES" |
||||
debugServiceExtension = "internal" |
||||
allowLocationSimulation = "YES"> |
||||
<MacroExpansion> |
||||
<BuildableReference |
||||
BuildableIdentifier = "primary" |
||||
BlueprintIdentifier = "63DC84331BE15294000708E8" |
||||
BuildableName = "InteropTestsLocalSSL.xctest" |
||||
BlueprintName = "InteropTestsLocalSSL" |
||||
ReferencedContainer = "container:Tests.xcodeproj"> |
||||
</BuildableReference> |
||||
</MacroExpansion> |
||||
<AdditionalOptions> |
||||
</AdditionalOptions> |
||||
</LaunchAction> |
||||
<ProfileAction |
||||
buildConfiguration = "Release" |
||||
shouldUseLaunchSchemeArgsEnv = "YES" |
||||
savedToolIdentifier = "" |
||||
useCustomWorkingDirectory = "NO" |
||||
debugDocumentVersioning = "YES"> |
||||
</ProfileAction> |
||||
<AnalyzeAction |
||||
buildConfiguration = "Debug"> |
||||
</AnalyzeAction> |
||||
<ArchiveAction |
||||
buildConfiguration = "Release" |
||||
revealArchiveInOrganizer = "YES"> |
||||
</ArchiveAction> |
||||
</Scheme> |
@ -0,0 +1,95 @@ |
||||
<?xml version="1.0" encoding="UTF-8"?> |
||||
<Scheme |
||||
LastUpgradeVersion = "0700" |
||||
version = "1.3"> |
||||
<BuildAction |
||||
parallelizeBuildables = "YES" |
||||
buildImplicitDependencies = "YES"> |
||||
<BuildActionEntries> |
||||
<BuildActionEntry |
||||
buildForTesting = "YES" |
||||
buildForRunning = "YES" |
||||
buildForProfiling = "NO" |
||||
buildForArchiving = "NO" |
||||
buildForAnalyzing = "YES"> |
||||
<BuildableReference |
||||
BuildableIdentifier = "primary" |
||||
BlueprintIdentifier = "63DC84221BE15267000708E8" |
||||
BuildableName = "InteropTestsRemote.xctest" |
||||
BlueprintName = "InteropTestsRemote" |
||||
ReferencedContainer = "container:Tests.xcodeproj"> |
||||
</BuildableReference> |
||||
</BuildActionEntry> |
||||
</BuildActionEntries> |
||||
</BuildAction> |
||||
<TestAction |
||||
buildConfiguration = "Debug" |
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB" |
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" |
||||
shouldUseLaunchSchemeArgsEnv = "YES"> |
||||
<Testables> |
||||
<TestableReference |
||||
skipped = "NO"> |
||||
<BuildableReference |
||||
BuildableIdentifier = "primary" |
||||
BlueprintIdentifier = "63DC84221BE15267000708E8" |
||||
BuildableName = "InteropTestsRemote.xctest" |
||||
BlueprintName = "InteropTestsRemote" |
||||
ReferencedContainer = "container:Tests.xcodeproj"> |
||||
</BuildableReference> |
||||
<SkippedTests> |
||||
<Test |
||||
Identifier = "InteropTests"> |
||||
</Test> |
||||
</SkippedTests> |
||||
</TestableReference> |
||||
</Testables> |
||||
<MacroExpansion> |
||||
<BuildableReference |
||||
BuildableIdentifier = "primary" |
||||
BlueprintIdentifier = "63DC84221BE15267000708E8" |
||||
BuildableName = "InteropTestsRemote.xctest" |
||||
BlueprintName = "InteropTestsRemote" |
||||
ReferencedContainer = "container:Tests.xcodeproj"> |
||||
</BuildableReference> |
||||
</MacroExpansion> |
||||
<AdditionalOptions> |
||||
</AdditionalOptions> |
||||
</TestAction> |
||||
<LaunchAction |
||||
buildConfiguration = "Debug" |
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB" |
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" |
||||
launchStyle = "0" |
||||
useCustomWorkingDirectory = "NO" |
||||
ignoresPersistentStateOnLaunch = "NO" |
||||
debugDocumentVersioning = "YES" |
||||
debugServiceExtension = "internal" |
||||
allowLocationSimulation = "YES"> |
||||
<MacroExpansion> |
||||
<BuildableReference |
||||
BuildableIdentifier = "primary" |
||||
BlueprintIdentifier = "63DC84221BE15267000708E8" |
||||
BuildableName = "InteropTestsRemote.xctest" |
||||
BlueprintName = "InteropTestsRemote" |
||||
ReferencedContainer = "container:Tests.xcodeproj"> |
||||
</BuildableReference> |
||||
</MacroExpansion> |
||||
<AdditionalOptions> |
||||
</AdditionalOptions> |
||||
</LaunchAction> |
||||
<ProfileAction |
||||
buildConfiguration = "Release" |
||||
shouldUseLaunchSchemeArgsEnv = "YES" |
||||
savedToolIdentifier = "" |
||||
useCustomWorkingDirectory = "NO" |
||||
debugDocumentVersioning = "YES"> |
||||
</ProfileAction> |
||||
<AnalyzeAction |
||||
buildConfiguration = "Debug"> |
||||
</AnalyzeAction> |
||||
<ArchiveAction |
||||
buildConfiguration = "Release" |
||||
revealArchiveInOrganizer = "YES"> |
||||
</ArchiveAction> |
||||
</Scheme> |
@ -0,0 +1,90 @@ |
||||
<?xml version="1.0" encoding="UTF-8"?> |
||||
<Scheme |
||||
LastUpgradeVersion = "0700" |
||||
version = "1.3"> |
||||
<BuildAction |
||||
parallelizeBuildables = "YES" |
||||
buildImplicitDependencies = "YES"> |
||||
<BuildActionEntries> |
||||
<BuildActionEntry |
||||
buildForTesting = "YES" |
||||
buildForRunning = "YES" |
||||
buildForProfiling = "NO" |
||||
buildForArchiving = "NO" |
||||
buildForAnalyzing = "YES"> |
||||
<BuildableReference |
||||
BuildableIdentifier = "primary" |
||||
BlueprintIdentifier = "63DC84121BE15179000708E8" |
||||
BuildableName = "RxLibraryUnitTests.xctest" |
||||
BlueprintName = "RxLibraryUnitTests" |
||||
ReferencedContainer = "container:Tests.xcodeproj"> |
||||
</BuildableReference> |
||||
</BuildActionEntry> |
||||
</BuildActionEntries> |
||||
</BuildAction> |
||||
<TestAction |
||||
buildConfiguration = "Debug" |
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB" |
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" |
||||
shouldUseLaunchSchemeArgsEnv = "YES"> |
||||
<Testables> |
||||
<TestableReference |
||||
skipped = "NO"> |
||||
<BuildableReference |
||||
BuildableIdentifier = "primary" |
||||
BlueprintIdentifier = "63DC84121BE15179000708E8" |
||||
BuildableName = "RxLibraryUnitTests.xctest" |
||||
BlueprintName = "RxLibraryUnitTests" |
||||
ReferencedContainer = "container:Tests.xcodeproj"> |
||||
</BuildableReference> |
||||
</TestableReference> |
||||
</Testables> |
||||
<MacroExpansion> |
||||
<BuildableReference |
||||
BuildableIdentifier = "primary" |
||||
BlueprintIdentifier = "63DC84121BE15179000708E8" |
||||
BuildableName = "RxLibraryUnitTests.xctest" |
||||
BlueprintName = "RxLibraryUnitTests" |
||||
ReferencedContainer = "container:Tests.xcodeproj"> |
||||
</BuildableReference> |
||||
</MacroExpansion> |
||||
<AdditionalOptions> |
||||
</AdditionalOptions> |
||||
</TestAction> |
||||
<LaunchAction |
||||
buildConfiguration = "Debug" |
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB" |
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" |
||||
launchStyle = "0" |
||||
useCustomWorkingDirectory = "NO" |
||||
ignoresPersistentStateOnLaunch = "NO" |
||||
debugDocumentVersioning = "YES" |
||||
debugServiceExtension = "internal" |
||||
allowLocationSimulation = "YES"> |
||||
<MacroExpansion> |
||||
<BuildableReference |
||||
BuildableIdentifier = "primary" |
||||
BlueprintIdentifier = "63DC84121BE15179000708E8" |
||||
BuildableName = "RxLibraryUnitTests.xctest" |
||||
BlueprintName = "RxLibraryUnitTests" |
||||
ReferencedContainer = "container:Tests.xcodeproj"> |
||||
</BuildableReference> |
||||
</MacroExpansion> |
||||
<AdditionalOptions> |
||||
</AdditionalOptions> |
||||
</LaunchAction> |
||||
<ProfileAction |
||||
buildConfiguration = "Release" |
||||
shouldUseLaunchSchemeArgsEnv = "YES" |
||||
savedToolIdentifier = "" |
||||
useCustomWorkingDirectory = "NO" |
||||
debugDocumentVersioning = "YES"> |
||||
</ProfileAction> |
||||
<AnalyzeAction |
||||
buildConfiguration = "Debug"> |
||||
</AnalyzeAction> |
||||
<ArchiveAction |
||||
buildConfiguration = "Release" |
||||
revealArchiveInOrganizer = "YES"> |
||||
</ArchiveAction> |
||||
</Scheme> |
@ -0,0 +1,40 @@ |
||||
#!/bin/bash |
||||
# Copyright 2015, 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 -e |
||||
command -v php-cs-fixer > /dev/null || { |
||||
echo "Cannot find php-cs-fixer. Exiting..." |
||||
exit 1 |
||||
} |
||||
cd $(dirname $0)/.. |
||||
php-cs-fixer fix lib/Grpc || true |
||||
php-cs-fixer fix tests/generated_code || true |
||||
php-cs-fixer fix tests/interop || true |
||||
php-cs-fixer fix tests/unit_tests || true |
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in new issue