Skip to content

Commit ed63f73

Browse files
committed
tests: cache and verify hash value of sample images
1 parent 58d3a62 commit ed63f73

File tree

8 files changed

+124
-32
lines changed

8 files changed

+124
-32
lines changed

.github/workflows/build_wheels.yml

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,15 @@ jobs:
3131

3232
steps:
3333
- uses: actions/checkout@v4
34+
- name: Cache sample files
35+
id: cache_samples
36+
uses: actions/cache@v4
37+
with:
38+
path: "${{ github.workspace }}/sampledata/"
39+
key: sample-images
40+
- name: download sample files
41+
if: steps.cache_samples.outputs.cache-hit != 'true'
42+
run: curl -L https://nexus.library.illinois.edu/repository/sample-data/images/sample_images.tar.gz --create-dirs -o "${{ github.workspace }}/sampledata/sample_images.tar.gz"
3443
- uses: actions/setup-python@v5
3544
with:
3645
python-version: '3.11'
@@ -51,6 +60,7 @@ jobs:
5160
# uses: pypa/[email protected]
5261
env:
5362
CONAN_COMPILER_VERSION: ${{ matrix.compiler_version }}
63+
SAMPLE_IMAGES_ARCHIVE: "${{ github.workspace }}/sampledata/sample_images.tar.gz"
5464

5565
# CIBW_SOME_OPTION: value
5666
- uses: actions/upload-artifact@v4

.github/workflows/tox_matrix.yml

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -42,20 +42,28 @@ jobs:
4242
fail-fast: false
4343
name: Python ${{ matrix.python-version }} ${{ matrix.os }} build
4444
steps:
45-
4645
- uses: actions/checkout@v3
46+
- name: Cache sample files
47+
id: cache_samples
48+
uses: actions/cache@v4
49+
with:
50+
path: "${{ github.workspace }}/sampledata/"
51+
key: sample-images
52+
- name: download sample files
53+
if: steps.cache_samples.outputs.cache-hit != 'true'
54+
run: curl -L https://nexus.library.illinois.edu/repository/sample-data/images/sample_images.tar.gz --create-dirs -o "${{ github.workspace }}/sampledata/sample_images.tar.gz"
4755
- uses: actions/setup-python@v5
4856
with:
4957
python-version: ${{ matrix.python-version }}
5058
cache: 'pip' # caching pip dependencies
5159
- name: "install Python dependencies"
5260
run: |
5361
pip install uv
54-
- uses: actions/cache@v3
62+
- uses: actions/cache@v4
5563
id: cache
5664
with:
5765
path: "${{ matrix.conan_user_home }}/.conan2"
58-
key: ${{ runner.os }}-${{ hashFiles('**/conanfile.py') }}
66+
key: ${{ runner.os }}-${{ hashFiles('**/conanfile.py', 'conan.lock') }}
5967

6068
- name: Build conan packages on Non-Windows Operating Systems
6169
if: ${{ !contains(matrix.os, 'windows') && steps.cache.outputs.cache-hit != 'true' }}
@@ -80,10 +88,11 @@ jobs:
8088
"C:\Program Files\Microsoft Visual Studio\2022\Enterprise\Common7\Tools\VsDevCmd.bat" -arch=amd64 && uv run --only-group tox --with tox-uv tox -e ${{ steps.tox-env.outputs.result }}
8189
env:
8290
CONAN_USER_HOME: ${{ matrix.conan_user_home }}
91+
SAMPLE_IMAGES_ARCHIVE: "${{ github.workspace }}/sampledata/sample_images.tar.gz"
8392
- name: Run tox
8493
if: "!contains(matrix.os, 'windows')"
8594
run: cc --version && cc -dumpfullversion -dumpversion && uv run --only-group tox --with tox-uv tox -e ${{ steps.tox-env.outputs.result }} -vvv
8695
env:
8796
CONAN_COMPILER_LIBCXX: ${{ matrix.compiler_libcxx }}
8897
CONAN_USER_HOME: ${{ matrix.conan_user_home }}
89-
98+
SAMPLE_IMAGES_ARCHIVE: "${{ github.workspace }}/sampledata/sample_images.tar.gz"

ci/docker/linux/jenkins/Dockerfile

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
ARG CONAN_USER_HOME=/conan
22
ARG CONAN_HOME=${CONAN_USER_HOME}/.conan2
33

4+
ARG SAMPLE_IMAGES_URL=https://nexus.library.illinois.edu/repository/sample-data/images/sample_images.tar.gz
5+
46
ARG PYTHON_VERSION=latest
57

68
ARG CONAN_CENTER_PROXY_V2_URL=https://center2.conan.io
@@ -33,6 +35,12 @@ RUN mkdir -p /.cache/pip && \
3335
#==============================================================================
3436

3537

38+
FROM base_image AS sample_files_downloader
39+
ARG SAMPLE_IMAGES_URL
40+
ENV EXPECTED_SHA256="0461f57db3806ca47d9063151eec4bc0720c66a83153dda04e230f838b64f063"
41+
RUN mkdir /sampledata && wget $SAMPLE_IMAGES_URL -P /sampledata && echo "$EXPECTED_SHA256 /sampledata/sample_images.tar.gz" | sha256sum --check
42+
43+
3644
FROM base_image AS sonar_builder
3745
ARG SONAR_USER_HOME
3846

@@ -141,11 +149,14 @@ COPY --from=dr_memory_builder /opt/drmemory /opt/drmemory/
141149
RUN ln -s /opt/drmemory/bin64/drmemory /usr/local/bin/drmemory && \
142150
drmemory -version
143151

152+
COPY --from=sample_files_downloader /sampledata /sampledata
153+
144154
ARG CONAN_USER_HOME
145155
ARG CONAN_HOME
146156
COPY --from=conan_builder --chmod=777 ${CONAN_HOME} ${CONAN_HOME}
147157
ENV CONAN_USER_HOME=${CONAN_USER_HOME}\
148-
CONAN_HOME=${CONAN_HOME}
158+
CONAN_HOME=${CONAN_HOME}\
159+
SAMPLE_IMAGES_ARCHIVE=/sampledata/sample_images.tar.gz
149160

150161
# To help mark the image as a CI image so it can be cleaned up more easily
151162
LABEL purpose=ci

ci/docker/linux/tox/Dockerfile

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ ARG CONAN_CENTER_PROXY_V2_URL=https://center2.conan.io
1111
# If you want to use a diffrent remote for Conan, such as a proxy. Set the CONAN_CENTER_PROXY_V2_URL
1212
# Not this is only for building the image. The actual conan center proxy URL is set in the remotes.json file.
1313

14+
ARG SAMPLE_IMAGES_URL=https://nexus.library.illinois.edu/repository/sample-data/images/sample_images.tar.gz
15+
1416
FROM ghcr.io/astral-sh/uv:latest AS uv_builder
1517

1618
FROM ubuntu:24.04 AS base
@@ -25,6 +27,18 @@ RUN --mount=type=cache,target=/var/cache/apt,sharing=locked \
2527
< /tmp/apt-packages.txt xargs apt-get install -y && \
2628
apt-get clean && \
2729
rm -rf /var/lib/apt/lists/*
30+
31+
# ==============================================================================
32+
FROM base AS sample_files_downloader
33+
RUN --mount=type=cache,target=/var/cache/apt,sharing=locked \
34+
apt-get update && \
35+
apt-get install -y wget
36+
37+
ARG SAMPLE_IMAGES_URL
38+
ENV EXPECTED_SHA256="0461f57db3806ca47d9063151eec4bc0720c66a83153dda04e230f838b64f063"
39+
40+
RUN mkdir /sampledata && wget $SAMPLE_IMAGES_URL -P /sampledata && echo "$EXPECTED_SHA256 /sampledata/sample_images.tar.gz" | sha256sum --check
41+
2842
# ==============================================================================
2943

3044
FROM base AS conan_builder
@@ -74,9 +88,11 @@ FROM base
7488
COPY --from=uv_builder /uv /uvx /bin/
7589
ARG CONAN_USER_HOME
7690
ARG CONAN_HOME
91+
COPY --from=sample_files_downloader /sampledata /sampledata
7792
COPY --from=conan_builder --chmod=777 ${CONAN_HOME}/ ${CONAN_HOME}/
7893
ENV CONAN_USER_HOME=${CONAN_USER_HOME}\
79-
CONAN_HOME=${CONAN_HOME}
94+
CONAN_HOME=${CONAN_HOME}\
95+
SAMPLE_IMAGES_ARCHIVE=/sampledata/sample_images.tar.gz
8096

8197
# To help mark the image as a CI image so it can be cleaned up more easily
8298
LABEL purpose=ci

scripts/resources/windows/tox/Dockerfile

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@ ARG PIP_DOWNLOAD_CACHE=c:/users/containeradministrator/appdata/local/pip
1515
ARG CHOCOLATEY_SOURCE=https://chocolatey.org/api/v2
1616
ARG chocolateyVersion
1717

18+
ARG SAMPLE_IMAGES_URL=https://nexus.library.illinois.edu/repository/sample-data/images/sample_images.tar.gz
19+
1820
FROM ${FROM_IMAGE} AS certsgen
1921
RUN certutil -generateSSTFromWU roots.sst
2022

@@ -61,6 +63,16 @@ RUN Set-ExecutionPolicy Bypass -Scope Process -Force; `
6163
Write-Host "Verifying installed packages - Done"
6264

6365

66+
# ==============================================================================
67+
FROM base_builder AS sample_files_downloader
68+
ARG SAMPLE_IMAGES_URL
69+
ENV EXPECTED_SHA256="0461f57db3806ca47d9063151eec4bc0720c66a83153dda04e230f838b64f063"
70+
ENV downloadPath="C:/sampledata/"
71+
RUN if (-not (Test-Path -Path ${env:downloadPath} -PathType Container)) {`
72+
New-Item -Path ${env:downloadPath} -ItemType Directory -Force`
73+
}; `
74+
Invoke-WebRequest -Uri ${env:SAMPLE_IMAGES_URL} -OutFile "${env:downloadPath}\sample_images.tar.gz"
75+
6476
# ==============================================================================
6577
FROM base_builder AS conan_builder
6678
ARG CONAN_HOME
@@ -105,11 +117,14 @@ RUN New-Item -type directory -path ${Env:PIP_DOWNLOAD_CACHE} -Force | Out-Null ;
105117
New-Item -type directory -path ${Env:UV_CACHE_DIR} -Force | Out-Null
106118
ARG CONAN_HOME
107119
COPY --from=conan_builder ${CONAN_HOME}/ ${CONAN_HOME}/
120+
COPY --from=sample_files_downloader c:/sampledata/ C:/sampledata/
121+
108122
ARG CONAN_USER_HOME
109123
ENV CONAN_USER_HOME=${CONAN_USER_HOME}`
110124
CONAN_HOME=${CONAN_HOME}`
111125
PIP_DOWNLOAD_CACHE=${PIP_DOWNLOAD_CACHE}`
112-
UV_CACHE_DIR=${UV_CACHE_DIR}
126+
UV_CACHE_DIR=${UV_CACHE_DIR}`
127+
SAMPLE_IMAGES_ARCHIVE=C:/sampledata/sample_images.tar.gz
113128

114129
WORKDIR C:/src
115130
ENV DISTUTILS_USE_SDK=1

tests/CMakeLists.txt

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,25 @@
11
include(FetchContent)
22
if (BUILD_TESTING AND Catch2_FOUND)
33
include(Catch)
4-
FetchContent_Declare(test_images
4+
set(SAMPLE_IMAGES_ARCHIVE "" CACHE FILEPATH "Path to sample images archive. If not set, it will be downloaded from the internet.")
5+
if(SAMPLE_IMAGES_ARCHIVE)
6+
set(TEST_IMAGE_PATH "${CMAKE_CURRENT_BINARY_DIR}/sample_images/")
7+
file(ARCHIVE_EXTRACT
8+
INPUT "${SAMPLE_IMAGES_ARCHIVE}"
9+
DESTINATION "${CMAKE_CURRENT_BINARY_DIR}/"
10+
)
11+
else ()
12+
FetchContent_Declare(test_images
513
URL https://nexus.library.illinois.edu/repository/sample-data/images/sample_images.tar.gz
14+
URL_HASH SHA256=0461f57db3806ca47d9063151eec4bc0720c66a83153dda04e230f838b64f063
615
SOURCE_DIR ${CMAKE_CURRENT_BINARY_DIR}/sample_images
7-
)
8-
FetchContent_GetProperties(test_images)
9-
FetchContent_MakeAvailable(test_images)
10-
find_path(TEST_IMAGE_PATH dummy.jp2
11-
PATHS ${test_images_SOURCE_DIR})
12-
set(TEST_IMAGE_PATH ${TEST_IMAGE_PATH}/)
16+
)
17+
FetchContent_GetProperties(test_images)
18+
FetchContent_MakeAvailable(test_images)
19+
find_path(TEST_IMAGE_PATH dummy.jp2
20+
PATHS ${test_images_SOURCE_DIR})
21+
set(TEST_IMAGE_PATH ${TEST_IMAGE_PATH}/)
22+
endif ()
1323
set(PYTHON_TEST_FILES test_core.py)
1424
find_package(Python3 COMPONENTS Interpreter)
1525
if(pyexiv2bind_generate_python_bindings)

tests/conftest.py

Lines changed: 38 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,37 @@
11
import os
22
import shutil
33
import tarfile
4+
import hashlib
45

56
import pytest
67
import urllib.request
78

9+
SAMPLE_IMAGES_SHA256 = "0461f57db3806ca47d9063151eec4bc0720c66a83153dda04e230f838b64f063"
10+
SAMPLE_IMAGES_URL = "https://nexus.library.illinois.edu/repository/sample-data/images/sample_images.tar.gz"
811

9-
def download_images(url, destination, download_path):
12+
# To save time from redownloading the sample_images.tar.gz file every time,
13+
# download it locally and set the environment variable SAMPLE_IMAGES_ARCHIVE
14+
# to the path of the downloaded file
1015

11-
print("Downloading {}".format(url))
12-
urllib.request.urlretrieve(url,
13-
filename=os.path.join(download_path, "sample_images.tar.gz"))
14-
if not os.path.exists(os.path.join(download_path, "sample_images.tar.gz")):
16+
def download_images(url, download_path):
17+
18+
print(f"Downloading {url}")
19+
output = os.path.join(download_path, "sample_images.tar.gz")
20+
urllib.request.urlretrieve(url, filename=output)
21+
if not os.path.exists(output):
1522
raise FileNotFoundError("sample images not download")
16-
print("Extracting images")
17-
with tarfile.open(os.path.join(download_path, "sample_images.tar.gz"), "r:gz") as archive_file:
18-
for item in archive_file.getmembers():
19-
print("Extracting {}".format(item.name))
20-
archive_file.extract(item, path=destination)
21-
pass
23+
return output
24+
def extract_images(path, destination):
25+
print("Extracting images")
26+
with tarfile.open(path, "r:gz") as archive_file:
27+
for item in archive_file.getmembers():
28+
print("Extracting {}".format(item.name))
29+
archive_file.extract(item, path=destination)
30+
31+
def verify_hash(path, sha256_hash):
32+
with open(path, "rb") as f:
33+
file_hash = hashlib.sha256(f.read()).hexdigest()
34+
assert file_hash == sha256_hash
2235

2336

2437
@pytest.fixture(scope="session")
@@ -28,16 +41,23 @@ def sample_images_readonly(tmpdir_factory):
2841
sample_images_path = os.path.join(test_path, "sample_images")
2942
download_path = tmpdir_factory.mktemp("downloaded_archives", numbered=False)
3043
if os.path.exists(sample_images_path):
31-
print("{} already exits".format(sample_images_path))
44+
print(f"{sample_images_path} already exits")
3245

3346
else:
34-
print("Downloading sample images")
35-
download_images(url="https://nexus.library.illinois.edu/repository/sample-data/images/sample_images.tar.gz",
36-
destination=test_path,
37-
download_path=download_path)
38-
47+
archive = os.getenv('SAMPLE_IMAGES_ARCHIVE')
48+
if not archive:
49+
print("Downloading sample images")
50+
archive = download_images(
51+
url=SAMPLE_IMAGES_URL,
52+
download_path=download_path
53+
)
54+
if not os.path.exists(archive):
55+
raise FileNotFoundError(f"sample image archive not found. {archive} does not exist.")
56+
verify_hash(archive, sha256_hash=SAMPLE_IMAGES_SHA256)
57+
extract_images(path=archive, destination=test_path)
3958
yield sample_images_path
40-
shutil.rmtree(test_path)
59+
if os.path.exists(test_path):
60+
shutil.rmtree(test_path)
4161

4262

4363
@pytest.fixture

tox.ini

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ passenv =
1717
LIB
1818
LIBPATH
1919
DISTUTILS_USE_SDK
20+
SAMPLE_IMAGES_ARCHIVE
2021

2122
commands_pre =
2223
{env_bin_dir}{/}python {tox_root}/scripts/get_linked_exiv2_version.py

0 commit comments

Comments
 (0)