-
Notifications
You must be signed in to change notification settings - Fork 231
/
SnappyHadoopCompatibleOutputStreamTest.java
149 lines (133 loc) · 6.01 KB
/
SnappyHadoopCompatibleOutputStreamTest.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
package org.xerial.snappy;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.IOUtils;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.io.compress.SnappyCodec;
import org.junit.AfterClass;
import org.junit.Assert;
import org.junit.BeforeClass;
import org.junit.Ignore;
import org.junit.Test;
import java.io.*;
import java.lang.reflect.Field;
import java.util.LinkedHashMap;
import java.util.Map;
public class SnappyHadoopCompatibleOutputStreamTest
{
private static File tempNativeLibFolder;
@BeforeClass
public static void loadHadoopNativeLibrary() throws Exception
{
final String libResourceFolder;
Map<String, String> libraryNames = new LinkedHashMap<>();
if (OSInfo.getOSName() == "Linux") {
libResourceFolder = "/lib/Linux";
libraryNames.put("libhadoop.so", "libhadoop.so");
// certain Linux systems need these shared library be copied before the JVM started, see build.sbt
libraryNames.put("libsnappy.so", "libsnappy.so");
libraryNames.put("libsnappy.so.1", "libsnappy.so");
} else if (OSInfo.getOSName() == "Mac") {
libResourceFolder = "/lib/MacOSX";
libraryNames.put("libhadoop.dylib", "libhadoop.dylib");
libraryNames.put("libsnappy.dylib", "libsnappy.dylib");
libraryNames.put("libsnappy.1.dylib", "libsnappy.dylib");
} else {
return; // not support
}
String testLibDir = System.getenv("XERIAL_SNAPPY_LIB");
tempNativeLibFolder = new File(testLibDir);
tempNativeLibFolder.mkdirs();
for (Map.Entry<String, String> entry : libraryNames.entrySet()) {
copyNativeLibraryToFS(libResourceFolder, entry.getValue(), entry.getKey());
}
System.setProperty("java.library.path", tempNativeLibFolder.getAbsolutePath());
// credit: https://stackoverflow.com/questions/15409223/adding-new-paths-for-native-libraries-at-runtime-in-java
//set sys_paths to null so that java.library.path will be reevalueted next time it is needed
final Field sysPathsField = ClassLoader.class.getDeclaredField("sys_paths");
sysPathsField.setAccessible(true);
sysPathsField.set(null, null);
}
private static void copyNativeLibraryToFS(String libResourceFolder, String libraryName, String toLibraryName) {
final String libraryResourceName = libResourceFolder + "/" + libraryName;
final File libraryPath = new File(tempNativeLibFolder, toLibraryName);
try (InputStream inputStream = SnappyHadoopCompatibleOutputStream.class.getResourceAsStream(libraryResourceName);
FileOutputStream outputStream = new FileOutputStream(libraryPath)) {
IOUtils.copy(inputStream, outputStream);
FileDescriptor fd = outputStream.getFD();
fd.sync();
} catch (IOException ex) {
throw new RuntimeException(ex);
}
}
@AfterClass
public static void cleanUpLibraryFolder()
{
FileUtils.deleteQuietly(tempNativeLibFolder);
}
@Ignore("This test doesn't work with openjdk11 in GitHub Action")
@Test
public void testXerialCompressionHadoopDecompressionCodec() throws Exception
{
String os = OSInfo.getOSName();
String arch = OSInfo.getArchName();
if(!((os.equals("Linux") || os.equals("Mac")) && arch.equals("x86_64"))) {
// This test works only in Linux/Mac x86_64
System.err.println("SnappyHadoopCompatibleOutputStreamTest works only in 64-bit Linux/Mac");
return;
}
File inputFile = File.createTempFile("TEST_hadoop_compatibility", ".txt");
File snappyFile = File.createTempFile("TEST_hadoop_compatibility", ".snappy");
InputStream snappyInput = null;
FileOutputStream outputStream = new FileOutputStream(inputFile);
try {
String text = "";
for (int i = 0; i < 1024; i++) {
text += "Some long long strings to be compressed. Some long long strings to be compressed.";
}
text += "odd bytes";
final byte[] bytes = text.getBytes("UTF-8");
outputStream.write(bytes);
outputStream.flush();
outputStream.close();
compress(inputFile, snappyFile);
// Test using Hadoop's Snappy Codec
if (tempNativeLibFolder != null) {
SnappyCodec hadoopCodec = new SnappyCodec();
hadoopCodec.setConf(new Configuration());
snappyInput = hadoopCodec.createInputStream(new FileInputStream(snappyFile));
byte[] buf = new byte[bytes.length];
int byteRead = IOUtils.read(snappyInput, buf);
String decompressed = new String(buf, 0, byteRead, "UTF-8");
Assert.assertEquals(decompressed, text);
} else {
System.err.println("WARNING: no hadoop library for this platform. skip hadoop decompression test");
}
} finally {
if (snappyInput != null) {
snappyInput.close();
}
inputFile.delete();
snappyFile.delete();
outputStream.close();
}
}
private void compress(File inputPath, File outputPath) throws Exception
{
FileInputStream fileInputStream = new FileInputStream(inputPath);
FileOutputStream fileOutputStream = new FileOutputStream(outputPath);
try {
InputStream inputStream = new BufferedInputStream(fileInputStream);
OutputStream outputStream = new SnappyHadoopCompatibleOutputStream(fileOutputStream);
int readCount;
byte[] buffer = new byte[64 * 1024];
while ((readCount = inputStream.read(buffer)) > 0) {
outputStream.write(buffer, 0, readCount);
}
inputStream.close();
outputStream.close();
} finally {
fileInputStream.close();
fileOutputStream.close();
}
}
}