Integration Tests
Integration tests validate how multiple components of the Ozone system work together. They are more comprehensive than unit tests but run in a more controlled environment than full acceptance tests.
Scope and Purpose
Integration tests serve a specific purpose in Ozone's testing strategy:
- Unit Tests: Test individual classes/methods in isolation with mocked dependencies
- Integration Tests: Test multiple components together within a JVM-based mini-cluster
- Acceptance Tests: Test a fully deployed Ozone system with actual Docker containers
Integration tests are ideal for validating:
- Component interactions (OM, SCM, Datanode)
- Client API behavior
- Data flow across components
- State transitions and recovery mechanisms
- Configuration changes
MiniOzoneCluster
The cornerstone of Ozone's integration testing is the MiniOzoneCluster
framework, which provides an in-memory Ozone cluster for testing.
Key Features
- Configurable components (OM, SCM, Datanodes, Recon)
- Support for HA configurations
- Ability to start/stop individual components
- Simulated failures and recovery testing
- Custom configuration options
Basic Usage
Here's how to create and use a MiniOzoneCluster:
@Rule
public TemporaryFolder folder = new TemporaryFolder();
private MiniOzoneCluster cluster;
private OzoneClient client;
@Before
public void setup() throws Exception {
MiniOzoneCluster.Builder builder = MiniOzoneCluster.newBuilder()
.setNumDatanodes(3)
.setTotalPipelineNumFactors(1)
.setConf(new OzoneConfiguration());
cluster = builder.build();
cluster.waitForClusterToBeReady();
client = cluster.newClient();
}
@After
public void tearDown() {
if (client != null) {
client.close();
}
if (cluster != null) {
cluster.shutdown();
}
}
@Test
public void testCreateVolume() throws Exception {
ObjectStore objectStore = client.getObjectStore();
objectStore.createVolume("test-volume");
OzoneVolume volume = objectStore.getVolume("test-volume");
assertEquals("test-volume", volume.getName());
}
HA Configuration
For testing HA scenarios:
MiniOzoneCluster.Builder builder = MiniOzoneCluster.newBuilder()
.setNumDatanodes(3)
.setTotalPipelineNumFactors(1)
.setOMServiceId("om-service-test1")
.setNumOfOzoneManagers(3)
.setConf(conf);
Project Structure
Integration tests are organized in a dedicated module: hadoop-ozone/integration-test
.
This separation provides several benefits:
- Clean Dependency Management: Integration tests often require dependencies that aren't needed for runtime
- Separate Compilation: Keeps build times manageable by separating integration tests
- Targeted Execution: Makes it easier to run only integration tests or skip them
The module is structured as follows:
hadoop-ozone/integration-test/
├── src/
│ └── test/
│ ├── java/
│ │ └── org/apache/hadoop/ozone/
│ │ ├── client/ # Client API tests
│ │ ├── container/ # Container-related tests
│ │ ├── om/ # Ozone Manager tests
│ │ ├── scm/ # Storage Container Manager tests
│ │ └── ...
│ └── resources/ # Test configurations
└── pom.xml # Module dependencies
Running Integration Tests
Integration tests can be run using Maven:
# Run all integration tests
cd hadoop-ozone
mvn verify -DskipUnitTests
# Run a specific test class
mvn verify -DskipUnitTests -Dit.test=TestOzoneManagerHA
# Run with a specific profile
mvn verify -P integration
Test Categories
Integration tests cover several areas:
- Component Tests: Test specific components like OM, SCM, or Datanode
- Client API Tests: Test client interfaces (e.g., Object Store, S3)
- Feature Tests: Test specific features (e.g., encryption, replication)
- Failure Tests: Test behavior during component failures
- Upgrade Tests: Test version compatibility and upgrade procedures
Best Practices
- Use appropriate test category: Choose between unit, integration, and acceptance tests based on what you're testing
- Minimize test time: Keep integration tests as focused as possible
- Clean up resources: Ensure all resources are properly closed in
@After
methods - Avoid network dependencies: Tests should not depend on external systems
- Use randomized ports: Avoid hardcoding ports to allow parallel test execution