summaryrefslogtreecommitdiffstats
path: root/src/engine/SCons/Sig
diff options
context:
space:
mode:
authorSteven Knight <knight@baldmt.com>2004-05-30 19:17:38 (GMT)
committerSteven Knight <knight@baldmt.com>2004-05-30 19:17:38 (GMT)
commit78b110985d41c80a1803e95f3f9fe7280a0c1cb1 (patch)
tree965379d611026b1b16b9b7e0d78bc130c1f664ae /src/engine/SCons/Sig
parentd941bfd4f886fc6b2a3f70d3f2f8e76b88bb4c9b (diff)
downloadSCons-78b110985d41c80a1803e95f3f9fe7280a0c1cb1.zip
SCons-78b110985d41c80a1803e95f3f9fe7280a0c1cb1.tar.gz
SCons-78b110985d41c80a1803e95f3f9fe7280a0c1cb1.tar.bz2
Eliminate the refactored-out-of-existence Sig.Calculator methods (whose jobs are now handled by Node methods). Stop tying calculators to Taskmaster objects, and eliminate the unused Taskmaster.Calc class.
Diffstat (limited to 'src/engine/SCons/Sig')
-rw-r--r--src/engine/SCons/Sig/SigTests.py372
-rw-r--r--src/engine/SCons/Sig/__init__.py127
2 files changed, 7 insertions, 492 deletions
diff --git a/src/engine/SCons/Sig/SigTests.py b/src/engine/SCons/Sig/SigTests.py
index 4390a60..8964c5c 100644
--- a/src/engine/SCons/Sig/SigTests.py
+++ b/src/engine/SCons/Sig/SigTests.py
@@ -24,393 +24,31 @@
__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
import unittest
-import TestCmd
import SCons.Sig
-import SCons.Sig.MD5
-import SCons.Sig.TimeStamp
import sys
-
-class DummyFile:
- """A class that simulates a file for testing purposes"""
- def __init__(self, path, contents, timestamp, builder):
- self.path = path
- self.contents = contents
- self.timestamp = timestamp
- self.builder = builder
-
- def modify(self, contents, timestamp):
- self.contents = contents
- self.timestamp = timestamp
-
-class DummyNode:
- """A node workalike for testing purposes"""
-
- def __init__(self, file):
- self.file = file
- self.path = file.path
- self.builder = file.builder
- self.depends = []
- self.ignore = []
- self.use_signature = 1
- self.bsig = None
- self.csig = None
- self.oldtime = 0
- self.oldbsig = 0
- self.oldcsig = 0
- self.always_build = 0
-
- def has_builder(self):
- return self.builder
-
- def get_contents(self):
- # a file that doesn't exist has no contents:
- assert self.exists()
-
- return self.file.contents
-
- def get_timestamp(self):
- # a file that doesn't exist has no timestamp:
- assert self.exists()
-
- return self.file.timestamp
-
- def exists(self):
- return not self.file.contents is None
-
- def cached_exists(self):
- try:
- return self.exists_cache
- except AttributeError:
- self.exists_cache = self.exists()
- return self.exists_cache
-
- def rexists(self):
- return not self.file.contents is None
-
- def children(self):
- return filter(lambda x, i=self.ignore: x not in i,
- self.sources + self.depends)
-
- def all_children(self):
- return self.sources + self.depends
-
- def current(self):
- if not self.exists():
- return 0
- return None
-
- def calc_signature(self, calc):
- if self.has_builder():
- return calc.bsig(self)
- else:
- return calc.csig(self)
-
- def set_binfo(self, bsig, bkids, bkidsigs, bact, bactsig):
- self.bsig = bsig
- self.bkids = bkids
- self.bkidsigs = bkidsigs
- self.bact = bact
- self.bactsig = bactsig
-
- def get_bsig(self):
- return self.bsig
-
- def store_bsig(self):
- pass
-
- def set_csig(self, csig):
- self.csig = csig
-
- def get_csig(self):
- return self.csig
-
- def store_csig(self):
- pass
-
- def get_prevsiginfo(self):
- return (self.oldtime, self.oldbsig, self.oldcsig)
-
- def get_stored_implicit(self):
- return None
-
- def store_timestamp(self):
- pass
-
- def get_executor(self):
- class Adapter:
- def get_contents(self):
- return 111
- def get_timestamp(self):
- return 222
- return Adapter()
-
-
-def create_files(test):
- args = [(test.workpath('f1.c'), 'blah blah', 111, 0), #0
- (test.workpath('f1'), None, 0, 1), #1
- (test.workpath('d1/f1.c'), 'blah blah', 111, 0), #2
- (test.workpath('d1/f1.h'), 'blah blah', 111, 0), #3
- (test.workpath('d1/f2.c'), 'blah blah', 111, 0), #4
- (test.workpath('d1/f3.h'), 'blah blah', 111, 0), #5
- (test.workpath('d1/f4.h'), 'blah blah', 111, 0), #6
- (test.workpath('d1/f1'), None, 0, 1), #7
- (test.workpath('d1/test.c'), 'blah blah', 111, 0),#8
- (test.workpath('d1/test.o'), None, 0, 1), #9
- (test.workpath('d1/test'), None, 0, 1)] #10
-
- files = map(lambda x: apply(DummyFile, x), args)
-
- return files
-
-def create_nodes(files):
- nodes = map(DummyNode, files)
-
- nodes[0].sources = []
- nodes[1].sources = [nodes[0]]
- nodes[2].sources = []
- nodes[3].sources = []
- nodes[4].sources = []
- nodes[5].sources = [nodes[6]]
- nodes[6].sources = [nodes[5]]
- nodes[7].sources = [nodes[2], nodes[4], nodes[3], nodes[5]]
- nodes[8].sources = []
- nodes[9].sources = [nodes[8]]
- nodes[10].sources = [nodes[9]]
-
- return nodes
-
-def current(calc, node):
- return calc.current(node, node.calc_signature(calc))
-
-def write(calc, nodes):
- for node in nodes:
- node.oldtime = node.file.timestamp
- node.oldbsig = calc.bsig(node)
- node.oldcsig = calc.csig(node)
-
-def clear(nodes):
- for node in nodes:
- node.csig = None
- node.bsig = None
-
class SConsignEntryTestCase(unittest.TestCase):
def runTest(self):
-
se = SCons.Sig.SConsignEntry()
assert hasattr(se, 'timestamp'), "no timestamp attribute"
assert hasattr(se, 'bsig'), "no bsig attribute"
assert hasattr(se, 'csig'), "no csig attribute"
assert hasattr(se, 'implicit'), "no implicit attribute"
-class SigTestBase:
-
- def runTest(self):
-
- test = TestCmd.TestCmd(workdir = '')
- test.subdir('d1')
-
- self.files = create_files(test)
- self.test_initial()
- self.test_built()
- self.test_modify()
- self.test_modify_same_time()
-
- def test_initial(self):
-
- nodes = create_nodes(self.files)
- calc = SCons.Sig.Calculator(self.module)
-
- for node in nodes:
- self.failUnless(not current(calc, node),
- "node %s should not be current" % node.path)
-
- # simulate a build:
- self.files[1].modify('built', 222)
- self.files[7].modify('built', 222)
- self.files[9].modify('built', 222)
- self.files[10].modify('built', 222)
-
- def test_built(self):
-
- nodes = create_nodes(self.files)
-
- calc = SCons.Sig.Calculator(self.module)
-
- write(calc, nodes)
-
- for node in nodes:
- self.failUnless(current(calc, node),
- "node %s should be current" % node.path)
-
- def test_modify(self):
-
- nodes = create_nodes(self.files)
-
- calc = SCons.Sig.Calculator(self.module)
-
- write(calc, nodes)
-
- #simulate a modification of some files
- self.files[0].modify('blah blah blah', 333)
- self.files[3].modify('blah blah blah', 333)
- self.files[6].modify('blah blah blah', 333)
- self.files[8].modify('blah blah blah', 333)
-
- clear(nodes)
-
- self.failUnless(not current(calc, nodes[0]), "modified directly")
- self.failUnless(not current(calc, nodes[1]), "direct source modified")
- self.failUnless(current(calc, nodes[2]))
- self.failUnless(not current(calc, nodes[3]), "modified directly")
- self.failUnless(current(calc, nodes[4]))
- self.failUnless(current(calc, nodes[5]))
- self.failUnless(not current(calc, nodes[6]), "modified directly")
- self.failUnless(not current(calc, nodes[7]), "indirect source modified")
- self.failUnless(not current(calc, nodes[8]), "modified directory")
- self.failUnless(not current(calc, nodes[9]), "direct source modified")
- self.failUnless(not current(calc, nodes[10]), "indirect source modified")
-
- def test_modify_same_time(self):
-
- nodes = create_nodes(self.files)
-
- calc = SCons.Sig.Calculator(self.module, 0)
-
- write(calc, nodes)
-
- #simulate a modification of some files without changing the timestamp:
- self.files[0].modify('blah blah blah blah', 333)
- self.files[3].modify('blah blah blah blah', 333)
- self.files[6].modify('blah blah blah blah', 333)
- self.files[8].modify('blah blah blah blah', 333)
-
- clear(nodes)
-
- for node in nodes:
- self.failUnless(current(calc, node),
- "node %s should be current" % node.path)
-
-
-class MD5TestCase(unittest.TestCase, SigTestBase):
- """Test MD5 signatures"""
-
- module = SCons.Sig.MD5
-
-class TimeStampTestCase(unittest.TestCase, SigTestBase):
- """Test timestamp signatures"""
-
- module = SCons.Sig.TimeStamp
-
-class CalcTestCase(unittest.TestCase):
+class CalculatorTestCase(unittest.TestCase):
def runTest(self):
class MySigModule:
- def collect(self, signatures):
- return reduce(lambda x, y: x + y, signatures)
- def current(self, newsig, oldsig):
- return newsig == oldsig
- def signature(self, node):
- return node.get_csig()
-
- class MyNode:
- def __init__(self, name, bsig, csig):
- self.name = name
- self.bsig = bsig
- self.csig = csig
- self.kids = []
- self.ignore = []
- self.builder = None
- self.use_signature = 1
- def has_builder(self):
- return not self.builder is None
- def children(self):
- return filter(lambda x, i=self.ignore: x not in i, self.kids)
- def all_children(self):
- return self.kids
- def exists(self):
- return 1
- def cached_exists(self):
- return 1
- def get_bsig(self):
- return self.bsig
- def set_binfo(self, bsig, bkids, bkidsig, bact, bactsig):
- self.bsig = bsig
- self.bkids = bkids
- self.bkidsigs = bkidsigs
- self.bact = bact
- self.bactsig = bactsig
- def get_csig(self):
- return self.csig
- def set_csig(self, csig):
- self.csig = csig
- def store_csig(self):
- pass
- def store_timestamp(self):
- pass
- def get_prevsiginfo(self):
- return 0, self.bsig, self.csig
- def get_stored_implicit(self):
- return None
- def get_timestamp(self):
- return 1
- def builder_sig_adapter(self):
- class MyAdapter:
- def get_csig(self):
- return 333
- def get_timestamp(self):
- return 444
- return MyAdapter()
-
- self.module = MySigModule()
- self.nodeclass = MyNode
- self.test_Calc___init__()
- self.test_Calc_bsig()
- self.test_Calc_current()
-
- def test_Calc___init__(self):
- self.calc = SCons.Sig.Calculator(self.module)
- assert self.calc.module == self.module
-
- def test_Calc_bsig(self):
- n1 = self.nodeclass('n1', 11, 12)
- n2 = self.nodeclass('n2', 22, 23)
- n3 = self.nodeclass('n3', 33, 34)
- n1.builder = 1
- n1.kids = [n2, n3]
-
- assert self.calc.bsig(n1) == 55
-
- n1.ignore = [n2]
-
- assert self.calc.bsig(n1) == 33
-
- def test_Calc_bsig(self):
- n = self.nodeclass('n', 11, 12)
-
- assert self.calc.csig(n) == 12
-
- def test_Calc_current(self):
- class NN(self.nodeclass):
- always_build = 0
- def current(self):
- return None
-
- nn = NN('nn', 33, 34)
- assert not self.calc.current(nn, 30)
- assert self.calc.current(nn, 33)
- nn.always_build = 1
- assert not self.calc.current(nn, 33)
-
+ pass
+ calc = SCons.Sig.Calculator(MySigModule)
+ assert calc.module == MySigModule
def suite():
suite = unittest.TestSuite()
suite.addTest(SConsignEntryTestCase())
- suite.addTest(MD5TestCase())
- suite.addTest(TimeStampTestCase())
- suite.addTest(CalcTestCase())
+ suite.addTest(CalculatorTestCase())
return suite
if __name__ == "__main__":
diff --git a/src/engine/SCons/Sig/__init__.py b/src/engine/SCons/Sig/__init__.py
index 6626571..2a9680e 100644
--- a/src/engine/SCons/Sig/__init__.py
+++ b/src/engine/SCons/Sig/__init__.py
@@ -29,14 +29,6 @@ The Signature package for the scons software construction utility.
__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
-import cPickle
-import os
-import os.path
-import time
-
-import SCons.Node
-import SCons.Warnings
-
try:
import MD5
default_module = MD5
@@ -44,6 +36,8 @@ except ImportError:
import TimeStamp
default_module = TimeStamp
+# XXX We should move max_drift into Node/FS.py,
+# since it's really something about files.
default_max_drift = 2*24*60*60
class SConsignEntry:
@@ -72,121 +66,4 @@ class Calculator:
self.module = module
self.max_drift = max_drift
- def bsig(self, node, cache=None):
- """
- Generate a node's build signature, the digested signatures
- of its dependency files and build information.
-
- node - the node whose sources will be collected
- cache - alternate node to use for the signature cache
- returns - the build signature
-
- This no longer handles the recursive descent of the
- node's children's signatures. We expect that they're
- already built and updated by someone else, if that's
- what's wanted.
- """
-
- if cache is None: cache = node
-
- bsig = cache.get_bsig()
- if bsig is not None:
- return bsig
-
- children = node.children()
- bkids = map(str, children)
-
- # double check bsig, because the call to children() above may
- # have set it:
- bsig = cache.get_bsig()
- if bsig is not None:
- return bsig
-
- sigs = map(lambda n, c=self: n.calc_signature(c), children)
-
- if node.has_builder():
- executor = node.get_executor()
- bact = str(executor)
- bactsig = self.module.signature(executor)
- sigs.append(bactsig)
- else:
- bact = ""
- bactsig = ""
-
- bsig = self.module.collect(filter(None, sigs))
-
- cache.set_binfo(bsig, bkids, sigs, bact, bactsig)
-
- # don't store the bsig here, because it isn't accurate until
- # the node is actually built.
-
- return bsig
-
- def csig(self, node, cache=None):
- """
- Generate a node's content signature, the digested signature
- of its content.
-
- node - the node
- cache - alternate node to use for the signature cache
- returns - the content signature
- """
-
- if cache is None: cache = node
-
- csig = cache.get_csig()
- if csig is not None:
- return csig
-
- if self.max_drift >= 0:
- oldtime, oldbsig, oldcsig = node.get_prevsiginfo()
- else:
- import SCons.SConsign
- oldtime, oldbsig, oldcsig = SCons.SConsign.Base.null_siginfo
-
- mtime = node.get_timestamp()
-
- if (oldtime and oldcsig and oldtime == mtime):
- # use the signature stored in the .sconsign file
- csig = oldcsig
- # Set the csig here so it doesn't get recalculated unnecessarily
- # and so it's set when the .sconsign file gets written
- cache.set_csig(csig)
- else:
- csig = self.module.signature(node)
- # Set the csig here so it doesn't get recalculated unnecessarily
- # and so it's set when the .sconsign file gets written
- cache.set_csig(csig)
-
- if self.max_drift >= 0 and (time.time() - mtime) > self.max_drift:
- node.store_csig()
- node.store_timestamp()
-
- return csig
-
- def current(self, node, newsig):
- """
- Check if a signature is up to date with respect to a node.
-
- node - the node whose signature will be checked
- newsig - the (presumably current) signature of the file
-
- returns - 1 if the file is current with the specified signature,
- 0 if it isn't
- """
-
- if node.always_build:
- return 0
-
- oldtime, oldbsig, oldcsig = node.get_prevsiginfo()
-
- if type(newsig) != type(oldbsig):
- return 0
-
- if not node.has_builder() and node.get_timestamp() == oldtime:
- return 1
-
- return self.module.current(newsig, oldbsig)
-
-
default_calc = Calculator()