Skip to content
This repository was archived by the owner on Aug 31, 2021. It is now read-only.

Commit b47ae06

Browse files
[[ cpptest ]] Run tests as part of build. Test memory allocation failure.
1 parent 6e05b90 commit b47ae06

File tree

5 files changed

+208
-1
lines changed

5 files changed

+208
-1
lines changed

config/cpptest.gypi

Lines changed: 59 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,8 +47,66 @@
4747
'SubSystem': '1', # /SUBSYSTEM:CONSOLE
4848
},
4949
},
50-
5150
},
51+
52+
{
53+
'target_name': 'run-test-<(module_name)',
54+
'type': 'none',
55+
56+
'variables':
57+
{
58+
'javascriptify': '',
59+
'test_suffix': '',
60+
'exec_wrapper': '',
61+
},
62+
63+
'dependencies': [ 'test-<(module_name)<(javascriptify)', ],
64+
65+
'conditions':
66+
[
67+
[
68+
'OS == "emscripten"',
69+
{
70+
'variables':
71+
{
72+
'javascriptify': '-javascriptify',
73+
'test_suffix': '.js',
74+
'exec_wrapper': 'node',
75+
},
76+
},
77+
],
78+
[
79+
'OS == "win"',
80+
{
81+
'variables':
82+
{
83+
'test_suffix': '.exe',
84+
},
85+
},
86+
],
87+
],
88+
89+
'actions':
90+
[
91+
{
92+
'action_name': 'run-test-<(module_name)',
93+
'message': 'Running test-<(module_name)',
94+
95+
'inputs': [ '<(PRODUCT_DIR)/test-<(module_name)<(test_suffix)', ],
96+
'outputs': [ '<(PRODUCT_DIR)/test-<(module_name).log' ],
97+
98+
'action':
99+
[
100+
'<@(perl)',
101+
'../util/run-tests.pl',
102+
'<(exec_wrapper)',
103+
'<(PRODUCT_DIR)/test-<(module_name)<(test_suffix)',
104+
],
105+
106+
},
107+
],
108+
109+
}
52110
],
53111

54112
'conditions':

config/linux-settings.gypi

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,7 @@
103103
'-std=<(c++_std)',
104104
'-fno-exceptions',
105105
'-fno-rtti',
106+
'-fcheck-new',
106107
],
107108

108109
'configurations':

engine/test/test_new.cpp

Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
/* Copyright (C) 2003-2015 LiveCode Ltd.
2+
3+
This file is part of LiveCode.
4+
5+
LiveCode is free software; you can redistribute it and/or modify it under
6+
the terms of the GNU General Public License v3 as published by the Free
7+
Software Foundation.
8+
9+
LiveCode is distributed in the hope that it will be useful, but WITHOUT ANY
10+
WARRANTY; without even the implied warranty of MERCHANTABILITY or
11+
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12+
for more details.
13+
14+
You should have received a copy of the GNU General Public License
15+
along with LiveCode. If not see <http://www.gnu.org/licenses/>. */
16+
17+
18+
/*
19+
LiveCode does not use exceptions and the codebase assumes that `new`
20+
returns NULL if the allocation fails. This is not the default
21+
behaviour of modern C++ compilers so we need to check that the
22+
compiler has the correct flags to get the desired behaviour.
23+
24+
We need to check that:
25+
26+
- If an allocation fails then new returns a null pointer and
27+
doesn't (try) to throw an exception.
28+
29+
- If an allocation fails then the constructor is not called.
30+
31+
*/
32+
33+
#include "gtest/gtest.h"
34+
35+
#include "prefix.h"
36+
37+
38+
enum {
39+
SIZE =
40+
#if defined(__EMSCRIPTEN__) || defined(__I386__)
41+
1 << 15
42+
#else
43+
1 << 20
44+
#endif
45+
};
46+
47+
class Big {
48+
public:
49+
Big() {
50+
// Check that the constructor is not called after the
51+
// allocation failed. If the compiler flags are not set
52+
// correctly it may be assuming that `new` never returns
53+
// NULL and so calls the constructor without checking it's
54+
// not NULL. Writing to `m_big[0]` will cause a seg fault
55+
// if `this` is NULL.
56+
m_big[0] = 0;
57+
}
58+
59+
char m_big[SIZE];
60+
};
61+
62+
struct VeryBig {
63+
Big m_bigger[SIZE];
64+
};
65+
66+
67+
TEST(new, new)
68+
//
69+
// Checks that new returns NULL on error.
70+
//
71+
{
72+
VeryBig* pointers[1000];
73+
int i = 0;
74+
75+
VeryBig* p = new VeryBig;
76+
77+
for (; p != NULL && i < 1000; i++) {
78+
pointers[i] = p;
79+
p = new VeryBig;
80+
}
81+
82+
ASSERT_NE(1000, i) << "All alocations succeed!";
83+
84+
for (i--; i >= 0; i--) {
85+
delete pointers[i];
86+
}
87+
}
88+
89+
90+
TEST(new, array)
91+
//
92+
// Checks that new[] returns NULL on error.
93+
//
94+
{
95+
VeryBig* pointers[1000];
96+
int i = 0;
97+
98+
VeryBig* p = new VeryBig[1];
99+
100+
for (; p != NULL && i < 1000; i++) {
101+
pointers[i] = p;
102+
p = new VeryBig[1];
103+
}
104+
105+
ASSERT_NE(1000, i) << "All alocations succeed!";
106+
107+
for (i--; i >= 0; i--) {
108+
delete [] pointers[i];
109+
}
110+
}

livecode.gyp

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -220,5 +220,32 @@
220220
],
221221
],
222222
},
223+
224+
{
225+
'target_name': 'cpptest-run-all',
226+
'type': 'none',
227+
228+
'dependencies':
229+
[
230+
'libcpptest/libcpptest.gyp:run-test-libcpptest',
231+
'engine/kernel-standalone.gyp:run-test-kernel-standalone',
232+
],
233+
234+
'conditions':
235+
[
236+
[
237+
'mobile == 0',
238+
{
239+
'dependencies':
240+
[
241+
'engine/kernel-server.gyp:run-test-kernel-server',
242+
'engine/kernel-development.gyp:run-test-kernel-development',
243+
'engine/kernel-installer.gyp:run-test-kernel-installer',
244+
],
245+
},
246+
],
247+
],
248+
},
249+
223250
],
224251
}

util/run-tests.pl

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
#!/usr/bin/env perl
2+
3+
use File::Basename;
4+
5+
$test_wrapper = $ARGV[0];
6+
$test_exec = $ARGV[1];
7+
$test_dir = dirname($test_exec);
8+
9+
chdir $test_dir or die "Failed to change directory!";
10+
print "$test_wrapper $test_exec\n";
11+
exec "$test_wrapper $test_exec";

0 commit comments

Comments
 (0)