You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

106 lines
3.4KB

  1. import subprocess
  2. import pytest
  3. from tests import DDS
  4. from dds_ci import proc, paths
  5. ## #############################################################################
  6. ## #############################################################################
  7. ## The test project in this directory contains a single application and two
  8. ## functions, each defined in a separate file. The two functions each return
  9. ## an integer, and the application exit code will be the difference between
  10. ## the two integers. (They are passed through std::abs(), so it is always a
  11. ## positive integer). The default value is 32 in both functions.
  12. ## #############################################################################
  13. ## The purpose of these tests is to ensure the reliability of the compilation
  14. ## dependency database. Having a miscompile because there was a failure to
  15. ## detect file changes is a catastrophic bug!
  16. def build_and_get_rc(dds: DDS) -> int:
  17. dds.build()
  18. app = dds.build_dir / ('app' + paths.EXE_SUFFIX)
  19. return proc.run([app]).returncode
  20. def test_simple_rebuild(dds: DDS) -> None:
  21. """
  22. Check that changing a source file will update the resulting application.
  23. """
  24. assert build_and_get_rc(dds) == 0
  25. dds.scope.enter_context(
  26. dds.set_contents(
  27. 'src/1.cpp',
  28. b'''
  29. int value_1() { return 33; }
  30. ''',
  31. ))
  32. # 33 - 32 = 1
  33. assert build_and_get_rc(dds) == 1
  34. def test_rebuild_header_change(dds: DDS) -> None:
  35. """Change the content of the header which defines the values"""
  36. assert build_and_get_rc(dds) == 0
  37. dds.scope.enter_context(
  38. dds.set_contents(
  39. 'src/values.hpp',
  40. b'''
  41. const int first_value = 63;
  42. const int second_value = 88;
  43. ''',
  44. ))
  45. assert build_and_get_rc(dds) == (88 - 63)
  46. def test_partial_build_rebuild(dds: DDS) -> None:
  47. """
  48. Change the content of a header, but cause one user of that header to fail
  49. compilation. The fact that compilation fails means it is still `out-of-date`,
  50. and will need to be compiled after we have fixed it up.
  51. """
  52. assert build_and_get_rc(dds) == 0
  53. dds.scope.enter_context(
  54. dds.set_contents(
  55. 'src/values.hpp',
  56. b'''
  57. const int first_value_q = 6;
  58. const int second_value_q = 99;
  59. ''',
  60. ))
  61. # Header now causes errors in 1.cpp and 2.cpp
  62. with pytest.raises(subprocess.CalledProcessError):
  63. dds.build()
  64. # Fix 1.cpp
  65. dds.scope.enter_context(
  66. dds.set_contents(
  67. 'src/1.cpp',
  68. b'''
  69. #include "./values.hpp"
  70. int value_1() { return first_value_q; }
  71. ''',
  72. ))
  73. # We will still see a failure, but now the DB will record the updated values.hpp
  74. with pytest.raises(subprocess.CalledProcessError):
  75. dds.build()
  76. # Should should raise _again_, even though we've successfully compiled one
  77. # of the two files with the changed `values.hpp`, because `2.cpp` still
  78. # has a pending update
  79. with pytest.raises(subprocess.CalledProcessError):
  80. dds.build()
  81. dds.scope.enter_context(
  82. dds.set_contents(
  83. 'src/2.cpp',
  84. b'''
  85. #include "./values.hpp"
  86. int value_2() { return second_value_q; }
  87. ''',
  88. ))
  89. # We should now compile and link to get the updated value
  90. assert build_and_get_rc(dds) == (99 - 6)