• 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.openers;
17 
18 import static com.google.common.truth.Truth.assertThat;
19 import static org.junit.Assert.assertThrows;
20 
21 import android.net.Uri;
22 import com.google.android.libraries.mobiledatadownload.file.SynchronousFileStorage;
23 import com.google.android.libraries.mobiledatadownload.file.backends.JavaFileBackend;
24 import com.google.android.libraries.mobiledatadownload.file.common.testing.BufferingMonitor;
25 import com.google.android.libraries.mobiledatadownload.file.common.testing.FileDescriptorLeakChecker;
26 import com.google.android.libraries.mobiledatadownload.file.common.testing.NoOpMonitor;
27 import com.google.android.libraries.mobiledatadownload.file.common.testing.StreamUtils;
28 import com.google.android.libraries.mobiledatadownload.file.common.testing.TemporaryUri;
29 import com.google.android.libraries.mobiledatadownload.file.transforms.CompressTransform;
30 import com.google.android.libraries.mobiledatadownload.file.transforms.TransformProtos;
31 import com.google.common.collect.ImmutableList;
32 import java.io.IOException;
33 import java.nio.ByteBuffer;
34 import java.nio.MappedByteBuffer;
35 import org.junit.Before;
36 import org.junit.Rule;
37 import org.junit.Test;
38 import org.junit.runner.RunWith;
39 import org.junit.runners.JUnit4;
40 
41 @RunWith(JUnit4.class)
42 public final class MappedByteBufferOpenerAndroidTest {
43 
44   private SynchronousFileStorage storage;
45 
46   @Rule public TemporaryUri tmpUri = new TemporaryUri();
47   @Rule public FileDescriptorLeakChecker leakChecker = new FileDescriptorLeakChecker();
48 
49   @Before
setUpStorage()50   public void setUpStorage() throws Exception {
51     storage =
52         new SynchronousFileStorage(
53             ImmutableList.of(new JavaFileBackend()), ImmutableList.of(new CompressTransform()));
54   }
55 
56   @Test
succeedsWithSimplePath()57   public void succeedsWithSimplePath() throws Exception {
58     Uri uri = tmpUri.newUri();
59     byte[] content = StreamUtils.makeArrayOfBytesContent();
60     StreamUtils.createFile(storage, uri, content);
61 
62     MappedByteBuffer buffer = storage.open(uri, MappedByteBufferOpener.createForRead());
63     assertThat(extractBytes(buffer)).isEqualTo(content);
64   }
65 
66   @Test
bufferIsReadOnly()67   public void bufferIsReadOnly() throws Exception {
68     Uri uri = tmpUri.newUri();
69     byte[] content = StreamUtils.makeArrayOfBytesContent();
70     StreamUtils.createFile(storage, uri, content);
71 
72     MappedByteBuffer buffer = storage.open(uri, MappedByteBufferOpener.createForRead());
73     assertThat(buffer.isReadOnly()).isTrue();
74   }
75 
76   @Test
failsWithTransform()77   public void failsWithTransform() throws Exception {
78     Uri uri = tmpUri.newUriBuilder().withTransform(TransformProtos.DEFAULT_COMPRESS_SPEC).build();
79     byte[] content = StreamUtils.makeArrayOfBytesContent();
80     StreamUtils.createFile(storage, uri, content);
81 
82     assertThrows(
83         IOException.class, () -> storage.open(uri, MappedByteBufferOpener.createForRead()));
84   }
85 
86   @Test
failsWithMissingFile()87   public void failsWithMissingFile() throws Exception {
88     Uri uri = Uri.parse("file:/does-not-exist");
89 
90     assertThrows(
91         IOException.class, () -> storage.open(uri, MappedByteBufferOpener.createForRead()));
92   }
93 
94   @Test
failsWithActiveMonitor()95   public void failsWithActiveMonitor() throws Exception {
96     SynchronousFileStorage storageWithMonitor =
97         new SynchronousFileStorage(
98             ImmutableList.of(new JavaFileBackend()),
99             ImmutableList.of(),
100             ImmutableList.of(new BufferingMonitor()));
101 
102     Uri uri = tmpUri.newUri();
103     byte[] content = StreamUtils.makeArrayOfBytesContent();
104     StreamUtils.createFile(storageWithMonitor, uri, content);
105 
106     assertThrows(
107         IOException.class,
108         () -> storageWithMonitor.open(uri, MappedByteBufferOpener.createForRead()));
109   }
110 
111   @Test
succeedsWithInactiveMonitor()112   public void succeedsWithInactiveMonitor() throws Exception {
113     SynchronousFileStorage storageWithMonitor =
114         new SynchronousFileStorage(
115             ImmutableList.of(new JavaFileBackend()),
116             ImmutableList.of(),
117             ImmutableList.of(new NoOpMonitor()));
118 
119     Uri uri = tmpUri.newUri();
120     byte[] content = StreamUtils.makeArrayOfBytesContent();
121     StreamUtils.createFile(storageWithMonitor, uri, content);
122 
123     MappedByteBuffer buffer = storageWithMonitor.open(uri, MappedByteBufferOpener.createForRead());
124     assertThat(extractBytes(buffer)).isEqualTo(content);
125   }
126 
127   /**
128    * Extracts the byte[] from the ByteBuffer. This method is forked from Guava ByteBuffers, which
129    * isn't available on Android.
130    */
extractBytes(ByteBuffer buf)131   private static byte[] extractBytes(ByteBuffer buf) {
132     byte[] result = new byte[buf.remaining()];
133     buf.get(result);
134     buf.position(buf.position() - result.length);
135     return result;
136   }
137 }
138