Back to Repositories

Testing Kubernetes Service Discovery Implementation in Apollo Config

This test suite validates the Kubernetes service discovery functionality in Apollo, focusing on configuration and admin service instance retrieval. It ensures proper handling of service URLs and instance management in Kubernetes environments.

Test Coverage Overview

The test suite provides comprehensive coverage of the KubernetesDiscoveryService functionality.

  • Tests invalid service ID handling
  • Validates null configuration scenarios
  • Verifies config service instance retrieval
  • Tests admin service multi-instance handling
  • Covers URL parsing and instance creation logic

Implementation Analysis

The testing approach utilizes JUnit and Mockito frameworks for robust unit testing. Mock objects simulate BizConfig behavior, allowing controlled testing of URL configurations and service instance creation. The tests verify both single and multiple URL scenarios, ensuring proper ServiceDTO object creation and attribute mapping.

Technical Details

  • JUnit 4 test framework
  • Mockito for dependency mocking
  • MockitoJUnitRunner for test execution
  • BizConfig mock for configuration simulation
  • ServiceDTO objects for service instance representation

Best Practices Demonstrated

The test suite exemplifies several testing best practices in Java unit testing.

  • Proper test setup with @Before initialization
  • Clear test method naming conventions
  • Thorough edge case coverage
  • Effective use of mocking
  • Validation of both positive and negative scenarios

apolloconfig/apollo

apollo-configservice/src/test/java/com/ctrip/framework/apollo/metaservice/service/KubernetesDiscoveryServiceTest.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.metaservice.service;

import static org.junit.Assert.*;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

import com.ctrip.framework.apollo.biz.config.BizConfig;
import com.ctrip.framework.apollo.core.ServiceNameConsts;
import com.ctrip.framework.apollo.core.dto.ServiceDTO;
import java.util.List;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.junit.MockitoJUnitRunner;

@RunWith(MockitoJUnitRunner.class)
public class KubernetesDiscoveryServiceTest {

  private String configServiceConfigName = "apollo.config-service.url";
  private String adminServiceConfigName = "apollo.admin-service.url";

  @Mock
  private BizConfig bizConfig;

  private KubernetesDiscoveryService kubernetesDiscoveryService;

  @Before
  public void setUp() throws Exception {
    kubernetesDiscoveryService = new KubernetesDiscoveryService(bizConfig);
  }

  @Test
  public void testGetServiceInstancesWithInvalidServiceId() {
    String someInvalidServiceId = "someInvalidServiceId";

    assertTrue(kubernetesDiscoveryService.getServiceInstances(someInvalidServiceId).isEmpty());
  }

  @Test
  public void testGetServiceInstancesWithNullConfig() {
    when(bizConfig.getValue(configServiceConfigName)).thenReturn(null);

    assertTrue(
        kubernetesDiscoveryService.getServiceInstances(ServiceNameConsts.APOLLO_CONFIGSERVICE)
            .isEmpty());

    verify(bizConfig, times(1)).getValue(configServiceConfigName);
  }

  @Test
  public void testGetConfigServiceInstances() {
    String someUrl = "http://some-host/some-path";
    when(bizConfig.getValue(configServiceConfigName)).thenReturn(someUrl);

    List<ServiceDTO> serviceDTOList = kubernetesDiscoveryService
        .getServiceInstances(ServiceNameConsts.APOLLO_CONFIGSERVICE);

    assertEquals(1, serviceDTOList.size());
    ServiceDTO serviceDTO = serviceDTOList.get(0);

    assertEquals(ServiceNameConsts.APOLLO_CONFIGSERVICE, serviceDTO.getAppName());
    assertEquals(String.format("%s:%s", ServiceNameConsts.APOLLO_CONFIGSERVICE, someUrl),
        serviceDTO.getInstanceId());
    assertEquals(someUrl, serviceDTO.getHomepageUrl());
  }

  @Test
  public void testGetAdminServiceInstances() {
    String someUrl = "http://some-host/some-path";
    String anotherUrl = "http://another-host/another-path";
    when(bizConfig.getValue(adminServiceConfigName))
        .thenReturn(String.format("%s,%s", someUrl, anotherUrl));

    List<ServiceDTO> serviceDTOList = kubernetesDiscoveryService
        .getServiceInstances(ServiceNameConsts.APOLLO_ADMINSERVICE);

    assertEquals(2, serviceDTOList.size());
    ServiceDTO serviceDTO = serviceDTOList.get(0);

    assertEquals(ServiceNameConsts.APOLLO_ADMINSERVICE, serviceDTO.getAppName());
    assertEquals(String.format("%s:%s", ServiceNameConsts.APOLLO_ADMINSERVICE, someUrl),
        serviceDTO.getInstanceId());
    assertEquals(someUrl, serviceDTO.getHomepageUrl());

    ServiceDTO anotherServiceDTO = serviceDTOList.get(1);

    assertEquals(ServiceNameConsts.APOLLO_ADMINSERVICE, anotherServiceDTO.getAppName());
    assertEquals(String.format("%s:%s", ServiceNameConsts.APOLLO_ADMINSERVICE, anotherUrl),
        anotherServiceDTO.getInstanceId());
    assertEquals(anotherUrl, anotherServiceDTO.getHomepageUrl());

  }

}