• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2022 Google LLC
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 package com.google.android.libraries.mobiledatadownload.file;
17 
18 import static com.google.android.libraries.mobiledatadownload.file.common.testing.StreamUtils.makeArrayOfBytesContent;
19 import static com.google.common.truth.Truth.assertThat;
20 import static org.mockito.ArgumentMatchers.any;
21 import static org.mockito.Mockito.doThrow;
22 import static org.mockito.Mockito.mock;
23 import static org.mockito.Mockito.times;
24 import static org.mockito.Mockito.verify;
25 import static org.mockito.Mockito.when;
26 
27 import android.net.Uri;
28 import com.google.android.libraries.mobiledatadownload.file.common.testing.BufferingMonitor;
29 import com.google.android.libraries.mobiledatadownload.file.spi.Monitor;
30 import java.io.ByteArrayInputStream;
31 import java.io.IOException;
32 import java.io.InputStream;
33 import java.util.Arrays;
34 import org.junit.Test;
35 import org.junit.runner.RunWith;
36 import org.robolectric.RobolectricTestRunner;
37 
38 /** Test {@link com.google.android.libraries.mobiledatadownload.file.MonitorInputStream}. */
39 @RunWith(RobolectricTestRunner.class)
40 public class MonitorInputStreamTest {
41 
42   private static final byte[] TEST_CONTENT = makeArrayOfBytesContent();
43 
44   @Test
monitorRead_shouldSeeAllBytes()45   public void monitorRead_shouldSeeAllBytes() throws Exception {
46     BufferingMonitor buffer = new BufferingMonitor();
47     Uri uri = Uri.parse("foo:");
48     InputStream in = new ByteArrayInputStream(TEST_CONTENT);
49     MonitorInputStream stream = MonitorInputStream.newInstance(Arrays.asList(buffer), uri, in);
50 
51     stream.read();
52     stream.read(new byte[5]);
53     stream.read();
54     stream.read(new byte[10], 5, 3);
55 
56     assertThat(buffer.bytesRead()).isEqualTo(Arrays.copyOf(TEST_CONTENT, 10));
57   }
58 
59   @Test
monitorRead_withNullInputMonitor_shouldReturnNull()60   public void monitorRead_withNullInputMonitor_shouldReturnNull() throws Exception {
61     Monitor mockMonitor = mock(Monitor.class);
62     when(mockMonitor.monitorRead(any())).thenReturn(null);
63     Uri uri = Uri.parse("foo:");
64     InputStream in = new ByteArrayInputStream(TEST_CONTENT);
65 
66     assertThat(MonitorInputStream.newInstance(Arrays.asList(mockMonitor), uri, in)).isNull();
67   }
68 
69   @Test
monitorRead_shouldCallClose()70   public void monitorRead_shouldCallClose() throws Exception {
71     Monitor mockMonitor = mock(Monitor.class);
72     Monitor.InputMonitor mockInputMonitor = mock(Monitor.InputMonitor.class);
73     when(mockMonitor.monitorRead(any())).thenReturn(mockInputMonitor);
74     Uri uri = Uri.parse("foo:");
75     InputStream in = new ByteArrayInputStream(TEST_CONTENT);
76     try (MonitorInputStream stream =
77         MonitorInputStream.newInstance(Arrays.asList(mockMonitor), uri, in)) {
78       stream.read(new byte[TEST_CONTENT.length]);
79     }
80     verify(mockInputMonitor, times(1)).close();
81   }
82 
83   @Test
monitorReadWithMonitorCloseException_shouldCallClose()84   public void monitorReadWithMonitorCloseException_shouldCallClose() throws Exception {
85     Monitor mockMonitor = mock(Monitor.class);
86     Monitor.InputMonitor mockInputMonitor = mock(Monitor.InputMonitor.class);
87     when(mockMonitor.monitorRead(any())).thenReturn(mockInputMonitor);
88     doThrow(new RuntimeException("Unchecked")).when(mockInputMonitor).close();
89     Uri uri = Uri.parse("foo:");
90     FakeInputStream fakeIn = new FakeInputStream();
91     try (MonitorInputStream stream =
92         MonitorInputStream.newInstance(Arrays.asList(mockMonitor), uri, fakeIn)) {
93       stream.read(new byte[TEST_CONTENT.length]);
94     }
95     verify(mockInputMonitor, times(1)).close();
96     assertThat(fakeIn.bytesRead).isEqualTo(TEST_CONTENT.length);
97     assertThat(fakeIn.closed).isTrue();
98   }
99 
100   private static class FakeInputStream extends InputStream {
101     private boolean closed = true;
102     private int bytesRead = 0;
103 
104     @Override
read()105     public int read() throws IOException {
106       bytesRead += 1;
107       return 0;
108     }
109 
110     @Override
close()111     public void close() throws IOException {
112       closed = true;
113     }
114   }
115 }
116