Skip to content

Commit ad533cc

Browse files
committed
APL-CORE: June 2020 Release of APL 1.3 compilant core engine (1.3.3)
For more details on this release refer to CHANGELOG.md To learn about APL see: https://developer.amazon.com/docs/alexa-presentation-language/understand-apl.html
1 parent 89c0013 commit ad533cc

File tree

10 files changed

+78
-21
lines changed

10 files changed

+78
-21
lines changed

CHANGELOG.md

+14
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,19 @@
11
# Changelog
22

3+
## [1.3.3]
4+
5+
This release is a bug fix release of apl-core-library
6+
7+
### Added
8+
9+
- Added support for memory checks with valgrind during unit testing
10+
11+
### Changed
12+
13+
- Fixed windows build
14+
- Fixed a bug in Math.random implementation that caused random numbers not to use the full range of possible values
15+
16+
317
## [1.3.2]
418

519
This release fixes a performance regression found in release 1.3.1.

README.md

+13-3
Original file line numberDiff line numberDiff line change
@@ -165,9 +165,19 @@ To build `libaplcore.a` and tests in your favorite C++ environment, do the
165165
following:
166166

167167
```
168-
$ source apl-dev-env.sh
169-
$ apl-build-core
170-
$ apl-test-core
168+
source apl-dev-env.sh
169+
170+
# Build the library
171+
apl-build-core
172+
173+
# Run unit tests
174+
apl-test-core
175+
176+
# Generate code coverage
177+
apl-coverage-core
178+
179+
# Run memcheck
180+
apl-check-core
171181
```
172182

173183
# Building APL Core + Tests (Windows)

apl-dev-env.sh

+9
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,15 @@ function apl-test-core { # Run unit tests in the core build
126126
)
127127
}
128128

129+
function apl-memcheck-core { # Run unit tests in the core build
130+
(
131+
apl-switch-to-build-directory build $@ && \
132+
$CMAKE -DBUILD_TESTS=ON -DCOVERAGE=OFF .. && \
133+
make -j$APL_BUILD_PROCS && \
134+
valgrind --tool=memcheck --gen-suppressions=all --track-origins=yes --leak-check=full --num-callers=50 ./unit/unittest
135+
)
136+
}
137+
129138
function apl-coverage-core { # Generate and print coverage report
130139
(
131140
apl-switch-to-build-directory build $@ && \

aplcore/src/datasource/dynamicindexlistdatasourceprovider.cpp

+8-1
Original file line numberDiff line numberDiff line change
@@ -226,6 +226,13 @@ DynamicIndexListDataSourceConnection::processUpdate(DynamicIndexListUpdateType t
226226
<< " is dead while trying to process update.";
227227
return false;
228228
}
229+
230+
if (index < mMinimumInclusiveIndex) {
231+
provider->constructAndReportError(ERROR_REASON_LIST_INDEX_OUT_OF_RANGE,
232+
shared_from_this(), index,
233+
"Requested index out of bounds.");
234+
return false;
235+
}
229236
size_t idx = index - mMinimumInclusiveIndex;
230237

231238
auto context = mContext.lock();
@@ -758,4 +765,4 @@ DynamicIndexListDataSourceProvider::constructAndReportError(
758765
const Object& operationIndex,
759766
const std::string& message) {
760767
constructAndReportError(reason, connection->getListId(), connection->getListVersion(), operationIndex, message);
761-
}
768+
}

aplcore/src/primitives/functions.cpp

+9-5
Original file line numberDiff line numberDiff line change
@@ -14,17 +14,17 @@
1414
*/
1515

1616
#include <algorithm>
17-
#include <climits>
1817
#include <cmath>
1918
#ifdef APL_CORE_UWP
2019
#include <random>
2120
#endif
21+
#include <stdint.h>
2222
#include <stdlib.h>
2323

24+
#include "apl/engine/context.h"
2425
#include "apl/primitives/functions.h"
2526
#include "apl/primitives/object.h"
2627
#include "apl/primitives/timefunctions.h"
27-
#include "apl/engine/context.h"
2828
#include "apl/primitives/timegrammar.h"
2929

3030
namespace apl {
@@ -77,16 +77,20 @@ mathClamp(const std::vector<Object>& args)
7777
#ifdef APL_CORE_UWP
7878
static std::random_device random_device;
7979
static std::mt19937 generator(random_device());
80-
static unsigned long random() { return generator(); }
8180
#endif
8281

8382
static Object
8483
mathRandom(const std::vector<Object>& args)
8584
{
8685
#ifdef HAVE_DECL_ARC4RANDOM
87-
return arc4random() / ((double) ULONG_MAX);
86+
// By contract, arc4random can return any valid uint32_t value
87+
return arc4random() / ((double) UINT32_MAX);
88+
#elif APL_CORE_UWP
89+
// By contract, std::mt19937 returns values between 0 and mt19937::max()
90+
return generator() / ((double) std::mt19937::max());
8891
#else
89-
return ((unsigned long)random()) / ((double) ULONG_MAX);
92+
// By contract, random() returns values between 0 and RAND_MAX
93+
return random() / ((double) RAND_MAX);
9094
#endif
9195
}
9296

aplcore/src/primitives/radii.cpp

+2
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@
1313
* permissions and limitations under the License.
1414
*/
1515

16+
#include <string>
17+
1618
#include "apl/primitives/radii.h"
1719
#include "apl/utils/streamer.h"
1820

components.cmake

+6-1
Original file line numberDiff line numberDiff line change
@@ -80,11 +80,16 @@ endif(BUILD_DOC)
8080

8181
# Test cases are built conditionally. Only affect core do not build them for everything else.
8282
if (BUILD_TESTS)
83-
enable_testing()
83+
include(CTest)
8484
include_directories(${GTEST_INCLUDE})
8585
add_subdirectory(unit)
8686
add_subdirectory(test)
8787
if (TELEMETRY)
8888
add_subdirectory(performance)
8989
endif(TELEMETRY)
90+
set(MEMCHECK_OPTIONS "--tool=memcheck --leak-check=full --show-reachable=no --error-exitcode=1 --errors-for-leak-kinds=definite,possible")
91+
add_custom_target(unittest_memcheck
92+
COMMAND ${CMAKE_CTEST_COMMAND} -VV
93+
--overwrite MemoryCheckCommandOptions=${MEMCHECK_OPTIONS}
94+
-T memcheck)
9095
endif (BUILD_TESTS)

gcc.cmake

+4-4
Original file line numberDiff line numberDiff line change
@@ -25,18 +25,18 @@ if(COVERAGE)
2525

2626
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} --coverage -fprofile-arcs -ftest-coverage")
2727
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} --coverage -fprofile-arcs -ftest-coverage")
28-
set(COVERAGE_CLEANED "${coverage_info}.cleaned")
2928

3029
function(target_add_code_coverage EXEC_NAME TARGET_NAME)
3130
set(COVERAGE_INFO "${CMAKE_BINARY_DIR}/${TARGET_NAME}.info")
31+
set(COVERAGE_CLEANED "${COVERAGE_INFO}.cleaned")
3232

3333
add_custom_target(coverage-${TARGET_NAME}
3434
${LCOV_PATH} --directory . --zerocounters
3535
COMMAND $<TARGET_FILE:${EXEC_NAME}>
36-
COMMAND ${LCOV_PATH} --directory ${CMAKE_SOURCE_DIR} --capture --output-file ${COVERAGE_INFO}
37-
COMMAND ${LCOV_PATH} --remove ${COVERAGE_INFO} '**/unit/*' '/usr/*' '**/build/*' '**/thirdparty/*' --output-file ${COVERAGE_CLEANED}
36+
COMMAND ${LCOV_PATH} --directory ${CMAKE_BINARY_DIR} --capture --output-file ${COVERAGE_INFO}
37+
COMMAND ${LCOV_PATH} --remove ${COVERAGE_INFO} '**/unit/*' '/usr/*' '**/*build/*' '**/thirdparty/*' --output-file ${COVERAGE_CLEANED}
3838
COMMAND ${GENHTML_PATH} -o ${CMAKE_BINARY_DIR}/coverage ${COVERAGE_CLEANED}
39-
COMMAND ${CMAKE_COMMAND} -E remove ${COVERAGE_INFO} ${COVERAGE_CLEANED}
39+
COMMAND ${CMAKE_COMMAND} -E remove ${COVERAGE_INFO}
4040
DEPENDS ${TARGET_NAME} ${EXEC_NAME}
4141
)
4242
add_custom_command(TARGET coverage-${TARGET_NAME} POST_BUILD

thirdparty/thirdparty.cmake

-4
Original file line numberDiff line numberDiff line change
@@ -25,10 +25,6 @@ list(APPEND CMAKE_ARGS -DCMAKE_CXX_FLAGS=${EXT_CXX_ARGS})
2525
list(APPEND CMAKE_ARGS -DCMAKE_INSTALL_PREFIX=${CMAKE_BINARY_DIR}/lib)
2626
list(APPEND CMAKE_ARGS -DCMAKE_TOOLCHAIN_FILE=${CMAKE_TOOLCHAIN_FILE})
2727

28-
if("${CMAKE_CXX_COMPILER_ID}" MATCHES "MSVC")
29-
set(PATCH_FLAGS "--binary")
30-
endif()
31-
3228
ExternalProject_Add(yoga
3329
URL ${APL_PROJECT_DIR}/thirdparty/yoga-1.16.0.tar.gz
3430
URL_MD5 c9e88076ec371513fb23a0a5370ec2fd

unit/CMakeLists.txt

+13-3
Original file line numberDiff line numberDiff line change
@@ -107,9 +107,19 @@ add_executable( unittest
107107
add_subdirectory(${CMAKE_BINARY_DIR}/googletest-src
108108
${CMAKE_BINARY_DIR}/googletest-build
109109
EXCLUDE_FROM_ALL)
110-
111-
target_link_libraries(unittest apl gtest gtest_main)
112-
113110
if(COVERAGE)
114111
target_add_code_coverage(unittest apl)
115112
endif()
113+
target_link_libraries(unittest apl gtest gtest_main)
114+
if(CTEST_INDIVIDUALLY)
115+
# NOTE: discovered ctest targets below are much slower than their direct counterparts. Ctest loads
116+
# tests individually instead of just running all in a class. This makes it take much
117+
# longer for execution. This is somewhat useful if you want to execute tests using ctest scripts, but is
118+
# completely unusable on dev machine: each test takes 800ms vs 20ms, and valgrind takes 4-5s per test.
119+
include(GoogleTest)
120+
gtest_discover_tests(unittest)
121+
else()
122+
# Adds the entire unittest executable as a single ctest. Great for speed.
123+
add_test(all-tests unittest)
124+
endif()
125+

0 commit comments

Comments
 (0)