From f22f9999c1b9098e709f9cedcc26bca3c709486b Mon Sep 17 00:00:00 2001 From: Jon Wayne Parrott Date: Wed, 5 Apr 2017 14:43:19 -0700 Subject: [PATCH 1/2] Remove resource fixture --- appengine/standard/bigquery/main_test.py | 5 +++-- bigquery/api/load_data_by_post_test.py | 13 +++++++------ bigquery/api/load_data_from_csv_test.py | 5 +++-- bigquery/api/streaming_test.py | 5 +++-- .../cloud-client/load_data_from_file_test.py | 7 +++++-- conftest.py | 8 -------- language/sentiment/sentiment_analysis_test.py | 19 +++++++++++-------- language/syntax_triples/main_test.py | 7 +++++-- .../api/v3/cloud-client/snippets_test.py | 2 +- speech/api-client/transcribe_async_test.py | 7 +++++-- speech/api-client/transcribe_test.py | 7 +++++-- speech/cloud-client/transcribe_async_test.py | 10 +++++++--- .../cloud-client/transcribe_streaming_test.py | 8 ++++++-- speech/cloud-client/transcribe_test.py | 9 ++++++--- speech/grpc/transcribe_async_test.py | 3 +-- .../grpc/transcribe_streaming_minute_test.py | 9 +++++++-- speech/grpc/transcribe_streaming_test.py | 7 +++++-- speech/grpc/transcribe_test.py | 3 +-- storage/api/compose_objects_test.py | 7 ++++--- vision/api/label/label_test.py | 7 +++++-- vision/api/label/snippets_test.py | 16 +++++++++------- .../cloud-client/face_detection/faces_test.py | 6 ++++-- 22 files changed, 103 insertions(+), 67 deletions(-) diff --git a/appengine/standard/bigquery/main_test.py b/appengine/standard/bigquery/main_test.py index dcad3391bb01..443d30b6dee0 100644 --- a/appengine/standard/bigquery/main_test.py +++ b/appengine/standard/bigquery/main_test.py @@ -22,6 +22,7 @@ import main +RESOURCES = os.path.join(os.path.dirname(__file__), 'resources') PROJECT = os.environ['GCLOUD_PROJECT'] @@ -49,11 +50,11 @@ def test_loggedin(app, login): assert re.search(r'.*oauth2.*', response.headers['Location']) -def test_oauthed(resource, app, login): +def test_oauthed(app, login): login() mock_http = HttpMock( - resource('datasets-list.json'), + os.path.join(RESOURCES, 'datasets-list.json'), {'status': '200'}) with mock.patch.object(main.decorator, 'http', return_value=mock_http): diff --git a/bigquery/api/load_data_by_post_test.py b/bigquery/api/load_data_by_post_test.py index b2d2e7706483..1fe7f1804d97 100644 --- a/bigquery/api/load_data_by_post_test.py +++ b/bigquery/api/load_data_by_post_test.py @@ -18,15 +18,16 @@ from load_data_by_post import load_data +RESOURCES = os.path.join(os.path.dirname(__file__), 'resources') PROJECT = os.environ['GCLOUD_PROJECT'] DATASET_ID = 'ephemeral_test_dataset' TABLE_ID = 'load_data_by_post' @flaky -def test_load_csv_data(resource, capsys): - schema_path = resource('schema.json') - data_path = resource('data.csv') +def test_load_csv_data(capsys): + schema_path = os.path.join(RESOURCES, 'schema.json') + data_path = os.path.join(RESOURCES, 'data.csv') load_data( schema_path, @@ -43,9 +44,9 @@ def test_load_csv_data(resource, capsys): @flaky -def test_load_json_data(resource, capsys): - schema_path = resource('schema.json') - data_path = resource('data.json') +def test_load_json_data(capsys): + schema_path = os.path.join(RESOURCES, 'schema.json') + data_path = os.path.join(RESOURCES, 'data.json') load_data( schema_path, diff --git a/bigquery/api/load_data_from_csv_test.py b/bigquery/api/load_data_from_csv_test.py index 8154b5d44284..908c908f0506 100644 --- a/bigquery/api/load_data_from_csv_test.py +++ b/bigquery/api/load_data_from_csv_test.py @@ -17,6 +17,7 @@ from load_data_from_csv import main +RESOURCES = os.path.join(os.path.dirname(__file__), 'resources') PROJECT = os.environ['GCLOUD_PROJECT'] BUCKET = os.environ['CLOUD_STORAGE_BUCKET'] DATASET_ID = 'test_dataset' @@ -24,9 +25,9 @@ @flaky -def test_load_table(resource): +def test_load_table(): cloud_storage_input_uri = 'gs://{}/data.csv'.format(BUCKET) - schema_file = resource('schema.json') + schema_file = os.path.join(RESOURCES, 'schema.json') main( PROJECT, diff --git a/bigquery/api/streaming_test.py b/bigquery/api/streaming_test.py index 97ddbc19dd42..9c8e6a2e43c9 100644 --- a/bigquery/api/streaming_test.py +++ b/bigquery/api/streaming_test.py @@ -16,13 +16,14 @@ import streaming +RESOURCES = os.path.join(os.path.dirname(__file__), 'resources') PROJECT = os.environ['GCLOUD_PROJECT'] DATASET_ID = 'test_dataset' TABLE_ID = 'test_table' -def test_stream_row_to_bigquery(resource, capsys): - with open(resource('streamrows.json'), 'r') as rows_file: +def test_stream_row_to_bigquery(capsys): + with open(os.path.join(RESOURCES, 'streamrows.json'), 'r') as rows_file: rows = json.load(rows_file) streaming.get_rows = lambda: rows diff --git a/bigquery/cloud-client/load_data_from_file_test.py b/bigquery/cloud-client/load_data_from_file_test.py index 434bbd1d84bc..960fe62c9d7c 100644 --- a/bigquery/cloud-client/load_data_from_file_test.py +++ b/bigquery/cloud-client/load_data_from_file_test.py @@ -11,14 +11,17 @@ # See the License for the specific language governing permissions and # limitations under the License. +import os + import load_data_from_file +RESOURCES = os.path.join(os.path.dirname(__file__), 'resources') DATASET_ID = 'test_dataset' TABLE_ID = 'test_import_table' -def test_load_table(resource, capsys): - data_path = resource('data.csv') +def test_load_table(capsys): + data_path = os.path.join(RESOURCES, 'data.csv') load_data_from_file.load_data_from_file( DATASET_ID, diff --git a/conftest.py b/conftest.py index de49705889d6..0009bb56d8e1 100644 --- a/conftest.py +++ b/conftest.py @@ -32,14 +32,6 @@ def get_resource_path(resource, local_path): os.path.join(*resource))) -@pytest.fixture(scope='module') -def resource(request): - """Provides a function that returns the full path to a local or global - testing resource""" - local_path = os.path.dirname(request.module.__file__) - return lambda *args: get_resource_path(args, local_path) - - def fetch_gcs_resource(resource, tmpdir, _chunk_size=1024): resp = requests.get(resource, stream=True) dest_file = str(tmpdir.join(os.path.basename(resource))) diff --git a/language/sentiment/sentiment_analysis_test.py b/language/sentiment/sentiment_analysis_test.py index 19ec86f17d5b..05d28ab27898 100644 --- a/language/sentiment/sentiment_analysis_test.py +++ b/language/sentiment/sentiment_analysis_test.py @@ -11,37 +11,40 @@ # See the License for the specific language governing permissions and # limitations under the License. +import os import re from sentiment_analysis import analyze +RESOURCES = os.path.join(os.path.dirname(__file__), 'resources') -def test_pos(resource, capsys): - analyze(resource('pos.txt')) + +def test_pos(capsys): + analyze(os.path.join(RESOURCES, 'pos.txt')) out, err = capsys.readouterr() score = float(re.search('score of (.+?) with', out).group(1)) magnitude = float(re.search('magnitude of (.+?)', out).group(1)) assert score * magnitude > 0 -def test_neg(resource, capsys): - analyze(resource('neg.txt')) +def test_neg(capsys): + analyze(os.path.join(RESOURCES, 'neg.txt')) out, err = capsys.readouterr() score = float(re.search('score of (.+?) with', out).group(1)) magnitude = float(re.search('magnitude of (.+?)', out).group(1)) assert score * magnitude < 0 -def test_mixed(resource, capsys): - analyze(resource('mixed.txt')) +def test_mixed(capsys): + analyze(os.path.join(RESOURCES, 'mixed.txt')) out, err = capsys.readouterr() score = float(re.search('score of (.+?) with', out).group(1)) assert score <= 0.3 assert score >= -0.3 -def test_neutral(resource, capsys): - analyze(resource('neutral.txt')) +def test_neutral(capsys): + analyze(os.path.join(RESOURCES, 'neutral.txt')) out, err = capsys.readouterr() magnitude = float(re.search('magnitude of (.+?)', out).group(1)) assert magnitude <= 2.0 diff --git a/language/syntax_triples/main_test.py b/language/syntax_triples/main_test.py index 62c2915da02e..6aa87818e35b 100755 --- a/language/syntax_triples/main_test.py +++ b/language/syntax_triples/main_test.py @@ -12,10 +12,13 @@ # See the License for the specific language governing permissions and # limitations under the License. +import os import re import main +RESOURCES = os.path.join(os.path.dirname(__file__), 'resources') + def test_dependents(): text = "I am eating a delicious banana" @@ -41,8 +44,8 @@ def test_find_triples(): assert (1, 2, 5) == triple -def test_obama_example(resource, capsys): - main.main(resource('obama_wikipedia.txt')) +def test_obama_example(capsys): + main.main(os.path.join(RESOURCES, 'obama_wikipedia.txt')) stdout, _ = capsys.readouterr() lines = stdout.split('\n') assert re.match( diff --git a/monitoring/api/v3/cloud-client/snippets_test.py b/monitoring/api/v3/cloud-client/snippets_test.py index f3a2b630bc31..744565421ecd 100644 --- a/monitoring/api/v3/cloud-client/snippets_test.py +++ b/monitoring/api/v3/cloud-client/snippets_test.py @@ -37,7 +37,7 @@ def test_list_resources(capsys): assert 'pubsub_topic' in out -def test_get_resource(capsys): +def test_get_resources(capsys): snippets.get_monitored_resource_descriptor('pubsub_topic') out, _ = capsys.readouterr() assert 'A topic in Google Cloud Pub/Sub' in out diff --git a/speech/api-client/transcribe_async_test.py b/speech/api-client/transcribe_async_test.py index d90f45608c8b..ab147ae9fec0 100644 --- a/speech/api-client/transcribe_async_test.py +++ b/speech/api-client/transcribe_async_test.py @@ -11,13 +11,16 @@ # See the License for the specific language governing permissions and # limitations under the License. +import os import re from transcribe_async import main +RESOURCES = os.path.join(os.path.dirname(__file__), 'resources') -def test_main(resource, capsys): - main(resource('audio.raw')) + +def test_main(capsys): + main(os.path.join(RESOURCES, 'audio.raw')) out, err = capsys.readouterr() assert re.search(r'how old is the Brooklyn Bridge', out, re.DOTALL | re.I) diff --git a/speech/api-client/transcribe_test.py b/speech/api-client/transcribe_test.py index c8cb0a703331..9e34d9d20620 100644 --- a/speech/api-client/transcribe_test.py +++ b/speech/api-client/transcribe_test.py @@ -11,13 +11,16 @@ # See the License for the specific language governing permissions and # limitations under the License. +import os import re from transcribe import main +RESOURCES = os.path.join(os.path.dirname(__file__), 'resources') -def test_main(resource, capsys): - main(resource('audio.raw')) + +def test_main(capsys): + main(os.path.join(RESOURCES, 'audio.raw')) out, err = capsys.readouterr() assert re.search(r'how old is the Brooklyn Bridge', out, re.DOTALL | re.I) diff --git a/speech/cloud-client/transcribe_async_test.py b/speech/cloud-client/transcribe_async_test.py index 6142d43db96b..7d66747eb446 100644 --- a/speech/cloud-client/transcribe_async_test.py +++ b/speech/cloud-client/transcribe_async_test.py @@ -11,19 +11,23 @@ # See the License for the specific language governing permissions and # limitations under the License. +import os import re import transcribe_async +RESOURCES = os.path.join(os.path.dirname(__file__), 'resources') -def test_transcribe(resource, capsys): - transcribe_async.transcribe_file(resource('audio.raw')) + +def test_transcribe(capsys): + transcribe_async.transcribe_file( + os.path.join(RESOURCES, 'audio.raw')) out, err = capsys.readouterr() assert re.search(r'how old is the Brooklyn Bridge', out, re.DOTALL | re.I) -def test_transcribe_gcs(resource, capsys): +def test_transcribe_gcs(capsys): transcribe_async.transcribe_gcs( 'gs://python-docs-samples-tests/speech/audio.flac') out, err = capsys.readouterr() diff --git a/speech/cloud-client/transcribe_streaming_test.py b/speech/cloud-client/transcribe_streaming_test.py index bd3f5cb59a81..2b3ca8ee5c0b 100644 --- a/speech/cloud-client/transcribe_streaming_test.py +++ b/speech/cloud-client/transcribe_streaming_test.py @@ -11,13 +11,17 @@ # See the License for the specific language governing permissions and # limitations under the License. +import os import re import transcribe_streaming +RESOURCES = os.path.join(os.path.dirname(__file__), 'resources') -def test_transcribe_streaming(resource, capsys): - transcribe_streaming.transcribe_streaming(resource('audio.raw')) + +def test_transcribe_streaming(capsys): + transcribe_streaming.transcribe_streaming( + os.path.join(RESOURCES, 'audio.raw')) out, err = capsys.readouterr() assert re.search(r'how old is the Brooklyn Bridge', out, re.DOTALL | re.I) diff --git a/speech/cloud-client/transcribe_test.py b/speech/cloud-client/transcribe_test.py index 5940fc7f9862..d1e9f6338ea6 100644 --- a/speech/cloud-client/transcribe_test.py +++ b/speech/cloud-client/transcribe_test.py @@ -11,19 +11,22 @@ # See the License for the specific language governing permissions and # limitations under the License. +import os import re import transcribe +RESOURCES = os.path.join(os.path.dirname(__file__), 'resources') -def test_transcribe_file(resource, capsys): - transcribe.transcribe_file(resource('audio.raw')) + +def test_transcribe_file(capsys): + transcribe.transcribe_file(os.path.join(RESOURCES, 'audio.raw')) out, err = capsys.readouterr() assert re.search(r'how old is the Brooklyn Bridge', out, re.DOTALL | re.I) -def test_transcribe_gcs(resource, capsys): +def test_transcribe_gcs(capsys): transcribe.transcribe_gcs( 'gs://python-docs-samples-tests/speech/audio.flac') out, err = capsys.readouterr() diff --git a/speech/grpc/transcribe_async_test.py b/speech/grpc/transcribe_async_test.py index 8f99bc47f1af..6a9563483f9c 100644 --- a/speech/grpc/transcribe_async_test.py +++ b/speech/grpc/transcribe_async_test.py @@ -19,8 +19,7 @@ BUCKET = os.environ['CLOUD_STORAGE_BUCKET'] -def test_main(resource, capsys): - +def test_main(capsys): # Run the transcribe sample on audio.raw, verify correct results storage_uri = 'gs://{}/speech/audio.raw'.format(BUCKET) main(storage_uri, 'LINEAR16', 16000) diff --git a/speech/grpc/transcribe_streaming_minute_test.py b/speech/grpc/transcribe_streaming_minute_test.py index 9d84f341cf9b..9a165fcf2640 100644 --- a/speech/grpc/transcribe_streaming_minute_test.py +++ b/speech/grpc/transcribe_streaming_minute_test.py @@ -13,12 +13,15 @@ # limitations under the License. import logging +import os import re import threading import time import transcribe_streaming_minute as transcribe_streaming +RESOURCES = os.path.join(os.path.dirname(__file__), 'resources') + class MockPyAudio(object): def __init__(self, *audio_filenames): @@ -78,11 +81,13 @@ def stream_audio(audio_filenames, callback, closed, num_frames=512): callback(b'\0' * num_bytes, None, None, None) -def test_main(resource, monkeypatch, capsys, caplog): +def test_main(monkeypatch, capsys, caplog): caplog.setLevel(logging.DEBUG) monkeypatch.setattr( transcribe_streaming.pyaudio, 'PyAudio', - MockPyAudio(resource('audio.raw'), resource('quit.raw'))) + MockPyAudio( + os.path.join(RESOURCES, 'audio.raw'), + os.path.join(RESOURCES, 'quit.raw'))) monkeypatch.setattr( transcribe_streaming, 'WRAP_IT_UP_SECS', 59) diff --git a/speech/grpc/transcribe_streaming_test.py b/speech/grpc/transcribe_streaming_test.py index d5b3c0d07d09..3b8d697a1804 100644 --- a/speech/grpc/transcribe_streaming_test.py +++ b/speech/grpc/transcribe_streaming_test.py @@ -11,12 +11,15 @@ # See the License for the specific language governing permissions and # limitations under the License. +import os import re import threading import time import transcribe_streaming +RESOURCES = os.path.join(os.path.dirname(__file__), 'resources') + class MockPyAudio(object): def __init__(self, audio_filename): @@ -55,10 +58,10 @@ def stream_audio(audio_filename, callback, closed, num_frames=512): callback(chunk, None, None, None) -def test_main(resource, monkeypatch, capsys): +def test_main(monkeypatch, capsys): monkeypatch.setattr( transcribe_streaming.pyaudio, 'PyAudio', - MockPyAudio(resource('quit.raw'))) + MockPyAudio(os.path.join(RESOURCES, 'quit.raw'))) transcribe_streaming.main() out, err = capsys.readouterr() diff --git a/speech/grpc/transcribe_test.py b/speech/grpc/transcribe_test.py index d7e815ebf182..2826bf6e2a5e 100644 --- a/speech/grpc/transcribe_test.py +++ b/speech/grpc/transcribe_test.py @@ -19,8 +19,7 @@ BUCKET = os.environ['CLOUD_STORAGE_BUCKET'] -def test_main(resource, capsys): - +def test_main(capsys): # Run the transcribe sample on audio.raw, verify correct results storage_uri = 'gs://{}/speech/audio.raw'.format(BUCKET) main(storage_uri, 'LINEAR16', 16000) diff --git a/storage/api/compose_objects_test.py b/storage/api/compose_objects_test.py index 3b5b05df372b..1847096a91f2 100644 --- a/storage/api/compose_objects_test.py +++ b/storage/api/compose_objects_test.py @@ -15,13 +15,14 @@ from compose_objects import main +RESOURCES = os.path.join(os.path.dirname(__file__), 'resources') BUCKET = os.environ['CLOUD_STORAGE_BUCKET'] -def test_main(resource): +def test_main(): main( BUCKET, 'dest.txt', - [resource('file1.txt'), - resource('file2.txt')] + [os.path.join(RESOURCES, 'file1.txt'), + os.path.join(RESOURCES, 'file2.txt')] ) diff --git a/vision/api/label/label_test.py b/vision/api/label/label_test.py index 71a37321083d..ea4ef455fff1 100644 --- a/vision/api/label/label_test.py +++ b/vision/api/label/label_test.py @@ -11,13 +11,16 @@ # See the License for the specific language governing permissions and # limitations under the License. +import os import re from label import main +RESOURCES = os.path.join(os.path.dirname(__file__), 'resources') -def test_main(resource, capsys): - in_file = resource('cat.jpg') + +def test_main(capsys): + in_file = os.path.join(RESOURCES, 'cat.jpg') main(in_file) diff --git a/vision/api/label/snippets_test.py b/vision/api/label/snippets_test.py index 9dd9eceb1583..0e8ac0334544 100644 --- a/vision/api/label/snippets_test.py +++ b/vision/api/label/snippets_test.py @@ -14,21 +14,23 @@ # See the License for the specific language governing permissions and # limitations under the License. - import json +import os import snippets +RESOURCES = os.path.join(os.path.dirname(__file__), 'resources') + -def test_crop_hint_response_count(capsys, resource): - snippets.crop_hint(resource('cat.jpg')) +def test_crop_hint_response_count(capsys): + snippets.crop_hint(os.path.join(RESOURCES, 'cat.jpg')) stdout, _ = capsys.readouterr() result = json.loads(stdout) assert len(result['responses']) == 1 -def test_crop_hint_response_dim(capsys, resource): - snippets.crop_hint(resource('cat.jpg')) +def test_crop_hint_response_dim(capsys): + snippets.crop_hint(os.path.join(RESOURCES, 'cat.jpg')) stdout, _ = capsys.readouterr() result = json.loads(stdout) crop_hint = result['responses'][0] @@ -38,8 +40,8 @@ def test_crop_hint_response_dim(capsys, resource): assert 0.5 < confidence < 0.9 -def test_web_annotations(capsys, resource): - snippets.web_annotation(resource('cat.jpg')) +def test_web_annotations(capsys): + snippets.web_annotation(os.path.join(RESOURCES, 'cat.jpg')) stdout, _ = capsys.readouterr() result = json.loads(stdout) web_annotation = result['responses'][0]['webDetection'] diff --git a/vision/cloud-client/face_detection/faces_test.py b/vision/cloud-client/face_detection/faces_test.py index 9611c82ed499..cca63c20e5b9 100644 --- a/vision/cloud-client/face_detection/faces_test.py +++ b/vision/cloud-client/face_detection/faces_test.py @@ -17,10 +17,12 @@ from faces import main +RESOURCES = os.path.join(os.path.dirname(__file__), 'resources') -def test_main(resource, tmpdir): + +def test_main(tmpdir): out_file = os.path.join(tmpdir.dirname, 'face-output.jpg') - in_file = resource('face-input.jpg') + in_file = os.path.join(RESOURCES, 'face-input.jpg') # Make sure there isn't already a green box im = Image.open(in_file) From 3baa687503560078d2f8ae702c07b060c3762384 Mon Sep 17 00:00:00 2001 From: Jon Wayne Parrott Date: Wed, 5 Apr 2017 14:54:43 -0700 Subject: [PATCH 2/2] Remove remote resource --- conftest.py | 33 --------------------------------- language/ocr_nl/main_test.py | 12 +++++++++--- 2 files changed, 9 insertions(+), 36 deletions(-) diff --git a/conftest.py b/conftest.py index 0009bb56d8e1..104baa322040 100644 --- a/conftest.py +++ b/conftest.py @@ -16,41 +16,8 @@ import mock import pytest -import requests PROJECT = os.environ['GCLOUD_PROJECT'] -BUCKET = os.environ['CLOUD_STORAGE_BUCKET'] - - -def get_resource_path(resource, local_path): - local_resource_path = os.path.join(local_path, 'resources', *resource) - - if os.path.exists(local_resource_path): - return local_resource_path - else: - raise EnvironmentError('Resource {} not found.'.format( - os.path.join(*resource))) - - -def fetch_gcs_resource(resource, tmpdir, _chunk_size=1024): - resp = requests.get(resource, stream=True) - dest_file = str(tmpdir.join(os.path.basename(resource))) - with open(dest_file, 'wb') as f: - for chunk in resp.iter_content(_chunk_size): - f.write(chunk) - - return dest_file - - -@pytest.fixture(scope='module') -def remote_resource(): - """Provides a function that downloads the given resource from Cloud - Storage, returning the path to the downloaded resource.""" - remote_uri = 'http://storage.googleapis.com/{}/'.format( - BUCKET) - - return lambda path, tmpdir: fetch_gcs_resource( - remote_uri + path.strip('/'), tmpdir) @pytest.fixture diff --git a/language/ocr_nl/main_test.py b/language/ocr_nl/main_test.py index 832483ca5317..afaf2e16576c 100755 --- a/language/ocr_nl/main_test.py +++ b/language/ocr_nl/main_test.py @@ -17,10 +17,14 @@ import re import zipfile +import requests + import main BUCKET = os.environ['CLOUD_STORAGE_BUCKET'] TEST_IMAGE_URI = 'gs://{}/language/image8.png'.format(BUCKET) +OCR_IMAGES_URI = 'http://storage.googleapis.com/{}/{}'.format( + BUCKET, 'language/ocr_nl-images-small.zip') def test_batch_empty(): @@ -79,14 +83,16 @@ def test_entities_list(): assert wurl == 'http://en.wikipedia.org/wiki/Mr_Bennet' -def test_main(remote_resource, tmpdir, capsys): +def test_main(tmpdir, capsys): images_path = str(tmpdir.mkdir('images')) # First, pull down some test data - zip_path = remote_resource('language/ocr_nl-images-small.zip', tmpdir) + response = requests.get(OCR_IMAGES_URI) + images_file = tmpdir.join('images.zip') + images_file.write_binary(response.content) # Extract it to the image directory - with zipfile.ZipFile(zip_path) as zfile: + with zipfile.ZipFile(str(images_file)) as zfile: zfile.extractall(images_path) main.main(images_path, str(tmpdir.join('ocr_nl.db')))