Skip to content

Refactor integration tests #3064

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

Open
wants to merge 185 commits into
base: master
Choose a base branch
from
Open

Conversation

the-horo
Copy link
Contributor

Main takeaways

  • make the testsuite work with gdc
  • have one test runner that runs all the (possible) tests on as many platforms
  • replace the .sh tests with .d programs (in order to run on windows)
  • run tests in parallel
  • make the test output prettier

It took me a while but I think it was worth it.

I've kept the commits to be one test each and the changes are staged to a new directory (new_tests). I don't expect this to be the final form if this PR is merged so I'll keep this as a draft but I hope that this would make reviewing easier.

From my notes while working on this:

Copy link

github-actions bot commented Jul 29, 2025

✅ PR OK, no changes in deprecations or warnings

Total deprecations: 0

Total warnings: 0

Build statistics:

 statistics (-before, +after)
 executable size=5265672 bin/dub
 rough build time=59s
Full build output
DUB version 1.40.0, built on Jun  7 2025
LDC - the LLVM D compiler (1.41.0):
  based on DMD v2.111.0 and LLVM 20.1.5
  built with LDC - the LLVM D compiler (1.41.0)
  Default target: x86_64-unknown-linux-gnu
  Host CPU: znver3
  http://dlang.org - http://wiki.dlang.org/LDC


  Registered Targets:
    aarch64     - AArch64 (little endian)
    aarch64_32  - AArch64 (little endian ILP32)
    aarch64_be  - AArch64 (big endian)
    amdgcn      - AMD GCN GPUs
    arm         - ARM
    arm64       - ARM64 (little endian)
    arm64_32    - ARM64 (little endian ILP32)
    armeb       - ARM (big endian)
    avr         - Atmel AVR Microcontroller
    bpf         - BPF (host endian)
    bpfeb       - BPF (big endian)
    bpfel       - BPF (little endian)
    hexagon     - Hexagon
    lanai       - Lanai
    loongarch32 - 32-bit LoongArch
    loongarch64 - 64-bit LoongArch
    mips        - MIPS (32-bit big endian)
    mips64      - MIPS (64-bit big endian)
    mips64el    - MIPS (64-bit little endian)
    mipsel      - MIPS (32-bit little endian)
    msp430      - MSP430 [experimental]
    nvptx       - NVIDIA PTX 32-bit
    nvptx64     - NVIDIA PTX 64-bit
    ppc32       - PowerPC 32
    ppc32le     - PowerPC 32 LE
    ppc64       - PowerPC 64
    ppc64le     - PowerPC 64 LE
    r600        - AMD GPUs HD2XXX-HD6XXX
    riscv32     - 32-bit RISC-V
    riscv64     - 64-bit RISC-V
    sparc       - Sparc
    sparcel     - Sparc LE
    sparcv9     - Sparc V9
    spirv       - SPIR-V Logical
    spirv32     - SPIR-V 32-bit
    spirv64     - SPIR-V 64-bit
    systemz     - SystemZ
    thumb       - Thumb
    thumbeb     - Thumb (big endian)
    ve          - VE
    wasm32      - WebAssembly 32-bit
    wasm64      - WebAssembly 64-bit
    x86         - 32-bit X86: Pentium-Pro and above
    x86-64      - 64-bit X86: EM64T and AMD64
    xcore       - XCore
    xtensa      - Xtensa 32
   Upgrading project in /home/runner/work/dub/dub/
    Starting Performing "release" build using /opt/hostedtoolcache/dc/ldc2-1.41.0/x64/ldc2-1.41.0-linux-x86_64/bin/ldc2 for x86_64.
    Building dub 1.39.0-rc.1+commit.264.g70640ea9: building configuration [application]
     Linking dub
STAT:statistics (-before, +after)
STAT:executable size=5265672 bin/dub
STAT:rough build time=59s

@the-horo the-horo force-pushed the run-unittest-ci branch 3 times, most recently from 604aa21 to 62d6498 Compare July 30, 2025 15:55
@the-horo the-horo marked this pull request as ready for review July 30, 2025 20:00
@the-horo
Copy link
Contributor Author

CI looking good, outside of buildkite which I don't have access to

@thewilsonator
Copy link
Contributor

rm: cannot remove 'test/issue895-local-configuration.sh': No such file or directory

@the-horo
Copy link
Contributor Author

rm: cannot remove 'test/issue895-local-configuration.sh': No such file or directory

Simply removing that line and changing whatever was used to invoke the test runner with dub run --root test/run_unittest should be good enough. I am trying to get the testsuite to run on as many platforms as it can and I don't want tests that fail on certain setups. It would be best if the tests worked but, if they really can't, they have full control to skip themselves, rather than requiring a user to remove the test directory.

Although, that test is one of the more intrusive ones. It used to overwrite ./etc/dub/settings.json but now it modified a scoped dub.settings.json so it should be safer. It also created a dummy ldc2 named file which can be picked up when invoking dub normally which can pose issues. This is why the test has must_be_run_alone = true, so it can't affect other tests.


I did get a few failures when running the testsuite as part of a Gentoo build and one of it seems to be a genuine (minor) bug in the vibe json code but I need more time to make sure it's an actual bug, because I can only reproduce it with a locally built ldc2, and not with dmd, gdc or the upstream releases of ldc2.

@Geod24
Copy link
Member

Geod24 commented Jul 31, 2025

The dlang/ci error is https://github.com/dlang/ci/blob/dc95e2fe07e163e159ae3b5b2bf1efc374fef818/buildkite/build_project.sh#L180-L184

Can get around it by adding -f and removing it once the PR is merged.

@the-horo
Copy link
Contributor Author

The dlang/ci error is https://github.com/dlang/ci/blob/dc95e2fe07e163e159ae3b5b2bf1efc374fef818/buildkite/build_project.sh#L180-L184

Oh, so that's where it was.

Can get around it by adding -f and removing it once the PR is merged.

buildkite doesn't look like it's running the integration tests, so what's the point in removing those unused test files? Should buildkite be running the full testsuite?

@the-horo
Copy link
Contributor Author

a genuine (minor) bug in the vibe json code

In regards to the bug:

assert(parseJsonString("17559991181826658461") == Json(BigInt(17559991181826658461UL)));
is calling Json.this(BigInt)
this(BigInt v) nothrow @trusted { zeroFields; m_type = Type.bigInt; initBigInt(); m_bigInt = v; }
which calls zeroFields and then initBigInt
m_bigInt = BigInt.init;
which calls BigInt.opAssign that, in turn, calls BigUint.opAssign. BigUint, however, has an invariant:
https://github.com/dlang/phobos/blob/2d8ae67b396f5cc5f4633695c1c5ac67d2bf448e/std/internal/math/biguintcore.d#L240-L244:

    pure invariant()
    {
        assert( data.length >= 1 && (data.length == 1 || data[$-1] != 0 ),
                "Invariant requires data to not empty or zero");
    }

which then fails because the data array has been zero-ed out by zeroFields. As a stack trace:

(gdb) bt
#0  0x00007ffff7f19c20 in _d_assert_msg () from /usr/lib/ldc2/1.40/lib64/libdruntime-ldc-shared.so.110
#1  0x00007ffff7c2feae in std.internal.math.biguintcore.BigUint.__invariant() const () from /usr/lib/ldc2/1.40/lib64/libphobos2-ldc-shared.so.110
#2  0x0000555555917f29 in std.internal.math.biguintcore.BigUint.opAssign!(void).opAssign(std.internal.math.biguintcore.BigUint) ()
#3  0x000055555590a60f in std.bigint.BigInt.opAssign!(std.bigint.BigInt).opAssign(std.bigint.BigInt) ()
#4  0x000055555590a191 in dub.internal.vibecompat.data.json.Json.initBigInt() ()
#5  0x000055555590a0f9 in dub.internal.vibecompat.data.json.Json.this(std.bigint.BigInt) ()
#6  0x000055555590e565 in dub.internal.vibecompat.data.json.__unittest_L1450_C7() ()
#7  0x000055555592827e in dub.internal.vibecompat.data.json.__unittest ()
#8  0x00007ffff7f3b7d8 in ?? () from /usr/lib/ldc2/1.40/lib64/libdruntime-ldc-shared.so.110
#9  0x00007ffff7f60607 in ?? () from /usr/lib/ldc2/1.40/lib64/libdruntime-ldc-shared.so.110
#10 0x00007ffff7f65c98 in rt.sections_elf_shared.DSO.opApply(scope int(ref rt.sections_elf_shared.DSO) delegate) ()
   from /usr/lib/ldc2/1.40/lib64/libdruntime-ldc-shared.so.110
#11 0x00007ffff7f605ac in rt.minfo.moduleinfos_apply(scope int(immutable(object.ModuleInfo*)) delegate) () from /usr/lib/ldc2/1.40/lib64/libdruntime-ldc-shared.so.110
#12 0x00007ffff7f4e4ff in object.ModuleInfo.opApply(scope int(object.ModuleInfo*) delegate) () from /usr/lib/ldc2/1.40/lib64/libdruntime-ldc-shared.so.110
#13 0x00007ffff7f3b5c8 in runModuleUnitTests () from /usr/lib/ldc2/1.40/lib64/libdruntime-ldc-shared.so.110
#14 0x00007ffff7f58bbb in rt.dmain2._d_run_main2(char[][], ulong, extern(C) int(char[][]) function).runAll() () from /usr/lib/ldc2/1.40/lib64/libdruntime-ldc-shared.so.110
#15 0x00007ffff7f589d4 in _d_run_main2 () from /usr/lib/ldc2/1.40/lib64/libdruntime-ldc-shared.so.110
#16 0x00007ffff7f587ed in _d_run_main () from /usr/lib/ldc2/1.40/lib64/libdruntime-ldc-shared.so.110
#17 0x0000555555bdbea2 in main ()
#18 0x00007ffff774c22e in ?? () from /usr/lib64/libc.so.6
#19 0x00007ffff774c2e9 in __libc_start_main () from /usr/lib64/libc.so.6
#20 0x00005555555d4bc5 in _start ()

You can hit this if the stdlib has been built without -release, which my ldc2 built was, but you can also hit this if you do:

$ DFLAGS='-unittest -link-defaultlib-debug -g' dub test --compiler=ldc2

This shouldn't be causing any problems though, since the bigint would be in a valid state after opAssign and the fact that it's invalid as per the invariant doesn't actually break any code. It still needs to be fixed not to trigger the failure though

the-horo added a commit to the-horo/dlang-ci that referenced this pull request Jul 31, 2025
See dlang/dub#3064 (comment)

1. It does nothing
2. It causes the run to fail when the tests are renamed/removed

Signed-off-by: Andrei Horodniceanu <[email protected]>
This changes makes the compiler version for gdmd match the gdc version
instead of the dmd FE version that gdc had been using. This matches
what happens for ldmd2 which mirrors the ldc2 version.

Specifically, now the versions look like:
- ldmd2-1.40 :: 1.40.X
- ldc2-1.40 :: 1.40.X
- gdc-14 :: 14.X.Y
- gdmd-14 :: 14.X.Y

When, previously, gdmd-14 would result in a version like 2.108.X

Signed-off-by: Andrei Horodniceanu <[email protected]>
@the-horo
Copy link
Contributor Author

the-horo commented Aug 2, 2025

Incorporated #3066 and changed issue1531 to use it since I got it to fail on one of my containers where gdc-14 was based on dmd 2.108.1 rather than 2.108.0

I've also updated the tests' README

@the-horo
Copy link
Contributor Author

the-horo commented Aug 3, 2025

As a small benchmark, doing two consecutive runs, the first with a clean repo and no ~/.dub, the second with all the artifacts from the first, with the old and the new test runner, using dmd:

run # run_unittest -j8 run-unittest.d
1st, clean 5m27.496s 6m45.855s
2nd, cache 2m43.358s 4m21.038s

the-horo added 13 commits August 9, 2025 13:51
Signed-off-by: Andrei Horodniceanu <[email protected]>
Signed-off-by: Andrei Horodniceanu <[email protected]>
Signed-off-by: Andrei Horodniceanu <[email protected]>
Signed-off-by: Andrei Horodniceanu <[email protected]>
Signed-off-by: Andrei Horodniceanu <[email protected]>
Signed-off-by: Andrei Horodniceanu <[email protected]>
Signed-off-by: Andrei Horodniceanu <[email protected]>
Signed-off-by: Andrei Horodniceanu <[email protected]>
Signed-off-by: Andrei Horodniceanu <[email protected]>
Signed-off-by: Andrei Horodniceanu <[email protected]>
Signed-off-by: Andrei Horodniceanu <[email protected]>
Signed-off-by: Andrei Horodniceanu <[email protected]>
Signed-off-by: Andrei Horodniceanu <[email protected]>
the-horo added 26 commits August 9, 2025 13:52
Signed-off-by: Andrei Horodniceanu <[email protected]>
Signed-off-by: Andrei Horodniceanu <[email protected]>
Signed-off-by: Andrei Horodniceanu <[email protected]>
Signed-off-by: Andrei Horodniceanu <[email protected]>
Signed-off-by: Andrei Horodniceanu <[email protected]>
Signed-off-by: Andrei Horodniceanu <[email protected]>
Signed-off-by: Andrei Horodniceanu <[email protected]>
Signed-off-by: Andrei Horodniceanu <[email protected]>
Signed-off-by: Andrei Horodniceanu <[email protected]>
Signed-off-by: Andrei Horodniceanu <[email protected]>
Signed-off-by: Andrei Horodniceanu <[email protected]>
Signed-off-by: Andrei Horodniceanu <[email protected]>
Signed-off-by: Andrei Horodniceanu <[email protected]>
Signed-off-by: Andrei Horodniceanu <[email protected]>
Signed-off-by: Andrei Horodniceanu <[email protected]>
Signed-off-by: Andrei Horodniceanu <[email protected]>
Signed-off-by: Andrei Horodniceanu <[email protected]>
Signed-off-by: Andrei Horodniceanu <[email protected]>
Signed-off-by: Andrei Horodniceanu <[email protected]>
Signed-off-by: Andrei Horodniceanu <[email protected]>
Signed-off-by: Andrei Horodniceanu <[email protected]>
Signed-off-by: Andrei Horodniceanu <[email protected]>
Signed-off-by: Andrei Horodniceanu <[email protected]>
ldc2 on alpine is configured to use the lld linker, however, the lld
package is not pulled in as a dependency.

Signed-off-by: Andrei Horodniceanu <[email protected]>
@the-horo
Copy link
Contributor Author

the-horo commented Aug 9, 2025

Changed run_unittest to compile with -preview=in and -preview=nosharedaccess

Copy link
Member

@Geod24 Geod24 left a comment

Choose a reason for hiding this comment

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

Would like to get this in soon (DConf hackathon perhaps?). Why the move the new_test though ?

Comment on lines +104 to +106
// Find the backend version of the compiler, not the dmd FE.
// Specificically, for gdmd-14 this function should return
// 14.X.Y not 2.108.Z
Copy link
Member

Choose a reason for hiding this comment

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

Why ? I don't think that makes a lot of sense.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

See #3066 (comment).

For short:

  • ldmd uses the version of ldc, not the dlang frontend version
  • I've only seen people depend on major versions of gcc, at most a minor version if they need a bug fix. Having versions like 2.108.1, 2.108.0-rc.1 etc. all map to gdc-14 seems like poor design.

@the-horo
Copy link
Contributor Author

Would like to get this in soon (DConf hackathon perhaps?). Why the move the new_test though ?

I feared that trying to do it in place would make it way harder to do atomic commits for easier review and I also worried that I would miss a dependency on one of the tests. Putting everything in another directory helped with safely porting tests one by one.

This does leave me with having to put everything back into tests. I'm fine doing it in 1 big commit but I think I can manage rebasing each commit to leave everything in /test, if you want it.

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.

3 participants