#!/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)

[((47, 11, 47, 41), 'osgeo.gdal.VSIFOpenExL', 'gdal.VSIFOpenExL', ({(47, 28, 47, 31): 'uri', (47, 33, 47, 37): '"""rb"""', (47, 39, 47, 40): '(1)'}, {}), "(uri, 'rb', 1)", False, 'from osgeo import gdal\n'), ((62, 4, 62, 56), 'osgeo.gdal.SetConfigOption', 'gdal.SetConfigOption', ({(62, 25, 62, 51): '"""CPL_AWS_CREDENTIALS_FILE"""', (62, 53, 62, 55): '""""""'}, {}), "('CPL_AWS_CREDENTIALS_FILE', '')", False, 'from osgeo import gdal\n'), ((63, 4, 63, 47), 'osgeo.gdal.SetConfigOption', 'gdal.SetConfigOption', ({(63, 25, 63, 42): '"""AWS_CONFIG_FILE"""', (63, 44, 63, 46): '""""""'}, {}), "('AWS_CONFIG_FILE', '')", False, 'from osgeo import gdal\n'), ((64, 4, 64, 56), 'osgeo.gdal.SetConfigOption', 'gdal.SetConfigOption', ({(64, 25, 64, 51): '"""CPL_AWS_EC2_API_ROOT_URL"""', (64, 53, 64, 55): '""""""'}, {}), "('CPL_AWS_EC2_API_ROOT_URL', '')", False, 'from osgeo import gdal\n'), ((90, 4, 90, 22), 'osgeo.gdal.VSIFCloseL', 'gdal.VSIFCloseL', ({(90, 20, 90, 21): 'f'}, {}), '(f)', False, 'from osgeo import gdal\n'), ((117, 4, 117, 66), 'osgeo.gdal.RmdirRecursive', 'gdal.RmdirRecursive', ({(117, 24, 117, 65): '"""/vsimem/test_vsis3_no_sign_request_sync"""'}, {}), "('/vsimem/test_vsis3_no_sign_request_sync')", False, 'from osgeo import gdal\n'), ((145, 4, 145, 66), 'osgeo.gdal.RmdirRecursive', 'gdal.RmdirRecursive', ({(145, 24, 145, 65): '"""/vsimem/test_vsis3_no_sign_request_sync"""'}, {}), "('/vsimem/test_vsis3_no_sign_request_sync')", False, 'from osgeo import gdal\n'), ((157, 4, 157, 21), 'osgeo.gdal.ErrorReset', 'gdal.ErrorReset', ({}, {}), '()', False, 'from osgeo import gdal\n'), ((162, 4, 162, 21), 'osgeo.gdal.ErrorReset', 'gdal.ErrorReset', ({}, {}), '()', False, 'from osgeo import gdal\n'), ((167, 4, 167, 74), 'osgeo.gdal.SetConfigOption', 'gdal.SetConfigOption', ({(167, 25, 167, 48): '"""AWS_SECRET_ACCESS_KEY"""', (167, 50, 167, 73): '"""AWS_SECRET_ACCESS_KEY"""'}, {}), "('AWS_SECRET_ACCESS_KEY', 'AWS_SECRET_ACCESS_KEY')", False, 'from osgeo import gdal\n'), ((170, 4, 170, 21), 'osgeo.gdal.ErrorReset', 'gdal.ErrorReset', ({}, {}), '()', False, 'from osgeo import gdal\n'), ((175, 4, 175, 66), 'osgeo.gdal.SetConfigOption', 'gdal.SetConfigOption', ({(175, 25, 175, 44): '"""AWS_ACCESS_KEY_ID"""', (175, 46, 175, 65): '"""AWS_ACCESS_KEY_ID"""'}, {}), "('AWS_ACCESS_KEY_ID', 'AWS_ACCESS_KEY_ID')", False, 'from osgeo import gdal\n'), ((178, 4, 178, 21), 'osgeo.gdal.ErrorReset', 'gdal.ErrorReset', ({}, {}), '()', False, 'from osgeo import gdal\n'), ((188, 4, 188, 21), 'osgeo.gdal.ErrorReset', 'gdal.ErrorReset', ({}, {}), '()', False, 'from osgeo import gdal\n'), ((204, 60, 204, 117), 'webserver.launch', 'webserver.launch', (), '', False, 'import webserver\n'), ((208, 4, 208, 74), 'osgeo.gdal.SetConfigOption', 'gdal.SetConfigOption', ({(208, 25, 208, 48): '"""AWS_SECRET_ACCESS_KEY"""', (208, 50, 208, 73): '"""AWS_SECRET_ACCESS_KEY"""'}, {}), "('AWS_SECRET_ACCESS_KEY', 'AWS_SECRET_ACCESS_KEY')", False, 'from osgeo import gdal\n'), ((209, 4, 209, 66), 'osgeo.gdal.SetConfigOption', 'gdal.SetConfigOption', ({(209, 25, 209, 44): '"""AWS_ACCESS_KEY_ID"""', (209, 46, 209, 65): '"""AWS_ACCESS_KEY_ID"""'}, {}), "('AWS_ACCESS_KEY_ID', 'AWS_ACCESS_KEY_ID')", False, 'from osgeo import gdal\n'), ((210, 4, 210, 61), 'osgeo.gdal.SetConfigOption', 'gdal.SetConfigOption', ({(210, 25, 210, 40): '"""AWS_TIMESTAMP"""', (210, 42, 210, 60): '"""20150101T000000Z"""'}, {}), "('AWS_TIMESTAMP', '20150101T000000Z')", False, 'from osgeo import gdal\n'), ((211, 4, 211, 43), 'osgeo.gdal.SetConfigOption', 'gdal.SetConfigOption', ({(211, 25, 211, 36): '"""AWS_HTTPS"""', (211, 38, 211, 42): '"""NO"""'}, {}), "('AWS_HTTPS', 'NO')", False, 'from osgeo import gdal\n'), ((212, 4, 212, 53), 'osgeo.gdal.SetConfigOption', 'gdal.SetConfigOption', ({(212, 25, 212, 46): '"""AWS_VIRTUAL_HOSTING"""', (212, 48, 212, 52): '"""NO"""'}, {}), "('AWS_VIRTUAL_HOSTING', 'NO')", False, 'from osgeo import gdal\n'), ((213, 4, 213, 85), 'osgeo.gdal.SetConfigOption', 'gdal.SetConfigOption', ({(213, 25, 213, 42): '"""AWS_S3_ENDPOINT"""', (213, 44, 213, 84): "('127.0.0.1:%d' % gdaltest.webserver_port)"}, {}), "('AWS_S3_ENDPOINT', '127.0.0.1:%d' % gdaltest.\n    webserver_port)", False, 'from osgeo import gdal\n'), ((246, 17, 246, 68), 'osgeo.gdal.GetSignedURL', 'gdal.GetSignedURL', ({(246, 35, 246, 67): '"""/vsis3/s3_fake_bucket/resource"""'}, {}), "('/vsis3/s3_fake_bucket/resource')", False, 'from osgeo import gdal\n'), ((251, 14, 251, 43), 'webserver.SequentialHandler', 'webserver.SequentialHandler', ({}, {}), '()', False, 'import webserver\n'), ((262, 14, 262, 43), 'webserver.SequentialHandler', 'webserver.SequentialHandler', ({}, {}), '()', False, 'import webserver\n'), ((272, 14, 272, 43), 'webserver.SequentialHandler', 'webserver.SequentialHandler', ({}, {}), '()', False, 'import webserver\n'), ((304, 14, 304, 43), 'webserver.SequentialHandler', 'webserver.SequentialHandler', ({}, {}), '()', False, 'import webserver\n'), ((342, 14, 342, 43), 'webserver.SequentialHandler', 'webserver.SequentialHandler', ({}, {}), '()', False, 'import webserver\n'), ((356, 14, 356, 43), 'webserver.SequentialHandler', 'webserver.SequentialHandler', ({}, {}), '()', False, 'import webserver\n'), ((422, 4, 422, 28), 'osgeo.gdal.VSICurlClearCache', 'gdal.VSICurlClearCache', ({}, {}), '()', False, 'from osgeo import gdal\n'), ((433, 14, 433, 43), 'webserver.SequentialHandler', 'webserver.SequentialHandler', ({}, {}), '()', False, 'import webserver\n'), ((454, 4, 454, 21), 'osgeo.gdal.ErrorReset', 'gdal.ErrorReset', ({}, {}), '()', False, 'from osgeo import gdal\n'), ((460, 14, 460, 43), 'webserver.SequentialHandler', 'webserver.SequentialHandler', ({}, {}), '()', False, 'import webserver\n'), ((467, 4, 467, 21), 'osgeo.gdal.ErrorReset', 'gdal.ErrorReset', ({}, {}), '()', False, 'from osgeo import gdal\n'), ((473, 14, 473, 43), 'webserver.SequentialHandler', 'webserver.SequentialHandler', ({}, {}), '()', False, 'import webserver\n'), ((480, 4, 480, 21), 'osgeo.gdal.ErrorReset', 'gdal.ErrorReset', ({}, {}), '()', False, 'from osgeo import gdal\n'), ((486, 14, 486, 43), 'webserver.SequentialHandler', 'webserver.SequentialHandler', ({}, {}), '()', False, 'import webserver\n'), ((493, 4, 493, 21), 'osgeo.gdal.ErrorReset', 'gdal.ErrorReset', ({}, {}), '()', False, 'from osgeo import gdal\n'), ((499, 14, 499, 43), 'webserver.SequentialHandler', 'webserver.SequentialHandler', ({}, {}), '()', False, 'import webserver\n'), ((506, 4, 506, 21), 'osgeo.gdal.ErrorReset', 'gdal.ErrorReset', ({}, {}), '()', False, 'from osgeo import gdal\n'), ((512, 14, 512, 43), 'webserver.SequentialHandler', 'webserver.SequentialHandler', ({}, {}), '()', False, 'import webserver\n'), ((519, 4, 519, 21), 'osgeo.gdal.ErrorReset', 'gdal.ErrorReset', ({}, {}), '()', False, 'from osgeo import gdal\n'), ((526, 14, 526, 43), 'webserver.SequentialHandler', 'webserver.SequentialHandler', ({}, {}), '()', False, 'import webserver\n'), ((564, 14, 564, 43), 'webserver.SequentialHandler', 'webserver.SequentialHandler', ({}, {}), '()', False, 'import webserver\n'), ((615, 14, 615, 43), 'webserver.SequentialHandler', 'webserver.SequentialHandler', ({}, {}), '()', False, 'import webserver\n'), ((638, 4, 638, 28), 'osgeo.gdal.VSICurlClearCache', 'gdal.VSICurlClearCache', ({}, {}), '()', False, 'from osgeo import gdal\n'), ((640, 14, 640, 43), 'webserver.SequentialHandler', 'webserver.SequentialHandler', ({}, {}), '()', False, 'import webserver\n'), ((682, 14, 682, 43), 'webserver.SequentialHandler', 'webserver.SequentialHandler', ({}, {}), '()', False, 'import webserver\n'), ((774, 4, 774, 22), 'osgeo.gdal.VSIFCloseL', 'gdal.VSIFCloseL', ({(774, 20, 774, 21): 'f'}, {}), '(f)', False, 'from osgeo import gdal\n'), ((784, 19, 784, 74), 'osgeo.gdal.ReadDir', 'gdal.ReadDir', ({(784, 32, 784, 73): '"""/vsis3/s3_fake_bucket2/a_dir with_space"""'}, {}), "('/vsis3/s3_fake_bucket2/a_dir with_space')", False, 'from osgeo import gdal\n'), ((788, 19, 788, 99), 'osgeo.gdal.ReadDir', 'gdal.ReadDir', ({(788, 32, 788, 98): '"""/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    )", False, 'from osgeo import gdal\n'), ((792, 4, 792, 68), 'osgeo.gdal.VSICurlPartialClearCache', 'gdal.VSICurlPartialClearCache', ({(792, 34, 792, 67): '"""/vsis3/s3_fake_bucket_unrelated"""'}, {}), "('/vsis3/s3_fake_bucket_unrelated')", False, 'from osgeo import gdal\n'), ((796, 19, 796, 74), 'osgeo.gdal.ReadDir', 'gdal.ReadDir', ({(796, 32, 796, 73): '"""/vsis3/s3_fake_bucket2/a_dir with_space"""'}, {}), "('/vsis3/s3_fake_bucket2/a_dir with_space')", False, 'from osgeo import gdal\n'), ((800, 4, 800, 76), 'osgeo.gdal.VSICurlPartialClearCache', 'gdal.VSICurlPartialClearCache', ({(800, 34, 800, 75): '"""/vsis3/s3_fake_bucket2/a_dir with_space"""'}, {}), "('/vsis3/s3_fake_bucket2/a_dir with_space')", False, 'from osgeo import gdal\n'), ((802, 14, 802, 43), 'webserver.SequentialHandler', 'webserver.SequentialHandler', ({}, {}), '()', False, 'import webserver\n'), ((808, 14, 808, 43), 'webserver.SequentialHandler', 'webserver.SequentialHandler', ({}, {}), '()', False, 'import webserver\n'), ((824, 4, 824, 28), 'osgeo.gdal.VSICurlClearCache', 'gdal.VSICurlClearCache', ({}, {}), '()', False, 'from osgeo import gdal\n'), ((825, 14, 825, 43), 'webserver.SequentialHandler', 'webserver.SequentialHandler', ({}, {}), '()', False, 'import webserver\n'), ((938, 14, 938, 43), 'webserver.SequentialHandler', 'webserver.SequentialHandler', ({}, {}), '()', False, 'import webserver\n'), ((950, 4, 950, 28), 'osgeo.gdal.VSICurlClearCache', 'gdal.VSICurlClearCache', ({}, {}), '()', False, 'from osgeo import gdal\n'), ((953, 14, 953, 43), 'webserver.SequentialHandler', 'webserver.SequentialHandler', ({}, {}), '()', False, 'import webserver\n'), ((969, 14, 969, 43), 'webserver.SequentialHandler', 'webserver.SequentialHandler', ({}, {}), '()', False, 'import webserver\n'), ((1024, 14, 1024, 43), 'webserver.SequentialHandler', 'webserver.SequentialHandler', ({}, {}), '()', False, 'import webserver\n'), ((1051, 14, 1051, 43), 'webserver.SequentialHandler', 'webserver.SequentialHandler', ({}, {}), '()', False, 'import webserver\n'), ((1078, 12, 1078, 35), 'osgeo.gdal.GetNextDirEntry', 'gdal.GetNextDirEntry', ({(1078, 33, 1078, 34): 'd'}, {}), '(d)', False, 'from osgeo import gdal\n'), ((1084, 12, 1084, 35), 'osgeo.gdal.GetNextDirEntry', 'gdal.GetNextDirEntry', ({(1084, 33, 1084, 34): 'd'}, {}), '(d)', False, 'from osgeo import gdal\n'), ((1088, 12, 1088, 35), 'osgeo.gdal.GetNextDirEntry', 'gdal.GetNextDirEntry', ({(1088, 33, 1088, 34): 'd'}, {}), '(d)', False, 'from osgeo import gdal\n'), ((1091, 12, 1091, 35), 'osgeo.gdal.GetNextDirEntry', 'gdal.GetNextDirEntry', ({(1091, 33, 1091, 34): 'd'}, {}), '(d)', False, 'from osgeo import gdal\n'), ((1094, 4, 1094, 20), 'osgeo.gdal.CloseDir', 'gdal.CloseDir', ({(1094, 18, 1094, 19): 'd'}, {}), '(d)', False, 'from osgeo import gdal\n'), ((1097, 14, 1097, 43), 'webserver.SequentialHandler', 'webserver.SequentialHandler', ({}, {}), '()', False, 'import webserver\n'), ((1117, 12, 1117, 35), 'osgeo.gdal.GetNextDirEntry', 'gdal.GetNextDirEntry', ({(1117, 33, 1117, 34): 'd'}, {}), '(d)', False, 'from osgeo import gdal\n'), ((1123, 12, 1123, 35), 'osgeo.gdal.GetNextDirEntry', 'gdal.GetNextDirEntry', ({(1123, 33, 1123, 34): 'd'}, {}), '(d)', False, 'from osgeo import gdal\n'), ((1127, 12, 1127, 35), 'osgeo.gdal.GetNextDirEntry', 'gdal.GetNextDirEntry', ({(1127, 33, 1127, 34): 'd'}, {}), '(d)', False, 'from osgeo import gdal\n'), ((1130, 4, 1130, 20), 'osgeo.gdal.CloseDir', 'gdal.CloseDir', ({(1130, 18, 1130, 19): 'd'}, {}), '(d)', False, 'from osgeo import gdal\n'), ((1133, 14, 1133, 43), 'webserver.SequentialHandler', 'webserver.SequentialHandler', ({}, {}), '()', False, 'import webserver\n'), ((1153, 12, 1153, 35), 'osgeo.gdal.GetNextDirEntry', 'gdal.GetNextDirEntry', ({(1153, 33, 1153, 34): 'd'}, {}), '(d)', False, 'from osgeo import gdal\n'), ((1159, 12, 1159, 35), 'osgeo.gdal.GetNextDirEntry', 'gdal.GetNextDirEntry', ({(1159, 33, 1159, 34): 'd'}, {}), '(d)', False, 'from osgeo import gdal\n'), ((1163, 14, 1163, 43), 'webserver.SequentialHandler', 'webserver.SequentialHandler', ({}, {}), '()', False, 'import webserver\n'), ((1180, 12, 1180, 35), 'osgeo.gdal.GetNextDirEntry', 'gdal.GetNextDirEntry', ({(1180, 33, 1180, 34): 'd'}, {}), '(d)', False, 'from osgeo import gdal\n'), ((1183, 4, 1183, 20), 'osgeo.gdal.CloseDir', 'gdal.CloseDir', ({(1183, 18, 1183, 19): 'd'}, {}), '(d)', False, 'from osgeo import gdal\n'), ((1199, 14, 1199, 43), 'webserver.SequentialHandler', 'webserver.SequentialHandler', ({}, {}), '()', False, 'import webserver\n'), ((1205, 14, 1205, 43), 'webserver.SequentialHandler', 'webserver.SequentialHandler', ({}, {}), '()', False, 'import webserver\n'), ((1226, 14, 1226, 43), 'webserver.SequentialHandler', 'webserver.SequentialHandler', ({}, {}), '()', False, 'import webserver\n'), ((1232, 14, 1232, 43), 'webserver.SequentialHandler', 'webserver.SequentialHandler', ({}, {}), '()', False, 'import webserver\n'), ((1242, 14, 1242, 43), 'webserver.SequentialHandler', 'webserver.SequentialHandler', ({}, {}), '()', False, 'import webserver\n'), ((1252, 14, 1252, 43), 'webserver.SequentialHandler', 'webserver.SequentialHandler', ({}, {}), '()', False, 'import webserver\n'), ((1264, 4, 1264, 28), 'osgeo.gdal.NetworkStatsReset', 'gdal.NetworkStatsReset', ({}, {}), '()', False, 'from osgeo import gdal\n'), ((1348, 4, 1348, 28), 'osgeo.gdal.NetworkStatsReset', 'gdal.NetworkStatsReset', ({}, {}), '()', False, 'from osgeo import gdal\n'), ((1356, 14, 1356, 43), 'webserver.SequentialHandler', 'webserver.SequentialHandler', ({}, {}), '()', False, 'import webserver\n'), ((1395, 4, 1395, 21), 'osgeo.gdal.ErrorReset', 'gdal.ErrorReset', ({}, {}), '()', False, 'from osgeo import gdal\n'), ((1463, 14, 1463, 43), 'webserver.SequentialHandler', 'webserver.SequentialHandler', ({}, {}), '()', False, 'import webserver\n'), ((1468, 14, 1468, 43), 'webserver.SequentialHandler', 'webserver.SequentialHandler', ({}, {}), '()', False, 'import webserver\n'), ((1472, 14, 1472, 43), 'webserver.SequentialHandler', 'webserver.SequentialHandler', ({}, {}), '()', False, 'import webserver\n'), ((1478, 14, 1478, 43), 'webserver.SequentialHandler', 'webserver.SequentialHandler', ({}, {}), '()', False, 'import webserver\n'), ((1484, 14, 1484, 43), 'webserver.SequentialHandler', 'webserver.SequentialHandler', ({}, {}), '()', False, 'import webserver\n'), ((1492, 14, 1492, 43), 'webserver.SequentialHandler', 'webserver.SequentialHandler', ({}, {}), '()', False, 'import webserver\n'), ((1561, 14, 1561, 43), 'webserver.SequentialHandler', 'webserver.SequentialHandler', ({}, {}), '()', False, 'import webserver\n'), ((1571, 14, 1571, 43), 'webserver.SequentialHandler', 'webserver.SequentialHandler', ({}, {}), '()', False, 'import webserver\n'), ((1588, 14, 1588, 43), 'webserver.SequentialHandler', 'webserver.SequentialHandler', ({}, {}), '()', False, 'import webserver\n'), ((1685, 14, 1685, 43), 'webserver.SequentialHandler', 'webserver.SequentialHandler', ({}, {}), '()', False, 'import webserver\n'), ((1730, 14, 1730, 43), 'webserver.SequentialHandler', 'webserver.SequentialHandler', ({}, {}), '()', False, 'import webserver\n'), ((1773, 4, 1773, 21), 'osgeo.gdal.ErrorReset', 'gdal.ErrorReset', ({}, {}), '()', False, 'from osgeo import gdal\n'), ((1778, 14, 1778, 43), 'webserver.SequentialHandler', 'webserver.SequentialHandler', ({}, {}), '()', False, 'import webserver\n'), ((1798, 14, 1798, 43), 'webserver.SequentialHandler', 'webserver.SequentialHandler', ({}, {}), '()', False, 'import webserver\n'), ((1823, 14, 1823, 43), 'webserver.SequentialHandler', 'webserver.SequentialHandler', ({}, {}), '()', False, 'import webserver\n'), ((1843, 14, 1843, 43), 'webserver.SequentialHandler', 'webserver.SequentialHandler', ({}, {}), '()', False, 'import webserver\n'), ((1929, 14, 1929, 43), 'webserver.SequentialHandler', 'webserver.SequentialHandler', ({}, {}), '()', False, 'import webserver\n'), ((1939, 18, 1939, 65), 'osgeo.gdal.ReadDir', 'gdal.ReadDir', ({(1939, 31, 1939, 64): '"""/vsis3/s3_bucket_test_mkdir/dir"""'}, {}), "('/vsis3/s3_bucket_test_mkdir/dir')", False, 'from osgeo import gdal\n'), ((1943, 14, 1943, 43), 'webserver.SequentialHandler', 'webserver.SequentialHandler', ({}, {}), '()', False, 'import webserver\n'), ((1949, 14, 1949, 43), 'webserver.SequentialHandler', 'webserver.SequentialHandler', ({}, {}), '()', False, 'import webserver\n'), ((1956, 14, 1956, 43), 'webserver.SequentialHandler', 'webserver.SequentialHandler', ({}, {}), '()', False, 'import webserver\n'), ((1964, 14, 1964, 43), 'webserver.SequentialHandler', 'webserver.SequentialHandler', ({}, {}), '()', False, 'import webserver\n'), ((1983, 14, 1983, 43), 'webserver.SequentialHandler', 'webserver.SequentialHandler', ({}, {}), '()', False, 'import webserver\n'), ((2001, 14, 2001, 43), 'webserver.SequentialHandler', 'webserver.SequentialHandler', ({}, {}), '()', False, 'import webserver\n'), ((2018, 14, 2018, 43), 'webserver.SequentialHandler', 'webserver.SequentialHandler', ({}, {}), '()', False, 'import webserver\n'), ((2036, 14, 2036, 43), 'webserver.SequentialHandler', 'webserver.SequentialHandler', ({}, {}), '()', False, 'import webserver\n'), ((2062, 14, 2062, 43), 'webserver.SequentialHandler', 'webserver.SequentialHandler', ({}, {}), '()', False, 'import webserver\n'), ((2083, 14, 2083, 43), 'webserver.SequentialHandler', 'webserver.SequentialHandler', ({}, {}), '()', False, 'import webserver\n'), ((2087, 14, 2087, 43), 'webserver.SequentialHandler', 'webserver.SequentialHandler', ({}, {}), '()', False, 'import webserver\n'), ((2101, 4, 2101, 28), 'osgeo.gdal.VSICurlClearCache', 'gdal.VSICurlClearCache', ({}, {}), '()', False, 'from osgeo import gdal\n'), ((2118, 14, 2118, 43), 'webserver.SequentialHandler', 'webserver.SequentialHandler', ({}, {}), '()', False, 'import webserver\n'), ((2148, 4, 2148, 57), 'osgeo.gdal.FileFromMemBuffer', 'gdal.FileFromMemBuffer', ({(2148, 27, 2148, 49): '"""/vsimem/testsync.txt"""', (2148, 51, 2148, 56): '"""foo"""'}, {}), "('/vsimem/testsync.txt', 'foo')", False, 'from osgeo import gdal\n'), ((2162, 14, 2162, 43), 'webserver.SequentialHandler', 'webserver.SequentialHandler', ({}, {}), '()', False, 'import webserver\n'), ((2167, 4, 2167, 28), 'osgeo.gdal.VSICurlClearCache', 'gdal.VSICurlClearCache', ({}, {}), '()', False, 'from osgeo import gdal\n'), ((2170, 14, 2170, 43), 'webserver.SequentialHandler', 'webserver.SequentialHandler', ({}, {}), '()', False, 'import webserver\n'), ((2184, 4, 2184, 57), 'osgeo.gdal.FileFromMemBuffer', 'gdal.FileFromMemBuffer', ({(2184, 27, 2184, 49): '"""/vsimem/testsync.txt"""', (2184, 51, 2184, 56): '"""bar"""'}, {}), "('/vsimem/testsync.txt', 'bar')", False, 'from osgeo import gdal\n'), ((2186, 14, 2186, 43), 'webserver.SequentialHandler', 'webserver.SequentialHandler', ({}, {}), '()', False, 'import webserver\n'), ((2193, 8, 2193, 52), 'osgeo.gdal.VSIFOpenL', 'gdal.VSIFOpenL', ({(2193, 23, 2193, 45): '"""/vsimem/testsync.txt"""', (2193, 47, 2193, 51): '"""rb"""'}, {}), "('/vsimem/testsync.txt', 'rb')", False, 'from osgeo import gdal\n'), ((2195, 4, 2195, 22), 'osgeo.gdal.VSIFCloseL', 'gdal.VSIFCloseL', ({(2195, 20, 2195, 21): 'f'}, {}), '(f)', False, 'from osgeo import gdal\n'), ((2199, 4, 2199, 28), 'osgeo.gdal.VSICurlClearCache', 'gdal.VSICurlClearCache', ({}, {}), '()', False, 'from osgeo import gdal\n'), ((2201, 14, 2201, 43), 'webserver.SequentialHandler', 'webserver.SequentialHandler', ({}, {}), '()', False, 'import webserver\n'), ((2210, 4, 2210, 39), 'osgeo.gdal.Unlink', 'gdal.Unlink', ({(2210, 16, 2210, 38): '"""/vsimem/testsync.txt"""'}, {}), "('/vsimem/testsync.txt')", False, 'from osgeo import gdal\n'), ((2213, 4, 2213, 28), 'osgeo.gdal.VSICurlClearCache', 'gdal.VSICurlClearCache', ({}, {}), '()', False, 'from osgeo import gdal\n'), ((2215, 4, 2215, 35), 'osgeo.gdal.Mkdir', 'gdal.Mkdir', ({(2215, 15, 2215, 31): '"""/vsimem/subdir"""', (2215, 33, 2215, 34): '(0)'}, {}), "('/vsimem/subdir', 0)", False, 'from osgeo import gdal\n'), ((2216, 4, 2216, 64), 'osgeo.gdal.FileFromMemBuffer', 'gdal.FileFromMemBuffer', ({(2216, 27, 2216, 56): '"""/vsimem/subdir/testsync.txt"""', (2216, 58, 2216, 63): '"""foo"""'}, {}), "('/vsimem/subdir/testsync.txt', 'foo')", False, 'from osgeo import gdal\n'), ((2217, 14, 2217, 43), 'webserver.SequentialHandler', 'webserver.SequentialHandler', ({}, {}), '()', False, 'import webserver\n'), ((2234, 4, 2234, 41), 'osgeo.gdal.RmdirRecursive', 'gdal.RmdirRecursive', ({(2234, 24, 2234, 40): '"""/vsimem/subdir"""'}, {}), "('/vsimem/subdir')", False, 'from osgeo import gdal\n'), ((2247, 4, 2247, 57), 'osgeo.gdal.FileFromMemBuffer', 'gdal.FileFromMemBuffer', ({(2247, 27, 2247, 49): '"""/vsimem/testsync.txt"""', (2247, 51, 2247, 56): '"""foo"""'}, {}), "('/vsimem/testsync.txt', 'foo')", False, 'from osgeo import gdal\n'), ((2250, 4, 2250, 28), 'osgeo.gdal.VSICurlClearCache', 'gdal.VSICurlClearCache', ({}, {}), '()', False, 'from osgeo import gdal\n'), ((2251, 14, 2251, 43), 'webserver.SequentialHandler', 'webserver.SequentialHandler', ({}, {}), '()', False, 'import webserver\n'), ((2264, 4, 2264, 28), 'osgeo.gdal.VSICurlClearCache', 'gdal.VSICurlClearCache', ({}, {}), '()', False, 'from osgeo import gdal\n'), ((2265, 14, 2265, 43), 'webserver.SequentialHandler', 'webserver.SequentialHandler', ({}, {}), '()', False, 'import webserver\n'), ((2275, 4, 2275, 28), 'osgeo.gdal.VSICurlClearCache', 'gdal.VSICurlClearCache', ({}, {}), '()', False, 'from osgeo import gdal\n'), ((2276, 14, 2276, 43), 'webserver.SequentialHandler', 'webserver.SequentialHandler', ({}, {}), '()', False, 'import webserver\n'), ((2287, 4, 2287, 28), 'osgeo.gdal.VSICurlClearCache', 'gdal.VSICurlClearCache', ({}, {}), '()', False, 'from osgeo import gdal\n'), ((2288, 14, 2288, 43), 'webserver.SequentialHandler', 'webserver.SequentialHandler', ({}, {}), '()', False, 'import webserver\n'), ((2297, 4, 2297, 39), 'osgeo.gdal.Unlink', 'gdal.Unlink', ({(2297, 16, 2297, 38): '"""/vsimem/testsync.txt"""'}, {}), "('/vsimem/testsync.txt')", False, 'from osgeo import gdal\n'), ((2310, 4, 2310, 57), 'osgeo.gdal.FileFromMemBuffer', 'gdal.FileFromMemBuffer', ({(2310, 27, 2310, 49): '"""/vsimem/testsync.txt"""', (2310, 51, 2310, 56): '"""foo"""'}, {}), "('/vsimem/testsync.txt', 'foo')", False, 'from osgeo import gdal\n'), ((2313, 4, 2313, 28), 'osgeo.gdal.VSICurlClearCache', 'gdal.VSICurlClearCache', ({}, {}), '()', False, 'from osgeo import gdal\n'), ((2314, 14, 2314, 43), 'webserver.SequentialHandler', 'webserver.SequentialHandler', ({}, {}), '()', False, 'import webserver\n'), ((2327, 4, 2327, 28), 'osgeo.gdal.VSICurlClearCache', 'gdal.VSICurlClearCache', ({}, {}), '()', False, 'from osgeo import gdal\n'), ((2328, 14, 2328, 43), 'webserver.SequentialHandler', 'webserver.SequentialHandler', ({}, {}), '()', False, 'import webserver\n'), ((2338, 4, 2338, 39), 'osgeo.gdal.Unlink', 'gdal.Unlink', ({(2338, 16, 2338, 38): '"""/vsimem/testsync.txt"""'}, {}), "('/vsimem/testsync.txt')", False, 'from osgeo import gdal\n'), ((2349, 4, 2349, 28), 'osgeo.gdal.VSICurlClearCache', 'gdal.VSICurlClearCache', ({}, {}), '()', False, 'from osgeo import gdal\n'), ((2350, 14, 2350, 43), 'webserver.SequentialHandler', 'webserver.SequentialHandler', ({}, {}), '()', False, 'import webserver\n'), ((2387, 4, 2387, 28), 'osgeo.gdal.VSICurlClearCache', 'gdal.VSICurlClearCache', ({}, {}), '()', False, 'from osgeo import gdal\n'), ((2388, 14, 2388, 43), 'webserver.SequentialHandler', 'webserver.SequentialHandler', ({}, {}), '()', False, 'import webserver\n'), ((2423, 4, 2423, 28), 'osgeo.gdal.VSICurlClearCache', 'gdal.VSICurlClearCache', ({}, {}), '()', False, 'from osgeo import gdal\n'), ((2424, 14, 2424, 43), 'webserver.SequentialHandler', 'webserver.SequentialHandler', ({}, {}), '()', False, 'import webserver\n'), ((2488, 4, 2488, 28), 'osgeo.gdal.VSICurlClearCache', 'gdal.VSICurlClearCache', ({}, {}), '()', False, 'from osgeo import gdal\n'), ((2489, 14, 2489, 43), 'webserver.SequentialHandler', 'webserver.SequentialHandler', ({}, {}), '()', False, 'import webserver\n'), ((2508, 4, 2508, 28), 'osgeo.gdal.VSICurlClearCache', 'gdal.VSICurlClearCache', ({}, {}), '()', False, 'from osgeo import gdal\n'), ((2515, 4, 2515, 33), 'osgeo.gdal.Mkdir', 'gdal.Mkdir', ({(2515, 15, 2515, 29): '"""/vsimem/test"""', (2515, 31, 2515, 32): '(0)'}, {}), "('/vsimem/test', 0)", False, 'from osgeo import gdal\n'), ((2516, 4, 2516, 55), 'osgeo.gdal.FileFromMemBuffer', 'gdal.FileFromMemBuffer', ({(2516, 27, 2516, 45): '"""/vsimem/test/foo"""', (2516, 47, 2516, 54): '"""foo\n"""'}, {}), "('/vsimem/test/foo', 'foo\\n')", False, 'from osgeo import gdal\n'), ((2519, 14, 2519, 43), 'webserver.SequentialHandler', 'webserver.SequentialHandler', ({}, {}), '()', False, 'import webserver\n'), ((2604, 4, 2604, 39), 'osgeo.gdal.RmdirRecursive', 'gdal.RmdirRecursive', ({(2604, 24, 2604, 38): '"""/vsimem/test"""'}, {}), "('/vsimem/test')", False, 'from osgeo import gdal\n'), ((2612, 4, 2612, 28), 'osgeo.gdal.VSICurlClearCache', 'gdal.VSICurlClearCache', ({}, {}), '()', False, 'from osgeo import gdal\n'), ((2614, 4, 2614, 33), 'osgeo.gdal.Mkdir', 'gdal.Mkdir', ({(2614, 15, 2614, 29): '"""/vsimem/test"""', (2614, 31, 2614, 32): '(0)'}, {}), "('/vsimem/test', 0)", False, 'from osgeo import gdal\n'), ((2615, 4, 2615, 55), 'osgeo.gdal.FileFromMemBuffer', 'gdal.FileFromMemBuffer', ({(2615, 27, 2615, 45): '"""/vsimem/test/foo"""', (2615, 47, 2615, 54): '"""foo\n"""'}, {}), "('/vsimem/test/foo', 'foo\\n')", False, 'from osgeo import gdal\n'), ((2617, 14, 2617, 43), 'webserver.SequentialHandler', 'webserver.SequentialHandler', ({}, {}), '()', False, 'import webserver\n'), ((2659, 4, 2659, 39), 'osgeo.gdal.RmdirRecursive', 'gdal.RmdirRecursive', ({(2659, 24, 2659, 38): '"""/vsimem/test"""'}, {}), "('/vsimem/test')", False, 'from osgeo import gdal\n'), ((2670, 4, 2670, 28), 'osgeo.gdal.VSICurlClearCache', 'gdal.VSICurlClearCache', ({}, {}), '()', False, 'from osgeo import gdal\n'), ((2673, 14, 2673, 43), 'webserver.SequentialHandler', 'webserver.SequentialHandler', ({}, {}), '()', False, 'import webserver\n'), ((2680, 14, 2680, 43), 'webserver.SequentialHandler', 'webserver.SequentialHandler', ({}, {}), '()', False, 'import webserver\n'), ((2688, 14, 2688, 43), 'webserver.SequentialHandler', 'webserver.SequentialHandler', ({}, {}), '()', False, 'import webserver\n'), ((2706, 14, 2706, 43), 'webserver.SequentialHandler', 'webserver.SequentialHandler', ({}, {}), '()', False, 'import webserver\n'), ((2737, 14, 2737, 43), 'webserver.SequentialHandler', 'webserver.SequentialHandler', ({}, {}), '()', False, 'import webserver\n'), ((2760, 4, 2760, 28), 'osgeo.gdal.VSICurlClearCache', 'gdal.VSICurlClearCache', ({}, {}), '()', False, 'from osgeo import gdal\n'), ((2762, 14, 2762, 43), 'webserver.SequentialHandler', 'webserver.SequentialHandler', ({}, {}), '()', False, 'import webserver\n'), ((2785, 4, 2785, 28), 'osgeo.gdal.VSICurlClearCache', 'gdal.VSICurlClearCache', ({}, {}), '()', False, 'from osgeo import gdal\n'), ((2799, 14, 2799, 43), 'webserver.SequentialHandler', 'webserver.SequentialHandler', ({}, {}), '()', False, 'import webserver\n'), ((2812, 4, 2812, 28), 'osgeo.gdal.VSICurlClearCache', 'gdal.VSICurlClearCache', ({}, {}), '()', False, 'from osgeo import gdal\n'), ((2818, 14, 2818, 43), 'webserver.SequentialHandler', 'webserver.SequentialHandler', ({}, {}), '()', False, 'import webserver\n'), ((2833, 4, 2833, 28), 'osgeo.gdal.VSICurlClearCache', 'gdal.VSICurlClearCache', ({}, {}), '()', False, 'from osgeo import gdal\n'), ((2841, 14, 2841, 43), 'webserver.SequentialHandler', 'webserver.SequentialHandler', ({}, {}), '()', False, 'import webserver\n'), ((2855, 4, 2855, 28), 'osgeo.gdal.VSICurlClearCache', 'gdal.VSICurlClearCache', ({}, {}), '()', False, 'from osgeo import gdal\n'), ((2857, 14, 2857, 43), 'webserver.SequentialHandler', 'webserver.SequentialHandler', ({}, {}), '()', False, 'import webserver\n'), ((2862, 13, 2862, 39), 'osgeo.gdal.Open', 'gdal.Open', ({(2862, 23, 2862, 38): '"""data/byte.tif"""'}, {}), "('data/byte.tif')", False, 'from osgeo import gdal\n'), ((2869, 14, 2869, 43), 'webserver.SequentialHandler', 'webserver.SequentialHandler', ({}, {}), '()', False, 'import webserver\n'), ((2883, 4, 2883, 53), 'osgeo.gdal.SetConfigOption', 'gdal.SetConfigOption', ({(2883, 25, 2883, 48): '"""AWS_SECRET_ACCESS_KEY"""', (2883, 50, 2883, 52): '""""""'}, {}), "('AWS_SECRET_ACCESS_KEY', '')", False, 'from osgeo import gdal\n'), ((2884, 4, 2884, 49), 'osgeo.gdal.SetConfigOption', 'gdal.SetConfigOption', ({(2884, 25, 2884, 44): '"""AWS_ACCESS_KEY_ID"""', (2884, 46, 2884, 48): '""""""'}, {}), "('AWS_ACCESS_KEY_ID', '')", False, 'from osgeo import gdal\n'), ((2886, 4, 2886, 79), 'osgeo.gdal.SetConfigOption', 'gdal.SetConfigOption', ({(2886, 25, 2886, 51): '"""CPL_AWS_CREDENTIALS_FILE"""', (2886, 53, 2886, 78): '"""/vsimem/aws_credentials"""'}, {}), "('CPL_AWS_CREDENTIALS_FILE', '/vsimem/aws_credentials')", False, 'from osgeo import gdal\n'), ((2888, 4, 2888, 28), 'osgeo.gdal.VSICurlClearCache', 'gdal.VSICurlClearCache', ({}, {}), '()', False, 'from osgeo import gdal\n'), ((2890, 4, 2900, 4), 'osgeo.gdal.FileFromMemBuffer', 'gdal.FileFromMemBuffer', ({(2890, 27, 2890, 52): '"""/vsimem/aws_credentials"""', (2890, 54, 2900, 3): '"""\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    )', False, 'from osgeo import gdal\n'), ((2902, 14, 2902, 43), 'webserver.SequentialHandler', 'webserver.SequentialHandler', ({}, {}), '()', False, 'import webserver\n'), ((2912, 4, 2912, 56), 'osgeo.gdal.SetConfigOption', 'gdal.SetConfigOption', ({(2912, 25, 2912, 51): '"""CPL_AWS_CREDENTIALS_FILE"""', (2912, 53, 2912, 55): '""""""'}, {}), "('CPL_AWS_CREDENTIALS_FILE', '')", False, 'from osgeo import gdal\n'), ((2913, 4, 2913, 42), 'osgeo.gdal.Unlink', 'gdal.Unlink', ({(2913, 16, 2913, 41): '"""/vsimem/aws_credentials"""'}, {}), "('/vsimem/aws_credentials')", False, 'from osgeo import gdal\n'), ((2924, 4, 2924, 53), 'osgeo.gdal.SetConfigOption', 'gdal.SetConfigOption', ({(2924, 25, 2924, 48): '"""AWS_SECRET_ACCESS_KEY"""', (2924, 50, 2924, 52): '""""""'}, {}), "('AWS_SECRET_ACCESS_KEY', '')", False, 'from osgeo import gdal\n'), ((2925, 4, 2925, 49), 'osgeo.gdal.SetConfigOption', 'gdal.SetConfigOption', ({(2925, 25, 2925, 44): '"""AWS_ACCESS_KEY_ID"""', (2925, 46, 2925, 48): '""""""'}, {}), "('AWS_ACCESS_KEY_ID', '')", False, 'from osgeo import gdal\n'), ((2927, 4, 2927, 65), 'osgeo.gdal.SetConfigOption', 'gdal.SetConfigOption', ({(2927, 25, 2927, 42): '"""AWS_CONFIG_FILE"""', (2927, 44, 2927, 64): '"""/vsimem/aws_config"""'}, {}), "('AWS_CONFIG_FILE', '/vsimem/aws_config')", False, 'from osgeo import gdal\n'), ((2929, 4, 2929, 28), 'osgeo.gdal.VSICurlClearCache', 'gdal.VSICurlClearCache', ({}, {}), '()', False, 'from osgeo import gdal\n'), ((2931, 4, 2942, 4), 'osgeo.gdal.FileFromMemBuffer', 'gdal.FileFromMemBuffer', ({(2931, 27, 2931, 47): '"""/vsimem/aws_config"""', (2931, 49, 2942, 3): '"""\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    )', False, 'from osgeo import gdal\n'), ((2944, 14, 2944, 43), 'webserver.SequentialHandler', 'webserver.SequentialHandler', ({}, {}), '()', False, 'import webserver\n'), ((2954, 4, 2954, 47), 'osgeo.gdal.SetConfigOption', 'gdal.SetConfigOption', ({(2954, 25, 2954, 42): '"""AWS_CONFIG_FILE"""', (2954, 44, 2954, 46): '""""""'}, {}), "('AWS_CONFIG_FILE', '')", False, 'from osgeo import gdal\n'), ((2955, 4, 2955, 37), 'osgeo.gdal.Unlink', 'gdal.Unlink', ({(2955, 16, 2955, 36): '"""/vsimem/aws_config"""'}, {}), "('/vsimem/aws_config')", False, 'from osgeo import gdal\n'), ((2966, 4, 2966, 53), 'osgeo.gdal.SetConfigOption', 'gdal.SetConfigOption', ({(2966, 25, 2966, 48): '"""AWS_SECRET_ACCESS_KEY"""', (2966, 50, 2966, 52): '""""""'}, {}), "('AWS_SECRET_ACCESS_KEY', '')", False, 'from osgeo import gdal\n'), ((2967, 4, 2967, 49), 'osgeo.gdal.SetConfigOption', 'gdal.SetConfigOption', ({(2967, 25, 2967, 44): '"""AWS_ACCESS_KEY_ID"""', (2967, 46, 2967, 48): '""""""'}, {}), "('AWS_ACCESS_KEY_ID', '')", False, 'from osgeo import gdal\n'), ((2969, 4, 2969, 79), 'osgeo.gdal.SetConfigOption', 'gdal.SetConfigOption', ({(2969, 25, 2969, 51): '"""CPL_AWS_CREDENTIALS_FILE"""', (2969, 53, 2969, 78): '"""/vsimem/aws_credentials"""'}, {}), "('CPL_AWS_CREDENTIALS_FILE', '/vsimem/aws_credentials')", False, 'from osgeo import gdal\n'), ((2970, 4, 2970, 65), 'osgeo.gdal.SetConfigOption', 'gdal.SetConfigOption', ({(2970, 25, 2970, 42): '"""AWS_CONFIG_FILE"""', (2970, 44, 2970, 64): '"""/vsimem/aws_config"""'}, {}), "('AWS_CONFIG_FILE', '/vsimem/aws_config')", False, 'from osgeo import gdal\n'), ((2972, 4, 2972, 28), 'osgeo.gdal.VSICurlClearCache', 'gdal.VSICurlClearCache', ({}, {}), '()', False, 'from osgeo import gdal\n'), ((2974, 4, 2984, 4), 'osgeo.gdal.FileFromMemBuffer', 'gdal.FileFromMemBuffer', ({(2974, 27, 2974, 52): '"""/vsimem/aws_credentials"""', (2974, 54, 2984, 3): '"""\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    )', False, 'from osgeo import gdal\n'), ((2986, 4, 2997, 4), 'osgeo.gdal.FileFromMemBuffer', 'gdal.FileFromMemBuffer', ({(2986, 27, 2986, 47): '"""/vsimem/aws_config"""', (2986, 49, 2997, 3): '"""\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    )', False, 'from osgeo import gdal\n'), ((2999, 14, 2999, 43), 'webserver.SequentialHandler', 'webserver.SequentialHandler', ({}, {}), '()', False, 'import webserver\n'), ((3009, 4, 3009, 56), 'osgeo.gdal.SetConfigOption', 'gdal.SetConfigOption', ({(3009, 25, 3009, 51): '"""CPL_AWS_CREDENTIALS_FILE"""', (3009, 53, 3009, 55): '""""""'}, {}), "('CPL_AWS_CREDENTIALS_FILE', '')", False, 'from osgeo import gdal\n'), ((3010, 4, 3010, 42), 'osgeo.gdal.Unlink', 'gdal.Unlink', ({(3010, 16, 3010, 41): '"""/vsimem/aws_credentials"""'}, {}), "('/vsimem/aws_credentials')", False, 'from osgeo import gdal\n'), ((3011, 4, 3011, 47), 'osgeo.gdal.SetConfigOption', 'gdal.SetConfigOption', ({(3011, 25, 3011, 42): '"""AWS_CONFIG_FILE"""', (3011, 44, 3011, 46): '""""""'}, {}), "('AWS_CONFIG_FILE', '')", False, 'from osgeo import gdal\n'), ((3012, 4, 3012, 37), 'osgeo.gdal.Unlink', 'gdal.Unlink', ({(3012, 16, 3012, 36): '"""/vsimem/aws_config"""'}, {}), "('/vsimem/aws_config')", False, 'from osgeo import gdal\n'), ((3024, 4, 3024, 53), 'osgeo.gdal.SetConfigOption', 'gdal.SetConfigOption', ({(3024, 25, 3024, 48): '"""AWS_SECRET_ACCESS_KEY"""', (3024, 50, 3024, 52): '""""""'}, {}), "('AWS_SECRET_ACCESS_KEY', '')", False, 'from osgeo import gdal\n'), ((3025, 4, 3025, 49), 'osgeo.gdal.SetConfigOption', 'gdal.SetConfigOption', ({(3025, 25, 3025, 44): '"""AWS_ACCESS_KEY_ID"""', (3025, 46, 3025, 48): '""""""'}, {}), "('AWS_ACCESS_KEY_ID', '')", False, 'from osgeo import gdal\n'), ((3026, 4, 3026, 58), 'osgeo.gdal.SetConfigOption', 'gdal.SetConfigOption', ({(3026, 25, 3026, 51): '"""CPL_AWS_CREDENTIALS_FILE"""', (3026, 53, 3026, 57): 'None'}, {}), "('CPL_AWS_CREDENTIALS_FILE', None)", False, 'from osgeo import gdal\n'), ((3027, 4, 3027, 49), 'osgeo.gdal.SetConfigOption', 'gdal.SetConfigOption', ({(3027, 25, 3027, 42): '"""AWS_CONFIG_FILE"""', (3027, 44, 3027, 48): 'None'}, {}), "('AWS_CONFIG_FILE', None)", False, 'from osgeo import gdal\n'), ((3028, 4, 3028, 52), 'osgeo.gdal.SetConfigOption', 'gdal.SetConfigOption', ({(3028, 25, 3028, 38): '"""AWS_PROFILE"""', (3028, 40, 3028, 51): '"""myprofile"""'}, {}), "('AWS_PROFILE', 'myprofile')", False, 'from osgeo import gdal\n'), ((3032, 4, 3032, 28), 'osgeo.gdal.VSICurlClearCache', 'gdal.VSICurlClearCache', ({}, {}), '()', False, 'from osgeo import gdal\n'), ((3057, 14, 3057, 43), 'webserver.SequentialHandler', 'webserver.SequentialHandler', ({}, {}), '()', False, 'import webserver\n'), ((3070, 4, 3070, 43), 'osgeo.gdal.SetConfigOption', 'gdal.SetConfigOption', ({(3070, 25, 3070, 38): '"""AWS_PROFILE"""', (3070, 40, 3070, 42): '""""""'}, {}), "('AWS_PROFILE', '')", False, 'from osgeo import gdal\n'), ((3081, 4, 3081, 53), 'osgeo.gdal.SetConfigOption', 'gdal.SetConfigOption', ({(3081, 25, 3081, 48): '"""AWS_SECRET_ACCESS_KEY"""', (3081, 50, 3081, 52): '""""""'}, {}), "('AWS_SECRET_ACCESS_KEY', '')", False, 'from osgeo import gdal\n'), ((3082, 4, 3082, 49), 'osgeo.gdal.SetConfigOption', 'gdal.SetConfigOption', ({(3082, 25, 3082, 44): '"""AWS_ACCESS_KEY_ID"""', (3082, 46, 3082, 48): '""""""'}, {}), "('AWS_ACCESS_KEY_ID', '')", False, 'from osgeo import gdal\n'), ((3084, 4, 3084, 79), 'osgeo.gdal.SetConfigOption', 'gdal.SetConfigOption', ({(3084, 25, 3084, 51): '"""CPL_AWS_CREDENTIALS_FILE"""', (3084, 53, 3084, 78): '"""/vsimem/aws_credentials"""'}, {}), "('CPL_AWS_CREDENTIALS_FILE', '/vsimem/aws_credentials')", False, 'from osgeo import gdal\n'), ((3085, 4, 3085, 65), 'osgeo.gdal.SetConfigOption', 'gdal.SetConfigOption', ({(3085, 25, 3085, 42): '"""AWS_CONFIG_FILE"""', (3085, 44, 3085, 64): '"""/vsimem/aws_config"""'}, {}), "('AWS_CONFIG_FILE', '/vsimem/aws_config')", False, 'from osgeo import gdal\n'), ((3087, 4, 3087, 28), 'osgeo.gdal.VSICurlClearCache', 'gdal.VSICurlClearCache', ({}, {}), '()', False, 'from osgeo import gdal\n'), ((3089, 4, 3099, 4), 'osgeo.gdal.FileFromMemBuffer', 'gdal.FileFromMemBuffer', ({(3089, 27, 3089, 52): '"""/vsimem/aws_credentials"""', (3089, 54, 3099, 3): '"""\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    )', False, 'from osgeo import gdal\n'), ((3101, 4, 3112, 4), 'osgeo.gdal.FileFromMemBuffer', 'gdal.FileFromMemBuffer', ({(3101, 27, 3101, 47): '"""/vsimem/aws_config"""', (3101, 49, 3112, 3): '"""\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    )', False, 'from osgeo import gdal\n'), ((3114, 4, 3114, 21), 'osgeo.gdal.ErrorReset', 'gdal.ErrorReset', ({}, {}), '()', False, 'from osgeo import gdal\n'), ((3115, 14, 3115, 43), 'webserver.SequentialHandler', 'webserver.SequentialHandler', ({}, {}), '()', False, 'import webserver\n'), ((3127, 4, 3127, 56), 'osgeo.gdal.SetConfigOption', 'gdal.SetConfigOption', ({(3127, 25, 3127, 51): '"""CPL_AWS_CREDENTIALS_FILE"""', (3127, 53, 3127, 55): '""""""'}, {}), "('CPL_AWS_CREDENTIALS_FILE', '')", False, 'from osgeo import gdal\n'), ((3128, 4, 3128, 42), 'osgeo.gdal.Unlink', 'gdal.Unlink', ({(3128, 16, 3128, 41): '"""/vsimem/aws_credentials"""'}, {}), "('/vsimem/aws_credentials')", False, 'from osgeo import gdal\n'), ((3129, 4, 3129, 47), 'osgeo.gdal.SetConfigOption', 'gdal.SetConfigOption', ({(3129, 25, 3129, 42): '"""AWS_CONFIG_FILE"""', (3129, 44, 3129, 46): '""""""'}, {}), "('AWS_CONFIG_FILE', '')", False, 'from osgeo import gdal\n'), ((3130, 4, 3130, 37), 'osgeo.gdal.Unlink', 'gdal.Unlink', ({(3130, 16, 3130, 36): '"""/vsimem/aws_config"""'}, {}), "('/vsimem/aws_config')", False, 'from osgeo import gdal\n'), ((3144, 4, 3144, 56), 'osgeo.gdal.SetConfigOption', 'gdal.SetConfigOption', ({(3144, 25, 3144, 51): '"""CPL_AWS_CREDENTIALS_FILE"""', (3144, 53, 3144, 55): '""""""'}, {}), "('CPL_AWS_CREDENTIALS_FILE', '')", False, 'from osgeo import gdal\n'), ((3145, 4, 3145, 47), 'osgeo.gdal.SetConfigOption', 'gdal.SetConfigOption', ({(3145, 25, 3145, 42): '"""AWS_CONFIG_FILE"""', (3145, 44, 3145, 46): '""""""'}, {}), "('AWS_CONFIG_FILE', '')", False, 'from osgeo import gdal\n'), ((3146, 4, 3146, 53), 'osgeo.gdal.SetConfigOption', 'gdal.SetConfigOption', ({(3146, 25, 3146, 48): '"""AWS_SECRET_ACCESS_KEY"""', (3146, 50, 3146, 52): '""""""'}, {}), "('AWS_SECRET_ACCESS_KEY', '')", False, 'from osgeo import gdal\n'), ((3147, 4, 3147, 49), 'osgeo.gdal.SetConfigOption', 'gdal.SetConfigOption', ({(3147, 25, 3147, 44): '"""AWS_ACCESS_KEY_ID"""', (3147, 46, 3147, 48): '""""""'}, {}), "('AWS_ACCESS_KEY_ID', '')", False, 'from osgeo import gdal\n'), ((3149, 4, 3150, 73), 'osgeo.gdal.SetConfigOption', 'gdal.SetConfigOption', ({(3149, 25, 3149, 51): '"""CPL_AWS_EC2_API_ROOT_URL"""', (3150, 25, 3150, 72): "('http://localhost:%d' % gdaltest.webserver_port)"}, {}), "('CPL_AWS_EC2_API_ROOT_URL', 'http://localhost:%d' %\n    gdaltest.webserver_port)", False, 'from osgeo import gdal\n'), ((3152, 4, 3152, 56), 'osgeo.gdal.SetConfigOption', 'gdal.SetConfigOption', ({(3152, 25, 3152, 49): '"""CPL_AWS_AUTODETECT_EC2"""', (3152, 51, 3152, 55): '"""NO"""'}, {}), "('CPL_AWS_AUTODETECT_EC2', 'NO')", False, 'from osgeo import gdal\n'), ((3154, 4, 3154, 28), 'osgeo.gdal.VSICurlClearCache', 'gdal.VSICurlClearCache', ({}, {}), '()', False, 'from osgeo import gdal\n'), ((3156, 14, 3156, 43), 'webserver.SequentialHandler', 'webserver.SequentialHandler', ({}, {}), '()', False, 'import webserver\n'), ((3179, 4, 3179, 56), 'osgeo.gdal.SetConfigOption', 'gdal.SetConfigOption', ({(3179, 25, 3179, 51): '"""CPL_AWS_EC2_API_ROOT_URL"""', (3179, 53, 3179, 55): '""""""'}, {}), "('CPL_AWS_EC2_API_ROOT_URL', '')", False, 'from osgeo import gdal\n'), ((3181, 14, 3181, 43), 'webserver.SequentialHandler', 'webserver.SequentialHandler', ({}, {}), '()', False, 'import webserver\n'), ((3191, 4, 3191, 56), 'osgeo.gdal.SetConfigOption', 'gdal.SetConfigOption', ({(3191, 25, 3191, 51): '"""CPL_AWS_EC2_API_ROOT_URL"""', (3191, 53, 3191, 55): '""""""'}, {}), "('CPL_AWS_EC2_API_ROOT_URL', '')", False, 'from osgeo import gdal\n'), ((3192, 4, 3192, 56), 'osgeo.gdal.SetConfigOption', 'gdal.SetConfigOption', ({(3192, 25, 3192, 49): '"""CPL_AWS_AUTODETECT_EC2"""', (3192, 51, 3192, 55): 'None'}, {}), "('CPL_AWS_AUTODETECT_EC2', None)", False, 'from osgeo import gdal\n'), ((3206, 4, 3206, 56), 'osgeo.gdal.SetConfigOption', 'gdal.SetConfigOption', ({(3206, 25, 3206, 51): '"""CPL_AWS_CREDENTIALS_FILE"""', (3206, 53, 3206, 55): '""""""'}, {}), "('CPL_AWS_CREDENTIALS_FILE', '')", False, 'from osgeo import gdal\n'), ((3207, 4, 3207, 47), 'osgeo.gdal.SetConfigOption', 'gdal.SetConfigOption', ({(3207, 25, 3207, 42): '"""AWS_CONFIG_FILE"""', (3207, 44, 3207, 46): '""""""'}, {}), "('AWS_CONFIG_FILE', '')", False, 'from osgeo import gdal\n'), ((3208, 4, 3208, 53), 'osgeo.gdal.SetConfigOption', 'gdal.SetConfigOption', ({(3208, 25, 3208, 48): '"""AWS_SECRET_ACCESS_KEY"""', (3208, 50, 3208, 52): '""""""'}, {}), "('AWS_SECRET_ACCESS_KEY', '')", False, 'from osgeo import gdal\n'), ((3209, 4, 3209, 49), 'osgeo.gdal.SetConfigOption', 'gdal.SetConfigOption', ({(3209, 25, 3209, 44): '"""AWS_ACCESS_KEY_ID"""', (3209, 46, 3209, 48): '""""""'}, {}), "('AWS_ACCESS_KEY_ID', '')", False, 'from osgeo import gdal\n'), ((3211, 4, 3212, 73), 'osgeo.gdal.SetConfigOption', 'gdal.SetConfigOption', ({(3211, 25, 3211, 51): '"""CPL_AWS_EC2_API_ROOT_URL"""', (3212, 25, 3212, 72): "('http://localhost:%d' % gdaltest.webserver_port)"}, {}), "('CPL_AWS_EC2_API_ROOT_URL', 'http://localhost:%d' %\n    gdaltest.webserver_port)", False, 'from osgeo import gdal\n'), ((3214, 4, 3214, 56), 'osgeo.gdal.SetConfigOption', 'gdal.SetConfigOption', ({(3214, 25, 3214, 49): '"""CPL_AWS_AUTODETECT_EC2"""', (3214, 51, 3214, 55): '"""NO"""'}, {}), "('CPL_AWS_AUTODETECT_EC2', 'NO')", False, 'from osgeo import gdal\n'), ((3216, 4, 3216, 28), 'osgeo.gdal.VSICurlClearCache', 'gdal.VSICurlClearCache', ({}, {}), '()', False, 'from osgeo import gdal\n'), ((3218, 14, 3218, 43), 'webserver.SequentialHandler', 'webserver.SequentialHandler', ({}, {}), '()', False, 'import webserver\n'), ((3240, 4, 3240, 56), 'osgeo.gdal.SetConfigOption', 'gdal.SetConfigOption', ({(3240, 25, 3240, 51): '"""CPL_AWS_EC2_API_ROOT_URL"""', (3240, 53, 3240, 55): '""""""'}, {}), "('CPL_AWS_EC2_API_ROOT_URL', '')", False, 'from osgeo import gdal\n'), ((3241, 4, 3241, 56), 'osgeo.gdal.SetConfigOption', 'gdal.SetConfigOption', ({(3241, 25, 3241, 49): '"""CPL_AWS_AUTODETECT_EC2"""', (3241, 51, 3241, 55): 'None'}, {}), "('CPL_AWS_AUTODETECT_EC2', None)", False, 'from osgeo import gdal\n'), ((3256, 4, 3256, 56), 'osgeo.gdal.SetConfigOption', 'gdal.SetConfigOption', ({(3256, 25, 3256, 51): '"""CPL_AWS_CREDENTIALS_FILE"""', (3256, 53, 3256, 55): '""""""'}, {}), "('CPL_AWS_CREDENTIALS_FILE', '')", False, 'from osgeo import gdal\n'), ((3257, 4, 3257, 47), 'osgeo.gdal.SetConfigOption', 'gdal.SetConfigOption', ({(3257, 25, 3257, 42): '"""AWS_CONFIG_FILE"""', (3257, 44, 3257, 46): '""""""'}, {}), "('AWS_CONFIG_FILE', '')", False, 'from osgeo import gdal\n'), ((3258, 4, 3258, 53), 'osgeo.gdal.SetConfigOption', 'gdal.SetConfigOption', ({(3258, 25, 3258, 48): '"""AWS_SECRET_ACCESS_KEY"""', (3258, 50, 3258, 52): '""""""'}, {}), "('AWS_SECRET_ACCESS_KEY', '')", False, 'from osgeo import gdal\n'), ((3259, 4, 3259, 49), 'osgeo.gdal.SetConfigOption', 'gdal.SetConfigOption', ({(3259, 25, 3259, 44): '"""AWS_ACCESS_KEY_ID"""', (3259, 46, 3259, 48): '""""""'}, {}), "('AWS_ACCESS_KEY_ID', '')", False, 'from osgeo import gdal\n'), ((3261, 4, 3262, 73), 'osgeo.gdal.SetConfigOption', 'gdal.SetConfigOption', ({(3261, 25, 3261, 51): '"""CPL_AWS_EC2_API_ROOT_URL"""', (3262, 25, 3262, 72): "('http://localhost:%d' % gdaltest.webserver_port)"}, {}), "('CPL_AWS_EC2_API_ROOT_URL', 'http://localhost:%d' %\n    gdaltest.webserver_port)", False, 'from osgeo import gdal\n'), ((3264, 4, 3264, 56), 'osgeo.gdal.SetConfigOption', 'gdal.SetConfigOption', ({(3264, 25, 3264, 49): '"""CPL_AWS_AUTODETECT_EC2"""', (3264, 51, 3264, 55): '"""NO"""'}, {}), "('CPL_AWS_AUTODETECT_EC2', 'NO')", False, 'from osgeo import gdal\n'), ((3266, 4, 3266, 28), 'osgeo.gdal.VSICurlClearCache', 'gdal.VSICurlClearCache', ({}, {}), '()', False, 'from osgeo import gdal\n'), ((3268, 14, 3268, 43), 'webserver.SequentialHandler', 'webserver.SequentialHandler', ({}, {}), '()', False, 'import webserver\n'), ((3299, 4, 3300, 81), 'osgeo.gdal.SetConfigOption', 'gdal.SetConfigOption', ({(3299, 25, 3299, 51): '"""CPL_AWS_EC2_API_ROOT_URL"""', (3300, 25, 3300, 80): "('http://localhost:%d/invalid' % gdaltest.webserver_port)"}, {}), "('CPL_AWS_EC2_API_ROOT_URL', \n    'http://localhost:%d/invalid' % gdaltest.webserver_port)", False, 'from osgeo import gdal\n'), ((3302, 14, 3302, 43), 'webserver.SequentialHandler', 'webserver.SequentialHandler', ({}, {}), '()', False, 'import webserver\n'), ((3310, 4, 3310, 56), 'osgeo.gdal.SetConfigOption', 'gdal.SetConfigOption', ({(3310, 25, 3310, 51): '"""CPL_AWS_EC2_API_ROOT_URL"""', (3310, 53, 3310, 55): '""""""'}, {}), "('CPL_AWS_EC2_API_ROOT_URL', '')", False, 'from osgeo import gdal\n'), ((3311, 4, 3311, 56), 'osgeo.gdal.SetConfigOption', 'gdal.SetConfigOption', ({(3311, 25, 3311, 49): '"""CPL_AWS_AUTODETECT_EC2"""', (3311, 51, 3311, 55): 'None'}, {}), "('CPL_AWS_AUTODETECT_EC2', None)", False, 'from osgeo import gdal\n'), ((3323, 4, 3323, 28), 'osgeo.gdal.VSICurlClearCache', 'gdal.VSICurlClearCache', ({}, {}), '()', False, 'from osgeo import gdal\n'), ((3325, 4, 3325, 78), 'webserver.server_stop', 'webserver.server_stop', ({(3325, 26, 3325, 52): 'gdaltest.webserver_process', (3325, 54, 3325, 77): 'gdaltest.webserver_port'}, {}), '(gdaltest.webserver_process, gdaltest.webserver_port)', False, 'import webserver\n'), ((3340, 18, 3340, 53), 'osgeo.gdal.GetConfigOption', 'gdal.GetConfigOption', ({(3340, 39, 3340, 52): '"""S3_RESOURCE"""'}, {}), "('S3_RESOURCE')", False, 'from osgeo import gdal\n'), ((3424, 10, 3424, 33), 'osgeo.gdal.VSIFReadL', 'gdal.VSIFReadL', ({(3424, 25, 3424, 26): '1', (3424, 28, 3424, 29): '1', (3424, 31, 3424, 32): 'f'}, {}), '(1, 1, f)', False, 'from osgeo import gdal\n'), ((3425, 4, 3425, 22), 'osgeo.gdal.VSIFCloseL', 'gdal.VSIFCloseL', ({(3425, 20, 3425, 21): 'f'}, {}), '(f)', False, 'from osgeo import gdal\n'), ((3432, 10, 3432, 33), 'osgeo.gdal.VSIFReadL', 'gdal.VSIFReadL', ({(3432, 25, 3432, 26): '1', (3432, 28, 3432, 29): '1', (3432, 31, 3432, 32): 'f'}, {}), '(1, 1, f)', False, 'from osgeo import gdal\n'), ((3433, 4, 3433, 22), 'osgeo.gdal.VSIFCloseL', 'gdal.VSIFCloseL', ({(3433, 20, 3433, 21): 'f'}, {}), '(f)', False, 'from osgeo import gdal\n'), ((3448, 4, 3448, 21), 'osgeo.gdal.ErrorReset', 'gdal.ErrorReset', ({}, {}), '()', False, 'from osgeo import gdal\n'), ((3450, 22, 3450, 47), 'osgeo.gdal.VSIGetLastErrorMsg', 'gdal.VSIGetLastErrorMsg', ({}, {}), '()', False, 'from osgeo import gdal\n'), ((3453, 17, 3453, 59), 'osgeo.gdal.GetSignedURL', 'gdal.GetSignedURL', ({(3453, 35, 3453, 58): "'/vsis3/' + s3_resource"}, {}), "('/vsis3/' + s3_resource)", False, 'from osgeo import gdal\n'), ((3456, 10, 3456, 33), 'osgeo.gdal.VSIFReadL', 'gdal.VSIFReadL', ({(3456, 25, 3456, 26): '1', (3456, 28, 3456, 29): '1', (3456, 31, 3456, 32): 'f'}, {}), '(1, 1, f)', False, 'from osgeo import gdal\n'), ((3457, 4, 3457, 22), 'osgeo.gdal.VSIFCloseL', 'gdal.VSIFCloseL', ({(3457, 20, 3457, 21): 'f'}, {}), '(f)', False, 'from osgeo import gdal\n'), ((3469, 4, 3469, 58), 'osgeo.gdal.SetConfigOption', 'gdal.SetConfigOption', ({(3469, 25, 3469, 51): '"""CPL_AWS_CREDENTIALS_FILE"""', (3469, 53, 3469, 57): 'None'}, {}), "('CPL_AWS_CREDENTIALS_FILE', None)", False, 'from osgeo import gdal\n'), ((3470, 4, 3470, 49), 'osgeo.gdal.SetConfigOption', 'gdal.SetConfigOption', ({(3470, 25, 3470, 42): '"""AWS_CONFIG_FILE"""', (3470, 44, 3470, 48): 'None'}, {}), "('AWS_CONFIG_FILE', None)", False, 'from osgeo import gdal\n'), ((3471, 4, 3471, 58), 'osgeo.gdal.SetConfigOption', 'gdal.SetConfigOption', ({(3471, 25, 3471, 51): '"""CPL_AWS_EC2_API_ROOT_URL"""', (3471, 53, 3471, 57): 'None'}, {}), "('CPL_AWS_EC2_API_ROOT_URL', None)", False, 'from osgeo import gdal\n'), ((56, 33, 56, 58), 'osgeo.gdal.GetConfigOption', 'gdal.GetConfigOption', ({(56, 54, 56, 57): 'var'}, {}), '(var)', False, 'from osgeo import gdal\n'), ((66, 11, 66, 46), 'osgeo.gdal.GetSignedURL', 'gdal.GetSignedURL', ({(66, 29, 66, 45): '"""/vsis3/foo/bar"""'}, {}), "('/vsis3/foo/bar')", False, 'from osgeo import gdal\n'), ((74, 11, 74, 40), 'gdaltest.built_against_curl', 'gdaltest.built_against_curl', ({}, {}), '()', False, 'import gdaltest\n'), ((75, 8, 75, 21), 'pytest.skip', 'pytest.skip', ({}, {}), '()', False, 'import pytest\n'), ((77, 9, 77, 61), 'gdaltest.config_option', 'gdaltest.config_option', ({(77, 32, 77, 53): '"""AWS_NO_SIGN_REQUEST"""', (77, 55, 77, 60): '"""YES"""'}, {}), "('AWS_NO_SIGN_REQUEST', 'YES')", False, 'import gdaltest\n'), ((78, 21, 78, 122), 'osgeo.gdal.GetActualURL', 'gdal.GetActualURL', ({(78, 39, 78, 121): '"""/vsis3/landsat-pds/L8/001/002/LC80010022016230LGN00/LC80010022016230LGN00_B1.TIF"""'}, {}), "(\n    '/vsis3/landsat-pds/L8/001/002/LC80010022016230LGN00/LC80010022016230LGN00_B1.TIF'\n    )", False, 'from osgeo import gdal\n'), ((81, 21, 81, 132), 'osgeo.gdal.GetActualURL', 'gdal.GetActualURL', ({(81, 39, 81, 131): '"""/vsis3_streaming/landsat-pds/L8/001/002/LC80010022016230LGN00/LC80010022016230LGN00_B1.TIF"""'}, {}), "(\n    '/vsis3_streaming/landsat-pds/L8/001/002/LC80010022016230LGN00/LC80010022016230LGN00_B1.TIF'\n    )", False, 'from osgeo import gdal\n'), ((89, 8, 89, 21), 'pytest.fail', 'pytest.fail', ({}, {}), '()', False, 'import pytest\n'), ((99, 11, 99, 40), 'gdaltest.built_against_curl', 'gdaltest.built_against_curl', ({}, {}), '()', False, 'import gdaltest\n'), ((100, 8, 100, 21), 'pytest.skip', 'pytest.skip', ({}, {}), '()', False, 'import pytest\n'), ((109, 9, 109, 61), 'gdaltest.config_option', 'gdaltest.config_option', ({(109, 32, 109, 53): '"""AWS_NO_SIGN_REQUEST"""', (109, 55, 109, 60): '"""YES"""'}, {}), "('AWS_NO_SIGN_REQUEST', 'YES')", False, 'import gdaltest\n'), ((110, 15, 113, 57), 'osgeo.gdal.Sync', 'gdal.Sync', (), '', False, 'from osgeo import gdal\n'), ((126, 11, 126, 40), 'gdaltest.built_against_curl', 'gdaltest.built_against_curl', ({}, {}), '()', False, 'import gdaltest\n'), ((127, 8, 127, 21), 'pytest.skip', 'pytest.skip', ({}, {}), '()', False, 'import pytest\n'), ((136, 9, 136, 61), 'gdaltest.config_option', 'gdaltest.config_option', ({(136, 32, 136, 53): '"""AWS_NO_SIGN_REQUEST"""', (136, 55, 136, 60): '"""YES"""'}, {}), "('AWS_NO_SIGN_REQUEST', 'YES')", False, 'import gdaltest\n'), ((137, 15, 140, 57), 'osgeo.gdal.Sync', 'gdal.Sync', (), '', False, 'from osgeo import gdal\n'), ((153, 11, 153, 40), 'gdaltest.built_against_curl', 'gdaltest.built_against_curl', ({}, {}), '()', False, 'import gdaltest\n'), ((154, 8, 154, 21), 'pytest.skip', 'pytest.skip', ({}, {}), '()', False, 'import pytest\n'), ((158, 9, 158, 33), 'gdaltest.error_handler', 'gdaltest.error_handler', ({}, {}), '()', False, 'import gdaltest\n'), ((163, 9, 163, 33), 'gdaltest.error_handler', 'gdaltest.error_handler', ({}, {}), '()', False, 'import gdaltest\n'), ((171, 9, 171, 33), 'gdaltest.error_handler', 'gdaltest.error_handler', ({}, {}), '()', False, 'import gdaltest\n'), ((179, 9, 179, 33), 'gdaltest.error_handler', 'gdaltest.error_handler', ({}, {}), '()', False, 'import gdaltest\n'), ((189, 9, 189, 33), 'gdaltest.error_handler', 'gdaltest.error_handler', ({}, {}), '()', False, 'import gdaltest\n'), ((201, 11, 201, 40), 'gdaltest.built_against_curl', 'gdaltest.built_against_curl', ({}, {}), '()', False, 'import gdaltest\n'), ((202, 8, 202, 21), 'pytest.skip', 'pytest.skip', ({}, {}), '()', False, 'import pytest\n'), ((206, 8, 206, 21), 'pytest.skip', 'pytest.skip', ({}, {}), '()', False, 'import pytest\n'), ((244, 8, 244, 21), 'pytest.skip', 'pytest.skip', ({}, {}), '()', False, 'import pytest\n'), ((254, 9, 254, 48), 'webserver.install_http_handler', 'webserver.install_http_handler', ({(254, 40, 254, 47): 'handler'}, {}), '(handler)', False, 'import webserver\n'), ((258, 8, 258, 26), 'osgeo.gdal.VSIFCloseL', 'gdal.VSIFCloseL', ({(258, 24, 258, 25): 'f'}, {}), '(f)', False, 'from osgeo import gdal\n'), ((264, 9, 264, 48), 'webserver.install_http_handler', 'webserver.install_http_handler', ({(264, 40, 264, 47): 'handler'}, {}), '(handler)', False, 'import webserver\n'), ((268, 8, 268, 26), 'osgeo.gdal.VSIFCloseL', 'gdal.VSIFCloseL', ({(268, 24, 268, 25): 'f'}, {}), '(f)', False, 'from osgeo import gdal\n'), ((297, 9, 297, 73), 'gdaltest.config_option', 'gdaltest.config_option', ({(297, 32, 297, 51): '"""AWS_SESSION_TOKEN"""', (297, 53, 297, 72): '"""AWS_SESSION_TOKEN"""'}, {}), "('AWS_SESSION_TOKEN', 'AWS_SESSION_TOKEN')", False, 'import gdaltest\n'), ((330, 9, 330, 48), 'webserver.install_http_handler', 'webserver.install_http_handler', ({(330, 40, 330, 47): 'handler'}, {}), '(handler)', False, 'import webserver\n'), ((333, 19, 333, 71), 'osgeo.gdal.VSIStatL', 'gdal.VSIStatL', ({(333, 33, 333, 70): '"""/vsis3/s3_fake_bucket/resource2.bin"""'}, {}), "('/vsis3/s3_fake_bucket/resource2.bin')", False, 'from osgeo import gdal\n'), ((347, 9, 347, 48), 'webserver.install_http_handler', 'webserver.install_http_handler', ({(347, 40, 347, 47): 'handler'}, {}), '(handler)', False, 'import webserver\n'), ((348, 19, 348, 81), 'osgeo.gdal.VSIStatL', 'gdal.VSIStatL', ({(348, 33, 348, 80): '"""/vsis3_streaming/s3_fake_bucket/resource2.bin"""'}, {}), "('/vsis3_streaming/s3_fake_bucket/resource2.bin')", False, 'from osgeo import gdal\n'), ((354, 8, 354, 21), 'pytest.fail', 'pytest.fail', ({}, {}), '()', False, 'import pytest\n'), ((408, 9, 408, 48), 'webserver.install_http_handler', 'webserver.install_http_handler', ({(408, 40, 408, 47): 'handler'}, {}), '(handler)', False, 'import webserver\n'), ((412, 8, 412, 26), 'osgeo.gdal.VSIFCloseL', 'gdal.VSIFCloseL', ({(412, 24, 412, 25): 'f'}, {}), '(f)', False, 'from osgeo import gdal\n'), ((416, 11, 416, 46), 'gdaltest.is_travis_branch', 'gdaltest.is_travis_branch', ({(416, 37, 416, 45): '"""trusty"""'}, {}), "('trusty')", False, 'import gdaltest\n'), ((419, 8, 419, 25), 'pytest.fail', 'pytest.fail', ({(419, 20, 419, 24): 'data'}, {}), '(data)', False, 'import pytest\n'), ((425, 9, 425, 48), 'webserver.install_http_handler', 'webserver.install_http_handler', ({(425, 40, 425, 47): 'handler'}, {}), '(handler)', False, 'import webserver\n'), ((429, 8, 429, 26), 'osgeo.gdal.VSIFCloseL', 'gdal.VSIFCloseL', ({(429, 24, 429, 25): 'f'}, {}), '(f)', False, 'from osgeo import gdal\n'), ((455, 9, 455, 48), 'webserver.install_http_handler', 'webserver.install_http_handler', ({(455, 40, 455, 47): 'handler'}, {}), '(handler)', False, 'import webserver\n'), ((468, 9, 468, 48), 'webserver.install_http_handler', 'webserver.install_http_handler', ({(468, 40, 468, 47): 'handler'}, {}), '(handler)', False, 'import webserver\n'), ((481, 9, 481, 48), 'webserver.install_http_handler', 'webserver.install_http_handler', ({(481, 40, 481, 47): 'handler'}, {}), '(handler)', False, 'import webserver\n'), ((494, 9, 494, 48), 'webserver.install_http_handler', 'webserver.install_http_handler', ({(494, 40, 494, 47): 'handler'}, {}), '(handler)', False, 'import webserver\n'), ((507, 9, 507, 48), 'webserver.install_http_handler', 'webserver.install_http_handler', ({(507, 40, 507, 47): 'handler'}, {}), '(handler)', False, 'import webserver\n'), ((520, 9, 520, 48), 'webserver.install_http_handler', 'webserver.install_http_handler', ({(520, 40, 520, 47): 'handler'}, {}), '(handler)', False, 'import webserver\n'), ((553, 9, 553, 65), 'gdaltest.config_option', 'gdaltest.config_option', ({(553, 32, 553, 51): '"""AWS_REQUEST_PAYER"""', (553, 53, 553, 64): '"""requester"""'}, {}), "('AWS_REQUEST_PAYER', 'requester')", False, 'import gdaltest\n'), ((606, 9, 606, 48), 'webserver.install_http_handler', 'webserver.install_http_handler', ({(606, 40, 606, 47): 'handler'}, {}), '(handler)', False, 'import webserver\n'), ((610, 8, 610, 26), 'osgeo.gdal.VSIFCloseL', 'gdal.VSIFCloseL', ({(610, 24, 610, 25): 'f'}, {}), '(f)', False, 'from osgeo import gdal\n'), ((621, 9, 621, 48), 'webserver.install_http_handler', 'webserver.install_http_handler', ({(621, 40, 621, 47): 'handler'}, {}), '(handler)', False, 'import webserver\n'), ((625, 8, 625, 26), 'osgeo.gdal.VSIFCloseL', 'gdal.VSIFCloseL', ({(625, 24, 625, 25): 'f'}, {}), '(f)', False, 'from osgeo import gdal\n'), ((636, 8, 636, 21), 'pytest.skip', 'pytest.skip', ({}, {}), '()', False, 'import pytest\n'), ((643, 9, 643, 48), 'webserver.install_http_handler', 'webserver.install_http_handler', ({(643, 40, 643, 47): 'handler'}, {}), '(handler)', False, 'import webserver\n'), ((653, 9, 653, 70), 'gdaltest.config_option', 'gdaltest.config_option', ({(653, 32, 653, 51): '"""AWS_ACCESS_KEY_ID"""', (653, 53, 653, 69): '"""another_key_id"""'}, {}), "('AWS_ACCESS_KEY_ID', 'another_key_id')", False, 'import gdaltest\n'), ((654, 18, 654, 47), 'webserver.SequentialHandler', 'webserver.SequentialHandler', ({}, {}), '()', False, 'import webserver\n'), ((680, 8, 680, 21), 'pytest.skip', 'pytest.skip', ({}, {}), '()', False, 'import pytest\n'), ((766, 9, 766, 48), 'webserver.install_http_handler', 'webserver.install_http_handler', ({(766, 40, 766, 47): 'handler'}, {}), '(handler)', False, 'import webserver\n'), ((770, 11, 770, 46), 'gdaltest.is_travis_branch', 'gdaltest.is_travis_branch', ({(770, 37, 770, 45): '"""trusty"""'}, {}), "('trusty')", False, 'import gdaltest\n'), ((773, 8, 773, 21), 'pytest.fail', 'pytest.fail', ({}, {}), '()', False, 'import pytest\n'), ((777, 23, 777, 78), 'osgeo.gdal.ReadDir', 'gdal.ReadDir', ({(777, 36, 777, 77): '"""/vsis3/s3_fake_bucket2/a_dir with_space"""'}, {}), "('/vsis3/s3_fake_bucket2/a_dir with_space')", False, 'from osgeo import gdal\n'), ((805, 9, 805, 48), 'webserver.install_http_handler', 'webserver.install_http_handler', ({(805, 40, 805, 47): 'handler'}, {}), '(handler)', False, 'import webserver\n'), ((806, 8, 806, 89), 'osgeo.gdal.VSIStatL', 'gdal.VSIStatL', ({(806, 22, 806, 88): '"""/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')", False, 'from osgeo import gdal\n'), ((820, 9, 820, 48), 'webserver.install_http_handler', 'webserver.install_http_handler', ({(820, 40, 820, 47): 'handler'}, {}), '(handler)', False, 'import webserver\n'), ((821, 23, 821, 67), 'osgeo.gdal.ReadDir', 'gdal.ReadDir', ({(821, 36, 821, 66): '"""/vsis3/s3_fake_bucket2/a_dir"""'}, {}), "('/vsis3/s3_fake_bucket2/a_dir')", False, 'from osgeo import gdal\n'), ((846, 9, 846, 77), 'gdaltest.config_option', 'gdaltest.config_option', ({(846, 32, 846, 70): '"""CPL_VSIL_CURL_IGNORE_GLACIER_STORAGE"""', (846, 72, 846, 76): '"""NO"""'}, {}), "('CPL_VSIL_CURL_IGNORE_GLACIER_STORAGE', 'NO')", False, 'import gdaltest\n'), ((946, 9, 946, 48), 'webserver.install_http_handler', 'webserver.install_http_handler', ({(946, 40, 946, 47): 'handler'}, {}), '(handler)', False, 'import webserver\n'), ((947, 23, 947, 46), 'osgeo.gdal.ReadDir', 'gdal.ReadDir', ({(947, 36, 947, 45): '"""/vsis3/"""'}, {}), "('/vsis3/')", False, 'from osgeo import gdal\n'), ((964, 9, 964, 48), 'webserver.install_http_handler', 'webserver.install_http_handler', ({(964, 40, 964, 47): 'handler'}, {}), '(handler)', False, 'import webserver\n'), ((965, 23, 965, 46), 'osgeo.gdal.ReadDir', 'gdal.ReadDir', ({(965, 36, 965, 45): '"""/vsis3/"""'}, {}), "('/vsis3/')", False, 'from osgeo import gdal\n'), ((1019, 9, 1019, 48), 'webserver.install_http_handler', 'webserver.install_http_handler', ({(1019, 40, 1019, 47): 'handler'}, {}), '(handler)', False, 'import webserver\n'), ((1020, 23, 1020, 81), 'osgeo.gdal.ReadDir', 'gdal.ReadDir', ({(1020, 36, 1020, 80): '"""/vsis3/s3_test_temporary_redirect_read_dir"""'}, {}), "('/vsis3/s3_test_temporary_redirect_read_dir')", False, 'from osgeo import gdal\n'), ((1037, 9, 1037, 48), 'webserver.install_http_handler', 'webserver.install_http_handler', ({(1037, 40, 1037, 47): 'handler'}, {}), '(handler)', False, 'import webserver\n'), ((1038, 23, 1038, 86), 'osgeo.gdal.ReadDir', 'gdal.ReadDir', ({(1038, 36, 1038, 85): '"""/vsis3/s3_test_temporary_redirect_read_dir/test"""'}, {}), "('/vsis3/s3_test_temporary_redirect_read_dir/test')", False, 'from osgeo import gdal\n'), ((1048, 8, 1048, 21), 'pytest.skip', 'pytest.skip', ({}, {}), '()', False, 'import pytest\n'), ((1074, 9, 1074, 48), 'webserver.install_http_handler', 'webserver.install_http_handler', ({(1074, 40, 1074, 47): 'handler'}, {}), '(handler)', False, 'import webserver\n'), ((1075, 12, 1075, 48), 'osgeo.gdal.OpenDir', 'gdal.OpenDir', ({(1075, 25, 1075, 47): '"""/vsis3/vsis3_opendir"""'}, {}), "('/vsis3/vsis3_opendir')", False, 'from osgeo import gdal\n'), ((1113, 9, 1113, 48), 'webserver.install_http_handler', 'webserver.install_http_handler', ({(1113, 40, 1113, 47): 'handler'}, {}), '(handler)', False, 'import webserver\n'), ((1114, 12, 1114, 51), 'osgeo.gdal.OpenDir', 'gdal.OpenDir', ({(1114, 25, 1114, 47): '"""/vsis3/vsis3_opendir"""', (1114, 49, 1114, 50): '0'}, {}), "('/vsis3/vsis3_opendir', 0)", False, 'from osgeo import gdal\n'), ((1149, 9, 1149, 48), 'webserver.install_http_handler', 'webserver.install_http_handler', ({(1149, 40, 1149, 47): 'handler'}, {}), '(handler)', False, 'import webserver\n'), ((1150, 12, 1150, 51), 'osgeo.gdal.OpenDir', 'gdal.OpenDir', ({(1150, 25, 1150, 47): '"""/vsis3/vsis3_opendir"""', (1150, 49, 1150, 50): '1'}, {}), "('/vsis3/vsis3_opendir', 1)", False, 'from osgeo import gdal\n'), ((1176, 9, 1176, 48), 'webserver.install_http_handler', 'webserver.install_http_handler', ({(1176, 40, 1176, 47): 'handler'}, {}), '(handler)', False, 'import webserver\n'), ((1177, 16, 1177, 39), 'osgeo.gdal.GetNextDirEntry', 'gdal.GetNextDirEntry', ({(1177, 37, 1177, 38): 'd'}, {}), '(d)', False, 'from osgeo import gdal\n'), ((1192, 8, 1192, 21), 'pytest.skip', 'pytest.skip', ({}, {}), '()', False, 'import pytest\n'), ((1201, 9, 1201, 48), 'webserver.install_http_handler', 'webserver.install_http_handler', ({(1201, 40, 1201, 47): 'handler'}, {}), '(handler)', False, 'import webserver\n'), ((1219, 9, 1219, 48), 'webserver.install_http_handler', 'webserver.install_http_handler', ({(1219, 40, 1219, 47): 'handler'}, {}), '(handler)', False, 'import webserver\n'), ((1220, 12, 1220, 73), 'osgeo.gdal.VSIFOpenL', 'gdal.VSIFOpenL', ({(1220, 27, 1220, 66): '"""/vsis3/s3_fake_bucket3/empty_file.bin"""', (1220, 68, 1220, 72): '"""wb"""'}, {}), "('/vsis3/s3_fake_bucket3/empty_file.bin', 'wb')", False, 'from osgeo import gdal\n'), ((1222, 8, 1222, 25), 'osgeo.gdal.ErrorReset', 'gdal.ErrorReset', ({}, {}), '()', False, 'from osgeo import gdal\n'), ((1223, 8, 1223, 26), 'osgeo.gdal.VSIFCloseL', 'gdal.VSIFCloseL', ({(1223, 24, 1223, 25): 'f'}, {}), '(f)', False, 'from osgeo import gdal\n'), ((1224, 11, 1224, 33), 'osgeo.gdal.GetLastErrorMsg', 'gdal.GetLastErrorMsg', ({}, {}), '()', False, 'from osgeo import gdal\n'), ((1228, 9, 1228, 48), 'webserver.install_http_handler', 'webserver.install_http_handler', ({(1228, 40, 1228, 47): 'handler'}, {}), '(handler)', False, 'import webserver\n'), ((1233, 9, 1233, 48), 'webserver.install_http_handler', 'webserver.install_http_handler', ({(1233, 40, 1233, 47): 'handler'}, {}), '(handler)', False, 'import webserver\n'), ((1234, 12, 1234, 73), 'osgeo.gdal.VSIFOpenL', 'gdal.VSIFOpenL', ({(1234, 27, 1234, 66): '"""/vsis3/s3_fake_bucket3/empty_file.bin"""', (1234, 68, 1234, 72): '"""wb"""'}, {}), "('/vsis3/s3_fake_bucket3/empty_file.bin', 'wb')", False, 'from osgeo import gdal\n'), ((1239, 8, 1239, 26), 'osgeo.gdal.VSIFCloseL', 'gdal.VSIFCloseL', ({(1239, 24, 1239, 25): 'f'}, {}), '(f)', False, 'from osgeo import gdal\n'), ((1243, 9, 1243, 48), 'webserver.install_http_handler', 'webserver.install_http_handler', ({(1243, 40, 1243, 47): 'handler'}, {}), '(handler)', False, 'import webserver\n'), ((1244, 12, 1244, 73), 'osgeo.gdal.VSIFOpenL', 'gdal.VSIFOpenL', ({(1244, 27, 1244, 66): '"""/vsis3/s3_fake_bucket3/empty_file.bin"""', (1244, 68, 1244, 72): '"""wb"""'}, {}), "('/vsis3/s3_fake_bucket3/empty_file.bin', 'wb')", False, 'from osgeo import gdal\n'), ((1249, 8, 1249, 26), 'osgeo.gdal.VSIFCloseL', 'gdal.VSIFCloseL', ({(1249, 24, 1249, 25): 'f'}, {}), '(f)', False, 'from osgeo import gdal\n'), ((1254, 9, 1254, 48), 'webserver.install_http_handler', 'webserver.install_http_handler', ({(1254, 40, 1254, 47): 'handler'}, {}), '(handler)', False, 'import webserver\n'), ((1255, 12, 1255, 79), 'osgeo.gdal.VSIFOpenL', 'gdal.VSIFOpenL', ({(1255, 27, 1255, 72): '"""/vsis3/s3_fake_bucket3/empty_file_error.bin"""', (1255, 74, 1255, 78): '"""wb"""'}, {}), "('/vsis3/s3_fake_bucket3/empty_file_error.bin', 'wb')", False, 'from osgeo import gdal\n'), ((1257, 8, 1257, 25), 'osgeo.gdal.ErrorReset', 'gdal.ErrorReset', ({}, {}), '()', False, 'from osgeo import gdal\n'), ((1260, 11, 1260, 33), 'osgeo.gdal.GetLastErrorMsg', 'gdal.GetLastErrorMsg', ({}, {}), '()', False, 'from osgeo import gdal\n'), ((1265, 9, 1265, 72), 'gdaltest.config_option', 'gdaltest.config_option', ({(1265, 32, 1265, 64): '"""CPL_VSIL_NETWORK_STATS_ENABLED"""', (1265, 66, 1265, 71): '"""YES"""'}, {}), "('CPL_VSIL_NETWORK_STATS_ENABLED', 'YES')", False, 'import gdaltest\n'), ((1276, 18, 1276, 47), 'webserver.SequentialHandler', 'webserver.SequentialHandler', ({}, {}), '()', False, 'import webserver\n'), ((1302, 8, 1302, 25), 'osgeo.gdal.ErrorReset', 'gdal.ErrorReset', ({}, {}), '()', False, 'from osgeo import gdal\n'), ((1307, 19, 1307, 57), 'osgeo.gdal.NetworkStatsGetAsSerializedJSON', 'gdal.NetworkStatsGetAsSerializedJSON', ({}, {}), '()', False, 'from osgeo import gdal\n'), ((1352, 12, 1352, 67), 'osgeo.gdal.VSIFOpenL', 'gdal.VSIFOpenL', ({(1352, 27, 1352, 60): '"""/vsis3/s3_fake_bucket3/redirect"""', (1352, 62, 1352, 66): '"""wb"""'}, {}), "('/vsis3/s3_fake_bucket3/redirect', 'wb')", False, 'from osgeo import gdal\n'), ((1396, 9, 1396, 48), 'webserver.install_http_handler', 'webserver.install_http_handler', ({(1396, 40, 1396, 47): 'handler'}, {}), '(handler)', False, 'import webserver\n'), ((1397, 8, 1397, 26), 'osgeo.gdal.VSIFCloseL', 'gdal.VSIFCloseL', ({(1397, 24, 1397, 25): 'f'}, {}), '(f)', False, 'from osgeo import gdal\n'), ((1398, 11, 1398, 33), 'osgeo.gdal.GetLastErrorMsg', 'gdal.GetLastErrorMsg', ({}, {}), '()', False, 'from osgeo import gdal\n'), ((1407, 8, 1407, 21), 'pytest.skip', 'pytest.skip', ({}, {}), '()', False, 'import pytest\n'), ((1409, 9, 1410, 67), 'gdaltest.config_options', 'gdaltest.config_options', ({(1409, 33, 1410, 66): "{'GDAL_HTTP_MAX_RETRY': '2', 'GDAL_HTTP_RETRY_DELAY': '0.01'}"}, {}), "({'GDAL_HTTP_MAX_RETRY': '2',\n    'GDAL_HTTP_RETRY_DELAY': '0.01'})", False, 'import gdaltest\n'), ((1417, 18, 1417, 47), 'webserver.SequentialHandler', 'webserver.SequentialHandler', ({}, {}), '()', False, 'import webserver\n'), ((1456, 8, 1456, 21), 'pytest.skip', 'pytest.skip', ({}, {}), '()', False, 'import pytest\n'), ((1465, 9, 1465, 48), 'webserver.install_http_handler', 'webserver.install_http_handler', ({(1465, 40, 1465, 47): 'handler'}, {}), '(handler)', False, 'import webserver\n'), ((1469, 9, 1469, 48), 'webserver.install_http_handler', 'webserver.install_http_handler', ({(1469, 40, 1469, 47): 'handler'}, {}), '(handler)', False, 'import webserver\n'), ((1474, 9, 1474, 48), 'webserver.install_http_handler', 'webserver.install_http_handler', ({(1474, 40, 1474, 47): 'handler'}, {}), '(handler)', False, 'import webserver\n'), ((1475, 14, 1475, 64), 'osgeo.gdal.Unlink', 'gdal.Unlink', ({(1475, 26, 1475, 63): '"""/vsis3/s3_delete_bucket/delete_file"""'}, {}), "('/vsis3/s3_delete_bucket/delete_file')", False, 'from osgeo import gdal\n'), ((1481, 9, 1481, 48), 'webserver.install_http_handler', 'webserver.install_http_handler', ({(1481, 40, 1481, 47): 'handler'}, {}), '(handler)', False, 'import webserver\n'), ((1487, 9, 1487, 48), 'webserver.install_http_handler', 'webserver.install_http_handler', ({(1487, 40, 1487, 47): 'handler'}, {}), '(handler)', False, 'import webserver\n'), ((1519, 9, 1519, 48), 'webserver.install_http_handler', 'webserver.install_http_handler', ({(1519, 40, 1519, 47): 'handler'}, {}), '(handler)', False, 'import webserver\n'), ((1520, 14, 1520, 61), 'osgeo.gdal.Unlink', 'gdal.Unlink', ({(1520, 26, 1520, 60): '"""/vsis3/s3_delete_bucket/redirect"""'}, {}), "('/vsis3/s3_delete_bucket/redirect')", False, 'from osgeo import gdal\n'), ((1530, 8, 1530, 21), 'pytest.skip', 'pytest.skip', ({}, {}), '()', False, 'import pytest\n'), ((1566, 9, 1566, 67), 'gdaltest.config_option', 'gdaltest.config_option', ({(1566, 32, 1566, 61): '"""CPL_VSIS3_UNLINK_BATCH_SIZE"""', (1566, 63, 1566, 66): '"""2"""'}, {}), "('CPL_VSIS3_UNLINK_BATCH_SIZE', '2')", False, 'import gdaltest\n'), ((1575, 9, 1575, 48), 'webserver.install_http_handler', 'webserver.install_http_handler', ({(1575, 40, 1575, 47): 'handler'}, {}), '(handler)', False, 'import webserver\n'), ((1576, 14, 1576, 59), 'osgeo.gdal.UnlinkBatch', 'gdal.UnlinkBatch', ({(1576, 31, 1576, 58): "['/vsis3/unlink_batch/foo']"}, {}), "(['/vsis3/unlink_batch/foo'])", False, 'from osgeo import gdal\n'), ((1586, 8, 1586, 21), 'pytest.skip', 'pytest.skip', ({}, {}), '()', False, 'import pytest\n'), ((1664, 9, 1664, 67), 'gdaltest.config_option', 'gdaltest.config_option', ({(1664, 32, 1664, 61): '"""CPL_VSIS3_UNLINK_BATCH_SIZE"""', (1664, 63, 1664, 66): '"""2"""'}, {}), "('CPL_VSIS3_UNLINK_BATCH_SIZE', '2')", False, 'import gdaltest\n'), ((1676, 8, 1676, 21), 'pytest.skip', 'pytest.skip', ({}, {}), '()', False, 'import pytest\n'), ((1678, 9, 1678, 56), 'gdaltest.config_option', 'gdaltest.config_option', ({(1678, 32, 1678, 50): '"""VSIS3_CHUNK_SIZE"""', (1678, 52, 1678, 55): '"""1"""'}, {}), "('VSIS3_CHUNK_SIZE', '1')", False, 'import gdaltest\n'), ((1727, 9, 1727, 48), 'webserver.install_http_handler', 'webserver.install_http_handler', ({(1727, 40, 1727, 47): 'handler'}, {}), '(handler)', False, 'import webserver\n'), ((1728, 14, 1728, 53), 'osgeo.gdal.VSIFWriteL', 'gdal.VSIFWriteL', ({(1728, 30, 1728, 40): 'big_buffer', (1728, 42, 1728, 43): '1', (1728, 45, 1728, 49): 'size', (1728, 51, 1728, 52): 'f'}, {}), '(big_buffer, 1, size, f)', False, 'from osgeo import gdal\n'), ((1774, 9, 1774, 48), 'webserver.install_http_handler', 'webserver.install_http_handler', ({(1774, 40, 1774, 47): 'handler'}, {}), '(handler)', False, 'import webserver\n'), ((1775, 8, 1775, 26), 'osgeo.gdal.VSIFCloseL', 'gdal.VSIFCloseL', ({(1775, 24, 1775, 25): 'f'}, {}), '(f)', False, 'from osgeo import gdal\n'), ((1776, 11, 1776, 33), 'osgeo.gdal.GetLastErrorMsg', 'gdal.GetLastErrorMsg', ({}, {}), '()', False, 'from osgeo import gdal\n'), ((1783, 9, 1783, 48), 'webserver.install_http_handler', 'webserver.install_http_handler', ({(1783, 40, 1783, 47): 'handler'}, {}), '(handler)', False, 'import webserver\n'), ((1809, 9, 1809, 48), 'webserver.install_http_handler', 'webserver.install_http_handler', ({(1809, 40, 1809, 47): 'handler'}, {}), '(handler)', False, 'import webserver\n'), ((1830, 9, 1830, 48), 'webserver.install_http_handler', 'webserver.install_http_handler', ({(1830, 40, 1830, 47): 'handler'}, {}), '(handler)', False, 'import webserver\n'), ((1837, 8, 1837, 25), 'osgeo.gdal.ErrorReset', 'gdal.ErrorReset', ({}, {}), '()', False, 'from osgeo import gdal\n'), ((1852, 9, 1852, 48), 'webserver.install_http_handler', 'webserver.install_http_handler', ({(1852, 40, 1852, 47): 'handler'}, {}), '(handler)', False, 'import webserver\n'), ((1871, 8, 1871, 21), 'pytest.skip', 'pytest.skip', ({}, {}), '()', False, 'import pytest\n'), ((1873, 9, 1874, 67), 'gdaltest.config_options', 'gdaltest.config_options', ({(1873, 33, 1874, 66): "{'GDAL_HTTP_MAX_RETRY': '2', 'GDAL_HTTP_RETRY_DELAY': '0.01'}"}, {}), "({'GDAL_HTTP_MAX_RETRY': '2',\n    'GDAL_HTTP_RETRY_DELAY': '0.01'})", False, 'import gdaltest\n'), ((1883, 18, 1883, 47), 'webserver.SequentialHandler', 'webserver.SequentialHandler', ({}, {}), '()', False, 'import webserver\n'), ((1903, 18, 1903, 47), 'webserver.SequentialHandler', 'webserver.SequentialHandler', ({}, {}), '()', False, 'import webserver\n'), ((1927, 8, 1927, 21), 'pytest.skip', 'pytest.skip', ({}, {}), '()', False, 'import pytest\n'), ((1933, 9, 1933, 48), 'webserver.install_http_handler', 'webserver.install_http_handler', ({(1933, 40, 1933, 47): 'handler'}, {}), '(handler)', False, 'import webserver\n'), ((1934, 14, 1934, 62), 'osgeo.gdal.Mkdir', 'gdal.Mkdir', ({(1934, 25, 1934, 58): '"""/vsis3/s3_bucket_test_mkdir/dir"""', (1934, 60, 1934, 61): '0'}, {}), "('/vsis3/s3_bucket_test_mkdir/dir', 0)", False, 'from osgeo import gdal\n'), ((1945, 9, 1945, 48), 'webserver.install_http_handler', 'webserver.install_http_handler', ({(1945, 40, 1945, 47): 'handler'}, {}), '(handler)', False, 'import webserver\n'), ((1946, 14, 1946, 62), 'osgeo.gdal.Mkdir', 'gdal.Mkdir', ({(1946, 25, 1946, 58): '"""/vsis3/s3_bucket_test_mkdir/dir"""', (1946, 60, 1946, 61): '0'}, {}), "('/vsis3/s3_bucket_test_mkdir/dir', 0)", False, 'from osgeo import gdal\n'), ((1951, 9, 1951, 48), 'webserver.install_http_handler', 'webserver.install_http_handler', ({(1951, 40, 1951, 47): 'handler'}, {}), '(handler)', False, 'import webserver\n'), ((1952, 14, 1952, 59), 'osgeo.gdal.Rmdir', 'gdal.Rmdir', ({(1952, 25, 1952, 58): '"""/vsis3/s3_bucket_test_mkdir/dir"""'}, {}), "('/vsis3/s3_bucket_test_mkdir/dir')", False, 'from osgeo import gdal\n'), ((1959, 9, 1959, 48), 'webserver.install_http_handler', 'webserver.install_http_handler', ({(1959, 40, 1959, 47): 'handler'}, {}), '(handler)', False, 'import webserver\n'), ((1960, 14, 1960, 59), 'osgeo.gdal.Rmdir', 'gdal.Rmdir', ({(1960, 25, 1960, 58): '"""/vsis3/s3_bucket_test_mkdir/dir"""'}, {}), "('/vsis3/s3_bucket_test_mkdir/dir')", False, 'from osgeo import gdal\n'), ((1978, 9, 1978, 48), 'webserver.install_http_handler', 'webserver.install_http_handler', ({(1978, 40, 1978, 47): 'handler'}, {}), '(handler)', False, 'import webserver\n'), ((1979, 14, 1979, 68), 'osgeo.gdal.Rmdir', 'gdal.Rmdir', ({(1979, 25, 1979, 67): '"""/vsis3/s3_bucket_test_mkdir/dir_nonempty"""'}, {}), "('/vsis3/s3_bucket_test_mkdir/dir_nonempty')", False, 'from osgeo import gdal\n'), ((1997, 9, 1997, 48), 'webserver.install_http_handler', 'webserver.install_http_handler', ({(1997, 40, 1997, 47): 'handler'}, {}), '(handler)', False, 'import webserver\n'), ((2014, 9, 2014, 48), 'webserver.install_http_handler', 'webserver.install_http_handler', ({(2014, 40, 2014, 47): 'handler'}, {}), '(handler)', False, 'import webserver\n'), ((2032, 9, 2032, 48), 'webserver.install_http_handler', 'webserver.install_http_handler', ({(2032, 40, 2032, 47): 'handler'}, {}), '(handler)', False, 'import webserver\n'), ((2049, 9, 2049, 48), 'webserver.install_http_handler', 'webserver.install_http_handler', ({(2049, 40, 2049, 47): 'handler'}, {}), '(handler)', False, 'import webserver\n'), ((2060, 8, 2060, 21), 'pytest.skip', 'pytest.skip', ({}, {}), '()', False, 'import pytest\n'), ((2079, 9, 2079, 48), 'webserver.install_http_handler', 'webserver.install_http_handler', ({(2079, 40, 2079, 47): 'handler'}, {}), '(handler)', False, 'import webserver\n'), ((2080, 18, 2080, 51), 'osgeo.gdal.ReadDir', 'gdal.ReadDir', ({(2080, 31, 2080, 47): '"""/vsis3/vsis3_8"""', (2080, 49, 2080, 50): '0'}, {}), "('/vsis3/vsis3_8', 0)", False, 'from osgeo import gdal\n'), ((2084, 9, 2084, 48), 'webserver.install_http_handler', 'webserver.install_http_handler', ({(2084, 40, 2084, 47): 'handler'}, {}), '(handler)', False, 'import webserver\n'), ((2088, 9, 2088, 48), 'webserver.install_http_handler', 'webserver.install_http_handler', ({(2088, 40, 2088, 47): 'handler'}, {}), '(handler)', False, 'import webserver\n'), ((2099, 8, 2099, 21), 'pytest.skip', 'pytest.skip', ({}, {}), '()', False, 'import pytest\n'), ((2105, 9, 2105, 33), 'gdaltest.error_handler', 'gdaltest.error_handler', ({}, {}), '()', False, 'import gdaltest\n'), ((2106, 18, 2106, 47), 'webserver.SequentialHandler', 'webserver.SequentialHandler', ({}, {}), '()', False, 'import webserver\n'), ((2110, 9, 2110, 33), 'gdaltest.error_handler', 'gdaltest.error_handler', ({}, {}), '()', False, 'import gdaltest\n'), ((2111, 18, 2111, 47), 'webserver.SequentialHandler', 'webserver.SequentialHandler', ({}, {}), '()', False, 'import webserver\n'), ((2156, 9, 2156, 48), 'webserver.install_http_handler', 'webserver.install_http_handler', ({(2156, 40, 2156, 47): 'handler'}, {}), '(handler)', False, 'import webserver\n'), ((2157, 15, 2158, 57), 'osgeo.gdal.Sync', 'gdal.Sync', (), '', False, 'from osgeo import gdal\n'), ((2163, 9, 2163, 48), 'webserver.install_http_handler', 'webserver.install_http_handler', ({(2163, 40, 2163, 47): 'handler'}, {}), '(handler)', False, 'import webserver\n'), ((2164, 15, 2164, 79), 'osgeo.gdal.Sync', 'gdal.Sync', (), '', False, 'from osgeo import gdal\n'), ((2165, 15, 2165, 92), 'osgeo.gdal.Sync', 'gdal.Sync', (), '', False, 'from osgeo import gdal\n'), ((2175, 9, 2175, 48), 'webserver.install_http_handler', 'webserver.install_http_handler', ({(2175, 40, 2175, 47): 'handler'}, {}), '(handler)', False, 'import webserver\n'), ((2176, 15, 2176, 81), 'osgeo.gdal.Sync', 'gdal.Sync', (), '', False, 'from osgeo import gdal\n'), ((2180, 15, 2180, 81), 'osgeo.gdal.Sync', 'gdal.Sync', (), '', False, 'from osgeo import gdal\n'), ((2181, 15, 2181, 93), 'osgeo.gdal.Sync', 'gdal.Sync', (), '', False, 'from osgeo import gdal\n'), ((2190, 9, 2190, 48), 'webserver.install_http_handler', 'webserver.install_http_handler', ({(2190, 40, 2190, 47): 'handler'}, {}), '(handler)', False, 'import webserver\n'), ((2191, 15, 2191, 81), 'osgeo.gdal.Sync', 'gdal.Sync', (), '', False, 'from osgeo import gdal\n'), ((2207, 9, 2207, 48), 'webserver.install_http_handler', 'webserver.install_http_handler', ({(2207, 40, 2207, 47): 'handler'}, {}), '(handler)', False, 'import webserver\n'), ((2208, 15, 2208, 79), 'osgeo.gdal.Sync', 'gdal.Sync', (), '', False, 'from osgeo import gdal\n'), ((2232, 9, 2232, 48), 'webserver.install_http_handler', 'webserver.install_http_handler', ({(2232, 40, 2232, 47): 'handler'}, {}), '(handler)', False, 'import webserver\n'), ((2233, 15, 2233, 74), 'osgeo.gdal.Sync', 'gdal.Sync', (), '', False, 'from osgeo import gdal\n'), ((2243, 8, 2243, 21), 'pytest.skip', 'pytest.skip', ({}, {}), '()', False, 'import pytest\n'), ((2259, 9, 2259, 48), 'webserver.install_http_handler', 'webserver.install_http_handler', ({(2259, 40, 2259, 47): 'handler'}, {}), '(handler)', False, 'import webserver\n'), ((2260, 15, 2261, 41), 'osgeo.gdal.Sync', 'gdal.Sync', (), '', False, 'from osgeo import gdal\n'), ((2270, 9, 2270, 48), 'webserver.install_http_handler', 'webserver.install_http_handler', ({(2270, 40, 2270, 47): 'handler'}, {}), '(handler)', False, 'import webserver\n'), ((2271, 15, 2272, 41), 'osgeo.gdal.Sync', 'gdal.Sync', (), '', False, 'from osgeo import gdal\n'), ((2282, 9, 2282, 48), 'webserver.install_http_handler', 'webserver.install_http_handler', ({(2282, 40, 2282, 47): 'handler'}, {}), '(handler)', False, 'import webserver\n'), ((2283, 15, 2284, 41), 'osgeo.gdal.Sync', 'gdal.Sync', (), '', False, 'from osgeo import gdal\n'), ((2293, 9, 2293, 48), 'webserver.install_http_handler', 'webserver.install_http_handler', ({(2293, 40, 2293, 47): 'handler'}, {}), '(handler)', False, 'import webserver\n'), ((2294, 15, 2295, 41), 'osgeo.gdal.Sync', 'gdal.Sync', (), '', False, 'from osgeo import gdal\n'), ((2306, 8, 2306, 21), 'pytest.skip', 'pytest.skip', ({}, {}), '()', False, 'import pytest\n'), ((2322, 9, 2322, 48), 'webserver.install_http_handler', 'webserver.install_http_handler', ({(2322, 40, 2322, 47): 'handler'}, {}), '(handler)', False, 'import webserver\n'), ((2323, 15, 2324, 41), 'osgeo.gdal.Sync', 'gdal.Sync', (), '', False, 'from osgeo import gdal\n'), ((2334, 9, 2334, 48), 'webserver.install_http_handler', 'webserver.install_http_handler', ({(2334, 40, 2334, 47): 'handler'}, {}), '(handler)', False, 'import webserver\n'), ((2335, 15, 2336, 41), 'osgeo.gdal.Sync', 'gdal.Sync', (), '', False, 'from osgeo import gdal\n'), ((2347, 8, 2347, 21), 'pytest.skip', 'pytest.skip', ({}, {}), '()', False, 'import pytest\n'), ((2376, 9, 2376, 48), 'webserver.install_http_handler', 'webserver.install_http_handler', ({(2376, 40, 2376, 47): 'handler'}, {}), '(handler)', False, 'import webserver\n'), ((2377, 15, 2377, 66), 'osgeo.gdal.Sync', 'gdal.Sync', ({(2377, 26, 2377, 50): '"""/vsis3/in/testsync.txt"""', (2377, 52, 2377, 65): '"""/vsis3/out/"""'}, {}), "('/vsis3/in/testsync.txt', '/vsis3/out/')", False, 'from osgeo import gdal\n'), ((2385, 8, 2385, 21), 'pytest.skip', 'pytest.skip', ({}, {}), '()', False, 'import pytest\n'), ((2412, 9, 2412, 48), 'webserver.install_http_handler', 'webserver.install_http_handler', ({(2412, 40, 2412, 47): 'handler'}, {}), '(handler)', False, 'import webserver\n'), ((2421, 8, 2421, 21), 'pytest.skip', 'pytest.skip', ({}, {}), '()', False, 'import pytest\n'), ((2477, 9, 2477, 48), 'webserver.install_http_handler', 'webserver.install_http_handler', ({(2477, 40, 2477, 47): 'handler'}, {}), '(handler)', False, 'import webserver\n'), ((2486, 8, 2486, 21), 'pytest.skip', 'pytest.skip', ({}, {}), '()', False, 'import pytest\n'), ((2495, 9, 2495, 48), 'webserver.install_http_handler', 'webserver.install_http_handler', ({(2495, 40, 2495, 47): 'handler'}, {}), '(handler)', False, 'import webserver\n'), ((2506, 8, 2506, 21), 'pytest.skip', 'pytest.skip', ({}, {}), '()', False, 'import pytest\n'), ((2596, 9, 2596, 66), 'gdaltest.config_option', 'gdaltest.config_option', ({(2596, 32, 2596, 58): '"""VSIS3_SIMULATE_THREADING"""', (2596, 60, 2596, 65): '"""YES"""'}, {}), "('VSIS3_SIMULATE_THREADING', 'YES')", False, 'import gdaltest\n'), ((2610, 8, 2610, 21), 'pytest.skip', 'pytest.skip', ({}, {}), '()', False, 'import pytest\n'), ((2651, 9, 2652, 69), 'gdaltest.config_options', 'gdaltest.config_options', ({(2651, 33, 2652, 68): "{'VSIS3_SIMULATE_THREADING': 'YES', 'VSIS3_SYNC_MULTITHREADING': 'NO'}"}, {}), "({'VSIS3_SIMULATE_THREADING': 'YES',\n    'VSIS3_SYNC_MULTITHREADING': 'NO'})", False, 'import gdaltest\n'), ((2668, 8, 2668, 21), 'pytest.skip', 'pytest.skip', ({}, {}), '()', False, 'import pytest\n'), ((2675, 9, 2675, 48), 'webserver.install_http_handler', 'webserver.install_http_handler', ({(2675, 40, 2675, 47): 'handler'}, {}), '(handler)', False, 'import webserver\n'), ((2676, 13, 2676, 76), 'osgeo.gdal.GetFileMetadata', 'gdal.GetFileMetadata', ({(2676, 34, 2676, 64): '"""/vsis3/test_metadata/foo.txt"""', (2676, 66, 2676, 75): '"""HEADERS"""'}, {}), "('/vsis3/test_metadata/foo.txt', 'HEADERS')", False, 'from osgeo import gdal\n'), ((2683, 9, 2683, 48), 'webserver.install_http_handler', 'webserver.install_http_handler', ({(2683, 40, 2683, 47): 'handler'}, {}), '(handler)', False, 'import webserver\n'), ((2684, 13, 2684, 73), 'osgeo.gdal.GetFileMetadata', 'gdal.GetFileMetadata', ({(2684, 34, 2684, 64): '"""/vsis3/test_metadata/foo.txt"""', (2684, 66, 2684, 72): '"""TAGS"""'}, {}), "('/vsis3/test_metadata/foo.txt', 'TAGS')", False, 'from osgeo import gdal\n'), ((2701, 9, 2701, 48), 'webserver.install_http_handler', 'webserver.install_http_handler', ({(2701, 40, 2701, 47): 'handler'}, {}), '(handler)', False, 'import webserver\n'), ((2702, 15, 2702, 94), 'osgeo.gdal.SetFileMetadata', 'gdal.SetFileMetadata', ({(2702, 36, 2702, 66): '"""/vsis3/test_metadata/foo.txt"""', (2702, 68, 2702, 82): "{'foo': 'bar'}", (2702, 84, 2702, 93): '"""HEADERS"""'}, {}), "('/vsis3/test_metadata/foo.txt', {'foo': 'bar'}, 'HEADERS')", False, 'from osgeo import gdal\n'), ((2733, 9, 2733, 48), 'webserver.install_http_handler', 'webserver.install_http_handler', ({(2733, 40, 2733, 47): 'handler'}, {}), '(handler)', False, 'import webserver\n'), ((2734, 15, 2734, 91), 'osgeo.gdal.SetFileMetadata', 'gdal.SetFileMetadata', ({(2734, 36, 2734, 66): '"""/vsis3/test_metadata/foo.txt"""', (2734, 68, 2734, 82): "{'foo': 'bar'}", (2734, 84, 2734, 90): '"""TAGS"""'}, {}), "('/vsis3/test_metadata/foo.txt', {'foo': 'bar'}, 'TAGS')", False, 'from osgeo import gdal\n'), ((2739, 9, 2739, 48), 'webserver.install_http_handler', 'webserver.install_http_handler', ({(2739, 40, 2739, 47): 'handler'}, {}), '(handler)', False, 'import webserver\n'), ((2740, 15, 2740, 79), 'osgeo.gdal.SetFileMetadata', 'gdal.SetFileMetadata', ({(2740, 36, 2740, 66): '"""/vsis3/test_metadata/foo.txt"""', (2740, 68, 2740, 70): '{}', (2740, 72, 2740, 78): '"""TAGS"""'}, {}), "('/vsis3/test_metadata/foo.txt', {}, 'TAGS')", False, 'from osgeo import gdal\n'), ((2743, 9, 2743, 33), 'gdaltest.error_handler', 'gdaltest.error_handler', ({}, {}), '()', False, 'import gdaltest\n'), ((2747, 9, 2747, 33), 'gdaltest.error_handler', 'gdaltest.error_handler', ({}, {}), '()', False, 'import gdaltest\n'), ((2758, 8, 2758, 21), 'pytest.skip', 'pytest.skip', ({}, {}), '()', False, 'import pytest\n'), ((2772, 9, 2772, 48), 'webserver.install_http_handler', 'webserver.install_http_handler', ({(2772, 40, 2772, 47): 'handler'}, {}), '(handler)', False, 'import webserver\n'), ((2783, 8, 2783, 21), 'pytest.skip', 'pytest.skip', ({}, {}), '()', False, 'import pytest\n'), ((2787, 9, 2787, 33), 'gdaltest.error_handler', 'gdaltest.error_handler', ({}, {}), '()', False, 'import gdaltest\n'), ((2790, 9, 2790, 81), 'gdaltest.config_option', 'gdaltest.config_option', ({(2790, 32, 2790, 73): '"""CPL_VSIL_USE_TEMP_FILE_FOR_RANDOM_WRITE"""', (2790, 75, 2790, 80): '"""YES"""'}, {}), "('CPL_VSIL_USE_TEMP_FILE_FOR_RANDOM_WRITE', 'YES')", False, 'import gdaltest\n'), ((2791, 12, 2791, 65), 'osgeo.gdal.VSIFOpenL', 'gdal.VSIFOpenL', ({(2791, 27, 2791, 57): '"""/vsis3/random_write/test.bin"""', (2791, 59, 2791, 64): '"""w+b"""'}, {}), "('/vsis3/random_write/test.bin', 'w+b')", False, 'from osgeo import gdal\n'), ((2793, 11, 2793, 42), 'osgeo.gdal.VSIFWriteL', 'gdal.VSIFWriteL', ({(2793, 27, 2793, 32): '"""foo"""', (2793, 34, 2793, 35): '(3)', (2793, 37, 2793, 38): '(1)', (2793, 40, 2793, 41): 'f'}, {}), "('foo', 3, 1, f)", False, 'from osgeo import gdal\n'), ((2794, 11, 2794, 34), 'osgeo.gdal.VSIFSeekL', 'gdal.VSIFSeekL', ({(2794, 26, 2794, 27): 'f', (2794, 29, 2794, 30): '(0)', (2794, 32, 2794, 33): '(0)'}, {}), '(f, 0, 0)', False, 'from osgeo import gdal\n'), ((2796, 11, 2796, 27), 'osgeo.gdal.VSIFEofL', 'gdal.VSIFEofL', ({(2796, 25, 2796, 26): 'f'}, {}), '(f)', False, 'from osgeo import gdal\n'), ((2797, 11, 2797, 28), 'osgeo.gdal.VSIFTellL', 'gdal.VSIFTellL', ({(2797, 26, 2797, 27): 'f'}, {}), '(f)', False, 'from osgeo import gdal\n'), ((2801, 9, 2801, 48), 'webserver.install_http_handler', 'webserver.install_http_handler', ({(2801, 40, 2801, 47): 'handler'}, {}), '(handler)', False, 'import webserver\n'), ((2810, 8, 2810, 21), 'pytest.skip', 'pytest.skip', ({}, {}), '()', False, 'import pytest\n'), ((2814, 9, 2814, 81), 'gdaltest.config_option', 'gdaltest.config_option', ({(2814, 32, 2814, 73): '"""CPL_VSIL_USE_TEMP_FILE_FOR_RANDOM_WRITE"""', (2814, 75, 2814, 80): '"""YES"""'}, {}), "('CPL_VSIL_USE_TEMP_FILE_FOR_RANDOM_WRITE', 'YES')", False, 'import gdaltest\n'), ((2815, 12, 2815, 65), 'osgeo.gdal.VSIFOpenL', 'gdal.VSIFOpenL', ({(2815, 27, 2815, 57): '"""/vsis3/random_write/test.bin"""', (2815, 59, 2815, 64): '"""w+b"""'}, {}), "('/vsis3/random_write/test.bin', 'w+b')", False, 'from osgeo import gdal\n'), ((2820, 9, 2820, 48), 'webserver.install_http_handler', 'webserver.install_http_handler', ({(2820, 40, 2820, 47): 'handler'}, {}), '(handler)', False, 'import webserver\n'), ((2831, 8, 2831, 21), 'pytest.skip', 'pytest.skip', ({}, {}), '()', False, 'import pytest\n'), ((2835, 9, 2835, 81), 'gdaltest.config_option', 'gdaltest.config_option', ({(2835, 32, 2835, 73): '"""CPL_VSIL_USE_TEMP_FILE_FOR_RANDOM_WRITE"""', (2835, 75, 2835, 80): '"""YES"""'}, {}), "('CPL_VSIL_USE_TEMP_FILE_FOR_RANDOM_WRITE', 'YES')", False, 'import gdaltest\n'), ((2839, 11, 2839, 42), 'osgeo.gdal.VSIFWriteL', 'gdal.VSIFWriteL', ({(2839, 27, 2839, 32): '"""foo"""', (2839, 34, 2839, 35): '(3)', (2839, 37, 2839, 38): '(1)', (2839, 40, 2839, 41): 'f'}, {}), "('foo', 3, 1, f)", False, 'from osgeo import gdal\n'), ((2843, 9, 2843, 48), 'webserver.install_http_handler', 'webserver.install_http_handler', ({(2843, 40, 2843, 47): 'handler'}, {}), '(handler)', False, 'import webserver\n'), ((2853, 8, 2853, 21), 'pytest.skip', 'pytest.skip', ({}, {}), '()', False, 'import pytest\n'), ((2864, 9, 2864, 81), 'gdaltest.config_option', 'gdaltest.config_option', ({(2864, 32, 2864, 73): '"""CPL_VSIL_USE_TEMP_FILE_FOR_RANDOM_WRITE"""', (2864, 75, 2864, 80): '"""YES"""'}, {}), "('CPL_VSIL_USE_TEMP_FILE_FOR_RANDOM_WRITE', 'YES')", False, 'import gdaltest\n'), ((2871, 9, 2871, 48), 'webserver.install_http_handler', 'webserver.install_http_handler', ({(2871, 40, 2871, 47): 'handler'}, {}), '(handler)', False, 'import webserver\n'), ((2881, 8, 2881, 21), 'pytest.skip', 'pytest.skip', ({}, {}), '()', False, 'import pytest\n'), ((2904, 9, 2904, 48), 'webserver.install_http_handler', 'webserver.install_http_handler', ({(2904, 40, 2904, 47): 'handler'}, {}), '(handler)', False, 'import webserver\n'), ((2908, 8, 2908, 26), 'osgeo.gdal.VSIFCloseL', 'gdal.VSIFCloseL', ({(2908, 24, 2908, 25): 'f'}, {}), '(f)', False, 'from osgeo import gdal\n'), ((2922, 8, 2922, 21), 'pytest.skip', 'pytest.skip', ({}, {}), '()', False, 'import pytest\n'), ((2946, 9, 2946, 48), 'webserver.install_http_handler', 'webserver.install_http_handler', ({(2946, 40, 2946, 47): 'handler'}, {}), '(handler)', False, 'import webserver\n'), ((2950, 8, 2950, 26), 'osgeo.gdal.VSIFCloseL', 'gdal.VSIFCloseL', ({(2950, 24, 2950, 25): 'f'}, {}), '(f)', False, 'from osgeo import gdal\n'), ((2964, 8, 2964, 21), 'pytest.skip', 'pytest.skip', ({}, {}), '()', False, 'import pytest\n'), ((3001, 9, 3001, 48), 'webserver.install_http_handler', 'webserver.install_http_handler', ({(3001, 40, 3001, 47): 'handler'}, {}), '(handler)', False, 'import webserver\n'), ((3005, 8, 3005, 26), 'osgeo.gdal.VSIFCloseL', 'gdal.VSIFCloseL', ({(3005, 24, 3005, 25): 'f'}, {}), '(f)', False, 'from osgeo import gdal\n'), ((3022, 8, 3022, 21), 'pytest.skip', 'pytest.skip', ({}, {}), '()', False, 'import pytest\n'), ((3059, 9, 3059, 48), 'webserver.install_http_handler', 'webserver.install_http_handler', ({(3059, 40, 3059, 47): 'handler'}, {}), '(handler)', False, 'import webserver\n'), ((3066, 8, 3066, 26), 'osgeo.gdal.VSIFCloseL', 'gdal.VSIFCloseL', ({(3066, 24, 3066, 25): 'f'}, {}), '(f)', False, 'from osgeo import gdal\n'), ((3079, 8, 3079, 21), 'pytest.skip', 'pytest.skip', ({}, {}), '()', False, 'import pytest\n'), ((3117, 9, 3117, 48), 'webserver.install_http_handler', 'webserver.install_http_handler', ({(3117, 40, 3117, 47): 'handler'}, {}), '(handler)', False, 'import webserver\n'), ((3123, 8, 3123, 26), 'osgeo.gdal.VSIFCloseL', 'gdal.VSIFCloseL', ({(3123, 24, 3123, 25): 'f'}, {}), '(f)', False, 'from osgeo import gdal\n'), ((3139, 8, 3139, 21), 'pytest.skip', 'pytest.skip', ({}, {}), '()', False, 'import pytest\n'), ((3142, 8, 3142, 21), 'pytest.skip', 'pytest.skip', ({}, {}), '()', False, 'import pytest\n'), ((3170, 9, 3170, 48), 'webserver.install_http_handler', 'webserver.install_http_handler', ({(3170, 40, 3170, 47): 'handler'}, {}), '(handler)', False, 'import webserver\n'), ((3174, 8, 3174, 26), 'osgeo.gdal.VSIFCloseL', 'gdal.VSIFCloseL', ({(3174, 24, 3174, 25): 'f'}, {}), '(f)', False, 'from osgeo import gdal\n'), ((3183, 9, 3183, 48), 'webserver.install_http_handler', 'webserver.install_http_handler', ({(3183, 40, 3183, 47): 'handler'}, {}), '(handler)', False, 'import webserver\n'), ((3187, 8, 3187, 26), 'osgeo.gdal.VSIFCloseL', 'gdal.VSIFCloseL', ({(3187, 24, 3187, 25): 'f'}, {}), '(f)', False, 'from osgeo import gdal\n'), ((3201, 8, 3201, 21), 'pytest.skip', 'pytest.skip', ({}, {}), '()', False, 'import pytest\n'), ((3204, 8, 3204, 21), 'pytest.skip', 'pytest.skip', ({}, {}), '()', False, 'import pytest\n'), ((3232, 9, 3232, 48), 'webserver.install_http_handler', 'webserver.install_http_handler', ({(3232, 40, 3232, 47): 'handler'}, {}), '(handler)', False, 'import webserver\n'), ((3236, 8, 3236, 26), 'osgeo.gdal.VSIFCloseL', 'gdal.VSIFCloseL', ({(3236, 24, 3236, 25): 'f'}, {}), '(f)', False, 'from osgeo import gdal\n'), ((3251, 8, 3251, 21), 'pytest.skip', 'pytest.skip', ({}, {}), '()', False, 'import pytest\n'), ((3254, 8, 3254, 21), 'pytest.skip', 'pytest.skip', ({}, {}), '()', False, 'import pytest\n'), ((3290, 9, 3290, 48), 'webserver.install_http_handler', 'webserver.install_http_handler', ({(3290, 40, 3290, 47): 'handler'}, {}), '(handler)', False, 'import webserver\n'), ((3294, 8, 3294, 26), 'osgeo.gdal.VSIFCloseL', 'gdal.VSIFCloseL', ({(3294, 24, 3294, 25): 'f'}, {}), '(f)', False, 'from osgeo import gdal\n'), ((3305, 9, 3305, 48), 'webserver.install_http_handler', 'webserver.install_http_handler', ({(3305, 40, 3305, 47): 'handler'}, {}), '(handler)', False, 'import webserver\n'), ((3319, 8, 3319, 21), 'pytest.skip', 'pytest.skip', ({}, {}), '()', False, 'import pytest\n'), ((3333, 11, 3333, 40), 'gdaltest.built_against_curl', 'gdaltest.built_against_curl', ({}, {}), '()', False, 'import gdaltest\n'), ((3334, 8, 3334, 21), 'pytest.skip', 'pytest.skip', ({}, {}), '()', False, 'import pytest\n'), ((3349, 8, 3349, 42), 'pytest.skip', 'pytest.skip', ({(3349, 20, 3349, 41): '"""Missing S3_RESOURCE"""'}, {}), "('Missing S3_RESOURCE')", False, 'import pytest\n'), ((3353, 18, 3353, 37), 'osgeo.gdal.VSIStatL', 'gdal.VSIStatL', ({(3353, 32, 3353, 36): 'path'}, {}), '(path)', False, 'from osgeo import gdal\n'), ((3357, 18, 3357, 36), 'osgeo.gdal.ReadDir', 'gdal.ReadDir', ({(3357, 31, 3357, 35): 'path'}, {}), '(path)', False, 'from osgeo import gdal\n'), ((3367, 14, 3367, 36), 'osgeo.gdal.Mkdir', 'gdal.Mkdir', ({(3367, 25, 3367, 32): 'subpath', (3367, 34, 3367, 35): '0'}, {}), '(subpath, 0)', False, 'from osgeo import gdal\n'), ((3370, 18, 3370, 36), 'osgeo.gdal.ReadDir', 'gdal.ReadDir', ({(3370, 31, 3370, 35): 'path'}, {}), '(path)', False, 'from osgeo import gdal\n'), ((3374, 14, 3374, 36), 'osgeo.gdal.Mkdir', 'gdal.Mkdir', ({(3374, 25, 3374, 32): 'subpath', (3374, 34, 3374, 35): '0'}, {}), '(subpath, 0)', False, 'from osgeo import gdal\n'), ((3377, 14, 3377, 33), 'osgeo.gdal.Rmdir', 'gdal.Rmdir', ({(3377, 25, 3377, 32): 'subpath'}, {}), '(subpath)', False, 'from osgeo import gdal\n'), ((3380, 18, 3380, 36), 'osgeo.gdal.ReadDir', 'gdal.ReadDir', ({(3380, 31, 3380, 35): 'path'}, {}), '(path)', False, 'from osgeo import gdal\n'), ((3384, 14, 3384, 33), 'osgeo.gdal.Rmdir', 'gdal.Rmdir', ({(3384, 25, 3384, 32): 'subpath'}, {}), '(subpath)', False, 'from osgeo import gdal\n'), ((3387, 14, 3387, 36), 'osgeo.gdal.Mkdir', 'gdal.Mkdir', ({(3387, 25, 3387, 32): 'subpath', (3387, 34, 3387, 35): '0'}, {}), '(subpath, 0)', False, 'from osgeo import gdal\n'), ((3390, 12, 3390, 55), 'osgeo.gdal.VSIFOpenL', 'gdal.VSIFOpenL', ({(3390, 27, 3390, 48): "subpath + '/test.txt'", (3390, 50, 3390, 54): '"""wb"""'}, {}), "(subpath + '/test.txt', 'wb')", False, 'from osgeo import gdal\n'), ((3392, 8, 3392, 41), 'osgeo.gdal.VSIFWriteL', 'gdal.VSIFWriteL', ({(3392, 24, 3392, 31): '"""hello"""', (3392, 33, 3392, 34): '(1)', (3392, 36, 3392, 37): '(5)', (3392, 39, 3392, 40): 'f'}, {}), "('hello', 1, 5, f)", False, 'from osgeo import gdal\n'), ((3393, 8, 3393, 26), 'osgeo.gdal.VSIFCloseL', 'gdal.VSIFCloseL', ({(3393, 24, 3393, 25): 'f'}, {}), '(f)', False, 'from osgeo import gdal\n'), ((3395, 14, 3395, 33), 'osgeo.gdal.Rmdir', 'gdal.Rmdir', ({(3395, 25, 3395, 32): 'subpath'}, {}), '(subpath)', False, 'from osgeo import gdal\n'), ((3399, 12, 3399, 55), 'osgeo.gdal.VSIFOpenL', 'gdal.VSIFOpenL', ({(3399, 27, 3399, 48): "subpath + '/test.txt'", (3399, 50, 3399, 54): '"""rb"""'}, {}), "(subpath + '/test.txt', 'rb')", False, 'from osgeo import gdal\n'), ((3403, 8, 3403, 26), 'osgeo.gdal.VSIFCloseL', 'gdal.VSIFCloseL', ({(3403, 24, 3403, 25): 'f'}, {}), '(f)', False, 'from osgeo import gdal\n'), ((3407, 12, 3407, 56), 'osgeo.gdal.VSIFOpenL', 'gdal.VSIFOpenL', ({(3407, 27, 3407, 49): "subpath + '/test2.txt'", (3407, 51, 3407, 55): '"""rb"""'}, {}), "(subpath + '/test2.txt', 'rb')", False, 'from osgeo import gdal\n'), ((3411, 8, 3411, 26), 'osgeo.gdal.VSIFCloseL', 'gdal.VSIFCloseL', ({(3411, 24, 3411, 25): 'f'}, {}), '(f)', False, 'from osgeo import gdal\n'), ((3413, 14, 3413, 49), 'osgeo.gdal.Unlink', 'gdal.Unlink', ({(3413, 26, 3413, 48): "subpath + '/test2.txt'"}, {}), "(subpath + '/test2.txt')", False, 'from osgeo import gdal\n'), ((3417, 14, 3417, 33), 'osgeo.gdal.Rmdir', 'gdal.Rmdir', ({(3417, 25, 3417, 32): 'subpath'}, {}), '(subpath)', False, 'from osgeo import gdal\n'), ((3440, 8, 3440, 25), 'osgeo.gdal.ErrorReset', 'gdal.ErrorReset', ({}, {}), '()', False, 'from osgeo import gdal\n'), ((3444, 8, 3444, 26), 'osgeo.gdal.VSIFCloseL', 'gdal.VSIFCloseL', ({(3444, 24, 3444, 25): 'f'}, {}), '(f)', False, 'from osgeo import gdal\n'), ((3467, 8, 3467, 57), 'osgeo.gdal.SetConfigOption', 'gdal.SetConfigOption', ({(3467, 29, 3467, 32): 'var', (3467, 34, 3467, 56): 'gdaltest.aws_vars[var]'}, {}), '(var, gdaltest.aws_vars[var])', False, 'from osgeo import gdal\n'), ((58, 12, 58, 41), 'osgeo.gdal.SetConfigOption', 'gdal.SetConfigOption', ({(58, 33, 58, 36): 'var', (58, 38, 58, 40): '""""""'}, {}), "(var, '')", False, 'from osgeo import gdal\n'), ((87, 11, 87, 133), 'gdaltest.gdalurlopen', 'gdaltest.gdalurlopen', ({(87, 32, 87, 132): '"""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    )", False, 'import gdaltest\n'), ((88, 12, 88, 42), 'pytest.skip', 'pytest.skip', ({(88, 24, 88, 41): '"""cannot open URL"""'}, {}), "('cannot open URL')", False, 'import pytest\n'), ((115, 11, 115, 82), 'osgeo.gdal.VSIStatL', 'gdal.VSIStatL', ({(115, 25, 115, 81): '"""/vsimem/test_vsis3_no_sign_request_sync/test_dummy/foo"""'}, {}), "('/vsimem/test_vsis3_no_sign_request_sync/test_dummy/foo')", False, 'from osgeo import gdal\n'), ((116, 11, 116, 82), 'osgeo.gdal.VSIStatL', 'gdal.VSIStatL', ({(116, 25, 116, 81): '"""/vsimem/test_vsis3_no_sign_request_sync/test_dummy/bar"""'}, {}), "('/vsimem/test_vsis3_no_sign_request_sync/test_dummy/bar')", False, 'from osgeo import gdal\n'), ((142, 11, 142, 82), 'osgeo.gdal.VSIStatL', 'gdal.VSIStatL', ({(142, 25, 142, 81): '"""/vsimem/test_vsis3_no_sign_request_sync/test_dummy/foo"""'}, {}), "('/vsimem/test_vsis3_no_sign_request_sync/test_dummy/foo')", False, 'from osgeo import gdal\n'), ((143, 11, 143, 82), 'osgeo.gdal.VSIStatL', 'gdal.VSIStatL', ({(143, 25, 143, 81): '"""/vsimem/test_vsis3_no_sign_request_sync/test_dummy/bar"""'}, {}), "('/vsimem/test_vsis3_no_sign_request_sync/test_dummy/bar')", False, 'from osgeo import gdal\n'), ((181, 24, 181, 49), 'osgeo.gdal.VSIGetLastErrorMsg', 'gdal.VSIGetLastErrorMsg', ({}, {}), '()', False, 'from osgeo import gdal\n'), ((183, 12, 183, 30), 'osgeo.gdal.VSIFCloseL', 'gdal.VSIFCloseL', ({(183, 28, 183, 29): 'f'}, {}), '(f)', False, 'from osgeo import gdal\n'), ((184, 11, 184, 43), 'osgeo.gdal.GetConfigOption', 'gdal.GetConfigOption', ({(184, 32, 184, 42): '"""APPVEYOR"""'}, {}), "('APPVEYOR')", False, 'from osgeo import gdal\n'), ((186, 20, 186, 45), 'osgeo.gdal.VSIGetLastErrorMsg', 'gdal.VSIGetLastErrorMsg', ({}, {}), '()', False, 'from osgeo import gdal\n'), ((191, 25, 191, 50), 'osgeo.gdal.VSIGetLastErrorMsg', 'gdal.VSIGetLastErrorMsg', ({}, {}), '()', False, 'from osgeo import gdal\n'), ((298, 13, 298, 52), 'webserver.install_http_handler', 'webserver.install_http_handler', ({(298, 44, 298, 51): 'handler'}, {}), '(handler)', False, 'import webserver\n'), ((302, 12, 302, 30), 'osgeo.gdal.VSIFCloseL', 'gdal.VSIFCloseL', ({(302, 28, 302, 29): 'f'}, {}), '(f)', False, 'from osgeo import gdal\n'), ((340, 12, 340, 25), 'pytest.fail', 'pytest.fail', ({}, {}), '()', False, 'import pytest\n'), ((417, 12, 417, 79), 'pytest.skip', 'pytest.skip', ({(417, 24, 417, 78): '"""Skipped on trusty branch, but should be investigated"""'}, {}), "('Skipped on trusty branch, but should be investigated')", False, 'import pytest\n'), ((456, 13, 456, 37), 'gdaltest.error_handler', 'gdaltest.error_handler', ({}, {}), '()', False, 'import gdaltest\n'), ((469, 13, 469, 37), 'gdaltest.error_handler', 'gdaltest.error_handler', ({}, {}), '()', False, 'import gdaltest\n'), ((482, 13, 482, 37), 'gdaltest.error_handler', 'gdaltest.error_handler', ({}, {}), '()', False, 'import gdaltest\n'), ((495, 13, 495, 37), 'gdaltest.error_handler', 'gdaltest.error_handler', ({}, {}), '()', False, 'import gdaltest\n'), ((508, 13, 508, 37), 'gdaltest.error_handler', 'gdaltest.error_handler', ({}, {}), '()', False, 'import gdaltest\n'), ((521, 13, 521, 37), 'gdaltest.error_handler', 'gdaltest.error_handler', ({}, {}), '()', False, 'import gdaltest\n'), ((554, 13, 554, 52), 'webserver.install_http_handler', 'webserver.install_http_handler', ({(554, 44, 554, 51): 'handler'}, {}), '(handler)', False, 'import webserver\n'), ((644, 13, 644, 37), 'gdaltest.error_handler', 'gdaltest.error_handler', ({}, {}), '()', False, 'import gdaltest\n'), ((667, 13, 667, 52), 'webserver.install_http_handler', 'webserver.install_http_handler', ({(667, 44, 667, 51): 'handler'}, {}), '(handler)', False, 'import webserver\n'), ((670, 12, 670, 30), 'osgeo.gdal.VSIFCloseL', 'gdal.VSIFCloseL', ({(670, 28, 670, 29): 'f'}, {}), '(f)', False, 'from osgeo import gdal\n'), ((771, 12, 771, 79), 'pytest.skip', 'pytest.skip', ({(771, 24, 771, 78): '"""Skipped on trusty branch, but should be investigated"""'}, {}), "('Skipped on trusty branch, but should be investigated')", False, 'import pytest\n'), ((776, 40, 776, 69), 'webserver.SequentialHandler', 'webserver.SequentialHandler', ({}, {}), '()', False, 'import webserver\n'), ((780, 11, 780, 92), 'osgeo.gdal.VSIStatL', 'gdal.VSIStatL', ({(780, 25, 780, 91): '"""/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')", False, 'from osgeo import gdal\n'), ((781, 11, 781, 92), 'osgeo.gdal.VSIStatL', 'gdal.VSIStatL', ({(781, 25, 781, 91): '"""/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')", False, 'from osgeo import gdal\n'), ((794, 11, 794, 92), 'osgeo.gdal.VSIStatL', 'gdal.VSIStatL', ({(794, 25, 794, 91): '"""/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')", False, 'from osgeo import gdal\n'), ((847, 13, 847, 52), 'webserver.install_http_handler', 'webserver.install_http_handler', ({(847, 44, 847, 51): 'handler'}, {}), '(handler)', False, 'import webserver\n'), ((848, 27, 848, 71), 'osgeo.gdal.ReadDir', 'gdal.ReadDir', ({(848, 40, 848, 70): '"""/vsis3/s3_fake_bucket2/a_dir"""'}, {}), "('/vsis3/s3_fake_bucket2/a_dir')", False, 'from osgeo import gdal\n'), ((858, 13, 858, 84), 'gdaltest.config_option', 'gdaltest.config_option', ({(858, 36, 858, 62): '"""CPL_VSIL_CURL_NON_CACHED"""', (858, 64, 858, 83): 'config_option_value'}, {}), "('CPL_VSIL_CURL_NON_CACHED', config_option_value)", False, 'import gdaltest\n'), ((860, 22, 860, 51), 'webserver.SequentialHandler', 'webserver.SequentialHandler', ({}, {}), '()', False, 'import webserver\n'), ((870, 22, 870, 51), 'webserver.SequentialHandler', 'webserver.SequentialHandler', ({}, {}), '()', False, 'import webserver\n'), ((877, 22, 877, 51), 'webserver.SequentialHandler', 'webserver.SequentialHandler', ({}, {}), '()', False, 'import webserver\n'), ((886, 22, 886, 51), 'webserver.SequentialHandler', 'webserver.SequentialHandler', ({}, {}), '()', False, 'import webserver\n'), ((899, 13, 899, 84), 'gdaltest.config_option', 'gdaltest.config_option', ({(899, 36, 899, 62): '"""CPL_VSIL_CURL_NON_CACHED"""', (899, 64, 899, 83): 'config_option_value'}, {}), "('CPL_VSIL_CURL_NON_CACHED', config_option_value)", False, 'import gdaltest\n'), ((901, 22, 901, 51), 'webserver.SequentialHandler', 'webserver.SequentialHandler', ({}, {}), '()', False, 'import webserver\n'), ((928, 22, 928, 51), 'webserver.SequentialHandler', 'webserver.SequentialHandler', ({}, {}), '()', False, 'import webserver\n'), ((1194, 40, 1194, 69), 'webserver.SequentialHandler', 'webserver.SequentialHandler', ({}, {}), '()', False, 'import webserver\n'), ((1195, 13, 1195, 37), 'gdaltest.error_handler', 'gdaltest.error_handler', ({}, {}), '()', False, 'import gdaltest\n'), ((1196, 16, 1196, 62), 'osgeo.gdal.VSIFOpenL', 'gdal.VSIFOpenL', ({(1196, 31, 1196, 55): '"""/vsis3/s3_fake_bucket3"""', (1196, 57, 1196, 61): '"""wb"""'}, {}), "('/vsis3/s3_fake_bucket3', 'wb')", False, 'from osgeo import gdal\n'), ((1236, 13, 1236, 37), 'gdaltest.error_handler', 'gdaltest.error_handler', ({}, {}), '()', False, 'import gdaltest\n'), ((1237, 18, 1237, 41), 'osgeo.gdal.VSIFSeekL', 'gdal.VSIFSeekL', ({(1237, 33, 1237, 34): 'f', (1237, 36, 1237, 37): '1', (1237, 39, 1237, 40): '0'}, {}), '(f, 1, 0)', False, 'from osgeo import gdal\n'), ((1246, 13, 1246, 37), 'gdaltest.error_handler', 'gdaltest.error_handler', ({}, {}), '()', False, 'import gdaltest\n'), ((1247, 18, 1247, 41), 'osgeo.gdal.VSIFReadL', 'gdal.VSIFReadL', ({(1247, 33, 1247, 34): '1', (1247, 36, 1247, 37): '1', (1247, 39, 1247, 40): 'f'}, {}), '(1, 1, f)', False, 'from osgeo import gdal\n'), ((1258, 13, 1258, 37), 'gdaltest.error_handler', 'gdaltest.error_handler', ({}, {}), '()', False, 'import gdaltest\n'), ((1259, 12, 1259, 30), 'osgeo.gdal.VSIFCloseL', 'gdal.VSIFCloseL', ({(1259, 28, 1259, 29): 'f'}, {}), '(f)', False, 'from osgeo import gdal\n'), ((1267, 16, 1267, 79), 'osgeo.gdal.VSIFOpenL', 'gdal.VSIFOpenL', ({(1267, 31, 1267, 72): '"""/vsis3/s3_fake_bucket3/another_file.bin"""', (1267, 74, 1267, 78): '"""wb"""'}, {}), "('/vsis3/s3_fake_bucket3/another_file.bin', 'wb')", False, 'from osgeo import gdal\n'), ((1303, 13, 1303, 52), 'webserver.install_http_handler', 'webserver.install_http_handler', ({(1303, 44, 1303, 51): 'handler'}, {}), '(handler)', False, 'import webserver\n'), ((1304, 12, 1304, 30), 'osgeo.gdal.VSIFCloseL', 'gdal.VSIFCloseL', ({(1304, 28, 1304, 29): 'f'}, {}), '(f)', False, 'from osgeo import gdal\n'), ((1305, 15, 1305, 37), 'osgeo.gdal.GetLastErrorMsg', 'gdal.GetLastErrorMsg', ({}, {}), '()', False, 'from osgeo import gdal\n'), ((1351, 40, 1351, 69), 'webserver.SequentialHandler', 'webserver.SequentialHandler', ({}, {}), '()', False, 'import webserver\n'), ((1354, 15, 1354, 49), 'osgeo.gdal.VSIFWriteL', 'gdal.VSIFWriteL', ({(1354, 31, 1354, 39): '"""foobar"""', (1354, 41, 1354, 42): '(1)', (1354, 44, 1354, 45): '(6)', (1354, 47, 1354, 48): 'f'}, {}), "('foobar', 1, 6, f)", False, 'from osgeo import gdal\n'), ((1413, 16, 1413, 81), 'osgeo.gdal.VSIFOpenL', 'gdal.VSIFOpenL', ({(1413, 31, 1413, 74): '"""/vsis3/s3_fake_bucket3/put_with_retry.bin"""', (1413, 76, 1413, 80): '"""wb"""'}, {}), "('/vsis3/s3_fake_bucket3/put_with_retry.bin', 'wb')", False, 'from osgeo import gdal\n'), ((1444, 13, 1444, 37), 'gdaltest.error_handler', 'gdaltest.error_handler', ({}, {}), '()', False, 'import gdaltest\n'), ((1458, 40, 1458, 69), 'webserver.SequentialHandler', 'webserver.SequentialHandler', ({}, {}), '()', False, 'import webserver\n'), ((1459, 13, 1459, 37), 'gdaltest.error_handler', 'gdaltest.error_handler', ({}, {}), '()', False, 'import gdaltest\n'), ((1460, 18, 1460, 43), 'osgeo.gdal.Unlink', 'gdal.Unlink', ({(1460, 30, 1460, 42): '"""/vsis3/foo"""'}, {}), "('/vsis3/foo')", False, 'from osgeo import gdal\n'), ((1482, 15, 1482, 67), 'osgeo.gdal.VSIStatL', 'gdal.VSIStatL', ({(1482, 29, 1482, 66): '"""/vsis3/s3_delete_bucket/delete_file"""'}, {}), "('/vsis3/s3_delete_bucket/delete_file')", False, 'from osgeo import gdal\n'), ((1488, 13, 1488, 37), 'gdaltest.error_handler', 'gdaltest.error_handler', ({}, {}), '()', False, 'import gdaltest\n'), ((1489, 18, 1489, 74), 'osgeo.gdal.Unlink', 'gdal.Unlink', ({(1489, 30, 1489, 73): '"""/vsis3/s3_delete_bucket/delete_file_error"""'}, {}), "('/vsis3/s3_delete_bucket/delete_file_error')", False, 'from osgeo import gdal\n'), ((1549, 12, 1549, 76), 'sys.stderr.write', 'sys.stderr.write', ({(1549, 29, 1549, 75): "('Did not get expected content: %s\\n' % content)"}, {}), "('Did not get expected content: %s\\n' % content)", False, 'import sys\n'), ((1567, 13, 1567, 52), 'webserver.install_http_handler', 'webserver.install_http_handler', ({(1567, 44, 1567, 51): 'handler'}, {}), '(handler)', False, 'import webserver\n'), ((1568, 18, 1568, 121), 'osgeo.gdal.UnlinkBatch', 'gdal.UnlinkBatch', ({(1568, 35, 1568, 120): "['/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'])", False, 'from osgeo import gdal\n'), ((1624, 12, 1624, 76), 'sys.stderr.write', 'sys.stderr.write', ({(1624, 29, 1624, 75): "('Did not get expected content: %s\\n' % content)"}, {}), "('Did not get expected content: %s\\n' % content)", False, 'import sys\n'), ((1650, 12, 1650, 76), 'sys.stderr.write', 'sys.stderr.write', ({(1650, 29, 1650, 75): "('Did not get expected content: %s\\n' % content)"}, {}), "('Did not get expected content: %s\\n' % content)", False, 'import sys\n'), ((1665, 13, 1665, 52), 'webserver.install_http_handler', 'webserver.install_http_handler', ({(1665, 44, 1665, 51): 'handler'}, {}), '(handler)', False, 'import webserver\n'), ((1680, 16, 1680, 77), 'osgeo.gdal.VSIFOpenL', 'gdal.VSIFOpenL', ({(1680, 31, 1680, 70): '"""/vsis3/s3_fake_bucket4/large_file.bin"""', (1680, 72, 1680, 76): '"""wb"""'}, {}), "('/vsis3/s3_fake_bucket4/large_file.bin', 'wb')", False, 'from osgeo import gdal\n'), ((1761, 12, 1761, 76), 'sys.stderr.write', 'sys.stderr.write', ({(1761, 29, 1761, 75): "('Did not get expected content: %s\\n' % content)"}, {}), "('Did not get expected content: %s\\n' % content)", False, 'import sys\n'), ((1794, 12, 1794, 29), 'osgeo.gdal.ErrorReset', 'gdal.ErrorReset', ({}, {}), '()', False, 'from osgeo import gdal\n'), ((1795, 12, 1795, 30), 'osgeo.gdal.VSIFCloseL', 'gdal.VSIFCloseL', ({(1795, 28, 1795, 29): 'f'}, {}), '(f)', False, 'from osgeo import gdal\n'), ((1818, 12, 1818, 29), 'osgeo.gdal.ErrorReset', 'gdal.ErrorReset', ({}, {}), '()', False, 'from osgeo import gdal\n'), ((1819, 12, 1819, 30), 'osgeo.gdal.VSIFCloseL', 'gdal.VSIFCloseL', ({(1819, 28, 1819, 29): 'f'}, {}), '(f)', False, 'from osgeo import gdal\n'), ((1831, 13, 1831, 60), 'gdaltest.config_option', 'gdaltest.config_option', ({(1831, 36, 1831, 54): '"""VSIS3_CHUNK_SIZE"""', (1831, 56, 1831, 59): '"""1"""'}, {}), "('VSIS3_CHUNK_SIZE', '1')", False, 'import gdaltest\n'), ((1832, 16, 1832, 46), 'osgeo.gdal.VSIFOpenL', 'gdal.VSIFOpenL', ({(1832, 31, 1832, 39): 'filename', (1832, 41, 1832, 45): '"""wb"""'}, {}), "(filename, 'wb')", False, 'from osgeo import gdal\n'), ((1834, 13, 1834, 37), 'gdaltest.error_handler', 'gdaltest.error_handler', ({}, {}), '()', False, 'import gdaltest\n'), ((1835, 18, 1835, 57), 'osgeo.gdal.VSIFWriteL', 'gdal.VSIFWriteL', ({(1835, 34, 1835, 44): 'big_buffer', (1835, 46, 1835, 47): '1', (1835, 49, 1835, 53): 'size', (1835, 55, 1835, 56): 'f'}, {}), '(big_buffer, 1, size, f)', False, 'from osgeo import gdal\n'), ((1838, 13, 1838, 37), 'gdaltest.error_handler', 'gdaltest.error_handler', ({}, {}), '()', False, 'import gdaltest\n'), ((1839, 12, 1839, 30), 'osgeo.gdal.VSIFCloseL', 'gdal.VSIFCloseL', ({(1839, 28, 1839, 29): 'f'}, {}), '(f)', False, 'from osgeo import gdal\n'), ((1840, 15, 1840, 37), 'osgeo.gdal.GetLastErrorMsg', 'gdal.GetLastErrorMsg', ({}, {}), '()', False, 'from osgeo import gdal\n'), ((1853, 13, 1853, 60), 'gdaltest.config_option', 'gdaltest.config_option', ({(1853, 36, 1853, 54): '"""VSIS3_CHUNK_SIZE"""', (1853, 56, 1853, 59): '"""1"""'}, {}), "('VSIS3_CHUNK_SIZE', '1')", False, 'import gdaltest\n'), ((1854, 16, 1854, 46), 'osgeo.gdal.VSIFOpenL', 'gdal.VSIFOpenL', ({(1854, 31, 1854, 39): 'filename', (1854, 41, 1854, 45): '"""wb"""'}, {}), "(filename, 'wb')", False, 'from osgeo import gdal\n'), ((1856, 18, 1856, 57), 'osgeo.gdal.VSIFWriteL', 'gdal.VSIFWriteL', ({(1856, 34, 1856, 44): 'big_buffer', (1856, 46, 1856, 47): '1', (1856, 49, 1856, 53): 'size', (1856, 55, 1856, 56): 'f'}, {}), '(big_buffer, 1, size, f)', False, 'from osgeo import gdal\n'), ((1858, 12, 1858, 29), 'osgeo.gdal.ErrorReset', 'gdal.ErrorReset', ({}, {}), '()', False, 'from osgeo import gdal\n'), ((1876, 13, 1876, 60), 'gdaltest.config_option', 'gdaltest.config_option', ({(1876, 36, 1876, 54): '"""VSIS3_CHUNK_SIZE"""', (1876, 56, 1876, 59): '"""1"""'}, {}), "('VSIS3_CHUNK_SIZE', '1')", False, 'import gdaltest\n'), ((1899, 13, 1899, 37), 'gdaltest.error_handler', 'gdaltest.error_handler', ({}, {}), '()', False, 'import gdaltest\n'), ((1915, 13, 1915, 37), 'gdaltest.error_handler', 'gdaltest.error_handler', ({}, {}), '()', False, 'import gdaltest\n'), ((1937, 24, 1937, 72), 'osgeo.gdal.VSIStatL', 'gdal.VSIStatL', ({(1937, 38, 1937, 71): '"""/vsis3/s3_bucket_test_mkdir/dir"""'}, {}), "('/vsis3/s3_bucket_test_mkdir/dir')", False, 'from osgeo import gdal\n'), ((2015, 15, 2015, 73), 'osgeo.gdal.ReadDir', 'gdal.ReadDir', ({(2015, 28, 2015, 72): '"""/vsis3/s3_bucket_test_readdir/test_dirread"""'}, {}), "('/vsis3/s3_bucket_test_readdir/test_dirread')", False, 'from osgeo import gdal\n'), ((2050, 15, 2050, 74), 'osgeo.gdal.ReadDir', 'gdal.ReadDir', ({(2050, 28, 2050, 73): '"""/vsis3/s3_bucket_test_readdir2/test_dirread"""'}, {}), "('/vsis3/s3_bucket_test_readdir2/test_dirread')", False, 'from osgeo import gdal\n'), ((2107, 13, 2107, 52), 'webserver.install_http_handler', 'webserver.install_http_handler', ({(2107, 44, 2107, 51): 'handler'}, {}), '(handler)', False, 'import webserver\n'), ((2115, 13, 2115, 52), 'webserver.install_http_handler', 'webserver.install_http_handler', ({(2115, 44, 2115, 51): 'handler'}, {}), '(handler)', False, 'import webserver\n'), ((2135, 12, 2135, 76), 'sys.stderr.write', 'sys.stderr.write', ({(2135, 29, 2135, 75): "('Did not get expected content: %s\\n' % content)"}, {}), "('Did not get expected content: %s\\n' % content)", False, 'import sys\n'), ((2179, 40, 2179, 69), 'webserver.SequentialHandler', 'webserver.SequentialHandler', ({}, {}), '()', False, 'import webserver\n'), ((2194, 11, 2194, 34), 'osgeo.gdal.VSIFReadL', 'gdal.VSIFReadL', ({(2194, 26, 2194, 27): '1', (2194, 29, 2194, 30): '3', (2194, 32, 2194, 33): 'f'}, {}), '(1, 3, f)', False, 'from osgeo import gdal\n'), ((2413, 15, 2413, 79), 'osgeo.gdal.Rename', 'gdal.Rename', ({(2413, 28, 2413, 52): '"""/vsis3/test/source.txt"""', (2413, 54, 2413, 78): '"""/vsis3/test/target.txt"""'}, {}), "('/vsis3/test/source.txt', '/vsis3/test/target.txt')", False, 'from osgeo import gdal\n'), ((2478, 15, 2478, 79), 'osgeo.gdal.Rename', 'gdal.Rename', ({(2478, 28, 2478, 52): '"""/vsis3/test/source_dir"""', (2478, 54, 2478, 78): '"""/vsis3/test/target_dir"""'}, {}), "('/vsis3/test/source_dir', '/vsis3/test/target_dir')", False, 'from osgeo import gdal\n'), ((2496, 15, 2496, 79), 'osgeo.gdal.Rename', 'gdal.Rename', ({(2496, 28, 2496, 52): '"""/vsis3/test/source.txt"""', (2496, 54, 2496, 78): '"""/vsis3/test_target_dir"""'}, {}), "('/vsis3/test/source.txt', '/vsis3/test_target_dir')", False, 'from osgeo import gdal\n'), ((2584, 12, 2584, 76), 'sys.stderr.write', 'sys.stderr.write', ({(2584, 29, 2584, 75): "('Did not get expected content: %s\\n' % content)"}, {}), "('Did not get expected content: %s\\n' % content)", False, 'import sys\n'), ((2597, 13, 2597, 52), 'webserver.install_http_handler', 'webserver.install_http_handler', ({(2597, 44, 2597, 51): 'handler'}, {}), '(handler)', False, 'import webserver\n'), ((2598, 19, 2601, 61), 'osgeo.gdal.Sync', 'gdal.Sync', (), '', False, 'from osgeo import gdal\n'), ((2653, 13, 2653, 52), 'webserver.install_http_handler', 'webserver.install_http_handler', ({(2653, 44, 2653, 51): 'handler'}, {}), '(handler)', False, 'import webserver\n'), ((2722, 12, 2722, 76), 'sys.stderr.write', 'sys.stderr.write', ({(2722, 29, 2722, 75): "('Did not get expected content: %s\\n' % content)"}, {}), "('Did not get expected content: %s\\n' % content)", False, 'import sys\n'), ((2744, 15, 2744, 82), 'osgeo.gdal.GetFileMetadata', 'gdal.GetFileMetadata', ({(2744, 36, 2744, 66): '"""/vsis3/test_metadata/foo.txt"""', (2744, 68, 2744, 81): '"""UNSUPPORTED"""'}, {}), "('/vsis3/test_metadata/foo.txt', 'UNSUPPORTED')", False, 'from osgeo import gdal\n'), ((2748, 19, 2748, 90), 'osgeo.gdal.SetFileMetadata', 'gdal.SetFileMetadata', ({(2748, 40, 2748, 70): '"""/vsis3/test_metadata/foo.txt"""', (2748, 72, 2748, 74): '{}', (2748, 76, 2748, 89): '"""UNSUPPORTED"""'}, {}), "('/vsis3/test_metadata/foo.txt', {}, 'UNSUPPORTED')", False, 'from osgeo import gdal\n'), ((2773, 15, 2773, 73), 'osgeo.gdal.VSIFOpenL', 'gdal.VSIFOpenL', ({(2773, 30, 2773, 66): '"""/vsis3/no_useless_requests/foo.txt"""', (2773, 68, 2773, 72): '"""rb"""'}, {}), "('/vsis3/no_useless_requests/foo.txt', 'rb')", False, 'from osgeo import gdal\n'), ((2774, 15, 2774, 73), 'osgeo.gdal.VSIFOpenL', 'gdal.VSIFOpenL', ({(2774, 30, 2774, 66): '"""/vsis3/no_useless_requests/bar.txt"""', (2774, 68, 2774, 72): '"""rb"""'}, {}), "('/vsis3/no_useless_requests/bar.txt', 'rb')", False, 'from osgeo import gdal\n'), ((2775, 15, 2775, 66), 'osgeo.gdal.VSIStatL', 'gdal.VSIStatL', ({(2775, 29, 2775, 65): '"""/vsis3/no_useless_requests/baz.txt"""'}, {}), "('/vsis3/no_useless_requests/baz.txt')", False, 'from osgeo import gdal\n'), ((2788, 15, 2788, 68), 'osgeo.gdal.VSIFOpenL', 'gdal.VSIFOpenL', ({(2788, 30, 2788, 60): '"""/vsis3/random_write/test.bin"""', (2788, 62, 2788, 67): '"""w+b"""'}, {}), "('/vsis3/random_write/test.bin', 'w+b')", False, 'from osgeo import gdal\n'), ((2802, 15, 2802, 33), 'osgeo.gdal.VSIFCloseL', 'gdal.VSIFCloseL', ({(2802, 31, 2802, 32): 'f'}, {}), '(f)', False, 'from osgeo import gdal\n'), ((2821, 13, 2821, 37), 'gdaltest.error_handler', 'gdaltest.error_handler', ({}, {}), '()', False, 'import gdaltest\n'), ((2836, 13, 2836, 66), 'gdaltest.config_option', 'gdaltest.config_option', ({(2836, 36, 2836, 60): '"""VSIS3_CHUNK_SIZE_BYTES"""', (2836, 62, 2836, 65): '"""1"""'}, {}), "('VSIS3_CHUNK_SIZE_BYTES', '1')", False, 'import gdaltest\n'), ((2837, 16, 2837, 69), 'osgeo.gdal.VSIFOpenL', 'gdal.VSIFOpenL', ({(2837, 31, 2837, 61): '"""/vsis3/random_write/test.bin"""', (2837, 63, 2837, 68): '"""w+b"""'}, {}), "('/vsis3/random_write/test.bin', 'w+b')", False, 'from osgeo import gdal\n'), ((2844, 13, 2844, 37), 'gdaltest.error_handler', 'gdaltest.error_handler', ({}, {}), '()', False, 'import gdaltest\n'), ((2865, 13, 2865, 52), 'webserver.install_http_handler', 'webserver.install_http_handler', ({(2865, 44, 2865, 51): 'handler'}, {}), '(handler)', False, 'import webserver\n'), ((3118, 13, 3118, 37), 'gdaltest.error_handler', 'gdaltest.error_handler', ({}, {}), '()', False, 'import gdaltest\n'), ((3121, 15, 3121, 37), 'osgeo.gdal.GetLastErrorMsg', 'gdal.GetLastErrorMsg', ({}, {}), '()', False, 'from osgeo import gdal\n'), ((3306, 13, 3306, 37), 'gdaltest.error_handler', 'gdaltest.error_handler', ({}, {}), '()', False, 'import gdaltest\n'), ((3337, 48, 3337, 87), 'osgeo.gdal.GetConfigOption', 'gdal.GetConfigOption', ({(3337, 69, 3337, 82): '"""USERPROFILE"""', (3337, 84, 3337, 86): '""""""'}, {}), "('USERPROFILE', '')", False, 'from osgeo import gdal\n'), ((3343, 11, 3343, 56), 'osgeo.gdal.GetConfigOption', 'gdal.GetConfigOption', ({(3343, 32, 3343, 55): '"""AWS_SECRET_ACCESS_KEY"""'}, {}), "('AWS_SECRET_ACCESS_KEY')", False, 'from osgeo import gdal\n'), ((3344, 12, 3344, 56), 'pytest.skip', 'pytest.skip', ({(3344, 24, 3344, 55): '"""Missing AWS_SECRET_ACCESS_KEY"""'}, {}), "('Missing AWS_SECRET_ACCESS_KEY')", False, 'import pytest\n'), ((3354, 39, 3354, 65), 'stat.S_ISDIR', 'stat.S_ISDIR', ({(3354, 52, 3354, 64): 'statres.mode'}, {}), '(statres.mode)', False, 'import stat\n'), ((3405, 15, 3405, 73), 'osgeo.gdal.Rename', 'gdal.Rename', ({(3405, 27, 3405, 48): "(subpath + '/test.txt')", (3405, 50, 3405, 72): "(subpath + '/test2.txt')"}, {}), "(subpath + '/test.txt', subpath + '/test2.txt')", False, 'from osgeo import gdal\n'), ((3442, 13, 3442, 37), 'gdaltest.error_handler', 'gdaltest.error_handler', ({}, {}), '()', False, 'import gdaltest\n'), ((3443, 12, 3443, 35), 'osgeo.gdal.VSIFReadL', 'gdal.VSIFReadL', ({(3443, 27, 3443, 28): '(1)', (3443, 30, 3443, 31): '(1)', (3443, 33, 3443, 34): 'f'}, {}), '(1, 1, f)', False, 'from osgeo import gdal\n'), ((3445, 15, 3445, 40), 'osgeo.gdal.VSIGetLastErrorMsg', 'gdal.VSIGetLastErrorMsg', ({}, {}), '()', False, 'from osgeo import gdal\n'), ((257, 15, 257, 38), 'osgeo.gdal.VSIFReadL', 'gdal.VSIFReadL', ({(257, 30, 257, 31): '1', (257, 33, 257, 34): '4', (257, 36, 257, 37): 'f'}, {}), '(1, 4, f)', False, 'from osgeo import gdal\n'), ((267, 15, 267, 38), 'osgeo.gdal.VSIFReadL', 'gdal.VSIFReadL', ({(267, 30, 267, 31): '1', (267, 33, 267, 34): '4', (267, 36, 267, 37): 'f'}, {}), '(1, 4, f)', False, 'from osgeo import gdal\n'), ((411, 15, 411, 38), 'osgeo.gdal.VSIFReadL', 'gdal.VSIFReadL', ({(411, 30, 411, 31): '1', (411, 33, 411, 34): '4', (411, 36, 411, 37): 'f'}, {}), '(1, 4, f)', False, 'from osgeo import gdal\n'), ((428, 15, 428, 38), 'osgeo.gdal.VSIFReadL', 'gdal.VSIFReadL', ({(428, 30, 428, 31): '1', (428, 33, 428, 34): '4', (428, 36, 428, 37): 'f'}, {}), '(1, 4, f)', False, 'from osgeo import gdal\n'), ((555, 17, 555, 41), 'gdaltest.error_handler', 'gdaltest.error_handler', ({}, {}), '()', False, 'import gdaltest\n'), ((559, 16, 559, 34), 'osgeo.gdal.VSIFCloseL', 'gdal.VSIFCloseL', ({(559, 32, 559, 33): 'f'}, {}), '(f)', False, 'from osgeo import gdal\n'), ((609, 15, 609, 38), 'osgeo.gdal.VSIFReadL', 'gdal.VSIFReadL', ({(609, 30, 609, 31): '1', (609, 33, 609, 34): '3', (609, 36, 609, 37): 'f'}, {}), '(1, 3, f)', False, 'from osgeo import gdal\n'), ((624, 15, 624, 38), 'osgeo.gdal.VSIFReadL', 'gdal.VSIFReadL', ({(624, 30, 624, 31): '1', (624, 33, 624, 34): '3', (624, 36, 624, 37): 'f'}, {}), '(1, 3, f)', False, 'from osgeo import gdal\n'), ((863, 17, 863, 56), 'webserver.install_http_handler', 'webserver.install_http_handler', ({(863, 48, 863, 55): 'handler'}, {}), '(handler)', False, 'import webserver\n'), ((867, 16, 867, 34), 'osgeo.gdal.VSIFCloseL', 'gdal.VSIFCloseL', ({(867, 32, 867, 33): 'f'}, {}), '(f)', False, 'from osgeo import gdal\n'), ((873, 17, 873, 56), 'webserver.install_http_handler', 'webserver.install_http_handler', ({(873, 48, 873, 55): 'handler'}, {}), '(handler)', False, 'import webserver\n'), ((880, 17, 880, 56), 'webserver.install_http_handler', 'webserver.install_http_handler', ({(880, 48, 880, 55): 'handler'}, {}), '(handler)', False, 'import webserver\n'), ((889, 17, 889, 56), 'webserver.install_http_handler', 'webserver.install_http_handler', ({(889, 48, 889, 55): 'handler'}, {}), '(handler)', False, 'import webserver\n'), ((893, 16, 893, 34), 'osgeo.gdal.VSIFCloseL', 'gdal.VSIFCloseL', ({(893, 32, 893, 33): 'f'}, {}), '(f)', False, 'from osgeo import gdal\n'), ((921, 17, 921, 56), 'webserver.install_http_handler', 'webserver.install_http_handler', ({(921, 48, 921, 55): 'handler'}, {}), '(handler)', False, 'import webserver\n'), ((925, 16, 925, 34), 'osgeo.gdal.VSIFCloseL', 'gdal.VSIFCloseL', ({(925, 32, 925, 33): 'f'}, {}), '(f)', False, 'from osgeo import gdal\n'), ((929, 17, 929, 56), 'webserver.install_http_handler', 'webserver.install_http_handler', ({(929, 48, 929, 55): 'handler'}, {}), '(handler)', False, 'import webserver\n'), ((933, 16, 933, 34), 'osgeo.gdal.VSIFCloseL', 'gdal.VSIFCloseL', ({(933, 32, 933, 33): 'f'}, {}), '(f)', False, 'from osgeo import gdal\n'), ((1202, 15, 1202, 69), 'osgeo.gdal.VSIStatL', 'gdal.VSIStatL', ({(1202, 29, 1202, 68): '"""/vsis3/s3_fake_bucket3/empty_file.bin"""'}, {}), "('/vsis3/s3_fake_bucket3/empty_file.bin')", False, 'from osgeo import gdal\n'), ((1229, 15, 1229, 69), 'osgeo.gdal.VSIStatL', 'gdal.VSIStatL', ({(1229, 29, 1229, 68): '"""/vsis3/s3_fake_bucket3/empty_file.bin"""'}, {}), "('/vsis3/s3_fake_bucket3/empty_file.bin')", False, 'from osgeo import gdal\n'), ((1266, 44, 1266, 73), 'webserver.SequentialHandler', 'webserver.SequentialHandler', ({}, {}), '()', False, 'import webserver\n'), ((1270, 19, 1270, 42), 'osgeo.gdal.VSIFSeekL', 'gdal.VSIFSeekL', ({(1270, 34, 1270, 35): 'f', (1270, 37, 1270, 38): '(0)', (1270, 40, 1270, 41): '(1)'}, {}), '(f, 0, 1)', False, 'from osgeo import gdal\n'), ((1271, 19, 1271, 42), 'osgeo.gdal.VSIFSeekL', 'gdal.VSIFSeekL', ({(1271, 34, 1271, 35): 'f', (1271, 37, 1271, 38): '(0)', (1271, 40, 1271, 41): '(2)'}, {}), '(f, 0, 2)', False, 'from osgeo import gdal\n'), ((1272, 19, 1272, 50), 'osgeo.gdal.VSIFWriteL', 'gdal.VSIFWriteL', ({(1272, 35, 1272, 40): '"""foo"""', (1272, 42, 1272, 43): '(1)', (1272, 45, 1272, 46): '(3)', (1272, 48, 1272, 49): 'f'}, {}), "('foo', 1, 3, f)", False, 'from osgeo import gdal\n'), ((1274, 19, 1274, 50), 'osgeo.gdal.VSIFWriteL', 'gdal.VSIFWriteL', ({(1274, 35, 1274, 40): '"""bar"""', (1274, 42, 1274, 43): '(1)', (1274, 45, 1274, 46): '(3)', (1274, 48, 1274, 49): 'f'}, {}), "('bar', 1, 3, f)", False, 'from osgeo import gdal\n'), ((1290, 16, 1290, 80), 'sys.stderr.write', 'sys.stderr.write', ({(1290, 33, 1290, 79): "('Did not get expected content: %s\\n' % content)"}, {}), "('Did not get expected content: %s\\n' % content)", False, 'import sys\n'), ((1412, 44, 1412, 73), 'webserver.SequentialHandler', 'webserver.SequentialHandler', ({}, {}), '()', False, 'import webserver\n'), ((1415, 19, 1415, 50), 'osgeo.gdal.VSIFWriteL', 'gdal.VSIFWriteL', ({(1415, 35, 1415, 40): '"""foo"""', (1415, 42, 1415, 43): '(1)', (1415, 45, 1415, 46): '(3)', (1415, 48, 1415, 49): 'f'}, {}), "('foo', 1, 3, f)", False, 'from osgeo import gdal\n'), ((1431, 16, 1431, 80), 'sys.stderr.write', 'sys.stderr.write', ({(1431, 33, 1431, 79): "('Did not get expected content: %s\\n' % content)"}, {}), "('Did not get expected content: %s\\n' % content)", False, 'import sys\n'), ((1445, 17, 1445, 56), 'webserver.install_http_handler', 'webserver.install_http_handler', ({(1445, 48, 1445, 55): 'handler'}, {}), '(handler)', False, 'import webserver\n'), ((1446, 16, 1446, 34), 'osgeo.gdal.VSIFCloseL', 'gdal.VSIFCloseL', ({(1446, 32, 1446, 33): 'f'}, {}), '(f)', False, 'from osgeo import gdal\n'), ((1466, 15, 1466, 67), 'osgeo.gdal.VSIStatL', 'gdal.VSIStatL', ({(1466, 29, 1466, 66): '"""/vsis3/s3_delete_bucket/delete_file"""'}, {}), "('/vsis3/s3_delete_bucket/delete_file')", False, 'from osgeo import gdal\n'), ((1470, 15, 1470, 67), 'osgeo.gdal.VSIStatL', 'gdal.VSIStatL', ({(1470, 29, 1470, 66): '"""/vsis3/s3_delete_bucket/delete_file"""'}, {}), "('/vsis3/s3_delete_bucket/delete_file')", False, 'from osgeo import gdal\n'), ((1666, 19, 1666, 77), 'osgeo.gdal.RmdirRecursive', 'gdal.RmdirRecursive', ({(1666, 39, 1666, 76): '"""/vsis3/test_rmdir_recursive/somedir"""'}, {}), "('/vsis3/test_rmdir_recursive/somedir')", False, 'from osgeo import gdal\n'), ((1679, 44, 1679, 73), 'webserver.SequentialHandler', 'webserver.SequentialHandler', ({}, {}), '()', False, 'import webserver\n'), ((1788, 17, 1788, 64), 'gdaltest.config_option', 'gdaltest.config_option', ({(1788, 40, 1788, 58): '"""VSIS3_CHUNK_SIZE"""', (1788, 60, 1788, 63): '"""1"""'}, {}), "('VSIS3_CHUNK_SIZE', '1')", False, 'import gdaltest\n'), ((1789, 20, 1789, 50), 'osgeo.gdal.VSIFOpenL', 'gdal.VSIFOpenL', ({(1789, 35, 1789, 43): 'filename', (1789, 45, 1789, 49): '"""wb"""'}, {}), "(filename, 'wb')", False, 'from osgeo import gdal\n'), ((1791, 17, 1791, 41), 'gdaltest.error_handler', 'gdaltest.error_handler', ({}, {}), '()', False, 'import gdaltest\n'), ((1792, 22, 1792, 61), 'osgeo.gdal.VSIFWriteL', 'gdal.VSIFWriteL', ({(1792, 38, 1792, 48): 'big_buffer', (1792, 50, 1792, 51): '1', (1792, 53, 1792, 57): 'size', (1792, 59, 1792, 60): 'f'}, {}), '(big_buffer, 1, size, f)', False, 'from osgeo import gdal\n'), ((1796, 19, 1796, 41), 'osgeo.gdal.GetLastErrorMsg', 'gdal.GetLastErrorMsg', ({}, {}), '()', False, 'from osgeo import gdal\n'), ((1812, 17, 1812, 64), 'gdaltest.config_option', 'gdaltest.config_option', ({(1812, 40, 1812, 58): '"""VSIS3_CHUNK_SIZE"""', (1812, 60, 1812, 63): '"""1"""'}, {}), "('VSIS3_CHUNK_SIZE', '1')", False, 'import gdaltest\n'), ((1813, 20, 1813, 50), 'osgeo.gdal.VSIFOpenL', 'gdal.VSIFOpenL', ({(1813, 35, 1813, 43): 'filename', (1813, 45, 1813, 49): '"""wb"""'}, {}), "(filename, 'wb')", False, 'from osgeo import gdal\n'), ((1815, 17, 1815, 41), 'gdaltest.error_handler', 'gdaltest.error_handler', ({}, {}), '()', False, 'import gdaltest\n'), ((1816, 22, 1816, 61), 'osgeo.gdal.VSIFWriteL', 'gdal.VSIFWriteL', ({(1816, 38, 1816, 48): 'big_buffer', (1816, 50, 1816, 51): '1', (1816, 53, 1816, 57): 'size', (1816, 59, 1816, 60): 'f'}, {}), '(big_buffer, 1, size, f)', False, 'from osgeo import gdal\n'), ((1820, 19, 1820, 41), 'osgeo.gdal.GetLastErrorMsg', 'gdal.GetLastErrorMsg', ({}, {}), '()', False, 'from osgeo import gdal\n'), ((1859, 17, 1859, 41), 'gdaltest.error_handler', 'gdaltest.error_handler', ({}, {}), '()', False, 'import gdaltest\n'), ((1860, 16, 1860, 34), 'osgeo.gdal.VSIFCloseL', 'gdal.VSIFCloseL', ({(1860, 32, 1860, 33): 'f'}, {}), '(f)', False, 'from osgeo import gdal\n'), ((1861, 19, 1861, 41), 'osgeo.gdal.GetLastErrorMsg', 'gdal.GetLastErrorMsg', ({}, {}), '()', False, 'from osgeo import gdal\n'), ((1878, 20, 1878, 81), 'osgeo.gdal.VSIFOpenL', 'gdal.VSIFOpenL', ({(1878, 35, 1878, 74): '"""/vsis3/s3_fake_bucket4/large_file.bin"""', (1878, 76, 1878, 80): '"""wb"""'}, {}), "('/vsis3/s3_fake_bucket4/large_file.bin', 'wb')", False, 'from osgeo import gdal\n'), ((1900, 17, 1900, 56), 'webserver.install_http_handler', 'webserver.install_http_handler', ({(1900, 48, 1900, 55): 'handler'}, {}), '(handler)', False, 'import webserver\n'), ((1901, 22, 1901, 61), 'osgeo.gdal.VSIFWriteL', 'gdal.VSIFWriteL', ({(1901, 38, 1901, 48): 'big_buffer', (1901, 50, 1901, 51): '1', (1901, 53, 1901, 57): 'size', (1901, 59, 1901, 60): 'f'}, {}), '(big_buffer, 1, size, f)', False, 'from osgeo import gdal\n'), ((1916, 17, 1916, 56), 'webserver.install_http_handler', 'webserver.install_http_handler', ({(1916, 48, 1916, 55): 'handler'}, {}), '(handler)', False, 'import webserver\n'), ((1917, 16, 1917, 34), 'osgeo.gdal.VSIFCloseL', 'gdal.VSIFCloseL', ({(1917, 32, 1917, 33): 'f'}, {}), '(f)', False, 'from osgeo import gdal\n'), ((1998, 28, 1998, 89), 'osgeo.gdal.VSIStatL', 'gdal.VSIStatL', ({(1998, 42, 1998, 88): '"""/vsis3/s3_bucket_test_dir_stat/test_dir_stat"""'}, {}), "('/vsis3/s3_bucket_test_dir_stat/test_dir_stat')", False, 'from osgeo import gdal\n'), ((2033, 28, 2033, 92), 'osgeo.gdal.VSIStatL', 'gdal.VSIStatL', ({(2033, 42, 2033, 91): '"""/vsis3/s3_bucket_test_dir_stat_2/test_dir_stat/"""'}, {}), "('/vsis3/s3_bucket_test_dir_stat_2/test_dir_stat/')", False, 'from osgeo import gdal\n'), ((2089, 28, 2089, 65), 'osgeo.gdal.VSIStatL', 'gdal.VSIStatL', ({(2089, 42, 2089, 64): '"""/vsis3/vsis3_8/test/"""'}, {}), "('/vsis3/vsis3_8/test/')", False, 'from osgeo import gdal\n'), ((2108, 23, 2108, 79), 'osgeo.gdal.Sync', 'gdal.Sync', (), '', False, 'from osgeo import gdal\n'), ((2116, 23, 2116, 86), 'osgeo.gdal.Sync', 'gdal.Sync', (), '', False, 'from osgeo import gdal\n'), ((2654, 17, 2654, 41), 'gdaltest.error_handler', 'gdaltest.error_handler', ({}, {}), '()', False, 'import gdaltest\n'), ((2795, 11, 2795, 34), 'osgeo.gdal.VSIFReadL', 'gdal.VSIFReadL', ({(2795, 26, 2795, 27): '(3)', (2795, 29, 2795, 30): '(1)', (2795, 32, 2795, 33): 'f'}, {}), '(3, 1, f)', False, 'from osgeo import gdal\n'), ((2822, 19, 2822, 37), 'osgeo.gdal.VSIFCloseL', 'gdal.VSIFCloseL', ({(2822, 35, 2822, 36): 'f'}, {}), '(f)', False, 'from osgeo import gdal\n'), ((2845, 23, 2845, 41), 'osgeo.gdal.VSIFCloseL', 'gdal.VSIFCloseL', ({(2845, 39, 2845, 40): 'f'}, {}), '(f)', False, 'from osgeo import gdal\n'), ((2907, 15, 2907, 38), 'osgeo.gdal.VSIFReadL', 'gdal.VSIFReadL', ({(2907, 30, 2907, 31): '1', (2907, 33, 2907, 34): '4', (2907, 36, 2907, 37): 'f'}, {}), '(1, 4, f)', False, 'from osgeo import gdal\n'), ((2949, 15, 2949, 38), 'osgeo.gdal.VSIFReadL', 'gdal.VSIFReadL', ({(2949, 30, 2949, 31): '1', (2949, 33, 2949, 34): '4', (2949, 36, 2949, 37): 'f'}, {}), '(1, 4, f)', False, 'from osgeo import gdal\n'), ((3004, 15, 3004, 38), 'osgeo.gdal.VSIFReadL', 'gdal.VSIFReadL', ({(3004, 30, 3004, 31): '1', (3004, 33, 3004, 34): '4', (3004, 36, 3004, 37): 'f'}, {}), '(1, 4, f)', False, 'from osgeo import gdal\n'), ((3065, 15, 3065, 38), 'osgeo.gdal.VSIFReadL', 'gdal.VSIFReadL', ({(3065, 30, 3065, 31): '1', (3065, 33, 3065, 34): '4', (3065, 36, 3065, 37): 'f'}, {}), '(1, 4, f)', False, 'from osgeo import gdal\n'), ((3122, 15, 3122, 38), 'osgeo.gdal.VSIFReadL', 'gdal.VSIFReadL', ({(3122, 30, 3122, 31): '1', (3122, 33, 3122, 34): '4', (3122, 36, 3122, 37): 'f'}, {}), '(1, 4, f)', False, 'from osgeo import gdal\n'), ((3173, 15, 3173, 38), 'osgeo.gdal.VSIFReadL', 'gdal.VSIFReadL', ({(3173, 30, 3173, 31): '1', (3173, 33, 3173, 34): '4', (3173, 36, 3173, 37): 'f'}, {}), '(1, 4, f)', False, 'from osgeo import gdal\n'), ((3186, 15, 3186, 38), 'osgeo.gdal.VSIFReadL', 'gdal.VSIFReadL', ({(3186, 30, 3186, 31): '1', (3186, 33, 3186, 34): '4', (3186, 36, 3186, 37): 'f'}, {}), '(1, 4, f)', False, 'from osgeo import gdal\n'), ((3235, 15, 3235, 38), 'osgeo.gdal.VSIFReadL', 'gdal.VSIFReadL', ({(3235, 30, 3235, 31): '1', (3235, 33, 3235, 34): '4', (3235, 36, 3235, 37): 'f'}, {}), '(1, 4, f)', False, 'from osgeo import gdal\n'), ((3293, 15, 3293, 38), 'osgeo.gdal.VSIFReadL', 'gdal.VSIFReadL', ({(3293, 30, 3293, 31): '1', (3293, 33, 3293, 34): '4', (3293, 36, 3293, 37): 'f'}, {}), '(1, 4, f)', False, 'from osgeo import gdal\n'), ((3345, 13, 3345, 54), 'osgeo.gdal.GetConfigOption', 'gdal.GetConfigOption', ({(3345, 34, 3345, 53): '"""AWS_ACCESS_KEY_ID"""'}, {}), "('AWS_ACCESS_KEY_ID')", False, 'from osgeo import gdal\n'), ((3346, 12, 3346, 52), 'pytest.skip', 'pytest.skip', ({(3346, 24, 3346, 51): '"""Missing AWS_ACCESS_KEY_ID"""'}, {}), "('Missing AWS_ACCESS_KEY_ID')", False, 'import pytest\n'), ((3401, 15, 3401, 38), 'osgeo.gdal.VSIFReadL', 'gdal.VSIFReadL', ({(3401, 30, 3401, 31): '1', (3401, 33, 3401, 34): '5', (3401, 36, 3401, 37): 'f'}, {}), '(1, 5, f)', False, 'from osgeo import gdal\n'), ((3409, 15, 3409, 38), 'osgeo.gdal.VSIFReadL', 'gdal.VSIFReadL', ({(3409, 30, 3409, 31): '1', (3409, 33, 3409, 34): '5', (3409, 36, 3409, 37): 'f'}, {}), '(1, 5, f)', False, 'from osgeo import gdal\n'), ((3449, 44, 3449, 79), 'osgeo.gdal.GetConfigOption', 'gdal.GetConfigOption', ({(3449, 65, 3449, 78): '"""S3_RESOURCE"""'}, {}), "('S3_RESOURCE')", False, 'from osgeo import gdal\n'), ((160, 25, 160, 50), 'osgeo.gdal.VSIGetLastErrorMsg', 'gdal.VSIGetLastErrorMsg', ({}, {}), '()', False, 'from osgeo import gdal\n'), ((165, 25, 165, 50), 'osgeo.gdal.VSIGetLastErrorMsg', 'gdal.VSIGetLastErrorMsg', ({}, {}), '()', False, 'from osgeo import gdal\n'), ((173, 25, 173, 50), 'osgeo.gdal.VSIGetLastErrorMsg', 'gdal.VSIGetLastErrorMsg', ({}, {}), '()', False, 'from osgeo import gdal\n'), ((301, 19, 301, 42), 'osgeo.gdal.VSIFReadL', 'gdal.VSIFReadL', ({(301, 34, 301, 35): '1', (301, 37, 301, 38): '4', (301, 40, 301, 41): 'f'}, {}), '(1, 4, f)', False, 'from osgeo import gdal\n'), ((458, 25, 458, 50), 'osgeo.gdal.VSIGetLastErrorMsg', 'gdal.VSIGetLastErrorMsg', ({}, {}), '()', False, 'from osgeo import gdal\n'), ((471, 25, 471, 50), 'osgeo.gdal.VSIGetLastErrorMsg', 'gdal.VSIGetLastErrorMsg', ({}, {}), '()', False, 'from osgeo import gdal\n'), ((484, 25, 484, 50), 'osgeo.gdal.VSIGetLastErrorMsg', 'gdal.VSIGetLastErrorMsg', ({}, {}), '()', False, 'from osgeo import gdal\n'), ((497, 25, 497, 50), 'osgeo.gdal.VSIGetLastErrorMsg', 'gdal.VSIGetLastErrorMsg', ({}, {}), '()', False, 'from osgeo import gdal\n'), ((510, 25, 510, 50), 'osgeo.gdal.VSIGetLastErrorMsg', 'gdal.VSIGetLastErrorMsg', ({}, {}), '()', False, 'from osgeo import gdal\n'), ((523, 25, 523, 50), 'osgeo.gdal.VSIGetLastErrorMsg', 'gdal.VSIGetLastErrorMsg', ({}, {}), '()', False, 'from osgeo import gdal\n'), ((874, 23, 874, 69), 'osgeo.gdal.VSIStatL', 'gdal.VSIStatL', ({(874, 37, 874, 68): '"""/vsis3/s3_non_cached/test.txt"""'}, {}), "('/vsis3/s3_non_cached/test.txt')", False, 'from osgeo import gdal\n'), ((881, 23, 881, 69), 'osgeo.gdal.VSIStatL', 'gdal.VSIStatL', ({(881, 37, 881, 68): '"""/vsis3/s3_non_cached/test.txt"""'}, {}), "('/vsis3/s3_non_cached/test.txt')", False, 'from osgeo import gdal\n'), ((884, 20, 884, 37), 'pytest.fail', 'pytest.fail', ({(884, 32, 884, 36): 'data'}, {}), '(data)', False, 'import pytest\n'), ((1269, 37, 1269, 54), 'osgeo.gdal.VSIFTellL', 'gdal.VSIFTellL', ({(1269, 52, 1269, 53): 'f'}, {}), '(f)', False, 'from osgeo import gdal\n'), ((1273, 37, 1273, 54), 'osgeo.gdal.VSIFTellL', 'gdal.VSIFTellL', ({(1273, 52, 1273, 53): 'f'}, {}), '(f)', False, 'from osgeo import gdal\n'), ((1378, 16, 1378, 80), 'sys.stderr.write', 'sys.stderr.write', ({(1378, 33, 1378, 79): "('Did not get expected content: %s\\n' % content)"}, {}), "('Did not get expected content: %s\\n' % content)", False, 'import sys\n'), ((1877, 48, 1877, 77), 'webserver.SequentialHandler', 'webserver.SequentialHandler', ({}, {}), '()', False, 'import webserver\n'), ((2085, 32, 2085, 68), 'osgeo.gdal.VSIStatL', 'gdal.VSIStatL', ({(2085, 46, 2085, 67): '"""/vsis3/vsis3_8/test"""'}, {}), "('/vsis3/vsis3_8/test')", False, 'from osgeo import gdal\n'), ((2655, 27, 2657, 79), 'osgeo.gdal.Sync', 'gdal.Sync', (), '', False, 'from osgeo import gdal\n'), ((2866, 17, 2866, 46), 'osgeo.gdal.GetDriverByName', 'gdal.GetDriverByName', ({(2866, 38, 2866, 45): '"""GTiff"""'}, {}), "('GTiff')", False, 'from osgeo import gdal\n'), ((3362, 23, 3362, 45), 'osgeo.gdal.VSIStatL', 'gdal.VSIStatL', ({(3362, 37, 3362, 44): 'subpath'}, {}), '(subpath)', False, 'from osgeo import gdal\n'), ((558, 23, 558, 46), 'osgeo.gdal.VSIFReadL', 'gdal.VSIFReadL', ({(558, 38, 558, 39): '1', (558, 41, 558, 42): '3', (558, 44, 558, 45): 'f'}, {}), '(1, 3, f)', False, 'from osgeo import gdal\n'), ((866, 23, 866, 46), 'osgeo.gdal.VSIFReadL', 'gdal.VSIFReadL', ({(866, 38, 866, 39): '1', (866, 41, 866, 42): '3', (866, 44, 866, 45): 'f'}, {}), '(1, 3, f)', False, 'from osgeo import gdal\n'), ((892, 23, 892, 46), 'osgeo.gdal.VSIFReadL', 'gdal.VSIFReadL', ({(892, 38, 892, 39): '1', (892, 41, 892, 42): '4', (892, 44, 892, 45): 'f'}, {}), '(1, 4, f)', False, 'from osgeo import gdal\n'), ((924, 23, 924, 46), 'osgeo.gdal.VSIFReadL', 'gdal.VSIFReadL', ({(924, 38, 924, 39): '1', (924, 41, 924, 42): '3', (924, 44, 924, 45): 'f'}, {}), '(1, 3, f)', False, 'from osgeo import gdal\n'), ((932, 23, 932, 46), 'osgeo.gdal.VSIFReadL', 'gdal.VSIFReadL', ({(932, 38, 932, 39): '1', (932, 41, 932, 42): '4', (932, 44, 932, 45): 'f'}, {}), '(1, 4, f)', False, 'from osgeo import gdal\n')]