summaryrefslogtreecommitdiffstats
path: root/test/Repository
diff options
context:
space:
mode:
Diffstat (limited to 'test/Repository')
-rw-r--r--test/Repository/.aeignore4
-rw-r--r--test/Repository/CPPPATH.py103
-rw-r--r--test/Repository/Default.py106
-rw-r--r--test/Repository/Install-Local.py88
-rw-r--r--test/Repository/Install.py65
-rw-r--r--test/Repository/InstallAs.py72
-rw-r--r--test/Repository/Java.py264
-rw-r--r--test/Repository/JavaH.py296
-rw-r--r--test/Repository/LIBPATH.py136
-rw-r--r--test/Repository/Local.py120
-rw-r--r--test/Repository/M4.py107
-rw-r--r--test/Repository/Program.py368
-rw-r--r--test/Repository/RMIC.py382
-rw-r--r--test/Repository/SConscript.py131
-rw-r--r--test/Repository/SConsignFile.py67
-rw-r--r--test/Repository/SharedLibrary.py129
-rw-r--r--test/Repository/StaticLibrary.py235
-rw-r--r--test/Repository/VariantDir.py205
-rw-r--r--test/Repository/absolute-path.py115
-rw-r--r--test/Repository/include.py196
-rw-r--r--test/Repository/link-object.py163
-rw-r--r--test/Repository/multi-dir.py146
-rw-r--r--test/Repository/no-SConsignFile.py81
-rw-r--r--test/Repository/no-repository.py102
-rw-r--r--test/Repository/option-c.py188
-rw-r--r--test/Repository/option-f.py104
-rw-r--r--test/Repository/option-n.py100
-rw-r--r--test/Repository/signature-order.py128
-rw-r--r--test/Repository/targets.py105
-rw-r--r--test/Repository/top-level-path.py114
-rw-r--r--test/Repository/variants.py430
-rw-r--r--test/Repository/within-repository.py157
32 files changed, 5007 insertions, 0 deletions
diff --git a/test/Repository/.aeignore b/test/Repository/.aeignore
new file mode 100644
index 0000000..877ac53
--- /dev/null
+++ b/test/Repository/.aeignore
@@ -0,0 +1,4 @@
+*,D
+.*.swp
+.consign
+.sconsign
diff --git a/test/Repository/CPPPATH.py b/test/Repository/CPPPATH.py
new file mode 100644
index 0000000..ff1dbfe
--- /dev/null
+++ b/test/Repository/CPPPATH.py
@@ -0,0 +1,103 @@
+#!/usr/bin/env python
+#
+# __COPYRIGHT__
+#
+# Permission is hereby granted, free of charge, to any person obtaining
+# a copy of this software and associated documentation files (the
+# "Software"), to deal in the Software without restriction, including
+# without limitation the rights to use, copy, modify, merge, publish,
+# distribute, sublicense, and/or sell copies of the Software, and to
+# permit persons to whom the Software is furnished to do so, subject to
+# the following conditions:
+#
+# The above copyright notice and this permission notice shall be included
+# in all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
+# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+#
+
+__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
+
+import sys
+import TestSCons
+
+if sys.platform == 'win32':
+ _exe = '.exe'
+else:
+ _exe = ''
+
+test = TestSCons.TestSCons()
+
+test.subdir('repository',
+ ['repository', 'include1'],
+ ['repository', 'include2'],
+ 'work')
+
+work_foo = test.workpath('work', 'foo')
+
+opts = '-Y ' + test.workpath('repository')
+
+#
+test.write(['repository', 'include1', 'foo.h'], r"""
+#define STRING "repository/include1/foo.h"
+""")
+
+test.write(['repository', 'include2', 'foo.h'], r"""
+#define STRING "repository/include2/foo.h"
+""")
+
+test.write(['repository', 'foo.c'], r"""
+#include <stdio.h>
+#include <stdlib.h>
+#include <foo.h>
+int
+main(int argc, char *argv[])
+{
+ argv[argc++] = "--";
+ printf("%s\n", STRING);
+ exit (0);
+}
+""")
+
+# Make the entire repository non-writable, so we'll detect
+# if we try to write into it accidentally.
+test.writable('repository', 0)
+
+#
+test.write(['work', 'SConstruct'], """
+env = Environment(CPPPATH = ['include1', 'include2'])
+env.Program(target = 'foo', source = 'foo.c')
+""")
+
+test.run(chdir = 'work', options = opts, arguments = '.')
+
+test.run(program = work_foo, stdout = "repository/include1/foo.h\n")
+
+test.up_to_date(chdir = 'work', options = opts, arguments = '.')
+
+#
+test.write(['work', 'SConstruct'], """
+env = Environment(CPPPATH = ['include2', 'include1'])
+env.Program(target = 'foo', source = 'foo.c')
+""")
+
+test.run(chdir = 'work', options = opts, arguments = '.')
+
+test.run(program = work_foo, stdout = "repository/include2/foo.h\n")
+
+test.up_to_date(chdir = 'work', options = opts, arguments = '.')
+
+#
+test.pass_test()
+
+# Local Variables:
+# tab-width:4
+# indent-tabs-mode:nil
+# End:
+# vim: set expandtab tabstop=4 shiftwidth=4:
diff --git a/test/Repository/Default.py b/test/Repository/Default.py
new file mode 100644
index 0000000..127c29a
--- /dev/null
+++ b/test/Repository/Default.py
@@ -0,0 +1,106 @@
+#!/usr/bin/env python
+#
+# __COPYRIGHT__
+#
+# Permission is hereby granted, free of charge, to any person obtaining
+# a copy of this software and associated documentation files (the
+# "Software"), to deal in the Software without restriction, including
+# without limitation the rights to use, copy, modify, merge, publish,
+# distribute, sublicense, and/or sell copies of the Software, and to
+# permit persons to whom the Software is furnished to do so, subject to
+# the following conditions:
+#
+# The above copyright notice and this permission notice shall be included
+# in all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
+# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+#
+
+__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
+
+import os.path
+
+import TestSCons
+
+test = TestSCons.TestSCons()
+
+test.subdir('repository', ['repository', 'subdir'], 'work')
+
+work_aaa_out = test.workpath('work', 'aaa.out')
+work_bbb_out = test.workpath('work', 'bbb.out')
+work_ccc_out = test.workpath('work', 'ccc.out')
+work_subdir_ddd_out = test.workpath('work', 'subdir', 'ddd.out')
+work_subdir_eee_out = test.workpath('work', 'subdir', 'eee.out')
+work_subdir_fff_out = test.workpath('work', 'subdir', 'fff.out')
+
+opts = "-Y " + test.workpath('repository')
+
+#
+test.write(['repository', 'SConstruct'], r"""
+def copy(env, source, target):
+ source = str(source[0])
+ target = str(target[0])
+ print 'copy() < %s > %s' % (source, target)
+ open(target, "wb").write(open(source, "rb").read())
+
+Build = Builder(action=copy)
+env = Environment(BUILDERS={'Build':Build})
+env.Build('aaa.out', 'aaa.in')
+env.Build('bbb.out', 'bbb.in')
+env.Build('ccc.out', 'ccc.in')
+Default('bbb.out')
+SConscript('subdir/SConscript', "env")
+""")
+
+test.write(['repository', 'subdir', 'SConscript'], r"""
+Import("env")
+Default('eee.out')
+env.Build('ddd.out', 'ddd.in')
+env.Build('eee.out', 'eee.in')
+env.Build('fff.out', 'fff.in')
+""")
+
+test.write(['repository', 'aaa.in'], "repository/aaa.in\n")
+test.write(['repository', 'bbb.in'], "repository/bbb.in\n")
+test.write(['repository', 'ccc.in'], "repository/ccc.in\n")
+test.write(['repository', 'subdir', 'ddd.in'], "repository/subdir/ddd.in\n")
+test.write(['repository', 'subdir', 'eee.in'], "repository/subdir/eee.in\n")
+test.write(['repository', 'subdir', 'fff.in'], "repository/subdir/fff.in\n")
+
+# Make the entire repository non-writable, so we'll detect
+# if we try to write into it accidentally.
+test.writable('repository', 0)
+
+test.run(chdir = 'work', options = opts, arguments = '')
+
+test.fail_test(os.path.exists(work_aaa_out))
+test.fail_test(test.read(work_bbb_out) != "repository/bbb.in\n")
+test.fail_test(os.path.exists(work_ccc_out))
+test.fail_test(os.path.exists(work_subdir_ddd_out))
+test.fail_test(test.read(work_subdir_eee_out) != "repository/subdir/eee.in\n")
+test.fail_test(os.path.exists(work_subdir_fff_out))
+
+#
+test.run(chdir = 'work', options = opts, arguments = '.')
+
+test.fail_test(test.read(work_aaa_out) != "repository/aaa.in\n")
+test.fail_test(test.read(work_ccc_out) != "repository/ccc.in\n")
+test.fail_test(test.read(work_subdir_ddd_out) != "repository/subdir/ddd.in\n")
+test.fail_test(test.read(work_subdir_fff_out) != "repository/subdir/fff.in\n")
+
+test.up_to_date(chdir = 'work', options = opts, arguments = '.')
+
+#
+test.pass_test()
+
+# Local Variables:
+# tab-width:4
+# indent-tabs-mode:nil
+# End:
+# vim: set expandtab tabstop=4 shiftwidth=4:
diff --git a/test/Repository/Install-Local.py b/test/Repository/Install-Local.py
new file mode 100644
index 0000000..3631043
--- /dev/null
+++ b/test/Repository/Install-Local.py
@@ -0,0 +1,88 @@
+#!/usr/bin/env python
+#
+# __COPYRIGHT__
+#
+# Permission is hereby granted, free of charge, to any person obtaining
+# a copy of this software and associated documentation files (the
+# "Software"), to deal in the Software without restriction, including
+# without limitation the rights to use, copy, modify, merge, publish,
+# distribute, sublicense, and/or sell copies of the Software, and to
+# permit persons to whom the Software is furnished to do so, subject to
+# the following conditions:
+#
+# The above copyright notice and this permission notice shall be included
+# in all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
+# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+#
+
+__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
+
+import os.path
+import TestSCons
+
+test = TestSCons.TestSCons()
+
+test.subdir('repository', 'work', ['work', 'install'])
+
+repository_install_file1 = test.workpath('repository', 'install', 'file1')
+repository_install_file2 = test.workpath('repository', 'install', 'file2')
+work_install_file1 = test.workpath('work', 'install', 'file1')
+work_install_file2 = test.workpath('work', 'install', 'file2')
+
+opts = "-Y " + test.workpath('repository')
+
+#
+test.write(['repository', 'SConstruct'], r"""
+env = Environment()
+env.Install('install', 'file1')
+Local(r'%s')
+Local(env.Install('install', 'file2'))
+""" % os.path.join('install', 'file1'))
+
+test.write(['repository', 'file1'], "repository/file1\n")
+test.write(['repository', 'file2'], "repository/file2\n")
+
+test.run(chdir = 'repository', options = opts, arguments = 'install')
+
+test.fail_test(test.read(repository_install_file1) != "repository/file1\n")
+test.fail_test(test.read(repository_install_file2) != "repository/file2\n")
+
+test.up_to_date(chdir = 'repository', options = opts, arguments = 'install')
+
+# Make the entire repository non-writable, so we'll detect
+# if we try to write into it accidentally.
+test.writable('repository', 0)
+
+test.run(chdir = 'work', options = opts, arguments = 'install')
+
+test.fail_test(test.read(work_install_file1) != "repository/file1\n")
+test.fail_test(test.read(work_install_file2) != "repository/file2\n")
+
+test.up_to_date(chdir = 'work', options = opts, arguments = 'install')
+
+#
+test.write(['work', 'file1'], "work/file1\n")
+test.write(['work', 'file2'], "work/file2\n")
+
+test.run(chdir = 'work', options = opts, arguments = 'install')
+
+test.fail_test(test.read(work_install_file1) != "work/file1\n")
+test.fail_test(test.read(work_install_file2) != "work/file2\n")
+
+test.up_to_date(chdir = 'work', options = opts, arguments = 'install')
+
+#
+test.pass_test()
+
+# Local Variables:
+# tab-width:4
+# indent-tabs-mode:nil
+# End:
+# vim: set expandtab tabstop=4 shiftwidth=4:
diff --git a/test/Repository/Install.py b/test/Repository/Install.py
new file mode 100644
index 0000000..5e64d55
--- /dev/null
+++ b/test/Repository/Install.py
@@ -0,0 +1,65 @@
+#!/usr/bin/env python
+#
+# __COPYRIGHT__
+#
+# Permission is hereby granted, free of charge, to any person obtaining
+# a copy of this software and associated documentation files (the
+# "Software"), to deal in the Software without restriction, including
+# without limitation the rights to use, copy, modify, merge, publish,
+# distribute, sublicense, and/or sell copies of the Software, and to
+# permit persons to whom the Software is furnished to do so, subject to
+# the following conditions:
+#
+# The above copyright notice and this permission notice shall be included
+# in all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
+# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+#
+
+__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
+
+import os.path
+
+import TestSCons
+
+test = TestSCons.TestSCons()
+
+test.subdir('install', 'repository', 'work')
+
+install = test.workpath('install')
+install_file = test.workpath('install', 'file')
+
+opts = "-Y " + test.workpath('repository')
+
+#
+test.write(['repository', 'SConstruct'], r"""
+env = Environment()
+env.Install(r'%s', 'file')
+""" % install)
+
+test.write(['repository', 'file'], "repository/file\n")
+
+# Make the entire repository non-writable, so we'll detect
+# if we try to write into it accidentally.
+test.writable('repository', 0)
+
+test.run(chdir = 'work', options = opts, arguments = install)
+
+test.fail_test(test.read(install_file) != "repository/file\n")
+
+test.up_to_date(chdir = 'work', options = opts, arguments = install)
+
+#
+test.pass_test()
+
+# Local Variables:
+# tab-width:4
+# indent-tabs-mode:nil
+# End:
+# vim: set expandtab tabstop=4 shiftwidth=4:
diff --git a/test/Repository/InstallAs.py b/test/Repository/InstallAs.py
new file mode 100644
index 0000000..0923d88
--- /dev/null
+++ b/test/Repository/InstallAs.py
@@ -0,0 +1,72 @@
+#!/usr/bin/env python
+#
+# __COPYRIGHT__
+#
+# Permission is hereby granted, free of charge, to any person obtaining
+# a copy of this software and associated documentation files (the
+# "Software"), to deal in the Software without restriction, including
+# without limitation the rights to use, copy, modify, merge, publish,
+# distribute, sublicense, and/or sell copies of the Software, and to
+# permit persons to whom the Software is furnished to do so, subject to
+# the following conditions:
+#
+# The above copyright notice and this permission notice shall be included
+# in all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
+# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+#
+
+__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
+
+import os.path
+
+import TestSCons
+
+test = TestSCons.TestSCons()
+
+test.subdir('install', 'repository', 'work')
+
+install = test.workpath('install')
+install_file1_out = test.workpath('install', 'file1.out')
+install_file2_out = test.workpath('install', 'file2.out')
+install_file3_out = test.workpath('install', 'file3.out')
+
+opts = "-Y " + test.workpath('repository')
+
+#
+test.write(['repository', 'SConstruct'], r"""
+env = Environment()
+env.InstallAs(r'%s', 'file1.in')
+env.InstallAs([r'%s', r'%s'], ['file2.in', 'file3.in'])
+""" % (install_file1_out, install_file2_out, install_file3_out))
+
+test.write(['repository', 'file1.in'], "repository/file1.in\n")
+test.write(['repository', 'file2.in'], "repository/file2.in\n")
+test.write(['repository', 'file3.in'], "repository/file3.in\n")
+
+# Make the entire repository non-writable, so we'll detect
+# if we try to write into it accidentally.
+test.writable('repository', 0)
+
+test.run(chdir = 'work', options = opts, arguments = install)
+
+test.fail_test(test.read(install_file1_out) != "repository/file1.in\n")
+test.fail_test(test.read(install_file2_out) != "repository/file2.in\n")
+test.fail_test(test.read(install_file3_out) != "repository/file3.in\n")
+
+test.up_to_date(chdir = 'work', options = opts, arguments = install)
+
+#
+test.pass_test()
+
+# Local Variables:
+# tab-width:4
+# indent-tabs-mode:nil
+# End:
+# vim: set expandtab tabstop=4 shiftwidth=4:
diff --git a/test/Repository/Java.py b/test/Repository/Java.py
new file mode 100644
index 0000000..dc6f202
--- /dev/null
+++ b/test/Repository/Java.py
@@ -0,0 +1,264 @@
+#!/usr/bin/env python
+#
+# __COPYRIGHT__
+#
+# Permission is hereby granted, free of charge, to any person obtaining
+# a copy of this software and associated documentation files (the
+# "Software"), to deal in the Software without restriction, including
+# without limitation the rights to use, copy, modify, merge, publish,
+# distribute, sublicense, and/or sell copies of the Software, and to
+# permit persons to whom the Software is furnished to do so, subject to
+# the following conditions:
+#
+# The above copyright notice and this permission notice shall be included
+# in all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
+# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+#
+
+__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
+
+"""
+Test building Java applications when using Repositories.
+"""
+
+import os
+
+import TestSCons
+
+python = TestSCons.python
+
+test = TestSCons.TestSCons()
+
+javac, java_version = test.java_where_javac()
+java = test.java_where_java()
+
+# where_java_home=test.java_where_java_home(java_version)
+os.environ['JAVA_HOME'] = test.java_where_java_home(java_version)
+
+###############################################################################
+
+#
+test.subdir('rep1', ['rep1', 'src'],
+ 'work1',
+ 'work2')
+
+#
+rep1_classes = test.workpath('rep1', 'classes')
+work1_classes = test.workpath('work1', 'classes')
+
+#
+opts = '-Y ' + test.workpath('rep1')
+
+#
+test.write(['rep1', 'SConstruct'], """
+env = Environment(tools = ['javac'],
+ JAVAC = r'%s')
+env.Java(target = 'classes', source = 'src')
+""" % javac)
+
+test.write(['rep1', 'src', 'Foo1.java'], """\
+public class Foo1
+{
+ public static void main(String[] args)
+ {
+ System.out.println("rep1/src/Foo1.java");
+
+ }
+}
+""")
+
+test.write(['rep1', 'src', 'Foo2.java'], """\
+public class Foo2
+{
+ public static void main(String[] args)
+ {
+ System.out.println("rep1/src/Foo2.java");
+
+ }
+}
+""")
+
+test.write(['rep1', 'src', 'Foo3.java'], """\
+public class Foo3
+{
+ public static void main(String[] args)
+ {
+ System.out.println("rep1/src/Foo3.java");
+
+ }
+}
+""")
+
+# Make the repository non-writable,
+# so we'll detect if we try to write into it accidentally.
+test.writable('repository', 0)
+
+#
+test.run(chdir = 'work1', options = opts, arguments = ".")
+
+
+test.run(program = java,
+ arguments = "-cp %s Foo1" % work1_classes,
+ stdout = "rep1/src/Foo1.java\n")
+
+test.run(program = java,
+ arguments = "-cp %s Foo2" % work1_classes,
+ stdout = "rep1/src/Foo2.java\n")
+
+test.run(program = java,
+ arguments = "-cp %s Foo3" % work1_classes,
+ stdout = "rep1/src/Foo3.java\n")
+
+test.up_to_date(chdir = 'work1', options = opts, arguments = ".")
+
+#
+test.subdir(['work1', 'src'])
+
+test.write(['work1', 'src', 'Foo1.java'], """\
+public class Foo1
+{
+ public static void main(String[] args)
+ {
+ System.out.println("work1/src/Foo1.java");
+
+ }
+}
+""")
+
+test.write(['work1', 'src', 'Foo2.java'], """\
+public class Foo2
+{
+ public static void main(String[] args)
+ {
+ System.out.println("work1/src/Foo2.java");
+
+ }
+}
+""")
+
+test.write(['work1', 'src', 'Foo3.java'], """\
+public class Foo3
+{
+ public static void main(String[] args)
+ {
+ System.out.println("work1/src/Foo3.java");
+
+ }
+}
+""")
+
+test.run(chdir = 'work1', options = opts, arguments = ".")
+
+test.run(program = java,
+ arguments = "-cp %s Foo1" % work1_classes,
+ stdout = "work1/src/Foo1.java\n")
+
+test.run(program = java,
+ arguments = "-cp %s Foo2" % work1_classes,
+ stdout = "work1/src/Foo2.java\n")
+
+test.run(program = java,
+ arguments = "-cp %s Foo3" % work1_classes,
+ stdout = "work1/src/Foo3.java\n")
+
+test.up_to_date(chdir = 'work1', options = opts, arguments = ".")
+
+#
+test.writable('rep1', 1)
+
+test.run(chdir = 'rep1', options = opts, arguments = ".")
+
+test.run(program = java,
+ arguments = "-cp %s Foo1" % rep1_classes,
+ stdout = "rep1/src/Foo1.java\n")
+
+test.run(program = java,
+ arguments = "-cp %s Foo2" % rep1_classes,
+ stdout = "rep1/src/Foo2.java\n")
+
+test.run(program = java,
+ arguments = "-cp %s Foo3" % rep1_classes,
+ stdout = "rep1/src/Foo3.java\n")
+
+test.up_to_date(chdir = 'rep1', options = opts, arguments = ".")
+
+#
+test.writable('repository', 0)
+
+#
+# If the Java builder were to interact with Repositories like the
+# other builders, then we'd uncomment the following test(s).
+#
+# This tests that, if the .class files are built in the repository,
+# then a local build says that everything is up-to-date. However,
+# because the destination target is a directory ("classes") not a
+# file, we don't detect that the individual .class files are
+# already there, and think things must be rebuilt.
+#
+#test.up_to_date(chdir = 'work2', options = opts, arguments = ".")
+#
+#test.subdir(['work2', 'src'])
+#
+#test.write(['work2', 'src', 'Foo1.java'], """\
+#public class Foo1
+#{
+# public static void main(String[] args)
+# {
+# System.out.println("work2/src/Foo1.java");
+#
+# }
+#}
+#""")
+#
+#test.write(['work2', 'src', 'Foo2.java'], """\
+#public class Foo2
+#{
+# public static void main(String[] args)
+# {
+# System.out.println("work2/src/Foo2.java");
+#
+# }
+#}
+#""")
+#
+#test.write(['work2', 'src', 'Foo3.java'], """\
+#public class Foo3
+#{
+# public static void main(String[] args)
+# {
+# System.out.println("work2/src/Foo3.java");
+#
+# }
+#}
+#""")
+#
+#test.run(chdir = 'work2', options = opts, arguments = ".")
+#
+#test.run(program = java,
+# arguments = "-cp %s Foo1" % work2_classes,
+# stdout = "work2/src/Foo1.java\n")
+#
+#test.run(program = java,
+# arguments = "-cp %s Foo2" % work2_classes,
+# stdout = "work2/src/Foo2.java\n")
+#
+#test.run(program = java,
+# arguments = "-cp %s Foo3" % work2_classes,
+# stdout = "work2/src/Foo3.java\n")
+#
+#test.up_to_date(chdir = 'work2', options = opts, arguments = ".")
+
+test.pass_test()
+
+# Local Variables:
+# tab-width:4
+# indent-tabs-mode:nil
+# End:
+# vim: set expandtab tabstop=4 shiftwidth=4:
diff --git a/test/Repository/JavaH.py b/test/Repository/JavaH.py
new file mode 100644
index 0000000..ee196cf
--- /dev/null
+++ b/test/Repository/JavaH.py
@@ -0,0 +1,296 @@
+#!/usr/bin/env python
+#
+# __COPYRIGHT__
+#
+# Permission is hereby granted, free of charge, to any person obtaining
+# a copy of this software and associated documentation files (the
+# "Software"), to deal in the Software without restriction, including
+# without limitation the rights to use, copy, modify, merge, publish,
+# distribute, sublicense, and/or sell copies of the Software, and to
+# permit persons to whom the Software is furnished to do so, subject to
+# the following conditions:
+#
+# The above copyright notice and this permission notice shall be included
+# in all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
+# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+#
+
+__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
+
+"""
+Test building Java applications when using Repositories.
+"""
+
+import os
+
+import TestSCons
+
+python = TestSCons.python
+
+test = TestSCons.TestSCons()
+
+where_javac, java_version = test.java_where_javac()
+where_java = test.java_where_java()
+where_javah = test.java_where_javah()
+
+java = where_java
+javac = where_javac
+javah = where_javah
+
+###############################################################################
+
+#
+test.subdir('rep1', ['rep1', 'src'],
+ 'work1',
+ 'work2',
+ 'work3')
+
+#
+rep1_classes = test.workpath('rep1', 'classes')
+work1_classes = test.workpath('work1', 'classes')
+work3_classes = test.workpath('work3', 'classes')
+
+#
+opts = '-Y ' + test.workpath('rep1')
+
+#
+test.write(['rep1', 'SConstruct'], """
+env = Environment(tools = ['javac', 'javah'],
+ JAVAC = r'%s',
+ JAVAH = r'%s')
+classes = env.Java(target = 'classes', source = 'src')
+env.JavaH(target = 'outdir', source = classes)
+""" % (javac, javah))
+
+test.write(['rep1', 'src', 'Foo1.java'], """\
+public class Foo1
+{
+ public static void main(String[] args)
+ {
+ System.out.println("rep1/src/Foo1.java");
+
+ }
+}
+""")
+
+test.write(['rep1', 'src', 'Foo2.java'], """\
+public class Foo2
+{
+ public static void main(String[] args)
+ {
+ System.out.println("rep1/src/Foo2.java");
+
+ }
+}
+""")
+
+test.write(['rep1', 'src', 'Foo3.java'], """\
+public class Foo3
+{
+ public static void main(String[] args)
+ {
+ System.out.println("rep1/src/Foo3.java");
+
+ }
+}
+""")
+
+# Make the repository non-writable,
+# so we'll detect if we try to write into it accidentally.
+test.writable('repository', 0)
+
+#
+test.run(chdir = 'work1', options = opts, arguments = ".")
+
+test.run(program = java,
+ arguments = "-cp %s Foo1" % work1_classes,
+ stdout = "rep1/src/Foo1.java\n")
+
+test.run(program = java,
+ arguments = "-cp %s Foo2" % work1_classes,
+ stdout = "rep1/src/Foo2.java\n")
+
+test.run(program = java,
+ arguments = "-cp %s Foo3" % work1_classes,
+ stdout = "rep1/src/Foo3.java\n")
+
+test.fail_test(not os.path.exists(test.workpath('work1', 'outdir', 'Foo1.h')))
+test.fail_test(not os.path.exists(test.workpath('work1', 'outdir', 'Foo2.h')))
+test.fail_test(not os.path.exists(test.workpath('work1', 'outdir', 'Foo3.h')))
+
+test.up_to_date(chdir = 'work1', options = opts, arguments = ".")
+
+#
+test.subdir(['work1', 'src'])
+
+test.write(['work1', 'src', 'Foo1.java'], """\
+public class Foo1
+{
+ public static void main(String[] args)
+ {
+ System.out.println("work1/src/Foo1.java");
+
+ }
+}
+""")
+
+test.write(['work1', 'src', 'Foo2.java'], """\
+public class Foo2
+{
+ public static void main(String[] args)
+ {
+ System.out.println("work1/src/Foo2.java");
+
+ }
+}
+""")
+
+test.write(['work1', 'src', 'Foo3.java'], """\
+public class Foo3
+{
+ public static void main(String[] args)
+ {
+ System.out.println("work1/src/Foo3.java");
+
+ }
+}
+""")
+
+test.run(chdir = 'work1', options = opts, arguments = ".")
+
+test.run(program = java,
+ arguments = "-cp %s Foo1" % work1_classes,
+ stdout = "work1/src/Foo1.java\n")
+
+test.run(program = java,
+ arguments = "-cp %s Foo2" % work1_classes,
+ stdout = "work1/src/Foo2.java\n")
+
+test.run(program = java,
+ arguments = "-cp %s Foo3" % work1_classes,
+ stdout = "work1/src/Foo3.java\n")
+
+test.up_to_date(chdir = 'work1', options = opts, arguments = ".")
+
+#
+test.writable('rep1', 1)
+
+test.run(chdir = 'rep1', options = opts, arguments = ".")
+
+test.run(program = java,
+ arguments = "-cp %s Foo1" % rep1_classes,
+ stdout = "rep1/src/Foo1.java\n")
+
+test.run(program = java,
+ arguments = "-cp %s Foo2" % rep1_classes,
+ stdout = "rep1/src/Foo2.java\n")
+
+test.run(program = java,
+ arguments = "-cp %s Foo3" % rep1_classes,
+ stdout = "rep1/src/Foo3.java\n")
+
+test.up_to_date(chdir = 'rep1', options = opts, arguments = ".")
+
+#
+test.writable('repository', 0)
+
+#
+test.up_to_date(chdir = 'work2', options = opts, arguments = ".")
+
+#
+test.write(['work3', 'SConstruct'], """
+env = Environment(tools = ['javac', 'javah'],
+ JAVAC = r'%s',
+ JAVAH = r'%s')
+classes = env.Java(target = 'classes', source = 'src')
+hfiles = env.JavaH(target = 'outdir', source = classes)
+Local(hfiles)
+""" % (javac, javah))
+
+test.run(chdir = 'work3', options = opts, arguments = ".")
+
+test.fail_test(os.path.exists(test.workpath('work3', 'classes', 'Foo1.class')))
+test.fail_test(os.path.exists(test.workpath('work3', 'classes', 'Foo2.class')))
+test.fail_test(os.path.exists(test.workpath('work3', 'classes', 'Foo3.class')))
+
+test.fail_test(not os.path.exists(test.workpath('work3', 'outdir', 'Foo1.h')))
+test.fail_test(not os.path.exists(test.workpath('work3', 'outdir', 'Foo2.h')))
+test.fail_test(not os.path.exists(test.workpath('work3', 'outdir', 'Foo3.h')))
+
+#
+# If the Java builder were to interact with Repositories like the
+# other builders, then we'd uncomment the following test(s).
+#
+# This tests that, if the .class files are built in the repository,
+# then a local build says that everything is up-to-date. However,
+# because the destination target is a directory ("classes") not a
+# file, we don't detect that the individual .class files are
+# already there, and think things must be rebuilt.
+#
+#test.up_to_date(chdir = 'work2', options = opts, arguments = ".")
+#
+#test.subdir(['work2', 'src'])
+#
+#test.write(['work2', 'src', 'Foo1.java'], """\
+#public class Foo1
+#{
+# public static void main(String[] args)
+# {
+# System.out.println("work2/src/Foo1.java");
+#
+# }
+#}
+#""")
+#
+#test.write(['work2', 'src', 'Foo2.java'], """\
+#public class Foo2
+#{
+# public static void main(String[] args)
+# {
+# System.out.println("work2/src/Foo2.java");
+#
+# }
+#}
+#""")
+#
+#test.write(['work2', 'src', 'Foo3.java'], """\
+#public class Foo3
+#{
+# public static void main(String[] args)
+# {
+# System.out.println("work2/src/Foo3.java");
+#
+# }
+#}
+#""")
+#
+#test.run(chdir = 'work2', options = opts, arguments = ".")
+#
+#test.run(program = java,
+# arguments = "-cp %s Foo1" % work2_classes,
+# stdout = "work2/src/Foo1.java\n")
+#
+#test.run(program = java,
+# arguments = "-cp %s Foo2" % work2_classes,
+# stdout = "work2/src/Foo2.java\n")
+#
+#test.run(program = java,
+# arguments = "-cp %s Foo3" % work2_classes,
+# stdout = "work2/src/Foo3.java\n")
+#
+#test.up_to_date(chdir = 'work2', options = opts, arguments = ".")
+
+test.pass_test()
+
+# Local Variables:
+# tab-width:4
+# indent-tabs-mode:nil
+# End:
+# vim: set expandtab tabstop=4 shiftwidth=4:
diff --git a/test/Repository/LIBPATH.py b/test/Repository/LIBPATH.py
new file mode 100644
index 0000000..c95d29a
--- /dev/null
+++ b/test/Repository/LIBPATH.py
@@ -0,0 +1,136 @@
+#!/usr/bin/env python
+#
+# __COPYRIGHT__
+#
+# Permission is hereby granted, free of charge, to any person obtaining
+# a copy of this software and associated documentation files (the
+# "Software"), to deal in the Software without restriction, including
+# without limitation the rights to use, copy, modify, merge, publish,
+# distribute, sublicense, and/or sell copies of the Software, and to
+# permit persons to whom the Software is furnished to do so, subject to
+# the following conditions:
+#
+# The above copyright notice and this permission notice shall be included
+# in all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
+# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+#
+
+__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
+
+import TestSCons
+
+test = TestSCons.TestSCons()
+
+test.subdir('foo', ['foo', 'zzz'], 'bar', ['bar', 'yyy'], 'work')
+
+workpath_foo = test.workpath('foo')
+workpath_foo_yyy = test.workpath('foo', 'yyy')
+workpath_foo_zzz = test.workpath('foo', 'zzz')
+workpath_bar = test.workpath('bar')
+workpath_bar_yyy = test.workpath('bar', 'yyy')
+workpath_bar_zzz = test.workpath('bar', 'zzz')
+workpath_work = test.workpath('work')
+
+test.write(['work', 'SConstruct'], r"""
+env_zzz = Environment(LIBPATH = ['.', 'zzz'])
+env_yyy = Environment(LIBPATH = ['yyy', '.'])
+aaa_exe = env_zzz.Program('aaa', 'aaa.c')
+bbb_exe = env_yyy.Program('bbb', 'bbb.c')
+def write_LIBDIRFLAGS(env, target, source):
+ pre = env.subst('$LIBDIRPREFIX')
+ suf = env.subst('$LIBDIRSUFFIX')
+ f = open(str(target[0]), 'wb')
+ for arg in env.subst('$_LIBDIRFLAGS', target=target).split():
+ if arg[:len(pre)] == pre:
+ arg = arg[len(pre):]
+ if arg[-len(suf):] == suf:
+ arg = arg[:-len(pre)]
+ f.write(arg + '\n')
+ f.close()
+ return 0
+env_zzz.Command('zzz.out', aaa_exe, write_LIBDIRFLAGS)
+env_yyy.Command('yyy.out', bbb_exe, write_LIBDIRFLAGS)
+
+if env_yyy['PLATFORM'] == 'darwin':
+ # The Mac OS X linker complains about nonexistent directories
+ # specified as -L arguments. Suppress its warnings so we don't
+ # treat the warnings on stderr as a failure.
+ env_yyy.Append(LINKFLAGS=['-w'])
+ env_zzz.Append(LINKFLAGS=['-w'])
+""")
+
+test.write(['work', 'aaa.c'], r"""
+#include <stdio.h>
+#include <stdlib.h>
+int
+main(int argc, char *argv[])
+{
+ argv[argc++] = "--";
+ printf("work/aaa.c\n");
+ exit (0);
+}
+""")
+
+test.write(['work', 'bbb.c'], r"""
+#include <stdio.h>
+#include <stdlib.h>
+int
+main(int argc, char *argv[])
+{
+ argv[argc++] = "--";
+ printf("work/bbb.c\n");
+ exit (0);
+}
+""")
+
+#
+opts = "-Y %s -Y %s -Y %s" % (workpath_foo, workpath_work, workpath_bar)
+test.run(chdir = 'work', options = opts, arguments = ".")
+
+#dirs = ['.', workpath_foo, workpath_bar, workpath_foo_zzz]
+dirs = ['.', workpath_foo, workpath_bar,
+ 'zzz', workpath_foo_zzz, workpath_bar_zzz]
+test.fail_test(test.read(['work', 'zzz.out']) !=
+ '\n'.join(dirs) + '\n')
+
+#dirs = [workpath_bar_yyy, '.', workpath_foo, workpath_bar]
+dirs = ['yyy', workpath_foo_yyy, workpath_bar_yyy,
+ '.', workpath_foo, workpath_bar]
+test.fail_test(test.read(['work', 'yyy.out']) !=
+ '\n'.join(dirs) + '\n')
+
+#
+test.run(chdir = 'work', options = '-c', arguments = ".")
+
+test.subdir(['work', 'zzz'], ['work', 'yyy'])
+
+#
+test.run(chdir = 'work', options = opts, arguments = ".")
+
+#dirs = ['.', workpath_foo, workpath_bar, 'zzz', workpath_foo_zzz]
+dirs = ['.', workpath_foo, workpath_bar,
+ 'zzz', workpath_foo_zzz, workpath_bar_zzz]
+test.fail_test(test.read(['work', 'zzz.out']) !=
+ '\n'.join(dirs) + '\n')
+
+#dirs = ['yyy', workpath_bar_yyy, '.', workpath_foo, workpath_bar]
+dirs = ['yyy', workpath_foo_yyy, workpath_bar_yyy,
+ '.', workpath_foo, workpath_bar]
+test.fail_test(test.read(['work', 'yyy.out']) !=
+ '\n'.join(dirs) + '\n')
+
+#
+test.pass_test()
+
+# Local Variables:
+# tab-width:4
+# indent-tabs-mode:nil
+# End:
+# vim: set expandtab tabstop=4 shiftwidth=4:
diff --git a/test/Repository/Local.py b/test/Repository/Local.py
new file mode 100644
index 0000000..1b63345
--- /dev/null
+++ b/test/Repository/Local.py
@@ -0,0 +1,120 @@
+#!/usr/bin/env python
+#
+# __COPYRIGHT__
+#
+# Permission is hereby granted, free of charge, to any person obtaining
+# a copy of this software and associated documentation files (the
+# "Software"), to deal in the Software without restriction, including
+# without limitation the rights to use, copy, modify, merge, publish,
+# distribute, sublicense, and/or sell copies of the Software, and to
+# permit persons to whom the Software is furnished to do so, subject to
+# the following conditions:
+#
+# The above copyright notice and this permission notice shall be included
+# in all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
+# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+#
+
+__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
+
+import os.path
+
+import TestSCons
+
+test = TestSCons.TestSCons()
+
+test.subdir('repository', ['repository', 'src'],
+ 'work', ['work', 'src'])
+
+repository_aaa_out = test.workpath('repository', 'aaa.out')
+repository_build_bbb_1 = test.workpath('repository', 'build', 'bbb.1')
+repository_build_bbb_2 = test.workpath('repository', 'build', 'bbb.2')
+work_aaa_mid = test.workpath('work', 'aaa.mid')
+work_aaa_out = test.workpath('work', 'aaa.out')
+work_build_bbb_1 = test.workpath('work', 'build', 'bbb.1')
+work_build_bbb_2 = test.workpath('work', 'build', 'bbb.2')
+
+opts = "-Y " + test.workpath('repository')
+
+#
+test.write(['repository', 'SConstruct'], r"""
+def copy(env, source, target):
+ source = str(source[0])
+ target = str(target[0])
+ print 'copy() < %s > %s' % (source, target)
+ open(target, "wb").write(open(source, "rb").read())
+
+Build = Builder(action=copy)
+env = Environment(BUILDERS={'Build':Build}, BBB='bbb')
+env.Build('aaa.mid', 'aaa.in')
+env.Build('aaa.out', 'aaa.mid')
+Local('aaa.out')
+
+Export("env")
+VariantDir('build', 'src')
+SConscript('build/SConscript')
+""")
+
+test.write(['repository', 'src', 'SConscript'], r"""
+def bbb_copy(env, source, target):
+ target = str(target[0])
+ print 'bbb_copy()'
+ open(target, "wb").write(open('build/bbb.1', "rb").read())
+
+Import("env")
+env.Build('bbb.1', 'bbb.0')
+env.Local('${BBB}.1')
+env.Command('bbb.2', 'bbb.x', bbb_copy)
+env.Depends('bbb.2', 'bbb.1')
+""")
+
+test.write(['repository', 'aaa.in'], "repository/aaa.in\n")
+test.write(['repository', 'src', 'bbb.0'], "repository/src/bbb.0\n")
+test.write(['repository', 'src', 'bbb.x'], "repository/src/bbb.x\n")
+
+#
+test.run(chdir = 'repository', options = opts, arguments = '.')
+
+test.fail_test(test.read(repository_aaa_out) != "repository/aaa.in\n")
+test.fail_test(test.read(repository_build_bbb_2) != "repository/src/bbb.0\n")
+
+test.up_to_date(chdir = 'repository', options = opts, arguments = '.')
+
+# Make the entire repository non-writable, so we'll detect
+# if we try to write into it accidentally.
+test.writable('repository', 0)
+
+#
+test.run(chdir = 'work', options = opts, arguments = 'aaa.out build/bbb.2')
+
+test.fail_test(os.path.exists(work_aaa_mid))
+test.fail_test(test.read(work_aaa_out) != "repository/aaa.in\n")
+test.fail_test(test.read(work_build_bbb_1) != "repository/src/bbb.0\n")
+test.fail_test(os.path.exists(work_build_bbb_2))
+
+#
+test.write(['work', 'aaa.in'], "work/aaa.in\n")
+
+#
+test.run(chdir = 'work', options = opts, arguments = '.')
+
+test.fail_test(test.read(work_aaa_mid) != "work/aaa.in\n")
+test.fail_test(test.read(work_aaa_out) != "work/aaa.in\n")
+
+test.up_to_date(chdir = 'work', options = opts, arguments = '.')
+
+#
+test.pass_test()
+
+# Local Variables:
+# tab-width:4
+# indent-tabs-mode:nil
+# End:
+# vim: set expandtab tabstop=4 shiftwidth=4:
diff --git a/test/Repository/M4.py b/test/Repository/M4.py
new file mode 100644
index 0000000..fe1eb7b
--- /dev/null
+++ b/test/Repository/M4.py
@@ -0,0 +1,107 @@
+#!/usr/bin/env python
+#
+# __COPYRIGHT__
+#
+# Permission is hereby granted, free of charge, to any person obtaining
+# a copy of this software and associated documentation files (the
+# "Software"), to deal in the Software without restriction, including
+# without limitation the rights to use, copy, modify, merge, publish,
+# distribute, sublicense, and/or sell copies of the Software, and to
+# permit persons to whom the Software is furnished to do so, subject to
+# the following conditions:
+#
+# The above copyright notice and this permission notice shall be included
+# in all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
+# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+#
+
+__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
+
+"""
+Test that $M4 and $M4FLAGS work with repositories.
+"""
+
+import os
+
+import TestSCons
+
+_python_ = TestSCons._python_
+
+test = TestSCons.TestSCons()
+
+test.subdir('work', 'repository', ['repository', 'src'])
+
+test.write('mym4.py', """
+import sys
+contents = sys.stdin.read()
+sys.stdout.write(contents.replace('M4', 'mym4.py'))
+sys.exit(0)
+""")
+
+mym4_py = test.workpath('mym4.py')
+
+
+
+opts = "-Y " + test.workpath('repository')
+
+test.write(['repository', 'SConstruct'], """\
+env = Environment(M4 = r'%(_python_)s %(mym4_py)s', tools=['default', 'm4'])
+env.M4(target = 'aaa.x', source = 'aaa.x.m4')
+SConscript('src/SConscript', "env", variant_dir="build")
+""" % locals())
+
+test.write(['repository', 'aaa.x.m4'], """\
+line 1
+M4
+line 3
+""")
+
+test.write(['repository', 'src', 'SConscript'], """
+Import("env")
+env.M4('bbb.y', 'bbb.y.m4')
+""")
+
+test.write(['repository', 'src', 'bbb.y.m4'], """\
+line 1 M4
+line 2
+line 3 M4
+""")
+
+#
+# Make the repository non-writable,
+# so we'll detect if we try to write into it accidentally.
+test.writable('repository', 0)
+
+#
+test.run(chdir = 'work', options = opts, arguments = ".")
+
+expect_aaa_x = """\
+line 1
+mym4.py
+line 3
+"""
+
+expect_bbb_y = """\
+line 1 mym4.py
+line 2
+line 3 mym4.py
+"""
+
+test.fail_test(test.read(test.workpath('work', 'aaa.x'), 'r') != expect_aaa_x)
+test.fail_test(test.read(test.workpath('work', 'build', 'bbb.y'), 'r') != expect_bbb_y)
+
+#
+test.pass_test()
+
+# Local Variables:
+# tab-width:4
+# indent-tabs-mode:nil
+# End:
+# vim: set expandtab tabstop=4 shiftwidth=4:
diff --git a/test/Repository/Program.py b/test/Repository/Program.py
new file mode 100644
index 0000000..1eb18d8
--- /dev/null
+++ b/test/Repository/Program.py
@@ -0,0 +1,368 @@
+#!/usr/bin/env python
+#
+# __COPYRIGHT__
+#
+# Permission is hereby granted, free of charge, to any person obtaining
+# a copy of this software and associated documentation files (the
+# "Software"), to deal in the Software without restriction, including
+# without limitation the rights to use, copy, modify, merge, publish,
+# distribute, sublicense, and/or sell copies of the Software, and to
+# permit persons to whom the Software is furnished to do so, subject to
+# the following conditions:
+#
+# The above copyright notice and this permission notice shall be included
+# in all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
+# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+#
+
+__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
+
+import sys
+import TestSCons
+
+if sys.platform == 'win32':
+ _exe = '.exe'
+else:
+ _exe = ''
+
+test = TestSCons.TestSCons()
+
+
+
+# First, test a single repository.
+test.subdir('repository', 'work1')
+
+repository = test.workpath('repository')
+repository_foo_c = test.workpath('repository', 'foo.c')
+work1_foo = test.workpath('work1', 'foo' + _exe)
+work1_foo_c = test.workpath('work1', 'foo.c')
+
+test.write(['work1', 'SConstruct'], r"""
+Repository(r'%s')
+env = Environment()
+env.Program(target= 'foo', source = Split('aaa.c bbb.c foo.c'))
+""" % repository)
+
+test.write(['repository', 'aaa.c'], r"""
+#include <stdio.h>
+void
+aaa(void)
+{
+ printf("repository/aaa.c\n");
+}
+""")
+
+test.write(['repository', 'bbb.c'], r"""
+#include <stdio.h>
+void
+bbb(void)
+{
+ printf("repository/bbb.c\n");
+}
+""")
+
+test.write(['repository', 'foo.c'], r"""
+#include <stdio.h>
+#include <stdlib.h>
+
+extern void aaa(void);
+extern void bbb(void);
+int
+main(int argc, char *argv[])
+{
+ argv[argc++] = "--";
+ aaa();
+ bbb();
+ printf("repository/foo.c\n");
+ exit (0);
+}
+""")
+
+# Make the entire repository non-writable, so we'll detect
+# if we try to write into it accidentally.
+test.writable('repository', 0)
+
+test.run(chdir = 'work1', arguments = '.')
+
+test.run(program = work1_foo, stdout = """repository/aaa.c
+repository/bbb.c
+repository/foo.c
+""")
+
+test.up_to_date(chdir = 'work1', arguments = '.')
+
+#
+test.write(['work1', 'bbb.c'], r"""
+#include <stdio.h>
+void
+bbb(void)
+{
+ printf("work1/bbb.c\n");
+}
+""")
+
+test.run(chdir = 'work1', arguments = '.')
+
+test.run(program = work1_foo, stdout = """repository/aaa.c
+work1/bbb.c
+repository/foo.c
+""")
+
+test.up_to_date(chdir = 'work1', arguments = '.')
+
+#
+test.write(['work1', 'aaa.c'], r"""
+#include <stdio.h>
+void
+aaa(void)
+{
+ printf("work1/aaa.c\n");
+}
+""")
+
+test.write(['work1', 'foo.c'], r"""
+#include <stdio.h>
+#include <stdlib.h>
+extern void aaa(void);
+extern void bbb(void);
+int
+main(int argc, char *argv[])
+{
+ argv[argc++] = "--";
+ aaa();
+ bbb();
+ printf("work1/foo.c\n");
+ exit (0);
+}
+""")
+
+test.run(chdir = 'work1', arguments = '.')
+
+test.run(program = work1_foo, stdout = """work1/aaa.c
+work1/bbb.c
+work1/foo.c
+""")
+
+test.up_to_date(chdir = 'work1', arguments = '.')
+
+#
+test.unlink(['work1', 'aaa.c'])
+
+test.run(chdir = 'work1', arguments = '.')
+
+test.run(program = work1_foo, stdout = """repository/aaa.c
+work1/bbb.c
+work1/foo.c
+""")
+
+test.up_to_date(chdir = 'work1', arguments = '.')
+
+#
+test.unlink(['work1', 'bbb.c'])
+test.unlink(['work1', 'foo.c'])
+
+test.run(chdir = 'work1', arguments = '.')
+
+test.run(program = work1_foo, stdout = """repository/aaa.c
+repository/bbb.c
+repository/foo.c
+""")
+
+test.up_to_date(chdir = 'work1', arguments = '.')
+
+
+
+# Now, test multiple repositories.
+test.subdir('repository.new', 'repository.old', 'work2')
+
+repository_new = test.workpath('repository.new')
+repository_old = test.workpath('repository.old')
+work2_foo = test.workpath('work2', 'foo' + _exe)
+
+test.write(['work2', 'SConstruct'], r"""
+Repository(r'%s')
+Repository(r'%s')
+env = Environment()
+env.Program(target= 'foo', source = Split('aaa.c bbb.c foo.c'))
+""" % (repository_new, repository_old))
+
+test.write(['repository.old', 'aaa.c'], r"""
+#include <stdio.h>
+void
+aaa(void)
+{
+ printf("repository.old/aaa.c\n");
+}
+""")
+
+test.write(['repository.old', 'bbb.c'], r"""
+#include <stdio.h>
+void
+bbb(void)
+{
+ printf("repository.old/bbb.c\n");
+}
+""")
+
+test.write(['repository.old', 'foo.c'], r"""
+#include <stdio.h>
+#include <stdlib.h>
+extern void aaa(void);
+extern void bbb(void);
+int
+main(int argc, char *argv[])
+{
+ argv[argc++] = "--";
+ aaa();
+ bbb();
+ printf("repository.old/foo.c\n");
+ exit (0);
+}
+""")
+
+# Make both repositories non-writable, so we'll detect
+# if we try to write into it accidentally.
+test.writable('repository.new', 0)
+test.writable('repository.old', 0)
+
+test.run(chdir = 'work2', arguments = '.')
+
+test.run(program = work2_foo, stdout = """repository.old/aaa.c
+repository.old/bbb.c
+repository.old/foo.c
+""")
+
+test.up_to_date(chdir = 'work2', arguments = '.')
+
+#
+test.writable('repository.new', 1)
+
+test.write(['repository.new', 'aaa.c'], r"""
+#include <stdio.h>
+#include <stdlib.h>
+void
+aaa(void)
+{
+ printf("repository.new/aaa.c\n");
+}
+""")
+
+test.write(['work2', 'bbb.c'], r"""
+#include <stdio.h>
+#include <stdlib.h>
+void
+bbb(void)
+{
+ printf("work2/bbb.c\n");
+}
+""")
+
+#
+test.writable('repository.new', 0)
+
+test.run(chdir = 'work2', arguments = '.')
+
+test.run(program = work2_foo, stdout = """repository.new/aaa.c
+work2/bbb.c
+repository.old/foo.c
+""")
+
+test.up_to_date(chdir = 'work2', arguments = '.')
+
+#
+test.write(['work2', 'aaa.c'], r"""
+#include <stdio.h>
+#include <stdlib.h>
+void
+aaa(void)
+{
+ printf("work2/aaa.c\n");
+}
+""")
+
+test.write(['work2', 'foo.c'], r"""
+#include <stdio.h>
+#include <stdlib.h>
+extern void aaa(void);
+extern void bbb(void);
+int
+main(int argc, char *argv[])
+{
+ argv[argc++] = "--";
+ aaa();
+ bbb();
+ printf("work2/foo.c\n");
+ exit (0);
+}
+""")
+
+#
+test.run(chdir = 'work2', arguments = '.')
+
+test.run(program = work2_foo, stdout = """work2/aaa.c
+work2/bbb.c
+work2/foo.c
+""")
+
+test.up_to_date(chdir = 'work2', arguments = '.')
+
+#
+test.unlink(['work2', 'aaa.c'])
+test.unlink(['work2', 'bbb.c'])
+
+#
+test.run(chdir = 'work2', arguments = '.')
+
+test.run(program = work2_foo, stdout = """repository.new/aaa.c
+repository.old/bbb.c
+work2/foo.c
+""")
+
+test.up_to_date(chdir = 'work2', arguments = '.')
+
+#
+test.unlink(['work2', 'foo.c'])
+
+#
+test.run(chdir = 'work2', arguments = '.')
+
+test.run(program = work2_foo, stdout = """repository.new/aaa.c
+repository.old/bbb.c
+repository.old/foo.c
+""")
+
+test.up_to_date(chdir = 'work2', arguments = '.')
+
+#
+test.writable('repository.new', 1)
+
+test.unlink(['repository.new', 'aaa.c'])
+
+test.writable('repository.new', 0)
+
+#
+test.run(chdir = 'work2', arguments = '.')
+
+test.run(program = work2_foo, stdout = """repository.old/aaa.c
+repository.old/bbb.c
+repository.old/foo.c
+""")
+
+test.up_to_date(chdir = 'work2', arguments = '.')
+
+
+#
+test.pass_test()
+
+# Local Variables:
+# tab-width:4
+# indent-tabs-mode:nil
+# End:
+# vim: set expandtab tabstop=4 shiftwidth=4:
diff --git a/test/Repository/RMIC.py b/test/Repository/RMIC.py
new file mode 100644
index 0000000..886ccdb
--- /dev/null
+++ b/test/Repository/RMIC.py
@@ -0,0 +1,382 @@
+#!/usr/bin/env python
+#
+# __COPYRIGHT__
+#
+# Permission is hereby granted, free of charge, to any person obtaining
+# a copy of this software and associated documentation files (the
+# "Software"), to deal in the Software without restriction, including
+# without limitation the rights to use, copy, modify, merge, publish,
+# distribute, sublicense, and/or sell copies of the Software, and to
+# permit persons to whom the Software is furnished to do so, subject to
+# the following conditions:
+#
+# The above copyright notice and this permission notice shall be included
+# in all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
+# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+#
+
+__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
+
+"""
+Test building Java applications when using Repositories.
+"""
+
+import TestSCons
+
+python = TestSCons.python
+
+test = TestSCons.TestSCons()
+
+where_javac, java_version = test.java_where_javac()
+
+# Try to get the major/minor Java version
+curver = (1, 0)
+if java_version.count('.') == 1:
+ # Check Java version
+ major, minor = java_version.split('.')
+ try:
+ curver = (int(major), int(minor))
+ except:
+ pass
+
+# Check the version of the found Java compiler.
+# If it's 1.8 or higher, we skip the further RMIC test
+# because we'll get warnings about the deprecated API...
+# it's just not state-of-the-art anymore.
+# Note, how we allow simple version strings like "5" and
+# "6" to successfully pass this test.
+if curver >= (1, 8):
+ test.skip_test('The found version of javac is higher than 1.7, skipping test.\n')
+
+
+where_java = test.java_where_java()
+where_rmic = test.java_where_rmic()
+
+java = where_java
+javac = where_javac
+rmic = where_rmic
+
+###############################################################################
+
+#
+test.subdir('rep1', ['rep1', 'src'],
+ 'work1',
+ 'work2',
+ 'work3')
+
+#
+rep1_classes = test.workpath('rep1', 'classes')
+work1_classes = test.workpath('work1', 'classes')
+work3_classes = test.workpath('work3', 'classes')
+
+#
+opts = '-Y ' + test.workpath('rep1')
+
+#
+test.write(['rep1', 'SConstruct'], """
+env = Environment(tools = ['javac', 'rmic'],
+ JAVAC = r'%s',
+ RMIC = r'%s')
+classes = env.Java(target = 'classes', source = 'src')
+# Brute-force removal of the "Hello" class.
+classes = [c for c in classes if str(c).find('Hello') == -1]
+env.RMIC(target = 'outdir', source = classes)
+""" % (javac, rmic))
+
+test.write(['rep1', 'src', 'Hello.java'], """\
+package com.sub.foo;
+
+import java.rmi.Remote;
+import java.rmi.RemoteException;
+
+public interface Hello extends Remote {
+ String sayHello() throws RemoteException;
+}
+""")
+
+test.write(['rep1', 'src', 'Foo1.java'], """\
+package com.sub.foo;
+
+import java.rmi.Naming;
+import java.rmi.RemoteException;
+import java.rmi.RMISecurityManager;
+import java.rmi.server.UnicastRemoteObject;
+
+public class Foo1 extends UnicastRemoteObject implements Hello {
+
+ static final long serialVersionUID = 0;
+
+ public Foo1() throws RemoteException {
+ super();
+ }
+
+ public String sayHello() {
+ return "rep1/src/Foo1.java";
+ }
+
+ public static void main(String args[]) {
+ if (System.getSecurityManager() == null) {
+ System.setSecurityManager(new RMISecurityManager());
+ }
+
+ try {
+ Foo1 obj = new Foo1();
+
+ Naming.rebind("//myhost/HelloServer", obj);
+
+ System.out.println("HelloServer bound in registry");
+ } catch (Exception e) {
+ System.out.println("Foo1 err: " + e.getMessage());
+ e.printStackTrace();
+ }
+ }
+}
+""")
+
+test.write(['rep1', 'src', 'Foo2.java'], """\
+package com.sub.foo;
+
+import java.rmi.Naming;
+import java.rmi.RemoteException;
+import java.rmi.RMISecurityManager;
+import java.rmi.server.UnicastRemoteObject;
+
+public class Foo2 extends UnicastRemoteObject implements Hello {
+
+ static final long serialVersionUID = 0;
+
+ public Foo2() throws RemoteException {
+ super();
+ }
+
+ public String sayHello() {
+ return "rep1/src/Foo2.java";
+ }
+
+ public static void main(String args[]) {
+ if (System.getSecurityManager() == null) {
+ System.setSecurityManager(new RMISecurityManager());
+ }
+
+ try {
+ Foo2 obj = new Foo2();
+
+ Naming.rebind("//myhost/HelloServer", obj);
+
+ System.out.println("HelloServer bound in registry");
+ } catch (Exception e) {
+ System.out.println("Foo2 err: " + e.getMessage());
+ e.printStackTrace();
+ }
+ }
+}
+""")
+
+# Make the repository non-writable,
+# so we'll detect if we try to write into it accidentally.
+test.writable('repository', 0)
+
+#
+test.run(chdir = 'work1', options = opts, arguments = ".")
+
+# XXX I'd rather run the resulting class files through the JVM here to
+# see that they were built from the proper rep1 sources, but I don't
+# know how to do that with RMI, so punt for now.
+
+test.must_not_exist(test.workpath('rep1', 'outdir', 'com', 'sub', 'foo', 'Foo1_Stub.class'))
+test.must_not_exist(test.workpath('rep1', 'outdir', 'com', 'sub', 'foo', 'Foo2_Stub.class'))
+
+test.must_exist (test.workpath('work1', 'outdir', 'com', 'sub', 'foo', 'Foo1_Stub.class'))
+test.must_exist (test.workpath('work1', 'outdir', 'com', 'sub', 'foo', 'Foo2_Stub.class'))
+
+# We used to check for _Skel.class files as well, but they're not
+# generated by default starting with Java 1.5, and they apparently
+# haven't been needed for a while. Don't bother looking, even if we're
+# running Java 1.4. If we think they're needed but they don't exist
+# the variou test.up_to_date() calls below will detect it.
+#test.must_not_exist(test.workpath('rep1', 'outdir', 'com', 'sub', 'foo', 'Foo2_Skel.class'))
+#test.must_exist (test.workpath('work1', 'outdir', 'com', 'sub', 'foo', 'Foo1_Skel.class'))
+#test.must_exist (test.workpath('work1', 'outdir', 'com', 'sub', 'foo', 'Foo2_Skel.class'))
+
+test.up_to_date(chdir = 'work1', options = opts, arguments = ".")
+
+#
+test.subdir(['work1', 'src'])
+
+test.write(['work1', 'src', 'Hello.java'], """\
+package com.sub.foo;
+
+import java.rmi.Remote;
+import java.rmi.RemoteException;
+
+public interface Hello extends Remote {
+ String sayHello() throws RemoteException;
+}
+""")
+
+test.write(['work1', 'src', 'Foo1.java'], """\
+package com.sub.foo;
+
+import java.rmi.Naming;
+import java.rmi.RemoteException;
+import java.rmi.RMISecurityManager;
+import java.rmi.server.UnicastRemoteObject;
+
+public class Foo1 extends UnicastRemoteObject implements Hello {
+
+ static final long serialVersionUID = 0;
+
+ public Foo1() throws RemoteException {
+ super();
+ }
+
+ public String sayHello() {
+ return "work1/src/Foo1.java";
+ }
+
+ public static void main(String args[]) {
+ if (System.getSecurityManager() == null) {
+ System.setSecurityManager(new RMISecurityManager());
+ }
+
+ try {
+ Foo1 obj = new Foo1();
+
+ Naming.rebind("//myhost/HelloServer", obj);
+
+ System.out.println("HelloServer bound in registry");
+ } catch (Exception e) {
+ System.out.println("Foo1 err: " + e.getMessage());
+ e.printStackTrace();
+ }
+ }
+}
+""")
+
+test.write(['work1', 'src', 'Foo2.java'], """\
+package com.sub.foo;
+
+import java.rmi.Naming;
+import java.rmi.RemoteException;
+import java.rmi.RMISecurityManager;
+import java.rmi.server.UnicastRemoteObject;
+
+public class Foo2 extends UnicastRemoteObject implements Hello {
+
+ static final long serialVersionUID = 0;
+
+ public Foo2() throws RemoteException {
+ super();
+ }
+
+ public String sayHello() {
+ return "work1/src/Foo2.java";
+ }
+
+ public static void main(String args[]) {
+ if (System.getSecurityManager() == null) {
+ System.setSecurityManager(new RMISecurityManager());
+ }
+
+ try {
+ Foo2 obj = new Foo2();
+
+ Naming.rebind("//myhost/HelloServer", obj);
+
+ System.out.println("HelloServer bound in registry");
+ } catch (Exception e) {
+ System.out.println("Foo2 err: " + e.getMessage());
+ e.printStackTrace();
+ }
+ }
+}
+""")
+
+test.run(chdir = 'work1', options = opts, arguments = ".")
+
+expect = [
+ ' src/Foo1.java src/Foo2.java',
+ ' com.sub.foo.Foo1 com.sub.foo.Foo2',
+]
+
+test.must_contain_all_lines(test.stdout(), expect)
+
+# XXX I'd rather run the resulting class files through the JVM here to
+# see that they were built from the proper work1 sources, but I don't
+# know how to do that with RMI, so punt for now.
+
+test.must_not_exist(test.workpath('rep1', 'outdir', 'com', 'sub', 'foo', 'Foo1_Stub.class'))
+test.must_not_exist(test.workpath('rep1', 'outdir', 'com', 'sub', 'foo', 'Foo2_Stub.class'))
+test.must_exist (test.workpath('work1', 'outdir', 'com', 'sub', 'foo', 'Foo1_Stub.class'))
+test.must_exist (test.workpath('work1', 'outdir', 'com', 'sub', 'foo', 'Foo2_Stub.class'))
+
+#test.must_not_exist(test.workpath('rep1', 'outdir', 'com', 'sub', 'foo', 'Foo1_Skel.class'))
+#test.must_not_exist(test.workpath('rep1', 'outdir', 'com', 'sub', 'foo', 'Foo2_Skel.class'))
+#test.must_exist (test.workpath('work1', 'outdir', 'com', 'sub', 'foo', 'Foo1_Skel.class'))
+#test.must_exist (test.workpath('work1', 'outdir', 'com', 'sub', 'foo', 'Foo2_Skel.class'))
+
+test.up_to_date(chdir = 'work1', options = opts, arguments = ".")
+
+#
+test.writable('rep1', 1)
+
+test.run(chdir = 'rep1', options = opts, arguments = ".")
+
+# XXX I'd rather run the resulting class files through the JVM here to
+# see that they were built from the proper work1 sources, but I don't
+# know how to do that with RMI, so punt for now.
+
+test.must_exist(test.workpath('rep1', 'outdir', 'com', 'sub', 'foo', 'Foo1_Stub.class'))
+test.must_exist(test.workpath('rep1', 'outdir', 'com', 'sub', 'foo', 'Foo2_Stub.class'))
+
+#test.must_exist(test.workpath('rep1', 'outdir', 'com', 'sub', 'foo', 'Foo1_Skel.class'))
+#test.must_exist(test.workpath('rep1', 'outdir', 'com', 'sub', 'foo', 'Foo2_Skel.class'))
+
+test.up_to_date(chdir = 'rep1', options = opts, arguments = ".")
+
+#
+test.writable('repository', 0)
+
+#
+test.up_to_date(chdir = 'work2', options = opts, arguments = ".")
+
+#
+test.write(['work3', 'SConstruct'], """
+env = Environment(tools = ['javac', 'rmic'],
+ JAVAC = r'%s',
+ RMIC = r'%s')
+classes = env.Java(target = 'classes', source = 'src')
+# Brute-force removal of the "Hello" class.
+classes = [c for c in classes if str(c).find('Hello') == -1]
+rmi_classes = env.RMIC(target = 'outdir', source = classes)
+Local(rmi_classes)
+""" % (javac, rmic))
+
+test.run(chdir = 'work3', options = opts, arguments = ".")
+
+test.must_not_exist(test.workpath('work3', 'classes', 'com', 'sub', 'foo', 'Hello.class'))
+test.must_not_exist(test.workpath('work3', 'classes', 'com', 'sub', 'foo', 'Foo1.class'))
+test.must_not_exist(test.workpath('work3', 'classes', 'com', 'sub', 'foo', 'Foo2.class'))
+
+test.must_exist (test.workpath('work3', 'outdir', 'com', 'sub', 'foo', 'Foo1_Stub.class'))
+test.must_exist (test.workpath('work3', 'outdir', 'com', 'sub', 'foo', 'Foo2_Stub.class'))
+
+#test.must_exist (test.workpath('work3', 'outdir', 'com', 'sub', 'foo', 'Foo1_Skel.class'))
+#test.must_exist (test.workpath('work3', 'outdir', 'com', 'sub', 'foo', 'Foo2_Skel.class'))
+
+test.up_to_date(chdir = 'work3', options = opts, arguments = ".")
+
+test.pass_test()
+
+# Local Variables:
+# tab-width:4
+# indent-tabs-mode:nil
+# End:
+# vim: set expandtab tabstop=4 shiftwidth=4:
diff --git a/test/Repository/SConscript.py b/test/Repository/SConscript.py
new file mode 100644
index 0000000..22956ac
--- /dev/null
+++ b/test/Repository/SConscript.py
@@ -0,0 +1,131 @@
+#!/usr/bin/env python
+#
+# __COPYRIGHT__
+#
+# Permission is hereby granted, free of charge, to any person obtaining
+# a copy of this software and associated documentation files (the
+# "Software"), to deal in the Software without restriction, including
+# without limitation the rights to use, copy, modify, merge, publish,
+# distribute, sublicense, and/or sell copies of the Software, and to
+# permit persons to whom the Software is furnished to do so, subject to
+# the following conditions:
+#
+# The above copyright notice and this permission notice shall be included
+# in all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
+# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+#
+
+__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
+
+"""
+Test how we handle SConscript calls when using a Repository.
+"""
+
+import sys
+import TestSCons
+
+if sys.platform == 'win32':
+ _exe = '.exe'
+else:
+ _exe = ''
+
+test = TestSCons.TestSCons()
+
+#
+test.subdir('work',
+ ['work', 'src'],
+ 'rep1',
+ ['rep1', 'src'],
+ 'rep2',
+ ['rep2', 'build'],
+ ['rep2', 'src'],
+ ['rep2', 'src', 'sub'])
+
+#
+workpath_rep1 = test.workpath('rep1')
+workpath_rep2 = test.workpath('rep2')
+
+#
+test.write(['work', 'SConstruct'], """
+Repository(r'%s')
+SConscript('src/SConscript')
+""" % workpath_rep1)
+
+test.write(['rep1', 'src', 'SConscript'], """\
+def cat(env, source, target):
+ target = str(target[0])
+ f = open(target, "wb")
+ for src in source:
+ f.write(open(str(src), "rb").read())
+ f.close()
+env = Environment(BUILDERS={'Cat':Builder(action=cat)})
+env.Cat(target = 'foo', source = ['aaa.in', 'bbb.in', 'ccc.in'])
+""")
+
+test.write(['rep1', 'src', 'aaa.in'], "rep1/src/aaa.in\n")
+test.write(['rep1', 'src', 'bbb.in'], "rep1/src/bbb.in\n")
+test.write(['rep1', 'src', 'ccc.in'], "rep1/src/ccc.in\n")
+
+# Make the rep1 non-writable,
+# so we'll detect if we try to write into it accidentally.
+test.writable('rep1', 0)
+
+test.run(chdir = 'work', arguments = ".")
+
+test.fail_test(test.read(['work', 'src', 'foo']) != """\
+rep1/src/aaa.in
+rep1/src/bbb.in
+rep1/src/ccc.in
+""")
+
+test.up_to_date(chdir = 'work', arguments = ".")
+
+#
+test.write(['rep2', 'build', 'SConstruct'], """
+env = Environment(REPOSITORY = r'%s')
+env.Repository('$REPOSITORY')
+SConscript('src/SConscript')
+""" % workpath_rep2)
+
+test.write(['rep2', 'src', 'SConscript'], """\
+def cat(env, source, target):
+ target = str(target[0])
+ f = open(target, "wb")
+ for src in source:
+ f.write(open(str(src), "rb").read())
+ f.close()
+env = Environment(BUILDERS={'Cat':Builder(action=cat)})
+env.Cat(target = 'foo', source = ['aaa.in', 'bbb.in', 'ccc.in'])
+SConscript('sub/SConscript')
+""")
+
+test.write(['rep2', 'src', 'sub', 'SConscript'], """\
+""")
+
+test.write(['rep2', 'src', 'aaa.in'], "rep2/src/aaa.in\n")
+test.write(['rep2', 'src', 'bbb.in'], "rep2/src/bbb.in\n")
+test.write(['rep2', 'src', 'ccc.in'], "rep2/src/ccc.in\n")
+
+test.run(chdir = 'rep2/build', arguments = ".")
+
+test.fail_test(test.read(['rep2', 'build', 'src', 'foo']) != """\
+rep2/src/aaa.in
+rep2/src/bbb.in
+rep2/src/ccc.in
+""")
+
+#
+test.pass_test()
+
+# Local Variables:
+# tab-width:4
+# indent-tabs-mode:nil
+# End:
+# vim: set expandtab tabstop=4 shiftwidth=4:
diff --git a/test/Repository/SConsignFile.py b/test/Repository/SConsignFile.py
new file mode 100644
index 0000000..fef2c75
--- /dev/null
+++ b/test/Repository/SConsignFile.py
@@ -0,0 +1,67 @@
+#!/usr/bin/env python
+#
+# __COPYRIGHT__
+#
+# Permission is hereby granted, free of charge, to any person obtaining
+# a copy of this software and associated documentation files (the
+# "Software"), to deal in the Software without restriction, including
+# without limitation the rights to use, copy, modify, merge, publish,
+# distribute, sublicense, and/or sell copies of the Software, and to
+# permit persons to whom the Software is furnished to do so, subject to
+# the following conditions:
+#
+# The above copyright notice and this permission notice shall be included
+# in all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
+# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+#
+
+__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
+
+"""
+Verify that the Repository option works when recording signature
+information in an SConsignFile().
+"""
+
+import TestSCons
+
+test = TestSCons.TestSCons()
+
+test.subdir('repository', 'work')
+
+SConstruct_contents = """\
+SConsignFile('sconsignfile')
+env = Environment()
+result = env.Command('file.out', 'file.in', Copy("$TARGET", "$SOURCE"))
+Default(result)
+"""
+
+test.write(['repository', 'SConstruct'], SConstruct_contents)
+
+test.write(['repository', 'file.in'], "repository/file.in\n")
+
+test.run(chdir='repository')
+
+test.must_match(['repository', 'file.out'], "repository/file.in\n")
+
+test.write(['work', 'SConstruct'], SConstruct_contents)
+
+test.run(chdir='work',
+ arguments='-Y ../repository -n --debug=explain',
+ stdout=test.wrap_stdout("scons: `file.out' is up to date.\n"))
+
+test.must_not_exist(['work', 'file.out'])
+
+test.pass_test()
+
+# Local Variables:
+# tab-width:4
+# indent-tabs-mode:nil
+# End:
+# vim: set expandtab tabstop=4 shiftwidth=4:
diff --git a/test/Repository/SharedLibrary.py b/test/Repository/SharedLibrary.py
new file mode 100644
index 0000000..51142aa
--- /dev/null
+++ b/test/Repository/SharedLibrary.py
@@ -0,0 +1,129 @@
+#!/usr/bin/env python
+#
+# __COPYRIGHT__
+#
+# Permission is hereby granted, free of charge, to any person obtaining
+# a copy of this software and associated documentation files (the
+# "Software"), to deal in the Software without restriction, including
+# without limitation the rights to use, copy, modify, merge, publish,
+# distribute, sublicense, and/or sell copies of the Software, and to
+# permit persons to whom the Software is furnished to do so, subject to
+# the following conditions:
+#
+# The above copyright notice and this permission notice shall be included
+# in all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
+# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+#
+
+__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
+
+"""
+Verify that we can create a local shared library containing shared
+object files built in a repository.
+"""
+
+import os
+import sys
+
+import TestSCons
+
+test = TestSCons.TestSCons()
+
+#
+test.subdir('repository', 'work')
+
+#
+opts = '-Y ' + test.workpath('repository')
+
+#
+test.write(['repository', 'SConstruct'], """\
+env = Environment()
+f1 = env.SharedObject('f1.c')
+f2 = env.SharedObject('f2.c')
+f3 = env.SharedObject('f3.c')
+if ARGUMENTS.get('PROGRAM'):
+ lib = env.SharedLibrary(target = 'foo',
+ source = f1 + f2 + f3,
+ WINDOWS_INSERT_DEF = 1)
+ env.Program(target='prog', source='prog.c', LIBS='foo', LIBPATH=['.'])
+""")
+
+for fx in ['1', '2', '3']:
+ test.write(['repository', 'f%s.c' % (fx)], r"""
+#include <stdio.h>
+
+void
+f%s(void)
+{
+ printf("f%s.c\n");
+ fflush(stdout);
+}
+""" % (fx,fx))
+
+test.write(['repository', "foo.def"], r"""
+LIBRARY "foo"
+DESCRIPTION "Foo Shared Library"
+
+EXPORTS
+ f1
+ f2
+ f3
+""")
+
+test.write(['repository', 'prog.c'], r"""
+#include <stdio.h>
+void f1(void);
+void f2(void);
+void f3(void);
+int
+main(int argc, char *argv[])
+{
+ argv[argc++] = "--";
+ f1();
+ f2();
+ f3();
+ printf("prog.c\n");
+ return 0;
+}
+""")
+
+# Build the relocatable objects within the repository
+test.run(chdir = 'repository', arguments = '.')
+
+# Make the repository non-writable,
+# so we'll detect if we try to write into it accidentally.
+test.writable('repository', 0)
+
+# Build the library and the program within the work area
+test.run(chdir='work',
+ options=opts,
+ arguments='PROGRAM=1',
+ stderr=TestSCons.noisy_ar,
+ match=TestSCons.match_re_dotall)
+
+# Run the program and verify that the library worked
+if os.name == 'posix':
+ if sys.platform[:6] == 'darwin':
+ os.environ['DYLD_LIBRARY_PATH'] = test.workpath('work')
+ else:
+ os.environ['LD_LIBRARY_PATH'] = test.workpath('work')
+if sys.platform.find('irix') != -1:
+ os.environ['LD_LIBRARYN32_PATH'] = test.workpath('work')
+
+test.run(program = test.workpath('work', 'prog'),
+ stdout = "f1.c\nf2.c\nf3.c\nprog.c\n")
+
+test.pass_test()
+
+# Local Variables:
+# tab-width:4
+# indent-tabs-mode:nil
+# End:
+# vim: set expandtab tabstop=4 shiftwidth=4:
diff --git a/test/Repository/StaticLibrary.py b/test/Repository/StaticLibrary.py
new file mode 100644
index 0000000..4f8160c
--- /dev/null
+++ b/test/Repository/StaticLibrary.py
@@ -0,0 +1,235 @@
+#!/usr/bin/env python
+#
+# __COPYRIGHT__
+#
+# Permission is hereby granted, free of charge, to any person obtaining
+# a copy of this software and associated documentation files (the
+# "Software"), to deal in the Software without restriction, including
+# without limitation the rights to use, copy, modify, merge, publish,
+# distribute, sublicense, and/or sell copies of the Software, and to
+# permit persons to whom the Software is furnished to do so, subject to
+# the following conditions:
+#
+# The above copyright notice and this permission notice shall be included
+# in all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
+# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+#
+
+__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
+
+import os.path
+import TestSCons
+
+_obj = TestSCons._obj
+_exe = TestSCons._exe
+
+test = TestSCons.TestSCons()
+
+#
+test.subdir('repository', 'work1', 'work2', 'work3')
+
+#
+workpath_repository = test.workpath('repository')
+repository_aaa_obj = test.workpath('repository', 'aaa' + _obj)
+repository_bbb_obj = test.workpath('repository', 'bbb' + _obj)
+repository_foo_obj = test.workpath('repository', 'foo' + _obj)
+repository_foo = test.workpath('repository', 'foo' + _exe)
+work1_foo = test.workpath('work1', 'foo' + _exe)
+work2_aaa_obj = test.workpath('work2', 'aaa' + _obj)
+work2_foo_obj = test.workpath('work2', 'foo' + _obj)
+work2_foo = test.workpath('work2', 'foo' + _exe)
+work3_aaa_obj = test.workpath('work3', 'aaa' + _obj)
+work3_bbb_obj = test.workpath('work3', 'bbb' + _obj)
+work3_foo = test.workpath('work3', 'foo' + _exe)
+
+opts = '-Y ' + workpath_repository
+
+#
+test.write(['repository', 'SConstruct'], """
+env = Environment(LIBS = ['xxx'], LIBPATH = '.')
+env.Library(target = 'xxx', source = ['aaa.c', 'bbb.c'])
+env.Program(target = 'foo', source = 'foo.c')
+""")
+
+test.write(['repository', 'aaa.c'], r"""
+#include <stdio.h>
+#include <stdlib.h>
+void
+aaa(void)
+{
+ printf("repository/aaa.c\n");
+}
+""")
+
+test.write(['repository', 'bbb.c'], r"""
+#include <stdio.h>
+#include <stdlib.h>
+void
+bbb(void)
+{
+ printf("repository/bbb.c\n");
+}
+""")
+
+test.write(['repository', 'foo.c'], r"""
+#include <stdio.h>
+#include <stdlib.h>
+extern void aaa(void);
+extern void bbb(void);
+int
+main(int argc, char *argv[])
+{
+ argv[argc++] = "--";
+ aaa();
+ bbb();
+ printf("repository/foo.c\n");
+ exit (0);
+}
+""")
+
+# Make the repository non-writable,
+# so we'll detect if we try to write into it accidentally.
+test.writable('repository', 0)
+
+#
+test.run(chdir = 'work1', options = opts, arguments = ".",
+ stderr=TestSCons.noisy_ar,
+ match=TestSCons.match_re_dotall)
+
+test.run(program = work1_foo, stdout =
+"""repository/aaa.c
+repository/bbb.c
+repository/foo.c
+""")
+
+test.fail_test(os.path.exists(repository_aaa_obj))
+test.fail_test(os.path.exists(repository_bbb_obj))
+test.fail_test(os.path.exists(repository_foo_obj))
+test.fail_test(os.path.exists(repository_foo))
+
+test.up_to_date(chdir = 'work1', options = opts, arguments = ".")
+
+test.write(['work1', 'bbb.c'], r"""
+#include <stdio.h>
+#include <stdlib.h>
+void
+bbb(void)
+{
+ printf("work1/bbb.c\n");
+}
+""")
+
+test.run(chdir = 'work1', options = opts, arguments = ".",
+ stderr=TestSCons.noisy_ar,
+ match=TestSCons.match_re_dotall)
+
+test.run(program = work1_foo, stdout =
+"""repository/aaa.c
+work1/bbb.c
+repository/foo.c
+""")
+
+test.fail_test(os.path.exists(repository_aaa_obj))
+test.fail_test(os.path.exists(repository_bbb_obj))
+test.fail_test(os.path.exists(repository_foo_obj))
+test.fail_test(os.path.exists(repository_foo))
+
+test.up_to_date(chdir = 'work1', options = opts, arguments = ".")
+
+#
+test.writable('repository', 1)
+
+test.run(chdir = 'repository', options = opts, arguments = ".",
+ stderr=TestSCons.noisy_ar,
+ match=TestSCons.match_re_dotall)
+
+test.run(program = repository_foo, stdout =
+"""repository/aaa.c
+repository/bbb.c
+repository/foo.c
+""")
+
+test.fail_test(not os.path.exists(repository_aaa_obj))
+test.fail_test(not os.path.exists(repository_bbb_obj))
+test.fail_test(not os.path.exists(repository_foo_obj))
+
+test.up_to_date(chdir = 'repository', options = opts, arguments = ".")
+
+#
+test.writable('repository', 0)
+
+#
+test.up_to_date(chdir = 'work2', options = opts, arguments = ".")
+
+test.write(['work2', 'bbb.c'], r"""
+#include <stdio.h>
+#include <stdlib.h>
+void
+bbb(void)
+{
+ printf("work2/bbb.c\n");
+}
+""")
+
+test.run(chdir = 'work2', options = opts, arguments = ".",
+ stderr=TestSCons.noisy_ar,
+ match=TestSCons.match_re_dotall)
+
+test.run(program = work2_foo, stdout =
+"""repository/aaa.c
+work2/bbb.c
+repository/foo.c
+""")
+
+test.fail_test(os.path.exists(work2_aaa_obj))
+test.fail_test(os.path.exists(work2_foo_obj))
+
+test.up_to_date(chdir = 'work2', options = opts, arguments = ".")
+
+#
+test.up_to_date(chdir = 'work3', options = opts, arguments = ".")
+
+test.write(['work3', 'foo.c'], r"""
+#include <stdio.h>
+#include <stdlib.h>
+extern void aaa(void);
+extern void bbb(void);
+int
+main(int argc, char *argv[])
+{
+ argv[argc++] = "--";
+ aaa();
+ bbb();
+ printf("work3/foo.c\n");
+ exit (0);
+}
+""")
+
+test.run(chdir = 'work3', options = opts, arguments = ".")
+
+test.run(program = work3_foo, stdout =
+"""repository/aaa.c
+repository/bbb.c
+work3/foo.c
+""")
+
+test.fail_test(os.path.exists(work3_aaa_obj))
+test.fail_test(os.path.exists(work3_bbb_obj))
+
+test.up_to_date(chdir = 'work3', options = opts, arguments = ".")
+
+#
+test.pass_test()
+
+# Local Variables:
+# tab-width:4
+# indent-tabs-mode:nil
+# End:
+# vim: set expandtab tabstop=4 shiftwidth=4:
diff --git a/test/Repository/VariantDir.py b/test/Repository/VariantDir.py
new file mode 100644
index 0000000..ec723c8
--- /dev/null
+++ b/test/Repository/VariantDir.py
@@ -0,0 +1,205 @@
+#!/usr/bin/env python
+#
+# __COPYRIGHT__
+#
+# Permission is hereby granted, free of charge, to any person obtaining
+# a copy of this software and associated documentation files (the
+# "Software"), to deal in the Software without restriction, including
+# without limitation the rights to use, copy, modify, merge, publish,
+# distribute, sublicense, and/or sell copies of the Software, and to
+# permit persons to whom the Software is furnished to do so, subject to
+# the following conditions:
+#
+# The above copyright notice and this permission notice shall be included
+# in all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
+# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+#
+
+__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
+
+import os.path
+
+import TestSCons
+
+test = TestSCons.TestSCons()
+
+test.subdir('repository', ['repository', 'src'],
+ 'work1', ['work1', 'src'],
+ 'work2', ['work2', 'src'])
+
+opts = "-Y " + test.workpath('repository')
+
+#
+test.write(['repository', 'SConstruct'], r"""
+VariantDir('build0', 'src', duplicate=0)
+VariantDir('build1', 'src', duplicate=1)
+SConscript('build0/SConscript')
+SConscript('build1/SConscript')
+""")
+
+test.write(['repository', 'src', 'SConscript'], r"""
+def cat(env, source, target):
+ target = str(target[0])
+ source = list(map(str, source))
+ print 'cat(%s) > %s' % (source, target)
+ f = open(target, "wb")
+ for src in source:
+ f.write(open(src, "rb").read())
+ f.close()
+
+env = Environment(BUILDERS={'Build':Builder(action=cat)})
+env.Build('aaa.mid', 'aaa.in')
+env.Build('bbb.mid', 'bbb.in')
+env.Build('ccc.mid', 'ccc.in')
+env.Build('output', ['aaa.mid', 'bbb.mid', 'ccc.mid'])
+""")
+
+test.write(['repository', 'src', 'aaa.in'], "repository/src/aaa.in\n")
+test.write(['repository', 'src', 'bbb.in'], "repository/src/bbb.in\n")
+test.write(['repository', 'src', 'ccc.in'], "repository/src/ccc.in\n")
+
+# Make the entire repository non-writable, so we'll detect
+# if we try to write into it accidentally.
+test.writable('repository', 0)
+
+#
+test.run(chdir = 'work1', options = opts, arguments = '.')
+
+test.fail_test(test.read(['work1', 'build0', 'output']) !=
+"""repository/src/aaa.in
+repository/src/bbb.in
+repository/src/ccc.in
+""")
+
+test.fail_test(os.path.exists('work1/build0/aaa.in'))
+test.fail_test(os.path.exists('work1/build0/bbb.in'))
+test.fail_test(os.path.exists('work1/build0/ccc.in'))
+test.fail_test(not os.path.exists('work1/build0/aaa.mid'))
+test.fail_test(not os.path.exists('work1/build0/bbb.mid'))
+test.fail_test(not os.path.exists('work1/build0/ccc.mid'))
+
+test.fail_test(test.read(['work1', 'build1', 'output']) !=
+"""repository/src/aaa.in
+repository/src/bbb.in
+repository/src/ccc.in
+""")
+
+test.fail_test(not os.path.exists('work1/build1/aaa.in'))
+test.fail_test(not os.path.exists('work1/build1/bbb.in'))
+test.fail_test(not os.path.exists('work1/build1/ccc.in'))
+test.fail_test(not os.path.exists('work1/build1/aaa.mid'))
+test.fail_test(not os.path.exists('work1/build1/bbb.mid'))
+test.fail_test(not os.path.exists('work1/build1/ccc.mid'))
+
+test.up_to_date(chdir = 'work1', options = opts, arguments = '.')
+
+#
+test.write(['work1', 'src', 'bbb.in'], "work1/src/bbb.in\n")
+
+test.run(chdir = 'work1', options = opts, arguments = '.')
+
+test.fail_test(test.read(['work1', 'build0', 'output']) !=
+"""repository/src/aaa.in
+work1/src/bbb.in
+repository/src/ccc.in
+""")
+
+test.fail_test(os.path.exists('work1/build0/aaa.in'))
+test.fail_test(os.path.exists('work1/build0/bbb.in'))
+test.fail_test(os.path.exists('work1/build0/ccc.in'))
+test.fail_test(not os.path.exists('work1/build0/aaa.mid'))
+test.fail_test(not os.path.exists('work1/build0/bbb.mid'))
+test.fail_test(not os.path.exists('work1/build0/ccc.mid'))
+
+test.fail_test(test.read(['work1', 'build1', 'output']) !=
+"""repository/src/aaa.in
+work1/src/bbb.in
+repository/src/ccc.in
+""")
+
+test.fail_test(not os.path.exists('work1/build1/aaa.in'))
+test.fail_test(not os.path.exists('work1/build1/bbb.in'))
+test.fail_test(not os.path.exists('work1/build1/ccc.in'))
+test.fail_test(not os.path.exists('work1/build1/aaa.mid'))
+test.fail_test(not os.path.exists('work1/build1/bbb.mid'))
+test.fail_test(not os.path.exists('work1/build1/ccc.mid'))
+
+test.up_to_date(chdir = 'work1', options = opts, arguments = '.')
+
+# Now build the stuff in the repository,
+# and redo the above steps in a fresh work directory.
+test.writable('repository', 1)
+
+test.run(chdir = 'repository', arguments = '.')
+
+test.writable('repository', 0)
+
+#
+test.run(chdir = 'work2', options = opts, arguments = '.')
+
+test.fail_test(os.path.exists('work2/build0/aaa.in'))
+test.fail_test(os.path.exists('work2/build0/bbb.in'))
+test.fail_test(os.path.exists('work2/build0/ccc.in'))
+test.fail_test(os.path.exists('work2/build0/aaa.mid'))
+test.fail_test(os.path.exists('work2/build0/bbb.mid'))
+test.fail_test(os.path.exists('work2/build0/ccc.mid'))
+test.fail_test(os.path.exists('work2/build0/output'))
+
+test.fail_test(not os.path.exists('work2/build1/aaa.in'))
+test.fail_test(not os.path.exists('work2/build1/bbb.in'))
+test.fail_test(not os.path.exists('work2/build1/ccc.in'))
+test.fail_test(os.path.exists('work2/build1/aaa.mid'))
+test.fail_test(os.path.exists('work2/build1/bbb.mid'))
+test.fail_test(os.path.exists('work2/build1/ccc.mid'))
+test.fail_test(os.path.exists('work2/build1/output'))
+
+test.up_to_date(chdir = 'work2', options = opts, arguments = '.')
+
+#
+test.write(['work2', 'src', 'bbb.in'], "work2/src/bbb.in\n")
+
+test.run(chdir = 'work2', options = opts, arguments = '.')
+
+test.fail_test(test.read(['work2', 'build0', 'output']) !=
+"""repository/src/aaa.in
+work2/src/bbb.in
+repository/src/ccc.in
+""")
+
+test.fail_test(os.path.exists('work2/build0/aaa.in'))
+test.fail_test(os.path.exists('work2/build0/bbb.in'))
+test.fail_test(os.path.exists('work2/build0/ccc.in'))
+test.fail_test(os.path.exists('work2/build0/aaa.mid'))
+test.fail_test(not os.path.exists('work2/build0/bbb.mid'))
+test.fail_test(os.path.exists('work2/build0/ccc.mid'))
+
+test.fail_test(test.read(['work2', 'build1', 'output']) !=
+"""repository/src/aaa.in
+work2/src/bbb.in
+repository/src/ccc.in
+""")
+
+test.fail_test(not os.path.exists('work2/build1/aaa.in'))
+test.fail_test(not os.path.exists('work2/build1/bbb.in'))
+test.fail_test(not os.path.exists('work2/build1/ccc.in'))
+test.fail_test(os.path.exists('work2/build1/aaa.mid'))
+test.fail_test(not os.path.exists('work2/build1/bbb.mid'))
+test.fail_test(os.path.exists('work2/build1/ccc.mid'))
+
+test.up_to_date(chdir = 'work2', options = opts, arguments = '.')
+
+#
+test.pass_test()
+
+# Local Variables:
+# tab-width:4
+# indent-tabs-mode:nil
+# End:
+# vim: set expandtab tabstop=4 shiftwidth=4:
diff --git a/test/Repository/absolute-path.py b/test/Repository/absolute-path.py
new file mode 100644
index 0000000..5bd10e4
--- /dev/null
+++ b/test/Repository/absolute-path.py
@@ -0,0 +1,115 @@
+#!/usr/bin/env python
+#
+# __COPYRIGHT__
+#
+# Permission is hereby granted, free of charge, to any person obtaining
+# a copy of this software and associated documentation files (the
+# "Software"), to deal in the Software without restriction, including
+# without limitation the rights to use, copy, modify, merge, publish,
+# distribute, sublicense, and/or sell copies of the Software, and to
+# permit persons to whom the Software is furnished to do so, subject to
+# the following conditions:
+#
+# The above copyright notice and this permission notice shall be included
+# in all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
+# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+#
+
+__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
+
+import os.path
+import sys
+import TestSCons
+
+if sys.platform == 'win32':
+ _exe = '.exe'
+else:
+ _exe = ''
+
+test = TestSCons.TestSCons()
+
+test.subdir('repository',
+ ['repository', 'src'],
+ 'subdir',
+ 'work')
+
+src_SConscript = os.path.join('src', 'SConscript')
+subdir_aaa_c = test.workpath('subdir', 'aaa.c')
+work_src_foo = test.workpath('work', 'src', 'foo' + _exe)
+
+opts = "-Y " + test.workpath('repository')
+
+#
+test.write(['repository', 'SConstruct'], r"""
+SConscript(r'%s')
+""" % src_SConscript)
+
+test.write(['repository', 'src', 'SConscript'], r"""
+env = Environment()
+env.Program('foo', ['aaa.c', r'%s', 'foo.c'])
+""" % subdir_aaa_c)
+
+test.write(['repository', 'src', 'aaa.c'], r"""
+#include <stdio.h>
+#include <stdlib.h>
+void
+src_aaa(void)
+{
+ printf("repository/src/aaa.c\n");
+}
+""")
+
+test.write(['subdir', 'aaa.c'], r"""
+#include <stdio.h>
+#include <stdlib.h>
+void
+subdir_aaa(void)
+{
+ printf("subdir/aaa.c\n");
+}
+""")
+
+test.write(['repository', 'src', 'foo.c'], r"""
+#include <stdio.h>
+#include <stdlib.h>
+extern void src_aaa(void);
+extern void subdir_aaa(void);
+int
+main(int argc, char *argv[])
+{
+ argv[argc++] = "--";
+ src_aaa();
+ subdir_aaa();
+ printf("repository/src/foo.c\n");
+ exit (0);
+}
+""")
+
+# Make the entire repository non-writable, so we'll detect
+# if we try to write into it accidentally.
+test.writable('repository', 0)
+
+test.run(chdir = 'work', options = opts, arguments = '.')
+
+test.run(program = work_src_foo, stdout = """repository/src/aaa.c
+subdir/aaa.c
+repository/src/foo.c
+""")
+
+test.up_to_date(chdir = 'work', options = opts, arguments = '.')
+
+#
+test.pass_test()
+
+# Local Variables:
+# tab-width:4
+# indent-tabs-mode:nil
+# End:
+# vim: set expandtab tabstop=4 shiftwidth=4:
diff --git a/test/Repository/include.py b/test/Repository/include.py
new file mode 100644
index 0000000..c52765c
--- /dev/null
+++ b/test/Repository/include.py
@@ -0,0 +1,196 @@
+#!/usr/bin/env python
+#
+# __COPYRIGHT__
+#
+# Permission is hereby granted, free of charge, to any person obtaining
+# a copy of this software and associated documentation files (the
+# "Software"), to deal in the Software without restriction, including
+# without limitation the rights to use, copy, modify, merge, publish,
+# distribute, sublicense, and/or sell copies of the Software, and to
+# permit persons to whom the Software is furnished to do so, subject to
+# the following conditions:
+#
+# The above copyright notice and this permission notice shall be included
+# in all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
+# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+#
+
+__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
+
+import sys
+import TestSCons
+
+if sys.platform == 'win32':
+ _exe = '.exe'
+else:
+ _exe = ''
+
+test = TestSCons.TestSCons()
+
+test.subdir('repository', 'work')
+
+repository = test.workpath('repository')
+work_foo = test.workpath('work', 'foo' + _exe)
+work_foo_h = test.workpath('work', 'foo.h')
+
+test.write(['work', 'SConstruct'], """
+Repository(r'%s')
+env = Environment(CPPPATH = ['.'])
+env.Program(target = 'foo', source = 'foo.c')
+""" % repository)
+
+test.write(['repository', 'foo.h'], r"""
+#define STRING1 "repository/foo.h"
+#include <bar.h>
+""")
+
+test.write(['repository', 'bar.h'], r"""
+#define STRING2 "repository/bar.h"
+""")
+
+test.write(['repository', 'foo.c'], r"""
+#include <stdio.h>
+#include <stdlib.h>
+#include <foo.h>
+int
+main(int argc, char *argv[])
+{
+ argv[argc++] = "--";
+ printf("%s\n", STRING1);
+ printf("%s\n", STRING2);
+ printf("repository/foo.c\n");
+ exit (0);
+}
+""")
+
+# Make the entire repository non-writable, so we'll detect
+# if we try to write into it accidentally.
+test.writable('repository', 0)
+
+test.run(chdir = 'work', arguments = '.')
+
+test.run(program = work_foo, stdout =
+"""repository/foo.h
+repository/bar.h
+repository/foo.c
+""")
+
+test.up_to_date(chdir = 'work', arguments = '.')
+
+#
+test.write(['work', 'foo.h'], r"""
+#define STRING1 "work/foo.h"
+#include <bar.h>
+""")
+
+test.run(chdir = 'work', arguments = '.')
+
+test.run(program = work_foo, stdout =
+"""work/foo.h
+repository/bar.h
+repository/foo.c
+""")
+
+test.up_to_date(chdir = 'work', arguments = '.')
+
+#
+test.write(['work', 'foo.c'], r"""
+#include <stdio.h>
+#include <stdlib.h>
+#include <foo.h>
+int
+main(int argc, char *argv[])
+{
+ argv[argc++] = "--";
+ printf("%s\n", STRING1);
+ printf("%s\n", STRING2);
+ printf("work/foo.c\n");
+ exit (0);
+}
+""")
+
+test.run(chdir = 'work', arguments = '.')
+
+test.run(program = work_foo, stdout =
+"""work/foo.h
+repository/bar.h
+work/foo.c
+""")
+
+test.up_to_date(chdir = 'work', arguments = '.')
+
+#
+test.write(['work', 'bar.h'], r"""
+#define STRING2 "work/bar.h"
+""")
+
+test.run(chdir = 'work', arguments = '.')
+
+test.run(program = work_foo, stdout =
+"""work/foo.h
+work/bar.h
+work/foo.c
+""")
+
+test.up_to_date(chdir = 'work', arguments = '.')
+
+#
+test.writable('repository', 1)
+test.unlink(['work', 'foo.h'])
+test.writable('repository', 0)
+
+test.run(chdir = 'work', arguments = '.')
+
+test.run(program = work_foo, stdout =
+"""repository/foo.h
+work/bar.h
+work/foo.c
+""")
+
+test.up_to_date(chdir = 'work', arguments = '.')
+
+#
+test.writable('repository', 1)
+test.unlink(['work', 'foo.c'])
+test.writable('repository', 0)
+
+test.run(chdir = 'work', arguments = '.')
+
+test.run(program = work_foo, stdout =
+"""repository/foo.h
+work/bar.h
+repository/foo.c
+""")
+
+test.up_to_date(chdir = 'work', arguments = '.')
+
+#
+test.writable('repository', 1)
+test.unlink(['work', 'bar.h'])
+test.writable('repository', 0)
+
+test.run(chdir = 'work', arguments = '.')
+
+test.run(program = work_foo, stdout =
+"""repository/foo.h
+repository/bar.h
+repository/foo.c
+""")
+
+test.up_to_date(chdir = 'work', arguments = '.')
+
+#
+test.pass_test()
+
+# Local Variables:
+# tab-width:4
+# indent-tabs-mode:nil
+# End:
+# vim: set expandtab tabstop=4 shiftwidth=4:
diff --git a/test/Repository/link-object.py b/test/Repository/link-object.py
new file mode 100644
index 0000000..78add90
--- /dev/null
+++ b/test/Repository/link-object.py
@@ -0,0 +1,163 @@
+#!/usr/bin/env python
+#
+# __COPYRIGHT__
+#
+# Permission is hereby granted, free of charge, to any person obtaining
+# a copy of this software and associated documentation files (the
+# "Software"), to deal in the Software without restriction, including
+# without limitation the rights to use, copy, modify, merge, publish,
+# distribute, sublicense, and/or sell copies of the Software, and to
+# permit persons to whom the Software is furnished to do so, subject to
+# the following conditions:
+#
+# The above copyright notice and this permission notice shall be included
+# in all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
+# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+#
+
+__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
+
+import sys
+import TestSCons
+
+if sys.platform == 'win32':
+ _exe = '.exe'
+else:
+ _exe = ''
+
+
+
+test = TestSCons.TestSCons()
+
+#
+test.subdir('repository', 'work')
+
+#
+workpath_repository = test.workpath('repository')
+repository_foo = test.workpath('repository', 'foo' + _exe)
+work_foo = test.workpath('work', 'foo' + _exe)
+
+#
+test.write(['repository', 'SConstruct'], """
+Repository(r'%s')
+env = Environment()
+env.Program(target = 'foo', source = ['aaa.c', 'bbb.c', 'foo.c'])
+""" % workpath_repository)
+
+test.write(['repository', 'aaa.c'], r"""
+#include <stdio.h>
+#include <stdlib.h>
+void
+aaa(void)
+{
+ printf("repository/aaa.c\n");
+}
+""")
+
+test.write(['repository', 'bbb.c'], r"""
+#include <stdio.h>
+#include <stdlib.h>
+void
+bbb(void)
+{
+ printf("repository/bbb.c\n");
+}
+""")
+
+test.write(['repository', 'foo.c'], r"""
+#include <stdio.h>
+#include <stdlib.h>
+extern void aaa(void);
+extern void bbb(void);
+int
+main(int argc, char *argv[])
+{
+ argv[argc++] = "--";
+ aaa();
+ bbb();
+ printf("repository/foo.c\n");
+ exit (0);
+}
+""")
+
+#
+test.run(chdir = 'repository', arguments = ".")
+
+test.run(program = repository_foo, stdout =
+"""repository/aaa.c
+repository/bbb.c
+repository/foo.c
+""")
+
+test.up_to_date(chdir = 'repository', arguments = ".")
+
+# Make the repository non-writable,
+# so we'll detect if we try to write into it accidentally.
+test.writable('repository', 0)
+
+#
+test.write(['work', 'SConstruct'], """
+Repository(r'%s')
+env = Environment()
+env.Program(target = 'foo', source = ['aaa.c', 'bbb.c', 'foo.c'])
+""" % workpath_repository)
+
+test.up_to_date(chdir = 'work', arguments = ".")
+
+#
+test.write(['work', 'bbb.c'], r"""
+#include <stdio.h>
+#include <stdlib.h>
+void
+bbb(void)
+{
+ printf("work/bbb.c\n");
+}
+""")
+
+#
+test.run(chdir = 'work', arguments = ".")
+
+test.run(program = work_foo, stdout =
+"""repository/aaa.c
+work/bbb.c
+repository/foo.c
+""")
+
+test.up_to_date(chdir = 'work', arguments = ".")
+
+#
+test.unlink(['work', 'bbb.c'])
+
+#
+test.run(chdir = 'work', arguments = ".")
+
+test.run(program = work_foo, stdout =
+"""repository/aaa.c
+repository/bbb.c
+repository/foo.c
+""")
+
+test.up_to_date(chdir = 'work', arguments = ".")
+
+#
+test.writable('repository', 1)
+
+#
+test.up_to_date(chdir = 'repository', arguments = ".")
+
+#
+test.pass_test()
+
+# Local Variables:
+# tab-width:4
+# indent-tabs-mode:nil
+# End:
+# vim: set expandtab tabstop=4 shiftwidth=4:
diff --git a/test/Repository/multi-dir.py b/test/Repository/multi-dir.py
new file mode 100644
index 0000000..8a82126
--- /dev/null
+++ b/test/Repository/multi-dir.py
@@ -0,0 +1,146 @@
+#!/usr/bin/env python
+#
+# __COPYRIGHT__
+#
+# Permission is hereby granted, free of charge, to any person obtaining
+# a copy of this software and associated documentation files (the
+# "Software"), to deal in the Software without restriction, including
+# without limitation the rights to use, copy, modify, merge, publish,
+# distribute, sublicense, and/or sell copies of the Software, and to
+# permit persons to whom the Software is furnished to do so, subject to
+# the following conditions:
+#
+# The above copyright notice and this permission notice shall be included
+# in all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
+# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+#
+
+__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
+
+import sys
+import TestSCons
+
+if sys.platform == 'win32':
+ _exe = '.exe'
+else:
+ _exe = ''
+
+
+
+test = TestSCons.TestSCons()
+
+#
+test.subdir('work',
+ ['work', 'src'],
+ ['work', 'include'],
+ 'repository',
+ ['repository', 'src'],
+ ['repository', 'include'])
+
+#
+workpath_repository = test.workpath('repository')
+work_include_my_string_h = test.workpath('work', 'include', 'my_string.h')
+work_src_xxx = test.workpath('work', 'src', 'xxx')
+repository_src_xxx = test.workpath('repository', 'src', 'xxx')
+
+opts = "-Y " + workpath_repository
+
+#
+test.write(['repository', 'SConstruct'], """
+env = Environment(CPPPATH = ['#src', '#include'])
+SConscript('src/SConscript', "env")
+""")
+
+test.write(['repository', 'src', 'SConscript'], """
+Import("env")
+env.Program(target = 'xxx', source = 'main.c')
+""")
+
+test.write(['repository', 'include', 'my_string.h'], r"""
+#define MY_STRING "repository/include/my_string.h"
+""")
+
+test.write(['repository', 'src', 'include.h'], r"""
+#include <my_string.h>
+#define LOCAL_STRING "repository/src/include.h"
+""")
+
+test.write(['repository', 'src', 'main.c'], r"""
+#include <stdio.h>
+#include <stdlib.h>
+#include <include.h>
+int
+main(int argc, char *argv[])
+{
+ argv[argc++] = "--";
+ printf("%s\n", MY_STRING);
+ printf("%s\n", LOCAL_STRING);
+ printf("repository/src/main.c\n");
+ exit (0);
+}
+""")
+
+# Make the repository non-writable,
+# so we'll detect if we try to write into it accidentally.
+test.writable('repository', 0)
+
+test.run(chdir = 'work', options = opts, arguments = ".")
+
+test.run(program = work_src_xxx, stdout =
+"""repository/include/my_string.h
+repository/src/include.h
+repository/src/main.c
+""")
+
+#
+test.write(['work', 'include', 'my_string.h'], r"""
+#define MY_STRING "work/include/my_string.h"
+""")
+
+test.run(chdir = 'work', options = opts, arguments = ".")
+
+test.run(program = work_src_xxx, stdout =
+"""work/include/my_string.h
+repository/src/include.h
+repository/src/main.c
+""")
+
+test.write(['work', 'src', 'include.h'], r"""
+#include <my_string.h>
+#define LOCAL_STRING "work/src/include.h"
+""")
+
+test.run(chdir = 'work', options = opts, arguments = ".")
+
+test.run(program = work_src_xxx, stdout =
+"""work/include/my_string.h
+work/src/include.h
+repository/src/main.c
+""")
+
+#
+test.unlink(work_include_my_string_h)
+
+test.run(chdir = 'work', options = opts, arguments = ".")
+
+test.run(program = work_src_xxx, stdout =
+"""repository/include/my_string.h
+work/src/include.h
+repository/src/main.c
+""")
+
+#
+test.pass_test()
+
+# Local Variables:
+# tab-width:4
+# indent-tabs-mode:nil
+# End:
+# vim: set expandtab tabstop=4 shiftwidth=4:
diff --git a/test/Repository/no-SConsignFile.py b/test/Repository/no-SConsignFile.py
new file mode 100644
index 0000000..d7f570c
--- /dev/null
+++ b/test/Repository/no-SConsignFile.py
@@ -0,0 +1,81 @@
+#!/usr/bin/env python
+#
+# __COPYRIGHT__
+#
+# Permission is hereby granted, free of charge, to any person obtaining
+# a copy of this software and associated documentation files (the
+# "Software"), to deal in the Software without restriction, including
+# without limitation the rights to use, copy, modify, merge, publish,
+# distribute, sublicense, and/or sell copies of the Software, and to
+# permit persons to whom the Software is furnished to do so, subject to
+# the following conditions:
+#
+# The above copyright notice and this permission notice shall be included
+# in all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
+# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+#
+
+__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
+
+"""
+Test that using Repository() works even when the Repository has no
+SConsignFile() and the source Repository files have their signatures
+saved because they're older than the max_drift time.
+"""
+
+import TestSCons
+
+test = TestSCons.TestSCons()
+
+test.subdir('build', 'src')
+
+test.write(['build', 'SConstruct'], """\
+SetOption('max_drift', 1)
+Repository('..')
+env = Environment()
+env.Program('foo', 'src/foo.c')
+""")
+
+test.write(['src', 'foo.c'], """\
+#include <stdio.h>
+#include <stdlib.h>
+#include "foo.h"
+int
+main(int argc, char *argv[])
+{
+ argv[argc++] = "--";
+ printf("%s\\n", STRING);
+ printf("src/foo.c\\n");
+ exit (0);
+}
+""")
+
+test.write(['src', 'foo.h'], """\
+#define STRING "src/foo.h"
+""")
+
+# Make sure it's past the max_drift time,
+# so the source file signatures get saved.
+test.sleep(2)
+
+test.run(chdir='build', arguments='.')
+
+test.run(program=test.workpath('build', 'foo'),
+ stdout="src/foo.h\nsrc/foo.c\n")
+
+test.up_to_date(chdir='build', arguments='.')
+
+test.pass_test()
+
+# Local Variables:
+# tab-width:4
+# indent-tabs-mode:nil
+# End:
+# vim: set expandtab tabstop=4 shiftwidth=4:
diff --git a/test/Repository/no-repository.py b/test/Repository/no-repository.py
new file mode 100644
index 0000000..dc45825
--- /dev/null
+++ b/test/Repository/no-repository.py
@@ -0,0 +1,102 @@
+#!/usr/bin/env python
+#
+# __COPYRIGHT__
+#
+# Permission is hereby granted, free of charge, to any person obtaining
+# a copy of this software and associated documentation files (the
+# "Software"), to deal in the Software without restriction, including
+# without limitation the rights to use, copy, modify, merge, publish,
+# distribute, sublicense, and/or sell copies of the Software, and to
+# permit persons to whom the Software is furnished to do so, subject to
+# the following conditions:
+#
+# The above copyright notice and this permission notice shall be included
+# in all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
+# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+#
+
+__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
+
+import sys
+
+import TestSCons
+
+python = TestSCons.python
+
+if sys.platform == 'win32':
+ _exe = '.exe'
+else:
+ _exe = ''
+
+test = TestSCons.TestSCons()
+
+test.subdir('work')
+
+no_repository = test.workpath('no_repository')
+work_foo = test.workpath('work', 'foo' + _exe)
+
+test.write(['work', 'SConstruct'], """
+Repository('%s')
+env = Environment()
+env.Program(target = 'foo', source = Split('aaa.c bbb.c foo.c'))
+""" % no_repository)
+
+test.write(['work', 'aaa.c'], r"""
+#include <stdio.h>
+#include <stdlib.h>
+void
+aaa(void)
+{
+ printf("work/aaa.c\n");
+}
+""")
+
+test.write(['work', 'bbb.c'], r"""
+#include <stdio.h>
+#include <stdlib.h>
+void
+bbb(void)
+{
+ printf("work/bbb.c\n");
+}
+""")
+
+test.write(['work', 'foo.c'], r"""
+#include <stdio.h>
+#include <stdlib.h>
+extern void aaa(void);
+extern void bbb(void);
+int
+main(int argc, char *argv[])
+{
+ argv[argc++] = "--";
+ aaa();
+ bbb();
+ printf("work/foo.c\n");
+ exit (0);
+}
+""")
+
+test.run(chdir = 'work', arguments = '.')
+
+test.run(program = work_foo, stdout = """work/aaa.c
+work/bbb.c
+work/foo.c
+""")
+
+test.up_to_date(chdir = 'work', arguments = '.')
+
+test.pass_test()
+
+# Local Variables:
+# tab-width:4
+# indent-tabs-mode:nil
+# End:
+# vim: set expandtab tabstop=4 shiftwidth=4:
diff --git a/test/Repository/option-c.py b/test/Repository/option-c.py
new file mode 100644
index 0000000..ea989c2
--- /dev/null
+++ b/test/Repository/option-c.py
@@ -0,0 +1,188 @@
+#!/usr/bin/env python
+#
+# __COPYRIGHT__
+#
+# Permission is hereby granted, free of charge, to any person obtaining
+# a copy of this software and associated documentation files (the
+# "Software"), to deal in the Software without restriction, including
+# without limitation the rights to use, copy, modify, merge, publish,
+# distribute, sublicense, and/or sell copies of the Software, and to
+# permit persons to whom the Software is furnished to do so, subject to
+# the following conditions:
+#
+# The above copyright notice and this permission notice shall be included
+# in all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
+# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+#
+
+__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
+
+import os.path
+
+import TestSCons
+
+test = TestSCons.TestSCons()
+
+test.subdir('repository', ['repository', 'subdir'], 'work')
+
+repository_aaa_in = test.workpath('repository', 'aaa.in')
+repository_aaa_mid = test.workpath('repository', 'aaa.mid')
+repository_aaa_out = test.workpath('repository', 'aaa.out')
+repository_bbb_in = test.workpath('repository', 'bbb.in')
+repository_bbb_mid = test.workpath('repository', 'bbb.mid')
+repository_bbb_out = test.workpath('repository', 'bbb.out')
+repository_subdir_ccc_in = test.workpath('repository', 'subdir', 'ccc.in')
+repository_subdir_ccc_mid = test.workpath('repository', 'subdir', 'ccc.mid')
+repository_subdir_ccc_out = test.workpath('repository', 'subdir', 'ccc.out')
+repository_subdir_ddd_in = test.workpath('repository', 'subdir', 'ddd.in')
+repository_subdir_ddd_mid = test.workpath('repository', 'subdir', 'ddd.mid')
+repository_subdir_ddd_out = test.workpath('repository', 'subdir', 'ddd.out')
+
+work_aaa_in = test.workpath('work', 'aaa.in')
+work_aaa_mid = test.workpath('work', 'aaa.mid')
+work_aaa_out = test.workpath('work', 'aaa.out')
+work_bbb_in = test.workpath('work', 'bbb.in')
+work_bbb_mid = test.workpath('work', 'bbb.mid')
+work_bbb_out = test.workpath('work', 'bbb.out')
+work_subdir_ccc_in = test.workpath('work', 'subdir', 'ccc.in')
+work_subdir_ccc_mid = test.workpath('work', 'subdir', 'ccc.mid')
+work_subdir_ccc_out = test.workpath('work', 'subdir', 'ccc.out')
+work_subdir_ddd_in = test.workpath('work', 'subdir', 'ddd.in')
+work_subdir_ddd_mid = test.workpath('work', 'subdir', 'ddd.mid')
+work_subdir_ddd_out = test.workpath('work', 'subdir', 'ddd.out')
+
+opts = "-Y " + test.workpath('repository')
+
+#
+test.write(['repository', 'SConstruct'], r"""
+def copy(env, source, target):
+ source = str(source[0])
+ target = str(target[0])
+ print 'copy() < %s > %s' % (source, target)
+ open(target, "wb").write(open(source, "rb").read())
+
+Build = Builder(action=copy)
+env = Environment(BUILDERS={'Build':Build})
+env.Build('aaa.mid', 'aaa.in')
+env.Build('aaa.out', 'aaa.mid')
+env.Build('bbb.mid', 'bbb.in')
+env.Build('bbb.out', 'bbb.mid')
+SConscript('subdir/SConscript', "env")
+""")
+
+test.write(['repository', 'subdir', 'SConscript'], r"""
+Import("env")
+env.Build('ccc.mid', 'ccc.in')
+env.Build('ccc.out', 'ccc.mid')
+env.Build('ddd.mid', 'ddd.in')
+env.Build('ddd.out', 'ddd.mid')
+""")
+
+test.write(repository_aaa_in, "repository/aaa.in\n")
+test.write(repository_bbb_in, "repository/bbb.in\n")
+
+test.write(repository_subdir_ccc_in, "repository/subdir/ccc.in\n")
+test.write(repository_subdir_ddd_in, "repository/subdir/ddd.in\n")
+
+# Make the entire repository non-writable, so we'll detect
+# if we try to write into it accidentally.
+test.writable('repository', 0)
+
+# Build in the work subdirectory first, so that it really
+# builds all of the target files locally instead of possibly
+# copying them from the Repository.
+test.run(chdir = 'work', options = opts, arguments = '.')
+
+test.fail_test(test.read(work_aaa_mid) != "repository/aaa.in\n")
+test.fail_test(test.read(work_aaa_out) != "repository/aaa.in\n")
+test.fail_test(test.read(work_bbb_mid) != "repository/bbb.in\n")
+test.fail_test(test.read(work_bbb_out) != "repository/bbb.in\n")
+test.fail_test(test.read(work_subdir_ccc_mid) != "repository/subdir/ccc.in\n")
+test.fail_test(test.read(work_subdir_ccc_out) != "repository/subdir/ccc.in\n")
+test.fail_test(test.read(work_subdir_ddd_mid) != "repository/subdir/ddd.in\n")
+test.fail_test(test.read(work_subdir_ddd_out) != "repository/subdir/ddd.in\n")
+
+test.up_to_date(chdir = 'work', options = opts, arguments = '.')
+
+# Make the repository writable, so we can build in it.
+test.writable('repository', 1)
+
+# Now build everything in the repository.
+test.run(chdir = 'repository', options = opts, arguments = '.')
+
+test.fail_test(test.read(repository_aaa_mid) != "repository/aaa.in\n")
+test.fail_test(test.read(repository_aaa_out) != "repository/aaa.in\n")
+test.fail_test(test.read(repository_bbb_mid) != "repository/bbb.in\n")
+test.fail_test(test.read(repository_bbb_out) != "repository/bbb.in\n")
+test.fail_test(test.read(repository_subdir_ccc_mid) != "repository/subdir/ccc.in\n")
+test.fail_test(test.read(repository_subdir_ccc_out) != "repository/subdir/ccc.in\n")
+test.fail_test(test.read(repository_subdir_ddd_mid) != "repository/subdir/ddd.in\n")
+test.fail_test(test.read(repository_subdir_ddd_out) != "repository/subdir/ddd.in\n")
+
+test.up_to_date(chdir = 'repository', options = opts, arguments = '.')
+
+# Make the entire repository non-writable again, so we'll detect
+# if we try to write into it accidentally.
+test.writable('repository', 0)
+
+#
+test.run(chdir = 'work', options = opts + ' -c', arguments = 'bbb.mid bbb.out')
+
+test.fail_test(test.read(work_aaa_mid) != "repository/aaa.in\n")
+test.fail_test(test.read(work_aaa_out) != "repository/aaa.in\n")
+test.fail_test(os.path.exists(work_bbb_mid))
+test.fail_test(os.path.exists(work_bbb_out))
+test.fail_test(test.read(work_subdir_ccc_mid) != "repository/subdir/ccc.in\n")
+test.fail_test(test.read(work_subdir_ccc_out) != "repository/subdir/ccc.in\n")
+test.fail_test(test.read(work_subdir_ddd_mid) != "repository/subdir/ddd.in\n")
+test.fail_test(test.read(work_subdir_ddd_out) != "repository/subdir/ddd.in\n")
+
+#
+test.run(chdir = 'work', options = opts + ' -c', arguments = 'subdir')
+
+test.fail_test(test.read(work_aaa_mid) != "repository/aaa.in\n")
+test.fail_test(test.read(work_aaa_out) != "repository/aaa.in\n")
+test.fail_test(os.path.exists(work_bbb_mid))
+test.fail_test(os.path.exists(work_bbb_out))
+test.fail_test(os.path.exists(work_subdir_ccc_mid))
+test.fail_test(os.path.exists(work_subdir_ccc_out))
+test.fail_test(os.path.exists(work_subdir_ddd_mid))
+test.fail_test(os.path.exists(work_subdir_ddd_out))
+
+#
+test.run(chdir = 'work', options = opts + ' -c', arguments = '.')
+
+test.fail_test(os.path.exists(work_aaa_mid))
+test.fail_test(os.path.exists(work_aaa_out))
+test.fail_test(os.path.exists(work_bbb_mid))
+test.fail_test(os.path.exists(work_bbb_out))
+test.fail_test(os.path.exists(work_subdir_ccc_mid))
+test.fail_test(os.path.exists(work_subdir_ccc_out))
+test.fail_test(os.path.exists(work_subdir_ddd_mid))
+test.fail_test(os.path.exists(work_subdir_ddd_out))
+
+# Double-check that nothing in the repository got deleted.
+test.fail_test(test.read(repository_aaa_mid) != "repository/aaa.in\n")
+test.fail_test(test.read(repository_aaa_out) != "repository/aaa.in\n")
+test.fail_test(test.read(repository_bbb_mid) != "repository/bbb.in\n")
+test.fail_test(test.read(repository_bbb_out) != "repository/bbb.in\n")
+test.fail_test(test.read(repository_subdir_ccc_mid) != "repository/subdir/ccc.in\n")
+test.fail_test(test.read(repository_subdir_ccc_out) != "repository/subdir/ccc.in\n")
+test.fail_test(test.read(repository_subdir_ddd_mid) != "repository/subdir/ddd.in\n")
+test.fail_test(test.read(repository_subdir_ddd_out) != "repository/subdir/ddd.in\n")
+
+#
+test.pass_test()
+
+# Local Variables:
+# tab-width:4
+# indent-tabs-mode:nil
+# End:
+# vim: set expandtab tabstop=4 shiftwidth=4:
diff --git a/test/Repository/option-f.py b/test/Repository/option-f.py
new file mode 100644
index 0000000..8511f6a
--- /dev/null
+++ b/test/Repository/option-f.py
@@ -0,0 +1,104 @@
+#!/usr/bin/env python
+#
+# __COPYRIGHT__
+#
+# Permission is hereby granted, free of charge, to any person obtaining
+# a copy of this software and associated documentation files (the
+# "Software"), to deal in the Software without restriction, including
+# without limitation the rights to use, copy, modify, merge, publish,
+# distribute, sublicense, and/or sell copies of the Software, and to
+# permit persons to whom the Software is furnished to do so, subject to
+# the following conditions:
+#
+# The above copyright notice and this permission notice shall be included
+# in all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
+# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+#
+
+__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
+
+import os.path
+import TestSCons
+
+test = TestSCons.TestSCons()
+
+test.subdir('work', 'repository', ['repository', 'src'])
+
+work_aaa = test.workpath('work', 'aaa')
+work_bbb = test.workpath('work', 'bbb')
+work_ccc = test.workpath('work', 'ccc')
+work_src_xxx = test.workpath('work', 'src', 'xxx')
+work_src_yyy = test.workpath('work', 'src', 'yyy')
+
+opts = "-f " + test.workpath('repository', 'SConstruct')
+
+test.write(['repository', 'SConstruct'], """\
+Repository(r'%s')
+def cat(env, source, target):
+ target = str(target[0])
+ f = open(target, "wb")
+ for src in source:
+ f.write(open(str(src), "rb").read())
+ f.close()
+
+env = Environment(BUILDERS={'Build':Builder(action=cat)})
+env.Build('aaa.out', 'aaa.in')
+env.Build('bbb.out', 'bbb.in')
+env.Build('ccc.out', 'ccc.in')
+SConscript('src/SConscript', "env")
+""" % test.workpath('repository'))
+
+test.write(['repository', 'src', 'SConscript'], """
+Import("env")
+env.Build('xxx.out', 'xxx.in')
+env.Build('yyy.out', 'yyy.in')
+""")
+
+test.write(['repository', 'aaa.in'], "repository/aaa.in\n")
+test.write(['repository', 'bbb.in'], "repository/bbb.in\n")
+test.write(['repository', 'ccc.in'], "repository/ccc.in\n")
+
+test.write(['repository', 'src', 'xxx.in'], "repository/src/xxx.in\n")
+test.write(['repository', 'src', 'yyy.in'], "repository/src/yyy.in\n")
+
+#
+# Make the repository non-writable,
+# so we'll detect if we try to write into it accidentally.
+test.writable('repository', 0)
+
+#
+test.run(chdir = 'work', options = opts, arguments = 'aaa.out')
+
+test.fail_test(test.read(['work', 'aaa.out']) != "repository/aaa.in\n")
+test.fail_test(os.path.exists(test.workpath('work', 'bbb.out')))
+test.fail_test(os.path.exists(test.workpath('work', 'ccc.out')))
+test.fail_test(os.path.exists(test.workpath('work', 'src', 'xxx.out')))
+test.fail_test(os.path.exists(test.workpath('work', 'src', 'yyy.out')))
+
+test.run(chdir = 'work', options = opts, arguments = 'bbb.out src')
+
+test.fail_test(test.read(['work', 'bbb.out']) != "repository/bbb.in\n")
+test.fail_test(os.path.exists(test.workpath('work', 'ccc.out')))
+test.fail_test(test.read(['work', 'src', 'xxx.out']) != "repository/src/xxx.in\n")
+test.fail_test(test.read(['work', 'src', 'yyy.out']) != "repository/src/yyy.in\n")
+
+#
+test.run(chdir = 'work', options = opts, arguments = '.')
+
+test.fail_test(test.read(['work', 'ccc.out']) != "repository/ccc.in\n")
+
+#
+test.pass_test()
+
+# Local Variables:
+# tab-width:4
+# indent-tabs-mode:nil
+# End:
+# vim: set expandtab tabstop=4 shiftwidth=4:
diff --git a/test/Repository/option-n.py b/test/Repository/option-n.py
new file mode 100644
index 0000000..220baad
--- /dev/null
+++ b/test/Repository/option-n.py
@@ -0,0 +1,100 @@
+#!/usr/bin/env python
+#
+# __COPYRIGHT__
+#
+# Permission is hereby granted, free of charge, to any person obtaining
+# a copy of this software and associated documentation files (the
+# "Software"), to deal in the Software without restriction, including
+# without limitation the rights to use, copy, modify, merge, publish,
+# distribute, sublicense, and/or sell copies of the Software, and to
+# permit persons to whom the Software is furnished to do so, subject to
+# the following conditions:
+#
+# The above copyright notice and this permission notice shall be included
+# in all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
+# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+#
+
+"""
+This test verifies that building using the -n option doesn't create a
+local copy of a file specified as Local() in the SConstruct.
+"""
+
+__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
+
+import os.path
+
+import TestSCons
+
+test = TestSCons.TestSCons()
+
+test.subdir('repository', ['repository', 'src'],
+ 'work', ['work', 'src'])
+
+repository_aaa_out = test.workpath('repository', 'aaa.out')
+work_aaa_out = test.workpath('work', 'aaa.out')
+
+opts = "-Y " + test.workpath('repository')
+
+#
+test.write(['repository', 'SConstruct'], r"""
+def copy(env, source, target):
+ source = str(source[0])
+ target = str(target[0])
+ print 'copy() < %s > %s' % (source, target)
+ open(target, "wb").write(open(source, "rb").read())
+
+Build = Builder(action=copy)
+env = Environment(BUILDERS={'Build':Build})
+env.Build('aaa.out', 'aaa.in')
+Local('aaa.out')
+""")
+
+test.write(['repository', 'aaa.in'], "repository/aaa.in\n")
+
+#
+test.run(chdir = 'repository', options = opts, arguments = '.')
+
+test.fail_test(test.read(repository_aaa_out) != "repository/aaa.in\n")
+
+test.up_to_date(chdir = 'repository', options = opts, arguments = '.')
+
+# Make the entire repository non-writable, so we'll detect
+# if we try to write into it accidentally.
+test.writable('repository', 0)
+
+#
+expect = test.wrap_stdout("""\
+Local copy of aaa.out from %s
+scons: `aaa.out' is up to date.
+""" % repository_aaa_out)
+
+test.run(chdir = 'work',
+ options = opts,
+ arguments = '-n aaa.out',
+ stdout = expect)
+
+test.fail_test(os.path.exists(work_aaa_out))
+
+test.run(chdir = 'work',
+ options = opts,
+ arguments = 'aaa.out',
+ stdout = expect)
+
+test.fail_test(test.read(work_aaa_out) != "repository/aaa.in\n")
+
+#
+test.pass_test()
+
+# Local Variables:
+# tab-width:4
+# indent-tabs-mode:nil
+# End:
+# vim: set expandtab tabstop=4 shiftwidth=4:
diff --git a/test/Repository/signature-order.py b/test/Repository/signature-order.py
new file mode 100644
index 0000000..2c00b34
--- /dev/null
+++ b/test/Repository/signature-order.py
@@ -0,0 +1,128 @@
+#!/usr/bin/env python
+#
+# __COPYRIGHT__
+#
+# Permission is hereby granted, free of charge, to any person obtaining
+# a copy of this software and associated documentation files (the
+# "Software"), to deal in the Software without restriction, including
+# without limitation the rights to use, copy, modify, merge, publish,
+# distribute, sublicense, and/or sell copies of the Software, and to
+# permit persons to whom the Software is furnished to do so, subject to
+# the following conditions:
+#
+# The above copyright notice and this permission notice shall be included
+# in all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
+# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+#
+
+__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
+
+"""
+Verify that we don't rebuild things unnecessarily when the order of
+signatures changes because an included file shifts from the local sandbox
+to a Repository and vice versa.
+"""
+
+import TestSCons
+
+_exe = TestSCons._exe
+
+test = TestSCons.TestSCons()
+
+test.subdir('repository', 'work')
+
+repository = test.workpath('repository')
+work_foo = test.workpath('work', 'foo' + _exe)
+work_foo_h = test.workpath('work', 'foo.h')
+
+test.write(['work', 'SConstruct'], """
+Repository(r'%s')
+env = Environment(CPPPATH = ['.'])
+env.Program(target = 'foo', source = 'foo.c')
+""" % repository)
+
+foo_h_contents = """\
+#define STRING1 "foo.h"
+"""
+
+bar_h_contents = """\
+#define STRING2 "bar.h"
+"""
+
+test.write(['repository', 'foo.h'], foo_h_contents)
+
+test.write(['repository', 'bar.h'], bar_h_contents)
+
+test.write(['repository', 'foo.c'], r"""
+#include <stdio.h>
+#include <stdlib.h>
+#include <foo.h>
+#include <bar.h>
+int
+main(int argc, char *argv[])
+{
+ argv[argc++] = "--";
+ printf("%s\n", STRING1);
+ printf("%s\n", STRING2);
+ printf("repository/foo.c\n");
+ exit (0);
+}
+""")
+
+# Make the entire repository non-writable, so we'll detect
+# if we try to write into it accidentally.
+test.writable('repository', 0)
+
+
+
+test.run(chdir = 'work', arguments = '.')
+
+test.run(program = work_foo, stdout =
+"""foo.h
+bar.h
+repository/foo.c
+""")
+
+test.up_to_date(chdir = 'work', arguments = '.')
+
+
+
+# Now create the bar.h file locally, and make sure it's still up-to-date.
+# This will change the order in which the include files are listed when
+# calculating the signature; the old order was something like:
+# /var/tmp/.../bar.h
+# /var/tmp/.../far.h
+# and the new order will be:
+# /var/tmp/.../far.h
+# bar.h
+# Because we write the same bar.h file contents, this should not cause
+# a rebuild (because we sort the resulting signatures).
+
+test.write(['work', 'bar.h'], bar_h_contents)
+
+test.up_to_date(chdir = 'work', arguments = '.')
+
+
+
+# And for good measure, write the same foo.h file locally.
+
+test.write(['work', 'foo.h'], foo_h_contents)
+
+test.up_to_date(chdir = 'work', arguments = '.')
+
+
+
+test.pass_test()
+
+# Local Variables:
+# tab-width:4
+# indent-tabs-mode:nil
+# End:
+# vim: set expandtab tabstop=4 shiftwidth=4:
diff --git a/test/Repository/targets.py b/test/Repository/targets.py
new file mode 100644
index 0000000..62f4785
--- /dev/null
+++ b/test/Repository/targets.py
@@ -0,0 +1,105 @@
+#!/usr/bin/env python
+#
+# __COPYRIGHT__
+#
+# Permission is hereby granted, free of charge, to any person obtaining
+# a copy of this software and associated documentation files (the
+# "Software"), to deal in the Software without restriction, including
+# without limitation the rights to use, copy, modify, merge, publish,
+# distribute, sublicense, and/or sell copies of the Software, and to
+# permit persons to whom the Software is furnished to do so, subject to
+# the following conditions:
+#
+# The above copyright notice and this permission notice shall be included
+# in all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
+# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+#
+
+__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
+
+import os.path
+import TestSCons
+
+test = TestSCons.TestSCons()
+
+test.subdir('work', 'repository', ['repository', 'src'])
+
+work_aaa = test.workpath('work', 'aaa')
+work_bbb = test.workpath('work', 'bbb')
+work_ccc = test.workpath('work', 'ccc')
+work_src_xxx = test.workpath('work', 'src', 'xxx')
+work_src_yyy = test.workpath('work', 'src', 'yyy')
+
+opts = "-Y " + test.workpath('repository')
+
+test.write(['repository', 'SConstruct'], """
+def cat(env, source, target):
+ target = str(target[0])
+ source = list(map(str, source))
+ print 'cat(%s) > %s' % (source, target)
+ f = open(target, "wb")
+ for src in source:
+ f.write(open(src, "rb").read())
+ f.close()
+
+env = Environment(BUILDERS={'Build':Builder(action=cat)})
+env.Build('aaa.out', 'aaa.in')
+env.Build('bbb.out', 'bbb.in')
+env.Build('ccc.out', 'ccc.in')
+SConscript('src/SConscript', "env")
+""")
+
+test.write(['repository', 'aaa.in'], "repository/aaa.in\n")
+test.write(['repository', 'bbb.in'], "repository/bbb.in\n")
+test.write(['repository', 'ccc.in'], "repository/ccc.in\n")
+
+test.write(['repository', 'src', 'SConscript'], """
+Import("env")
+env.Build('xxx.out', 'xxx.in')
+env.Build('yyy.out', 'yyy.in')
+""")
+
+test.write(['repository', 'src', 'xxx.in'], "repository/src/xxx.in\n")
+test.write(['repository', 'src', 'yyy.in'], "repository/src/yyy.in\n")
+
+#
+# Make the repository non-writable,
+# so we'll detect if we try to write into it accidentally.
+test.writable('repository', 0)
+
+#
+test.run(chdir = 'work', options = opts, arguments = 'aaa.out')
+
+test.fail_test(test.read(['work', 'aaa.out']) != "repository/aaa.in\n")
+test.fail_test(os.path.exists(test.workpath('work', 'bbb.out')))
+test.fail_test(os.path.exists(test.workpath('work', 'ccc.out')))
+test.fail_test(os.path.exists(test.workpath('work', 'src', 'xxx.out')))
+test.fail_test(os.path.exists(test.workpath('work', 'src', 'yyy.out')))
+
+test.run(chdir = 'work', options = opts, arguments = 'bbb.out src')
+
+test.fail_test(test.read(['work', 'bbb.out']) != "repository/bbb.in\n")
+test.fail_test(os.path.exists(test.workpath('work', 'ccc.out')))
+test.fail_test(test.read(['work', 'src', 'xxx.out']) != "repository/src/xxx.in\n")
+test.fail_test(test.read(['work', 'src', 'yyy.out']) != "repository/src/yyy.in\n")
+
+#
+test.run(chdir = 'work', options = opts, arguments = '.')
+
+test.fail_test(test.read(['work', 'ccc.out']) != "repository/ccc.in\n")
+
+#
+test.pass_test()
+
+# Local Variables:
+# tab-width:4
+# indent-tabs-mode:nil
+# End:
+# vim: set expandtab tabstop=4 shiftwidth=4:
diff --git a/test/Repository/top-level-path.py b/test/Repository/top-level-path.py
new file mode 100644
index 0000000..d8ed9e2
--- /dev/null
+++ b/test/Repository/top-level-path.py
@@ -0,0 +1,114 @@
+#!/usr/bin/env python
+#
+# __COPYRIGHT__
+#
+# Permission is hereby granted, free of charge, to any person obtaining
+# a copy of this software and associated documentation files (the
+# "Software"), to deal in the Software without restriction, including
+# without limitation the rights to use, copy, modify, merge, publish,
+# distribute, sublicense, and/or sell copies of the Software, and to
+# permit persons to whom the Software is furnished to do so, subject to
+# the following conditions:
+#
+# The above copyright notice and this permission notice shall be included
+# in all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
+# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+#
+
+__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
+
+import os.path
+import sys
+import TestSCons
+
+if sys.platform == 'win32':
+ _exe = '.exe'
+else:
+ _exe = ''
+
+test = TestSCons.TestSCons()
+
+test.subdir('repository',
+ ['repository', 'src'],
+ ['repository', 'subdir'],
+ 'work')
+
+src_SConscript = os.path.join('src', 'SConscript')
+work_src_foo = test.workpath('work', 'src', 'foo' + _exe)
+
+opts = "-Y " + test.workpath('repository')
+
+#
+test.write(['repository', 'SConstruct'], r"""
+SConscript(r'%s')
+""" % src_SConscript)
+
+test.write(['repository', 'src', 'SConscript'], r"""
+env = Environment()
+env.Program('foo', ['aaa.c', '#subdir/aaa.c', 'foo.c'])
+""")
+
+test.write(['repository', 'src', 'aaa.c'], r"""
+#include <stdio.h>
+#include <stdlib.h>
+void
+src_aaa(void)
+{
+ printf("repository/src/aaa.c\n");
+}
+""")
+
+test.write(['repository', 'subdir', 'aaa.c'], r"""
+#include <stdio.h>
+#include <stdlib.h>
+void
+subdir_aaa(void)
+{
+ printf("repository/subdir/aaa.c\n");
+}
+""")
+
+test.write(['repository', 'src', 'foo.c'], r"""
+#include <stdio.h>
+#include <stdlib.h>
+extern void src_aaa(void);
+extern void subdir_aaa(void);
+int
+main(int argc, char *argv[])
+{
+ argv[argc++] = "--";
+ src_aaa();
+ subdir_aaa();
+ printf("repository/src/foo.c\n");
+ exit (0);
+}
+""")
+
+# Make the entire repository non-writable, so we'll detect
+# if we try to write into it accidentally.
+test.writable('repository', 0)
+
+test.run(chdir = 'work', options = opts, arguments = '.')
+
+test.run(program = work_src_foo, stdout = """repository/src/aaa.c
+repository/subdir/aaa.c
+repository/src/foo.c
+""")
+
+test.up_to_date(chdir = 'work', options = opts, arguments = '.')
+
+#
+test.pass_test()
+
+# Local Variables:
+# tab-width:4
+# indent-tabs-mode:nil
+# End:
+# vim: set expandtab tabstop=4 shiftwidth=4:
diff --git a/test/Repository/variants.py b/test/Repository/variants.py
new file mode 100644
index 0000000..e8c07a7
--- /dev/null
+++ b/test/Repository/variants.py
@@ -0,0 +1,430 @@
+#!/usr/bin/env python
+#
+# __COPYRIGHT__
+#
+# Permission is hereby granted, free of charge, to any person obtaining
+# a copy of this software and associated documentation files (the
+# "Software"), to deal in the Software without restriction, including
+# without limitation the rights to use, copy, modify, merge, publish,
+# distribute, sublicense, and/or sell copies of the Software, and to
+# permit persons to whom the Software is furnished to do so, subject to
+# the following conditions:
+#
+# The above copyright notice and this permission notice shall be included
+# in all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
+# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+#
+
+__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
+
+import os.path
+import sys
+import time
+import TestSCons
+
+if sys.platform == 'win32':
+ _obj = '.obj'
+ _exe = '.exe'
+else:
+ _obj = '.o'
+ _exe = ''
+
+test = TestSCons.TestSCons()
+
+test.subdir('repository',
+ ['repository', 'src1'],
+ ['repository', 'src2'],
+ ['repository', 'src2', 'include'],
+ ['repository', 'src2', 'xxx'],
+ ['repository', 'build2'],
+ ['repository', 'build2', 'foo'],
+ ['repository', 'build2', 'bar'],
+ 'work1',
+ ['work1', 'src1'],
+ 'work2',
+ ['work2', 'src2'],
+ ['work2', 'src2', 'include'],
+ ['work2', 'src2', 'xxx'])
+
+aaa_obj = 'aaa' + _obj
+bbb_obj = 'bbb' + _obj
+main_obj = 'main' + _obj
+
+xxx_exe = 'xxx' + _exe
+
+repository_build1_foo_xxx = test.workpath('repository', 'build1', 'foo', 'xxx')
+work1_build1_foo_xxx = test.workpath('work1', 'build1', 'foo', 'xxx')
+work1_build1_bar_xxx = test.workpath('work1', 'build1', 'bar', 'xxx')
+
+repository_build2_foo_src2_xxx_xxx = test.workpath('repository', 'build2',
+ 'foo', 'src2', 'xxx', 'xxx')
+repository_build2_bar_src2_xxx_xxx = test.workpath('repository', 'build2',
+ 'bar', 'src2', 'xxx', 'xxx')
+work2_build2_foo_src2_xxx_xxx = test.workpath('work2', 'build2',
+ 'foo', 'src2', 'xxx', 'xxx')
+work2_build2_bar_src2_xxx_xxx = test.workpath('work2', 'build2',
+ 'bar', 'src2', 'xxx', 'xxx')
+
+opts = "-Y " + test.workpath('repository')
+
+#
+test.write(['repository', 'SConstruct'], r"""
+OS = ARGUMENTS.get('OS', '')
+build1_os = "#build1/" + OS
+default = Environment()
+ccflags = {
+ '' : '',
+ 'foo' : '-DFOO',
+ 'bar' : '-DBAR',
+}
+env1 = Environment(CCFLAGS = default.subst('$CCFLAGS %s' % ccflags[OS]),
+ CPPPATH = build1_os)
+VariantDir(build1_os, 'src1')
+SConscript(build1_os + '/SConscript', "env1")
+
+SConscript('build2/foo/SConscript')
+SConscript('build2/bar/SConscript')
+""")
+
+test.write(['repository', 'src1', 'SConscript'], r"""
+Import("env1")
+env1.Program('xxx', ['aaa.c', 'bbb.c', 'main.c'])
+""")
+
+test.write(['repository', 'build2', 'foo', 'SConscript'], r"""
+VariantDir('src2', '#src2')
+
+default = Environment()
+env2 = Environment(CCFLAGS = default.subst('$CCFLAGS -DFOO'),
+ CPPPATH = ['#src2/xxx', '#src2/include'])
+
+SConscript('src2/xxx/SConscript', "env2")
+""")
+
+test.write(['repository', 'build2', 'bar', 'SConscript'], r"""
+VariantDir('src2', '#src2')
+
+default = Environment()
+env2 = Environment(CCFLAGS = default.subst('$CCFLAGS -DBAR'),
+ CPPPATH = ['#src2/xxx', '#src2/include'])
+
+SConscript('src2/xxx/SConscript', "env2")
+""")
+
+test.write(['repository', 'src2', 'xxx', 'SConscript'], r"""
+Import("env2")
+env2.Program('xxx', ['main.c'])
+""")
+
+test.write(['repository', 'src1', 'iii.h'], r"""
+#ifdef FOO
+#define STRING "REPOSITORY_FOO"
+#endif
+#ifdef BAR
+#define STRING "REPOSITORY_BAR"
+#endif
+""")
+
+test.write(['repository', 'src1', 'aaa.c'], r"""
+#include <stdio.h>
+#include <stdlib.h>
+#include <iii.h>
+void
+aaa(void)
+{
+ printf("repository/src1/aaa.c: %s\n", STRING);
+}
+""")
+
+test.write(['repository', 'src1', 'bbb.c'], r"""
+#include <stdio.h>
+#include <stdlib.h>
+#include <iii.h>
+void
+bbb(void)
+{
+ printf("repository/src1/bbb.c: %s\n", STRING);
+}
+""")
+
+test.write(['repository', 'src1', 'main.c'], r"""
+#include <stdio.h>
+#include <stdlib.h>
+#include <iii.h>
+extern void aaa(void);
+extern void bbb(void);
+int
+main(int argc, char *argv[])
+{
+#ifdef BAR
+ printf("Only when -DBAR.\n");
+#endif
+ aaa();
+ bbb();
+ printf("repository/src1/main.c: %s\n", STRING);
+ exit (0);
+}
+""")
+
+test.write(['repository', 'src2', 'include', 'my_string.h'], r"""
+#ifdef FOO
+#define INCLUDE_OS "FOO"
+#endif
+#ifdef BAR
+#define INCLUDE_OS "BAR"
+#endif
+#define INCLUDE_STRING "repository/src2/include/my_string.h: %s\n"
+""")
+
+test.write(['repository', 'src2', 'xxx', 'include.h'], r"""
+#include <my_string.h>
+#ifdef FOO
+#define XXX_OS "FOO"
+#endif
+#ifdef BAR
+#define XXX_OS "BAR"
+#endif
+#define XXX_STRING "repository/src2/xxx/include.h: %s\n"
+""")
+
+test.write(['repository', 'src2', 'xxx', 'main.c'], r"""
+#include <stdio.h>
+#include <stdlib.h>
+#include <include.h>
+#ifdef FOO
+#define MAIN_OS "FOO"
+#endif
+#ifdef BAR
+#define MAIN_OS "BAR"
+#endif
+int
+main(int argc, char *argv[])
+{
+ printf(INCLUDE_STRING, INCLUDE_OS);
+ printf(XXX_STRING, XXX_OS);
+ printf("repository/src2/xxx/main.c: %s\n", MAIN_OS);
+ exit (0);
+}
+""")
+
+#
+test.run(chdir = 'repository', options = opts + " OS=foo", arguments = '.')
+
+test.run(program = repository_build1_foo_xxx, stdout = """\
+repository/src1/aaa.c: REPOSITORY_FOO
+repository/src1/bbb.c: REPOSITORY_FOO
+repository/src1/main.c: REPOSITORY_FOO
+""")
+
+test.fail_test(os.path.exists(test.workpath('repository', 'src1', '.sconsign')))
+test.fail_test(os.path.exists(test.workpath('repository', 'src2', '.sconsign')))
+test.fail_test(os.path.exists(test.workpath('work1', 'src1', '.sconsign')))
+test.fail_test(os.path.exists(test.workpath('work2', 'src2', '.sconsign')))
+
+test.run(program = repository_build2_foo_src2_xxx_xxx, stdout = """\
+repository/src2/include/my_string.h: FOO
+repository/src2/xxx/include.h: FOO
+repository/src2/xxx/main.c: FOO
+""")
+
+test.run(program = repository_build2_bar_src2_xxx_xxx, stdout = """\
+repository/src2/include/my_string.h: BAR
+repository/src2/xxx/include.h: BAR
+repository/src2/xxx/main.c: BAR
+""")
+
+test.fail_test(os.path.exists(test.workpath('repository', 'src1', '.sconsign')))
+test.fail_test(os.path.exists(test.workpath('repository', 'src2', '.sconsign')))
+test.fail_test(os.path.exists(test.workpath('work1', 'src1', '.sconsign')))
+test.fail_test(os.path.exists(test.workpath('work2', 'src2', '.sconsign')))
+
+# Make the entire repository non-writable, so we'll detect
+# if we try to write into it accidentally.
+test.writable('repository', 0)
+
+#
+test.up_to_date(chdir = 'work1', options = opts + " OS=foo", arguments = 'build1')
+
+test.fail_test(os.path.exists(test.workpath('work1', 'build1', 'foo', aaa_obj)))
+test.fail_test(os.path.exists(test.workpath('work1', 'build1', 'foo', bbb_obj)))
+test.fail_test(os.path.exists(test.workpath('work1', 'build1', 'foo', main_obj)))
+
+test.fail_test(os.path.exists(test.workpath('work1', 'build1', 'foo', xxx_exe)))
+
+#
+test.run(chdir = 'work1', options = opts, arguments = 'OS=bar .')
+
+test.run(program = work1_build1_bar_xxx, stdout = """\
+Only when -DBAR.
+repository/src1/aaa.c: REPOSITORY_BAR
+repository/src1/bbb.c: REPOSITORY_BAR
+repository/src1/main.c: REPOSITORY_BAR
+""")
+
+test.fail_test(os.path.exists(test.workpath('repository', 'src1', '.sconsign')))
+test.fail_test(os.path.exists(test.workpath('repository', 'src2', '.sconsign')))
+test.fail_test(os.path.exists(test.workpath('work1', 'src1', '.sconsign')))
+test.fail_test(os.path.exists(test.workpath('work2', 'src2', '.sconsign')))
+
+test.up_to_date(chdir = 'work1', options = opts + " OS=bar", arguments = 'build1')
+
+# Ensure file time stamps will be newer.
+time.sleep(2)
+
+test.write(['work1', 'src1', 'iii.h'], r"""
+#ifdef FOO
+#define STRING "WORK_FOO"
+#endif
+#ifdef BAR
+#define STRING "WORK_BAR"
+#endif
+""")
+
+#
+test.run(chdir = 'work1', options = opts + " OS=bar", arguments = 'build1')
+
+test.run(program = work1_build1_bar_xxx, stdout = """\
+Only when -DBAR.
+repository/src1/aaa.c: WORK_BAR
+repository/src1/bbb.c: WORK_BAR
+repository/src1/main.c: WORK_BAR
+""")
+
+test.fail_test(os.path.exists(test.workpath('repository', 'src1', '.sconsign')))
+test.fail_test(os.path.exists(test.workpath('repository', 'src2', '.sconsign')))
+test.fail_test(os.path.exists(test.workpath('work1', 'src1', '.sconsign')))
+test.fail_test(os.path.exists(test.workpath('work2', 'src2', '.sconsign')))
+
+test.up_to_date(chdir = 'work1', options = opts + " OS=bar", arguments = 'build1')
+
+#
+test.run(chdir = 'work1', options = opts + " OS=foo", arguments = 'build1')
+
+test.run(program = work1_build1_foo_xxx, stdout = """\
+repository/src1/aaa.c: WORK_FOO
+repository/src1/bbb.c: WORK_FOO
+repository/src1/main.c: WORK_FOO
+""")
+
+test.fail_test(os.path.exists(test.workpath('repository', 'src1', '.sconsign')))
+test.fail_test(os.path.exists(test.workpath('repository', 'src2', '.sconsign')))
+test.fail_test(os.path.exists(test.workpath('work1', 'src1', '.sconsign')))
+test.fail_test(os.path.exists(test.workpath('work2', 'src2', '.sconsign')))
+
+test.up_to_date(chdir = 'work1', options = opts + " OS=foo", arguments = 'build1')
+
+#
+test.up_to_date(chdir = 'work2', options = opts, arguments = 'build2')
+
+test.fail_test(os.path.exists(test.workpath('work2', 'build2', 'foo', 'src2', 'xxx', aaa_obj)))
+test.fail_test(os.path.exists(test.workpath('work2', 'build2', 'foo', 'src2', 'xxx', bbb_obj)))
+test.fail_test(os.path.exists(test.workpath('work2', 'build2', 'foo', 'src2', 'xxx', main_obj)))
+test.fail_test(os.path.exists(test.workpath('work2', 'build2', 'foo', 'src2', 'xxx', xxx_exe)))
+test.fail_test(os.path.exists(test.workpath('work2', 'build2', 'bar', 'src2', 'xxx', aaa_obj)))
+test.fail_test(os.path.exists(test.workpath('work2', 'build2', 'bar', 'src2', 'xxx', bbb_obj)))
+test.fail_test(os.path.exists(test.workpath('work2', 'build2', 'bar', 'src2', 'xxx', main_obj)))
+test.fail_test(os.path.exists(test.workpath('work2', 'build2', 'bar', 'src2', 'xxx', xxx_exe)))
+
+# Ensure file time stamps will be newer.
+time.sleep(2)
+
+test.write(['work2', 'src2', 'include', 'my_string.h'], r"""
+#ifdef FOO
+#define INCLUDE_OS "FOO"
+#endif
+#ifdef BAR
+#define INCLUDE_OS "BAR"
+#endif
+#define INCLUDE_STRING "work2/src2/include/my_string.h: %s\n"
+""")
+
+#
+test.run(chdir = 'work2', options = opts, arguments = 'build2')
+
+test.run(program = work2_build2_foo_src2_xxx_xxx, stdout = """\
+work2/src2/include/my_string.h: FOO
+repository/src2/xxx/include.h: FOO
+repository/src2/xxx/main.c: FOO
+""")
+
+test.run(program = work2_build2_bar_src2_xxx_xxx, stdout = """\
+work2/src2/include/my_string.h: BAR
+repository/src2/xxx/include.h: BAR
+repository/src2/xxx/main.c: BAR
+""")
+
+test.fail_test(os.path.exists(test.workpath('repository', 'src1', '.sconsign')))
+test.fail_test(os.path.exists(test.workpath('repository', 'src2', '.sconsign')))
+test.fail_test(os.path.exists(test.workpath('work1', 'src1', '.sconsign')))
+test.fail_test(os.path.exists(test.workpath('work2', 'src2', '.sconsign')))
+
+# Ensure file time stamps will be newer.
+time.sleep(2)
+
+test.write(['work2', 'src2', 'xxx', 'include.h'], r"""
+#include <my_string.h>
+#ifdef FOO
+#define XXX_OS "FOO"
+#endif
+#ifdef BAR
+#define XXX_OS "BAR"
+#endif
+#define XXX_STRING "work2/src2/xxx/include.h: %s\n"
+""")
+
+test.run(chdir = 'work2', options = opts, arguments = 'build2')
+
+test.run(program = work2_build2_foo_src2_xxx_xxx, stdout = """\
+work2/src2/include/my_string.h: FOO
+work2/src2/xxx/include.h: FOO
+repository/src2/xxx/main.c: FOO
+""")
+
+test.run(program = work2_build2_bar_src2_xxx_xxx, stdout = """\
+work2/src2/include/my_string.h: BAR
+work2/src2/xxx/include.h: BAR
+repository/src2/xxx/main.c: BAR
+""")
+
+test.fail_test(os.path.exists(test.workpath('repository', 'src1', '.sconsign')))
+test.fail_test(os.path.exists(test.workpath('repository', 'src2', '.sconsign')))
+test.fail_test(os.path.exists(test.workpath('work1', 'src1', '.sconsign')))
+test.fail_test(os.path.exists(test.workpath('work2', 'src2', '.sconsign')))
+
+#
+test.unlink(['work2', 'src2', 'include', 'my_string.h'])
+
+test.run(chdir = 'work2', options = opts, arguments = 'build2')
+
+test.run(program = work2_build2_foo_src2_xxx_xxx, stdout = """\
+repository/src2/include/my_string.h: FOO
+work2/src2/xxx/include.h: FOO
+repository/src2/xxx/main.c: FOO
+""")
+
+test.run(program = work2_build2_bar_src2_xxx_xxx, stdout = """\
+repository/src2/include/my_string.h: BAR
+work2/src2/xxx/include.h: BAR
+repository/src2/xxx/main.c: BAR
+""")
+
+test.fail_test(os.path.exists(test.workpath('repository', 'src1', '.sconsign')))
+test.fail_test(os.path.exists(test.workpath('repository', 'src2', '.sconsign')))
+test.fail_test(os.path.exists(test.workpath('work1', 'src1', '.sconsign')))
+test.fail_test(os.path.exists(test.workpath('work2', 'src2', '.sconsign')))
+
+#
+test.pass_test()
+
+# Local Variables:
+# tab-width:4
+# indent-tabs-mode:nil
+# End:
+# vim: set expandtab tabstop=4 shiftwidth=4:
diff --git a/test/Repository/within-repository.py b/test/Repository/within-repository.py
new file mode 100644
index 0000000..6bcc2fa
--- /dev/null
+++ b/test/Repository/within-repository.py
@@ -0,0 +1,157 @@
+#!/usr/bin/env python
+#
+# __COPYRIGHT__
+#
+# Permission is hereby granted, free of charge, to any person obtaining
+# a copy of this software and associated documentation files (the
+# "Software"), to deal in the Software without restriction, including
+# without limitation the rights to use, copy, modify, merge, publish,
+# distribute, sublicense, and/or sell copies of the Software, and to
+# permit persons to whom the Software is furnished to do so, subject to
+# the following conditions:
+#
+# The above copyright notice and this permission notice shall be included
+# in all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
+# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+#
+
+__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
+
+import sys
+import TestSCons
+
+if sys.platform == 'win32':
+ _exe = '.exe'
+else:
+ _exe = ''
+
+
+
+test = TestSCons.TestSCons()
+
+#
+test.subdir('repository', ['repository', 'src'])
+
+#
+workpath_repository = test.workpath('repository')
+repository_foo = test.workpath('repository', 'foo' + _exe)
+repository_src_bar = test.workpath('repository', 'src', 'bar' + _exe)
+
+#
+test.write(['repository', 'SConstruct'], """
+Repository(r'%s')
+SConscript('src/SConscript')
+env = Environment()
+env.Program(target = 'foo', source = ['aaa.c', 'bbb.c', 'foo.c'])
+""" % workpath_repository)
+
+test.write(['repository', 'aaa.c'], r"""
+#include <stdio.h>
+#include <stdlib.h>
+void
+aaa(void)
+{
+ printf("repository/aaa.c\n");
+}
+""")
+
+test.write(['repository', 'bbb.c'], r"""
+#include <stdio.h>
+#include <stdlib.h>
+void
+bbb(void)
+{
+ printf("repository/bbb.c\n");
+}
+""")
+
+test.write(['repository', 'foo.c'], r"""
+#include <stdio.h>
+#include <stdlib.h>
+extern void aaa(void);
+extern void bbb(void);
+int
+main(int argc, char *argv[])
+{
+ argv[argc++] = "--";
+ aaa();
+ bbb();
+ printf("repository/foo.c\n");
+ exit (0);
+}
+""")
+
+test.write(['repository', 'src', 'SConscript'], """
+env = Environment()
+env.Program(target = 'bar', source = ['aaa.c', 'bbb.c', 'bar.c'])
+""")
+
+test.write(['repository', 'src', 'aaa.c'], r"""
+#include <stdio.h>
+#include <stdlib.h>
+void
+aaa(void)
+{
+ printf("repository/src/aaa.c\n");
+}
+""")
+
+test.write(['repository', 'src', 'bbb.c'], r"""
+#include <stdio.h>
+#include <stdlib.h>
+void
+bbb(void)
+{
+ printf("repository/src/bbb.c\n");
+}
+""")
+
+test.write(['repository', 'src', 'bar.c'], r"""
+#include <stdio.h>
+#include <stdlib.h>
+extern void aaa(void);
+extern void bbb(void);
+int
+main(int argc, char *argv[])
+{
+ argv[argc++] = "--";
+ aaa();
+ bbb();
+ printf("repository/src/bar.c\n");
+ exit (0);
+}
+""")
+
+#
+test.run(chdir = 'repository', arguments = ".")
+
+test.run(program = repository_foo, stdout =
+"""repository/aaa.c
+repository/bbb.c
+repository/foo.c
+""")
+
+test.run(program = repository_src_bar, stdout =
+"""repository/src/aaa.c
+repository/src/bbb.c
+repository/src/bar.c
+""")
+
+#
+test.up_to_date(chdir = 'repository', arguments = ".")
+
+#
+test.pass_test()
+
+# Local Variables:
+# tab-width:4
+# indent-tabs-mode:nil
+# End:
+# vim: set expandtab tabstop=4 shiftwidth=4: