Skip to content

Commit c0b48f9

Browse files
committed
test: add unit tests for log4j-iceberg with 100% line coverage
Covers all code paths in IcebergAppender and IcebergManager including: - Table creation, loading existing tables, idempotent startup - Event write, batch-triggered flush, empty flush, manual flush - Events with thrown exceptions, null messages - Commit retry on transient failure, crash after retry exhaustion - Parquet write failure, interrupted retry - Stop lifecycle (closeable catalog, IOException on close, null scheduler) - Builder setters and factory method JaCoCo enforces 100% line coverage at build time.
1 parent 874083d commit c0b48f9

2 files changed

Lines changed: 667 additions & 0 deletions

File tree

Lines changed: 149 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,149 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one or more
3+
* contributor license agreements. See the NOTICE file distributed with
4+
* this work for additional information regarding copyright ownership.
5+
* The ASF licenses this file to you under the Apache License, Version 2.0
6+
* (the "License"); you may not use this file except in compliance with
7+
* the License. You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
package org.apache.logging.log4j.iceberg;
18+
19+
import static org.assertj.core.api.Assertions.assertThat;
20+
21+
import java.io.File;
22+
import java.io.IOException;
23+
import java.nio.file.Files;
24+
import java.nio.file.Path;
25+
import java.util.Comparator;
26+
import java.util.concurrent.TimeUnit;
27+
import org.apache.iceberg.data.IcebergGenerics;
28+
import org.apache.iceberg.data.Record;
29+
import org.apache.iceberg.io.CloseableIterable;
30+
import org.apache.logging.log4j.Level;
31+
import org.apache.logging.log4j.core.LogEvent;
32+
import org.apache.logging.log4j.core.impl.Log4jLogEvent;
33+
import org.apache.logging.log4j.message.SimpleMessage;
34+
import org.junit.jupiter.api.AfterEach;
35+
import org.junit.jupiter.api.BeforeEach;
36+
import org.junit.jupiter.api.Test;
37+
38+
class IcebergAppenderTest {
39+
40+
private Path warehouseDir;
41+
private IcebergAppender appender;
42+
43+
@BeforeEach
44+
void setUp() throws IOException {
45+
warehouseDir = Files.createTempDirectory("iceberg-appender-test");
46+
}
47+
48+
@AfterEach
49+
void tearDown() throws IOException {
50+
if (appender != null && appender.isStarted()) {
51+
appender.stop(5, TimeUnit.SECONDS);
52+
}
53+
Files.walk(warehouseDir)
54+
.sorted(Comparator.reverseOrder())
55+
.map(Path::toFile)
56+
.forEach(File::delete);
57+
}
58+
59+
@SuppressWarnings("unchecked")
60+
private IcebergAppender buildAppender(final String tableName) {
61+
final IcebergAppender.Builder<? extends IcebergAppender.Builder<?>> builder = IcebergAppender.newBuilder();
62+
builder.setName("testAppender");
63+
builder.setCatalogName("test_catalog");
64+
builder.setCatalogImpl("hadoop");
65+
builder.setCatalogWarehouse(warehouseDir.toAbsolutePath().toString());
66+
builder.setTableNamespace("test_ns");
67+
builder.setTableName(tableName);
68+
builder.setBatchSize(100);
69+
builder.setFlushIntervalSeconds(3600);
70+
return builder.build();
71+
}
72+
73+
@Test
74+
void builderCreatesAppender() {
75+
appender = buildAppender("builder_test");
76+
assertThat(appender).isNotNull();
77+
assertThat(appender.getName()).isEqualTo("testAppender");
78+
}
79+
80+
@Test
81+
void startAndStop() {
82+
appender = buildAppender("start_stop");
83+
appender.start();
84+
assertThat(appender.isStarted()).isTrue();
85+
86+
assertThat(appender.stop(5, TimeUnit.SECONDS)).isTrue();
87+
assertThat(appender.isStopped()).isTrue();
88+
}
89+
90+
@Test
91+
void appendWritesEvents() throws IOException {
92+
appender = buildAppender("append_test");
93+
appender.start();
94+
95+
final LogEvent event = Log4jLogEvent.newBuilder()
96+
.setLoggerName("com.example.AppenderTest")
97+
.setLevel(Level.WARN)
98+
.setMessage(new SimpleMessage("appender test message"))
99+
.setThreadName("test-thread")
100+
.setTimeMillis(System.currentTimeMillis())
101+
.build();
102+
103+
appender.append(event);
104+
appender.stop(5, TimeUnit.SECONDS);
105+
106+
final IcebergManager reader = new IcebergManager(
107+
"reader",
108+
"test_catalog",
109+
"hadoop",
110+
null,
111+
warehouseDir.toAbsolutePath().toString(),
112+
"test_ns",
113+
"append_test",
114+
100,
115+
3600);
116+
reader.startup();
117+
reader.table.refresh();
118+
try (CloseableIterable<Record> records =
119+
IcebergGenerics.read(reader.table).build()) {
120+
int count = 0;
121+
for (final Record record : records) {
122+
assertThat(record.getField("level")).isEqualTo("WARN");
123+
assertThat(record.getField("message")).isEqualTo("appender test message");
124+
count++;
125+
}
126+
assertThat(count).isEqualTo(1);
127+
}
128+
reader.stop(5, TimeUnit.SECONDS);
129+
}
130+
131+
@Test
132+
void newBuilderFactory() {
133+
final IcebergAppender.Builder<?> builder = IcebergAppender.newBuilder();
134+
assertThat(builder).isNotNull();
135+
}
136+
137+
@Test
138+
void builderSettersReturnBuilder() {
139+
final IcebergAppender.Builder<?> builder = IcebergAppender.newBuilder();
140+
assertThat(builder.setCatalogName("c")).isSameAs(builder);
141+
assertThat(builder.setCatalogImpl("i")).isSameAs(builder);
142+
assertThat(builder.setCatalogUri("u")).isSameAs(builder);
143+
assertThat(builder.setCatalogWarehouse("w")).isSameAs(builder);
144+
assertThat(builder.setTableNamespace("n")).isSameAs(builder);
145+
assertThat(builder.setTableName("t")).isSameAs(builder);
146+
assertThat(builder.setBatchSize(10)).isSameAs(builder);
147+
assertThat(builder.setFlushIntervalSeconds(5)).isSameAs(builder);
148+
}
149+
}

0 commit comments

Comments
 (0)