Exemple #1
0
def test_cache_checks_url_validity(broker, req):
    res, meta = broker.execute("mock_retrieve", req).wait()
    assert cache_status(meta) == "miss"

    meta = broker.execute("mock_retrieve", req).metadata
    assert cache_status(meta) == "hit"

    first_result_url = res[0]["result"]["location"]
    path = urlparse(first_result_url).path
    os.unlink(path)
    assert requests.head(first_result_url).status_code == 404

    res, meta = broker.execute("mock_retrieve", req).wait()
    assert cache_status(meta) == "miss"

    first_result_url = res[0]["result"]["location"]
    path = urlparse(first_result_url).path
    with open(path, "wb") as f:
        f.write(b"make file size not match cached value")
    assert requests.head(first_result_url).status_code == 200
    assert os.stat(path).st_size != res[0]["result"]["contentLength"]
    meta = broker.execute("mock_retrieve", req).metadata
    assert cache_status(meta) == "miss"

    meta = broker.execute("mock_retrieve", req).metadata
    assert cache_status(meta) == "hit"
Exemple #2
0
def download(result, path):
    url = result["location"]
    p = urlparse(url)
    if p.scheme not in {"http", "https"}:
        raise Exception("{}: Unsupported URL scheme '{}'".format(
            url, p.scheme))

    if PY2:
        path = str(path)

    fd, tmp_fname = tempfile.mkstemp(dir=os.path.dirname(path))
    try:
        with closing(requests.get(url, stream=True, timeout=20)) as res:
            res.raise_for_status()
            for chunk in res.iter_content(XFER_BLOCK_SIZE):
                os.write(fd, chunk)
    except Exception as exc:
        try:
            os.unlink(tmp_fname)
        except Exception:
            pass
        raise_from(exc, exc)
    finally:
        os.close(fd)

    # TODO: Verify number of bytes downloaded matches `result["contentLength"]`

    os.rename(tmp_fname, path)
Exemple #3
0
def instance(url=None, group=None, name=None):
    """Factory for config clients.

    Returns a config client reading values from the URL taken from the
    environment variable `SERVICELIB_CONFIG_URL`. If that environment variable
    is not set, the hard-coded value `http://localhost:9999/settings/` will be
    used.

    """

    if url is None:
        url = os.environ.get("SERVICELIB_CONFIG_URL",
                             "http://localhost:9999/settings/")
    try:
        return _instances[url]
    except KeyError:
        scheme = urlparse(url).scheme

        if scheme in {"http", "https"}:
            ret = HTTPConfigClient(url, group=group, name=name)
        elif scheme == "file":
            ret = FileConfigClient(url, group=group, name=name)
        else:
            raise ValueError("Unsupported URL scheme in {}".format(url))
        _instances[url] = ret
        return ret
Exemple #4
0
 def as_local_file(self, result):
     ret = Path(urlparse(result["location"]).path)
     for d in self.result_dirs:
         try:
             d = Path(d)
             ret.relative_to(d)
             st_size = ret.stat().st_size
             if st_size == result["contentLength"]:
                 return ret
             self.log.debug(
                 "as_local_file(%s): size %s does not match contentLength",
                 result,
                 st_size,
             )
         except Exception as exc:
             self.log.info("as_local_file(%s): Not in %s: %s", result, d,
                           exc)
Exemple #5
0
def service_url(name, local_only=False):
    # TODO: Cache results.
    c = _redis_pool.connection()
    k = redis_key(name)

    url = None
    if local_only:
        for parsed, unparsed in [(urlparse(u), u) for u in c.smembers(k)]:
            if parsed.netloc.split(":")[0] == HOSTNAME:
                url = unparsed
                break
    else:
        url = c.srandmember(k)

    if url is None:
        raise Exception(
            "No URL for service {} (local-only: {})".format(name, local_only)
        )
    return url
Exemple #6
0
def services_by_netloc():
    ret = {}
    for service, urls in services_by_name().items():
        for url in urls:
            ret.setdefault(urlparse(url).netloc, set()).add(service)
    return ret
Exemple #7
0
 def __init__(self, url, *args, **kwargs):
     super(FileConfigClient, self).__init__(url, *args, **kwargs)
     self._fname = urlparse(self.url).path