Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Code improvements around NDK download #961

Merged
merged 8 commits into from
Oct 5, 2019

Conversation

inclement
Copy link
Member

Made a few improvements while checking NDK version downloads were working correctly.

I'm pretty satisfied that everything is good, thanks @opacam for doing the real work here.

In particular, the scenarios that need covering are:

  • New install: buildozer downloads p4a latest release then a matching NDK.
  • P4a already downloaded: buildozer checks the p4a recommendations and fetches a matching NDK.
  • NDK already downloaded: buildozer downloads p4a latest release, then fetches a matching NDK if necessary.

I was worried there might be some issues with how buildozer stores the NDKs, but it all seems basically good.

Also added a new command buildozer appclean that deletes the build directory (i.e. app_dir/.buildozer), because this is much nicer than telling users to delete it themselves.

AndreMiras
AndreMiras previously approved these changes Sep 17, 2019
Copy link
Member

@AndreMiras AndreMiras left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is looking very good, thank you!
I wrote some comments, but most of them are remark or nitpick, just so we're aware of. So as usual feel free to ignore obviously.
Something more major however is tests are failing. Do you have an idea why? Do you need help investigating?

======================================================================
ERROR: test_p4a_recommended_android_ndk_found (tests.test_buildozer.TestBuildozer)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/usr/lib/python3.4/unittest/mock.py", line 1128, in patched
    arg = patching.__enter__()
  File "/usr/lib/python3.4/unittest/mock.py", line 1197, in __enter__
    original, local = self.get_original()
  File "/usr/lib/python3.4/unittest/mock.py", line 1171, in get_original
    "%s does not have the attribute %r" % (target, name)
AttributeError: <module 'buildozer.targets.android' from '/home/travis/build/kivy/buildozer/buildozer/targets/android.py'> does not have the attribute 'open'
----------------------------------------------------------------------

buildozer/__init__.py Show resolved Hide resolved
@@ -879,10 +871,27 @@ def namify(self, name):
def root_dir(self):
return realpath(dirname(self.specfilename))

@property
def user_build_dir(self):
'''The user-provided build dir, if any.'''
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I like that we now have a dedicated method for this. But I also have a nitpick.
PEP-0257 say docstring should be double quotes, not single. Same in other docstrings. I know buildozer and p4a is already inconsistent here.
https://www.python.org/dev/peps/pep-0257/#what-is-a-docstring

if self.user_build_dir is not None:
self.error(
('Failed: build_dir is specified as {} in the buildozer config. `appclean` will '
'not attempt to delete files in a user-specified build directory.').format(self.user_build_dir))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice that you thought about preventing that

# that python-for-android cannot provide a recommendation, which in
# turn only happens if the python-for-android is old and probably
# doesn't support any newer NDK.
DEFAULT_ANDROID_NDK_VERSION = '17c'
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for that comment

# Default p4a dir
p4a_dir = join(self.buildozer.platform_dir, self.p4a_directory_name)

# Possibly overriden by user setting
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

s/overriden/overridden/

else:
pa_dir = self.pa_dir
# make sure to read p4a version only the first time
if self.p4a_recommended_ndk_version is not None:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if we implement some kind of caching, then maybe in the future we want to make it a dedicated property that automagically deals with it

@@ -430,7 +437,7 @@ def _install_android_ndk(self):
archive = 'android-ndk-r{0}-linux-{1}.tar.bz2'
is_64 = (os.uname()[4] == 'x86_64')
else:
raise SystemError('Unsupported platform: {0}'.format(platform))
raise SystemError('Unsupported platform: {}'.format(platform))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm wondering if you caught that with unit tests or with sharp eyes 😄

@inclement
Copy link
Member Author

I fixed the previous test failure about the open function (which seemed like a reasonable failure, I don't know why it worked locally), but now I get another issue that I can't reproduce locally:

======================================================================

FAIL: test_p4a_recommended_android_ndk_found (tests.test_buildozer.TestBuildozer)

----------------------------------------------------------------------

Traceback (most recent call last):

  File "/usr/lib/python3.4/unittest/mock.py", line 1136, in patched

    return func(*args, **keywargs)

  File "/home/travis/build/kivy/buildozer/tests/test_buildozer.py", line 247, in test_p4a_recommended_android_ndk_found

    assert ndk_version == expected_ndk

AssertionError

The failure is straightforward enough, but it isn't clear why it's failing and why it only fails in travis...

@inclement inclement force-pushed the make_ndk_match_recommendation branch from d5ac294 to f3dab17 Compare October 1, 2019 21:27
@inclement
Copy link
Member Author

I've pushed an improvement to how the dist dir is calculated (including a backwards compatibility fix, I think this was broken in #978 for existing dists). Let's see if the tests will pass now...

@inclement inclement force-pushed the make_ndk_match_recommendation branch from f3dab17 to 5d1ddd2 Compare October 1, 2019 21:42
@inclement
Copy link
Member Author

Actually there might be some further rebase issues, not for merging quite yet.

@inclement inclement force-pushed the make_ndk_match_recommendation branch 2 times, most recently from 59d744b to 877fc87 Compare October 2, 2019 21:48
@AndreMiras
Copy link
Member

I fixed the previous test failure about the open function (which seemed like a reasonable failure, I don't know why it worked locally), but now I get another issue that I can't reproduce locally:

======================================================================

FAIL: test_p4a_recommended_android_ndk_found (tests.test_buildozer.TestBuildozer)

----------------------------------------------------------------------

Traceback (most recent call last):

  File "/usr/lib/python3.4/unittest/mock.py", line 1136, in patched

    return func(*args, **keywargs)

  File "/home/travis/build/kivy/buildozer/tests/test_buildozer.py", line 247, in test_p4a_recommended_android_ndk_found

    assert ndk_version == expected_ndk

AssertionError

The failure is straightforward enough, but it isn't clear why it's failing and why it only fails in travis...

I could reproduce on my local Ubuntu.

======================================================================
FAIL: test_p4a_recommended_android_ndk_found (tests.test_buildozer.TestBuildozer)
----------------------------------------------------------------------                                                                             
Traceback (most recent call last):                                                                                                                                                                                                                                                       
  File "/home/andre/workspace/buildozer/.tox/py27/lib/python2.7/site-packages/mock/mock.py", line 1305, in patched
    return func(*args, **keywargs)
  File "/home/andre/workspace/buildozer/tests/test_buildozer.py", line 253, in test_p4a_recommended_android_ndk_found
    assert ndk_version == expected_ndk                                          
AssertionError                                                           
                                                                                                           
----------------------------------------------------------------------

Using pytest gave more insights:

venv/bin/pytest tests/test_buildozer.py
================================================================================================================================== test session starts ==================================================================================================================================
platform linux -- Python 3.6.7, pytest-4.1.1, py-1.7.0, pluggy-0.8.1
rootdir: /home/andre/workspace/buildozer, inifile:
collected 11 items                                                                                                                                                                                                                                                                      

tests/test_buildozer.py ........F..                                                                                                                                                                                                                                               [100%]

======================================================================================================================================= FAILURES ========================================================================================================================================
_________________________________________________________________________________________________________________ TestBuildozer.test_p4a_recommended_android_ndk_found __________________________________________________________________________________________________________________

self = <tests.test_buildozer.TestBuildozer testMethod=test_p4a_recommended_android_ndk_found>, mock_open = <MagicMock name='open' id='140137745055416'>, mock_exists = <MagicMock name='exists' id='140137745014624'>, mock_isfile = <MagicMock name='isfile' id='140137744984832'>

    @mock.patch('buildozer.targets.android.os.path.isfile')
    @mock.patch('buildozer.targets.android.os.path.exists')
    @mock.patch('buildozer.targets.android.open', create=True)
    def test_p4a_recommended_android_ndk_found(
            self, mock_open, mock_exists, mock_isfile
    ):
        self.set_specfile_log_level(self.specfile.name, 1)
        buildozer = Buildozer(self.specfile.name, 'android')
    
        expected_ndk = '19b'
        mock_open.side_effect = [
            mock.mock_open(
                read_data='RECOMMENDED_NDK_VERSION = {expected_ndk}\n'.format(
                    expected_ndk=expected_ndk)
            ).return_value
        ]
        ndk_version = buildozer.target.p4a_recommended_android_ndk
        p4a_dir = os.path.join(
            buildozer.platform_dir, buildozer.target.p4a_directory_name)
        mock_open.assert_called_once_with(
            os.path.join(p4a_dir, "pythonforandroid", "recommendations.py"), 'r'
        )
        print('Found "{}" vs expected "{}"'.format(ndk_version, expected_ndk))
        print('Values are equal: {}'.format(ndk_version == expected_ndk))
        print('Types {} {}'.format(type(ndk_version), type(expected_ndk)))
        print('Lengths {} {}'.format(len(ndk_version), len(expected_ndk)))
>       assert ndk_version == expected_ndk
E       AssertionError: assert '17c' == '19b'
E         - 17c
E         + 19b

tests/test_buildozer.py:253: AssertionError

Also as I suggested on Discord, maybe we should also migrate that build to docker (and Makefile), I promise build won't run for over 10 minutes 😬

@inclement inclement force-pushed the make_ndk_match_recommendation branch from 877fc87 to 8bc5ffd Compare October 4, 2019 22:13
@@ -47,26 +47,28 @@
# does.
DEFAULT_SDK_TAG = '4333796'

DEFAULT_ARCH = 'armeabi-v7a'
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually at some point maybe the default should be arm64-v8a since the play store requires at least that one when uploading APK

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree, but chose not to change the default in this particular PR.

@inclement
Copy link
Member Author

Hah, looks like just importing mock works. Must be a unittest.mock change between Python 3.6 and 3.7.

I've just changed the code to import mock for now, this can easily be changed and investigated later. I'd rather get this merged as soon as possible.

Copy link
Member

@AndreMiras AndreMiras left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've tried it locally the APK build OK. Let's squash and merge it

@AndreMiras AndreMiras merged commit 9fcf28b into kivy:master Oct 5, 2019
@AndreMiras
Copy link
Member

Here's the follow up PR that fixes mocking #983

@inclement
Copy link
Member Author

Thanks @AndreMiras!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants