1#!/bin/bash
2
3# Run all the different permutations of all the tests and other things
4# This helps ensure that nothing gets broken.
5
6_tests() {
7    local vet="" # TODO: make it off
8    local gover=$( go version | cut -f 3 -d ' ' )
9    # note that codecgen requires fastpath, so you cannot do "codecgen notfastpath"
10    local a=( "" "safe"  "notfastpath" "notfastpath safe" "codecgen" "codecgen safe" )
11    for i in "${a[@]}"
12    do
13        echo ">>>> TAGS: $i"
14        local i2=${i:-default}
15        case $gover in
16            go1.[0-6]*) go test ${zargs[*]} -tags "$i" "$@" ;;
17            *) go vet -printfuncs "errorf" "$@" &&
18                     go test ${zargs[*]} -vet "$vet" -tags "alltests $i" -run "Suite" -coverprofile "${i2// /-}.cov.out" "$@" ;;
19        esac
20        if [[ "$?" != 0 ]]; then return 1; fi
21    done
22    echo "++++++++ TEST SUITES ALL PASSED ++++++++"
23}
24
25
26# is a generation needed?
27_ng() {
28    local a="$1"
29    if [[ ! -e "$a" ]]; then echo 1; return; fi
30    for i in `ls -1 *.go.tmpl gen.go values_test.go`
31    do
32        if [[ "$a" -ot "$i" ]]; then echo 1; return; fi
33    done
34}
35
36_prependbt() {
37    cat > ${2} <<EOF
38// +build generated
39
40EOF
41    cat ${1} >> ${2}
42    rm -f ${1}
43}
44
45# _build generates fast-path.go and gen-helper.go.
46_build() {
47    if ! [[ "${zforce}" || $(_ng "fast-path.generated.go") || $(_ng "gen-helper.generated.go") || $(_ng "gen.generated.go") ]]; then return 0; fi
48
49    if [ "${zbak}" ]; then
50        _zts=`date '+%m%d%Y_%H%M%S'`
51        _gg=".generated.go"
52        [ -e "gen-helper${_gg}" ] && mv gen-helper${_gg} gen-helper${_gg}__${_zts}.bak
53        [ -e "fast-path${_gg}" ] && mv fast-path${_gg} fast-path${_gg}__${_zts}.bak
54        [ -e "gen${_gg}" ] && mv gen${_gg} gen${_gg}__${_zts}.bak
55    fi
56    rm -f gen-helper.generated.go fast-path.generated.go gen.generated.go \
57       *safe.generated.go *_generated_test.go *.generated_ffjson_expose.go
58
59    cat > gen.generated.go <<EOF
60// +build codecgen.exec
61
62// Copyright (c) 2012-2018 Ugorji Nwoke. All rights reserved.
63// Use of this source code is governed by a MIT license found in the LICENSE file.
64
65package codec
66
67// DO NOT EDIT. THIS FILE IS AUTO-GENERATED FROM gen-dec-(map|array).go.tmpl
68
69const genDecMapTmpl = \`
70EOF
71    cat >> gen.generated.go < gen-dec-map.go.tmpl
72    cat >> gen.generated.go <<EOF
73\`
74
75const genDecListTmpl = \`
76EOF
77    cat >> gen.generated.go < gen-dec-array.go.tmpl
78    cat >> gen.generated.go <<EOF
79\`
80
81const genEncChanTmpl = \`
82EOF
83    cat >> gen.generated.go < gen-enc-chan.go.tmpl
84    cat >> gen.generated.go <<EOF
85\`
86EOF
87    cat > gen-from-tmpl.codec.generated.go <<EOF
88package codec 
89import "io"
90func GenInternalGoFile(r io.Reader, w io.Writer) error {
91return genInternalGoFile(r, w)
92}
93EOF
94    cat > gen-from-tmpl.generated.go <<EOF
95//+build ignore
96
97package main
98
99import "${zpkg}"
100import "os"
101
102func run(fnameIn, fnameOut string) {
103println("____ " + fnameIn + " --> " + fnameOut + " ______")
104fin, err := os.Open(fnameIn)
105if err != nil { panic(err) }
106defer fin.Close()
107fout, err := os.Create(fnameOut)
108if err != nil { panic(err) }
109defer fout.Close()
110err = codec.GenInternalGoFile(fin, fout)
111if err != nil { panic(err) }
112}
113
114func main() {
115run("fast-path.go.tmpl", "fast-path.generated.go")
116run("gen-helper.go.tmpl", "gen-helper.generated.go")
117run("mammoth-test.go.tmpl", "mammoth_generated_test.go")
118run("mammoth2-test.go.tmpl", "mammoth2_generated_test.go")
119// run("sort-slice.go.tmpl", "sort-slice.generated.go")
120}
121EOF
122
123    sed -e 's+// __DO_NOT_REMOVE__NEEDED_FOR_REPLACING__IMPORT_PATH__FOR_CODEC_BENCH__+import . "github.com/ugorji/go/codec"+' \
124        shared_test.go > bench/shared_test.go
125
126    # explicitly return 0 if this passes, else return 1
127    go run -tags "prebuild" prebuild.go || return 1
128    go run -tags "notfastpath safe codecgen.exec" gen-from-tmpl.generated.go || return 1
129    rm -f gen-from-tmpl.*generated.go
130    return 0
131}
132
133_codegenerators() {
134    local c5="_generated_test.go"
135    local c7="$PWD/codecgen"
136    local c8="$c7/__codecgen"
137    local c9="codecgen-scratch.go"
138
139    if ! [[ $zforce || $(_ng "values_codecgen${c5}") ]]; then return 0; fi
140
141    # Note: ensure you run the codecgen for this codebase/directory i.e. ./codecgen/codecgen
142    true &&
143        echo "codecgen ... " &&
144        if [[ $zforce || ! -f "$c8" || "$c7/gen.go" -nt "$c8" ]]; then
145            echo "rebuilding codecgen ... " && ( cd codecgen && go build -o $c8 ${zargs[*]} . )
146        fi &&
147        $c8 -rt codecgen -t 'codecgen generated' -o values_codecgen${c5} -d 19780 $zfin $zfin2 &&
148        cp mammoth2_generated_test.go $c9 &&
149        $c8 -t 'codecgen,!notfastpath generated,!notfastpath' -o mammoth2_codecgen${c5} -d 19781 mammoth2_generated_test.go &&
150        rm -f $c9 &&
151        echo "generators done!"
152}
153
154_prebuild() {
155    echo "prebuild: zforce: $zforce"
156    local d="$PWD"
157    local zfin="test_values.generated.go"
158    local zfin2="test_values_flex.generated.go"
159    local zpkg="github.com/ugorji/go/codec"
160    # zpkg=${d##*/src/}
161    # zgobase=${d%%/src/*}
162    # rm -f *_generated_test.go
163    rm -f codecgen-*.go &&
164        _build &&
165        cp $d/values_test.go $d/$zfin &&
166        cp $d/values_flex_test.go $d/$zfin2 &&
167        _codegenerators &&
168        if [[ "$(type -t _codegenerators_external )" = "function" ]]; then _codegenerators_external ; fi &&
169        if [[ $zforce ]]; then go install ${zargs[*]} .; fi &&
170        echo "prebuild done successfully"
171    rm -f $d/$zfin $d/$zfin2
172    # unset zfin zfin2 zpkg
173}
174
175_make() {
176    local makeforce=${zforce}
177    zforce=1
178    (cd codecgen && go install ${zargs[*]} .) && _prebuild && go install ${zargs[*]} .
179    zforce=${makeforce}
180}
181
182_clean() {
183    rm -f gen-from-tmpl.*generated.go \
184       codecgen-*.go \
185       test_values.generated.go test_values_flex.generated.go
186}
187
188_release() {
189    local reply
190    read -p "Pre-release validation takes a few minutes and MUST be run from within GOPATH/src. Confirm y/n? " -n 1 -r reply
191    echo
192    if [[ ! $reply =~ ^[Yy]$ ]]; then return 1; fi
193
194    # expects GOROOT, GOROOT_BOOTSTRAP to have been set.
195    if [[ -z "${GOROOT// }" || -z "${GOROOT_BOOTSTRAP// }" ]]; then return 1; fi
196    # (cd $GOROOT && git checkout -f master && git pull && git reset --hard)
197    (cd $GOROOT && git pull)
198    local f=`pwd`/make.release.out
199    cat > $f <<EOF
200========== `date` ===========
201EOF
202    # # go 1.6 and below kept giving memory errors on Mac OS X during SDK build or go run execution,
203    # # that is fine, as we only explicitly test the last 3 releases and tip (2 years).
204    local makeforce=${zforce}
205    zforce=1
206    for i in 1.10 1.11 1.12 master
207    do
208        echo "*********** $i ***********" >>$f
209        if [[ "$i" != "master" ]]; then i="release-branch.go$i"; fi
210        (false ||
211             (echo "===== BUILDING GO SDK for branch: $i ... =====" &&
212                  cd $GOROOT &&
213                  git checkout -f $i && git reset --hard && git clean -f . &&
214                  cd src && ./make.bash >>$f 2>&1 && sleep 1 ) ) &&
215            echo "===== GO SDK BUILD DONE =====" &&
216            _prebuild &&
217            echo "===== PREBUILD DONE with exit: $? =====" &&
218            _tests "$@"
219        if [[ "$?" != 0 ]]; then return 1; fi
220    done
221    zforce=${makeforce}
222    echo "++++++++ RELEASE TEST SUITES ALL PASSED ++++++++"
223}
224
225_usage() {
226    cat <<EOF
227primary usage: $0 
228    -[tmpfxnld]           -> [tests, make, prebuild (force) (external), inlining diagnostics, mid-stack inlining, race detector]
229    -v                    -> verbose
230EOF
231    if [[ "$(type -t _usage_run)" = "function" ]]; then _usage_run ; fi
232}
233
234_main() {
235    if [[ -z "$1" ]]; then _usage; return 1; fi
236    local x
237    local zforce
238    local zargs=()
239    local zverbose=()
240    local zbenchflags=""
241    OPTIND=1
242    while getopts ":ctmnrgpfvlyzdb:" flag
243    do
244        case "x$flag" in
245            'xf') zforce=1 ;;
246            'xv') zverbose+=(1) ;;
247            'xl') zargs+=("-gcflags"); zargs+=("-l=4") ;;
248            'xn') zargs+=("-gcflags"); zargs+=("-m=2") ;;
249            'xd') zargs+=("-race") ;;
250            'xb') x='b'; zbenchflags=${OPTARG} ;;
251            x\?) _usage; return 1 ;;
252            *) x=$flag ;;
253        esac
254    done
255    shift $((OPTIND-1))
256    # echo ">>>> _main: extra args: $@"
257    case "x$x" in
258        'xt') _tests "$@" ;;
259        'xm') _make "$@" ;;
260        'xr') _release "$@" ;;
261        'xg') _go ;;
262        'xp') _prebuild "$@" ;;
263        'xc') _clean "$@" ;;
264        'xy') _analyze_extra "$@" ;;
265        'xz') _analyze "$@" ;;
266        'xb') _bench "$@" ;;
267    esac
268    # unset zforce zargs zbenchflags
269}
270
271[ "." = `dirname $0` ] && _main "$@"
272
273