From patchwork Tue Apr 7 11:15:14 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jagan Teki X-Patchwork-Id: 1075 Return-Path: X-Original-To: linux-amarula@patchwork.amarulasolutions.com Delivered-To: linux-amarula@patchwork.amarulasolutions.com Received: from mail-oi1-f200.google.com (mail-oi1-f200.google.com [209.85.167.200]) by ganimede.amarulasolutions.com (Postfix) with ESMTPS id 3748F3F379 for ; Tue, 7 Apr 2020 13:16:18 +0200 (CEST) Received: by mail-oi1-f200.google.com with SMTP id a69sf2460887oib.11 for ; Tue, 07 Apr 2020 04:16:18 -0700 (PDT) ARC-Seal: i=2; a=rsa-sha256; t=1586258176; cv=pass; d=google.com; s=arc-20160816; b=b3QIHBjIRCpoCE7EBdGRffELZMbjswGu440wTAGKQnyVvG+mhTDCQiyOUDgSfdWnJ1 z+MSKXjYuR/LvtL7c4baJ5XoiAP4uIf9UyOj1zBPwbE/P+7l7fjPKSbLzaj3LaGv/Nsv vIeZObuhvEpyteumvpXrbVZxhkrjwfG/8ZS7+zm7UPyy0BsopgzNR1qP0Aq84ckHBQXq SLMyc9y6mjm4KTbEmNTmsFTOf5amPkR9l/isSnnynh4WvFr+wpe1FftQMLX27yx3F2w9 CMWJqOS8d2/yUcKZ6hXaBs78vW5tXYWGwzx4vSi4PLsaaZIxEYlaTNws83BRm1x03UHs 8Otw== ARC-Message-Signature: i=2; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-unsubscribe:list-archive:list-help:list-post:list-id :mailing-list:precedence:content-transfer-encoding:references :in-reply-to:message-id:date:subject:cc:to:from:mime-version :dkim-signature; bh=l1gRXUzFN3aHX727OME7XhgN0VEFMJLMUhx+Xs06z0E=; b=hxIwnzO6/p63msvDe24NZxofGmH/rT/TPIlTUHUGSDvpR6GYJTCxdBb7eBc2bl7QhP wSu2670KUA6XcpSjsi5/2dZr4Bz3Zdc08xSVuElzUuucOpihPMRWQOS7baAAAW6fg8C/ O6Yxdt1P+UOBtSsjaby8jTyfOmqbO4QHwd9MFeGYaShJjub3LnHIu+DDNEpsf4gFNom5 gGTUZsYBwSUFVXvJnBAMCrIpoyMVtTwW7v2EiP9aTqyX7she7iwzvu/YLRAE70stjOpF QDIjviEex+FucpvZmas+udT+elVDEq1sDUKebWdy7pRTR5lCAsVDSqFkfr7MO+NwSKW/ OLFw== ARC-Authentication-Results: i=2; mx.google.com; dkim=pass header.i=@amarulasolutions.com header.s=google header.b=O70b+R1k; spf=pass (google.com: domain of jagan@amarulasolutions.com designates 209.85.220.41 as permitted sender) smtp.mailfrom=jagan@amarulasolutions.com DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=amarulasolutions.com; s=google; h=mime-version:from:to:cc:subject:date:message-id:in-reply-to :references:x-original-sender:x-original-authentication-results :content-transfer-encoding:precedence:mailing-list:list-id:list-post :list-help:list-archive:list-unsubscribe; bh=l1gRXUzFN3aHX727OME7XhgN0VEFMJLMUhx+Xs06z0E=; b=Kxhxcp6EQEaYcvDkzPsEZ7C230BW26W26L0vcJK3I6RPvHzkFSoZiiOOpiHMKBcc5P 4lsqYrtr/PFU7AU5qQ4iGvKdoiQIjeWsNzyPx8aSarK7WcDM+vfRl1iNRi/Q2y7+mesW s60gVBSzVyCwf//rTsYeziNwt+N2mfRMouRpo= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:mime-version:from:to:cc:subject:date:message-id :in-reply-to:references:x-original-sender :x-original-authentication-results:content-transfer-encoding :precedence:mailing-list:list-id:x-spam-checked-in-group:list-post :list-help:list-archive:list-unsubscribe; bh=l1gRXUzFN3aHX727OME7XhgN0VEFMJLMUhx+Xs06z0E=; b=Kb2iE3edizI5NWT5AaQF2Q0jeK+70U1Xa6Q99eNr+TSFm9mCNDEKPOniYKbPw2iyAu jBWftbLxdVDEzhmvc6FQazQV/aXgZAKdBr1M6ColHHgcMWCmJ3kFn+fsdK3Gzfi4Afwt vuHBZcbih04CcTQqCr98+t0mks52lcr2itlDAIS1QULIlcLcg2fq7SnV+SoQsQ4U+lKU pKFivsmS5sppWI2aqVr8SjHokffSUwPLvRfrgGylajSYxqbpE0WykTIQvwBqTREC03Zq T15czizpP0WCiaopytj5FUGAUkBdUOzvAG+oeJd3uxVYtQmMip4kjOvQKrkkvl1IwfXu 0X+g== X-Gm-Message-State: AGi0PuYGtFsOyt/gJuOfi919WQ02GNUb+ZEV8at5cqnkNzCzf4IVMzxr mwyDGmd0Kb8qTwQMClH/Jajxbgyn X-Google-Smtp-Source: APiQypLUbLPLE7Ii+MAAnSWdh4kfbBFalt7DHHisp3qsP0HBWob4TxZZl/6+QccF1VjTwlJ1jAh2tg== X-Received: by 2002:a9d:b8f:: with SMTP id 15mr1082790oth.256.1586258176117; Tue, 07 Apr 2020 04:16:16 -0700 (PDT) MIME-Version: 1.0 X-BeenThere: linux-amarula@amarulasolutions.com Received: by 2002:aca:ec0a:: with SMTP id k10ls441061oih.8.gmail; Tue, 07 Apr 2020 04:16:15 -0700 (PDT) X-Received: by 2002:aca:abcd:: with SMTP id u196mr1247559oie.86.1586258175567; Tue, 07 Apr 2020 04:16:15 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1586258175; cv=none; d=google.com; s=arc-20160816; b=jbxWto/N37SlYBgVtV2QdbsV1DrCWqKV7D7ksX++xX1mxdTbuCYWMB5g8m2U5uRmQq boV72hHpQJ1ZEwsMWy95HiaZ2OdvDZ1FKxHyW59EbmXq6sty+ivm2v1MeIalpB1qFGRP 7zqr/kmF4ILs1jdAz6G455U8R3yeSZJYrOAJ+tKfZjIoGaR/I+d9QB3oLuX9p/Py7qDI NO0iK0EF/Nup3RLGAWnqdiyR/DpkIsFiFzKvq+z7SjdS7g2nK8tSwz/DfT1ahDXO7HxP Sp41T8V6ZfmTJonbR1YbJeupkT7YV1Kr5erRMMXwoLNzSOhcNDJqNUULY9FnxzLsy4dz xhBQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=DY4gm/2gckIRThfc01K7LpoTCXd7W3t+Gf9gufa5/Jo=; b=o5UZKnxx+4pJV62VsVSowHOlyH9Np28RmHBlpQL+RrKcrvTR2453QnUgCqy1LddnXV mptvWb7eI73S/h6G4dKjbnJKKCa2i3ti4tP7Yirvg4fgBZj1DMd0nRslY+hQd65jbA/h YaLpmDQWZntGn6B9+Qwd/tQFT1ea7nqgAT5D8m55zqElMrFUgy6eOYaLemqlwvW0QN9d NCMEv7PeUrl+C3cqFEDzO9kzhPDZ7/29VHZPROiHxw1gW1X141xFK1IkNyelKOXIziep +8buNf31JffXlLujCwFrTJTHDm+vrbQ9U7flc1tfARwC9kWv/O3SD6Y4r2qXRNJ9QQm+ zK8Q== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@amarulasolutions.com header.s=google header.b=O70b+R1k; spf=pass (google.com: domain of jagan@amarulasolutions.com designates 209.85.220.41 as permitted sender) smtp.mailfrom=jagan@amarulasolutions.com Received: from mail-sor-f41.google.com (mail-sor-f41.google.com. [209.85.220.41]) by mx.google.com with SMTPS id n65sor2556061oib.107.2020.04.07.04.16.14 for (Google Transport Security); Tue, 07 Apr 2020 04:16:14 -0700 (PDT) Received-SPF: pass (google.com: domain of jagan@amarulasolutions.com designates 209.85.220.41 as permitted sender) client-ip=209.85.220.41; X-Received: by 2002:a17:90a:2a06:: with SMTP id i6mr1915292pjd.99.1586258173594; Tue, 07 Apr 2020 04:16:13 -0700 (PDT) Received: from localhost.localdomain ([2405:201:c809:c7d5:79b0:3a91:34a5:abd7]) by smtp.gmail.com with ESMTPSA id e187sm13788802pfe.50.2020.04.07.04.16.10 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 07 Apr 2020 04:16:12 -0700 (PDT) From: Jagan Teki To: buildroot@buildroot.org Cc: "Yann E . MORIN" , Angelo Compagnucci , Suniel Mahesh , Esben Haabendal , Yegor Yefremov , linux-amarula@amarulasolutions.com, Adam Duskett , Jagan Teki Subject: [PATCH v8 4/5] support/testing: add python-pybind11 test Date: Tue, 7 Apr 2020 16:45:14 +0530 Message-Id: <20200407111515.21131-5-jagan@amarulasolutions.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20200407111515.21131-1-jagan@amarulasolutions.com> References: <20200407111515.21131-1-jagan@amarulasolutions.com> X-Original-Sender: jagan@amarulasolutions.com X-Original-Authentication-Results: mx.google.com; dkim=pass header.i=@amarulasolutions.com header.s=google header.b=O70b+R1k; spf=pass (google.com: domain of jagan@amarulasolutions.com designates 209.85.220.41 as permitted sender) smtp.mailfrom=jagan@amarulasolutions.com Content-Type: text/plain; charset="UTF-8" Precedence: list Mailing-list: list linux-amarula@amarulasolutions.com; contact linux-amarula+owners@amarulasolutions.com List-ID: X-Spam-Checked-In-Group: linux-amarula@amarulasolutions.com X-Google-Group-Id: 476853432473 List-Post: , List-Help: , List-Archive: List-Unsubscribe: , From: Adam Duskett This test is a simple integration test of the python-pybind11 package. It consists of the following: - The python-pybind11-addition-example package compiles a simple cpp file which adds two given numbers together and returns the results and installs the compiled file to /root/ This example is from the following URL: https://pybind11.readthedocs.io/en/stable/basics.html - The python-pybind11-addition-example package installs the sample_python_pybind11.py file which imports the above-compiled file and adds 1 and 2 together to /root/ - Execute the sample_python_pybind11.py in an emulator with the expected output of 3 and an exit code of 0. Signed-off-by: Adam Duskett [jagan: rebase, fix trailing whitespace, new line warninings] Signed-off-by: Jagan Teki --- Changes for v8 - new patch .gitlab-ci.yml | 2 + DEVELOPERS | 2 + .../br2-external/python-pybind11/Config.in | 1 + .../python-pybind11/external.desc | 1 + .../br2-external/python-pybind11/external.mk | 1 + .../Config.in | 5 ++ .../pybind11_addition_example.cpp | 9 +++ .../python-pybind11-addition-example.mk | 39 ++++++++++ .../sample_python_pybind11.py | 4 + .../tests/package/test_python_pybind11.py | 76 +++++++++++++++++++ 10 files changed, 140 insertions(+) create mode 100644 support/testing/tests/package/br2-external/python-pybind11/Config.in create mode 100644 support/testing/tests/package/br2-external/python-pybind11/external.desc create mode 100644 support/testing/tests/package/br2-external/python-pybind11/external.mk create mode 100644 support/testing/tests/package/br2-external/python-pybind11/package/python-pybind11-addition-example/Config.in create mode 100644 support/testing/tests/package/br2-external/python-pybind11/package/python-pybind11-addition-example/pybind11_addition_example.cpp create mode 100644 support/testing/tests/package/br2-external/python-pybind11/package/python-pybind11-addition-example/python-pybind11-addition-example.mk create mode 100644 support/testing/tests/package/br2-external/python-pybind11/package/python-pybind11-addition-example/sample_python_pybind11.py create mode 100644 support/testing/tests/package/test_python_pybind11.py diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index d9519c3812..ce524337cb 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -471,6 +471,8 @@ tests.package.test_python_passlib.TestPythonPy2Passlib: { extends: .runtime_test tests.package.test_python_passlib.TestPythonPy3Passlib: { extends: .runtime_test } tests.package.test_python_pexpect.TestPythonPy2Pexpect: { extends: .runtime_test } tests.package.test_python_pexpect.TestPythonPy3Pexpect: { extends: .runtime_test } +tests.package.test_python_pybind11.TestPythonPy2Pybind11: { extends: .runtime_test } +tests.package.test_python_pybind11.TestPythonPy3Pybind11: { extends: .runtime_test } tests.package.test_python_pynacl.TestPythonPy2Pynacl: { extends: .runtime_test } tests.package.test_python_pynacl.TestPythonPy3Pynacl: { extends: .runtime_test } tests.package.test_python_pyyaml.TestPythonPy2Pyyaml: { extends: .runtime_test } diff --git a/DEVELOPERS b/DEVELOPERS index 308a59b264..f06d54a662 100644 --- a/DEVELOPERS +++ b/DEVELOPERS @@ -85,6 +85,8 @@ F: package/sngrep/ F: package/spidermonkey/ F: package/systemd/ F: support/testing/tests/package/test_python_gobject.py +F: support/testing/tests/package/br2-external/python-pybind11/ +F: support/testing/tests/package/test_python_pybind11.py N: Adam Heinrich F: package/jack1/ diff --git a/support/testing/tests/package/br2-external/python-pybind11/Config.in b/support/testing/tests/package/br2-external/python-pybind11/Config.in new file mode 100644 index 0000000000..27b502313b --- /dev/null +++ b/support/testing/tests/package/br2-external/python-pybind11/Config.in @@ -0,0 +1 @@ +source "$BR2_EXTERNAL_PYTHON_PYBIND11_PATH/package/python-pybind11-addition-example/Config.in" diff --git a/support/testing/tests/package/br2-external/python-pybind11/external.desc b/support/testing/tests/package/br2-external/python-pybind11/external.desc new file mode 100644 index 0000000000..04a636053a --- /dev/null +++ b/support/testing/tests/package/br2-external/python-pybind11/external.desc @@ -0,0 +1 @@ +name: PYTHON_PYBIND11 diff --git a/support/testing/tests/package/br2-external/python-pybind11/external.mk b/support/testing/tests/package/br2-external/python-pybind11/external.mk new file mode 100644 index 0000000000..db34e5f54d --- /dev/null +++ b/support/testing/tests/package/br2-external/python-pybind11/external.mk @@ -0,0 +1 @@ +include $(sort $(wildcard $(BR2_EXTERNAL_PYTHON_PYBIND11_PATH)/package/*/*.mk)) diff --git a/support/testing/tests/package/br2-external/python-pybind11/package/python-pybind11-addition-example/Config.in b/support/testing/tests/package/br2-external/python-pybind11/package/python-pybind11-addition-example/Config.in new file mode 100644 index 0000000000..7860559a13 --- /dev/null +++ b/support/testing/tests/package/br2-external/python-pybind11/package/python-pybind11-addition-example/Config.in @@ -0,0 +1,5 @@ +config BR2_PACKAGE_PYTHON_PYBIND11_ADDITION_EXAMPLE + bool "python-pybind11 addition example" + depends on BR2_PACKAGE_PYTHON_PYBIND11 + help + Simple class for testing python-pybind11 diff --git a/support/testing/tests/package/br2-external/python-pybind11/package/python-pybind11-addition-example/pybind11_addition_example.cpp b/support/testing/tests/package/br2-external/python-pybind11/package/python-pybind11-addition-example/pybind11_addition_example.cpp new file mode 100644 index 0000000000..61b3fce051 --- /dev/null +++ b/support/testing/tests/package/br2-external/python-pybind11/package/python-pybind11-addition-example/pybind11_addition_example.cpp @@ -0,0 +1,9 @@ +#include + +int add(int i, int j) { + return i + j; +} + +PYBIND11_MODULE(pybind11_addition_example, m) { + m.def("add", &add, "A function which adds two numbers"); +} diff --git a/support/testing/tests/package/br2-external/python-pybind11/package/python-pybind11-addition-example/python-pybind11-addition-example.mk b/support/testing/tests/package/br2-external/python-pybind11/package/python-pybind11-addition-example/python-pybind11-addition-example.mk new file mode 100644 index 0000000000..f620424fca --- /dev/null +++ b/support/testing/tests/package/br2-external/python-pybind11/package/python-pybind11-addition-example/python-pybind11-addition-example.mk @@ -0,0 +1,39 @@ +################################################################################ +# +# python-pybind11_addition_example +# +################################################################################ + +PYTHON_PYBIND11_ADDITION_EXAMPLE_DEPENDENCIES = python-pybind11 + +ifeq ($(BR2_PACKAGE_PYTHON),y) +PYTHON_PYBIND11_ADDITION_EXAMPLE_INCLUDES=`$(STAGING_DIR)/usr/bin/python2-config --includes` +PYTHON_PYBIND11_ADDITION_EXAMPLE_SUFFIX=`$(STAGING_DIR)/usr/bin/python2-config --extension-suffix` +else +PYTHON_PYBIND11_ADDITION_EXAMPLE_INCLUDES=`$(STAGING_DIR)/usr/bin/python3-config --includes` +PYTHON_PYBIND11_ADDITION_EXAMPLE_SUFFIX=`$(STAGING_DIR)/usr/bin/python3-config --extension-suffix` +endif +PYTHON_PYBIND11_ADDITION_EXAMPLE_OUTPUT=pybind11_addition_example$(PYTHON_PYBIND11_ADDITION_EXAMPLE_SUFFIX) + +define PYTHON_PYBIND11_ADDITION_EXAMPLE_BUILD_CMDS + $(INSTALL) -D $(PYTHON_PYBIND11_ADDITION_EXAMPLE_PKGDIR)/pybind11_addition_example.cpp \ + $(@D)/pybind11_addition_example.cpp + + $(INSTALL) -D $(PYTHON_PYBIND11_ADDITION_EXAMPLE_PKGDIR)/sample_python_pybind11.py \ + $(@D)/sample_python_pybind11.py + + cd $(@D); \ + $(TARGET_CXX) -std=c++11 -fPIC -shared \ + $(PYTHON_PYBIND11_ADDITION_EXAMPLE_INCLUDES) pybind11_addition_example.cpp \ + -o $(PYTHON_PYBIND11_ADDITION_EXAMPLE_OUTPUT) +endef + +define PYTHON_PYBIND11_ADDITION_EXAMPLE_INSTALL_TARGET_CMDS + $(INSTALL) -D -m 755 $(@D)/$(PYTHON_PYBIND11_ADDITION_EXAMPLE_OUTPUT) \ + $(TARGET_DIR)/root/$(PYTHON_PYBIND11_ADDITION_EXAMPLE_OUTPUT) + + $(INSTALL) -D -m 755 $(@D)/sample_python_pybind11.py \ + $(TARGET_DIR)/root/sample_python_pybind11.py +endef + +$(eval $(generic-package)) diff --git a/support/testing/tests/package/br2-external/python-pybind11/package/python-pybind11-addition-example/sample_python_pybind11.py b/support/testing/tests/package/br2-external/python-pybind11/package/python-pybind11-addition-example/sample_python_pybind11.py new file mode 100644 index 0000000000..29196481e1 --- /dev/null +++ b/support/testing/tests/package/br2-external/python-pybind11/package/python-pybind11-addition-example/sample_python_pybind11.py @@ -0,0 +1,4 @@ +#!/usr/bin/env python +import pybind11_addition_example + +print(pybind11_addition_example.add(1, 2)) diff --git a/support/testing/tests/package/test_python_pybind11.py b/support/testing/tests/package/test_python_pybind11.py new file mode 100644 index 0000000000..12bd77807e --- /dev/null +++ b/support/testing/tests/package/test_python_pybind11.py @@ -0,0 +1,76 @@ +import os +import infra.basetest + +class TestPythonPy2Pybind11(infra.basetest.BRTest): + br2_external = [infra.filepath("tests/package/br2-external/python-pybind11")] + config = \ + """ + BR2_aarch64=y + BR2_TOOLCHAIN_EXTERNAL=y + BR2_TARGET_GENERIC_GETTY_PORT="ttyAMA0" + BR2_LINUX_KERNEL=y + BR2_LINUX_KERNEL_CUSTOM_VERSION=y + BR2_LINUX_KERNEL_CUSTOM_VERSION_VALUE="4.19.86" + BR2_LINUX_KERNEL_USE_CUSTOM_CONFIG=y + BR2_LINUX_KERNEL_CUSTOM_CONFIG_FILE="board/qemu/aarch64-virt/linux.config" + BR2_LINUX_KERNEL_NEEDS_HOST_OPENSSL=y + BR2_TARGET_ROOTFS_CPIO=y + BR2_TARGET_ROOTFS_CPIO_GZIP=y + BR2_PACKAGE_PYTHON=y + BR2_PACKAGE_PYTHON_PYBIND11=y + BR2_PACKAGE_PYTHON_PYBIND11_ADDITION_EXAMPLE=y + """ + + def login(self): + img = os.path.join(self.builddir, "images", "rootfs.cpio.gz") + kern = os.path.join(self.builddir, "images", "Image") + self.emulator.boot(arch="aarch64", + kernel=kern, + kernel_cmdline=["console=ttyAMA0"], + options=["-M", "virt", "-cpu", "cortex-a57", "-m", "512M", "-initrd", img]) + self.emulator.login() + + def test_run(self): + self.login() + cmd = "python sample_python_pybind11.py" + output, exit_code = self.emulator.run(cmd, 120) + print(output) + self.assertEqual(exit_code, 0) + self.assertEqual(output, ["3"]) + +class TestPythonPy3Pybind11(infra.basetest.BRTest): + br2_external = [infra.filepath("tests/package/br2-external/python-pybind11")] + config = \ + """ + BR2_aarch64=y + BR2_TOOLCHAIN_EXTERNAL=y + BR2_TARGET_GENERIC_GETTY_PORT="ttyAMA0" + BR2_LINUX_KERNEL=y + BR2_LINUX_KERNEL_CUSTOM_VERSION=y + BR2_LINUX_KERNEL_CUSTOM_VERSION_VALUE="4.19.86" + BR2_LINUX_KERNEL_USE_CUSTOM_CONFIG=y + BR2_LINUX_KERNEL_CUSTOM_CONFIG_FILE="board/qemu/aarch64-virt/linux.config" + BR2_LINUX_KERNEL_NEEDS_HOST_OPENSSL=y + BR2_TARGET_ROOTFS_CPIO=y + BR2_TARGET_ROOTFS_CPIO_GZIP=y + BR2_PACKAGE_PYTHON3=y + BR2_PACKAGE_PYTHON_PYBIND11=y + BR2_PACKAGE_PYTHON_PYBIND11_ADDITION_EXAMPLE=y + """ + + def login(self): + img = os.path.join(self.builddir, "images", "rootfs.cpio.gz") + kern = os.path.join(self.builddir, "images", "Image") + self.emulator.boot(arch="aarch64", + kernel=kern, + kernel_cmdline=["console=ttyAMA0"], + options=["-M", "virt", "-cpu", "cortex-a57", "-m", "512M", "-initrd", img]) + self.emulator.login() + + def test_run(self): + self.login() + cmd = "python3 sample_python_pybind11.py" + output, exit_code = self.emulator.run(cmd, 120) + print(output) + self.assertEqual(exit_code, 0) + self.assertEqual(output, ["3"])