diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 3a55e86b040..00000000000 --- a/.travis.yml +++ /dev/null @@ -1,92 +0,0 @@ -# Travis-CI Build for libgit2 -# see travis-ci.org for details - -language: c - -os: - - linux - - osx - -compiler: - - gcc - - clang - -# Settings to try -env: - global: - - secure: "YnhS+8n6B+uoyaYfaJ3Lei7cSJqHDPiKJCKFIF2c87YDfmCvAJke8QtE7IzjYDs7UFkTCM4ox+ph2bERUrxZbSCyEkHdjIZpKuMJfYWja/jgMqTMxdyOH9y8JLFbZsSXDIXDwqBlC6vVyl1fP90M35wuWcNTs6tctfVWVofEFbs=" - - GITTEST_INVASIVE_FS_SIZE=1 - matrix: - - OPTIONS="-DTHREADSAFE=ON -DENABLE_TRACE=ON -DCMAKE_BUILD_TYPE=Release -DENABLE_WERROR=ON" - - OPTIONS="-DTHREADSAFE=OFF -DBUILD_EXAMPLES=ON -DENABLE_WERROR=ON" - -dist: trusty -osx_image: xcode8.3 -sudo: false - -addons: - apt: - sources: - - sourceline: 'deb https://dl.bintray.com/libgit2/ci-dependencies trusty libgit2deps' - key_url: 'https://bintray.com/user/downloadSubjectPublicKey?username=bintray' - packages: - cmake - curl - libcurl3 - libcurl3-gnutls - libcurl4-gnutls-dev - libssh2-1-dev - openssh-client - openssh-server - valgrind - -matrix: - fast_finish: true - exclude: - - os: osx - compiler: gcc - include: - - compiler: gcc - env: COVERITY=1 - os: linux - dist: trusty - - compiler: gcc - env: - - VALGRIND=1 - OPTIONS="-DBUILD_CLAR=ON -DBUILD_EXAMPLES=OFF -DDEBUG_POOL=ON -DCMAKE_BUILD_TYPE=Debug" - os: linux - dist: trusty - allow_failures: - - env: COVERITY=1 - -install: - - if [ -f ./script/install-deps-${TRAVIS_OS_NAME}.sh ]; then ./script/install-deps-${TRAVIS_OS_NAME}.sh; fi - -# Run the Build script and tests -script: - - script/cibuild.sh - -# Run Tests -after_success: - - if [ "$TRAVIS_OS_NAME" = "linux" -a -n "$VALGRIND" ]; then valgrind --leak-check=full --show-reachable=yes --suppressions=./libgit2_clar.supp _build/libgit2_clar -ionline; fi - -# Only watch the development and master branches -branches: - only: - - master - - /^maint.*/ - -# Notify development list when needed -notifications: - irc: - channels: - - irc.freenode.net#libgit2 - on_success: change - on_failure: always - use_notice: true - skip_join: true - campfire: - on_success: always - on_failure: always - rooms: - - secure: "sH0dpPWMirbEe7AvLddZ2yOp8rzHalGmv0bYL/LIhVw3JDI589HCYckeLMSB\n3e/FeXw4bn0EqXWEXijVa4ijbilVY6d8oprdqMdWHEodng4KvY5vID3iZSGT\nxylhahO1XHmRynKQLOAvxlc93IlpVW38vQfby8giIY1nkpspb2w=" diff --git a/README.md b/README.md index 9fe99d8d568..d297aaa1062 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,7 @@ libgit2 - the Git linkable library ================================== -[![Travis Build Status](https://secure.travis-ci.org/libgit2/libgit2.svg?branch=master)](http://travis-ci.org/libgit2/libgit2) -[![AppVeyor Build Status](https://ci.appveyor.com/api/projects/status/xvof5b4t5480a2q3/branch/master?svg=true)](https://ci.appveyor.com/project/libgit2/libgit2/branch/master) +[![VSTS Build Status](https://libgit2.visualstudio.com/libgit2/_apis/build/status/libgit2)](https://libgit2.visualstudio.com/libgit2/_build/latest?definitionId=7) [![Coverity Scan Build Status](https://scan.coverity.com/projects/639/badge.svg)](https://scan.coverity.com/projects/639) `libgit2` is a portable, pure C implementation of the Git core methods @@ -64,7 +63,7 @@ slack channel once you've registered. If you have questions about the library, please be sure to check out the [API documentation](http://libgit2.github.com/libgit2/). If you still have -questions, reach out to us on Slack or post a question on +questions, reach out to us on Slack or post a question on [StackOverflow](http://stackoverflow.com/questions/tagged/libgit2) (with the `libgit2` tag). **Reporting Bugs** diff --git a/appveyor.yml b/appveyor.yml deleted file mode 100644 index f76830cb417..00000000000 --- a/appveyor.yml +++ /dev/null @@ -1,60 +0,0 @@ -version: '{build}' -branches: - only: - - master - - appveyor - - /^maint.*/ -environment: - GITTEST_INVASIVE_FS_STRUCTURE: 1 - GITTEST_INVASIVE_FS_SIZE: 1 - - matrix: - - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2013 - GENERATOR: "Visual Studio 10 2010" - ARCH: 32 - - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2013 - GENERATOR: "Visual Studio 10 2010 Win64" - ARCH: 64 - - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015 - GENERATOR: "Visual Studio 14 2015" - ARCH: 32 - - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015 - GENERATOR: "Visual Studio 14 2015 Win64" - ARCH: 64 - - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015 - GENERATOR: "MSYS Makefiles" - ARCH: i686 # this is for 32-bit MinGW-w64 - - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015 - GENERATOR: "MSYS Makefiles" - ARCH: 64 -cache: -- i686-4.9.2-release-win32-sjlj-rt_v3-rev1.7z -- x86_64-4.9.2-release-win32-seh-rt_v3-rev1.7z - -build_script: -- ps: | - mkdir build - cd build - if ($env:GENERATOR -ne "MSYS Makefiles") { - cmake -D ENABLE_TRACE=ON -D BUILD_CLAR=ON -D BUILD_EXAMPLES=ON -D MSVC_CRTDBG=ON .. -G"$env:GENERATOR" - cmake --build . --config Debug - } -- cmd: | - if "%GENERATOR%"=="MSYS Makefiles" (C:\MinGW\msys\1.0\bin\sh --login /c/projects/libgit2/script/appveyor-mingw.sh) -test_script: -- ps: | - # Disable DHE key exchange to fix intermittent build failures ("A buffer - # provided was too small") due to SChannel bug. See e.g. - # - https://github.com/aws/aws-sdk-cpp/issues/671 - # - https://github.com/dotnet/corefx/issues/7812 - New-Item HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\KeyExchangeAlgorithms\Diffie-Hellman -Force | New-ItemProperty -Name Enabled -Value 0 -Force - $ErrorActionPreference="Stop" - Start-FileDownload https://github.com/ethomson/poxyproxy/releases/download/v0.1.0/poxyproxy-0.1.0.jar -FileName poxyproxy.jar - # Run this early so we know it's ready by the time we need it - $proxyJob = Start-Job { java -jar $Env:APPVEYOR_BUILD_FOLDER\build\poxyproxy.jar -d --port 8080 --credentials foo:bar } - ctest -V -R libgit2_clar - Receive-Job -Job $proxyJob - $env:GITTEST_REMOTE_PROXY_URL = "localhost:8080" - $env:GITTEST_REMOTE_PROXY_USER = "foo" - $env:GITTEST_REMOTE_PROXY_PASS = "bar" - ctest -V -R libgit2_clar-proxy_credentials diff --git a/azure-pipelines.yml b/azure-pipelines.yml new file mode 100644 index 00000000000..5844270c215 --- /dev/null +++ b/azure-pipelines.yml @@ -0,0 +1,101 @@ +resources: +- repo: self + +trigger: +- master +- maint/* + +phases: +- phase: linux_trusty_gcc_openssl + displayName: 'Linux (Trusty; GCC; OpenSSL)' + queue: + name: 'Hosted Linux Preview' + steps: + - template: ci/docker.yml + parameters: + imageName: 'libgit2/trusty-openssl:latest' + environmentVariables: | + CC=gcc + LEAK_CHECK=valgrind + +- phase: linux_trusty_clang_openssl + displayName: 'Linux (Trusty; Clang; OpenSSL)' + queue: + name: 'Hosted Linux Preview' + steps: + - template: ci/docker.yml + parameters: + imageName: 'libgit2/trusty-openssl:latest' + environmentVariables: | + CC=clang + LEAK_CHECK=valgrind + workDir: '/build' + containerCommand: '/src/ci/test.sh' + detached: false + +- phase: macos + displayName: 'macOS' + queue: + name: 'Hosted macOS Preview' + steps: + - bash: . '$(Build.SourcesDirectory)/ci/setup-osx.sh' + displayName: Setup + - template: ci/bash.yml + parameters: + environmentVariables: + TMPDIR: $(Agent.TempDirectory) + PKG_CONFIG_PATH: /usr/local/opt/openssl/lib/pkgconfig + LEAK_CHECK: leaks + +- phase: windows_vs_amd64 + displayName: 'Windows (Visual Studio; amd64)' + queue: + name: Hosted + steps: + - template: ci/powershell.yml + parameters: + environmentVariables: + CMAKE_OPTIONS: -DMSVC_CRTDBG=ON -G"Visual Studio 12 2013 Win64" + +- phase: windows_vs_x86 + displayName: 'Windows (Visual Studio; x86)' + queue: + name: Hosted + steps: + - template: ci/powershell.yml + parameters: + environmentVariables: + CMAKE_OPTIONS: -DMSVC_CRTDBG=ON -G"Visual Studio 12 2013" + +- phase: windows_mingw_amd64 + displayName: 'Windows (MinGW; amd64)' + queue: + name: Hosted + steps: + - powershell: . '$(Build.SourcesDirectory)\ci\setup-mingw.ps1' + displayName: Setup + env: + TEMP: $(Agent.TempDirectory) + ARCH: amd64 + - template: ci/powershell.yml + parameters: + environmentVariables: + CMAKE_OPTIONS: -G"MinGW Makefiles" + PATH: $(Agent.TempDirectory)\mingw64\bin;C:\ProgramData\Oracle\Java\javapath;C:\Windows\system32;C:\Windows;C:\Windows\System32\Wbem;C:\Windows\System32\WindowsPowerShell\v1.0\;C:\Program Files (x86)\CMake\bin + +- phase: windows_mingw_x86 + displayName: 'Windows (MinGW; x86)' + queue: + name: Hosted + steps: + - powershell: . '$(Build.SourcesDirectory)\ci\setup-mingw.ps1' + displayName: Setup + workingDirectory: '$(Build.BinariesDirectory)' + env: + TEMP: $(Agent.TempDirectory) + ARCH: x86 + - template: ci/powershell.yml + parameters: + environmentVariables: + CMAKE_OPTIONS: -G"MinGW Makefiles" + PATH: $(Agent.TempDirectory)\mingw32\bin;C:\ProgramData\Oracle\Java\javapath;C:\Windows\system32;C:\Windows;C:\Windows\System32\Wbem;C:\Windows\System32\WindowsPowerShell\v1.0\;C:\Program Files (x86)\CMake\bin diff --git a/ci/bash.yml b/ci/bash.yml new file mode 100644 index 00000000000..d776a364996 --- /dev/null +++ b/ci/bash.yml @@ -0,0 +1,17 @@ +# These are the steps used for building on machines with bash. +steps: +- bash: . '$(Build.SourcesDirectory)/ci/build.sh' + displayName: Build + workingDirectory: '$(Build.BinariesDirectory)' + env: ${{ parameters.environmentVariables }} +- bash: . '$(Build.SourcesDirectory)/ci/test.sh' + displayName: Test + workingDirectory: '$(Build.BinariesDirectory)' + env: ${{ parameters.environmentVariables }} +- task: PublishTestResults@2 + displayName: Publish Test Results + condition: succeededOrFailed() + inputs: + testResultsFiles: 'results_*.xml' + searchFolder: '$(Build.BinariesDirectory)' + mergeTestResults: true diff --git a/ci/build.ps1 b/ci/build.ps1 new file mode 100644 index 00000000000..159c1dd1b92 --- /dev/null +++ b/ci/build.ps1 @@ -0,0 +1,30 @@ +Set-StrictMode -Version Latest + +$ErrorActionPreference = "Stop" +$PSDefaultParameterValues['*:ErrorAction'] = 'Stop' + +if ($Env:SOURCE_DIR) { $SourceDirectory = $Env:SOURCE_DIR } else { $SourceDirectory = Split-Path (Split-Path $MyInvocation.MyCommand.Path -Parent) -Parent } +$BuildDirectory = $(Get-Location).Path + +Write-Host "Source directory: ${SourceDirectory}" +Write-Host "Build directory: ${BuildDirectory}" +Write-Host "" +Write-Host "Operating system version:" +Get-CimInstance Win32_OperatingSystem | Select-Object Caption, Version, ServicePackMajorVersion, BuildNumber, OSArchitecture | Format-List +Write-Host "PATH: ${Env:PATH}" +Write-Host "" + +Write-Host "##############################################################################" +Write-Host "## Configuring build environment" +Write-Host "##############################################################################" + +Invoke-Expression "cmake ${SourceDirectory} -DBUILD_EXAMPLES=ON ${Env:CMAKE_OPTIONS}" +if ($LastExitCode -ne 0) { [Environment]::Exit($LastExitCode) } + +Write-Host "" +Write-Host "##############################################################################" +Write-Host "## Building libgit2" +Write-Host "##############################################################################" + +cmake --build . +if ($LastExitCode -ne 0) { [Environment]::Exit($LastExitCode) } diff --git a/ci/build.sh b/ci/build.sh new file mode 100755 index 00000000000..a1deab3f2d3 --- /dev/null +++ b/ci/build.sh @@ -0,0 +1,39 @@ +#!/usr/bin/env bash +# +# Environment variables: +# +# SOURCE_DIR: Set to the directory of the libgit2 source (optional) +# If not set, it will be derived relative to this script. + +set -e + +SOURCE_DIR=${SOURCE_DIR:-$( cd "$( dirname "${BASH_SOURCE[0]}" )" && dirname $( pwd ) )} +BUILD_DIR=$(pwd) +CC=${CC:-cc} + +indent() { sed "s/^/ /"; } + +echo "Source directory: ${SOURCE_DIR}" +echo "Build directory: ${BUILD_DIR}" +echo "" +echo "Operating system version:" +uname -a 2>&1 | indent +echo "CMake version:" +cmake --version 2>&1 | indent +echo "Compiler version:" +$CC --version 2>&1 | indent +echo "" + +echo "##############################################################################" +echo "## Configuring build environment" +echo "##############################################################################" + +echo cmake ${SOURCE_DIR} -DBUILD_EXAMPLES=ON ${CMAKE_OPTIONS} +cmake ${SOURCE_DIR} -DBUILD_EXAMPLES=ON ${CMAKE_OPTIONS} + +echo "" +echo "##############################################################################" +echo "## Building libgit2" +echo "##############################################################################" + +cmake --build . diff --git a/script/coverity.sh b/ci/coverity.sh similarity index 67% rename from script/coverity.sh rename to ci/coverity.sh index 5fe16c0311d..ae6d46ef4c9 100755 --- a/script/coverity.sh +++ b/ci/coverity.sh @@ -1,17 +1,13 @@ #!/bin/bash -set -e -# Only run this on our branches -echo "Branch: $TRAVIS_BRANCH | Pull request: $TRAVIS_PULL_REQUEST | Slug: $TRAVIS_REPO_SLUG" -if [ "$TRAVIS_BRANCH" != "master" -o "$TRAVIS_PULL_REQUEST" != "false" -o "$TRAVIS_REPO_SLUG" != "libgit2/libgit2" ]; -then - echo "Only analyzing the 'master' brach of the main repository." - exit 0 -fi +set -e # Environment check [ -z "$COVERITY_TOKEN" ] && echo "Need to set a coverity token" && exit 1 +SOURCE_DIR=${SOURCE_DIR:-$( cd "$( dirname "${BASH_SOURCE[0]}" )" && dirname $( pwd ) )} +BUILD_DIR=$(pwd) + case $(uname -m) in i?86) BITS=32 ;; amd64|x86_64) BITS=64 ;; @@ -32,31 +28,29 @@ if [ ! -d "$TOOL_BASE" ]; then ln -s "$TOOL_DIR" "$TOOL_BASE"/cov-analysis fi -cp script/user_nodefs.h "$TOOL_BASE"/cov-analysis/config/user_nodefs.h +cp "${SOURCE_DIR}/script/user_nodefs.h" "$TOOL_BASE"/cov-analysis/config/user_nodefs.h COV_BUILD="$TOOL_BASE/cov-analysis/bin/cov-build" # Configure and build -rm -rf _build -mkdir _build -cd _build -cmake .. -DTHREADSAFE=ON +cmake ${SOURCE_DIR} + COVERITY_UNSUPPORTED=1 \ $COV_BUILD --dir cov-int \ cmake --build . # Upload results tar czf libgit2.tgz cov-int -SHA=$(git rev-parse --short HEAD) +SHA=$(cd ${SOURCE_DIR} && git rev-parse --short HEAD) HTML="$(curl \ --silent \ --write-out "\n%{http_code}" \ --form token="$COVERITY_TOKEN" \ - --form email=bs@github.com \ + --form email=libgit2@gmail.com \ --form file=@libgit2.tgz \ --form version="$SHA" \ - --form description="Travis build" \ + --form description="libgit2 build" \ https://scan.coverity.com/builds?project=libgit2)" # Body is everything up to the last line BODY="$(echo "$HTML" | head -n-1)" @@ -65,7 +59,7 @@ STATUS_CODE="$(echo "$HTML" | tail -n1)" echo "${BODY}" -if [ "${STATUS_CODE}" != "201" ]; then +if [ "${STATUS_CODE}" != "200" -o "${STATUS_CODE}" != "201" ]; then echo "Received error code ${STATUS_CODE} from Coverity" exit 1 fi diff --git a/ci/docker.yml b/ci/docker.yml new file mode 100644 index 00000000000..e9251047832 --- /dev/null +++ b/ci/docker.yml @@ -0,0 +1,33 @@ +# These are the steps used in a container-based build in VSTS. +steps: +- task: docker@0 + displayName: Build + inputs: + action: 'Run an image' + imageName: ${{ parameters.imageName }} + volumes: | + $(Build.SourcesDirectory):/src + $(Build.BinariesDirectory):/build + envVars: ${{ parameters.environmentVariables }} + workDir: '/build' + containerCommand: '/src/ci/build.sh' + detached: false +- task: docker@0 + displayName: Test + inputs: + action: 'Run an image' + imageName: ${{ parameters.imageName }} + volumes: | + $(Build.SourcesDirectory):/src + $(Build.BinariesDirectory):/build + envVars: ${{ parameters.environmentVariables }} + workDir: '/build' + containerCommand: '/src/ci/test.sh' + detached: false +- task: publishtestresults@2 + displayName: Publish Test Results + condition: succeededOrFailed() + inputs: + testResultsFiles: 'results_*.xml' + searchFolder: '$(Build.BinariesDirectory)' + mergeTestResults: true diff --git a/ci/nightly.yml b/ci/nightly.yml new file mode 100644 index 00000000000..6c5d0ebb4b1 --- /dev/null +++ b/ci/nightly.yml @@ -0,0 +1,22 @@ +resources: +- repo: self + +phases: +- phase: coverity + displayName: 'Coverity' + queue: + name: 'Hosted Linux Preview' + steps: + - task: Docker@0 + displayName: Build + inputs: + action: 'Run an image' + imageName: 'libgit2/trusty-openssl:latest' + volumes: | + $(Build.SourcesDirectory):/src + $(Build.BinariesDirectory):/build + envVars: | + COVERITY_TOKEN=$(COVERITY_TOKEN) + workDir: '/build' + containerCommand: '/src/ci/coverity.sh' + detached: false diff --git a/ci/powershell.yml b/ci/powershell.yml new file mode 100644 index 00000000000..a2eb175d571 --- /dev/null +++ b/ci/powershell.yml @@ -0,0 +1,17 @@ +# These are the steps used for building on machines with PowerShell. +steps: +- powershell: . '$(Build.SourcesDirectory)\ci\build.ps1' + displayName: Build + workingDirectory: '$(Build.BinariesDirectory)' + env: ${{ parameters.environmentVariables }} +- powershell: . '$(Build.SourcesDirectory)\ci\test.ps1' + displayName: Test + workingDirectory: '$(Build.BinariesDirectory)' + env: ${{ parameters.environmentVariables }} +- task: PublishTestResults@2 + displayName: Publish Test Results + condition: succeededOrFailed() + inputs: + testResultsFiles: 'results_*.xml' + searchFolder: '$(Build.BinariesDirectory)' + mergeTestResults: true diff --git a/ci/setup-linux.sh b/ci/setup-linux.sh new file mode 100755 index 00000000000..c5ecb550b88 --- /dev/null +++ b/ci/setup-linux.sh @@ -0,0 +1,27 @@ +#!/bin/sh + +set -e +set -x + +TMPDIR=${TMPDIR:-/tmp} + +if [ -z "$SKIP_APT" ]; then + apt-get update + apt-get -y install build-essential pkg-config clang cmake openssl libssl-dev libssh2-1-dev libcurl4-gnutls-dev openssh-server +fi + +mkdir -p /var/run/sshd + +if [ "$MBEDTLS" ]; then + MBEDTLS_DIR=${MBEDTLS_DIR:-$(mktemp -d ${TMPDIR}/mbedtls.XXXXXXXX)} + + git clone --depth 10 --single-branch --branch mbedtls-2.6.1 https://github.com/ARMmbed/mbedtls.git ${MBEDTLS_DIR} + cd ${MBEDTLS_DIR} + + CFLAGS=-fPIC cmake -DENABLE_PROGRAMS=OFF -DENABLE_TESTING=OFF -DUSE_SHARED_MBEDTLS_LIBRARY=OFF -DUSE_STATIC_MBEDTLS_LIBRARY=ON . + cmake --build . + + if [ -z "$SKIP_MBEDTLS_INSTALL" ]; then + make install + fi +fi diff --git a/ci/setup-mingw.ps1 b/ci/setup-mingw.ps1 new file mode 100644 index 00000000000..76ecd3987ad --- /dev/null +++ b/ci/setup-mingw.ps1 @@ -0,0 +1,25 @@ +Set-StrictMode -Version Latest + +$ErrorActionPreference = "Stop" +$PSDefaultParameterValues['*:ErrorAction'] = 'Stop' + +[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 + +[Reflection.Assembly]::LoadWithPartialName("System.IO.Compression.FileSystem"); + +Write-Host "##############################################################################" +Write-Host "## Downloading mingw" +Write-Host "##############################################################################" + +if ($env:ARCH -eq "amd64") { + $mingw_uri = "https://bintray.com/libgit2/build-dependencies/download_file?file_path=mingw-w64-x86_64-8.1.0-release-win32-seh-rt_v6-rev0.zip" + $platform = "x86_64" +} else { + $mingw_uri = "https://bintray.com/libgit2/build-dependencies/download_file?file_path=mingw-w64-i686-8.1.0-release-win32-sjlj-rt_v6-rev0.zip" + $platform = "x86" +} + +$wc = New-Object net.webclient +$wc.Downloadfile($mingw_uri, "${Env:TEMP}/mingw-${Env:ARCH}.zip") + +[System.IO.Compression.ZipFile]::ExtractToDirectory("${Env:TEMP}/mingw-${Env:ARCH}.zip", $Env:TEMP) diff --git a/ci/setup-osx.sh b/ci/setup-osx.sh new file mode 100755 index 00000000000..564910e4158 --- /dev/null +++ b/ci/setup-osx.sh @@ -0,0 +1,8 @@ +#!/bin/sh + +set -x + +brew update +brew install pkgconfig zlib curl openssl libssh2 + +ln -s /Applications/Xcode.app/Contents/Developer/usr/lib/libLeaksAtExit.dylib /usr/local/lib diff --git a/ci/test.ps1 b/ci/test.ps1 new file mode 100644 index 00000000000..21e8bd7644f --- /dev/null +++ b/ci/test.ps1 @@ -0,0 +1,42 @@ +Set-StrictMode -Version Latest + +$ErrorActionPreference = "Stop" +$PSDefaultParameterValues['*:ErrorAction'] = 'Stop' + +[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 + +if ($Env:SKIP_TESTS) { exit } + +Write-Host "##############################################################################" +Write-Host "## Configuring test environment" +Write-Host "##############################################################################" + +Write-Host "" +Write-Host "Starting HTTP proxy..." +Invoke-WebRequest -Method GET -Uri https://github.com/ethomson/poxyproxy/releases/download/v0.1.0/poxyproxy-0.1.0.jar -OutFile poxyproxy.jar +javaw -jar poxyproxy.jar -d --port 8080 --credentials foo:bar + +Write-Host "" +Write-Host "##############################################################################" +Write-Host "## Running default tests" +Write-Host "##############################################################################" + +ctest -V -R libgit2_clar +if ($LastExitCode -ne 0) { [Environment]::Exit($LastExitCode) } + +Write-Host "" +Write-Host "##############################################################################" +Write-Host "## Running online tests" +Write-Host "##############################################################################" + +Write-Host "" +Write-Host "Running proxy tests" +Write-Host "" + +$Env:GITTEST_REMOTE_PROXY_URL="localhost:8080" +$Env:GITTEST_REMOTE_PROXY_USER="foo" +$Env:GITTEST_REMOTE_PROXY_PASS="bar" +ctest -V -R libgit2_clar-proxy_credentials +if ($LastExitCode -ne 0) { [Environment]::Exit($LastExitCode) } + +taskkill /F /IM javaw.exe diff --git a/ci/test.sh b/ci/test.sh new file mode 100755 index 00000000000..e9736461fb0 --- /dev/null +++ b/ci/test.sh @@ -0,0 +1,177 @@ +#!/usr/bin/env bash + +set -e + +if [ -n "$SKIP_TESTS" ]; then + exit 0 +fi + +SOURCE_DIR=${SOURCE_DIR:-$( cd "$( dirname "${BASH_SOURCE[0]}" )" && dirname $( pwd ) )} +BUILD_DIR=$(pwd) +TMPDIR=${TMPDIR:-/tmp} +USER=${USER:-$(whoami)} + +VALGRIND="valgrind --leak-check=full --show-reachable=yes --error-exitcode=125 --num-callers=50 --suppressions=\"$SOURCE_DIR/libgit2_clar.supp\"" +LEAKS="MallocStackLogging=1 MallocScribble=1 leaks -quiet -atExit -- nohup" + +cleanup() { + echo "Cleaning up..." + + if [ ! -z "$GITDAEMON_DIR" -a -f "${GITDAEMON_DIR}/pid" ]; then + echo "Stopping git daemon..." + kill $(cat "${GITDAEMON_DIR}/pid") + fi + + if [ ! -z "$SSHD_DIR" -a -f "${SSHD_DIR}/pid" ]; then + echo "Stopping SSH..." + kill $(cat "${SSHD_DIR}/pid") + fi + + echo "Done." +} + +die() { + echo "Test exited with code: $1" + + cleanup + exit $1 +} + +# Ask ctest what it would run if we were to invoke it directly. This lets us manage the +# test configuration in a single place (tests/CMakeLists.txt) instead of running clar +# here as well. But it allows us to wrap our test harness with a leak checker like valgrind. +run_test() { + TEST_CMD=$(ctest -N -V -R "^${1}$" | sed -n 's/^[0-9]*: Test command: //p') + + if [ "$LEAK_CHECK" = "valgrind" ]; then + RUNNER="$VALGRIND $TEST_CMD" + elif [ "$LEAK_CHECK" = "leaks" ]; then + RUNNER="$LEAKS $TEST_CMD" + else + RUNNER="$TEST_CMD" + fi + + eval $RUNNER || die $? +} + +# Configure the test environment; run them early so that we're certain +# that they're started by the time we need them. + +echo "##############################################################################" +echo "## Configuring test environment" +echo "##############################################################################" + +if [ -z "$SKIP_GITDAEMON_TESTS" ]; then + echo "Starting git daemon..." + GITDAEMON_DIR=`mktemp -d ${TMPDIR}/gitdaemon.XXXXXXXX` + git init --bare "${GITDAEMON_DIR}/test.git" + git daemon --listen=localhost --export-all --enable=receive-pack --pid-file="${GITDAEMON_DIR}/pid" --base-path="${GITDAEMON_DIR}" "${GITDAEMON_DIR}" 2>/dev/null & +fi + +if [ -z "$SKIP_PROXY_TESTS" ]; then + echo "Starting HTTP proxy..." + curl -L https://github.com/ethomson/poxyproxy/releases/download/v0.1.0/poxyproxy-0.1.0.jar >poxyproxy.jar + java -jar poxyproxy.jar -d --port 8080 --credentials foo:bar >/dev/null 2>&1 & +fi + +if [ -z "$SKIP_SSH_TESTS" ]; then + echo "Starting ssh daemon..." + HOME=`mktemp -d ${TMPDIR}/home.XXXXXXXX` + SSHD_DIR=`mktemp -d ${TMPDIR}/sshd.XXXXXXXX` + git init --bare "${SSHD_DIR}/test.git" + cat >"${SSHD_DIR}/sshd_config" <<-EOF + Port 2222 + ListenAddress 0.0.0.0 + Protocol 2 + HostKey ${SSHD_DIR}/id_rsa + PidFile ${SSHD_DIR}/pid + AuthorizedKeysFile ${HOME}/.ssh/authorized_keys + LogLevel DEBUG + RSAAuthentication yes + PasswordAuthentication yes + PubkeyAuthentication yes + ChallengeResponseAuthentication no + StrictModes no + # Required here as sshd will simply close connection otherwise + UsePAM no + EOF + ssh-keygen -t rsa -f "${SSHD_DIR}/id_rsa" -N "" -q + /usr/sbin/sshd -f "${SSHD_DIR}/sshd_config" -E "${SSHD_DIR}/log" + + # Set up keys + mkdir "${HOME}/.ssh" + ssh-keygen -t rsa -f "${HOME}/.ssh/id_rsa" -N "" -q + cat "${HOME}/.ssh/id_rsa.pub" >>"${HOME}/.ssh/authorized_keys" + while read algorithm key comment; do + echo "[localhost]:2222 $algorithm $key" >>"${HOME}/.ssh/known_hosts" + done <"${SSHD_DIR}/id_rsa.pub" + + # Get the fingerprint for localhost and remove the colons so we can + # parse it as a hex number. Older versions have a different output + # format. + if [[ $(ssh -V 2>&1) == OpenSSH_6* ]]; then + SSH_FINGERPRINT=$(ssh-keygen -F '[localhost]:2222' -f "${HOME}/.ssh/known_hosts" -l | tail -n 1 | cut -d ' ' -f 2 | tr -d ':') + else + SSH_FINGERPRINT=$(ssh-keygen -E md5 -F '[localhost]:2222' -f "${HOME}/.ssh/known_hosts" -l | tail -n 1 | cut -d ' ' -f 3 | cut -d : -f2- | tr -d :) + fi +fi + +# Run the tests that do not require network connectivity. + +if [ -z "$SKIP_GITDAEMON_TESTS" ]; then + export GITTEST_REMOTE_URL="git://localhost/test.git" +fi + +echo "" +echo "##############################################################################" +echo "## Running (offline) tests" +echo "##############################################################################" + +run_test libgit2_clar + +# Run the various online tests. The "online" test suite only includes the +# default online tests that do not require additional configuration. The +# "proxy" and "ssh" test suites require further setup. + +echo "" +echo "##############################################################################" +echo "## Running (online) tests" +echo "##############################################################################" + +if [ -z "$SKIP_PROXY_TESTS" ]; then + echo "" + echo "Running proxy tests" + echo "" + + export GITTEST_REMOTE_PROXY_URL="localhost:8080" + export GITTEST_REMOTE_PROXY_USER="foo" + export GITTEST_REMOTE_PROXY_PASS="bar" + run_test libgit2_clar-proxy_credentials + unset GITTEST_REMOTE_PROXY_URL + unset GITTEST_REMOTE_PROXY_USER + unset GITTEST_REMOTE_PROXY_PASS +fi + +if [ -z "$SKIP_SSH_TESTS" ]; then + echo "" + echo "Running ssh tests" + echo "" + + export GITTEST_REMOTE_URL="ssh://localhost:2222/$SSHD_DIR/test.git" + export GITTEST_REMOTE_USER=$USER + export GITTEST_REMOTE_SSH_KEY="${HOME}/.ssh/id_rsa" + export GITTEST_REMOTE_SSH_PUBKEY="${HOME}/.ssh/id_rsa.pub" + export GITTEST_REMOTE_SSH_PASSPHRASE="" + export GITTEST_REMOTE_SSH_FINGERPRINT="${SSH_FINGERPRINT}" + run_test libgit2_clar-ssh + unset GITTEST_REMOTE_URL + unset GITTEST_REMOTE_USER + unset GITTEST_REMOTE_SSH_KEY + unset GITTEST_REMOTE_SSH_PUBKEY + unset GITTEST_REMOTE_SSH_PASSPHRASE + unset GITTEST_REMOTE_SSH_FINGERPRINT +fi + +echo "Success." +cleanup +exit 0 diff --git a/libgit2_clar.supp b/libgit2_clar.supp index bd22ada460f..0cc89b57f4c 100644 --- a/libgit2_clar.supp +++ b/libgit2_clar.supp @@ -47,3 +47,28 @@ ... fun:__check_pf } + +{ + ignore-curl-global-init + Memcheck:Leak + ... + fun:curl_global_init +} + +{ + ignore-libssh2-gcrypt-leak + Memcheck:Leak + ... + fun:gcry_control + obj:*libssh2.so* +} + +{ + ignore-noai6ai_cached-double-free + Memcheck:Free + fun:free + fun:__libc_freeres + ... + fun:exit + ... +} diff --git a/script/appveyor-mingw.sh b/script/appveyor-mingw.sh deleted file mode 100755 index 6b2a9425eda..00000000000 --- a/script/appveyor-mingw.sh +++ /dev/null @@ -1,23 +0,0 @@ -#!/bin/sh -set -e -cd `dirname "$0"`/.. -if [ "$ARCH" = "i686" ]; then - f=i686-4.9.2-release-win32-sjlj-rt_v3-rev1.7z - if ! [ -e $f ]; then - curl -LsSO http://sourceforge.net/projects/mingw-w64/files/Toolchains%20targetting%20Win32/Personal%20Builds/mingw-builds/4.9.2/threads-win32/sjlj/$f - fi - 7z x $f > /dev/null - export PATH=`pwd`/mingw32/bin:$PATH -else - f=x86_64-4.9.2-release-win32-seh-rt_v3-rev1.7z - if ! [ -e $f ]; then - curl -LsSO http://sourceforge.net/projects/mingw-w64/files/Toolchains%20targetting%20Win64/Personal%20Builds/mingw-builds/4.9.2/threads-win32/seh/$f - fi - 7z x $f > /dev/null - export PATH=`pwd`/mingw64/bin:$PATH -fi -cd build -gcc --version -cmake --version -cmake -D ENABLE_TRACE=ON -D BUILD_CLAR=ON -D BUILD_EXAMPLES=ON .. -G"$GENERATOR" -cmake --build . --config RelWithDebInfo diff --git a/script/cibuild.sh b/script/cibuild.sh deleted file mode 100755 index 5d70e750640..00000000000 --- a/script/cibuild.sh +++ /dev/null @@ -1,102 +0,0 @@ -#!/bin/sh - -set -x - -if [ -n "$COVERITY" ]; -then - ./script/coverity.sh; - exit $?; -fi - -if [ "$TRAVIS_OS_NAME" = "osx" ]; then - export PKG_CONFIG_PATH=$(ls -d /usr/local/Cellar/{curl,zlib}/*/lib/pkgconfig | paste -s -d':' -) - - # Set up a ramdisk for us to put our test data on to speed up tests on macOS - export CLAR_TMP="$HOME"/_clar_tmp - mkdir -p $CLAR_TMP - - # 5*2M sectors aka ~5GB of space - device=$(hdiutil attach -nomount ram://$((5 * 2 * 1024 * 1024))) - newfs_hfs $device - mount -t hfs $device $CLAR_TMP -fi - -# Should we ask Travis to cache this file? -curl -L https://github.com/ethomson/poxyproxy/releases/download/v0.1.0/poxyproxy-0.1.0.jar >poxyproxy.jar || exit $? -# Run this early so we know it's ready by the time we need it -java -jar poxyproxy.jar -d --port 8080 --credentials foo:bar & - -mkdir _build -cd _build -# shellcheck disable=SC2086 -cmake .. -DBUILD_EXAMPLES=ON -DCMAKE_INSTALL_PREFIX=../_install $OPTIONS || exit $? -make -j2 install || exit $? - -# If this platform doesn't support test execution, bail out now -if [ -n "$SKIP_TESTS" ]; -then - exit $?; -fi - -# Create a test repo which we can use for the online::push tests -mkdir "$HOME"/_temp -git init --bare "$HOME"/_temp/test.git -git daemon --listen=localhost --export-all --enable=receive-pack --base-path="$HOME"/_temp "$HOME"/_temp 2>/dev/null & -export GITTEST_REMOTE_URL="git://localhost/test.git" - -# Run the test suite -ctest -V -R libgit2_clar || exit $? - -# Now that we've tested the raw git protocol, let's set up ssh to we -# can do the push tests over it - -killall git-daemon - -# Set up sshd -mkdir ~/sshd/ -cat >~/sshd/sshd_config<<-EOF - Port 2222 - ListenAddress 0.0.0.0 - Protocol 2 - HostKey ${HOME}/sshd/id_rsa - PidFile ${HOME}/sshd/pid - RSAAuthentication yes - PasswordAuthentication yes - PubkeyAuthentication yes - ChallengeResponseAuthentication no - # Required here as sshd will simply close connection otherwise - UsePAM no -EOF -ssh-keygen -t rsa -f ~/sshd/id_rsa -N "" -q -/usr/sbin/sshd -f ~/sshd/sshd_config - -# Set up keys -ssh-keygen -t rsa -f ~/.ssh/id_rsa -N "" -q -cat ~/.ssh/id_rsa.pub >>~/.ssh/authorized_keys -while read algorithm key comment; do - echo "[localhost]:2222 $algorithm $key" >>~/.ssh/known_hosts -done <~/sshd/id_rsa.pub - -# Get the fingerprint for localhost and remove the colons so we can parse it as -# a hex number. The Mac version is newer so it has a different output format. -if [ "$TRAVIS_OS_NAME" = "osx" ]; then - export GITTEST_REMOTE_SSH_FINGERPRINT=$(ssh-keygen -E md5 -F '[localhost]:2222' -l | tail -n 1 | cut -d ' ' -f 3 | cut -d : -f2- | tr -d :) -else - export GITTEST_REMOTE_SSH_FINGERPRINT=$(ssh-keygen -F '[localhost]:2222' -l | tail -n 1 | cut -d ' ' -f 2 | tr -d ':') -fi - -# Use the SSH server -export GITTEST_REMOTE_URL="ssh://localhost:2222/$HOME/_temp/test.git" -export GITTEST_REMOTE_USER=$USER -export GITTEST_REMOTE_SSH_KEY="$HOME/.ssh/id_rsa" -export GITTEST_REMOTE_SSH_PUBKEY="$HOME/.ssh/id_rsa.pub" -export GITTEST_REMOTE_SSH_PASSPHRASE="" -ctest -V -R libgit2_clar-ssh || exit $? - -# Use the proxy we started at the beginning -export GITTEST_REMOTE_PROXY_URL="localhost:8080" -export GITTEST_REMOTE_PROXY_USER="foo" -export GITTEST_REMOTE_PROXY_PASS="bar" -ctest -V -R libgit2_clar-proxy_credentials || exit $? - -kill $(cat "$HOME/sshd/pid") diff --git a/script/install-deps-osx.sh b/script/install-deps-osx.sh deleted file mode 100755 index 94314dbaac6..00000000000 --- a/script/install-deps-osx.sh +++ /dev/null @@ -1,9 +0,0 @@ -#!/bin/sh - -set -x - -brew update -brew install zlib -brew install curl -brew install openssl -brew install libssh2 diff --git a/src/transports/smart.c b/src/transports/smart.c index 6d5d95fbff5..5fedd394e7b 100644 --- a/src/transports/smart.c +++ b/src/transports/smart.c @@ -45,6 +45,11 @@ GIT_INLINE(int) git_smart__reset_stream(transport_smart *t, bool close_subtransp t->current_stream = NULL; } + if (t->url) { + git__free(t->url); + t->url = NULL; + } + if (close_subtransport && t->wrapped->close(t->wrapped) < 0) return -1; diff --git a/src/transports/winhttp.c b/src/transports/winhttp.c index e52d54b6d70..fbb69b3872d 100644 --- a/src/transports/winhttp.c +++ b/src/transports/winhttp.c @@ -845,23 +845,27 @@ static int winhttp_connect( static int do_send_request(winhttp_stream *s, size_t len, int ignore_length) { - if (ignore_length) { - if (!WinHttpSendRequest(s->request, - WINHTTP_NO_ADDITIONAL_HEADERS, 0, - WINHTTP_NO_REQUEST_DATA, 0, - WINHTTP_IGNORE_REQUEST_TOTAL_LENGTH, 0)) { - return -1; - } - } else { - if (!WinHttpSendRequest(s->request, - WINHTTP_NO_ADDITIONAL_HEADERS, 0, - WINHTTP_NO_REQUEST_DATA, 0, - len, 0)) { - return -1; + int attempts; + bool success; + + for (attempts = 0; attempts < 5; attempts++) { + if (ignore_length) { + success = WinHttpSendRequest(s->request, + WINHTTP_NO_ADDITIONAL_HEADERS, 0, + WINHTTP_NO_REQUEST_DATA, 0, + WINHTTP_IGNORE_REQUEST_TOTAL_LENGTH, 0); + } else { + success = WinHttpSendRequest(s->request, + WINHTTP_NO_ADDITIONAL_HEADERS, 0, + WINHTTP_NO_REQUEST_DATA, 0, + len, 0); } + + if (success || GetLastError() != SEC_E_BUFFER_TOO_SMALL) + break; } - return 0; + return success ? 0 : -1; } static int send_request(winhttp_stream *s, size_t len, int ignore_length) diff --git a/tests/buf/oom.c b/tests/buf/oom.c index b9fd29cbb0a..16a03cc1a3a 100644 --- a/tests/buf/oom.c +++ b/tests/buf/oom.c @@ -1,10 +1,22 @@ #include "clar_libgit2.h" #include "buffer.h" -#if defined(GIT_ARCH_64) -#define TOOBIG 0xffffffffffffff00 +/* + * We want to use some ridiculous size that `malloc` will fail with + * but that does not otherwise interfere with testing. On Linux, choose + * a number that is large enough to fail immediately but small enough + * that valgrind doesn't believe it to erroneously be a negative number. + * On macOS, choose a number that is large enough to fail immediately + * without having libc print warnings to stderr. + */ +#if defined(GIT_ARCH_64) && defined(__linux__) +# define TOOBIG 0x0fffffffffffffff +#elif defined(__linux__) +# define TOOBIG 0x0fffffff +#elif defined(GIT_ARCH_64) +# define TOOBIG 0xffffffffffffff00 #else -#define TOOBIG 0xffffff00 +# define TOOBIG 0xffffff00 #endif /** diff --git a/tests/online/clone.c b/tests/online/clone.c index 27b7b96610d..4d409cb77dd 100644 --- a/tests/online/clone.c +++ b/tests/online/clone.c @@ -263,6 +263,9 @@ static int cred_failure_cb( void test_online_clone__cred_callback_failure_return_code_is_tunnelled(void) { + git__free(_remote_url); _remote_url = NULL; + git__free(_remote_user); _remote_user = NULL; + _remote_url = git__strdup("https://github.com/libgit2/non-existent"); _remote_user = git__strdup("libgit2test"); @@ -293,6 +296,9 @@ void test_online_clone__cred_callback_called_again_on_auth_failure(void) { size_t counter = 0; + git__free(_remote_url); _remote_url = NULL; + git__free(_remote_user); _remote_user = NULL; + _remote_url = git__strdup("https://github.com/libgit2/non-existent"); _remote_user = git__strdup("libgit2test"); diff --git a/tests/online/push.c b/tests/online/push.c index f72b4f8cb22..3b98278e054 100644 --- a/tests/online/push.c +++ b/tests/online/push.c @@ -152,8 +152,12 @@ static void do_verify_push_status(record_callbacks_data *data, const push_status git_buf_free(&msg); } - git_vector_foreach(actual, i, iter) - git__free(iter); + git_vector_foreach(actual, i, iter) { + push_status *s = (push_status *)iter; + git__free(s->ref); + git__free(s->msg); + git__free(s); + } git_vector_free(actual); } @@ -393,7 +397,7 @@ void test_online_push__initialize(void) } git_remote_disconnect(_remote); - git_vector_free(&delete_specs); + git_vector_free_deep(&delete_specs); /* Now that we've deleted everything, fetch from the remote */ memcpy(&fetch_opts.callbacks, &_record_cbs, sizeof(git_remote_callbacks));