Я пытаюсь создать рабочий процесс в GitHub Actions, который запускает мои интеграционные тесты в моем весеннем загрузочном проекте, написанном на kotlin, упакованном с помощью gradle и использующем базу данных mysql. Я продолжаю получать эту ошибку при достижении этапа сборки и тестирования, а также при каждом запуске теста ./gradlew clean build:
Caused by: java.lang.IllegalStateException at DefaultCacheAwareContextLoaderDelegate.java:98
Caused by: org.springframework.beans.factory.BeanCreationException at AbstractAutowireCapableBeanFactory.java:1804
Caused by: javax.persistence.PersistenceException at AbstractEntityManagerFactoryBean.java:421
Caused by: org.hibernate.exception.JDBCConnectionException at SQLStateConversionDelegate.java:112
Caused by: com.mysql.cj.jdbc.exceptions.CommunicationsException at SQLError.java:174
Caused by: com.mysql.cj.exceptions.CJCommunicationsException at NativeConstructorAccessorImpl.java:-2
Caused by: java.net.ConnectException at PlainSocketImpl.java:-2
Вот мой gradle.yml:
name: CI with Gradle
on: [push]
permissions:
contents: read
jobs:
build:
runs-on: ubuntu-latest
container: openjdk:11
services:
mysql:
image: mysql:latest
steps:
- uses: actions/checkout@v3
- name: Set up JDK 11
uses: actions/setup-java@v3
with:
java-version: '11'
distribution: 'temurin'
- name: Grant execute permission for gradlew
run: chmod +x gradlew
- name: Build & Test with Gradle
uses: gradle/gradle-build-action@v2
with:
arguments: build
Вот мой application.properties:
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/wct?useSSL=true&serverTimezone=UTC
spring.datasource.username=root
spring.datasource.password=pw
spring.jpa.hibernate.ddl-auto=update
spring.jpa.database=mysql
server.port=8081
И вот пример одного из всех моих тестов JUnit, которые терпят неудачу:
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
internal class CustomerControllerTests(
@Autowired val context: WebApplicationContext,
@Autowired val mapper: ObjectMapper,
@Autowired val customerRepository: CustomerRepository,
) {
private val mvc: MockMvc = (MockMvcBuilders.webAppContextSetup(context).apply<DefaultMockMvcBuilder>(
SecurityMockMvcConfigurers.springSecurity()).build())
@Test
fun `GET customers should return an empty list of customers and 200 OK if one of the required roles is provided`() {
val response = mvc.perform(
MockMvcRequestBuilders.get("/customers")
.contentType(MediaType.APPLICATION_JSON)
).andExpect(MockMvcResultMatchers.status().isOk).andReturn().response
response.contentLength shouldBe 0
}
}
Что я здесь делаю неправильно/упускаю?






Я вижу как минимум четыре проблемы в вашей настройке:
Вы используете localhost:3306 в качестве <hostname>:<port> в URL-адресе подключения (spring.datasource.url), но в соответствии с документами GitHub Actions:
Когда вы запускаете задания в контейнере, GitHub подключает сервисные контейнеры к заданию, используя определяемые пользователем мостовые сети Docker.
Запуск задания и служб в контейнере упрощает доступ к сети. Вы можете получить доступ к сервисному контейнеру, используя метку, настроенную в рабочем процессе. Имя хоста сервисного контейнера автоматически сопоставляется с именем метки.
Итак, в вашем случае свойство url для теста должно выглядеть так:
spring.datasource.url=jdbc:mysql://mysql:3306/wct?useSSL=true&serverTimezone=UTC
Согласно Официальной странице образа Docker MySql и многочисленным примерам с настройкой GitHub Actions MySql, вы должны указать хотя бы одну обязательную переменную env, а именно MYSQL_ROOT_PASSWORD:
Эта переменная является обязательной и указывает пароль, который будет установлен для учетной записи root суперпользователя MySQL.
В вашем случае это будет следующим образом (в блоке env службы mysql):
MYSQL_ROOT_PASSWORD: pw
Насколько я вижу из строки подключения, вы пытаетесь подключиться к базе данных wct, но я не вижу, чтобы эта база данных создавалась в вашей конфигурации. Для этого вам нужно будет использовать переменную env MYSQL_DATABASE, как указано на официальной странице образа Docker MySql. В вашем блоке env это будет выглядеть так:
MYSQL_DATABASE: wct
Согласно Официальному примеру GitHub Actions Postgres вам лучше подождать, пока ваш экземпляр MySql не будет готов обслуживать запросы. Это можно сделать следующим образом:
services:
mysql:
options: >-
--health-cmd mysqladmin ping
--health-interval 10s
--health-timeout 5s
--health-retries 5
Итак, учитывая, что вы используете пользователя root в тестах (согласно вашему коду), ваша окончательная «gradle.yml» часть mysql будет выглядеть так:
services:
mysql:
image: mysql:latest
env:
MYSQL_DATABASE: wct
MYSQL_ROOT_PASSWORD: pw
options: >-
--health-cmd mysqladmin ping
--health-interval 10s
--health-timeout 5s
--health-retries 5
И не забудьте исправить spring.datasource.url, как указано в первой проблеме «Неверный URL-адрес источника данных» выше.
Кроме того, я считаю, что он должен охватывать все или, по крайней мере, основные проблемы в вашей конфигурации. Но я не удивлюсь, если в этом ответе не будут освещены некоторые незначительные ошибки неправильной конфигурации. Вы могли бы сообщить мне, как это происходит.
@JohnAdams ах, верно. Этот mysqladmin ping не установлен в образе mysql. На самом деле, это может не понадобиться, если приложение настроено на это. Кроме того, официальная документация mysql docker может привести вас к этому примеру без использования каких-либо дополнительных пакетов.
Спасибо, изменена конфигурация конвейера, чтобы включить все необходимое для настройки mysql, возникла проблема только с № 4, я получил ошибку
Error response from daemon: pull access denied for ping. Но после удаления этих параметров контейнер запускается, а проект создает и запускает свои тесты.