View Javadoc
1   /*
2    *  Licensed to the Apache Software Foundation (ASF) under one or more
3    *  contributor license agreements.  See the NOTICE file distributed with
4    *  this work for additional information regarding copyright ownership.
5    *  The ASF licenses this file to You under the Apache License, Version 2.0
6    *  (the "License"); you may not use this file except in compliance with
7    *  the License.  You may obtain a copy of the License at
8    *
9    *      http://www.apache.org/licenses/LICENSE-2.0
10   *
11   *  Unless required by applicable law or agreed to in writing, software
12   *  distributed under the License is distributed on an "AS IS" BASIS,
13   *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   *  See the License for the specific language governing permissions and
15   *  limitations under the License.
16   */
17  
18  package org.apache.commons.compress.utils;
19  
20  import static org.apache.commons.compress.AbstractTest.getFile;
21  import static org.apache.commons.compress.AbstractTest.getPath;
22  import static org.junit.jupiter.api.Assertions.assertEquals;
23  import static org.junit.jupiter.api.Assertions.assertSame;
24  import static org.junit.jupiter.api.Assertions.assertThrows;
25  import static org.junit.jupiter.api.Assertions.assertTrue;
26  
27  import java.io.File;
28  import java.io.IOException;
29  import java.nio.channels.SeekableByteChannel;
30  import java.nio.file.Files;
31  import java.nio.file.Path;
32  import java.nio.file.StandardOpenOption;
33  import java.util.ArrayList;
34  import java.util.List;
35  import java.util.Random;
36  
37  import org.apache.commons.compress.archivers.zip.ZipSplitReadOnlySeekableByteChannel;
38  import org.junit.jupiter.api.Test;
39  
40  public class ZipSplitReadOnlySeekableByteChannelTest {
41  
42      private List<SeekableByteChannel> getSplitZipChannels() throws IOException {
43          final List<SeekableByteChannel> channels = new ArrayList<>();
44          final File file1 = getFile("COMPRESS-477/split_zip_created_by_zip/split_zip_created_by_zip.z01");
45          channels.add(Files.newByteChannel(file1.toPath(), StandardOpenOption.READ));
46  
47          final File file2 = getFile("COMPRESS-477/split_zip_created_by_zip/split_zip_created_by_zip.z02");
48          channels.add(Files.newByteChannel(file2.toPath(), StandardOpenOption.READ));
49  
50          final File lastFile = getFile("COMPRESS-477/split_zip_created_by_zip/split_zip_created_by_zip.zip");
51          channels.add(Files.newByteChannel(lastFile.toPath(), StandardOpenOption.READ));
52  
53          return channels;
54      }
55  
56      @Test
57      public void testBuildFromLastSplitSegmentThrowsOnNotZipFile() throws IOException {
58          final File lastFile = getFile("COMPRESS-477/split_zip_created_by_zip/split_zip_created_by_zip.z01");
59          assertThrows(IllegalArgumentException.class, () -> ZipSplitReadOnlySeekableByteChannel.buildFromLastSplitSegment(lastFile));
60      }
61  
62      @Test
63      public void testChannelsPositionIsZeroAfterConstructor() throws IOException {
64          final List<SeekableByteChannel> channels = getSplitZipChannels();
65          new ZipSplitReadOnlySeekableByteChannel(channels);
66          for (final SeekableByteChannel channel : channels) {
67              assertEquals(0, channel.position());
68          }
69      }
70  
71      @Test
72      public void testConstructorThrowsOnNonSplitZipFiles() throws IOException {
73          final List<SeekableByteChannel> channels = new ArrayList<>();
74          final File file = getFile("COMPRESS-189.zip");
75          try (SeekableByteChannel byteChannel = Files.newByteChannel(file.toPath(), StandardOpenOption.READ)) {
76              channels.add(byteChannel);
77              assertThrows(IOException.class, () -> new ZipSplitReadOnlySeekableByteChannel(channels));
78          }
79      }
80  
81      @Test
82      public void testConstructorThrowsOnNullArg() {
83          assertThrows(NullPointerException.class, () -> new ZipSplitReadOnlySeekableByteChannel(null));
84      }
85  
86      @Test
87      public void testForFilesOfTwoParametersThrowsOnNullArg() {
88          assertThrows(NullPointerException.class, () -> ZipSplitReadOnlySeekableByteChannel.forFiles(null, null));
89      }
90  
91      @Test
92      public void testForFilesReturnCorrectClass() throws IOException {
93          final File firstFile = getFile("COMPRESS-477/split_zip_created_by_zip/split_zip_created_by_zip.z01");
94          final File secondFile = getFile("COMPRESS-477/split_zip_created_by_zip/split_zip_created_by_zip.z02");
95          final File lastFile = getFile("COMPRESS-477/split_zip_created_by_zip/split_zip_created_by_zip.z01");
96  
97          final ArrayList<File> list = new ArrayList<>();
98          list.add(firstFile);
99          list.add(secondFile);
100 
101         try (SeekableByteChannel channel = ZipSplitReadOnlySeekableByteChannel.forFiles(lastFile, list)) {
102             assertTrue(channel instanceof ZipSplitReadOnlySeekableByteChannel);
103         }
104 
105         try (SeekableByteChannel channel = ZipSplitReadOnlySeekableByteChannel.forFiles(firstFile, secondFile, lastFile)) {
106             assertTrue(channel instanceof ZipSplitReadOnlySeekableByteChannel);
107         }
108     }
109 
110     @Test
111     public void testForFilesThrowsOnNullArg() {
112         assertThrows(NullPointerException.class, () -> ZipSplitReadOnlySeekableByteChannel.forFiles(null));
113     }
114 
115     @Test
116     public void testForOrderedSeekableByteChannelsOfTwoParametersThrowsOnNullArg() {
117         assertThrows(NullPointerException.class, () -> ZipSplitReadOnlySeekableByteChannel.forOrderedSeekableByteChannels(null, null));
118     }
119 
120     @Test
121     public void testForOrderedSeekableByteChannelsReturnCorrectClass() throws IOException {
122         final File file1 = getFile("COMPRESS-477/split_zip_created_by_zip/split_zip_created_by_zip.z01");
123         final File file2 = getFile("COMPRESS-477/split_zip_created_by_zip/split_zip_created_by_zip.z02");
124         final File lastFile = getFile("COMPRESS-477/split_zip_created_by_zip/split_zip_created_by_zip.zip");
125 
126         try (SeekableByteChannel firstChannel = Files.newByteChannel(file1.toPath(), StandardOpenOption.READ);
127                 SeekableByteChannel secondChannel = Files.newByteChannel(file2.toPath(), StandardOpenOption.READ);
128                 SeekableByteChannel lastChannel = Files.newByteChannel(lastFile.toPath(), StandardOpenOption.READ)) {
129 
130             final List<SeekableByteChannel> channels = new ArrayList<>();
131             channels.add(firstChannel);
132             channels.add(secondChannel);
133 
134             @SuppressWarnings("resource") // try-with-resources closes
135             final SeekableByteChannel channel1 = ZipSplitReadOnlySeekableByteChannel.forOrderedSeekableByteChannels(lastChannel, channels);
136             assertTrue(channel1 instanceof ZipSplitReadOnlySeekableByteChannel);
137 
138             @SuppressWarnings("resource") // try-with-resources closes
139             final SeekableByteChannel channel2 = ZipSplitReadOnlySeekableByteChannel.forOrderedSeekableByteChannels(firstChannel, secondChannel, lastChannel);
140             assertTrue(channel2 instanceof ZipSplitReadOnlySeekableByteChannel);
141         }
142     }
143 
144     @Test
145     public void testForOrderedSeekableByteChannelsReturnsIdentityForSingleElement() throws IOException {
146         try (SeekableByteChannel emptyChannel = new SeekableInMemoryByteChannel(ByteUtils.EMPTY_BYTE_ARRAY);
147                 SeekableByteChannel channel = ZipSplitReadOnlySeekableByteChannel.forOrderedSeekableByteChannels(emptyChannel)) {
148             assertSame(emptyChannel, channel);
149         }
150     }
151 
152     @Test
153     public void testForOrderedSeekableByteChannelsThrowsOnNullArg() {
154         assertThrows(NullPointerException.class, () -> ZipSplitReadOnlySeekableByteChannel.forOrderedSeekableByteChannels(null));
155     }
156 
157     @Test
158     public void testForPathsOfTwoParametersThrowsOnNullArg() {
159         assertThrows(NullPointerException.class, () -> ZipSplitReadOnlySeekableByteChannel.forPaths((Path) null, null));
160     }
161 
162     @Test
163     public void testForPathsReturnCorrectClass() throws IOException {
164         final Path firstFile = getPath("COMPRESS-477/split_zip_created_by_zip/split_zip_created_by_zip.z01");
165         final Path secondFile = getPath("COMPRESS-477/split_zip_created_by_zip/split_zip_created_by_zip.z02");
166         final Path lastFile = getPath("COMPRESS-477/split_zip_created_by_zip/split_zip_created_by_zip.zip");
167 
168         final ArrayList<Path> list = new ArrayList<>();
169         list.add(firstFile);
170         list.add(secondFile);
171 
172         try (SeekableByteChannel channel = ZipSplitReadOnlySeekableByteChannel.forPaths(lastFile, list)) {
173             assertTrue(channel instanceof ZipSplitReadOnlySeekableByteChannel);
174         }
175 
176         try (SeekableByteChannel channel = ZipSplitReadOnlySeekableByteChannel.forPaths(firstFile, secondFile, lastFile)) {
177             assertTrue(channel instanceof ZipSplitReadOnlySeekableByteChannel);
178         }
179     }
180 
181     @Test
182     public void testForPathsThrowsOnNullArg() {
183         assertThrows(NullPointerException.class, () -> ZipSplitReadOnlySeekableByteChannel.forPaths(null));
184     }
185 
186     @Test
187     public void testPositionToSomeZipSplitSegment() throws IOException {
188         final File firstFile = getFile("COMPRESS-477/split_zip_created_by_zip/split_zip_created_by_zip.z01");
189         final int firstFileSize = (int) firstFile.length();
190 
191         final File secondFile = getFile("COMPRESS-477/split_zip_created_by_zip/split_zip_created_by_zip.z02");
192         final int secondFileSize = (int) secondFile.length();
193 
194         final File lastFile = getFile("COMPRESS-477/split_zip_created_by_zip/split_zip_created_by_zip.zip");
195         final int lastFileSize = (int) lastFile.length();
196 
197         final Random random = new Random();
198         final int randomDiskNumber = random.nextInt(3);
199         final int randomOffset = randomDiskNumber < 2 ? random.nextInt(firstFileSize) : random.nextInt(lastFileSize);
200 
201         try (ZipSplitReadOnlySeekableByteChannel channel = (ZipSplitReadOnlySeekableByteChannel) ZipSplitReadOnlySeekableByteChannel
202                 .buildFromLastSplitSegment(lastFile)) {
203             channel.position(randomDiskNumber, randomOffset);
204             long expectedPosition = randomOffset;
205 
206             expectedPosition += randomDiskNumber > 0 ? firstFileSize : 0;
207             expectedPosition += randomDiskNumber > 1 ? secondFileSize : 0;
208 
209             assertEquals(expectedPosition, channel.position());
210         }
211     }
212 }