make tests pass on windows (#618)

This commit is contained in:
tamarrow
2016-06-24 18:41:17 -07:00
committed by GitHub
parent 592c92692b
commit 18dd1f0d45
10 changed files with 117 additions and 45 deletions

View File

@@ -5,11 +5,12 @@ BASEDIR=`dirname $0`/..
cd $BASEDIR
PATH=$(pwd)/dist:$PATH
cp tests/data/dcos.toml $DCOS_CONFIG
if [ -f "$BASEDIR/env/bin/activate" ]; then
source $BASEDIR/env/bin/activate
cp tests/data/dcos.toml $DCOS_CONFIG
source $BASEDIR/env/bin/activate
else
$BASEDIR/env/Scripts/activate
export DCOS_CONFIG=tests/data/dcos.toml
$BASEDIR/env/Scripts/activate
fi
py.test tests/integrations
deactivate

View File

@@ -42,7 +42,7 @@ def default_command_info(command):
"""
doc = default_command_documentation(command)
return doc.split('\n')[1].strip(".").lstrip()
return doc.splitlines()[1].strip(".").lstrip()
def default_command_documentation(command):
@@ -54,7 +54,7 @@ def default_command_documentation(command):
:rtype: str
"""
return default_doc(command).rstrip('\n')
return default_doc(command).rstrip('\r\n')
class SubcommandMain():

View File

@@ -2,7 +2,6 @@ import collections
import contextlib
import json
import os
import pty
import subprocess
import time
@@ -466,6 +465,8 @@ def popen_tty(cmd):
:rtype: (Popen, int)
"""
import pty
master, slave = pty.openpty()
proc = subprocess.Popen(cmd,
stdin=slave,

View File

@@ -2,6 +2,7 @@ import contextlib
import json
import os
import re
import sys
import threading
from dcos import constants
@@ -695,6 +696,8 @@ def test_app_locked_error():
b'Override with --force.\n'))
@pytest.mark.skipif(sys.platform == 'win32',
reason="No pseudo terminal on windows")
def test_app_add_no_tty():
proc, master = popen_tty('dcos marathon app add')

View File

@@ -1,12 +1,15 @@
import json
import os
import re
import sys
import dcos.util as util
import six
from dcos import mesos
from dcos.util import create_schema
import pytest
from ..fixtures.node import slave_fixture
from .common import assert_command, assert_lines, exec_command, ssh_output
@@ -91,15 +94,21 @@ def test_node_log_invalid_lines():
returncode=1)
@pytest.mark.skipif(sys.platform == 'win32',
reason='No pseudo terminal on windows')
def test_node_ssh_leader():
_node_ssh(['--leader'])
@pytest.mark.skipif(sys.platform == 'win32',
reason='No pseudo terminal on windows')
def test_node_ssh_slave():
slave_id = mesos.DCOSClient().get_state_summary()['slaves'][0]['id']
_node_ssh(['--mesos-id={}'.format(slave_id), '--master-proxy'])
@pytest.mark.skipif(sys.platform == 'win32',
reason='No pseudo terminal on windows')
def test_node_ssh_option():
stdout, stderr, _ = _node_ssh_output(
['--leader', '--option', 'Protocol=0'])
@@ -107,6 +116,8 @@ def test_node_ssh_option():
assert b'ignoring bad proto spec' in stderr
@pytest.mark.skipif(sys.platform == 'win32',
reason='No pseudo terminal on windows')
def test_node_ssh_config_file():
stdout, stderr, _ = _node_ssh_output(
['--leader', '--config-file', 'tests/data/node/ssh_config'])
@@ -114,6 +125,8 @@ def test_node_ssh_config_file():
assert b'ignoring bad proto spec' in stderr
@pytest.mark.skipif(sys.platform == 'win32',
reason='No pseudo terminal on windows')
def test_node_ssh_user():
stdout, stderr, _ = _node_ssh_output(
['--master-proxy', '--leader', '--user=bogus', '--option',
@@ -137,6 +150,8 @@ def test_node_ssh_master_proxy_no_agent():
env=env)
@pytest.mark.skipif(sys.platform == 'win32',
reason='No pseudo terminal on windows')
def test_node_ssh_master_proxy():
_node_ssh(['--leader', '--master-proxy'])

View File

@@ -1,8 +1,8 @@
import base64
import contextlib
import json
import sys
import pkg_resources
import six
from dcos import subcommand
@@ -39,11 +39,9 @@ def zk_znode(request):
def test_package():
stdout = pkg_resources.resource_string(
'tests',
'data/help/package.txt')
assert_command(['dcos', 'package', '--help'],
stdout=stdout)
with open('tests/data/help/package.txt') as content:
assert_command(['dcos', 'package', '--help'],
stdout=content.read().encode('utf-8'))
def test_info():
@@ -316,8 +314,9 @@ def test_bad_install_marathon_msg():
b'[0.1.0] with app id [/foo]\n'
b'Installing CLI subcommand for package [helloworld] '
b'version [0.1.0]\n'
b'New command available: dcos helloworld\n'
b'A sample post-installation message\n')
b'New command available: dcos ' +
_executable_name(b'helloworld') +
b'\nA sample post-installation message\n')
_install_helloworld(['--yes', '--app-id=/foo'],
stdout=stdout)
@@ -552,8 +551,9 @@ def test_uninstall_multiple_apps():
b'[0.1.0] with app id [/helloworld-1]\n'
b'Installing CLI subcommand for package [helloworld] '
b'version [0.1.0]\n'
b'New command available: dcos helloworld\n'
b'A sample post-installation message\n')
b'New command available: dcos ' +
_executable_name(b'helloworld') +
b'\nA sample post-installation message\n')
_install_helloworld(['--yes', '--app-id=/helloworld-1'],
stdout=stdout)
@@ -563,8 +563,9 @@ def test_uninstall_multiple_apps():
b'[0.1.0] with app id [/helloworld-2]\n'
b'Installing CLI subcommand for package [helloworld] '
b'version [0.1.0]\n'
b'New command available: dcos helloworld\n'
b'A sample post-installation message\n')
b'New command available: dcos ' +
_executable_name(b'helloworld') +
b'\nA sample post-installation message\n')
_install_helloworld(['--yes', '--app-id=/helloworld-2'],
stdout=stdout)
@@ -620,8 +621,9 @@ def test_install_yes():
b'[0.1.0]\n'
b'Installing CLI subcommand for package [helloworld] '
b'version [0.1.0]\n'
b'New command available: dcos helloworld\n'
b'A sample post-installation message\n')
b'New command available: dcos ' +
_executable_name(b'helloworld') +
b'\nA sample post-installation message\n')
_uninstall_helloworld()
@@ -664,7 +666,9 @@ def test_list_cli():
stdout = (b"Installing CLI subcommand for package [helloworld] " +
b"version [0.1.0]\n"
b"New command available: dcos helloworld\n")
b"New command available: dcos " +
_executable_name(b'helloworld') +
b"\n")
_install_helloworld(args=['--cli', '--yes'], stdout=stdout)
stdout = b"""\
@@ -828,6 +832,13 @@ def _get_app_labels(app_id):
return app_json.get('labels')
def _executable_name(name):
if sys.platform == 'win32':
return name + b'.exe'
else:
return name
def _install_helloworld(
args=['--yes'],
stdout=b'A sample pre-installation message\n'
@@ -835,8 +846,9 @@ def _install_helloworld(
b'version [0.1.0]\n'
b'Installing CLI subcommand for package [helloworld] '
b'version [0.1.0]\n'
b'New command available: dcos helloworld\n'
b'A sample post-installation message\n',
b'New command available: dcos ' +
_executable_name(b'helloworld') +
b'\nA sample post-installation message\n',
stderr=b'',
returncode=0,
stdin=None):
@@ -937,12 +949,14 @@ def _list_remove_nulls(args=['--json'], stdout=b'[]\n'):
def _helloworld():
stdout = b'''A sample pre-installation message
Installing Marathon app for package [helloworld] version [0.1.0]
Installing CLI subcommand for package [helloworld] version [0.1.0]
New command available: dcos helloworld
A sample post-installation message
'''
stdout = (b'A sample pre-installation message\n'
b'Installing Marathon app for package [helloworld] version '
b'[0.1.0]\n'
b'Installing CLI subcommand for package [helloworld] '
b'version [0.1.0]\n'
b'New command available: dcos ' +
_executable_name(b'helloworld') +
b'\nA sample post-installation message\n')
stderr = b'Uninstalled package [helloworld] version [0.1.0]\n'
return _package('helloworld',

View File

@@ -1,5 +1,7 @@
import os
import signal
import subprocess
import sys
import time
import dcos.util as util
@@ -161,6 +163,8 @@ def test_log_marathon_file():
returncode=1)
@pytest.mark.skipif(sys.platform == 'win32',
reason='No pseduo terminal on windows')
def test_log_marathon_config():
stdout, stderr, _ = ssh_output(
'dcos service log marathon ' +
@@ -197,16 +201,33 @@ def test_log_config():
def test_log_follow():
wait_for_service('chronos')
proc = subprocess.Popen(['dcos', 'service', 'log', 'chronos', '--follow'],
preexec_fn=os.setsid,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE)
args = ['dcos', 'service', 'log', 'chronos', '--follow']
if sys.platform == 'win32':
proc = subprocess.Popen(
args,
creationflags=subprocess.CREATE_NEW_PROCESS_GROUP,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE)
else:
# os.setsid is only available for Unix:
# https://docs.python.org/2/library/os.html#os.setsid
proc = subprocess.Popen(
args,
preexec_fn=os.setsid,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE)
time.sleep(10)
proc.poll()
assert proc.returncode is None
os.killpg(os.getpgid(proc.pid), 15)
if sys.platform == 'win32':
os.kill(proc.pid, signal.CTRL_BREAK_EVENT)
else:
# using Unix-only commands os.killpg + os.getgid
# https://docs.python.org/2/library/os.html#os.killpg
# https://docs.python.org/2/library/os.html#os.getpgid
os.killpg(os.getpgid(proc.pid), 15)
stdout = proc.stdout.read()
stderr = proc.stderr.read()

View File

@@ -13,6 +13,8 @@ def env():
r.update({
constants.PATH_ENV: os.environ[constants.PATH_ENV],
constants.DCOS_CONFIG_ENV: os.path.join("tests", "data", "dcos.toml"),
'DCOS_SNAKEOIL_CRT_PATH': os.environ.get(
"DCOS_SNAKEOIL_CRT_PATH", "/dcos-cli/adminrouter/snakeoil.crt")
})
return r
@@ -86,7 +88,7 @@ def test_verify_ssl_with_bad_cert_config(env):
def test_verify_ssl_with_good_cert_env_var(env):
env['DCOS_SSL_VERIFY'] = '/dcos-cli/adminrouter/snakeoil.crt'
env['DCOS_SSL_VERIFY'] = env['DCOS_SNAKEOIL_CRT_PATH']
with update_config('core.ssl_verify', None, env):
returncode, stdout, stderr = exec_command(
@@ -99,7 +101,7 @@ def test_verify_ssl_with_good_cert_env_var(env):
def test_verify_ssl_with_good_cert_config(env):
with update_config(
'core.ssl_verify', '/dcos-cli/adminrouter/snakeoil.crt', env):
'core.ssl_verify', env['DCOS_SNAKEOIL_CRT_PATH'], env):
returncode, stdout, stderr = exec_command(
['dcos', 'marathon', 'app', 'list'], env)
assert returncode == 0

View File

@@ -1,17 +1,19 @@
import collections
import fcntl
import json
import os
import re
import subprocess
import sys
import time
import dcos.util as util
from dcos.util import create_schema
import pytest
from ..fixtures.task import task_fixture
from .common import (add_app, app, assert_command, assert_lines,
exec_command, remove_app, watch_all_deployments)
from .common import (add_app, app, assert_command, assert_lines, exec_command,
remove_app, watch_all_deployments)
SLEEP_COMPLETED = 'tests/data/marathon/apps/sleep-completed.json'
SLEEP_COMPLETED1 = 'tests/data/marathon/apps/sleep-completed1.json'
@@ -144,6 +146,8 @@ def test_log_lines_invalid():
returncode=1)
@pytest.mark.skipif(sys.platform == 'win32',
reason="Using Windows unsupported import (fcntl)")
def test_log_follow():
""" Test --follow """
# verify output
@@ -180,6 +184,8 @@ def test_log_two_tasks():
assert re.match('===>.*<===', lines[5])
@pytest.mark.skipif(sys.platform == 'win32',
reason='Using Windows unsupported import (fcntl)')
def test_log_two_tasks_follow():
""" Test tailing a single file on two separate tasks with --follow """
with app(TWO_TASKS_FOLLOW, 'two-tasks-follow'):
@@ -288,6 +294,7 @@ def test_ls_completed():
def _mark_non_blocking(file_):
import fcntl
fcntl.fcntl(file_.fileno(), fcntl.F_SETFL, os.O_NONBLOCK)

View File

@@ -3,6 +3,7 @@ import copy
import json
import os
import stat
import sys
import pkg_resources
import toml
@@ -160,12 +161,19 @@ def _enforce_config_permissions(path):
:type path: str
:rtype: None
"""
permissions = oct(stat.S_IMODE(os.lstat(path).st_mode))
if permissions not in ['0o600', '0600']:
msg = ("Permissions '{}' for configuration file '{}' are too open. "
"File must only be accessible by owner. "
"Aborting...".format(permissions, path))
raise DCOSException(msg)
# Unix permissions are incompatible with windows
# TODO: https://github.com/dcos/dcos-cli/issues/662
if sys.platform == 'win32':
return
else:
permissions = oct(stat.S_IMODE(os.lstat(path).st_mode))
if permissions not in ['0o600', '0600']:
msg = (
"Permissions '{}' for configuration file '{}' are too open. "
"File must only be accessible by owner. "
"Aborting...".format(permissions, path))
raise DCOSException(msg)
def load_from_path(path, mutable=False):