From 8d22b774c73830ae597c56415ae907aeac5f06ba Mon Sep 17 00:00:00 2001 From: Ryan Sanford Date: Wed, 7 Jun 2017 07:59:09 -0500 Subject: [PATCH 01/10] Make sniper compatible with orthanc --- bin/dicom_sniper | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/bin/dicom_sniper b/bin/dicom_sniper index a720028..33275bb 100755 --- a/bin/dicom_sniper +++ b/bin/dicom_sniper @@ -44,6 +44,7 @@ auth_group.add_argument('--key', help='user API key') args = arg_parser.parse_args(sys.argv[1:] or ['--help']) args.query = dict(args.query) + args.timezone = reaper.util.validate_timezone(args.timezone) if args.timezone is None: log.error('invalid timezone') @@ -60,9 +61,12 @@ matched_series = {} for study in scu_studies: scu_series = scu_.find(reaper.scu.SeriesQuery(**reaper.scu.SCUQuery(StudyInstanceUID=study.StudyInstanceUID))) for series in scu_series: - if series.NumberOfSeriesRelatedInstances is None: + if not series.NumberOfSeriesRelatedInstances: scu_images = scu_.find(reaper.scu.ImageQuery(**reaper.scu.SCUQuery(SeriesInstanceUID=series.SeriesInstanceUID))) series.NumberOfSeriesRelatedInstances = len(scu_images) + log.error(len(scu_images)) + log.error(series.NumberOfSeriesRelatedInstances) + log.error(series.NumberOfSeriesRelatedInstances) matched_series[series.SeriesInstanceUID] = { 'study_uid': study.StudyInstanceUID, 'image_cnt': int(series.NumberOfSeriesRelatedInstances), From 5db36e2f3a40ff6dc625d0985f5eb5cfd4391385 Mon Sep 17 00:00:00 2001 From: Ryan Sanford Date: Wed, 7 Jun 2017 07:59:29 -0500 Subject: [PATCH 02/10] Rough outline of dockerized test pattern --- .dockerignore | 4 + .gitignore | 1 + docker/Dockerfile-orthanc | 20 +++ docker/orthanc-config.json | 261 +++++++++++++++++++++++++++++++++++++ docker/test.sh | 106 +++++++++++++++ test/bin/test.sh | 100 ++++++++++++++ test/requirements.txt | 1 - 7 files changed, 492 insertions(+), 1 deletion(-) create mode 100644 docker/Dockerfile-orthanc create mode 100644 docker/orthanc-config.json create mode 100755 docker/test.sh create mode 100755 test/bin/test.sh diff --git a/.dockerignore b/.dockerignore index f78244c..5f6b13d 100644 --- a/.dockerignore +++ b/.dockerignore @@ -1,4 +1,8 @@ +.git + +# --- Below Should mirror .gitignore, without leading '/' --- # .DS_Store .*sw[op] *.py[co] *.egg-info +testdata diff --git a/.gitignore b/.gitignore index f78244c..cf8c79a 100644 --- a/.gitignore +++ b/.gitignore @@ -2,3 +2,4 @@ .*sw[op] *.py[co] *.egg-info +testdata diff --git a/docker/Dockerfile-orthanc b/docker/Dockerfile-orthanc new file mode 100644 index 0000000..caf26ca --- /dev/null +++ b/docker/Dockerfile-orthanc @@ -0,0 +1,20 @@ +# +# Image used for hosting . +# +# Example usage is in README.md +# + +FROM ubuntu:16.04 + + +# Install pre-requisites +RUN apt-get update \ + && apt-get install -y --no-install-recommends \ + ca-certificates curl \ + dcmtk \ + orthanc \ + && rm -rf /var/lib/apt/lists/* + +COPY orthanc-config.json /etc/orthanc/orthanc-reaper-config.json + +ENTRYPOINT ["Orthanc", "/etc/orthanc/orthanc-reaper-config.json"] diff --git a/docker/orthanc-config.json b/docker/orthanc-config.json new file mode 100644 index 0000000..b334ca4 --- /dev/null +++ b/docker/orthanc-config.json @@ -0,0 +1,261 @@ +{ +/** + * General configuration of Orthanc + **/ + +// The logical name of this instance of Orthanc. This one is +// displayed in Orthanc Explorer and at the URI "/system". +"Name" : "Orthanc", + +// Path to the directory that holds the heavyweight files +// (i.e. the raw DICOM instances) +"StorageDirectory" : "/var/lib/orthanc/db-v6", + +// Path to the directory that holds the SQLite index (if unset, +// the value of StorageDirectory is used). This index could be +// stored on a RAM-drive or a SSD device for performance reasons. +"IndexDirectory" : "/var/lib/orthanc/db-v6", + +// Enable the transparent compression of the DICOM instances +"StorageCompression" : false, + +// Maximum size of the storage in MB (a value of "0" indicates no +// limit on the storage size) +"MaximumStorageSize" : 0, + +// Maximum number of patients that can be stored at a given time +// in the storage (a value of "0" indicates no limit on the number +// of patients) +"MaximumPatientCount" : 0, + +// List of paths to the custom Lua scripts that are to be loaded +// into this instance of Orthanc +"LuaScripts" : [ +], + +// List of paths to the plugins that are to be loaded into this +// instance of Orthanc (e.g. "./libPluginTest.so" for Linux, or +// "./PluginTest.dll" for Windows). These paths can refer to +// folders, in which case they will be scanned non-recursively to +// find shared libraries. +"Plugins" : [ + "/usr/share/orthanc/plugins/" +], + + + +/** + * Configuration of the HTTP server + **/ + +// Enable the HTTP server. If this parameter is set to "false", +// Orthanc acts as a pure DICOM server. The REST API and Orthanc +// Explorer will not be available. +"HttpServerEnabled" : true, + +// HTTP port for the REST services and for the GUI +"HttpPort" : 8042, + +// When the following option is "true", if an error is encountered +// while calling the REST API, a JSON message describing the error +// is put in the HTTP answer. This feature can be disabled if the +// HTTP client does not properly handles such answers. +"HttpDescribeErrors" : true, + +// Enable HTTP compression to improve network bandwidth utilization, +// at the expense of more computations on the server. Orthanc +// supports the "gzip" and "deflate" HTTP encodings. +"HttpCompressionEnabled" : true, + + + +/** + * Configuration of the DICOM server + **/ + +// Enable the DICOM server. If this parameter is set to "false", +// Orthanc acts as a pure REST server. It will not be possible to +// receive files or to do query/retrieve through the DICOM protocol. +"DicomServerEnabled" : true, + +// The DICOM Application Entity Title +"DicomAet" : "ORTHANC", + +// Check whether the called AET corresponds during a DICOM request +"DicomCheckCalledAet" : false, + +// The DICOM port +"DicomPort" : 4242, + +// The default encoding that is assumed for DICOM files without +// "SpecificCharacterSet" DICOM tag. The allowed values are "Ascii", +// "Utf8", "Latin1", "Latin2", "Latin3", "Latin4", "Latin5", +// "Cyrillic", "Windows1251", "Arabic", "Greek", "Hebrew", "Thai", +// "Japanese", and "Chinese". +"DefaultEncoding" : "Latin1", + +// The transfer syntaxes that are accepted by Orthanc C-Store SCP +"DeflatedTransferSyntaxAccepted" : true, +"JpegTransferSyntaxAccepted" : true, +"Jpeg2000TransferSyntaxAccepted" : true, +"JpegLosslessTransferSyntaxAccepted" : true, +"JpipTransferSyntaxAccepted" : true, +"Mpeg2TransferSyntaxAccepted" : true, +"RleTransferSyntaxAccepted" : true, + +// Whether Orthanc accepts to act as C-Store SCP for unknown storage +// SOP classes (aka. "promiscuous mode") +"UnknownSopClassAccepted" : true, + + + +/** + * Security-related options for the HTTP server + **/ + +// Whether remote hosts can connect to the HTTP server +"RemoteAccessAllowed" : true, + +// Whether or not SSL is enabled +"SslEnabled" : false, + +// Path to the SSL certificate (meaningful only if SSL is enabled) +"SslCertificate" : "certificate.pem", + +// Whether or not the password protection is enabled +"AuthenticationEnabled" : false, + +// The list of the registered users. Because Orthanc uses HTTP +// Basic Authentication, the passwords are stored as plain text. +"RegisteredUsers" : { + // "alice" : "alicePassword" +}, + + + +/** + * Network topology + **/ + +// The list of the known DICOM modalities +"DicomModalities" : { + "flywheelCore" : [ "REAPER", "reaper-test", 5104] +}, + +// The list of the known Orthanc peers +"OrthancPeers" : { +}, + +// Parameters of the HTTP proxy to be used by Orthanc. If set to the +// empty string, no HTTP proxy is used. For instance: +// "HttpProxy" : "192.168.0.1:3128" +// "HttpProxy" : "proxyUser:proxyPassword@192.168.0.1:3128" +"HttpProxy" : "", + +// Set the timeout for HTTP requests issued by Orthanc (in seconds). +"HttpTimeout" : 10, + +// Enable the verification of the peers during HTTPS requests. +// Reference: http://curl.haxx.se/docs/sslcerts.html +"HttpsVerifyPeers" : true, + +// Path to the CA (certification authority) certificates to validate +// peers in HTTPS requests. From curl documentation ("--cacert" +// option): "Tells curl to use the specified certificate file to +// verify the peers. The file may contain multiple CA +// certificates. The certificate(s) must be in PEM format." +"HttpsCACertificates" : "", + + + +/** + * Advanced options + **/ + +// Dictionary of symbolic names for the user-defined metadata. Each +// entry must map an unique string to an unique number between 1024 +// and 65535. +"UserMetadata" : { + // "Sample" : 1024 +}, + +// Dictionary of symbolic names for the user-defined types of +// attached files. Each entry must map an unique string to an unique +// number between 1024 and 65535. Optionally, a second argument can +// provided to specify a MIME content type for the attachment. +"UserContentType" : { + // "sample" : 1024 + // "sample2" : [ 1025, "application/pdf" ] +}, + +// Number of seconds without receiving any instance before a +// patient, a study or a series is considered as stable. +"StableAge" : 60, + +// By default, Orthanc compares AET (Application Entity Titles) in a +// case-insensitive way. Setting this option to "true" will enable +// case-sensitive matching. +"StrictAetComparison" : false, + +// When the following option is "true", the MD5 of the DICOM files +// will be computed and stored in the Orthanc database. This +// information can be used to detect disk corruption, at the price +// of a small performance overhead. +"StoreMD5ForAttachments" : true, + +// The maximum number of results for a single C-FIND request at the +// Patient, Study or Series level. Setting this option to "0" means +// no limit. +"LimitFindResults" : 0, + +// The maximum number of results for a single C-FIND request at the +// Instance level. Setting this option to "0" means no limit. +"LimitFindInstances" : 0, + +// The maximum number of active jobs in the Orthanc scheduler. When +// this limit is reached, the addition of new jobs is blocked until +// some job finishes. +"LimitJobs" : 10, + +// If this option is set to "false", Orthanc will not log the +// resources that are exported to other DICOM modalities of Orthanc +// peers in the URI "/exports". This is useful to prevent the index +// to grow indefinitely in auto-routing tasks. +"LogExportedResources" : true, + +// Enable or disable HTTP Keep-Alive (deprecated). Set this option +// to "true" only in the case of high HTTP loads. +"KeepAlive" : false, + +// If this option is set to "false", Orthanc will run in index-only +// mode. The DICOM files will not be stored on the drive. Note that +// this option might prevent the upgrade to newer versions of Orthanc. +"StoreDicom" : true, + +// DICOM associations are kept open as long as new DICOM commands +// are issued. This option sets the number of seconds of inactivity +// to wait before automatically closing a DICOM association. If set +// to 0, the connection is closed immediately. +"DicomAssociationCloseDelay" : 5, + +// Maximum number of query/retrieve DICOM requests that are +// maintained by Orthanc. The least recently used requests get +// deleted as new requests are issued. +"QueryRetrieveSize" : 10, + +// When handling a C-Find SCP request, setting this flag to "true" +// will enable case-sensitive match for PN value representation +// (such as PatientName). By default, the search is +// case-insensitive, which does not follow the DICOM standard. +"CaseSensitivePN" : false, + +// Register a new tag in the dictionary of DICOM tags that are known +// to Orthanc. Each line must contain the tag (formatted as 2 +// hexadecimal numbers), the value representation (2 upcase +// characters), a nickname for the tag, possibly the minimum +// multiplicity (> 0 with defaults to 1), and possibly the maximum +// multiplicity (0 means arbitrary multiplicity, defaults to 1). +"Dictionary" : { + // "0014,1020" : [ "DA", "ValidationExpiryDate", 1, 1 ] +} +} diff --git a/docker/test.sh b/docker/test.sh new file mode 100755 index 0000000..877059c --- /dev/null +++ b/docker/test.sh @@ -0,0 +1,106 @@ +#!/usr/bin/env bash + +set -ex + +unset CDPATH +cd "$( dirname "${BASH_SOURCE[0]}" )/.." + +function usage() { +cat >&2 < 0 ]]; do + case "$1" in + -B|--no-build) DOCKER_BUILD=false; ;; + -h|--help) usage; exit 0;; + *) echo "Invalid argument: $1" >&2; usage; exit 1;; + esac + shift + done + + if $DOCKER_BUILD ; then + # build this repo + docker build -t reaper-test . + + # build dependencies + docker build -t orthanc-test -f docker/Dockerfile-orthanc docker/ + fi + + #Spin up dependencies + docker network create reaper-test + + + # Orthanc + # calledAE = ORTHANC 4242 + # REST port = 8042 + docker run -d --rm --name orthanc-test --network reaper-test orthanc-test + + + # scitran-core + docker run -d --rm --name scitran-core-mongo --network reaper-test mongo + docker run -d --rm --name scitran-core \ + --network reaper-test \ + -e "SCITRAN_PERSISTENT_DB_URI=mongodb://scitran-core-mongo:27017/scitran" \ + -e "SCITRAN_PERSISTENT_DB_LOG_URI=mongodb://scitran-core-mongo:27017/logs" \ + -e "SCITRAN_CORE_DRONE_SECRET=secret" \ + scitran/core + + + # Fetch test data + TESTDATA_DIR="./testdata" + mkdir -p $TESTDATA_DIR + if [ ! "$(ls -A $TESTDATA_DIR)" ]; then + curl -L https://github.com/scitran/testdata/archive/master.tar.gz | tar xz -C "$TESTDATA_DIR" --strip-components 1 + fi + + + docker run -it \ + --rm \ + --name reaper-test \ + --network reaper-test \ + -v "$(pwd)/testdata:/testdata" \ + -v "$(pwd)/bin:/src/reaper/bin" \ + -v "$(pwd)/reaper:/src/reaper/reaper" \ + -v "$(pwd)/test:/src/reaper/test" \ + reaper-test \ + /src/reaper/test/bin/test.sh \ + --testdata /testdata \ + --core http://scitran-core:8080 secret \ + --dicom-scp-host orthanc-test + --dicom-scp-port 4242 + --dicom-scp-aet ORTHANC + --orthanc http://orthanc-test:8042 +} + +clean_up () {( + set +e + + # Spin down dependencies + docker logs scitran-core-mongo + docker stop scitran-core-mongo + + docker logs scitran-core + docker stop scitran-core + + docker logs orthanc-test + docker stop orthanc-test + + docker network rm reaper-test +)} +trap clean_up EXIT + +main "$@" diff --git a/test/bin/test.sh b/test/bin/test.sh new file mode 100755 index 0000000..d105989 --- /dev/null +++ b/test/bin/test.sh @@ -0,0 +1,100 @@ +#!/usr/bin/env bash + +set -e + +function usage() { +cat >&2 < 0 ]]; do + case "$1" in + -L|--no-lint) RUN_LINT=false; ;; + -U|--no-unit) RUN_UNIT=false; ;; + --core) + CORE_URL="$2" + CORE_SECRET="$3" + shift 2;; + --dicom-scp-host) + DICOM_SCP_HOST="$2" + shift;; + --dicom-scp-port) + DICOM_SCP_PORT="$2" + shift;; + --dicom-scp-aet) + DICOM_SCP_AET="$2" + shift;; + --orthanc) + ORTHANC_REST_URL="$2" + shift;; + --testdata) + TESTDATA_DIR="$2" + shift;; + --) PYTEST_ARGS="${@:2}"; break;; + -h|--help) usage; exit 0;; + *) echo "Invalid argument: $1" >&2; usage; exit 1;; + esac + shift + done + + if ${RUN_LINT} ; then + echo + echo "Running pylint ..." + pylint --jobs=2 --reports=no --disable=R1705 reaper + + echo + echo "Running pep8 ..." + pep8 --max-line-length=150 --ignore=E402 reaper + fi + + if ${RUN_UNIT} ; then + echo + echo "Running unit tests ..." + #TODO: add unit tests + fi + + # TODO: Make this conditional for tests that require it. + storescu -v --scan-directories -aec "${DICOM_SCP_AET}" "${DICOM_SCP_HOST}" "${DICOM_SCP_PORT}" $(find $TESTDATA_DIR -type d -name dicom | tail -n 1) + + # Test DICOM Sniper + dicom_sniper -y --secret "${CORE_SECRET}" -k StudyID "" "${DICOM_SCP_HOST}" "${DICOM_SCP_PORT}" 5104 REAPER "${DICOM_SCP_AET}" "${CORE_URL}" + + + # Test DICOM Reaper + dicom_reaper -o -s 1 --secret "${CORE_SECRET}" $(mktemp) "${DICOM_SCP_HOST}" "${DICOM_SCP_PORT}" 5104 REAPER "${DICOM_SCP_AET}" "${CORE_URL}" + + + # Test Folder Sniper + folder_sniper -y --secret "${CORE_SECRET}" "${TESTDATA_DIR}" "${CORE_URL}" + + + orthanc_reaper -o -s 1 --secret "${CORE_SECRET}" $(mktemp) "${DICOM_SCP_HOST}" "${DICOM_SCP_PORT}" 5104 REAPER "${DICOM_SCP_AET}" "${ORTHANC_REST_URL}" "${CORE_URL}" + + + sleep 10000 +} + + +main "$@" diff --git a/test/requirements.txt b/test/requirements.txt index bb825fa..cfa44af 100644 --- a/test/requirements.txt +++ b/test/requirements.txt @@ -1,3 +1,2 @@ pep8 pylint -uwsgi From 18470b33e97c47a36cde76dbc4e2eb49bb4f00a9 Mon Sep 17 00:00:00 2001 From: Ryan Sanford Date: Thu, 8 Jun 2017 08:59:20 -0500 Subject: [PATCH 03/10] Remove debugging log messages --- bin/dicom_sniper | 3 --- 1 file changed, 3 deletions(-) diff --git a/bin/dicom_sniper b/bin/dicom_sniper index 33275bb..1049727 100755 --- a/bin/dicom_sniper +++ b/bin/dicom_sniper @@ -64,9 +64,6 @@ for study in scu_studies: if not series.NumberOfSeriesRelatedInstances: scu_images = scu_.find(reaper.scu.ImageQuery(**reaper.scu.SCUQuery(SeriesInstanceUID=series.SeriesInstanceUID))) series.NumberOfSeriesRelatedInstances = len(scu_images) - log.error(len(scu_images)) - log.error(series.NumberOfSeriesRelatedInstances) - log.error(series.NumberOfSeriesRelatedInstances) matched_series[series.SeriesInstanceUID] = { 'study_uid': study.StudyInstanceUID, 'image_cnt': int(series.NumberOfSeriesRelatedInstances), From 3806a2941407eadea8cd50c500788faca8fcf3c5 Mon Sep 17 00:00:00 2001 From: Ryan Sanford Date: Thu, 8 Jun 2017 12:04:45 -0500 Subject: [PATCH 04/10] Resolve pylint issue --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index da15f31..b5d592e 100644 --- a/setup.py +++ b/setup.py @@ -6,7 +6,7 @@ 'pydicom', 'python-dateutil', 'pytz', - 'requests', + 'requests<2.16', 'requests_toolbelt', 'tzlocal', ] From 7f82a90ccc151a95555cb1d11c745601184e7568 Mon Sep 17 00:00:00 2001 From: Ryan Sanford Date: Thu, 8 Jun 2017 12:05:29 -0500 Subject: [PATCH 05/10] Latest rev using travis cache for testing --- .travis.yml | 34 ++++++--------- docker/test.sh | 70 ++++++++++++++++++++---------- test/{ => bin}/lint.sh | 10 ++--- test/bin/test.sh | 71 +++++++++++++++++++----------- test/install_deps.sh | 32 -------------- test/test.sh | 91 --------------------------------------- test/upload_receiver.wsgi | 6 --- 7 files changed, 114 insertions(+), 200 deletions(-) rename test/{ => bin}/lint.sh (54%) delete mode 100755 test/install_deps.sh delete mode 100755 test/test.sh delete mode 100644 test/upload_receiver.wsgi diff --git a/.travis.yml b/.travis.yml index 6d6eba0..2a80094 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,39 +1,33 @@ sudo: false -language: python -python: - - "2.7" +dist: trusty +services: + - docker env: global: - - DCMTK_VERSION="dcmtk-3.6.1_20150924" - - DCMTK_DB_DIR="dcmtk_dicom_db" - - TESTDATA_DIR="testdata" - - ORTHANC_VERSION="Orthanc-1.1.0" + - TESTDATA_DIR="$HOME/.cache/testdata" + - DOCKER_DIR="$HOME/.cache/docker" - secure: tLyIDfETpHCDRyEqF2ROM8ue+D+fl/IeOdFBY/Mov7zhAHpgBdQQJi+HQ1/RK+G7DDsnM/FIjvCcf4etphmBHK3xs8vDM1oPntYs+3iE2AbTcVGglHYoX1++H76xPt3eXyf1S0frgVg6qYCNmuP0chhDUkYXPydcKvq1ANjfTQU= # BUILD_TRIGGER_URL cache: - pip: true directories: - - $DCMTK_VERSION - - $DCMTK_DB_DIR - $TESTDATA_DIR - - $ORTHANC_VERSION + - $DOCKER_DIR + -addons: - apt: - packages: - - uuid-dev before_install: - ln -s bin $VIRTUAL_ENV/sbin -install: - - pip install . - - pip install -r test/requirements.txt - - ./test/install_deps.sh +install: tr script: - - ./test/lint.sh && ./test/test.sh + - test -f "$DOCKER_DIR/image.tar" && sudo docker load -i "$DOCKER_DIR/image.tar" || true + - docker build -t my_image . + - docker save -o "$DOCKER_DIR/image.tar" $(docker history -q my_image | grep -v '') + - mkdir -p "$TESTDATA_DIR" + - curl -L https://github.com/scitran/testdata/archive/master.tar.gz | tar xz -C "$TESTDATA_DIR" --strip-components 1 + - ./docker/test.sh --testdata "$TESTDATA_DIR" after_success: - if [ "$TRAVIS_TAG" ]; then diff --git a/docker/test.sh b/docker/test.sh index 877059c..82bd397 100755 --- a/docker/test.sh +++ b/docker/test.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash -set -ex +set -e unset CDPATH cd "$( dirname "${BASH_SOURCE[0]}" )/.." @@ -10,24 +10,37 @@ cat >&2 < Path to testdata. EOF } function main() { local DOCKER_BUILD=true + local TEST_ARGS= + local TESTDATA_DIR= while [[ "$#" > 0 ]]; do case "$1" in - -B|--no-build) DOCKER_BUILD=false; ;; - -h|--help) usage; exit 0;; - *) echo "Invalid argument: $1" >&2; usage; exit 1;; + -B|--no-build) DOCKER_BUILD=false; ;; + -h|--help) usage; exit 0 ;; + --testdata) + TESTDATA_DIR="$2"; + if [ ! "$(ls -A $TESTDATA_DIR)" ] ; then + >&2 echo "ERROR: --testdata must exist and not be empty." + exit 1 + fi + shift + ;; + --) TEST_ARGS="${@:2}"; break;; + *) echo "Invalid argument: $1" >&2; usage; exit 1 ;; esac shift done @@ -61,44 +74,57 @@ function main() { # Fetch test data - TESTDATA_DIR="./testdata" - mkdir -p $TESTDATA_DIR - if [ ! "$(ls -A $TESTDATA_DIR)" ]; then - curl -L https://github.com/scitran/testdata/archive/master.tar.gz | tar xz -C "$TESTDATA_DIR" --strip-components 1 + if [ -z ${TESTDATA_DIR} ]; then + TESTDATA_DIR="./testdata" + mkdir -p $TESTDATA_DIR + if [ ! "$(ls -A $TESTDATA_DIR)" ]; then + curl -L https://github.com/scitran/testdata/archive/master.tar.gz | tar xz -C "$TESTDATA_DIR" --strip-components 1 + fi fi + # Make sure testdata path is absolute. Could be either absolute or relative. + TESTDATA_DIR="$(cd "$(dirname "$TESTDATA_DIR")" && pwd)/$(basename "$TESTDATA_DIR")" + set +e docker run -it \ --rm \ --name reaper-test \ --network reaper-test \ - -v "$(pwd)/testdata:/testdata" \ + -v "$TESTDATA_DIR:/testdata" \ -v "$(pwd)/bin:/src/reaper/bin" \ -v "$(pwd)/reaper:/src/reaper/reaper" \ -v "$(pwd)/test:/src/reaper/test" \ reaper-test \ /src/reaper/test/bin/test.sh \ --testdata /testdata \ - --core http://scitran-core:8080 secret \ - --dicom-scp-host orthanc-test - --dicom-scp-port 4242 - --dicom-scp-aet ORTHANC - --orthanc http://orthanc-test:8042 + --core-url http://scitran-core:8080 \ + --core-secret secret \ + --dicom-scp-host orthanc-test \ + --dicom-scp-port 4242 \ + --dicom-scp-aet ORTHANC \ + --orthanc http://orthanc-test:8042 \ + $TEST_ARGS + + TEST_RESULT_CODE=$? + >&2 echo + >&2 echo "INFO: Test return code = $TEST_RESULT_CODE" + if [ "${TEST_RESULT_CODE}" != "0" ] ; then + >&2 echo "INFO: Printing container logs..." + docker logs scitran-core-mongo + docker logs scitran-core + docker logs orthanc-test + >&2 echo + >&2 echo "ERROR: Test return code = $TEST_RESULT_CODE. Container logs printed above." + fi } clean_up () {( set +e # Spin down dependencies - docker logs scitran-core-mongo docker stop scitran-core-mongo - - docker logs scitran-core docker stop scitran-core - - docker logs orthanc-test docker stop orthanc-test - docker network rm reaper-test )} trap clean_up EXIT diff --git a/test/lint.sh b/test/bin/lint.sh similarity index 54% rename from test/lint.sh rename to test/bin/lint.sh index e71742e..8504c1e 100755 --- a/test/lint.sh +++ b/test/bin/lint.sh @@ -3,12 +3,12 @@ set -eu unset CDPATH -cd "$( dirname "${BASH_SOURCE[0]}" )/.." +cd "$( dirname "${BASH_SOURCE[0]}" )/../.." -echo "Running pylint ..." +>&2 echo +>&2 echo "Running pylint ..." pylint --jobs=2 --reports=no --disable=R1705 reaper -echo - -echo "Running pep8 ..." +>&2 echo +>&2 echo "Running pep8 ..." pep8 --max-line-length=150 --ignore=E402 reaper diff --git a/test/bin/test.sh b/test/bin/test.sh index d105989..ce55123 100755 --- a/test/bin/test.sh +++ b/test/bin/test.sh @@ -1,6 +1,9 @@ #!/usr/bin/env bash set -e +unset CDPATH +cd "$( dirname "${BASH_SOURCE[0]}" )/../.." + function usage() { cat >&2 <&2; usage; exit 1;; + *) >&2 echo "Invalid argument: $1"; usage; exit 1;; esac shift done - if ${RUN_LINT} ; then - echo - echo "Running pylint ..." - pylint --jobs=2 --reports=no --disable=R1705 reaper + # install dependencies + pip install -r test/requirements.txt + pip freeze - echo - echo "Running pep8 ..." - pep8 --max-line-length=150 --ignore=E402 reaper + if ${RUN_LINT} ; then + ./test/bin/lint.sh fi if ${RUN_UNIT} ; then - echo - echo "Running unit tests ..." + >&2 echo + >&2 echo "Running unit tests ..." #TODO: add unit tests fi - # TODO: Make this conditional for tests that require it. + # Validate input dependencies + + # Dicom_SCP required TESTDATA_DIR + + + # Orthanc requires DICOM_SCP + if [ ${ORTHANC_REST_URL} ] ; then + if [ -z ${DICOM_SCP_HOST} ] || [ -z ${DICOM_SCP_PORT} ] || [ -z ${DICOM_SCP_AET} ] || [ -z ${CORE_URL} ] || [ -z ${CORE_SECRET} ] ; then + >&2 echo "ERROR: orthanc testing requires ..." + fi + fi + + # TODO: check testdata provided if DICOM stuff provided + + if [ ${DICOM_SCP_HOST} ] && [ ${DICOM_SCP_PORT} ] && [ ${DICOM_SCP_AET} ] && [ ${TESTDATA_DIR} ] ; then + >&2 echo + >&2 echo "INFO: Loading test data into DICOM SCP" storescu -v --scan-directories -aec "${DICOM_SCP_AET}" "${DICOM_SCP_HOST}" "${DICOM_SCP_PORT}" $(find $TESTDATA_DIR -type d -name dicom | tail -n 1) - # Test DICOM Sniper + >&2 echo + >&2 echo "INFO: Test DICOM Sniper" dicom_sniper -y --secret "${CORE_SECRET}" -k StudyID "" "${DICOM_SCP_HOST}" "${DICOM_SCP_PORT}" 5104 REAPER "${DICOM_SCP_AET}" "${CORE_URL}" - - # Test DICOM Reaper + >&2 echo + >&2 echo "INFO: Test DICOM Reaper" dicom_reaper -o -s 1 --secret "${CORE_SECRET}" $(mktemp) "${DICOM_SCP_HOST}" "${DICOM_SCP_PORT}" 5104 REAPER "${DICOM_SCP_AET}" "${CORE_URL}" + if [ ${ORTHANC_REST_URL} ] ; then + >&2 echo + >&2 echo "INFO: Test Orthanc DICOM Reaper" + orthanc_reaper -o -s 1 --secret "${CORE_SECRET}" $(mktemp) "${DICOM_SCP_HOST}" "${DICOM_SCP_PORT}" 5104 REAPER "${DICOM_SCP_AET}" "${ORTHANC_REST_URL}" "${CORE_URL}" + fi + fi + if [ ${TESTDATA_DIR} ] && [ ${CORE_URL} ] && [ ${CORE_SECRET} ] ; then # Test Folder Sniper folder_sniper -y --secret "${CORE_SECRET}" "${TESTDATA_DIR}" "${CORE_URL}" + fi - orthanc_reaper -o -s 1 --secret "${CORE_SECRET}" $(mktemp) "${DICOM_SCP_HOST}" "${DICOM_SCP_PORT}" 5104 REAPER "${DICOM_SCP_AET}" "${ORTHANC_REST_URL}" "${CORE_URL}" - - - sleep 10000 } diff --git a/test/install_deps.sh b/test/install_deps.sh deleted file mode 100755 index c53d427..0000000 --- a/test/install_deps.sh +++ /dev/null @@ -1,32 +0,0 @@ -#!/usr/bin/env bash - -set -ue - -# DCMTK -( -if [ ! -f $DCMTK_VERSION/config/config.status ]; then - curl http://dicom.offis.de/download/dcmtk/snapshot/old/$DCMTK_VERSION.tar.gz | tar xz - cd $DCMTK_VERSION - curl https://raw.githubusercontent.com/scitran/reaper/master/movescu.cc.patch | patch --strip 1 - ./configure --prefix=$VIRTUAL_ENV - make all -else - cd $DCMTK_VERSION -fi - -make install -) - -# Orthanc -( -if [ ! -f "$ORTHANC_VERSION/Orthanc" ]; then - curl -L "http://www.orthanc-server.com/downloads/get.php?path=/orthanc/$ORTHANC_VERSION.tar.gz" | tar xz - cd "$ORTHANC_VERSION" - cmake -DCMAKE_INSTALL_PREFIX=$VIRTUAL_ENV -DSTATIC_BUILD=ON -DCMAKE_BUILD_TYPE=Release - make -else - cd "$ORTHANC_VERSION" -fi - -make install -) diff --git a/test/test.sh b/test/test.sh deleted file mode 100755 index e7455e0..0000000 --- a/test/test.sh +++ /dev/null @@ -1,91 +0,0 @@ -#!/usr/bin/env bash - -set -eu - -unset CDPATH -cd "$( dirname "${BASH_SOURCE[0]}" )/.." - -DCMTK_DB_DIR=${DCMTK_DB_DIR:-"./dcmtk_dicom_db"} -TESTDATA_DIR=${TESTDATA_DIR:-"./testdata"} - -PORT=${PORT:-"8027"} -HOST=${HOST:-"http://localhost:$PORT"} - - -# Set up exit and error trap to shutdown dependencies -shutdown() { - echo 'Exit signal trapped' - kill $DCMQRSCP_PID || true - kill $RECEIVER_PID || true - kill $ORTHANC_PID || true - wait -} -trap "shutdown" EXIT ERR - - -# Launch dummy upload receiver -uwsgi --http :$PORT --wsgi-file ./test/upload_receiver.wsgi --master --die-on-term & -RECEIVER_PID=$! - - -# Fetch test data -mkdir -p $TESTDATA_DIR -if [ ! "$(ls -A $TESTDATA_DIR)" ]; then - curl -L https://github.com/scitran/testdata/archive/master.tar.gz | tar xz -C $TESTDATA_DIR --strip-components 1 -fi - - -# Populate DICOM test server -if [ ! -f $DCMTK_DB_DIR/index.dat ]; then - mkdir -p $DCMTK_DB_DIR - find $TESTDATA_DIR -type f -exec dcmqridx $DCMTK_DB_DIR {} + -fi - - -# Configure and launch DICOM test server -DCMQRSCP_CONFIG_FILE=$(mktemp) -cat << EOF > $DCMQRSCP_CONFIG_FILE -NetworkTCPPort = 5104 -MaxPDUSize = 16384 -MaxAssociations = 16 - -HostTable BEGIN -reaper = (REAPER, localhost, 3333) -HostTable END - -AETable BEGIN -DCMQRSCP $DCMTK_DB_DIR RW (200, 1024mb) ANY -AETable END -EOF - -dcmqrscp -c $DCMQRSCP_CONFIG_FILE & -DCMQRSCP_PID=$! - - -# Test DICOM Sniper -dicom_sniper -y --secret secret -k StudyID "" localhost 5104 3333 REAPER DCMQRSCP $HOST - - -# Test DICOM Reaper -dicom_reaper -o -s 1 --secret secret $(mktemp) localhost 5104 3333 REAPER DCMQRSCP $HOST - - -# Test Folder Sniper -folder_sniper -y --secret secret $TESTDATA_DIR $HOST - -# Test Orthanc DICOM Reaper -ORTHANC_CONFIG_FILE="orthanc-config.json" -cat << EOF > $ORTHANC_CONFIG_FILE -{ - "DicomModalities" : { - "reaper" : [ "REAPER", "127.0.0.1", 3333 ] - } -} -EOF - -Orthanc "${ORTHANC_CONFIG_FILE}" & -ORTHANC_PID=$! -sleep 5 - -storescu -v --scan-directories -aec ORTHANC localhost 4242 $(find $TESTDATA_DIR -type d -name dicom | tail -n 1) -orthanc_reaper -o -s 1 --secret secret $(mktemp) localhost 4242 3333 REAPER ORTHANC "http://localhost:8042" $HOST diff --git a/test/upload_receiver.wsgi b/test/upload_receiver.wsgi deleted file mode 100644 index 8d6519c..0000000 --- a/test/upload_receiver.wsgi +++ /dev/null @@ -1,6 +0,0 @@ -# vim: filetype=python - -def application(env, start_response): - env['wsgi.input'].read() - start_response('200 OK', [('Content-Type','text/html')]) - return [] From 6b01f98a8f8a76316b0b9bcd035f332bc1b41901 Mon Sep 17 00:00:00 2001 From: Ryan Sanford Date: Thu, 8 Jun 2017 12:07:53 -0500 Subject: [PATCH 06/10] Fix broken travis config --- .travis.yml | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/.travis.yml b/.travis.yml index 2a80094..e492614 100644 --- a/.travis.yml +++ b/.travis.yml @@ -15,11 +15,7 @@ cache: - $DOCKER_DIR - -before_install: - - ln -s bin $VIRTUAL_ENV/sbin - -install: tr +install: true script: - test -f "$DOCKER_DIR/image.tar" && sudo docker load -i "$DOCKER_DIR/image.tar" || true From e731a579891e9852f78db954c5ee690054ba8d49 Mon Sep 17 00:00:00 2001 From: Ryan Sanford Date: Thu, 8 Jun 2017 12:30:41 -0500 Subject: [PATCH 07/10] Use more compatible docker options --- docker/test.sh | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/docker/test.sh b/docker/test.sh index 82bd397..e904265 100755 --- a/docker/test.sh +++ b/docker/test.sh @@ -60,12 +60,12 @@ function main() { # Orthanc # calledAE = ORTHANC 4242 # REST port = 8042 - docker run -d --rm --name orthanc-test --network reaper-test orthanc-test + docker run -d --name orthanc-test --network reaper-test orthanc-test # scitran-core - docker run -d --rm --name scitran-core-mongo --network reaper-test mongo - docker run -d --rm --name scitran-core \ + docker run -d --name scitran-core-mongo --network reaper-test mongo + docker run -d --name scitran-core \ --network reaper-test \ -e "SCITRAN_PERSISTENT_DB_URI=mongodb://scitran-core-mongo:27017/scitran" \ -e "SCITRAN_PERSISTENT_DB_LOG_URI=mongodb://scitran-core-mongo:27017/logs" \ @@ -122,9 +122,9 @@ clean_up () {( set +e # Spin down dependencies - docker stop scitran-core-mongo - docker stop scitran-core - docker stop orthanc-test + docker rm -f -v scitran-core-mongo + docker rm -f -v scitran-core + docker rm -f -v orthanc-test docker network rm reaper-test )} trap clean_up EXIT From ecafec95a379c30049a044d76cf249213218ef07 Mon Sep 17 00:00:00 2001 From: Ryan Sanford Date: Thu, 8 Jun 2017 13:20:31 -0500 Subject: [PATCH 08/10] Fix up script usage docs --- docker/test.sh | 6 ++---- test/bin/test.sh | 19 +++++++++++++------ 2 files changed, 15 insertions(+), 10 deletions(-) diff --git a/docker/test.sh b/docker/test.sh index e904265..2cee604 100755 --- a/docker/test.sh +++ b/docker/test.sh @@ -12,12 +12,11 @@ Run scitran-reaper tests Usage: $0 [OPTION...] [-- TEST_ARGS...] -TEST_ARGS: Arguments passed to test/bin/test.sh - Options: -B, --no-build Skip Docker Builds -h, --help Print this help and exit - --testdata Path to testdata. + --testdata path Path to testdata. + -- TEST_ARGS Arguments passed to test/bin/test.sh EOF } @@ -120,7 +119,6 @@ function main() { clean_up () {( set +e - # Spin down dependencies docker rm -f -v scitran-core-mongo docker rm -f -v scitran-core diff --git a/test/bin/test.sh b/test/bin/test.sh index ce55123..0101942 100755 --- a/test/bin/test.sh +++ b/test/bin/test.sh @@ -10,14 +10,21 @@ cat >&2 < Date: Tue, 27 Jun 2017 11:11:02 -0500 Subject: [PATCH 09/10] Minimize orthanc config --- docker/orthanc-config.json | 264 +------------------------------------ 1 file changed, 5 insertions(+), 259 deletions(-) diff --git a/docker/orthanc-config.json b/docker/orthanc-config.json index b334ca4..bc2e974 100644 --- a/docker/orthanc-config.json +++ b/docker/orthanc-config.json @@ -1,261 +1,7 @@ { -/** - * General configuration of Orthanc - **/ - -// The logical name of this instance of Orthanc. This one is -// displayed in Orthanc Explorer and at the URI "/system". -"Name" : "Orthanc", - -// Path to the directory that holds the heavyweight files -// (i.e. the raw DICOM instances) -"StorageDirectory" : "/var/lib/orthanc/db-v6", - -// Path to the directory that holds the SQLite index (if unset, -// the value of StorageDirectory is used). This index could be -// stored on a RAM-drive or a SSD device for performance reasons. -"IndexDirectory" : "/var/lib/orthanc/db-v6", - -// Enable the transparent compression of the DICOM instances -"StorageCompression" : false, - -// Maximum size of the storage in MB (a value of "0" indicates no -// limit on the storage size) -"MaximumStorageSize" : 0, - -// Maximum number of patients that can be stored at a given time -// in the storage (a value of "0" indicates no limit on the number -// of patients) -"MaximumPatientCount" : 0, - -// List of paths to the custom Lua scripts that are to be loaded -// into this instance of Orthanc -"LuaScripts" : [ -], - -// List of paths to the plugins that are to be loaded into this -// instance of Orthanc (e.g. "./libPluginTest.so" for Linux, or -// "./PluginTest.dll" for Windows). These paths can refer to -// folders, in which case they will be scanned non-recursively to -// find shared libraries. -"Plugins" : [ - "/usr/share/orthanc/plugins/" -], - - - -/** - * Configuration of the HTTP server - **/ - -// Enable the HTTP server. If this parameter is set to "false", -// Orthanc acts as a pure DICOM server. The REST API and Orthanc -// Explorer will not be available. -"HttpServerEnabled" : true, - -// HTTP port for the REST services and for the GUI -"HttpPort" : 8042, - -// When the following option is "true", if an error is encountered -// while calling the REST API, a JSON message describing the error -// is put in the HTTP answer. This feature can be disabled if the -// HTTP client does not properly handles such answers. -"HttpDescribeErrors" : true, - -// Enable HTTP compression to improve network bandwidth utilization, -// at the expense of more computations on the server. Orthanc -// supports the "gzip" and "deflate" HTTP encodings. -"HttpCompressionEnabled" : true, - - - -/** - * Configuration of the DICOM server - **/ - -// Enable the DICOM server. If this parameter is set to "false", -// Orthanc acts as a pure REST server. It will not be possible to -// receive files or to do query/retrieve through the DICOM protocol. -"DicomServerEnabled" : true, - -// The DICOM Application Entity Title -"DicomAet" : "ORTHANC", - -// Check whether the called AET corresponds during a DICOM request -"DicomCheckCalledAet" : false, - -// The DICOM port -"DicomPort" : 4242, - -// The default encoding that is assumed for DICOM files without -// "SpecificCharacterSet" DICOM tag. The allowed values are "Ascii", -// "Utf8", "Latin1", "Latin2", "Latin3", "Latin4", "Latin5", -// "Cyrillic", "Windows1251", "Arabic", "Greek", "Hebrew", "Thai", -// "Japanese", and "Chinese". -"DefaultEncoding" : "Latin1", - -// The transfer syntaxes that are accepted by Orthanc C-Store SCP -"DeflatedTransferSyntaxAccepted" : true, -"JpegTransferSyntaxAccepted" : true, -"Jpeg2000TransferSyntaxAccepted" : true, -"JpegLosslessTransferSyntaxAccepted" : true, -"JpipTransferSyntaxAccepted" : true, -"Mpeg2TransferSyntaxAccepted" : true, -"RleTransferSyntaxAccepted" : true, - -// Whether Orthanc accepts to act as C-Store SCP for unknown storage -// SOP classes (aka. "promiscuous mode") -"UnknownSopClassAccepted" : true, - - - -/** - * Security-related options for the HTTP server - **/ - -// Whether remote hosts can connect to the HTTP server -"RemoteAccessAllowed" : true, - -// Whether or not SSL is enabled -"SslEnabled" : false, - -// Path to the SSL certificate (meaningful only if SSL is enabled) -"SslCertificate" : "certificate.pem", - -// Whether or not the password protection is enabled -"AuthenticationEnabled" : false, - -// The list of the registered users. Because Orthanc uses HTTP -// Basic Authentication, the passwords are stored as plain text. -"RegisteredUsers" : { - // "alice" : "alicePassword" -}, - - - -/** - * Network topology - **/ - -// The list of the known DICOM modalities -"DicomModalities" : { - "flywheelCore" : [ "REAPER", "reaper-test", 5104] -}, - -// The list of the known Orthanc peers -"OrthancPeers" : { -}, - -// Parameters of the HTTP proxy to be used by Orthanc. If set to the -// empty string, no HTTP proxy is used. For instance: -// "HttpProxy" : "192.168.0.1:3128" -// "HttpProxy" : "proxyUser:proxyPassword@192.168.0.1:3128" -"HttpProxy" : "", - -// Set the timeout for HTTP requests issued by Orthanc (in seconds). -"HttpTimeout" : 10, - -// Enable the verification of the peers during HTTPS requests. -// Reference: http://curl.haxx.se/docs/sslcerts.html -"HttpsVerifyPeers" : true, - -// Path to the CA (certification authority) certificates to validate -// peers in HTTPS requests. From curl documentation ("--cacert" -// option): "Tells curl to use the specified certificate file to -// verify the peers. The file may contain multiple CA -// certificates. The certificate(s) must be in PEM format." -"HttpsCACertificates" : "", - - - -/** - * Advanced options - **/ - -// Dictionary of symbolic names for the user-defined metadata. Each -// entry must map an unique string to an unique number between 1024 -// and 65535. -"UserMetadata" : { - // "Sample" : 1024 -}, - -// Dictionary of symbolic names for the user-defined types of -// attached files. Each entry must map an unique string to an unique -// number between 1024 and 65535. Optionally, a second argument can -// provided to specify a MIME content type for the attachment. -"UserContentType" : { - // "sample" : 1024 - // "sample2" : [ 1025, "application/pdf" ] -}, - -// Number of seconds without receiving any instance before a -// patient, a study or a series is considered as stable. -"StableAge" : 60, - -// By default, Orthanc compares AET (Application Entity Titles) in a -// case-insensitive way. Setting this option to "true" will enable -// case-sensitive matching. -"StrictAetComparison" : false, - -// When the following option is "true", the MD5 of the DICOM files -// will be computed and stored in the Orthanc database. This -// information can be used to detect disk corruption, at the price -// of a small performance overhead. -"StoreMD5ForAttachments" : true, - -// The maximum number of results for a single C-FIND request at the -// Patient, Study or Series level. Setting this option to "0" means -// no limit. -"LimitFindResults" : 0, - -// The maximum number of results for a single C-FIND request at the -// Instance level. Setting this option to "0" means no limit. -"LimitFindInstances" : 0, - -// The maximum number of active jobs in the Orthanc scheduler. When -// this limit is reached, the addition of new jobs is blocked until -// some job finishes. -"LimitJobs" : 10, - -// If this option is set to "false", Orthanc will not log the -// resources that are exported to other DICOM modalities of Orthanc -// peers in the URI "/exports". This is useful to prevent the index -// to grow indefinitely in auto-routing tasks. -"LogExportedResources" : true, - -// Enable or disable HTTP Keep-Alive (deprecated). Set this option -// to "true" only in the case of high HTTP loads. -"KeepAlive" : false, - -// If this option is set to "false", Orthanc will run in index-only -// mode. The DICOM files will not be stored on the drive. Note that -// this option might prevent the upgrade to newer versions of Orthanc. -"StoreDicom" : true, - -// DICOM associations are kept open as long as new DICOM commands -// are issued. This option sets the number of seconds of inactivity -// to wait before automatically closing a DICOM association. If set -// to 0, the connection is closed immediately. -"DicomAssociationCloseDelay" : 5, - -// Maximum number of query/retrieve DICOM requests that are -// maintained by Orthanc. The least recently used requests get -// deleted as new requests are issued. -"QueryRetrieveSize" : 10, - -// When handling a C-Find SCP request, setting this flag to "true" -// will enable case-sensitive match for PN value representation -// (such as PatientName). By default, the search is -// case-insensitive, which does not follow the DICOM standard. -"CaseSensitivePN" : false, - -// Register a new tag in the dictionary of DICOM tags that are known -// to Orthanc. Each line must contain the tag (formatted as 2 -// hexadecimal numbers), the value representation (2 upcase -// characters), a nickname for the tag, possibly the minimum -// multiplicity (> 0 with defaults to 1), and possibly the maximum -// multiplicity (0 means arbitrary multiplicity, defaults to 1). -"Dictionary" : { - // "0014,1020" : [ "DA", "ValidationExpiryDate", 1, 1 ] -} + "UnknownSopClassAccepted" : true, + "RemoteAccessAllowed" : true, + "DicomModalities" : { + "reaper" : [ "REAPER", "reaper-test", 5104] + } } From 426f1b3020a4069b3ee1edfef48c4a678e37023a Mon Sep 17 00:00:00 2001 From: Ryan Sanford Date: Tue, 27 Jun 2017 11:11:29 -0500 Subject: [PATCH 10/10] Rename folder test to tests --- docker/test.sh | 4 ++-- {test => tests}/bin/lint.sh | 0 {test => tests}/bin/test.sh | 4 ++-- {test => tests}/requirements.txt | 0 4 files changed, 4 insertions(+), 4 deletions(-) rename {test => tests}/bin/lint.sh (100%) rename {test => tests}/bin/test.sh (98%) rename {test => tests}/requirements.txt (100%) diff --git a/docker/test.sh b/docker/test.sh index 2cee604..69390a1 100755 --- a/docker/test.sh +++ b/docker/test.sh @@ -92,9 +92,9 @@ function main() { -v "$TESTDATA_DIR:/testdata" \ -v "$(pwd)/bin:/src/reaper/bin" \ -v "$(pwd)/reaper:/src/reaper/reaper" \ - -v "$(pwd)/test:/src/reaper/test" \ + -v "$(pwd)/tests:/src/reaper/tests" \ reaper-test \ - /src/reaper/test/bin/test.sh \ + /src/reaper/tests/bin/test.sh \ --testdata /testdata \ --core-url http://scitran-core:8080 \ --core-secret secret \ diff --git a/test/bin/lint.sh b/tests/bin/lint.sh similarity index 100% rename from test/bin/lint.sh rename to tests/bin/lint.sh diff --git a/test/bin/test.sh b/tests/bin/test.sh similarity index 98% rename from test/bin/test.sh rename to tests/bin/test.sh index 0101942..6ad58ad 100755 --- a/test/bin/test.sh +++ b/tests/bin/test.sh @@ -71,11 +71,11 @@ function main() { done # install dependencies - pip install -r test/requirements.txt + pip install -r tests/requirements.txt pip freeze if ${RUN_LINT} ; then - ./test/bin/lint.sh + ./tests/bin/lint.sh fi if ${RUN_UNIT} ; then diff --git a/test/requirements.txt b/tests/requirements.txt similarity index 100% rename from test/requirements.txt rename to tests/requirements.txt