Prechádzať zdrojové kódy

Merge pull request #178 from MikeMirzayanov/dev-mikemirzayanov

Fixed BOM issues, fixed tests and CI
Mike Mirzayanov 9 mesiacov pred
rodič
commit
c3f7215e68
49 zmenil súbory, kde vykonal 1121 pridanie a 182 odobranie
  1. 21 3
      .github/workflows/ci.yml
  2. 3 4
      testlib.h
  3. 7 0
      tests/docker/clang-11/Dockerfile
  4. 4 0
      tests/docker/clang-11/build.bat
  5. 4 0
      tests/docker/clang-11/run.bat
  6. 10 0
      tests/docker/clang-11/startup.sh
  7. 7 0
      tests/docker/clang-latest/Dockerfile
  8. 4 0
      tests/docker/clang-latest/build.bat
  9. 4 0
      tests/docker/clang-latest/run.bat
  10. 10 0
      tests/docker/clang-latest/startup.sh
  11. 7 0
      tests/docker/gcc-7/Dockerfile
  12. 4 0
      tests/docker/gcc-7/build.bat
  13. 4 0
      tests/docker/gcc-7/run.bat
  14. 10 0
      tests/docker/gcc-7/startup.sh
  15. 7 0
      tests/docker/gcc-latest/Dockerfile
  16. 4 0
      tests/docker/gcc-latest/build.bat
  17. 4 0
      tests/docker/gcc-latest/run.bat
  18. 10 0
      tests/docker/gcc-latest/startup.sh
  19. 9 0
      tests/file-runner.py
  20. BIN
      tests/lib/msvc-2022-include.7z
  21. 441 131
      tests/lib/testlib.h
  22. BIN
      tests/lib/windows-kit-10.0.19041.0-include.7z
  23. 44 32
      tests/run.sh
  24. 9 12
      tests/scripts/compile
  25. 3 0
      tests/test-002_run-fcmp-wcmp/files/output.01.bom
  26. 5 0
      tests/test-002_run-fcmp-wcmp/run.sh
  27. 21 0
      tests/test-003_run-rnd/refs/r1/stdout
  28. 21 0
      tests/test-003_run-rnd/refs/r2/stdout
  29. 25 0
      tests/test-003_run-rnd/src/gen.cpp
  30. BIN
      tests/test-006_interactors/files/crossrun/CrossRun.jar
  31. 162 0
      tests/test-006_interactors/files/crossrun/CrossRun.java
  32. 53 0
      tests/test-006_interactors/files/crossrun/build-cross-run.sh
  33. 4 0
      tests/test-006_interactors/files/unix/input.01
  34. 3 0
      tests/test-006_interactors/files/unix/participant.01
  35. 4 0
      tests/test-006_interactors/files/win/input.01
  36. 3 0
      tests/test-006_interactors/files/win/participant.01
  37. 1 0
      tests/test-006_interactors/refs/r-interactor-a-plus-b-1-1/exit_code
  38. 1 0
      tests/test-006_interactors/refs/r-interactor-a-plus-b-1-1/stderr
  39. 3 0
      tests/test-006_interactors/refs/r-interactor-a-plus-b-1-1/stdout
  40. 1 0
      tests/test-006_interactors/refs/r-interactor-a-plus-b-1-2/exit_code
  41. 0 0
      tests/test-006_interactors/refs/r-interactor-a-plus-b-1-2/stderr
  42. 3 0
      tests/test-006_interactors/refs/r-interactor-a-plus-b-1-2/stdout
  43. 1 0
      tests/test-006_interactors/refs/r-interactor-a-plus-b-2-1/exit_code
  44. 0 0
      tests/test-006_interactors/refs/r-interactor-a-plus-b-2-1/stderr
  45. 3 0
      tests/test-006_interactors/refs/r-interactor-a-plus-b-2-1/stdout
  46. 20 0
      tests/test-006_interactors/run.sh
  47. 9 0
      tests/test-006_interactors/src/interactive-a-plus-b.cpp
  48. 122 0
      tests/test-006_interactors/src/interactive_runner.py
  49. 26 0
      tests/test-006_interactors/src/interactor-a-plus-b.cpp

+ 21 - 3
.github/workflows/ci.yml

@@ -19,6 +19,7 @@ env:
 
 jobs:
   tests-ubuntu1804-gpp:
+    if: false # Disabled job
     strategy:
       matrix:
         os: [ubuntu-18.04]
@@ -34,6 +35,7 @@ jobs:
           bash ./run.sh ${{ matrix.compiler }} v${{ matrix.version }}
 
   tests-ubuntu1804-clang:
+    if: false # Disabled job
     strategy:
       matrix:
         os: [ubuntu-18.04]
@@ -79,6 +81,7 @@ jobs:
           bash ./run.sh ${{ matrix.compiler }} v${{ matrix.version }}
 
   tests-ubuntu1804-gpp-32:
+    if: false # Disabled job
     strategy:
       matrix:
         os: [ubuntu-18.04]
@@ -95,6 +98,7 @@ jobs:
           bash ./run.sh ${{ matrix.compiler }} v${{ matrix.version }} 32
 
   tests-ubuntu1804-clang-32:
+    if: false # Disabled job
     strategy:
       matrix:
         os: [ubuntu-18.04]
@@ -147,7 +151,7 @@ jobs:
       matrix:
         os: [macos-11]
         compiler: [g++]
-        version: [9, 10]
+        version: [10, 11, 12]
     name: Use ${{ matrix.compiler }}-${{ matrix.version }} on ${{ matrix.os }}
     runs-on: ${{ matrix.os }}
     steps:
@@ -200,10 +204,10 @@ jobs:
           cd tests
           bash ./run.sh ${{ matrix.compiler }}
 
-  tests-windows:
+  tests-windows-2019:
     strategy:
       matrix:
-        os: [windows-2019, windows-2022]
+        os: [windows-2019]
         compiler: [msvc, g++, clang++]
     name: Use ${{ matrix.compiler }} on ${{ matrix.os }}
     runs-on: ${{ matrix.os }}
@@ -213,3 +217,17 @@ jobs:
         run: |
           cd tests
           bash ./run.sh ${{ matrix.compiler }}
+
+  tests-windows-2022:
+    strategy:
+      matrix:
+        os: [windows-2022]
+        compiler: [msvc, g++]
+    name: Use ${{ matrix.compiler }} on ${{ matrix.os }}
+    runs-on: ${{ matrix.os }}
+    steps:
+      - uses: actions/checkout@v3
+      - name: Run tests
+        run: |
+          cd tests
+          bash ./run.sh ${{ matrix.compiler }}

+ 3 - 4
testlib.h

@@ -746,8 +746,8 @@ public:
 
     /* Sets seed by given value. */
     void setSeed(long long _seed) {
-        _seed = (_seed ^ multiplier) & mask;
-        seed = _seed;
+        seed = (unsigned long long) _seed;
+        seed = (seed ^ multiplier) & mask;
     }
 
 #ifndef __BORLANDC__
@@ -3121,7 +3121,6 @@ void InStream::init(std::string fileName, TMode mode) {
     }
 
     reset();
-    skipBom();
 }
 
 void InStream::init(std::FILE *f, TMode mode) {
@@ -3137,7 +3136,6 @@ void InStream::init(std::FILE *f, TMode mode) {
         name = "stderr", stdfile = true;
 
     reset(f);
-    skipBom();
 }
 
 void InStream::skipBom() {
@@ -4628,6 +4626,7 @@ void registerTestlibCmd(int argc, char *argv[]) {
 
     inf.init(args[1], _input);
     ouf.init(args[2], _output);
+    ouf.skipBom();
     ans.init(args[3], _answer);
 }
 

+ 7 - 0
tests/docker/clang-11/Dockerfile

@@ -0,0 +1,7 @@
+FROM silkeh/clang:11
+RUN apt-get update
+RUN apt-get install -y git default-jre
+COPY startup.sh /
+WORKDIR /
+RUN chmod +x /startup.sh
+CMD ["/bin/bash", "/startup.sh"]

+ 4 - 0
tests/docker/clang-11/build.bat

@@ -0,0 +1,4 @@
+"C:\Program Files\Docker\Docker"\DockerCli.exe -SwitchLinuxEngine
+
+docker build . -t test-testlib-clang-11
+

+ 4 - 0
tests/docker/clang-11/run.bat

@@ -0,0 +1,4 @@
+"C:\Program Files\Docker\Docker"\DockerCli.exe -SwitchLinuxEngine
+
+docker run -it test-testlib-clang-11
+

+ 10 - 0
tests/docker/clang-11/startup.sh

@@ -0,0 +1,10 @@
+#!/bin/bash
+set -e -o pipefail
+
+git clone https://github.com/MikeMirzayanov/testlib.git
+cd testlib
+git checkout dev-mikemirzayanov
+cd tests
+./run.sh v0 11
+cd /
+rm -rf testlib

+ 7 - 0
tests/docker/clang-latest/Dockerfile

@@ -0,0 +1,7 @@
+FROM silkeh/clang:latest
+RUN apt-get update
+RUN apt-get install -y git default-jre valgrind
+COPY startup.sh /
+WORKDIR /
+RUN chmod +x /startup.sh
+CMD ["/bin/bash", "/startup.sh"]

+ 4 - 0
tests/docker/clang-latest/build.bat

@@ -0,0 +1,4 @@
+"C:\Program Files\Docker\Docker"\DockerCli.exe -SwitchLinuxEngine
+
+docker build . -t test-testlib-clang-latest
+

+ 4 - 0
tests/docker/clang-latest/run.bat

@@ -0,0 +1,4 @@
+"C:\Program Files\Docker\Docker"\DockerCli.exe -SwitchLinuxEngine
+
+docker run -it test-testlib-clang-latest
+

+ 10 - 0
tests/docker/clang-latest/startup.sh

@@ -0,0 +1,10 @@
+#!/bin/bash
+set -e -o pipefail
+
+git clone https://github.com/MikeMirzayanov/testlib.git
+cd testlib
+git checkout dev-mikemirzayanov
+cd tests
+./run.sh v0 23
+cd /
+rm -rf testlib

+ 7 - 0
tests/docker/gcc-7/Dockerfile

@@ -0,0 +1,7 @@
+FROM gcc:7
+RUN apt-get update
+RUN apt-get install -y git default-jre valgrind
+COPY startup.sh /
+WORKDIR /
+RUN chmod +x /startup.sh
+CMD ["/bin/bash", "/startup.sh"]

+ 4 - 0
tests/docker/gcc-7/build.bat

@@ -0,0 +1,4 @@
+"C:\Program Files\Docker\Docker"\DockerCli.exe -SwitchLinuxEngine
+
+docker build . -t test-testlib-gcc-7
+

+ 4 - 0
tests/docker/gcc-7/run.bat

@@ -0,0 +1,4 @@
+"C:\Program Files\Docker\Docker"\DockerCli.exe -SwitchLinuxEngine
+
+docker run -it test-testlib-gcc-7
+

+ 10 - 0
tests/docker/gcc-7/startup.sh

@@ -0,0 +1,10 @@
+#!/bin/bash
+set -e -o pipefail
+
+git clone https://github.com/MikeMirzayanov/testlib.git
+cd testlib
+git checkout dev-mikemirzayanov
+cd tests
+./run.sh g++ v0 11
+cd /
+rm -rf testlib

+ 7 - 0
tests/docker/gcc-latest/Dockerfile

@@ -0,0 +1,7 @@
+FROM gcc:latest
+RUN apt-get update
+RUN apt-get install -y git default-jre valgrind
+COPY startup.sh /
+WORKDIR /
+RUN chmod +x /startup.sh
+CMD ["/bin/bash", "/startup.sh"]

+ 4 - 0
tests/docker/gcc-latest/build.bat

@@ -0,0 +1,4 @@
+"C:\Program Files\Docker\Docker"\DockerCli.exe -SwitchLinuxEngine
+
+docker build . -t test-testlib-gcc-latest
+

+ 4 - 0
tests/docker/gcc-latest/run.bat

@@ -0,0 +1,4 @@
+"C:\Program Files\Docker\Docker"\DockerCli.exe -SwitchLinuxEngine
+
+docker run -it test-testlib-gcc-latest
+

+ 10 - 0
tests/docker/gcc-latest/startup.sh

@@ -0,0 +1,10 @@
+#!/bin/bash
+set -e -o pipefail
+
+git clone https://github.com/MikeMirzayanov/testlib.git
+cd testlib
+git checkout dev-mikemirzayanov
+cd tests
+./run.sh g++ v0 23
+cd /
+rm -rf testlib

+ 9 - 0
tests/file-runner.py

@@ -0,0 +1,9 @@
+import subprocess
+import sys
+
+if len(sys.argv) > 1:
+    file_path = sys.argv[1]
+    subprocess.run([file_path])
+else:
+    print("Use python runner.py <file>")
+    sys.exit(1)

BIN
tests/lib/msvc-2022-include.7z


Rozdielové dáta súboru neboli zobrazené, pretože súbor je príliš veľký
+ 441 - 131
tests/lib/testlib.h


BIN
tests/lib/windows-kit-10.0.19041.0-include.7z


+ 44 - 32
tests/run.sh

@@ -1,5 +1,8 @@
 #!/bin/bash
-set -eo pipefail
+set -e -o pipefail
+
+echo "Checking installed Java"
+java -version
 
 TESTS_DIR=$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" &>/dev/null && pwd)
 export TESTS_DIR="$TESTS_DIR"
@@ -17,6 +20,10 @@ ARGS_CPP_STANDARDS=","
 ARGS_CPP_VERSIONS=","
 ARGS_TESTS=","
 ARGS_CPP_BITS=""
+
+MSVC_INCLUDE_YEAR="2022"
+WINKIT_INCLUDE_VERSION="10.0.19041.0"
+
 for arg in "$@"; do
   if [[ "$arg" == test-* ]]; then
     ARGS_TESTS="${ARGS_TESTS}${arg},"
@@ -104,12 +111,12 @@ MSYS*) machine=Windows ;;
 esac
 export MACHINE="$machine"
 
-if [[ "$machine" == "Windows" && ("$ARGS_CPP" == "" || "$ARGS_CPP" == "msvc") ]]; then
-  for f in msvc-2022-include windows-kit-10.0.19041.0-include; do
-    rm -rf "${TESTS_DIR:?}"/lib/$f && mkdir -p "$TESTS_DIR"/lib/$f
-    7z x -o"${TESTS_DIR:?}"/lib/$f "$TESTS_DIR"/lib/$f.7z
-  done
-fi
+#if [[ "$machine" == "Windows" && ("$ARGS_CPP" == "" || "$ARGS_CPP" == "clang++") ]]; then
+#  for f in msvc-${MSVC_INCLUDE_YEAR}-include windows-kit-${WINKIT_INCLUDE_VERSION}-include; do
+#    rm -rf "${TESTS_DIR:?}"/lib/$f && mkdir -p "$TESTS_DIR"/lib/$f
+#    7z x -o"${TESTS_DIR:?}"/lib/$f "$TESTS_DIR"/lib/$f.7z
+#  done
+#fi
 
 run_tests() {
   export INVOCATION_ID=$RANDOM
@@ -170,9 +177,10 @@ if [[ "$machine" == "Windows" && ("$ARGS_CPP" == "" || "$ARGS_CPP" == "msvc") ]]
               echo "Compiler Visual Studio $version ($vs_release-$bits) has been found"
               echo call \""$vcvars_bat_file"\" >do-vcvars.bat
               echo "bash -c export > vcvars.env" >>do-vcvars.bat
-              ./do-vcvars.bat
-              source vcvars.env
-              rm -f do-vcvars.bat vcvars.env
+              python file-runner.py do-vcvars.bat
+              grep -v -E "(\(.*=)|(\!.*=)|([A-Z]\-[A-Z].*=)" <vcvars.env >vcvars_filtered.env
+              source vcvars_filtered.env
+              rm -f do-vcvars.bat vcvars.env vcvars_filtered.env
               for cpp_standard in "${MSVC_CPP_STANDARDS[@]}"; do
                 touch empty_file.cpp
                 cpp_output=$(cl.exe "$cpp_standard" empty_file.cpp 2>&1 || true)
@@ -196,24 +204,28 @@ fi
 
 # Find /c/Programs/*/bin/g++ in case of Windows and no ARGS_CPP
 if [[ "$MACHINE" == "Windows" && "$ARGS_CPP" == "" ]]; then
-    for d in /c/Programs/*/ ; do
-        gpp="${d}bin/g++.exe"
-        gpp_output=$($gpp 2>&1 || true)
-        if [[ $gpp_output == *"no input files"* ]]; then
-          for gpp_standard in "${CPP_STANDARDS[@]}"; do
-            touch empty_file.cpp
-            gpp_output=$($gpp "$gpp_standard" empty_file.cpp 2>&1 || true)
-            if [[ ! $gpp_output == *"unrecognized"* && ! $gpp_output == *"standard"* ]]; then
-              run_tests "$gpp" "$gpp_standard"
-              if [[ ! "$done" == "" ]]; then
-                done="$done, "
-              fi
-              done="$done$gpp@$gpp_standard"
-            fi
-            rm -f empty_file.*
-          done
+  for d in /c/Programs/*/; do
+    dir="${d}bin"
+    OLD_PATH="$PATH"
+    export PATH="$dir":$PATH
+    gpp="${d}bin/g++.exe"
+    gpp_output=$($gpp 2>&1 || true)
+    if [[ $gpp_output == *"no input files"* ]]; then
+      for gpp_standard in "${CPP_STANDARDS[@]}"; do
+        touch empty_file.cpp
+        gpp_output=$($gpp "$gpp_standard" empty_file.cpp 2>&1 || true)
+        if [[ ! $gpp_output == *"unrecognized"* && ! $gpp_output == *"standard"* ]]; then
+          run_tests "$gpp" "$gpp_standard"
+          if [[ ! "$done" == "" ]]; then
+            done="$done, "
+          fi
+          done="$done$gpp@$gpp_standard"
         fi
-    done
+        rm -f empty_file.*
+      done
+    fi
+    export PATH="$OLD_PATH"
+  done
 fi
 
 for compiler in "${COMPILERS[@]}"; do
@@ -247,11 +259,11 @@ for compiler in "${COMPILERS[@]}"; do
   done
 done
 
-if [[ "$machine" == "Windows" ]]; then
-  for f in msvc-2022-include windows-kit-10.0.19041.0-include; do
-    rm -rf "${TESTS_DIR:?}"/lib/$f
-  done
-fi
+#if [[ "$machine" == "Windows" ]]; then
+#  for f in msvc-${MSVC_INCLUDE_YEAR}-include windows-kit-${WINKIT_INCLUDE_VERSION}-include; do
+#    rm -rf "${TESTS_DIR:?}"/lib/$f
+#  done
+#fi
 
 if [[ -z "$done" ]]; then
   echo -e "${RED}[ERROR]${NC} No compilers found\n"

+ 9 - 12
tests/scripts/compile

@@ -33,29 +33,26 @@ fi
 rm -f "$exe_file"
 
 EXTRA_ARGS=""
-if [[ "$CPP" == "clang++" && "$MACHINE" == "Windows" ]]; then
-  msvc_version="2022"
-  wk_version="10.0.19041.0"
-  EXTRA_ARGS=" -I\"$TESTS_DIR/lib/msvc-$msvc_version-include\""
-  for s in cppwinrt shared ucrt um winrt; do
-    EXTRA_ARGS="$EXTRA_ARGS -I\"$TESTS_DIR/lib/windows-kit-$wk_version-include/$s\""
-  done
-fi
+#if [[ "$CPP" == "clang++" && "$MACHINE" == "Windows" ]]; then
+#  msvc_version="2022"
+#  wk_version="10.0.19041.0"
+#  EXTRA_ARGS=" -I\"$TESTS_DIR/lib/msvc-$msvc_version-include\""
+#  for s in cppwinrt shared ucrt um winrt; do
+#    EXTRA_ARGS="$EXTRA_ARGS -I\"$TESTS_DIR/lib/windows-kit-$wk_version-include/$s\""
+#  done
+#fi
 
 if [[ "$CPP" == "cl.exe" ]]; then
   echo "Compiling $src_file, running:" "$CPP" "$CPP_STANDARD" "-F268435456" "-EHsc" "-O2" -I"${CPP_INCLUDE_DIR}" -Fe"$exe_file" "$src_file"
-  "$CPP" "$CPP_STANDARD" "-F268435456" "-EHsc" "-O2" -I"${CPP_INCLUDE_DIR}" -Fe"$exe_file" "$src_file" &>/dev/null
+  "$CPP" "$CPP_STANDARD" "-F268435456" "-EHsc" "-O2" -I"${CPP_INCLUDE_DIR}" -Fe"$exe_file" "$src_file"
 else
   "$CPP" -v
   echo "Compiling $src_file, running:" "$CPP" "$CPP_OPTS" "$CPP_STANDARD" -Wpedantic -Werror -I"${CPP_INCLUDE_DIR}""$EXTRA_ARGS" -o"$exe_file" -O2 "$src_file"
   dir=$(dirname "$CPP")
-  OLD_PATH="$PATH"
   if [[ "$dir" == *"/bin" ]]; then
-    export PATH="$dir":$PATH
     EXTRA_ARGS="${EXTRA_ARGS} -static"
   fi
   eval "$CPP" "$CPP_OPTS" "$CPP_STANDARD" -Wpedantic -Werror -I"${CPP_INCLUDE_DIR}""$EXTRA_ARGS" -o"$exe_file" -O2 "$src_file"
-  export PATH="$OLD_PATH"
 fi
 
 rm -f ./*.o ./*.obj

+ 3 - 0
tests/test-002_run-fcmp-wcmp/files/output.01.bom

@@ -0,0 +1,3 @@
+abc 01 \%test!$
+
+me

+ 5 - 0
tests/test-002_run-fcmp-wcmp/run.sh

@@ -5,6 +5,11 @@ bash ../scripts/compile src/wcmp.cpp
 bash ../scripts/test-ref r1 "$VALGRIND" ./wcmp files/input.01 files/output.01 files/answer.01
 bash ../scripts/test-ref r2 "$VALGRIND" ./wcmp files/input.01 files/output.01 files/output.01
 bash ../scripts/test-ref r3 "$VALGRIND" ./wcmp files/input.01 files/output.01 files/answer2.01
+
+# BOM shouldn't change refs
+bash ../scripts/test-ref r1 "$VALGRIND" ./wcmp files/input.01 files/output.01.bom files/answer.01
+bash ../scripts/test-ref r2 "$VALGRIND" ./wcmp files/input.01 files/output.01.bom files/output.01
+bash ../scripts/test-ref r3 "$VALGRIND" ./wcmp files/input.01 files/output.01.bom files/answer2.01
 rm -f wcmp wcmp.exe
 
 bash ../scripts/compile src/fcmp.cpp

+ 21 - 0
tests/test-003_run-rnd/refs/r1/stdout

@@ -30,3 +30,24 @@ vutwaahqooeqoxzxwetlpecqiwgdbogiqqulttysyohwhzxzphvsfmnplizxoebzcvvfyppqbhxjksuz
 980
 96952
 99843
+277.6710
+1652.0276
+1871.0491
+1771.8652
+521.1956
+461.5447
+1631
+828
+761
+266
+804
+409
+1085
+1837
+1834
+557
+119
+62
+1880
+1973
+1850

+ 21 - 0
tests/test-003_run-rnd/refs/r2/stdout

@@ -120,3 +120,24 @@ clizwkchataumicxkohcrpqnyrjyzbjvsypznpembvkkkbyzvzckcmhbjbuopfbwbkntswhwsdfzabjg
 860
 99644
 98400
+373.3556
+109.6260
+1999.1647
+1871.5326
+311.6935
+562.6932
+638
+730
+52
+334
+62
+983
+1686
+1538
+1911
+71
+259
+445
+1363
+1897
+1175

+ 25 - 0
tests/test-003_run-rnd/src/gen.cpp

@@ -102,4 +102,29 @@ int main(int argc, char* argv[])
     println(rnd.wnext(1000LL, 20LL));
     println(rnd.wnext(100000, 200));
     println(rnd.wnext(100000LL, 200LL));
+
+    std::cout << std::fixed << std::setprecision(4) << rnd.next((float) 42.0, (float) 2011.1109) << std::endl;
+    std::cout << std::fixed << std::setprecision(4) << rnd.next((double) 42.0, (double) 2011.1109) << std::endl;
+    std::cout << std::fixed << std::setprecision(4) << rnd.wnext((float) 42.0, (float) 2011.1109, 5) << std::endl;
+    std::cout << std::fixed << std::setprecision(4) << rnd.wnext((double) 42.0, (double) 2011.1109, 5) << std::endl;
+    std::cout << std::fixed << std::setprecision(4) << rnd.wnext((float) 42.0, (float) 2011.1109, -7) << std::endl;
+    std::cout << std::fixed << std::setprecision(4) << rnd.wnext((double) 42.0, (double) 2011.1109, -7) << std::endl;
+
+    std::cout << rnd.next((unsigned long long) 42, (unsigned long long) 2011) << std::endl;
+    std::cout << rnd.next((unsigned int) 42, (unsigned int) 2011) << std::endl;
+    std::cout << rnd.next((unsigned short) 42, (unsigned short) 2011) << std::endl;
+
+    std::cout << rnd.wnext((unsigned long long) 42, (unsigned long long) 2011, -3) << std::endl;
+    std::cout << rnd.wnext((unsigned int) 42, (unsigned int) 2011, -3) << std::endl;
+    std::cout << rnd.wnext((unsigned short) 42, (unsigned short) 2011, -3) << std::endl;
+    std::cout << rnd.wnext((unsigned long long) 42, (unsigned long long) 2011, 3) << std::endl;
+    std::cout << rnd.wnext((unsigned int) 42, (unsigned int) 2011, 3) << std::endl;
+    std::cout << rnd.wnext((unsigned short) 42, (unsigned short) 2011, 3) << std::endl;
+
+    std::cout << rnd.wnext((signed long long) 42, (signed long long) 2011, -5) << std::endl;
+    std::cout << rnd.wnext((signed int) 42, (signed int) 2011, -5) << std::endl;
+    std::cout << rnd.wnext((signed short) 42, (signed short) 2011, -5) << std::endl;
+    std::cout << rnd.wnext((signed long long) 42, (signed long long) 2011, 4) << std::endl;
+    std::cout << rnd.wnext((signed int) 42, (signed int) 2011, 4) << std::endl;
+    std::cout << rnd.wnext((signed short) 42, (signed short) 2011, 4) << std::endl;
 }

BIN
tests/test-006_interactors/files/crossrun/CrossRun.jar


+ 162 - 0
tests/test-006_interactors/files/crossrun/CrossRun.java

@@ -0,0 +1,162 @@
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+public class CrossRun {
+    private static final List<String> messages = Collections.synchronizedList(new ArrayList<String>());
+    
+    private static volatile boolean failed = false;
+
+    private static void error(String message) {
+        System.out.println("ERROR: " + message);
+        System.exit(1);
+    }
+
+    public static void main(String[] args) {
+        int sep = -1;
+        for (int i = 0; i < args.length; i++) {
+            if (args[i].equals("--")) {
+                sep = i;
+                break;
+            }
+        }
+        
+        if (sep == -1) {
+            error("Expected exactly one '--' as separator for the two process command lines.");
+        }
+        
+        String[] params1 = new String[sep];
+        System.arraycopy(args, 0, params1, 0, params1.length);
+        
+        String[] params2 = new String[args.length - sep - 1];
+        System.arraycopy(args, sep + 1, params2, 0, params2.length);
+        
+        long startTime = System.currentTimeMillis();
+
+        try {
+            runProcesses(params1, params2);
+        } catch (IOException e) {
+            error(e.getMessage());
+        }
+
+        System.out.println("Completed in " + (System.currentTimeMillis() - startTime) + " ms.");
+    }
+
+    private static void runProcesses(String[] params1, String[] params2) throws IOException {
+        Process process1 = new ProcessBuilder(params1).start();
+        Process process2 = new ProcessBuilder(params2).start();
+
+        Thread readProcess1WriteProcess2Thread =
+                new Thread(new StreamProxyRunner("process1", "process2", process1.getInputStream(), process2.getOutputStream()));
+        Thread readProcess2WriteProcess1Thread =
+                new Thread(new StreamProxyRunner("process2", "process1", process2.getInputStream(), process1.getOutputStream()));
+
+        readProcess1WriteProcess2Thread.start();
+        readProcess2WriteProcess1Thread.start();
+
+        int processExitCode1 = -1;
+        try {
+            processExitCode1 = process1.waitFor();
+        } catch (InterruptedException e) {
+            error(e.getMessage());
+        }
+
+        int processExitCode2 = -1;
+        try {
+            processExitCode2 = process2.waitFor();
+        } catch (InterruptedException e) {
+            error(e.getMessage());
+        }
+
+        try {
+            readProcess1WriteProcess2Thread.join();
+        } catch (InterruptedException e) {
+            error(e.getMessage());
+        }
+
+        try {
+            readProcess2WriteProcess1Thread.join();
+        } catch (InterruptedException e) {
+            error(e.getMessage());
+        }
+
+        if (processExitCode1 != 0) {
+            messages.add("The process 1 returned with exit code " + processExitCode1 + ".");
+        }
+
+        if (processExitCode2 != 0) {
+            messages.add("The process 2 returned with exit code " + processExitCode2 + ".");
+        }
+
+        for (String message : messages) {
+            System.out.println("* " + message);
+        }
+
+        if (failed) {
+            System.exit(1);
+        }
+    }
+
+    @SuppressWarnings("ClassCanBeRecord")
+    private static final class StreamProxyRunner implements Runnable {
+        private final String processName1;
+        private final String processName2;
+        private final InputStream inputStream;
+        private final OutputStream outputStream;
+
+        private StreamProxyRunner(final String processName1,
+                                  final String processName2,
+                                  final InputStream inputStream,
+                                  final OutputStream outputStream) {
+            this.processName1 = processName1;
+            this.processName2 = processName2;
+            this.inputStream = inputStream;
+            this.outputStream = outputStream;
+        }
+
+        @Override
+        public void run() {
+            byte[] buffer = new byte[65536];
+
+            while (true) {
+                int size;
+
+                try {
+                    size = inputStream.read(buffer);
+                } catch (IOException e) {
+                    messages.add("Unexpected exception " + e.getClass().getSimpleName() + " while reading from the output of the " + processName1 + " process: " + e.getMessage());
+                    failed = true;
+                    break;
+                }
+
+                if (size < 0) {
+                    break;
+                }
+
+                try {
+                    outputStream.write(buffer, 0, size);
+                    outputStream.flush();
+                } catch (IOException e) {
+                    messages.add("Unexpected exception " + e.getClass().getSimpleName() + " while writing to the input of the " + processName2 + " process: " + e.getMessage());
+                    failed = true;
+                    break;
+                }
+            }
+
+            try {
+                inputStream.close();
+            } catch (IOException e) {
+                // No operations.
+            }
+
+            try {
+                outputStream.close();
+            } catch (IOException e) {
+                // No operations.
+            }
+        }
+    }
+}

+ 53 - 0
tests/test-006_interactors/files/crossrun/build-cross-run.sh

@@ -0,0 +1,53 @@
+#!/bin/bash
+
+uname_output="$(uname -s)"
+case "${uname_output}" in
+Linux*) machine=Linux ;;
+Darwin*) machine=Mac ;;
+CYGWIN*) machine=Windows ;;
+MINGW*) machine=Windows ;;
+MSYS*) machine=Windows ;;
+*) echo "Unknown system '${uname_output}'" && exit 1 ;;
+esac
+
+# If JAVA8_32_HOME is set, use its javac
+if [[ -n "$JAVA8_32_HOME" ]]; then
+    if [[ "$machine" == "Windows" ]]; then
+        JAVA8_32_HOME=$(cygpath "$JAVA8_32_HOME")
+    fi
+    export PATH="$JAVA8_32_HOME/bin:$PATH"
+fi
+
+# If JAVA7_32_HOME is set, use its javac
+if [[ -n "$JAVA7_32_HOME" ]]; then
+    if [[ "$machine" == "Windows" ]]; then
+        JAVA7_32_HOME=$(cygpath "$JAVA7_32_HOME")
+    fi
+    export PATH="$JAVA7_32_HOME/bin:$PATH"
+fi
+
+echo $PATH
+
+# Show javac version
+javac -version
+
+# Compile all .java files
+javac *.java
+
+# Check if the compilation was successful
+if [ $? -ne 0 ]; then
+    echo "Error during compilation. Exiting."
+    exit 1
+fi
+
+# Create a manifest file for the jar
+echo "Main-Class: CrossRun" > manifest.mf
+
+# Package all .class files into a jar
+jar cvfm CrossRun.jar manifest.mf *.class
+
+# Cleanup .class files and manifest file (optional)
+rm *.class
+rm manifest.mf
+
+echo "Done. CrossRun.jar created."

+ 4 - 0
tests/test-006_interactors/files/unix/input.01

@@ -0,0 +1,4 @@
+3
+1 2
+3 4
+-1 -1

+ 3 - 0
tests/test-006_interactors/files/unix/participant.01

@@ -0,0 +1,3 @@
+5
+6
+7

+ 4 - 0
tests/test-006_interactors/files/win/input.01

@@ -0,0 +1,4 @@
+3
+1 2
+3 4
+-1 -1

+ 3 - 0
tests/test-006_interactors/files/win/participant.01

@@ -0,0 +1,3 @@
+5
+6
+7

+ 1 - 0
tests/test-006_interactors/refs/r-interactor-a-plus-b-1-1/exit_code

@@ -0,0 +1 @@
+0

+ 1 - 0
tests/test-006_interactors/refs/r-interactor-a-plus-b-1-1/stderr

@@ -0,0 +1 @@
+ok 3 queries processed

+ 3 - 0
tests/test-006_interactors/refs/r-interactor-a-plus-b-1-1/stdout

@@ -0,0 +1,3 @@
+1 2
+3 4
+-1 -1

+ 1 - 0
tests/test-006_interactors/refs/r-interactor-a-plus-b-1-2/exit_code

@@ -0,0 +1 @@
+0

+ 0 - 0
tests/test-006_interactors/refs/r-interactor-a-plus-b-1-2/stderr


+ 3 - 0
tests/test-006_interactors/refs/r-interactor-a-plus-b-1-2/stdout

@@ -0,0 +1,3 @@
+5
+6
+7

+ 1 - 0
tests/test-006_interactors/refs/r-interactor-a-plus-b-2-1/exit_code

@@ -0,0 +1 @@
+0

+ 0 - 0
tests/test-006_interactors/refs/r-interactor-a-plus-b-2-1/stderr


+ 3 - 0
tests/test-006_interactors/refs/r-interactor-a-plus-b-2-1/stdout

@@ -0,0 +1,3 @@
+3
+7
+-2

+ 20 - 0
tests/test-006_interactors/run.sh

@@ -0,0 +1,20 @@
+#!/bin/bash
+set -eo pipefail
+
+os="unix"
+if [[ "$MACHINE" == "Windows" ]]; then
+  os="win"
+fi
+
+bash ../scripts/compile src/interactor-a-plus-b.cpp
+bash ../scripts/test-ref r-interactor-a-plus-b-1-1 "$VALGRIND" ./interactor-a-plus-b files/"$os"/input.01 output.01 < files/"$os"/participant.01
+tr -d '\r' < output.01 > output.01.nix
+bash ../scripts/test-ref r-interactor-a-plus-b-1-2 cat output.01.nix
+rm -f output.01 output.01.nix
+
+bash ../scripts/compile src/interactive-a-plus-b.cpp
+echo "Running 'java -jar files/crossrun/CrossRun.jar ./interactor-a-plus-b files/"$os"/input.01 output.02 -- ./interactive-a-plus-b'"
+java -jar files/crossrun/CrossRun.jar ./interactor-a-plus-b files/"$os"/input.01 output.02 -- ./interactive-a-plus-b
+tr -d '\r' < output.02 > output.02.nix
+bash ../scripts/test-ref r-interactor-a-plus-b-2-1 cat output.02.nix
+rm -f output.02 output.02.nix interactive-a-plus-b interactive-a-plus-b.exe interactor-a-plus-b interactor-a-plus-b.exe interactive_runner.out interactive_runner.err

+ 9 - 0
tests/test-006_interactors/src/interactive-a-plus-b.cpp

@@ -0,0 +1,9 @@
+#include <iostream>
+
+using namespace std;
+
+int main() {
+    int a, b;
+    while (cin >> a >> b)
+        cout << a + b << endl;
+}

+ 122 - 0
tests/test-006_interactors/src/interactive_runner.py

@@ -0,0 +1,122 @@
+# This code can be run as python2 or python3 in most systems.
+#
+# This is a small program that runs two processes, connecting the stdin of each
+# one to the stdout of the other.
+# It doesn't perform a lot of checking, so many errors may
+# be caught internally by Python (e.g., if your command line has incorrect
+# syntax) or not caught at all (e.g., if the judge or solution hangs).
+#
+# Run this as:
+# python interactive_runner.py <cmd_line_judge> -- <cmd_line_solution>
+#
+# For example, if you have a testing_tool.py in python3 (that takes a single
+# integer as a command line parameter) to use as judge -- like one
+# downloaded from a problem statement -- and you would run your solution
+# in a standalone using one of the following:
+#   1. python3 my_solution.py
+#   2. ./my_solution
+#   3. java Solution
+#   4. my_solution.exe
+# Then you could run the judge and solution together, using this, as:
+#   1. python interactive_runner.py python3 testing_tool.py 0 -- python3 my_solution.py
+#   2. python interactive_runner.py python3 testing_tool.py 0 -- ./my_solution
+#   3. python interactive_runner.py python3 testing_tool.py 0 -- java solution
+#   4. python interactive_runner.py python3 testing_tool.py 0 -- my_solution.exe
+# Notice that the solution in cases 2, 3 and 4 would usually have a
+# compilation step before running, which you should run in your usual way
+# before using this tool.
+#
+# This is only intended as a convenient tool to help contestants test solutions
+# locally. In particular, it is not identical to the implementation on our
+# server, which is more complex.
+#
+# The standard streams are handled the following way:
+# - judge's stdin is connected to the solution's stdout;
+# - judge's stdout is connected to the solution's stdin;
+# - stderrs of both judge and solution are piped to standard error stream, with
+#   lines prepended by "judge: " or "sol: " respectively (note, no
+#   synchronization is done so it's possible for the messages from both programs
+#   to overlap with each other).
+
+from __future__ import print_function
+import sys, subprocess, threading
+
+class SubprocessThread(threading.Thread):
+  def __init__(self,
+               args,
+               stdin_pipe=subprocess.PIPE,
+               stdout_pipe=subprocess.PIPE,
+               stderr_prefix=None):
+    threading.Thread.__init__(self)
+    self.stderr_prefix = stderr_prefix
+    self.p = subprocess.Popen(
+        args, stdin=stdin_pipe, stdout=stdout_pipe, stderr=subprocess.PIPE)
+
+  def run(self):
+    try:
+      self.pipeToStdErr(self.p.stderr)
+      self.return_code = self.p.wait()
+      self.error_message = None
+    except (SystemError, OSError):
+      self.return_code = -1
+      self.error_message = "The process crashed or produced too much output."
+
+  # Reads bytes from the stream and writes them to sys.stderr prepending lines
+  # with self.stderr_prefix.
+  # We are not reading by lines to guard against the case when EOL is never
+  # found in the stream.
+  def pipeToStdErr(self, stream):
+    new_line = True
+    while True:
+      chunk = stream.readline(1)
+      if not chunk:
+        return
+      chunk = chunk.decode("UTF-8")
+      if new_line and self.stderr_prefix:
+        chunk = self.stderr_prefix + chunk
+        new_line = False
+      sys.stderr.write(chunk)
+      if chunk.endswith("\n"):
+        new_line = True
+      sys.stderr.flush()
+
+
+assert sys.argv.count("--") == 1, (
+    "There should be exactly one instance of '--' in the command line.")
+sep_index = sys.argv.index("--")
+judge_args = sys.argv[1:sep_index]
+sol_args = sys.argv[sep_index + 1:]
+
+t_sol = SubprocessThread(sol_args, stderr_prefix="  sol: ")
+t_judge = SubprocessThread(
+    judge_args,
+    stdin_pipe=t_sol.p.stdout,
+    stdout_pipe=t_sol.p.stdin,
+    stderr_prefix="judge: ")
+t_sol.start()
+t_judge.start()
+t_sol.join()
+t_judge.join()
+
+# Print an empty line to handle the case when stderr doesn't print EOL.
+print()
+print("Judge return code:", t_judge.return_code)
+if t_judge.error_message:
+  print("Judge error message:", t_judge.error_message)
+
+print("Solution return code:", t_sol.return_code)
+if t_sol.error_message:
+  print("Solution error message:", t_sol.error_message)
+
+if t_sol.return_code:
+  print("A solution finishing with exit code other than 0 (without exceeding "
+        "time or memory limits) would be interpreted as a Runtime Error "
+        "in the system.")
+elif t_judge.return_code:
+  print("A solution finishing with exit code 0 (without exceeding time or "
+        "memory limits) and a judge finishing with exit code other than 0 "
+        "would be interpreted as a Wrong Answer in the system.")
+else:
+  print("A solution and judge both finishing with exit code 0 (without "
+        "exceeding time or memory limits) would be interpreted as Correct "
+        "in the system.")

+ 26 - 0
tests/test-006_interactors/src/interactor-a-plus-b.cpp

@@ -0,0 +1,26 @@
+#include "testlib.h"
+#include <iostream>
+
+using namespace std;
+
+int main(int argc, char *argv[]) {
+    setName("Interactor A+B");
+    registerInteraction(argc, argv);
+
+    // reads number of queries from test (input) file
+    int n = inf.readInt();
+    for (int i = 0; i < n; i++) {
+        // reads query from test (input) file
+        int a = inf.readInt();
+        int b = inf.readInt();
+
+        // writes query to the solution, endl makes flush
+        cout << a << " " << b << endl;
+
+        // writes output file to be verified by checker later
+        tout << ouf.readInt() << endl;
+    }
+
+    // just message
+    quitf(_ok, "%d queries processed", n);
+}

Niektoré súbory nie sú zobrazené, pretože je v týchto rozdielových dátach zmenené mnoho súborov