Skip to content

Commit

Permalink
Dev: + [exclude, include, from, into] params to 'push-resource' task …
Browse files Browse the repository at this point in the history
…/ code refactoring
  • Loading branch information
albertaleksieiev authored and zayass committed May 18, 2018
1 parent 9521d83 commit aad672b
Show file tree
Hide file tree
Showing 3 changed files with 219 additions and 82 deletions.
170 changes: 170 additions & 0 deletions src/python/resources.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,170 @@
from utils import *
import os
from os import path
import json
from glob import glob

def is_glob(path):
return "*" in path or "?" in path
class CopyCommand(object):
def __init__(self):
self.from_folder = ""
self.into_folder = ""

@classmethod
def load_commands(cls, line):
def wrap(prop):
if prop is None:
return []
elif isinstance(prop, (str, unicode)):
return [prop]
elif isinstance(prop, (list, tuple)):
return prop

def get_or_default(obj, field, default=""):
if field in obj:
return obj[field]
return default

commands = []
includes = get_or_default(line, 'include', None)

if includes is not None and get_or_default(line, "into", None) is None:
print("You need to pass `into` if you pass `include` line %s" % json.dumps(line))
exit(1)

from_ = get_or_default(line, 'from', line)


into = get_or_default(line, "into", ".")

exclude = wrap(get_or_default(line, "exclude", None))
FROM_PATH = from_

# Multiplication `from` * `include`, i.e. [from|include1, from|include2, from|include3]
if includes is not None:
froms = []
for include in includes:
froms.append(path.join(from_, include))
from_ = froms
else:
from_ = wrap(from_)


# Iterate each `from` folder, after multiplication
for f in from_:
command = CopyCommand()
command.into_folder = into


if len(exclude) == 0:
if is_glob(f):
command.from_folder = glob(f)
else:
command.from_folder = [f]
commands.append(command)
else:
# Expand folder. Retrieve all files recursively
froms = get_all_files_rec(glob(f))

for copy in froms:
command = CopyCommand()
command.into_folder = path.normpath(path.join(into, copy['into']))
command.from_folder = copy['files']

from_folder_len = len(command.from_folder)

for excl in exclude:
def filter_path(p):
subpath = is_subpath(p, path.join(FROM_PATH, excl))

if subpath:
print "Excluding resource { %s }" % p
return False
return True

command.from_folder = filter(filter_path, command.from_folder)

if from_folder_len == len(command.from_folder) and copy['into'] != '.': # Excluding file not here
command.from_folder = [path.join(copy['base'], copy['into'])] # merge it back
command.into_folder = path.normpath(path.join(command.into_folder, path.pardir))

commands.append(command)
return commands


def is_subpath(p, subpath):
path_components = path.normpath(p).split(path.sep) # ['a','b','c','d']
subpath_components = path.normpath(subpath).split(path.sep) # ['a','b']

if len(path_components) < len(subpath_components):
return False

for i in range(len(subpath_components)):
if path_components[i] != subpath_components[i]:
return False
return True


def get_all_files_rec(srcs):
res = []
for src in srcs:
base = path.normpath(path.join(src, path.pardir))
if path.isfile(src):
res.append(
{
"into": path.normpath(path.join(src[len(base) + 1:], path.pardir)),
"base": base,
"files": [src]
}
)
else:
for root, dirs, files in os.walk(src):
if len(files) > 0:
res.append(
{ # TestData/Input/Resource1/file1, TestData/Input/Resource1/file2
"into": path.normpath(path.join(path.join(root, files[0])[len(base) + 1:], path.pardir)),
# Resource1
"base": base, # TestData/Input/
"files": [path.join(root, f) for f in files] # [file1, file2]
}
)

return res


def copy_resources():
"""
Copying resources to Android device by using `adb_push`
It trying to find `resources.json` file inside `build-android-swift` folder,
this file contains instructions, which file need to be adb_push to device
Files will be located under `/data/local/tmp/${Testing Folder}/resources` -> `/data/local/tmp/${Testing Folder}/resources`
"""

base_dir = Dirs.base_dir()

copy_resources_filepath = path.join(base_dir, "build-android-swift/resources.json")

if not os.path.exists(copy_resources_filepath):
return
else:
print("Copy resources: %s is found!" % copy_resources_filepath)

dst = path.join(TestingApp.get_app_folder(), "resources")

# Clean
ADB.shell(["rm", "-rf", dst])
ADB.makedirs(dst)

print("Copying resources...")

resources = json.load(open(copy_resources_filepath))
for line in resources:
commands = CopyCommand.load_commands(line)
for command in commands:
dst_path = path.normpath(path.join(dst, command.into_folder))
ADB.makedirs(dst_path)
ADB.push(dst_path, command.from_folder)
76 changes: 10 additions & 66 deletions src/python/run_tests.py
Original file line number Diff line number Diff line change
@@ -1,95 +1,39 @@
#!/usr/bin/env python
from __future__ import print_function
from utils import *
from resources import copy_resources


self_dir = os.path.dirname(__file__)
swift_build = os.path.join(self_dir, "swift-build")


def extract_tests_package(package):
return package["name"] + "PackageTests.xctest"


def copy_resources():
"""
Copying resources to Android device by using `adb_push`
It trying to find `resources.json` file inside `build-android-swift` folder,
this file contains instructions, which file need to be adb_push to device
Files will be located under `/data/local/tmp/${Testing Folder}/resources` -> `/data/local/tmp/RDEWSFrameworkPackageTests/resources`
Sample `resources.json` file:
[
"ewsSwiftTestAppTests/Resources/*.xml",
"ewsSwiftTestAppTests/Resources/*.eml",
"ewsSwiftTestAppTests/Resources/*.literal",
"ewsSwiftTestAppTests/Resources/mime_sample_*",
"build-android-swift/cacert.pem",
"somfolder/*"
]
"""

import os
import json
from glob import glob
base_dir = Dirs.base_dir()

copy_resources_filepath = os.path.join(base_dir, "build-android-swift/resources.json")

if not os.path.exists(copy_resources_filepath):
return
else:
print("Copy resources: %s is found!" % copy_resources_filepath)

dst = os.path.join(get_folder(get_name()), "resources")

# Clean
adb_shell(["rm", "-rf", dst])
adb_shell(["mkdir", "-p", dst])

print("Copying resources...")

resources = json.load(open(copy_resources_filepath))
for resource in resources:
adb_push(dst, glob(os.path.join(base_dir, resource)))


def push(dst, name, skip_push_stdlib, skip_push_external, skip_push_resources):
from os.path import join
from glob import glob

adb_shell(["mkdir", "-p", dst])
ADB.makedirs(dst)

if not skip_push_resources:
copy_resources()

if not skip_push_stdlib:
adb_push(dst, glob(join(SWIFT_ANDROID_HOME, "toolchain/usr/lib/swift/android", "*.so")))
ADB.push(dst, glob(join(SWIFT_ANDROID_HOME, "toolchain/usr/lib/swift/android", "*.so")))

if not skip_push_external:
adb_push(dst, glob(join(Dirs.external_libs_dir(), "*.so")))
ADB.push(dst, glob(join(Dirs.external_libs_dir(), "*.so")))

adb_push(dst, glob(join(Dirs.build_dir(), "*.so")))
adb_push(dst, [join(Dirs.build_dir(), name)])
ADB.push(dst, glob(join(Dirs.build_dir(), "*.so")))
ADB.push(dst, [join(Dirs.build_dir(), name)])


def exec_tests(folder, name, args):
ld_path = "LD_LIBRARY_PATH=" + folder
test_path = folder + "/" + name

adb_shell([ld_path, test_path] + args)


def get_name():
package = get_package_description()
return extract_tests_package(package)
ADB.shell([ld_path, test_path] + args)


def get_folder(name):
return "/data/local/tmp/" + name.split(".")[0]


def run(args):
Expand All @@ -106,8 +50,8 @@ def run(args):
[swift_build, "--build-tests"] + args.build_args
)

name = get_name()
folder = get_folder(name)
name = TestingApp.get_name()
folder = TestingApp.get_folder(name)

if not skip_push:
push(folder, name, skip_push_stdlib, skip_push_external, skip_push_resources)
Expand Down
55 changes: 39 additions & 16 deletions src/python/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,45 @@ def external_include_dir(cls):
def external_libs_dir(cls):
return os.path.join(cls.external_out_dir(), BuildConfig.abi())

class TestingApp(object):
@classmethod
def extract_tests_package(cls, package):
return package["name"] + "PackageTests.xctest"

@classmethod
def get_name(cls):
package = get_package_description()
return cls.extract_tests_package(package)

@classmethod
def get_folder(cls, name):
return "/data/local/tmp/" + name.split(".")[0]

@classmethod
def get_app_folder(cls):
return cls.get_folder(cls.get_name())

class ADB(object):
@classmethod
def push(cls, dst, files):
for f in files:
sh_checked(["adb", "push", f, dst])

@classmethod
def shell(cls, args):
env = []

for key, value in os.environ.iteritems():
if key.startswith("X_ANDROID"):
name = key[len("X_ANDROID_"):]
env.append(name + "=" + value)

sh_checked(["adb", "shell"] + env + args)

@classmethod
def makedirs(cls, dir):
cls.shell(["mkdir", "-p", dir])


def traverse_dependencies(func, include_root=False):
_traverse(_get_packages_tree(), include_root, func)
Expand All @@ -174,22 +213,6 @@ def copytree(src, dst):
subprocess.call(["rsync", "-r"] + src_files + [dst])


def adb_push(dst, files):
for f in files:
sh_checked(["adb", "push", f, dst])


def adb_shell(args):
env = []

for key, value in os.environ.iteritems():
if key.startswith("X_ANDROID"):
name = key[len("X_ANDROID_"):]
env.append(name + "=" + value)

sh_checked(["adb", "shell"] + env + args)


def check_swift_home():
if SWIFT_ANDROID_HOME is None or not os.path.isdir(SWIFT_ANDROID_HOME):
print("SWIFT_ANDROID_HOME not set execution stopped")
Expand Down

0 comments on commit aad672b

Please sign in to comment.