Permalink
  • 10 commits
  • 12 files changed
  • 0 commit comments
  • 1 contributor
View
@@ -1,6 +1,7 @@
language: python
python:
- "3.4"
+ - "3.5"
# command to install dependencies
install:
- "pip install . coverage"
View
@@ -26,9 +26,18 @@ Builtin unit tests
pyfrc comes with testing functions that can be used to test basic
functionality of just about any robot, including running through a
-simulated practice match. To use these standardized tests, just create a file
-in your tests directory called pyfrc_test.py, and put the following contents
-in the file::
+simulated practice match. As of pyfrc 2016.1.1, to add these standardized
+tests to your robot code, you can run the following:
+
+.. code-block:: sh
+
+ Windows: py robot.py add-tests
+
+ Linux/OSX: python3 robot.py add-tests
+
+Running this command creates a directory called 'tests' if it doesn't already
+exist, and then creates a file in your tests directory called pyfrc_test.py,
+and put the following contents in the file::
from pyfrc.tests import *
@@ -0,0 +1,51 @@
+
+import inspect
+import os
+from os.path import abspath, dirname, exists, join
+
+builtin_tests = \
+"""'''
+ This test module imports tests that come with pyfrc, and can be used
+ to test basic functionality of just about any robot.
+'''
+
+from pyfrc.tests import *
+"""
+
+
+class PyFrcAddTests:
+
+ def __init__(self, parser=None):
+ pass
+
+ def run(self, options, robot_class, **static_options):
+
+ robot_file = abspath(inspect.getfile(robot_class))
+ robot_path = dirname(robot_file)
+
+ try_dirs = [
+ abspath(join(robot_path, 'tests')),
+ abspath(join(robot_path, '..', 'tests'))
+ ]
+
+ test_directory = try_dirs[0]
+
+ for d in try_dirs:
+ if exists(d):
+ test_directory = d
+ break
+ else:
+ os.makedirs(test_directory)
+
+ print("Tests directory is %s" % test_directory)
+ print()
+ builtin_tests_file = join(test_directory, 'pyfrc_test.py')
+ if exists(builtin_tests_file):
+ print('- pyfrc_test.py already exists')
+ else:
+ with open(builtin_tests_file, 'w') as fp:
+ fp.write(builtin_tests)
+ print("- builtin tests created at", builtin_tests_file)
+
+ print()
+ print("Robot tests can be ran via 'python3 robot.py test'")
@@ -10,6 +10,7 @@
from os.path import abspath, basename, dirname, exists, join, splitext
from ..robotpy import installer
+from ..util import print_err, yesno
import wpilib
@@ -21,9 +22,6 @@ def relpath(path):
'''Path helper, gives you a path relative to this file'''
return os.path.normpath(os.path.join(os.path.abspath(os.path.dirname(__file__)), path))
-def print_err(*args):
- print(*args, file=sys.stderr)
-
class PyFrcDeploy:
"""
Uploads your robot code to the robot and executes it immediately
@@ -51,6 +49,9 @@ def __init__(self, parser):
parser.add_argument('-n', '--no-version-check', action='store_true', default=False,
help="If specified, don't verify that your local wpilib install matches the version on the robot (not recommended)")
+
+ parser.add_argument('--robot', default=None,
+ help="Set hostname or IP address of robot")
def run(self, options, robot_class, **static_options):
@@ -65,8 +66,20 @@ def run(self, options, robot_class, **static_options):
retval = tester.run_test([], robot_class, options.builtin, ignore_missing_test=True)
if retval != 0:
- print_err("ERROR: Your robot tests failed, aborting upload. Use --skip-tests if you want to upload anyways")
- return retval
+ print_err("ERROR: Your robot tests failed, aborting upload.")
+ if not sys.stdin.isatty():
+ print_err("- Use --skip-tests if you want to upload anyways")
+ return retval
+
+ print()
+ if not yesno('- Upload anyways?'):
+ return retval
+
+ if not yesno('- Are you sure? Your robot code may crash!'):
+ return retval
+
+ print()
+ print("WARNING: Uploading code against my better judgement...")
# upload all files in the robot.py source directory
robot_file = abspath(inspect.getfile(robot_class))
@@ -135,14 +148,11 @@ def run(self, options, robot_class, **static_options):
nc_thread = None
try:
- controller = installer.SshController(cfg_filename,
- username='lvuser',
- password='',
- allow_mitm=True)
-
- # This asks the user if not configured, so get the value first
- hostname = controller.hostname
- print("Deploying to robot at", hostname)
+ controller = installer.ssh_from_cfg(cfg_filename,
+ username='lvuser',
+ password='',
+ hostname=options.robot,
+ allow_mitm=True)
# Housekeeping first
logger.debug('SSH: %s', sshcmd)
@@ -159,16 +169,6 @@ def run(self, options, robot_class, **static_options):
finally:
shutil.rmtree(tmp_dir)
- if not options.in_place:
- # Restart the robot code and we're done!
- sshcmd = "/bin/bash -ce '" + \
- '. /etc/profile.d/natinst-path.sh; ' + \
- 'chown -R lvuser:ni %s; ' + \
- '/usr/local/frc/bin/frcKillRobot.sh -t -r' + \
- "'"
-
- sshcmd %= (py_deploy_dir)
-
# start the netconsole listener now if requested, *before* we
# actually start the robot code, so we can see all messages
if options.nc:
@@ -181,9 +181,18 @@ def run(self, options, robot_class, **static_options):
nc_event.wait(5)
logger.info("Netconsole is listening...")
- logger.debug('SSH: %s', sshcmd)
- controller.ssh(sshcmd)
- controller.close()
+ if not options.in_place:
+ # Restart the robot code and we're done!
+ sshcmd = "/bin/bash -ce '" + \
+ '. /etc/profile.d/natinst-path.sh; ' + \
+ 'chown -R lvuser:ni %s; ' + \
+ '/usr/local/frc/bin/frcKillRobot.sh -t -r' + \
+ "'"
+
+ sshcmd %= (py_deploy_dir)
+
+ logger.debug('SSH: %s', sshcmd)
+ controller.ssh(sshcmd)
except installer.SshExecError as e:
if e.retval == 87:
@@ -1,16 +1,21 @@
import os
import inspect
+import sys
from os.path import abspath, dirname, exists, join
import pytest
+from ..util import yesno
from ..test_support import pytest_plugin
# TODO: setting the plugins so that the end user can invoke py.test directly
# could be a useful thing. Will have to consider that later.
+class _TryAgain(Exception):
+ pass
+
#
# main test class
#
@@ -31,22 +36,29 @@ def __init__(self, parser=None):
def run(self, options, robot_class, **static_options):
# wrapper around run_test that sets the appropriate mode
+
from .. import config
config.mode = 'test'
config.coverage_mode = options.coverage_mode
return self.run_test(options.pytest_args, robot_class, options.builtin, **static_options)
- def run_test(self, pytest_args, robot_class, use_builtin, **static_options):
+ def run_test(self, *a, **k):
+ try:
+ return self._run_test(*a, **k)
+ except _TryAgain:
+ return self._run_test(*a, **k)
+
+ def _run_test(self, pytest_args, robot_class, use_builtin, **static_options):
# find test directory, change current directory so py.test can find the tests
# -> assume that tests reside in tests or ../tests
curdir = abspath(os.getcwd())
+ self.robot_class = robot_class
robot_file = abspath(inspect.getfile(robot_class))
robot_path = dirname(robot_file)
- test_directory = None
if robot_file.endswith('cProfile.py'):
# so, the module for the robot class is __main__, and __main__ is
@@ -58,36 +70,63 @@ def run_test(self, pytest_args, robot_class, use_builtin, **static_options):
"ERROR: Cannot run profiling from a directory that does not contain robot.py"
return 1
- try_dirs = [join(robot_path, 'tests'), abspath(join(robot_path, '..', 'tests'))]
+ self.try_dirs = [
+ abspath(join(robot_path, 'tests')),
+ abspath(join(robot_path, '..', 'tests'))
+ ]
- for d in try_dirs:
+ for d in self.try_dirs:
if exists(d):
test_directory = d
+ os.chdir(test_directory)
break
-
- if test_directory is None:
+ else:
if not use_builtin:
print("ERROR: Cannot run robot tests, as test directory was not found!")
- print()
- print("Looked for tests at:")
- for d in try_dirs:
- print('- %s' % d)
- print()
- print("If you don't want to write your own tests, use the --builtin option to run")
- print("generic tests that should work on any robot.")
+ retv = self._no_tests()
return 1
from ..tests import basic
pytest_args.insert(0, abspath(inspect.getfile(basic)))
- else:
- os.chdir(test_directory)
try:
- return pytest.main(pytest_args,
+ retv = pytest.main(pytest_args,
plugins=[pytest_plugin.PyFrcPlugin(robot_class,
robot_file,
robot_path)])
finally:
os.chdir(curdir)
-
+ # requires pytest 2.8.x
+ if retv == 5:
+ print()
+ print("ERROR: a tests directory was found, but no tests were defined")
+ retv = self._no_tests(retv)
+
+ return retv
+
+ def _no_tests(self, r=1):
+ print()
+ print("Looked for tests at:")
+ for d in self.try_dirs:
+ print('- %s' % d)
+ print()
+ print("If you don't want to write your own tests, pyfrc comes with generic tests")
+ print("that can test basic functionality of most robots. You can run them by")
+ print("specifying the --builtin option.")
+ print()
+
+ if not sys.stdin.isatty():
+ print("Alternatively, to create a tests directory with the builtin tests, you can run:")
+ print()
+ print(" python3 robot.py add-tests")
+ print()
+ else:
+ if yesno("Create a tests directory with builtin tests now?"):
+ from .cli_add_tests import PyFrcAddTests
+ add_tests = PyFrcAddTests()
+ add_tests.run(None, self.robot_class)
+
+ raise _TryAgain()
+
+ return r
Oops, something went wrong.

No commit comments for this range