Repository: ulmo-dev/ulmo (language: python)

Issue:
Travis CI runs not exposed on PR's
Travis CI results when a PR is submitted haven't been visible on the PR for a while. For example, the PR I submitted today, #196, and also a PR from July 26 (#188). However, the Travis CI jobs **are** running! See [here](https://travis-ci.org/github/ulmo-dev/ulmo/pull_requests). The issue seems to be due to a combination of a travis migration from `.org` to `.com` and a change in GitHub policy. See [this late April blog post](https://jamescooke.info/migrating-open-source-projects-on-travis-ci-to-fix-github-api-limit-problems.html) and the [preceding post from early April](https://jamescooke.info/travis-hitting-githubs-api-limits-for-open-source-projects.html) for the likely explanation and fix.


Discussion / hints:
The writing is on the wall. Time to drop Travis CI and move to GitHub Actions. Some helpful discussions and guides:

- https://www.jeffgeerling.com/blog/2020/travis-cis-new-pricing-plan-threw-wrench-my-open-source-works
- https://github.com/marketplace/actions/run-travis-yml
- https://github.com/numpy/numpy/issues/17824
- https://github.com/lagadic/visp/issues/872


Fix patch:
diff --git a/.continuous-integration/README.md b/.continuous-integration/README.md
deleted file mode 100644
index bcfb2867..00000000
--- a/.continuous-integration/README.md
+++ /dev/null
@@ -1,12 +0,0 @@
-About
-=====
-
-This directory contains a set of scripts that are used by the ``appveyor.yml`` files 
-for the [AppVeyor](http://www.appveyor.com/) service.
-
-This folder was forked from the [Astropy](https://github.com/astropy/astropy) repo.
-
-The scripts include:
-
-* ``appveyor/install-miniconda.ps1`` - set up conda on Windows
-* ``appveyor/windows_sdk.cmd`` - set up the compiler environment on Windows
diff --git a/.continuous-integration/appveyor/run_with_env.cmd b/.continuous-integration/appveyor/run_with_env.cmd
deleted file mode 100644
index 3a472bc8..00000000
--- a/.continuous-integration/appveyor/run_with_env.cmd
+++ /dev/null
@@ -1,47 +0,0 @@
-:: To build extensions for 64 bit Python 3, we need to configure environment
-:: variables to use the MSVC 2010 C++ compilers from GRMSDKX_EN_DVD.iso of:
-:: MS Windows SDK for Windows 7 and .NET Framework 4 (SDK v7.1)
-::
-:: To build extensions for 64 bit Python 2, we need to configure environment
-:: variables to use the MSVC 2008 C++ compilers from GRMSDKX_EN_DVD.iso of:
-:: MS Windows SDK for Windows 7 and .NET Framework 3.5 (SDK v7.0)
-::
-:: 32 bit builds do not require specific environment configurations.
-::
-:: Note: this script needs to be run with the /E:ON and /V:ON flags for the
-:: cmd interpreter, at least for (SDK v7.0)
-::
-:: More details at:
-:: https://github.com/cython/cython/wiki/64BitCythonExtensionsOnWindows
-:: http://stackoverflow.com/a/13751649/163740
-::
-:: Author: Olivier Grisel
-:: License: CC0 1.0 Universal: http://creativecommons.org/publicdomain/zero/1.0/
-@ECHO OFF
-
-SET COMMAND_TO_RUN=%*
-SET WIN_SDK_ROOT=C:\Program Files\Microsoft SDKs\Windows
-
-SET MAJOR_PYTHON_VERSION="%PYTHON_VERSION:~0,1%"
-IF %MAJOR_PYTHON_VERSION% == "2" (
-    SET WINDOWS_SDK_VERSION="v7.0"
-) ELSE IF %MAJOR_PYTHON_VERSION% == "3" (
-    SET WINDOWS_SDK_VERSION="v7.1"
-) ELSE (
-    ECHO Unsupported Python version: "%MAJOR_PYTHON_VERSION%"
-    EXIT 1
-)
-
-IF "%PYTHON_ARCH%"=="64" (
-    ECHO Configuring Windows SDK %WINDOWS_SDK_VERSION% for Python %MAJOR_PYTHON_VERSION% on a 64 bit architecture
-    SET DISTUTILS_USE_SDK=1
-    SET MSSdk=1
-    "%WIN_SDK_ROOT%\%WINDOWS_SDK_VERSION%\Setup\WindowsSdkVer.exe" -q -version:%WINDOWS_SDK_VERSION%
-    "%WIN_SDK_ROOT%\%WINDOWS_SDK_VERSION%\Bin\SetEnv.cmd" /x64 /release
-    ECHO Executing: %COMMAND_TO_RUN%
-    call %COMMAND_TO_RUN% || EXIT 1
-) ELSE (
-    ECHO Using default MSVC build environment for 32 bit architecture
-    ECHO Executing: %COMMAND_TO_RUN%
-    call %COMMAND_TO_RUN% || EXIT 1
-)
diff --git a/.travis.yml b/.travis.yml
deleted file mode 100644
index 2b872ee0..00000000
--- a/.travis.yml
+++ /dev/null
@@ -1,73 +0,0 @@
-language: c
-
-# Setting sudo to false opts in to Travis-CI container-based builds.
-sudo: false
-
-# Turn off email notifications
-notifications:
-  email: false
-
-matrix:
-  include:
-    - os: linux
-      env: PYTHON_VERSION="3.6"
-    - os: linux
-      env: PYTHON_VERSION="3.7"
-    - os: linux
-      env: PYTHON_VERSION="3.8"
-    - os: linux
-      env: PYTHON_VERSION="3.9"
-    - os: osx
-      osx_image: xcode9.4
-      env: PYTHON_VERSION="3.6"
-    - os: osx
-      osx_image: xcode9.4
-      env: PYTHON_VERSION="3.7"
-    - os: osx
-      osx_image: xcode9.4
-      env: PYTHON_VERSION="3.8"
-    - os: osx
-      osx_image: xcode9.4
-      env: PYTHON_VERSION="3.9"
-
-cache:
-  directories:
-    - $TRAVIS_BUILD_DIR/ulmo_test_cache
-    - $HOME/ulmo
-
-# commands to install quest
-install:
-  - if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then
-      OS_VERSION="Linux";
-      SED_OPTIONS="-i";
-    else
-      OS_VERSION="MacOSX";
-      SED_OPTIONS="-i ''";
-    fi
-  # We do this conditionally because it saves us some downloading if the
-  # version is the same.
-  - wget https://repo.continuum.io/miniconda/Miniconda3-latest-${OS_VERSION}-x86_64.sh -O miniconda.sh;
-  - bash miniconda.sh -b -p $HOME/miniconda
-  - export PATH="$HOME/miniconda/bin:$PATH"
-  - hash -r
-  - conda config --set always_yes yes --set changeps1 no
-  - conda update -q conda
-  # Useful for debugging any issues with conda
-  - conda info -a
-  # Create quest conda env and install deps
-  # - sed $SED_OPTIONS "s/python=3/python=$PYTHON_VERSION/" conda_environment.yml
-  # - conda env create -q -n test-environment -f conda_environment.yml
-  - conda create -n test-environment -c conda-forge python=$PYTHON_VERSION --file requirements.txt --file requirements-dev.txt
-  - source activate test-environment
-  - python setup.py install
-  - conda list
-  - export ULMO_CACHE_DIR=$TRAVIS_BUILD_DIR/ulmo_test_cache
-  - export COVERAGE=$HOME/miniconda/envs/test-environment/lib/python$PYTHON_VERSION/site-packages/ulmo
-
-# command to run tests
-script:
-  - pytest --cov=$COVERAGE -vv -k 'not lcra and not hdf5 and not pytables';
-    
-# generate test coverage information
-after_success:
-  coveralls
diff --git a/appveyor.yml b/appveyor.yml
deleted file mode 100644
index a945dfaf..00000000
--- a/appveyor.yml
+++ /dev/null
@@ -1,40 +0,0 @@
-environment:
-  global:
-    # SDK v7.0 MSVC Express 2008's SetEnv.cmd script will fail if the
-    # /E:ON and /V:ON options are not enabled in the batch script intepreter
-    # See: http://stackoverflow.com/a/13751649/163740
-    CMD_IN_ENV: "cmd /E:ON /V:ON /C .\\.continuous-integration\\appveyor\\run_with_env.cmd"
-#    QUEST_CACHE_DIR: quest_test_cache
-  matrix:
-    - PYTHON_VERSION: 3.5
-      PYTHON_BUILD: 35
-      MINICONDA: C:\Miniconda3-x64
-    - PYTHON_VERSION: 3.6
-      MINICONDA: C:\Miniconda3-x64
-      PYTHON_BUILD: 36
-    - PYTHON_VERSION: 3.7
-      MINICONDA: C:\Miniconda3-x64
-      PYTHON_BUILD: 37
-
-init:
-  - "ECHO %PYTHON_VERSION% %MINICONDA%"
-
-cache:
-  - "%ULMO_CACHE_DIR%"
-
-build: false
-
-install:
-  # Install miniconda using a powershell script.
-  - "set PATH=%MINICONDA%;%MINICONDA%\\Scripts;%PATH%"
-  - "conda config --set always_yes yes --set changeps1 no"
-#  - "conda update -q conda"
-  - "conda info -a"
-  - ps: "(Get-Content conda_environment.yml).replace('python=3', \"python=$env:PYTHON_VERSION\") | Set-Content conda_environment.yml"
-  - "conda env create -q -n test-environment -f conda_environment.yml"
-  - "activate test-environment"
-  - "python setup.py install"
-  - "conda list"
-  
-test_script:
-  - "%CMD_IN_ENV% pytest -vv -k \"not lcra and not hdf5 and not pytables\""
diff --git a/ulmo/ncdc/cirs/core.py b/ulmo/ncdc/cirs/core.py
index 0e69cea1..2ec24ccf 100644
--- a/ulmo/ncdc/cirs/core.py
+++ b/ulmo/ncdc/cirs/core.py
@@ -11,7 +11,7 @@
 from builtins import str
 from builtins import range
 from past.builtins import basestring
-import distutils
+import distutils.version
 import os.path
 
 import pandas


Test patch:
diff --git a/.github/workflows/default-tests.yml b/.github/workflows/default-tests.yml
new file mode 100644
index 00000000..9e86c087
--- /dev/null
+++ b/.github/workflows/default-tests.yml
@@ -0,0 +1,46 @@
+name: Default Tests
+
+on:
+  pull_request:
+  push:
+    branches: [master]
+
+jobs:
+  run:
+    runs-on: ${{ matrix.os }}
+    strategy:
+      matrix:
+        python-version: ["3.6", "3.7", "3.8", "3.9"]
+        # Just ubuntu, for now
+        # os: [windows-latest, ubuntu-latest, macos-latest]
+        os: [windows-latest, ubuntu-latest, macos-latest]
+      fail-fast: false
+
+    steps:
+    - uses: actions/checkout@v2
+
+    - name: Setup Conda
+      uses: s-weigand/setup-conda@v1
+      with:
+        activate-conda: false
+        conda-channels: conda-forge
+
+    - name: Python ${{ matrix.python-version }}
+      shell: bash -l {0}
+      run: |
+        conda create --name TEST python=${{ matrix.python-version }} --file requirements.txt --file requirements-dev.txt --strict-channel-priority
+        source activate TEST
+        pip install -e . --no-deps --force-reinstall
+
+    - name: Conda Info
+      shell: bash -l {0}
+      run: |
+        source activate TEST
+        conda info --all
+        conda list
+
+    - name: Default Tests
+      shell: bash -l {0}
+      run: |
+        source activate TEST
+        pytest -s -rxs -vv -k "not lcra"
diff --git a/test/gsod_test.py b/test/gsod_test.py
index 695a8a8c..c07819e5 100644
--- a/test/gsod_test.py
+++ b/test/gsod_test.py
@@ -79,7 +79,9 @@ def test_get_stations_with_country():
         assert '409900-99999' in stations
 
         stations = ulmo.ncdc.gsod.get_stations(country=['US', 'MX', 'CA'])
-        assert len(stations) > 9500
+        # Live service now (2021-8-30) returns 9437 stations
+        # assert len(stations) > 9500
+        assert len(stations) > 9400
         assert '768420-99999' in stations
         assert '911660-99999' in stations
         assert '729675-99999' in stations
diff --git a/test/usgs_nwis_hdf5_test.py b/test/usgs_nwis_hdf5_test.py
deleted file mode 100644
index 61dc370f..00000000
--- a/test/usgs_nwis_hdf5_test.py
+++ /dev/null
@@ -1,593 +0,0 @@
-from builtins import range
-import os
-import shutil
-import datetime
-
-import freezegun
-import pandas
-import pytest
-
-from ulmo.usgs import nwis
-import test_util
-
-
-TEST_FILE_DIR = os.path.abspath('tmp')
-
-
-@pytest.fixture
-def test_file_path(request):
-    return os.path.join(TEST_FILE_DIR, request.function.__name__)
-
-
-def setup_module(module):
-    if os.path.exists(TEST_FILE_DIR):
-        shutil.rmtree(TEST_FILE_DIR)
-    os.makedirs(TEST_FILE_DIR)
-
-
-def teardown_module(module):
-    shutil.rmtree(TEST_FILE_DIR)
-
-
-def test_update_site_list(test_file_path):
-    site_files = [
-            os.path.join('usgs','nwis', 'RI_daily.xml'), 
-            os.path.join('usgs','nwis', 'RI_instantaneous.xml'),
-        ]
-    for site_file in site_files:
-        test_site_file = test_util.get_test_file_path(site_file)
-        nwis.hdf5.update_site_list(path=test_file_path,
-                input_file=test_site_file, autorepack=False)
-
-    sites = nwis.hdf5.get_sites(test_file_path)
-    assert len(sites) == 64
-
-    test_sites = {
-        # uses_dst == False
-        '01111410': {
-            'agency': 'USGS',
-            'code': '01111410',
-            'county': '44007',
-            'huc': '01090003',
-            'location': {
-                'latitude': '41.9409318',
-                'longitude': '-71.6481214',
-                'srs': 'EPSG:4326'
-            },
-            'name': 'CHEPACHET RIVER WEST OF GAZZA RD AT GAZZAVILLE, RI',
-            'state_code': '44',
-            'network': 'NWIS',
-            'site_type': 'ST',
-            'timezone_info': {
-                'default_tz': {
-                    'abbreviation': 'EST',
-                    'offset': '-05:00'
-                },
-                'dst_tz': {
-                    'abbreviation': 'EDT',
-                    'offset': '-04:00',
-                },
-                'uses_dst': False,
-            }
-        },
-        # only in RI_daily
-        '01116300': {
-            'agency': 'USGS',
-            'code': '01116300',
-            'county': '44007',
-            'huc': '01090004',
-            'location': {
-                'latitude': '41.7564892',
-                'longitude': '-71.4972824',
-                'srs': 'EPSG:4326'
-            },
-            'name': 'FURNACE HILL BROOK AT CRANSTON, RI',
-            'network': 'NWIS',
-            'site_type': 'ST',
-            'state_code': '44',
-            'timezone_info': {
-                'default_tz': {'abbreviation': 'EST', 'offset': '-05:00'},
-                'dst_tz': {'abbreviation': 'EDT', 'offset': '-04:00'},
-                'uses_dst': True
-            },
-        },
-        # only in RI_instantaneous
-        '01115170': {
-            'agency': 'USGS',
-            'code': '01115170',
-            'county': '44007',
-            'huc': '01090004',
-            'location': {
-                'latitude': '41.84093269',
-                'longitude': '-71.584508',
-                'srs': 'EPSG:4326',
-            },
-            'name': 'MOSWANSICUT STREAM NR NORTH SCITUATE, RI',
-            'network': 'NWIS',
-            'site_type': 'ST',
-            'state_code': '44',
-            'timezone_info': {
-                'default_tz': {'abbreviation': 'EST', 'offset': '-05:00'},
-                'dst_tz': {'abbreviation': 'EDT', 'offset': '-04:00'},
-                'uses_dst': True
-            },
-        },
-    }
-
-    for test_code, test_value in test_sites.items():
-        assert sites[test_code] == test_value
-
-
-def test_update_site_list_with_changes(test_file_path):
-    site_files = [
-        (os.path.join('usgs','nwis', 'RI_daily.xml'), {
-            'agency': 'USGS',
-            'code': '01106000',
-            'county': '44005',
-            'huc': '01090002',
-            'location': {'latitude': '41.5584366',
-                        'longitude': '-71.12921047',
-                        'srs': 'EPSG:4326'},
-            'name': 'ADAMSVILLE BROOK AT ADAMSVILLE, RI',
-            'network': 'NWIS',
-            'site_type': 'ST',
-            'state_code': '44',
-            'timezone_info': {
-                'default_tz': {'abbreviation': 'EST', 'offset': '-05:00'},
-                'dst_tz': {'abbreviation': 'EDT', 'offset': '-04:00'},
-                'uses_dst': True}}),
-        (os.path.join('usgs','nwis', 'RI_daily_update.xml'), {
-            'agency': 'USGS',
-            'code': '01106000',
-            'county': '44005',
-            'huc': '01090002',
-            'location': {'latitude': '41.5584366',
-                        'longitude': '-71.12921047',
-                        'srs': 'EPSG:4326'},
-            'name': 'UPDATED NAME',
-            'network': 'NWIS',
-            'site_type': 'ST',
-            'state_code': '44',
-            'timezone_info': {
-                'default_tz': {'abbreviation': 'EST', 'offset': '-05:00'},
-                'dst_tz': {'abbreviation': 'EDT', 'offset': '-04:00'},
-                'uses_dst': True}}),
-    ]
-    for test_file, test_site in site_files:
-        test_site_file = test_util.get_test_file_path(test_file)
-        nwis.hdf5.update_site_list(path=test_file_path,
-                input_file=test_site_file, autorepack=False)
-        sites = nwis.hdf5.get_sites(path=test_file_path)
-        test_code = test_site['code']
-        assert sites[test_code] == test_site
-
-
-def test_sites_table_remains_unique(test_file_path):
-    test_file_path = os.path.join(test_file_path, "test.h5")
-    site_files = [
-            os.path.join('usgs','nwis', 'RI_daily.xml'), 
-            os.path.join('usgs','nwis', 'RI_instantaneous.xml'),
-        ]
-    for site_file in site_files:
-        test_site_file = test_util.get_test_file_path(site_file)
-        nwis.hdf5.update_site_list(path=test_file_path,
-            input_file=test_site_file, autorepack=False)
-
-    with pandas.io.pytables.get_store(test_file_path) as store:
-        sites_df = store.select('sites')
-    assert len(sites_df) == len(set(sites_df.index))
-
-
-def test_get_site(test_file_path):
-    site_code = '08068500'
-    site_data_file = os.path.join('usgs','nwis', 'site_%s_daily.xml' % site_code)
-    input_file = test_util.get_test_file_path(site_data_file)
-    nwis.hdf5.update_site_list(path=test_file_path,
-            input_file=input_file, autorepack=False)
-
-    site = nwis.hdf5.get_site(site_code, path=test_file_path)
-    assert site == {
-        'agency': 'USGS',
-        'code': '08068500',
-        'county': '48339',
-        'huc': '12040102',
-        'location': {
-            'latitude': '30.11049517',
-            'longitude': '-95.4363275',
-            'srs': 'EPSG:4326'
-        },
-        'name': 'Spring Ck nr Spring, TX',
-        'network': 'NWIS',
-        'site_type': 'ST',
-        'state_code': '48',
-        'timezone_info': {
-            'default_tz': {'abbreviation': 'CST', 'offset': '-06:00'},
-            'dst_tz': {'abbreviation': 'CDT', 'offset': '-05:00'},
-            'uses_dst': True
-        },
-    }
-
-
-def test_get_sites_isnt_cached_between_calls(test_file_path):
-    test_file_path = os.path.join(test_file_path, "test.h5")
-
-    site_data_file = os.path.join('usgs', 'nwis', 'RI_daily.xml')
-    input_file = test_util.get_test_file_path(site_data_file)
-
-    nwis.hdf5.update_site_list(input_file=input_file, path=test_file_path,
-            autorepack=False)
-    sites = nwis.hdf5.get_sites(path=test_file_path)
-    assert len(sites) > 0
-
-    if os.path.exists(test_file_path):
-        os.remove(test_file_path)
-    sites = nwis.hdf5.get_sites(path=test_file_path)
-    assert len(sites) == 0
-
-
-def test_empty_update_list_doesnt_error(test_file_path):
-    site_code = '98068500'
-    site_data_file = os.path.join('usgs','nwis', 'site_%s_daily.xml' % site_code)
-    input_file = test_util.get_test_file_path(site_data_file)
-
-    sites = nwis.hdf5.get_sites(path=test_file_path)
-    assert sites == {}
-    nwis.hdf5.update_site_list(path=test_file_path,
-        input_file=input_file, autorepack=False)
-
-    sites = nwis.hdf5.get_sites(path=test_file_path)
-    assert sites == {}
-
-
-def test_get_site_for_missing_raises_lookup(test_file_path):
-    site_code = '08068500'
-    site_data_file = os.path.join('usgs','nwis', 'site_%s_daily.xml' % site_code)
-    input_file = test_util.get_test_file_path(site_data_file)
-    nwis.hdf5.update_site_list(path=test_file_path,
-        input_file=input_file, autorepack=False)
-
-    with pytest.raises(LookupError):
-        missing_code = '98068500'
-        nwis.hdf5.get_site(missing_code, path=test_file_path)
-
-
-def test_non_usgs_site(test_file_path):
-    site_code = '07335390'
-    site_data_file = test_util.get_test_file_path(
-        os.path.join('usgs','nwis', 'site_%s_instantaneous.xml' % site_code))
-    nwis.hdf5.update_site_data(site_code, period='all',
-            path=test_file_path, input_file=site_data_file, autorepack=False)
-
-    site_data = nwis.hdf5.get_site_data(site_code, path=test_file_path)
-    assert len(site_data['00062:00011']['values']) > 1000
-
-
-def test_remove_values(test_file_path):
-    from datetime import datetime
-    site_code = '07335390'
-    parameter_code = '00062:00011'
-    values_to_remove = {
-        parameter_code: ['2012-10-25 06:00', '2012-10-25 23:00',
-            '2012-10-30 15:00:00', datetime(2012, 11, 15, 13)]
-    }
-    site_data_file = test_util.get_test_file_path(
-        os.path.join('usgs','nwis', 'site_%s_instantaneous.xml' % site_code))
-    nwis.hdf5.update_site_data(site_code, period='all',
-            path=test_file_path, input_file=site_data_file, autorepack=False)
-    nwis.hdf5.remove_values(site_code, values_to_remove, path=test_file_path,
-        autorepack=False)
-
-    test_values = [
-        dict(datetime="2012-10-25T01:00:00-05:00", last_checked=None, last_modified=None, qualifiers="P", value=None),
-        dict(datetime="2012-10-25T18:00:00-05:00", last_checked=None, last_modified=None, qualifiers="P", value=None),
-        dict(datetime="2012-10-30T10:00:00-05:00", last_checked=None, last_modified=None, qualifiers="P", value=None),
-        dict(datetime="2012-11-15T07:00:00-06:00", last_checked=None, last_modified=None, qualifiers="P", value=None),
-    ]
-
-    site_data = nwis.hdf5.get_site_data(site_code, path=test_file_path)
-    site_values = site_data[parameter_code]['values']
-    for test_value in test_values:
-        assert test_value in site_values
-
-
-def test_remove_values_with_missing_code(test_file_path):
-    site_code = '08068500'
-    values_to_remove = {
-        '12345:0000': ['2010-01-01'],
-        '00010:00002': ['2012-12-10']
-    }
-    site_data_file = test_util.get_test_file_path(os.path.join('usgs','nwis', 'site_%s_daily.xml' % site_code))
-
-    nwis.hdf5.update_site_data(site_code, period='all', path=test_file_path,
-            input_file=site_data_file, autorepack=False)
-    nwis.hdf5.remove_values(site_code, values_to_remove, path=test_file_path,
-            autorepack=False)
-
-    test_value = dict(datetime="2012-12-10T00:00:00", last_checked=None, last_modified=None, qualifiers="P", value=None)
-
-    site_data = nwis.hdf5.get_site_data(site_code, path=test_file_path)
-    site_values = site_data['00010:00002']['values']
-    assert test_value in site_values
-
-
-def test_site_data_is_sorted(test_file_path):
-    site_code = '01117800'
-    site_data_file = test_util.get_test_file_path(os.path.join('usgs','nwis', 'site_%s_daily.xml' % site_code))
-    nwis.hdf5.update_site_data(site_code, path=test_file_path,
-            input_file=site_data_file, autorepack=False)
-    site_data = nwis.hdf5.get_site_data(site_code, path=test_file_path)
-
-    values = site_data['00060:00003']['values']
-    assert all(
-        values[i]['datetime'] < values[i+1]['datetime']
-        for i in range(len(values) - 1))
-
-
-def test_update_site_data_basic_data_parsing(test_file_path):
-    site_code = '01117800'
-    site_data_file = test_util.get_test_file_path(os.path.join('usgs','nwis', 'site_%s_daily.xml' % site_code))
-    nwis.hdf5.update_site_data(site_code, path=test_file_path,
-            input_file=site_data_file, autorepack=False)
-    site_data = nwis.hdf5.get_site_data(site_code, path=test_file_path)
-
-    test_values = [
-        dict(datetime="1964-01-23T00:00:00", last_checked=None, last_modified=None, qualifiers="A", value='240'),
-        dict(datetime="1964-08-22T00:00:00", last_checked=None, last_modified=None, qualifiers="A", value='7.9'),
-        dict(datetime="2011-12-15T00:00:00", last_checked=None, last_modified=None, qualifiers="P Eqp", value='-999999'),
-        dict(datetime="2012-01-15T00:00:00", last_checked=None, last_modified=None, qualifiers="P e", value='97'),
-        dict(datetime="2012-06-05T00:00:00", last_checked=None, last_modified=None, qualifiers="P", value='74'),
-    ]
-
-    site_values = site_data['00060:00003']['values']
-
-    for test_value in test_values:
-        assert test_value in site_values
-
-
-def test_site_data_filter_by_one_parameter_code(test_file_path):
-    site_code = '08068500'
-    parameter_code = '00065:00003'
-    site_data_file = test_util.get_test_file_path(
-        'usgs/nwis/site_%s_daily.xml' % site_code)
-    nwis.hdf5.update_site_data(site_code, path=test_file_path,
-            input_file=site_data_file, autorepack=False)
-    all_site_data = nwis.hdf5.get_site_data(site_code, path=test_file_path)
-    site_data = nwis.hdf5.get_site_data(site_code, parameter_code=parameter_code, path=test_file_path)
-
-    assert site_data[parameter_code] == all_site_data[parameter_code]
-
-
-def test_site_data_filter_by_multiple_parameter_codes(test_file_path):
-    site_code = '08068500'
-    parameter_code = ['00060:00003', '00065:00003', 'nonexistent']
-    site_data_file = test_util.get_test_file_path(
-        'usgs/nwis/site_%s_daily.xml' % site_code)
-    nwis.hdf5.update_site_data(site_code, path=test_file_path,
-            input_file=site_data_file, autorepack=False)
-    all_site_data = nwis.hdf5.get_site_data(site_code, path=test_file_path)
-    site_data = nwis.hdf5.get_site_data(site_code, parameter_code=parameter_code, path=test_file_path)
-
-    for code in parameter_code:
-        if code in list(site_data.keys()):
-            assert site_data[code] == all_site_data[code]
-
-
-def test_site_data_filter_by_date_all_param(test_file_path):
-    site_code = '08068500'
-    parameter_code = '00065:00003'
-    date_str = '2000-01-01'
-    site_data_file = test_util.get_test_file_path(
-        'usgs/nwis/site_%s_daily.xml' % site_code)
-    nwis.hdf5.update_site_data(site_code, path=test_file_path,
-            input_file=site_data_file, autorepack=False)
-    site_data = nwis.hdf5.get_site_data(site_code, path=test_file_path, start=date_str)
-    for par, data in site_data.items():
-        first_value = data['values'][0]
-        assert datetime.datetime.strptime(first_value["datetime"], '%Y-%m-%dT%H:%M:%S') >= datetime.datetime.strptime(date_str, '%Y-%m-%d')
-
-
-
-def test_site_data_filter_by_date_single_param(test_file_path):
-    site_code = '08068500'
-    parameter_code = '00065:00003'
-    date_str = '2000-01-01'
-    site_data_file = test_util.get_test_file_path(
-        'usgs/nwis/site_%s_daily.xml' % site_code)
-    nwis.hdf5.update_site_data(site_code, path=test_file_path,
-            input_file=site_data_file, autorepack=False)
-    site_data = nwis.hdf5.get_site_data(site_code, path=test_file_path, start=date_str)
-    first_value = site_data[parameter_code]['values'][0]
-    assert datetime.datetime.strptime(first_value["datetime"], '%Y-%m-%dT%H:%M:%S') >= datetime.datetime.strptime(date_str, '%Y-%m-%d')
-
-
-def test_site_data_update_site_list_with_multiple_updates(test_file_path):
-    first_timestamp = '2013-01-01T01:01:01'
-    second_timestamp = '2013-02-02T02:02:02'
-    site_code = '01117800'
-    site_data_file = test_util.get_test_file_path(
-        'usgs/nwis/site_%s_daily.xml' % site_code)
-    with test_util.mocked_urls(site_data_file):
-        with freezegun.freeze_time(first_timestamp):
-            nwis.hdf5.update_site_data(site_code, path=test_file_path,
-                    autorepack=False)
-    site_data = nwis.hdf5.get_site_data(site_code, path=test_file_path)
-
-    last_value = site_data['00060:00003']['values'][-1]
-
-    assert first_timestamp == last_value['last_checked'] == last_value['last_modified']
-
-    update_data_file = test_util.get_test_file_path(os.path.join(
-        'usgs', 'nwis', 'site_%s_daily_update.xml' % site_code))
-    with test_util.mocked_urls(update_data_file):
-        with freezegun.freeze_time(second_timestamp):
-            nwis.hdf5.update_site_data(site_code, path=test_file_path,
-                    autorepack=False)
-    updated_site_data = nwis.hdf5.get_site_data(site_code, path=test_file_path)
-
-    updated_values = updated_site_data['00060:00003']['values']
-    last_value = updated_values[-1]
-    assert last_value['last_checked'] != first_timestamp
-    assert second_timestamp == last_value['last_checked'] == last_value['last_modified']
-
-    original_timestamp = first_timestamp
-    modified_timestamp = second_timestamp
-
-    test_values = [
-        dict(datetime="1963-01-23T00:00:00", last_checked=modified_timestamp, last_modified=modified_timestamp, qualifiers="A", value='7'),
-        dict(datetime="1964-01-23T00:00:00", last_checked=modified_timestamp, last_modified=modified_timestamp, qualifiers="A", value='1017'),
-        dict(datetime="1964-01-24T00:00:00", last_checked=original_timestamp, last_modified=original_timestamp, qualifiers="A", value='191'),
-        dict(datetime="1964-08-22T00:00:00", last_checked=original_timestamp, last_modified=original_timestamp, qualifiers="A", value='7.9'),
-        dict(datetime="1969-05-26T00:00:00", last_checked=modified_timestamp, last_modified=modified_timestamp, qualifiers="A", value='1080'),
-        dict(datetime="2011-12-06T00:00:00", last_checked=modified_timestamp, last_modified=modified_timestamp, qualifiers="P", value='222'),
-        dict(datetime="2011-12-15T00:00:00", last_checked=original_timestamp, last_modified=original_timestamp, qualifiers="P Eqp", value='-999999'),
-        dict(datetime="2012-01-15T00:00:00", last_checked=original_timestamp, last_modified=original_timestamp, qualifiers="P e", value='97'),
-        dict(datetime="2012-05-25T00:00:00", last_checked=modified_timestamp, last_modified=original_timestamp, qualifiers="P", value='56'),
-        dict(datetime="2012-05-26T00:00:00", last_checked=modified_timestamp, last_modified=original_timestamp, qualifiers="P", value='55'),
-        dict(datetime="2012-05-27T00:00:00", last_checked=modified_timestamp, last_modified=modified_timestamp, qualifiers="A", value='52'),
-        dict(datetime="2012-05-28T00:00:00", last_checked=modified_timestamp, last_modified=original_timestamp, qualifiers="P", value='48'),
-        dict(datetime="2012-05-29T00:00:00", last_checked=modified_timestamp, last_modified=modified_timestamp, qualifiers="P", value='1099'),
-        dict(datetime="2012-05-30T00:00:00", last_checked=modified_timestamp, last_modified=modified_timestamp, qualifiers="P", value='1098'),
-        dict(datetime="2012-05-31T00:00:00", last_checked=modified_timestamp, last_modified=original_timestamp, qualifiers="P", value='41'),
-        dict(datetime="2012-06-01T00:00:00", last_checked=modified_timestamp, last_modified=original_timestamp, qualifiers="P", value='37'),
-        dict(datetime="2012-06-02T00:00:00", last_checked=modified_timestamp, last_modified=modified_timestamp, qualifiers="P", value='1097'),
-        dict(datetime="2012-06-03T00:00:00", last_checked=modified_timestamp, last_modified=original_timestamp, qualifiers="P", value='69'),
-        dict(datetime="2012-06-04T00:00:00", last_checked=modified_timestamp, last_modified=original_timestamp, qualifiers="P", value='81'),
-        dict(datetime="2012-06-05T00:00:00", last_checked=modified_timestamp, last_modified=modified_timestamp, qualifiers="P", value='1071'),
-        dict(datetime="2012-06-06T00:00:00", last_checked=modified_timestamp, last_modified=modified_timestamp, qualifiers="P", value='2071'),
-    ]
-
-    for test_value in test_values:
-        assert updated_values.index(test_value) >= 0
-
-
-def test_last_refresh_gets_updated(test_file_path):
-    test_file_path = os.path.join(test_file_path, "test.h5")
-
-    first_timestamp = '2013-01-01T01:01:01'
-    second_timestamp = '2013-02-02T02:02:02'
-    forth_timestamp = '2013-03-03T03:03:03'
-    site_code = '01117800'
-    site_data_file = test_util.get_test_file_path(
-        'usgs/nwis/site_%s_daily.xml' % site_code)
-
-    with test_util.mocked_urls(site_data_file):
-        with freezegun.freeze_time(first_timestamp):
-            nwis.hdf5.update_site_data(site_code, path=test_file_path,
-                    autorepack=False)
-        first_refresh = nwis.hdf5._get_last_refresh(site_code, test_file_path)
-        assert first_refresh == first_timestamp
-
-        with freezegun.freeze_time(second_timestamp):
-            nwis.hdf5.update_site_data(site_code, path=test_file_path,
-                    autorepack=False)
-        second_refresh = nwis.hdf5._get_last_refresh(site_code, test_file_path)
-        assert second_refresh == second_timestamp
-
-        nwis.hdf5.update_site_data(site_code, path=test_file_path,
-                input_file=site_data_file, autorepack=False)
-        third_refresh = nwis.hdf5._get_last_refresh(site_code, test_file_path)
-        assert third_refresh == None
-
-        with freezegun.freeze_time(forth_timestamp):
-            nwis.hdf5.update_site_data(site_code, path=test_file_path,
-                    autorepack=False)
-        forth_refresh = nwis.hdf5._get_last_refresh(site_code, test_file_path)
-        assert forth_refresh is not None
-        assert forth_refresh == forth_timestamp
-
-
-def test_update_site_data_updates_site_list(test_file_path):
-    site_code = '01117800'
-    site_data_file = test_util.get_test_file_path(os.path.join(
-        'usgs', 'nwis', 'site_%s_daily_update.xml' % site_code))
-    nwis.hdf5.update_site_data(site_code, path=test_file_path,
-            input_file=site_data_file, autorepack=False)
-    site = nwis.hdf5.get_site(site_code, path=test_file_path)
-
-    test_site = {
-        'agency': 'USGS',
-        'code': '01117800',
-        'county': '44009',
-        'huc': '01090005',
-        'location': {
-            'latitude': '41.5739884',
-            'longitude': '-71.72062318',
-            'srs': 'EPSG:4326'
-        },
-        'name': 'WOOD RIVER NEAR ARCADIA, RI',
-        'network': 'NWIS',
-        'site_type': 'ST',
-        'state_code': '44',
-        'timezone_info': {
-            'default_tz': {'abbreviation': 'EST', 'offset': '-05:00'},
-            'dst_tz': {'abbreviation': 'EDT', 'offset': '-04:00'},
-            'uses_dst': True
-        }
-    }
-
-    assert site == test_site
-
-
-def test_handles_empty_updates(test_file_path):
-    site_code = '01117800'
-    site_data_file = test_util.get_test_file_path(os.path.join(
-        'usgs', 'nwis', 'site_%s_daily.xml' % site_code))
-    empty_site_data_file = test_util.get_test_file_path(os.path.join(
-        'usgs', 'nwis', 'site_%s_daily_empty.xml' % site_code))
-
-    nwis.hdf5.update_site_data(site_code, path=test_file_path,
-            input_file=empty_site_data_file, autorepack=False)
-    empty_site_data = nwis.hdf5.get_site_data(site_code, path=test_file_path)
-    assert empty_site_data['00060:00003']['values'] == []
-
-    nwis.hdf5.update_site_data(site_code, path=test_file_path,
-            input_file=site_data_file, autorepack=False)
-
-    nwis.hdf5.update_site_data(site_code, path=test_file_path,
-            input_file=empty_site_data_file, autorepack=False)
-    site_data = nwis.hdf5.get_site_data(site_code, path=test_file_path)
-
-    values = site_data['00060:00003']['values']
-    test_values = [
-        dict(datetime="1964-01-23T00:00:00", last_checked=None, last_modified=None, qualifiers="A", value='240'),
-    ]
-
-    for test_value in test_values:
-        assert values.index(test_value) >= 0
-
-
-def test_file_size_doesnt_balloon_with_update_site_data(test_file_path):
-    test_file_path = os.path.join(test_file_path, "test.h5")
-    site_code = '01117800'
-    site_data_file = test_util.get_test_file_path(os.path.join(
-        'usgs', 'nwis', 'site_%s_daily.xml' % site_code))
-    update_site_data_file = test_util.get_test_file_path(os.path.join(
-        'usgs', 'nwis', 'site_%s_daily_update.xml' % site_code))
-
-    nwis.hdf5.update_site_data(site_code, path=test_file_path,
-            input_file=site_data_file)
-    nwis.hdf5.update_site_data(site_code, path=test_file_path,
-            input_file=update_site_data_file)
-    original_size = os.path.getsize(test_file_path)
-    for i in range(20):
-        nwis.hdf5.update_site_data(site_code, path=test_file_path,
-                input_file=update_site_data_file)
-
-    expected_size = original_size * 1.01
-    assert os.path.getsize(test_file_path) <= expected_size
-
-
-def test_file_size_doesnt_balloon_with_update_site_list(test_file_path):
-    test_file_path = os.path.join(test_file_path, "test.h5")
-    site_list_file = test_util.get_test_file_path(os.path.join('usgs', 'nwis', 'RI_daily.xml'))
-    updated_site_list_file = test_util.get_test_file_path(os.path.join('usgs', 'nwis', 'RI_daily.xml'))
-    nwis.hdf5.update_site_list(path=test_file_path,
-        input_file=site_list_file)
-    nwis.hdf5.update_site_list(path=test_file_path,
-            input_file=updated_site_list_file)
-    original_size = os.path.getsize(test_file_path)
-    for i in range(3):
-        nwis.hdf5.update_site_list(path=test_file_path,
-                input_file=updated_site_list_file)
-    expected_size = original_size * 1.01
-    assert os.path.getsize(test_file_path) <= expected_size
diff --git a/test/usgs_nwis_pytables_test.py b/test/usgs_nwis_pytables_test.py
deleted file mode 100644
index cf07b5da..00000000
--- a/test/usgs_nwis_pytables_test.py
+++ /dev/null
@@ -1,17 +0,0 @@
-from builtins import str
-import pytest
-
-from ulmo.usgs import nwis
-
-
-def test_pytables_raises_deprecation_warnings(recwarn):
-    nwis.pytables.get_sites()
-    w = recwarn.pop(DeprecationWarning)
-    assert issubclass(w.category, DeprecationWarning)
-    assert 'nwis.pytables module has moved' in str(w.message)
-
-
-def test_hdf5_doesnt_raise_deprecation_warnings(recwarn):
-    nwis.hdf5.get_sites()
-    with pytest.raises(AssertionError):
-        recwarn.pop(DeprecationWarning)
diff --git a/test/usgs_nwis_test.py b/test/usgs_nwis_test.py
index 0af89936..287724de 100644
--- a/test/usgs_nwis_test.py
+++ b/test/usgs_nwis_test.py
@@ -129,4 +129,5 @@ def test_get_site_data_multiple_methods():
     with test_util.mocked_urls(site_data_file):
         site_data = ulmo.usgs.nwis.get_site_data(site_code, methods={'62614': 'all', '45592': 'all'})
         assert len(site_data['00054:00003']['values']) == 1
-        assert len(site_data.keys()) == 17
+        print(site_data.keys())
+        assert len(site_data.keys()) == 13
diff --git a/test/wof_test.py b/test/wof_test.py
index 961f7940..468bd980 100644
--- a/test/wof_test.py
+++ b/test/wof_test.py
@@ -3,7 +3,7 @@
 
 
 def test_core_get_sites_waterml_1_0():
-    WSDL_URL = 'http://hydroportal.cuahsi.org/muddyriver/cuahsi_1_0.asmx?WSDL'
+    WSDL_URL = 'https://hydroportal.cuahsi.org/muddyriver/cuahsi_1_0.asmx?WSDL'
     get_sites_file = 'cuahsi/wof/get_sites_muddyriver_1_0.xml'
     with test_util.mocked_suds_client('1.0', dict(GetSitesXml=get_sites_file)):
         sites = ulmo.cuahsi.wof.get_sites(WSDL_URL)
@@ -11,7 +11,7 @@ def test_core_get_sites_waterml_1_0():
 
 
 def test_core_get_sites_waterml_1_1():
-    WSDL_URL = 'http://hydroportal.cuahsi.org/ipswich/cuahsi_1_1.asmx?WSDL'
+    WSDL_URL = 'https://hydroportal.cuahsi.org/ipswich/cuahsi_1_1.asmx?WSDL'
     get_sites_file = 'cuahsi/wof/get_sites_ipswich_1_1.xml'
     with test_util.mocked_suds_client('1.1', dict(GetSites=get_sites_file)):
         sites = ulmo.cuahsi.wof.get_sites(WSDL_URL)
@@ -19,7 +19,7 @@ def test_core_get_sites_waterml_1_1():
 
 
 def test_core_get_site_info_waterml_1_0():
-    WSDL_URL = 'http://hydroportal.cuahsi.org/muddyriver/cuahsi_1_0.asmx?WSDL'
+    WSDL_URL = 'https://hydroportal.cuahsi.org/muddyriver/cuahsi_1_0.asmx?WSDL'
     site_info_file = 'cuahsi/wof/get_site_info_muddyriver_14_1_0.xml'
     with test_util.mocked_suds_client('1.0', dict(GetSiteInfo=site_info_file)):
         site_info = ulmo.cuahsi.wof.get_site_info(WSDL_URL, 'MuddyRiver:MuddyRiver_14')
@@ -38,7 +38,7 @@ def test_core_get_site_info_waterml_1_0():
 
 
 def test_core_get_site_info_waterml_1_1():
-    WSDL_URL = 'http://hydroportal.cuahsi.org/ipswich/cuahsi_1_1.asmx?WSDL'
+    WSDL_URL = 'https://hydroportal.cuahsi.org/ipswich/cuahsi_1_1.asmx?WSDL'
     site_info_file = 'cuahsi/wof/get_site_info_ipswich_MMB_1_1.xml'
     with test_util.mocked_suds_client('1.1', dict(GetSiteInfo=site_info_file)):
         site_info = ulmo.cuahsi.wof.get_site_info(WSDL_URL, 'ipswich:MMB')
@@ -56,7 +56,7 @@ def test_core_get_site_info_waterml_1_1():
 
 
 def test_core_get_values_waterml_1_0():
-    WSDL_URL = 'http://hydroportal.cuahsi.org/muddyriver/cuahsi_1_0.asmx?WSDL'
+    WSDL_URL = 'https://hydroportal.cuahsi.org/muddyriver/cuahsi_1_0.asmx?WSDL'
     get_values_file = 'cuahsi/wof/get_values_1_0_MuddyRiver_MuddyRiver_14_MR_MuddyRiver_ACID.xml'
     with test_util.mocked_suds_client('1.0', dict(GetValues=get_values_file)):
         values = ulmo.cuahsi.wof.get_values(
@@ -84,7 +84,7 @@ def test_core_get_values_waterml_1_0():
 
 
 def test_core_get_values_start_and_end_parsing():
-    WSDL_URL = 'http://hydroportal.cuahsi.org/muddyriver/cuahsi_1_0.asmx?WSDL'
+    WSDL_URL = 'https://hydroportal.cuahsi.org/muddyriver/cuahsi_1_0.asmx?WSDL'
     file_template = 'cuahsi/wof/get_values_1_0_MuddyRiver_MuddyRiver_14_MR_MuddyRiver_ACID_%(start)s_%(end)s.xml'
 
     start_ends = [
@@ -112,7 +112,7 @@ def test_core_get_values_start_and_end_parsing():
 
 
 def test_core_get_values_waterml_1_1():
-    WSDL_URL = 'http://hydroportal.cuahsi.org/ipswich/cuahsi_1_1.asmx?WSDL'
+    WSDL_URL = 'https://hydroportal.cuahsi.org/ipswich/cuahsi_1_1.asmx?WSDL'
     get_values_file = 'cuahsi/wof/get_values_1_1_ipswich_MMB_ipswich_Temp.xml'
     with test_util.mocked_suds_client('1.1', dict(GetValues=get_values_file)):
         values = ulmo.cuahsi.wof.get_values(WSDL_URL, 'ipswich:MMB', 'ipswich:Temp')
@@ -138,7 +138,7 @@ def test_core_get_values_waterml_1_1():
 
 
 def test_core_get_variable_info_waterml_single_1_0():
-    WSDL_URL = 'http://hydroportal.cuahsi.org/muddyriver/cuahsi_1_0.asmx?WSDL'
+    WSDL_URL = 'https://hydroportal.cuahsi.org/muddyriver/cuahsi_1_0.asmx?WSDL'
     get_variable_info_file = 'cuahsi/wof/get_variable_info_1_0_MR_MuddyRiver_ACID.xml'
     with test_util.mocked_suds_client('1.0', dict(GetVariableInfo=get_variable_info_file)):
         variable_info = ulmo.cuahsi.wof.get_variable_info(WSDL_URL, 'MR:MuddyRiver_ACID')
@@ -164,7 +164,7 @@ def test_core_get_variable_info_waterml_single_1_0():
 
 
 def test_core_get_variable_info_waterml_all_1_0():
-    WSDL_URL = 'http://hydroportal.cuahsi.org/muddyriver/cuahsi_1_0.asmx?WSDL'
+    WSDL_URL = 'https://hydroportal.cuahsi.org/muddyriver/cuahsi_1_0.asmx?WSDL'
     get_variable_info_file = 'cuahsi/wof/get_variable_info_1_0_MR_all.xml'
     with test_util.mocked_suds_client('1.0', dict(GetVariableInfo=get_variable_info_file)):
         variable_info = ulmo.cuahsi.wof.get_variable_info(WSDL_URL)
@@ -201,7 +201,7 @@ def test_core_get_variable_info_waterml_all_1_0():
 
 
 def test_core_get_variable_info_waterml_single_1_1():
-    WSDL_URL = 'http://hydroportal.cuahsi.org/ipswich/cuahsi_1_1.asmx?WSDL'
+    WSDL_URL = 'https://hydroportal.cuahsi.org/ipswich/cuahsi_1_1.asmx?WSDL'
     get_variable_info_file = 'cuahsi/wof/get_variable_info_1_1_ipswich_Temp.xml'
     with test_util.mocked_suds_client('1.1', dict(GetVariableInfo=get_variable_info_file)):
         variable_info = ulmo.cuahsi.wof.get_variable_info(WSDL_URL, 'ipswich:Temp')
@@ -210,7 +210,7 @@ def test_core_get_variable_info_waterml_single_1_1():
 
 
 def test_core_get_variable_info_waterml_all_1_1():
-    WSDL_URL = 'http://hydroportal.cuahsi.org/ipswich/cuahsi_1_1.asmx?WSDL'
+    WSDL_URL = 'https://hydroportal.cuahsi.org/ipswich/cuahsi_1_1.asmx?WSDL'
     get_variable_info_file = 'cuahsi/wof/get_variable_info_1_1_ipswich_all.xml'
     with test_util.mocked_suds_client('1.1', dict(GetVariableInfo=get_variable_info_file)):
         variable_info = ulmo.cuahsi.wof.get_variable_info(WSDL_URL)