Skip to content

Commit 009a813

Browse files
committed
add more tests
1 parent 8237188 commit 009a813

11 files changed

+340
-1
lines changed
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
package net.zetetic.tests.support;
2+
3+
import net.sqlcipher.database.SQLiteDatabase;
4+
import net.zetetic.tests.SQLCipherTest;
5+
6+
public class CheckIsWriteAheadLoggingEnabledTest extends SupportTest {
7+
@Override
8+
public boolean execute(SQLiteDatabase database) {
9+
database.enableWriteAheadLogging();
10+
boolean statusWhenEnabled = database.isWriteAheadLoggingEnabled();
11+
database.disableWriteAheadLogging();
12+
boolean statusWhenDisabled = database.isWriteAheadLoggingEnabled();
13+
return statusWhenEnabled && !statusWhenDisabled;
14+
}
15+
16+
@Override
17+
public String getName() {
18+
return "Test isWriteAheadLoggingEnabled";
19+
}
20+
}
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
package net.zetetic.tests.support;
2+
3+
import net.sqlcipher.database.SQLiteDatabase;
4+
import net.zetetic.QueryHelper;
5+
import net.zetetic.tests.SQLCipherTest;
6+
7+
public class DisableWriteAheadLoggingTest extends SupportTest {
8+
@Override
9+
public boolean execute(SQLiteDatabase database) {
10+
boolean result = database.enableWriteAheadLogging();
11+
String currentMode = getJournalModeState(database);
12+
if(!result || !currentMode.equals("wal")) return false;
13+
database.disableWriteAheadLogging();
14+
currentMode = getJournalModeState(database);
15+
return currentMode.equals("delete");
16+
}
17+
18+
private String getJournalModeState(SQLiteDatabase database){
19+
return QueryHelper.singleValueFromQuery(database, "PRAGMA journal_mode;");
20+
}
21+
22+
@Override
23+
public String getName() {
24+
return "Disable WAL mode";
25+
}
26+
}
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
package net.zetetic.tests.support;
2+
3+
import net.sqlcipher.database.SQLiteDatabase;
4+
import net.zetetic.QueryHelper;
5+
import net.zetetic.tests.SQLCipherTest;
6+
7+
public class EnableForeignKeyConstraintsTest extends SupportTest {
8+
@Override
9+
public boolean execute(SQLiteDatabase database) {
10+
String initialState = getForeignKeyState(database);
11+
if(!initialState.equals("0")) return false;
12+
database.setForeignKeyConstraintsEnabled(true);
13+
String currentState = getForeignKeyState(database);
14+
if(!currentState.equals("1")) return false;
15+
return true;
16+
}
17+
18+
private String getForeignKeyState(SQLiteDatabase database){
19+
return QueryHelper.singleValueFromQuery(database, "PRAGMA foreign_keys");
20+
}
21+
22+
@Override
23+
public String getName() {
24+
return "Enable Foreign Key Constraints";
25+
}
26+
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
package net.zetetic.tests.support;
2+
3+
import net.sqlcipher.database.SQLiteDatabase;
4+
import net.zetetic.QueryHelper;
5+
import net.zetetic.tests.SQLCipherTest;
6+
7+
public class EnableWriteAheadLoggingTest extends SupportTest {
8+
@Override
9+
public boolean execute(SQLiteDatabase database) {
10+
boolean result = database.enableWriteAheadLogging();
11+
String currentMode = QueryHelper.singleValueFromQuery(database, "PRAGMA journal_mode;");
12+
return result && currentMode.equals("wal");
13+
}
14+
15+
@Override
16+
public String getName() {
17+
return "Enable WAL mode";
18+
}
19+
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
package net.zetetic.tests.support;
2+
3+
import net.sqlcipher.database.SQLiteDatabase;
4+
import net.zetetic.tests.SQLCipherTest;
5+
6+
public class ForeignKeyConstraintsEnabledWithTransactionTest extends SupportTest {
7+
@Override
8+
public boolean execute(SQLiteDatabase database) {
9+
database.beginTransaction();
10+
try {
11+
database.setForeignKeyConstraintsEnabled(true);
12+
}catch (IllegalStateException ex){
13+
if(ex.getMessage().equals("Foreign key constraints may not be changed while in a transaction")) {
14+
return true;
15+
}
16+
}
17+
return false;
18+
}
19+
20+
@Override
21+
public String getName() {
22+
return "Disallow foreign key constraints in transaction";
23+
}
24+
}
Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
package net.zetetic.tests.support;
2+
3+
import android.util.Log;
4+
import net.sqlcipher.Cursor;
5+
import net.sqlcipher.CursorWindow;
6+
import net.sqlcipher.CustomCursorWindowAllocation;
7+
import net.sqlcipher.database.SQLiteDatabase;
8+
import net.zetetic.tests.RowColumnValueBuilder;
9+
import net.zetetic.tests.SQLCipherTest;
10+
import java.io.UnsupportedEncodingException;
11+
import java.security.MessageDigest;
12+
import java.security.SecureRandom;
13+
import java.util.ArrayList;
14+
import java.util.Arrays;
15+
import java.util.List;
16+
17+
public class LargeDatabaseCursorAccessTest extends SupportTest {
18+
19+
@Override
20+
public boolean execute(SQLiteDatabase database) {
21+
try {
22+
int rowCount = 1000;
23+
long windowAllocationSize = 1024 * 1024 / 20;
24+
buildDatabase(database, rowCount, 30, new RowColumnValueBuilder() {
25+
@Override
26+
public Object buildRowColumnValue(String[] columns, int row, int column) {
27+
try {
28+
MessageDigest digest = MessageDigest.getInstance("SHA-1");
29+
String columnName = columns[column];
30+
String value = String.format("%s%d", columnName, row);
31+
return digest.digest(value.getBytes("UTF-8"));
32+
} catch (Exception e) {
33+
Log.e(TAG, e.toString());
34+
return null;
35+
}
36+
}
37+
});
38+
39+
Integer[] randomRows = generateRandomNumbers(rowCount, rowCount);
40+
CursorWindow.setCursorWindowAllocation(new CustomCursorWindowAllocation(windowAllocationSize, 0, windowAllocationSize));
41+
Cursor cursor = database.rawQuery("SELECT * FROM t1;", null);
42+
MessageDigest digest = MessageDigest.getInstance("SHA-1");
43+
int row = 0;
44+
Log.i(TAG, "Walking cursor forward");
45+
while(cursor.moveToNext()){
46+
if (!CompareDigestForAllColumns(cursor, digest, row)) return false;
47+
row++;
48+
}
49+
Log.i(TAG, "Walking cursor backward");
50+
while(cursor.moveToPrevious()){
51+
row--;
52+
if (!CompareDigestForAllColumns(cursor, digest, row)) return false;
53+
}
54+
Log.i(TAG, "Walking cursor randomly");
55+
for(int randomRow : randomRows){
56+
cursor.moveToPosition(randomRow);
57+
if (!CompareDigestForAllColumns(cursor, digest, randomRow)) return false;
58+
}
59+
60+
} catch (Exception e){
61+
return false;
62+
}
63+
return true;
64+
}
65+
66+
@Override
67+
public String getName() {
68+
return "Large Database Cursor Access Test";
69+
}
70+
71+
private boolean CompareDigestForAllColumns(Cursor cursor, MessageDigest digest, int row) throws UnsupportedEncodingException {
72+
int columnCount = cursor.getColumnCount();
73+
for(int column = 0; column < columnCount; column++){
74+
Log.i(TAG, String.format("Comparing SHA-1 digest for row:%d", row));
75+
String columnName = cursor.getColumnName(column);
76+
byte[] actual = cursor.getBlob(column);
77+
String value = String.format("%s%d", columnName, row);
78+
byte[] expected = digest.digest(value.getBytes("UTF-8"));
79+
if(!Arrays.equals(actual, expected)){
80+
Log.e(TAG, String.format("SHA-1 digest mismatch for row:%d column:%d", row, column));
81+
return false;
82+
}
83+
}
84+
return true;
85+
}
86+
87+
private Integer[] generateRandomNumbers(int max, int times){
88+
SecureRandom random = new SecureRandom();
89+
List<Integer> numbers = new ArrayList<>();
90+
for(int index = 0; index < times; index++){
91+
boolean alreadyExists;
92+
do {
93+
int value = random.nextInt(max);
94+
alreadyExists = numbers.contains(value);
95+
if(!alreadyExists){
96+
numbers.add(value);
97+
}
98+
} while(alreadyExists);
99+
}
100+
return numbers.toArray(new Integer[0]);
101+
}
102+
}

app/src/main/java/net/zetetic/tests/support/SupportSuiteRunner.java

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,9 +93,21 @@ private List<SupportTest> getTestsToRun() {
9393
// TODO rewrite tests.add(new SQLiteOpenHelperEnableWriteAheadLogAfterGetDatabaseTest());
9494
tests.add(new SQLiteOpenHelperGetNameTest());
9595
// TODO rewrite tests.add(new SQLiteOpenHelperOnDowngradeTest());
96-
// TODO rewrite tests.add(new SQLiteOpenHelperConfigureTest());
96+
// TODO rewrite tests.add(new SQLiteOpenHelperConfigureTest());
9797
tests.add(new CheckIsDatabaseIntegrityOkTest());
9898
tests.add(new GetAttachedDatabasesTest());
99+
tests.add(new EnableForeignKeyConstraintsTest());
100+
tests.add(new ForeignKeyConstraintsEnabledWithTransactionTest());
101+
tests.add(new EnableWriteAheadLoggingTest());
102+
tests.add(new DisableWriteAheadLoggingTest());
103+
tests.add(new CheckIsWriteAheadLoggingEnabledTest());
104+
tests.add(new WriteAheadLoggingWithTransactionTest());
105+
// TODO rewrite tests.add(new WriteAheadLoggingWithInMemoryDatabaseTest());
106+
tests.add(new WriteAheadLoggingWithAttachedDatabaseTest());
107+
tests.add(new TransactionNonExclusiveTest());
108+
tests.add(new TransactionWithListenerTest());
109+
tests.add(new LargeDatabaseCursorAccessTest());
110+
99111
/*
100112
101113
//// tests.add(new TimeLargeByteArrayQueryTest());
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
package net.zetetic.tests.support;
2+
3+
import net.sqlcipher.database.SQLiteDatabase;
4+
import net.zetetic.tests.SQLCipherTest;
5+
6+
public class TransactionNonExclusiveTest extends SupportTest {
7+
8+
@Override
9+
public boolean execute(SQLiteDatabase database) {
10+
database.beginTransactionNonExclusive();
11+
database.execSQL("create table t1(a,b);");
12+
database.setTransactionSuccessful();
13+
database.endTransaction();
14+
return true;
15+
}
16+
17+
@Override
18+
public String getName() {
19+
return "Transaction Immediate Mode";
20+
}
21+
}
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
package net.zetetic.tests.support;
2+
3+
import net.sqlcipher.database.SQLiteDatabase;
4+
import net.sqlcipher.database.SQLiteTransactionListener;
5+
import net.zetetic.tests.SQLCipherTest;
6+
7+
public class TransactionWithListenerTest extends SupportTest {
8+
9+
boolean beginCalled = false;
10+
11+
@Override
12+
public boolean execute(SQLiteDatabase database) {
13+
database.beginTransactionWithListener(listener);
14+
database.execSQL("create table t1(a,b);");
15+
database.setTransactionSuccessful();
16+
database.endTransaction();
17+
return beginCalled;
18+
}
19+
20+
@Override
21+
public String getName() {
22+
return "Transaction Exclusive Mode";
23+
}
24+
25+
SQLiteTransactionListener listener = new SQLiteTransactionListener() {
26+
@Override
27+
public void onBegin() {
28+
beginCalled = true;
29+
}
30+
31+
@Override
32+
public void onCommit() {
33+
34+
}
35+
36+
@Override
37+
public void onRollback() {
38+
39+
}
40+
};
41+
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
package net.zetetic.tests.support;
2+
3+
import net.sqlcipher.database.SQLiteDatabase;
4+
import net.zetetic.ZeteticApplication;
5+
import net.zetetic.tests.SQLCipherTest;
6+
import java.io.File;
7+
import java.util.UUID;
8+
9+
public class WriteAheadLoggingWithAttachedDatabaseTest extends SupportTest {
10+
@Override
11+
public boolean execute(SQLiteDatabase database) {
12+
UUID name = UUID.randomUUID();
13+
File databasePath = ZeteticApplication.getInstance().getDatabasePath(name.toString());
14+
database.execSQL("ATTACH DATABASE ? as foo;", new Object[]{databasePath.getAbsolutePath()});
15+
boolean result = database.enableWriteAheadLogging();
16+
return result == false;
17+
}
18+
19+
@Override
20+
public String getName() {
21+
return "Disallow WAL Mode with Attached DB";
22+
}
23+
}

0 commit comments

Comments
 (0)