Revnic Robert-Nick
Revnic Robert-Nick

Reputation: 627

UnknownHostException for embedded Mongo DB tests in Jenkins build

I have a Spring Boot REST service and some unit tests written for the data layer. I use the embedded MongoDB dependency to perform the basic CRUD tests for my Repository class:

public interface UserRepository extends MongoRepository<UserEntity, String> {
    Optional<UserEntity> findByUsername(String username);
}

I load the data from a JSON file (located under test/java/resources/data) and with the help of an ObjectMapper instance, I load the data into the embedded DB before each test and drop the collection after it's completed:

@DataMongoTest
class UserRepositoryTest {

    // the path to the JSON file
    private final File USER_DATA_JSON = Paths.get("src", "test", "resources", "data", "UserData.json").toFile();

    // used to load a JSON file into a list of Users
    private final ObjectMapper objectMapper = new ObjectMapper();

    @Autowired
    private MongoTemplate mongoTemplate; // makes the interaction with the embedded MongoDB much easier

    @Autowired
    private UserRepository userRepository;

    @BeforeEach
    void setUp() throws IOException {
        // deserialize the JSON file to an array of users
        UserEntity[] users = objectMapper.readValue(USER_DATA_JSON, UserEntity[].class);

        // load each user into embedded MongoDB
        Arrays.stream(users).forEach(mongoTemplate::save);
    }

    @AfterEach
    void tearDown() {
        // drop the users collection
        mongoTemplate.dropCollection("users");
    }

    @Test
    void testFindAllSuccess() {
        // WHEN
        List<UserEntity> users = userRepository.findAll();

        // THEN
        assertEquals(2, users.size(), "findAll() should return 2 users!");
    }

    // other test methods
}

In my local environment, everything works just fine, no configuration is needed inside the application.properties file. But when I execute a build on Jenkins, the following error appears for all the Repository tests:

UserRepositoryTest > testFindAllSuccess() FAILED
java.lang.IllegalStateException at DefaultCacheAwareContextLoaderDelegate.java:132
    Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException at ConstructorResolver.java:800
        Caused by: org.springframework.beans.factory.BeanCreationException at ConstructorResolver.java:658
            Caused by: org.springframework.beans.BeanInstantiationException at SimpleInstantiationStrategy.java:185
                Caused by: java.net.UnknownHostException at InetAddress.java:1642
                    Caused by: java.net.UnknownHostException at Inet6AddressImpl.java:-2

The build.gradle file dependencies are declared as follows:

implementation 'org.openapitools:openapi-generator-gradle-plugin:5.0.0'
implementation 'org.springframework.boot:spring-boot-starter'
implementation 'org.springframework.boot:spring-boot-starter-data-mongodb'
implementation 'org.springframework.boot:spring-boot-starter-web'
implementation "io.springfox:springfox-boot-starter:3.0.0"
implementation('org.modelmapper:modelmapper:2.3.0')
testImplementation 'org.springframework.boot:spring-boot-starter-test'
testImplementation 'de.flapdoodle.embed:de.flapdoodle.embed.mongo'
testImplementation 'io.projectreactor:reactor-test'
compile 'io.springfox:springfox-swagger-ui:3.0.0'
annotationProcessor group: 'org.springframework.boot', name: 'spring-boot-configuration-processor'
compile 'org.mongodb:mongodb-driver-sync'
implementation 'org.springframework.boot:spring-boot-starter-security'
implementation 'org.springframework.security:spring-security-test'
// https://mvnrepository.com/artifact/io.jsonwebtoken/jjwt
implementation group: 'io.jsonwebtoken', name: 'jjwt', version: '0.9.1'

I assume Spring Boot is not identifying the embedded MongoDB anymore. How can I configure it as simple as possible?

I saw there is a possibility of using containerized MongoDB and test it using @TestContainers, but for now I need to fix this issue since every build fails due to the tests.

LATER EDIT: By activating the --debug option in Jenkins when running the build, I discovered the following cause:

java.net.UnknownHostException: dev096.dev.cloud.******.eu: dev096.dev.cloud.******.eu: Name or service not known

Do you know if I have to add that address to the known hosts to my local machine (etc/hosts) or it should be configured locally with profiles (localhost for development and dev096.dev.cloud.******.eu for production)?

Upvotes: 4

Views: 1651

Answers (3)

Revnic Robert-Nick
Revnic Robert-Nick

Reputation: 627

Unfortunately, none of your solutions worked for me, but I found out later that dev096.dev.cloud.******.eu is the Jenkins instance itself.

The fix was to add an entry in /etc/hosts/ such that the server's IP to be also recognized as dev096.dev.cloud.******.eu

Upvotes: 1

Andy Valerio
Andy Valerio

Reputation: 861

I managed to reproduce the same error locally and, if you haven't solved it yet, this is my take.

Remove all MongoDB custom configurations/properties, then add the following class to your project:

@Configuration
public class MongoTestConfig {

    @Bean
    MongoProperties properties() {
        MongoProperties mongoProperties = new MongoProperties();
        mongoProperties.setPort(33333);
        mongoProperties.setHost("localhost");
        return mongoProperties;
    }
}

Make sure you tag your test class (UserRepositoryTest) with these three annotations:

@RunWith(SpringRunner.class)
@DataMongoTest
@Import(MongoTestConfig.class)

@DataMongoTest ignores all other bean definitions so we force the test to include the configuration that we just created using the explicit @Import.

Now the test will be forced to run on localhost. Hope it's going to work for you as it did for me! 😁

Upvotes: 3

Simon
Simon

Reputation: 3264

If dev096.dev.cloud.******.eu is a host used only in production, then your production server needs to know that host; not your local PC, nor Jenkins.

Ideally, you'd run your Jenkins tests using a 'jenkins' Spring profile, and then define the localhost in application-jenkins.properties.

Upvotes: 2

Related Questions