mirror of
https://codeberg.org/Freeyourgadget/Gadgetbridge
synced 2024-12-25 18:15:49 +01:00
Revert "Revert "Adjust test case setup and fix failing tests""
This reverts commit b0384e90d5
.
This commit is contained in:
parent
c4f8f86c00
commit
f1fbab7dd9
@ -88,11 +88,18 @@ public class GBApplication extends Application {
|
||||
|
||||
public static final String ACTION_QUIT
|
||||
= "nodomain.freeyourgadget.gadgetbridge.gbapplication.action.quit";
|
||||
|
||||
private static GBApplication app;
|
||||
|
||||
private static Logging logging = new Logging() {
|
||||
@Override
|
||||
protected String createLogDirectory() throws IOException {
|
||||
File dir = FileUtils.getExternalFilesDir();
|
||||
return dir.getAbsolutePath();
|
||||
if (GBEnvironment.env().isLocalTest()) {
|
||||
return System.getProperty(Logging.PROP_LOGFILES_DIR);
|
||||
} else {
|
||||
File dir = FileUtils.getExternalFilesDir();
|
||||
return dir.getAbsolutePath();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@ -110,12 +117,17 @@ public class GBApplication extends Application {
|
||||
// don't do anything here, add it to onCreate instead
|
||||
}
|
||||
|
||||
public static Logging getLogging() {
|
||||
return logging;
|
||||
}
|
||||
|
||||
protected DeviceService createDeviceService() {
|
||||
return new GBDeviceService(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreate() {
|
||||
app = this;
|
||||
super.onCreate();
|
||||
|
||||
if (lockHandler != null) {
|
||||
@ -137,9 +149,12 @@ public class GBApplication extends Application {
|
||||
|
||||
setupExceptionHandler();
|
||||
|
||||
GB.environment = GBEnvironment.createDeviceEnvironment();
|
||||
|
||||
setupDatabase(this);
|
||||
if (!GBEnvironment.isEnvironmentSetup()) {
|
||||
GBEnvironment.setupEnvironment(GBEnvironment.createDeviceEnvironment());
|
||||
// setup db after the environment is set up, but don't do it in test mode
|
||||
// in test mode, it's done individually, see TestBase
|
||||
setupDatabase();
|
||||
}
|
||||
|
||||
deviceManager = new DeviceManager(this);
|
||||
|
||||
@ -195,8 +210,14 @@ public class GBApplication extends Application {
|
||||
return prefs.getBoolean("minimize_priority", false);
|
||||
}
|
||||
|
||||
static void setupDatabase(Context context) {
|
||||
DBOpenHelper helper = new DBOpenHelper(context, DATABASE_NAME, null);
|
||||
public void setupDatabase() {
|
||||
DaoMaster.OpenHelper helper;
|
||||
GBEnvironment env = GBEnvironment.env();
|
||||
if (env.isTest()) {
|
||||
helper = new DaoMaster.DevOpenHelper(this, null, null);
|
||||
} else {
|
||||
helper = new DBOpenHelper(this, DATABASE_NAME, null);
|
||||
}
|
||||
SQLiteDatabase db = helper.getWritableDatabase();
|
||||
DaoMaster daoMaster = new DaoMaster(db);
|
||||
if (lockHandler == null) {
|
||||
@ -471,4 +492,8 @@ public class GBApplication extends Application {
|
||||
public DeviceManager getDeviceManager() {
|
||||
return deviceManager;
|
||||
}
|
||||
|
||||
public static GBApplication app() {
|
||||
return app;
|
||||
}
|
||||
}
|
||||
|
@ -20,6 +20,10 @@ package nodomain.freeyourgadget.gadgetbridge;
|
||||
* Some more or less useful utility methods to aid local (non-device) testing.
|
||||
*/
|
||||
public class GBEnvironment {
|
||||
// DO NOT USE A LOGGER HERE. Will break LoggingTest!
|
||||
// private static final Logger LOG = LoggerFactory.getLogger(GBEnvironment.class);
|
||||
|
||||
private static GBEnvironment environment;
|
||||
private boolean localTest;
|
||||
private boolean deviceTest;
|
||||
|
||||
@ -41,4 +45,15 @@ public class GBEnvironment {
|
||||
return localTest;
|
||||
}
|
||||
|
||||
public static synchronized GBEnvironment env() {
|
||||
return environment;
|
||||
}
|
||||
|
||||
static synchronized boolean isEnvironmentSetup() {
|
||||
return environment != null;
|
||||
}
|
||||
|
||||
public synchronized static void setupEnvironment(GBEnvironment env) {
|
||||
environment = env;
|
||||
}
|
||||
}
|
||||
|
@ -20,7 +20,6 @@ import android.database.sqlite.SQLiteDatabase;
|
||||
import android.database.sqlite.SQLiteOpenHelper;
|
||||
|
||||
import nodomain.freeyourgadget.gadgetbridge.database.DBHandler;
|
||||
import nodomain.freeyourgadget.gadgetbridge.database.DBOpenHelper;
|
||||
import nodomain.freeyourgadget.gadgetbridge.entities.DaoMaster;
|
||||
import nodomain.freeyourgadget.gadgetbridge.entities.DaoSession;
|
||||
|
||||
@ -36,7 +35,7 @@ public class LockHandler implements DBHandler {
|
||||
public LockHandler() {
|
||||
}
|
||||
|
||||
public void init(DaoMaster daoMaster, DBOpenHelper helper) {
|
||||
public void init(DaoMaster daoMaster, DaoMaster.OpenHelper helper) {
|
||||
if (isValid()) {
|
||||
throw new IllegalStateException("DB must be closed before initializing it again");
|
||||
}
|
||||
@ -82,7 +81,7 @@ public class LockHandler implements DBHandler {
|
||||
throw new IllegalStateException("session must be null");
|
||||
}
|
||||
// this will create completely new db instances and in turn update this handler through #init()
|
||||
GBApplication.setupDatabase(GBApplication.getContext());
|
||||
GBApplication.app().setupDatabase();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -34,6 +34,7 @@ import java.util.List;
|
||||
|
||||
import de.greenrobot.dao.query.QueryBuilder;
|
||||
import nodomain.freeyourgadget.gadgetbridge.GBApplication;
|
||||
import nodomain.freeyourgadget.gadgetbridge.GBException;
|
||||
import nodomain.freeyourgadget.gadgetbridge.database.DBHandler;
|
||||
import nodomain.freeyourgadget.gadgetbridge.database.DBHelper;
|
||||
import nodomain.freeyourgadget.gadgetbridge.entities.CalendarSyncState;
|
||||
@ -97,76 +98,76 @@ public class CalendarReceiver extends BroadcastReceiver {
|
||||
}
|
||||
|
||||
public void syncCalendar(List<CalendarEvents.CalendarEvent> eventList) {
|
||||
LOG.info("Syncing with calendar.");
|
||||
Hashtable<Long, CalendarEvents.CalendarEvent> eventTable = new Hashtable<>();
|
||||
|
||||
try (DBHandler dbHandler = GBApplication.acquireDB()) {
|
||||
DaoSession session = dbHandler.getDaoSession();
|
||||
Long deviceId = DBHelper.getDevice(mGBDevice, session).getId();
|
||||
|
||||
QueryBuilder<CalendarSyncState> qb = session.getCalendarSyncStateDao().queryBuilder();
|
||||
|
||||
|
||||
for (CalendarEvents.CalendarEvent e : eventList) {
|
||||
long id = e.getId();
|
||||
eventTable.put(id, e);
|
||||
if (!eventState.containsKey(e.getId())) {
|
||||
qb = session.getCalendarSyncStateDao().queryBuilder();
|
||||
|
||||
CalendarSyncState calendarSyncState = qb.where(qb.and(CalendarSyncStateDao.Properties.DeviceId.eq(deviceId), CalendarSyncStateDao.Properties.CalendarEntryId.eq(id)))
|
||||
.build().unique();
|
||||
if (calendarSyncState == null) {
|
||||
eventState.put(id, new EventSyncState(e, EventState.NOT_SYNCED));
|
||||
LOG.info("event id=" + id + " is yet unknown to device id=" + deviceId);
|
||||
} else if (calendarSyncState.getHash() == e.hashCode()) {
|
||||
eventState.put(id, new EventSyncState(e, EventState.SYNCED));
|
||||
LOG.info("event id=" + id + " is up to date on device id=" + deviceId);
|
||||
}
|
||||
else {
|
||||
eventState.put(id, new EventSyncState(e, EventState.NEEDS_UPDATE));
|
||||
LOG.info("event id=" + id + " is not up to date on device id=" + deviceId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// add all missing calendar ids on the device to sync status (so that they are deleted later)
|
||||
List<CalendarSyncState> CalendarSyncStateList = qb.where(CalendarSyncStateDao.Properties.DeviceId.eq(deviceId)).build().list();
|
||||
for (CalendarSyncState CalendarSyncState : CalendarSyncStateList) {
|
||||
if (!eventState.containsKey(CalendarSyncState.getCalendarEntryId())) {
|
||||
eventState.put(CalendarSyncState.getCalendarEntryId(), new EventSyncState(null, EventState.NEEDS_DELETE));
|
||||
LOG.info("insert null event for orphanded calendar id=" + CalendarSyncState.getCalendarEntryId() + " for device=" + mGBDevice.getName());
|
||||
}
|
||||
}
|
||||
|
||||
Enumeration<Long> ids = eventState.keys();
|
||||
while (ids.hasMoreElements()) {
|
||||
qb = session.getCalendarSyncStateDao().queryBuilder();
|
||||
Long i = ids.nextElement();
|
||||
EventSyncState es = eventState.get(i);
|
||||
if (eventTable.containsKey(i)) {
|
||||
if (es.getState() == EventState.SYNCED) {
|
||||
if (!es.getEvent().equals(eventTable.get(i))) {
|
||||
eventState.put(i, new EventSyncState(eventTable.get(i), EventState.NEEDS_UPDATE));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (es.getState() == EventState.NOT_SYNCED) {
|
||||
// delete for current device only
|
||||
qb.where(qb.and(CalendarSyncStateDao.Properties.DeviceId.eq(deviceId), CalendarSyncStateDao.Properties.CalendarEntryId.eq(i)))
|
||||
.buildDelete().executeDeleteWithoutDetachingEntities();
|
||||
eventState.remove(i);
|
||||
} else {
|
||||
es.setState(EventState.NEEDS_DELETE);
|
||||
eventState.put(i, es);
|
||||
}
|
||||
}
|
||||
updateEvents(deviceId, session);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
syncCalendar(eventList, session);
|
||||
} catch (Exception e1) {
|
||||
GB.toast("Database Error while syncing Calendar", Toast.LENGTH_SHORT, GB.ERROR);
|
||||
}
|
||||
}
|
||||
|
||||
public void syncCalendar(List<CalendarEvents.CalendarEvent> eventList, DaoSession session) {
|
||||
LOG.info("Syncing with calendar.");
|
||||
Hashtable<Long, CalendarEvents.CalendarEvent> eventTable = new Hashtable<>();
|
||||
Long deviceId = DBHelper.getDevice(mGBDevice, session).getId();
|
||||
QueryBuilder<CalendarSyncState> qb = session.getCalendarSyncStateDao().queryBuilder();
|
||||
|
||||
|
||||
for (CalendarEvents.CalendarEvent e : eventList) {
|
||||
long id = e.getId();
|
||||
eventTable.put(id, e);
|
||||
if (!eventState.containsKey(e.getId())) {
|
||||
qb = session.getCalendarSyncStateDao().queryBuilder();
|
||||
|
||||
CalendarSyncState calendarSyncState = qb.where(qb.and(CalendarSyncStateDao.Properties.DeviceId.eq(deviceId), CalendarSyncStateDao.Properties.CalendarEntryId.eq(id)))
|
||||
.build().unique();
|
||||
if (calendarSyncState == null) {
|
||||
eventState.put(id, new EventSyncState(e, EventState.NOT_SYNCED));
|
||||
LOG.info("event id=" + id + " is yet unknown to device id=" + deviceId);
|
||||
} else if (calendarSyncState.getHash() == e.hashCode()) {
|
||||
eventState.put(id, new EventSyncState(e, EventState.SYNCED));
|
||||
LOG.info("event id=" + id + " is up to date on device id=" + deviceId);
|
||||
}
|
||||
else {
|
||||
eventState.put(id, new EventSyncState(e, EventState.NEEDS_UPDATE));
|
||||
LOG.info("event id=" + id + " is not up to date on device id=" + deviceId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// add all missing calendar ids on the device to sync status (so that they are deleted later)
|
||||
List<CalendarSyncState> CalendarSyncStateList = qb.where(CalendarSyncStateDao.Properties.DeviceId.eq(deviceId)).build().list();
|
||||
for (CalendarSyncState CalendarSyncState : CalendarSyncStateList) {
|
||||
if (!eventState.containsKey(CalendarSyncState.getCalendarEntryId())) {
|
||||
eventState.put(CalendarSyncState.getCalendarEntryId(), new EventSyncState(null, EventState.NEEDS_DELETE));
|
||||
LOG.info("insert null event for orphanded calendar id=" + CalendarSyncState.getCalendarEntryId() + " for device=" + mGBDevice.getName());
|
||||
}
|
||||
}
|
||||
|
||||
Enumeration<Long> ids = eventState.keys();
|
||||
while (ids.hasMoreElements()) {
|
||||
qb = session.getCalendarSyncStateDao().queryBuilder();
|
||||
Long i = ids.nextElement();
|
||||
EventSyncState es = eventState.get(i);
|
||||
if (eventTable.containsKey(i)) {
|
||||
if (es.getState() == EventState.SYNCED) {
|
||||
if (!es.getEvent().equals(eventTable.get(i))) {
|
||||
eventState.put(i, new EventSyncState(eventTable.get(i), EventState.NEEDS_UPDATE));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (es.getState() == EventState.NOT_SYNCED) {
|
||||
// delete for current device only
|
||||
qb.where(qb.and(CalendarSyncStateDao.Properties.DeviceId.eq(deviceId), CalendarSyncStateDao.Properties.CalendarEntryId.eq(i)))
|
||||
.buildDelete().executeDeleteWithoutDetachingEntities();
|
||||
eventState.remove(i);
|
||||
} else {
|
||||
es.setState(EventState.NEEDS_DELETE);
|
||||
eventState.put(i, es);
|
||||
}
|
||||
}
|
||||
updateEvents(deviceId, session);
|
||||
}
|
||||
}
|
||||
|
||||
private void updateEvents(Long deviceId, DaoSession session) {
|
||||
|
@ -38,6 +38,7 @@ import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import nodomain.freeyourgadget.gadgetbridge.GBApplication;
|
||||
import nodomain.freeyourgadget.gadgetbridge.GBEnvironment;
|
||||
|
||||
public class FileUtils {
|
||||
// Don't use slf4j here -- would be a bootstrapping problem
|
||||
@ -209,9 +210,11 @@ public class FileUtils {
|
||||
|
||||
// the first directory is also the primary external storage, i.e. the same as Environment.getExternalFilesDir()
|
||||
// TODO: check the mount state of *all* dirs when switching to later API level
|
||||
if (i == 0 && !Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState())) {
|
||||
GB.log("ignoring unmounted external storage dir: " + dir, GB.INFO, null);
|
||||
continue;
|
||||
if (!GBEnvironment.env().isLocalTest()) { // don't do this with robolectric
|
||||
if (i == 0 && !Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState())) {
|
||||
GB.log("ignoring unmounted external storage dir: " + dir, GB.INFO, null);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
result.add(dir); // add last
|
||||
}
|
||||
|
@ -60,10 +60,9 @@ public class GB {
|
||||
public static final String DISPLAY_MESSAGE_MESSAGE = "message";
|
||||
public static final String DISPLAY_MESSAGE_DURATION = "duration";
|
||||
public static final String DISPLAY_MESSAGE_SEVERITY = "severity";
|
||||
public static GBEnvironment environment;
|
||||
|
||||
public static Notification createNotification(String text, boolean connected, Context context) {
|
||||
if (env().isLocalTest()) {
|
||||
if (GBEnvironment.env().isLocalTest()) {
|
||||
return null;
|
||||
}
|
||||
Intent notificationIntent = new Intent(context, ControlCenterv2.class);
|
||||
@ -227,7 +226,7 @@ public class GB {
|
||||
*/
|
||||
public static void toast(final Context context, final String message, final int displayTime, final int severity, final Throwable ex) {
|
||||
log(message, severity, ex); // log immediately, not delayed
|
||||
if (env().isLocalTest()) {
|
||||
if (GBEnvironment.env().isLocalTest()) {
|
||||
return;
|
||||
}
|
||||
Looper mainLooper = Looper.getMainLooper();
|
||||
@ -358,7 +357,7 @@ public class GB {
|
||||
}
|
||||
|
||||
public static void updateBatteryNotification(String text, String bigText, Context context) {
|
||||
if (env().isLocalTest()) {
|
||||
if (GBEnvironment.env().isLocalTest()) {
|
||||
return;
|
||||
}
|
||||
Notification notification = createBatteryNotification(text, bigText, context);
|
||||
@ -369,10 +368,6 @@ public class GB {
|
||||
removeNotification(NOTIFICATION_ID_LOW_BATTERY, context);
|
||||
}
|
||||
|
||||
public static GBEnvironment env() {
|
||||
return environment;
|
||||
}
|
||||
|
||||
public static void assertThat(boolean condition, String errorMessage) {
|
||||
if (!condition) {
|
||||
throw new AssertionError(errorMessage);
|
||||
|
@ -6,7 +6,9 @@ import org.junit.Test;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import nodomain.freeyourgadget.gadgetbridge.database.DBHelper;
|
||||
import nodomain.freeyourgadget.gadgetbridge.entities.CalendarSyncStateDao;
|
||||
import nodomain.freeyourgadget.gadgetbridge.entities.Device;
|
||||
import nodomain.freeyourgadget.gadgetbridge.externalevents.CalendarReceiver;
|
||||
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
|
||||
import nodomain.freeyourgadget.gadgetbridge.model.CalendarEvents;
|
||||
|
@ -6,8 +6,8 @@ import org.junit.After;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
|
||||
import nodomain.freeyourgadget.gadgetbridge.GBApplication;
|
||||
import nodomain.freeyourgadget.gadgetbridge.Logging;
|
||||
import nodomain.freeyourgadget.gadgetbridge.util.FileUtils;
|
||||
|
||||
@ -25,16 +25,12 @@ public class LoggingTest extends TestBase {
|
||||
public LoggingTest() throws Exception {
|
||||
}
|
||||
|
||||
private Logging logging = new Logging() {
|
||||
@Override
|
||||
protected String createLogDirectory() throws IOException {
|
||||
return logFilesDir.getAbsolutePath();
|
||||
}
|
||||
};
|
||||
private Logging logging = GBApplication.getLogging();
|
||||
|
||||
@Override
|
||||
@After
|
||||
public void tearDown() {
|
||||
public void tearDown() throws Exception {
|
||||
super.tearDown();
|
||||
assertTrue(FileUtils.deleteRecursively(getLogFilesDir()));
|
||||
}
|
||||
|
||||
|
@ -1,7 +1,6 @@
|
||||
package nodomain.freeyourgadget.gadgetbridge.test;
|
||||
|
||||
import android.content.Context;
|
||||
import android.database.sqlite.SQLiteDatabase;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
@ -16,9 +15,9 @@ import java.io.File;
|
||||
import ch.qos.logback.classic.util.ContextInitializer;
|
||||
import nodomain.freeyourgadget.gadgetbridge.BuildConfig;
|
||||
import nodomain.freeyourgadget.gadgetbridge.GBApplication;
|
||||
import nodomain.freeyourgadget.gadgetbridge.GBEnvironment;
|
||||
import nodomain.freeyourgadget.gadgetbridge.Logging;
|
||||
import nodomain.freeyourgadget.gadgetbridge.database.DBHandler;
|
||||
import nodomain.freeyourgadget.gadgetbridge.entities.DaoMaster;
|
||||
import nodomain.freeyourgadget.gadgetbridge.entities.DaoSession;
|
||||
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
|
||||
import nodomain.freeyourgadget.gadgetbridge.model.DeviceType;
|
||||
@ -46,9 +45,10 @@ public abstract class TestBase {
|
||||
// Make sure logging is set up for all testcases, so that we can debug problems
|
||||
@BeforeClass
|
||||
public static void setupSuite() throws Exception {
|
||||
GBEnvironment.setupEnvironment(GBEnvironment.createLocalTestEnvironment());
|
||||
|
||||
// print everything going to android.util.Log to System.out
|
||||
System.setProperty("robolectric.logging", "stdout");
|
||||
// ShadowLog.stream = System.out;
|
||||
|
||||
// properties might be preconfigured in build.gradle because of test ordering problems
|
||||
String logDir = System.getProperty(Logging.PROP_LOGFILES_DIR);
|
||||
@ -69,20 +69,19 @@ public abstract class TestBase {
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
app = (GBApplication) RuntimeEnvironment.application;
|
||||
assertNotNull(app);
|
||||
assertNotNull(getContext());
|
||||
// doesn't work with Robolectric yet
|
||||
// dbHandler = GBApplication.acquireDB();
|
||||
// daoSession = dbHandler.getDaoSession();
|
||||
DaoMaster.DevOpenHelper openHelper = new DaoMaster.DevOpenHelper(app, null, null);
|
||||
SQLiteDatabase db = openHelper.getWritableDatabase();
|
||||
daoSession = new DaoMaster(db).newSession();
|
||||
app.setupDatabase();
|
||||
dbHandler = GBApplication.acquireDB();
|
||||
daoSession = dbHandler.getDaoSession();
|
||||
assertNotNull(daoSession);
|
||||
}
|
||||
|
||||
@After
|
||||
public void tearDown() throws Exception {
|
||||
// GBApplication.releaseDB();
|
||||
dbHandler.closeDb();
|
||||
GBApplication.releaseDB();
|
||||
}
|
||||
|
||||
protected GBDevice createDummyGDevice(String macAddress) {
|
||||
|
Loading…
Reference in New Issue
Block a user