1#!/usr/bin/env bash
2
3#############################################################################
4#
5# This is a test script that can be used on some Linux/Unix/Apple machines to
6# automate testing of the shared object to ensure linking and symbols don't go
7# missing from release to release.
8#
9# Written and placed in public domain by Jeffrey Walton and Uri Blumenthal.
10#
11# Crypto++ Library is copyrighted as a compilation and (as of version 5.6.2)
12# licensed under the Boost Software License 1.0, while the individual files
13# in the compilation are all public domain.
14#
15# See http://www.cryptopp.com/wiki/Android.mk_(Command_Line) for more details
16#
17#############################################################################
18
19#############################################################################
20# Tags to test
21
22OLD_VERSION_TAG=CRYPTOPP_8_3_0
23NEW_VERSION_TAG=master
24
25#############################################################################
26# If local repo is dirty, then promt first
27
28DIRTY=$(git diff --shortstat 2> /dev/null | tail -1)
29if [[ ! -z "$DIRTY" ]]; then
30
31	echo
32	echo "The local repo is dirty. Continuing will reset the repo and lose changes."
33	read -p "Type 'Y' to proceed or 'N' to exit. Proceed? " -n 1 -r
34	echo # (optional) move to a new line
35	if [[ !($REPLY =~ ^[Yy]$) ]]; then
36		exit 0
37	fi
38else
39	echo
40	echo "The local repo is clean. Proceeding..."
41fi
42
43#############################################################################
44
45echo
46echo "****************************************************************"
47echo "Testing '$NEW_VERSION_TAG' against '$OLD_VERSION_TAG'"
48echo "****************************************************************"
49
50#############################################################################
51# Setup tools and platforms
52
53GREP=grep
54EGREP=egrep
55SED=sed
56AWK=awk
57CXXFILT=c++filt
58
59THIS_SYSTEM=$(uname -s 2>&1)
60IS_DARWIN=$("${GREP}" -i -c darwin <<< "${THIS_SYSTEM}")
61IS_LINUX=$("${GREP}" -i -c linux <<< "${THIS_SYSTEM}")
62IS_CYGWIN=$("${GREP}" -i -c cygwin <<< "${THIS_SYSTEM}")
63IS_MINGW=$("${GREP}" -i -c mingw <<< "${THIS_SYSTEM}")
64IS_OPENBSD=$("${GREP}" -i -c openbsd <<< "${THIS_SYSTEM}")
65IS_FREEBSD=$("${GREP}" -i -c freebsd <<< "${THIS_SYSTEM}")
66IS_NETBSD=$("${GREP}" -i -c netbsd <<< "${THIS_SYSTEM}")
67IS_SOLARIS=$("${GREP}" -i -c sunos <<< "${THIS_SYSTEM}")
68
69THIS_MACHINE=$(uname -m 2>&1)
70IS_X86=$("${EGREP}" -i -c 'i386|i486|i586|i686' <<< "${THIS_MACHINE}")
71IS_X64=$("${EGREP}" -i -c "amd64|x86_64" <<< "${THIS_MACHINE}")
72IS_PPC32=$("${EGREP}" -i -c "PowerPC|PPC" <<< "${THIS_MACHINE}")
73IS_PPC64=$("${EGREP}" -i -c "PowerPC64|PPC64" <<< "${THIS_MACHINE}")
74IS_ARM32=$("${EGREP}" -i -c "arm|aarch32" <<< "${THIS_MACHINE}")
75IS_ARMV8=$("${EGREP}" -i -c "arm64|aarch64" <<< "${THIS_MACHINE}")
76IS_S390=$("${EGREP}" -i -c "s390" <<< "${THIS_MACHINE}")
77
78if [[ "${IS_X64}" -eq 1 ]]; then IS_X86=0; fi
79if [[ "${IS_ARMV8}" -eq 1 ]]; then IS_ARM32=0; fi
80if [[ "${IS_PPC64}" -eq 1 ]]; then IS_PPC32=0; fi
81
82# Fixup
83if [[ "$IS_FREEBSD" -ne "0" || "$IS_OPENBSD" -ne "0" || "$IS_NETBSD" -ne "0" ]]; then
84	MAKE=gmake
85elif [[ "$IS_SOLARIS" -ne "0" ]]; then
86	MAKE=$(command -v gmake 2>/dev/null | "${GREP}" -v "no gmake" | head -1)
87	if [[ -z "$MAKE" && -e "/usr/sfw/bin/gmake" ]]; then
88		MAKE=/usr/sfw/bin/gmake
89	fi
90else
91	MAKE=make
92fi
93
94if [[ "$IS_DARWIN" -ne "0" ]]; then
95	LINK_LIBRARY=libcryptopp.dylib
96else
97	LINK_LIBRARY=libcryptopp.so
98fi
99
100if [[ -z "${CXX}" ]]; then CXX=c++; fi
101
102SUN_COMPILER=$("${CXX}" -V 2>&1 | "${EGREP}" -i -c "CC: (Sun|Studio)")
103GCC_COMPILER=$("${CXX}" --version 2>&1 | "${EGREP}" -i -c "^(gcc|g\+\+)")
104INTEL_COMPILER=$("${CXX}" --version 2>&1 | "${GREP}" -i -c "icc")
105MACPORTS_COMPILER=$("${CXX}" --version 2>&1 | "${GREP}" -i -c "MacPorts")
106CLANG_COMPILER=$("${CXX}" --version 2>&1 | "${GREP}" -i -c "clang")
107
108#############################################################################
109
110# CPU is logical count, memory is in MiB. Low resource boards have
111#   fewer than 4 cores and 1GB or less memory. We use this to
112#   determine if we can build in parallel without an OOM kill.
113CPU_COUNT=1
114MEM_SIZE=512
115
116if [[ -e "/proc/cpuinfo" && -e "/proc/meminfo" ]]; then
117	CPU_COUNT=$(cat /proc/cpuinfo | "${GREP}" -c '^processor')
118	MEM_SIZE=$(cat /proc/meminfo | "${GREP}" "MemTotal" | "${AWK}" '{print $2}')
119	MEM_SIZE=$(($MEM_SIZE/1024))
120elif [[ "$IS_DARWIN" -ne "0" ]]; then
121	CPU_COUNT=$(sysctl -a 2>&1 | "${GREP}" 'hw.availcpu' | "${AWK}" '{print $3; exit}')
122	MEM_SIZE=$(sysctl -a 2>&1 | "${GREP}" 'hw.memsize' | "${AWK}" '{print $3; exit;}')
123	MEM_SIZE=$(($MEM_SIZE/1024/1024))
124elif [[ "$IS_SOLARIS" -ne "0" ]]; then
125	CPU_COUNT=$(psrinfo 2>/dev/null | wc -l | "${AWK}" '{print $1}')
126	MEM_SIZE=$(prtconf 2>/dev/null | "${GREP}" Memory | "${AWK}" '{print $3}')
127fi
128
129# Some ARM devboards cannot use 'make -j N', even with multiple cores and RAM
130#  An 8-core Cubietruck Plus with 2GB RAM experiences OOM kills with '-j 2'.
131HAVE_SWAP=1
132if [[ "$IS_LINUX" -ne "0" ]]; then
133	if [[ -e "/proc/meminfo" ]]; then
134		SWAP_SIZE=$(cat /proc/meminfo | "${GREP}" "SwapTotal" | "${AWK}" '{print $2}')
135		if [[ "$SWAP_SIZE" -eq "0" ]]; then
136			HAVE_SWAP=0
137		fi
138	else
139		HAVE_SWAP=0
140	fi
141fi
142
143if [[ "$CPU_COUNT" -ge "2" && "$MEM_SIZE" -ge "1280" && "$HAVE_SWAP" -ne "0" ]]; then
144	MAKEARGS=(-j "$CPU_COUNT")
145fi
146
147#############################################################################
148#############################################################################
149
150"${MAKE}" distclean &>/dev/null && cleanup &>/dev/null
151git checkout master -f &>/dev/null
152git checkout "$OLD_VERSION_TAG" -f &>/dev/null
153
154if [[ "$?" -ne "0" ]]; then
155	echo "Failed to checkout $OLD_VERSION_TAG"
156	exit 1
157fi
158
159echo
160echo "****************************************************************"
161echo "Building dynamic library for $OLD_VERSION_TAG"
162echo "****************************************************************"
163echo
164
165LINK_LIBRARY="$LINK_LIBRARY" "$MAKE" "${MAKEARGS[@]}" -f GNUmakefile cryptest.exe dynamic
166
167if [[ ! -f "$LINK_LIBRARY" ]]; then
168	echo "Failed to make $OLD_VERSION_TAG library"
169	exit 1
170fi
171
172echo
173echo "****************************************************************"
174echo "Running $OLD_VERSION_TAG cryptest.exe using $OLD_VERSION_TAG library"
175echo "****************************************************************"
176echo
177
178if [[ "$IS_DARWIN" -ne "0" ]]; then
179	DYLD_LIBRARY_PATH="$PWD:$DYLD_LIBRARY_PATH" ./cryptest.exe v 2>&1 | "$CXXFILT"
180	DYLD_LIBRARY_PATH="$PWD:$DYLD_LIBRARY_PATH" ./cryptest.exe tv all 2>&1 | "$CXXFILT"
181else
182	LD_LIBRARY_PATH="$PWD:$LD_LIBRARY_PATH" ./cryptest.exe v 2>&1 | "$CXXFILT"
183	LD_LIBRARY_PATH="$PWD:$LD_LIBRARY_PATH" ./cryptest.exe tv all 2>&1 | "$CXXFILT"
184fi
185
186# Stash away old cryptest.exe
187cp cryptest.exe cryptest.exe.saved
188
189echo
190echo "****************************************************************"
191echo "Building dynamic library for $NEW_VERSION_TAG"
192echo "****************************************************************"
193echo
194
195"${MAKE}" distclean &>/dev/null && cleanup &>/dev/null
196git checkout master -f &>/dev/null
197git checkout "$NEW_VERSION_TAG" -f &>/dev/null
198
199LINK_LIBRARY="$LINK_LIBRARY" "$MAKE" "${MAKEARGS[@]}" -f GNUmakefile cryptest.exe dynamic
200
201if [[ ! -f "$LINK_LIBRARY" ]]; then
202	echo "Failed to make $NEW_VERSION_TAG library"
203	exit 1
204fi
205
206# Fetch old cryptest.exe
207cp cryptest.exe.saved cryptest.exe
208
209echo
210echo "****************************************************************"
211echo "Running $OLD_VERSION_TAG cryptest.exe using $NEW_VERSION_TAG library"
212echo "****************************************************************"
213echo
214
215if [[ "$IS_DARWIN" -ne "0" ]]; then
216	DYLD_LIBRARY_PATH="$PWD:$DYLD_LIBRARY_PATH" ./cryptest.exe v 2>&1 | "$CXXFILT"
217	DYLD_LIBRARY_PATH="$PWD:$DYLD_LIBRARY_PATH" ./cryptest.exe tv all 2>&1 | "$CXXFILT"
218else
219	LD_LIBRARY_PATH="$PWD:$LD_LIBRARY_PATH" ./cryptest.exe v 2>&1 | "$CXXFILT"
220	LD_LIBRARY_PATH="$PWD:$LD_LIBRARY_PATH" ./cryptest.exe tv all 2>&1 | "$CXXFILT"
221fi
222
223"${MAKE}" distclean &>/dev/null && cleanup &>/dev/null
224git checkout master -f &>/dev/null
225
226exit 0
227