View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   *   https://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing,
13   * software distributed under the License is distributed on an
14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   * KIND, either express or implied.  See the License for the
16   * specific language governing permissions and limitations
17   * under the License.
18   */
19  
20  package org.apache.commons.compress.archivers.tar;
21  
22  import static org.junit.jupiter.api.Assertions.assertEquals;
23  import static org.junit.jupiter.api.Assertions.assertFalse;
24  import static org.junit.jupiter.api.Assertions.assertNotNull;
25  import static org.junit.jupiter.api.Assertions.assertNull;
26  import static org.junit.jupiter.api.Assertions.assertTrue;
27  
28  import java.io.BufferedInputStream;
29  import java.io.IOException;
30  import java.nio.file.Files;
31  import java.nio.file.Path;
32  import java.nio.file.Paths;
33  import java.nio.file.attribute.FileTime;
34  import java.time.Instant;
35  import java.util.Arrays;
36  import java.util.Collections;
37  import java.util.Date;
38  import java.util.List;
39  import java.util.concurrent.atomic.AtomicInteger;
40  
41  import org.apache.commons.compress.archivers.ArchiveStreamFactory;
42  import org.junit.jupiter.api.Test;
43  
44  /**
45   * Tests https://issues.apache.org/jira/browse/COMPRESS-699
46   */
47  class Compress700Test {
48  
49      private static final Path PATH = Paths.get("src/test/resources/org/apache/commons/compress/COMPRESS-700/flutter_awesome_buttons-0.1.0.tar");
50  
51      @Test
52      void testFirstTarArchiveEntry() throws Exception {
53          try (TarArchiveInputStream inputStream = new TarArchiveInputStream(new BufferedInputStream(Files.newInputStream(PATH)))) {
54              final TarArchiveEntry entry = inputStream.getNextEntry();
55              assertNull(entry.getCreationTime());
56              assertEquals(-1, entry.getDataOffset());
57              assertEquals(0, entry.getDevMajor());
58              assertEquals(0, entry.getDevMinor());
59              assertEquals(Collections.emptyMap(), entry.getExtraPaxHeaders());
60              assertEquals(0, entry.getGroupId());
61              assertEquals("", entry.getGroupName());
62              assertNull(entry.getLastAccessTime());
63              assertEquals(Date.parse("Tue Dec 03 05:08:42 EST 2019"), entry.getLastModifiedDate().getTime());
64              assertEquals(FileTime.from(Instant.parse("2019-12-03T10:08:42Z")), entry.getLastModifiedTime());
65              assertEquals(48, entry.getLinkFlag());
66              assertEquals("", entry.getLinkName());
67              assertEquals(0, entry.getLongGroupId());
68              assertEquals(0, entry.getLongUserId());
69              assertEquals(33279, entry.getMode());
70              assertEquals(Date.parse("Tue Dec 03 05:08:42 EST 2019"), entry.getModTime().getTime());
71              assertEquals("build/app.dill", entry.getName());
72              assertNull(entry.getPath());
73              assertEquals(0, entry.getRealSize());
74              assertEquals(0, entry.getSize());
75              assertNull(entry.getStatusChangeTime());
76              assertEquals(0, entry.getUserId());
77              assertEquals("", entry.getUserName());
78              assertTrue(entry.isFile());
79              assertFalse(entry.isBlockDevice());
80              assertFalse(entry.isCharacterDevice());
81              assertTrue(entry.isCheckSumOK());
82              assertFalse(entry.isDirectory());
83              assertFalse(entry.isExtended());
84              assertFalse(entry.isFIFO());
85              assertFalse(entry.isGlobalPaxHeader());
86              assertFalse(entry.isGNULongLinkEntry());
87              assertFalse(entry.isGNULongNameEntry());
88              assertFalse(entry.isGNUSparse());
89              assertFalse(entry.isLink());
90              assertFalse(entry.isOldGNUSparse());
91              assertFalse(entry.isPaxGNU1XSparse());
92              assertFalse(entry.isPaxGNUSparse());
93              assertFalse(entry.isPaxHeader());
94              assertFalse(entry.isSparse());
95              assertFalse(entry.isStarSparse());
96              assertTrue(entry.isStreamContiguous());
97              assertFalse(entry.isSymbolicLink());
98              assertTrue(entry.isTypeFlagUstar());
99          }
100     }
101 
102     @Test
103     void testListEntries() throws IOException {
104         final List<Object[]> list = Arrays.asList(
105                 new Object[] {0,     "build/app.dill"}, // 0
106                 new Object[] {105,   "CHANGELOG.md"},
107                 new Object[] {2119,  "example/android/app/build.gradle"},
108                 new Object[] {339,   "example/android/app/src/debug/AndroidManifest.xml"},
109                 new Object[] {1745,  "example/android/app/src/main/AndroidManifest.xml"},
110                 new Object[] {559,   "example/android/app/src/main/java/io/flutter/plugins/GeneratedPluginRegistrant.java"},
111                 new Object[] {353,   "example/android/app/src/main/kotlin/com/example/test_package/MainActivity.kt"},
112                 new Object[] {446,   "example/android/app/src/main/res/drawable/launch_background.xml"},
113                 new Object[] {544,   "example/android/app/src/main/res/mipmap-hdpi/ic_launcher.png"},
114                 new Object[] {442,   "example/android/app/src/main/res/mipmap-mdpi/ic_launcher.png"},
115                 new Object[] {721,   "example/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png"}, // 10
116                 new Object[] {1031,  "example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png"},
117                 new Object[] {1443,  "example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png"},
118                 new Object[] {369,   "example/android/app/src/main/res/values/styles.xml"},
119                 new Object[] {339,   "example/android/app/src/profile/AndroidManifest.xml"},
120                 new Object[] {613,   "example/android/build.gradle"},
121                 new Object[] {32,    "example/android/gradle.properties"},
122                 new Object[] {4971,  "example/android/gradlew"},
123                 new Object[] {2404,  "example/android/gradlew.bat"},
124                 new Object[] {53636, "example/android/gradle/wrapper/gradle-wrapper.jar"},
125                 new Object[] {240,   "example/android/gradle/wrapper/gradle-wrapper.properties"}, // 20
126                 new Object[] {150,   "example/android/local.properties"},
127                 new Object[] {499,   "example/android/settings.gradle"},
128                 new Object[] {1630,  "example/android/test_package_android.iml"},
129                 new Object[] {820,   "example/ios/Flutter/AppFrameworkInfo.plist"},
130                 new Object[] {31,    "example/ios/Flutter/Debug.xcconfig"},
131                 new Object[] {461,   "example/ios/Flutter/flutter_export_environment.sh"},
132                 new Object[] {380,   "example/ios/Flutter/Generated.xcconfig"},
133                 new Object[] {31,    "example/ios/Flutter/Release.xcconfig"},
134                 new Object[] {21606, "example/ios/Runner.xcodeproj/project.pbxproj"},
135                 new Object[] {159,   "example/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata"}, // 30
136                 new Object[] {3382,  "example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme"},
137                 new Object[] {159,   "example/ios/Runner.xcworkspace/contents.xcworkspacedata"},
138                 new Object[] {417,   "example/ios/Runner/AppDelegate.swift"},
139                 new Object[] {2641,  "example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json"},
140                 new Object[] {10932, "example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png"},
141                 new Object[] {564,   "example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png"},
142                 new Object[] {1283,  "example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png"},
143                 new Object[] {1588,  "example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png"},
144                 new Object[] {1025,  "example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png"},
145                 new Object[] {1716,  "example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png"},
146                 new Object[] {1920,  "example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png"},
147                 new Object[] {1283,  "example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png"},
148                 new Object[] {1895,  "example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png"},
149                 new Object[] {2665,  "example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png"},
150                 new Object[] {2665,  "example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png"},
151                 new Object[] {3831,  "example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png"},
152                 new Object[] {1888,  "example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png"},
153                 new Object[] {3294,  "example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png"},
154                 new Object[] {3612,  "example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png"},
155                 new Object[] {414,   "example/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json"},
156                 new Object[] {68,    "example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png"},
157                 new Object[] {68,    "example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png"},
158                 new Object[] {68,    "example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png"},
159                 new Object[] {340,   "example/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md"},
160                 new Object[] {2414,  "example/ios/Runner/Base.lproj/LaunchScreen.storyboard"},
161                 new Object[] {1631,  "example/ios/Runner/Base.lproj/Main.storyboard"},
162                 new Object[] {310,   "example/ios/Runner/GeneratedPluginRegistrant.h"},
163                 new Object[] {204,   "example/ios/Runner/GeneratedPluginRegistrant.m"},
164                 new Object[] {1576,  "example/ios/Runner/Info.plist"},
165                 new Object[] {37,    "example/ios/Runner/Runner-Bridging-Header.h"},
166                 new Object[] {8996,  "example/lib/main.dart"},
167                 new Object[] {2759,  "example/pubspec.yaml"},
168                 new Object[] {9879,  "example/README.md"},
169                 new Object[] {1081,  "example/test/widget_test.dart"},
170                 new Object[] {913,   "example/test_package.iml"},
171                 new Object[] {1000,  "flutter_buttons.iml"},
172                 new Object[] {36861, "lib/flutter_awesome_buttons.dart"},
173                 new Object[] {30,    "LICENSE"},
174                 new Object[] {1751,  "pubspec.yaml"},
175                 new Object[] {9879,  "README.md"},
176                 new Object[] {433,   "test/flutter_buttons_test.dart"});
177         // @formatter:on
178         try (TarArchiveInputStream inputStream = new TarArchiveInputStream(new BufferedInputStream(Files.newInputStream(PATH)))) {
179             final AtomicInteger i = new AtomicInteger();
180             for (final Object[] pair : list) {
181                 final TarArchiveEntry entry = inputStream.getNextEntry();
182                 assertNotNull(entry, entry.getName());
183                 // System.out.println(entry);
184                 final String name = (String) pair[1];
185                 assertEquals(name, entry.getName(), () -> String.format("[%d] %s", i.get(), entry));
186                 final int size = ((Integer) pair[0]).intValue();
187                 assertEquals(size, entry.getSize(), () -> String.format("[%d] %s", i.get(), entry));
188                 assertEquals(size, entry.getRealSize(), () -> String.format("[%d] %s", i.get(), entry));
189                 i.incrementAndGet();
190             }
191         }
192     }
193 
194     //@Disabled
195     //@Ignore
196     @Test
197     void testTarArchive() throws Exception {
198         try (BufferedInputStream fileInputStream = new BufferedInputStream(Files.newInputStream(PATH))) {
199             assertEquals(ArchiveStreamFactory.TAR, ArchiveStreamFactory.detect(fileInputStream));
200         }
201     }
202 }