summaryrefslogtreecommitdiff
path: root/security/nss/tests/ssl_gtests/ssl_gtests.sh
blob: eef77f16f3411e6ec4e8972de9e27bff42786ef4 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
#!/bin/bash
#
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.

########################################################################
#
# tests/ssl_gtests/ssl_gtests.sh
#
# Script to drive the ssl gtest unit tests
#
# needs to work on all Unix and Windows platforms
#
# special strings
# ---------------
#   FIXME ... known problems, search for this string
#   NOTE .... unexpected behavior
#
########################################################################

# Generate input to certutil
certscript() {
  ca=n
  while [ $# -gt 0 ]; do
    case $1 in
      sign) echo 0 ;;
      kex) echo 2 ;;
      ca) echo 5;echo 6;ca=y ;;
    esac; shift
  done;
  echo 9
  echo n
  echo $ca
  echo
  echo n
}

# $1: name
# $2: type
# $3+: usages: sign or kex
make_cert() {
  name=$1
  type=$2
  unset type_args trust sign
  case $type in
    dsa) type_args='-g 1024' ;;
    rsa) type_args='-g 1024' ;;
    rsa2048) type_args='-g 2048';type=rsa ;;
    rsa8192) type_args='-g 8192';type=rsa ;;
    rsapss) type_args='-g 1024 --pss';type=rsa ;;
    p256) type_args='-q nistp256';type=ec ;;
    p384) type_args='-q secp384r1';type=ec ;;
    p521) type_args='-q secp521r1';type=ec ;;
    rsa_ca) type_args='-g 1024';trust='CT,CT,CT';type=rsa ;;
    rsa_chain) type_args='-g 1024';sign='-c rsa_ca';type=rsa;;
    rsapss_ca) type_args='-g 1024 --pss';trust='CT,CT,CT';type=rsa ;;
    rsapss_chain) type_args='-g 1024';sign='-c rsa_pss_ca';type=rsa;;
    rsa_ca_rsapss_chain) type_args='-g 1024 --pss-sign';sign='-c rsa_ca';type=rsa;;
    ecdh_rsa) type_args='-q nistp256';sign='-c rsa_ca';type=ec ;;
  esac
  shift 2
  counter=$(($counter + 1))
  certscript $@ | ${BINDIR}/certutil -S \
    -z ${R_NOISE_FILE} -d "${PROFILEDIR}" \
    -n $name -s "CN=$name" -t ${trust:-,,} ${sign:--x} -m $counter \
    -w -2 -v 120 -k $type $type_args -Z SHA256 -1 -2
  html_msg $? 0 "create certificate: $@"
}

ssl_gtest_certs() {
  mkdir -p "${SSLGTESTDIR}"
  cd "${SSLGTESTDIR}"

  PROFILEDIR=`pwd`
  if [ "${OS_ARCH}" = "WINNT" -a "$OS_NAME" = "CYGWIN_NT" ]; then
    PROFILEDIR=`cygpath -m "${PROFILEDIR}"`
  fi

  ${BINDIR}/certutil -N -d "${PROFILEDIR}" --empty-password 2>&1
  html_msg $? 0 "create ssl_gtest database"

  counter=0
  make_cert client rsa sign
  make_cert rsa rsa sign kex
  make_cert rsa2048 rsa2048 sign kex
  make_cert rsa8192 rsa8192 sign kex
  make_cert rsa_sign rsa sign
  make_cert rsa_pss rsapss sign
  make_cert rsa_decrypt rsa kex
  make_cert ecdsa256 p256 sign
  make_cert ecdsa384 p384 sign
  make_cert ecdsa521 p521 sign
  make_cert ecdh_ecdsa p256 kex
  make_cert rsa_ca rsa_ca ca
  make_cert rsa_chain rsa_chain sign
  make_cert rsa_pss_ca rsapss_ca ca
  make_cert rsa_pss_chain rsapss_chain sign
  make_cert rsa_ca_rsa_pss_chain rsa_ca_rsapss_chain sign
  make_cert ecdh_rsa ecdh_rsa kex
  make_cert dsa dsa sign
}

############################## ssl_gtest_init ##########################
# local shell function to initialize this script
########################################################################
ssl_gtest_init()
{
  SCRIPTNAME=ssl_gtest.sh      # sourced - $0 would point to all.sh

  if [ -z "${CLEANUP}" ] ; then     # if nobody else is responsible for
      CLEANUP="${SCRIPTNAME}"       # cleaning this script will do it
  fi
  if [ -z "${INIT_SOURCED}" -o "${INIT_SOURCED}" != "TRUE" ]; then
      cd ../common
      . ./init.sh
  fi

  SCRIPTNAME=ssl_gtest.sh
  html_head SSL Gtests

  if [ ! -d "${SSLGTESTDIR}" ]; then
    ssl_gtest_certs
  fi

  cd "${SSLGTESTDIR}"
}

########################## ssl_gtest_start #########################
# Local function to actually start the test
####################################################################
ssl_gtest_start()
{
  if [ ! -f ${BINDIR}/ssl_gtest ]; then
    html_unknown "Skipping ssl_gtest (not built)"
    return
  fi

  SSLGTESTREPORT="${SSLGTESTDIR}/report.xml"

  local nshards=1
  local prefix=""
  local postfix=""

  export -f parallel_fallback

  # Determine the number of chunks.
  if [ -n "$GTESTFILTER" ]; then
    echo "DEBUG: Not parallelizing ssl_gtests because \$GTESTFILTER is set"
  elif type parallel 2>/dev/null; then
    nshards=$(parallel --number-of-cores || 1)
  fi

  if [ "$nshards" != 1 ]; then
    local indices=$(for ((i=0; i<$nshards; i++)); do echo $i; done)
    prefix="parallel -j$nshards --line-buffer --halt soon,fail=1"
    postfix="\&\& exit 0 \|\| exit 1 ::: $indices"
  fi

  echo "DEBUG: ssl_gtests will be divided into $nshards chunk(s)"

  # Run tests.
  ${prefix:-parallel_fallback} \
    GTEST_SHARD_INDEX={} \
      GTEST_TOTAL_SHARDS=$nshards \
        DYLD_LIBRARY_PATH="${DIST}/${OBJDIR}/lib" \
          ${BINDIR}/ssl_gtest -d "${SSLGTESTDIR}" \
            --gtest_output=xml:"${SSLGTESTREPORT}.{}" \
            --gtest_filter="${GTESTFILTER-*}" \
            $postfix

  html_msg $? 0 "ssl_gtests ran successfully"

  # Parse XML report(s).
  if type xmllint &>/dev/null; then
    echo "DEBUG: Using xmllint to parse GTest XML report(s)"
    parse_report
  else
    echo "DEBUG: Falling back to legacy XML report parsing using only sed"
    parse_report_legacy
  fi
}

# Helper function used when 'parallel' isn't available.
parallel_fallback()
{
  eval "${@//\{\}/0}"
}

parse_report()
{
  # Check XML reports for normal test runs and failures.
  local successes=$(parse_report_xpath "//testcase[@status='run'][count(*)=0]")
  local failures=$(parse_report_xpath "//failure/..")

  # Print all tests that succeeded.
  while read result name; do
    html_passed_ignore_core "$name"
  done <<< "$successes"

  # Print failing tests.
  if [ -n "$failures" ]; then
    printf "\nFAILURES:\n=========\n"

    while read result name; do
      html_failed_ignore_core "$name"
    done <<< "$failures"

    printf "\n"
  fi
}

parse_report_xpath()
{
  # Query the XML report with the given XPath pattern.
  xmllint --xpath "$1" "${SSLGTESTREPORT}".* 2>/dev/null | \
    # Insert newlines to help sed.
    sed $'s/<testcase/\\\n<testcase/g' | \
    # Use sed to parse the report.
    sed -f "${COMMON}/parsegtestreport.sed"
}

# This legacy report parser can't actually detect failures. It always relied
# on the binary's exit code. Print the tests we ran to keep the old behavior.
parse_report_legacy()
{
  while read result name && [ -n "$name" ]; do
    if [ "$result" = "run" ]; then
      html_passed_ignore_core "$name"
    fi
  done <<< "$(sed -f "${COMMON}/parsegtestreport.sed" "${SSLGTESTREPORT}".*)"
}

ssl_gtest_cleanup()
{
  cd ${QADIR}
  . common/cleanup.sh
}

################## main #################################################
cd "$(dirname "$0")"
ssl_gtest_init
ssl_gtest_start
ssl_gtest_cleanup