多平台测试

Sage打算在各种平台上构建和运行,包括所有主要的Linux发行版,以及MacOS和Windows(使用Cygwin)。

这些平台之间存在相当大的差异。为了确保Sage继续在用户的机器上正确地构建,测试Sage的更改是至关重要的,尤其是在广泛的平台上添加或升级外部包时。

Sage补丁

这个 Sage patchbots 将通过尝试增量生成Sage并运行doctest来自动测试您的Trac票证。

Sage构建机器人

这个 Sage Release buildbot 在各种机器上构建整个tarball(例如,所有的开发版本)。

开发人员和用户对sage版本的测试

我们鼓励Sage开发人员和用户参与测试发布于 Sage Release 并通过响应公告来报告测试结果(成功和失败)。

使用Docker在不同平台上测试Sage

Docker 是一个流行的虚拟化软件,在共享Linux内核的容器中运行Linux操作系统映像(“Docker映像”)。这些容器可以使用Docker客户机在Linux、Mac或Windows box上运行,也可以在各种云服务上运行。

要开始,您需要安装 Docker client . 客户机可用于Linux、Mac和Windows。后者的客户端被称为“Docker桌面”。

本节中的所有示例都是使用Docker Desktop for Mac获得的;但是 command-line user interface 对于其他平台是相同的。

所有主要的Linux发行版都提供现成的Docker映像,这些映像通过 Docker Hub . 例如,要以交互方式运行Ubuntu的当前稳定(LTS)版本,可以使用shell命令:

[mkoeppe@sage sage]$ docker run -it ubuntu:latest
root@9f3398da43c2:/#

在这里 ubuntu 称为“图像(名称)”和 latest 作为“标签”。其他版本的Ubuntu可以在不同的标签下使用,比如 xenialdevel .

上面的命令将您放入容器的根shell::

root@9f3398da43c2:/# uname -a
Linux 9f3398da43c2 4.19.76-linuxkit #1 SMP Thu Oct 17 19:31:58 UTC 2019 x86_64 x86_64 x86_64 GNU/Linux
root@9f3398da43c2:/# df -h
Filesystem      Size  Used Avail Use% Mounted on
overlay         181G  116G   56G  68% /
tmpfs            64M     0   64M   0% /dev
tmpfs           2.7G     0  2.7G   0% /sys/fs/cgroup
shm              64M     0   64M   0% /dev/shm
/dev/sda1       181G  116G   56G  68% /etc/hosts
tmpfs           2.7G     0  2.7G   0% /proc/acpi
tmpfs           2.7G     0  2.7G   0% /sys/firmware

退出shell将终止容器:

root@9f3398da43c2:/# ^D
[mkoeppe@sage sage]$

让我们使用一个distclean Sage源树。如果您正在使用git,这是一个很好的方法来获得git(而不会丢失宝贵的安装) SAGE_LOCAL )通过创建新的工作树:

[mkoeppe@sage sage] git worktree add worktree-ubuntu-latest
[mkoeppe@sage sage] cd worktree-ubuntu-latest
[mkoeppe@sage worktree-ubuntu-latest] ls
COPYING.txt ... Makefile ... configure.ac ... src tox.ini

这不是自举的 (configure ,所以让我们引导它:

[mkoeppe@sage worktree-ubuntu-latest] make configure
...

我们可以用同样的图像重新启动容器, ubuntu:latest ,但这次让我们将当前目录装载到其中:

[mkoeppe@sage worktree-ubuntu-latest]$ docker run -it --mount type=bind,source=$(pwd),target=/sage ubuntu:latest
root@39d693b2a75d:/# mount | grep sage
osxfs on /sage type fuse.osxfs (rw,nosuid,nodev,relatime,user_id=0,group_id=0,allow_other,max_read=1048576)
root@39d693b2a75d:/# cd sage
root@39d693b2a75d:/sage# ls
COPYING.txt ... Makefile ... config configure configure.ac ... src tox.ini

典型的Docker映像只提供最少的软件包安装:

root@39d693b2a75d:/sage# command -v python
root@39d693b2a75d:/sage# command -v gcc
root@39d693b2a75d:/sage#

如上图所示 ubuntu:latest 既没有安装Python也没有安装GCC,这是Sage构建的先决条件。我们需要先使用发行版的包管理器安装它们。

Sage有助于在Docker上测试各种发行版,如下所示。

发现系统的包系统

root@39d693b2a75d:/sage# build/bin/sage-guess-package-system
debian

让我们安装gcc,希望提供gcc的Ubuntu包仅仅命名为 gcc . 如果我们忘记了Debian派生发行版上的包管理器的名称,我们可以向Sage请求提醒:

root@39d693b2a75d:/sage# build/bin/sage-print-system-package-command debian install gcc
sudo apt-get install gcc

我们已经是根,所以我们可以放弃 sudo 当然。我们还记得,我们需要先从服务器获取当前的包列表:

root@39d693b2a75d:/sage# apt-get update
root@39d693b2a75d:/sage# apt-get install gcc

使用Sage发布先决条件数据库

Sage发行版的源代码包含各种发行版的包管理器中的包名数据库。例如,文件 build/pkgs/debian.txt 包含以下内容

# This file, build/pkgs/debian.txt, contains names of Debian/Ubuntu packages
# needed for installation of Sage from source.
#
# In addition, the files build/pkgs/SPKG/debian.txt contain the names
# of packages that provide the equivalent of SPKG.
#
# Everything on a line after a # character is ignored.
binutils
make
m4
perl
# python3-minimal is not enough on debian buster, ubuntu bionic - it does not have urllib
python3    # system python for bootstrapping the build
tar
bc
gcc
# On debian buster, need C++ even to survive 'configure'. Otherwise:
# checking how to run the C++ preprocessor... /lib/cpp
# configure: error: in `/sage':
# configure: error: C++ preprocessor "/lib/cpp" fails sanity check
g++
# Needed if we download some packages from a https upstream URL
ca-certificates

从这些信息中,我们知道可以在容器上使用以下命令来安装必要的生成先决条件:

root@39d693b2a75d:/sage# apt-get install binutils make m4 perl python3 tar bc gcc g++ ca-certificates
Reading package lists... Done
Building dependency tree
Reading state information... Done
tar is already the newest version (1.29b-2ubuntu0.1).
The following additional packages will be installed:
...
Done.

(Sage Installation Guide 还为某些发行版提供了这样的命令行;这些命令行是从包名数据库自动生成的。)

现在我们可以开始构建了:

root@39d693b2a75d:/sage# ./configure
checking for a BSD-compatible install... /usr/bin/install -c
checking for root user... yes
configure: error: You cannot build Sage as root, switch to an unprivileged user.  (If building in a container, use --enable-build-as-root.)

让我们遵循这个有用的提示:

root@39d693b2a75d:/sage# ./configure --enable-build-as-root
checking for a BSD-compatible install... /usr/bin/install -c
...

使用Sage的等效分发包数据库

./configure 跑吧,萨奇发了一条信息如下:

configure: notice: the following SPKGs did not find equivalent system packages: arb boost boost_cropped bzip2 ... yasm zeromq zlib
checking for the package system in use... debian
configure: hint: installing the following system packages is recommended and may avoid building some of the above SPKGs from source:
configure:   $ sudo apt-get install libflint-arb-dev ... yasm libzmq3-dev libz-dev
configure: After installation, re-run configure using:
configure:   $ ./config.status --recheck && ./config.status

这些信息来自Sage的等效分发包数据库。例如::

root@39d693b2a75d:/sage# ls build/pkgs/arb/distros/
arch.txt      conda.txt       debian.txt      gentoo.txt
root@39d693b2a75d:/sage# cat build/pkgs/arb/distros/debian.txt
libflint-arb-dev

请注意,这些包的等价性是基于当前稳定的或测试版本的发行版的;这些包不一定存在于每个发行版或衍生发行版中。

Sage发行版的目的是正确构建,无论系统上安装了构成最小构建先决条件的包集合的超集。如果没有,这就是Sage分发的错误,应该报告并在罚单上修复。错误报告的关键部分是系统的配置,特别是已安装软件包及其版本的列表。

让我们安装这些包的一个子集:

root@39d693b2a75d:/sage# apt-get install libbz2-dev bzip2 yasm libz-dev
Reading package lists... Done
...
Setting up zlib1g-dev:amd64 (1:1.2.11.dfsg-0ubuntu2) ...
root@39d693b2a75d:/sage#

将容器提交到磁盘

终止容器后,我们可以创建一个与其当前状态相对应的新映像:

root@39d693b2a75d:/sage# ^D
[mkoeppe@sage worktree-ubuntu-latest]$ docker ps -a | head -n3
CONTAINER ID        IMAGE                   COMMAND                   CREATED             STATUS
39d693b2a75d        ubuntu:latest           "/bin/bash"               8 minutes ago       Exited (0) 6 seconds ago
9f3398da43c2        ubuntu:latest           "/bin/bash"               8 minutes ago       Exited (0) 8 minutes ago
[mkoeppe@sage worktree-ubuntu-latest]$ docker commit 39d693b2a75d ubuntu-latest-minimal-17
sha256:4151c5ca4476660f6181cdb13923da8fe44082222b984c377fb4fd6cc05415c1

在这里, 39d693b2a75d 是容器id(它出现在shell提示和 docker psubuntu-latest-minimal-17 是新图像的任意符号名称。命令的输出是新图像的id。我们可以使用符号名或id来表示新图像。

我们可以运行映像并获得一个与终止的容器状态相同的新容器。我们再次希望将我们的工作树装入其中;否则,因为我们没有制作副本,新容器将无法访问工作树::

[mkoeppe@sage worktree-ubuntu-latest]$ docker run -it \
  --mount type=bind,source=$(pwd),target=/sage ubuntu-latest-minimal-17
root@73987568712c:/# cd sage
root@73987568712c:/sage# command -v gcc
/usr/bin/gcc
root@73987568712c:/sage# command -v yasm
/usr/bin/yasm
root@73987568712c:/sage# ^D
[mkoeppe@sage worktree-ubuntu-latest]$

形象 ubuntu-latest-minimal-17 可以在任意多个容器中运行,也可以与其他用户或开发人员共享,以便他们可以在其计算机上的容器中运行它。(参见Docker文档中关于如何 share images on Docker Hubsave images to a tar archive

这有助于协作修复Sage发行版的可移植性缺陷。在容器上复制了一个可移植性错误之后,几个开发人员可以使用运行在各自机器上的容器来修复该缺陷。

生成Dockerfiles

Sage还提供了一个脚本来生成 Dockerfile ,这是自动构建新映像的方法:

[mkoeppe@sage sage]$ build/bin/write-dockerfile.sh debian "@(standard|optional)" > Dockerfile

(第二个参数是包类型的bash extglob模式。)

这个 Dockerfile 指示命令 docker build 创建新的Docker映像。让我们快速查看一下生成的文件;这稍微简化了一下:

[mkoeppe@sage sage]$ cat Dockerfile
# Automatically generated by SAGE_ROOT/build/bin/write-dockerfile.sh
# the :comments: separate the generated file into sections
# to simplify writing scripts that customize this file
...

首先,指示它 docker build 从现有的基础映像开始…:

...
ARG BASE_IMAGE=ubuntu:latest
FROM ${BASE_IMAGE}
...

然后,要安装系统包…:

...
RUN apt-get update && DEBIAN_FRONTEND=noninteractive apt-get install -qqq --no-install-recommends --yes binutils make m4 perl python3 ... yasm libzmq3-dev libz-dev && apt-get clean

然后,引导并配置…:

RUN mkdir -p /sage
WORKDIR /sage
ADD Makefile VERSION.txt README.md bootstrap configure.ac sage ./
ADD src/doc/bootstrap src/doc/bootstrap
ADD m4 ./m4
ADD build ./build
ADD src/bin/sage-version.sh src/bin/sage-version.sh
RUN ./bootstrap
ADD src/bin src/bin
ADD src/Makefile.in src/Makefile.in
ARG EXTRA_CONFIGURE_ARGS=""
RUN ./configure --enable-build-as-root ${EXTRA_CONFIGURE_ARGS} || (cat config.log; exit 1)

最后,构建和测试…:

ARG NUMPROC=8
ENV MAKE="make -j${NUMPROC}"
ARG USE_MAKEFLAGS="-k"
RUN make ${USE_MAKEFLAGS} base-toolchain
ARG TARGETS_PRE="sagelib-build-deps"
RUN make ${USE_MAKEFLAGS} ${TARGETS_PRE}
ADD src src
ARG TARGETS="build ptest"
RUN make ${USE_MAKEFLAGS} ${TARGETS}

通过向命令传递生成参数,可以自定义映像生成过程 docker build . 例如::

[mkoeppe@sage sage]$ docker build . -f Dockerfile \
  --build-arg BASE_IMAGE=ubuntu:latest \
  --build-arg NUMPROC=4 \
  --build-arg EXTRA_CONFIGURE_ARGS="--with-python=2"

这些参数(及其默认值)是使用 ARG 中的命令 Dockerfile .

上面的命令将从头开始构建Sage,因此需要相当长的时间。相反,让我们通过设置参数来完成一个由一个小包组成的部分构建 TARGETS_PRETARGETS . 我们使用静默构建 (make V=0 ):

[mkoeppe@sage sage]$ docker build . -f Dockerfile \
  --build-arg TARGETS_PRE=ratpoints \
  --build-arg TARGETS=ratpoints \
  --build-arg USE_MAKEFLAGS="V=0"
Sending build context to Docker daemon    285MB
Step 1/28 : ARG BASE_IMAGE=ubuntu:latest
...
Step 2/28 : FROM ${BASE_IMAGE}
 ---> 549b9b86cb8d
...
Step 25/28 : RUN make SAGE_SPKG="sage-spkg -y -o" ${USE_MAKEFLAGS} ${TARGETS_PRE}
...
make[1]: Entering directory '/sage/build/make'
sage-logger -p 'sage-spkg -y -o  ratpoints-2.1.3.p5' '/sage/logs/pkgs/ratpoints-2.1.3.p5.log'
[ratpoints-2.1.3.p5] installing. Log file: /sage/logs/pkgs/ratpoints-2.1.3.p5.log
  [ratpoints-2.1.3.p5] successfully installed.
make[1]: Leaving directory '/sage/build/make'

real  0m18.886s
user  0m1.779s
sys   0m0.314s
Sage build/upgrade complete!
...
---> 2d06689d39fa
Successfully built 2d06689d39fa

我们现在可以使用最后一步中显示的图像id启动容器:

[mkoeppe@sage sage]$ docker run -it 2d06689d39fa bash
root@fab59e09a641:/sage# ls -l logs/pkgs/
total 236
-rw-r--r-- 1 root root 231169 Mar 26 22:07 config.log
-rw-r--r-- 1 root root   6025 Mar 26 22:27 ratpoints-2.1.3.p5.log
root@fab59e09a641:/sage# ls -l local/lib/*rat*
-rw-r--r-- 1 root root 177256 Mar 26 22:27 local/lib/libratpoints.a

您可以通过编辑进一步自定义图像 Dockerfile . 例如,默认情况下,生成 Dockerfile 配置、构建和测试Sage。通过删除或注释掉后者的命令,可以将Dockerfile调整为在 configure 例如,阶段。

Dockerfile Dockerfiles的默认文件名。您可以将其更改为任何其他名称,但建议使用 Dockerfile 作为前缀,例如 Dockerfile-debian-standard . 它应该放在当前目录的根目录树中 (. );如果你想把它放在其他地方,你需要了解“Docker build contexts”的细节。

Note that in contrast to the workflow described in the above sections, the Dockerfile copies a snapshot of your Sage worktree into the build container, using ADD commands, instead of mounting the directory into it. This copying is subject to the exclusions in the .gitignore file (via a symbolic link from .dockerignore). Therefore, only the sources are copied, but not your configuration (such as the file config.status), nor the $SAGE_LOCAL tree, nor any other build artefacts.

因此,您可以使用生成的 Dockerfile 从你的主要Sage发展树。它不必是distclean才能启动,而且构建根本不会写入其中。因此,即使Docker构建正在运行,您也可以继续编辑和编译Sage开发树。

使用Docker调试可移植性错误

让我们做另一个部分构建。我们选择了一个我们怀疑可能不适用于所有平台的软件包, surf ,2017年被评为“实验性”:

[mkoeppe@sage sage]$ docker build . -f Dockerfile \
  --build-arg BASE_IMAGE=ubuntu:latest \
  --build-arg NUMPROC=4 \
  --build-arg TARGETS_PRE=surf \
  --build-arg TARGETS=surf
Sending build context to Docker daemon    285MB
Step 1/28 : ARG BASE_IMAGE=ubuntu:latest
Step 2/28 : FROM ${BASE_IMAGE}
 ---> 549b9b86cb8d
...
Step 24/28 : ARG TARGETS_PRE="sagelib-build-deps"
 ---> Running in 17d0ddb5ad7b
Removing intermediate container 17d0ddb5ad7b
 ---> 7b51411520c3
Step 25/28 : RUN make SAGE_SPKG="sage-spkg -y -o" ${USE_MAKEFLAGS} ${TARGETS_PRE}
 ---> Running in 61833bea6a6d
make -j4 build/make/Makefile --stop
...
[surf-1.0.6-gcc6] Attempting to download package surf-1.0.6-gcc6.tar.gz from mirrors
...
[surf-1.0.6-gcc6] http://mirrors.mit.edu/sage/spkg/upstream/surf/surf-1.0.6-gcc6.tar.gz
...
[surf-1.0.6-gcc6] Setting up build directory for surf-1.0.6-gcc6
...
[surf-1.0.6-gcc6] /usr/bin/ld: cannot find -lfl
[surf-1.0.6-gcc6] collect2: error: ld returned 1 exit status
[surf-1.0.6-gcc6] Makefile:504: recipe for target 'surf' failed
[surf-1.0.6-gcc6] make[3]: *** [surf] Error 1
...
[surf-1.0.6-gcc6] Error installing package surf-1.0.6-gcc6
...
Makefile:2088: recipe for target '/sage/local/var/lib/sage/installed/surf-1.0.6-gcc6' failed
make[1]: *** [/sage/local/var/lib/sage/installed/surf-1.0.6-gcc6] Error 1
make[1]: Target 'surf' not remade because of errors.
make[1]: Leaving directory '/sage/build/make'
...
Error building Sage.

The following package(s) may have failed to build (not necessarily
during this run of 'make surf'):

* package:         surf-1.0.6-gcc6
  last build time: Mar 26 22:07
  log file:        /sage/logs/pkgs/surf-1.0.6-gcc6.log
  build directory: /sage/local/var/tmp/sage/build/surf-1.0.6-gcc6

...
Makefile:31: recipe for target 'surf' failed
make: *** [surf] Error 1
The command '/bin/sh -c make SAGE_SPKG="sage-spkg -y -o" ${USE_MAKEFLAGS} ${TARGETS_PRE}' returned a non-zero code: 2

注意,最后没有显示图像id;构建失败,也没有创建图像。但是,尝试生成的最后一步所在的容器存在:

[mkoeppe@sage sage]$ docker ps -a |head -n3
CONTAINER ID        IMAGE                      COMMAND                   CREATED             STATUS
61833bea6a6d        7b51411520c3               "/bin/sh -c 'make SA…"    9 minutes ago       Exited (2) 1 minute ago
73987568712c        ubuntu-latest-minimal-17   "/bin/bash"               24 hours ago        Exited (0) 23 hours ago

我们可以从目录中复制:

[mkoeppe@sage sage]$ docker cp 61833bea6a6d:/sage/local/var/tmp/sage/build ubuntu-build
[mkoeppe@sage sage]$ ls ubuntu-build/surf*/src
AUTHORS         TODO            curve           misc
COPYING         acinclude.m4    debug           missing
ChangeLog       aclocal.m4      dither          mkinstalldirs
INSTALL         background.pic  docs            mt
Makefile        config.guess    draw            src
Makefile.am     config.log      drawfunc        surf.1
Makefile.global config.status   examples        surf.xpm
Makefile.in     config.sub      gtkgui          yaccsrc
NEWS            configure       image-formats
README          configure.in    install-sh

或者,我们可以使用 docker commit 如前所述,从容器创建图像:

[mkoeppe@sage sage]$ docker commit 61833bea6a6d
sha256:003fbd511016fe305bd8494bb1747f0fbf4cb2c788b4e755e9099d9f2014a60d
[mkoeppe@sage sage]$ docker run -it 003fbd511 bash
root@2d9ac65f4572:/sage# (cd /sage/local/var/tmp/sage/build/surf* && /sage/sage --buildsh)

Starting subshell with Sage environment variables set.  Don't forget
to exit when you are done.
...
Note: SAGE_ROOT=/sage
(sage-buildsh) root@2d9ac65f4572:surf-1.0.6-gcc6$ ls /usr/lib/libfl*
/usr/lib/libflint-2.5.2.so  /usr/lib/libflint-2.5.2.so.13.5.2  /usr/lib/libflint.a  /usr/lib/libflint.so
(sage-buildsh) root@2d9ac65f4572:surf-1.0.6-gcc6$ apt-get update && apt-get install apt-file
(sage-buildsh) root@2d9ac65f4572:surf-1.0.6-gcc6$ apt-file update
(sage-buildsh) root@2d9ac65f4572:surf-1.0.6-gcc6$ apt-file search "/usr/lib/libfl.a"
flex-old: /usr/lib/libfl.a
freebsd-buildutils: /usr/lib/libfl.a
(sage-buildsh) root@2d9ac65f4572:surf-1.0.6-gcc6$ apt-get install flex-old
(sage-buildsh) root@2d9ac65f4572:surf-1.0.6-gcc6$ ./spkg-install
checking for a BSD-compatible install... /usr/bin/install -c
checking whether build environment is sane... yes
...
  /usr/bin/install -c  surf /sage/local/bin/surf
 /usr/bin/install -c -m 644 ./surf.1 /sage/local/share/man/man1/surf.1
...
make[1]: Leaving directory '/sage/local/var/tmp/sage/build/surf-1.0.6-gcc6/src'
(sage-buildsh) root@2d9ac65f4572:surf-1.0.6-gcc6$ exit
root@2d9ac65f4572:/sage# exit
[mkoeppe@sage sage]$

一个标准的比特洛特病例。

基于tox的基于Docker的自动构建测试

tox 是一个Python包,广泛用于自动测试Python项目。

安装 tox 用于系统Python,例如使用:

[mkoeppe@sage sage]$ pip install --user tox

毒物“环境”是由一个由几个 Tox "factors" ,在文件中定义 $SAGE_ROOT/tox.ini .

这个 技术 factor描述环境的运行方式:

  • docker 按上述方法构建Docker映像。

  • local 而是在主机操作系统上运行测试。我们将在后面的章节中解释这项技术。

下面两个因素决定主机系统配置: 系统因素 描述基本操作系统映像。

  • 例如 ubuntu-focaldebian-busterarchlinux-latestfedora-30slackware-14.2centos-7-i386ubuntu-bionic-arm64 .

  • $SAGE_ROOT/tox.ini 完整的列表,以及它们对应的Docker hub上的图像。

这个 包装系数 描述在生成Sage之前要在系统上安装的系统包的列表:

  • minimal 安装Sage已知的系统包,以便为引导和构建Sage发行版提供最少的先决条件。

  • standard 另外,安装与Sage发行版的标准包等效的所有已知系统包,该机制 spkg-configure.m4 实现。这与类型模式相对应 @(standard) .

  • maximal 对所有标准和可选软件包都是一样的。这与类型模式相对应 @(standard|optional) .

这些因子通过连字符连接,以命名系统配置,例如 debian-buster-standardcentos-7-i386-minimal .

最后, 配置 因子(允许为空)控制 configure 脚本已运行。

  • python2 添加参数 --with-python=2configure 跑。

这些因子通过连字符连接起来,以命名毒性环境。(因子的顺序无关紧要;但是,为了保持一致性,并且由于排序的名称用于缓存目的,我们建议按列出的顺序使用因子。)

运行环境:

[mkoeppe@sage sage]$ tox -e docker-slackware-14.2-minimal
[mkoeppe@sage sage]$ tox -e docker-ubuntu-bionic-standard-python2

任意附加参数 docker build 可以通过环境变量提供 EXTRA_DOCKER_BUILD_ARGS . 例如,对于非静默生成 (make V=1 ),用途:

[mkoeppe@sage sage]$ EXTRA_DOCKER_BUILD_ARGS="--build-arg USE_MAKEFLAGS=\"V=1\"" \
  tox -e docker-ubuntu-bionic-standard

默认情况下,tox使用 TARGETS_PRE=sagelib-build-depsTARGETS=build ,导致没有文档的Sage的完整构建。如果将位置参数传递给tox(与tox选项分开 -- ),然后两者都有 TARGETS_PRETARGETS 设置为这些参数。通过这种方式,您可以构建一些特定的包,而不是全部Sage,例如:

[mkoeppe@sage sage]$ tox -e docker-centos-8-standard -- ratpoints

如果构建成功,这将创建一个名为 sage-docker-centos-8-standard-with-targets:9.1.beta9-431-gca4b5b2f33-dirty 在哪里

  • 映像名来自tox环境名和后缀 with-targets 表示 make 给出的目标 TARGETS 已经建成;

  • 标记名描述源树的git修订版,如 git describe --dirty .

您也可以要求tox创建命名的中间图像。例如,在安装完所有系统包后,创建与操作系统状态相对应的映像 (with-system-packages )和刚刚运行完 configure 脚本 (configured ):

[mkoeppe@sage sage]$ DOCKER_TARGETS="with-system-packages configured with-targets" \
  tox -e docker-centos-8-standard -- ratpoints
...
Sending build context to Docker daemon ...
Step 1/109 : ARG BASE_IMAGE=fedora:latest
Step 2/109 : FROM ${BASE_IMAGE} as with-system-packages
...
Step 109/109 : RUN yum install -y zlib-devel || echo "(ignoring error)"
...
Successfully built 4bb14c3d5646
Successfully tagged sage-docker-centos-8-standard-with-system-packages:9.1.beta9-435-g861ba33bbc-dirty
Sending build context to Docker daemon ...
...
Successfully tagged sage-docker-centos-8-standard-configured:9.1.beta9-435-g861ba33bbc-dirty
...
Sending build context to Docker daemon ...
...
Successfully tagged sage-docker-centos-8-standard-with-targets:9.1.beta9-435-g861ba33bbc-dirty

让我们验证图像是否可用:

(base) egret:~/s/sage/sage-rebasing/worktree-algebraic-2018-spring (mkoeppe *$%>)$ docker images | head
REPOSITORY                                                TAG                               IMAGE ID
sage-docker-centos-8-standard-with-targets                9.1.beta9-435-g861ba33bbc-dirty   7ecfa86fceab
sage-docker-centos-8-standard-configured                  9.1.beta9-435-g861ba33bbc-dirty   4314929e2b4c
sage-docker-centos-8-standard-with-system-packages        9.1.beta9-435-g861ba33bbc-dirty   4bb14c3d5646
...

使用tox-e local direct在主机操作系统上进行自动构建测试

这个 local 技术在主机操作系统上运行测试。

docker 技术,它不会复制源树。从单独的distclean git工作树运行它是最简单的。

让我们试试 local 技术,毒物环境 local-direct . 因为所有使用tox的构建都是从引导源树开始的,所以您需要在系统中安装自动工具和其他先决条件。看到了吗 build/pkgs/*-bootstrap.txt 提供这些先决条件的系统包的列表。

我们首先创建一个新的(distclean)git工作树。

[mkoeppe@SageSage] git worktree本地添加worktree [mkoeppe@SageSage] 本地cd工作树 [mkoeppe@sage worktree-local] ls公司复制.txt... 生成文件。。。配置.ac... src公司毒性试验

同样,我们只构建了一个小的包。构建目标可以作为位置参数传递(与tox选项分开 -- ):

[mkoeppe@sage worktree-local] tox -e local-direct -- ratpoints
local-direct create: /Users/mkoeppe/.../worktree-local/.tox/local-direct
local-direct run-test-pre: PYTHONHASHSEED='2211987514'
...
src/doc/bootstrap:48: installing src/doc/en/installation/debian.txt...
bootstrap:69: installing 'config/config.rpath'
configure.ac:328: installing 'config/compile'
configure.ac:113: installing 'config/config.guess'
...
checking for a BSD-compatible install... /usr/bin/install -c
checking whether build environment is sane... yes
...
sage-logger -p 'sage-spkg -y -o  ratpoints-2.1.3.p5' '.../worktree-local/logs/pkgs/ratpoints-2.1.3.p5.log'
[ratpoints-2.1.3.p5] installing. Log file: .../worktree-local/logs/pkgs/ratpoints-2.1.3.p5.log
  [ratpoints-2.1.3.p5] successfully installed.
...
  local-direct: commands succeeded
  congratulations :)

让我们调查一下这里发生的事情:

[mkoeppe@sage worktree-local]$ ls -la
total 2576
drwxr-xr-x  35 mkoeppe  staff    1120 Mar 26 22:20 .
drwxr-xr-x  63 mkoeppe  staff    2016 Mar 27 09:35 ..
...
lrwxr-xr-x   1 mkoeppe  staff      10 Mar 26 20:34 .dockerignore -> .gitignore
-rw-r--r--   1 mkoeppe  staff      74 Mar 26 20:34 .git
...
-rw-r--r--   1 mkoeppe  staff    1212 Mar 26 20:41 .gitignore
...
drwxr-xr-x   7 mkoeppe  staff     224 Mar 26 22:11 .tox
...
-rw-r--r--   1 mkoeppe  staff    7542 Mar 26 20:41 Makefile
...
lrwxr-xr-x   1 mkoeppe  staff     114 Mar 26 20:45 config.log -> .tox/local-direct/log/config.log
-rwxr-xr-x   1 mkoeppe  staff   90411 Mar 26 20:46 config.status
-rwxr-xr-x   1 mkoeppe  staff  887180 Mar 26 20:45 configure
-rw-r--r--   1 mkoeppe  staff   17070 Mar 26 20:41 configure.ac
...
lrwxr-xr-x   1 mkoeppe  staff     103 Mar 26 20:45 logs -> .tox/local-direct/log
drwxr-xr-x  24 mkoeppe  staff     768 Mar 26 20:45 m4
lrwxr-xr-x   1 mkoeppe  staff     105 Mar 26 20:45 prefix -> .tox/local-direct/local
-rwxr-xr-x   1 mkoeppe  staff    4868 Mar 26 20:34 sage
drwxr-xr-x  16 mkoeppe  staff     512 Mar 26 20:46 src
-rw-r--r--   1 mkoeppe  staff   13478 Mar 26 20:41 tox.ini
drwxr-xr-x   4 mkoeppe  staff     128 Mar 26 20:46 upstream

没有 local 子目录。这是尽可能保持源树干净的策略的一部分。特别地:

  • tox 已将生成配置为使用单独的 $SAGE_LOCAL tox环境目录下目录中的层次结构 .tox/local-direct . 它创建了一个符号链接 prefix 为了方便起见,这里有几点:

    [mkoeppe@sage worktree-local]$ ls -l prefix/lib/*rat*
    -rw-r--r--  1 mkoeppe  staff  165968 Mar 26 20:46 prefix/lib/libratpoints.a
    
  • 同样,它创造了一个独立的 logs 目录,同样在tox环境目录下,还有一个符号链接。

这使得高级用户可以测试 local 毒物环境(如 local-directlocal-direct-python2 )在一棵树上。但是,因为构建仍然编写配置脚本和构建构件(例如 config.status )进入工作树,只有一个 local 生成一次可以在给定的工作树中运行。

tox环境目录将在下一个 tox 运行,这将执行增量构建。要开始新构建,可以使用 -r 选择权。

使用tox-e local在主机操作系统上进行自动构建测试,并尽最大努力进行隔离

tox -e local (没有) -direct )尝试从用户环境中尽最大努力隔离,如下所示:

  • 所有环境变量都设置为标准值;除了 MAKEEXTRA_CONFIGURE_ARGS . 特别地, PATH 设置为 /usr/bin:/bin:/usr/sbin:/sbin ;不包括 /usr/local/bin .

但是请注意,不同的包都有使用 /usr/local 或其他流行的文件系统位置,如 /opt/sfw/ . 因此,隔离并不完全。使用 /usr/local 被认为是标准行为。另一方面,我们认为检查其他文件系统位置的包构建脚本是Sage发行版的一个bug,应该在记录单上报告并修复它。

在macOS上进行自动构建测试,尽最大努力独立安装自制程序

macOS上的XCode不提供引导Sage发行版的先决条件。安装它们的一个好方法是使用自制软件包管理器。

实际上,Sage提供了一个tox环境,它可以自动安装一个独立的自制程序副本,并具有引导的所有先决条件:

[mkoeppe@sage worktree-local]$ tox -e local-homebrew-macos-minimal -- lrslib
local-homebrew-macos-minimal create: .../worktree-local/.tox/local-homebrew-macos-minimal
local-homebrew-macos-minimal run-test-pre: PYTHONHASHSEED='4246149402'
...
Initialized empty Git repository in .../worktree-local/.tox/local-homebrew-macos-minimal/homebrew/.git/
...
Tapped 2 commands and 4942 formulae (5,205 files, 310.7MB).
==> Downloading https://ftp.gnu.org/gnu/gettext/gettext-0.20.1.tar.xz
...
==> Pouring autoconf-2.69.catalina.bottle.4.tar.gz
...
==> Pouring pkg-config-0.29.2.catalina.bottle.1.tar.gz
  .../worktree-local/.tox/local-homebrew-macos-minimal/homebrew/Cellar/pkg-config/0.29.2: 11 files, 623.4KB
==> Caveats
==> gettext
gettext is keg-only, which means it was not symlinked into .../worktree-local/.tox/local-homebrew-macos-minimal/homebrew,
because macOS provides the BSD gettext library & some software gets confused if both are in the library path.

If you need to have gettext first in your PATH run:
  echo 'export PATH=".../worktree-local/.tox/local-homebrew-macos-minimal/homebrew/opt/gettext/bin:$PATH"' >> ~/.bash_profile

For compilers to find gettext you may need to set:
  export LDFLAGS="-L.../worktree-local/.tox/local-homebrew-macos-minimal/homebrew/opt/gettext/lib"
  export CPPFLAGS="-I.../worktree-local/.tox/local-homebrew-macos-minimal/homebrew/opt/gettext/include"
...
local-homebrew-macos-minimal run-test: commands[0] | bash -c 'export PATH=.../worktree-local/.tox/local-homebrew-macos-minimal/homebrew/bin:/usr/bin:/bin:/usr/sbin:/sbin && . .homebrew-build-env && ./bootstrap && ./configure --prefix=.../worktree-local/.tox/local-homebrew-macos-minimal/local    && make -k V=0 ... lrslib'
...
bootstrap:69: installing 'config/config.rpath'
...
checking for a BSD-compatible install... /usr/bin/install -c
checking whether build environment is sane... yes
...
configure: notice: the following SPKGs did not find equivalent system packages: arb cbc cliquer ... tachyon xz yasm zeromq
checking for the package system in use... homebrew
configure: hint: installing the following system packages is recommended and may avoid building some of the above SPKGs from source:
configure:   $ brew install cmake gcc gsl mpfi ninja openblas gpatch r readline xz yasm zeromq
...
sage-logger -p 'sage-spkg -y -o  lrslib-062+autotools-2017-03-03.p1' '.../worktree-local/logs/pkgs/lrslib-062+autotools-2017-03-03.p1.log'
[lrslib-062+autotools-2017-03-03.p1] installing. Log file: .../worktree-local/logs/pkgs/lrslib-062+autotools-2017-03-03.p1.log
  [lrslib-062+autotools-2017-03-03.p1] successfully installed.
...
  local-homebrew-macos-minimal: commands succeeded
  congratulations :)

tox环境使用子目录 homebrew 环境目录的 .tox/local-homebrew-macos-minimal 作为自制前缀。此安装不会以任何方式与中的自制程序安装交互 /usr/local 你可能有的。

测试脚本设置 PATHbin 自制前缀的目录,后跟 /usr/bin:/bin:/usr/sbin:/sbin . 然后使用脚本 $SAGE_ROOT/.homebrew-build-env 设置环境变量,以便Sage的构建脚本可以找到“keg only”包,例如 gettext .

这个 local-homebrew-macos-minimal 环境不安装自制程序 python3 包裹。它使用XCode的 /usr/bin/python3 作为系统python。但是,由于Sage将不同的包视为依赖项而丢失,Sage会构建自己的这些包和 python3 .

这个 local-homebrew-macos-standard environment会额外安装(在其独立的自制程序副本中)Sage已知的所有自制程序包,其中 spkg-configure.m4 机制是实现的;这与 docker-standard 前面描述的毒物环境。特别是安装和使用自制的 python3 包裹。

通过使用配置因子,可以测试更多变体。这个 local-homebrew-macos-standard-python3_xcode 环境安装相同的包,但使用XCode的 /usr/bin/python3 .

这个 local-homebrew-macos-standard-python3_pythonorg 期望在中安装Python 3.7 /Library/Frameworks/Python.framework ;这是由python.org网站自行安装。

尽最大努力独立安装Conda的自动构建测试

Sage提供环境 local-conda-forge-standardlocal-conda-forge-minimal 在子目录中创建Miniconda的独立安装 conda 环境目录的。它们不会以任何方式与您系统上的其他水蟒或小型水蟒装置进行交互。

环境使用conda forge通道并使用 python 包和来自此频道的编译器。

在GitHub操作上运行自动并行tox

Sage源代码树包含一个GitHub操作的默认配置,该配置在多个平台上运行tox,每次pull请求和将标记(而不是分支)推送到启用GitHub操作的存储库。

这是在文件中定义的 $SAGE_ROOT/.github/workflows/tox.yml .

文件中定义了一个附加的GitHub操作工作流,用于测试Cygwin,而不是基于tox $SAGE_ROOT/.github/workflows/ci-cygwin.yml .

GitHub Actions在具有7gb RAM内存和14gb SSD磁盘空间的2核计算机上运行这些构建作业。 here ,每个作业的时间限制为6小时。对于一个典型的 minimal 后接生成 make ptest 有足够的时间 standard 为成功而努力。

当工作流的所有作业都已完成时,构建日志将作为“工件”提供。每个作业生成一个tarball。”“注释”突出显示在生成过程中发出的某些顶级错误或警告。

以下过程将触发使用默认系统配置集的测试运行。我们假设 github 是与Sage存储库的GitHub分支相对应的远程名称:

$ git remote -v | grep /my-github
my-github      https://github.com/mkoeppe/sage.git (fetch)
my-github      https://github.com/mkoeppe/sage.git (push)
  • 创建一个具有任意名称的(“轻量级”,而不是“带注释的”)标记,例如 ci (对于“持续集成”):

    git tag -f ci
    
  • 然后将标记推送到GitHub存储库:

    git push -f my-github ci
    

(在两个命令中,“force”选项 (-f )允许覆盖该名称的前一个标记。)

对于在开发期间根据一组定制的系统配置测试分支,下面的过程似乎可以很好地工作。它可以避免更改开发分支上的CI配置:

  • 从最近的beta版创建一个包含默认GitHub操作配置的分支;命名它 TESTER ,比如说。

  • 编辑 $SAGE_ROOT/.github/workflows/tox.yml 以包含要测试的系统配置。

  • 提交并将分支推送到您的GitHub sage分支。

  • 将开发分支推送到GitHub存储库,并针对 TESTER 分支机构。这将触发GitHub操作工作流。

您将在存储库的“操作”选项卡中找到工作流状态页。

以下是如何阅读它。左窗格中的每个项目都代表特定系统配置上Sage的完整构建。左窗格中的测试项在左窗格中标记为绿色复选标记,如果 make build doc-html 完成时没有出错。(它还运行包testsuites和Sage doctests,但这些测试中的失败不会反映在左侧窗格中;请参见下面的内容。)

右窗格(“Artifacts”)提供了日志的存档以供下载。

在右窗格中向下滚动显示“注释”:

  • 对于包含生成错误的每个日志文件,将显示红色的“检查失败”批注。例如,您可能会看到:

    docker (fedora-28, standard)
    artifacts/logs-commit-8ca1c2df8f1fb4c6d54b44b34b4d8320ebecb164-tox-docker-fedora-28-standard/logs/pkgs/sagetex-3.4.log#L1
    ==== ERROR IN LOG FILE artifacts/logs-commit-8ca1c2df8f1fb4c6d54b44b34b4d8320ebecb164-tox-docker-fedora-28-standard/logs/pkgs/sagetex-3.4.log ====
    
  • 黄色“检查警告”注释。有两种类型:

    1. 包testsuite或Sage doctest失败,如下所示:

      docker (fedora-30, standard)
      artifacts/logs-commit-8ca1c2df8f1fb4c6d54b44b34b4d8320ebecb164-tox-docker-fedora-30-standard/logs/ptest.log#L1
      ==== TESTSUITE FAILURE IN LOG FILE artifacts/logs-commit-8ca1c2df8f1fb4c6d54b44b34b4d8320ebecb164-tox-docker-fedora-30-standard/logs/ptest.log ====
      
    2. 来自./configure的关于找不到等效系统包的通知,如下所示:

      docker (fedora-31, standard)
      artifacts/logs-commit-8ca1c2df8f1fb4c6d54b44b34b4d8320ebecb164-tox-docker-fedora-31-standard/config.log#L1
      configure: notice: the following SPKGs did not find equivalent system packages: arb cbc cddlib cmake eclib ecm fflas_ffpack flint flintqs fplll givaro gp
      

点击注解并不能把你带到一个非常有用的地方。要查看详细信息,请单击窗格中的一个项目。这会将右窗格更改为日志查看器。

这个 docker 工作流自动将图像推送到 docker.pkg.github.com . 您可以在GitHub存储库的Packages选项卡中找到它们。

为了在您的计算机上使用它们,您需要首先生成一个提供 read:packages 范围如下。访问https://github.com/settings/tokens/new(这可能会提示您输入GitHub密码)。键入“Access”作为“Note”docker.pkg.github.com”;然后在“选择范围”中,选中 read:packages . 最后,按下底部的“生成令牌”按钮。这将导致显示您的令牌的页面,例如 de1ec7ab1ec0ffee5ca1dedbaff1ed0ddba11 . 复制此令牌并将其粘贴到命令行:

$ echo de1ec7ab1ec0ffee5ca1dedbaff1ed0ddba11 | docker login docker.pkg.github.com --username YOUR-GITHUB-USERNAME

你用你的代币代替代币,当然,还有 YOUR-GITHUB-USERNAME 你的GitHub用户名。

现在您可以拉取图像并运行它:

$ docker pull docker.pkg.github.com/YOUR-GITHUB-USERNAME/sage/sage-docker-fedora-31-standard-configured:f4bd671
$ docker run -it docker.pkg.github.com/YOUR-GITHUB-USERNAME/sage/sage-docker-fedora-31-standard-configured:f4bd671 bash