Ошибка CTest в MacOS: Исполняемый файл теста не найден

Я работаю над проектом CMake. Для CI я решил использовать Azure Pipelines. Однако я столкнулся с небольшой проблемой на MacOS на этапе тестирования. Проблема в том, что MacOS не может найти тестовый исполняемый файл, даже если он там есть.

Раньше мой проект не развивался должным образом. Но теперь весь конвейер работает успешно (спасибо сообществу Stack Overflow), за исключением небольшого сбоя в MacOS. Я обновил свой вопрос, и теперь в нем рассказывается, в чем была проблема и как я ее исправил, чтобы он мог быть полезен другим, таким как я, новичкам в мире CI.

Изменить 1:

Раньше моя задача CMake не запускала процесс сборки. Это произошло потому, что я не предоставлял никаких аргументов командной строки для CMake. Все, что я сделал, было это:

- task: CMake@1
  displayName: Generate CMake Cache
  inputs:
    workingDirectory: build

Я предполагал, что задача CMake будет управлять процессом сборки автоматически, поскольку в документации не было четко указано, что эта задача на самом деле делает. Это ничего не делало, кроме печати использования CMake. Затем я обнаружил, что нам нужно запустить задачу CMake дважды (один раз для конфигурации проекта, а затем для фактической сборки), используя соответствующие аргументы командной строки.

Изменить 2:

Это мой обновленный файл AzurePipelines.yml.

Контурная конфигурация Azure Pipelines

stages:
- stage: Build
  displayName: Build

  jobs:
  - job: RunCMakeTask
    displayName: Run CMake Task

    strategy:
      matrix:
        LinuxDebug:
          OS: 'Linux'
          imageName: 'ubuntu-latest'
          BuildConfiguration: 'Debug'
        LinuxRelease:
          OS: 'Linux'
          imageName: 'ubuntu-latest'
          BuildConfiguration: 'RelWithDebInfo'
        MacOSDebug:
          OS: 'MacOS'
          imageName: 'macos-latest'
          BuildConfiguration: 'Debug'
        MacOSRelease:
          OS: 'MacOS'
          imageName: 'macos-latest'
          BuildConfiguration: 'RelWithDebInfo'
        WindowsDebug:
          OS: 'Windows'
          imageName: 'windows-latest'
          BuildConfiguration: 'Debug'
        WindowsRelease:
          OS: 'Windows'
          imageName: 'windows-latest'
          BuildConfiguration: 'RelWithDebInfo'

    pool:
      vmImage: $(imageName)

    steps:
    - script: mkdir $(BuildConfiguration)
      displayName: Create Build Directory
      workingDirectory: $(Build.SourcesDirectory)
    - task: CMake@1
      displayName: Generate CMake Cache
      inputs:
        workingDirectory: $(BuildConfiguration)
        cmakeArgs: '-DCMAKE_BUILD_TYPE=$(BuildConfiguration) ..'
    - task: CMake@1
      displayName: Run Build Process
      inputs:
        workingDirectory: $(BuildConfiguration)
        cmakeArgs: '--build . --config $(BuildConfiguration)'
    - task: PublishPipelineArtifact@1
      displayName: Publish Build Artifact
      inputs:
        targetPath: $(BuildConfiguration)
        artifactName: '$(OS)$(BuildConfiguration)'
    
- stage: Test   
  displayName: Test
  dependsOn: Build

  jobs:
  - job: RunCTestOnWindows
    displayName: Run CTest on Windows

    variables:
      OS: Windows

    strategy:
      matrix:
        Debug:
          BuildConfiguration: 'Debug'
        Release:
          BuildConfiguration: 'RelWithDebInfo'

    pool:
      vmImage: 'windows-latest'

    steps:
    - task: DownloadPipelineArtifact@2
      displayName: Download Build Artifact
      inputs:
        artifact: '$(OS)$(BuildConfiguration)'
        path: $(Build.SourcesDirectory)/$(BuildConfiguration)
    - script: ctest -C $(BuildConfiguration) --output-on-failure
      workingDirectory: $(BuildConfiguration)
      
  - job: RunCTestOnUnixBasedSystems
    displayName: Run CTest on Unix Based Systems

    strategy:
      matrix:
        LinuxDebug:
          OS: 'Linux'
          imageName: 'ubuntu-latest'
          BuildConfiguration: 'Debug'
        LinuxRelease:
          OS: 'Linux'
          imageName: 'ubuntu-latest'
          BuildConfiguration: 'RelWithDebInfo'
        MacOSDebug:
          OS: 'MacOS'
          imageName: 'macos-latest'
          BuildConfiguration: 'Debug'
        MacOSRelease:
          OS: 'MacOS'
          imageName: 'macos-latest'
          BuildConfiguration: 'RelWithDebInfo'

    steps:
    - task: DownloadPipelineArtifact@2
      displayName: Download Build Artifact
      inputs:
        artifact: '$(OS)$(BuildConfiguration)'
        path: $(Build.SourcesDirectory)/$(BuildConfiguration)
    - script: find $(BuildConfiguration)/Tests -type f -name "Test*" ! -name "*.*" ! -exec chmod u+rx {} \;
      displayName: Change File Permissions
    - script: ctest -C $(BuildConfiguration) --output-on-failure
      workingDirectory: $(BuildConfiguration)

Конвейер работает нормально в Windows и Linux, но я столкнулся с небольшой проблемой в MacOS. В MacOS ctest не удается найти тестовый исполняемый файл, даже если он существует. (Если в моем конвейере или в моем файле CMakeLists.txt возникла проблема, она также должна была выйти из строя в Windows и Linux)

Изменить 3:

И на этапе тестирования в MacOS я получаю сообщение об ошибке:

Тестовый проект / home / vsts / work / 1 / s / Debug Start 1: StringOperations_CaseIgnore Не удалось найти исполняемый файл / Users / runner / work / 1 / s / Debug / Tests / StringOperations / TestStringOperations Поискался в следующих местах: / Users / runner / work / 1 / s / Debug / Tests / StringOperations / TestStringOperations / Users / runner / work / 1 / s / Debug / Tests / StringOperations / TestStringOperations / Users / runner / work / 1 / s / Debug / Tests / StringOperations / Debug / TestStringOperations / Users / runner / work / 1 / s / Debug / Tests / StringOperations / Debug / TestStringOperations Debug // Users / runner / work / 1 / s / Debug / Tests / StringOperations / TestStringOperations Debug // Users / runner / work / 1 / s / Debug / Tests / StringOperations / TestStringOperations Users / runner / work / 1 / s / Debug / Tests / StringOperations / TestStringOperations Users / runner / work / 1 / s / Debug / Tests / StringOperations / TestStringOperations Users / runner / work / 1 / s / Debug / Tests / StringOperations / Debug / TestStringOperations Users / runner / work / 1 / s / Debug / Tests / StringOperations / Debug / TestStringOperations Debug / Users / runner / work / 1 / s / Deb ug / Tests / StringOperations / TestStringOperations Debug / Users / runner / work / 1 / s / Debug / Tests / StringOperations / TestStringOperations 1/1 Тест №1: StringOperations_CaseIgnore ...... *** Не запускается 0,00 сек.

0% тестов пройдены, 1 тест не пройден из 1

Общее время тестирования (реальное) = 0,00 сек.

Следующие тесты НЕ ВЫПОЛНЕНЫ: 1 - StringOperations_CaseIgnore (Not Run) Невозможно найти исполняемый файл: / Users / runner / work / 1 / s / Debug / Tests / StringOperations / TestStringOperations Ошибки при запуске CTest

Изменить 4:

Я попытался проверить, существует ли на самом деле исполняемый файл теста, используя:

ls -l Debug/Tests/StringOperations

И вот результат:

drwxr-xr-x 3 vsts docker    4096 Aug  6 15:05 CMakeFiles
-rw-r--r-- 1 vsts docker    1208 Aug  6 15:05 cmake_install.cmake
-rw-r--r-- 1 vsts docker     642 Aug  6 15:05 CTestTestfile.cmake
-rw-r--r-- 1 vsts docker    9838 Aug  6 15:05 Makefile
-rwxr--r-- 1 vsts docker 1715072 Aug  6 15:05 TestStringOperations

Это подтверждает, что исполняемый файл теста (TestStringOperations) находится там же, где он был для Windows и Linux, но все же процесс не выполняется.

Вот файл CMakeLists.txt для этого исполняемого файла, если он вам понадобится:

Set(SRC StringOperations.cpp)

Add_Executable(TestStringOperations ${SRC})

Target_Include_Directories(TestStringOperations PUBLIC
                           ${HEADER_PATH}/StringOperations
)

Target_Link_Libraries(TestStringOperations
                      PRIVATE ${GTEST_LIBS}
                      PRIVATE StringOperations
)

Add_Test(NAME StringOperations_CaseIgnore COMMAND TestStringOperations)

Я пытался найти помощь по этой проблеме на Stack Overflow и некоторых других сайтах, но их решения не приносят мне пользы.

Например: CTest не может найти исполняемый файл и CMake: Как указать каталог, в котором ctest должен искать исполняемые файлы?

Если вам нужна дополнительная информация, здесь мой проект на GitHub. Вы также можете обратиться к журналам конвейера на dev.azure.com.

Не могли бы вы помочь мне решить эту проблему? Также приветствуются любые предложения относительно общей реализации этого файла.


person Community    schedule 28.07.2020    source источник
comment
Очевидно, это связано с тем, что задача Cmake не выполняется правильно, папка сборки не создается. Нам нужно проверить задачу cmake, чтобы она правильно построилась. Вы можете проверить, правильно ли вы построили его на своем локальном компьютере, и поделиться журналом сборки cmake в своем вопросе.   -  person Leo Liu-MSFT    schedule 29.07.2020
comment
На моем локальном компьютере процесс сборки работает нормально.   -  person    schedule 30.07.2020
comment
Этапы конвейеров Azure не имеют общего локального состояния, поэтому каталог build не существует на этапе Test. Для передачи файлов между этапами необходимо использовать артефакты. Однако я бы посоветовал избегать использования нескольких этапов до тех пор, пока вы не более знакомы с конвейерами Azure, и просто запустите сборку + тест на одном этапе. Обратите внимание, что в отличие от большинства служб CI, AZP продолжит выполнение команд после ненулевого выхода команды. если вы не используете set -e (для bash) или аналогичные проверки.   -  person Isaiah Norton    schedule 03.08.2020
comment
Обратите внимание, что приведенные выше комментарии относятся к тому моменту, когда мой процесс сборки не запускался. Теперь у меня совсем другая проблема.   -  person    schedule 07.08.2020


Ответы (1)


Попробуйте запустить Опубликовать задачу «Артефакт конвейера» после сборки. Как ускользает от комментариев, это опубликует ваше содержимое сборки и позволит делиться им на разных этапах.

После этого вы также сможете увидеть его как опубликованный артефакт в пользовательском интерфейсе конвейера.

# Publish pipeline artifacts
# Publish (upload) a file or directory as a named artifact for the current run
- task: PublishPipelineArtifact@1
  inputs:
    targetPath: '$(Pipeline.Workspace)' 
    artifactName: # 'drop'

Также еще одна проверка кишечника, которую можно выполнить в конце этапа, - это включить сценарий PowerShell для просмотра содержимого каталога, в котором вы работаете:

-powershell: Get-ChildItem -Path 'Insert root path' -recurse
person DreadedFrost    schedule 05.08.2020
comment
Я успешно смог пройти процедуру сборки. Выяснилось, что построенные объекты не будут доступны на этапе тестирования. Поэтому я опубликовал построенные объекты как артефакт, а затем загрузил его во время тестирования, как вы продемонстрировали выше. См. Мой отредактированный вопрос. - person ; 06.08.2020
comment
Я могу взглянуть. Я бы посоветовал закрыть этот вопрос, если на исходный вопрос был дан правильный ответ. Таким образом, вы можете получить более целевую аудиторию при тестировании Cmake. - person DreadedFrost; 06.08.2020