1 /*
2  * Copyright 2015 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.protobuf.nano;
18 
19 import static org.junit.Assert.assertArrayEquals;
20 import static org.junit.Assert.assertEquals;
21 import static org.junit.Assert.assertNotSame;
22 import static org.junit.Assert.assertTrue;
23 import static org.junit.Assert.fail;
24 
25 import com.google.protobuf.nano.InvalidProtocolBufferNanoException;
26 import com.google.protobuf.nano.MessageNano;
27 import io.grpc.MethodDescriptor.Marshaller;
28 import io.grpc.Status;
29 import io.grpc.StatusRuntimeException;
30 import io.grpc.protobuf.nano.Messages.Message;
31 import java.io.ByteArrayInputStream;
32 import java.io.IOException;
33 import java.io.InputStream;
34 import org.junit.Test;
35 import org.junit.runner.RunWith;
36 import org.junit.runners.JUnit4;
37 
38 /** Unit tests for {@link NanoUtils}. */
39 @RunWith(JUnit4.class)
40 public class NanoUtilsTest {
41   private Marshaller<Message> marshaller = NanoUtils.marshaller(new MessageNanoFactory<Message>() {
42     @Override
43     public Message newInstance() {
44       return new Message();
45     }
46   });
47 
48   @Test
testRoundTrip()49   public void testRoundTrip() {
50     Message m = new Message();
51     m.i = 2;
52     m.b = true;
53     m.s = "string";
54     Message m2 = marshaller.parse(marshaller.stream(m));
55     assertNotSame(m, m2);
56     assertEquals(2, m2.i);
57     assertEquals(true, m2.b);
58     assertEquals("string", m2.s);
59     assertTrue(MessageNano.messageNanoEquals(m, m2));
60   }
61 
62   @Test
parseInvalid()63   public void parseInvalid() throws Exception {
64     InputStream is = new ByteArrayInputStream(new byte[] {-127});
65     try {
66       marshaller.parse(is);
67       fail("Expected exception");
68     } catch (StatusRuntimeException ex) {
69       assertEquals(Status.Code.INTERNAL, ex.getStatus().getCode());
70       assertTrue(ex.getCause() instanceof InvalidProtocolBufferNanoException);
71     }
72   }
73 
74   @Test
testLarge()75   public void testLarge() {
76     Message m = new Message();
77     // The default limit is 64MB. Using a larger proto to verify that the limit is not enforced.
78     m.bs = new byte[70 * 1024 * 1024];
79     Message m2 = marshaller.parse(marshaller.stream(m));
80     assertNotSame(m, m2);
81     // TODO(carl-mastrangelo): assertArrayEquals is REALLY slow, and been fixed in junit4.12.
82     // Eventually switch back to it once we are using 4.12 everywhere.
83     // assertArrayEquals(m.bs, m2.bs);
84     assertEquals(m.bs.length, m2.bs.length);
85     for (int i = 0; i < m.bs.length; i++) {
86       assertEquals(m.bs[i], m2.bs[i]);
87     }
88   }
89 
90   @Test
testAvailable()91   public void testAvailable() throws Exception {
92     Message m = new Message();
93     m.s = "string";
94     InputStream is = marshaller.stream(m);
95     assertEquals(m.getSerializedSize(), is.available());
96     is.read();
97     assertEquals(m.getSerializedSize() - 1, is.available());
98     while (is.read() != -1) {}
99     assertEquals(-1, is.read());
100     assertEquals(0, is.available());
101   }
102 
103   @Test
testEmpty()104   public void testEmpty() throws IOException {
105     InputStream is = marshaller.stream(new Message());
106     assertEquals(0, is.available());
107     byte[] b = new byte[10];
108     assertEquals(-1, is.read(b));
109     assertArrayEquals(new byte[10], b);
110     // Do the same thing again, because the internal state may be different
111     assertEquals(-1, is.read(b));
112     assertArrayEquals(new byte[10], b);
113     assertEquals(-1, is.read());
114     assertEquals(0, is.available());
115   }
116 }
117