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.

90 satır
3.3KB

  1. import subprocess
  2. import pytest
  3. from dds_ci.testing import ProjectOpener, Project
  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. @pytest.fixture()
  17. def test_project(project_opener: ProjectOpener) -> Project:
  18. return project_opener.open('projects/compile_deps')
  19. def build_and_get_rc(proj: Project) -> int:
  20. proj.build()
  21. app = proj.build_root.joinpath('app' + paths.EXE_SUFFIX)
  22. return proc.run([app]).returncode
  23. def test_simple_rebuild(test_project: Project) -> None:
  24. """
  25. Check that changing a source file will update the resulting application.
  26. """
  27. assert build_and_get_rc(test_project) == 0
  28. test_project.write('src/1.cpp', 'int value_1() { return 33; }')
  29. # 33 - 32 = 1
  30. assert build_and_get_rc(test_project) == 1
  31. def test_rebuild_header_change(test_project: Project) -> None:
  32. """Change the content of the header which defines the values"""
  33. assert build_and_get_rc(test_project) == 0
  34. test_project.write('src/values.hpp', '''
  35. const int first_value = 63;
  36. const int second_value = 88;
  37. ''')
  38. assert build_and_get_rc(test_project) == (88 - 63)
  39. def test_partial_build_rebuild(test_project: Project) -> None:
  40. """
  41. Change the content of a header, but cause one user of that header to fail
  42. compilation. The fact that compilation fails means it is still `out-of-date`,
  43. and will need to be compiled after we have fixed it up.
  44. """
  45. assert build_and_get_rc(test_project) == 0
  46. test_project.write('src/values.hpp', '''
  47. const int first_value_q = 6;
  48. const int second_value_q = 99;
  49. ''')
  50. # Header now causes errors in 1.cpp and 2.cpp
  51. with pytest.raises(subprocess.CalledProcessError):
  52. test_project.build()
  53. # Fix 1.cpp
  54. test_project.write('src/1.cpp', '''
  55. #include "./values.hpp"
  56. int value_1() { return first_value_q; }
  57. ''')
  58. # We will still see a failure, but now the DB will record the updated values.hpp
  59. with pytest.raises(subprocess.CalledProcessError):
  60. test_project.build()
  61. # Should should raise _again_, even though we've successfully compiled one
  62. # of the two files with the changed `values.hpp`, because `2.cpp` still
  63. # has a pending update
  64. with pytest.raises(subprocess.CalledProcessError):
  65. test_project.build()
  66. # Pause long enough for timestamps to change
  67. test_project.write('src/2.cpp', '''
  68. #include "./values.hpp"
  69. int value_2() { return second_value_q; }
  70. ''')
  71. # We should now compile and link to get the updated value
  72. assert build_and_get_rc(test_project) == (99 - 6)