Skip to content
This repository was archived by the owner on Mar 6, 2026. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 1 addition & 3 deletions noxfile.py
Original file line number Diff line number Diff line change
Expand Up @@ -115,9 +115,7 @@ def system(session):
session.install("ipython", "-c", constraints_path)

# Run py.test against the system tests.
session.run(
"py.test", "--quiet", os.path.join("tests", "system.py"), *session.posargs
)
session.run("py.test", "--quiet", os.path.join("tests", "system"), *session.posargs)


@nox.session(python=["3.8"])
Expand Down
13 changes: 13 additions & 0 deletions tests/system/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# Copyright 2020 Google LLC
Comment thread
tswast marked this conversation as resolved.
Outdated
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
68 changes: 0 additions & 68 deletions tests/system.py → tests/system/test_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,8 @@
import time
import unittest
import uuid
import re

import psutil
import pytest
import pytz
import pkg_resources

Expand All @@ -51,13 +49,6 @@
import pyarrow.types
except ImportError: # pragma: NO COVER
pyarrow = None
try:
import IPython
from IPython.utils import io as ipython_io
from IPython.testing import tools
from IPython.terminal import interactiveshell
except ImportError: # pragma: NO COVER
IPython = None

from google.api_core.exceptions import PreconditionFailed
from google.api_core.exceptions import BadRequest
Expand Down Expand Up @@ -2979,47 +2970,6 @@ def temp_dataset(self, dataset_id, location=None):
return dataset


@pytest.mark.skipif(pandas is None, reason="Requires `pandas`")
@pytest.mark.skipif(IPython is None, reason="Requires `ipython`")
@pytest.mark.usefixtures("ipython_interactive")
def test_bigquery_magic():
ip = IPython.get_ipython()
current_process = psutil.Process()
conn_count_start = len(current_process.connections())

ip.extension_manager.load_extension("google.cloud.bigquery")
sql = """
SELECT
CONCAT(
'https://stackoverflow.com/questions/',
CAST(id as STRING)) as url,
view_count
FROM `bigquery-public-data.stackoverflow.posts_questions`
WHERE tags like '%google-bigquery%'
ORDER BY view_count DESC
LIMIT 10
"""
with ipython_io.capture_output() as captured:
result = ip.run_cell_magic("bigquery", "--use_rest_api", sql)

conn_count_end = len(current_process.connections())

lines = re.split("\n|\r", captured.stdout)
# Removes blanks & terminal code (result of display clearing)
updates = list(filter(lambda x: bool(x) and x != "\x1b[2K", lines))
assert re.match("Executing query with job ID: .*", updates[0])
assert all(re.match("Query executing: .*s", line) for line in updates[1:-1])
assert re.match("Query complete after .*s", updates[-1])
assert isinstance(result, pandas.DataFrame)
assert len(result) == 10 # verify row count
assert list(result) == ["url", "view_count"] # verify column names

# NOTE: For some reason, the number of open sockets is sometimes one *less*
# than expected when running system tests on Kokoro, thus using the <= assertion.
# That's still fine, however, since the sockets are apparently not leaked.
assert conn_count_end <= conn_count_start # system resources are released


def _job_done(instance):
return instance.state.lower() == "done"

Expand All @@ -3039,21 +2989,3 @@ def _table_exists(t):
return True
except NotFound:
return False


@pytest.fixture(scope="session")
def ipython():
config = tools.default_config()
config.TerminalInteractiveShell.simple_prompt = True
shell = interactiveshell.TerminalInteractiveShell.instance(config=config)
return shell


@pytest.fixture()
def ipython_interactive(request, ipython):
"""Activate IPython's builtin hooks

for the duration of the test scope.
"""
with ipython.builtin_trap:
yield ipython
83 changes: 83 additions & 0 deletions tests/system/test_magics.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
# Copyright 2020 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

"""System tests for Jupyter/IPython connector."""

import re

import pytest
import psutil


IPython = pytest.importorskip("IPython")
io = pytest.importorskip("IPython.utils.io")
pandas = pytest.importorskip("pandas")
tools = pytest.importorskip("IPython.testing.tools")
interactiveshell = pytest.importorskip("IPython.terminal.interactiveshell")
Comment on lines +23 to +27
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice, this is IMO more clean that those skipIf decorators. 👍



@pytest.fixture(scope="session")
def ipython():
config = tools.default_config()
config.TerminalInteractiveShell.simple_prompt = True
shell = interactiveshell.TerminalInteractiveShell.instance(config=config)
return shell


@pytest.fixture()
def ipython_interactive(ipython):
"""Activate IPython's builtin hooks

for the duration of the test scope.
"""
with ipython.builtin_trap:
yield ipython


def test_bigquery_magic(ipython_interactive):
ip = IPython.get_ipython()
current_process = psutil.Process()
conn_count_start = len(current_process.connections())

ip.extension_manager.load_extension("google.cloud.bigquery")
sql = """
SELECT
CONCAT(
'https://stackoverflow.com/questions/',
CAST(id as STRING)) as url,
view_count
FROM `bigquery-public-data.stackoverflow.posts_questions`
WHERE tags like '%google-bigquery%'
ORDER BY view_count DESC
LIMIT 10
"""
with io.capture_output() as captured:
result = ip.run_cell_magic("bigquery", "--use_rest_api", sql)

conn_count_end = len(current_process.connections())

lines = re.split("\n|\r", captured.stdout)
# Removes blanks & terminal code (result of display clearing)
updates = list(filter(lambda x: bool(x) and x != "\x1b[2K", lines))
assert re.match("Executing query with job ID: .*", updates[0])
assert all(re.match("Query executing: .*s", line) for line in updates[1:-1])
assert re.match("Query complete after .*s", updates[-1])
assert isinstance(result, pandas.DataFrame)
assert len(result) == 10 # verify row count
assert list(result) == ["url", "view_count"] # verify column names

# NOTE: For some reason, the number of open sockets is sometimes one *less*
# than expected when running system tests on Kokoro, thus using the <= assertion.
# That's still fine, however, since the sockets are apparently not leaked.
assert conn_count_end <= conn_count_start # system resources are released