• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2017 The gRPC Authors
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package io.grpc.testing.integration;
18 
19 import static org.junit.Assert.assertEquals;
20 import static org.junit.Assert.assertTrue;
21 
22 import io.grpc.Grpc;
23 import io.grpc.ManagedChannelBuilder;
24 import io.grpc.TlsChannelCredentials;
25 import io.grpc.netty.NettyChannelBuilder;
26 import java.io.IOException;
27 import java.io.PrintWriter;
28 import java.io.StringWriter;
29 import java.text.SimpleDateFormat;
30 import java.util.Calendar;
31 import java.util.Locale;
32 import java.util.Queue;
33 import java.util.concurrent.ConcurrentLinkedQueue;
34 import java.util.logging.Handler;
35 import java.util.logging.LogRecord;
36 import java.util.logging.Logger;
37 import java.util.logging.SimpleFormatter;
38 import javax.servlet.http.HttpServlet;
39 import javax.servlet.http.HttpServletRequest;
40 import javax.servlet.http.HttpServletResponse;
41 import org.junit.Ignore;
42 import org.junit.runner.JUnitCore;
43 import org.junit.runner.Result;
44 import org.junit.runner.notification.Failure;
45 
46 /**
47  * This servlet communicates with {@code grpc-test.sandbox.googleapis.com}, which is a server
48  * managed by the gRPC team. For more information, see
49  * <a href="https://github.com/grpc/grpc/blob/master/doc/interop-test-descriptions.md">
50  *   Interoperability Test Case Descriptions</a>.
51  */
52 @SuppressWarnings("serial")
53 public final class NettyClientInteropServlet extends HttpServlet {
54   private static final String INTEROP_TEST_ADDRESS = "grpc-test.sandbox.googleapis.com:443";
55 
56   private static final class LogEntryRecorder extends Handler {
57     private Queue<LogRecord> loggedMessages = new ConcurrentLinkedQueue<>();
58 
59     @Override
publish(LogRecord logRecord)60     public void publish(LogRecord logRecord) {
61       loggedMessages.add(logRecord);
62     }
63 
64     @Override
flush()65     public void flush() {}
66 
67     @Override
close()68     public void close() {}
69 
getLogOutput()70     public String getLogOutput() {
71       SimpleFormatter formatter = new SimpleFormatter();
72       StringBuilder sb = new StringBuilder();
73       for (LogRecord loggedMessage : loggedMessages) {
74         sb.append(formatter.format(loggedMessage));
75       }
76       return sb.toString();
77     }
78   }
79 
80   @Override
doGet(HttpServletRequest req, HttpServletResponse resp)81   public void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException {
82     LogEntryRecorder handler = new LogEntryRecorder();
83     Logger.getLogger("").addHandler(handler);
84     try {
85       doGetHelper(resp);
86     } finally {
87       Logger.getLogger("").removeHandler(handler);
88     }
89     resp.getWriter().append("=======================================\n")
90         .append("Server side java.util.logging messages:\n")
91         .append(handler.getLogOutput());
92   }
93 
doGetHelper(HttpServletResponse resp)94   private void doGetHelper(HttpServletResponse resp) throws IOException {
95     resp.setContentType("text/plain");
96     PrintWriter writer = resp.getWriter();
97     writer.println("Test invoked at: ");
98     writer.println(new SimpleDateFormat("yyyy/MM/dd HH:mm:ss Z")
99         .format(Calendar.getInstance().getTime()));
100 
101     Result result = new JUnitCore().run(Tester.class);
102     if (result.wasSuccessful()) {
103       resp.setStatus(200);
104       writer.println(
105           String.format(
106               Locale.US,
107               "PASS! Tests ran %d, tests ignored %d",
108               result.getRunCount(),
109               result.getIgnoreCount()));
110     } else {
111       resp.setStatus(500);
112       writer.println(
113           String.format(
114               Locale.US,
115               "FAILED! Tests ran %d, tests failed %d, tests ignored %d",
116               result.getRunCount(),
117               result.getFailureCount(),
118               result.getIgnoreCount()));
119       for (Failure failure : result.getFailures()) {
120         writer.println("================================");
121         writer.println(failure.getTestHeader());
122         Throwable thrown = failure.getException();
123         StringWriter stringWriter = new StringWriter();
124         PrintWriter printWriter = new PrintWriter(stringWriter);
125         thrown.printStackTrace(printWriter);
126         writer.println(stringWriter);
127       }
128     }
129   }
130 
131   public static final class Tester extends AbstractInteropTest {
132     @Override
createChannelBuilder()133     protected ManagedChannelBuilder<?> createChannelBuilder() {
134       assertEquals(
135           "jdk8 required",
136           "1.8",
137           System.getProperty("java.specification.version"));
138       ManagedChannelBuilder<?> builder =
139           Grpc.newChannelBuilder(INTEROP_TEST_ADDRESS, TlsChannelCredentials.create())
140               .maxInboundMessageSize(AbstractInteropTest.MAX_MESSAGE_SIZE);
141       assertTrue(builder instanceof NettyChannelBuilder);
142       ((NettyChannelBuilder) builder)
143           .flowControlWindow(AbstractInteropTest.TEST_FLOW_CONTROL_WINDOW);
144       return builder;
145     }
146 
147     @Override
metricsExpected()148     protected boolean metricsExpected() {
149       // Server-side metrics won't be found because the server is running remotely.
150       return false;
151     }
152 
153     // grpc-test.sandbox.googleapis.com does not support these tests
154     @Ignore
155     @Override
customMetadata()156     public void customMetadata() { }
157 
158     @Ignore
159     @Override
statusCodeAndMessage()160     public void statusCodeAndMessage() { }
161 
162     @Ignore
163     @Override
exchangeMetadataUnaryCall()164     public void exchangeMetadataUnaryCall() { }
165 
166     @Ignore
167     @Override
exchangeMetadataStreamingCall()168     public void exchangeMetadataStreamingCall() { }
169 
170     @Ignore
171     @Override
specialStatusMessage()172     public void specialStatusMessage() {}
173   }
174 }
175