package org.robolectric.util;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.TestRunners;
import org.robolectric.shadows.util.SQLiteLibraryLoader;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import static org.assertj.core.api.Assertions.assertThat;
@RunWith(TestRunners.SelfTest.class)
public class SQLiteLibraryLoaderTest {
/** Saved system properties. */
private String savedOs, savedArch;
private SQLiteLibraryLoader loader;
@Before
public void deleteExtractedLibrary() {
loader = new SQLiteLibraryLoader();
loader.getNativeLibraryPath().delete();
}
@Before
public void saveSystemProperties() {
savedOs = System.getProperty("os.name");
savedArch = System.getProperty("os.arch");
}
@After
public void restoreSystemProperties() {
System.setProperty("os.name", savedOs);
System.setProperty("os.arch", savedArch);
}
@Test
public void shouldExtractNativeLibrary() {
File extractedPath = loader.getNativeLibraryPath();
assertThat(extractedPath).doesNotExist();
loader.doLoad();
assertThat(extractedPath).exists();
}
@Test
public void shouldNotRewriteExistingLibraryIfThereAreNoChanges() throws Exception{
loader.doLoad();
File extractedPath = loader.getNativeLibraryPath();
assertThat(extractedPath).exists();
final long resetTime = 1234L;
assertThat(extractedPath.setLastModified(resetTime)).describedAs("Cannot reset modification date").isTrue();
// actual time may be truncated to seconds
long time = extractedPath.lastModified();
assertThat(time).isLessThanOrEqualTo(resetTime);
loader.mustReload();
loader.doLoad();
extractedPath = loader.getNativeLibraryPath();
assertThat(extractedPath.lastModified()).isEqualTo(time);
}
@Test
public void shouldRewriteExistingLibraryIfThereAreChanges() throws Exception {
loader.getNativeLibraryPath().getParentFile().mkdirs();
SQLiteLibraryLoader.copy(
new ByteArrayInputStream("changed".getBytes()),
new FileOutputStream(loader.getNativeLibraryPath()));
long firstSize = loader.getNativeLibraryPath().length();
loader.doLoad();
File extractedPath = loader.getNativeLibraryPath();
assertThat(extractedPath).exists();
assertThat(extractedPath.length()).isGreaterThan(firstSize);
}
@Test
public void shouldFindLibraryForWindowsXPX86() throws IOException {
assertThat(loadLibrary(new SQLiteLibraryLoader(WINDOWS), "Windows XP", "x86"))
.isEqualTo("/windows-x86/sqlite4java.dll");
}
@Test
public void shouldFindLibraryForWindows7X86() throws IOException {
assertThat(loadLibrary(new SQLiteLibraryLoader(WINDOWS), "Windows 7", "x86"))
.isEqualTo("/windows-x86/sqlite4java.dll");
}
@Test
public void shouldFindLibraryForWindowsXPAmd64() throws IOException {
assertThat(loadLibrary(new SQLiteLibraryLoader(WINDOWS), "Windows XP", "amd64"))
.isEqualTo("/windows-x86_64/sqlite4java.dll");
}
@Test
public void shouldFindLibraryForWindows7Amd64() throws IOException {
assertThat(loadLibrary(new SQLiteLibraryLoader(WINDOWS), "Windows 7", "amd64"))
.isEqualTo("/windows-x86_64/sqlite4java.dll");
}
@Test
public void shouldFindLibraryForLinuxi386() throws IOException {
assertThat(loadLibrary(new SQLiteLibraryLoader(LINUX), "Some linux version", "i386"))
.isEqualTo("/linux-x86/libsqlite4java.so");
}
@Test
public void shouldFindLibraryForLinuxx86() throws IOException {
assertThat(loadLibrary(new SQLiteLibraryLoader(LINUX), "Some linux version", "x86"))
.isEqualTo("/linux-x86/libsqlite4java.so");
}
@Test
public void shouldFindLibraryForLinuxAmd64() throws IOException {
assertThat(loadLibrary(new SQLiteLibraryLoader(LINUX), "Some linux version", "amd64"))
.isEqualTo("/linux-x86_64/libsqlite4java.so");
}
@Test
public void shouldFindLibraryForMacWithAnyArch() throws IOException {
assertThat(loadLibrary(new SQLiteLibraryLoader(MAC), "Mac OS X", "any architecture"))
.isEqualTo("/mac-x86_64/libsqlite4java.jnilib");
}
@Test
public void shouldFindLibraryForMacWithAnyArchAndDyLibMapping() throws IOException {
assertThat(loadLibrary(new SQLiteLibraryLoader(MAC_DYLIB), "Mac OS X", "any architecture"))
.isEqualTo("/mac-x86_64/libsqlite4java.jnilib");
}
@Test(expected = UnsupportedOperationException.class)
public void shouldThrowExceptionIfUnknownNameAndArch() throws Exception {
loadLibrary(new SQLiteLibraryLoader(LINUX), "ACME Electronic", "FooBar2000");
}
private String loadLibrary(SQLiteLibraryLoader loader, String name, String arch) throws IOException {
setNameAndArch(name, arch);
return loader.getLibClasspathResourceName();
}
private static class LibraryMapperTest implements SQLiteLibraryLoader.LibraryNameMapper {
private final String prefix;
private final String ext;
private LibraryMapperTest(String prefix, String ext) {
this.prefix = prefix;
this.ext = ext;
}
@Override
public String mapLibraryName(String name) {
return prefix + name + "." + ext;
}
}
private static void setNameAndArch(String name, String arch) {
System.setProperty("os.name", name);
System.setProperty("os.arch", arch);
}
private static final SQLiteLibraryLoader.LibraryNameMapper LINUX = new LibraryMapperTest("lib", "so");
private static final SQLiteLibraryLoader.LibraryNameMapper WINDOWS = new LibraryMapperTest("", "dll");
private static final SQLiteLibraryLoader.LibraryNameMapper MAC = new LibraryMapperTest("lib", "jnilib");
private static final SQLiteLibraryLoader.LibraryNameMapper MAC_DYLIB = new LibraryMapperTest("lib", "dylib");
}