Skip to content

Commit 09b056a

Browse files
PercentBoat4164TheLartiansiboB
authored
Add file locking to support parallel runs. (#427)
* Add file locking to support parallel runs. * Fixed formatting. * Prevent double locking file. * Fix SegFault from test 2. * Remove unnecessary debugging messages. * Lock the package directory rather than the cache directory. Only synchronize if CPM_SOURCE_CACHE is defined. * Lock the version specific cache entry rather than the package specific entry. * Remove unnecessary arguments in conditional statements. * Change back to locking entire cache directory. * Only check CPM_HAS_CACHE_LOCK. * Lock on a per-package basis rather than the entire cache. * Clean up the locked file. * Unlock then remove to fix Windows. * Specify use of cmake.lock as the lock file. * - Changed CPM_HAS_CACHE_LOCK to ${CPM_ARGS_NAME}_CPM_HAS_CACHE_LOCK. - Removed redundant variable initialization. * Add unit test. * Actually test if resulting git cache is clean in unit test. * - Added comments - Fixed formatting - Removed unnecessary imports * convert parallelism test to integration test * remove comment * - Removed now unnecessary variable. - Only delete file instead of unlocking it then deleting it. * Forgot to change variable name. * Add similar changes to the missed section. * Fixed formatting. * Unlock the file, but do not delete it. * Only unlock the file if it exists. * Changed cache.cmake test to ignore non-directory entries. * Integration test lib make_project: * keyword args * 'name' arg to allow multiple projects from the same test * - Moved checks to function. - Fixed small grammatical errors. * - Fix formatting * Switch to snake case. --------- Co-authored-by: Lars Melchior <[email protected]> Co-authored-by: Lars Melchior <[email protected]> Co-authored-by: Borislav Stanimirov <[email protected]>
1 parent d34d2a8 commit 09b056a

10 files changed

+60
-28
lines changed

cmake/CPM.cmake

+7
Original file line numberDiff line numberDiff line change
@@ -712,6 +712,9 @@ function(CPMAddPackage)
712712
# relative paths.
713713
get_filename_component(download_directory ${download_directory} ABSOLUTE)
714714
list(APPEND CPM_ARGS_UNPARSED_ARGUMENTS SOURCE_DIR ${download_directory})
715+
716+
file(LOCK ${download_directory}/../cmake.lock)
717+
715718
if(EXISTS ${download_directory})
716719
cpm_store_fetch_properties(
717720
${CPM_ARGS_NAME} "${download_directory}"
@@ -790,6 +793,10 @@ function(CPMAddPackage)
790793
cpm_get_fetch_properties("${CPM_ARGS_NAME}")
791794
endif()
792795

796+
if(EXISTS ${download_directory}/../cmake.lock)
797+
file(LOCK ${download_directory}/../cmake.lock RELEASE)
798+
endif()
799+
793800
set(${CPM_ARGS_NAME}_ADDED YES)
794801
cpm_export_variables("${CPM_ARGS_NAME}")
795802
endfunction()

test/integration/lib.rb

+6-5
Original file line numberDiff line numberDiff line change
@@ -180,19 +180,20 @@ def cur_test_dir
180180
@@test_dir
181181
end
182182

183-
def make_project(template_dir = nil)
183+
def make_project(name: nil, from_template: nil)
184184
test_name = local_name
185185
test_name = test_name[5..] if test_name.start_with?('test_')
186186

187187
base = File.join(cur_test_dir, test_name)
188+
base += "-#{name}" if name
188189
src_dir = base + '-src'
189190

190191
FileUtils.mkdir_p src_dir
191192

192-
if template_dir
193-
template_dir = File.join(TestLib::TEMPLATES_DIR, template_dir)
194-
raise "#{template_dir} is not a directory" if !File.directory?(template_dir)
195-
FileUtils.copy_entry template_dir, src_dir
193+
if from_template
194+
from_template = File.join(TestLib::TEMPLATES_DIR, from_template)
195+
raise "#{from_template} is not a directory" if !File.directory?(from_template)
196+
FileUtils.copy_entry from_template, src_dir
196197
end
197198

198199
Project.new src_dir, base + '-bin'

test/integration/reference.md

+4-3
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# Integration Test Framework Refernce
1+
# Integration Test Framework Reference
22

33
## `TestLib`
44

@@ -60,6 +60,7 @@ The class which must be a parent of all integration test case classes. It itself
6060
### Utils
6161

6262
* `cur_test_dir` - the directory of the current test case. A subdirectory of `TestLib::TMP_DIR`
63-
* `make_project(template_dir = nil)` - create a project from a test method. Will create a the project's source and binary directories as subdirectories of `cur_test_dir`.
64-
* Optionally work with a template directory, in which case it will copy the contents of the template directory (one from `templates`) in the project's source directory.
63+
* `make_project(name: nil, from_template: nil)` - create a project from a test method. Will create the project's source and binary directories as subdirectories of `cur_test_dir`.
64+
* Optionally provide a name which will be concatenated to the project directory. This allows creating multiple projects in a test
65+
* Optionally work with a template, in which case it will copy the contents of the template directory (one from `templates`) in the project's source directory.
6566

test/integration/test_basics.rb

+2-2
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
class Basics < IntegrationTest
66
# Test cpm caches with no cpm-related env vars
77
def test_cpm_default
8-
prj = make_project 'no-deps'
8+
prj = make_project from_template: 'no-deps'
99
prj.create_lists_from_default_template
1010
assert_success prj.configure
1111

@@ -38,7 +38,7 @@ def test_cpm_default
3838
def test_env_cpm_source_cache
3939
ENV['CPM_SOURCE_CACHE'] = cur_test_dir
4040

41-
prj = make_project 'no-deps'
41+
prj = make_project from_template: 'no-deps'
4242
prj.create_lists_from_default_template
4343
assert_success prj.configure
4444

test/integration/test_fetchcontent_compatibility.rb

+2-2
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,8 @@ def setup
99
end
1010

1111
def test_add_dependency_cpm_and_fetchcontent
12-
prj = make_project 'using-adder'
13-
12+
prj = make_project from_template: 'using-adder'
13+
1414
prj.create_lists_from_default_template package: <<~PACK
1515
CPMAddPackage(
1616
NAME testpack-adder

test/integration/test_parallelism.rb

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
require_relative './lib'
2+
3+
class Parallelism < IntegrationTest
4+
def setup
5+
@cache_dir = File.join(cur_test_dir, 'cpmcache')
6+
ENV['CPM_SOURCE_CACHE'] = @cache_dir
7+
end
8+
9+
def test_populate_cache_in_parallel
10+
4.times.map { |i|
11+
prj = make_project name: i.to_s, from_template: 'using-fibadder'
12+
prj.create_lists_from_default_template package: 'CPMAddPackage("gh:cpm-cmake/[email protected]")'
13+
prj
14+
}.map { |prj|
15+
Thread.new do
16+
assert_success prj.configure
17+
assert_success prj.build
18+
end
19+
}.map(&:join)
20+
end
21+
end

test/integration/test_remove_source_dir.rb

+2-2
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@
22

33
class RemoveSourceDir < IntegrationTest
44
def test_remove_source_dir
5-
prj = make_project 'using-adder'
6-
5+
prj = make_project from_template: 'using-adder'
6+
77
prj.create_lists_from_default_template package: <<~PACK
88
CPMAddPackage(
99
NAME testpack-adder

test/integration/test_simple.rb

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ class Simple < IntegrationTest
44
ADDER_PACKAGE_NAME = 'testpack-adder'
55

66
def test_update_single_package
7-
prj = make_project 'using-adder'
7+
prj = make_project from_template: 'using-adder'
88
adder_cache0 = nil
99
adder_ver_file = nil
1010

test/integration/test_source_cache.rb

+2-2
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ def setup
99
end
1010

1111
def test_add_remove_dependency
12-
prj = make_project 'using-fibadder'
12+
prj = make_project from_template: 'using-fibadder'
1313

1414
###################################
1515
# create
@@ -45,7 +45,7 @@ def test_add_remove_dependency
4545
end
4646

4747
def test_second_project
48-
prj = make_project 'using-fibadder'
48+
prj = make_project from_template: 'using-fibadder'
4949
prj.create_lists_from_default_template package: 'CPMAddPackage("gh:cpm-cmake/[email protected]")'
5050
assert_success prj.configure
5151

test/unit/cache.cmake

+13-11
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,17 @@ function(reset_test)
2626
update_cmake_lists()
2727
endfunction()
2828

29+
function(assert_cache_directory_count directory count)
30+
set(version_count 0)
31+
file(GLOB potential_versions ${directory})
32+
foreach(entry ${potential_versions})
33+
if(IS_DIRECTORY ${entry})
34+
math(EXPR version_count "${version_count} + 1")
35+
endif()
36+
endforeach()
37+
assert_equal("${version_count}" "${count}")
38+
endfunction()
39+
2940
set(FIBONACCI_VERSION 1.0)
3041

3142
# Read CPM_SOURCE_CACHE from arguments
@@ -40,26 +51,17 @@ execute_process(
4051
assert_equal(${ret} "0")
4152
assert_exists("${CPM_SOURCE_CACHE_DIR}/fibonacci")
4253

43-
file(GLOB FIBONACCI_VERSIONs "${CPM_SOURCE_CACHE_DIR}/fibonacci/*")
44-
list(LENGTH FIBONACCI_VERSIONs FIBONACCI_VERSION_count)
45-
assert_equal(${FIBONACCI_VERSION_count} "1")
46-
47-
file(GLOB fibonacci_versions "${CPM_SOURCE_CACHE_DIR}/fibonacci/*")
48-
list(LENGTH fibonacci_versions fibonacci_version_count)
49-
assert_equal(${fibonacci_version_count} "1")
54+
assert_cache_directory_count("${CPM_SOURCE_CACHE_DIR}/fibonacci/*" 1)
5055

5156
# Update dependency and keep CPM_SOURCE_CACHE
5257

5358
set(FIBONACCI_VERSION 2.0)
5459
update_cmake_lists()
5560

5661
execute_process(COMMAND ${CMAKE_COMMAND} ${TEST_BUILD_DIR} RESULT_VARIABLE ret)
57-
5862
assert_equal(${ret} "0")
5963

60-
file(GLOB FIBONACCI_VERSIONs "${CPM_SOURCE_CACHE_DIR}/fibonacci/*")
61-
list(LENGTH FIBONACCI_VERSIONs FIBONACCI_VERSION_count)
62-
assert_equal(${FIBONACCI_VERSION_count} "2")
64+
assert_cache_directory_count("${CPM_SOURCE_CACHE_DIR}/fibonacci/*" 2)
6365

6466
# Clear cache and update
6567

0 commit comments

Comments
 (0)