1 // Copyright (c) 2014, Facebook, Inc. All rights reserved. 2 // This source code is licensed under both the GPLv2 (found in the 3 // COPYING file in the root directory) and Apache 2.0 License 4 // (found in the LICENSE.Apache file in the root directory). 5 package org.rocksdb.util; 6 7 import org.junit.AfterClass; 8 import org.junit.BeforeClass; 9 import org.junit.Test; 10 11 import java.lang.reflect.Field; 12 import java.lang.reflect.Modifier; 13 14 import static org.assertj.core.api.Assertions.assertThat; 15 16 public class EnvironmentTest { 17 private final static String ARCH_FIELD_NAME = "ARCH"; 18 private final static String OS_FIELD_NAME = "OS"; 19 private final static String MUSL_LIBC_FIELD_NAME = "MUSL_LIBC"; 20 21 private static String INITIAL_OS; 22 private static String INITIAL_ARCH; 23 private static boolean INITIAL_MUSL_LIBC; 24 25 @BeforeClass saveState()26 public static void saveState() { 27 INITIAL_ARCH = getEnvironmentClassField(ARCH_FIELD_NAME); 28 INITIAL_OS = getEnvironmentClassField(OS_FIELD_NAME); 29 INITIAL_MUSL_LIBC = getEnvironmentClassField(MUSL_LIBC_FIELD_NAME); 30 } 31 32 @Test mac32()33 public void mac32() { 34 setEnvironmentClassFields("mac", "32"); 35 assertThat(Environment.isWindows()).isFalse(); 36 assertThat(Environment.getJniLibraryExtension()). 37 isEqualTo(".jnilib"); 38 assertThat(Environment.getJniLibraryFileName("rocksdb")). 39 isEqualTo("librocksdbjni-osx.jnilib"); 40 assertThat(Environment.getSharedLibraryFileName("rocksdb")). 41 isEqualTo("librocksdbjni.dylib"); 42 } 43 44 @Test mac64()45 public void mac64() { 46 setEnvironmentClassFields("mac", "64"); 47 assertThat(Environment.isWindows()).isFalse(); 48 assertThat(Environment.getJniLibraryExtension()). 49 isEqualTo(".jnilib"); 50 assertThat(Environment.getJniLibraryFileName("rocksdb")). 51 isEqualTo("librocksdbjni-osx.jnilib"); 52 assertThat(Environment.getSharedLibraryFileName("rocksdb")). 53 isEqualTo("librocksdbjni.dylib"); 54 } 55 56 @Test nix32()57 public void nix32() { 58 // Linux 59 setEnvironmentClassField(MUSL_LIBC_FIELD_NAME, false); 60 setEnvironmentClassFields("Linux", "32"); 61 assertThat(Environment.isWindows()).isFalse(); 62 assertThat(Environment.getJniLibraryExtension()). 63 isEqualTo(".so"); 64 assertThat(Environment.getJniLibraryFileName("rocksdb")). 65 isEqualTo("librocksdbjni-linux32.so"); 66 assertThat(Environment.getSharedLibraryFileName("rocksdb")). 67 isEqualTo("librocksdbjni.so"); 68 // Linux musl-libc (Alpine) 69 setEnvironmentClassField(MUSL_LIBC_FIELD_NAME, true); 70 assertThat(Environment.isWindows()).isFalse(); 71 assertThat(Environment.getJniLibraryExtension()). 72 isEqualTo(".so"); 73 assertThat(Environment.getJniLibraryFileName("rocksdb")). 74 isEqualTo("librocksdbjni-linux32-musl.so"); 75 assertThat(Environment.getSharedLibraryFileName("rocksdb")). 76 isEqualTo("librocksdbjni.so"); 77 // UNIX 78 setEnvironmentClassField(MUSL_LIBC_FIELD_NAME, false); 79 setEnvironmentClassFields("Unix", "32"); 80 assertThat(Environment.isWindows()).isFalse(); 81 assertThat(Environment.getJniLibraryExtension()). 82 isEqualTo(".so"); 83 assertThat(Environment.getJniLibraryFileName("rocksdb")). 84 isEqualTo("librocksdbjni-linux32.so"); 85 assertThat(Environment.getSharedLibraryFileName("rocksdb")). 86 isEqualTo("librocksdbjni.so"); 87 } 88 89 @Test(expected = UnsupportedOperationException.class) aix32()90 public void aix32() { 91 // AIX 92 setEnvironmentClassFields("aix", "32"); 93 assertThat(Environment.isWindows()).isFalse(); 94 assertThat(Environment.getJniLibraryExtension()). 95 isEqualTo(".so"); 96 Environment.getJniLibraryFileName("rocksdb"); 97 } 98 99 @Test nix64()100 public void nix64() { 101 setEnvironmentClassField(MUSL_LIBC_FIELD_NAME, false); 102 setEnvironmentClassFields("Linux", "x64"); 103 assertThat(Environment.isWindows()).isFalse(); 104 assertThat(Environment.getJniLibraryExtension()). 105 isEqualTo(".so"); 106 assertThat(Environment.getJniLibraryFileName("rocksdb")). 107 isEqualTo("librocksdbjni-linux64.so"); 108 assertThat(Environment.getSharedLibraryFileName("rocksdb")). 109 isEqualTo("librocksdbjni.so"); 110 // Linux musl-libc (Alpine) 111 setEnvironmentClassField(MUSL_LIBC_FIELD_NAME, true); 112 assertThat(Environment.isWindows()).isFalse(); 113 assertThat(Environment.getJniLibraryExtension()). 114 isEqualTo(".so"); 115 assertThat(Environment.getJniLibraryFileName("rocksdb")). 116 isEqualTo("librocksdbjni-linux64-musl.so"); 117 assertThat(Environment.getSharedLibraryFileName("rocksdb")). 118 isEqualTo("librocksdbjni.so"); 119 // UNIX 120 setEnvironmentClassField(MUSL_LIBC_FIELD_NAME, false); 121 setEnvironmentClassFields("Unix", "x64"); 122 assertThat(Environment.isWindows()).isFalse(); 123 assertThat(Environment.getJniLibraryExtension()). 124 isEqualTo(".so"); 125 assertThat(Environment.getJniLibraryFileName("rocksdb")). 126 isEqualTo("librocksdbjni-linux64.so"); 127 assertThat(Environment.getSharedLibraryFileName("rocksdb")). 128 isEqualTo("librocksdbjni.so"); 129 // AIX 130 setEnvironmentClassFields("aix", "x64"); 131 assertThat(Environment.isWindows()).isFalse(); 132 assertThat(Environment.getJniLibraryExtension()). 133 isEqualTo(".so"); 134 assertThat(Environment.getJniLibraryFileName("rocksdb")). 135 isEqualTo("librocksdbjni-aix64.so"); 136 assertThat(Environment.getSharedLibraryFileName("rocksdb")). 137 isEqualTo("librocksdbjni.so"); 138 } 139 140 @Test detectWindows()141 public void detectWindows(){ 142 setEnvironmentClassFields("win", "x64"); 143 assertThat(Environment.isWindows()).isTrue(); 144 } 145 146 @Test win64()147 public void win64() { 148 setEnvironmentClassFields("win", "x64"); 149 assertThat(Environment.isWindows()).isTrue(); 150 assertThat(Environment.getJniLibraryExtension()). 151 isEqualTo(".dll"); 152 assertThat(Environment.getJniLibraryFileName("rocksdb")). 153 isEqualTo("librocksdbjni-win64.dll"); 154 assertThat(Environment.getSharedLibraryFileName("rocksdb")). 155 isEqualTo("librocksdbjni.dll"); 156 } 157 158 @Test ppc64le()159 public void ppc64le() { 160 setEnvironmentClassField(MUSL_LIBC_FIELD_NAME, false); 161 setEnvironmentClassFields("Linux", "ppc64le"); 162 assertThat(Environment.isUnix()).isTrue(); 163 assertThat(Environment.isPowerPC()).isTrue(); 164 assertThat(Environment.is64Bit()).isTrue(); 165 assertThat(Environment.getJniLibraryExtension()).isEqualTo(".so"); 166 assertThat(Environment.getSharedLibraryName("rocksdb")).isEqualTo("rocksdbjni"); 167 assertThat(Environment.getJniLibraryName("rocksdb")).isEqualTo("rocksdbjni-linux-ppc64le"); 168 assertThat(Environment.getJniLibraryFileName("rocksdb")) 169 .isEqualTo("librocksdbjni-linux-ppc64le.so"); 170 assertThat(Environment.getSharedLibraryFileName("rocksdb")).isEqualTo("librocksdbjni.so"); 171 // Linux musl-libc (Alpine) 172 setEnvironmentClassField(MUSL_LIBC_FIELD_NAME, true); 173 setEnvironmentClassFields("Linux", "ppc64le"); 174 assertThat(Environment.isUnix()).isTrue(); 175 assertThat(Environment.isPowerPC()).isTrue(); 176 assertThat(Environment.is64Bit()).isTrue(); 177 assertThat(Environment.getJniLibraryExtension()).isEqualTo(".so"); 178 assertThat(Environment.getSharedLibraryName("rocksdb")).isEqualTo("rocksdbjni"); 179 assertThat(Environment.getJniLibraryName("rocksdb")).isEqualTo("rocksdbjni-linux-ppc64le-musl"); 180 assertThat(Environment.getJniLibraryFileName("rocksdb")) 181 .isEqualTo("librocksdbjni-linux-ppc64le-musl.so"); 182 assertThat(Environment.getSharedLibraryFileName("rocksdb")).isEqualTo("librocksdbjni.so"); 183 setEnvironmentClassField(MUSL_LIBC_FIELD_NAME, false); 184 } 185 186 @Test aarch64()187 public void aarch64() { 188 setEnvironmentClassField(MUSL_LIBC_FIELD_NAME, false); 189 setEnvironmentClassFields("Linux", "aarch64"); 190 assertThat(Environment.isUnix()).isTrue(); 191 assertThat(Environment.isAarch64()).isTrue(); 192 assertThat(Environment.is64Bit()).isTrue(); 193 assertThat(Environment.getJniLibraryExtension()).isEqualTo(".so"); 194 assertThat(Environment.getSharedLibraryName("rocksdb")).isEqualTo("rocksdbjni"); 195 assertThat(Environment.getJniLibraryName("rocksdb")).isEqualTo("rocksdbjni-linux-aarch64"); 196 assertThat(Environment.getJniLibraryFileName("rocksdb")) 197 .isEqualTo("librocksdbjni-linux-aarch64.so"); 198 assertThat(Environment.getSharedLibraryFileName("rocksdb")).isEqualTo("librocksdbjni.so"); 199 // Linux musl-libc (Alpine) 200 setEnvironmentClassField(MUSL_LIBC_FIELD_NAME, true); 201 setEnvironmentClassFields("Linux", "aarch64"); 202 assertThat(Environment.isUnix()).isTrue(); 203 assertThat(Environment.isAarch64()).isTrue(); 204 assertThat(Environment.is64Bit()).isTrue(); 205 assertThat(Environment.getJniLibraryExtension()).isEqualTo(".so"); 206 assertThat(Environment.getSharedLibraryName("rocksdb")).isEqualTo("rocksdbjni"); 207 assertThat(Environment.getJniLibraryName("rocksdb")).isEqualTo("rocksdbjni-linux-aarch64-musl"); 208 assertThat(Environment.getJniLibraryFileName("rocksdb")) 209 .isEqualTo("librocksdbjni-linux-aarch64-musl.so"); 210 assertThat(Environment.getSharedLibraryFileName("rocksdb")).isEqualTo("librocksdbjni.so"); 211 setEnvironmentClassField(MUSL_LIBC_FIELD_NAME, false); 212 } 213 setEnvironmentClassFields(String osName, String osArch)214 private void setEnvironmentClassFields(String osName, 215 String osArch) { 216 setEnvironmentClassField(OS_FIELD_NAME, osName); 217 setEnvironmentClassField(ARCH_FIELD_NAME, osArch); 218 } 219 220 @AfterClass restoreState()221 public static void restoreState() { 222 setEnvironmentClassField(OS_FIELD_NAME, INITIAL_OS); 223 setEnvironmentClassField(ARCH_FIELD_NAME, INITIAL_ARCH); 224 setEnvironmentClassField(MUSL_LIBC_FIELD_NAME, INITIAL_MUSL_LIBC); 225 } 226 227 @SuppressWarnings("unchecked") getEnvironmentClassField(String fieldName)228 private static <T> T getEnvironmentClassField(String fieldName) { 229 final Field field; 230 try { 231 field = Environment.class.getDeclaredField(fieldName); 232 field.setAccessible(true); 233 /* Fails in JDK 13; and not needed unless fields are final 234 final Field modifiersField = Field.class.getDeclaredField("modifiers"); 235 modifiersField.setAccessible(true); 236 modifiersField.setInt(field, field.getModifiers() & ~Modifier.FINAL); 237 */ 238 return (T)field.get(null); 239 } catch (final NoSuchFieldException | IllegalAccessException e) { 240 throw new RuntimeException(e); 241 } 242 } 243 setEnvironmentClassField(String fieldName, Object value)244 private static void setEnvironmentClassField(String fieldName, Object value) { 245 final Field field; 246 try { 247 field = Environment.class.getDeclaredField(fieldName); 248 field.setAccessible(true); 249 /* Fails in JDK 13; and not needed unless fields are final 250 final Field modifiersField = Field.class.getDeclaredField("modifiers"); 251 modifiersField.setAccessible(true); 252 modifiersField.setInt(field, field.getModifiers() & ~Modifier.FINAL); 253 */ 254 field.set(null, value); 255 } catch (final NoSuchFieldException | IllegalAccessException e) { 256 throw new RuntimeException(e); 257 } 258 } 259 } 260