diff mbox series

[v5,10/10] support/testing: test extra download with site method git

Message ID 20180512025833.22998-11-ricardo.martincoski@gmail.com
State Changes Requested
Headers show
Series tests for git download infra v5 | expand

Commit Message

Ricardo Martincoski May 12, 2018, 2:58 a.m. UTC
Add one test case to ensure the use of extra download works for git
packages:
 - an extra download is correctly downloaded using wget after the main
   download finished using the git backend;
 - when the main download using the git backend fails, the build fails;
 - when the extra download using wget fails, the build fails.

Reuse the commit in the static repo.
Add required infra and fixture:
 - a HttpServer class, that starts a http server in the host machine to
   emulate a remote http server under the control of the test;
 - a file to be served by the http server;
 - a br2-external (git-extra-download) with one package for each part of
   the test case.
Since the HttpServer is similar to GitRemote, extract the commonalities
to a new base class called Server.

Signed-off-by: Ricardo Martincoski <ricardo.martincoski@gmail.com>
Cc: Luca Ceresoli <luca@lucaceresoli.net>
Cc: Thomas Petazzoni <thomas.petazzoni@bootlin.com>
Cc: Yann E. MORIN <yann.morin.1998@free.fr>
---
Changes v4 -> v5:
  - no changes

Changes v3 -> v4:
  - new patch

I use docker only with the Buildroot image for the test infra.
Sorry, I give up for now on trying to run apache on the docker image.

As a midground solution between:
 - adding more files to http://autobuild.buildroot.net/artefacts/ that
   won't scale well if we need different files for different test cases;
 - installing a full web server to the docker image auto-loading as root
   when the container is started as user and allowing the test infra to
   copy files to the served path as user;
and inspired by this article:
https://www.pcsuggest.com/best-lightweight-web-server-linux/
I created this patch using SimpleHTTPServer being started by the test
infra as a user.
I know it is weird to use pexpect to fork a server written in Python,
but it has these advantages:
 - theoretically replacing SimpleHTTPServer with a similar solution (say
   the busybox httpd) in the future would require only small changes to
   the test infra code;
 - SimpleHTTPServer is already on the docker image, busybox isn't, so no
   need to change the Dockerfile, generate the image, publish it and
   update the docker image tag on .gitlab-ci.yml;
 - the log file generated by the server is handled in the same way as
   other log files generated by the test infra;
---
 .gitlab-ci.yml                                |  1 +
 support/testing/infra/server.py               | 39 +++++++++++++++++
 .../br2-external/git-extra-download/Config.in |  0
 .../git-extra-download/external.desc          |  1 +
 .../git-extra-download/external.mk            |  6 +++
 .../package/extra-fails/extra-fails.hash      |  3 ++
 .../package/extra-fails/extra-fails.mk        | 12 ++++++
 .../package/main-fails/main-fails.hash        |  3 ++
 .../package/main-fails/main-fails.mk          | 12 ++++++
 .../git-extra-download/package/ok/ok.hash     |  3 ++
 .../git-extra-download/package/ok/ok.mk       | 12 ++++++
 support/testing/tests/download/gitremote.py   | 43 +++----------------
 .../testing/tests/download/http-server/extra  |  1 +
 support/testing/tests/download/httpserver.py  | 14 ++++++
 support/testing/tests/download/test_git.py    | 21 +++++++++
 15 files changed, 135 insertions(+), 36 deletions(-)
 create mode 100644 support/testing/infra/server.py
 create mode 100644 support/testing/tests/download/br2-external/git-extra-download/Config.in
 create mode 100644 support/testing/tests/download/br2-external/git-extra-download/external.desc
 create mode 100644 support/testing/tests/download/br2-external/git-extra-download/external.mk
 create mode 100644 support/testing/tests/download/br2-external/git-extra-download/package/extra-fails/extra-fails.hash
 create mode 100644 support/testing/tests/download/br2-external/git-extra-download/package/extra-fails/extra-fails.mk
 create mode 100644 support/testing/tests/download/br2-external/git-extra-download/package/main-fails/main-fails.hash
 create mode 100644 support/testing/tests/download/br2-external/git-extra-download/package/main-fails/main-fails.mk
 create mode 100644 support/testing/tests/download/br2-external/git-extra-download/package/ok/ok.hash
 create mode 100644 support/testing/tests/download/br2-external/git-extra-download/package/ok/ok.mk
 create mode 100644 support/testing/tests/download/http-server/extra
 create mode 100644 support/testing/tests/download/httpserver.py

Comments

Arnout Vandecappelle Feb. 6, 2019, 10:34 a.m. UTC | #1
On 12/05/2018 04:58, Ricardo Martincoski wrote:
> Add one test case to ensure the use of extra download works for git
> packages:
>  - an extra download is correctly downloaded using wget after the main
>    download finished using the git backend;
>  - when the main download using the git backend fails, the build fails;
>  - when the extra download using wget fails, the build fails.
> 
> Reuse the commit in the static repo.
> Add required infra and fixture:
>  - a HttpServer class, that starts a http server in the host machine to
>    emulate a remote http server under the control of the test;
>  - a file to be served by the http server;
>  - a br2-external (git-extra-download) with one package for each part of
>    the test case.
> Since the HttpServer is similar to GitRemote, extract the commonalities
> to a new base class called Server.

 This one is a little too complicated to just apply, so I'm going to leave it
here for the time being...

 It should for sure be split into two patches, one adding the common Server
class to the infra, and the next one adding the http test.

 Also I'd probably prefer first just adding an http download test case and only
later adding the extra downloads test.


 However, I also don't really like the approach of launching our own http
server. I think it's much easier to rely on an existing one, perhaps using
sources.buildroot.org. You could say that it makes it impossible to run the
tests offline, but that's already the case for a most of them, because they
download sources and kernel binaries etc.


 So I've marked this one as Changes Requested in patchwork.


 Regards,
 Arnout


> 
> Signed-off-by: Ricardo Martincoski <ricardo.martincoski@gmail.com>
> Cc: Luca Ceresoli <luca@lucaceresoli.net>
> Cc: Thomas Petazzoni <thomas.petazzoni@bootlin.com>
> Cc: Yann E. MORIN <yann.morin.1998@free.fr>
> ---
> Changes v4 -> v5:
>   - no changes
> 
> Changes v3 -> v4:
>   - new patch
> 
> I use docker only with the Buildroot image for the test infra.
> Sorry, I give up for now on trying to run apache on the docker image.
> 
> As a midground solution between:
>  - adding more files to http://autobuild.buildroot.net/artefacts/ that
>    won't scale well if we need different files for different test cases;
>  - installing a full web server to the docker image auto-loading as root
>    when the container is started as user and allowing the test infra to
>    copy files to the served path as user;
> and inspired by this article:
> https://www.pcsuggest.com/best-lightweight-web-server-linux/
> I created this patch using SimpleHTTPServer being started by the test
> infra as a user.
> I know it is weird to use pexpect to fork a server written in Python,
> but it has these advantages:
>  - theoretically replacing SimpleHTTPServer with a similar solution (say
>    the busybox httpd) in the future would require only small changes to
>    the test infra code;
>  - SimpleHTTPServer is already on the docker image, busybox isn't, so no
>    need to change the Dockerfile, generate the image, publish it and
>    update the docker image tag on .gitlab-ci.yml;
>  - the log file generated by the server is handled in the same way as
>    other log files generated by the test infra;
> ---
>  .gitlab-ci.yml                                |  1 +
>  support/testing/infra/server.py               | 39 +++++++++++++++++
>  .../br2-external/git-extra-download/Config.in |  0
>  .../git-extra-download/external.desc          |  1 +
>  .../git-extra-download/external.mk            |  6 +++
>  .../package/extra-fails/extra-fails.hash      |  3 ++
>  .../package/extra-fails/extra-fails.mk        | 12 ++++++
>  .../package/main-fails/main-fails.hash        |  3 ++
>  .../package/main-fails/main-fails.mk          | 12 ++++++
>  .../git-extra-download/package/ok/ok.hash     |  3 ++
>  .../git-extra-download/package/ok/ok.mk       | 12 ++++++
>  support/testing/tests/download/gitremote.py   | 43 +++----------------
>  .../testing/tests/download/http-server/extra  |  1 +
>  support/testing/tests/download/httpserver.py  | 14 ++++++
>  support/testing/tests/download/test_git.py    | 21 +++++++++
>  15 files changed, 135 insertions(+), 36 deletions(-)
>  create mode 100644 support/testing/infra/server.py
>  create mode 100644 support/testing/tests/download/br2-external/git-extra-download/Config.in
>  create mode 100644 support/testing/tests/download/br2-external/git-extra-download/external.desc
>  create mode 100644 support/testing/tests/download/br2-external/git-extra-download/external.mk
>  create mode 100644 support/testing/tests/download/br2-external/git-extra-download/package/extra-fails/extra-fails.hash
>  create mode 100644 support/testing/tests/download/br2-external/git-extra-download/package/extra-fails/extra-fails.mk
>  create mode 100644 support/testing/tests/download/br2-external/git-extra-download/package/main-fails/main-fails.hash
>  create mode 100644 support/testing/tests/download/br2-external/git-extra-download/package/main-fails/main-fails.mk
>  create mode 100644 support/testing/tests/download/br2-external/git-extra-download/package/ok/ok.hash
>  create mode 100644 support/testing/tests/download/br2-external/git-extra-download/package/ok/ok.mk
>  create mode 100644 support/testing/tests/download/http-server/extra
>  create mode 100644 support/testing/tests/download/httpserver.py
> 
> diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
> index 61ccfdfd2d..53f7c72ac3 100644
> --- a/.gitlab-ci.yml
> +++ b/.gitlab-ci.yml
> @@ -263,6 +263,7 @@ tests.core.test_rootfs_overlay.TestRootfsOverlay: *runtime_test
>  tests.core.test_timezone.TestGlibcAllTimezone: *runtime_test
>  tests.core.test_timezone.TestGlibcNonDefaultLimitedTimezone: *runtime_test
>  tests.core.test_timezone.TestNoTimezone: *runtime_test
> +tests.download.test_git.TestGitExtraDownload: *runtime_test
>  tests.download.test_git.TestGitHash: *runtime_test
>  tests.download.test_git.TestGitRefs: *runtime_test
>  tests.fs.test_ext.TestExt2: *runtime_test
> diff --git a/support/testing/infra/server.py b/support/testing/infra/server.py
> new file mode 100644
> index 0000000000..0fbffdf846
> --- /dev/null
> +++ b/support/testing/infra/server.py
> @@ -0,0 +1,39 @@
> +# subprocess does not kill the child daemon when a test case fails by raising
> +# an exception. So use pexpect instead.
> +import pexpect
> +
> +import infra
> +
> +
> +class Server(object):
> +    def __init__(self, builddir, serveddir, logtofile, daemon_cmd, port_arg, port_initial, port_last, good_msg, bad_msg):
> +        """
> +        Start a local server.
> +
> +        In order to support test cases in parallel, select the port the
> +        server will listen to in runtime. Since there is no reliable way
> +        to allocate the port prior to starting the server (another
> +        process in the host machine can use the port between it is
> +        selected from a list and it is really allocated to the server)
> +        try to start the server in a port and in the case it is already
> +        in use, try the next one in the allowed range.
> +        """
> +        self.name = self.__class__.__name__.lower()
> +        self.daemon = None
> +        self.port = None
> +        self.logfile = infra.open_log_file(builddir, self.name, logtofile)
> +
> +        for port in range(port_initial, port_last + 1):
> +            cmd = daemon_cmd + [port_arg.format(port=port)]
> +            self.logfile.write("> starting {} with 'cd {} && {}'\n".format(self.name, serveddir, " ".join(cmd)))
> +            self.daemon = pexpect.spawn(cmd[0], cmd[1:], logfile=self.logfile, cwd=serveddir)
> +            ret = self.daemon.expect(good_msg + bad_msg)
> +            if ret < len(good_msg):
> +                self.port = port
> +                return
> +        raise SystemError("Could not find a free port to run {}".format(self.name))
> +
> +    def stop(self):
> +        if self.daemon is None:
> +            return
> +        self.daemon.terminate(force=True)
> diff --git a/support/testing/tests/download/br2-external/git-extra-download/Config.in b/support/testing/tests/download/br2-external/git-extra-download/Config.in
> new file mode 100644
> index 0000000000..e69de29bb2
> diff --git a/support/testing/tests/download/br2-external/git-extra-download/external.desc b/support/testing/tests/download/br2-external/git-extra-download/external.desc
> new file mode 100644
> index 0000000000..6ebd5a534d
> --- /dev/null
> +++ b/support/testing/tests/download/br2-external/git-extra-download/external.desc
> @@ -0,0 +1 @@
> +name: GIT_EXTRA_DOWNLOAD
> diff --git a/support/testing/tests/download/br2-external/git-extra-download/external.mk b/support/testing/tests/download/br2-external/git-extra-download/external.mk
> new file mode 100644
> index 0000000000..c6080f571b
> --- /dev/null
> +++ b/support/testing/tests/download/br2-external/git-extra-download/external.mk
> @@ -0,0 +1,6 @@
> +include $(sort $(wildcard $(BR2_EXTERNAL_GIT_EXTRA_DOWNLOAD_PATH)/package/*/*.mk))
> +
> +# Get the git server port number from the test infra
> +GITREMOTE_PORT_NUMBER ?= 9418
> +# Get the http server port number from the test infra
> +HTTP_SERVER_PORT_NUMBER ?= 8000
> diff --git a/support/testing/tests/download/br2-external/git-extra-download/package/extra-fails/extra-fails.hash b/support/testing/tests/download/br2-external/git-extra-download/package/extra-fails/extra-fails.hash
> new file mode 100644
> index 0000000000..89b1b1f682
> --- /dev/null
> +++ b/support/testing/tests/download/br2-external/git-extra-download/package/extra-fails/extra-fails.hash
> @@ -0,0 +1,3 @@
> +sha256  1e6bc73fabdcce8857361e36e3c812c4ee42d8ffa30d56492bc56f8fcad7eb90  extra-fails-a238b1dfcd825d47d834af3c5223417c8411d90d.tar.gz
> +sha256  b9e68e1bea3e5b19ca6b2f98b73a54b73daafaa250484902e09982e07a12e733  notfound
> +sha256  da68f54607d5f5644954096ce1597c006c5bb9f2497e07441bf064b81003ef8a  file
> diff --git a/support/testing/tests/download/br2-external/git-extra-download/package/extra-fails/extra-fails.mk b/support/testing/tests/download/br2-external/git-extra-download/package/extra-fails/extra-fails.mk
> new file mode 100644
> index 0000000000..dcf3ebe7a6
> --- /dev/null
> +++ b/support/testing/tests/download/br2-external/git-extra-download/package/extra-fails/extra-fails.mk
> @@ -0,0 +1,12 @@
> +################################################################################
> +#
> +# extra-fails
> +#
> +################################################################################
> +
> +EXTRA_FAILS_VERSION = a238b1dfcd825d47d834af3c5223417c8411d90d
> +EXTRA_FAILS_SITE = git://localhost:$(GITREMOTE_PORT_NUMBER)/repo.git
> +EXTRA_FAILS_EXTRA_DOWNLOADS = http://localhost:$(HTTP_SERVER_PORT_NUMBER)/notfound
> +EXTRA_FAILS_LICENSE_FILES = file
> +
> +$(eval $(generic-package))
> diff --git a/support/testing/tests/download/br2-external/git-extra-download/package/main-fails/main-fails.hash b/support/testing/tests/download/br2-external/git-extra-download/package/main-fails/main-fails.hash
> new file mode 100644
> index 0000000000..ad81243751
> --- /dev/null
> +++ b/support/testing/tests/download/br2-external/git-extra-download/package/main-fails/main-fails.hash
> @@ -0,0 +1,3 @@
> +sha256  cd6851ef519a83345e4547f376b33d6bbd622d4ccbb234af9997c43854c602de  main-fails-a238b1dfcd825d47d834af3c5223417c8411d90d.tar.gz
> +sha256  b9e68e1bea3e5b19ca6b2f98b73a54b73daafaa250484902e09982e07a12e733  extra
> +sha256  da68f54607d5f5644954096ce1597c006c5bb9f2497e07441bf064b81003ef8a  file
> diff --git a/support/testing/tests/download/br2-external/git-extra-download/package/main-fails/main-fails.mk b/support/testing/tests/download/br2-external/git-extra-download/package/main-fails/main-fails.mk
> new file mode 100644
> index 0000000000..022bb37cbb
> --- /dev/null
> +++ b/support/testing/tests/download/br2-external/git-extra-download/package/main-fails/main-fails.mk
> @@ -0,0 +1,12 @@
> +################################################################################
> +#
> +# main-fails
> +#
> +################################################################################
> +
> +MAIN_FAILS_VERSION = a238b1dfcd825d47d834af3c5223417c8411d90d
> +MAIN_FAILS_SITE = git://localhost:$(GITREMOTE_PORT_NUMBER)/notfound.git
> +MAIN_FAILS_EXTRA_DOWNLOADS = http://localhost:$(HTTP_SERVER_PORT_NUMBER)/extra
> +MAIN_FAILS_LICENSE_FILES = file
> +
> +$(eval $(generic-package))
> diff --git a/support/testing/tests/download/br2-external/git-extra-download/package/ok/ok.hash b/support/testing/tests/download/br2-external/git-extra-download/package/ok/ok.hash
> new file mode 100644
> index 0000000000..366940754b
> --- /dev/null
> +++ b/support/testing/tests/download/br2-external/git-extra-download/package/ok/ok.hash
> @@ -0,0 +1,3 @@
> +sha256  737b4fd21506dbaa34cedc93c53c1ebb1f950db2c7644572bb006ae9297961da  ok-a238b1dfcd825d47d834af3c5223417c8411d90d.tar.gz
> +sha256  b9e68e1bea3e5b19ca6b2f98b73a54b73daafaa250484902e09982e07a12e733  extra
> +sha256  da68f54607d5f5644954096ce1597c006c5bb9f2497e07441bf064b81003ef8a  file
> diff --git a/support/testing/tests/download/br2-external/git-extra-download/package/ok/ok.mk b/support/testing/tests/download/br2-external/git-extra-download/package/ok/ok.mk
> new file mode 100644
> index 0000000000..ce102cb0de
> --- /dev/null
> +++ b/support/testing/tests/download/br2-external/git-extra-download/package/ok/ok.mk
> @@ -0,0 +1,12 @@
> +################################################################################
> +#
> +# ok
> +#
> +################################################################################
> +
> +OK_VERSION = a238b1dfcd825d47d834af3c5223417c8411d90d
> +OK_SITE = git://localhost:$(GITREMOTE_PORT_NUMBER)/repo.git
> +OK_EXTRA_DOWNLOADS = http://localhost:$(HTTP_SERVER_PORT_NUMBER)/extra
> +OK_LICENSE_FILES = file
> +
> +$(eval $(generic-package))
> diff --git a/support/testing/tests/download/gitremote.py b/support/testing/tests/download/gitremote.py
> index 60bc49fbf8..9766b19ce0 100644
> --- a/support/testing/tests/download/gitremote.py
> +++ b/support/testing/tests/download/gitremote.py
> @@ -1,44 +1,15 @@
> -# subprocess does not kill the child daemon when a test case fails by raising
> -# an exception. So use pexpect instead.
> -import pexpect
> -
> -import infra
> +from infra.server import Server
>  
>  GIT_REMOTE_PORT_INITIAL = 9418
>  GIT_REMOTE_PORT_LAST = GIT_REMOTE_PORT_INITIAL + 99
>  
>  
> -class GitRemote(object):
> +class GitRemote(Server):
>      def __init__(self, builddir, serveddir, logtofile):
> -        """
> -        Start a local git server.
> -
> -        In order to support test cases in parallel, select the port the
> -        server will listen to in runtime. Since there is no reliable way
> -        to allocate the port prior to starting the server (another
> -        process in the host machine can use the port between it is
> -        selected from a list and it is really allocated to the server)
> -        try to start the server in a port and in the case it is already
> -        in use, try the next one in the allowed range.
> -        """
> -        self.daemon = None
> -        self.port = None
> -        self.logfile = infra.open_log_file(builddir, "gitremote", logtofile)
> -
>          daemon_cmd = ["git", "daemon", "--reuseaddr", "--verbose", "--listen=localhost", "--export-all",
>                        "--base-path={}".format(serveddir)]
> -        for port in range(GIT_REMOTE_PORT_INITIAL, GIT_REMOTE_PORT_LAST + 1):
> -            cmd = daemon_cmd + ["--port={port}".format(port=port)]
> -            self.logfile.write("> starting git remote with '{}'\n".format(" ".join(cmd)))
> -            self.daemon = pexpect.spawn(cmd[0], cmd[1:], logfile=self.logfile)
> -            ret = self.daemon.expect(["Ready to rumble",
> -                                      "Address already in use"])
> -            if ret == 0:
> -                self.port = port
> -                return
> -        raise SystemError("Could not find a free port to run git remote")
> -
> -    def stop(self):
> -        if self.daemon is None:
> -            return
> -        self.daemon.terminate(force=True)
> +        super(GitRemote, self).__init__(
> +            builddir, serveddir, logtofile,
> +            daemon_cmd, "--port={port}", GIT_REMOTE_PORT_INITIAL, GIT_REMOTE_PORT_LAST,
> +            ["Ready to rumble"],
> +            ["Address already in use"])
> diff --git a/support/testing/tests/download/http-server/extra b/support/testing/tests/download/http-server/extra
> new file mode 100644
> index 0000000000..8e27be7d61
> --- /dev/null
> +++ b/support/testing/tests/download/http-server/extra
> @@ -0,0 +1 @@
> +text
> diff --git a/support/testing/tests/download/httpserver.py b/support/testing/tests/download/httpserver.py
> new file mode 100644
> index 0000000000..9f4f947304
> --- /dev/null
> +++ b/support/testing/tests/download/httpserver.py
> @@ -0,0 +1,14 @@
> +from infra.server import Server
> +
> +HTTP_SERVER_PORT_INITIAL = 8000
> +HTTP_SERVER_PORT_LAST = HTTP_SERVER_PORT_INITIAL + 99
> +
> +
> +class HttpServer(Server):
> +    def __init__(self, builddir, serveddir, logtofile):
> +        daemon_cmd = ["python", "-m", "SimpleHTTPServer"]
> +        super(HttpServer, self).__init__(
> +            builddir, serveddir, logtofile,
> +            daemon_cmd, "{port}", HTTP_SERVER_PORT_INITIAL, HTTP_SERVER_PORT_LAST,
> +            ["Serving HTTP"],
> +            ["Address already in use"])
> diff --git a/support/testing/tests/download/test_git.py b/support/testing/tests/download/test_git.py
> index 162c03623b..e0abc3fa65 100644
> --- a/support/testing/tests/download/test_git.py
> +++ b/support/testing/tests/download/test_git.py
> @@ -3,6 +3,7 @@ import shutil
>  
>  import infra
>  from gitremote import GitRemote
> +from httpserver import HttpServer
>  
>  
>  class GitTestBase(infra.basetest.BRTest):
> @@ -12,13 +13,19 @@ class GitTestBase(infra.basetest.BRTest):
>          """
>      gitremotedir = infra.filepath("tests/download/git-remote")
>      gitremote = None
> +    httpserverdir = None
> +    httpserver = None
>  
>      def setUp(self):
>          super(GitTestBase, self).setUp()
>          self.gitremote = GitRemote(self.builddir, self.gitremotedir, self.logtofile)
> +        if self.httpserverdir:
> +            self.httpserver = HttpServer(self.builddir, self.httpserverdir, self.logtofile)
>  
>      def tearDown(self):
>          self.show_msg("Cleaning up")
> +        if self.httpserver:
> +            self.httpserver.stop()
>          if self.gitremote:
>              self.gitremote.stop()
>          if self.b and not self.keepbuilds:
> @@ -42,11 +49,25 @@ class GitTestBase(infra.basetest.BRTest):
>              shutil.rmtree(dl_dir)
>          env = {"BR2_DL_DIR": dl_dir,
>                 "GITREMOTE_PORT_NUMBER": str(self.gitremote.port)}
> +        if self.httpserver:
> +            env["HTTP_SERVER_PORT_NUMBER"] = str(self.httpserver.port)
>          self.b.build(["{}-dirclean".format(package),
>                        "{}-legal-info".format(package)],
>                       env)
>  
>  
> +class TestGitExtraDownload(GitTestBase):
> +    br2_external = [infra.filepath("tests/download/br2-external/git-extra-download")]
> +    httpserverdir = infra.filepath("tests/download/http-server")
> +
> +    def test_run(self):
> +        with self.assertRaises(SystemError):
> +            self.check_download("extra-fails")
> +        with self.assertRaises(SystemError):
> +            self.check_download("main-fails")
> +        self.check_download("ok")
> +
> +
>  class TestGitHash(GitTestBase):
>      br2_external = [infra.filepath("tests/download/br2-external/git-hash")]
>  
>
diff mbox series

Patch

diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 61ccfdfd2d..53f7c72ac3 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -263,6 +263,7 @@  tests.core.test_rootfs_overlay.TestRootfsOverlay: *runtime_test
 tests.core.test_timezone.TestGlibcAllTimezone: *runtime_test
 tests.core.test_timezone.TestGlibcNonDefaultLimitedTimezone: *runtime_test
 tests.core.test_timezone.TestNoTimezone: *runtime_test
+tests.download.test_git.TestGitExtraDownload: *runtime_test
 tests.download.test_git.TestGitHash: *runtime_test
 tests.download.test_git.TestGitRefs: *runtime_test
 tests.fs.test_ext.TestExt2: *runtime_test
diff --git a/support/testing/infra/server.py b/support/testing/infra/server.py
new file mode 100644
index 0000000000..0fbffdf846
--- /dev/null
+++ b/support/testing/infra/server.py
@@ -0,0 +1,39 @@ 
+# subprocess does not kill the child daemon when a test case fails by raising
+# an exception. So use pexpect instead.
+import pexpect
+
+import infra
+
+
+class Server(object):
+    def __init__(self, builddir, serveddir, logtofile, daemon_cmd, port_arg, port_initial, port_last, good_msg, bad_msg):
+        """
+        Start a local server.
+
+        In order to support test cases in parallel, select the port the
+        server will listen to in runtime. Since there is no reliable way
+        to allocate the port prior to starting the server (another
+        process in the host machine can use the port between it is
+        selected from a list and it is really allocated to the server)
+        try to start the server in a port and in the case it is already
+        in use, try the next one in the allowed range.
+        """
+        self.name = self.__class__.__name__.lower()
+        self.daemon = None
+        self.port = None
+        self.logfile = infra.open_log_file(builddir, self.name, logtofile)
+
+        for port in range(port_initial, port_last + 1):
+            cmd = daemon_cmd + [port_arg.format(port=port)]
+            self.logfile.write("> starting {} with 'cd {} && {}'\n".format(self.name, serveddir, " ".join(cmd)))
+            self.daemon = pexpect.spawn(cmd[0], cmd[1:], logfile=self.logfile, cwd=serveddir)
+            ret = self.daemon.expect(good_msg + bad_msg)
+            if ret < len(good_msg):
+                self.port = port
+                return
+        raise SystemError("Could not find a free port to run {}".format(self.name))
+
+    def stop(self):
+        if self.daemon is None:
+            return
+        self.daemon.terminate(force=True)
diff --git a/support/testing/tests/download/br2-external/git-extra-download/Config.in b/support/testing/tests/download/br2-external/git-extra-download/Config.in
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/support/testing/tests/download/br2-external/git-extra-download/external.desc b/support/testing/tests/download/br2-external/git-extra-download/external.desc
new file mode 100644
index 0000000000..6ebd5a534d
--- /dev/null
+++ b/support/testing/tests/download/br2-external/git-extra-download/external.desc
@@ -0,0 +1 @@ 
+name: GIT_EXTRA_DOWNLOAD
diff --git a/support/testing/tests/download/br2-external/git-extra-download/external.mk b/support/testing/tests/download/br2-external/git-extra-download/external.mk
new file mode 100644
index 0000000000..c6080f571b
--- /dev/null
+++ b/support/testing/tests/download/br2-external/git-extra-download/external.mk
@@ -0,0 +1,6 @@ 
+include $(sort $(wildcard $(BR2_EXTERNAL_GIT_EXTRA_DOWNLOAD_PATH)/package/*/*.mk))
+
+# Get the git server port number from the test infra
+GITREMOTE_PORT_NUMBER ?= 9418
+# Get the http server port number from the test infra
+HTTP_SERVER_PORT_NUMBER ?= 8000
diff --git a/support/testing/tests/download/br2-external/git-extra-download/package/extra-fails/extra-fails.hash b/support/testing/tests/download/br2-external/git-extra-download/package/extra-fails/extra-fails.hash
new file mode 100644
index 0000000000..89b1b1f682
--- /dev/null
+++ b/support/testing/tests/download/br2-external/git-extra-download/package/extra-fails/extra-fails.hash
@@ -0,0 +1,3 @@ 
+sha256  1e6bc73fabdcce8857361e36e3c812c4ee42d8ffa30d56492bc56f8fcad7eb90  extra-fails-a238b1dfcd825d47d834af3c5223417c8411d90d.tar.gz
+sha256  b9e68e1bea3e5b19ca6b2f98b73a54b73daafaa250484902e09982e07a12e733  notfound
+sha256  da68f54607d5f5644954096ce1597c006c5bb9f2497e07441bf064b81003ef8a  file
diff --git a/support/testing/tests/download/br2-external/git-extra-download/package/extra-fails/extra-fails.mk b/support/testing/tests/download/br2-external/git-extra-download/package/extra-fails/extra-fails.mk
new file mode 100644
index 0000000000..dcf3ebe7a6
--- /dev/null
+++ b/support/testing/tests/download/br2-external/git-extra-download/package/extra-fails/extra-fails.mk
@@ -0,0 +1,12 @@ 
+################################################################################
+#
+# extra-fails
+#
+################################################################################
+
+EXTRA_FAILS_VERSION = a238b1dfcd825d47d834af3c5223417c8411d90d
+EXTRA_FAILS_SITE = git://localhost:$(GITREMOTE_PORT_NUMBER)/repo.git
+EXTRA_FAILS_EXTRA_DOWNLOADS = http://localhost:$(HTTP_SERVER_PORT_NUMBER)/notfound
+EXTRA_FAILS_LICENSE_FILES = file
+
+$(eval $(generic-package))
diff --git a/support/testing/tests/download/br2-external/git-extra-download/package/main-fails/main-fails.hash b/support/testing/tests/download/br2-external/git-extra-download/package/main-fails/main-fails.hash
new file mode 100644
index 0000000000..ad81243751
--- /dev/null
+++ b/support/testing/tests/download/br2-external/git-extra-download/package/main-fails/main-fails.hash
@@ -0,0 +1,3 @@ 
+sha256  cd6851ef519a83345e4547f376b33d6bbd622d4ccbb234af9997c43854c602de  main-fails-a238b1dfcd825d47d834af3c5223417c8411d90d.tar.gz
+sha256  b9e68e1bea3e5b19ca6b2f98b73a54b73daafaa250484902e09982e07a12e733  extra
+sha256  da68f54607d5f5644954096ce1597c006c5bb9f2497e07441bf064b81003ef8a  file
diff --git a/support/testing/tests/download/br2-external/git-extra-download/package/main-fails/main-fails.mk b/support/testing/tests/download/br2-external/git-extra-download/package/main-fails/main-fails.mk
new file mode 100644
index 0000000000..022bb37cbb
--- /dev/null
+++ b/support/testing/tests/download/br2-external/git-extra-download/package/main-fails/main-fails.mk
@@ -0,0 +1,12 @@ 
+################################################################################
+#
+# main-fails
+#
+################################################################################
+
+MAIN_FAILS_VERSION = a238b1dfcd825d47d834af3c5223417c8411d90d
+MAIN_FAILS_SITE = git://localhost:$(GITREMOTE_PORT_NUMBER)/notfound.git
+MAIN_FAILS_EXTRA_DOWNLOADS = http://localhost:$(HTTP_SERVER_PORT_NUMBER)/extra
+MAIN_FAILS_LICENSE_FILES = file
+
+$(eval $(generic-package))
diff --git a/support/testing/tests/download/br2-external/git-extra-download/package/ok/ok.hash b/support/testing/tests/download/br2-external/git-extra-download/package/ok/ok.hash
new file mode 100644
index 0000000000..366940754b
--- /dev/null
+++ b/support/testing/tests/download/br2-external/git-extra-download/package/ok/ok.hash
@@ -0,0 +1,3 @@ 
+sha256  737b4fd21506dbaa34cedc93c53c1ebb1f950db2c7644572bb006ae9297961da  ok-a238b1dfcd825d47d834af3c5223417c8411d90d.tar.gz
+sha256  b9e68e1bea3e5b19ca6b2f98b73a54b73daafaa250484902e09982e07a12e733  extra
+sha256  da68f54607d5f5644954096ce1597c006c5bb9f2497e07441bf064b81003ef8a  file
diff --git a/support/testing/tests/download/br2-external/git-extra-download/package/ok/ok.mk b/support/testing/tests/download/br2-external/git-extra-download/package/ok/ok.mk
new file mode 100644
index 0000000000..ce102cb0de
--- /dev/null
+++ b/support/testing/tests/download/br2-external/git-extra-download/package/ok/ok.mk
@@ -0,0 +1,12 @@ 
+################################################################################
+#
+# ok
+#
+################################################################################
+
+OK_VERSION = a238b1dfcd825d47d834af3c5223417c8411d90d
+OK_SITE = git://localhost:$(GITREMOTE_PORT_NUMBER)/repo.git
+OK_EXTRA_DOWNLOADS = http://localhost:$(HTTP_SERVER_PORT_NUMBER)/extra
+OK_LICENSE_FILES = file
+
+$(eval $(generic-package))
diff --git a/support/testing/tests/download/gitremote.py b/support/testing/tests/download/gitremote.py
index 60bc49fbf8..9766b19ce0 100644
--- a/support/testing/tests/download/gitremote.py
+++ b/support/testing/tests/download/gitremote.py
@@ -1,44 +1,15 @@ 
-# subprocess does not kill the child daemon when a test case fails by raising
-# an exception. So use pexpect instead.
-import pexpect
-
-import infra
+from infra.server import Server
 
 GIT_REMOTE_PORT_INITIAL = 9418
 GIT_REMOTE_PORT_LAST = GIT_REMOTE_PORT_INITIAL + 99
 
 
-class GitRemote(object):
+class GitRemote(Server):
     def __init__(self, builddir, serveddir, logtofile):
-        """
-        Start a local git server.
-
-        In order to support test cases in parallel, select the port the
-        server will listen to in runtime. Since there is no reliable way
-        to allocate the port prior to starting the server (another
-        process in the host machine can use the port between it is
-        selected from a list and it is really allocated to the server)
-        try to start the server in a port and in the case it is already
-        in use, try the next one in the allowed range.
-        """
-        self.daemon = None
-        self.port = None
-        self.logfile = infra.open_log_file(builddir, "gitremote", logtofile)
-
         daemon_cmd = ["git", "daemon", "--reuseaddr", "--verbose", "--listen=localhost", "--export-all",
                       "--base-path={}".format(serveddir)]
-        for port in range(GIT_REMOTE_PORT_INITIAL, GIT_REMOTE_PORT_LAST + 1):
-            cmd = daemon_cmd + ["--port={port}".format(port=port)]
-            self.logfile.write("> starting git remote with '{}'\n".format(" ".join(cmd)))
-            self.daemon = pexpect.spawn(cmd[0], cmd[1:], logfile=self.logfile)
-            ret = self.daemon.expect(["Ready to rumble",
-                                      "Address already in use"])
-            if ret == 0:
-                self.port = port
-                return
-        raise SystemError("Could not find a free port to run git remote")
-
-    def stop(self):
-        if self.daemon is None:
-            return
-        self.daemon.terminate(force=True)
+        super(GitRemote, self).__init__(
+            builddir, serveddir, logtofile,
+            daemon_cmd, "--port={port}", GIT_REMOTE_PORT_INITIAL, GIT_REMOTE_PORT_LAST,
+            ["Ready to rumble"],
+            ["Address already in use"])
diff --git a/support/testing/tests/download/http-server/extra b/support/testing/tests/download/http-server/extra
new file mode 100644
index 0000000000..8e27be7d61
--- /dev/null
+++ b/support/testing/tests/download/http-server/extra
@@ -0,0 +1 @@ 
+text
diff --git a/support/testing/tests/download/httpserver.py b/support/testing/tests/download/httpserver.py
new file mode 100644
index 0000000000..9f4f947304
--- /dev/null
+++ b/support/testing/tests/download/httpserver.py
@@ -0,0 +1,14 @@ 
+from infra.server import Server
+
+HTTP_SERVER_PORT_INITIAL = 8000
+HTTP_SERVER_PORT_LAST = HTTP_SERVER_PORT_INITIAL + 99
+
+
+class HttpServer(Server):
+    def __init__(self, builddir, serveddir, logtofile):
+        daemon_cmd = ["python", "-m", "SimpleHTTPServer"]
+        super(HttpServer, self).__init__(
+            builddir, serveddir, logtofile,
+            daemon_cmd, "{port}", HTTP_SERVER_PORT_INITIAL, HTTP_SERVER_PORT_LAST,
+            ["Serving HTTP"],
+            ["Address already in use"])
diff --git a/support/testing/tests/download/test_git.py b/support/testing/tests/download/test_git.py
index 162c03623b..e0abc3fa65 100644
--- a/support/testing/tests/download/test_git.py
+++ b/support/testing/tests/download/test_git.py
@@ -3,6 +3,7 @@  import shutil
 
 import infra
 from gitremote import GitRemote
+from httpserver import HttpServer
 
 
 class GitTestBase(infra.basetest.BRTest):
@@ -12,13 +13,19 @@  class GitTestBase(infra.basetest.BRTest):
         """
     gitremotedir = infra.filepath("tests/download/git-remote")
     gitremote = None
+    httpserverdir = None
+    httpserver = None
 
     def setUp(self):
         super(GitTestBase, self).setUp()
         self.gitremote = GitRemote(self.builddir, self.gitremotedir, self.logtofile)
+        if self.httpserverdir:
+            self.httpserver = HttpServer(self.builddir, self.httpserverdir, self.logtofile)
 
     def tearDown(self):
         self.show_msg("Cleaning up")
+        if self.httpserver:
+            self.httpserver.stop()
         if self.gitremote:
             self.gitremote.stop()
         if self.b and not self.keepbuilds:
@@ -42,11 +49,25 @@  class GitTestBase(infra.basetest.BRTest):
             shutil.rmtree(dl_dir)
         env = {"BR2_DL_DIR": dl_dir,
                "GITREMOTE_PORT_NUMBER": str(self.gitremote.port)}
+        if self.httpserver:
+            env["HTTP_SERVER_PORT_NUMBER"] = str(self.httpserver.port)
         self.b.build(["{}-dirclean".format(package),
                       "{}-legal-info".format(package)],
                      env)
 
 
+class TestGitExtraDownload(GitTestBase):
+    br2_external = [infra.filepath("tests/download/br2-external/git-extra-download")]
+    httpserverdir = infra.filepath("tests/download/http-server")
+
+    def test_run(self):
+        with self.assertRaises(SystemError):
+            self.check_download("extra-fails")
+        with self.assertRaises(SystemError):
+            self.check_download("main-fails")
+        self.check_download("ok")
+
+
 class TestGitHash(GitTestBase):
     br2_external = [infra.filepath("tests/download/br2-external/git-hash")]