Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 41ac6b9b authored by Vincent Bourgmayer's avatar Vincent Bourgmayer
Browse files

Merge branch '445-o-cleanTests' into 'v1-oreo'

Clean eDrive unit tests

See merge request !141
parents 99b7f9d2 24c441d5
Loading
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -22,7 +22,7 @@ test:
  stage: test
  script:
    - ls /usr/lib/jvm/
    - ./gradlew test -Dorg.gradle.java.home=/usr/lib/jvm/java-8-openjdk-amd64 -PtestAccountName="$testAccountName" -PtestAccountPwd="$testAccountPwd" -PtestServerUrl="$testServerUrl"
    - ./gradlew test -PtestAccountName="$testAccountName" -PtestAccountPwd="$testAccountPwd" -PtestServerUrl="$testServerUrl"
  artifacts:
    when: always
    paths:
+9 −6
Original line number Diff line number Diff line
@@ -27,9 +27,6 @@ android {
        versionCode versionMajor * 1000000 + versionMinor * 1000 + versionPatch
        versionName "${versionMajor}.${versionMinor}.${versionPatch}"
        setProperty("archivesBaseName", "eDrive-$versionName")
        buildConfigField "String", "testAccountName", "\""+getTestProp("testAccountName")+"\""
        buildConfigField "String", "testAccountPWd", "\""+getTestProp("testAccountPwd")+"\""
        buildConfigField "String", "testServerUrl", "\""+getTestProp("testServerUrl")+"\""
    }
    buildTypes {
        release {
@@ -46,7 +43,12 @@ android {
    testOptions {
        unitTests {
            returnDefaultValues = true
            //includeAndroidResources = true
            includeAndroidResources = true
            unitTests.all {
                systemProperty 'test.account.url', getTestProp("testServerUrl")
                systemProperty 'test.account.username', getTestProp("testAccountName")
                systemProperty 'test.account.password', getTestProp("testAccountPwd")
            }
        }
    }
    buildFeatures {
@@ -83,6 +85,7 @@ dependencies {
    testImplementation 'androidx.test:runner:1.4.0'
    testImplementation 'androidx.test:rules:1.4.0'
    testImplementation 'junit:junit:4.12'
    testImplementation 'org.robolectric:robolectric:4.4'
    testImplementation('org.mockito:mockito-inline:3.4.0')
    testImplementation 'org.robolectric:robolectric:4.8.1'
    testImplementation 'org.mockito:mockito-inline:3.4.0'
    testImplementation "androidx.work:work-testing:$work_version"
}
+44 −32
Original line number Diff line number Diff line
@@ -3,6 +3,8 @@ package foundation.e.drive;
import android.accounts.Account;
import android.accounts.AccountManager;
import android.content.Context;
import android.os.Bundle;
import android.util.Log;

import com.owncloud.android.lib.common.OwnCloudClient;
import com.owncloud.android.lib.common.network.CertificateCombinedException;
@@ -11,8 +13,6 @@ import com.owncloud.android.lib.common.operations.RemoteOperationResult;
import com.owncloud.android.lib.common.utils.Log_OC;
import com.owncloud.android.lib.resources.status.GetRemoteStatusOperation;

import org.junit.BeforeClass;

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
@@ -20,10 +20,14 @@ import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.Properties;

import static com.owncloud.android.lib.common.accounts.AccountUtils.Constants.KEY_OC_BASE_URL;
import static org.junit.Assert.assertTrue;
import static org.robolectric.Shadows.shadowOf;

import androidx.work.Configuration;
import androidx.work.testing.SynchronousExecutor;
import androidx.work.testing.WorkManagerTestInitHelper;

public abstract class TestUtils {
    public static final String TEST_LOCAL_ROOT_FOLDER_PATH = "/tmp/eDrive/test/"; //THis is where test file and folder for synchronisatio will be stored
@@ -31,8 +35,7 @@ public abstract class TestUtils {
    public static String TEST_ACCOUNT_TYPE ="eelo";
    public static String TEST_SERVER_URI;
    public static String TEST_ACCOUNT_NAME;

    private static String TEST_ACCOUNT_PASSWORD; //Shouldn't be accessible from outside
    private static String TEST_ACCOUNT_PASSWORD;
    private static Account validAccount;


@@ -40,15 +43,16 @@ public abstract class TestUtils {
     * This method execute before the class, it assure that credentials are available
     */
    public static void loadServerCredentials() {
        TEST_ACCOUNT_PASSWORD = BuildConfig.testAccountPWd;
        TEST_ACCOUNT_NAME = BuildConfig.testAccountName;
        TEST_SERVER_URI = BuildConfig.testServerUrl;
        final Properties properties = System.getProperties();
        TEST_ACCOUNT_PASSWORD = properties.getProperty("test.account.password");
        TEST_ACCOUNT_NAME = properties.getProperty("test.account.username");
        TEST_SERVER_URI = properties.getProperty("test.account.url");
    }


    /**
     * Get the valid Account object. Create it if it isn't already instanciated
     * @return
     * @return Account
     */
    public static Account getValidAccount() {
        if (validAccount == null) {
@@ -65,23 +69,22 @@ public abstract class TestUtils {
        storeAccountInManager(getValidAccount(), TEST_ACCOUNT_PASSWORD, TEST_SERVER_URI, accountManager);
    }


    public static void storeAccountInManager(Account account, String password, String serverUrl, AccountManager manager) {
        shadowOf(manager).addAccount(account); // Commenting this make failure due to JobUtils.stopScheduleJob()" method...
        shadowOf(manager).setPassword(account, password);
        shadowOf(manager).setUserData(account, KEY_OC_BASE_URL, serverUrl);
        final Bundle userData = new Bundle();
        userData.putString(KEY_OC_BASE_URL, serverUrl);
        manager.addAccountExplicitly(account, password, userData);
    }

    /**
     * Test the connexion to the server
     * Add the certificate to the knownServerCertificateStore if required
     * @throws KeyStoreException
     * @throws CertificateException
     * @throws NoSuchAlgorithmException
     * @throws IOException
     * @throws InterruptedException
     * @throws KeyStoreException exception
     * @throws CertificateException exception
     * @throws NoSuchAlgorithmException exception
     * @throws IOException exception
     * @throws InterruptedException exception
     */
    public static void testConnection(OwnCloudClient client, Context context) throws KeyStoreException,
    public static void testConnection(final OwnCloudClient client, final Context context) throws KeyStoreException,
            CertificateException,
            NoSuchAlgorithmException,
            IOException,
@@ -97,8 +100,8 @@ public abstract class TestUtils {
            if (RemoteOperationResult.ResultCode.SSL_RECOVERABLE_PEER_UNVERIFIED.equals(result.getCode())) {
                Log_OC.d("AbstractIT", "Accepting certificate");

                CertificateCombinedException exception = (CertificateCombinedException) result.getException();
                X509Certificate certificate = exception.getServerCertificate();
                final CertificateCombinedException exception = (CertificateCombinedException) result.getException();
                final X509Certificate certificate = exception.getServerCertificate();

                NetworkUtils.addCertToKnownServersStore(certificate, context);
                Thread.sleep(1000);
@@ -110,7 +113,6 @@ public abstract class TestUtils {
                if (!result.isSuccess()) {
                    throw new RuntimeException("No connection to server possible, even with accepted cert");
                }

            } else {
                throw new RuntimeException("No connection to server possible");
            }
@@ -123,18 +125,18 @@ public abstract class TestUtils {
     * @param filePath path of the file to create
     * @param iteration number of time to write dummy content
     * @return the File instance
     * @throws IOException
     * @throws SecurityException
     * @throws IOException exception
     * @throws SecurityException exception
     */
    public static File createFile(String filePath, int iteration) throws IOException, SecurityException{
        File file = new File(filePath);
        if (!file.getParentFile().exists()) {
        final File file = new File(filePath);
        if (file.getParentFile() != null && !file.getParentFile().exists()) {
            assertTrue(file.getParentFile().mkdirs());
        }

        file.createNewFile();

        FileWriter writer = new FileWriter(file);
        final FileWriter writer = new FileWriter(file);

        for (int i = 0; i < iteration; i++) {
            writer.write("123123123123123123123123123\n");
@@ -144,4 +146,14 @@ public abstract class TestUtils {

        return file;
    }


    public static void initializeWorkmanager(Context context) {
        final Configuration config = new Configuration.Builder()
                .setMinimumLoggingLevel(Log.DEBUG)
                .setExecutor(new SynchronousExecutor())
                .build();
        WorkManagerTestInitHelper.initializeTestWorkManager(
                context, config);
    }
}
+83 −83
Original line number Diff line number Diff line
package foundation.e.drive.operations;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;

import android.accounts.AccountManager;
import android.content.Context;
import android.os.Build;

import com.owncloud.android.lib.common.OwnCloudClient;
@@ -8,8 +16,6 @@ import com.owncloud.android.lib.common.UserInfo;
import com.owncloud.android.lib.common.operations.RemoteOperationResult;
import com.owncloud.android.lib.resources.users.GetRemoteUserInfoOperation;

import junit.framework.Assert;

import org.junit.After;
import org.junit.Before;
import org.junit.Ignore;
@@ -26,7 +32,6 @@ import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import foundation.e.drive.BuildConfig;
import foundation.e.drive.database.DbHelper;
import foundation.e.drive.models.SyncedFileState;
import foundation.e.drive.models.SyncedFolder;
@@ -35,24 +40,25 @@ import foundation.e.drive.utils.CommonUtils;


@RunWith(RobolectricTestRunner.class)
@Config(constants = BuildConfig.class, sdk = Build.VERSION_CODES.O, manifest = Config.NONE)
@Config(sdk = Build.VERSION_CODES.O, manifest = Config.NONE)
public class UploadFileOperationTest {

    private List<SyncedFileState> syncedFileStates= new ArrayList<>();
    private OwnCloudClient client;
    private AccountManager accountManager;

    private final OwnCloudClient client;
    private final AccountManager accountManager;
    private final Context context;
    private long userFreeQuota;

    public UploadFileOperationTest() {
        context = RuntimeEnvironment.getApplication();
        accountManager = AccountManager.get(context);
        ShadowLog.stream = System.out;
        TestUtils.loadServerCredentials();
        accountManager = AccountManager.get(RuntimeEnvironment.application);
        TestUtils.prepareValidAccount(accountManager);
        ShadowLog.stream = System.out;
        client = CommonUtils.getOwnCloudClient(CommonUtils.getAccount(TestUtils.TEST_ACCOUNT_NAME, TestUtils.TEST_ACCOUNT_TYPE, accountManager), RuntimeEnvironment.application);
        client = CommonUtils.getOwnCloudClient(CommonUtils.getAccount(TestUtils.TEST_ACCOUNT_NAME, TestUtils.TEST_ACCOUNT_TYPE, accountManager), context);

        try {
            TestUtils.testConnection(client, RuntimeEnvironment.application);
            TestUtils.testConnection(client, context);
        } catch (Exception e) {
            System.out.println("test connection failed: "+e.getMessage());
        }
@@ -62,26 +68,20 @@ public class UploadFileOperationTest {
    @Before
    public void setUp() {
        prepareDB();        //Create DB
        Assert.assertNotNull("Client is null. unexpected!", client);
    }

    @After
    public void tearDown(){
        assertNotNull("Client is null. unexpected!", client);
    }

    /**
     * Prepare content of database for test
     * Insert three test folder: small, medium, large
     */
    private void prepareDB() {
        //Insert three test folder: small, medium, large


        DbHelper.insertSyncedFolder(createSyncedFolder("small"), RuntimeEnvironment.application);
        DbHelper.insertSyncedFolder(createSyncedFolder("medium"), RuntimeEnvironment.application);
        DbHelper.insertSyncedFolder(createSyncedFolder("large"), RuntimeEnvironment.application);
        DbHelper.insertSyncedFolder(createSyncedFolder("small"), context);
        DbHelper.insertSyncedFolder(createSyncedFolder("medium"), context);
        DbHelper.insertSyncedFolder(createSyncedFolder("large"), context);

        //Insert at least one file for each folder
        Assert.assertEquals("There isn't three folder in DB as expected", 3, DbHelper.getSyncedFolderList(RuntimeEnvironment.application, true).size());
        //assertion for debug purpose
        assertEquals("There isn't three folder in DB as expected", 3, DbHelper.getSyncedFolderList(context, true).size());
    }

    /**
@@ -90,23 +90,25 @@ public class UploadFileOperationTest {
     * @return SyncedFolder instance
     */
    private SyncedFolder createSyncedFolder(String name) {
        return new SyncedFolder(name, TestUtils.TEST_LOCAL_ROOT_FOLDER_PATH+name+"/", TestUtils.TEST_REMOTE_ROOT_FOLDER_PATH+name+"/", true, true, true, true);
        return new SyncedFolder(name,
                TestUtils.TEST_LOCAL_ROOT_FOLDER_PATH+name+"/",
                TestUtils.TEST_REMOTE_ROOT_FOLDER_PATH+name+"/",
                true, true, true, true);
    }

    /**
     * Create local file to use for upload test
     * Create a local small file to use for upload test
     */
    private void createSmallFile() {

        final String smallDummyFilePath = TestUtils.TEST_LOCAL_ROOT_FOLDER_PATH+"small/dummy.txt";
        try {
            TestUtils.createFile(smallDummyFilePath, 2);
        } catch (IOException | SecurityException e ) {
            Assert.fail(e.getMessage());
            fail(e.getMessage());
        }

        final SyncedFileState sfs = new SyncedFileState(-1, "dummy.txt", TestUtils.TEST_LOCAL_ROOT_FOLDER_PATH+"small/dummy.txt", TestUtils.TEST_REMOTE_ROOT_FOLDER_PATH+"small/dummy.txt",  "", 0l, 0, true);
        sfs.setId(DbHelper.manageSyncedFileStateDB(sfs, "INSERT", RuntimeEnvironment.application));
        final SyncedFileState sfs = new SyncedFileState(-1, "dummy.txt", TestUtils.TEST_LOCAL_ROOT_FOLDER_PATH+"small/dummy.txt", TestUtils.TEST_REMOTE_ROOT_FOLDER_PATH+"small/dummy.txt",  "", 0l, 0, true, 3);
        sfs.setId(DbHelper.manageSyncedFileStateDB(sfs, "INSERT", context));

        syncedFileStates.add(sfs);
    }
@@ -121,21 +123,21 @@ public class UploadFileOperationTest {
        if (!syncedFileStates.isEmpty()) {
            final SyncedFileState sfs = syncedFileStates.get(0);
            if (sfs != null) {
                RemoveFileOperation removeRemoteFileOp = new RemoveFileOperation(sfs);
                final RemoveFileOperation removeRemoteFileOp = new RemoveFileOperation(sfs);
                removeRemoteFileOp.execute(client);
            }
        }

        final String smallDummyFilePath = TestUtils.TEST_LOCAL_ROOT_FOLDER_PATH+"small/dummy.txt";
        File smallFile = new File(smallDummyFilePath);
        final File smallFile = new File(smallDummyFilePath);
        if (smallFile.exists()) {
            return smallFile.delete();
        } else return true;
    }

    private long getUserRemoteFreeQuota() {
        GetRemoteUserInfoOperation getRemoteUserInfoOperation = new GetRemoteUserInfoOperation();
        RemoteOperationResult ocsResult = getRemoteUserInfoOperation.execute(client);
        final GetRemoteUserInfoOperation getRemoteUserInfoOperation = new GetRemoteUserInfoOperation();
        final RemoteOperationResult ocsResult = getRemoteUserInfoOperation.execute(client);

        if (ocsResult.isSuccess() && ocsResult.getData() != null) {
            UserInfo userInfo = (UserInfo) ocsResult.getData().get(0);
@@ -156,15 +158,13 @@ public class UploadFileOperationTest {
        removeSmallFile(); //clean the environnement
        createSmallFile(); //preparation

        final SyncedFileState sfs_fromDB = DbHelper.loadSyncedFile(RuntimeEnvironment.application, syncedFileStates.get(0).getLocalPath(), true);
        Assert.assertTrue("SyncedFileState loaded from DB must have an empty Etag", sfs_fromDB.getLastETAG().isEmpty());

        final SyncedFileState sfs_fromDB = DbHelper.loadSyncedFile(context, syncedFileStates.get(0).getLocalPath(), true);
        assertTrue("SyncedFileState loaded from DB must have an empty Etag", sfs_fromDB.getLastETAG().isEmpty());

        boolean checkEtag = false;
        UploadFileOperation testOperation = new UploadFileOperation(syncedFileStates.get(0));
        testOperation.setContext(RuntimeEnvironment.application); //Without it, it won't update database
        UploadFileOperation testOperation = new UploadFileOperation(syncedFileStates.get(0), context);

        RemoteOperationResult result = testOperation.execute(client);
        final RemoteOperationResult result = testOperation.execute(client);
        String errorMsg = "The upload failed:\n http code: "+result.getHttpCode()
                +"\n, is success ?"+result.isSuccess()
                +"\n, log msg: "+result.getLogMessage()
@@ -172,10 +172,10 @@ public class UploadFileOperationTest {
        if (result.getException() != null) {
            errorMsg += "\n, exception msg: "+result.getException().getMessage();
        }
        Assert.assertTrue( errorMsg, result.isSuccess());
        assertTrue( errorMsg, result.isSuccess());

        final SyncedFileState sfs_fromDBAfterUpload = DbHelper.loadSyncedFile(RuntimeEnvironment.application, syncedFileStates.get(0).getLocalPath(), true);
        Assert.assertFalse("After upload, the database must store the etag of the syncedFileState. But here it is empty", sfs_fromDBAfterUpload.getLastETAG().isEmpty());
        final SyncedFileState sfs_fromDBAfterUpload = DbHelper.loadSyncedFile(context, syncedFileStates.get(0).getLocalPath(), true);
        assertFalse("After upload, the database must store the etag of the syncedFileState. But here it is empty", sfs_fromDBAfterUpload.getLastETAG().isEmpty());
    }


@@ -192,11 +192,10 @@ public class UploadFileOperationTest {
        SyncedFileState syncedFileState = null;
        //Test fails at the moment because of UploadFileOperation's constructor not checking for syncedFileState is null)
        // check https://gitlab.e.foundation/e/apps/eDrive/-/issues/120
        UploadFileOperation testOperation = new UploadFileOperation(syncedFileState);
        testOperation.setContext(RuntimeEnvironment.application);
        final UploadFileOperation testOperation = new UploadFileOperation(syncedFileState, context);

        RemoteOperationResult result = testOperation.execute(client);
        Assert.assertEquals("Expected result code was FORBIDDEN but got: "+result.getCode().name(), RemoteOperationResult.ResultCode.FORBIDDEN, result.getCode());
        assertEquals("Expected result code was FORBIDDEN but got: "+result.getCode().name(), RemoteOperationResult.ResultCode.FORBIDDEN, result.getCode());
    }


@@ -209,17 +208,17 @@ public class UploadFileOperationTest {
        removeSmallFile(); //clean the environnement
        createSmallFile(); //preparation

        final SyncedFileState sfs_fromDB = DbHelper.loadSyncedFile(RuntimeEnvironment.application, syncedFileStates.get(0).getLocalPath(), true);
        Assert.assertTrue("SyncedFileState loaded from DB must have an empty Etag", sfs_fromDB.getLastETAG().isEmpty());
        final SyncedFileState sfs_fromDB = DbHelper.loadSyncedFile(context, syncedFileStates.get(0).getLocalPath(), true);
        assertTrue("SyncedFileState loaded from DB must have an empty Etag", sfs_fromDB.getLastETAG().isEmpty());

        boolean checkEtag = false;
        UploadFileOperation testOperation = new UploadFileOperation(syncedFileStates.get(0));
        UploadFileOperation testOperation = new UploadFileOperation(syncedFileStates.get(0), context);

        File smallFile = new File(sfs_fromDB.getLocalPath());
        Assert.assertTrue("Local file deletion return false instead of true", smallFile.delete());
        final File smallFile = new File(sfs_fromDB.getLocalPath());
        assertTrue("Local file deletion return false instead of true", smallFile.delete());

        RemoteOperationResult result = testOperation.execute(client);
        Assert.assertEquals("Expected result code was FORBIDDEN but got: "+result.getCode().name(), RemoteOperationResult.ResultCode.FORBIDDEN, result.getCode());
        final RemoteOperationResult result = testOperation.execute(client);
        assertEquals("Expected result code was FORBIDDEN but got: "+result.getCode().name(), RemoteOperationResult.ResultCode.FORBIDDEN, result.getCode());
    }


@@ -229,28 +228,30 @@ public class UploadFileOperationTest {
    @Test
    public void fileSizeBiggerThanFreeQuota_shouldnotBeAllowed() {
        //long freeQuota = getUserRemoteFreeQuota();
        Assert.assertFalse("Reading remote free quota fails"+userFreeQuota, -1 == userFreeQuota);
        assertFalse("Reading remote free quota fails"+userFreeQuota, -1 == userFreeQuota);
        //We don't care of parameter of UploadFileOperation's constructor
        RemoteOperationResult actualResult = new UploadFileOperation(Mockito.mock(SyncedFileState.class))
        final RemoteOperationResult actualResult = new UploadFileOperation(Mockito.mock(SyncedFileState.class), context)
                .checkAvailableSpace(client, (userFreeQuota+1));
        Assert.assertEquals("Quota check ("+ userFreeQuota+"vs"+(userFreeQuota+1)+") failed", RemoteOperationResult.ResultCode.QUOTA_EXCEEDED, actualResult.getCode());
        assertEquals("Quota check ("+ userFreeQuota+"vs"+(userFreeQuota+1)+") failed", RemoteOperationResult.ResultCode.QUOTA_EXCEEDED, actualResult.getCode());
    }

    /**
     * Assert that uploading a file which size is exactly the amount of free quota isn't allowed
     *
     */
    @Test
    public void fileSizeEqualToFreeQuota_shouldnotBeAllowed(){
    public void fileSizeEqualToFreeQuota_shouldBeAllowed() {
        //I don't know why but it always fail for this test.
        //long freeQuota = getUserRemoteFreeQuota();
        Assert.assertFalse("Reading remote free quota fails"+userFreeQuota, -1 == userFreeQuota);
        assertFalse("Reading remote free quota fails"+userFreeQuota, -1 == userFreeQuota);

        RemoteOperationResult actualResult = new UploadFileOperation(Mockito.mock(SyncedFileState.class))
        final RemoteOperationResult actualResult = new UploadFileOperation(Mockito.mock(SyncedFileState.class), context)
                .checkAvailableSpace(client, userFreeQuota);
        Assert.assertEquals("Quota check  ("+ userFreeQuota+" vs "+userFreeQuota+") failed",
        assertNotEquals("Quota check is Quota Exceeded ("+ userFreeQuota+" vs "+userFreeQuota+")",
                RemoteOperationResult.ResultCode.QUOTA_EXCEEDED,
                actualResult.getCode());
        assertEquals("Quota Check is not OK",
                RemoteOperationResult.ResultCode.OK,
                actualResult.getCode());
    }


@@ -261,13 +262,12 @@ public class UploadFileOperationTest {
    @Test
    public void fileSizeSmallerThanFreeQuota_shouldBeAllowed() {
        //long freeQuota = getUserRemoteFreeQuota();
        Assert.assertFalse("Reading remote free quota fails "+userFreeQuota, -1 == userFreeQuota);
        assertFalse("Reading remote free quota fails "+userFreeQuota, -1 == userFreeQuota);

        RemoteOperationResult actualResult = new UploadFileOperation(Mockito.mock(SyncedFileState.class))
        final RemoteOperationResult actualResult = new UploadFileOperation(Mockito.mock(SyncedFileState.class), context)
                .checkAvailableSpace(client, (userFreeQuota-1));
        Assert.assertEquals("Quota check ("+ userFreeQuota+" vs "+(userFreeQuota-1)+") failed",
        assertEquals("Quota check ("+ userFreeQuota+" vs "+(userFreeQuota-1)+") failed",
                RemoteOperationResult.ResultCode.OK,
                actualResult.getCode());

    }
}
 No newline at end of file
+1 −2
Original line number Diff line number Diff line
@@ -17,7 +17,6 @@ import org.robolectric.android.controller.ServiceController;
import org.robolectric.annotation.Config;
import org.robolectric.shadows.ShadowLog;

import foundation.e.drive.BuildConfig;
import foundation.e.drive.TestUtils;
import foundation.e.drive.database.DbHelper;
import foundation.e.drive.utils.AppConstants;
@@ -27,7 +26,7 @@ import static foundation.e.drive.utils.AppConstants.MEDIASYNC_PROVIDER_AUTHORITY
import static foundation.e.drive.utils.AppConstants.SETTINGSYNC_PROVIDER_AUTHORITY;

@RunWith(RobolectricTestRunner.class)
@Config(constants = BuildConfig.class, sdk = Build.VERSION_CODES.O, manifest = Config.NONE)
@Config(sdk = Build.VERSION_CODES.O, manifest = Config.NONE)
public abstract class AbstractServiceIT<T extends Service> {

    /**
Loading