This repository was archived by the owner on Feb 4, 2020. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 82
Handle base dir in get manifest hash #238
Merged
Merged
Changes from 3 commits
Commits
Show all changes
6 commits
Select commit
Hold shift + click to select a range
52fe08c
Make ASSETS_DIR an absolute path
siu 4ec76a1
Add more integration tests to TestBasedir
siu 4b3cdd9
Handle CLCACHE_BASEDIR in manifest hash computation
siu ea01aef
Remove trailing separator in normalizeBaseDir
siu 69dfb04
Minor cleanup: variable names
siu 7d45cb3
Update comment
siu File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -24,7 +24,7 @@ | |
|
|
||
| PYTHON_BINARY = sys.executable | ||
| CLCACHE_SCRIPT = os.path.join(os.path.dirname(os.path.realpath(__file__)), "clcache.py") | ||
| ASSETS_DIR = os.path.join("tests", "integrationtests") | ||
| ASSETS_DIR = os.path.join(os.path.dirname(os.path.realpath(__file__)), "tests", "integrationtests") | ||
|
Owner
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I have a suspicion, but I'm not quite sure - why did you change this?
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This was changed only to simplify the code in TestBasedir. The cwd is changed with
Owner
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I see, makes sense! 👍 |
||
|
|
||
| # pytest-cov note: subprocesses are coverage tested by default with some limitations | ||
| # "For subprocess measurement environment variables must make it from the main process to the | ||
|
|
@@ -1073,37 +1073,102 @@ def testHitsViaMpConcurrent(self): | |
|
|
||
|
|
||
| class TestBasedir(unittest.TestCase): | ||
| def testBasedir(self): | ||
| with cd(os.path.join(ASSETS_DIR, "basedir")), tempfile.TemporaryDirectory() as tempDir: | ||
| # First, create two separate build directories with the same sources | ||
| for buildDir in ["builddir_a", "builddir_b"]: | ||
| shutil.rmtree(buildDir, ignore_errors=True) | ||
| os.mkdir(buildDir) | ||
| def setUp(self): | ||
| self.projectDir = os.path.join(ASSETS_DIR, "basedir") | ||
| self.tempDir = tempfile.TemporaryDirectory() | ||
| self.clcacheDir = os.path.join(self.tempDir.name, "clcache") | ||
| self.savedCwd = os.getcwd() | ||
|
|
||
| os.chdir(self.tempDir.name) | ||
|
|
||
| # First, create two separate build directories with the same sources | ||
| for buildDir in ["builddir_a", "builddir_b"]: | ||
| shutil.copytree(self.projectDir, buildDir) | ||
|
|
||
| self.cache = clcache.Cache(self.clcacheDir) | ||
|
|
||
| def tearDown(self): | ||
| os.chdir(self.savedCwd) | ||
| self.tempDir.cleanup() | ||
|
|
||
| def _runCompiler(self, cppFile, extraArgs=None): | ||
| cmd = CLCACHE_CMD + ["/nologo", "/EHsc", "/c"] | ||
| if extraArgs: | ||
| cmd.extend(extraArgs) | ||
| cmd = cmd + [cppFile] | ||
| env = dict(os.environ, CLCACHE_DIR=self.clcacheDir, CLCACHE_BASEDIR=os.getcwd()) | ||
| self.assertEqual(subprocess.call(cmd, env=env), 0) | ||
|
|
||
| def expectHit(self, runCompiler): | ||
| # Build once in one directory | ||
| with cd("builddir_a"): | ||
| runCompiler[0]() | ||
| with self.cache.statistics as stats: | ||
| self.assertEqual(stats.numCacheMisses(), 1) | ||
| self.assertEqual(stats.numCacheHits(), 0) | ||
|
|
||
| shutil.copy("main.cpp", buildDir) | ||
| shutil.copy("constants.h", buildDir) | ||
| # Build again in a different directory, this should hit now because of CLCACHE_BASEDIR | ||
| with cd("builddir_b"): | ||
| runCompiler[1]() | ||
| with self.cache.statistics as stats: | ||
| self.assertEqual(stats.numCacheMisses(), 1) | ||
| self.assertEqual(stats.numCacheHits(), 1) | ||
|
|
||
| cache = clcache.Cache(tempDir) | ||
| def expectMiss(self, runCompiler): | ||
| # Build once in one directory | ||
| with cd("builddir_a"): | ||
| runCompiler[0]() | ||
| with self.cache.statistics as stats: | ||
| self.assertEqual(stats.numCacheMisses(), 1) | ||
| self.assertEqual(stats.numCacheHits(), 0) | ||
|
|
||
| # Build again in a different directory, this should hit now because of CLCACHE_BASEDIR | ||
| with cd("builddir_b"): | ||
| runCompiler[1]() | ||
| with self.cache.statistics as stats: | ||
| self.assertEqual(stats.numCacheMisses(), 2) | ||
| self.assertEqual(stats.numCacheHits(), 0) | ||
|
|
||
| def testBasedirRelativePaths(self): | ||
| def runCompiler(): | ||
| self._runCompiler("main.cpp") | ||
| self.expectHit([runCompiler, runCompiler]) | ||
|
|
||
| def testBasedirAbsolutePaths(self): | ||
| def runCompiler(): | ||
| self._runCompiler(os.path.join(os.getcwd(), "main.cpp")) | ||
| self.expectHit([runCompiler, runCompiler]) | ||
|
|
||
| def testBasedirIncludeArg(self): | ||
| def runCompiler(): | ||
| self._runCompiler("main.cpp", ["/I{}".format(os.getcwd())]) | ||
| self.expectHit([runCompiler, runCompiler]) | ||
|
|
||
| def testBasedirIncludeSlashes(self): | ||
| runCompiler1 = lambda: self._runCompiler("main.cpp", ["/I{}/".format(os.getcwd())]) | ||
| runCompiler2 = lambda: self._runCompiler("main.cpp", ["/I{}".format(os.getcwd())]) | ||
| self.expectHit([runCompiler1, runCompiler2]) | ||
|
|
||
| def testBasedirIncludeArgDifferentCapitalization(self): | ||
| def runCompiler(): | ||
| self._runCompiler("main.cpp", ["/I{}".format(os.getcwd().upper())]) | ||
| self.expectHit([runCompiler, runCompiler]) | ||
|
|
||
| def testBasedirDefineArg(self): | ||
| def runCompiler(): | ||
| self._runCompiler("main.cpp", ["/DRESOURCES_DIR={}".format(os.getcwd())]) | ||
| self.expectMiss([runCompiler, runCompiler]) | ||
|
|
||
| def testBasedirRelativeIncludeArg(self): | ||
| basedir = os.getcwd() | ||
|
|
||
| def runCompiler(cppFile="main.cpp"): | ||
| cmd = CLCACHE_CMD + ["/nologo", "/EHsc", "/c", "/I."] | ||
| cmd = cmd + [cppFile] | ||
| env = dict(os.environ, CLCACHE_DIR=self.clcacheDir, CLCACHE_BASEDIR=basedir) | ||
| self.assertEqual(subprocess.call(cmd, env=env), 0) | ||
|
|
||
| cmd = CLCACHE_CMD + ["/nologo", "/EHsc", "/c", "main.cpp"] | ||
|
|
||
| # Build once in one directory | ||
| with cd("builddir_a"): | ||
| env = dict(os.environ, CLCACHE_DIR=tempDir, CLCACHE_BASEDIR=os.getcwd()) | ||
| self.assertEqual(subprocess.call(cmd, env=env), 0) | ||
| with cache.statistics as stats: | ||
| self.assertEqual(stats.numCacheMisses(), 1) | ||
| self.assertEqual(stats.numCacheHits(), 0) | ||
|
|
||
| shutil.rmtree("builddir_a", ignore_errors=True) | ||
|
|
||
| # Build again in a different directory, this should hit now because of CLCACHE_BASEDIR | ||
| with cd("builddir_b"): | ||
| env = dict(os.environ, CLCACHE_DIR=tempDir, CLCACHE_BASEDIR=os.getcwd()) | ||
| self.assertEqual(subprocess.call(cmd, env=env), 0) | ||
| with cache.statistics as stats: | ||
| self.assertEqual(stats.numCacheMisses(), 1) | ||
| self.assertEqual(stats.numCacheHits(), 1) | ||
| self.expectMiss([runCompiler, runCompiler]) | ||
|
|
||
|
|
||
| class TestCleanCache(unittest.TestCase): | ||
|
|
||
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why do you use
sortedhere?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actually the sorted is very important to have repeatable manifest hashes. As dictionaries in python are unordered the only way to guarantee that we generate the same hash every invocation is to iterate over the keys in the same order. It is the same case that #235 solved.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah, so this basically improves the manifest cache hit rate, i.e. it's an improvement but not directly related to the BASEDIR feature? Ok.
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It is going to have that side effect but at same time it is needed for correctness since the implementation changed in this PR to use a dictionary.