1 /* 2 * Copyright (C) 2024 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.nfc; 18 19 import static com.android.nfc.NfcEventLog.FORMATTER; 20 21 import static com.google.common.truth.Truth.assertThat; 22 23 import static org.mockito.Mockito.verify; 24 import static org.mockito.Mockito.when; 25 26 import android.content.Context; 27 import android.content.res.Resources; 28 import android.os.test.TestLooper; 29 import android.util.AtomicFile; 30 31 import com.android.nfc.proto.NfcEventProto; 32 33 import org.junit.After; 34 import org.junit.Assert; 35 import org.junit.Before; 36 import org.junit.Test; 37 import org.junit.runner.RunWith; 38 import org.mockito.AdditionalMatchers; 39 import org.mockito.Mock; 40 import org.mockito.MockitoAnnotations; 41 42 import androidx.test.ext.junit.runners.AndroidJUnit4; 43 44 import java.io.FileOutputStream; 45 import java.time.LocalDateTime; 46 import java.util.ArrayDeque; 47 48 @RunWith(AndroidJUnit4.class) 49 public class NfcEventLogTest { 50 @Mock Context mContext; 51 @Mock NfcInjector mNfcInjector; 52 @Mock AtomicFile mLogFile; 53 @Mock Resources mResources; 54 @Mock FileOutputStream mFileOutputStream; 55 TestLooper mLooper; 56 NfcEventLog mNfcEventLog; 57 58 @Before setUp()59 public void setUp() throws Exception { 60 MockitoAnnotations.initMocks(this); 61 mLooper = new TestLooper(); 62 when(mContext.getResources()).thenReturn(mResources); 63 when(mResources.getInteger(R.integer.max_event_log_num)).thenReturn(10); 64 when(mLogFile.startWrite()).thenReturn(mFileOutputStream); 65 mNfcEventLog = new NfcEventLog(mContext, mNfcInjector, mLooper.getLooper(), mLogFile); 66 } 67 68 @After tearDown()69 public void tearDown() throws Exception { 70 } 71 72 @Test testLogEvent()73 public void testLogEvent() throws Exception { 74 NfcEventProto.EventType eventType = 75 NfcEventProto.EventType.newBuilder() 76 .setBootupState(NfcEventProto.NfcBootupState.newBuilder() 77 .setEnabled(true) 78 .build()) 79 .build(); 80 LocalDateTime localDateTime = LocalDateTime.MIN; 81 when(mNfcInjector.getLocalDateTime()).thenReturn(localDateTime); 82 mNfcEventLog.logEvent(eventType); 83 mLooper.dispatchAll(); 84 85 NfcEventProto.Event expectedEvent = NfcEventProto.Event.newBuilder() 86 .setTimestamp(localDateTime.format(FORMATTER)) 87 .setEventType(eventType) 88 .build(); 89 NfcEventProto.EventList expectedEventList = 90 NfcEventProto.EventList.newBuilder().addEvents(expectedEvent).build(); 91 verify(mFileOutputStream).write(AdditionalMatchers.aryEq(expectedEventList.toByteArray())); 92 } 93 94 @Test testMultipleLogEvents()95 public void testMultipleLogEvents() throws Exception { 96 NfcEventProto.EventType eventType = 97 NfcEventProto.EventType.newBuilder() 98 .setBootupState(NfcEventProto.NfcBootupState.newBuilder() 99 .setEnabled(true) 100 .build()) 101 .build(); 102 LocalDateTime localDateTime = LocalDateTime.MIN; 103 when(mNfcInjector.getLocalDateTime()).thenReturn(localDateTime); 104 105 // Log the event twice. 106 mNfcEventLog.logEvent(eventType); 107 mLooper.dispatchAll(); 108 109 mNfcEventLog.logEvent(eventType); 110 mLooper.dispatchAll(); 111 112 NfcEventProto.Event expectedEvent = NfcEventProto.Event.newBuilder() 113 .setTimestamp(localDateTime.format(FORMATTER)) 114 .setEventType(eventType) 115 .build(); 116 NfcEventProto.EventList expectedEventList = 117 NfcEventProto.EventList.newBuilder() 118 .addEvents(expectedEvent) 119 .addEvents(expectedEvent) 120 .build(); 121 verify(mFileOutputStream).write(AdditionalMatchers.aryEq(expectedEventList.toByteArray())); 122 } 123 124 @Test testReadEventsFromLogFile()125 public void testReadEventsFromLogFile() throws Exception { 126 LocalDateTime localDateTime = LocalDateTime.MIN; 127 NfcEventProto.EventType eventType = 128 NfcEventProto.EventType.newBuilder() 129 .setBootupState(NfcEventProto.NfcBootupState.newBuilder() 130 .setEnabled(true) 131 .build()) 132 .build(); 133 NfcEventProto.Event event = NfcEventProto.Event.newBuilder() 134 .setTimestamp(localDateTime.format(FORMATTER)) 135 .setEventType(eventType) 136 .build(); 137 NfcEventProto.EventList eventList = 138 NfcEventProto.EventList.newBuilder() 139 .addEvents(event) 140 .addEvents(event) 141 .build(); 142 143 when(mLogFile.readFully()).thenReturn(eventList.toByteArray()); 144 // Recreate the instance to simulate reading the log file. 145 mNfcEventLog = new NfcEventLog(mContext, mNfcInjector, mLooper.getLooper(), mLogFile); 146 mLooper.dispatchAll(); 147 148 ArrayDeque<NfcEventProto.Event> expectedEventList = new ArrayDeque<NfcEventProto.Event>(); 149 expectedEventList.add(event); 150 expectedEventList.add(event); 151 152 ArrayDeque<NfcEventProto.Event> retrievedEventsList = mNfcEventLog.getEventsList(); 153 assertThat(retrievedEventsList.toString()).isEqualTo(expectedEventList.toString()); 154 155 } 156 } 157