#!/usr/bin/env pytest
###############################################################################
# $Id$
#
# Project:  GDAL/OGR Test Suite
# Purpose:  Test /vsis3
# Author:   Even Rouault <even dot rouault at spatialys dot com>
#
###############################################################################
# Copyright (c) 2015, Even Rouault <even dot rouault at spatialys dot com>
#
# Permission is hereby granted, free of charge, to any person obtaining a
# copy of this software and associated documentation files (the "Software"),
# to deal in the Software without restriction, including without limitation
# the rights to use, copy, modify, merge, publish, distribute, sublicense,
# and/or sell copies of the Software, and to permit persons to whom the
# Software is furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included
# in all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
# DEALINGS IN THE SOFTWARE.
###############################################################################

import json
import os.path
import stat
import sys
from osgeo import gdal


import gdaltest
import webserver
import pytest


def open_for_read(uri):
    """
    Opens a test file for reading.
    """
    return gdal.VSIFOpenExL(uri, 'rb', 1)

###############################################################################


def test_vsis3_init():

    gdaltest.aws_vars = {}
    for var in ('AWS_SECRET_ACCESS_KEY', 'AWS_ACCESS_KEY_ID', 'AWS_TIMESTAMP', 'AWS_HTTPS', 'AWS_VIRTUAL_HOSTING', 'AWS_S3_ENDPOINT', 'AWS_REQUEST_PAYER', 'AWS_DEFAULT_REGION', 'AWS_DEFAULT_PROFILE', 'AWS_PROFILE', 'AWS_NO_SIGN_REQUEST'):
        gdaltest.aws_vars[var] = gdal.GetConfigOption(var)
        if gdaltest.aws_vars[var] is not None:
            gdal.SetConfigOption(var, "")

    # To avoid user AWS credentials in ~/.aws/credentials and ~/.aws/config
    # to mess up our tests
    gdal.SetConfigOption('CPL_AWS_CREDENTIALS_FILE', '')
    gdal.SetConfigOption('AWS_CONFIG_FILE', '')
    gdal.SetConfigOption('CPL_AWS_EC2_API_ROOT_URL', '')

    assert gdal.GetSignedURL('/vsis3/foo/bar') is None

###############################################################################
# Test AWS_NO_SIGN_REQUEST=YES


def test_vsis3_no_sign_request():

    if not gdaltest.built_against_curl():
        pytest.skip()

    with gdaltest.config_option('AWS_NO_SIGN_REQUEST', 'YES'):
        actual_url = gdal.GetActualURL('/vsis3/landsat-pds/L8/001/002/LC80010022016230LGN00/LC80010022016230LGN00_B1.TIF')
        assert actual_url == 'https://landsat-pds.s3.amazonaws.com/L8/001/002/LC80010022016230LGN00/LC80010022016230LGN00_B1.TIF'

        actual_url = gdal.GetActualURL('/vsis3_streaming/landsat-pds/L8/001/002/LC80010022016230LGN00/LC80010022016230LGN00_B1.TIF')
        assert actual_url == 'https://landsat-pds.s3.amazonaws.com/L8/001/002/LC80010022016230LGN00/LC80010022016230LGN00_B1.TIF'

        f = open_for_read('/vsis3/landsat-pds/L8/001/002/LC80010022016230LGN00/LC80010022016230LGN00_B1.TIF')

    if f is None:
        if gdaltest.gdalurlopen('https://landsat-pds.s3.amazonaws.com/L8/001/002/LC80010022016230LGN00/LC80010022016230LGN00_B1.TIF') is None:
            pytest.skip('cannot open URL')
        pytest.fail()
    gdal.VSIFCloseL(f)


###############################################################################
# Test Sync() and multithreaded download


def test_vsis3_sync_multithreaded_download():

    if not gdaltest.built_against_curl():
        pytest.skip()

    def cbk(pct, _, tab):
        assert pct >= tab[0]
        tab[0] = pct
        return True

    tab = [ -1 ]
    # Use a public bucket with /test_dummy/foo and /test_dummy/bar files
    with gdaltest.config_option('AWS_NO_SIGN_REQUEST', 'YES'):
        assert gdal.Sync('/vsis3/cdn.proj.org/test_dummy',
                         '/vsimem/test_vsis3_no_sign_request_sync',
                         options=['NUM_THREADS=2'],
                         callback=cbk, callback_data=tab)
    assert tab[0] == 1.0
    assert gdal.VSIStatL('/vsimem/test_vsis3_no_sign_request_sync/test_dummy/foo').size == 4
    assert gdal.VSIStatL('/vsimem/test_vsis3_no_sign_request_sync/test_dummy/bar').size == 4
    gdal.RmdirRecursive('/vsimem/test_vsis3_no_sign_request_sync')


###############################################################################
# Test Sync() and multithreaded download and CHUNK_SIZE


def test_vsis3_sync_multithreaded_download_chunk_size():

    if not gdaltest.built_against_curl():
        pytest.skip()

    def cbk(pct, _, tab):
        assert pct >= tab[0]
        tab[0] = pct
        return True

    tab = [ -1 ]
    # Use a public bucket with /test_dummy/foo and /test_dummy/bar files
    with gdaltest.config_option('AWS_NO_SIGN_REQUEST', 'YES'):
        assert gdal.Sync('/vsis3/cdn.proj.org/test_dummy',
                         '/vsimem/test_vsis3_no_sign_request_sync',
                         options=['NUM_THREADS=2', 'CHUNK_SIZE=3'],
                         callback=cbk, callback_data=tab)
    assert tab[0] == 1.0
    assert gdal.VSIStatL('/vsimem/test_vsis3_no_sign_request_sync/test_dummy/foo').size == 4
    assert gdal.VSIStatL('/vsimem/test_vsis3_no_sign_request_sync/test_dummy/bar').size == 4

    gdal.RmdirRecursive('/vsimem/test_vsis3_no_sign_request_sync')

###############################################################################
# Error cases


def test_vsis3_1():

    if not gdaltest.built_against_curl():
        pytest.skip()

    # Missing AWS_SECRET_ACCESS_KEY
    gdal.ErrorReset()
    with gdaltest.error_handler():
        f = open_for_read('/vsis3/foo/bar')
    assert f is None and gdal.VSIGetLastErrorMsg().find('AWS_SECRET_ACCESS_KEY') >= 0

    gdal.ErrorReset()
    with gdaltest.error_handler():
        f = open_for_read('/vsis3_streaming/foo/bar')
    assert f is None and gdal.VSIGetLastErrorMsg().find('AWS_SECRET_ACCESS_KEY') >= 0

    gdal.SetConfigOption('AWS_SECRET_ACCESS_KEY', 'AWS_SECRET_ACCESS_KEY')

    # Missing AWS_ACCESS_KEY_ID
    gdal.ErrorReset()
    with gdaltest.error_handler():
        f = open_for_read('/vsis3/foo/bar')
    assert f is None and gdal.VSIGetLastErrorMsg().find('AWS_ACCESS_KEY_ID') >= 0

    gdal.SetConfigOption('AWS_ACCESS_KEY_ID', 'AWS_ACCESS_KEY_ID')

    # ERROR 1: The AWS Access Key Id you provided does not exist in our records.
    gdal.ErrorReset()
    with gdaltest.error_handler():
        f = open_for_read('/vsis3/foo/bar.baz')
    if f is not None or gdal.VSIGetLastErrorMsg() == '':
        if f is not None:
            gdal.VSIFCloseL(f)
        if gdal.GetConfigOption('APPVEYOR') is not None:
            return
        pytest.fail(gdal.VSIGetLastErrorMsg())

    gdal.ErrorReset()
    with gdaltest.error_handler():
        f = open_for_read('/vsis3_streaming/foo/bar.baz')
    assert f is None and gdal.VSIGetLastErrorMsg() != ''

###############################################################################


def test_vsis3_start_webserver():

    gdaltest.webserver_process = None
    gdaltest.webserver_port = 0

    if not gdaltest.built_against_curl():
        pytest.skip()

    (gdaltest.webserver_process, gdaltest.webserver_port) = webserver.launch(handler=webserver.DispatcherHttpHandler)
    if gdaltest.webserver_port == 0:
        pytest.skip()

    gdal.SetConfigOption('AWS_SECRET_ACCESS_KEY', 'AWS_SECRET_ACCESS_KEY')
    gdal.SetConfigOption('AWS_ACCESS_KEY_ID', 'AWS_ACCESS_KEY_ID')
    gdal.SetConfigOption('AWS_TIMESTAMP', '20150101T000000Z')
    gdal.SetConfigOption('AWS_HTTPS', 'NO')
    gdal.SetConfigOption('AWS_VIRTUAL_HOSTING', 'NO')
    gdal.SetConfigOption('AWS_S3_ENDPOINT', '127.0.0.1:%d' % gdaltest.webserver_port)


def get_s3_fake_bucket_resource_method(request):
    request.protocol_version = 'HTTP/1.1'

    if 'Authorization' not in request.headers:
        sys.stderr.write('Bad headers: %s\n' % str(request.headers))
        request.send_response(403)
        return
    expected_authorization_8080 = 'AWS4-HMAC-SHA256 Credential=AWS_ACCESS_KEY_ID/20150101/us-east-1/s3/aws4_request,SignedHeaders=host;x-amz-content-sha256;x-amz-date,Signature=38901846b865b12ac492bc005bb394ca8d60c098b68db57c084fac686a932f9e'
    expected_authorization_8081 = 'AWS4-HMAC-SHA256 Credential=AWS_ACCESS_KEY_ID/20150101/us-east-1/s3/aws4_request,SignedHeaders=host;x-amz-content-sha256;x-amz-date,Signature=9f623b7ffce76188a456c70fb4813eb31969e88d130d6b4d801b3accbf050d6c'
    if request.headers['Authorization'] != expected_authorization_8080 and request.headers['Authorization'] != expected_authorization_8081:
        sys.stderr.write("Bad Authorization: '%s'\n" % str(request.headers['Authorization']))
        request.send_response(403)
        return

    request.send_response(200)
    request.send_header('Content-type', 'text/plain')
    request.send_header('Content-Length', 3)
    request.send_header('Connection', 'close')
    request.end_headers()
    request.wfile.write("""foo""".encode('ascii'))

###############################################################################
# Test with a fake AWS server


def test_vsis3_2():

    if gdaltest.webserver_port == 0:
        pytest.skip()

    signed_url = gdal.GetSignedURL('/vsis3/s3_fake_bucket/resource')
    expected_url_8080 = 'http://127.0.0.1:8080/s3_fake_bucket/resource?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=AWS_ACCESS_KEY_ID%2F20150101%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Date=20150101T000000Z&X-Amz-Expires=3600&X-Amz-Signature=dca239dd95f72ff8c37c15c840afc54cd19bdb07f7aaee2223108b5b0ad35da8&X-Amz-SignedHeaders=host'
    expected_url_8081 = 'http://127.0.0.1:8081/s3_fake_bucket/resource?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=AWS_ACCESS_KEY_ID%2F20150101%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Date=20150101T000000Z&X-Amz-Expires=3600&X-Amz-Signature=ef5216bc5971863414c69f6ca095276c0d62c0da97fa4f6ab80c30bd7fc146ac&X-Amz-SignedHeaders=host'
    assert signed_url in (expected_url_8080, expected_url_8081)

    handler = webserver.SequentialHandler()
    handler.add('GET', '/s3_fake_bucket/resource', custom_method=get_s3_fake_bucket_resource_method)

    with webserver.install_http_handler(handler):
        f = open_for_read('/vsis3/s3_fake_bucket/resource')
        assert f is not None
        data = gdal.VSIFReadL(1, 4, f).decode('ascii')
        gdal.VSIFCloseL(f)

        assert data == 'foo'

    handler = webserver.SequentialHandler()
    handler.add('GET', '/s3_fake_bucket/resource', custom_method=get_s3_fake_bucket_resource_method)
    with webserver.install_http_handler(handler):
        f = open_for_read('/vsis3_streaming/s3_fake_bucket/resource')
        assert f is not None
        data = gdal.VSIFReadL(1, 4, f).decode('ascii')
        gdal.VSIFCloseL(f)

    assert data == 'foo'

    handler = webserver.SequentialHandler()

    def method(request):
        request.protocol_version = 'HTTP/1.1'

        if 'Authorization' not in request.headers:
            sys.stderr.write('Bad headers: %s\n' % str(request.headers))
            request.send_response(403)
            return
        expected_authorization_8080 = 'AWS4-HMAC-SHA256 Credential=AWS_ACCESS_KEY_ID/20150101/us-east-1/s3/aws4_request,SignedHeaders=host;x-amz-content-sha256;x-amz-date;x-amz-security-token,Signature=464a21835038b4f4d292b6463b8a005b9aaa980513aa8c42fc170abb733dce85'
        expected_authorization_8081 = 'AWS4-HMAC-SHA256 Credential=AWS_ACCESS_KEY_ID/20150101/us-east-1/s3/aws4_request,SignedHeaders=host;x-amz-content-sha256;x-amz-date;x-amz-security-token,Signature=b10e91575186342f9f2acfc91c4c2c9938c4a9e8cdcbc043d09d59d9641ad7fb'
        if request.headers['Authorization'] != expected_authorization_8080 and request.headers['Authorization'] != expected_authorization_8081:
            sys.stderr.write("Bad Authorization: '%s'\n" % str(request.headers['Authorization']))
            request.send_response(403)
            return

        request.send_response(200)
        request.send_header('Content-type', 'text/plain')
        request.send_header('Content-Length', 3)
        request.end_headers()
        request.wfile.write("""foo""".encode('ascii'))

    handler.add('GET', '/s3_fake_bucket_with_session_token/resource', custom_method=method)

    # Test with temporary credentials
    with gdaltest.config_option('AWS_SESSION_TOKEN', 'AWS_SESSION_TOKEN'):
        with webserver.install_http_handler(handler):
            f = open_for_read('/vsis3/s3_fake_bucket_with_session_token/resource')
            assert f is not None
            data = gdal.VSIFReadL(1, 4, f).decode('ascii')
            gdal.VSIFCloseL(f)

    handler = webserver.SequentialHandler()

    def method(request):
        request.protocol_version = 'HTTP/1.1'
        if 'Range' in request.headers:
            if request.headers['Range'] != 'bytes=0-16383':
                sys.stderr.write("Bad Range: '%s'\n" % str(request.headers['Range']))
                request.send_response(403)
                return
            request.send_response(206)
            request.send_header('Content-type', 'text/plain')
            request.send_header('Content-Range', 'bytes 0-16383/1000000')
            request.send_header('Content-Length', 16384)
            request.send_header('Connection', 'close')
            request.end_headers()
            request.wfile.write(('a' * 16384).encode('ascii'))
        else:
            request.send_response(200)
            request.send_header('Content-type', 'text/plain')
            request.send_header('Content-Length', 1000000)
            request.send_header('Connection', 'close')
            request.end_headers()
            request.wfile.write(('a' * 1000000).encode('ascii'))

    handler.add('GET', '/s3_fake_bucket/resource2.bin', custom_method=method)

    with webserver.install_http_handler(handler):
        # old_val = gdal.GetConfigOption('GDAL_DISABLE_READDIR_ON_OPEN')
        # gdal.SetConfigOption('GDAL_DISABLE_READDIR_ON_OPEN', 'EMPTY_DIR')
        stat_res = gdal.VSIStatL('/vsis3/s3_fake_bucket/resource2.bin')
        # gdal.SetConfigOption('GDAL_DISABLE_READDIR_ON_OPEN', old_val)
        if stat_res is None or stat_res.size != 1000000:
            if stat_res is not None:
                print(stat_res.size)
            else:
                print(stat_res)
            pytest.fail()

    handler = webserver.SequentialHandler()
    handler.add('HEAD', '/s3_fake_bucket/resource2.bin', 200,
                {'Content-type': 'text/plain',
                 'Content-Length': 1000000,
                 'Connection': 'close'})
    with webserver.install_http_handler(handler):
        stat_res = gdal.VSIStatL('/vsis3_streaming/s3_fake_bucket/resource2.bin')
    if stat_res is None or stat_res.size != 1000000:
        if stat_res is not None:
            print(stat_res.size)
        else:
            print(stat_res)
        pytest.fail()

    handler = webserver.SequentialHandler()

    def method(request):
        request.protocol_version = 'HTTP/1.1'
        if request.headers['Authorization'].find('us-east-1') >= 0:
            request.send_response(400)
            response = '<?xml version="1.0" encoding="UTF-8"?><Error><Message>bla</Message><Code>AuthorizationHeaderMalformed</Code><Region>us-west-2</Region></Error>'
            response = '%x\r\n%s\r\n0\r\n\r\n' % (len(response), response)
            request.send_header('Content-type', 'application/xml')
            request.send_header('Transfer-Encoding', 'chunked')
            request.send_header('Connection', 'close')
            request.end_headers()
            request.wfile.write(response.encode('ascii'))
        else:
            sys.stderr.write('Bad headers: %s\n' % str(request.headers))
            request.send_response(403)

    handler.add('GET', '/s3_fake_bucket/redirect', custom_method=method)

    def method(request):
        request.protocol_version = 'HTTP/1.1'
        if request.headers['Authorization'].find('us-west-2') >= 0 and request.headers['Host'].startswith('127.0.0.1'):
            request.send_response(301)
            response = '<?xml version="1.0" encoding="UTF-8"?><Error><Message>bla</Message><Code>PermanentRedirect</Code><Endpoint>localhost:%d</Endpoint></Error>' % request.server.port
            response = '%x\r\n%s\r\n0\r\n\r\n' % (len(response), response)
            request.send_header('Content-type', 'application/xml')
            request.send_header('Transfer-Encoding', 'chunked')
            request.send_header('Connection', 'close')
            request.end_headers()
            request.wfile.write(response.encode('ascii'))
        else:
            sys.stderr.write('Bad headers: %s\n' % str(request.headers))
            request.send_response(403)

    handler.add('GET', '/s3_fake_bucket/redirect', custom_method=method)

    def method(request):
        request.protocol_version = 'HTTP/1.1'
        if request.headers['Authorization'].find('us-west-2') >= 0 and request.headers['Host'].startswith('localhost'):
            request.send_response(200)
            request.send_header('Content-type', 'text/plain')
            request.send_header('Content-Length', 3)
            request.send_header('Connection', 'close')
            request.end_headers()
            request.wfile.write("""foo""".encode('ascii'))
        else:
            sys.stderr.write('Bad headers: %s\n' % str(request.headers))
            request.send_response(403)

    handler.add('GET', '/s3_fake_bucket/redirect', custom_method=method)

    # Test region and endpoint 'redirects'
    with webserver.install_http_handler(handler):
        f = open_for_read('/vsis3/s3_fake_bucket/redirect')
        assert f is not None
        data = gdal.VSIFReadL(1, 4, f).decode('ascii')
        gdal.VSIFCloseL(f)

    if data != 'foo':

        if gdaltest.is_travis_branch('trusty'):
            pytest.skip('Skipped on trusty branch, but should be investigated')

        pytest.fail(data)

    # Test region and endpoint 'redirects'
    gdal.VSICurlClearCache()

    handler.req_count = 0
    with webserver.install_http_handler(handler):
        f = open_for_read('/vsis3_streaming/s3_fake_bucket/redirect')
        assert f is not None
        data = gdal.VSIFReadL(1, 4, f).decode('ascii')
        gdal.VSIFCloseL(f)

    assert data == 'foo'

    handler = webserver.SequentialHandler()

    def method(request):
        # /vsis3_streaming/ should have remembered the change of region and endpoint
        if request.headers['Authorization'].find('us-west-2') < 0 or \
                not request.headers['Host'].startswith('localhost'):
            sys.stderr.write('Bad headers: %s\n' % str(request.headers))
            request.send_response(403)

        request.protocol_version = 'HTTP/1.1'
        request.send_response(400)
        response = 'bla'
        response = '%x\r\n%s\r\n0\r\n\r\n' % (len(response), response)
        request.send_header('Content-type', 'application/xml')
        request.send_header('Transfer-Encoding', 'chunked')
        request.send_header('Connection', 'close')
        request.end_headers()
        request.wfile.write(response.encode('ascii'))

    handler.add('GET', '/s3_fake_bucket/non_xml_error', custom_method=method)

    gdal.ErrorReset()
    with webserver.install_http_handler(handler):
        with gdaltest.error_handler():
            f = open_for_read('/vsis3_streaming/s3_fake_bucket/non_xml_error')
    assert f is None and gdal.VSIGetLastErrorMsg().find('bla') >= 0

    handler = webserver.SequentialHandler()
    response = '<?xml version="1.0" encoding="UTF-8"?><oops>'
    response = '%x\r\n%s\r\n0\r\n\r\n' % (len(response), response)
    handler.add('GET', '/s3_fake_bucket/invalid_xml_error', 400,
                {'Content-type': 'application/xml',
                 'Transfer-Encoding': 'chunked',
                 'Connection': 'close'}, response)
    gdal.ErrorReset()
    with webserver.install_http_handler(handler):
        with gdaltest.error_handler():
            f = open_for_read('/vsis3_streaming/s3_fake_bucket/invalid_xml_error')
    assert f is None and gdal.VSIGetLastErrorMsg().find('<oops>') >= 0

    handler = webserver.SequentialHandler()
    response = '<?xml version="1.0" encoding="UTF-8"?><Error/>'
    response = '%x\r\n%s\r\n0\r\n\r\n' % (len(response), response)
    handler.add('GET', '/s3_fake_bucket/no_code_in_error', 400,
                {'Content-type': 'application/xml',
                 'Transfer-Encoding': 'chunked',
                 'Connection': 'close'}, response)
    gdal.ErrorReset()
    with webserver.install_http_handler(handler):
        with gdaltest.error_handler():
            f = open_for_read('/vsis3_streaming/s3_fake_bucket/no_code_in_error')
    assert f is None and gdal.VSIGetLastErrorMsg().find('<Error/>') >= 0

    handler = webserver.SequentialHandler()
    response = '<?xml version="1.0" encoding="UTF-8"?><Error><Code>AuthorizationHeaderMalformed</Code></Error>'
    response = '%x\r\n%s\r\n0\r\n\r\n' % (len(response), response)
    handler.add('GET', '/s3_fake_bucket/no_region_in_AuthorizationHeaderMalformed_error', 400,
                {'Content-type': 'application/xml',
                 'Transfer-Encoding': 'chunked',
                 'Connection': 'close'}, response)
    gdal.ErrorReset()
    with webserver.install_http_handler(handler):
        with gdaltest.error_handler():
            f = open_for_read('/vsis3_streaming/s3_fake_bucket/no_region_in_AuthorizationHeaderMalformed_error')
    assert f is None and gdal.VSIGetLastErrorMsg().find('<Error>') >= 0

    handler = webserver.SequentialHandler()
    response = '<?xml version="1.0" encoding="UTF-8"?><Error><Code>PermanentRedirect</Code></Error>'
    response = '%x\r\n%s\r\n0\r\n\r\n' % (len(response), response)
    handler.add('GET', '/s3_fake_bucket/no_endpoint_in_PermanentRedirect_error', 400,
                {'Content-type': 'application/xml',
                 'Transfer-Encoding': 'chunked',
                 'Connection': 'close'}, response)
    gdal.ErrorReset()
    with webserver.install_http_handler(handler):
        with gdaltest.error_handler():
            f = open_for_read('/vsis3_streaming/s3_fake_bucket/no_endpoint_in_PermanentRedirect_error')
    assert f is None and gdal.VSIGetLastErrorMsg().find('<Error>') >= 0

    handler = webserver.SequentialHandler()
    response = '<?xml version="1.0" encoding="UTF-8"?><Error><Code>bla</Code></Error>'
    response = '%x\r\n%s\r\n0\r\n\r\n' % (len(response), response)
    handler.add('GET', '/s3_fake_bucket/no_message_in_error', 400,
                {'Content-type': 'application/xml',
                 'Transfer-Encoding': 'chunked',
                 'Connection': 'close'}, response)
    gdal.ErrorReset()
    with webserver.install_http_handler(handler):
        with gdaltest.error_handler():
            f = open_for_read('/vsis3_streaming/s3_fake_bucket/no_message_in_error')
    assert f is None and gdal.VSIGetLastErrorMsg().find('<Error>') >= 0

    # Test with requester pays
    handler = webserver.SequentialHandler()

    def method(request):
        if 'x-amz-request-payer' not in request.headers:
            sys.stderr.write('Bad headers: %s\n' % str(request.headers))
            request.send_response(403)
            return
        expected_authorization_8080 = 'AWS4-HMAC-SHA256 Credential=AWS_ACCESS_KEY_ID/20150101/us-east-1/s3/aws4_request,SignedHeaders=host;x-amz-content-sha256;x-amz-date;x-amz-request-payer,Signature=cf713a394e1b629ac0e468d60d3d4a12f5236fd72d21b6005c758b0dfc7049cd'
        expected_authorization_8081 = 'AWS4-HMAC-SHA256 Credential=AWS_ACCESS_KEY_ID/20150101/us-east-1/s3/aws4_request,SignedHeaders=host;x-amz-content-sha256;x-amz-date;x-amz-request-payer,Signature=4756166679008a1a40cd6ff91dbbef670a71c11bf8e3c998dd7385577c3ac4d9'
        if request.headers['Authorization'] != expected_authorization_8080 and request.headers['Authorization'] != expected_authorization_8081:
            sys.stderr.write("Bad Authorization: '%s'\n" % str(request.headers['Authorization']))
            request.send_response(403)
            return
        if request.headers['x-amz-request-payer'] != 'requester':
            sys.stderr.write("Bad x-amz-request-payer: '%s'\n" % str(request.headers['x-amz-request-payer']))
            request.send_response(403)
            return

        request.send_response(200)
        request.send_header('Content-type', 'text/plain')
        request.send_header('Content-Length', 3)
        request.send_header('Connection', 'close')
        request.end_headers()
        request.wfile.write("""foo""".encode('ascii'))

    handler.add('GET', '/s3_fake_bucket_with_requester_pays/resource', custom_method=method)

    with gdaltest.config_option('AWS_REQUEST_PAYER', 'requester'):
        with webserver.install_http_handler(handler):
            with gdaltest.error_handler():
                f = open_for_read('/vsis3/s3_fake_bucket_with_requester_pays/resource')
                assert f is not None
                data = gdal.VSIFReadL(1, 3, f).decode('ascii')
                gdal.VSIFCloseL(f)

    assert data == 'foo'

    # Test temporary redirect
    handler = webserver.SequentialHandler()

    class HandlerClass(object):
        def __init__(self, response_value):
            self.old_authorization = None
            self.response_value = response_value

        def method_req_1(self, request):
            if request.headers['Host'].find('127.0.0.1') < 0:
                sys.stderr.write('Bad headers: %s\n' % str(request.headers))
                request.send_response(403)
                return
            self.old_authorization = request.headers['Authorization']
            request.protocol_version = 'HTTP/1.1'
            request.send_response(307)
            response = '<?xml version="1.0" encoding="UTF-8"?><Error><Message>bla</Message><Code>TemporaryRedirect</Code><Endpoint>localhost:%d</Endpoint></Error>' % request.server.port
            response = '%x\r\n%s\r\n0\r\n\r\n' % (len(response), response)
            request.send_header('Content-type', 'application/xml')
            request.send_header('Transfer-Encoding', 'chunked')
            request.end_headers()
            request.wfile.write(response.encode('ascii'))

        def method_req_2(self, request):
            if request.headers['Host'].find('localhost') < 0:
                sys.stderr.write('Bad headers: %s\n' % str(request.headers))
                request.send_response(403)
                return
            if self.old_authorization == request.headers['Authorization']:
                sys.stderr.write('Should have get a different Authorization. Bad headers: %s\n' % str(request.headers))
                request.send_response(403)
                return
            request.protocol_version = 'HTTP/1.1'
            request.send_response(200)
            response = self.response_value
            request.send_header('Content-Length', len(response))
            request.end_headers()
            request.wfile.write(response.encode('ascii'))

    h = HandlerClass('foo')
    handler.add('GET', '/s3_test_temporary_redirect_read/resource', custom_method=h.method_req_1)
    handler.add('GET', '/s3_test_temporary_redirect_read/resource', custom_method=h.method_req_2)

    with webserver.install_http_handler(handler):
        f = open_for_read('/vsis3/s3_test_temporary_redirect_read/resource')
        assert f is not None
        data = gdal.VSIFReadL(1, 3, f).decode('ascii')
        gdal.VSIFCloseL(f)

    assert data == 'foo'

    # Retry on the same bucket and check that the redirection was indeed temporary
    handler = webserver.SequentialHandler()

    h = HandlerClass('bar')
    handler.add('GET', '/s3_test_temporary_redirect_read/resource2', custom_method=h.method_req_1)
    handler.add('GET', '/s3_test_temporary_redirect_read/resource2', custom_method=h.method_req_2)

    with webserver.install_http_handler(handler):
        f = open_for_read('/vsis3/s3_test_temporary_redirect_read/resource2')
        assert f is not None
        data = gdal.VSIFReadL(1, 3, f).decode('ascii')
        gdal.VSIFCloseL(f)

    assert data == 'bar'

###############################################################################
# Test re-opening after changing configuration option (#2294)


def test_vsis3_open_after_config_option_chage():

    if gdaltest.webserver_port == 0:
        pytest.skip()

    gdal.VSICurlClearCache()

    handler = webserver.SequentialHandler()
    handler.add('GET', '/test_vsis3_change_config_options/?delimiter=%2F', 403)
    handler.add('GET', '/test_vsis3_change_config_options/test.bin', 403)
    with webserver.install_http_handler(handler):
        with gdaltest.error_handler():
            f = open_for_read('/vsis3/test_vsis3_change_config_options/test.bin')
        assert f is None

    # Does not attempt any network access since we didn't change significant
    # parameters
    f = open_for_read('/vsis3/test_vsis3_change_config_options/test.bin')
    assert f is None

    with gdaltest.config_option('AWS_ACCESS_KEY_ID', 'another_key_id'):
        handler = webserver.SequentialHandler()
        handler.add('GET', '/test_vsis3_change_config_options/?delimiter=%2F', 200,
            {'Content-type': 'application/xml'},
            """<?xml version="1.0" encoding="UTF-8"?>
            <ListBucketResult>
                <Prefix></Prefix>
                <Contents>
                    <Key>test.bin</Key>
                    <LastModified>1970-01-01T00:00:01.000Z</LastModified>
                    <Size>123456</Size>
                </Contents>
            </ListBucketResult>
        """)
        with webserver.install_http_handler(handler):
            f = open_for_read('/vsis3/test_vsis3_change_config_options/test.bin')
            assert f is not None
            gdal.VSIFCloseL(f)


###############################################################################
# Test ReadDir() with a fake AWS server


def test_vsis3_readdir():

    if gdaltest.webserver_port == 0:
        pytest.skip()

    handler = webserver.SequentialHandler()

    def method(request):
        request.protocol_version = 'HTTP/1.1'
        if request.headers['Authorization'].find('us-east-1') >= 0:
            request.send_response(400)
            response = '<?xml version="1.0" encoding="UTF-8"?><Error><Message>bla</Message><Code>AuthorizationHeaderMalformed</Code><Region>us-west-2</Region></Error>'
            response = '%x\r\n%s\r\n0\r\n\r\n' % (len(response), response)
            request.send_header('Content-type', 'application/xml')
            request.send_header('Transfer-Encoding', 'chunked')
            request.end_headers()
            request.wfile.write(response.encode('ascii'))
        elif request.headers['Authorization'].find('us-west-2') >= 0:
            if request.headers['Host'].startswith('127.0.0.1'):
                request.send_response(301)
                response = '<?xml version="1.0" encoding="UTF-8"?><Error><Message>bla</Message><Code>PermanentRedirect</Code><Endpoint>localhost:%d</Endpoint></Error>' % request.server.port
                response = '%x\r\n%s\r\n0\r\n\r\n' % (len(response), response)
                request.send_header('Content-type', 'application/xml')
                request.send_header('Transfer-Encoding', 'chunked')
                request.end_headers()
                request.wfile.write(response.encode('ascii'))
            elif request.headers['Host'].startswith('localhost'):
                request.send_response(200)
                request.send_header('Content-type', 'application/xml')
                response = """<?xml version="1.0" encoding="UTF-8"?>
                    <ListBucketResult>
                        <Prefix>a_dir with_space/</Prefix>
                        <NextMarker>bla</NextMarker>
                        <Contents>
                            <Key>a_dir with_space/resource3 with_space.bin</Key>
                            <LastModified>1970-01-01T00:00:01.000Z</LastModified>
                            <Size>123456</Size>
                        </Contents>
                    </ListBucketResult>
                """
                request.send_header('Content-Length', len(response))
                request.end_headers()
                request.wfile.write(response.encode('ascii'))
            else:
                sys.stderr.write('Bad headers: %s\n' % str(request.headers))
                request.send_response(403)
        else:
            sys.stderr.write('Bad headers: %s\n' % str(request.headers))
            request.send_response(403)

    handler.add('GET', '/s3_fake_bucket2/?delimiter=%2F&prefix=a_dir%20with_space%2F', custom_method=method)
    handler.add('GET', '/s3_fake_bucket2/?delimiter=%2F&prefix=a_dir%20with_space%2F', custom_method=method)
    handler.add('GET', '/s3_fake_bucket2/?delimiter=%2F&prefix=a_dir%20with_space%2F', custom_method=method)

    def method(request):
        # /vsis3/ should have remembered the change of region and endpoint
        if request.headers['Authorization'].find('us-west-2') < 0 or \
                not request.headers['Host'].startswith('localhost'):
            sys.stderr.write('Bad headers: %s\n' % str(request.headers))
            request.send_response(403)

        request.protocol_version = 'HTTP/1.1'
        request.send_response(200)
        request.send_header('Content-type', 'application/xml')
        response = """<?xml version="1.0" encoding="UTF-8"?>
            <ListBucketResult>
                <Prefix>a_dir with_space/</Prefix>
                <Contents>
                    <Key>a_dir with_space/resource4.bin</Key>
                    <LastModified>2015-10-16T12:34:56.000Z</LastModified>
                    <Size>456789</Size>
                </Contents>
                <Contents>
                    <Key>a_dir with_space/i_am_a_glacier_file</Key>
                    <LastModified>2015-10-16T12:34:56.000Z</LastModified>
                    <Size>456789</Size>
                     <StorageClass>GLACIER</StorageClass>
                </Contents>
                <CommonPrefixes>
                    <Prefix>a_dir with_space/subdir/</Prefix>
                </CommonPrefixes>
            </ListBucketResult>
        """
        request.send_header('Content-Length', len(response))
        request.end_headers()
        request.wfile.write(response.encode('ascii'))

    handler.add('GET', '/s3_fake_bucket2/?delimiter=%2F&marker=bla&prefix=a_dir%20with_space%2F', custom_method=method)

    with webserver.install_http_handler(handler):
        f = open_for_read('/vsis3/s3_fake_bucket2/a_dir with_space/resource3 with_space.bin')
    if f is None:

        if gdaltest.is_travis_branch('trusty'):
            pytest.skip('Skipped on trusty branch, but should be investigated')

        pytest.fail()
    gdal.VSIFCloseL(f)

    with webserver.install_http_handler(webserver.SequentialHandler()):
        dir_contents = gdal.ReadDir('/vsis3/s3_fake_bucket2/a_dir with_space')
    assert dir_contents == ['resource3 with_space.bin', 'resource4.bin', 'subdir']

    assert gdal.VSIStatL('/vsis3/s3_fake_bucket2/a_dir with_space/resource3 with_space.bin').size == 123456
    assert gdal.VSIStatL('/vsis3/s3_fake_bucket2/a_dir with_space/resource3 with_space.bin').mtime == 1

    # Same as above: cached
    dir_contents = gdal.ReadDir('/vsis3/s3_fake_bucket2/a_dir with_space')
    assert dir_contents == ['resource3 with_space.bin', 'resource4.bin', 'subdir']

    # ReadDir on something known to be a file shouldn't cause network access
    dir_contents = gdal.ReadDir('/vsis3/s3_fake_bucket2/a_dir with_space/resource3 with_space.bin')
    assert dir_contents is None

    # Test unrelated partial clear of the cache
    gdal.VSICurlPartialClearCache('/vsis3/s3_fake_bucket_unrelated')

    assert gdal.VSIStatL('/vsis3/s3_fake_bucket2/a_dir with_space/resource3 with_space.bin').size == 123456

    dir_contents = gdal.ReadDir('/vsis3/s3_fake_bucket2/a_dir with_space')
    assert dir_contents == ['resource3 with_space.bin', 'resource4.bin', 'subdir']

    # Test partial clear of the cache
    gdal.VSICurlPartialClearCache('/vsis3/s3_fake_bucket2/a_dir with_space')

    handler = webserver.SequentialHandler()
    handler.add('GET', '/s3_fake_bucket2/a_dir%20with_space/resource3%20with_space.bin', 400)
    handler.add('GET', '/s3_fake_bucket2/?delimiter=%2F&max-keys=100&prefix=a_dir%20with_space%2Fresource3%20with_space.bin%2F', 400)
    with webserver.install_http_handler(handler):
        gdal.VSIStatL('/vsis3/s3_fake_bucket2/a_dir with_space/resource3 with_space.bin')

    handler = webserver.SequentialHandler()
    handler.add('GET', '/s3_fake_bucket2/?delimiter=%2F&prefix=a_dir%2F', 200, {'Content-type': 'application/xml'},
                """<?xml version="1.0" encoding="UTF-8"?>
            <ListBucketResult>
                <Prefix>a_dir/</Prefix>
                <Contents>
                    <Key>a_dir/test.txt</Key>
                    <LastModified>1970-01-01T00:00:01.000Z</LastModified>
                    <Size>40</Size>
                </Contents>
            </ListBucketResult>
        """)
    with webserver.install_http_handler(handler):
        dir_contents = gdal.ReadDir('/vsis3/s3_fake_bucket2/a_dir')
    assert dir_contents == ['test.txt']

    gdal.VSICurlClearCache()
    handler = webserver.SequentialHandler()
    handler.add('GET', '/s3_fake_bucket2/?delimiter=%2F&prefix=a_dir%2F', 200, {},
        """<?xml version="1.0" encoding="UTF-8"?>
            <ListBucketResult>
                <Prefix>a_dir/</Prefix>
                <Contents>
                    <Key>a_dir/resource4.bin</Key>
                    <LastModified>2015-10-16T12:34:56.000Z</LastModified>
                    <Size>456789</Size>
                </Contents>
                <Contents>
                    <Key>a_dir/i_am_a_glacier_file</Key>
                    <LastModified>2015-10-16T12:34:56.000Z</LastModified>
                    <Size>456789</Size>
                     <StorageClass>GLACIER</StorageClass>
                </Contents>
                <CommonPrefixes>
                    <Prefix>a_dir/subdir/</Prefix>
                </CommonPrefixes>
            </ListBucketResult>
        """)
    with gdaltest.config_option('CPL_VSIL_CURL_IGNORE_GLACIER_STORAGE', 'NO'):
        with webserver.install_http_handler(handler):
            dir_contents = gdal.ReadDir('/vsis3/s3_fake_bucket2/a_dir')
    assert dir_contents == ['resource4.bin', 'i_am_a_glacier_file', 'subdir']


    # Test CPL_VSIL_CURL_NON_CACHED
    for config_option_value in ['/vsis3/s3_non_cached/test.txt',
                                '/vsis3/s3_non_cached',
                                '/vsis3/s3_non_cached:/vsis3/unrelated',
                                '/vsis3/unrelated:/vsis3/s3_non_cached',
                                '/vsis3/unrelated:/vsis3/s3_non_cached:/vsis3/unrelated']:
        with gdaltest.config_option('CPL_VSIL_CURL_NON_CACHED', config_option_value):

            handler = webserver.SequentialHandler()
            handler.add('GET', '/s3_non_cached/test.txt', 200, {}, 'foo')

            with webserver.install_http_handler(handler):
                f = open_for_read('/vsis3/s3_non_cached/test.txt')
                assert f is not None, config_option_value
                data = gdal.VSIFReadL(1, 3, f).decode('ascii')
                gdal.VSIFCloseL(f)
                assert data == 'foo', config_option_value

            handler = webserver.SequentialHandler()
            handler.add('GET', '/s3_non_cached/test.txt', 200, {}, 'bar2')

            with webserver.install_http_handler(handler):
                size = gdal.VSIStatL('/vsis3/s3_non_cached/test.txt').size
            assert size == 4, config_option_value

            handler = webserver.SequentialHandler()
            handler.add('GET', '/s3_non_cached/test.txt', 200, {}, 'foo')

            with webserver.install_http_handler(handler):
                size = gdal.VSIStatL('/vsis3/s3_non_cached/test.txt').size
                if size != 3:
                    print(config_option_value)
                    pytest.fail(data)

            handler = webserver.SequentialHandler()
            handler.add('GET', '/s3_non_cached/test.txt', 200, {}, 'bar2')

            with webserver.install_http_handler(handler):
                f = open_for_read('/vsis3/s3_non_cached/test.txt')
                assert f is not None, config_option_value
                data = gdal.VSIFReadL(1, 4, f).decode('ascii')
                gdal.VSIFCloseL(f)
                assert data == 'bar2', config_option_value

    # Retry without option
    for config_option_value in [None,
                                '/vsis3/s3_non_cached/bar.txt']:
        with gdaltest.config_option('CPL_VSIL_CURL_NON_CACHED', config_option_value):

            handler = webserver.SequentialHandler()
            if config_option_value is None:
                handler.add('GET', '/s3_non_cached/?delimiter=%2F', 200, {'Content-type': 'application/xml'},
                            """<?xml version="1.0" encoding="UTF-8"?>
                        <ListBucketResult>
                            <Prefix></Prefix>
                            <Contents>
                                <Key>test.txt</Key>
                                <LastModified>1970-01-01T00:00:01.000Z</LastModified>
                                <Size>40</Size>
                            </Contents>
                            <Contents>
                                <Key>test2.txt</Key>
                                <LastModified>1970-01-01T00:00:01.000Z</LastModified>
                                <Size>40</Size>
                            </Contents>
                        </ListBucketResult>
                    """)
                handler.add('GET', '/s3_non_cached/test.txt', 200, {}, 'foo')

            with webserver.install_http_handler(handler):
                f = open_for_read('/vsis3/s3_non_cached/test.txt')
                assert f is not None, config_option_value
                data = gdal.VSIFReadL(1, 3, f).decode('ascii')
                gdal.VSIFCloseL(f)
                assert data == 'foo', config_option_value

            handler = webserver.SequentialHandler()
            with webserver.install_http_handler(handler):
                f = open_for_read('/vsis3/s3_non_cached/test.txt')
                assert f is not None, config_option_value
                data = gdal.VSIFReadL(1, 4, f).decode('ascii')
                gdal.VSIFCloseL(f)
                # We should still get foo because of caching
                assert data == 'foo', config_option_value

    # List buckets (empty result)
    handler = webserver.SequentialHandler()
    handler.add('GET', '/', 200, {'Content-type': 'application/xml'},
                """<?xml version="1.0" encoding="UTF-8"?>
        <ListAllMyBucketsResult>
        <Buckets>
        </Buckets>
        </ListAllMyBucketsResult>
        """)
    with webserver.install_http_handler(handler):
        dir_contents = gdal.ReadDir('/vsis3/')
    assert dir_contents == ['.']

    gdal.VSICurlClearCache()

    # List buckets
    handler = webserver.SequentialHandler()
    handler.add('GET', '/', 200, {'Content-type': 'application/xml'},
                """<?xml version="1.0" encoding="UTF-8"?>
        <ListAllMyBucketsResult>
        <Buckets>
            <Bucket>
                <Name>mybucket</Name>
            </Bucket>
        </Buckets>
        </ListAllMyBucketsResult>
        """)
    with webserver.install_http_handler(handler):
        dir_contents = gdal.ReadDir('/vsis3/')
    assert dir_contents == ['mybucket']

    # Test temporary redirect
    handler = webserver.SequentialHandler()

    class HandlerClass(object):
        def __init__(self, response_value):
            self.old_authorization = None
            self.response_value = response_value

        def method_req_1(self, request):
            if request.headers['Host'].find('127.0.0.1') < 0:
                sys.stderr.write('Bad headers: %s\n' % str(request.headers))
                request.send_response(403)
                return
            self.old_authorization = request.headers['Authorization']
            request.protocol_version = 'HTTP/1.1'
            request.send_response(307)
            response = '<?xml version="1.0" encoding="UTF-8"?><Error><Message>bla</Message><Code>TemporaryRedirect</Code><Endpoint>localhost:%d</Endpoint></Error>' % request.server.port
            response = '%x\r\n%s\r\n0\r\n\r\n' % (len(response), response)
            request.send_header('Content-type', 'application/xml')
            request.send_header('Transfer-Encoding', 'chunked')
            request.end_headers()
            request.wfile.write(response.encode('ascii'))

        def method_req_2(self, request):
            if request.headers['Host'].find('localhost') < 0:
                sys.stderr.write('Bad headers: %s\n' % str(request.headers))
                request.send_response(403)
                return
            if self.old_authorization == request.headers['Authorization']:
                sys.stderr.write('Should have get a different Authorization. Bad headers: %s\n' % str(request.headers))
                request.send_response(403)
                return
            request.protocol_version = 'HTTP/1.1'
            request.send_response(200)
            request.send_header('Content-type', 'application/xml')
            response = self.response_value
            request.send_header('Content-Length', len(response))
            request.end_headers()
            request.wfile.write(response.encode('ascii'))

    h = HandlerClass("""<?xml version="1.0" encoding="UTF-8"?>
                <ListBucketResult>
                    <Prefix></Prefix>
                    <CommonPrefixes>
                        <Prefix>test</Prefix>
                    </CommonPrefixes>
                </ListBucketResult>
            """)
    handler.add('GET', '/s3_test_temporary_redirect_read_dir/?delimiter=%2F', custom_method=h.method_req_1)
    handler.add('GET', '/s3_test_temporary_redirect_read_dir/?delimiter=%2F', custom_method=h.method_req_2)

    with webserver.install_http_handler(handler):
        dir_contents = gdal.ReadDir('/vsis3/s3_test_temporary_redirect_read_dir')
    assert dir_contents == ['test']

    # Retry on the same bucket and check that the redirection was indeed temporary
    handler = webserver.SequentialHandler()

    h = HandlerClass("""<?xml version="1.0" encoding="UTF-8"?>
            <ListBucketResult>
                <Prefix>test/</Prefix>
                <CommonPrefixes>
                    <Prefix>test/test2</Prefix>
                </CommonPrefixes>
            </ListBucketResult>
        """)
    handler.add('GET', '/s3_test_temporary_redirect_read_dir/?delimiter=%2F&prefix=test%2F', custom_method=h.method_req_1)
    handler.add('GET', '/s3_test_temporary_redirect_read_dir/?delimiter=%2F&prefix=test%2F', custom_method=h.method_req_2)

    with webserver.install_http_handler(handler):
        dir_contents = gdal.ReadDir('/vsis3/s3_test_temporary_redirect_read_dir/test')
    assert dir_contents == ['test2']

###############################################################################
# Test OpenDir() with a fake AWS server


def test_vsis3_opendir():

    if gdaltest.webserver_port == 0:
        pytest.skip()

    # Unlimited depth
    handler = webserver.SequentialHandler()
    handler.add('GET', '/vsis3_opendir/', 200, {'Content-type': 'application/xml'},
                """<?xml version="1.0" encoding="UTF-8"?>
            <ListBucketResult>
                <Prefix/>
                <Marker/>
                <Contents>
                    <Key>test.txt</Key>
                    <LastModified>1970-01-01T00:00:01.000Z</LastModified>
                    <Size>40</Size>
                </Contents>
                <Contents>
                    <Key>subdir/</Key>
                    <LastModified>1970-01-01T00:00:01.000Z</LastModified>
                    <Size>0</Size>
                </Contents>
                <Contents>
                    <Key>subdir/test.txt</Key>
                    <LastModified>1970-01-01T00:00:01.000Z</LastModified>
                    <Size>5</Size>
                </Contents>
            </ListBucketResult>
        """)
    with webserver.install_http_handler(handler):
        d = gdal.OpenDir('/vsis3/vsis3_opendir')
    assert d is not None

    entry = gdal.GetNextDirEntry(d)
    assert entry.name == 'test.txt'
    assert entry.size == 40
    assert entry.mode == 32768
    assert entry.mtime == 1

    entry = gdal.GetNextDirEntry(d)
    assert entry.name == 'subdir'
    assert entry.mode == 16384

    entry = gdal.GetNextDirEntry(d)
    assert entry.name == 'subdir/test.txt'

    entry = gdal.GetNextDirEntry(d)
    assert entry is None

    gdal.CloseDir(d)

    # Depth = 0
    handler = webserver.SequentialHandler()
    handler.add('GET', '/vsis3_opendir/?delimiter=%2F', 200, {'Content-type': 'application/xml'},
                """<?xml version="1.0" encoding="UTF-8"?>
            <ListBucketResult>
                <Prefix/>
                <Marker/>
                <Contents>
                    <Key>test.txt</Key>
                    <LastModified>1970-01-01T00:00:01.000Z</LastModified>
                    <Size>40</Size>
                </Contents>
                <CommonPrefixes>
                    <Prefix>subdir/</Prefix>
                </CommonPrefixes>
            </ListBucketResult>
        """)
    with webserver.install_http_handler(handler):
        d = gdal.OpenDir('/vsis3/vsis3_opendir', 0)
    assert d is not None

    entry = gdal.GetNextDirEntry(d)
    assert entry.name == 'test.txt'
    assert entry.size == 40
    assert entry.mode == 32768
    assert entry.mtime == 1

    entry = gdal.GetNextDirEntry(d)
    assert entry.name == 'subdir'
    assert entry.mode == 16384

    entry = gdal.GetNextDirEntry(d)
    assert entry is None

    gdal.CloseDir(d)

    # Depth = 1
    handler = webserver.SequentialHandler()
    handler.add('GET', '/vsis3_opendir/?delimiter=%2F', 200, {'Content-type': 'application/xml'},
                """<?xml version="1.0" encoding="UTF-8"?>
            <ListBucketResult>
                <Prefix/>
                <Marker/>
                <Contents>
                    <Key>test.txt</Key>
                    <LastModified>1970-01-01T00:00:01.000Z</LastModified>
                    <Size>40</Size>
                </Contents>
                <CommonPrefixes>
                    <Prefix>subdir/</Prefix>
                </CommonPrefixes>
            </ListBucketResult>
        """)
    with webserver.install_http_handler(handler):
        d = gdal.OpenDir('/vsis3/vsis3_opendir', 1)
        assert d is not None

    entry = gdal.GetNextDirEntry(d)
    assert entry.name == 'test.txt'
    assert entry.size == 40
    assert entry.mode == 32768
    assert entry.mtime == 1

    entry = gdal.GetNextDirEntry(d)
    assert entry.name == 'subdir'
    assert entry.mode == 16384

    handler = webserver.SequentialHandler()
    handler.add('GET', '/vsis3_opendir/?delimiter=%2F&prefix=subdir%2F', 200, {'Content-type': 'application/xml'},
                """<?xml version="1.0" encoding="UTF-8"?>
            <ListBucketResult>
                <Prefix>subdir/</Prefix>
                <Marker/>
                <Contents>
                    <Key>subdir/test.txt</Key>
                    <LastModified>1970-01-01T00:00:01.000Z</LastModified>
                    <Size>5</Size>
                </Contents>
            </ListBucketResult>
        """)
    with webserver.install_http_handler(handler):
        entry = gdal.GetNextDirEntry(d)
        assert entry.name == 'subdir/test.txt'

    entry = gdal.GetNextDirEntry(d)
    assert entry is None

    gdal.CloseDir(d)

###############################################################################
# Test simple PUT support with a fake AWS server


def test_vsis3_4():

    if gdaltest.webserver_port == 0:
        pytest.skip()

    with webserver.install_http_handler(webserver.SequentialHandler()):
        with gdaltest.error_handler():
            f = gdal.VSIFOpenL('/vsis3/s3_fake_bucket3', 'wb')
    assert f is None

    handler = webserver.SequentialHandler()
    handler.add('GET', '/s3_fake_bucket3/empty_file.bin', 200, {'Connection': 'close'}, 'foo')
    with webserver.install_http_handler(handler):
        assert gdal.VSIStatL('/vsis3/s3_fake_bucket3/empty_file.bin').size == 3

    # Empty file
    handler = webserver.SequentialHandler()

    def method(request):
        if request.headers['Content-Length'] != '0':
            sys.stderr.write('Did not get expected headers: %s\n' % str(request.headers))
            request.send_response(400)
            return

        request.send_response(200)
        request.send_header('Content-Length', 0)
        request.end_headers()

    handler.add('PUT', '/s3_fake_bucket3/empty_file.bin', custom_method=method)

    with webserver.install_http_handler(handler):
        f = gdal.VSIFOpenL('/vsis3/s3_fake_bucket3/empty_file.bin', 'wb')
        assert f is not None
        gdal.ErrorReset()
        gdal.VSIFCloseL(f)
    assert gdal.GetLastErrorMsg() == ''

    handler = webserver.SequentialHandler()
    handler.add('GET', '/s3_fake_bucket3/empty_file.bin', 200, {'Connection': 'close'}, '')
    with webserver.install_http_handler(handler):
        assert gdal.VSIStatL('/vsis3/s3_fake_bucket3/empty_file.bin').size == 0

    # Invalid seek
    handler = webserver.SequentialHandler()
    with webserver.install_http_handler(handler):
        f = gdal.VSIFOpenL('/vsis3/s3_fake_bucket3/empty_file.bin', 'wb')
        assert f is not None
        with gdaltest.error_handler():
            ret = gdal.VSIFSeekL(f, 1, 0)
        assert ret != 0
        gdal.VSIFCloseL(f)

    # Invalid read
    handler = webserver.SequentialHandler()
    with webserver.install_http_handler(handler):
        f = gdal.VSIFOpenL('/vsis3/s3_fake_bucket3/empty_file.bin', 'wb')
        assert f is not None
        with gdaltest.error_handler():
            ret = gdal.VSIFReadL(1, 1, f)
        assert not ret
        gdal.VSIFCloseL(f)

    # Error case
    handler = webserver.SequentialHandler()
    handler.add('PUT', '/s3_fake_bucket3/empty_file_error.bin', 403)
    with webserver.install_http_handler(handler):
        f = gdal.VSIFOpenL('/vsis3/s3_fake_bucket3/empty_file_error.bin', 'wb')
        assert f is not None
        gdal.ErrorReset()
        with gdaltest.error_handler():
            gdal.VSIFCloseL(f)
    assert gdal.GetLastErrorMsg() != ''

    # Nominal case

    gdal.NetworkStatsReset()
    with gdaltest.config_option('CPL_VSIL_NETWORK_STATS_ENABLED', 'YES'):
        with webserver.install_http_handler(webserver.SequentialHandler()):
            f = gdal.VSIFOpenL('/vsis3/s3_fake_bucket3/another_file.bin', 'wb')
            assert f is not None
            assert gdal.VSIFSeekL(f, gdal.VSIFTellL(f), 0) == 0
            assert gdal.VSIFSeekL(f, 0, 1) == 0
            assert gdal.VSIFSeekL(f, 0, 2) == 0
            assert gdal.VSIFWriteL('foo', 1, 3, f) == 3
            assert gdal.VSIFSeekL(f, gdal.VSIFTellL(f), 0) == 0
            assert gdal.VSIFWriteL('bar', 1, 3, f) == 3

        handler = webserver.SequentialHandler()

        def method(request):
            if request.headers['Content-Length'] != '6':
                sys.stderr.write('Did not get expected headers: %s\n' % str(request.headers))
                request.send_response(400)
                request.send_header('Content-Length', 0)
                request.end_headers()
                return

            request.wfile.write('HTTP/1.1 100 Continue\r\n\r\n'.encode('ascii'))

            content = request.rfile.read(6).decode('ascii')
            if content != 'foobar':
                sys.stderr.write('Did not get expected content: %s\n' % content)
                request.send_response(400)
                request.send_header('Content-Length', 0)
                request.end_headers()
                return

            request.send_response(200)
            request.send_header('Content-Length', 0)
            request.end_headers()

        handler.add('PUT', '/s3_fake_bucket3/another_file.bin', custom_method=method)

        gdal.ErrorReset()
        with webserver.install_http_handler(handler):
            gdal.VSIFCloseL(f)
        assert gdal.GetLastErrorMsg() == ''

    j = json.loads(gdal.NetworkStatsGetAsSerializedJSON())
    #print(j)
    assert j == {
        "methods": {
            "PUT": {
                "count": 1,
                "uploaded_bytes": 6
            }
        },
        "handlers": {
            "vsis3": {
                "files": {
                    "/vsis3/s3_fake_bucket3/another_file.bin": {
                        "methods": {
                            "PUT": {
                                "count": 1,
                                "uploaded_bytes": 6
                            }
                        },
                        "actions": {
                            "Write": {
                                "methods": {
                                    "PUT": {
                                        "count": 1,
                                        "uploaded_bytes": 6
                                    }
                                }
                            }
                        }
                    }
                },
                "methods": {
                    "PUT": {
                        "count": 1,
                        "uploaded_bytes": 6
                    }
                }
            }
        }
    }

    gdal.NetworkStatsReset()

    # Redirect case
    with webserver.install_http_handler(webserver.SequentialHandler()):
        f = gdal.VSIFOpenL('/vsis3/s3_fake_bucket3/redirect', 'wb')
        assert f is not None
        assert gdal.VSIFWriteL('foobar', 1, 6, f) == 6

    handler = webserver.SequentialHandler()

    def method(request):
        request.protocol_version = 'HTTP/1.1'
        if request.headers['Authorization'].find('us-east-1') >= 0:
            request.send_response(400)
            response = '<?xml version="1.0" encoding="UTF-8"?><Error><Message>bla</Message><Code>AuthorizationHeaderMalformed</Code><Region>us-west-2</Region></Error>'
            response = '%x\r\n%s\r\n0\r\n\r\n' % (len(response), response)
            request.send_header('Content-type', 'application/xml')
            request.send_header('Transfer-Encoding', 'chunked')
            request.end_headers()
            request.wfile.write(response.encode('ascii'))
        elif request.headers['Authorization'].find('us-west-2') >= 0:
            if request.headers['Content-Length'] != '6':
                sys.stderr.write('Did not get expected headers: %s\n' % str(request.headers))
                request.send_response(400)
                request.send_header('Content-Length', 0)
                request.end_headers()
                return
            request.wfile.write('HTTP/1.1 100 Continue\r\n\r\n'.encode('ascii'))
            content = request.rfile.read(6).decode('ascii')
            if content != 'foobar':
                sys.stderr.write('Did not get expected content: %s\n' % content)
                request.send_response(400)
                request.send_header('Content-Length', 0)
                request.end_headers()
                return
            request.send_response(200)
            request.send_header('Content-Length', 0)
            request.end_headers()
        else:
            sys.stderr.write('Bad headers: %s\n' % str(request.headers))
            request.send_response(403)
            request.send_header('Content-Length', 0)
            request.end_headers()

    handler.add('PUT', '/s3_fake_bucket3/redirect', custom_method=method)
    handler.add('PUT', '/s3_fake_bucket3/redirect', custom_method=method)

    gdal.ErrorReset()
    with webserver.install_http_handler(handler):
        gdal.VSIFCloseL(f)
    assert gdal.GetLastErrorMsg() == ''

###############################################################################
# Test simple PUT support with retry logic


def test_vsis3_write_single_put_retry():

    if gdaltest.webserver_port == 0:
        pytest.skip()

    with gdaltest.config_options({'GDAL_HTTP_MAX_RETRY': '2',
                                  'GDAL_HTTP_RETRY_DELAY': '0.01'}):

        with webserver.install_http_handler(webserver.SequentialHandler()):
            f = gdal.VSIFOpenL('/vsis3/s3_fake_bucket3/put_with_retry.bin', 'wb')
            assert f is not None
            assert gdal.VSIFWriteL('foo', 1, 3, f) == 3

        handler = webserver.SequentialHandler()

        def method(request):
            if request.headers['Content-Length'] != '3':
                sys.stderr.write('Did not get expected headers: %s\n' % str(request.headers))
                request.send_response(400)
                request.send_header('Content-Length', 0)
                request.end_headers()
                return

            request.wfile.write('HTTP/1.1 100 Continue\r\n\r\n'.encode('ascii'))

            content = request.rfile.read(3).decode('ascii')
            if content != 'foo':
                sys.stderr.write('Did not get expected content: %s\n' % content)
                request.send_response(400)
                request.send_header('Content-Length', 0)
                request.end_headers()
                return

            request.send_response(200)
            request.send_header('Content-Length', 0)
            request.end_headers()

        handler.add('PUT', '/s3_fake_bucket3/put_with_retry.bin', 502)
        handler.add('PUT', '/s3_fake_bucket3/put_with_retry.bin', custom_method=method)

        with gdaltest.error_handler():
            with webserver.install_http_handler(handler):
                gdal.VSIFCloseL(f)


###############################################################################
# Test simple DELETE support with a fake AWS server


def test_vsis3_5():

    if gdaltest.webserver_port == 0:
        pytest.skip()

    with webserver.install_http_handler(webserver.SequentialHandler()):
        with gdaltest.error_handler():
            ret = gdal.Unlink('/vsis3/foo')
    assert ret != 0

    handler = webserver.SequentialHandler()
    handler.add('GET', '/s3_delete_bucket/delete_file', 200, {'Connection': 'close'}, 'foo')
    with webserver.install_http_handler(handler):
        assert gdal.VSIStatL('/vsis3/s3_delete_bucket/delete_file').size == 3

    handler = webserver.SequentialHandler()
    with webserver.install_http_handler(handler):
        assert gdal.VSIStatL('/vsis3/s3_delete_bucket/delete_file').size == 3

    handler = webserver.SequentialHandler()
    handler.add('DELETE', '/s3_delete_bucket/delete_file', 204)
    with webserver.install_http_handler(handler):
        ret = gdal.Unlink('/vsis3/s3_delete_bucket/delete_file')
    assert ret == 0

    handler = webserver.SequentialHandler()
    handler.add('GET', '/s3_delete_bucket/delete_file', 404, {'Connection': 'close'})
    handler.add('GET', '/s3_delete_bucket/?delimiter=%2F&max-keys=100&prefix=delete_file%2F', 404, {'Connection': 'close'})
    with webserver.install_http_handler(handler):
        assert gdal.VSIStatL('/vsis3/s3_delete_bucket/delete_file') is None

    handler = webserver.SequentialHandler()
    handler.add('GET', '/s3_delete_bucket/delete_file_error', 200)
    handler.add('DELETE', '/s3_delete_bucket/delete_file_error', 403)
    with webserver.install_http_handler(handler):
        with gdaltest.error_handler():
            ret = gdal.Unlink('/vsis3/s3_delete_bucket/delete_file_error')
    assert ret != 0

    handler = webserver.SequentialHandler()

    handler.add('GET', '/s3_delete_bucket/redirect', 200)

    def method(request):
        request.protocol_version = 'HTTP/1.1'
        if request.headers['Authorization'].find('us-east-1') >= 0:
            request.send_response(400)
            response = '<?xml version="1.0" encoding="UTF-8"?><Error><Message>bla</Message><Code>AuthorizationHeaderMalformed</Code><Region>us-west-2</Region></Error>'
            response = '%x\r\n%s\r\n0\r\n\r\n' % (len(response), response)
            request.send_header('Content-type', 'application/xml')
            request.send_header('Transfer-Encoding', 'chunked')
            request.end_headers()
            request.wfile.write(response.encode('ascii'))
        elif request.headers['Authorization'].find('us-west-2') >= 0:
            request.send_response(204)
            request.send_header('Content-Length', 0)
            request.end_headers()
        else:
            sys.stderr.write('Bad headers: %s\n' % str(request.headers))
            request.send_response(403)
            request.send_header('Content-Length', 0)
            request.end_headers()

    handler.add('DELETE', '/s3_delete_bucket/redirect', custom_method=method)
    handler.add('DELETE', '/s3_delete_bucket/redirect', custom_method=method)

    with webserver.install_http_handler(handler):
        ret = gdal.Unlink('/vsis3/s3_delete_bucket/redirect')
    assert ret == 0

###############################################################################
# Test DeleteObjects with a fake AWS server


def test_vsis3_unlink_batch():

    if gdaltest.webserver_port == 0:
        pytest.skip()

    def method(request):
        if request.headers['Content-MD5'] != 'Ze0X4LdlTwCsT+WpNxD9FA==':
            sys.stderr.write('Did not get expected headers: %s\n' % str(request.headers))
            request.send_response(403)
            return

        content = request.rfile.read(int(request.headers['Content-Length'])).decode('ascii')
        if content != """<?xml version="1.0" encoding="UTF-8"?>
<Delete xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
  <Object>
    <Key>foo</Key>
  </Object>
  <Object>
    <Key>bar/baz</Key>
  </Object>
</Delete>
""":
            sys.stderr.write('Did not get expected content: %s\n' % content)
            request.send_response(403)
            return

        request.protocol_version = 'HTTP/1.1'
        request.send_response(200)
        response = """<DeleteResult xmlns="http://s3.amazonaws.com/doc/2006-03-01/"><Deleted><Key>foo</Key></Deleted><Deleted><Key>bar/baz</Key></Deleted></DeleteResult>"""
        request.send_header('Content-Length', len(response))
        request.send_header('Connection', 'close')
        request.end_headers()
        request.wfile.write(response.encode('ascii'))

    handler = webserver.SequentialHandler()
    handler.add('POST', '/unlink_batch/?delete', custom_method=method)
    handler.add('POST', '/unlink_batch/?delete', 200, {},
                """<DeleteResult xmlns="http://s3.amazonaws.com/doc/2006-03-01/"><Deleted><Key>baw</Key></Deleted></DeleteResult>""")

    with gdaltest.config_option('CPL_VSIS3_UNLINK_BATCH_SIZE', '2'):
        with webserver.install_http_handler(handler):
            ret = gdal.UnlinkBatch(['/vsis3/unlink_batch/foo', '/vsis3/unlink_batch/bar/baz', '/vsis3/unlink_batch/baw'])
    assert ret

    handler = webserver.SequentialHandler()
    handler.add('POST', '/unlink_batch/?delete', 200, {},
                """<DeleteResult xmlns="http://s3.amazonaws.com/doc/2006-03-01/"><Failed><Key>foo</Key></Failed></DeleteResult>""")

    with webserver.install_http_handler(handler):
        ret = gdal.UnlinkBatch(['/vsis3/unlink_batch/foo'])
    assert not ret

###############################################################################
# Test RmdirRecursive() with a fake AWS server


def test_vsis3_rmdir_recursive():

    if gdaltest.webserver_port == 0:
        pytest.skip()

    handler = webserver.SequentialHandler()
    handler.add('GET', '/test_rmdir_recursive/?prefix=somedir%2F', 200, {'Content-type': 'application/xml'},
                """<?xml version="1.0" encoding="UTF-8"?>
            <ListBucketResult>
                <Prefix>somedir/</Prefix>
                <Marker/>
                <Contents>
                    <Key>somedir/test.txt</Key>
                    <LastModified>1970-01-01T00:00:01.000Z</LastModified>
                    <Size>40</Size>
                </Contents>
                <Contents>
                    <Key>somedir/subdir/</Key>
                    <LastModified>1970-01-01T00:00:01.000Z</LastModified>
                    <Size>0</Size>
                </Contents>
                <Contents>
                    <Key>somedir/subdir/test.txt</Key>
                    <LastModified>1970-01-01T00:00:01.000Z</LastModified>
                    <Size>5</Size>
                </Contents>
            </ListBucketResult>
        """)

    def method(request):
        content = request.rfile.read(int(request.headers['Content-Length'])).decode('ascii')
        if content != """<?xml version="1.0" encoding="UTF-8"?>
<Delete xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
  <Object>
    <Key>somedir/test.txt</Key>
  </Object>
  <Object>
    <Key>somedir/subdir/</Key>
  </Object>
</Delete>
""":
            sys.stderr.write('Did not get expected content: %s\n' % content)
            request.send_response(403)
            return

        request.protocol_version = 'HTTP/1.1'
        request.send_response(200)
        response = """<DeleteResult xmlns="http://s3.amazonaws.com/doc/2006-03-01/"><Deleted><Key>somedir/test.txt</Key></Deleted><Deleted><Key>somedir/subdir/</Key></Deleted></DeleteResult>"""
        request.send_header('Content-Length', len(response))
        request.send_header('Connection', 'close')
        request.end_headers()
        request.wfile.write(response.encode('ascii'))

    handler.add('POST', '/test_rmdir_recursive/?delete', custom_method=method)

    def method(request):
        content = request.rfile.read(int(request.headers['Content-Length'])).decode('ascii')
        if content != """<?xml version="1.0" encoding="UTF-8"?>
<Delete xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
  <Object>
    <Key>somedir/subdir/test.txt</Key>
  </Object>
  <Object>
    <Key>somedir/</Key>
  </Object>
</Delete>
""":
            sys.stderr.write('Did not get expected content: %s\n' % content)
            request.send_response(403)
            return

        request.protocol_version = 'HTTP/1.1'
        request.send_response(200)
        response = """<DeleteResult xmlns="http://s3.amazonaws.com/doc/2006-03-01/"><Deleted><Key>somedir/subdir/test.txt</Key></Deleted><Deleted><Key>somedir/</Key></Deleted></DeleteResult>"""
        request.send_header('Content-Length', len(response))
        request.send_header('Connection', 'close')
        request.end_headers()
        request.wfile.write(response.encode('ascii'))

    handler.add('POST', '/test_rmdir_recursive/?delete', custom_method=method)

    with gdaltest.config_option('CPL_VSIS3_UNLINK_BATCH_SIZE', '2'):
        with webserver.install_http_handler(handler):
            assert gdal.RmdirRecursive('/vsis3/test_rmdir_recursive/somedir') == 0


###############################################################################
# Test multipart upload with a fake AWS server


def test_vsis3_6():

    if gdaltest.webserver_port == 0:
        pytest.skip()

    with gdaltest.config_option('VSIS3_CHUNK_SIZE', '1'):  # 1 MB
        with webserver.install_http_handler(webserver.SequentialHandler()):
            f = gdal.VSIFOpenL('/vsis3/s3_fake_bucket4/large_file.bin', 'wb')
    assert f is not None
    size = 1024 * 1024 + 1
    big_buffer = 'a' * size

    handler = webserver.SequentialHandler()

    def method(request):
        request.protocol_version = 'HTTP/1.1'
        if request.headers['Authorization'].find('us-east-1') >= 0:
            request.send_response(400)
            response = '<?xml version="1.0" encoding="UTF-8"?><Error><Message>bla</Message><Code>AuthorizationHeaderMalformed</Code><Region>us-west-2</Region></Error>'
            response = '%x\r\n%s\r\n0\r\n\r\n' % (len(response), response)
            request.send_header('Content-type', 'application/xml')
            request.send_header('Transfer-Encoding', 'chunked')
            request.end_headers()
            request.wfile.write(response.encode('ascii'))
        elif request.headers['Authorization'].find('us-west-2') >= 0:
            response = '<?xml version="1.0" encoding="UTF-8"?><InitiateMultipartUploadResult><UploadId>my_id</UploadId></InitiateMultipartUploadResult>'
            request.send_response(200)
            request.send_header('Content-type', 'application/xml')
            request.send_header('Content-Length', len(response))
            request.end_headers()
            request.wfile.write(response.encode('ascii'))
        else:
            sys.stderr.write('Bad headers: %s\n' % str(request.headers))
            request.send_response(403)
            request.send_header('Content-Length', 0)
            request.end_headers()

    handler.add('POST', '/s3_fake_bucket4/large_file.bin?uploads', custom_method=method)
    handler.add('POST', '/s3_fake_bucket4/large_file.bin?uploads', custom_method=method)

    def method(request):
        if request.headers['Content-Length'] != '1048576':
            sys.stderr.write('Did not get expected headers: %s\n' % str(request.headers))
            request.send_response(400)
            request.send_header('Content-Length', 0)
            request.end_headers()
            return
        request.send_response(200)
        request.send_header('ETag', '"first_etag"')
        request.send_header('Content-Length', 0)
        request.end_headers()

    handler.add('PUT', '/s3_fake_bucket4/large_file.bin?partNumber=1&uploadId=my_id', custom_method=method)

    with webserver.install_http_handler(handler):
        ret = gdal.VSIFWriteL(big_buffer, 1, size, f)
    assert ret == size
    handler = webserver.SequentialHandler()

    def method(request):
        if request.headers['Content-Length'] != '1':
            sys.stderr.write('Did not get expected headers: %s\n' % str(request.headers))
            request.send_response(400)
            return
        request.send_response(200)
        request.send_header('ETag', '"second_etag"')
        request.send_header('Content-Length', 0)
        request.end_headers()

    handler.add('PUT', '/s3_fake_bucket4/large_file.bin?partNumber=2&uploadId=my_id', custom_method=method)

    def method(request):

        if request.headers['Content-Length'] != '186':
            sys.stderr.write('Did not get expected headers: %s\n' % str(request.headers))
            request.send_response(400)
            request.send_header('Content-Length', 0)
            request.end_headers()
            return

        content = request.rfile.read(186).decode('ascii')
        if content != """<CompleteMultipartUpload>
<Part>
<PartNumber>1</PartNumber><ETag>"first_etag"</ETag></Part>
<Part>
<PartNumber>2</PartNumber><ETag>"second_etag"</ETag></Part>
</CompleteMultipartUpload>
""":
            sys.stderr.write('Did not get expected content: %s\n' % content)
            request.send_response(400)
            request.send_header('Content-Length', 0)
            request.end_headers()
            return

        request.send_response(200)
        request.send_header('Content-Length', 0)
        request.end_headers()

    handler.add('POST', '/s3_fake_bucket4/large_file.bin?uploadId=my_id', custom_method=method)

    gdal.ErrorReset()
    with webserver.install_http_handler(handler):
        gdal.VSIFCloseL(f)
    assert gdal.GetLastErrorMsg() == ''

    handler = webserver.SequentialHandler()
    handler.add('POST', '/s3_fake_bucket4/large_file_initiate_403_error.bin?uploads', 403)
    handler.add('POST', '/s3_fake_bucket4/large_file_initiate_empty_result.bin?uploads', 200)
    handler.add('POST', '/s3_fake_bucket4/large_file_initiate_invalid_xml_result.bin?uploads', 200, {}, 'foo')
    handler.add('POST', '/s3_fake_bucket4/large_file_initiate_no_uploadId.bin?uploads', 200, {}, '<foo/>')
    with webserver.install_http_handler(handler):
        for filename in ['/vsis3/s3_fake_bucket4/large_file_initiate_403_error.bin',
                         '/vsis3/s3_fake_bucket4/large_file_initiate_empty_result.bin',
                         '/vsis3/s3_fake_bucket4/large_file_initiate_invalid_xml_result.bin',
                         '/vsis3/s3_fake_bucket4/large_file_initiate_no_uploadId.bin']:
            with gdaltest.config_option('VSIS3_CHUNK_SIZE', '1'):  # 1 MB
                f = gdal.VSIFOpenL(filename, 'wb')
            assert f is not None
            with gdaltest.error_handler():
                ret = gdal.VSIFWriteL(big_buffer, 1, size, f)
            assert ret == 0
            gdal.ErrorReset()
            gdal.VSIFCloseL(f)
            assert gdal.GetLastErrorMsg() == ''

    handler = webserver.SequentialHandler()
    handler.add('POST', '/s3_fake_bucket4/large_file_upload_part_403_error.bin?uploads', 200, {},
                '<?xml version="1.0" encoding="UTF-8"?><InitiateMultipartUploadResult><UploadId>my_id</UploadId></InitiateMultipartUploadResult>')
    handler.add('PUT', '/s3_fake_bucket4/large_file_upload_part_403_error.bin?partNumber=1&uploadId=my_id', 403)
    handler.add('DELETE', '/s3_fake_bucket4/large_file_upload_part_403_error.bin?uploadId=my_id', 204)

    handler.add('POST', '/s3_fake_bucket4/large_file_upload_part_no_etag.bin?uploads', 200, {},
                '<?xml version="1.0" encoding="UTF-8"?><InitiateMultipartUploadResult><UploadId>my_id</UploadId></InitiateMultipartUploadResult>')
    handler.add('PUT', '/s3_fake_bucket4/large_file_upload_part_no_etag.bin?partNumber=1&uploadId=my_id', 200)
    handler.add('DELETE', '/s3_fake_bucket4/large_file_upload_part_no_etag.bin?uploadId=my_id', 204)

    with webserver.install_http_handler(handler):
        for filename in ['/vsis3/s3_fake_bucket4/large_file_upload_part_403_error.bin',
                         '/vsis3/s3_fake_bucket4/large_file_upload_part_no_etag.bin']:
            with gdaltest.config_option('VSIS3_CHUNK_SIZE', '1'):  # 1 MB
                f = gdal.VSIFOpenL(filename, 'wb')
            assert f is not None, filename
            with gdaltest.error_handler():
                ret = gdal.VSIFWriteL(big_buffer, 1, size, f)
            assert ret == 0, filename
            gdal.ErrorReset()
            gdal.VSIFCloseL(f)
            assert gdal.GetLastErrorMsg() == '', filename

    # Simulate failure in AbortMultipart stage
    handler = webserver.SequentialHandler()
    handler.add('POST', '/s3_fake_bucket4/large_file_abortmultipart_403_error.bin?uploads', 200, {},
                '<?xml version="1.0" encoding="UTF-8"?><InitiateMultipartUploadResult><UploadId>my_id</UploadId></InitiateMultipartUploadResult>')
    handler.add('PUT', '/s3_fake_bucket4/large_file_abortmultipart_403_error.bin?partNumber=1&uploadId=my_id', 403)
    handler.add('DELETE', '/s3_fake_bucket4/large_file_abortmultipart_403_error.bin?uploadId=my_id', 403)

    filename = '/vsis3/s3_fake_bucket4/large_file_abortmultipart_403_error.bin'
    with webserver.install_http_handler(handler):
        with gdaltest.config_option('VSIS3_CHUNK_SIZE', '1'):  # 1 MB
            f = gdal.VSIFOpenL(filename, 'wb')
        assert f is not None, filename
        with gdaltest.error_handler():
            ret = gdal.VSIFWriteL(big_buffer, 1, size, f)
        assert ret == 0, filename
        gdal.ErrorReset()
        with gdaltest.error_handler():
            gdal.VSIFCloseL(f)
        assert gdal.GetLastErrorMsg() != '', filename

    # Simulate failure in CompleteMultipartUpload stage
    handler = webserver.SequentialHandler()
    handler.add('POST', '/s3_fake_bucket4/large_file_completemultipart_403_error.bin?uploads', 200, {},
                '<?xml version="1.0" encoding="UTF-8"?><InitiateMultipartUploadResult><UploadId>my_id</UploadId></InitiateMultipartUploadResult>')
    handler.add('PUT', '/s3_fake_bucket4/large_file_completemultipart_403_error.bin?partNumber=1&uploadId=my_id', 200, {'ETag': 'first_etag'}, '')
    handler.add('PUT', '/s3_fake_bucket4/large_file_completemultipart_403_error.bin?partNumber=2&uploadId=my_id', 200, {'ETag': 'second_etag'}, '')
    handler.add('POST', '/s3_fake_bucket4/large_file_completemultipart_403_error.bin?uploadId=my_id', 403)
    # handler.add('DELETE', '/s3_fake_bucket4/large_file_completemultipart_403_error.bin?uploadId=my_id', 204)

    filename = '/vsis3/s3_fake_bucket4/large_file_completemultipart_403_error.bin'
    with webserver.install_http_handler(handler):
        with gdaltest.config_option('VSIS3_CHUNK_SIZE', '1'):  # 1 MB
            f = gdal.VSIFOpenL(filename, 'wb')
            assert f is not None, filename
            ret = gdal.VSIFWriteL(big_buffer, 1, size, f)
            assert ret == size, filename
            gdal.ErrorReset()
            with gdaltest.error_handler():
                gdal.VSIFCloseL(f)
            assert gdal.GetLastErrorMsg() != '', filename


###############################################################################
# Test multipart upload with retry logic


def test_vsis3_write_multipart_retry():

    if gdaltest.webserver_port == 0:
        pytest.skip()

    with gdaltest.config_options({'GDAL_HTTP_MAX_RETRY': '2',
                                  'GDAL_HTTP_RETRY_DELAY': '0.01'}):

        with gdaltest.config_option('VSIS3_CHUNK_SIZE', '1'):  # 1 MB
            with webserver.install_http_handler(webserver.SequentialHandler()):
                f = gdal.VSIFOpenL('/vsis3/s3_fake_bucket4/large_file.bin', 'wb')
        assert f is not None
        size = 1024 * 1024 + 1
        big_buffer = 'a' * size

        handler = webserver.SequentialHandler()

        response = '<?xml version="1.0" encoding="UTF-8"?><InitiateMultipartUploadResult><UploadId>my_id</UploadId></InitiateMultipartUploadResult>'
        handler.add('POST', '/s3_fake_bucket4/large_file.bin?uploads', 502)
        handler.add('POST', '/s3_fake_bucket4/large_file.bin?uploads', 200,
                    {'Content-type': 'application/xml',
                    'Content-Length': len(response),
                    'Connection': 'close'},
                    response)

        handler.add('PUT', '/s3_fake_bucket4/large_file.bin?partNumber=1&uploadId=my_id', 502)
        handler.add('PUT', '/s3_fake_bucket4/large_file.bin?partNumber=1&uploadId=my_id', 200,
                    {'Content-Length': '0',
                    'ETag': '"first_etag"',
                    'Connection': 'close'}, {})

        with gdaltest.error_handler():
            with webserver.install_http_handler(handler):
                ret = gdal.VSIFWriteL(big_buffer, 1, size, f)
        assert ret == size
        handler = webserver.SequentialHandler()

        handler.add('PUT', '/s3_fake_bucket4/large_file.bin?partNumber=2&uploadId=my_id', 200,
                    {'Content-Length': '0',
                    'ETag': '"second_etag"',
                    'Connection': 'close'}, {})

        handler.add('POST', '/s3_fake_bucket4/large_file.bin?uploadId=my_id', 502)
        handler.add('POST', '/s3_fake_bucket4/large_file.bin?uploadId=my_id', 200,
                    {'Content-Length': '0',
                    'Connection': 'close'}, {})

        with gdaltest.error_handler():
            with webserver.install_http_handler(handler):
                gdal.VSIFCloseL(f)


###############################################################################
# Test Mkdir() / Rmdir()


def test_vsis3_7():

    if gdaltest.webserver_port == 0:
        pytest.skip()

    handler = webserver.SequentialHandler()
    handler.add('GET', '/s3_bucket_test_mkdir/dir/', 404, {'Connection': 'close'})
    handler.add('GET', '/s3_bucket_test_mkdir/?delimiter=%2F&max-keys=100&prefix=dir%2F', 404, {'Connection': 'close'})
    handler.add('PUT', '/s3_bucket_test_mkdir/dir/', 200)
    with webserver.install_http_handler(handler):
        ret = gdal.Mkdir('/vsis3/s3_bucket_test_mkdir/dir', 0)
    assert ret == 0

    assert stat.S_ISDIR(gdal.VSIStatL('/vsis3/s3_bucket_test_mkdir/dir').mode)

    dir_content = gdal.ReadDir('/vsis3/s3_bucket_test_mkdir/dir')
    assert dir_content == ['.']

    # Try creating already existing directory
    handler = webserver.SequentialHandler()
    handler.add('GET', '/s3_bucket_test_mkdir/dir/', 416, {'Connection': 'close'})
    with webserver.install_http_handler(handler):
        ret = gdal.Mkdir('/vsis3/s3_bucket_test_mkdir/dir', 0)
    assert ret != 0

    handler = webserver.SequentialHandler()
    handler.add('DELETE', '/s3_bucket_test_mkdir/dir/', 204)
    with webserver.install_http_handler(handler):
        ret = gdal.Rmdir('/vsis3/s3_bucket_test_mkdir/dir')
    assert ret == 0

    # Try deleting already deleted directory
    handler = webserver.SequentialHandler()
    handler.add('GET', '/s3_bucket_test_mkdir/dir/', 404)
    handler.add('GET', '/s3_bucket_test_mkdir/?delimiter=%2F&max-keys=100&prefix=dir%2F', 404, {'Connection': 'close'})
    with webserver.install_http_handler(handler):
        ret = gdal.Rmdir('/vsis3/s3_bucket_test_mkdir/dir')
    assert ret != 0

    # Try deleting non-empty directory
    handler = webserver.SequentialHandler()
    handler.add('GET', '/s3_bucket_test_mkdir/dir_nonempty/', 416)
    handler.add('GET', '/s3_bucket_test_mkdir/?delimiter=%2F&max-keys=100&prefix=dir_nonempty%2F', 200,
                {'Content-type': 'application/xml'},
                """<?xml version="1.0" encoding="UTF-8"?>
                    <ListBucketResult>
                        <Prefix>dir_nonempty/</Prefix>
                        <Contents>
                            <Key>dir_nonempty/test.txt</Key>
                            <LastModified>1970-01-01T00:00:01.000Z</LastModified>
                            <Size>40</Size>
                        </Contents>
                    </ListBucketResult>
                """)
    with webserver.install_http_handler(handler):
        ret = gdal.Rmdir('/vsis3/s3_bucket_test_mkdir/dir_nonempty')
    assert ret != 0

    # Try stat'ing a directory not ending with slash
    handler = webserver.SequentialHandler()
    handler.add('GET', '/s3_bucket_test_dir_stat/test_dir_stat', 400)
    handler.add('GET', '/s3_bucket_test_dir_stat/?delimiter=%2F&max-keys=100&prefix=test_dir_stat%2F', 200,
                {'Content-type': 'application/xml'},
                """<?xml version="1.0" encoding="UTF-8"?>
                    <ListBucketResult>
                        <Prefix>test_dir_stat/</Prefix>
                        <Contents>
                            <Key>test_dir_stat/test.txt</Key>
                            <LastModified>1970-01-01T00:00:01.000Z</LastModified>
                            <Size>40</Size>
                        </Contents>
                    </ListBucketResult>
                """)
    with webserver.install_http_handler(handler):
        assert stat.S_ISDIR(gdal.VSIStatL('/vsis3/s3_bucket_test_dir_stat/test_dir_stat').mode)

    # Try ReadDi'ing a directory not ending with slash
    handler = webserver.SequentialHandler()
    handler.add('GET', '/s3_bucket_test_readdir/?delimiter=%2F&prefix=test_dirread%2F', 200,
                {'Content-type': 'application/xml'},
                """<?xml version="1.0" encoding="UTF-8"?>
                    <ListBucketResult>
                        <Prefix>test_dirread/</Prefix>
                        <Contents>
                            <Key>test_dirread/test.txt</Key>
                            <LastModified>1970-01-01T00:00:01.000Z</LastModified>
                            <Size>40</Size>
                        </Contents>
                    </ListBucketResult>
                """)
    with webserver.install_http_handler(handler):
        assert gdal.ReadDir('/vsis3/s3_bucket_test_readdir/test_dirread') is not None

    # Try stat'ing a directory ending with slash
    handler = webserver.SequentialHandler()
    handler.add('GET', '/s3_bucket_test_dir_stat_2/test_dir_stat/', 400)
    handler.add('GET', '/s3_bucket_test_dir_stat_2/?delimiter=%2F&max-keys=100&prefix=test_dir_stat%2F', 200,
                {'Content-type': 'application/xml'},
                """<?xml version="1.0" encoding="UTF-8"?>
                    <ListBucketResult>
                        <Prefix>test_dir_stat/</Prefix>
                        <Contents>
                            <Key>test_dir_stat/test.txt</Key>
                            <LastModified>1970-01-01T00:00:01.000Z</LastModified>
                            <Size>40</Size>
                        </Contents>
                    </ListBucketResult>
                """)
    with webserver.install_http_handler(handler):
        assert stat.S_ISDIR(gdal.VSIStatL('/vsis3/s3_bucket_test_dir_stat_2/test_dir_stat/').mode)

    # Try ReadDi'ing a directory ending with slash
    handler = webserver.SequentialHandler()
    handler.add('GET', '/s3_bucket_test_readdir2/?delimiter=%2F&prefix=test_dirread%2F', 200,
                {'Content-type': 'application/xml'},
                """<?xml version="1.0" encoding="UTF-8"?>
                    <ListBucketResult>
                        <Prefix>test_dirread/</Prefix>
                        <Contents>
                            <Key>test_dirread/test.txt</Key>
                            <LastModified>1970-01-01T00:00:01.000Z</LastModified>
                            <Size>40</Size>
                        </Contents>
                    </ListBucketResult>
                """)
    with webserver.install_http_handler(handler):
        assert gdal.ReadDir('/vsis3/s3_bucket_test_readdir2/test_dirread') is not None

    
###############################################################################
# Test handling of file and directory with same name


def test_vsis3_8():

    if gdaltest.webserver_port == 0:
        pytest.skip()

    handler = webserver.SequentialHandler()
    handler.add('GET', '/vsis3_8/?delimiter=%2F', 200,
                {'Content-type': 'application/xml'},
                """<?xml version="1.0" encoding="UTF-8"?>
                    <ListBucketResult>
                        <Prefix></Prefix>
                        <Contents>
                            <Key>test</Key>
                            <LastModified>1970-01-01T00:00:01.000Z</LastModified>
                            <Size>40</Size>
                        </Contents>
                        <CommonPrefixes>
                            <Prefix>test/</Prefix>
                        </CommonPrefixes>
                    </ListBucketResult>
                """)

    with webserver.install_http_handler(handler):
        listdir = gdal.ReadDir('/vsis3/vsis3_8', 0)
    assert listdir == ['test', 'test/']

    handler = webserver.SequentialHandler()
    with webserver.install_http_handler(handler):
        assert not stat.S_ISDIR(gdal.VSIStatL('/vsis3/vsis3_8/test').mode)

    handler = webserver.SequentialHandler()
    with webserver.install_http_handler(handler):
        assert stat.S_ISDIR(gdal.VSIStatL('/vsis3/vsis3_8/test/').mode)

    
###############################################################################
# Test vsisync() with SYNC_STRATEGY=ETAG


def test_vsis3_sync_etag():

    if gdaltest.webserver_port == 0:
        pytest.skip()

    gdal.VSICurlClearCache()

    options = ['SYNC_STRATEGY=ETAG']

    with gdaltest.error_handler():
        handler = webserver.SequentialHandler()
        with webserver.install_http_handler(handler):
            assert not gdal.Sync('/i_do/not/exist', '/vsis3/', options=options)

    with gdaltest.error_handler():
        handler = webserver.SequentialHandler()
        handler.add('GET', '/do_not/exist', 404)
        handler.add('GET', '/do_not/?delimiter=%2F&max-keys=100&prefix=exist%2F', 404)
        handler.add('PUT', '/do_not/exist', 404)
        with webserver.install_http_handler(handler):
            assert not gdal.Sync('vsifile.py', '/vsis3/do_not/exist', options=options)

    handler = webserver.SequentialHandler()
    handler.add('GET', '/out/', 200)
    handler.add('GET', '/out/testsync.txt', 404)
    handler.add('GET', '/out/?delimiter=%2F&max-keys=100&prefix=testsync.txt%2F', 404)

    def method(request):
        if request.headers['Content-Length'] != '3':
            sys.stderr.write('Did not get expected headers: %s\n' % str(request.headers))
            request.send_response(400)
            request.send_header('Content-Length', 0)
            request.end_headers()
            return

        request.wfile.write('HTTP/1.1 100 Continue\r\n\r\n'.encode('ascii'))

        content = request.rfile.read(3).decode('ascii')
        if content != 'foo':
            sys.stderr.write('Did not get expected content: %s\n' % content)
            request.send_response(400)
            request.send_header('Content-Length', 0)
            request.end_headers()
            return

        request.send_response(200)
        request.send_header('Content-Length', 0)
        request.send_header('ETag', '"acbd18db4cc2f85cedef654fccc4a4d8"')
        request.end_headers()

    handler.add('PUT', '/out/testsync.txt', custom_method=method)

    gdal.FileFromMemBuffer('/vsimem/testsync.txt', 'foo')

    def cbk(pct, _, tab):
        assert pct > tab[0]
        tab[0] = pct
        return True

    tab = [ 0 ]
    with webserver.install_http_handler(handler):
        assert gdal.Sync('/vsimem/testsync.txt', '/vsis3/out', options=options,
                         callback=cbk, callback_data=tab)
    assert tab[0] == 1.0

    # Re-try with cached ETag. Should generate no network access
    handler = webserver.SequentialHandler()
    with webserver.install_http_handler(handler):
        assert gdal.Sync('/vsimem/testsync.txt', '/vsis3/out', options=options)
        assert gdal.Sync('/vsimem/testsync.txt', '/vsis3/out/testsync.txt', options=options)

    gdal.VSICurlClearCache()

    # Other direction: S3 to /vsimem
    handler = webserver.SequentialHandler()
    handler.add('GET', '/out/testsync.txt', 206,
                { 'Content-Length' : '3',
                  'Content-Range': 'bytes 0-2/3',
                  'ETag' : '"acbd18db4cc2f85cedef654fccc4a4d8"' }, "foo")
    with webserver.install_http_handler(handler):
        assert gdal.Sync( '/vsis3/out/testsync.txt', '/vsimem/', options=options)

    # Shouldn't do any copy, but hard to verify
    with webserver.install_http_handler(webserver.SequentialHandler()):
        assert gdal.Sync( '/vsis3/out/testsync.txt', '/vsimem/', options=options)
        assert gdal.Sync( '/vsis3/out/testsync.txt', '/vsimem/testsync.txt', options=options)

    # Modify target file, and redo synchronization
    gdal.FileFromMemBuffer('/vsimem/testsync.txt', 'bar')

    handler = webserver.SequentialHandler()
    handler.add('GET', '/out/testsync.txt', 200,
                { 'Content-Length' : '3',
                  'ETag' : '"acbd18db4cc2f85cedef654fccc4a4d8"' }, "foo")
    with webserver.install_http_handler(handler):
        assert gdal.Sync( '/vsis3/out/testsync.txt', '/vsimem/', options=options)

    f = gdal.VSIFOpenL('/vsimem/testsync.txt', 'rb')
    data = gdal.VSIFReadL(1, 3, f).decode('ascii')
    gdal.VSIFCloseL(f)
    assert data == 'foo'

    # /vsimem to S3, but after cleaning the cache
    gdal.VSICurlClearCache()

    handler = webserver.SequentialHandler()
    handler.add('GET', '/out/', 200)
    handler.add('GET', '/out/testsync.txt', 206,
                { 'Content-Length' : '3',
                  'Content-Range': 'bytes 0-2/3',
                  'ETag' : '"acbd18db4cc2f85cedef654fccc4a4d8"' }, "foo")
    with webserver.install_http_handler(handler):
        assert gdal.Sync('/vsimem/testsync.txt', '/vsis3/out', options=options)

    gdal.Unlink('/vsimem/testsync.txt')

    # Directory copying
    gdal.VSICurlClearCache()

    gdal.Mkdir('/vsimem/subdir', 0)
    gdal.FileFromMemBuffer('/vsimem/subdir/testsync.txt', 'foo')
    handler = webserver.SequentialHandler()
    handler.add('GET', '/out/', 200, {},
                """<?xml version="1.0" encoding="UTF-8"?>
                    <ListBucketResult>
                        <Prefix/>
                        <Marker/>
                        <IsTruncated>false</IsTruncated>
                        <Contents>
                            <Key>testsync.txt</Key>
                            <LastModified>1970-01-01T00:00:01.000Z</LastModified>
                            <Size>3</Size>
                            <ETag>"acbd18db4cc2f85cedef654fccc4a4d8"</ETag>
                        </Contents>
                    </ListBucketResult>
                """)
    with webserver.install_http_handler(handler):
        assert gdal.Sync('/vsimem/subdir/', '/vsis3/out', options=options)
    gdal.RmdirRecursive('/vsimem/subdir')

###############################################################################
# Test vsisync() with SYNC_STRATEGY=TIMESTAMP


def test_vsis3_sync_timestamp():

    if gdaltest.webserver_port == 0:
        pytest.skip()

    options = ['SYNC_STRATEGY=TIMESTAMP']

    gdal.FileFromMemBuffer('/vsimem/testsync.txt', 'foo')

    # S3 to local: S3 file is older -> download
    gdal.VSICurlClearCache()
    handler = webserver.SequentialHandler()
    handler.add('GET', '/out/testsync.txt', 206,
                { 'Content-Length' : '3',
                  'Content-Range': 'bytes 0-2/3',
                  'Last-Modified': 'Mon, 01 Jan 1970 00:00:01 GMT' }, "foo")
    handler.add('GET', '/out/testsync.txt', 200,
                { 'Content-Length' : '3',
                  'Last-Modified': 'Mon, 01 Jan 1970 00:00:01 GMT' }, "foo")
    with webserver.install_http_handler(handler):
        assert gdal.Sync( '/vsis3/out/testsync.txt', '/vsimem/',
                         options=options)

    # S3 to local: S3 file is newer -> do nothing
    gdal.VSICurlClearCache()
    handler = webserver.SequentialHandler()
    handler.add('GET', '/out/testsync.txt', 206,
                { 'Content-Length' : '3',
                  'Content-Range': 'bytes 0-2/3',
                  'Last-Modified': 'Mon, 01 Jan 2037 00:00:01 GMT' }, "foo")
    with webserver.install_http_handler(handler):
        assert gdal.Sync( '/vsis3/out/testsync.txt', '/vsimem/',
                         options=options)

    # Local to S3: S3 file is older -> upload
    gdal.VSICurlClearCache()
    handler = webserver.SequentialHandler()
    handler.add('GET', '/out/testsync.txt', 206,
                { 'Content-Length' : '3',
                  'Content-Range': 'bytes 0-2/3',
                  'Last-Modified': 'Mon, 01 Jan 1970 00:00:01 GMT' }, "foo")
    handler.add('PUT', '/out/testsync.txt', 200)
    with webserver.install_http_handler(handler):
        assert gdal.Sync( '/vsimem/testsync.txt', '/vsis3/out/testsync.txt',
                         options=options)

    # Local to S3: S3 file is newer -> do nothgin
    gdal.VSICurlClearCache()
    handler = webserver.SequentialHandler()
    handler.add('GET', '/out/testsync.txt', 206,
                { 'Content-Length' : '3',
                  'Content-Range': 'bytes 0-2/3',
                  'Last-Modified': 'Mon, 01 Jan 2037 00:00:01 GMT' }, "foo")
    with webserver.install_http_handler(handler):
        assert gdal.Sync( '/vsimem/testsync.txt', '/vsis3/out/testsync.txt',
                         options=options)

    gdal.Unlink('/vsimem/testsync.txt')

###############################################################################
# Test vsisync() with SYNC_STRATEGY=OVERWRITE


def test_vsis3_sync_overwrite():

    if gdaltest.webserver_port == 0:
        pytest.skip()

    options = ['SYNC_STRATEGY=OVERWRITE']

    gdal.FileFromMemBuffer('/vsimem/testsync.txt', 'foo')

    # S3 to local: S3 file is newer
    gdal.VSICurlClearCache()
    handler = webserver.SequentialHandler()
    handler.add('GET', '/out/testsync.txt', 206,
                { 'Content-Length' : '3',
                  'Content-Range': 'bytes 0-2/3',
                  'Last-Modified': 'Mon, 01 Jan 2037 00:00:01 GMT' }, "foo")
    handler.add('GET', '/out/testsync.txt', 200,
                { 'Content-Length' : '3',
                  'Last-Modified': 'Mon, 01 Jan 2037 00:00:01 GMT' }, "foo")
    with webserver.install_http_handler(handler):
        assert gdal.Sync( '/vsis3/out/testsync.txt', '/vsimem/',
                         options=options)

    # Local to S3: S3 file is newer
    gdal.VSICurlClearCache()
    handler = webserver.SequentialHandler()
    handler.add('GET', '/out/testsync.txt', 206,
                { 'Content-Length' : '3',
                  'Content-Range': 'bytes 0-2/3',
                  'Last-Modified': 'Mon, 01 Jan 2037 00:00:01 GMT' }, "foo")
    handler.add('PUT', '/out/testsync.txt', 200)
    with webserver.install_http_handler(handler):
        assert gdal.Sync( '/vsimem/testsync.txt', '/vsis3/out/testsync.txt',
                         options=options)

    gdal.Unlink('/vsimem/testsync.txt')

###############################################################################
# Test vsisync() with source and target in /vsis3


def test_vsis3_sync_source_target_in_vsis3():

    if gdaltest.webserver_port == 0:
        pytest.skip()

    gdal.VSICurlClearCache()
    handler = webserver.SequentialHandler()
    handler.add('GET', '/in/testsync.txt', 200,
                { 'Content-Length' : '3',
                  'Content-Range': 'bytes 0-2/3',
                  'Last-Modified': 'Mon, 01 Jan 1970 00:00:01 GMT' }, "foo")
    handler.add('GET', '/out/', 200)
    handler.add('GET', '/out/testsync.txt', 200,
                { 'Content-Length' : '3',
                  'Last-Modified': 'Mon, 01 Jan 1970 00:00:01 GMT' }, "foo")

    def method(request):
        if request.headers['Content-Length'] != '0':
            sys.stderr.write('Did not get expected headers: %s\n' % str(request.headers))
            request.send_response(400)
            return
        if request.headers['x-amz-copy-source'] != '/in/testsync.txt':
            sys.stderr.write('Did not get expected headers: %s\n' % str(request.headers))
            request.send_response(400)
            return

        request.send_response(200)
        request.send_header('Content-Length', 0)
        request.end_headers()

    handler.add('PUT', '/out/testsync.txt', custom_method=method)

    with webserver.install_http_handler(handler):
        assert gdal.Sync( '/vsis3/in/testsync.txt', '/vsis3/out/')

###############################################################################
# Test rename

def test_vsis3_fake_rename():

    if gdaltest.webserver_port == 0:
        pytest.skip()

    gdal.VSICurlClearCache()
    handler = webserver.SequentialHandler()
    handler.add('GET', '/test/source.txt', 206,
                { 'Content-Length' : '3',
                  'Content-Range': 'bytes 0-2/3' }, "foo")
    handler.add('GET', '/test/target.txt', 404)
    handler.add('GET', '/test/?delimiter=%2F&max-keys=100&prefix=target.txt%2F', 200)

    def method(request):
        if request.headers['Content-Length'] != '0':
            sys.stderr.write('Did not get expected headers: %s\n' % str(request.headers))
            request.send_response(400)
            return
        if request.headers['x-amz-copy-source'] != '/test/source.txt':
            sys.stderr.write('Did not get expected headers: %s\n' % str(request.headers))
            request.send_response(400)
            return

        request.send_response(200)
        request.send_header('Content-Length', 0)
        request.end_headers()

    handler.add('PUT', '/test/target.txt', custom_method=method)
    handler.add('DELETE', '/test/source.txt', 204)

    with webserver.install_http_handler(handler):
        assert gdal.Rename( '/vsis3/test/source.txt', '/vsis3/test/target.txt') == 0

###############################################################################
# Test rename

def test_vsis3_fake_rename_dir():

    if gdaltest.webserver_port == 0:
        pytest.skip()

    gdal.VSICurlClearCache()
    handler = webserver.SequentialHandler()
    handler.add('GET', '/test/source_dir', 404)
    handler.add('GET', '/test/?delimiter=%2F&max-keys=100&prefix=source_dir%2F', 200,
                {'Content-type': 'application/xml'},
                """<?xml version="1.0" encoding="UTF-8"?>
                    <ListBucketResult>
                        <Prefix>source_dir/</Prefix>
                        <Contents>
                            <Key>source_dir/test.txt</Key>
                            <LastModified>1970-01-01T00:00:01.000Z</LastModified>
                            <Size>3</Size>
                        </Contents>
                    </ListBucketResult>
                """)
    handler.add('GET', '/test/target_dir/', 404)
    handler.add('GET', '/test/?delimiter=%2F&max-keys=100&prefix=target_dir%2F', 404)

    def method(request):
        if request.headers['Content-Length'] != '0':
            sys.stderr.write('Did not get expected headers: %s\n' % str(request.headers))
            request.send_response(400)
            request.send_header('Content-Length', 0)
            request.end_headers()
            return

        request.wfile.write('HTTP/1.1 100 Continue\r\n\r\n'.encode('ascii'))
        request.send_response(200)
        request.send_header('Content-Length', 0)
        request.end_headers()

    handler.add('PUT', '/test/target_dir/', custom_method=method)

    def method(request):
        if request.headers['Content-Length'] != '0':
            sys.stderr.write('Did not get expected headers: %s\n' % str(request.headers))
            request.send_response(400)
            return
        if request.headers['x-amz-copy-source'] != '/test/source_dir/test.txt':
            sys.stderr.write('Did not get expected headers: %s\n' % str(request.headers))
            request.send_response(400)
            return

        request.send_response(200)
        request.send_header('Content-Length', 0)
        request.end_headers()

    handler.add('PUT', '/test/target_dir/test.txt', custom_method=method)

    handler.add('DELETE', '/test/source_dir/test.txt', 204)

    handler.add('GET', '/test/source_dir/', 404)
    handler.add('GET', '/test/?delimiter=%2F&max-keys=100&prefix=source_dir%2F', 404)

    with webserver.install_http_handler(handler):
        assert gdal.Rename( '/vsis3/test/source_dir', '/vsis3/test/target_dir') == 0

###############################################################################
# Test rename onto existing dir is not allowed

def test_vsis3_fake_rename_on_existing_dir():

    if gdaltest.webserver_port == 0:
        pytest.skip()

    gdal.VSICurlClearCache()
    handler = webserver.SequentialHandler()
    handler.add('GET', '/test/source.txt', 206,
                { 'Content-Length' : '3',
                  'Content-Range': 'bytes 0-2/3' }, "foo")
    handler.add('GET', '/test_target_dir/', 200)

    with webserver.install_http_handler(handler):
        assert gdal.Rename( '/vsis3/test/source.txt', '/vsis3/test_target_dir') == -1


###############################################################################
# Test Sync() and multithreaded download and CHUNK_SIZE


def test_vsis3_fake_sync_multithreaded_upload_chunk_size():

    if gdaltest.webserver_port == 0:
        pytest.skip()

    gdal.VSICurlClearCache()

    def cbk(pct, _, tab):
        assert pct >= tab[0]
        tab[0] = pct
        return True

    gdal.Mkdir('/vsimem/test', 0)
    gdal.FileFromMemBuffer('/vsimem/test/foo', 'foo\n')

    tab = [ -1 ]
    handler = webserver.SequentialHandler()
    handler.add('GET', '/test_bucket/?prefix=test%2F', 200)
    handler.add('GET', '/test_bucket/test', 404)
    handler.add('GET', '/test_bucket/?delimiter=%2F&max-keys=100&prefix=test%2F', 200)
    handler.add('GET', '/test_bucket/', 200)
    handler.add('GET', '/test_bucket/test/', 404)
    handler.add('PUT', '/test_bucket/test/', 200)

    def method(request):
        request.protocol_version = 'HTTP/1.1'
        response = '<?xml version="1.0" encoding="UTF-8"?><InitiateMultipartUploadResult><UploadId>my_id</UploadId></InitiateMultipartUploadResult>'
        request.send_response(200)
        request.send_header('Content-type', 'application/xml')
        request.send_header('Content-Length', len(response))
        request.end_headers()
        request.wfile.write(response.encode('ascii'))

    handler.add('POST', '/test_bucket/test/foo?uploads', custom_method=method)

    def method(request):
        if request.headers['Content-Length'] != '3':
            sys.stderr.write('Did not get expected headers: %s\n' % str(request.headers))
            request.send_response(400)
            request.send_header('Content-Length', 0)
            request.end_headers()
            return
        request.send_response(200)
        request.send_header('ETag', '"first_etag"')
        request.send_header('Content-Length', 0)
        request.end_headers()

    handler.add('PUT', '/test_bucket/test/foo?partNumber=1&uploadId=my_id', custom_method=method)

    def method(request):
        if request.headers['Content-Length'] != '1':
            sys.stderr.write('Did not get expected headers: %s\n' % str(request.headers))
            request.send_response(400)
            request.send_header('Content-Length', 0)
            request.end_headers()
            return
        request.send_response(200)
        request.send_header('ETag', '"second_etag"')
        request.send_header('Content-Length', 0)
        request.end_headers()

    handler.add('PUT', '/test_bucket/test/foo?partNumber=2&uploadId=my_id', custom_method=method)


    def method(request):

        if request.headers['Content-Length'] != '186':
            sys.stderr.write('Did not get expected headers: %s\n' % str(request.headers))
            request.send_response(400)
            request.send_header('Content-Length', 0)
            request.end_headers()
            return

        content = request.rfile.read(186).decode('ascii')
        if content != """<CompleteMultipartUpload>
<Part>
<PartNumber>1</PartNumber><ETag>"first_etag"</ETag></Part>
<Part>
<PartNumber>2</PartNumber><ETag>"second_etag"</ETag></Part>
</CompleteMultipartUpload>
""":
            sys.stderr.write('Did not get expected content: %s\n' % content)
            request.send_response(400)
            request.send_header('Content-Length', 0)
            request.end_headers()
            return

        request.send_response(200)
        request.send_header('Content-Length', 0)
        request.end_headers()

    handler.add('POST', '/test_bucket/test/foo?uploadId=my_id', custom_method=method)

    with gdaltest.config_option('VSIS3_SIMULATE_THREADING', 'YES'):
        with webserver.install_http_handler(handler):
            assert gdal.Sync('/vsimem/test',
                             '/vsis3/test_bucket',
                             options=['NUM_THREADS=1', 'CHUNK_SIZE=3'],
                             callback=cbk, callback_data=tab)
    assert tab[0] == 1.0

    gdal.RmdirRecursive('/vsimem/test')


def test_vsis3_fake_sync_multithreaded_upload_chunk_size_failure():

    if gdaltest.webserver_port == 0:
        pytest.skip()

    gdal.VSICurlClearCache()

    gdal.Mkdir('/vsimem/test', 0)
    gdal.FileFromMemBuffer('/vsimem/test/foo', 'foo\n')

    handler = webserver.SequentialHandler()
    handler.add('GET', '/test_bucket/?prefix=test%2F', 200)
    handler.add('GET', '/test_bucket/test', 404)
    handler.add('GET', '/test_bucket/?delimiter=%2F&max-keys=100&prefix=test%2F', 200)
    handler.add('GET', '/test_bucket/', 200)
    handler.add('GET', '/test_bucket/test/', 404)
    handler.add('PUT', '/test_bucket/test/', 200)

    def method(request):
        request.protocol_version = 'HTTP/1.1'
        response = '<?xml version="1.0" encoding="UTF-8"?><InitiateMultipartUploadResult><UploadId>my_id</UploadId></InitiateMultipartUploadResult>'
        request.send_response(200)
        request.send_header('Content-type', 'application/xml')
        request.send_header('Content-Length', len(response))
        request.end_headers()
        request.wfile.write(response.encode('ascii'))

    handler.add('POST', '/test_bucket/test/foo?uploads', custom_method=method)

    def method(request):
        if request.headers['Content-Length'] != '3':
            sys.stderr.write('Did not get expected headers: %s\n' % str(request.headers))
            request.send_response(400)
            request.send_header('Content-Length', 0)
            request.end_headers()
            return
        request.send_response(200)
        request.send_header('ETag', '"first_etag"')
        request.send_header('Content-Length', 0)
        request.end_headers()

    handler.add('PUT', '/test_bucket/test/foo?partNumber=1&uploadId=my_id', 400)
    handler.add('DELETE', '/test_bucket/test/foo?uploadId=my_id', 204)

    with gdaltest.config_options({'VSIS3_SIMULATE_THREADING': 'YES',
                                  'VSIS3_SYNC_MULTITHREADING': 'NO'}):
        with webserver.install_http_handler(handler):
            with gdaltest.error_handler():
                assert not gdal.Sync('/vsimem/test',
                                     '/vsis3/test_bucket',
                                     options=['NUM_THREADS=1', 'CHUNK_SIZE=3'])

    gdal.RmdirRecursive('/vsimem/test')

###############################################################################
# Test reading/writing metadata


def test_vsis3_metadata():

    if gdaltest.webserver_port == 0:
        pytest.skip()

    gdal.VSICurlClearCache()

    # Read HEADERS domain
    handler = webserver.SequentialHandler()
    handler.add('GET', '/test_metadata/foo.txt', 200, {'foo': 'bar'})
    with webserver.install_http_handler(handler):
        md = gdal.GetFileMetadata('/vsis3/test_metadata/foo.txt', 'HEADERS')
    assert 'foo' in md and md['foo'] == 'bar'

    # Read TAGS domain
    handler = webserver.SequentialHandler()
    handler.add('GET', '/test_metadata/foo.txt?tagging', 200, {},
                """<Tagging><TagSet><Tag><Key>foo</Key><Value>bar</Value></Tag></TagSet></Tagging>""")
    with webserver.install_http_handler(handler):
        md = gdal.GetFileMetadata('/vsis3/test_metadata/foo.txt', 'TAGS')
    assert 'foo' in md and md['foo'] == 'bar'

    # Write HEADERS domain
    handler = webserver.SequentialHandler()

    def method(request):
        if request.headers['foo'] != 'bar':
            sys.stderr.write('Did not get expected headers: %s\n' % str(request.headers))
            request.send_response(400)
            request.send_header('Content-Length', 0)
            request.end_headers()
            return
        request.send_response(200)
        request.end_headers()

    handler.add('PUT', '/test_metadata/foo.txt', custom_method=method)
    with webserver.install_http_handler(handler):
        assert gdal.SetFileMetadata('/vsis3/test_metadata/foo.txt', {'foo': 'bar'}, 'HEADERS')


    # Write TAGS domain
    handler = webserver.SequentialHandler()

    def method(request):
        request.wfile.write('HTTP/1.1 100 Continue\r\n\r\n'.encode('ascii'))

        content = request.rfile.read(int(request.headers['Content-Length'])).decode('ascii')
        if content != """<?xml version="1.0" encoding="UTF-8"?>
<Tagging xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
  <TagSet>
    <Tag>
      <Key>foo</Key>
      <Value>bar</Value>
    </Tag>
  </TagSet>
</Tagging>
""":
            sys.stderr.write('Did not get expected content: %s\n' % content)
            request.send_response(400)
            request.send_header('Content-Length', 0)
            request.end_headers()
            return

        request.send_response(200)
        request.send_header('Content-Length', 0)
        request.end_headers()

    handler.add('PUT', '/test_metadata/foo.txt?tagging', custom_method=method)
    with webserver.install_http_handler(handler):
        assert gdal.SetFileMetadata('/vsis3/test_metadata/foo.txt', {'foo': 'bar'}, 'TAGS')

    # Write TAGS domain (wiping tags)
    handler = webserver.SequentialHandler()
    handler.add('DELETE', '/test_metadata/foo.txt?tagging', 204)
    with webserver.install_http_handler(handler):
        assert gdal.SetFileMetadata('/vsis3/test_metadata/foo.txt', {}, 'TAGS')

    # Error case
    with gdaltest.error_handler():
        assert gdal.GetFileMetadata('/vsis3/test_metadata/foo.txt', 'UNSUPPORTED') == {}

    # Error case
    with gdaltest.error_handler():
        assert not gdal.SetFileMetadata('/vsis3/test_metadata/foo.txt', {}, 'UNSUPPORTED')

###############################################################################
# Test that we take into account directory listing to avoid useless
# requests


def test_vsis3_no_useless_requests():

    if gdaltest.webserver_port == 0:
        pytest.skip()

    gdal.VSICurlClearCache()

    handler = webserver.SequentialHandler()
    handler.add('GET', '/no_useless_requests/?delimiter=%2F', 200,
        {'Content-type': 'application/xml'},
        """<?xml version="1.0" encoding="UTF-8"?>
        <ListBucketResult>
            <Prefix></Prefix>
            <Contents>
            </Contents>
        </ListBucketResult>
    """)
    with webserver.install_http_handler(handler):
        assert gdal.VSIFOpenL('/vsis3/no_useless_requests/foo.txt', 'rb') is None
        assert gdal.VSIFOpenL('/vsis3/no_useless_requests/bar.txt', 'rb') is None
        assert gdal.VSIStatL('/vsis3/no_useless_requests/baz.txt') is None

###############################################################################
# Test w+ access

def test_vsis3_random_write():

    if gdaltest.webserver_port == 0:
        pytest.skip()

    gdal.VSICurlClearCache()

    with gdaltest.error_handler():
        assert gdal.VSIFOpenL('/vsis3/random_write/test.bin', 'w+b') is None

    with gdaltest.config_option('CPL_VSIL_USE_TEMP_FILE_FOR_RANDOM_WRITE', 'YES'):
        f = gdal.VSIFOpenL('/vsis3/random_write/test.bin', 'w+b')
    assert f
    assert gdal.VSIFWriteL('foo', 3, 1, f) == 1
    assert gdal.VSIFSeekL(f, 0, 0) == 0
    assert gdal.VSIFReadL(3, 1, f).decode('ascii') == 'foo'
    assert gdal.VSIFEofL(f) == 0
    assert gdal.VSIFTellL(f) == 3

    handler = webserver.SequentialHandler()
    handler.add('PUT', '/random_write/test.bin', 200, {}, expected_body=b'foo')
    with webserver.install_http_handler(handler):
        assert gdal.VSIFCloseL(f) == 0

###############################################################################
# Test w+ access

def test_vsis3_random_write_failure_1():

    if gdaltest.webserver_port == 0:
        pytest.skip()

    gdal.VSICurlClearCache()

    with gdaltest.config_option('CPL_VSIL_USE_TEMP_FILE_FOR_RANDOM_WRITE', 'YES'):
        f = gdal.VSIFOpenL('/vsis3/random_write/test.bin', 'w+b')
    assert f

    handler = webserver.SequentialHandler()
    handler.add('PUT', '/random_write/test.bin', 400, {})
    with webserver.install_http_handler(handler):
        with gdaltest.error_handler():
            assert gdal.VSIFCloseL(f) != 0


###############################################################################
# Test w+ access

def test_vsis3_random_write_failure_2():

    if gdaltest.webserver_port == 0:
        pytest.skip()

    gdal.VSICurlClearCache()

    with gdaltest.config_option('CPL_VSIL_USE_TEMP_FILE_FOR_RANDOM_WRITE', 'YES'):
        with gdaltest.config_option('VSIS3_CHUNK_SIZE_BYTES', '1'):
            f = gdal.VSIFOpenL('/vsis3/random_write/test.bin', 'w+b')
    assert f
    assert gdal.VSIFWriteL('foo', 3, 1, f) == 1

    handler = webserver.SequentialHandler()
    handler.add('POST', '/random_write/test.bin?uploads', 400, {})
    with webserver.install_http_handler(handler):
        with gdaltest.error_handler():
                assert gdal.VSIFCloseL(f) != 0

###############################################################################
# Test w+ access

def test_vsis3_random_write_gtiff_create_copy():

    if gdaltest.webserver_port == 0:
        pytest.skip()

    gdal.VSICurlClearCache()

    handler = webserver.SequentialHandler()
    handler.add('GET', '/random_write/test.tif', 404, {})
    handler.add('GET', '/random_write/?delimiter=%2F&max-keys=100&prefix=test.tif%2F', 404, {})
    handler.add('GET', '/random_write/?delimiter=%2F', 404, {})

    src_ds = gdal.Open('data/byte.tif')

    with gdaltest.config_option('CPL_VSIL_USE_TEMP_FILE_FOR_RANDOM_WRITE', 'YES'):
        with webserver.install_http_handler(handler):
            ds = gdal.GetDriverByName('GTiff').CreateCopy('/vsis3/random_write/test.tif', src_ds)
    assert ds is not None

    handler = webserver.SequentialHandler()
    handler.add('PUT', '/random_write/test.tif', 200, {})
    with webserver.install_http_handler(handler):
        ds = None

###############################################################################
# Read credentials from simulated ~/.aws/credentials


def test_vsis3_read_credentials_file():

    if gdaltest.webserver_port == 0:
        pytest.skip()

    gdal.SetConfigOption('AWS_SECRET_ACCESS_KEY', '')
    gdal.SetConfigOption('AWS_ACCESS_KEY_ID', '')

    gdal.SetConfigOption('CPL_AWS_CREDENTIALS_FILE', '/vsimem/aws_credentials')

    gdal.VSICurlClearCache()

    gdal.FileFromMemBuffer('/vsimem/aws_credentials', """
[unrelated]
aws_access_key_id = foo
aws_secret_access_key = bar
[default]
aws_access_key_id = AWS_ACCESS_KEY_ID
aws_secret_access_key = AWS_SECRET_ACCESS_KEY
[unrelated]
aws_access_key_id = foo
aws_secret_access_key = bar
""")

    handler = webserver.SequentialHandler()
    handler.add('GET', '/s3_fake_bucket/resource', custom_method=get_s3_fake_bucket_resource_method)
    with webserver.install_http_handler(handler):
        f = open_for_read('/vsis3/s3_fake_bucket/resource')
        assert f is not None
        data = gdal.VSIFReadL(1, 4, f).decode('ascii')
        gdal.VSIFCloseL(f)

    assert data == 'foo'

    gdal.SetConfigOption('CPL_AWS_CREDENTIALS_FILE', '')
    gdal.Unlink('/vsimem/aws_credentials')

###############################################################################
# Read credentials from simulated  ~/.aws/config


def test_vsis3_read_config_file():

    if gdaltest.webserver_port == 0:
        pytest.skip()

    gdal.SetConfigOption('AWS_SECRET_ACCESS_KEY', '')
    gdal.SetConfigOption('AWS_ACCESS_KEY_ID', '')

    gdal.SetConfigOption('AWS_CONFIG_FILE', '/vsimem/aws_config')

    gdal.VSICurlClearCache()

    gdal.FileFromMemBuffer('/vsimem/aws_config', """
[unrelated]
aws_access_key_id = foo
aws_secret_access_key = bar
[default]
aws_access_key_id = AWS_ACCESS_KEY_ID
aws_secret_access_key = AWS_SECRET_ACCESS_KEY
region = us-east-1
[unrelated]
aws_access_key_id = foo
aws_secret_access_key = bar
""")

    handler = webserver.SequentialHandler()
    handler.add('GET', '/s3_fake_bucket/resource', custom_method=get_s3_fake_bucket_resource_method)
    with webserver.install_http_handler(handler):
        f = open_for_read('/vsis3/s3_fake_bucket/resource')
        assert f is not None
        data = gdal.VSIFReadL(1, 4, f).decode('ascii')
        gdal.VSIFCloseL(f)

    assert data == 'foo'

    gdal.SetConfigOption('AWS_CONFIG_FILE', '')
    gdal.Unlink('/vsimem/aws_config')

###############################################################################
# Read credentials from simulated ~/.aws/credentials and ~/.aws/config


def test_vsis3_read_credentials_config_file():

    if gdaltest.webserver_port == 0:
        pytest.skip()

    gdal.SetConfigOption('AWS_SECRET_ACCESS_KEY', '')
    gdal.SetConfigOption('AWS_ACCESS_KEY_ID', '')

    gdal.SetConfigOption('CPL_AWS_CREDENTIALS_FILE', '/vsimem/aws_credentials')
    gdal.SetConfigOption('AWS_CONFIG_FILE', '/vsimem/aws_config')

    gdal.VSICurlClearCache()

    gdal.FileFromMemBuffer('/vsimem/aws_credentials', """
[unrelated]
aws_access_key_id = foo
aws_secret_access_key = bar
[default]
aws_access_key_id = AWS_ACCESS_KEY_ID
aws_secret_access_key = AWS_SECRET_ACCESS_KEY
[unrelated]
aws_access_key_id = foo
aws_secret_access_key = bar
""")

    gdal.FileFromMemBuffer('/vsimem/aws_config', """
[unrelated]
aws_access_key_id = foo
aws_secret_access_key = bar
[default]
aws_access_key_id = AWS_ACCESS_KEY_ID
aws_secret_access_key = AWS_SECRET_ACCESS_KEY
region = us-east-1
[unrelated]
aws_access_key_id = foo
aws_secret_access_key = bar
""")

    handler = webserver.SequentialHandler()
    handler.add('GET', '/s3_fake_bucket/resource', custom_method=get_s3_fake_bucket_resource_method)
    with webserver.install_http_handler(handler):
        f = open_for_read('/vsis3/s3_fake_bucket/resource')
        assert f is not None
        data = gdal.VSIFReadL(1, 4, f).decode('ascii')
        gdal.VSIFCloseL(f)

    assert data == 'foo'

    gdal.SetConfigOption('CPL_AWS_CREDENTIALS_FILE', '')
    gdal.Unlink('/vsimem/aws_credentials')
    gdal.SetConfigOption('AWS_CONFIG_FILE', '')
    gdal.Unlink('/vsimem/aws_config')

###############################################################################
# Read credentials from simulated ~/.aws/credentials and ~/.aws/config with
# a non default profile


def test_vsis3_read_credentials_config_file_non_default_profile(tmpdir):

    if gdaltest.webserver_port == 0:
        pytest.skip()

    gdal.SetConfigOption('AWS_SECRET_ACCESS_KEY', '')
    gdal.SetConfigOption('AWS_ACCESS_KEY_ID', '')
    gdal.SetConfigOption('CPL_AWS_CREDENTIALS_FILE', None)
    gdal.SetConfigOption('AWS_CONFIG_FILE', None)
    gdal.SetConfigOption('AWS_PROFILE', 'myprofile')

    os_aws = tmpdir.mkdir(".aws")

    gdal.VSICurlClearCache()

    os_aws.join('credentials').write("""
[unrelated]
aws_access_key_id = foo
aws_secret_access_key = bar
[myprofile]
aws_access_key_id = AWS_ACCESS_KEY_ID
aws_secret_access_key = AWS_SECRET_ACCESS_KEY
[default]
aws_access_key_id = foo
aws_secret_access_key = bar
""")

    os_aws.join('config').write("""
[unrelated]
aws_access_key_id = foo
aws_secret_access_key = bar
[profile myprofile]
region = us-east-1
[default]
aws_access_key_id = foo
aws_secret_access_key = bar
""")

    handler = webserver.SequentialHandler()
    handler.add('GET', '/s3_fake_bucket/resource', custom_method=get_s3_fake_bucket_resource_method)
    with webserver.install_http_handler(handler):
        with gdaltest.config_option(
            'USERPROFILE' if sys.platform == 'win32' else 'HOME', str(tmpdir)
        ):
            f = open_for_read('/vsis3/s3_fake_bucket/resource')
        assert f is not None
        data = gdal.VSIFReadL(1, 4, f).decode('ascii')
        gdal.VSIFCloseL(f)

    assert data == 'foo'

    gdal.SetConfigOption('AWS_PROFILE', '')

###############################################################################
# Read credentials from simulated ~/.aws/credentials and ~/.aws/config


def test_vsis3_read_credentials_config_file_inconsistent():

    if gdaltest.webserver_port == 0:
        pytest.skip()

    gdal.SetConfigOption('AWS_SECRET_ACCESS_KEY', '')
    gdal.SetConfigOption('AWS_ACCESS_KEY_ID', '')

    gdal.SetConfigOption('CPL_AWS_CREDENTIALS_FILE', '/vsimem/aws_credentials')
    gdal.SetConfigOption('AWS_CONFIG_FILE', '/vsimem/aws_config')

    gdal.VSICurlClearCache()

    gdal.FileFromMemBuffer('/vsimem/aws_credentials', """
[unrelated]
aws_access_key_id = foo
aws_secret_access_key = bar
[default]
aws_access_key_id = AWS_ACCESS_KEY_ID
aws_secret_access_key = AWS_SECRET_ACCESS_KEY
[unrelated]
aws_access_key_id = foo
aws_secret_access_key = bar
""")

    gdal.FileFromMemBuffer('/vsimem/aws_config', """
[unrelated]
aws_access_key_id = foo
aws_secret_access_key = bar
[default]
aws_access_key_id = AWS_ACCESS_KEY_ID_inconsistent
aws_secret_access_key = AWS_SECRET_ACCESS_KEY_inconsistent
region = us-east-1
[unrelated]
aws_access_key_id = foo
aws_secret_access_key = bar
""")

    gdal.ErrorReset()
    handler = webserver.SequentialHandler()
    handler.add('GET', '/s3_fake_bucket/resource', custom_method=get_s3_fake_bucket_resource_method)
    with webserver.install_http_handler(handler):
        with gdaltest.error_handler():
            f = open_for_read('/vsis3/s3_fake_bucket/resource')
        assert f is not None
        assert gdal.GetLastErrorMsg() != ''
        data = gdal.VSIFReadL(1, 4, f).decode('ascii')
        gdal.VSIFCloseL(f)

    assert data == 'foo'

    gdal.SetConfigOption('CPL_AWS_CREDENTIALS_FILE', '')
    gdal.Unlink('/vsimem/aws_credentials')
    gdal.SetConfigOption('AWS_CONFIG_FILE', '')
    gdal.Unlink('/vsimem/aws_config')

###############################################################################
# Read credentials from simulated EC2 instance


def test_vsis3_read_credentials_ec2_imdsv2():

    if gdaltest.webserver_port == 0:
        pytest.skip()

    if sys.platform not in ('linux', 'linux2', 'win32'):
        pytest.skip()

    gdal.SetConfigOption('CPL_AWS_CREDENTIALS_FILE', '')
    gdal.SetConfigOption('AWS_CONFIG_FILE', '')
    gdal.SetConfigOption('AWS_SECRET_ACCESS_KEY', '')
    gdal.SetConfigOption('AWS_ACCESS_KEY_ID', '')

    gdal.SetConfigOption('CPL_AWS_EC2_API_ROOT_URL',
                         'http://localhost:%d' % gdaltest.webserver_port)
    # Disable hypervisor related check to test if we are really on EC2
    gdal.SetConfigOption('CPL_AWS_AUTODETECT_EC2', 'NO')

    gdal.VSICurlClearCache()

    handler = webserver.SequentialHandler()
    handler.add('PUT', '/latest/api/token', 200, {}, 'mytoken',
                expected_headers={'X-aws-ec2-metadata-token-ttl-seconds': '10'})
    handler.add('GET', '/latest/meta-data/iam/security-credentials/', 200, {}, 'myprofile',
                expected_headers={'X-aws-ec2-metadata-token': 'mytoken'})
    handler.add('GET', '/latest/meta-data/iam/security-credentials/myprofile', 200, {},
                """{
                "AccessKeyId": "AWS_ACCESS_KEY_ID",
                "SecretAccessKey": "AWS_SECRET_ACCESS_KEY",
                "Expiration": "3000-01-01T00:00:00Z"
                }""",
                expected_headers={'X-aws-ec2-metadata-token': 'mytoken'})

    handler.add('GET', '/s3_fake_bucket/resource', custom_method=get_s3_fake_bucket_resource_method)
    with webserver.install_http_handler(handler):
        f = open_for_read('/vsis3/s3_fake_bucket/resource')
        assert f is not None
        data = gdal.VSIFReadL(1, 4, f).decode('ascii')
        gdal.VSIFCloseL(f)

    assert data == 'foo'

    # Set a fake URL to check that credentials re-use works
    gdal.SetConfigOption('CPL_AWS_EC2_API_ROOT_URL', '')

    handler = webserver.SequentialHandler()
    handler.add('GET', '/s3_fake_bucket/bar', 200, {}, 'bar')
    with webserver.install_http_handler(handler):
        f = open_for_read('/vsis3/s3_fake_bucket/bar')
        assert f is not None
        data = gdal.VSIFReadL(1, 4, f).decode('ascii')
        gdal.VSIFCloseL(f)

    assert data == 'bar'

    gdal.SetConfigOption('CPL_AWS_EC2_API_ROOT_URL', '')
    gdal.SetConfigOption('CPL_AWS_AUTODETECT_EC2', None)

###############################################################################
# Read credentials from simulated EC2 instance that only supports IMDSv1


def test_vsis3_read_credentials_ec2_imdsv1():

    if gdaltest.webserver_port == 0:
        pytest.skip()

    if sys.platform not in ('linux', 'linux2', 'win32'):
        pytest.skip()

    gdal.SetConfigOption('CPL_AWS_CREDENTIALS_FILE', '')
    gdal.SetConfigOption('AWS_CONFIG_FILE', '')
    gdal.SetConfigOption('AWS_SECRET_ACCESS_KEY', '')
    gdal.SetConfigOption('AWS_ACCESS_KEY_ID', '')

    gdal.SetConfigOption('CPL_AWS_EC2_API_ROOT_URL',
                         'http://localhost:%d' % gdaltest.webserver_port)
    # Disable hypervisor related check to test if we are really on EC2
    gdal.SetConfigOption('CPL_AWS_AUTODETECT_EC2', 'NO')

    gdal.VSICurlClearCache()

    handler = webserver.SequentialHandler()
    handler.add('PUT', '/latest/api/token', 403, {},
                expected_headers={'X-aws-ec2-metadata-token-ttl-seconds': '10'})
    handler.add('GET', '/latest/meta-data/iam/security-credentials/', 200, {}, 'myprofile',
                unexpected_headers=['X-aws-ec2-metadata-token'])
    handler.add('GET', '/latest/meta-data/iam/security-credentials/myprofile', 200, {},
                """{
                "AccessKeyId": "AWS_ACCESS_KEY_ID",
                "SecretAccessKey": "AWS_SECRET_ACCESS_KEY",
                "Expiration": "3000-01-01T00:00:00Z"
                }""",
                unexpected_headers=['X-aws-ec2-metadata-token'])

    handler.add('GET', '/s3_fake_bucket/resource', custom_method=get_s3_fake_bucket_resource_method)
    with webserver.install_http_handler(handler):
        f = open_for_read('/vsis3/s3_fake_bucket/resource')
        assert f is not None
        data = gdal.VSIFReadL(1, 4, f).decode('ascii')
        gdal.VSIFCloseL(f)

    assert data == 'foo'

    gdal.SetConfigOption('CPL_AWS_EC2_API_ROOT_URL', '')
    gdal.SetConfigOption('CPL_AWS_AUTODETECT_EC2', None)

###############################################################################
# Read credentials from simulated EC2 instance with expiration of the
# cached credentials


def test_vsis3_read_credentials_ec2_expiration():

    if gdaltest.webserver_port == 0:
        pytest.skip()

    if sys.platform not in ('linux', 'linux2', 'win32'):
        pytest.skip()

    gdal.SetConfigOption('CPL_AWS_CREDENTIALS_FILE', '')
    gdal.SetConfigOption('AWS_CONFIG_FILE', '')
    gdal.SetConfigOption('AWS_SECRET_ACCESS_KEY', '')
    gdal.SetConfigOption('AWS_ACCESS_KEY_ID', '')

    gdal.SetConfigOption('CPL_AWS_EC2_API_ROOT_URL',
                         'http://localhost:%d' % gdaltest.webserver_port)
    # Disable hypervisor related check to test if we are really on EC2
    gdal.SetConfigOption('CPL_AWS_AUTODETECT_EC2', 'NO')

    gdal.VSICurlClearCache()

    handler = webserver.SequentialHandler()
    handler.add('PUT', '/latest/api/token', 200, {}, 'mytoken',
                expected_headers={'X-aws-ec2-metadata-token-ttl-seconds': '10'})
    handler.add('GET', '/latest/meta-data/iam/security-credentials/', 200, {}, 'myprofile',
                expected_headers={'X-aws-ec2-metadata-token': 'mytoken'})
    handler.add('GET', '/latest/meta-data/iam/security-credentials/myprofile', 200, {},
                """{
                "AccessKeyId": "AWS_ACCESS_KEY_ID",
                "SecretAccessKey": "AWS_SECRET_ACCESS_KEY",
                "Expiration": "1970-01-01T00:00:00Z"
                }""",
                expected_headers={'X-aws-ec2-metadata-token': 'mytoken'})
    handler.add('PUT', '/latest/api/token', 200, {}, 'mytoken2',
                expected_headers={'X-aws-ec2-metadata-token-ttl-seconds': '10'})
    handler.add('GET', '/latest/meta-data/iam/security-credentials/myprofile', 200, {},
                """{
                "AccessKeyId": "AWS_ACCESS_KEY_ID",
                "SecretAccessKey": "AWS_SECRET_ACCESS_KEY",
                "Expiration": "1970-01-01T00:00:00Z"
                }""",
                expected_headers={'X-aws-ec2-metadata-token': 'mytoken2'})
    handler.add('GET', '/s3_fake_bucket/resource', custom_method=get_s3_fake_bucket_resource_method)
    with webserver.install_http_handler(handler):
        f = open_for_read('/vsis3/s3_fake_bucket/resource')
        assert f is not None
        data = gdal.VSIFReadL(1, 4, f).decode('ascii')
        gdal.VSIFCloseL(f)

    assert data == 'foo'

    # Set a fake URL to demonstrate we try to re-fetch credentials
    gdal.SetConfigOption('CPL_AWS_EC2_API_ROOT_URL',
                         'http://localhost:%d/invalid' % gdaltest.webserver_port)

    handler = webserver.SequentialHandler()
    handler.add('PUT', '/invalid/latest/api/token', 404)
    handler.add('GET', '/invalid/latest/meta-data/iam/security-credentials/myprofile', 404)
    with webserver.install_http_handler(handler):
        with gdaltest.error_handler():
            f = open_for_read('/vsis3/s3_fake_bucket/bar')
        assert f is None

    gdal.SetConfigOption('CPL_AWS_EC2_API_ROOT_URL', '')
    gdal.SetConfigOption('CPL_AWS_AUTODETECT_EC2', None)

###############################################################################


def test_vsis3_stop_webserver():

    if gdaltest.webserver_port == 0:
        pytest.skip()

    # Clearcache needed to close all connections, since the Python server
    # can only handle one connection at a time
    gdal.VSICurlClearCache()

    webserver.server_stop(gdaltest.webserver_process, gdaltest.webserver_port)

###############################################################################
# Nominal cases (require valid credentials)


def test_vsis3_extra_1():

    if not gdaltest.built_against_curl():
        pytest.skip()

    credentials_filename = gdal.GetConfigOption('HOME',
                                                gdal.GetConfigOption('USERPROFILE', '')) + '/.aws/credentials'

    # Either a bucket name or bucket/filename
    s3_resource = gdal.GetConfigOption('S3_RESOURCE')

    if not os.path.exists(credentials_filename):
        if gdal.GetConfigOption('AWS_SECRET_ACCESS_KEY') is None:
            pytest.skip('Missing AWS_SECRET_ACCESS_KEY')
        elif gdal.GetConfigOption('AWS_ACCESS_KEY_ID') is None:
            pytest.skip('Missing AWS_ACCESS_KEY_ID')

    if s3_resource is None:
        pytest.skip('Missing S3_RESOURCE')

    if '/' not in s3_resource:
        path = '/vsis3/' + s3_resource
        statres = gdal.VSIStatL(path)
        assert statres is not None and stat.S_ISDIR(statres.mode), \
            ('%s is not a valid bucket' % path)

        readdir = gdal.ReadDir(path)
        assert readdir is not None, 'ReadDir() should not return empty list'
        for filename in readdir:
            if filename != '.':
                subpath = path + '/' + filename
                assert gdal.VSIStatL(subpath) is not None, \
                    ('Stat(%s) should not return an error' % subpath)

        unique_id = 'vsis3_test'
        subpath = path + '/' + unique_id
        ret = gdal.Mkdir(subpath, 0)
        assert ret >= 0, ('Mkdir(%s) should not return an error' % subpath)

        readdir = gdal.ReadDir(path)
        assert unique_id in readdir, \
            ('ReadDir(%s) should contain %s' % (path, unique_id))

        ret = gdal.Mkdir(subpath, 0)
        assert ret != 0, ('Mkdir(%s) repeated should return an error' % subpath)

        ret = gdal.Rmdir(subpath)
        assert ret >= 0, ('Rmdir(%s) should not return an error' % subpath)

        readdir = gdal.ReadDir(path)
        assert unique_id not in readdir, \
            ('ReadDir(%s) should not contain %s' % (path, unique_id))

        ret = gdal.Rmdir(subpath)
        assert ret != 0, ('Rmdir(%s) repeated should return an error' % subpath)

        ret = gdal.Mkdir(subpath, 0)
        assert ret >= 0, ('Mkdir(%s) should not return an error' % subpath)

        f = gdal.VSIFOpenL(subpath + '/test.txt', 'wb')
        assert f is not None
        gdal.VSIFWriteL('hello', 1, 5, f)
        gdal.VSIFCloseL(f)

        ret = gdal.Rmdir(subpath)
        assert ret != 0, \
            ('Rmdir(%s) on non empty directory should return an error' % subpath)

        f = gdal.VSIFOpenL(subpath + '/test.txt', 'rb')
        assert f is not None
        data = gdal.VSIFReadL(1, 5, f).decode('utf-8')
        assert data == 'hello'
        gdal.VSIFCloseL(f)

        assert gdal.Rename(subpath + '/test.txt', subpath + '/test2.txt') == 0

        f = gdal.VSIFOpenL(subpath + '/test2.txt', 'rb')
        assert f is not None
        data = gdal.VSIFReadL(1, 5, f).decode('utf-8')
        assert data == 'hello'
        gdal.VSIFCloseL(f)

        ret = gdal.Unlink(subpath + '/test2.txt')
        assert ret >= 0, \
            ('Unlink(%s) should not return an error' % (subpath + '/test2.txt'))

        ret = gdal.Rmdir(subpath)
        assert ret >= 0, ('Rmdir(%s) should not return an error' % subpath)

        return

    f = open_for_read('/vsis3/' + s3_resource)
    assert f is not None, ('cannot open %s' % ('/vsis3/' + s3_resource))
    ret = gdal.VSIFReadL(1, 1, f)
    gdal.VSIFCloseL(f)

    assert len(ret) == 1

    # Same with /vsis3_streaming/
    f = open_for_read('/vsis3_streaming/' + s3_resource)
    assert f is not None
    ret = gdal.VSIFReadL(1, 1, f)
    gdal.VSIFCloseL(f)

    assert len(ret) == 1

    if False:  # pylint: disable=using-constant-test
        # we actually try to read at read() time and bSetError = false
        # Invalid bucket : "The specified bucket does not exist"
        gdal.ErrorReset()
        f = open_for_read('/vsis3/not_existing_bucket/foo')
        with gdaltest.error_handler():
            gdal.VSIFReadL(1, 1, f)
        gdal.VSIFCloseL(f)
        assert gdal.VSIGetLastErrorMsg() != ''

    # Invalid resource
    gdal.ErrorReset()
    f = open_for_read('/vsis3_streaming/' + gdal.GetConfigOption('S3_RESOURCE') + '/invalid_resource.baz')
    assert f is None, gdal.VSIGetLastErrorMsg()

    # Test GetSignedURL()
    signed_url = gdal.GetSignedURL('/vsis3/' + s3_resource)
    f = open_for_read('/vsicurl_streaming/' + signed_url)
    assert f is not None
    ret = gdal.VSIFReadL(1, 1, f)
    gdal.VSIFCloseL(f)

    assert len(ret) == 1

###############################################################################


def test_vsis3_cleanup():

    for var in gdaltest.aws_vars:
        gdal.SetConfigOption(var, gdaltest.aws_vars[var])

    gdal.SetConfigOption('CPL_AWS_CREDENTIALS_FILE', None)
    gdal.SetConfigOption('AWS_CONFIG_FILE', None)
    gdal.SetConfigOption('CPL_AWS_EC2_API_ROOT_URL', None)

[((1737, 1767), 'osgeo.gdal.VSIFOpenExL', 'gdal.VSIFOpenExL', (['uri', '"""rb"""', '(1)'], {}), "(uri, 'rb', 1)\n", (1753, 1767), False, 'from osgeo import gdal\n'), ((2397, 2449), 'osgeo.gdal.SetConfigOption', 'gdal.SetConfigOption', (['"""CPL_AWS_CREDENTIALS_FILE"""', '""""""'], {}), "('CPL_AWS_CREDENTIALS_FILE', '')\n", (2417, 2449), False, 'from osgeo import gdal\n'), ((2454, 2497), 'osgeo.gdal.SetConfigOption', 'gdal.SetConfigOption', (['"""AWS_CONFIG_FILE"""', '""""""'], {}), "('AWS_CONFIG_FILE', '')\n", (2474, 2497), False, 'from osgeo import gdal\n'), ((2502, 2554), 'osgeo.gdal.SetConfigOption', 'gdal.SetConfigOption', (['"""CPL_AWS_EC2_API_ROOT_URL"""', '""""""'], {}), "('CPL_AWS_EC2_API_ROOT_URL', '')\n", (2522, 2554), False, 'from osgeo import gdal\n'), ((3747, 3765), 'osgeo.gdal.VSIFCloseL', 'gdal.VSIFCloseL', (['f'], {}), '(f)\n', (3762, 3765), False, 'from osgeo import gdal\n'), ((4705, 4767), 'osgeo.gdal.RmdirRecursive', 'gdal.RmdirRecursive', (['"""/vsimem/test_vsis3_no_sign_request_sync"""'], {}), "('/vsimem/test_vsis3_no_sign_request_sync')\n", (4724, 4767), False, 'from osgeo import gdal\n'), ((5750, 5812), 'osgeo.gdal.RmdirRecursive', 'gdal.RmdirRecursive', (['"""/vsimem/test_vsis3_no_sign_request_sync"""'], {}), "('/vsimem/test_vsis3_no_sign_request_sync')\n", (5769, 5812), False, 'from osgeo import gdal\n'), ((6036, 6053), 'osgeo.gdal.ErrorReset', 'gdal.ErrorReset', ([], {}), '()\n', (6051, 6053), False, 'from osgeo import gdal\n'), ((6224, 6241), 'osgeo.gdal.ErrorReset', 'gdal.ErrorReset', ([], {}), '()\n', (6239, 6241), False, 'from osgeo import gdal\n'), ((6422, 6492), 'osgeo.gdal.SetConfigOption', 'gdal.SetConfigOption', (['"""AWS_SECRET_ACCESS_KEY"""', '"""AWS_SECRET_ACCESS_KEY"""'], {}), "('AWS_SECRET_ACCESS_KEY', 'AWS_SECRET_ACCESS_KEY')\n", (6442, 6492), False, 'from osgeo import gdal\n'), ((6530, 6547), 'osgeo.gdal.ErrorReset', 'gdal.ErrorReset', ([], {}), '()\n', (6545, 6547), False, 'from osgeo import gdal\n'), ((6714, 6776), 'osgeo.gdal.SetConfigOption', 'gdal.SetConfigOption', (['"""AWS_ACCESS_KEY_ID"""', '"""AWS_ACCESS_KEY_ID"""'], {}), "('AWS_ACCESS_KEY_ID', 'AWS_ACCESS_KEY_ID')\n", (6734, 6776), False, 'from osgeo import gdal\n'), ((6863, 6880), 'osgeo.gdal.ErrorReset', 'gdal.ErrorReset', ([], {}), '()\n', (6878, 6880), False, 'from osgeo import gdal\n'), ((7206, 7223), 'osgeo.gdal.ErrorReset', 'gdal.ErrorReset', ([], {}), '()\n', (7221, 7223), False, 'from osgeo import gdal\n'), ((7688, 7745), 'webserver.launch', 'webserver.launch', ([], {'handler': 'webserver.DispatcherHttpHandler'}), '(handler=webserver.DispatcherHttpHandler)\n', (7704, 7745), False, 'import webserver\n'), ((7810, 7880), 'osgeo.gdal.SetConfigOption', 'gdal.SetConfigOption', (['"""AWS_SECRET_ACCESS_KEY"""', '"""AWS_SECRET_ACCESS_KEY"""'], {}), "('AWS_SECRET_ACCESS_KEY', 'AWS_SECRET_ACCESS_KEY')\n", (7830, 7880), False, 'from osgeo import gdal\n'), ((7885, 7947), 'osgeo.gdal.SetConfigOption', 'gdal.SetConfigOption', (['"""AWS_ACCESS_KEY_ID"""', '"""AWS_ACCESS_KEY_ID"""'], {}), "('AWS_ACCESS_KEY_ID', 'AWS_ACCESS_KEY_ID')\n", (7905, 7947), False, 'from osgeo import gdal\n'), ((7952, 8009), 'osgeo.gdal.SetConfigOption', 'gdal.SetConfigOption', (['"""AWS_TIMESTAMP"""', '"""20150101T000000Z"""'], {}), "('AWS_TIMESTAMP', '20150101T000000Z')\n", (7972, 8009), False, 'from osgeo import gdal\n'), ((8014, 8053), 'osgeo.gdal.SetConfigOption', 'gdal.SetConfigOption', (['"""AWS_HTTPS"""', '"""NO"""'], {}), "('AWS_HTTPS', 'NO')\n", (8034, 8053), False, 'from osgeo import gdal\n'), ((8058, 8107), 'osgeo.gdal.SetConfigOption', 'gdal.SetConfigOption', (['"""AWS_VIRTUAL_HOSTING"""', '"""NO"""'], {}), "('AWS_VIRTUAL_HOSTING', 'NO')\n", (8078, 8107), False, 'from osgeo import gdal\n'), ((8112, 8198), 'osgeo.gdal.SetConfigOption', 'gdal.SetConfigOption', (['"""AWS_S3_ENDPOINT"""', "('127.0.0.1:%d' % gdaltest.webserver_port)"], {}), "('AWS_S3_ENDPOINT', '127.0.0.1:%d' % gdaltest.\n    webserver_port)\n", (8132, 8198), False, 'from osgeo import gdal\n'), ((9690, 9741), 'osgeo.gdal.GetSignedURL', 'gdal.GetSignedURL', (['"""/vsis3/s3_fake_bucket/resource"""'], {}), "('/vsis3/s3_fake_bucket/resource')\n", (9707, 9741), False, 'from osgeo import gdal\n'), ((10493, 10522), 'webserver.SequentialHandler', 'webserver.SequentialHandler', ([], {}), '()\n', (10520, 10522), False, 'import webserver\n'), ((10891, 10920), 'webserver.SequentialHandler', 'webserver.SequentialHandler', ([], {}), '()\n', (10918, 10920), False, 'import webserver\n'), ((11294, 11323), 'webserver.SequentialHandler', 'webserver.SequentialHandler', ([], {}), '()\n', (11321, 11323), False, 'import webserver\n'), ((13125, 13154), 'webserver.SequentialHandler', 'webserver.SequentialHandler', ([], {}), '()\n', (13152, 13154), False, 'import webserver\n'), ((14835, 14864), 'webserver.SequentialHandler', 'webserver.SequentialHandler', ([], {}), '()\n', (14862, 14864), False, 'import webserver\n'), ((15389, 15418), 'webserver.SequentialHandler', 'webserver.SequentialHandler', ([], {}), '()\n', (15416, 15418), False, 'import webserver\n'), ((18475, 18499), 'osgeo.gdal.VSICurlClearCache', 'gdal.VSICurlClearCache', ([], {}), '()\n', (18497, 18499), False, 'from osgeo import gdal\n'), ((18799, 18828), 'webserver.SequentialHandler', 'webserver.SequentialHandler', ([], {}), '()\n', (18826, 18828), False, 'import webserver\n'), ((19712, 19729), 'osgeo.gdal.ErrorReset', 'gdal.ErrorReset', ([], {}), '()\n', (19727, 19729), False, 'from osgeo import gdal\n'), ((19981, 20010), 'webserver.SequentialHandler', 'webserver.SequentialHandler', ([], {}), '()\n', (20008, 20010), False, 'import webserver\n'), ((20361, 20378), 'osgeo.gdal.ErrorReset', 'gdal.ErrorReset', ([], {}), '()\n', (20376, 20378), False, 'from osgeo import gdal\n'), ((20637, 20666), 'webserver.SequentialHandler', 'webserver.SequentialHandler', ([], {}), '()\n', (20664, 20666), False, 'import webserver\n'), ((21018, 21035), 'osgeo.gdal.ErrorReset', 'gdal.ErrorReset', ([], {}), '()\n', (21033, 21035), False, 'from osgeo import gdal\n'), ((21295, 21324), 'webserver.SequentialHandler', 'webserver.SequentialHandler', ([], {}), '()\n', (21322, 21324), False, 'import webserver\n'), ((21755, 21772), 'osgeo.gdal.ErrorReset', 'gdal.ErrorReset', ([], {}), '()\n', (21770, 21772), False, 'from osgeo import gdal\n'), ((22062, 22091), 'webserver.SequentialHandler', 'webserver.SequentialHandler', ([], {}), '()\n', (22089, 22091), False, 'import webserver\n'), ((22502, 22519), 'osgeo.gdal.ErrorReset', 'gdal.ErrorReset', ([], {}), '()\n', (22517, 22519), False, 'from osgeo import gdal\n'), ((22800, 22829), 'webserver.SequentialHandler', 'webserver.SequentialHandler', ([], {}), '()\n', (22827, 22829), False, 'import webserver\n'), ((23207, 23224), 'osgeo.gdal.ErrorReset', 'gdal.ErrorReset', ([], {}), '()\n', (23222, 23224), False, 'from osgeo import gdal\n'), ((23517, 23546), 'webserver.SequentialHandler', 'webserver.SequentialHandler', ([], {}), '()\n', (23544, 23546), False, 'import webserver\n'), ((25661, 25690), 'webserver.SequentialHandler', 'webserver.SequentialHandler', ([], {}), '()\n', (25688, 25690), False, 'import webserver\n'), ((28134, 28163), 'webserver.SequentialHandler', 'webserver.SequentialHandler', ([], {}), '()\n', (28161, 28163), False, 'import webserver\n'), ((28916, 28940), 'osgeo.gdal.VSICurlClearCache', 'gdal.VSICurlClearCache', ([], {}), '()\n', (28938, 28940), False, 'from osgeo import gdal\n'), ((28956, 28985), 'webserver.SequentialHandler', 'webserver.SequentialHandler', ([], {}), '()\n', (28983, 28985), False, 'import webserver\n'), ((30578, 30607), 'webserver.SequentialHandler', 'webserver.SequentialHandler', ([], {}), '()\n', (30605, 30607), False, 'import webserver\n'), ((35366, 35384), 'osgeo.gdal.VSIFCloseL', 'gdal.VSIFCloseL', (['f'], {}), '(f)\n', (35381, 35384), False, 'from osgeo import gdal\n'), ((35881, 35936), 'osgeo.gdal.ReadDir', 'gdal.ReadDir', (['"""/vsis3/s3_fake_bucket2/a_dir with_space"""'], {}), "('/vsis3/s3_fake_bucket2/a_dir with_space')\n", (35893, 35936), False, 'from osgeo import gdal\n'), ((36117, 36202), 'osgeo.gdal.ReadDir', 'gdal.ReadDir', (['"""/vsis3/s3_fake_bucket2/a_dir with_space/resource3 with_space.bin"""'], {}), "('/vsis3/s3_fake_bucket2/a_dir with_space/resource3 with_space.bin'\n    )\n", (36129, 36202), False, 'from osgeo import gdal\n'), ((36283, 36347), 'osgeo.gdal.VSICurlPartialClearCache', 'gdal.VSICurlPartialClearCache', (['"""/vsis3/s3_fake_bucket_unrelated"""'], {}), "('/vsis3/s3_fake_bucket_unrelated')\n", (36312, 36347), False, 'from osgeo import gdal\n'), ((36477, 36532), 'osgeo.gdal.ReadDir', 'gdal.ReadDir', (['"""/vsis3/s3_fake_bucket2/a_dir with_space"""'], {}), "('/vsis3/s3_fake_bucket2/a_dir with_space')\n", (36489, 36532), False, 'from osgeo import gdal\n'), ((36659, 36731), 'osgeo.gdal.VSICurlPartialClearCache', 'gdal.VSICurlPartialClearCache', (['"""/vsis3/s3_fake_bucket2/a_dir with_space"""'], {}), "('/vsis3/s3_fake_bucket2/a_dir with_space')\n", (36688, 36731), False, 'from osgeo import gdal\n'), ((36747, 36776), 'webserver.SequentialHandler', 'webserver.SequentialHandler', ([], {}), '()\n', (36774, 36776), False, 'import webserver\n'), ((37160, 37189), 'webserver.SequentialHandler', 'webserver.SequentialHandler', ([], {}), '()\n', (37187, 37189), False, 'import webserver\n'), ((37854, 37878), 'osgeo.gdal.VSICurlClearCache', 'gdal.VSICurlClearCache', ([], {}), '()\n', (37876, 37878), False, 'from osgeo import gdal\n'), ((37893, 37922), 'webserver.SequentialHandler', 'webserver.SequentialHandler', ([], {}), '()\n', (37920, 37922), False, 'import webserver\n'), ((43286, 43315), 'webserver.SequentialHandler', 'webserver.SequentialHandler', ([], {}), '()\n', (43313, 43315), False, 'import webserver\n'), ((43696, 43720), 'osgeo.gdal.VSICurlClearCache', 'gdal.VSICurlClearCache', ([], {}), '()\n', (43718, 43720), False, 'from osgeo import gdal\n'), ((43755, 43784), 'webserver.SequentialHandler', 'webserver.SequentialHandler', ([], {}), '()\n', (43782, 43784), False, 'import webserver\n'), ((44293, 44322), 'webserver.SequentialHandler', 'webserver.SequentialHandler', ([], {}), '()\n', (44320, 44322), False, 'import webserver\n'), ((47039, 47068), 'webserver.SequentialHandler', 'webserver.SequentialHandler', ([], {}), '()\n', (47066, 47068), False, 'import webserver\n'), ((48030, 48059), 'webserver.SequentialHandler', 'webserver.SequentialHandler', ([], {}), '()\n', (48057, 48059), False, 'import webserver\n'), ((49086, 49109), 'osgeo.gdal.GetNextDirEntry', 'gdal.GetNextDirEntry', (['d'], {}), '(d)\n', (49106, 49109), False, 'from osgeo import gdal\n'), ((49246, 49269), 'osgeo.gdal.GetNextDirEntry', 'gdal.GetNextDirEntry', (['d'], {}), '(d)\n', (49266, 49269), False, 'from osgeo import gdal\n'), ((49348, 49371), 'osgeo.gdal.GetNextDirEntry', 'gdal.GetNextDirEntry', (['d'], {}), '(d)\n', (49368, 49371), False, 'from osgeo import gdal\n'), ((49428, 49451), 'osgeo.gdal.GetNextDirEntry', 'gdal.GetNextDirEntry', (['d'], {}), '(d)\n', (49448, 49451), False, 'from osgeo import gdal\n'), ((49482, 49498), 'osgeo.gdal.CloseDir', 'gdal.CloseDir', (['d'], {}), '(d)\n', (49495, 49498), False, 'from osgeo import gdal\n'), ((49530, 49559), 'webserver.SequentialHandler', 'webserver.SequentialHandler', ([], {}), '()\n', (49557, 49559), False, 'import webserver\n'), ((50301, 50324), 'osgeo.gdal.GetNextDirEntry', 'gdal.GetNextDirEntry', (['d'], {}), '(d)\n', (50321, 50324), False, 'from osgeo import gdal\n'), ((50461, 50484), 'osgeo.gdal.GetNextDirEntry', 'gdal.GetNextDirEntry', (['d'], {}), '(d)\n', (50481, 50484), False, 'from osgeo import gdal\n'), ((50563, 50586), 'osgeo.gdal.GetNextDirEntry', 'gdal.GetNextDirEntry', (['d'], {}), '(d)\n', (50583, 50586), False, 'from osgeo import gdal\n'), ((50617, 50633), 'osgeo.gdal.CloseDir', 'gdal.CloseDir', (['d'], {}), '(d)\n', (50630, 50633), False, 'from osgeo import gdal\n'), ((50665, 50694), 'webserver.SequentialHandler', 'webserver.SequentialHandler', ([], {}), '()\n', (50692, 50694), False, 'import webserver\n'), ((51440, 51463), 'osgeo.gdal.GetNextDirEntry', 'gdal.GetNextDirEntry', (['d'], {}), '(d)\n', (51460, 51463), False, 'from osgeo import gdal\n'), ((51600, 51623), 'osgeo.gdal.GetNextDirEntry', 'gdal.GetNextDirEntry', (['d'], {}), '(d)\n', (51620, 51623), False, 'from osgeo import gdal\n'), ((51704, 51733), 'webserver.SequentialHandler', 'webserver.SequentialHandler', ([], {}), '()\n', (51731, 51733), False, 'import webserver\n'), ((52411, 52434), 'osgeo.gdal.GetNextDirEntry', 'gdal.GetNextDirEntry', (['d'], {}), '(d)\n', (52431, 52434), False, 'from osgeo import gdal\n'), ((52465, 52481), 'osgeo.gdal.CloseDir', 'gdal.CloseDir', (['d'], {}), '(d)\n', (52478, 52481), False, 'from osgeo import gdal\n'), ((52905, 52934), 'webserver.SequentialHandler', 'webserver.SequentialHandler', ([], {}), '()\n', (52932, 52934), False, 'import webserver\n'), ((53192, 53221), 'webserver.SequentialHandler', 'webserver.SequentialHandler', ([], {}), '()\n', (53219, 53221), False, 'import webserver\n'), ((53907, 53936), 'webserver.SequentialHandler', 'webserver.SequentialHandler', ([], {}), '()\n', (53934, 53936), False, 'import webserver\n'), ((54193, 54222), 'webserver.SequentialHandler', 'webserver.SequentialHandler', ([], {}), '()\n', (54220, 54222), False, 'import webserver\n'), ((54542, 54571), 'webserver.SequentialHandler', 'webserver.SequentialHandler', ([], {}), '()\n', (54569, 54571), False, 'import webserver\n'), ((54888, 54917), 'webserver.SequentialHandler', 'webserver.SequentialHandler', ([], {}), '()\n', (54915, 54917), False, 'import webserver\n'), ((55307, 55331), 'osgeo.gdal.NetworkStatsReset', 'gdal.NetworkStatsReset', ([], {}), '()\n', (55329, 55331), False, 'from osgeo import gdal\n'), ((58360, 58384), 'osgeo.gdal.NetworkStatsReset', 'gdal.NetworkStatsReset', ([], {}), '()\n', (58382, 58384), False, 'from osgeo import gdal\n'), ((58645, 58674), 'webserver.SequentialHandler', 'webserver.SequentialHandler', ([], {}), '()\n', (58672, 58674), False, 'import webserver\n'), ((60614, 60631), 'osgeo.gdal.ErrorReset', 'gdal.ErrorReset', ([], {}), '()\n', (60629, 60631), False, 'from osgeo import gdal\n'), ((62992, 63021), 'webserver.SequentialHandler', 'webserver.SequentialHandler', ([], {}), '()\n', (63019, 63021), False, 'import webserver\n'), ((63258, 63287), 'webserver.SequentialHandler', 'webserver.SequentialHandler', ([], {}), '()\n', (63285, 63287), False, 'import webserver\n'), ((63431, 63460), 'webserver.SequentialHandler', 'webserver.SequentialHandler', ([], {}), '()\n', (63458, 63460), False, 'import webserver\n'), ((63675, 63704), 'webserver.SequentialHandler', 'webserver.SequentialHandler', ([], {}), '()\n', (63702, 63704), False, 'import webserver\n'), ((64056, 64085), 'webserver.SequentialHandler', 'webserver.SequentialHandler', ([], {}), '()\n', (64083, 64085), False, 'import webserver\n'), ((64422, 64451), 'webserver.SequentialHandler', 'webserver.SequentialHandler', ([], {}), '()\n', (64449, 64451), False, 'import webserver\n'), ((67239, 67268), 'webserver.SequentialHandler', 'webserver.SequentialHandler', ([], {}), '()\n', (67266, 67268), False, 'import webserver\n'), ((67808, 67837), 'webserver.SequentialHandler', 'webserver.SequentialHandler', ([], {}), '()\n', (67835, 67837), False, 'import webserver\n'), ((68397, 68426), 'webserver.SequentialHandler', 'webserver.SequentialHandler', ([], {}), '()\n', (68424, 68426), False, 'import webserver\n'), ((72217, 72246), 'webserver.SequentialHandler', 'webserver.SequentialHandler', ([], {}), '()\n', (72244, 72246), False, 'import webserver\n'), ((74507, 74536), 'webserver.SequentialHandler', 'webserver.SequentialHandler', ([], {}), '()\n', (74534, 74536), False, 'import webserver\n'), ((76071, 76088), 'osgeo.gdal.ErrorReset', 'gdal.ErrorReset', ([], {}), '()\n', (76086, 76088), False, 'from osgeo import gdal\n'), ((76221, 76250), 'webserver.SequentialHandler', 'webserver.SequentialHandler', ([], {}), '()\n', (76248, 76250), False, 'import webserver\n'), ((77474, 77503), 'webserver.SequentialHandler', 'webserver.SequentialHandler', ([], {}), '()\n', (77501, 77503), False, 'import webserver\n'), ((79139, 79168), 'webserver.SequentialHandler', 'webserver.SequentialHandler', ([], {}), '()\n', (79166, 79168), False, 'import webserver\n'), ((80278, 80307), 'webserver.SequentialHandler', 'webserver.SequentialHandler', ([], {}), '()\n', (80305, 80307), False, 'import webserver\n'), ((84238, 84267), 'webserver.SequentialHandler', 'webserver.SequentialHandler', ([], {}), '()\n', (84265, 84267), False, 'import webserver\n'), ((84761, 84808), 'osgeo.gdal.ReadDir', 'gdal.ReadDir', (['"""/vsis3/s3_bucket_test_mkdir/dir"""'], {}), "('/vsis3/s3_bucket_test_mkdir/dir')\n", (84773, 84808), False, 'from osgeo import gdal\n'), ((84902, 84931), 'webserver.SequentialHandler', 'webserver.SequentialHandler', ([], {}), '()\n', (84929, 84931), False, 'import webserver\n'), ((85163, 85192), 'webserver.SequentialHandler', 'webserver.SequentialHandler', ([], {}), '()\n', (85190, 85192), False, 'import webserver\n'), ((85444, 85473), 'webserver.SequentialHandler', 'webserver.SequentialHandler', ([], {}), '()\n', (85471, 85473), False, 'import webserver\n'), ((85836, 85865), 'webserver.SequentialHandler', 'webserver.SequentialHandler', ([], {}), '()\n', (85863, 85865), False, 'import webserver\n'), ((86768, 86797), 'webserver.SequentialHandler', 'webserver.SequentialHandler', ([], {}), '()\n', (86795, 86797), False, 'import webserver\n'), ((87718, 87747), 'webserver.SequentialHandler', 'webserver.SequentialHandler', ([], {}), '()\n', (87745, 87747), False, 'import webserver\n'), ((88565, 88594), 'webserver.SequentialHandler', 'webserver.SequentialHandler', ([], {}), '()\n', (88592, 88594), False, 'import webserver\n'), ((89519, 89548), 'webserver.SequentialHandler', 'webserver.SequentialHandler', ([], {}), '()\n', (89546, 89548), False, 'import webserver\n'), ((90540, 90569), 'webserver.SequentialHandler', 'webserver.SequentialHandler', ([], {}), '()\n', (90567, 90569), False, 'import webserver\n'), ((91411, 91440), 'webserver.SequentialHandler', 'webserver.SequentialHandler', ([], {}), '()\n', (91438, 91440), False, 'import webserver\n'), ((91581, 91610), 'webserver.SequentialHandler', 'webserver.SequentialHandler', ([], {}), '()\n', (91608, 91610), False, 'import webserver\n'), ((91955, 91979), 'osgeo.gdal.VSICurlClearCache', 'gdal.VSICurlClearCache', ([], {}), '()\n', (91977, 91979), False, 'from osgeo import gdal\n'), ((92661, 92690), 'webserver.SequentialHandler', 'webserver.SequentialHandler', ([], {}), '()\n', (92688, 92690), False, 'import webserver\n'), ((93825, 93878), 'osgeo.gdal.FileFromMemBuffer', 'gdal.FileFromMemBuffer', (['"""/vsimem/testsync.txt"""', '"""foo"""'], {}), "('/vsimem/testsync.txt', 'foo')\n", (93847, 93878), False, 'from osgeo import gdal\n'), ((94285, 94314), 'webserver.SequentialHandler', 'webserver.SequentialHandler', ([], {}), '()\n', (94312, 94314), False, 'import webserver\n'), ((94543, 94567), 'osgeo.gdal.VSICurlClearCache', 'gdal.VSICurlClearCache', ([], {}), '()\n', (94565, 94567), False, 'from osgeo import gdal\n'), ((94620, 94649), 'webserver.SequentialHandler', 'webserver.SequentialHandler', ([], {}), '()\n', (94647, 94649), False, 'import webserver\n'), ((95350, 95403), 'osgeo.gdal.FileFromMemBuffer', 'gdal.FileFromMemBuffer', (['"""/vsimem/testsync.txt"""', '"""bar"""'], {}), "('/vsimem/testsync.txt', 'bar')\n", (95372, 95403), False, 'from osgeo import gdal\n'), ((95419, 95448), 'webserver.SequentialHandler', 'webserver.SequentialHandler', ([], {}), '()\n', (95446, 95448), False, 'import webserver\n'), ((95755, 95799), 'osgeo.gdal.VSIFOpenL', 'gdal.VSIFOpenL', (['"""/vsimem/testsync.txt"""', '"""rb"""'], {}), "('/vsimem/testsync.txt', 'rb')\n", (95769, 95799), False, 'from osgeo import gdal\n'), ((95855, 95873), 'osgeo.gdal.VSIFCloseL', 'gdal.VSIFCloseL', (['f'], {}), '(f)\n', (95870, 95873), False, 'from osgeo import gdal\n'), ((95954, 95978), 'osgeo.gdal.VSICurlClearCache', 'gdal.VSICurlClearCache', ([], {}), '()\n', (95976, 95978), False, 'from osgeo import gdal\n'), ((95994, 96023), 'webserver.SequentialHandler', 'webserver.SequentialHandler', ([], {}), '()\n', (96021, 96023), False, 'import webserver\n'), ((96411, 96446), 'osgeo.gdal.Unlink', 'gdal.Unlink', (['"""/vsimem/testsync.txt"""'], {}), "('/vsimem/testsync.txt')\n", (96422, 96446), False, 'from osgeo import gdal\n'), ((96476, 96500), 'osgeo.gdal.VSICurlClearCache', 'gdal.VSICurlClearCache', ([], {}), '()\n', (96498, 96500), False, 'from osgeo import gdal\n'), ((96506, 96537), 'osgeo.gdal.Mkdir', 'gdal.Mkdir', (['"""/vsimem/subdir"""', '(0)'], {}), "('/vsimem/subdir', 0)\n", (96516, 96537), False, 'from osgeo import gdal\n'), ((96542, 96602), 'osgeo.gdal.FileFromMemBuffer', 'gdal.FileFromMemBuffer', (['"""/vsimem/subdir/testsync.txt"""', '"""foo"""'], {}), "('/vsimem/subdir/testsync.txt', 'foo')\n", (96564, 96602), False, 'from osgeo import gdal\n'), ((96617, 96646), 'webserver.SequentialHandler', 'webserver.SequentialHandler', ([], {}), '()\n', (96644, 96646), False, 'import webserver\n'), ((97424, 97461), 'osgeo.gdal.RmdirRecursive', 'gdal.RmdirRecursive', (['"""/vsimem/subdir"""'], {}), "('/vsimem/subdir')\n", (97443, 97461), False, 'from osgeo import gdal\n'), ((97732, 97785), 'osgeo.gdal.FileFromMemBuffer', 'gdal.FileFromMemBuffer', (['"""/vsimem/testsync.txt"""', '"""foo"""'], {}), "('/vsimem/testsync.txt', 'foo')\n", (97754, 97785), False, 'from osgeo import gdal\n'), ((97839, 97863), 'osgeo.gdal.VSICurlClearCache', 'gdal.VSICurlClearCache', ([], {}), '()\n', (97861, 97863), False, 'from osgeo import gdal\n'), ((97878, 97907), 'webserver.SequentialHandler', 'webserver.SequentialHandler', ([], {}), '()\n', (97905, 97907), False, 'import webserver\n'), ((98506, 98530), 'osgeo.gdal.VSICurlClearCache', 'gdal.VSICurlClearCache', ([], {}), '()\n', (98528, 98530), False, 'from osgeo import gdal\n'), ((98545, 98574), 'webserver.SequentialHandler', 'webserver.SequentialHandler', ([], {}), '()\n', (98572, 98574), False, 'import webserver\n'), ((99001, 99025), 'osgeo.gdal.VSICurlClearCache', 'gdal.VSICurlClearCache', ([], {}), '()\n', (99023, 99025), False, 'from osgeo import gdal\n'), ((99040, 99069), 'webserver.SequentialHandler', 'webserver.SequentialHandler', ([], {}), '()\n', (99067, 99069), False, 'import webserver\n'), ((99561, 99585), 'osgeo.gdal.VSICurlClearCache', 'gdal.VSICurlClearCache', ([], {}), '()\n', (99583, 99585), False, 'from osgeo import gdal\n'), ((99600, 99629), 'webserver.SequentialHandler', 'webserver.SequentialHandler', ([], {}), '()\n', (99627, 99629), False, 'import webserver\n'), ((100022, 100057), 'osgeo.gdal.Unlink', 'gdal.Unlink', (['"""/vsimem/testsync.txt"""'], {}), "('/vsimem/testsync.txt')\n", (100033, 100057), False, 'from osgeo import gdal\n'), ((100328, 100381), 'osgeo.gdal.FileFromMemBuffer', 'gdal.FileFromMemBuffer', (['"""/vsimem/testsync.txt"""', '"""foo"""'], {}), "('/vsimem/testsync.txt', 'foo')\n", (100350, 100381), False, 'from osgeo import gdal\n'), ((100423, 100447), 'osgeo.gdal.VSICurlClearCache', 'gdal.VSICurlClearCache', ([], {}), '()\n', (100445, 100447), False, 'from osgeo import gdal\n'), ((100462, 100491), 'webserver.SequentialHandler', 'webserver.SequentialHandler', ([], {}), '()\n', (100489, 100491), False, 'import webserver\n'), ((101076, 101100), 'osgeo.gdal.VSICurlClearCache', 'gdal.VSICurlClearCache', ([], {}), '()\n', (101098, 101100), False, 'from osgeo import gdal\n'), ((101115, 101144), 'webserver.SequentialHandler', 'webserver.SequentialHandler', ([], {}), '()\n', (101142, 101144), False, 'import webserver\n'), ((101586, 101621), 'osgeo.gdal.Unlink', 'gdal.Unlink', (['"""/vsimem/testsync.txt"""'], {}), "('/vsimem/testsync.txt')\n", (101597, 101621), False, 'from osgeo import gdal\n'), ((101866, 101890), 'osgeo.gdal.VSICurlClearCache', 'gdal.VSICurlClearCache', ([], {}), '()\n', (101888, 101890), False, 'from osgeo import gdal\n'), ((101905, 101934), 'webserver.SequentialHandler', 'webserver.SequentialHandler', ([], {}), '()\n', (101932, 101934), False, 'import webserver\n'), ((103294, 103318), 'osgeo.gdal.VSICurlClearCache', 'gdal.VSICurlClearCache', ([], {}), '()\n', (103316, 103318), False, 'from osgeo import gdal\n'), ((103333, 103362), 'webserver.SequentialHandler', 'webserver.SequentialHandler', ([], {}), '()\n', (103360, 103362), False, 'import webserver\n'), ((104655, 104679), 'osgeo.gdal.VSICurlClearCache', 'gdal.VSICurlClearCache', ([], {}), '()\n', (104677, 104679), False, 'from osgeo import gdal\n'), ((104694, 104723), 'webserver.SequentialHandler', 'webserver.SequentialHandler', ([], {}), '()\n', (104721, 104723), False, 'import webserver\n'), ((107303, 107327), 'osgeo.gdal.VSICurlClearCache', 'gdal.VSICurlClearCache', ([], {}), '()\n', (107325, 107327), False, 'from osgeo import gdal\n'), ((107342, 107371), 'webserver.SequentialHandler', 'webserver.SequentialHandler', ([], {}), '()\n', (107369, 107371), False, 'import webserver\n'), ((107972, 107996), 'osgeo.gdal.VSICurlClearCache', 'gdal.VSICurlClearCache', ([], {}), '()\n', (107994, 107996), False, 'from osgeo import gdal\n'), ((108099, 108128), 'osgeo.gdal.Mkdir', 'gdal.Mkdir', (['"""/vsimem/test"""', '(0)'], {}), "('/vsimem/test', 0)\n", (108109, 108128), False, 'from osgeo import gdal\n'), ((108133, 108184), 'osgeo.gdal.FileFromMemBuffer', 'gdal.FileFromMemBuffer', (['"""/vsimem/test/foo"""', '"""foo\n"""'], {}), "('/vsimem/test/foo', 'foo\\n')\n", (108155, 108184), False, 'from osgeo import gdal\n'), ((108217, 108246), 'webserver.SequentialHandler', 'webserver.SequentialHandler', ([], {}), '()\n', (108244, 108246), False, 'import webserver\n'), ((111691, 111726), 'osgeo.gdal.RmdirRecursive', 'gdal.RmdirRecursive', (['"""/vsimem/test"""'], {}), "('/vsimem/test')\n", (111710, 111726), False, 'from osgeo import gdal\n'), ((111862, 111886), 'osgeo.gdal.VSICurlClearCache', 'gdal.VSICurlClearCache', ([], {}), '()\n', (111884, 111886), False, 'from osgeo import gdal\n'), ((111892, 111921), 'osgeo.gdal.Mkdir', 'gdal.Mkdir', (['"""/vsimem/test"""', '(0)'], {}), "('/vsimem/test', 0)\n", (111902, 111921), False, 'from osgeo import gdal\n'), ((111926, 111977), 'osgeo.gdal.FileFromMemBuffer', 'gdal.FileFromMemBuffer', (['"""/vsimem/test/foo"""', '"""foo\n"""'], {}), "('/vsimem/test/foo', 'foo\\n')\n", (111948, 111977), False, 'from osgeo import gdal\n'), ((111993, 112022), 'webserver.SequentialHandler', 'webserver.SequentialHandler', ([], {}), '()\n', (112020, 112022), False, 'import webserver\n'), ((113976, 114011), 'osgeo.gdal.RmdirRecursive', 'gdal.RmdirRecursive', (['"""/vsimem/test"""'], {}), "('/vsimem/test')\n", (113995, 114011), False, 'from osgeo import gdal\n'), ((114219, 114243), 'osgeo.gdal.VSICurlClearCache', 'gdal.VSICurlClearCache', ([], {}), '()\n', (114241, 114243), False, 'from osgeo import gdal\n'), ((114285, 114314), 'webserver.SequentialHandler', 'webserver.SequentialHandler', ([], {}), '()\n', (114312, 114314), False, 'import webserver\n'), ((114596, 114625), 'webserver.SequentialHandler', 'webserver.SequentialHandler', ([], {}), '()\n', (114623, 114625), False, 'import webserver\n'), ((115007, 115036), 'webserver.SequentialHandler', 'webserver.SequentialHandler', ([], {}), '()\n', (115034, 115036), False, 'import webserver\n'), ((115664, 115693), 'webserver.SequentialHandler', 'webserver.SequentialHandler', ([], {}), '()\n', (115691, 115693), False, 'import webserver\n'), ((116731, 116760), 'webserver.SequentialHandler', 'webserver.SequentialHandler', ([], {}), '()\n', (116758, 116760), False, 'import webserver\n'), ((117507, 117531), 'osgeo.gdal.VSICurlClearCache', 'gdal.VSICurlClearCache', ([], {}), '()\n', (117529, 117531), False, 'from osgeo import gdal\n'), ((117547, 117576), 'webserver.SequentialHandler', 'webserver.SequentialHandler', ([], {}), '()\n', (117574, 117576), False, 'import webserver\n'), ((118364, 118388), 'osgeo.gdal.VSICurlClearCache', 'gdal.VSICurlClearCache', ([], {}), '()\n', (118386, 118388), False, 'from osgeo import gdal\n'), ((118895, 118924), 'webserver.SequentialHandler', 'webserver.SequentialHandler', ([], {}), '()\n', (118922, 118924), False, 'import webserver\n'), ((119299, 119323), 'osgeo.gdal.VSICurlClearCache', 'gdal.VSICurlClearCache', ([], {}), '()\n', (119321, 119323), False, 'from osgeo import gdal\n'), ((119502, 119531), 'webserver.SequentialHandler', 'webserver.SequentialHandler', ([], {}), '()\n', (119529, 119531), False, 'import webserver\n'), ((119928, 119952), 'osgeo.gdal.VSICurlClearCache', 'gdal.VSICurlClearCache', ([], {}), '()\n', (119950, 119952), False, 'from osgeo import gdal\n'), ((120251, 120280), 'webserver.SequentialHandler', 'webserver.SequentialHandler', ([], {}), '()\n', (120278, 120280), False, 'import webserver\n'), ((120697, 120721), 'osgeo.gdal.VSICurlClearCache', 'gdal.VSICurlClearCache', ([], {}), '()\n', (120719, 120721), False, 'from osgeo import gdal\n'), ((120737, 120766), 'webserver.SequentialHandler', 'webserver.SequentialHandler', ([], {}), '()\n', (120764, 120766), False, 'import webserver\n'), ((120999, 121025), 'osgeo.gdal.Open', 'gdal.Open', (['"""data/byte.tif"""'], {}), "('data/byte.tif')\n", (121008, 121025), False, 'from osgeo import gdal\n'), ((121303, 121332), 'webserver.SequentialHandler', 'webserver.SequentialHandler', ([], {}), '()\n', (121330, 121332), False, 'import webserver\n'), ((121700, 121749), 'osgeo.gdal.SetConfigOption', 'gdal.SetConfigOption', (['"""AWS_SECRET_ACCESS_KEY"""', '""""""'], {}), "('AWS_SECRET_ACCESS_KEY', '')\n", (121720, 121749), False, 'from osgeo import gdal\n'), ((121754, 121799), 'osgeo.gdal.SetConfigOption', 'gdal.SetConfigOption', (['"""AWS_ACCESS_KEY_ID"""', '""""""'], {}), "('AWS_ACCESS_KEY_ID', '')\n", (121774, 121799), False, 'from osgeo import gdal\n'), ((121805, 121880), 'osgeo.gdal.SetConfigOption', 'gdal.SetConfigOption', (['"""CPL_AWS_CREDENTIALS_FILE"""', '"""/vsimem/aws_credentials"""'], {}), "('CPL_AWS_CREDENTIALS_FILE', '/vsimem/aws_credentials')\n", (121825, 121880), False, 'from osgeo import gdal\n'), ((121886, 121910), 'osgeo.gdal.VSICurlClearCache', 'gdal.VSICurlClearCache', ([], {}), '()\n', (121908, 121910), False, 'from osgeo import gdal\n'), ((121916, 122205), 'osgeo.gdal.FileFromMemBuffer', 'gdal.FileFromMemBuffer', (['"""/vsimem/aws_credentials"""', '"""\n[unrelated]\naws_access_key_id = foo\naws_secret_access_key = bar\n[default]\naws_access_key_id = AWS_ACCESS_KEY_ID\naws_secret_access_key = AWS_SECRET_ACCESS_KEY\n[unrelated]\naws_access_key_id = foo\naws_secret_access_key = bar\n"""'], {}), '(\'/vsimem/aws_credentials\',\n    """\n[unrelated]\naws_access_key_id = foo\naws_secret_access_key = bar\n[default]\naws_access_key_id = AWS_ACCESS_KEY_ID\naws_secret_access_key = AWS_SECRET_ACCESS_KEY\n[unrelated]\naws_access_key_id = foo\naws_secret_access_key = bar\n"""\n    )\n', (121938, 122205), False, 'from osgeo import gdal\n'), ((122212, 122241), 'webserver.SequentialHandler', 'webserver.SequentialHandler', ([], {}), '()\n', (122239, 122241), False, 'import webserver\n'), ((122595, 122647), 'osgeo.gdal.SetConfigOption', 'gdal.SetConfigOption', (['"""CPL_AWS_CREDENTIALS_FILE"""', '""""""'], {}), "('CPL_AWS_CREDENTIALS_FILE', '')\n", (122615, 122647), False, 'from osgeo import gdal\n'), ((122652, 122690), 'osgeo.gdal.Unlink', 'gdal.Unlink', (['"""/vsimem/aws_credentials"""'], {}), "('/vsimem/aws_credentials')\n", (122663, 122690), False, 'from osgeo import gdal\n'), ((122923, 122972), 'osgeo.gdal.SetConfigOption', 'gdal.SetConfigOption', (['"""AWS_SECRET_ACCESS_KEY"""', '""""""'], {}), "('AWS_SECRET_ACCESS_KEY', '')\n", (122943, 122972), False, 'from osgeo import gdal\n'), ((122977, 123022), 'osgeo.gdal.SetConfigOption', 'gdal.SetConfigOption', (['"""AWS_ACCESS_KEY_ID"""', '""""""'], {}), "('AWS_ACCESS_KEY_ID', '')\n", (122997, 123022), False, 'from osgeo import gdal\n'), ((123028, 123089), 'osgeo.gdal.SetConfigOption', 'gdal.SetConfigOption', (['"""AWS_CONFIG_FILE"""', '"""/vsimem/aws_config"""'], {}), "('AWS_CONFIG_FILE', '/vsimem/aws_config')\n", (123048, 123089), False, 'from osgeo import gdal\n'), ((123095, 123119), 'osgeo.gdal.VSICurlClearCache', 'gdal.VSICurlClearCache', ([], {}), '()\n', (123117, 123119), False, 'from osgeo import gdal\n'), ((123125, 123428), 'osgeo.gdal.FileFromMemBuffer', 'gdal.FileFromMemBuffer', (['"""/vsimem/aws_config"""', '"""\n[unrelated]\naws_access_key_id = foo\naws_secret_access_key = bar\n[default]\naws_access_key_id = AWS_ACCESS_KEY_ID\naws_secret_access_key = AWS_SECRET_ACCESS_KEY\nregion = us-east-1\n[unrelated]\naws_access_key_id = foo\naws_secret_access_key = bar\n"""'], {}), '(\'/vsimem/aws_config\',\n    """\n[unrelated]\naws_access_key_id = foo\naws_secret_access_key = bar\n[default]\naws_access_key_id = AWS_ACCESS_KEY_ID\naws_secret_access_key = AWS_SECRET_ACCESS_KEY\nregion = us-east-1\n[unrelated]\naws_access_key_id = foo\naws_secret_access_key = bar\n"""\n    )\n', (123147, 123428), False, 'from osgeo import gdal\n'), ((123435, 123464), 'webserver.SequentialHandler', 'webserver.SequentialHandler', ([], {}), '()\n', (123462, 123464), False, 'import webserver\n'), ((123818, 123861), 'osgeo.gdal.SetConfigOption', 'gdal.SetConfigOption', (['"""AWS_CONFIG_FILE"""', '""""""'], {}), "('AWS_CONFIG_FILE', '')\n", (123838, 123861), False, 'from osgeo import gdal\n'), ((123866, 123899), 'osgeo.gdal.Unlink', 'gdal.Unlink', (['"""/vsimem/aws_config"""'], {}), "('/vsimem/aws_config')\n", (123877, 123899), False, 'from osgeo import gdal\n'), ((124166, 124215), 'osgeo.gdal.SetConfigOption', 'gdal.SetConfigOption', (['"""AWS_SECRET_ACCESS_KEY"""', '""""""'], {}), "('AWS_SECRET_ACCESS_KEY', '')\n", (124186, 124215), False, 'from osgeo import gdal\n'), ((124220, 124265), 'osgeo.gdal.SetConfigOption', 'gdal.SetConfigOption', (['"""AWS_ACCESS_KEY_ID"""', '""""""'], {}), "('AWS_ACCESS_KEY_ID', '')\n", (124240, 124265), False, 'from osgeo import gdal\n'), ((124271, 124346), 'osgeo.gdal.SetConfigOption', 'gdal.SetConfigOption', (['"""CPL_AWS_CREDENTIALS_FILE"""', '"""/vsimem/aws_credentials"""'], {}), "('CPL_AWS_CREDENTIALS_FILE', '/vsimem/aws_credentials')\n", (124291, 124346), False, 'from osgeo import gdal\n'), ((124351, 124412), 'osgeo.gdal.SetConfigOption', 'gdal.SetConfigOption', (['"""AWS_CONFIG_FILE"""', '"""/vsimem/aws_config"""'], {}), "('AWS_CONFIG_FILE', '/vsimem/aws_config')\n", (124371, 124412), False, 'from osgeo import gdal\n'), ((124418, 124442), 'osgeo.gdal.VSICurlClearCache', 'gdal.VSICurlClearCache', ([], {}), '()\n', (124440, 124442), False, 'from osgeo import gdal\n'), ((124448, 124737), 'osgeo.gdal.FileFromMemBuffer', 'gdal.FileFromMemBuffer', (['"""/vsimem/aws_credentials"""', '"""\n[unrelated]\naws_access_key_id = foo\naws_secret_access_key = bar\n[default]\naws_access_key_id = AWS_ACCESS_KEY_ID\naws_secret_access_key = AWS_SECRET_ACCESS_KEY\n[unrelated]\naws_access_key_id = foo\naws_secret_access_key = bar\n"""'], {}), '(\'/vsimem/aws_credentials\',\n    """\n[unrelated]\naws_access_key_id = foo\naws_secret_access_key = bar\n[default]\naws_access_key_id = AWS_ACCESS_KEY_ID\naws_secret_access_key = AWS_SECRET_ACCESS_KEY\n[unrelated]\naws_access_key_id = foo\naws_secret_access_key = bar\n"""\n    )\n', (124470, 124737), False, 'from osgeo import gdal\n'), ((124734, 125037), 'osgeo.gdal.FileFromMemBuffer', 'gdal.FileFromMemBuffer', (['"""/vsimem/aws_config"""', '"""\n[unrelated]\naws_access_key_id = foo\naws_secret_access_key = bar\n[default]\naws_access_key_id = AWS_ACCESS_KEY_ID\naws_secret_access_key = AWS_SECRET_ACCESS_KEY\nregion = us-east-1\n[unrelated]\naws_access_key_id = foo\naws_secret_access_key = bar\n"""'], {}), '(\'/vsimem/aws_config\',\n    """\n[unrelated]\naws_access_key_id = foo\naws_secret_access_key = bar\n[default]\naws_access_key_id = AWS_ACCESS_KEY_ID\naws_secret_access_key = AWS_SECRET_ACCESS_KEY\nregion = us-east-1\n[unrelated]\naws_access_key_id = foo\naws_secret_access_key = bar\n"""\n    )\n', (124756, 125037), False, 'from osgeo import gdal\n'), ((125044, 125073), 'webserver.SequentialHandler', 'webserver.SequentialHandler', ([], {}), '()\n', (125071, 125073), False, 'import webserver\n'), ((125427, 125479), 'osgeo.gdal.SetConfigOption', 'gdal.SetConfigOption', (['"""CPL_AWS_CREDENTIALS_FILE"""', '""""""'], {}), "('CPL_AWS_CREDENTIALS_FILE', '')\n", (125447, 125479), False, 'from osgeo import gdal\n'), ((125484, 125522), 'osgeo.gdal.Unlink', 'gdal.Unlink', (['"""/vsimem/aws_credentials"""'], {}), "('/vsimem/aws_credentials')\n", (125495, 125522), False, 'from osgeo import gdal\n'), ((125527, 125570), 'osgeo.gdal.SetConfigOption', 'gdal.SetConfigOption', (['"""AWS_CONFIG_FILE"""', '""""""'], {}), "('AWS_CONFIG_FILE', '')\n", (125547, 125570), False, 'from osgeo import gdal\n'), ((125575, 125608), 'osgeo.gdal.Unlink', 'gdal.Unlink', (['"""/vsimem/aws_config"""'], {}), "('/vsimem/aws_config')\n", (125586, 125608), False, 'from osgeo import gdal\n'), ((125930, 125979), 'osgeo.gdal.SetConfigOption', 'gdal.SetConfigOption', (['"""AWS_SECRET_ACCESS_KEY"""', '""""""'], {}), "('AWS_SECRET_ACCESS_KEY', '')\n", (125950, 125979), False, 'from osgeo import gdal\n'), ((125984, 126029), 'osgeo.gdal.SetConfigOption', 'gdal.SetConfigOption', (['"""AWS_ACCESS_KEY_ID"""', '""""""'], {}), "('AWS_ACCESS_KEY_ID', '')\n", (126004, 126029), False, 'from osgeo import gdal\n'), ((126034, 126088), 'osgeo.gdal.SetConfigOption', 'gdal.SetConfigOption', (['"""CPL_AWS_CREDENTIALS_FILE"""', 'None'], {}), "('CPL_AWS_CREDENTIALS_FILE', None)\n", (126054, 126088), False, 'from osgeo import gdal\n'), ((126093, 126138), 'osgeo.gdal.SetConfigOption', 'gdal.SetConfigOption', (['"""AWS_CONFIG_FILE"""', 'None'], {}), "('AWS_CONFIG_FILE', None)\n", (126113, 126138), False, 'from osgeo import gdal\n'), ((126143, 126191), 'osgeo.gdal.SetConfigOption', 'gdal.SetConfigOption', (['"""AWS_PROFILE"""', '"""myprofile"""'], {}), "('AWS_PROFILE', 'myprofile')\n", (126163, 126191), False, 'from osgeo import gdal\n'), ((126232, 126256), 'osgeo.gdal.VSICurlClearCache', 'gdal.VSICurlClearCache', ([], {}), '()\n', (126254, 126256), False, 'from osgeo import gdal\n'), ((126748, 126777), 'webserver.SequentialHandler', 'webserver.SequentialHandler', ([], {}), '()\n', (126775, 126777), False, 'import webserver\n'), ((127261, 127300), 'osgeo.gdal.SetConfigOption', 'gdal.SetConfigOption', (['"""AWS_PROFILE"""', '""""""'], {}), "('AWS_PROFILE', '')\n", (127281, 127300), False, 'from osgeo import gdal\n'), ((127580, 127629), 'osgeo.gdal.SetConfigOption', 'gdal.SetConfigOption', (['"""AWS_SECRET_ACCESS_KEY"""', '""""""'], {}), "('AWS_SECRET_ACCESS_KEY', '')\n", (127600, 127629), False, 'from osgeo import gdal\n'), ((127634, 127679), 'osgeo.gdal.SetConfigOption', 'gdal.SetConfigOption', (['"""AWS_ACCESS_KEY_ID"""', '""""""'], {}), "('AWS_ACCESS_KEY_ID', '')\n", (127654, 127679), False, 'from osgeo import gdal\n'), ((127685, 127760), 'osgeo.gdal.SetConfigOption', 'gdal.SetConfigOption', (['"""CPL_AWS_CREDENTIALS_FILE"""', '"""/vsimem/aws_credentials"""'], {}), "('CPL_AWS_CREDENTIALS_FILE', '/vsimem/aws_credentials')\n", (127705, 127760), False, 'from osgeo import gdal\n'), ((127765, 127826), 'osgeo.gdal.SetConfigOption', 'gdal.SetConfigOption', (['"""AWS_CONFIG_FILE"""', '"""/vsimem/aws_config"""'], {}), "('AWS_CONFIG_FILE', '/vsimem/aws_config')\n", (127785, 127826), False, 'from osgeo import gdal\n'), ((127832, 127856), 'osgeo.gdal.VSICurlClearCache', 'gdal.VSICurlClearCache', ([], {}), '()\n', (127854, 127856), False, 'from osgeo import gdal\n'), ((127862, 128151), 'osgeo.gdal.FileFromMemBuffer', 'gdal.FileFromMemBuffer', (['"""/vsimem/aws_credentials"""', '"""\n[unrelated]\naws_access_key_id = foo\naws_secret_access_key = bar\n[default]\naws_access_key_id = AWS_ACCESS_KEY_ID\naws_secret_access_key = AWS_SECRET_ACCESS_KEY\n[unrelated]\naws_access_key_id = foo\naws_secret_access_key = bar\n"""'], {}), '(\'/vsimem/aws_credentials\',\n    """\n[unrelated]\naws_access_key_id = foo\naws_secret_access_key = bar\n[default]\naws_access_key_id = AWS_ACCESS_KEY_ID\naws_secret_access_key = AWS_SECRET_ACCESS_KEY\n[unrelated]\naws_access_key_id = foo\naws_secret_access_key = bar\n"""\n    )\n', (127884, 128151), False, 'from osgeo import gdal\n'), ((128148, 128477), 'osgeo.gdal.FileFromMemBuffer', 'gdal.FileFromMemBuffer', (['"""/vsimem/aws_config"""', '"""\n[unrelated]\naws_access_key_id = foo\naws_secret_access_key = bar\n[default]\naws_access_key_id = AWS_ACCESS_KEY_ID_inconsistent\naws_secret_access_key = AWS_SECRET_ACCESS_KEY_inconsistent\nregion = us-east-1\n[unrelated]\naws_access_key_id = foo\naws_secret_access_key = bar\n"""'], {}), '(\'/vsimem/aws_config\',\n    """\n[unrelated]\naws_access_key_id = foo\naws_secret_access_key = bar\n[default]\naws_access_key_id = AWS_ACCESS_KEY_ID_inconsistent\naws_secret_access_key = AWS_SECRET_ACCESS_KEY_inconsistent\nregion = us-east-1\n[unrelated]\naws_access_key_id = foo\naws_secret_access_key = bar\n"""\n    )\n', (128170, 128477), False, 'from osgeo import gdal\n'), ((128474, 128491), 'osgeo.gdal.ErrorReset', 'gdal.ErrorReset', ([], {}), '()\n', (128489, 128491), False, 'from osgeo import gdal\n'), ((128506, 128535), 'webserver.SequentialHandler', 'webserver.SequentialHandler', ([], {}), '()\n', (128533, 128535), False, 'import webserver\n'), ((128976, 129028), 'osgeo.gdal.SetConfigOption', 'gdal.SetConfigOption', (['"""CPL_AWS_CREDENTIALS_FILE"""', '""""""'], {}), "('CPL_AWS_CREDENTIALS_FILE', '')\n", (128996, 129028), False, 'from osgeo import gdal\n'), ((129033, 129071), 'osgeo.gdal.Unlink', 'gdal.Unlink', (['"""/vsimem/aws_credentials"""'], {}), "('/vsimem/aws_credentials')\n", (129044, 129071), False, 'from osgeo import gdal\n'), ((129076, 129119), 'osgeo.gdal.SetConfigOption', 'gdal.SetConfigOption', (['"""AWS_CONFIG_FILE"""', '""""""'], {}), "('AWS_CONFIG_FILE', '')\n", (129096, 129119), False, 'from osgeo import gdal\n'), ((129124, 129157), 'osgeo.gdal.Unlink', 'gdal.Unlink', (['"""/vsimem/aws_config"""'], {}), "('/vsimem/aws_config')\n", (129135, 129157), False, 'from osgeo import gdal\n'), ((129479, 129531), 'osgeo.gdal.SetConfigOption', 'gdal.SetConfigOption', (['"""CPL_AWS_CREDENTIALS_FILE"""', '""""""'], {}), "('CPL_AWS_CREDENTIALS_FILE', '')\n", (129499, 129531), False, 'from osgeo import gdal\n'), ((129536, 129579), 'osgeo.gdal.SetConfigOption', 'gdal.SetConfigOption', (['"""AWS_CONFIG_FILE"""', '""""""'], {}), "('AWS_CONFIG_FILE', '')\n", (129556, 129579), False, 'from osgeo import gdal\n'), ((129584, 129633), 'osgeo.gdal.SetConfigOption', 'gdal.SetConfigOption', (['"""AWS_SECRET_ACCESS_KEY"""', '""""""'], {}), "('AWS_SECRET_ACCESS_KEY', '')\n", (129604, 129633), False, 'from osgeo import gdal\n'), ((129638, 129683), 'osgeo.gdal.SetConfigOption', 'gdal.SetConfigOption', (['"""AWS_ACCESS_KEY_ID"""', '""""""'], {}), "('AWS_ACCESS_KEY_ID', '')\n", (129658, 129683), False, 'from osgeo import gdal\n'), ((129689, 129790), 'osgeo.gdal.SetConfigOption', 'gdal.SetConfigOption', (['"""CPL_AWS_EC2_API_ROOT_URL"""', "('http://localhost:%d' % gdaltest.webserver_port)"], {}), "('CPL_AWS_EC2_API_ROOT_URL', 'http://localhost:%d' %\n    gdaltest.webserver_port)\n", (129709, 129790), False, 'from osgeo import gdal\n'), ((129887, 129939), 'osgeo.gdal.SetConfigOption', 'gdal.SetConfigOption', (['"""CPL_AWS_AUTODETECT_EC2"""', '"""NO"""'], {}), "('CPL_AWS_AUTODETECT_EC2', 'NO')\n", (129907, 129939), False, 'from osgeo import gdal\n'), ((129945, 129969), 'osgeo.gdal.VSICurlClearCache', 'gdal.VSICurlClearCache', ([], {}), '()\n', (129967, 129969), False, 'from osgeo import gdal\n'), ((129985, 130014), 'webserver.SequentialHandler', 'webserver.SequentialHandler', ([], {}), '()\n', (130012, 130014), False, 'import webserver\n'), ((131110, 131162), 'osgeo.gdal.SetConfigOption', 'gdal.SetConfigOption', (['"""CPL_AWS_EC2_API_ROOT_URL"""', '""""""'], {}), "('CPL_AWS_EC2_API_ROOT_URL', '')\n", (131130, 131162), False, 'from osgeo import gdal\n'), ((131178, 131207), 'webserver.SequentialHandler', 'webserver.SequentialHandler', ([], {}), '()\n', (131205, 131207), False, 'import webserver\n'), ((131517, 131569), 'osgeo.gdal.SetConfigOption', 'gdal.SetConfigOption', (['"""CPL_AWS_EC2_API_ROOT_URL"""', '""""""'], {}), "('CPL_AWS_EC2_API_ROOT_URL', '')\n", (131537, 131569), False, 'from osgeo import gdal\n'), ((131574, 131626), 'osgeo.gdal.SetConfigOption', 'gdal.SetConfigOption', (['"""CPL_AWS_AUTODETECT_EC2"""', 'None'], {}), "('CPL_AWS_AUTODETECT_EC2', None)\n", (131594, 131626), False, 'from osgeo import gdal\n'), ((131974, 132026), 'osgeo.gdal.SetConfigOption', 'gdal.SetConfigOption', (['"""CPL_AWS_CREDENTIALS_FILE"""', '""""""'], {}), "('CPL_AWS_CREDENTIALS_FILE', '')\n", (131994, 132026), False, 'from osgeo import gdal\n'), ((132031, 132074), 'osgeo.gdal.SetConfigOption', 'gdal.SetConfigOption', (['"""AWS_CONFIG_FILE"""', '""""""'], {}), "('AWS_CONFIG_FILE', '')\n", (132051, 132074), False, 'from osgeo import gdal\n'), ((132079, 132128), 'osgeo.gdal.SetConfigOption', 'gdal.SetConfigOption', (['"""AWS_SECRET_ACCESS_KEY"""', '""""""'], {}), "('AWS_SECRET_ACCESS_KEY', '')\n", (132099, 132128), False, 'from osgeo import gdal\n'), ((132133, 132178), 'osgeo.gdal.SetConfigOption', 'gdal.SetConfigOption', (['"""AWS_ACCESS_KEY_ID"""', '""""""'], {}), "('AWS_ACCESS_KEY_ID', '')\n", (132153, 132178), False, 'from osgeo import gdal\n'), ((132184, 132285), 'osgeo.gdal.SetConfigOption', 'gdal.SetConfigOption', (['"""CPL_AWS_EC2_API_ROOT_URL"""', "('http://localhost:%d' % gdaltest.webserver_port)"], {}), "('CPL_AWS_EC2_API_ROOT_URL', 'http://localhost:%d' %\n    gdaltest.webserver_port)\n", (132204, 132285), False, 'from osgeo import gdal\n'), ((132382, 132434), 'osgeo.gdal.SetConfigOption', 'gdal.SetConfigOption', (['"""CPL_AWS_AUTODETECT_EC2"""', '"""NO"""'], {}), "('CPL_AWS_AUTODETECT_EC2', 'NO')\n", (132402, 132434), False, 'from osgeo import gdal\n'), ((132440, 132464), 'osgeo.gdal.VSICurlClearCache', 'gdal.VSICurlClearCache', ([], {}), '()\n', (132462, 132464), False, 'from osgeo import gdal\n'), ((132480, 132509), 'webserver.SequentialHandler', 'webserver.SequentialHandler', ([], {}), '()\n', (132507, 132509), False, 'import webserver\n'), ((133516, 133568), 'osgeo.gdal.SetConfigOption', 'gdal.SetConfigOption', (['"""CPL_AWS_EC2_API_ROOT_URL"""', '""""""'], {}), "('CPL_AWS_EC2_API_ROOT_URL', '')\n", (133536, 133568), False, 'from osgeo import gdal\n'), ((133573, 133625), 'osgeo.gdal.SetConfigOption', 'gdal.SetConfigOption', (['"""CPL_AWS_AUTODETECT_EC2"""', 'None'], {}), "('CPL_AWS_AUTODETECT_EC2', None)\n", (133593, 133625), False, 'from osgeo import gdal\n'), ((133995, 134047), 'osgeo.gdal.SetConfigOption', 'gdal.SetConfigOption', (['"""CPL_AWS_CREDENTIALS_FILE"""', '""""""'], {}), "('CPL_AWS_CREDENTIALS_FILE', '')\n", (134015, 134047), False, 'from osgeo import gdal\n'), ((134052, 134095), 'osgeo.gdal.SetConfigOption', 'gdal.SetConfigOption', (['"""AWS_CONFIG_FILE"""', '""""""'], {}), "('AWS_CONFIG_FILE', '')\n", (134072, 134095), False, 'from osgeo import gdal\n'), ((134100, 134149), 'osgeo.gdal.SetConfigOption', 'gdal.SetConfigOption', (['"""AWS_SECRET_ACCESS_KEY"""', '""""""'], {}), "('AWS_SECRET_ACCESS_KEY', '')\n", (134120, 134149), False, 'from osgeo import gdal\n'), ((134154, 134199), 'osgeo.gdal.SetConfigOption', 'gdal.SetConfigOption', (['"""AWS_ACCESS_KEY_ID"""', '""""""'], {}), "('AWS_ACCESS_KEY_ID', '')\n", (134174, 134199), False, 'from osgeo import gdal\n'), ((134205, 134306), 'osgeo.gdal.SetConfigOption', 'gdal.SetConfigOption', (['"""CPL_AWS_EC2_API_ROOT_URL"""', "('http://localhost:%d' % gdaltest.webserver_port)"], {}), "('CPL_AWS_EC2_API_ROOT_URL', 'http://localhost:%d' %\n    gdaltest.webserver_port)\n", (134225, 134306), False, 'from osgeo import gdal\n'), ((134403, 134455), 'osgeo.gdal.SetConfigOption', 'gdal.SetConfigOption', (['"""CPL_AWS_AUTODETECT_EC2"""', '"""NO"""'], {}), "('CPL_AWS_AUTODETECT_EC2', 'NO')\n", (134423, 134455), False, 'from osgeo import gdal\n'), ((134461, 134485), 'osgeo.gdal.VSICurlClearCache', 'gdal.VSICurlClearCache', ([], {}), '()\n', (134483, 134485), False, 'from osgeo import gdal\n'), ((134501, 134530), 'webserver.SequentialHandler', 'webserver.SequentialHandler', ([], {}), '()\n', (134528, 134530), False, 'import webserver\n'), ((136149, 136259), 'osgeo.gdal.SetConfigOption', 'gdal.SetConfigOption', (['"""CPL_AWS_EC2_API_ROOT_URL"""', "('http://localhost:%d/invalid' % gdaltest.webserver_port)"], {}), "('CPL_AWS_EC2_API_ROOT_URL', \n    'http://localhost:%d/invalid' % gdaltest.webserver_port)\n", (136169, 136259), False, 'from osgeo import gdal\n'), ((136295, 136324), 'webserver.SequentialHandler', 'webserver.SequentialHandler', ([], {}), '()\n', (136322, 136324), False, 'import webserver\n'), ((136652, 136704), 'osgeo.gdal.SetConfigOption', 'gdal.SetConfigOption', (['"""CPL_AWS_EC2_API_ROOT_URL"""', '""""""'], {}), "('CPL_AWS_EC2_API_ROOT_URL', '')\n", (136672, 136704), False, 'from osgeo import gdal\n'), ((136709, 136761), 'osgeo.gdal.SetConfigOption', 'gdal.SetConfigOption', (['"""CPL_AWS_AUTODETECT_EC2"""', 'None'], {}), "('CPL_AWS_AUTODETECT_EC2', None)\n", (136729, 136761), False, 'from osgeo import gdal\n'), ((137064, 137088), 'osgeo.gdal.VSICurlClearCache', 'gdal.VSICurlClearCache', ([], {}), '()\n', (137086, 137088), False, 'from osgeo import gdal\n'), ((137094, 137168), 'webserver.server_stop', 'webserver.server_stop', (['gdaltest.webserver_process', 'gdaltest.webserver_port'], {}), '(gdaltest.webserver_process, gdaltest.webserver_port)\n', (137115, 137168), False, 'import webserver\n'), ((137620, 137655), 'osgeo.gdal.GetConfigOption', 'gdal.GetConfigOption', (['"""S3_RESOURCE"""'], {}), "('S3_RESOURCE')\n", (137640, 137655), False, 'from osgeo import gdal\n'), ((140740, 140763), 'osgeo.gdal.VSIFReadL', 'gdal.VSIFReadL', (['(1)', '(1)', 'f'], {}), '(1, 1, f)\n', (140754, 140763), False, 'from osgeo import gdal\n'), ((140768, 140786), 'osgeo.gdal.VSIFCloseL', 'gdal.VSIFCloseL', (['f'], {}), '(f)\n', (140783, 140786), False, 'from osgeo import gdal\n'), ((140940, 140963), 'osgeo.gdal.VSIFReadL', 'gdal.VSIFReadL', (['(1)', '(1)', 'f'], {}), '(1, 1, f)\n', (140954, 140963), False, 'from osgeo import gdal\n'), ((140968, 140986), 'osgeo.gdal.VSIFCloseL', 'gdal.VSIFCloseL', (['f'], {}), '(f)\n', (140983, 140986), False, 'from osgeo import gdal\n'), ((141466, 141483), 'osgeo.gdal.ErrorReset', 'gdal.ErrorReset', ([], {}), '()\n', (141481, 141483), False, 'from osgeo import gdal\n'), ((141613, 141638), 'osgeo.gdal.VSIGetLastErrorMsg', 'gdal.VSIGetLastErrorMsg', ([], {}), '()\n', (141636, 141638), False, 'from osgeo import gdal\n'), ((141683, 141725), 'osgeo.gdal.GetSignedURL', 'gdal.GetSignedURL', (["('/vsis3/' + s3_resource)"], {}), "('/vsis3/' + s3_resource)\n", (141700, 141725), False, 'from osgeo import gdal\n'), ((141819, 141842), 'osgeo.gdal.VSIFReadL', 'gdal.VSIFReadL', (['(1)', '(1)', 'f'], {}), '(1, 1, f)\n', (141833, 141842), False, 'from osgeo import gdal\n'), ((141847, 141865), 'osgeo.gdal.VSIFCloseL', 'gdal.VSIFCloseL', (['f'], {}), '(f)\n', (141862, 141865), False, 'from osgeo import gdal\n'), ((142099, 142153), 'osgeo.gdal.SetConfigOption', 'gdal.SetConfigOption', (['"""CPL_AWS_CREDENTIALS_FILE"""', 'None'], {}), "('CPL_AWS_CREDENTIALS_FILE', None)\n", (142119, 142153), False, 'from osgeo import gdal\n'), ((142158, 142203), 'osgeo.gdal.SetConfigOption', 'gdal.SetConfigOption', (['"""AWS_CONFIG_FILE"""', 'None'], {}), "('AWS_CONFIG_FILE', None)\n", (142178, 142203), False, 'from osgeo import gdal\n'), ((142208, 142262), 'osgeo.gdal.SetConfigOption', 'gdal.SetConfigOption', (['"""CPL_AWS_EC2_API_ROOT_URL"""', 'None'], {}), "('CPL_AWS_EC2_API_ROOT_URL', None)\n", (142228, 142262), False, 'from osgeo import gdal\n'), ((2174, 2199), 'osgeo.gdal.GetConfigOption', 'gdal.GetConfigOption', (['var'], {}), '(var)\n', (2194, 2199), False, 'from osgeo import gdal\n'), ((2567, 2602), 'osgeo.gdal.GetSignedURL', 'gdal.GetSignedURL', (['"""/vsis3/foo/bar"""'], {}), "('/vsis3/foo/bar')\n", (2584, 2602), False, 'from osgeo import gdal\n'), ((2771, 2800), 'gdaltest.built_against_curl', 'gdaltest.built_against_curl', ([], {}), '()\n', (2798, 2800), False, 'import gdaltest\n'), ((2810, 2823), 'pytest.skip', 'pytest.skip', ([], {}), '()\n', (2821, 2823), False, 'import pytest\n'), ((2834, 2886), 'gdaltest.config_option', 'gdaltest.config_option', (['"""AWS_NO_SIGN_REQUEST"""', '"""YES"""'], {}), "('AWS_NO_SIGN_REQUEST', 'YES')\n", (2856, 2886), False, 'import gdaltest\n'), ((2909, 3020), 'osgeo.gdal.GetActualURL', 'gdal.GetActualURL', (['"""/vsis3/landsat-pds/L8/001/002/LC80010022016230LGN00/LC80010022016230LGN00_B1.TIF"""'], {}), "(\n    '/vsis3/landsat-pds/L8/001/002/LC80010022016230LGN00/LC80010022016230LGN00_B1.TIF'\n    )\n", (2926, 3020), False, 'from osgeo import gdal\n'), ((3163, 3284), 'osgeo.gdal.GetActualURL', 'gdal.GetActualURL', (['"""/vsis3_streaming/landsat-pds/L8/001/002/LC80010022016230LGN00/LC80010022016230LGN00_B1.TIF"""'], {}), "(\n    '/vsis3_streaming/landsat-pds/L8/001/002/LC80010022016230LGN00/LC80010022016230LGN00_B1.TIF'\n    )\n", (3180, 3284), False, 'from osgeo import gdal\n'), ((3729, 3742), 'pytest.fail', 'pytest.fail', ([], {}), '()\n', (3740, 3742), False, 'import pytest\n'), ((3949, 3978), 'gdaltest.built_against_curl', 'gdaltest.built_against_curl', ([], {}), '()\n', (3976, 3978), False, 'import gdaltest\n'), ((3988, 4001), 'pytest.skip', 'pytest.skip', ([], {}), '()\n', (3999, 4001), False, 'import pytest\n'), ((4199, 4251), 'gdaltest.config_option', 'gdaltest.config_option', (['"""AWS_NO_SIGN_REQUEST"""', '"""YES"""'], {}), "('AWS_NO_SIGN_REQUEST', 'YES')\n", (4221, 4251), False, 'import gdaltest\n'), ((4268, 4422), 'osgeo.gdal.Sync', 'gdal.Sync', (['"""/vsis3/cdn.proj.org/test_dummy"""', '"""/vsimem/test_vsis3_no_sign_request_sync"""'], {'options': "['NUM_THREADS=2']", 'callback': 'cbk', 'callback_data': 'tab'}), "('/vsis3/cdn.proj.org/test_dummy',\n    '/vsimem/test_vsis3_no_sign_request_sync', options=['NUM_THREADS=2'],\n    callback=cbk, callback_data=tab)\n", (4277, 4422), False, 'from osgeo import gdal\n'), ((4977, 5006), 'gdaltest.built_against_curl', 'gdaltest.built_against_curl', ([], {}), '()\n', (5004, 5006), False, 'import gdaltest\n'), ((5016, 5029), 'pytest.skip', 'pytest.skip', ([], {}), '()\n', (5027, 5029), False, 'import pytest\n'), ((5227, 5279), 'gdaltest.config_option', 'gdaltest.config_option', (['"""AWS_NO_SIGN_REQUEST"""', '"""YES"""'], {}), "('AWS_NO_SIGN_REQUEST', 'YES')\n", (5249, 5279), False, 'import gdaltest\n'), ((5296, 5466), 'osgeo.gdal.Sync', 'gdal.Sync', (['"""/vsis3/cdn.proj.org/test_dummy"""', '"""/vsimem/test_vsis3_no_sign_request_sync"""'], {'options': "['NUM_THREADS=2', 'CHUNK_SIZE=3']", 'callback': 'cbk', 'callback_data': 'tab'}), "('/vsis3/cdn.proj.org/test_dummy',\n    '/vsimem/test_vsis3_no_sign_request_sync', options=['NUM_THREADS=2',\n    'CHUNK_SIZE=3'], callback=cbk, callback_data=tab)\n", (5305, 5466), False, 'from osgeo import gdal\n'), ((5942, 5971), 'gdaltest.built_against_curl', 'gdaltest.built_against_curl', ([], {}), '()\n', (5969, 5971), False, 'import gdaltest\n'), ((5981, 5994), 'pytest.skip', 'pytest.skip', ([], {}), '()\n', (5992, 5994), False, 'import pytest\n'), ((6063, 6087), 'gdaltest.error_handler', 'gdaltest.error_handler', ([], {}), '()\n', (6085, 6087), False, 'import gdaltest\n'), ((6251, 6275), 'gdaltest.error_handler', 'gdaltest.error_handler', ([], {}), '()\n', (6273, 6275), False, 'import gdaltest\n'), ((6557, 6581), 'gdaltest.error_handler', 'gdaltest.error_handler', ([], {}), '()\n', (6579, 6581), False, 'import gdaltest\n'), ((6890, 6914), 'gdaltest.error_handler', 'gdaltest.error_handler', ([], {}), '()\n', (6912, 6914), False, 'import gdaltest\n'), ((7233, 7257), 'gdaltest.error_handler', 'gdaltest.error_handler', ([], {}), '()\n', (7255, 7257), False, 'import gdaltest\n'), ((7574, 7603), 'gdaltest.built_against_curl', 'gdaltest.built_against_curl', ([], {}), '()\n', (7601, 7603), False, 'import gdaltest\n'), ((7613, 7626), 'pytest.skip', 'pytest.skip', ([], {}), '()\n', (7624, 7626), False, 'import pytest\n'), ((7791, 7804), 'pytest.skip', 'pytest.skip', ([], {}), '()\n', (7802, 7804), False, 'import pytest\n'), ((9658, 9671), 'pytest.skip', 'pytest.skip', ([], {}), '()\n', (9669, 9671), False, 'import pytest\n'), ((10634, 10673), 'webserver.install_http_handler', 'webserver.install_http_handler', (['handler'], {}), '(handler)\n', (10664, 10673), False, 'import webserver\n'), ((10827, 10845), 'osgeo.gdal.VSIFCloseL', 'gdal.VSIFCloseL', (['f'], {}), '(f)\n', (10842, 10845), False, 'from osgeo import gdal\n'), ((11031, 11070), 'webserver.install_http_handler', 'webserver.install_http_handler', (['handler'], {}), '(handler)\n', (11061, 11070), False, 'import webserver\n'), ((11234, 11252), 'osgeo.gdal.VSIFCloseL', 'gdal.VSIFCloseL', (['f'], {}), '(f)\n', (11249, 11252), False, 'from osgeo import gdal\n'), ((12784, 12848), 'gdaltest.config_option', 'gdaltest.config_option', (['"""AWS_SESSION_TOKEN"""', '"""AWS_SESSION_TOKEN"""'], {}), "('AWS_SESSION_TOKEN', 'AWS_SESSION_TOKEN')\n", (12806, 12848), False, 'import gdaltest\n'), ((14279, 14318), 'webserver.install_http_handler', 'webserver.install_http_handler', (['handler'], {}), '(handler)\n', (14309, 14318), False, 'import webserver\n'), ((14488, 14540), 'osgeo.gdal.VSIStatL', 'gdal.VSIStatL', (['"""/vsis3/s3_fake_bucket/resource2.bin"""'], {}), "('/vsis3/s3_fake_bucket/resource2.bin')\n", (14501, 14540), False, 'from osgeo import gdal\n'), ((15068, 15107), 'webserver.install_http_handler', 'webserver.install_http_handler', (['handler'], {}), '(handler)\n', (15098, 15107), False, 'import webserver\n'), ((15128, 15190), 'osgeo.gdal.VSIStatL', 'gdal.VSIStatL', (['"""/vsis3_streaming/s3_fake_bucket/resource2.bin"""'], {}), "('/vsis3_streaming/s3_fake_bucket/resource2.bin')\n", (15141, 15190), False, 'from osgeo import gdal\n'), ((15360, 15373), 'pytest.fail', 'pytest.fail', ([], {}), '()\n', (15371, 15373), False, 'import pytest\n'), ((18036, 18075), 'webserver.install_http_handler', 'webserver.install_http_handler', (['handler'], {}), '(handler)\n', (18066, 18075), False, 'import webserver\n'), ((18229, 18247), 'osgeo.gdal.VSIFCloseL', 'gdal.VSIFCloseL', (['f'], {}), '(f)\n', (18244, 18247), False, 'from osgeo import gdal\n'), ((18283, 18318), 'gdaltest.is_travis_branch', 'gdaltest.is_travis_branch', (['"""trusty"""'], {}), "('trusty')\n", (18308, 18318), False, 'import gdaltest\n'), ((18409, 18426), 'pytest.fail', 'pytest.fail', (['data'], {}), '(data)\n', (18420, 18426), False, 'import pytest\n'), ((18536, 18575), 'webserver.install_http_handler', 'webserver.install_http_handler', (['handler'], {}), '(handler)\n', (18566, 18575), False, 'import webserver\n'), ((18739, 18757), 'osgeo.gdal.VSIFCloseL', 'gdal.VSIFCloseL', (['f'], {}), '(f)\n', (18754, 18757), False, 'from osgeo import gdal\n'), ((19739, 19778), 'webserver.install_http_handler', 'webserver.install_http_handler', (['handler'], {}), '(handler)\n', (19769, 19778), False, 'import webserver\n'), ((20388, 20427), 'webserver.install_http_handler', 'webserver.install_http_handler', (['handler'], {}), '(handler)\n', (20418, 20427), False, 'import webserver\n'), ((21045, 21084), 'webserver.install_http_handler', 'webserver.install_http_handler', (['handler'], {}), '(handler)\n', (21075, 21084), False, 'import webserver\n'), ((21782, 21821), 'webserver.install_http_handler', 'webserver.install_http_handler', (['handler'], {}), '(handler)\n', (21812, 21821), False, 'import webserver\n'), ((22529, 22568), 'webserver.install_http_handler', 'webserver.install_http_handler', (['handler'], {}), '(handler)\n', (22559, 22568), False, 'import webserver\n'), ((23234, 23273), 'webserver.install_http_handler', 'webserver.install_http_handler', (['handler'], {}), '(handler)\n', (23264, 23273), False, 'import webserver\n'), ((25212, 25268), 'gdaltest.config_option', 'gdaltest.config_option', (['"""AWS_REQUEST_PAYER"""', '"""requester"""'], {}), "('AWS_REQUEST_PAYER', 'requester')\n", (25234, 25268), False, 'import gdaltest\n'), ((27781, 27820), 'webserver.install_http_handler', 'webserver.install_http_handler', (['handler'], {}), '(handler)\n', (27811, 27820), False, 'import webserver\n'), ((27991, 28009), 'osgeo.gdal.VSIFCloseL', 'gdal.VSIFCloseL', (['f'], {}), '(f)\n', (28006, 28009), False, 'from osgeo import gdal\n'), ((28401, 28440), 'webserver.install_http_handler', 'webserver.install_http_handler', (['handler'], {}), '(handler)\n', (28431, 28440), False, 'import webserver\n'), ((28612, 28630), 'osgeo.gdal.VSIFCloseL', 'gdal.VSIFCloseL', (['f'], {}), '(f)\n', (28627, 28630), False, 'from osgeo import gdal\n'), ((28897, 28910), 'pytest.skip', 'pytest.skip', ([], {}), '()\n', (28908, 28910), False, 'import pytest\n'), ((29149, 29188), 'webserver.install_http_handler', 'webserver.install_http_handler', (['handler'], {}), '(handler)\n', (29179, 29188), False, 'import webserver\n'), ((29536, 29597), 'gdaltest.config_option', 'gdaltest.config_option', (['"""AWS_ACCESS_KEY_ID"""', '"""another_key_id"""'], {}), "('AWS_ACCESS_KEY_ID', 'another_key_id')\n", (29558, 29597), False, 'import gdaltest\n'), ((29617, 29646), 'webserver.SequentialHandler', 'webserver.SequentialHandler', ([], {}), '()\n', (29644, 29646), False, 'import webserver\n'), ((30549, 30562), 'pytest.skip', 'pytest.skip', ([], {}), '()\n', (30560, 30562), False, 'import pytest\n'), ((35057, 35096), 'webserver.install_http_handler', 'webserver.install_http_handler', (['handler'], {}), '(handler)\n', (35087, 35096), False, 'import webserver\n'), ((35222, 35257), 'gdaltest.is_travis_branch', 'gdaltest.is_travis_branch', (['"""trusty"""'], {}), "('trusty')\n", (35247, 35257), False, 'import gdaltest\n'), ((35348, 35361), 'pytest.fail', 'pytest.fail', ([], {}), '()\n', (35359, 35361), False, 'import pytest\n'), ((35481, 35536), 'osgeo.gdal.ReadDir', 'gdal.ReadDir', (['"""/vsis3/s3_fake_bucket2/a_dir with_space"""'], {}), "('/vsis3/s3_fake_bucket2/a_dir with_space')\n", (35493, 35536), False, 'from osgeo import gdal\n'), ((37014, 37053), 'webserver.install_http_handler', 'webserver.install_http_handler', (['handler'], {}), '(handler)\n', (37044, 37053), False, 'import webserver\n'), ((37063, 37149), 'osgeo.gdal.VSIStatL', 'gdal.VSIStatL', (['"""/vsis3/s3_fake_bucket2/a_dir with_space/resource3 with_space.bin"""'], {}), "(\n    '/vsis3/s3_fake_bucket2/a_dir with_space/resource3 with_space.bin')\n", (37076, 37149), False, 'from osgeo import gdal\n'), ((37700, 37739), 'webserver.install_http_handler', 'webserver.install_http_handler', (['handler'], {}), '(handler)\n', (37730, 37739), False, 'import webserver\n'), ((37764, 37808), 'osgeo.gdal.ReadDir', 'gdal.ReadDir', (['"""/vsis3/s3_fake_bucket2/a_dir"""'], {}), "('/vsis3/s3_fake_bucket2/a_dir')\n", (37776, 37808), False, 'from osgeo import gdal\n'), ((38803, 38871), 'gdaltest.config_option', 'gdaltest.config_option', (['"""CPL_VSIL_CURL_IGNORE_GLACIER_STORAGE"""', '"""NO"""'], {}), "('CPL_VSIL_CURL_IGNORE_GLACIER_STORAGE', 'NO')\n", (38825, 38871), False, 'import gdaltest\n'), ((43570, 43609), 'webserver.install_http_handler', 'webserver.install_http_handler', (['handler'], {}), '(handler)\n', (43600, 43609), False, 'import webserver\n'), ((43634, 43657), 'osgeo.gdal.ReadDir', 'gdal.ReadDir', (['"""/vsis3/"""'], {}), "('/vsis3/')\n", (43646, 43657), False, 'from osgeo import gdal\n'), ((44120, 44159), 'webserver.install_http_handler', 'webserver.install_http_handler', (['handler'], {}), '(handler)\n', (44150, 44159), False, 'import webserver\n'), ((44184, 44207), 'osgeo.gdal.ReadDir', 'gdal.ReadDir', (['"""/vsis3/"""'], {}), "('/vsis3/')\n", (44196, 44207), False, 'from osgeo import gdal\n'), ((46782, 46821), 'webserver.install_http_handler', 'webserver.install_http_handler', (['handler'], {}), '(handler)\n', (46812, 46821), False, 'import webserver\n'), ((46846, 46904), 'osgeo.gdal.ReadDir', 'gdal.ReadDir', (['"""/vsis3/s3_test_temporary_redirect_read_dir"""'], {}), "('/vsis3/s3_test_temporary_redirect_read_dir')\n", (46858, 46904), False, 'from osgeo import gdal\n'), ((47619, 47658), 'webserver.install_http_handler', 'webserver.install_http_handler', (['handler'], {}), '(handler)\n', (47649, 47658), False, 'import webserver\n'), ((47683, 47746), 'osgeo.gdal.ReadDir', 'gdal.ReadDir', (['"""/vsis3/s3_test_temporary_redirect_read_dir/test"""'], {}), "('/vsis3/s3_test_temporary_redirect_read_dir/test')\n", (47695, 47746), False, 'from osgeo import gdal\n'), ((47979, 47992), 'pytest.skip', 'pytest.skip', ([], {}), '()\n', (47990, 47992), False, 'import pytest\n'), ((48958, 48997), 'webserver.install_http_handler', 'webserver.install_http_handler', (['handler'], {}), '(handler)\n', (48988, 48997), False, 'import webserver\n'), ((49011, 49047), 'osgeo.gdal.OpenDir', 'gdal.OpenDir', (['"""/vsis3/vsis3_opendir"""'], {}), "('/vsis3/vsis3_opendir')\n", (49023, 49047), False, 'from osgeo import gdal\n'), ((50170, 50209), 'webserver.install_http_handler', 'webserver.install_http_handler', (['handler'], {}), '(handler)\n', (50200, 50209), False, 'import webserver\n'), ((50223, 50262), 'osgeo.gdal.OpenDir', 'gdal.OpenDir', (['"""/vsis3/vsis3_opendir"""', '(0)'], {}), "('/vsis3/vsis3_opendir', 0)\n", (50235, 50262), False, 'from osgeo import gdal\n'), ((51305, 51344), 'webserver.install_http_handler', 'webserver.install_http_handler', (['handler'], {}), '(handler)\n', (51335, 51344), False, 'import webserver\n'), ((51358, 51397), 'osgeo.gdal.OpenDir', 'gdal.OpenDir', (['"""/vsis3/vsis3_opendir"""', '(1)'], {}), "('/vsis3/vsis3_opendir', 1)\n", (51370, 51397), False, 'from osgeo import gdal\n'), ((52270, 52309), 'webserver.install_http_handler', 'webserver.install_http_handler', (['handler'], {}), '(handler)\n', (52300, 52309), False, 'import webserver\n'), ((52327, 52350), 'osgeo.gdal.GetNextDirEntry', 'gdal.GetNextDirEntry', (['d'], {}), '(d)\n', (52347, 52350), False, 'from osgeo import gdal\n'), ((52680, 52693), 'pytest.skip', 'pytest.skip', ([], {}), '()\n', (52691, 52693), False, 'import pytest\n'), ((53039, 53078), 'webserver.install_http_handler', 'webserver.install_http_handler', (['handler'], {}), '(handler)\n', (53069, 53078), False, 'import webserver\n'), ((53655, 53694), 'webserver.install_http_handler', 'webserver.install_http_handler', (['handler'], {}), '(handler)\n', (53685, 53694), False, 'import webserver\n'), ((53708, 53769), 'osgeo.gdal.VSIFOpenL', 'gdal.VSIFOpenL', (['"""/vsis3/s3_fake_bucket3/empty_file.bin"""', '"""wb"""'], {}), "('/vsis3/s3_fake_bucket3/empty_file.bin', 'wb')\n", (53722, 53769), False, 'from osgeo import gdal\n'), ((53807, 53824), 'osgeo.gdal.ErrorReset', 'gdal.ErrorReset', ([], {}), '()\n', (53822, 53824), False, 'from osgeo import gdal\n'), ((53833, 53851), 'osgeo.gdal.VSIFCloseL', 'gdal.VSIFCloseL', (['f'], {}), '(f)\n', (53848, 53851), False, 'from osgeo import gdal\n'), ((53863, 53885), 'osgeo.gdal.GetLastErrorMsg', 'gdal.GetLastErrorMsg', ([], {}), '()\n', (53883, 53885), False, 'from osgeo import gdal\n'), ((54038, 54077), 'webserver.install_http_handler', 'webserver.install_http_handler', (['handler'], {}), '(handler)\n', (54068, 54077), False, 'import webserver\n'), ((54232, 54271), 'webserver.install_http_handler', 'webserver.install_http_handler', (['handler'], {}), '(handler)\n', (54262, 54271), False, 'import webserver\n'), ((54285, 54346), 'osgeo.gdal.VSIFOpenL', 'gdal.VSIFOpenL', (['"""/vsis3/s3_fake_bucket3/empty_file.bin"""', '"""wb"""'], {}), "('/vsis3/s3_fake_bucket3/empty_file.bin', 'wb')\n", (54299, 54346), False, 'from osgeo import gdal\n'), ((54489, 54507), 'osgeo.gdal.VSIFCloseL', 'gdal.VSIFCloseL', (['f'], {}), '(f)\n', (54504, 54507), False, 'from osgeo import gdal\n'), ((54581, 54620), 'webserver.install_http_handler', 'webserver.install_http_handler', (['handler'], {}), '(handler)\n', (54611, 54620), False, 'import webserver\n'), ((54634, 54695), 'osgeo.gdal.VSIFOpenL', 'gdal.VSIFOpenL', (['"""/vsis3/s3_fake_bucket3/empty_file.bin"""', '"""wb"""'], {}), "('/vsis3/s3_fake_bucket3/empty_file.bin', 'wb')\n", (54648, 54695), False, 'from osgeo import gdal\n'), ((54837, 54855), 'osgeo.gdal.VSIFCloseL', 'gdal.VSIFCloseL', (['f'], {}), '(f)\n', (54852, 54855), False, 'from osgeo import gdal\n'), ((54996, 55035), 'webserver.install_http_handler', 'webserver.install_http_handler', (['handler'], {}), '(handler)\n', (55026, 55035), False, 'import webserver\n'), ((55049, 55116), 'osgeo.gdal.VSIFOpenL', 'gdal.VSIFOpenL', (['"""/vsis3/s3_fake_bucket3/empty_file_error.bin"""', '"""wb"""'], {}), "('/vsis3/s3_fake_bucket3/empty_file_error.bin', 'wb')\n", (55063, 55116), False, 'from osgeo import gdal\n'), ((55154, 55171), 'osgeo.gdal.ErrorReset', 'gdal.ErrorReset', ([], {}), '()\n', (55169, 55171), False, 'from osgeo import gdal\n'), ((55253, 55275), 'osgeo.gdal.GetLastErrorMsg', 'gdal.GetLastErrorMsg', ([], {}), '()\n', (55273, 55275), False, 'from osgeo import gdal\n'), ((55341, 55404), 'gdaltest.config_option', 'gdaltest.config_option', (['"""CPL_VSIL_NETWORK_STATS_ENABLED"""', '"""YES"""'], {}), "('CPL_VSIL_NETWORK_STATS_ENABLED', 'YES')\n", (55363, 55404), False, 'import gdaltest\n'), ((55950, 55979), 'webserver.SequentialHandler', 'webserver.SequentialHandler', ([], {}), '()\n', (55977, 55979), False, 'import webserver\n'), ((56966, 56983), 'osgeo.gdal.ErrorReset', 'gdal.ErrorReset', ([], {}), '()\n', (56981, 56983), False, 'from osgeo import gdal\n'), ((57133, 57171), 'osgeo.gdal.NetworkStatsGetAsSerializedJSON', 'gdal.NetworkStatsGetAsSerializedJSON', ([], {}), '()\n', (57169, 57171), False, 'from osgeo import gdal\n'), ((58490, 58545), 'osgeo.gdal.VSIFOpenL', 'gdal.VSIFOpenL', (['"""/vsis3/s3_fake_bucket3/redirect"""', '"""wb"""'], {}), "('/vsis3/s3_fake_bucket3/redirect', 'wb')\n", (58504, 58545), False, 'from osgeo import gdal\n'), ((60641, 60680), 'webserver.install_http_handler', 'webserver.install_http_handler', (['handler'], {}), '(handler)\n', (60671, 60680), False, 'import webserver\n'), ((60690, 60708), 'osgeo.gdal.VSIFCloseL', 'gdal.VSIFCloseL', (['f'], {}), '(f)\n', (60705, 60708), False, 'from osgeo import gdal\n'), ((60720, 60742), 'osgeo.gdal.GetLastErrorMsg', 'gdal.GetLastErrorMsg', ([], {}), '()\n', (60740, 60742), False, 'from osgeo import gdal\n'), ((60962, 60975), 'pytest.skip', 'pytest.skip', ([], {}), '()\n', (60973, 60975), False, 'import pytest\n'), ((60986, 61076), 'gdaltest.config_options', 'gdaltest.config_options', (["{'GDAL_HTTP_MAX_RETRY': '2', 'GDAL_HTTP_RETRY_DELAY': '0.01'}"], {}), "({'GDAL_HTTP_MAX_RETRY': '2',\n    'GDAL_HTTP_RETRY_DELAY': '0.01'})\n", (61009, 61076), False, 'import gdaltest\n'), ((61375, 61404), 'webserver.SequentialHandler', 'webserver.SequentialHandler', ([], {}), '()\n', (61402, 61404), False, 'import webserver\n'), ((62787, 62800), 'pytest.skip', 'pytest.skip', ([], {}), '()\n', (62798, 62800), False, 'import pytest\n'), ((63124, 63163), 'webserver.install_http_handler', 'webserver.install_http_handler', (['handler'], {}), '(handler)\n', (63154, 63163), False, 'import webserver\n'), ((63297, 63336), 'webserver.install_http_handler', 'webserver.install_http_handler', (['handler'], {}), '(handler)\n', (63327, 63336), False, 'import webserver\n'), ((63534, 63573), 'webserver.install_http_handler', 'webserver.install_http_handler', (['handler'], {}), '(handler)\n', (63564, 63573), False, 'import webserver\n'), ((63589, 63639), 'osgeo.gdal.Unlink', 'gdal.Unlink', (['"""/vsis3/s3_delete_bucket/delete_file"""'], {}), "('/vsis3/s3_delete_bucket/delete_file')\n", (63600, 63639), False, 'from osgeo import gdal\n'), ((63924, 63963), 'webserver.install_http_handler', 'webserver.install_http_handler', (['handler'], {}), '(handler)\n', (63954, 63963), False, 'import webserver\n'), ((64232, 64271), 'webserver.install_http_handler', 'webserver.install_http_handler', (['handler'], {}), '(handler)\n', (64262, 64271), False, 'import webserver\n'), ((65732, 65771), 'webserver.install_http_handler', 'webserver.install_http_handler', (['handler'], {}), '(handler)\n', (65762, 65771), False, 'import webserver\n'), ((65787, 65834), 'osgeo.gdal.Unlink', 'gdal.Unlink', (['"""/vsis3/s3_delete_bucket/redirect"""'], {}), "('/vsis3/s3_delete_bucket/redirect')\n", (65798, 65834), False, 'from osgeo import gdal\n'), ((66059, 66072), 'pytest.skip', 'pytest.skip', ([], {}), '()\n', (66070, 66072), False, 'import pytest\n'), ((67542, 67600), 'gdaltest.config_option', 'gdaltest.config_option', (['"""CPL_VSIS3_UNLINK_BATCH_SIZE"""', '"""2"""'], {}), "('CPL_VSIS3_UNLINK_BATCH_SIZE', '2')\n", (67564, 67600), False, 'import gdaltest\n'), ((68038, 68077), 'webserver.install_http_handler', 'webserver.install_http_handler', (['handler'], {}), '(handler)\n', (68068, 68077), False, 'import webserver\n'), ((68093, 68138), 'osgeo.gdal.UnlinkBatch', 'gdal.UnlinkBatch', (["['/vsis3/unlink_batch/foo']"], {}), "(['/vsis3/unlink_batch/foo'])\n", (68109, 68138), False, 'from osgeo import gdal\n'), ((68368, 68381), 'pytest.skip', 'pytest.skip', ([], {}), '()\n', (68379, 68381), False, 'import pytest\n'), ((71493, 71551), 'gdaltest.config_option', 'gdaltest.config_option', (['"""CPL_VSIS3_UNLINK_BATCH_SIZE"""', '"""2"""'], {}), "('CPL_VSIS3_UNLINK_BATCH_SIZE', '2')\n", (71515, 71551), False, 'import gdaltest\n'), ((71887, 71900), 'pytest.skip', 'pytest.skip', ([], {}), '()\n', (71898, 71900), False, 'import pytest\n'), ((71911, 71958), 'gdaltest.config_option', 'gdaltest.config_option', (['"""VSIS3_CHUNK_SIZE"""', '"""1"""'], {}), "('VSIS3_CHUNK_SIZE', '1')\n", (71933, 71958), False, 'import gdaltest\n'), ((74375, 74414), 'webserver.install_http_handler', 'webserver.install_http_handler', (['handler'], {}), '(handler)\n', (74405, 74414), False, 'import webserver\n'), ((74430, 74469), 'osgeo.gdal.VSIFWriteL', 'gdal.VSIFWriteL', (['big_buffer', '(1)', 'size', 'f'], {}), '(big_buffer, 1, size, f)\n', (74445, 74469), False, 'from osgeo import gdal\n'), ((76098, 76137), 'webserver.install_http_handler', 'webserver.install_http_handler', (['handler'], {}), '(handler)\n', (76128, 76137), False, 'import webserver\n'), ((76147, 76165), 'osgeo.gdal.VSIFCloseL', 'gdal.VSIFCloseL', (['f'], {}), '(f)\n', (76162, 76165), False, 'from osgeo import gdal\n'), ((76177, 76199), 'osgeo.gdal.GetLastErrorMsg', 'gdal.GetLastErrorMsg', ([], {}), '()\n', (76197, 76199), False, 'from osgeo import gdal\n'), ((76663, 76702), 'webserver.install_http_handler', 'webserver.install_http_handler', (['handler'], {}), '(handler)\n', (76693, 76702), False, 'import webserver\n'), ((78431, 78470), 'webserver.install_http_handler', 'webserver.install_http_handler', (['handler'], {}), '(handler)\n', (78461, 78470), False, 'import webserver\n'), ((79729, 79768), 'webserver.install_http_handler', 'webserver.install_http_handler', (['handler'], {}), '(handler)\n', (79759, 79768), False, 'import webserver\n'), ((80065, 80082), 'osgeo.gdal.ErrorReset', 'gdal.ErrorReset', ([], {}), '()\n', (80080, 80082), False, 'from osgeo import gdal\n'), ((81165, 81204), 'webserver.install_http_handler', 'webserver.install_http_handler', (['handler'], {}), '(handler)\n', (81195, 81204), False, 'import webserver\n'), ((81842, 81855), 'pytest.skip', 'pytest.skip', ([], {}), '()\n', (81853, 81855), False, 'import pytest\n'), ((81866, 81956), 'gdaltest.config_options', 'gdaltest.config_options', (["{'GDAL_HTTP_MAX_RETRY': '2', 'GDAL_HTTP_RETRY_DELAY': '0.01'}"], {}), "({'GDAL_HTTP_MAX_RETRY': '2',\n    'GDAL_HTTP_RETRY_DELAY': '0.01'})\n", (81889, 81956), False, 'import gdaltest\n'), ((82332, 82361), 'webserver.SequentialHandler', 'webserver.SequentialHandler', ([], {}), '()\n', (82359, 82361), False, 'import webserver\n'), ((83379, 83408), 'webserver.SequentialHandler', 'webserver.SequentialHandler', ([], {}), '()\n', (83406, 83408), False, 'import webserver\n'), ((84209, 84222), 'pytest.skip', 'pytest.skip', ([], {}), '()\n', (84220, 84222), False, 'import pytest\n'), ((84538, 84577), 'webserver.install_http_handler', 'webserver.install_http_handler', (['handler'], {}), '(handler)\n', (84568, 84577), False, 'import webserver\n'), ((84593, 84641), 'osgeo.gdal.Mkdir', 'gdal.Mkdir', (['"""/vsis3/s3_bucket_test_mkdir/dir"""', '(0)'], {}), "('/vsis3/s3_bucket_test_mkdir/dir', 0)\n", (84603, 84641), False, 'from osgeo import gdal\n'), ((85024, 85063), 'webserver.install_http_handler', 'webserver.install_http_handler', (['handler'], {}), '(handler)\n', (85054, 85063), False, 'import webserver\n'), ((85079, 85127), 'osgeo.gdal.Mkdir', 'gdal.Mkdir', (['"""/vsis3/s3_bucket_test_mkdir/dir"""', '(0)'], {}), "('/vsis3/s3_bucket_test_mkdir/dir', 0)\n", (85089, 85127), False, 'from osgeo import gdal\n'), ((85263, 85302), 'webserver.install_http_handler', 'webserver.install_http_handler', (['handler'], {}), '(handler)\n', (85293, 85302), False, 'import webserver\n'), ((85318, 85363), 'osgeo.gdal.Rmdir', 'gdal.Rmdir', (['"""/vsis3/s3_bucket_test_mkdir/dir"""'], {}), "('/vsis3/s3_bucket_test_mkdir/dir')\n", (85328, 85363), False, 'from osgeo import gdal\n'), ((85661, 85700), 'webserver.install_http_handler', 'webserver.install_http_handler', (['handler'], {}), '(handler)\n', (85691, 85700), False, 'import webserver\n'), ((85716, 85761), 'osgeo.gdal.Rmdir', 'gdal.Rmdir', (['"""/vsis3/s3_bucket_test_mkdir/dir"""'], {}), "('/vsis3/s3_bucket_test_mkdir/dir')\n", (85726, 85761), False, 'from osgeo import gdal\n'), ((86570, 86609), 'webserver.install_http_handler', 'webserver.install_http_handler', (['handler'], {}), '(handler)\n', (86600, 86609), False, 'import webserver\n'), ((86625, 86679), 'osgeo.gdal.Rmdir', 'gdal.Rmdir', (['"""/vsis3/s3_bucket_test_mkdir/dir_nonempty"""'], {}), "('/vsis3/s3_bucket_test_mkdir/dir_nonempty')\n", (86635, 86679), False, 'from osgeo import gdal\n'), ((87511, 87550), 'webserver.install_http_handler', 'webserver.install_http_handler', (['handler'], {}), '(handler)\n', (87541, 87550), False, 'import webserver\n'), ((88374, 88413), 'webserver.install_http_handler', 'webserver.install_http_handler', (['handler'], {}), '(handler)\n', (88404, 88413), False, 'import webserver\n'), ((89313, 89352), 'webserver.install_http_handler', 'webserver.install_http_handler', (['handler'], {}), '(handler)\n', (89343, 89352), False, 'import webserver\n'), ((90176, 90215), 'webserver.install_http_handler', 'webserver.install_http_handler', (['handler'], {}), '(handler)\n', (90206, 90215), False, 'import webserver\n'), ((90511, 90524), 'pytest.skip', 'pytest.skip', ([], {}), '()\n', (90522, 90524), False, 'import pytest\n'), ((91263, 91302), 'webserver.install_http_handler', 'webserver.install_http_handler', (['handler'], {}), '(handler)\n', (91293, 91302), False, 'import webserver\n'), ((91322, 91355), 'osgeo.gdal.ReadDir', 'gdal.ReadDir', (['"""/vsis3/vsis3_8"""', '(0)'], {}), "('/vsis3/vsis3_8', 0)\n", (91334, 91355), False, 'from osgeo import gdal\n'), ((91450, 91489), 'webserver.install_http_handler', 'webserver.install_http_handler', (['handler'], {}), '(handler)\n', (91480, 91489), False, 'import webserver\n'), ((91620, 91659), 'webserver.install_http_handler', 'webserver.install_http_handler', (['handler'], {}), '(handler)\n', (91650, 91659), False, 'import webserver\n'), ((91936, 91949), 'pytest.skip', 'pytest.skip', ([], {}), '()\n', (91947, 91949), False, 'import pytest\n'), ((92028, 92052), 'gdaltest.error_handler', 'gdaltest.error_handler', ([], {}), '()\n', (92050, 92052), False, 'import gdaltest\n'), ((92072, 92101), 'webserver.SequentialHandler', 'webserver.SequentialHandler', ([], {}), '()\n', (92099, 92101), False, 'import webserver\n'), ((92246, 92270), 'gdaltest.error_handler', 'gdaltest.error_handler', ([], {}), '()\n', (92268, 92270), False, 'import gdaltest\n'), ((92290, 92319), 'webserver.SequentialHandler', 'webserver.SequentialHandler', ([], {}), '()\n', (92317, 92319), False, 'import webserver\n'), ((94001, 94040), 'webserver.install_http_handler', 'webserver.install_http_handler', (['handler'], {}), '(handler)\n', (94031, 94040), False, 'import webserver\n'), ((94057, 94159), 'osgeo.gdal.Sync', 'gdal.Sync', (['"""/vsimem/testsync.txt"""', '"""/vsis3/out"""'], {'options': 'options', 'callback': 'cbk', 'callback_data': 'tab'}), "('/vsimem/testsync.txt', '/vsis3/out', options=options, callback=\n    cbk, callback_data=tab)\n", (94066, 94159), False, 'from osgeo import gdal\n'), ((94324, 94363), 'webserver.install_http_handler', 'webserver.install_http_handler', (['handler'], {}), '(handler)\n', (94354, 94363), False, 'import webserver\n'), ((94380, 94444), 'osgeo.gdal.Sync', 'gdal.Sync', (['"""/vsimem/testsync.txt"""', '"""/vsis3/out"""'], {'options': 'options'}), "('/vsimem/testsync.txt', '/vsis3/out', options=options)\n", (94389, 94444), False, 'from osgeo import gdal\n'), ((94460, 94537), 'osgeo.gdal.Sync', 'gdal.Sync', (['"""/vsimem/testsync.txt"""', '"""/vsis3/out/testsync.txt"""'], {'options': 'options'}), "('/vsimem/testsync.txt', '/vsis3/out/testsync.txt', options=options)\n", (94469, 94537), False, 'from osgeo import gdal\n'), ((94874, 94913), 'webserver.install_http_handler', 'webserver.install_http_handler', (['handler'], {}), '(handler)\n', (94904, 94913), False, 'import webserver\n'), ((94930, 94995), 'osgeo.gdal.Sync', 'gdal.Sync', (['"""/vsis3/out/testsync.txt"""', '"""/vsimem/"""'], {'options': 'options'}), "('/vsis3/out/testsync.txt', '/vsimem/', options=options)\n", (94939, 94995), False, 'from osgeo import gdal\n'), ((95133, 95198), 'osgeo.gdal.Sync', 'gdal.Sync', (['"""/vsis3/out/testsync.txt"""', '"""/vsimem/"""'], {'options': 'options'}), "('/vsis3/out/testsync.txt', '/vsimem/', options=options)\n", (95142, 95198), False, 'from osgeo import gdal\n'), ((95215, 95292), 'osgeo.gdal.Sync', 'gdal.Sync', (['"""/vsis3/out/testsync.txt"""', '"""/vsimem/testsync.txt"""'], {'options': 'options'}), "('/vsis3/out/testsync.txt', '/vsimem/testsync.txt', options=options)\n", (95224, 95292), False, 'from osgeo import gdal\n'), ((95623, 95662), 'webserver.install_http_handler', 'webserver.install_http_handler', (['handler'], {}), '(handler)\n', (95653, 95662), False, 'import webserver\n'), ((95679, 95744), 'osgeo.gdal.Sync', 'gdal.Sync', (['"""/vsis3/out/testsync.txt"""', '"""/vsimem/"""'], {'options': 'options'}), "('/vsis3/out/testsync.txt', '/vsimem/', options=options)\n", (95688, 95744), False, 'from osgeo import gdal\n'), ((96285, 96324), 'webserver.install_http_handler', 'webserver.install_http_handler', (['handler'], {}), '(handler)\n', (96315, 96324), False, 'import webserver\n'), ((96341, 96405), 'osgeo.gdal.Sync', 'gdal.Sync', (['"""/vsimem/testsync.txt"""', '"""/vsis3/out"""'], {'options': 'options'}), "('/vsimem/testsync.txt', '/vsis3/out', options=options)\n", (96350, 96405), False, 'from osgeo import gdal\n'), ((97304, 97343), 'webserver.install_http_handler', 'webserver.install_http_handler', (['handler'], {}), '(handler)\n', (97334, 97343), False, 'import webserver\n'), ((97360, 97419), 'osgeo.gdal.Sync', 'gdal.Sync', (['"""/vsimem/subdir/"""', '"""/vsis3/out"""'], {'options': 'options'}), "('/vsimem/subdir/', '/vsis3/out', options=options)\n", (97369, 97419), False, 'from osgeo import gdal\n'), ((97670, 97683), 'pytest.skip', 'pytest.skip', ([], {}), '()\n', (97681, 97683), False, 'import pytest\n'), ((98303, 98342), 'webserver.install_http_handler', 'webserver.install_http_handler', (['handler'], {}), '(handler)\n', (98333, 98342), False, 'import webserver\n'), ((98359, 98424), 'osgeo.gdal.Sync', 'gdal.Sync', (['"""/vsis3/out/testsync.txt"""', '"""/vsimem/"""'], {'options': 'options'}), "('/vsis3/out/testsync.txt', '/vsimem/', options=options)\n", (98368, 98424), False, 'from osgeo import gdal\n'), ((98802, 98841), 'webserver.install_http_handler', 'webserver.install_http_handler', (['handler'], {}), '(handler)\n', (98832, 98841), False, 'import webserver\n'), ((98858, 98923), 'osgeo.gdal.Sync', 'gdal.Sync', (['"""/vsis3/out/testsync.txt"""', '"""/vsimem/"""'], {'options': 'options'}), "('/vsis3/out/testsync.txt', '/vsimem/', options=options)\n", (98867, 98923), False, 'from osgeo import gdal\n'), ((99346, 99385), 'webserver.install_http_handler', 'webserver.install_http_handler', (['handler'], {}), '(handler)\n', (99376, 99385), False, 'import webserver\n'), ((99402, 99479), 'osgeo.gdal.Sync', 'gdal.Sync', (['"""/vsimem/testsync.txt"""', '"""/vsis3/out/testsync.txt"""'], {'options': 'options'}), "('/vsimem/testsync.txt', '/vsis3/out/testsync.txt', options=options)\n", (99411, 99479), False, 'from osgeo import gdal\n'), ((99857, 99896), 'webserver.install_http_handler', 'webserver.install_http_handler', (['handler'], {}), '(handler)\n', (99887, 99896), False, 'import webserver\n'), ((99913, 99990), 'osgeo.gdal.Sync', 'gdal.Sync', (['"""/vsimem/testsync.txt"""', '"""/vsis3/out/testsync.txt"""'], {'options': 'options'}), "('/vsimem/testsync.txt', '/vsis3/out/testsync.txt', options=options)\n", (99922, 99990), False, 'from osgeo import gdal\n'), ((100266, 100279), 'pytest.skip', 'pytest.skip', ([], {}), '()\n', (100277, 100279), False, 'import pytest\n'), ((100887, 100926), 'webserver.install_http_handler', 'webserver.install_http_handler', (['handler'], {}), '(handler)\n', (100917, 100926), False, 'import webserver\n'), ((100943, 101008), 'osgeo.gdal.Sync', 'gdal.Sync', (['"""/vsis3/out/testsync.txt"""', '"""/vsimem/"""'], {'options': 'options'}), "('/vsis3/out/testsync.txt', '/vsimem/', options=options)\n", (100952, 101008), False, 'from osgeo import gdal\n'), ((101421, 101460), 'webserver.install_http_handler', 'webserver.install_http_handler', (['handler'], {}), '(handler)\n', (101451, 101460), False, 'import webserver\n'), ((101477, 101554), 'osgeo.gdal.Sync', 'gdal.Sync', (['"""/vsimem/testsync.txt"""', '"""/vsis3/out/testsync.txt"""'], {'options': 'options'}), "('/vsimem/testsync.txt', '/vsis3/out/testsync.txt', options=options)\n", (101486, 101554), False, 'from osgeo import gdal\n'), ((101847, 101860), 'pytest.skip', 'pytest.skip', ([], {}), '()\n', (101858, 101860), False, 'import pytest\n'), ((102995, 103034), 'webserver.install_http_handler', 'webserver.install_http_handler', (['handler'], {}), '(handler)\n', (103025, 103034), False, 'import webserver\n'), ((103051, 103101), 'osgeo.gdal.Sync', 'gdal.Sync', (['"""/vsis3/in/testsync.txt"""', '"""/vsis3/out/"""'], {}), "('/vsis3/in/testsync.txt', '/vsis3/out/')\n", (103060, 103101), False, 'from osgeo import gdal\n'), ((103275, 103288), 'pytest.skip', 'pytest.skip', ([], {}), '()\n', (103286, 103288), False, 'import pytest\n'), ((104334, 104373), 'webserver.install_http_handler', 'webserver.install_http_handler', (['handler'], {}), '(handler)\n', (104364, 104373), False, 'import webserver\n'), ((104636, 104649), 'pytest.skip', 'pytest.skip', ([], {}), '()\n', (104647, 104649), False, 'import pytest\n'), ((106937, 106976), 'webserver.install_http_handler', 'webserver.install_http_handler', (['handler'], {}), '(handler)\n', (106967, 106976), False, 'import webserver\n'), ((107284, 107297), 'pytest.skip', 'pytest.skip', ([], {}), '()\n', (107295, 107297), False, 'import pytest\n'), ((107580, 107619), 'webserver.install_http_handler', 'webserver.install_http_handler', (['handler'], {}), '(handler)\n', (107610, 107619), False, 'import webserver\n'), ((107953, 107966), 'pytest.skip', 'pytest.skip', ([], {}), '()\n', (107964, 107966), False, 'import pytest\n'), ((111318, 111375), 'gdaltest.config_option', 'gdaltest.config_option', (['"""VSIS3_SIMULATE_THREADING"""', '"""YES"""'], {}), "('VSIS3_SIMULATE_THREADING', 'YES')\n", (111340, 111375), False, 'import gdaltest\n'), ((111843, 111856), 'pytest.skip', 'pytest.skip', ([], {}), '()\n', (111854, 111856), False, 'import pytest\n'), ((113551, 113650), 'gdaltest.config_options', 'gdaltest.config_options', (["{'VSIS3_SIMULATE_THREADING': 'YES', 'VSIS3_SYNC_MULTITHREADING': 'NO'}"], {}), "({'VSIS3_SIMULATE_THREADING': 'YES',\n    'VSIS3_SYNC_MULTITHREADING': 'NO'})\n", (113574, 113650), False, 'import gdaltest\n'), ((114200, 114213), 'pytest.skip', 'pytest.skip', ([], {}), '()\n', (114211, 114213), False, 'import pytest\n'), ((114394, 114433), 'webserver.install_http_handler', 'webserver.install_http_handler', (['handler'], {}), '(handler)\n', (114424, 114433), False, 'import webserver\n'), ((114448, 114511), 'osgeo.gdal.GetFileMetadata', 'gdal.GetFileMetadata', (['"""/vsis3/test_metadata/foo.txt"""', '"""HEADERS"""'], {}), "('/vsis3/test_metadata/foo.txt', 'HEADERS')\n", (114468, 114511), False, 'from osgeo import gdal\n'), ((114804, 114843), 'webserver.install_http_handler', 'webserver.install_http_handler', (['handler'], {}), '(handler)\n', (114834, 114843), False, 'import webserver\n'), ((114858, 114918), 'osgeo.gdal.GetFileMetadata', 'gdal.GetFileMetadata', (['"""/vsis3/test_metadata/foo.txt"""', '"""TAGS"""'], {}), "('/vsis3/test_metadata/foo.txt', 'TAGS')\n", (114878, 114918), False, 'from osgeo import gdal\n'), ((115488, 115527), 'webserver.install_http_handler', 'webserver.install_http_handler', (['handler'], {}), '(handler)\n', (115518, 115527), False, 'import webserver\n'), ((115544, 115623), 'osgeo.gdal.SetFileMetadata', 'gdal.SetFileMetadata', (['"""/vsis3/test_metadata/foo.txt"""', "{'foo': 'bar'}", '"""HEADERS"""'], {}), "('/vsis3/test_metadata/foo.txt', {'foo': 'bar'}, 'HEADERS')\n", (115564, 115623), False, 'from osgeo import gdal\n'), ((116545, 116584), 'webserver.install_http_handler', 'webserver.install_http_handler', (['handler'], {}), '(handler)\n', (116575, 116584), False, 'import webserver\n'), ((116601, 116677), 'osgeo.gdal.SetFileMetadata', 'gdal.SetFileMetadata', (['"""/vsis3/test_metadata/foo.txt"""', "{'foo': 'bar'}", '"""TAGS"""'], {}), "('/vsis3/test_metadata/foo.txt', {'foo': 'bar'}, 'TAGS')\n", (116621, 116677), False, 'from osgeo import gdal\n'), ((116835, 116874), 'webserver.install_http_handler', 'webserver.install_http_handler', (['handler'], {}), '(handler)\n', (116865, 116874), False, 'import webserver\n'), ((116891, 116955), 'osgeo.gdal.SetFileMetadata', 'gdal.SetFileMetadata', (['"""/vsis3/test_metadata/foo.txt"""', '{}', '"""TAGS"""'], {}), "('/vsis3/test_metadata/foo.txt', {}, 'TAGS')\n", (116911, 116955), False, 'from osgeo import gdal\n'), ((116983, 117007), 'gdaltest.error_handler', 'gdaltest.error_handler', ([], {}), '()\n', (117005, 117007), False, 'import gdaltest\n'), ((117125, 117149), 'gdaltest.error_handler', 'gdaltest.error_handler', ([], {}), '()\n', (117147, 117149), False, 'import gdaltest\n'), ((117488, 117501), 'pytest.skip', 'pytest.skip', ([], {}), '()\n', (117499, 117501), False, 'import pytest\n'), ((117889, 117928), 'webserver.install_http_handler', 'webserver.install_http_handler', (['handler'], {}), '(handler)\n', (117919, 117928), False, 'import webserver\n'), ((118345, 118358), 'pytest.skip', 'pytest.skip', ([], {}), '()\n', (118356, 118358), False, 'import pytest\n'), ((118399, 118423), 'gdaltest.error_handler', 'gdaltest.error_handler', ([], {}), '()\n', (118421, 118423), False, 'import gdaltest\n'), ((118512, 118584), 'gdaltest.config_option', 'gdaltest.config_option', (['"""CPL_VSIL_USE_TEMP_FILE_FOR_RANDOM_WRITE"""', '"""YES"""'], {}), "('CPL_VSIL_USE_TEMP_FILE_FOR_RANDOM_WRITE', 'YES')\n", (118534, 118584), False, 'import gdaltest\n'), ((118598, 118651), 'osgeo.gdal.VSIFOpenL', 'gdal.VSIFOpenL', (['"""/vsis3/random_write/test.bin"""', '"""w+b"""'], {}), "('/vsis3/random_write/test.bin', 'w+b')\n", (118612, 118651), False, 'from osgeo import gdal\n'), ((118676, 118707), 'osgeo.gdal.VSIFWriteL', 'gdal.VSIFWriteL', (['"""foo"""', '(3)', '(1)', 'f'], {}), "('foo', 3, 1, f)\n", (118691, 118707), False, 'from osgeo import gdal\n'), ((118724, 118747), 'osgeo.gdal.VSIFSeekL', 'gdal.VSIFSeekL', (['f', '(0)', '(0)'], {}), '(f, 0, 0)\n', (118738, 118747), False, 'from osgeo import gdal\n'), ((118824, 118840), 'osgeo.gdal.VSIFEofL', 'gdal.VSIFEofL', (['f'], {}), '(f)\n', (118837, 118840), False, 'from osgeo import gdal\n'), ((118857, 118874), 'osgeo.gdal.VSIFTellL', 'gdal.VSIFTellL', (['f'], {}), '(f)\n', (118871, 118874), False, 'from osgeo import gdal\n'), ((119014, 119053), 'webserver.install_http_handler', 'webserver.install_http_handler', (['handler'], {}), '(handler)\n', (119044, 119053), False, 'import webserver\n'), ((119280, 119293), 'pytest.skip', 'pytest.skip', ([], {}), '()\n', (119291, 119293), False, 'import pytest\n'), ((119334, 119406), 'gdaltest.config_option', 'gdaltest.config_option', (['"""CPL_VSIL_USE_TEMP_FILE_FOR_RANDOM_WRITE"""', '"""YES"""'], {}), "('CPL_VSIL_USE_TEMP_FILE_FOR_RANDOM_WRITE', 'YES')\n", (119356, 119406), False, 'import gdaltest\n'), ((119420, 119473), 'osgeo.gdal.VSIFOpenL', 'gdal.VSIFOpenL', (['"""/vsis3/random_write/test.bin"""', '"""w+b"""'], {}), "('/vsis3/random_write/test.bin', 'w+b')\n", (119434, 119473), False, 'from osgeo import gdal\n'), ((119599, 119638), 'webserver.install_http_handler', 'webserver.install_http_handler', (['handler'], {}), '(handler)\n', (119629, 119638), False, 'import webserver\n'), ((119909, 119922), 'pytest.skip', 'pytest.skip', ([], {}), '()\n', (119920, 119922), False, 'import pytest\n'), ((119963, 120035), 'gdaltest.config_option', 'gdaltest.config_option', (['"""CPL_VSIL_USE_TEMP_FILE_FOR_RANDOM_WRITE"""', '"""YES"""'], {}), "('CPL_VSIL_USE_TEMP_FILE_FOR_RANDOM_WRITE', 'YES')\n", (119985, 120035), False, 'import gdaltest\n'), ((120199, 120230), 'osgeo.gdal.VSIFWriteL', 'gdal.VSIFWriteL', (['"""foo"""', '(3)', '(1)', 'f'], {}), "('foo', 3, 1, f)\n", (120214, 120230), False, 'from osgeo import gdal\n'), ((120357, 120396), 'webserver.install_http_handler', 'webserver.install_http_handler', (['handler'], {}), '(handler)\n', (120387, 120396), False, 'import webserver\n'), ((120678, 120691), 'pytest.skip', 'pytest.skip', ([], {}), '()\n', (120689, 120691), False, 'import pytest\n'), ((121036, 121108), 'gdaltest.config_option', 'gdaltest.config_option', (['"""CPL_VSIL_USE_TEMP_FILE_FOR_RANDOM_WRITE"""', '"""YES"""'], {}), "('CPL_VSIL_USE_TEMP_FILE_FOR_RANDOM_WRITE', 'YES')\n", (121058, 121108), False, 'import gdaltest\n'), ((121400, 121439), 'webserver.install_http_handler', 'webserver.install_http_handler', (['handler'], {}), '(handler)\n', (121430, 121439), False, 'import webserver\n'), ((121681, 121694), 'pytest.skip', 'pytest.skip', ([], {}), '()\n', (121692, 121694), False, 'import pytest\n'), ((122352, 122391), 'webserver.install_http_handler', 'webserver.install_http_handler', (['handler'], {}), '(handler)\n', (122382, 122391), False, 'import webserver\n'), ((122545, 122563), 'osgeo.gdal.VSIFCloseL', 'gdal.VSIFCloseL', (['f'], {}), '(f)\n', (122560, 122563), False, 'from osgeo import gdal\n'), ((122904, 122917), 'pytest.skip', 'pytest.skip', ([], {}), '()\n', (122915, 122917), False, 'import pytest\n'), ((123575, 123614), 'webserver.install_http_handler', 'webserver.install_http_handler', (['handler'], {}), '(handler)\n', (123605, 123614), False, 'import webserver\n'), ((123768, 123786), 'osgeo.gdal.VSIFCloseL', 'gdal.VSIFCloseL', (['f'], {}), '(f)\n', (123783, 123786), False, 'from osgeo import gdal\n'), ((124147, 124160), 'pytest.skip', 'pytest.skip', ([], {}), '()\n', (124158, 124160), False, 'import pytest\n'), ((125184, 125223), 'webserver.install_http_handler', 'webserver.install_http_handler', (['handler'], {}), '(handler)\n', (125214, 125223), False, 'import webserver\n'), ((125377, 125395), 'osgeo.gdal.VSIFCloseL', 'gdal.VSIFCloseL', (['f'], {}), '(f)\n', (125392, 125395), False, 'from osgeo import gdal\n'), ((125911, 125924), 'pytest.skip', 'pytest.skip', ([], {}), '()\n', (125922, 125924), False, 'import pytest\n'), ((126888, 126927), 'webserver.install_http_handler', 'webserver.install_http_handler', (['handler'], {}), '(handler)\n', (126918, 126927), False, 'import webserver\n'), ((127211, 127229), 'osgeo.gdal.VSIFCloseL', 'gdal.VSIFCloseL', (['f'], {}), '(f)\n', (127226, 127229), False, 'from osgeo import gdal\n'), ((127561, 127574), 'pytest.skip', 'pytest.skip', ([], {}), '()\n', (127572, 127574), False, 'import pytest\n'), ((128646, 128685), 'webserver.install_http_handler', 'webserver.install_http_handler', (['handler'], {}), '(handler)\n', (128676, 128685), False, 'import webserver\n'), ((128926, 128944), 'osgeo.gdal.VSIFCloseL', 'gdal.VSIFCloseL', (['f'], {}), '(f)\n', (128941, 128944), False, 'from osgeo import gdal\n'), ((129380, 129393), 'pytest.skip', 'pytest.skip', ([], {}), '()\n', (129391, 129393), False, 'import pytest\n'), ((129460, 129473), 'pytest.skip', 'pytest.skip', ([], {}), '()\n', (129471, 129473), False, 'import pytest\n'), ((130807, 130846), 'webserver.install_http_handler', 'webserver.install_http_handler', (['handler'], {}), '(handler)\n', (130837, 130846), False, 'import webserver\n'), ((131000, 131018), 'osgeo.gdal.VSIFCloseL', 'gdal.VSIFCloseL', (['f'], {}), '(f)\n', (131015, 131018), False, 'from osgeo import gdal\n'), ((131279, 131318), 'webserver.install_http_handler', 'webserver.install_http_handler', (['handler'], {}), '(handler)\n', (131309, 131318), False, 'import webserver\n'), ((131467, 131485), 'osgeo.gdal.VSIFCloseL', 'gdal.VSIFCloseL', (['f'], {}), '(f)\n', (131482, 131485), False, 'from osgeo import gdal\n'), ((131875, 131888), 'pytest.skip', 'pytest.skip', ([], {}), '()\n', (131886, 131888), False, 'import pytest\n'), ((131955, 131968), 'pytest.skip', 'pytest.skip', ([], {}), '()\n', (131966, 131968), False, 'import pytest\n'), ((133273, 133312), 'webserver.install_http_handler', 'webserver.install_http_handler', (['handler'], {}), '(handler)\n', (133303, 133312), False, 'import webserver\n'), ((133466, 133484), 'osgeo.gdal.VSIFCloseL', 'gdal.VSIFCloseL', (['f'], {}), '(f)\n', (133481, 133484), False, 'from osgeo import gdal\n'), ((133896, 133909), 'pytest.skip', 'pytest.skip', ([], {}), '()\n', (133907, 133909), False, 'import pytest\n'), ((133976, 133989), 'pytest.skip', 'pytest.skip', ([], {}), '()\n', (133987, 133989), False, 'import pytest\n'), ((135839, 135878), 'webserver.install_http_handler', 'webserver.install_http_handler', (['handler'], {}), '(handler)\n', (135869, 135878), False, 'import webserver\n'), ((136032, 136050), 'osgeo.gdal.VSIFCloseL', 'gdal.VSIFCloseL', (['f'], {}), '(f)\n', (136047, 136050), False, 'from osgeo import gdal\n'), ((136483, 136522), 'webserver.install_http_handler', 'webserver.install_http_handler', (['handler'], {}), '(handler)\n', (136513, 136522), False, 'import webserver\n'), ((136924, 136937), 'pytest.skip', 'pytest.skip', ([], {}), '()\n', (136935, 136937), False, 'import pytest\n'), ((137334, 137363), 'gdaltest.built_against_curl', 'gdaltest.built_against_curl', ([], {}), '()\n', (137361, 137363), False, 'import gdaltest\n'), ((137373, 137386), 'pytest.skip', 'pytest.skip', ([], {}), '()\n', (137384, 137386), False, 'import pytest\n'), ((137983, 138017), 'pytest.skip', 'pytest.skip', (['"""Missing S3_RESOURCE"""'], {}), "('Missing S3_RESOURCE')\n", (137994, 138017), False, 'import pytest\n'), ((138107, 138126), 'osgeo.gdal.VSIStatL', 'gdal.VSIStatL', (['path'], {}), '(path)\n', (138120, 138126), False, 'from osgeo import gdal\n'), ((138263, 138281), 'osgeo.gdal.ReadDir', 'gdal.ReadDir', (['path'], {}), '(path)\n', (138275, 138281), False, 'from osgeo import gdal\n'), ((138692, 138714), 'osgeo.gdal.Mkdir', 'gdal.Mkdir', (['subpath', '(0)'], {}), '(subpath, 0)\n', (138702, 138714), False, 'from osgeo import gdal\n'), ((138810, 138828), 'osgeo.gdal.ReadDir', 'gdal.ReadDir', (['path'], {}), '(path)\n', (138822, 138828), False, 'from osgeo import gdal\n'), ((138949, 138971), 'osgeo.gdal.Mkdir', 'gdal.Mkdir', (['subpath', '(0)'], {}), '(subpath, 0)\n', (138959, 138971), False, 'from osgeo import gdal\n'), ((139068, 139087), 'osgeo.gdal.Rmdir', 'gdal.Rmdir', (['subpath'], {}), '(subpath)\n', (139078, 139087), False, 'from osgeo import gdal\n'), ((139183, 139201), 'osgeo.gdal.ReadDir', 'gdal.ReadDir', (['path'], {}), '(path)\n', (139195, 139201), False, 'from osgeo import gdal\n'), ((139330, 139349), 'osgeo.gdal.Rmdir', 'gdal.Rmdir', (['subpath'], {}), '(subpath)\n', (139340, 139349), False, 'from osgeo import gdal\n'), ((139446, 139468), 'osgeo.gdal.Mkdir', 'gdal.Mkdir', (['subpath', '(0)'], {}), '(subpath, 0)\n', (139456, 139468), False, 'from osgeo import gdal\n'), ((139558, 139601), 'osgeo.gdal.VSIFOpenL', 'gdal.VSIFOpenL', (["(subpath + '/test.txt')", '"""wb"""'], {}), "(subpath + '/test.txt', 'wb')\n", (139572, 139601), False, 'from osgeo import gdal\n'), ((139639, 139672), 'osgeo.gdal.VSIFWriteL', 'gdal.VSIFWriteL', (['"""hello"""', '(1)', '(5)', 'f'], {}), "('hello', 1, 5, f)\n", (139654, 139672), False, 'from osgeo import gdal\n'), ((139681, 139699), 'osgeo.gdal.VSIFCloseL', 'gdal.VSIFCloseL', (['f'], {}), '(f)\n', (139696, 139699), False, 'from osgeo import gdal\n'), ((139715, 139734), 'osgeo.gdal.Rmdir', 'gdal.Rmdir', (['subpath'], {}), '(subpath)\n', (139725, 139734), False, 'from osgeo import gdal\n'), ((139857, 139900), 'osgeo.gdal.VSIFOpenL', 'gdal.VSIFOpenL', (["(subpath + '/test.txt')", '"""rb"""'], {}), "(subpath + '/test.txt', 'rb')\n", (139871, 139900), False, 'from osgeo import gdal\n'), ((140024, 140042), 'osgeo.gdal.VSIFCloseL', 'gdal.VSIFCloseL', (['f'], {}), '(f)\n', (140039, 140042), False, 'from osgeo import gdal\n'), ((140136, 140180), 'osgeo.gdal.VSIFOpenL', 'gdal.VSIFOpenL', (["(subpath + '/test2.txt')", '"""rb"""'], {}), "(subpath + '/test2.txt', 'rb')\n", (140150, 140180), False, 'from osgeo import gdal\n'), ((140304, 140322), 'osgeo.gdal.VSIFCloseL', 'gdal.VSIFCloseL', (['f'], {}), '(f)\n', (140319, 140322), False, 'from osgeo import gdal\n'), ((140338, 140373), 'osgeo.gdal.Unlink', 'gdal.Unlink', (["(subpath + '/test2.txt')"], {}), "(subpath + '/test2.txt')\n", (140349, 140373), False, 'from osgeo import gdal\n'), ((140497, 140516), 'osgeo.gdal.Rmdir', 'gdal.Rmdir', (['subpath'], {}), '(subpath)\n', (140507, 140516), False, 'from osgeo import gdal\n'), ((141211, 141228), 'osgeo.gdal.ErrorReset', 'gdal.ErrorReset', ([], {}), '()\n', (141226, 141228), False, 'from osgeo import gdal\n'), ((141372, 141390), 'osgeo.gdal.VSIFCloseL', 'gdal.VSIFCloseL', (['f'], {}), '(f)\n', (141387, 141390), False, 'from osgeo import gdal\n'), ((142044, 142093), 'osgeo.gdal.SetConfigOption', 'gdal.SetConfigOption', (['var', 'gdaltest.aws_vars[var]'], {}), '(var, gdaltest.aws_vars[var])\n', (142064, 142093), False, 'from osgeo import gdal\n'), ((2259, 2288), 'osgeo.gdal.SetConfigOption', 'gdal.SetConfigOption', (['var', '""""""'], {}), "(var, '')\n", (2279, 2288), False, 'from osgeo import gdal\n'), ((3546, 3678), 'gdaltest.gdalurlopen', 'gdaltest.gdalurlopen', (['"""https://landsat-pds.s3.amazonaws.com/L8/001/002/LC80010022016230LGN00/LC80010022016230LGN00_B1.TIF"""'], {}), "(\n    'https://landsat-pds.s3.amazonaws.com/L8/001/002/LC80010022016230LGN00/LC80010022016230LGN00_B1.TIF'\n    )\n", (3566, 3678), False, 'import gdaltest\n'), ((3690, 3720), 'pytest.skip', 'pytest.skip', (['"""cannot open URL"""'], {}), "('cannot open URL')\n", (3701, 3720), False, 'import pytest\n'), ((4526, 4597), 'osgeo.gdal.VSIStatL', 'gdal.VSIStatL', (['"""/vsimem/test_vsis3_no_sign_request_sync/test_dummy/foo"""'], {}), "('/vsimem/test_vsis3_no_sign_request_sync/test_dummy/foo')\n", (4539, 4597), False, 'from osgeo import gdal\n'), ((4619, 4690), 'osgeo.gdal.VSIStatL', 'gdal.VSIStatL', (['"""/vsimem/test_vsis3_no_sign_request_sync/test_dummy/bar"""'], {}), "('/vsimem/test_vsis3_no_sign_request_sync/test_dummy/bar')\n", (4632, 4690), False, 'from osgeo import gdal\n'), ((5570, 5641), 'osgeo.gdal.VSIStatL', 'gdal.VSIStatL', (['"""/vsimem/test_vsis3_no_sign_request_sync/test_dummy/foo"""'], {}), "('/vsimem/test_vsis3_no_sign_request_sync/test_dummy/foo')\n", (5583, 5641), False, 'from osgeo import gdal\n'), ((5663, 5734), 'osgeo.gdal.VSIStatL', 'gdal.VSIStatL', (['"""/vsimem/test_vsis3_no_sign_request_sync/test_dummy/bar"""'], {}), "('/vsimem/test_vsis3_no_sign_request_sync/test_dummy/bar')\n", (5676, 5734), False, 'from osgeo import gdal\n'), ((6988, 7013), 'osgeo.gdal.VSIGetLastErrorMsg', 'gdal.VSIGetLastErrorMsg', ([], {}), '()\n', (7011, 7013), False, 'from osgeo import gdal\n'), ((7059, 7077), 'osgeo.gdal.VSIFCloseL', 'gdal.VSIFCloseL', (['f'], {}), '(f)\n', (7074, 7077), False, 'from osgeo import gdal\n'), ((7089, 7121), 'osgeo.gdal.GetConfigOption', 'gdal.GetConfigOption', (['"""APPVEYOR"""'], {}), "('APPVEYOR')\n", (7109, 7121), False, 'from osgeo import gdal\n'), ((7174, 7199), 'osgeo.gdal.VSIGetLastErrorMsg', 'gdal.VSIGetLastErrorMsg', ([], {}), '()\n', (7197, 7199), False, 'from osgeo import gdal\n'), ((7342, 7367), 'osgeo.gdal.VSIGetLastErrorMsg', 'gdal.VSIGetLastErrorMsg', ([], {}), '()\n', (7365, 7367), False, 'from osgeo import gdal\n'), ((12863, 12902), 'webserver.install_http_handler', 'webserver.install_http_handler', (['handler'], {}), '(handler)\n', (12893, 12902), False, 'import webserver\n'), ((13091, 13109), 'osgeo.gdal.VSIFCloseL', 'gdal.VSIFCloseL', (['f'], {}), '(f)\n', (13106, 13109), False, 'from osgeo import gdal\n'), ((14806, 14819), 'pytest.fail', 'pytest.fail', ([], {}), '()\n', (14817, 14819), False, 'import pytest\n'), ((18332, 18399), 'pytest.skip', 'pytest.skip', (['"""Skipped on trusty branch, but should be investigated"""'], {}), "('Skipped on trusty branch, but should be investigated')\n", (18343, 18399), False, 'import pytest\n'), ((19793, 19817), 'gdaltest.error_handler', 'gdaltest.error_handler', ([], {}), '()\n', (19815, 19817), False, 'import gdaltest\n'), ((20442, 20466), 'gdaltest.error_handler', 'gdaltest.error_handler', ([], {}), '()\n', (20464, 20466), False, 'import gdaltest\n'), ((21099, 21123), 'gdaltest.error_handler', 'gdaltest.error_handler', ([], {}), '()\n', (21121, 21123), False, 'import gdaltest\n'), ((21836, 21860), 'gdaltest.error_handler', 'gdaltest.error_handler', ([], {}), '()\n', (21858, 21860), False, 'import gdaltest\n'), ((22583, 22607), 'gdaltest.error_handler', 'gdaltest.error_handler', ([], {}), '()\n', (22605, 22607), False, 'import gdaltest\n'), ((23288, 23312), 'gdaltest.error_handler', 'gdaltest.error_handler', ([], {}), '()\n', (23310, 23312), False, 'import gdaltest\n'), ((25283, 25322), 'webserver.install_http_handler', 'webserver.install_http_handler', (['handler'], {}), '(handler)\n', (25313, 25322), False, 'import webserver\n'), ((29203, 29227), 'gdaltest.error_handler', 'gdaltest.error_handler', ([], {}), '()\n', (29225, 29227), False, 'import gdaltest\n'), ((30166, 30205), 'webserver.install_http_handler', 'webserver.install_http_handler', (['handler'], {}), '(handler)\n', (30196, 30205), False, 'import webserver\n'), ((30334, 30352), 'osgeo.gdal.VSIFCloseL', 'gdal.VSIFCloseL', (['f'], {}), '(f)\n', (30349, 30352), False, 'from osgeo import gdal\n'), ((35271, 35338), 'pytest.skip', 'pytest.skip', (['"""Skipped on trusty branch, but should be investigated"""'], {}), "('Skipped on trusty branch, but should be investigated')\n", (35282, 35338), False, 'import pytest\n'), ((35426, 35455), 'webserver.SequentialHandler', 'webserver.SequentialHandler', ([], {}), '()\n', (35453, 35455), False, 'import webserver\n'), ((35632, 35718), 'osgeo.gdal.VSIStatL', 'gdal.VSIStatL', (['"""/vsis3/s3_fake_bucket2/a_dir with_space/resource3 with_space.bin"""'], {}), "(\n    '/vsis3/s3_fake_bucket2/a_dir with_space/resource3 with_space.bin')\n", (35645, 35718), False, 'from osgeo import gdal\n'), ((35740, 35826), 'osgeo.gdal.VSIStatL', 'gdal.VSIStatL', (['"""/vsis3/s3_fake_bucket2/a_dir with_space/resource3 with_space.bin"""'], {}), "(\n    '/vsis3/s3_fake_bucket2/a_dir with_space/resource3 with_space.bin')\n", (35753, 35826), False, 'from osgeo import gdal\n'), ((36360, 36446), 'osgeo.gdal.VSIStatL', 'gdal.VSIStatL', (['"""/vsis3/s3_fake_bucket2/a_dir with_space/resource3 with_space.bin"""'], {}), "(\n    '/vsis3/s3_fake_bucket2/a_dir with_space/resource3 with_space.bin')\n", (36373, 36446), False, 'from osgeo import gdal\n'), ((38886, 38925), 'webserver.install_http_handler', 'webserver.install_http_handler', (['handler'], {}), '(handler)\n', (38916, 38925), False, 'import webserver\n'), ((38954, 38998), 'osgeo.gdal.ReadDir', 'gdal.ReadDir', (['"""/vsis3/s3_fake_bucket2/a_dir"""'], {}), "('/vsis3/s3_fake_bucket2/a_dir')\n", (38966, 38998), False, 'from osgeo import gdal\n'), ((39486, 39557), 'gdaltest.config_option', 'gdaltest.config_option', (['"""CPL_VSIL_CURL_NON_CACHED"""', 'config_option_value'], {}), "('CPL_VSIL_CURL_NON_CACHED', config_option_value)\n", (39508, 39557), False, 'import gdaltest\n'), ((39582, 39611), 'webserver.SequentialHandler', 'webserver.SequentialHandler', ([], {}), '()\n', (39609, 39611), False, 'import webserver\n'), ((40049, 40078), 'webserver.SequentialHandler', 'webserver.SequentialHandler', ([], {}), '()\n', (40076, 40078), False, 'import webserver\n'), ((40361, 40390), 'webserver.SequentialHandler', 'webserver.SequentialHandler', ([], {}), '()\n', (40388, 40390), False, 'import webserver\n'), ((40737, 40766), 'webserver.SequentialHandler', 'webserver.SequentialHandler', ([], {}), '()\n', (40764, 40766), False, 'import webserver\n'), ((41327, 41398), 'gdaltest.config_option', 'gdaltest.config_option', (['"""CPL_VSIL_CURL_NON_CACHED"""', 'config_option_value'], {}), "('CPL_VSIL_CURL_NON_CACHED', config_option_value)\n", (41349, 41398), False, 'import gdaltest\n'), ((41423, 41452), 'webserver.SequentialHandler', 'webserver.SequentialHandler', ([], {}), '()\n', (41450, 41452), False, 'import webserver\n'), ((42807, 42836), 'webserver.SequentialHandler', 'webserver.SequentialHandler', ([], {}), '()\n', (42834, 42836), False, 'import webserver\n'), ((52735, 52764), 'webserver.SequentialHandler', 'webserver.SequentialHandler', ([], {}), '()\n', (52762, 52764), False, 'import webserver\n'), ((52780, 52804), 'gdaltest.error_handler', 'gdaltest.error_handler', ([], {}), '()\n', (52802, 52804), False, 'import gdaltest\n'), ((52822, 52868), 'osgeo.gdal.VSIFOpenL', 'gdal.VSIFOpenL', (['"""/vsis3/s3_fake_bucket3"""', '"""wb"""'], {}), "('/vsis3/s3_fake_bucket3', 'wb')\n", (52836, 52868), False, 'from osgeo import gdal\n'), ((54389, 54413), 'gdaltest.error_handler', 'gdaltest.error_handler', ([], {}), '()\n', (54411, 54413), False, 'import gdaltest\n'), ((54433, 54456), 'osgeo.gdal.VSIFSeekL', 'gdal.VSIFSeekL', (['f', '(1)', '(0)'], {}), '(f, 1, 0)\n', (54447, 54456), False, 'from osgeo import gdal\n'), ((54738, 54762), 'gdaltest.error_handler', 'gdaltest.error_handler', ([], {}), '()\n', (54760, 54762), False, 'import gdaltest\n'), ((54782, 54805), 'osgeo.gdal.VSIFReadL', 'gdal.VSIFReadL', (['(1)', '(1)', 'f'], {}), '(1, 1, f)\n', (54796, 54805), False, 'from osgeo import gdal\n'), ((55185, 55209), 'gdaltest.error_handler', 'gdaltest.error_handler', ([], {}), '()\n', (55207, 55209), False, 'import gdaltest\n'), ((55223, 55241), 'osgeo.gdal.VSIFCloseL', 'gdal.VSIFCloseL', (['f'], {}), '(f)\n', (55238, 55241), False, 'from osgeo import gdal\n'), ((55498, 55561), 'osgeo.gdal.VSIFOpenL', 'gdal.VSIFOpenL', (['"""/vsis3/s3_fake_bucket3/another_file.bin"""', '"""wb"""'], {}), "('/vsis3/s3_fake_bucket3/another_file.bin', 'wb')\n", (55512, 55561), False, 'from osgeo import gdal\n'), ((56997, 57036), 'webserver.install_http_handler', 'webserver.install_http_handler', (['handler'], {}), '(handler)\n', (57027, 57036), False, 'import webserver\n'), ((57050, 57068), 'osgeo.gdal.VSIFCloseL', 'gdal.VSIFCloseL', (['f'], {}), '(f)\n', (57065, 57068), False, 'from osgeo import gdal\n'), ((57084, 57106), 'osgeo.gdal.GetLastErrorMsg', 'gdal.GetLastErrorMsg', ([], {}), '()\n', (57104, 57106), False, 'from osgeo import gdal\n'), ((58446, 58475), 'webserver.SequentialHandler', 'webserver.SequentialHandler', ([], {}), '()\n', (58473, 58475), False, 'import webserver\n'), ((58590, 58624), 'osgeo.gdal.VSIFWriteL', 'gdal.VSIFWriteL', (['"""foobar"""', '(1)', '(6)', 'f'], {}), "('foobar', 1, 6, f)\n", (58605, 58624), False, 'from osgeo import gdal\n'), ((61201, 61266), 'osgeo.gdal.VSIFOpenL', 'gdal.VSIFOpenL', (['"""/vsis3/s3_fake_bucket3/put_with_retry.bin"""', '"""wb"""'], {}), "('/vsis3/s3_fake_bucket3/put_with_retry.bin', 'wb')\n", (61215, 61266), False, 'from osgeo import gdal\n'), ((62466, 62490), 'gdaltest.error_handler', 'gdaltest.error_handler', ([], {}), '()\n', (62488, 62490), False, 'import gdaltest\n'), ((62842, 62871), 'webserver.SequentialHandler', 'webserver.SequentialHandler', ([], {}), '()\n', (62869, 62871), False, 'import webserver\n'), ((62887, 62911), 'gdaltest.error_handler', 'gdaltest.error_handler', ([], {}), '()\n', (62909, 62911), False, 'import gdaltest\n'), ((62931, 62956), 'osgeo.gdal.Unlink', 'gdal.Unlink', (['"""/vsis3/foo"""'], {}), "('/vsis3/foo')\n", (62942, 62956), False, 'from osgeo import gdal\n'), ((63980, 64032), 'osgeo.gdal.VSIStatL', 'gdal.VSIStatL', (['"""/vsis3/s3_delete_bucket/delete_file"""'], {}), "('/vsis3/s3_delete_bucket/delete_file')\n", (63993, 64032), False, 'from osgeo import gdal\n'), ((64286, 64310), 'gdaltest.error_handler', 'gdaltest.error_handler', ([], {}), '()\n', (64308, 64310), False, 'import gdaltest\n'), ((64330, 64386), 'osgeo.gdal.Unlink', 'gdal.Unlink', (['"""/vsis3/s3_delete_bucket/delete_file_error"""'], {}), "('/vsis3/s3_delete_bucket/delete_file_error')\n", (64341, 64386), False, 'from osgeo import gdal\n'), ((66650, 66714), 'sys.stderr.write', 'sys.stderr.write', (["('Did not get expected content: %s\\n' % content)"], {}), "('Did not get expected content: %s\\n' % content)\n", (66666, 66714), False, 'import sys\n'), ((67615, 67654), 'webserver.install_http_handler', 'webserver.install_http_handler', (['handler'], {}), '(handler)\n', (67645, 67654), False, 'import webserver\n'), ((67674, 67781), 'osgeo.gdal.UnlinkBatch', 'gdal.UnlinkBatch', (["['/vsis3/unlink_batch/foo', '/vsis3/unlink_batch/bar/baz',\n    '/vsis3/unlink_batch/baw']"], {}), "(['/vsis3/unlink_batch/foo', '/vsis3/unlink_batch/bar/baz',\n    '/vsis3/unlink_batch/baw'])\n", (67690, 67781), False, 'from osgeo import gdal\n'), ((69757, 69821), 'sys.stderr.write', 'sys.stderr.write', (["('Did not get expected content: %s\\n' % content)"], {}), "('Did not get expected content: %s\\n' % content)\n", (69773, 69821), False, 'import sys\n'), ((70808, 70872), 'sys.stderr.write', 'sys.stderr.write', (["('Did not get expected content: %s\\n' % content)"], {}), "('Did not get expected content: %s\\n' % content)\n", (70824, 70872), False, 'import sys\n'), ((71566, 71605), 'webserver.install_http_handler', 'webserver.install_http_handler', (['handler'], {}), '(handler)\n', (71596, 71605), False, 'import webserver\n'), ((72060, 72121), 'osgeo.gdal.VSIFOpenL', 'gdal.VSIFOpenL', (['"""/vsis3/s3_fake_bucket4/large_file.bin"""', '"""wb"""'], {}), "('/vsis3/s3_fake_bucket4/large_file.bin', 'wb')\n", (72074, 72121), False, 'from osgeo import gdal\n'), ((75644, 75708), 'sys.stderr.write', 'sys.stderr.write', (["('Did not get expected content: %s\\n' % content)"], {}), "('Did not get expected content: %s\\n' % content)\n", (75660, 75708), False, 'import sys\n'), ((77362, 77379), 'osgeo.gdal.ErrorReset', 'gdal.ErrorReset', ([], {}), '()\n', (77377, 77379), False, 'from osgeo import gdal\n'), ((77392, 77410), 'osgeo.gdal.VSIFCloseL', 'gdal.VSIFCloseL', (['f'], {}), '(f)\n', (77407, 77410), False, 'from osgeo import gdal\n'), ((78970, 78987), 'osgeo.gdal.ErrorReset', 'gdal.ErrorReset', ([], {}), '()\n', (78985, 78987), False, 'from osgeo import gdal\n'), ((79000, 79018), 'osgeo.gdal.VSIFCloseL', 'gdal.VSIFCloseL', (['f'], {}), '(f)\n', (79015, 79018), False, 'from osgeo import gdal\n'), ((79783, 79830), 'gdaltest.config_option', 'gdaltest.config_option', (['"""VSIS3_CHUNK_SIZE"""', '"""1"""'], {}), "('VSIS3_CHUNK_SIZE', '1')\n", (79805, 79830), False, 'import gdaltest\n'), ((79856, 79886), 'osgeo.gdal.VSIFOpenL', 'gdal.VSIFOpenL', (['filename', '"""wb"""'], {}), "(filename, 'wb')\n", (79870, 79886), False, 'from osgeo import gdal\n'), ((79939, 79963), 'gdaltest.error_handler', 'gdaltest.error_handler', ([], {}), '()\n', (79961, 79963), False, 'import gdaltest\n'), ((79983, 80022), 'osgeo.gdal.VSIFWriteL', 'gdal.VSIFWriteL', (['big_buffer', '(1)', 'size', 'f'], {}), '(big_buffer, 1, size, f)\n', (79998, 80022), False, 'from osgeo import gdal\n'), ((80096, 80120), 'gdaltest.error_handler', 'gdaltest.error_handler', ([], {}), '()\n', (80118, 80120), False, 'import gdaltest\n'), ((80134, 80152), 'osgeo.gdal.VSIFCloseL', 'gdal.VSIFCloseL', (['f'], {}), '(f)\n', (80149, 80152), False, 'from osgeo import gdal\n'), ((80168, 80190), 'osgeo.gdal.GetLastErrorMsg', 'gdal.GetLastErrorMsg', ([], {}), '()\n', (80188, 80190), False, 'from osgeo import gdal\n'), ((81219, 81266), 'gdaltest.config_option', 'gdaltest.config_option', (['"""VSIS3_CHUNK_SIZE"""', '"""1"""'], {}), "('VSIS3_CHUNK_SIZE', '1')\n", (81241, 81266), False, 'import gdaltest\n'), ((81292, 81322), 'osgeo.gdal.VSIFOpenL', 'gdal.VSIFOpenL', (['filename', '"""wb"""'], {}), "(filename, 'wb')\n", (81306, 81322), False, 'from osgeo import gdal\n'), ((81384, 81423), 'osgeo.gdal.VSIFWriteL', 'gdal.VSIFWriteL', (['big_buffer', '(1)', 'size', 'f'], {}), '(big_buffer, 1, size, f)\n', (81399, 81423), False, 'from osgeo import gdal\n'), ((81477, 81494), 'osgeo.gdal.ErrorReset', 'gdal.ErrorReset', ([], {}), '()\n', (81492, 81494), False, 'from osgeo import gdal\n'), ((82002, 82049), 'gdaltest.config_option', 'gdaltest.config_option', (['"""VSIS3_CHUNK_SIZE"""', '"""1"""'], {}), "('VSIS3_CHUNK_SIZE', '1')\n", (82024, 82049), False, 'import gdaltest\n'), ((83188, 83212), 'gdaltest.error_handler', 'gdaltest.error_handler', ([], {}), '()\n', (83210, 83212), False, 'import gdaltest\n'), ((83915, 83939), 'gdaltest.error_handler', 'gdaltest.error_handler', ([], {}), '()\n', (83937, 83939), False, 'import gdaltest\n'), ((84687, 84735), 'osgeo.gdal.VSIStatL', 'gdal.VSIStatL', (['"""/vsis3/s3_bucket_test_mkdir/dir"""'], {}), "('/vsis3/s3_bucket_test_mkdir/dir')\n", (84700, 84735), False, 'from osgeo import gdal\n'), ((88430, 88488), 'osgeo.gdal.ReadDir', 'gdal.ReadDir', (['"""/vsis3/s3_bucket_test_readdir/test_dirread"""'], {}), "('/vsis3/s3_bucket_test_readdir/test_dirread')\n", (88442, 88488), False, 'from osgeo import gdal\n'), ((90232, 90291), 'osgeo.gdal.ReadDir', 'gdal.ReadDir', (['"""/vsis3/s3_bucket_test_readdir2/test_dirread"""'], {}), "('/vsis3/s3_bucket_test_readdir2/test_dirread')\n", (90244, 90291), False, 'from osgeo import gdal\n'), ((92115, 92154), 'webserver.install_http_handler', 'webserver.install_http_handler', (['handler'], {}), '(handler)\n', (92145, 92154), False, 'import webserver\n'), ((92518, 92557), 'webserver.install_http_handler', 'webserver.install_http_handler', (['handler'], {}), '(handler)\n', (92548, 92557), False, 'import webserver\n'), ((93354, 93418), 'sys.stderr.write', 'sys.stderr.write', (["('Did not get expected content: %s\\n' % content)"], {}), "('Did not get expected content: %s\\n' % content)\n", (93370, 93418), False, 'import sys\n'), ((95086, 95115), 'webserver.SequentialHandler', 'webserver.SequentialHandler', ([], {}), '()\n', (95113, 95115), False, 'import webserver\n'), ((95811, 95834), 'osgeo.gdal.VSIFReadL', 'gdal.VSIFReadL', (['(1)', '(3)', 'f'], {}), '(1, 3, f)\n', (95825, 95834), False, 'from osgeo import gdal\n'), ((104390, 104453), 'osgeo.gdal.Rename', 'gdal.Rename', (['"""/vsis3/test/source.txt"""', '"""/vsis3/test/target.txt"""'], {}), "('/vsis3/test/source.txt', '/vsis3/test/target.txt')\n", (104401, 104453), False, 'from osgeo import gdal\n'), ((106993, 107056), 'osgeo.gdal.Rename', 'gdal.Rename', (['"""/vsis3/test/source_dir"""', '"""/vsis3/test/target_dir"""'], {}), "('/vsis3/test/source_dir', '/vsis3/test/target_dir')\n", (107004, 107056), False, 'from osgeo import gdal\n'), ((107636, 107699), 'osgeo.gdal.Rename', 'gdal.Rename', (['"""/vsis3/test/source.txt"""', '"""/vsis3/test_target_dir"""'], {}), "('/vsis3/test/source.txt', '/vsis3/test_target_dir')\n", (107647, 107699), False, 'from osgeo import gdal\n'), ((110896, 110960), 'sys.stderr.write', 'sys.stderr.write', (["('Did not get expected content: %s\\n' % content)"], {}), "('Did not get expected content: %s\\n' % content)\n", (110912, 110960), False, 'import sys\n'), ((111390, 111429), 'webserver.install_http_handler', 'webserver.install_http_handler', (['handler'], {}), '(handler)\n', (111420, 111429), False, 'import webserver\n'), ((111450, 111577), 'osgeo.gdal.Sync', 'gdal.Sync', (['"""/vsimem/test"""', '"""/vsis3/test_bucket"""'], {'options': "['NUM_THREADS=1', 'CHUNK_SIZE=3']", 'callback': 'cbk', 'callback_data': 'tab'}), "('/vsimem/test', '/vsis3/test_bucket', options=['NUM_THREADS=1',\n    'CHUNK_SIZE=3'], callback=cbk, callback_data=tab)\n", (111459, 111577), False, 'from osgeo import gdal\n'), ((113695, 113734), 'webserver.install_http_handler', 'webserver.install_http_handler', (['handler'], {}), '(handler)\n', (113725, 113734), False, 'import webserver\n'), ((116131, 116195), 'sys.stderr.write', 'sys.stderr.write', (["('Did not get expected content: %s\\n' % content)"], {}), "('Did not get expected content: %s\\n' % content)\n", (116147, 116195), False, 'import sys\n'), ((117024, 117091), 'osgeo.gdal.GetFileMetadata', 'gdal.GetFileMetadata', (['"""/vsis3/test_metadata/foo.txt"""', '"""UNSUPPORTED"""'], {}), "('/vsis3/test_metadata/foo.txt', 'UNSUPPORTED')\n", (117044, 117091), False, 'from osgeo import gdal\n'), ((117170, 117241), 'osgeo.gdal.SetFileMetadata', 'gdal.SetFileMetadata', (['"""/vsis3/test_metadata/foo.txt"""', '{}', '"""UNSUPPORTED"""'], {}), "('/vsis3/test_metadata/foo.txt', {}, 'UNSUPPORTED')\n", (117190, 117241), False, 'from osgeo import gdal\n'), ((117945, 118003), 'osgeo.gdal.VSIFOpenL', 'gdal.VSIFOpenL', (['"""/vsis3/no_useless_requests/foo.txt"""', '"""rb"""'], {}), "('/vsis3/no_useless_requests/foo.txt', 'rb')\n", (117959, 118003), False, 'from osgeo import gdal\n'), ((118027, 118085), 'osgeo.gdal.VSIFOpenL', 'gdal.VSIFOpenL', (['"""/vsis3/no_useless_requests/bar.txt"""', '"""rb"""'], {}), "('/vsis3/no_useless_requests/bar.txt', 'rb')\n", (118041, 118085), False, 'from osgeo import gdal\n'), ((118109, 118160), 'osgeo.gdal.VSIStatL', 'gdal.VSIStatL', (['"""/vsis3/no_useless_requests/baz.txt"""'], {}), "('/vsis3/no_useless_requests/baz.txt')\n", (118122, 118160), False, 'from osgeo import gdal\n'), ((118440, 118493), 'osgeo.gdal.VSIFOpenL', 'gdal.VSIFOpenL', (['"""/vsis3/random_write/test.bin"""', '"""w+b"""'], {}), "('/vsis3/random_write/test.bin', 'w+b')\n", (118454, 118493), False, 'from osgeo import gdal\n'), ((119070, 119088), 'osgeo.gdal.VSIFCloseL', 'gdal.VSIFCloseL', (['f'], {}), '(f)\n', (119085, 119088), False, 'from osgeo import gdal\n'), ((119653, 119677), 'gdaltest.error_handler', 'gdaltest.error_handler', ([], {}), '()\n', (119675, 119677), False, 'import gdaltest\n'), ((120050, 120103), 'gdaltest.config_option', 'gdaltest.config_option', (['"""VSIS3_CHUNK_SIZE_BYTES"""', '"""1"""'], {}), "('VSIS3_CHUNK_SIZE_BYTES', '1')\n", (120072, 120103), False, 'import gdaltest\n'), ((120121, 120174), 'osgeo.gdal.VSIFOpenL', 'gdal.VSIFOpenL', (['"""/vsis3/random_write/test.bin"""', '"""w+b"""'], {}), "('/vsis3/random_write/test.bin', 'w+b')\n", (120135, 120174), False, 'from osgeo import gdal\n'), ((120411, 120435), 'gdaltest.error_handler', 'gdaltest.error_handler', ([], {}), '()\n', (120433, 120435), False, 'import gdaltest\n'), ((121123, 121162), 'webserver.install_http_handler', 'webserver.install_http_handler', (['handler'], {}), '(handler)\n', (121153, 121162), False, 'import webserver\n'), ((128700, 128724), 'gdaltest.error_handler', 'gdaltest.error_handler', ([], {}), '()\n', (128722, 128724), False, 'import gdaltest\n'), ((128834, 128856), 'osgeo.gdal.GetLastErrorMsg', 'gdal.GetLastErrorMsg', ([], {}), '()\n', (128854, 128856), False, 'from osgeo import gdal\n'), ((136537, 136561), 'gdaltest.error_handler', 'gdaltest.error_handler', ([], {}), '()\n', (136559, 136561), False, 'import gdaltest\n'), ((137492, 137531), 'osgeo.gdal.GetConfigOption', 'gdal.GetConfigOption', (['"""USERPROFILE"""', '""""""'], {}), "('USERPROFILE', '')\n", (137512, 137531), False, 'from osgeo import gdal\n'), ((137717, 137762), 'osgeo.gdal.GetConfigOption', 'gdal.GetConfigOption', (['"""AWS_SECRET_ACCESS_KEY"""'], {}), "('AWS_SECRET_ACCESS_KEY')\n", (137737, 137762), False, 'from osgeo import gdal\n'), ((137784, 137828), 'pytest.skip', 'pytest.skip', (['"""Missing AWS_SECRET_ACCESS_KEY"""'], {}), "('Missing AWS_SECRET_ACCESS_KEY')\n", (137795, 137828), False, 'import pytest\n'), ((138166, 138192), 'stat.S_ISDIR', 'stat.S_ISDIR', (['statres.mode'], {}), '(statres.mode)\n', (138178, 138192), False, 'import stat\n'), ((140059, 140117), 'osgeo.gdal.Rename', 'gdal.Rename', (["(subpath + '/test.txt')", "(subpath + '/test2.txt')"], {}), "(subpath + '/test.txt', subpath + '/test2.txt')\n", (140070, 140117), False, 'from osgeo import gdal\n'), ((141302, 141326), 'gdaltest.error_handler', 'gdaltest.error_handler', ([], {}), '()\n', (141324, 141326), False, 'import gdaltest\n'), ((141340, 141363), 'osgeo.gdal.VSIFReadL', 'gdal.VSIFReadL', (['(1)', '(1)', 'f'], {}), '(1, 1, f)\n', (141354, 141363), False, 'from osgeo import gdal\n'), ((141406, 141431), 'osgeo.gdal.VSIGetLastErrorMsg', 'gdal.VSIGetLastErrorMsg', ([], {}), '()\n', (141429, 141431), False, 'from osgeo import gdal\n'), ((10779, 10802), 'osgeo.gdal.VSIFReadL', 'gdal.VSIFReadL', (['(1)', '(4)', 'f'], {}), '(1, 4, f)\n', (10793, 10802), False, 'from osgeo import gdal\n'), ((11186, 11209), 'osgeo.gdal.VSIFReadL', 'gdal.VSIFReadL', (['(1)', '(4)', 'f'], {}), '(1, 4, f)\n', (11200, 11209), False, 'from osgeo import gdal\n'), ((18181, 18204), 'osgeo.gdal.VSIFReadL', 'gdal.VSIFReadL', (['(1)', '(4)', 'f'], {}), '(1, 4, f)\n', (18195, 18204), False, 'from osgeo import gdal\n'), ((18691, 18714), 'osgeo.gdal.VSIFReadL', 'gdal.VSIFReadL', (['(1)', '(4)', 'f'], {}), '(1, 4, f)\n', (18705, 18714), False, 'from osgeo import gdal\n'), ((25341, 25365), 'gdaltest.error_handler', 'gdaltest.error_handler', ([], {}), '()\n', (25363, 25365), False, 'import gdaltest\n'), ((25571, 25589), 'osgeo.gdal.VSIFCloseL', 'gdal.VSIFCloseL', (['f'], {}), '(f)\n', (25586, 25589), False, 'from osgeo import gdal\n'), ((27943, 27966), 'osgeo.gdal.VSIFReadL', 'gdal.VSIFReadL', (['(1)', '(3)', 'f'], {}), '(1, 3, f)\n', (27957, 27966), False, 'from osgeo import gdal\n'), ((28564, 28587), 'osgeo.gdal.VSIFReadL', 'gdal.VSIFReadL', (['(1)', '(3)', 'f'], {}), '(1, 3, f)\n', (28578, 28587), False, 'from osgeo import gdal\n'), ((39704, 39743), 'webserver.install_http_handler', 'webserver.install_http_handler', (['handler'], {}), '(handler)\n', (39734, 39743), False, 'import webserver\n'), ((39949, 39967), 'osgeo.gdal.VSIFCloseL', 'gdal.VSIFCloseL', (['f'], {}), '(f)\n', (39964, 39967), False, 'from osgeo import gdal\n'), ((40172, 40211), 'webserver.install_http_handler', 'webserver.install_http_handler', (['handler'], {}), '(handler)\n', (40202, 40211), False, 'import webserver\n'), ((40483, 40522), 'webserver.install_http_handler', 'webserver.install_http_handler', (['handler'], {}), '(handler)\n', (40513, 40522), False, 'import webserver\n'), ((40860, 40899), 'webserver.install_http_handler', 'webserver.install_http_handler', (['handler'], {}), '(handler)\n', (40890, 40899), False, 'import webserver\n'), ((41105, 41123), 'osgeo.gdal.VSIFCloseL', 'gdal.VSIFCloseL', (['f'], {}), '(f)\n', (41120, 41123), False, 'from osgeo import gdal\n'), ((42462, 42501), 'webserver.install_http_handler', 'webserver.install_http_handler', (['handler'], {}), '(handler)\n', (42492, 42501), False, 'import webserver\n'), ((42707, 42725), 'osgeo.gdal.VSIFCloseL', 'gdal.VSIFCloseL', (['f'], {}), '(f)\n', (42722, 42725), False, 'from osgeo import gdal\n'), ((42854, 42893), 'webserver.install_http_handler', 'webserver.install_http_handler', (['handler'], {}), '(handler)\n', (42884, 42893), False, 'import webserver\n'), ((43099, 43117), 'osgeo.gdal.VSIFCloseL', 'gdal.VSIFCloseL', (['f'], {}), '(f)\n', (43114, 43117), False, 'from osgeo import gdal\n'), ((53095, 53149), 'osgeo.gdal.VSIStatL', 'gdal.VSIStatL', (['"""/vsis3/s3_fake_bucket3/empty_file.bin"""'], {}), "('/vsis3/s3_fake_bucket3/empty_file.bin')\n", (53108, 53149), False, 'from osgeo import gdal\n'), ((54094, 54148), 'osgeo.gdal.VSIStatL', 'gdal.VSIStatL', (['"""/vsis3/s3_fake_bucket3/empty_file.bin"""'], {}), "('/vsis3/s3_fake_bucket3/empty_file.bin')\n", (54107, 54148), False, 'from osgeo import gdal\n'), ((55450, 55479), 'webserver.SequentialHandler', 'webserver.SequentialHandler', ([], {}), '()\n', (55477, 55479), False, 'import webserver\n'), ((55678, 55701), 'osgeo.gdal.VSIFSeekL', 'gdal.VSIFSeekL', (['f', '(0)', '(1)'], {}), '(f, 0, 1)\n', (55692, 55701), False, 'from osgeo import gdal\n'), ((55726, 55749), 'osgeo.gdal.VSIFSeekL', 'gdal.VSIFSeekL', (['f', '(0)', '(2)'], {}), '(f, 0, 2)\n', (55740, 55749), False, 'from osgeo import gdal\n'), ((55774, 55805), 'osgeo.gdal.VSIFWriteL', 'gdal.VSIFWriteL', (['"""foo"""', '(1)', '(3)', 'f'], {}), "('foo', 1, 3, f)\n", (55789, 55805), False, 'from osgeo import gdal\n'), ((55894, 55925), 'osgeo.gdal.VSIFWriteL', 'gdal.VSIFWriteL', (['"""bar"""', '(1)', '(3)', 'f'], {}), "('bar', 1, 3, f)\n", (55909, 55925), False, 'from osgeo import gdal\n'), ((56517, 56581), 'sys.stderr.write', 'sys.stderr.write', (["('Did not get expected content: %s\\n' % content)"], {}), "('Did not get expected content: %s\\n' % content)\n", (56533, 56581), False, 'import sys\n'), ((61153, 61182), 'webserver.SequentialHandler', 'webserver.SequentialHandler', ([], {}), '()\n', (61180, 61182), False, 'import webserver\n'), ((61319, 61350), 'osgeo.gdal.VSIFWriteL', 'gdal.VSIFWriteL', (['"""foo"""', '(1)', '(3)', 'f'], {}), "('foo', 1, 3, f)\n", (61334, 61350), False, 'from osgeo import gdal\n'), ((61939, 62003), 'sys.stderr.write', 'sys.stderr.write', (["('Did not get expected content: %s\\n' % content)"], {}), "('Did not get expected content: %s\\n' % content)\n", (61955, 62003), False, 'import sys\n'), ((62509, 62548), 'webserver.install_http_handler', 'webserver.install_http_handler', (['handler'], {}), '(handler)\n', (62539, 62548), False, 'import webserver\n'), ((62566, 62584), 'osgeo.gdal.VSIFCloseL', 'gdal.VSIFCloseL', (['f'], {}), '(f)\n', (62581, 62584), False, 'from osgeo import gdal\n'), ((63180, 63232), 'osgeo.gdal.VSIStatL', 'gdal.VSIStatL', (['"""/vsis3/s3_delete_bucket/delete_file"""'], {}), "('/vsis3/s3_delete_bucket/delete_file')\n", (63193, 63232), False, 'from osgeo import gdal\n'), ((63353, 63405), 'osgeo.gdal.VSIStatL', 'gdal.VSIStatL', (['"""/vsis3/s3_delete_bucket/delete_file"""'], {}), "('/vsis3/s3_delete_bucket/delete_file')\n", (63366, 63405), False, 'from osgeo import gdal\n'), ((71626, 71684), 'osgeo.gdal.RmdirRecursive', 'gdal.RmdirRecursive', (['"""/vsis3/test_rmdir_recursive/somedir"""'], {}), "('/vsis3/test_rmdir_recursive/somedir')\n", (71645, 71684), False, 'from osgeo import gdal\n'), ((72012, 72041), 'webserver.SequentialHandler', 'webserver.SequentialHandler', ([], {}), '()\n', (72039, 72041), False, 'import webserver\n'), ((77076, 77123), 'gdaltest.config_option', 'gdaltest.config_option', (['"""VSIS3_CHUNK_SIZE"""', '"""1"""'], {}), "('VSIS3_CHUNK_SIZE', '1')\n", (77098, 77123), False, 'import gdaltest\n'), ((77153, 77183), 'osgeo.gdal.VSIFOpenL', 'gdal.VSIFOpenL', (['filename', '"""wb"""'], {}), "(filename, 'wb')\n", (77167, 77183), False, 'from osgeo import gdal\n'), ((77234, 77258), 'gdaltest.error_handler', 'gdaltest.error_handler', ([], {}), '()\n', (77256, 77258), False, 'import gdaltest\n'), ((77282, 77321), 'osgeo.gdal.VSIFWriteL', 'gdal.VSIFWriteL', (['big_buffer', '(1)', 'size', 'f'], {}), '(big_buffer, 1, size, f)\n', (77297, 77321), False, 'from osgeo import gdal\n'), ((77430, 77452), 'osgeo.gdal.GetLastErrorMsg', 'gdal.GetLastErrorMsg', ([], {}), '()\n', (77450, 77452), False, 'from osgeo import gdal\n'), ((78664, 78711), 'gdaltest.config_option', 'gdaltest.config_option', (['"""VSIS3_CHUNK_SIZE"""', '"""1"""'], {}), "('VSIS3_CHUNK_SIZE', '1')\n", (78686, 78711), False, 'import gdaltest\n'), ((78741, 78771), 'osgeo.gdal.VSIFOpenL', 'gdal.VSIFOpenL', (['filename', '"""wb"""'], {}), "(filename, 'wb')\n", (78755, 78771), False, 'from osgeo import gdal\n'), ((78832, 78856), 'gdaltest.error_handler', 'gdaltest.error_handler', ([], {}), '()\n', (78854, 78856), False, 'import gdaltest\n'), ((78880, 78919), 'osgeo.gdal.VSIFWriteL', 'gdal.VSIFWriteL', (['big_buffer', '(1)', 'size', 'f'], {}), '(big_buffer, 1, size, f)\n', (78895, 78919), False, 'from osgeo import gdal\n'), ((79038, 79060), 'osgeo.gdal.GetLastErrorMsg', 'gdal.GetLastErrorMsg', ([], {}), '()\n', (79058, 79060), False, 'from osgeo import gdal\n'), ((81512, 81536), 'gdaltest.error_handler', 'gdaltest.error_handler', ([], {}), '()\n', (81534, 81536), False, 'import gdaltest\n'), ((81554, 81572), 'osgeo.gdal.VSIFCloseL', 'gdal.VSIFCloseL', (['f'], {}), '(f)\n', (81569, 81572), False, 'from osgeo import gdal\n'), ((81592, 81614), 'osgeo.gdal.GetLastErrorMsg', 'gdal.GetLastErrorMsg', ([], {}), '()\n', (81612, 81614), False, 'from osgeo import gdal\n'), ((82159, 82220), 'osgeo.gdal.VSIFOpenL', 'gdal.VSIFOpenL', (['"""/vsis3/s3_fake_bucket4/large_file.bin"""', '"""wb"""'], {}), "('/vsis3/s3_fake_bucket4/large_file.bin', 'wb')\n", (82173, 82220), False, 'from osgeo import gdal\n'), ((83231, 83270), 'webserver.install_http_handler', 'webserver.install_http_handler', (['handler'], {}), '(handler)\n', (83261, 83270), False, 'import webserver\n'), ((83294, 83333), 'osgeo.gdal.VSIFWriteL', 'gdal.VSIFWriteL', (['big_buffer', '(1)', 'size', 'f'], {}), '(big_buffer, 1, size, f)\n', (83309, 83333), False, 'from osgeo import gdal\n'), ((83958, 83997), 'webserver.install_http_handler', 'webserver.install_http_handler', (['handler'], {}), '(handler)\n', (83988, 83997), False, 'import webserver\n'), ((84015, 84033), 'osgeo.gdal.VSIFCloseL', 'gdal.VSIFCloseL', (['f'], {}), '(f)\n', (84030, 84033), False, 'from osgeo import gdal\n'), ((87580, 87641), 'osgeo.gdal.VSIStatL', 'gdal.VSIStatL', (['"""/vsis3/s3_bucket_test_dir_stat/test_dir_stat"""'], {}), "('/vsis3/s3_bucket_test_dir_stat/test_dir_stat')\n", (87593, 87641), False, 'from osgeo import gdal\n'), ((89382, 89446), 'osgeo.gdal.VSIStatL', 'gdal.VSIStatL', (['"""/vsis3/s3_bucket_test_dir_stat_2/test_dir_stat/"""'], {}), "('/vsis3/s3_bucket_test_dir_stat_2/test_dir_stat/')\n", (89395, 89446), False, 'from osgeo import gdal\n'), ((91689, 91726), 'osgeo.gdal.VSIStatL', 'gdal.VSIStatL', (['"""/vsis3/vsis3_8/test/"""'], {}), "('/vsis3/vsis3_8/test/')\n", (91702, 91726), False, 'from osgeo import gdal\n'), ((92179, 92235), 'osgeo.gdal.Sync', 'gdal.Sync', (['"""/i_do/not/exist"""', '"""/vsis3/"""'], {'options': 'options'}), "('/i_do/not/exist', '/vsis3/', options=options)\n", (92188, 92235), False, 'from osgeo import gdal\n'), ((92582, 92645), 'osgeo.gdal.Sync', 'gdal.Sync', (['"""vsifile.py"""', '"""/vsis3/do_not/exist"""'], {'options': 'options'}), "('vsifile.py', '/vsis3/do_not/exist', options=options)\n", (92591, 92645), False, 'from osgeo import gdal\n'), ((113753, 113777), 'gdaltest.error_handler', 'gdaltest.error_handler', ([], {}), '()\n', (113775, 113777), False, 'import gdaltest\n'), ((118764, 118787), 'osgeo.gdal.VSIFReadL', 'gdal.VSIFReadL', (['(3)', '(1)', 'f'], {}), '(3, 1, f)\n', (118778, 118787), False, 'from osgeo import gdal\n'), ((119698, 119716), 'osgeo.gdal.VSIFCloseL', 'gdal.VSIFCloseL', (['f'], {}), '(f)\n', (119713, 119716), False, 'from osgeo import gdal\n'), ((120460, 120478), 'osgeo.gdal.VSIFCloseL', 'gdal.VSIFCloseL', (['f'], {}), '(f)\n', (120475, 120478), False, 'from osgeo import gdal\n'), ((122497, 122520), 'osgeo.gdal.VSIFReadL', 'gdal.VSIFReadL', (['(1)', '(4)', 'f'], {}), '(1, 4, f)\n', (122511, 122520), False, 'from osgeo import gdal\n'), ((123720, 123743), 'osgeo.gdal.VSIFReadL', 'gdal.VSIFReadL', (['(1)', '(4)', 'f'], {}), '(1, 4, f)\n', (123734, 123743), False, 'from osgeo import gdal\n'), ((125329, 125352), 'osgeo.gdal.VSIFReadL', 'gdal.VSIFReadL', (['(1)', '(4)', 'f'], {}), '(1, 4, f)\n', (125343, 125352), False, 'from osgeo import gdal\n'), ((127163, 127186), 'osgeo.gdal.VSIFReadL', 'gdal.VSIFReadL', (['(1)', '(4)', 'f'], {}), '(1, 4, f)\n', (127177, 127186), False, 'from osgeo import gdal\n'), ((128878, 128901), 'osgeo.gdal.VSIFReadL', 'gdal.VSIFReadL', (['(1)', '(4)', 'f'], {}), '(1, 4, f)\n', (128892, 128901), False, 'from osgeo import gdal\n'), ((130952, 130975), 'osgeo.gdal.VSIFReadL', 'gdal.VSIFReadL', (['(1)', '(4)', 'f'], {}), '(1, 4, f)\n', (130966, 130975), False, 'from osgeo import gdal\n'), ((131419, 131442), 'osgeo.gdal.VSIFReadL', 'gdal.VSIFReadL', (['(1)', '(4)', 'f'], {}), '(1, 4, f)\n', (131433, 131442), False, 'from osgeo import gdal\n'), ((133418, 133441), 'osgeo.gdal.VSIFReadL', 'gdal.VSIFReadL', (['(1)', '(4)', 'f'], {}), '(1, 4, f)\n', (133432, 133441), False, 'from osgeo import gdal\n'), ((135984, 136007), 'osgeo.gdal.VSIFReadL', 'gdal.VSIFReadL', (['(1)', '(4)', 'f'], {}), '(1, 4, f)\n', (135998, 136007), False, 'from osgeo import gdal\n'), ((137842, 137883), 'osgeo.gdal.GetConfigOption', 'gdal.GetConfigOption', (['"""AWS_ACCESS_KEY_ID"""'], {}), "('AWS_ACCESS_KEY_ID')\n", (137862, 137883), False, 'from osgeo import gdal\n'), ((137905, 137945), 'pytest.skip', 'pytest.skip', (['"""Missing AWS_ACCESS_KEY_ID"""'], {}), "('Missing AWS_ACCESS_KEY_ID')\n", (137916, 137945), False, 'import pytest\n'), ((139945, 139968), 'osgeo.gdal.VSIFReadL', 'gdal.VSIFReadL', (['(1)', '(5)', 'f'], {}), '(1, 5, f)\n', (139959, 139968), False, 'from osgeo import gdal\n'), ((140225, 140248), 'osgeo.gdal.VSIFReadL', 'gdal.VSIFReadL', (['(1)', '(5)', 'f'], {}), '(1, 5, f)\n', (140239, 140248), False, 'from osgeo import gdal\n'), ((141528, 141563), 'osgeo.gdal.GetConfigOption', 'gdal.GetConfigOption', (['"""S3_RESOURCE"""'], {}), "('S3_RESOURCE')\n", (141548, 141563), False, 'from osgeo import gdal\n'), ((6158, 6183), 'osgeo.gdal.VSIGetLastErrorMsg', 'gdal.VSIGetLastErrorMsg', ([], {}), '()\n', (6181, 6183), False, 'from osgeo import gdal\n'), ((6356, 6381), 'osgeo.gdal.VSIGetLastErrorMsg', 'gdal.VSIGetLastErrorMsg', ([], {}), '()\n', (6379, 6381), False, 'from osgeo import gdal\n'), ((6652, 6677), 'osgeo.gdal.VSIGetLastErrorMsg', 'gdal.VSIGetLastErrorMsg', ([], {}), '()\n', (6675, 6677), False, 'from osgeo import gdal\n'), ((13039, 13062), 'osgeo.gdal.VSIFReadL', 'gdal.VSIFReadL', (['(1)', '(4)', 'f'], {}), '(1, 4, f)\n', (13053, 13062), False, 'from osgeo import gdal\n'), ((19923, 19948), 'osgeo.gdal.VSIGetLastErrorMsg', 'gdal.VSIGetLastErrorMsg', ([], {}), '()\n', (19946, 19948), False, 'from osgeo import gdal\n'), ((20576, 20601), 'osgeo.gdal.VSIGetLastErrorMsg', 'gdal.VSIGetLastErrorMsg', ([], {}), '()\n', (20599, 20601), False, 'from osgeo import gdal\n'), ((21232, 21257), 'osgeo.gdal.VSIGetLastErrorMsg', 'gdal.VSIGetLastErrorMsg', ([], {}), '()\n', (21255, 21257), False, 'from osgeo import gdal\n'), ((22000, 22025), 'osgeo.gdal.VSIGetLastErrorMsg', 'gdal.VSIGetLastErrorMsg', ([], {}), '()\n', (22023, 22025), False, 'from osgeo import gdal\n'), ((22738, 22763), 'osgeo.gdal.VSIGetLastErrorMsg', 'gdal.VSIGetLastErrorMsg', ([], {}), '()\n', (22761, 22763), False, 'from osgeo import gdal\n'), ((23424, 23449), 'osgeo.gdal.VSIGetLastErrorMsg', 'gdal.VSIGetLastErrorMsg', ([], {}), '()\n', (23447, 23449), False, 'from osgeo import gdal\n'), ((40236, 40282), 'osgeo.gdal.VSIStatL', 'gdal.VSIStatL', (['"""/vsis3/s3_non_cached/test.txt"""'], {}), "('/vsis3/s3_non_cached/test.txt')\n", (40249, 40282), False, 'from osgeo import gdal\n'), ((40547, 40593), 'osgeo.gdal.VSIStatL', 'gdal.VSIStatL', (['"""/vsis3/s3_non_cached/test.txt"""'], {}), "('/vsis3/s3_non_cached/test.txt')\n", (40560, 40593), False, 'from osgeo import gdal\n'), ((40696, 40713), 'pytest.fail', 'pytest.fail', (['data'], {}), '(data)\n', (40707, 40713), False, 'import pytest\n'), ((55632, 55649), 'osgeo.gdal.VSIFTellL', 'gdal.VSIFTellL', (['f'], {}), '(f)\n', (55646, 55649), False, 'from osgeo import gdal\n'), ((55848, 55865), 'osgeo.gdal.VSIFTellL', 'gdal.VSIFTellL', (['f'], {}), '(f)\n', (55862, 55865), False, 'from osgeo import gdal\n'), ((59895, 59959), 'sys.stderr.write', 'sys.stderr.write', (["('Did not get expected content: %s\\n' % content)"], {}), "('Did not get expected content: %s\\n' % content)\n", (59911, 59959), False, 'import sys\n'), ((82107, 82136), 'webserver.SequentialHandler', 'webserver.SequentialHandler', ([], {}), '()\n', (82134, 82136), False, 'import webserver\n'), ((91523, 91559), 'osgeo.gdal.VSIStatL', 'gdal.VSIStatL', (['"""/vsis3/vsis3_8/test"""'], {}), "('/vsis3/vsis3_8/test')\n", (91536, 91559), False, 'from osgeo import gdal\n'), ((113806, 113900), 'osgeo.gdal.Sync', 'gdal.Sync', (['"""/vsimem/test"""', '"""/vsis3/test_bucket"""'], {'options': "['NUM_THREADS=1', 'CHUNK_SIZE=3']"}), "('/vsimem/test', '/vsis3/test_bucket', options=['NUM_THREADS=1',\n    'CHUNK_SIZE=3'])\n", (113815, 113900), False, 'from osgeo import gdal\n'), ((121181, 121210), 'osgeo.gdal.GetDriverByName', 'gdal.GetDriverByName', (['"""GTiff"""'], {}), "('GTiff')\n", (121201, 121210), False, 'from osgeo import gdal\n'), ((138495, 138517), 'osgeo.gdal.VSIStatL', 'gdal.VSIStatL', (['subpath'], {}), '(subpath)\n', (138508, 138517), False, 'from osgeo import gdal\n'), ((25515, 25538), 'osgeo.gdal.VSIFReadL', 'gdal.VSIFReadL', (['(1)', '(3)', 'f'], {}), '(1, 3, f)\n', (25529, 25538), False, 'from osgeo import gdal\n'), ((39893, 39916), 'osgeo.gdal.VSIFReadL', 'gdal.VSIFReadL', (['(1)', '(3)', 'f'], {}), '(1, 3, f)\n', (39907, 39916), False, 'from osgeo import gdal\n'), ((41049, 41072), 'osgeo.gdal.VSIFReadL', 'gdal.VSIFReadL', (['(1)', '(4)', 'f'], {}), '(1, 4, f)\n', (41063, 41072), False, 'from osgeo import gdal\n'), ((42651, 42674), 'osgeo.gdal.VSIFReadL', 'gdal.VSIFReadL', (['(1)', '(3)', 'f'], {}), '(1, 3, f)\n', (42665, 42674), False, 'from osgeo import gdal\n'), ((43043, 43066), 'osgeo.gdal.VSIFReadL', 'gdal.VSIFReadL', (['(1)', '(4)', 'f'], {}), '(1, 4, f)\n', (43057, 43066), False, 'from osgeo import gdal\n')]