make tests pass on windows (#618)
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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():
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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')
|
||||
|
||||
|
||||
@@ -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'])
|
||||
|
||||
|
||||
@@ -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',
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
|
||||
@@ -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):
|
||||
|
||||
Reference in New Issue
Block a user