Home | History | Annotate | Download | only in integration
      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.ManagedChannel;
     23 import io.grpc.ManagedChannelBuilder;
     24 import io.grpc.netty.NettyChannelBuilder;
     25 import java.io.IOException;
     26 import java.io.PrintWriter;
     27 import java.io.StringWriter;
     28 import java.text.SimpleDateFormat;
     29 import java.util.Calendar;
     30 import java.util.Queue;
     31 import java.util.concurrent.ConcurrentLinkedQueue;
     32 import java.util.logging.Handler;
     33 import java.util.logging.LogRecord;
     34 import java.util.logging.Logger;
     35 import java.util.logging.SimpleFormatter;
     36 import javax.servlet.http.HttpServlet;
     37 import javax.servlet.http.HttpServletRequest;
     38 import javax.servlet.http.HttpServletResponse;
     39 import org.junit.Ignore;
     40 import org.junit.runner.JUnitCore;
     41 import org.junit.runner.Result;
     42 import org.junit.runner.notification.Failure;
     43 
     44 /**
     45  * This servlet communicates with {@code grpc-test.sandbox.googleapis.com}, which is a server
     46  * managed by the gRPC team. For more information, see
     47  * <a href="https://github.com/grpc/grpc/blob/master/doc/interop-test-descriptions.md">
     48  *   Interoperability Test Case Descriptions</a>.
     49  */
     50 @SuppressWarnings("serial")
     51 public final class NettyClientInteropServlet extends HttpServlet {
     52   private static final String INTEROP_TEST_ADDRESS = "grpc-test.sandbox.googleapis.com:443";
     53 
     54   private static final class LogEntryRecorder extends Handler {
     55     private Queue<LogRecord> loggedMessages = new ConcurrentLinkedQueue<>();
     56 
     57     @Override
     58     public void publish(LogRecord logRecord) {
     59       loggedMessages.add(logRecord);
     60     }
     61 
     62     @Override
     63     public void flush() {}
     64 
     65     @Override
     66     public void close() {}
     67 
     68     public String getLogOutput() {
     69       SimpleFormatter formatter = new SimpleFormatter();
     70       StringBuilder sb = new StringBuilder();
     71       for (LogRecord loggedMessage : loggedMessages) {
     72         sb.append(formatter.format(loggedMessage));
     73       }
     74       return sb.toString();
     75     }
     76   }
     77 
     78   @Override
     79   public void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException {
     80     LogEntryRecorder handler = new LogEntryRecorder();
     81     Logger.getLogger("").addHandler(handler);
     82     try {
     83       doGetHelper(req, resp);
     84     } finally {
     85       Logger.getLogger("").removeHandler(handler);
     86     }
     87     resp.getWriter().append("=======================================\n")
     88         .append("Server side java.util.logging messages:\n")
     89         .append(handler.getLogOutput());
     90   }
     91 
     92   private void doGetHelper(HttpServletRequest req, HttpServletResponse resp) throws IOException {
     93     resp.setContentType("text/plain");
     94     PrintWriter writer = resp.getWriter();
     95     writer.println("Test invoked at: ");
     96     writer.println(new SimpleDateFormat("yyyy/MM/dd HH:mm:ss Z")
     97         .format(Calendar.getInstance().getTime()));
     98 
     99     Result result = new JUnitCore().run(Tester.class);
    100     if (result.wasSuccessful()) {
    101       resp.setStatus(200);
    102       writer.println(
    103           String.format(
    104               "PASS! Tests ran %d, tests ignored %d",
    105               result.getRunCount(),
    106               result.getIgnoreCount()));
    107     } else {
    108       resp.setStatus(500);
    109       writer.println(
    110           String.format(
    111               "FAILED! Tests ran %d, tests failed %d, tests ignored %d",
    112               result.getRunCount(),
    113               result.getFailureCount(),
    114               result.getIgnoreCount()));
    115       for (Failure failure : result.getFailures()) {
    116         writer.println("================================");
    117         writer.println(failure.getTestHeader());
    118         Throwable thrown = failure.getException();
    119         StringWriter stringWriter = new StringWriter();
    120         PrintWriter printWriter = new PrintWriter(stringWriter);
    121         thrown.printStackTrace(printWriter);
    122         writer.println(stringWriter);
    123       }
    124     }
    125   }
    126 
    127   public static final class Tester extends AbstractInteropTest {
    128     @Override
    129     protected ManagedChannel createChannel() {
    130       assertEquals(
    131           "jdk8 required",
    132           "1.8",
    133           System.getProperty("java.specification.version"));
    134       ManagedChannelBuilder<?> builder =
    135           ManagedChannelBuilder.forTarget(INTEROP_TEST_ADDRESS)
    136               .maxInboundMessageSize(AbstractInteropTest.MAX_MESSAGE_SIZE);
    137       assertTrue(builder instanceof NettyChannelBuilder);
    138       ((NettyChannelBuilder) builder).flowControlWindow(65 * 1024);
    139       return builder.build();
    140     }
    141 
    142     @Override
    143     protected boolean metricsExpected() {
    144       // Server-side metrics won't be found because the server is running remotely.
    145       return false;
    146     }
    147 
    148     // grpc-test.sandbox.googleapis.com does not support these tests
    149     @Ignore
    150     @Override
    151     public void customMetadata() { }
    152 
    153     @Ignore
    154     @Override
    155     public void statusCodeAndMessage() { }
    156 
    157     @Ignore
    158     @Override
    159     public void exchangeMetadataUnaryCall() { }
    160 
    161     @Ignore
    162     @Override
    163     public void exchangeMetadataStreamingCall() { }
    164 
    165     @Ignore
    166     @Override
    167     public void specialStatusMessage() {}
    168   }
    169 }
    170