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;
18
19import static org.hamcrest.CoreMatchers.is;
20import static org.hamcrest.CoreMatchers.not;
21import static org.hamcrest.CoreMatchers.sameInstance;
22import static org.hamcrest.MatcherAssert.assertThat;
23import static org.mockito.Mockito.mock;
24import static org.mockito.Mockito.verify;
25
26import androidx.sqlite.db.SupportSQLiteProgram;
27
28import org.junit.Before;
29import org.junit.Test;
30import org.junit.runner.RunWith;
31import org.junit.runners.JUnit4;
32
33import java.util.ArrayList;
34import java.util.Iterator;
35import java.util.List;
36
37@RunWith(JUnit4.class)
38public class RoomSQLiteQueryTest {
39    @Before
40    public void clear() {
41        RoomSQLiteQuery.sQueryPool.clear();
42    }
43
44    @Test
45    public void acquireBasic() {
46        RoomSQLiteQuery query = RoomSQLiteQuery.acquire("abc", 3);
47        assertThat(query.getSql(), is("abc"));
48        assertThat(query.mArgCount, is(3));
49        assertThat(query.mBlobBindings.length, is(4));
50        assertThat(query.mLongBindings.length, is(4));
51        assertThat(query.mStringBindings.length, is(4));
52        assertThat(query.mDoubleBindings.length, is(4));
53    }
54
55    @Test
56    public void acquireSameSizeAgain() {
57        RoomSQLiteQuery query = RoomSQLiteQuery.acquire("abc", 3);
58        query.release();
59        assertThat(RoomSQLiteQuery.acquire("blah", 3), sameInstance(query));
60    }
61
62    @Test
63    public void acquireSameSizeWithoutRelease() {
64        RoomSQLiteQuery query = RoomSQLiteQuery.acquire("abc", 3);
65        assertThat(RoomSQLiteQuery.acquire("fda", 3), not(sameInstance(query)));
66    }
67
68    @Test
69    public void bindings() {
70        RoomSQLiteQuery query = RoomSQLiteQuery.acquire("abc", 6);
71        byte[] myBlob = new byte[3];
72        long myLong = 3L;
73        double myDouble = 7.0;
74        String myString = "ss";
75        query.bindBlob(1, myBlob);
76        query.bindLong(2, myLong);
77        query.bindNull(3);
78        query.bindDouble(4, myDouble);
79        query.bindString(5, myString);
80        query.bindNull(6);
81        SupportSQLiteProgram program = mock(SupportSQLiteProgram.class);
82        query.bindTo(program);
83
84        verify(program).bindBlob(1, myBlob);
85        verify(program).bindLong(2, myLong);
86        verify(program).bindNull(3);
87        verify(program).bindDouble(4, myDouble);
88        verify(program).bindString(5, myString);
89        verify(program).bindNull(6);
90    }
91
92    @Test
93    public void dontKeepSameSizeTwice() {
94        RoomSQLiteQuery query1 = RoomSQLiteQuery.acquire("abc", 3);
95        RoomSQLiteQuery query2 = RoomSQLiteQuery.acquire("zx", 3);
96        RoomSQLiteQuery query3 = RoomSQLiteQuery.acquire("qw", 0);
97
98        query1.release();
99        query2.release();
100        assertThat(RoomSQLiteQuery.sQueryPool.size(), is(1));
101
102        query3.release();
103        assertThat(RoomSQLiteQuery.sQueryPool.size(), is(2));
104    }
105
106    @Test
107    public void returnExistingForSmallerSize() {
108        RoomSQLiteQuery query = RoomSQLiteQuery.acquire("abc", 3);
109        query.release();
110        assertThat(RoomSQLiteQuery.acquire("dsa", 2), sameInstance(query));
111    }
112
113    @Test
114    public void returnNewForBigger() {
115        RoomSQLiteQuery query = RoomSQLiteQuery.acquire("abc", 3);
116        query.release();
117        assertThat(RoomSQLiteQuery.acquire("dsa", 4), not(sameInstance(query)));
118    }
119
120    @Test
121    public void pruneCache() {
122        for (int i = 0; i < RoomSQLiteQuery.POOL_LIMIT; i++) {
123            RoomSQLiteQuery.acquire("dsdsa", i).release();
124        }
125        pruneCacheTest();
126    }
127
128    @Test
129    public void pruneCacheReverseInsertion() {
130        List<RoomSQLiteQuery> queries = new ArrayList<>();
131        for (int i = RoomSQLiteQuery.POOL_LIMIT - 1; i >= 0; i--) {
132            queries.add(RoomSQLiteQuery.acquire("dsdsa", i));
133        }
134        for (RoomSQLiteQuery query : queries) {
135            query.release();
136        }
137        pruneCacheTest();
138    }
139
140    private void pruneCacheTest() {
141        assertThat(RoomSQLiteQuery.sQueryPool.size(), is(RoomSQLiteQuery.POOL_LIMIT));
142        RoomSQLiteQuery.acquire("dsadsa", RoomSQLiteQuery.POOL_LIMIT + 1).release();
143        assertThat(RoomSQLiteQuery.sQueryPool.size(), is(RoomSQLiteQuery.DESIRED_POOL_SIZE));
144        Iterator<RoomSQLiteQuery> itr = RoomSQLiteQuery.sQueryPool.values().iterator();
145        for (int i = 0; i < RoomSQLiteQuery.DESIRED_POOL_SIZE; i++) {
146            assertThat(itr.next().mCapacity, is(i));
147        }
148    }
149}
150