From 24fda212b377c2dfae82797e9ce9974fcf2b9446 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jurko=20Gospodneti=C4=87?= Date: Wed, 8 Aug 2012 22:29:29 +0000 Subject: [PATCH] Added a new internal Boost Build test checking Boost Build's project id handling. [SVN r79939] --- v2/test/project_id.py | 320 ++++++++++++++++++++++++++++++++++++++++++ v2/test/test_all.py | 1 + 2 files changed, 321 insertions(+) create mode 100755 v2/test/project_id.py diff --git a/v2/test/project_id.py b/v2/test/project_id.py new file mode 100755 index 000000000..0489fc8f3 --- /dev/null +++ b/v2/test/project_id.py @@ -0,0 +1,320 @@ +#!/usr/bin/python + +# Copyright (C) 2012. Jurko Gospodnetic +# Distributed under the Boost Software License, Version 1.0. +# (See accompanying file LICENSE_1_0.txt or copy at +# http://www.boost.org/LICENSE_1_0.txt) + +# Tests Boost Build's project-id handling. + +import BoostBuild + + +def test_assigning_project_ids(): + t = BoostBuild.Tester(pass_toolset=False) + t.write("jamroot.jam", """\ +import assert ; +import modules ; +import notfile ; +import project ; + +rule assert-project-id ( id ? : module-name ? ) +{ + module-name ?= [ CALLER_MODULE ] ; + assert.result $(id) : project.attribute $(module-name) id ; +} + +# Project rule modifies the main project id. +assert-project-id ; # Initial project id is empty +project foo ; assert-project-id /foo ; +project ; assert-project-id /foo ; +project foo ; assert-project-id /foo ; +project bar ; assert-project-id /bar ; +project /foo ; assert-project-id /foo ; +project "" ; assert-project-id /foo ; + +# Calling the use-project rule does not modify the project's main id. +use-project id1 : a ; +# We need to load the 'a' Jamfile module manually as the use-project rule will +# only schedule the load to be done after the current module load finishes. +a-module = [ project.load "a" ] ; +assert-project-id : $(a-module) ; +use-project id2 : a ; +assert-project-id : $(a-module) ; +modules.call-in $(a-module) : project baz ; +assert-project-id /baz : $(a-module) ; +use-project id3 : a ; +assert-project-id /baz : $(a-module) ; + +# Make sure the project id still holds after all the scheduled use-project loads +# complete. We do this by scheduling the assert for the Jam action scheduling +# phase. +notfile x : @assert-a-rule ; +rule assert-a-rule ( target : : properties * ) +{ + assert-project-id /baz : $(a-module) ; +} +""") + t.write("a/jamfile.jam", """\ +# Initial project id for this module is empty. +assert-project-id ; +""") + t.run_build_system() + t.cleanup() + + +def test_assigning_using_project_ids_in_target_references(): + t = BoostBuild.Tester() + __write_appender(t, "appender.jam") + t.write("jamroot.jam", """\ +import type ; +type.register AAA : _a ; +type.register BBB : _b ; +type.register CCC : _c ; + +import appender ; +appender.register aaa-to-bbb : AAA : BBB ; +appender.register bbb-to-ccc : BBB : CCC ; + +use-project id1 : b ; +use-project /id2 : b ; + +ccc c1 : /id1//target ; +ccc c2 : /id2//target ; +ccc c3 : /id3//target ; +ccc c4 : b//target ; +ccc c5 : /project-a1//target ; +ccc c6 : /project-a2//target ; +ccc c7 : /project-a3//target ; + +use-project id3 : b ; +""") + t.write("b/source._a", "") + t.write("b/jamfile.jam", """\ +project project-a1 ; +project /project-a2 ; +bbb target : source._a ; +project /project-a3 ; +""") + + t.run_build_system() + t.expect_addition("b/bin/$toolset/target._b") + t.expect_addition("bin/$toolset/c%d._c" % x for x in range(1, 8)) + t.expect_nothing_more() + + t.cleanup() + + +def test_repeated_ids(): + t = BoostBuild.Tester() + t.write("jamroot.jam", "project foo ; project foo ;") + t.run_build_system() + + t.write("a/jamfile.jam", "") + t.write("jamroot.jam", "project foo ; use-project foo : a ;") + t.run_build_system(status=1) + t.expect_output_lines("""\ +error: Attempt to redeclare already registered project id '/foo'. +error: Original project: +error: Name: Jamfile<*> +error: Main id: /foo +error: File: jamroot.jam +error: Location: . +error: New project: +error: File: a*jamfile.jam +error: Location: a""") + + t.write("jamroot.jam", "use-project foo : a ; project foo ;") + t.run_build_system(status=1) + t.expect_output_lines("""\ +error: Attempt to redeclare already registered project id '/foo'. +error: Original project: +error: Name: Jamfile<*> +error: Main id: /foo +error: File: jamroot.jam +error: Location: . +error: New project: +error: File: a*jamfile.jam +error: Location: a""") + + t.write("jamroot.jam", """\ +import modules ; +import project ; +modules.call-in [ project.load a ] : project foo ; +project foo ; +""") + t.run_build_system(status=1) + t.expect_output_lines("""\ +error: at jamroot.jam:4 +error: Attempt to redeclare already registered project id '/foo'. +error: Original project: +error: Name: Jamfile<*> +error: Main id: /foo +error: File: a*jamfile.jam +error: Location: a +error: New project: +error: File: jamroot.jam +error: Location: .""") + + t.cleanup() + + +def test_unresolved_project_references(): + t = BoostBuild.Tester() + + __write_appender(t, "appender.jam") + t.write("b/source._a", "") + t.write("b/jamfile.jam", "bbb target : source._a ;") + t.write("jamroot.jam", """\ +import type ; +type.register AAA : _a ; +type.register BBB : _b ; +type.register CCC : _c ; + +import appender ; +appender.register aaa-to-bbb : AAA : BBB ; +appender.register bbb-to-ccc : BBB : CCC ; + +use-project foo : b ; + +ccc c1 : b//target ; +ccc c2 : /foo//target ; +ccc c-invalid : invalid//target ; +ccc c-root-invalid : /invalid//target ; +ccc c-missing-root : foo//target ; +ccc c-invalid-target : /foo//invalid ; +""") + + t.run_build_system(["c1", "c2"]) + t.expect_addition("b/bin/$toolset/debug/target._b") + t.expect_addition("bin/$toolset/debug/c%s._c" % x for x in range(1, 3)) + t.expect_nothing_more() + + t.run_build_system(["c-invalid"], status=1) + t.expect_output_lines("""\ +error: Unable to find file or target named +error: 'invalid//target' +error: referred to from project at +error: '.' +error: could not resolve project reference 'invalid'""") + + t.run_build_system(["c-root-invalid"], status=1) + t.expect_output_lines("""\ +error: Unable to find file or target named +error: '/invalid//target' +error: referred to from project at +error: '.' +error: could not resolve project reference '/invalid'""") + + t.run_build_system(["c-missing-root"], status=1) + t.expect_output_lines("""\ +error: Unable to find file or target named +error: 'foo//target' +error: referred to from project at +error: '.' +error: could not resolve project reference 'foo' - possibly missing a """ + "leading slash ('/') character.") + + t.run_build_system(["c-invalid-target"], status=1) + t.expect_output_lines("""\ +error: Unable to find file or target named +error: '/foo//invalid' +error: referred to from project at +error: '.'""") + t.expect_output_lines("*could not resolve project reference*", False) + + t.cleanup() + + +def __write_appender(t, name): + t.write(name, +r"""# Copyright 2012 Jurko Gospodnetic +# Distributed under the Boost Software License, Version 1.0. +# (See accompanying file LICENSE_1_0.txt or copy at +# http://www.boost.org/LICENSE_1_0.txt) + +# Support for registering test generators that construct their targets by +# simply appending their given input data, e.g. list of sources & targets. + +import "class" : new ; +import generators ; +import modules ; +import sequence ; + +rule register ( id composing ? : source-types + : target-types + ) +{ + local caller-module = [ CALLER_MODULE ] ; + id = $(caller-module).$(id) ; + local g = [ new generator $(id) $(composing) : $(source-types) : + $(target-types) ] ; + $(g).set-rule-name $(__name__).appender ; + generators.register $(g) ; + return $(id) ; +} + +if [ modules.peek : NT ] +{ + X = ")" ; + ECHO_CMD = (echo. ; +} +else +{ + X = \" ; + ECHO_CMD = "echo $(X)" ; +} + +local appender-runs ; + +# We set up separate actions for building each target in order to avoid having +# to iterate over them in action (i.e. shell) code. We have to be extra careful +# though to achieve the exact same effect as if doing all the work in just one +# action. Otherwise Boost Jam might, under some circumstances, run only some of +# our actions. To achieve this we register a series of actions for all the +# targets (since they all have the same target list - either all or none of them +# get run independent of which target actually needs to get built), each +# building only a single target. Since all our actions use the same targets, we +# can not use 'on-target' parameters to pass data to a specific action so we +# pass them using the second 'sources' parameter which our actions then know how +# to interpret correctly. This works well since Boost Jam does not automatically +# add dependency relations between specified action targets & sources and so the +# second argument, even though most often used to pass in a list of sources, can +# actually be used for passing in any type of information. +rule appender ( targets + : sources + : properties * ) +{ + appender-runs = [ CALC $(appender-runs:E=0) + 1 ] ; + local target-index = 0 ; + local target-count = [ sequence.length $(targets) ] ; + local original-targets ; + for t in $(targets) + { + target-index = [ CALC $(target-index) + 1 ] ; + local appender-run = $(appender-runs) ; + if $(targets[2])-defined + { + appender-run += [$(target-index)/$(target-count)] ; + } + append $(targets) : $(appender-run:J=" ") $(t) $(sources) ; + } +} + +actions append +{ + $(ECHO_CMD)-------------------------------------------------$(X) + $(ECHO_CMD)Appender run: $(>[1])$(X) + $(ECHO_CMD)Appender run: $(>[1])$(X)>> "$(>[2])" + $(ECHO_CMD)Target group: $(<:J=' ')$(X) + $(ECHO_CMD)Target group: $(<:J=' ')$(X)>> "$(>[2])" + $(ECHO_CMD) Target: '$(>[2])'$(X) + $(ECHO_CMD) Target: '$(>[2])'$(X)>> "$(>[2])" + $(ECHO_CMD) Sources: '$(>[3-]:J=' ')'$(X) + $(ECHO_CMD) Sources: '$(>[3-]:J=' ')'$(X)>> "$(>[2])" + $(ECHO_CMD)=================================================$(X) + $(ECHO_CMD)-------------------------------------------------$(X)>> "$(>[2])" +} +""") + + +test_assigning_project_ids() +test_assigning_using_project_ids_in_target_references() +test_repeated_ids() +test_unresolved_project_references() diff --git a/v2/test/test_all.py b/v2/test/test_all.py index 382a7f4ca..e408cca38 100644 --- a/v2/test/test_all.py +++ b/v2/test/test_all.py @@ -233,6 +233,7 @@ tests = ["absolute_sources", "print", "project_dependencies", "project_glob", + "project_id", "project_root_constants", "project_root_rule", "project_test3",