13db6d309415576ef0080c29705dc30496636a986Yigit Boyar/*
23db6d309415576ef0080c29705dc30496636a986Yigit Boyar * Copyright (C) 2016 The Android Open Source Project
33db6d309415576ef0080c29705dc30496636a986Yigit Boyar *
43db6d309415576ef0080c29705dc30496636a986Yigit Boyar * Licensed under the Apache License, Version 2.0 (the "License");
53db6d309415576ef0080c29705dc30496636a986Yigit Boyar * you may not use this file except in compliance with the License.
63db6d309415576ef0080c29705dc30496636a986Yigit Boyar * You may obtain a copy of the License at
73db6d309415576ef0080c29705dc30496636a986Yigit Boyar *
83db6d309415576ef0080c29705dc30496636a986Yigit Boyar *      http://www.apache.org/licenses/LICENSE-2.0
93db6d309415576ef0080c29705dc30496636a986Yigit Boyar *
103db6d309415576ef0080c29705dc30496636a986Yigit Boyar * Unless required by applicable law or agreed to in writing, software
113db6d309415576ef0080c29705dc30496636a986Yigit Boyar * distributed under the License is distributed on an "AS IS" BASIS,
123db6d309415576ef0080c29705dc30496636a986Yigit Boyar * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
133db6d309415576ef0080c29705dc30496636a986Yigit Boyar * See the License for the specific language governing permissions and
143db6d309415576ef0080c29705dc30496636a986Yigit Boyar * limitations under the License.
153db6d309415576ef0080c29705dc30496636a986Yigit Boyar */
16bdc4c86d3dff74f6634a38e2f7b316b0e823a2c8Alan Viverettepackage androidx.room;
173db6d309415576ef0080c29705dc30496636a986Yigit Boyar
183db6d309415576ef0080c29705dc30496636a986Yigit Boyarimport static org.hamcrest.CoreMatchers.is;
193db6d309415576ef0080c29705dc30496636a986Yigit Boyarimport static org.hamcrest.CoreMatchers.not;
203db6d309415576ef0080c29705dc30496636a986Yigit Boyarimport static org.hamcrest.CoreMatchers.notNullValue;
213db6d309415576ef0080c29705dc30496636a986Yigit Boyarimport static org.hamcrest.MatcherAssert.assertThat;
223db6d309415576ef0080c29705dc30496636a986Yigit Boyarimport static org.mockito.Matchers.anyString;
233db6d309415576ef0080c29705dc30496636a986Yigit Boyarimport static org.mockito.Mockito.mock;
242e8d5608ba4b3da0a05d6b6cc23d81fe10371970Yigit Boyarimport static org.mockito.Mockito.verify;
253db6d309415576ef0080c29705dc30496636a986Yigit Boyarimport static org.mockito.Mockito.when;
263db6d309415576ef0080c29705dc30496636a986Yigit Boyar
27bdc4c86d3dff74f6634a38e2f7b316b0e823a2c8Alan Viveretteimport androidx.sqlite.db.SupportSQLiteStatement;
283db6d309415576ef0080c29705dc30496636a986Yigit Boyar
293db6d309415576ef0080c29705dc30496636a986Yigit Boyarimport org.junit.Before;
303db6d309415576ef0080c29705dc30496636a986Yigit Boyarimport org.junit.Test;
313db6d309415576ef0080c29705dc30496636a986Yigit Boyarimport org.junit.runner.RunWith;
323db6d309415576ef0080c29705dc30496636a986Yigit Boyarimport org.junit.runners.JUnit4;
333db6d309415576ef0080c29705dc30496636a986Yigit Boyarimport org.mockito.invocation.InvocationOnMock;
343db6d309415576ef0080c29705dc30496636a986Yigit Boyarimport org.mockito.stubbing.Answer;
353db6d309415576ef0080c29705dc30496636a986Yigit Boyar
363db6d309415576ef0080c29705dc30496636a986Yigit Boyarimport java.util.concurrent.Callable;
373db6d309415576ef0080c29705dc30496636a986Yigit Boyarimport java.util.concurrent.ExecutionException;
383db6d309415576ef0080c29705dc30496636a986Yigit Boyarimport java.util.concurrent.FutureTask;
393db6d309415576ef0080c29705dc30496636a986Yigit Boyar
403db6d309415576ef0080c29705dc30496636a986Yigit Boyar@RunWith(JUnit4.class)
413db6d309415576ef0080c29705dc30496636a986Yigit Boyarpublic class SharedSQLiteStatementTest {
423db6d309415576ef0080c29705dc30496636a986Yigit Boyar    private SharedSQLiteStatement mSharedStmt;
432e8d5608ba4b3da0a05d6b6cc23d81fe10371970Yigit Boyar    RoomDatabase mDb;
443db6d309415576ef0080c29705dc30496636a986Yigit Boyar    @Before
453db6d309415576ef0080c29705dc30496636a986Yigit Boyar    public void init() {
462e8d5608ba4b3da0a05d6b6cc23d81fe10371970Yigit Boyar        mDb = mock(RoomDatabase.class);
472e8d5608ba4b3da0a05d6b6cc23d81fe10371970Yigit Boyar        when(mDb.compileStatement(anyString())).thenAnswer(new Answer<SupportSQLiteStatement>() {
483db6d309415576ef0080c29705dc30496636a986Yigit Boyar
493db6d309415576ef0080c29705dc30496636a986Yigit Boyar            @Override
503db6d309415576ef0080c29705dc30496636a986Yigit Boyar            public SupportSQLiteStatement answer(InvocationOnMock invocation) throws Throwable {
513db6d309415576ef0080c29705dc30496636a986Yigit Boyar                return mock(SupportSQLiteStatement.class);
523db6d309415576ef0080c29705dc30496636a986Yigit Boyar            }
533db6d309415576ef0080c29705dc30496636a986Yigit Boyar        });
542e8d5608ba4b3da0a05d6b6cc23d81fe10371970Yigit Boyar        when(mDb.getInvalidationTracker()).thenReturn(mock(InvalidationTracker.class));
552e8d5608ba4b3da0a05d6b6cc23d81fe10371970Yigit Boyar        mSharedStmt = new SharedSQLiteStatement(mDb) {
563db6d309415576ef0080c29705dc30496636a986Yigit Boyar            @Override
573db6d309415576ef0080c29705dc30496636a986Yigit Boyar            protected String createQuery() {
583db6d309415576ef0080c29705dc30496636a986Yigit Boyar                return "foo";
593db6d309415576ef0080c29705dc30496636a986Yigit Boyar            }
603db6d309415576ef0080c29705dc30496636a986Yigit Boyar        };
613db6d309415576ef0080c29705dc30496636a986Yigit Boyar    }
623db6d309415576ef0080c29705dc30496636a986Yigit Boyar
633db6d309415576ef0080c29705dc30496636a986Yigit Boyar    @Test
642e8d5608ba4b3da0a05d6b6cc23d81fe10371970Yigit Boyar    public void checkMainThread() {
652e8d5608ba4b3da0a05d6b6cc23d81fe10371970Yigit Boyar        mSharedStmt.acquire();
662e8d5608ba4b3da0a05d6b6cc23d81fe10371970Yigit Boyar        verify(mDb).assertNotMainThread();
672e8d5608ba4b3da0a05d6b6cc23d81fe10371970Yigit Boyar    }
682e8d5608ba4b3da0a05d6b6cc23d81fe10371970Yigit Boyar
692e8d5608ba4b3da0a05d6b6cc23d81fe10371970Yigit Boyar    @Test
703db6d309415576ef0080c29705dc30496636a986Yigit Boyar    public void basic() {
713db6d309415576ef0080c29705dc30496636a986Yigit Boyar        assertThat(mSharedStmt.acquire(), notNullValue());
723db6d309415576ef0080c29705dc30496636a986Yigit Boyar    }
733db6d309415576ef0080c29705dc30496636a986Yigit Boyar
743db6d309415576ef0080c29705dc30496636a986Yigit Boyar    @Test
753db6d309415576ef0080c29705dc30496636a986Yigit Boyar    public void getTwiceWithoutReleasing() {
763db6d309415576ef0080c29705dc30496636a986Yigit Boyar        SupportSQLiteStatement stmt1 = mSharedStmt.acquire();
773db6d309415576ef0080c29705dc30496636a986Yigit Boyar        SupportSQLiteStatement stmt2 = mSharedStmt.acquire();
783db6d309415576ef0080c29705dc30496636a986Yigit Boyar        assertThat(stmt1, notNullValue());
793db6d309415576ef0080c29705dc30496636a986Yigit Boyar        assertThat(stmt2, notNullValue());
803db6d309415576ef0080c29705dc30496636a986Yigit Boyar        assertThat(stmt1, is(not(stmt2)));
813db6d309415576ef0080c29705dc30496636a986Yigit Boyar    }
823db6d309415576ef0080c29705dc30496636a986Yigit Boyar
833db6d309415576ef0080c29705dc30496636a986Yigit Boyar    @Test
843db6d309415576ef0080c29705dc30496636a986Yigit Boyar    public void getTwiceWithReleasing() {
853db6d309415576ef0080c29705dc30496636a986Yigit Boyar        SupportSQLiteStatement stmt1 = mSharedStmt.acquire();
863db6d309415576ef0080c29705dc30496636a986Yigit Boyar        mSharedStmt.release(stmt1);
873db6d309415576ef0080c29705dc30496636a986Yigit Boyar        SupportSQLiteStatement stmt2 = mSharedStmt.acquire();
883db6d309415576ef0080c29705dc30496636a986Yigit Boyar        assertThat(stmt1, notNullValue());
893db6d309415576ef0080c29705dc30496636a986Yigit Boyar        assertThat(stmt1, is(stmt2));
903db6d309415576ef0080c29705dc30496636a986Yigit Boyar    }
913db6d309415576ef0080c29705dc30496636a986Yigit Boyar
923db6d309415576ef0080c29705dc30496636a986Yigit Boyar    @Test
933db6d309415576ef0080c29705dc30496636a986Yigit Boyar    public void getFromAnotherThreadWhileHolding() throws ExecutionException, InterruptedException {
943db6d309415576ef0080c29705dc30496636a986Yigit Boyar        SupportSQLiteStatement stmt1 = mSharedStmt.acquire();
953db6d309415576ef0080c29705dc30496636a986Yigit Boyar        FutureTask<SupportSQLiteStatement> task = new FutureTask<>(
963db6d309415576ef0080c29705dc30496636a986Yigit Boyar                new Callable<SupportSQLiteStatement>() {
973db6d309415576ef0080c29705dc30496636a986Yigit Boyar                    @Override
983db6d309415576ef0080c29705dc30496636a986Yigit Boyar                    public SupportSQLiteStatement call() throws Exception {
993db6d309415576ef0080c29705dc30496636a986Yigit Boyar                        return mSharedStmt.acquire();
1003db6d309415576ef0080c29705dc30496636a986Yigit Boyar                    }
1013db6d309415576ef0080c29705dc30496636a986Yigit Boyar                });
1023db6d309415576ef0080c29705dc30496636a986Yigit Boyar        new Thread(task).run();
1033db6d309415576ef0080c29705dc30496636a986Yigit Boyar        SupportSQLiteStatement stmt2 = task.get();
1043db6d309415576ef0080c29705dc30496636a986Yigit Boyar        assertThat(stmt1, notNullValue());
1053db6d309415576ef0080c29705dc30496636a986Yigit Boyar        assertThat(stmt2, notNullValue());
1063db6d309415576ef0080c29705dc30496636a986Yigit Boyar        assertThat(stmt1, is(not(stmt2)));
1073db6d309415576ef0080c29705dc30496636a986Yigit Boyar    }
1083db6d309415576ef0080c29705dc30496636a986Yigit Boyar
1093db6d309415576ef0080c29705dc30496636a986Yigit Boyar    @Test
1103db6d309415576ef0080c29705dc30496636a986Yigit Boyar    public void getFromAnotherThreadAfterReleasing() throws ExecutionException,
1113db6d309415576ef0080c29705dc30496636a986Yigit Boyar            InterruptedException {
1123db6d309415576ef0080c29705dc30496636a986Yigit Boyar        SupportSQLiteStatement stmt1 = mSharedStmt.acquire();
1133db6d309415576ef0080c29705dc30496636a986Yigit Boyar        mSharedStmt.release(stmt1);
1143db6d309415576ef0080c29705dc30496636a986Yigit Boyar        FutureTask<SupportSQLiteStatement> task = new FutureTask<>(
1153db6d309415576ef0080c29705dc30496636a986Yigit Boyar                new Callable<SupportSQLiteStatement>() {
1163db6d309415576ef0080c29705dc30496636a986Yigit Boyar                    @Override
1173db6d309415576ef0080c29705dc30496636a986Yigit Boyar                    public SupportSQLiteStatement call() throws Exception {
1183db6d309415576ef0080c29705dc30496636a986Yigit Boyar                        return mSharedStmt.acquire();
1193db6d309415576ef0080c29705dc30496636a986Yigit Boyar                    }
1203db6d309415576ef0080c29705dc30496636a986Yigit Boyar                });
1213db6d309415576ef0080c29705dc30496636a986Yigit Boyar        new Thread(task).run();
1223db6d309415576ef0080c29705dc30496636a986Yigit Boyar        SupportSQLiteStatement stmt2 = task.get();
1233db6d309415576ef0080c29705dc30496636a986Yigit Boyar        assertThat(stmt1, notNullValue());
1243db6d309415576ef0080c29705dc30496636a986Yigit Boyar        assertThat(stmt1, is(stmt2));
1253db6d309415576ef0080c29705dc30496636a986Yigit Boyar    }
1263db6d309415576ef0080c29705dc30496636a986Yigit Boyar}
127