In compiler/, all entities have a `c_name` method to get a fully qualified mangled C identifier also usable to name files. All, except for one small class of indomitable entities that still holds out against the namespaces.
`c_name` where developed before the proposition of projects. This PR add a `c_name` for mmodules and update the places where its simple name was used.
Pull-Request: #898
Reviewed-by: Alexis Laferrière <alexis.laf@xymus.net>
var done_tag: Tag = 5.tag
# Number of tasks within each task assignation with `task_tag`
- var tasks_per_packet = 4
+ var tasks_per_packet = 1
# Run the main logic of this node
fun run is abstract
# Gather and registar all tasks
fun create_tasks
do
- var c = 0
- for engine in engines do for prog in test_programs do
+ for prog in test_programs do for engine in engines do
tasks.add new Task(engine, prog)
- c += 1
end
end
end
if res == 5 then result.fail = true
if res == 6 then result.soso = true
if res == 7 then result.skip = true
+ if res == 8 then result.todo = true
+ if res == 9 then result.skip_exec = true
if res == 0 then result.unknown = true
results.add result
print "* {results.fixmes.length} fixmes"
print "* {results.sosos.length} sosos"
print "* {results.skips.length} skips"
+ print "* {results.todos.length} todos"
+ print "* {results.skip_execs.length} skip execs"
print "* {results.unknowns.length} unknowns (bug in tests.sh or nitester)"
end
# Output file directory
var out_dir = "/dev/shm/nit_out{rank}" is lazy
+ # Directory to store the xml files produced for Jenkins
+ var xml_dir = "~/jenkins_xml/"
+
# Output file of the `tests.sh` script
var tests_sh_out = "/dev/shm/nit_local_out{rank}" is lazy
- # Path to the local copy of the Nit repository
- var nit_copy_dir = "/dev/shm/nit{rank}/" is lazy
-
# Source Nit repository, must be already updated and `make` before execution
var nit_source_dir = "~/nit"
fun setup
do
if verbose > 0 then sys.system "hostname"
- sys.system "git clone {nit_source_dir} {nit_copy_dir}"
end
# Clean up the testing environment
do
if comp_dir.file_exists then comp_dir.rmdir
if out_dir.file_exists then out_dir.rmdir
- if nit_copy_dir.file_exists then nit_copy_dir.rmdir
if tests_sh_out.file_exists then tests_sh_out.file_delete
end
# Receive tasks to execute
mpi.recv_into(task_buffer, 0, 1, status.source, status.tag, comm_world)
var first_id = task_buffer[0]
- for task_id in [first_id .. first_id + tasks_per_packet] do
+ for task_id in [first_id .. first_id + tasks_per_packet[ do
# If id is over all known tasks, stop right here
if task_id >= tasks.length then break
var task = tasks[task_id]
# Command line to execute test
- var cmd = "XMLDIR={out_dir} ERRLIST={out_dir}/errlist TMPDIR={out_dir} " +
+ var cmd = "XMLDIR={xml_dir} ERRLIST={out_dir}/errlist TMPDIR={out_dir} " +
"CCACHE_DIR={ccache_dir} CCACHE_TEMPDIR={ccache_dir} CCACHE_BASEDIR={comp_dir} " +
- "./tests.sh --compdir {comp_dir} --outdir {out_dir} -o \"--make-flags '-j1'\"" +
- " --node --engine {task.engine} {nit_copy_dir / "tests" / task.test_program} > {tests_sh_out}"
+ "./tests.sh --compdir {comp_dir} --outdir {out_dir} " +
+ " --node --engine {task.engine} {task.test_program} > {tests_sh_out}"
# Execute test
sys.system cmd
if line.has("[======= fail") then res = 5
if line.has("[======= soso") then res = 6
if line.has("[skip]") then res = 7
+ if line.has("[todo]") then res = 8
+ if line.has("[skip exec]") then res = 9
if res == null then
res = 0
# Is `self` result a _soso_?
var soso = false
- # Is `self` skipped test?
+ # Has `self` been skipped?
var skip = false
+ # Is `self` TODO?
+ var todo = false
+
+ # Has the execution of `self` been skipped?
+ var skip_exec = false
+
# Is `self` an unknown result, probably an error
var unknown = false
if ok_empty then err = "0k"
if fixme then err = "fixme"
if fail then err = "fail"
+ if soso then err = "soso"
+ if skip then err = "skip"
+ if todo then err = "todo"
+ if skip_exec then err = "skip_exec"
return "{task} arg{arg} alt{alt} => {err}"
end
var fails = new HashSet[Result]
var sosos = new HashSet[Result]
var skips = new HashSet[Result]
+ var todos = new HashSet[Result]
+ var skip_execs = new HashSet[Result]
var unknowns = new HashSet[Result]
# TODO remove
if result.fail then fails.add result
if result.soso then sosos.add result
if result.skip then skips.add result
+ if result.todo then todos.add result
+ if result.skip_exec then skip_execs.add result
if result.unknown then unknowns.add result
super
break
end
- print "Solved, after looking at {r.steps} positions during {c.lapse}"
+ print "Solved, after looking at {r.steps} positions"
pb.print_plan(r.plan)
end
--- /dev/null
+# This file is part of NIT ( http://www.nitlanguage.org ).
+#
+# This file is free software, which comes along with NIT. This software is
+# distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+# without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE. You can modify it is you want, provided this header
+# is kept unaltered, and a notification of the changes is added.
+# You are allowed to redistribute it and sell it, alone or is a part of
+# another product.
+
+# Uses JSON as a storage medium for a Neo4j subgraph.
+module neo4j::json_store
+
+import neo4j
+private import template
+
+# A Neo4j graph that uses as a storage medium.
+#
+# The graph is stored as a JSON object with the following properties:
+#
+# * `"nodes"`: An array with all nodes. Each node is an object with the
+# following properties:
+# * `"id"`: The ID (`Int`) that uniquely identifies the node in the current
+# graph.
+# * `"labels"`: An array of all applied labels.
+# * `"properties"`: An object mapping each defined property to its value.
+# * `"links"`: An array with all relationships. Each relationship is an object
+# with the following properties:
+# * `"type"`: The type (`String`) of the relationship.
+# * `"properties"`: An object mapping each defined property to its value.
+# * `"from"`: The ID (`Int`) of the source node.
+# * `"to"`: The ID (`Int`) of the destination node.
+#
+# TODO Refine the graph API instead when it will be available.
+class JsonGraph
+ super Jsonable
+
+ # All nodes in the graph.
+ var nodes: SimpleCollection[NeoNode] = new Array[NeoNode]
+
+ # All relationships in the graph.
+ var links: SimpleCollection[NeoEdge] = new Array[NeoEdge]
+
+ # Create an empty graph.
+ init do end
+
+ # Retrieve the graph from the specified JSON value.
+ #
+ # var graph = new JsonGraph
+ # var a = new NeoNode
+ # a.labels.add "Foo"
+ # a["answer"] = 42
+ # a["Ultimate question of"] = new JsonArray.from(["life",
+ # "the Universe", "and Everything."])
+ # graph.nodes.add a
+ # var b = new NeoNode
+ # b.labels.add "Foo"
+ # b.labels.add "Bar"
+ # graph.nodes.add b
+ # graph.links.add new NeoEdge(a, "BAZ", b)
+ # #
+ # graph = new JsonGraph.from_json(graph.to_json)
+ # assert 1 == graph.links.length
+ # for link in graph.links do
+ # assert "BAZ" == link.rel_type
+ # assert a.labels == link.from.labels
+ # for k, v in a.properties do assert v == link.from.properties[k]
+ # assert b.labels == link.to.labels
+ # for k, v in b.properties do assert v == link.to.properties[k]
+ # end
+ # assert 2 == graph.nodes.length
+ init from_json(t: Text) do
+ from_json_object(t.to_jsonable.as(JsonObject))
+ end
+
+ # Retrieve the graph from the specified JSON object.
+ init from_json_object(o: JsonObject) do
+ var node_by_id = new HashMap[Int, NeoNode]
+ var nodes = o["nodes"].as(JsonArray)
+ for json_node in nodes do
+ assert json_node isa JsonObject
+ var node = new NeoNode.from_json_object(json_node)
+ node_by_id[json_node["id"].as(Int)] = node
+ self.nodes.add node
+ end
+ var links = o["links"].as(JsonArray)
+ for json_link in links do
+ assert json_link isa JsonObject
+ var from = node_by_id[json_link["from"].as(Int)]
+ var to = node_by_id[json_link["to"].as(Int)]
+ var rel_type = json_link["type"].as(String)
+ var json_properties = json_link["properties"].as(JsonObject)
+ var link = new NeoEdge(from, rel_type, to)
+ link.properties.recover_with(json_properties)
+ self.links.add link
+ end
+ end
+
+ redef fun to_json do
+ var t = new Template
+ t.add "\{\"nodes\":["
+ var i = 0
+ for n in nodes do
+ if i > 0 then t.add ","
+ t.add n.to_json
+ i += 1
+ end
+ t.add "],\"links\":["
+ i = 0
+ for link in links do
+ if i > 0 then t.add ","
+ t.add link.to_json
+ i += 1
+ end
+ t.add "]\}"
+ return t.write_to_string
+ end
+end
+
+# Make `NeoNode` `Jsonable`.
+redef class NeoNode
+ super Jsonable
+
+ # Retrieve the node from the specified JSON value.
+ #
+ # Note: Here, the `"id"` is optional and ignored.
+ #
+ # SEE: `JsonGraph`
+ #
+ # var node = new NeoNode.from_json("""
+ # {
+ # "labels": ["foo", "Bar"],
+ # "properties": {
+ # "baz": 42
+ # }
+ # }
+ # """)
+ # assert ["foo", "Bar"] == node.labels
+ # assert 42 == node["baz"]
+ init from_json(t: Text) do
+ from_json_object(t.to_jsonable.as(JsonObject))
+ end
+
+ # Retrieve the node from the specified JSON value.
+ #
+ # Note: Here, the `"id"` is optional and ignored.
+ #
+ # SEE: `JsonGraph`
+ init from_json_object(o: JsonObject) do
+ init
+ var labels = o["labels"].as(JsonArray)
+ for lab in labels do self.labels.add(lab.as(String))
+ var json_properties = o["properties"].as(JsonObject)
+ properties.recover_with(json_properties)
+ end
+
+ # Get the JSON representation of `self`.
+ #
+ # SEE: `JsonGraph`
+ redef fun to_json do
+ var t = new Template
+ t.add "\{\"id\":"
+ t.add object_id.to_json
+ t.add ",\"labels\":["
+ var i = 0
+ for lab in labels do
+ if i > 0 then t.add ","
+ t.add lab.to_json
+ i += 1
+ end
+ t.add "],\"properties\":"
+ t.add properties.to_json
+ t.add "}"
+ return t.write_to_string
+ end
+
+ redef fun to_s do return to_json
+end
+
+# Make `NeoEdge` `Jsonable`.
+redef class NeoEdge
+ super Jsonable
+
+ redef fun to_json do
+ var t = new Template
+ t.add "\{\"type\":"
+ t.add rel_type.to_json
+ t.add ",\"properties\":"
+ t.add properties.to_json
+ t.add ",\"from\":"
+ t.add from.object_id.to_json
+ t.add ",\"to\":"
+ t.add to.object_id.to_json
+ t.add "}"
+ return t.write_to_string
+ end
+
+ redef fun to_s do return to_json
+end
# Perform a `CypherQuery`
# see: CypherQuery
fun cypher(query: CypherQuery): Jsonable do
- return post("{cypher_url}", query.to_json)
+ return post("{cypher_url}", query.to_rest)
end
# GET JSON data from `url`
return self
end
- # Translate the query to JSON
- fun to_json: JsonObject do
+ # Translate the query to the body of a corresponding Neo4j REST request.
+ fun to_rest: JsonObject do
var obj = new JsonObject
obj["query"] = query
if not params.is_empty then
return obj
end
- redef fun to_s do return to_json.to_s
+ redef fun to_s do return to_rest.to_s
end
# The fundamental units that form a graph are nodes and relationships.
# Is the property `key` set?
fun has_key(key: String): Bool do return properties.has_key(key)
-
- # Translate `self` to JSON
- fun to_json: JsonObject do return properties
end
# Nodes are used to represent entities stored in base.
var tpl = new FlatBuffer
tpl.append "\{"
tpl.append "labels: [{labels.join(", ")}],"
- tpl.append "data: {to_json}"
+ tpl.append "data: {properties.to_json}"
tpl.append "\}"
return tpl.write_to_string
end
# Get edge type
fun rel_type: nullable String do return internal_type
- redef fun to_json do
+ # Get the JSON body of a REST request that create the relationship.
+ private fun to_rest: JsonObject do
var obj = new JsonObject
if to.is_linked then
obj["to"] = to.url
else
job.to = "\{{edge.from.batch_id.to_s}\}/relationships"
end
- job.body = edge.to_json
+ job.body = edge.to_rest
end
# Create multiple edges
var request = new JsonPOST(client.batch_url, client.curl)
# request.headers["X-Stream"] = "true"
var json_jobs = new JsonArray
- for job in jobs.values do json_jobs.add job.to_json
+ for job in jobs.values do json_jobs.add job.to_rest
request.data = json_jobs
var response = request.execute
var res = client.parse_response(response)
var body: nullable Jsonable = null
# JSON formated job
- fun to_json: JsonObject do
+ fun to_rest: JsonObject do
var job = new JsonObject
job["id"] = id
job["method"] = method
--- /dev/null
+#!/bin/bash
+# This file is part of NIT ( http://www.nitlanguage.org ).
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# This script is a wrapper for `nitester` which also manages a local repo
+#
+# The first argument _must_ be the hash of the commit at the head of the
+# branch to test. The other arguments are passed on to `nitester`.
+
+hash=$1
+shift
+
+set +x
+
+local_repo=nit/
+remote_repo=privat
+
+tools_dir=misc/jenkins/
+
+cd $local_repo
+git clean -fdxq .
+
+git fetch $remote_repo
+git checkout $hash
+
+# Make nitg and tools
+$tools_dir/unitrun.sh "run-make-0initial_make" make
+
+# Make nitester
+$tools_dir/unitrun.sh "run-make-nitester" make -C contrib/nitester/
+
+# Run tests
+cd tests
+mkdir -p out
+rm ~/jenkins_xml/*.xml
+mpirun -np 30 ../contrib/nitester/bin/nitester $@
name=$1
shift
+# Detect a working time command
+if env time --quiet -f%U true 2>/dev/null; then
+ TIME="env time --quiet -f%U -o '${name}.t.out'"
+elif env time -f%U true 2>/dev/null; then
+ TIME="env time -f%U -o '${name}.t.out'"
+else
+ TIME=
+fi
+
# Magic here! This tee and save both stdout and stderr in distinct files without messing with them
# Time just get the user time
-/usr/bin/time -f%U --quiet -o "${name}.t.out" "$@" > >(tee "${name}.out") 2> >(tee "${name}.2.out" >&2)
+$TIME "$@" > >(tee "${name}.out") 2> >(tee "${name}.2.out" >&2)
res=$?
c=`echo "${name%-*}" | tr "-" "."`
# build graph
var op = new RopeBuffer
var name = "dep_module_{mmodule.nitdoc_id}"
- op.append("digraph {name} \{ rankdir=BT; node[shape=none,margin=0,width=0,height=0,fontsize=10]; edge[dir=none,color=gray]; ranksep=0.2; nodesep=0.1;\n")
+ op.append("digraph \"{name.escape_to_dot}\" \{ rankdir=BT; node[shape=none,margin=0,width=0,height=0,fontsize=10]; edge[dir=none,color=gray]; ranksep=0.2; nodesep=0.1;\n")
for mmodule in poset do
if mmodule == self.mmodule then
- op.append("\"{mmodule.name}\"[shape=box,margin=0.03];\n")
+ op.append("\"{mmodule.name.escape_to_dot}\"[shape=box,margin=0.03];\n")
else
- op.append("\"{mmodule.name}\"[URL=\"{mmodule.nitdoc_url}\"];\n")
+ op.append("\"{mmodule.name.escape_to_dot}\"[URL=\"{mmodule.nitdoc_url.escape_to_dot}\"];\n")
end
for omodule in poset[mmodule].direct_greaters do
- op.append("\"{mmodule.name}\"->\"{omodule.name}\";\n")
+ op.append("\"{mmodule.name.escape_to_dot}\"->\"{omodule.name.escape_to_dot}\";\n")
end
end
op.append("\}\n")
var op = new RopeBuffer
var name = "dep_class_{mclass.nitdoc_id}"
- op.append("digraph {name} \{ rankdir=BT; node[shape=none,margin=0,width=0,height=0,fontsize=10]; edge[dir=none,color=gray]; ranksep=0.2; nodesep=0.1;\n")
+ op.append("digraph \"{name.escape_to_dot}\" \{ rankdir=BT; node[shape=none,margin=0,width=0,height=0,fontsize=10]; edge[dir=none,color=gray]; ranksep=0.2; nodesep=0.1;\n")
var classes = poset.to_a
var todo = new Array[MClass]
var done = new HashSet[MClass]
if done.has(c) then continue
done.add c
if c == mclass then
- op.append("\"{c.name}\"[shape=box,margin=0.03];\n")
+ op.append("\"{c.name.escape_to_dot}\"[shape=box,margin=0.03];\n")
else
- op.append("\"{c.name}\"[URL=\"{c.nitdoc_url}\"];\n")
+ op.append("\"{c.name.escape_to_dot}\"[URL=\"{c.nitdoc_url.escape_to_dot}\"];\n")
end
var smallers = poset[c].direct_smallers
if smallers.length < 10 then
for c2 in smallers do
- op.append("\"{c2.name}\"->\"{c.name}\";\n")
+ op.append("\"{c2.name.escape_to_dot}\"->\"{c.name.escape_to_dot}\";\n")
end
todo.add_all smallers
else
- op.append("\"...\"->\"{c.name}\";\n")
+ op.append("\"...\"->\"{c.name.escape_to_dot}\";\n")
end
end
op.append("\}\n")
dot.mprojects.add(g.mproject)
end
var projectpath = toolcontext.output_dir.join_path("project_hierarchy.dot")
- print "generating {projectpath}"
+ print "generating project_hierarchy.dot"
dot.write_to_file(projectpath)
var modulepath = toolcontext.output_dir.join_path("module_hierarchy.dot")
dot.mprojects.add_all(model.mprojects)
- print "generating {modulepath}"
+ print "generating module_hierarchy.dot"
dot.write_to_file(modulepath)
end
var file = toolcontext.opt_output.value
if file == null then file = "nitunit.xml"
page.write_to_file(file)
-print "Results saved in {file}"
# print docunits results
-print "\nDocUnits:"
+print "DocUnits:"
if modelbuilder.unit_entities == 0 then
print "No doc units found"
else if modelbuilder.failed_entities == 0 and not toolcontext.opt_noact.value then
#!/bin/sh
-printf "%s\n" "$@" *.nit \
+printf "%s\n" "$@" \
+ ../src/nit*.nit \
+ ../src/test_*.nit \
../examples/*.nit \
../examples/*/*.nit \
../examples/shoot/src/shoot_logic.nit \
../lib/*/examples/*.nit \
../contrib/friendz/src/solver_cmd.nit \
../contrib/pep8analysis/src/pep8analysis.nit \
- ../src/nit*.nit \
- ../src/test_*.nit
+ *.nit
Total size of tables (classes and instances): 38 (not including stuff like info for subtyping or call-next-method)
Average size of table by runtime class: 6.33
Values never redefined: 32 (84.21%)
-generating out/nitmetrics_args1.write/project_hierarchy.dot
-generating out/nitmetrics_args1.write/module_hierarchy.dot
+generating project_hierarchy.dot
+generating module_hierarchy.dot
# Inheritance metrics
test_test_nitunit.nit:36,2--40,4: ERROR: test_foo1 (in file .nitunit/test_test_nitunit_TestX_test_foo1.nit): Runtime error: Assert failed (test_test_nitunit.nit:39)
-Results saved in out/nitunit_args1.write
-
DocUnits:
Entities: 27; Documented ones: 3; With nitunits: 3; Failures: 2
eab
f.c
dgh
-Solved, after looking at 14 positions during 0.0s
+Solved, after looking at 14 positions
Solution in 10 moves: right(>) down(v) left(<) left(<) up(^) right(>) right(>) up(^) left(<) left(<)
if [ "x$XMLDIR" = "x" ]; then
xml="tests-$engine.xml"
else
- xml="$XMLDIR/tests-$engine.xml"
+ sum=`echo $@ | md5sum | cut -f1 -d " "`
+ xml="$XMLDIR/tests-$engine-$sum.xml"
+ mkdir -p "$XMLDIR"
fi
echo >$xml "<testsuites><testsuite>"