Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,189 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/

package org.apache.ranger.audit.queue;

import org.apache.ranger.audit.model.AuditEventBase;
import org.apache.ranger.audit.provider.AuditHandler;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;

import java.util.Arrays;
import java.util.concurrent.TimeUnit;

import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertNull;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.mockito.ArgumentMatchers.anyCollection;
import static org.mockito.Mockito.atLeastOnce;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.doThrow;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

/**
* @generated by copilot
* @description Unit Test cases for AuditAsyncQueue
* */
class AuditAsyncQueueTest {
private AuditHandler mockHandler;
private AuditAsyncQueue queue;

@BeforeEach
void setUp() {
mockHandler = mock(AuditHandler.class);
queue = new AuditAsyncQueue(mockHandler);
}

@Test
void testLogSingleEvent() {
AuditEventBase event = mock(AuditEventBase.class);
assertTrue(queue.log(event));
assertEquals(1, queue.queue.size());
}

@Test
void testLogMultipleEvents() {
AuditEventBase event1 = mock(AuditEventBase.class);
AuditEventBase event2 = mock(AuditEventBase.class);
assertTrue(queue.log(Arrays.asList(event1, event2)));
assertEquals(2, queue.queue.size());
}

@Test
void testLogReturnsFalseWhenQueueFull() {
queue = spy(queue);
doReturn(0).when(queue).getMaxQueueSize();
AuditEventBase event = mock(AuditEventBase.class);
assertFalse(queue.log(event));
}

@Test
void testStartAndStop() throws InterruptedException {
queue.start();
assertNotNull(queue.consumerThread);
assertTrue(queue.consumerThread.isAlive());

queue.stop();
// Give some time for thread to stop
TimeUnit.MILLISECONDS.sleep(100);
assertNull(queue.consumerThread);
}

@Test
void testStopCallsConsumerStop() throws InterruptedException {
queue.start();
queue.stop();
TimeUnit.MILLISECONDS.sleep(100);
verify(mockHandler, atLeastOnce()).stop();
}

@Test
void testRunLogAuditDrainModeExitsWhenQueueEmpty() throws Exception {
// Set drain mode
queue.setDrain(true);

// Queue is already empty in the setUp method

// Should exit the loop without exceptions
assertDoesNotThrow(() -> queue.runLogAudit());

// Consumer.stop should be called when exiting the loop
verify(mockHandler).stop();
}

@Test
void testRunLogAuditDrainModeProcessesRemainingEvents() throws Exception {
// Add an event to the queue
AuditEventBase event = mock(AuditEventBase.class);
queue.queue.add(event);

// Set drain mode
queue.setDrain(true);

// Process the queue in drain mode
assertDoesNotThrow(() -> queue.runLogAudit());

// Event should be processed
verify(mockHandler).log(anyCollection());

// Consumer.stop should be called when exiting the loop
verify(mockHandler).stop();
}

@Test
void testRunLogAuditExitsWhenDrainMaxTimeElapsed() throws Exception {
// Create a spy to control isDrainMaxTimeElapsed behavior
AuditAsyncQueue queueSpy = spy(queue);

// Add an event to prevent immediate exit due to empty queue
AuditEventBase event = mock(AuditEventBase.class);
queueSpy.queue.add(event);

// Set drain mode
queueSpy.setDrain(true);

// Make isDrainMaxTimeElapsed return true after first event
when(queueSpy.isDrainMaxTimeElapsed())
.thenReturn(false) // First check after processing the event
.thenReturn(true); // Second check to break the loop

// Should exit the loop after processing one event
assertDoesNotThrow(() -> queueSpy.runLogAudit());

// Event should be processed
verify(mockHandler).log(anyCollection());
}

@Test
void testConsumerStopThrowsException() throws Exception {
// Setup consumer to throw exception when stop is called
doThrow(new RuntimeException("Stop error")).when(mockHandler).stop();

// Set drain mode to trigger exit
queue.setDrain(true);

// Should catch the exception from consumer.stop
assertDoesNotThrow(() -> queue.runLogAudit());

// Verify stop was called
verify(mockHandler).stop();
}

@Test
void testStartWithNullConsumer() {
// Create queue with null consumer
AuditAsyncQueue queueWithNullConsumer = new AuditAsyncQueue(null);

// Should not throw exception, but log error
assertDoesNotThrow(() -> queueWithNullConsumer.start());

// Thread should still be created
assertNotNull(queueWithNullConsumer.consumerThread);
assertTrue(queueWithNullConsumer.consumerThread.isAlive());

// Clean up
queueWithNullConsumer.stop();
}
}
Loading