From d92de5b97fc6204db4b1e3ed20c03ac06f5d53f0 Mon Sep 17 00:00:00 2001 From: jamarshon Date: Fri, 24 May 2019 15:45:39 -0400 Subject: [PATCH] Setup Travis CI so that unit tests are run automatically (#117) --- .travis.yml | 39 +++++++++++++------- README.md | 2 ++ build_tools/travis/install.sh | 60 +++++++++++++++++++++++++++++++ build_tools/travis/test_script.sh | 36 +++++++++++++++++++ requirements.txt | 12 +++++++ test/common_utils.py | 18 ++++++++++ test/test.py | 3 +- test/test_dataloader.py | 21 ++++++----- test/test_kaldi_io.py | 3 +- test/test_legacy.py | 3 +- test/test_sox_effects.py | 13 +++++-- test/test_transforms.py | 3 +- 12 files changed, 185 insertions(+), 28 deletions(-) create mode 100644 build_tools/travis/install.sh create mode 100644 build_tools/travis/test_script.sh create mode 100644 requirements.txt create mode 100644 test/common_utils.py diff --git a/.travis.yml b/.travis.yml index a12844258c..643f29cdc3 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,17 +1,30 @@ -language: python +# note dist: 'trusty' does not work here dist: xenial + +language: python + +# cache miniconda installer and similar files +cache: + directories: + - /home/travis/download + +# This matrix tests that the code works on Python 3.5, 3.6, and passes lint. matrix: + fast_finish: true include: - - python: "3.5" + - env: PYTHON_VERSION="3.5" + - env: PYTHON_VERSION="3.6" + - env: PYTHON_VERSION="3.5" RUN_FLAKE8="true" SKIP_TESTS="true" + addons: - apt: - packages: - sox - libsox-dev - libsox-fmt-all - libpython3.5-dev -install: - - pip install torch - - python setup.py install -script: - - python -m unittest + apt: + packages: + sox + libsox-dev + libsox-fmt-all + +notifications: + email: false + +install: source build_tools/travis/install.sh +script: bash build_tools/travis/test_script.sh diff --git a/README.md b/README.md index 106fd2e967..c74cfe8e26 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,8 @@ torchaudio: an audio library for PyTorch ================================================ +[![Build Status](https://travis-ci.org/pytorch/audio.svg?branch=master)](https://travis-ci.org/pytorch/audio) + - [Support audio I/O (Load files, Save files)](http://pytorch.org/audio/) - Load the following formats into a torch Tensor - mp3, wav, aac, ogg, flac, avr, cdda, cvs/vms, diff --git a/build_tools/travis/install.sh b/build_tools/travis/install.sh new file mode 100644 index 0000000000..866193457b --- /dev/null +++ b/build_tools/travis/install.sh @@ -0,0 +1,60 @@ +#!/bin/bash +# This script is meant to be called by the "install" step defined in +# .travis.yml. See http://docs.travis-ci.com/ for more details. +# The behavior of the script is controlled by environment variabled defined +# in the .travis.yml in the top level folder of the project. + + set -e + + echo 'List files from cached directories' +if [ -d $HOME/download ]; then + echo 'download:' + ls $HOME/download +fi +if [ -d $HOME/.cache/pip ]; then + echo 'pip:' + ls $HOME/.cache/pip +fi + + # Deactivate the travis-provided virtual environment and setup a +# conda-based environment instead +deactivate + + # Add the miniconda bin directory to $PATH +export PATH=/home/travis/miniconda3/bin:$PATH +echo $PATH + + # Use the miniconda installer for setup of conda itself +pushd . +cd +mkdir -p download +cd download +if [[ ! -f /home/travis/miniconda3/bin/activate ]] +then + if [[ ! -f miniconda.sh ]] + then + wget http://repo.continuum.io/miniconda/Miniconda3-latest-Linux-x86_64.sh \ + -O miniconda.sh + fi + chmod +x miniconda.sh && ./miniconda.sh -b -f + conda update --yes conda + echo "Creating environment to run tests in." + conda create -n testenv --yes python="$PYTHON_VERSION" +fi +cd .. +popd + + # Activate the python environment we created. +source activate testenv + + # Install requirements via pip in our conda environment +pip install -r requirements.txt + + # Install the following only if running tests +if [[ "$SKIP_TESTS" != "true" ]]; then + # PyTorch + conda install --yes pytorch -c pytorch + + # TorchAudio CPP Extensions + pip install . +fi diff --git a/build_tools/travis/test_script.sh b/build_tools/travis/test_script.sh new file mode 100644 index 0000000000..cab5687308 --- /dev/null +++ b/build_tools/travis/test_script.sh @@ -0,0 +1,36 @@ +#!/bin/bash +# This script is meant to be called by the "script" step defined in +# .travis.yml. See http://docs.travis-ci.com/ for more details. +# The behavior of the script is controlled by environment variabled defined +# in the .travis.yml in the top level folder of the project. +set -e + +python --version + +run_tests() { + # find all the test files that match "test*.py" + TEST_FILES="$(find test/ -type f -name "test*.py" | sort)" + echo "Test files are:" + echo $TEST_FILES + + echo "Executing tests:" + EXIT_STATUS=0 + for FILE in $TEST_FILES; do + # run each file on a separate process. if one fails, just keep going and + # return the final exit status. + python -m unittest -v $FILE + STATUS=$? + EXIT_STATUS="$(($EXIT_STATUS+STATUS))" + done + + echo "Done, exit status: $EXIT_STATUS" + exit $EXIT_STATUS +} + +if [[ "$RUN_FLAKE8" == "true" ]]; then + flake8 +fi + +if [[ "$SKIP_TESTS" != "true" ]]; then + run_tests +fi diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000000..ac36816e56 --- /dev/null +++ b/requirements.txt @@ -0,0 +1,12 @@ +# Optional for torchaudio.kaldi_io +numpy +kaldi_io + +# Required for tests only: + +# Style-checking for PEP8 +flake8 + +# Used for comparison of outputs in tests +librosa +scipy diff --git a/test/common_utils.py b/test/common_utils.py new file mode 100644 index 0000000000..9d8543023f --- /dev/null +++ b/test/common_utils.py @@ -0,0 +1,18 @@ +import os +from shutil import copytree +import tempfile + + +TEST_DIR_PATH = os.path.dirname(os.path.realpath(__file__)) + + +def create_temp_assets_dir(): + """ + Creates a temporary directory and moves all files from test/assets there. + Returns a Tuple[string, TemporaryDirectory] which is the folder path + and object. + """ + tmp_dir = tempfile.TemporaryDirectory() + copytree(os.path.join(TEST_DIR_PATH, "assets"), + os.path.join(tmp_dir.name, "assets")) + return tmp_dir.name, tmp_dir diff --git a/test/test.py b/test/test.py index 1931fc55df..0348a1c3a5 100644 --- a/test/test.py +++ b/test/test.py @@ -1,4 +1,5 @@ import unittest +import test.common_utils import torch import torchaudio import math @@ -6,7 +7,7 @@ class Test_LoadSave(unittest.TestCase): - test_dirpath = os.path.dirname(os.path.realpath(__file__)) + test_dirpath, test_dir = test.common_utils.create_temp_assets_dir() test_filepath = os.path.join(test_dirpath, "assets", "steam-train-whistle-daniel_simon.mp3") diff --git a/test/test_dataloader.py b/test/test_dataloader.py index 34bf4db65e..cb6dcb959f 100644 --- a/test/test_dataloader.py +++ b/test/test_dataloader.py @@ -1,4 +1,5 @@ import unittest +import test.common_utils import torch import torch.nn as nn from torch.utils.data import Dataset, DataLoader @@ -9,11 +10,12 @@ class TORCHAUDIODS(Dataset): - test_dirpath = os.path.dirname(os.path.realpath(__file__)) + test_dirpath, test_dir = test.common_utils.create_temp_assets_dir() def __init__(self): self.asset_dirpath = os.path.join(self.test_dirpath, "assets") - self.data = [os.path.join(self.asset_dirpath, fn) for fn in os.listdir(self.asset_dirpath)] + sound_files = list(filter(lambda x: '.wav' in x or '.mp3' in x, os.listdir(self.asset_dirpath))) + self.data = [os.path.join(self.asset_dirpath, fn) for fn in sound_files] self.si, self.ei = torchaudio.info(os.path.join(self.asset_dirpath, "sinewave.wav")) self.si.precision = 16 self.E = torchaudio.sox_effects.SoxEffectsChain() @@ -32,17 +34,20 @@ def __len__(self): class Test_DataLoader(unittest.TestCase): + @classmethod + def setUpClass(cls): + torchaudio.initialize_sox() + + @classmethod + def tearDownClass(cls): + torchaudio.shutdown_sox() + def test_1(self): expected_size = (2, 1, 16000) ds = TORCHAUDIODS() dl = DataLoader(ds, batch_size=2) for x in dl: - # print(x.size()) - continue - - self.assertTrue(x.size() == expected_size) + self.assertTrue(x.size() == expected_size) if __name__ == '__main__': - torchaudio.initialize_sox() unittest.main() - torchaudio.shutdown_sox() diff --git a/test/test_kaldi_io.py b/test/test_kaldi_io.py index 75e1ea5b85..29119f773f 100644 --- a/test/test_kaldi_io.py +++ b/test/test_kaldi_io.py @@ -2,12 +2,13 @@ import torch import torchaudio.kaldi_io as kio import unittest +import test.common_utils class KaldiIOTest(unittest.TestCase): data1 = [[1, 2, 3], [11, 12, 13], [21, 22, 23]] data2 = [[31, 32, 33], [41, 42, 43], [51, 52, 53]] - test_dirpath = os.path.dirname(os.path.realpath(__file__)) + test_dirpath, test_dir = test.common_utils.create_temp_assets_dir() def _test_helper(self, file_name, expected_data, fn, expected_dtype): """ Takes a file_name to the input data and a function fn to extract the diff --git a/test/test_legacy.py b/test/test_legacy.py index d7f97f67bd..83af035daa 100644 --- a/test/test_legacy.py +++ b/test/test_legacy.py @@ -1,4 +1,5 @@ import unittest +import test.common_utils import torch import torchaudio from torchaudio.legacy import save, load @@ -7,7 +8,7 @@ class Test_LoadSave(unittest.TestCase): - test_dirpath = os.path.dirname(os.path.realpath(__file__)) + test_dirpath, test_dir = test.common_utils.create_temp_assets_dir() test_filepath = os.path.join(test_dirpath, "assets", "steam-train-whistle-daniel_simon.mp3") diff --git a/test/test_sox_effects.py b/test/test_sox_effects.py index b0dc0aaf6e..2b35a841be 100644 --- a/test/test_sox_effects.py +++ b/test/test_sox_effects.py @@ -1,4 +1,5 @@ import unittest +import test.common_utils import torch import torchaudio import math @@ -6,10 +7,18 @@ class Test_SoxEffectsChain(unittest.TestCase): - test_dirpath = os.path.dirname(os.path.realpath(__file__)) + test_dirpath, test_dir = test.common_utils.create_temp_assets_dir() test_filepath = os.path.join(test_dirpath, "assets", "steam-train-whistle-daniel_simon.mp3") + @classmethod + def setUpClass(cls): + torchaudio.initialize_sox() + + @classmethod + def tearDownClass(cls): + torchaudio.shutdown_sox() + def test_single_channel(self): fn_sine = os.path.join(self.test_dirpath, "assets", "sinewave.wav") E = torchaudio.sox_effects.SoxEffectsChain() @@ -220,6 +229,4 @@ def test_invalid_effect_options(self): if __name__ == '__main__': - torchaudio.initialize_sox() unittest.main() - torchaudio.shutdown_sox() diff --git a/test/test_transforms.py b/test/test_transforms.py index b0b315c4fd..31b5f994be 100644 --- a/test/test_transforms.py +++ b/test/test_transforms.py @@ -7,6 +7,7 @@ from torchaudio.common_utils import IMPORT_LIBROSA, IMPORT_SCIPY import torchaudio.transforms as transforms import unittest +import test.common_utils if IMPORT_LIBROSA: import librosa @@ -25,7 +26,7 @@ class Tester(unittest.TestCase): sig.unsqueeze_(1) # (64000, 1) sig = (sig * volume * 2**31).long() # file for stereo stft test - test_dirpath = os.path.dirname(os.path.realpath(__file__)) + test_dirpath, test_dir = test.common_utils.create_temp_assets_dir() test_filepath = os.path.join(test_dirpath, "assets", "steam-train-whistle-daniel_simon.mp3")