1 /*
2  * Copyright (C) 2023 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 
17 package com.android.server.backup;
18 
19 import static com.google.common.truth.Truth.assertThat;
20 
21 import static org.mockito.Mockito.when;
22 import static org.testng.Assert.assertEquals;
23 
24 import android.platform.test.annotations.Presubmit;
25 
26 import androidx.test.filters.SmallTest;
27 import androidx.test.runner.AndroidJUnit4;
28 
29 import org.junit.Before;
30 import org.junit.Rule;
31 import org.junit.Test;
32 import org.junit.rules.TemporaryFolder;
33 import org.junit.runner.RunWith;
34 import org.mockito.InOrder;
35 import org.mockito.Mock;
36 import org.mockito.Mockito;
37 import org.mockito.MockitoAnnotations;
38 
39 import java.io.DataInputStream;
40 import java.io.File;
41 import java.io.FileInputStream;
42 import java.io.IOException;
43 import java.util.function.Consumer;
44 
45 @SmallTest
46 @Presubmit
47 @RunWith(AndroidJUnit4.class)
48 public class DataChangedJournalTest {
49     private static final String GMAIL = "com.google.gmail";
50     private static final String DOCS = "com.google.docs";
51     private static final String GOOGLE_PLUS = "com.google.plus";
52 
53     @Rule public TemporaryFolder mTemporaryFolder = new TemporaryFolder();
54 
55     @Mock private Consumer<String> mConsumer;
56     @Mock private File invalidFile;
57 
58     private File mFile;
59     private DataChangedJournal mJournal;
60 
61     @Before
setUp()62     public void setUp() throws Exception {
63         MockitoAnnotations.initMocks(this);
64         mFile = mTemporaryFolder.newFile();
65         mJournal = new DataChangedJournal(mFile);
66     }
67 
68     @Test
addPackage_addsPackagesToEndOfFile()69     public void addPackage_addsPackagesToEndOfFile() throws Exception {
70         mJournal.addPackage(GMAIL);
71         mJournal.addPackage(DOCS);
72         mJournal.addPackage(GOOGLE_PLUS);
73 
74         FileInputStream fos = new FileInputStream(mFile);
75         DataInputStream dos = new DataInputStream(fos);
76         assertThat(dos.readUTF()).isEqualTo(GMAIL);
77         assertThat(dos.readUTF()).isEqualTo(DOCS);
78         assertThat(dos.readUTF()).isEqualTo(GOOGLE_PLUS);
79         assertThat(dos.available()).isEqualTo(0);
80     }
81 
82     @Test
delete_deletesTheFile()83     public void delete_deletesTheFile() throws Exception {
84         mJournal.addPackage(GMAIL);
85 
86         mJournal.delete();
87 
88         assertThat(mFile.exists()).isFalse();
89     }
90 
91     @Test
equals_isTrueForTheSameFile()92     public void equals_isTrueForTheSameFile() throws Exception {
93         assertEqualsBothWaysAndHashCode(mJournal, new DataChangedJournal(mFile));
94     }
95 
assertEqualsBothWaysAndHashCode(T a, T b)96     private static <T> void assertEqualsBothWaysAndHashCode(T a, T b) {
97         assertEquals(a, b);
98         assertEquals(b, a);
99         assertEquals(a.hashCode(), b.hashCode());
100     }
101 
102     @Test
equals_isFalseForDifferentFiles()103     public void equals_isFalseForDifferentFiles() throws Exception {
104         assertThat(mJournal.equals(new DataChangedJournal(mTemporaryFolder.newFile()))).isFalse();
105     }
106 
107     @Test
forEach_iteratesThroughPackagesInFileInOrder()108     public void forEach_iteratesThroughPackagesInFileInOrder() throws Exception {
109         mJournal.addPackage(GMAIL);
110         mJournal.addPackage(DOCS);
111 
112         mJournal.forEach(mConsumer);
113 
114         InOrder inOrder = Mockito.inOrder(mConsumer);
115         inOrder.verify(mConsumer).accept(GMAIL);
116         inOrder.verify(mConsumer).accept(DOCS);
117         inOrder.verifyNoMoreInteractions();
118     }
119 
120     @Test
listJournals_returnsJournalsForEveryFileInDirectory()121     public void listJournals_returnsJournalsForEveryFileInDirectory() throws Exception {
122         File folder = mTemporaryFolder.newFolder();
123         DataChangedJournal.newJournal(folder);
124         DataChangedJournal.newJournal(folder);
125 
126         assertThat(DataChangedJournal.listJournals(folder)).hasSize(2);
127     }
128 
129     @Test
newJournal_createsANewTemporaryFile()130     public void newJournal_createsANewTemporaryFile() throws Exception {
131         File folder = mTemporaryFolder.newFolder();
132 
133         DataChangedJournal.newJournal(folder);
134 
135         assertThat(folder.listFiles()).hasLength(1);
136     }
137 
138     @Test(expected = NullPointerException.class)
newJournal_nullJournalDir()139     public void newJournal_nullJournalDir() throws IOException {
140         DataChangedJournal.newJournal(null);
141     }
142 
143     @Test(expected = NullPointerException.class)
nullFile()144     public void nullFile() {
145         new DataChangedJournal(null);
146     }
147 
148     @Test
toString_isSameAsFileToString()149     public void toString_isSameAsFileToString() throws Exception {
150         assertThat(mJournal.toString()).isEqualTo(mFile.toString());
151     }
152 
153     @Test
listJournals_invalidJournalFile_returnsEmptyList()154     public void listJournals_invalidJournalFile_returnsEmptyList() throws Exception {
155         when(invalidFile.listFiles()).thenReturn(null);
156 
157         assertThat(DataChangedJournal.listJournals(invalidFile)).isEmpty();
158     }
159 }
160