Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
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
2 changes: 1 addition & 1 deletion .github/workflows/pre-commit.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ jobs:
max-parallel: 4
matrix:
python-version: [2.7]
os: [ubuntu-latest, macos-latest]
os: [ubuntu-latest, macos-latest, windows-latest]
package: [common, libs, platform, tools]

steps:
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#
# Copyright (c) 2019 by Delphix. All rights reserved.
# Copyright (c) 2019, 2020 by Delphix. All rights reserved.
#

import logging
Expand Down Expand Up @@ -62,8 +62,8 @@ def standardize_path(path):
if standardized_path == '.':
standardized_path = os.path.realpath(standardized_path)
else:
standardized_path = os.path.normpath(standardized_path)
standardized_path = os.path.normcase(standardized_path)
standardized_path = os.path.abspath(standardized_path)
standardized_path = os.path.abspath(standardized_path)
return standardized_path


Expand Down Expand Up @@ -95,7 +95,6 @@ def get_src_dir_path(config_file_path, src_dir):
# absolute for comparison later.
plugin_root_dir = os.path.dirname(config_file_path)
plugin_root_dir = standardize_path(plugin_root_dir)
plugin_root_dir = os.path.abspath(plugin_root_dir)

# The plugin's src directory is relative to the plugin root not to the
# current working directory. os.path.abspath makes a relative path
Expand All @@ -109,8 +108,13 @@ def get_src_dir_path(config_file_path, src_dir):
if not os.path.isdir(src_dir_absolute):
raise exceptions.PathTypeError(src_dir_absolute, 'directory')

if not src_dir_absolute.startswith(
plugin_root_dir) or src_dir_absolute == plugin_root_dir:
normcase_src_dir = os.path.normcase(src_dir_absolute)
normcase_plugin_root = os.path.normcase(plugin_root_dir)

if (
not normcase_src_dir.startswith(normcase_plugin_root)
or normcase_src_dir == normcase_plugin_root
):
raise exceptions.UserError(
"The src directory {} is not a subdirectory "
"of the plugin root at {}".format(src_dir_absolute,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ def __import_in_subprocess(src_dir, module, entry_point, plugin_type,
in a sub-process and on completion return the output.
"""
queue = Queue()
process = Process(target=_get_manifest,
process = Process(target=_import_module_and_get_manifest,
args=(queue, src_dir, module, entry_point,
plugin_type, validate))
process.start()
Expand Down Expand Up @@ -184,7 +184,8 @@ def __check_for_required_methods(self):
return warnings


def _get_manifest(queue, src_dir, module, entry_point, plugin_type, validate):
def _import_module_and_get_manifest(queue, src_dir, module, entry_point,
plugin_type, validate):
"""
Imports the plugin module, runs validations and returns the manifest.
"""
Expand All @@ -199,6 +200,26 @@ def _get_manifest(queue, src_dir, module, entry_point, plugin_type, validate):
#
return

manifest = get_manifest(src_dir, module, entry_point,
module_content, plugin_type,
validate, queue)
queue.put({'manifest': manifest})


def get_manifest(src_dir, module, entry_point, module_content,
plugin_type, validate, queue):
"""
Helper method to run validations and prepare the manifest.

NOTE:
This code is moved out into a separate method to help running
unit tests on windows for validations. Since the behaviour of
multiprocessing.Process module is different for windows and linux,
unit testing validate_plugin_module method using mock has issues.

More details at :
https://rhodesmill.org/brandon/2010/python-multiprocessing-linux-windows/
"""
#
# Create an instance of plugin module with associated state to pass around
# to the validation code.
Expand All @@ -219,8 +240,7 @@ def _get_manifest(queue, src_dir, module, entry_point, plugin_type, validate):
warnings = import_util.validate_post_import(plugin_module)
_process_warnings(queue, warnings)

manifest = _prepare_manifest(entry_point, module_content)
queue.put({'manifest': manifest})
return _prepare_manifest(entry_point, module_content)


def _import_helper(queue, src_dir, module):
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -432,16 +432,17 @@ def test_plugin_bad_language(mock_generate_python, plugin_config_file,
assert not mock_generate_python.called

@staticmethod
@pytest.mark.parametrize('src_dir', ['/not/a/real/dir/src'])
@pytest.mark.parametrize('src_dir', [os.path.join('fake', 'dir')])
@mock.patch('os.path.isabs', return_value=False)
@mock.patch('dlpx.virtualization._internal.codegen.generate_python')
def test_plugin_no_src_dir(mock_generate_python, mock_path_is_relative,
plugin_config_file, artifact_file):
plugin_config_file, artifact_file, tmpdir):
with pytest.raises(exceptions.UserError) as err_info:
build.build(plugin_config_file, artifact_file, False, False)

message = err_info.value.message
assert message == "The path '/not/a/real/dir/src' does not exist."
assert message == "The path '{}' does not exist.".format(
tmpdir.join(os.path.join('fake', 'dir')).strpath)

assert not mock_generate_python.called

Expand Down Expand Up @@ -499,7 +500,15 @@ def test_schema_file_bad_permission(mock_generate_python,
plugin_config_file, artifact_file,
schema_file):
# Make it so we can't read the file
os.chmod(schema_file, 0000)
if os.name == 'nt':
pytest.skip('skipping this test on windows as os.chmod has issues removing permissions on file')
#
# The schema_file can be made unreadable on windows using pypiwin32 but
# since it adds dependency on pypiwin32 for the sdk, skipping this test
# instead of potentially destabilizing the sdk by adding this dependency.
#
else:
os.chmod(schema_file, 0000)
with pytest.raises(exceptions.UserError) as err_info:
build.build(plugin_config_file, artifact_file, False, False)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -363,12 +363,16 @@ def test_copy_generated_to_dir_success(tmpdir, popen_helper):

@staticmethod
def test_copy_generated_to_dir_fail(tmpdir):
src_dir = '/not/a/real/dir'
src_dir = os.path.join('fake', 'dir')
# dst_dir needs to be real so that making the dir inside it works.
dst_dir = tmpdir.strpath

with pytest.raises(OSError) as err_info:
codegen._copy_generated_to_dir(src_dir, dst_dir)

assert err_info.value.strerror == 'No such file or directory'
assert err_info.value.filename.startswith('/not/a/real/dir')
if os.name == 'nt':
assert err_info.value.strerror == 'The system cannot find the path specified'
else:
assert err_info.value.strerror == 'No such file or directory'

assert err_info.value.filename.startswith(src_dir)
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#
# Copyright (c) 2019 by Delphix. All rights reserved.
# Copyright (c) 2019, 2020 by Delphix. All rights reserved.
#

import os
Expand Down Expand Up @@ -34,13 +34,13 @@ def test_get_src_dir_path_relative(tmp_path):

cwd = os.getcwd()
try:
os.chdir(tmp_path.as_posix())
actual = file_util.get_src_dir_path('plugin/plugin_config.yml',
os.chdir(str(tmp_path))
actual = file_util.get_src_dir_path(os.path.join('plugin', 'plugin_config.yml'),
'src')
finally:
os.chdir(cwd)

assert actual == src_dir.as_posix()
assert actual == str(src_dir)

@staticmethod
def test_get_src_dir_path_is_abs_fail():
Expand Down Expand Up @@ -80,13 +80,13 @@ def test_get_src_dir_path_is_dir_fail(mock_existing_path,
@mock.patch('os.path.isabs', return_value=False)
@pytest.mark.parametrize(
'plugin_config_file_path, src_dir_path',
[(os.path.join(os.getenv('HOME'), 'plugin/file_name'), '.'),
[('plugin/file_name', '.'),
('/mongo/file_name', '/src'), ('/plugin/mongo/file_name', '/plugin'),
('/plugin/file_name', '/plugin/src/../..')])
def test_get_src_dir_path_fail(mock_relative_path, mock_existing_path,
mock_directory_path,
plugin_config_file_path, src_dir_path):
expected_plugin_root_dir = os.path.dirname(plugin_config_file_path)
expected_plugin_root_dir = os.path.join(os.getcwd(), os.path.dirname(plugin_config_file_path))

expected_plugin_root_dir = file_util.standardize_path(
expected_plugin_root_dir)
Expand All @@ -113,12 +113,14 @@ def test_get_src_dir_path_fail(mock_relative_path, mock_existing_path,
'plugin_config_file_path, src_dir_path',
[(os.path.join(os.path.dirname(os.getcwd()),
'plugin/filename'), '../plugin/src'),
(os.path.join(os.getenv('HOME'), 'plugin/file_name'), '~/plugin/src'),
(os.path.join(os.getcwd(), 'plugin/file_name'), './plugin/src'),
('/UPPERCASE/file_name', '/UPPERCASE/src'),
('/mongo/file_name', '/mongo/src/main/python'),
('~/plugin/file_name', '~/plugin/src'),
(r'windows\path\some_file', r'windows\path')])
(os.path.join(os.path.dirname(os.getcwd()),
'plugin/filename'), './plugin/src'),
(os.path.join(os.path.dirname(os.getcwd()),
'/UPPERCASE/file_name'), '/UPPERCASE/src'),
(os.path.join(os.path.dirname(os.getcwd()),
'/mongo/file_name'), '/mongo/src/main/python'),
(os.path.join(os.path.dirname(os.getcwd()),
r'windows\path\some_file'), r'windows\path')])
def test_get_src_dir_path_success(mock_relative_path, mock_existing_path,
mock_directory_path,
plugin_config_file_path, src_dir_path):
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#
# Copyright (c) 2019, 2020 by Delphix. All rights reserved.
#

import os
from dlpx.virtualization._internal import package_util

import pytest
Expand Down Expand Up @@ -43,7 +43,7 @@ def test_get_engine_api_version_json():
@staticmethod
def test_get_internal_package_root():
assert package_util.get_internal_package_root().endswith(
'dlpx/virtualization/_internal')
os.path.join('dlpx', 'virtualization', '_internal'))

@staticmethod
@pytest.mark.parametrize('version_string', [
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#
# Copyright (c) 2019 by Delphix. All rights reserved.
# Copyright (c) 2019, 2020 by Delphix. All rights reserved.
#

import os
Expand Down Expand Up @@ -51,18 +51,18 @@ def build_wheel(package, dir):
dist_path.touch()

global packages
packages.add(dist_path.as_posix())
packages.add(str(dist_path))

def clean_up(a, b, c):
file_util.delete_paths(wheel_dir.as_posix())
file_util.delete_paths(str(wheel_dir))

mock_tmpdir.return_value.__enter__.return_value = wheel_dir.as_posix()
mock_tmpdir.return_value.__enter__.return_value = str(wheel_dir)
mock_tmpdir.return_value.__exit__.side_effect = clean_up
mock_build_wheel.side_effect = build_wheel

pdu.install_deps(build_dir.as_posix(), local_vsdk_root='vsdk')
pdu.install_deps(str(build_dir), local_vsdk_root='vsdk')
mock_install_to_dir.assert_called_once_with(packages,
build_dir.as_posix())
str(build_dir))

@staticmethod
@mock.patch.object(subprocess, 'Popen')
Expand Down
Loading