1/*
2 * Copyright (C) 2017 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package androidx.room.integration.testapp.test;
18
19import static org.hamcrest.CoreMatchers.instanceOf;
20import static org.hamcrest.CoreMatchers.is;
21import static org.hamcrest.MatcherAssert.assertThat;
22import static org.junit.Assert.fail;
23
24import android.support.test.InstrumentationRegistry;
25import android.support.test.filters.SmallTest;
26import android.support.test.runner.AndroidJUnit4;
27import android.util.Log;
28
29import androidx.room.Room;
30import androidx.room.integration.testapp.TestDatabase;
31import androidx.room.integration.testapp.vo.User;
32import androidx.sqlite.db.SupportSQLiteDatabase;
33
34import org.junit.After;
35import org.junit.Before;
36import org.junit.Test;
37import org.junit.runner.RunWith;
38
39import java.io.File;
40
41@RunWith(AndroidJUnit4.class)
42@SmallTest
43public class IdentityDetectionTest {
44    static final String TAG = "IdentityDetectionTest";
45    static final String DB_FILE_NAME = "identity_test_db";
46    TestDatabase mTestDatabase;
47    @Before
48    public void createTestDatabase() {
49        deleteDbFile();
50    }
51
52    @Test
53    public void reOpenWithoutIssues() {
54        openDb();
55        mTestDatabase.getUserDao().insert(TestUtil.createUser(3));
56        closeDb();
57        openDb();
58        User[] users = mTestDatabase.getUserDao().loadByIds(3);
59        assertThat(users.length, is(1));
60    }
61
62    @Test
63    public void reOpenChangedHash() {
64        openDb();
65        mTestDatabase.getUserDao().insert(TestUtil.createUser(3));
66        // change the hash
67        SupportSQLiteDatabase db = mTestDatabase.getOpenHelper().getWritableDatabase();
68        db.execSQL("UPDATE " + Room.MASTER_TABLE_NAME + " SET `identity_hash` = ?"
69                + " WHERE id = 42", new String[]{"bad hash"});
70        closeDb();
71        Throwable[] exceptions = new Throwable[1];
72        try {
73            openDb();
74            mTestDatabase.getUserDao().loadByIds(3);
75        } catch (Throwable t) {
76            exceptions[0] = t;
77            mTestDatabase = null;
78        }
79        assertThat(exceptions[0], instanceOf(IllegalStateException.class));
80    }
81
82    @Test
83    public void reOpenMasterTableDropped() {
84        openDb();
85        mTestDatabase.getUserDao().insert(TestUtil.createUser(3));
86        // drop the master table
87        SupportSQLiteDatabase db = mTestDatabase.getOpenHelper().getWritableDatabase();
88        db.execSQL("DROP TABLE " + Room.MASTER_TABLE_NAME);
89        closeDb();
90        try {
91            openDb();
92            mTestDatabase.getUserDao().loadByIds(3);
93            fail("Was expecting an exception.");
94        } catch (Throwable t) {
95            assertThat(t, instanceOf(IllegalStateException.class));
96        }
97    }
98
99    private void closeDb() {
100        mTestDatabase.close();
101    }
102
103    private void openDb() {
104        mTestDatabase = Room.databaseBuilder(InstrumentationRegistry.getTargetContext(),
105                TestDatabase.class, DB_FILE_NAME).build();
106    }
107
108    @After
109    public void clear() {
110        try {
111            if (mTestDatabase != null) {
112                closeDb();
113            }
114            deleteDbFile();
115        } catch (Throwable t) {
116            Log.e(TAG, "could not close test database", t);
117            throw t;
118        }
119    }
120
121    private void deleteDbFile() {
122        File testDb = InstrumentationRegistry.getTargetContext().getDatabasePath(DB_FILE_NAME);
123        testDb.delete();
124    }
125}
126