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.hasItem; 20import static org.hamcrest.CoreMatchers.nullValue; 21import static org.hamcrest.MatcherAssert.assertThat; 22import static org.hamcrest.collection.IsCollectionWithSize.hasSize; 23 24import android.content.Context; 25import android.support.test.InstrumentationRegistry; 26import android.support.test.filters.SmallTest; 27import android.support.test.runner.AndroidJUnit4; 28 29import androidx.annotation.NonNull; 30import androidx.arch.core.executor.testing.CountingTaskExecutorRule; 31import androidx.room.InvalidationTracker; 32import androidx.room.Room; 33import androidx.room.integration.testapp.TestDatabase; 34import androidx.room.integration.testapp.dao.UserDao; 35import androidx.room.integration.testapp.vo.User; 36 37import org.junit.After; 38import org.junit.Before; 39import org.junit.Rule; 40import org.junit.Test; 41import org.junit.runner.RunWith; 42 43import java.util.Set; 44import java.util.concurrent.TimeUnit; 45import java.util.concurrent.TimeoutException; 46 47/** 48 * Tests invalidation tracking. 49 */ 50@SmallTest 51@RunWith(AndroidJUnit4.class) 52public class InvalidationTest { 53 @Rule 54 public CountingTaskExecutorRule executorRule = new CountingTaskExecutorRule(); 55 private UserDao mUserDao; 56 private TestDatabase mDb; 57 58 @Before 59 public void createDb() throws TimeoutException, InterruptedException { 60 Context context = InstrumentationRegistry.getTargetContext(); 61 mDb = Room.inMemoryDatabaseBuilder(context, TestDatabase.class).build(); 62 mUserDao = mDb.getUserDao(); 63 drain(); 64 } 65 66 @After 67 public void closeDb() throws TimeoutException, InterruptedException { 68 mDb.close(); 69 drain(); 70 } 71 72 private void drain() throws TimeoutException, InterruptedException { 73 executorRule.drainTasks(1, TimeUnit.MINUTES); 74 } 75 76 @Test 77 public void testInvalidationOnUpdate() throws InterruptedException, TimeoutException { 78 User user = TestUtil.createUser(3); 79 mUserDao.insert(user); 80 LoggingObserver observer = new LoggingObserver("User"); 81 mDb.getInvalidationTracker().addObserver(observer); 82 drain(); 83 mUserDao.updateById(3, "foo2"); 84 drain(); 85 assertThat(observer.getInvalidatedTables(), hasSize(1)); 86 assertThat(observer.getInvalidatedTables(), hasItem("User")); 87 } 88 89 @Test 90 public void testInvalidationOnDelete() throws InterruptedException, TimeoutException { 91 User user = TestUtil.createUser(3); 92 mUserDao.insert(user); 93 LoggingObserver observer = new LoggingObserver("User"); 94 mDb.getInvalidationTracker().addObserver(observer); 95 drain(); 96 mUserDao.delete(user); 97 drain(); 98 assertThat(observer.getInvalidatedTables(), hasSize(1)); 99 assertThat(observer.getInvalidatedTables(), hasItem("User")); 100 } 101 102 @Test 103 public void testInvalidationOnInsert() throws InterruptedException, TimeoutException { 104 LoggingObserver observer = new LoggingObserver("User"); 105 mDb.getInvalidationTracker().addObserver(observer); 106 drain(); 107 mUserDao.insert(TestUtil.createUser(3)); 108 drain(); 109 assertThat(observer.getInvalidatedTables(), hasSize(1)); 110 assertThat(observer.getInvalidatedTables(), hasItem("User")); 111 } 112 113 @Test 114 public void testDontInvalidateOnLateInsert() throws InterruptedException, TimeoutException { 115 LoggingObserver observer = new LoggingObserver("User"); 116 mUserDao.insert(TestUtil.createUser(3)); 117 drain(); 118 mDb.getInvalidationTracker().addObserver(observer); 119 drain(); 120 assertThat(observer.getInvalidatedTables(), nullValue()); 121 } 122 123 @Test 124 public void testMultipleTables() throws InterruptedException, TimeoutException { 125 LoggingObserver observer = new LoggingObserver("User", "Pet"); 126 mDb.getInvalidationTracker().addObserver(observer); 127 drain(); 128 mUserDao.insert(TestUtil.createUser(3)); 129 drain(); 130 assertThat(observer.getInvalidatedTables(), hasSize(1)); 131 assertThat(observer.getInvalidatedTables(), hasItem("User")); 132 } 133 134 private static class LoggingObserver extends InvalidationTracker.Observer { 135 private Set<String> mInvalidatedTables; 136 137 LoggingObserver(String... tables) { 138 super(tables); 139 } 140 141 @Override 142 public void onInvalidated(@NonNull Set<String> tables) { 143 mInvalidatedTables = tables; 144 } 145 146 Set<String> getInvalidatedTables() { 147 return mInvalidatedTables; 148 } 149 } 150} 151