Skip to content
This repository was archived by the owner on Apr 12, 2019. It is now read-only.

Commit 66c36d4

Browse files
rbehrendsfingolfin
authored andcommitted
Add tests for the new GC extensions.
1 parent 3adc378 commit 66c36d4

File tree

6 files changed

+812
-1
lines changed

6 files changed

+812
-1
lines changed

test/Makefile

+7-1
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@ TESTS = all stdlib $(TESTGROUPS) \
1616

1717
EMBEDDING_ARGS := "JULIA=$(JULIA_EXECUTABLE)" "BIN=$(SRCDIR)/embedding" "CC=$(CC)"
1818

19+
GCEXT_ARGS := "JULIA=$(JULIA_EXECUTABLE)" "BIN=$(SRCDIR)/gcext" "CC=$(CC)"
20+
1921
default: all
2022

2123
$(TESTS):
@@ -25,7 +27,11 @@ $(TESTS):
2527
embedding:
2628
@$(MAKE) -C $(SRCDIR)/$@ check $(EMBEDDING_ARGS)
2729

30+
gcext:
31+
@$(MAKE) -C $(SRCDIR)/$@ check $(GCEXT_ARGS)
32+
2833
clean:
2934
@$(MAKE) -C embedding $@ $(EMBEDDING_ARGS)
35+
@$(MAKE) -C gcext $@ $(GCEXT_ARGS)
3036

31-
.PHONY: $(TESTS) embedding clean
37+
.PHONY: $(TESTS) embedding gcext clean

test/gcext/.gitignore

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
/gcext
2+
/gcext-debug

test/gcext/LocalTest.jl

+85
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
# This file is a part of Julia. License is MIT: https://julialang.org/license
2+
3+
module LocalTest
4+
const Stack = Main.TestGCExt.Stack
5+
function make()
6+
ccall(:stk_make, Stack, ())
7+
end
8+
function push(stack :: Stack, val :: String)
9+
ccall(:stk_push, Nothing, (Stack, String), stack, val)
10+
end
11+
function top(stack :: Stack)
12+
return ccall(:stk_top, String, (Stack,), stack)
13+
end
14+
function pop(stack :: Stack)
15+
return ccall(:stk_pop, String, (Stack,), stack)
16+
end
17+
function size(stack :: Stack)
18+
return ccall(:stk_size, UInt, (Stack,), stack)
19+
end
20+
function empty(stack :: Stack)
21+
return size(stack) == 0
22+
end
23+
function blob(stack :: Stack)
24+
return ccall(:stk_blob, Any, (Stack,), stack)
25+
end
26+
function gc_counter_full()
27+
return ccall(:get_gc_counter, UInt, (Cint,), 1)
28+
end
29+
function gc_counter_inc()
30+
return ccall(:get_gc_counter, UInt, (Cint,), 0)
31+
end
32+
function gc_counter()
33+
return gc_counter_full() + gc_counter_inc()
34+
end
35+
function num_obj_sweeps()
36+
return ccall(:get_obj_sweeps, UInt, ())
37+
end
38+
function get_aux_root(n :: Int)
39+
return ccall(:get_aux_root, String, (UInt,), n)
40+
end
41+
function set_aux_root(n :: Int, x :: String)
42+
return ccall(:set_aux_root, Nothing, (UInt, String), n, x)
43+
end
44+
function internal_obj_scan(p :: Any)
45+
if ccall(:internal_obj_scan, Cint, (Any,), p) == 0
46+
global internal_obj_scan_failures += 1
47+
end
48+
end
49+
50+
global internal_obj_scan_failures = 0
51+
for i in 0:1000
52+
set_aux_root(i, string(i))
53+
end
54+
function test()
55+
local stack = make()
56+
for i in 1:100000
57+
push(stack, string(i, base=2))
58+
internal_obj_scan(top(stack))
59+
end
60+
for i in 1:1000
61+
local stack2 = make()
62+
internal_obj_scan(stack2)
63+
internal_obj_scan(blob(stack2))
64+
while !empty(stack)
65+
push(stack2, pop(stack))
66+
end
67+
stack = stack2
68+
if i % 100 == 0
69+
GC.gc()
70+
end
71+
end
72+
end
73+
global corrupted_roots = 0
74+
for i in 0:1000
75+
if get_aux_root(i) != string(i)
76+
global corrupted_roots += 1
77+
end
78+
end
79+
@time test()
80+
print(gc_counter_full(), " full collections.\n")
81+
print(gc_counter_inc(), " partial collections.\n")
82+
print(num_obj_sweeps(), " object sweeps.\n")
83+
print(internal_obj_scan_failures, " internal object scan failures.\n")
84+
print(corrupted_roots, " corrupted auxiliary roots.\n")
85+
end

test/gcext/Makefile

+60
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
# This file is a part of Julia. License is MIT: https://julialang.org/license
2+
3+
# This Makefile template requires the following variables to be set
4+
# in the environment or on the command-line:
5+
# JULIA: path to julia[.exe] executable
6+
# BIN: binary build directory
7+
8+
ifndef JULIA
9+
$(error "Please pass JULIA=[path of target julia binary], or set as environment variable!")
10+
endif
11+
ifndef BIN
12+
$(error "Please pass BIN=[path of build directory], or set as environment variable!")
13+
endif
14+
15+
#=============================================================================
16+
# this source directory where gcext.c is located
17+
SRCDIR := $(abspath $(dir $(lastword $(MAKEFILE_LIST))))
18+
19+
# get the executable suffix, if any
20+
EXE := $(suffix $(abspath $(JULIA)))
21+
22+
# get compiler and linker flags. (see: `contrib/julia-config.jl`)
23+
JULIA_CONFIG := $(JULIA) -e 'include(joinpath(Sys.BINDIR, Base.DATAROOTDIR, "julia", "julia-config.jl"))' --
24+
CPPFLAGS_ADD :=
25+
CFLAGS_ADD = $(shell $(JULIA_CONFIG) --cflags)
26+
LDFLAGS_ADD = -lm $(shell $(JULIA_CONFIG) --ldflags --ldlibs)
27+
28+
DEBUGFLAGS += -g
29+
30+
#=============================================================================
31+
32+
release: $(BIN)/gcext$(EXE)
33+
debug: $(BIN)/gcext-debug$(EXE)
34+
35+
$(BIN)/gcext$(EXE): $(SRCDIR)/gcext.c
36+
$(CC) $^ -o $@ $(CPPFLAGS_ADD) $(CPPFLAGS) $(CFLAGS_ADD) $(CFLAGS) $(LDFLAGS_ADD) $(LDFLAGS)
37+
38+
$(BIN)/gcext-debug$(EXE): $(SRCDIR)/gcext.c
39+
$(CC) $^ -o $@ $(CPPFLAGS_ADD) $(CPPFLAGS) $(CFLAGS_ADD) $(CFLAGS) $(LDFLAGS_ADD) $(LDFLAGS) $(DEBUGFLAGS)
40+
41+
ifneq ($(abspath $(BIN)),$(abspath $(SRCDIR)))
42+
# for demonstration purposes, our demo code is also installed
43+
# in $BIN, although this would likely not be typical
44+
$(BIN)/LocalModule.jl: $(SRCDIR)/LocalModule.jl
45+
cp $< $@
46+
endif
47+
48+
check: $(BIN)/gcext$(EXE) $(BIN)/LocalTest.jl
49+
$(JULIA) --depwarn=error $(SRCDIR)/gcext-test.jl $<
50+
@echo SUCCESS
51+
52+
clean:
53+
-rm -f $(BIN)/gcext-debug$(EXE) $(BIN)/gcext$(EXE)
54+
55+
.PHONY: release debug clean check
56+
57+
# Makefile debugging trick:
58+
# call print-VARIABLE to see the runtime value of any variable
59+
print-%:
60+
@echo '$*=$($*)'

test/gcext/gcext-test.jl

+42
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
# This file is a part of Julia. License is MIT: https://julialang.org/license
2+
3+
# tests the output of the embedding example is correct
4+
using Test
5+
6+
if Sys.iswindows()
7+
# libjulia needs to be in the same directory as the embedding executable or in path
8+
ENV["PATH"] = string(Sys.BINDIR, ";", ENV["PATH"])
9+
end
10+
11+
function checknum(s, rx, cond)
12+
m = match(rx, s)
13+
if m === nothing
14+
return false
15+
else
16+
num = m[1]
17+
return cond(parse(UInt, num))
18+
end
19+
end
20+
21+
@test length(ARGS) == 1
22+
@testset "gcext example" begin
23+
out = Pipe()
24+
err = Pipe()
25+
p = run(pipeline(Cmd(ARGS), stdin=devnull, stdout=out, stderr=err), wait=false)
26+
close(out.in)
27+
close(err.in)
28+
out_task = @async readlines(out)
29+
err_task = @async readlines(err)
30+
# @test success(p)
31+
errlines = fetch(err_task)
32+
lines = fetch(out_task)
33+
@test length(errlines) == 0
34+
@test length(lines) == 6
35+
@test checknum(lines[2], r"([0-9]+) full collections", n -> n >= 10)
36+
@test checknum(lines[3], r"([0-9]+) partial collections", n -> n > 0)
37+
@test checknum(lines[4], r"([0-9]+) object sweeps", n -> n > 0)
38+
@test checknum(lines[5], r"([0-9]+) internal object scan failures",
39+
n -> n == 0)
40+
@test checknum(lines[6], r"([0-9]+) corrupted auxiliary roots",
41+
n -> n == 0)
42+
end

0 commit comments

Comments
 (0)