Back to Repositories

Testing Service Registry Cleanup Integration in Apollo Config

This integration test suite validates the Apollo Service Registry cleanup functionality, focusing on the automatic removal of unhealthy service instances from the registry. The test ensures proper maintenance of service registry entries based on their health status and last modified timestamps.

Test Coverage Overview

The test suite provides comprehensive coverage of the service registry cleanup mechanism in Apollo.

  • Tests service instance cleanup based on health status
  • Validates retention of healthy service instances
  • Verifies proper filtering using timestamp-based queries
  • Covers multiple service registry entries with different health states

Implementation Analysis

The testing approach utilizes Spring’s test context framework with specific property configurations to simulate the service registry environment.

The implementation employs JUnit for test execution and leverages Spring’s dependency injection for accessing repository and runner components. The test demonstrates proper setup of test data with controlled timestamps and verification of cleanup operations.

Technical Details

  • Uses Spring Test Context framework with custom property sources
  • Implements AbstractIntegrationTest as the base class
  • Utilizes ServiceRegistryRepository for data operations
  • Configures test environment with specific service registry properties
  • Employs LocalDateTime for timestamp management
  • Uses JUnit assertions for result verification

Best Practices Demonstrated

The test exhibits several testing best practices for integration testing.

  • Clear test data setup and cleanup
  • Proper use of dependency injection
  • Explicit verification of system state before and after operations
  • Isolation of test environment through configuration
  • Meaningful assertions with specific failure messages

apolloconfig/apollo

apollo-biz/src/test/java/com/ctrip/framework/apollo/biz/registry/configuration/support/ApolloServiceRegistryClearApplicationRunnerIntegrationTest.java

            
/*
 * Copyright 2024 Apollo Authors
 *
 * Licensed 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 com.ctrip.framework.apollo.biz.registry.configuration.support;

import static org.junit.jupiter.api.Assertions.assertEquals;

import com.ctrip.framework.apollo.biz.AbstractIntegrationTest;
import com.ctrip.framework.apollo.biz.entity.ServiceRegistry;
import com.ctrip.framework.apollo.biz.registry.configuration.ApolloServiceDiscoveryAutoConfiguration;
import com.ctrip.framework.apollo.biz.registry.configuration.ApolloServiceRegistryAutoConfiguration;
import com.ctrip.framework.apollo.biz.repository.ServiceRegistryRepository;
import java.time.LocalDateTime;
import java.util.List;
import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.TestPropertySource;

@TestPropertySource(
    properties = {
        "apollo.service.registry.enabled=true",
        "apollo.service.registry.cluster=default",
        "apollo.service.discovery.enabled=true",
        "spring.application.name=for-test-service",
        "server.port=10000",
    }
)
@ContextConfiguration(classes = {
    ApolloServiceRegistryAutoConfiguration.class,
    ApolloServiceDiscoveryAutoConfiguration.class,
})
public class ApolloServiceRegistryClearApplicationRunnerIntegrationTest
    extends AbstractIntegrationTest {

  @Autowired
  private ServiceRegistryRepository repository;

  @Autowired
  private ApolloServiceRegistryClearApplicationRunner runner;

  @Test
  public void clearUnhealthyInstances() {
    final String serviceName = "h-service";

    final String healthUri = "http://10.240.11.22:8080/";
    ServiceRegistry healthy = new ServiceRegistry();
    healthy.setServiceName(serviceName);
    healthy.setCluster("c-1");
    healthy.setUri(healthUri);
    healthy.setDataChangeCreatedTime(LocalDateTime.now());
    healthy.setDataChangeLastModifiedTime(LocalDateTime.now());
    this.repository.save(healthy);

    LocalDateTime unhealthyTime = LocalDateTime.now().minusDays(2L);
    ServiceRegistry unhealthy = new ServiceRegistry();
    unhealthy.setServiceName("h-service");
    unhealthy.setCluster("c-2");
    unhealthy.setUri("http://10.240.33.44:9090/");
    unhealthy.setDataChangeCreatedTime(unhealthyTime);
    unhealthy.setDataChangeLastModifiedTime(unhealthyTime);
    this.repository.save(unhealthy);

    {
      List<ServiceRegistry> serviceRegistryList = this.repository.findByServiceNameAndDataChangeLastModifiedTimeGreaterThan(
          serviceName,
          LocalDateTime.now().minusDays(3L)
      );
      assertEquals(2, serviceRegistryList.size());
    }

    runner.clearUnhealthyInstances();

    {
      List<ServiceRegistry> serviceRegistryList = this.repository.findByServiceNameAndDataChangeLastModifiedTimeGreaterThan(
          serviceName,
          LocalDateTime.now().minusDays(3L)
      );
      assertEquals(1, serviceRegistryList.size());
      ServiceRegistry registry = serviceRegistryList.get(0);
      assertEquals(serviceName, registry.getServiceName());
      assertEquals(healthUri, registry.getUri());
    }
  }

}