Skip to content
This repository was archived by the owner on Feb 4, 2020. It is now read-only.
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
* text eol=crlf
40 changes: 40 additions & 0 deletions integrationtests.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@
import sys
import tempfile
import unittest
import time
import concurrent.futures

import clcache

Expand Down Expand Up @@ -1071,6 +1073,44 @@ def testHitsViaMpConcurrent(self):
self.assertEqual(stats.numCacheMisses(), 2)
self.assertEqual(stats.numCacheEntries(), 2)

class TestConcurrent(unittest.TestCase):
@staticmethod
def runCompiler():
with cd(os.path.join(ASSETS_DIR, "hits-and-misses")):
cmd = CLCACHE_CMD + ["/nologo", "/EHsc", "/c", 'hit.cpp']
return subprocess.check_call(cmd)

def testRaceAddingAnObject(self):
""" This tests attempts to expose a race condition when two clcache invocations decide to add an object to the
cache at the same time """

# object cache key
cachekey = '5080f03ed6fda8fecd7562c0fad99926'

# Obtain final object lock and write the object file
cache = clcache.Cache()
section = cache.compilerArtifactsRepository.section(cachekey)
section.lock.acquire()

executor = concurrent.futures.ThreadPoolExecutor(max_workers=1)
compilerTask = executor.submit(TestConcurrent.runCompiler)

# Give the clcache process time to get locked acquiring the artifactsSection lock
time.sleep(5)

# Replacing artifacts
print('Replacing artifacts')
artifactsPath = lambda objectName: os.path.join(section.cacheEntryDir(cachekey), objectName)
artifacts = [artifactsPath('object'), artifactsPath('output.txt'), artifactsPath('stderr.txt')]
clcache.ensureDirectoryExists(section.cacheEntryDir(cachekey))
for artifact in artifacts:
with open(artifact, 'w+') as f:
f.write('dummy')

section.lock.release()

timeoutSeconds = 5
self.assertEqual(0, compilerTask.result(timeout=timeoutSeconds))

class TestBasedir(unittest.TestCase):
def testBasedir(self):
Expand Down