Skip to content

Commit 5677abe

Browse files
authored
feat(docs): generating test index (#3052)
Signed-off-by: Attila Mészáros <a_meszaros@apple.com>
1 parent 680cfd7 commit 5677abe

File tree

110 files changed

+1316
-0
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

110 files changed

+1316
-0
lines changed

.github/workflows/hugo.yaml

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,16 @@ jobs:
4545
with:
4646
submodules: recursive
4747
fetch-depth: 0
48+
- name: Set up JDK 17
49+
uses: actions/setup-java@v4
50+
with:
51+
java-version: '17'
52+
distribution: 'temurin'
53+
cache: maven
54+
- name: Build test-index-processor and generate test documentation
55+
run: |
56+
./mvnw clean install -DskipTests -pl test-index-processor
57+
./mvnw process-test-classes -DskipTests -pl operator-framework
4858
- name: Setup Pages
4959
id: pages
5060
uses: actions/configure-pages@v5

operator-framework/pom.xml

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,13 @@
8484
<artifactId>kube-api-test-client-inject</artifactId>
8585
<scope>test</scope>
8686
</dependency>
87+
<dependency>
88+
<groupId>io.javaoperatorsdk</groupId>
89+
<artifactId>test-index-processor</artifactId>
90+
<version>${project.version}</version>
91+
<scope>test</scope>
92+
<optional>true</optional>
93+
</dependency>
8794
</dependencies>
8895

8996
<build>
@@ -106,6 +113,23 @@
106113
</compilerArgs>
107114
</configuration>
108115
</execution>
116+
<!-- Enable annotation processing for test compilation to generate samples.md -->
117+
<execution>
118+
<id>default-testCompile</id>
119+
<goals>
120+
<goal>testCompile</goal>
121+
</goals>
122+
<phase>test-compile</phase>
123+
<configuration>
124+
<annotationProcessorPaths>
125+
<path>
126+
<groupId>io.javaoperatorsdk</groupId>
127+
<artifactId>test-index-processor</artifactId>
128+
<version>${project.version}</version>
129+
</path>
130+
</annotationProcessorPaths>
131+
</configuration>
132+
</execution>
109133
</executions>
110134
</plugin>
111135
<plugin>
@@ -138,6 +162,50 @@
138162
<groupId>org.apache.maven.plugins</groupId>
139163
<artifactId>maven-surefire-plugin</artifactId>
140164
</plugin>
165+
<plugin>
166+
<groupId>org.apache.maven.plugins</groupId>
167+
<artifactId>maven-resources-plugin</artifactId>
168+
<executions>
169+
<execution>
170+
<id>copy-samples-to-docs</id>
171+
<goals>
172+
<goal>copy-resources</goal>
173+
</goals>
174+
<phase>process-test-classes</phase>
175+
<configuration>
176+
<outputDirectory>${project.basedir}/../docs/content/en/docs/testindex</outputDirectory>
177+
<resources>
178+
<resource>
179+
<directory>${project.build.directory}/generated-test-sources/test-annotations</directory>
180+
<includes>
181+
<include>samples.md</include>
182+
</includes>
183+
<filtering>false</filtering>
184+
</resource>
185+
</resources>
186+
</configuration>
187+
</execution>
188+
</executions>
189+
</plugin>
190+
<plugin>
191+
<groupId>org.apache.maven.plugins</groupId>
192+
<artifactId>maven-antrun-plugin</artifactId>
193+
<version>3.1.0</version>
194+
<executions>
195+
<execution>
196+
<id>rename-samples-to-index</id>
197+
<goals>
198+
<goal>run</goal>
199+
</goals>
200+
<phase>process-test-classes</phase>
201+
<configuration>
202+
<target>
203+
<move failonerror="false" file="${project.basedir}/../docs/content/en/docs/testindex/samples.md" tofile="${project.basedir}/../docs/content/en/docs/testindex/_index.md"/>
204+
</target>
205+
</configuration>
206+
</execution>
207+
</executions>
208+
</plugin>
141209
</plugins>
142210
</build>
143211
</project>

operator-framework/src/test/java/io/javaoperatorsdk/operator/CRDMappingInTestExtensionIT.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
import io.fabric8.kubernetes.model.annotation.Group;
1313
import io.fabric8.kubernetes.model.annotation.Kind;
1414
import io.fabric8.kubernetes.model.annotation.Version;
15+
import io.javaoperatorsdk.annotation.Sample;
1516
import io.javaoperatorsdk.operator.api.reconciler.Context;
1617
import io.javaoperatorsdk.operator.api.reconciler.ControllerConfiguration;
1718
import io.javaoperatorsdk.operator.api.reconciler.Reconciler;
@@ -21,6 +22,15 @@
2122
import static org.assertj.core.api.Assertions.assertThat;
2223
import static org.awaitility.Awaitility.await;
2324

25+
@Sample(
26+
tldr = "Custom CRD Mapping in Test Extension",
27+
description =
28+
"""
29+
Demonstrates how to manually specify and apply Custom Resource Definitions (CRDs) in \
30+
integration tests using the LocallyRunOperatorExtension. This test verifies that CRDs \
31+
can be loaded from specified file paths and properly registered with the Kubernetes API \
32+
server during test execution.
33+
""")
2434
public class CRDMappingInTestExtensionIT {
2535
private final KubernetesClient client = new KubernetesClientBuilder().build();
2636

operator-framework/src/test/java/io/javaoperatorsdk/operator/baseapi/ConcurrencyIT.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
import org.slf4j.LoggerFactory;
1111

1212
import io.fabric8.kubernetes.api.model.ConfigMap;
13+
import io.javaoperatorsdk.annotation.Sample;
1314
import io.javaoperatorsdk.operator.baseapi.simple.TestCustomResource;
1415
import io.javaoperatorsdk.operator.baseapi.simple.TestReconciler;
1516
import io.javaoperatorsdk.operator.junit.LocallyRunOperatorExtension;
@@ -18,6 +19,15 @@
1819
import static org.assertj.core.api.Assertions.assertThat;
1920
import static org.awaitility.Awaitility.await;
2021

22+
@Sample(
23+
tldr = "Concurrent Reconciliation of Multiple Resources",
24+
description =
25+
"""
26+
Demonstrates the operator's ability to handle concurrent reconciliation of multiple \
27+
resources. The test creates, updates, and deletes many resources simultaneously to \
28+
verify proper handling of concurrent operations, ensuring thread safety and correct \
29+
resource state management under load.
30+
""")
2131
class ConcurrencyIT {
2232
public static final int NUMBER_OF_RESOURCES_CREATED = 50;
2333
public static final int NUMBER_OF_RESOURCES_DELETED = 30;

operator-framework/src/test/java/io/javaoperatorsdk/operator/baseapi/InformerErrorHandlerStartIT.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,22 @@
99
import io.fabric8.kubernetes.client.ConfigBuilder;
1010
import io.fabric8.kubernetes.client.KubernetesClient;
1111
import io.fabric8.kubernetes.client.KubernetesClientBuilder;
12+
import io.javaoperatorsdk.annotation.Sample;
1213
import io.javaoperatorsdk.operator.Operator;
1314
import io.javaoperatorsdk.operator.api.reconciler.Context;
1415
import io.javaoperatorsdk.operator.api.reconciler.ControllerConfiguration;
1516
import io.javaoperatorsdk.operator.api.reconciler.Reconciler;
1617
import io.javaoperatorsdk.operator.api.reconciler.UpdateControl;
1718

19+
@Sample(
20+
tldr = "Operator Startup with Informer Errors",
21+
description =
22+
"""
23+
Demonstrates that the operator can start successfully even when informers encounter \
24+
errors during startup, such as insufficient access rights. By setting \
25+
stopOnInformerErrorDuringStartup to false, the operator gracefully handles permission \
26+
errors and continues initialization, allowing it to operate with partial access.
27+
""")
1828
class InformerErrorHandlerStartIT {
1929
/** Test showcases that the operator starts even if there is no access right for some resource. */
2030
@Test

operator-framework/src/test/java/io/javaoperatorsdk/operator/baseapi/LeaderElectionPermissionIT.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
import io.fabric8.kubernetes.client.ConfigBuilder;
99
import io.fabric8.kubernetes.client.KubernetesClient;
1010
import io.fabric8.kubernetes.client.KubernetesClientBuilder;
11+
import io.javaoperatorsdk.annotation.Sample;
1112
import io.javaoperatorsdk.operator.Operator;
1213
import io.javaoperatorsdk.operator.OperatorException;
1314
import io.javaoperatorsdk.operator.ReconcilerUtils;
@@ -21,6 +22,15 @@
2122
import static org.assertj.core.api.Assertions.assertThat;
2223
import static org.junit.jupiter.api.Assertions.assertThrows;
2324

25+
@Sample(
26+
tldr = "Leader Election with Insufficient Permissions",
27+
description =
28+
"""
29+
Verifies that the operator fails gracefully when leader election is configured but \
30+
the service account lacks permissions to access lease resources. This test ensures \
31+
proper error handling and messaging when RBAC permissions are insufficient for \
32+
leader election functionality.
33+
""")
2434
class LeaderElectionPermissionIT {
2535

2636
KubernetesClient adminClient = new KubernetesClientBuilder().build();

operator-framework/src/test/java/io/javaoperatorsdk/operator/baseapi/builtinresourcecleaner/BuiltInResourceCleanerIT.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,23 @@
88
import org.slf4j.LoggerFactory;
99

1010
import io.fabric8.kubernetes.api.model.Service;
11+
import io.javaoperatorsdk.annotation.Sample;
1112
import io.javaoperatorsdk.operator.ReconcilerUtils;
1213
import io.javaoperatorsdk.operator.dependent.standalonedependent.StandaloneDependentResourceIT;
1314
import io.javaoperatorsdk.operator.junit.LocallyRunOperatorExtension;
1415

1516
import static org.assertj.core.api.Assertions.assertThat;
1617
import static org.awaitility.Awaitility.await;
1718

19+
@Sample(
20+
tldr = "Cleanup handler for built-in Kubernetes resources",
21+
description =
22+
"""
23+
Demonstrates how to implement cleanup handlers (finalizers) for built-in Kubernetes \
24+
resources like Service and Pod. These resources don't use generation the same way \
25+
as custom resources, so this sample shows the proper approach to handle their \
26+
lifecycle and cleanup logic.
27+
""")
1828
class BuiltInResourceCleanerIT {
1929

2030
private static final Logger log = LoggerFactory.getLogger(BuiltInResourceCleanerIT.class);

operator-framework/src/test/java/io/javaoperatorsdk/operator/baseapi/changenamespace/ChangeNamespaceIT.java

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,13 +14,24 @@
1414
import io.fabric8.kubernetes.api.model.NamespaceBuilder;
1515
import io.fabric8.kubernetes.api.model.ObjectMetaBuilder;
1616
import io.fabric8.kubernetes.client.KubernetesClient;
17+
import io.javaoperatorsdk.annotation.Sample;
1718
import io.javaoperatorsdk.operator.RegisteredController;
1819
import io.javaoperatorsdk.operator.api.reconciler.Constants;
1920
import io.javaoperatorsdk.operator.junit.LocallyRunOperatorExtension;
2021

2122
import static org.assertj.core.api.Assertions.assertThat;
2223
import static org.awaitility.Awaitility.await;
2324

25+
@Sample(
26+
tldr = "Dynamically Changing Watched Namespaces",
27+
description =
28+
"""
29+
Demonstrates how to dynamically change the set of namespaces that an operator watches at \
30+
runtime. This feature allows operators to add or remove namespaces from their watch \
31+
list, including switching between specific namespaces and watching all namespaces. \
32+
The test verifies that resources in newly added namespaces are reconciled and \
33+
resources in removed namespaces are no longer watched.
34+
""")
2435
class ChangeNamespaceIT {
2536

2637
public static final String TEST_RESOURCE_NAME_1 = "test1";

operator-framework/src/test/java/io/javaoperatorsdk/operator/baseapi/cleanerforreconciler/CleanerForReconcilerIT.java

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,23 @@
44
import org.junit.jupiter.api.extension.RegisterExtension;
55

66
import io.fabric8.kubernetes.api.model.ObjectMeta;
7+
import io.javaoperatorsdk.annotation.Sample;
78
import io.javaoperatorsdk.operator.junit.LocallyRunOperatorExtension;
89

910
import static org.assertj.core.api.Assertions.assertThat;
1011
import static org.awaitility.Awaitility.await;
1112

13+
@Sample(
14+
tldr = "Implementing Cleanup Logic with Cleaner Interface",
15+
description =
16+
"""
17+
Demonstrates how to implement cleanup logic for custom resources using the Cleaner \
18+
interface. When a reconciler implements Cleaner, the framework automatically adds a \
19+
finalizer to resources and calls the cleanup method when the resource is deleted. \
20+
This pattern is useful for cleaning up external resources or performing custom \
21+
deletion logic. The test verifies finalizer handling, cleanup execution, and the \
22+
ability to reschedule cleanup operations.
23+
""")
1224
class CleanerForReconcilerIT {
1325

1426
public static final String TEST_RESOURCE_NAME = "cleaner-for-reconciler-test1";

operator-framework/src/test/java/io/javaoperatorsdk/operator/baseapi/cleanupconflict/CleanupConflictIT.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,21 @@
66
import org.junit.jupiter.api.extension.RegisterExtension;
77

88
import io.fabric8.kubernetes.api.model.ObjectMeta;
9+
import io.javaoperatorsdk.annotation.Sample;
910
import io.javaoperatorsdk.operator.junit.LocallyRunOperatorExtension;
1011

1112
import static io.javaoperatorsdk.operator.baseapi.cleanupconflict.CleanupConflictReconciler.WAIT_TIME;
1213
import static org.assertj.core.api.Assertions.assertThat;
1314
import static org.awaitility.Awaitility.await;
1415

16+
@Sample(
17+
tldr = "Cleanup Finalizer Removal Without Conflicts",
18+
description =
19+
"""
20+
Tests that finalizers are removed correctly during cleanup without causing conflicts, \
21+
even when multiple finalizers are present and removed concurrently. This verifies the \
22+
operator's ability to handle finalizer updates safely during resource deletion.
23+
""")
1524
class CleanupConflictIT {
1625

1726
private static final String ADDITIONAL_FINALIZER = "javaoperatorsdk.io/additionalfinalizer";

0 commit comments

Comments
 (0)