Skip to content

Commit

Permalink
Merge pull request #948 from plotly/R-test-cwd
Browse files Browse the repository at this point in the history
cwd for running dashr tests - auto and override
  • Loading branch information
alexcjohnson authored Oct 7, 2019
2 parents ba17890 + 8e287c3 commit 5a76e8e
Show file tree
Hide file tree
Showing 3 changed files with 38 additions and 11 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ This project adheres to [Semantic Versioning](http://semver.org/).

## Unreleased
### Added
- [#948](https://github.com/plotly/dash/pull/948) Support setting working directory for R apps run using the `dashr` fixture, primarily useful for tests with assets. `dashr.start_server` supports a `cwd` argument to set an explicit working directory, and has smarter defaults when it's omitted: if `app` is a path to an R script, uses the directory of that path; if `app` is a string, uses the directory the test file itself is in.
- [#944](https://github.com/plotly/dash/pull/944)
- Relevant `dash.testing` methods can now be called with either an element or a CSS selector: `select_dcc_dropdown`, `multiple_click`, `clear_input`, `zoom_in_graph_by_ratio`, `click_at_coord_fractions`.
- Three new `dash.testing` methods: `clear_local_storage`, `clear_session_storage`, and `clear_storage` (to clear both together)
Expand Down
41 changes: 33 additions & 8 deletions dash/testing/application_runners.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import threading
import subprocess
import logging
import inspect

import runpy
import future.utils as utils
Expand All @@ -30,7 +31,7 @@ def import_app(app_file, application_name="app"):
:Example:
>>> app = import_app('my_app.app')
>>> app = import_app("my_app.app")
Will import the application in module `app` of the package `my_app`.
Expand Down Expand Up @@ -248,28 +249,52 @@ def __init__(self, keep_open=False, stop_timeout=3):
self.proc = None

# pylint: disable=arguments-differ
def start(self, app, start_timeout=2):
"""Start the server with waitress-serve in process flavor."""
def start(self, app, start_timeout=2, cwd=None):
"""Start the server with subprocess and Rscript."""

# app is a R string chunk
if not (os.path.isfile(app) and os.path.exists(app)):
if (os.path.isfile(app) and os.path.exists(app)):
# app is already a file in a dir - use that as cwd
if not cwd:
cwd = os.path.dirname(app)
logger.info("RRunner inferred cwd from app path: %s", cwd)
else:
path = (
"/tmp/app_{}.R".format(uuid.uuid4().hex)
if not self.is_windows
else os.path.join(
(os.getenv("TEMP"), "app_{}.R".format(uuid.uuid4().hex))
)
)
logger.info("RRuner start => app is R code chunk")
logger.info("make a temporay R file for execution=> %s", path)
logger.debug("the content of dashR app")
logger.info("RRunner start => app is R code chunk")
logger.info("make a temporary R file for execution => %s", path)
logger.debug("content of the dashR app")
logger.debug("%s", app)

with open(path, "w") as fp:
fp.write(app)

app = path

# try to find the path to the calling script to use as cwd
if not cwd:
for entry in inspect.stack():
if "/dash/testing/" not in entry[1].replace("\\", "/"):
cwd = os.path.dirname(os.path.realpath(entry[1]))
break
if cwd:
logger.info(
"RRunner inferred cwd from the Python call stack: %s",
cwd
)
else:
logger.warning(
"RRunner found no cwd in the Python call stack. "
"You may wish to specify an explicit working directory "
"using something like: "
"dashr.run_server(app, cwd=os.path.dirname(__file__))"
)

logger.info("Run dashR app with Rscript => %s", app)
args = shlex.split(
"Rscript {}".format(os.path.realpath(app)),
Expand All @@ -279,7 +304,7 @@ def start(self, app, start_timeout=2):

try:
self.proc = subprocess.Popen(
args, stdout=subprocess.PIPE, stderr=subprocess.PIPE
args, stdout=subprocess.PIPE, stderr=subprocess.PIPE, cwd=cwd
)
# wait until server is able to answer http request
wait.until(lambda: self.accessible(self.url), timeout=start_timeout)
Expand Down
7 changes: 4 additions & 3 deletions dash/testing/composite.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,11 @@ def __init__(self, server, **kwargs):
super(DashRComposite, self).__init__(**kwargs)
self.server = server

def start_server(self, app):
def start_server(self, app, cwd=None):

# start server with dashR app, the dash arguments are hardcoded
self.server(app)
# start server with dashR app. The app sets its own run_server args
# on the R side, but we support overriding the automatic cwd
self.server(app, cwd=cwd)

# set the default server_url, it implicitly call wait_for_page
self.server_url = self.server.url

0 comments on commit 5a76e8e

Please sign in to comment.