github.com/ethanhsieh/snapd@v0.0.0-20210615102523-3db9b8e4edc5/run-checks (about)

     1  #!/bin/sh -eu
     2  
     3  export LANG=C.UTF-8
     4  export LANGUAGE=en
     5  
     6  if command -v goctest >/dev/null; then
     7      goctest="goctest"
     8  else
     9      goctest="go test"
    10  fi
    11  COVERMODE=${COVERMODE:-atomic}
    12  
    13  if [ -z "${GITHUB_WORKFLOW:-}" ]; then
    14      # when *not* running inside github, ensure we use go-1.10 by default
    15      export PATH=/usr/lib/go-1.10/bin:${PATH}
    16  fi
    17  
    18  # add workaround for https://github.com/golang/go/issues/24449
    19  if [ "$(uname -m)" = "s390x" ]; then
    20      if go version | grep -q go1.10; then
    21          echo "covermode 'atomic' crashes on s390x with go1.10, reseting "
    22          echo "to 'set'. see https://github.com/golang/go/issues/24449"
    23          COVERMODE="set"
    24      fi
    25  fi
    26  
    27  export GOPATH="${GOPATH:-$(realpath "$(dirname "$0")"/../../../../)}"
    28  export PATH="$PATH:${GOPATH%%:*}/bin"
    29  
    30  short=
    31  
    32  STATIC=
    33  UNIT=
    34  
    35  case "${1:-all}" in
    36      all)
    37          STATIC=1
    38          UNIT=1
    39          ;;
    40      --static)
    41          STATIC=1
    42          ;;
    43      --unit)
    44          UNIT=1
    45          ;;
    46      --short-unit)
    47          UNIT=1
    48          short=1
    49          ;;
    50      *)
    51          echo "Wrong flag ${1}. To run a single suite use --static, --unit, --spread."
    52          exit 1
    53  esac
    54  
    55  CURRENTTRAP="true"
    56  EXIT_CODE=99
    57  
    58  store_exit_code() {
    59      EXIT_CODE=$?
    60  }
    61  
    62  exit_with_exit_code() {
    63      exit $EXIT_CODE
    64  }
    65  
    66  addtrap() {
    67      CURRENTTRAP="$CURRENTTRAP ; $1"
    68      # shellcheck disable=SC2064
    69      trap "store_exit_code; $CURRENTTRAP ; exit_with_exit_code" EXIT
    70  }
    71  
    72  endmsg() {
    73      if [ $EXIT_CODE -eq 0 ]; then
    74          p="success.txt"
    75          m="All good, what could possibly go wrong."
    76      else
    77          p="failure.txt"
    78          m="Crushing failure and despair."
    79      fi
    80      echo
    81      if [ -t 1 ] && [ -z "$STATIC" ]; then
    82          cat "data/$p"
    83      else
    84          echo "$m"
    85      fi
    86  }
    87  addtrap endmsg
    88  
    89  # Append the coverage profile of a package to the project coverage.
    90  append_coverage() (
    91      profile="$1"
    92      if [ -f "$profile" ]; then
    93          grep -v "^mode:" -- "$profile" >> .coverage/coverage.out || true
    94          rm "$profile"
    95      fi
    96  )
    97  
    98  missing_interface_spread_test() {
    99      snap_yaml="tests/lib/snaps/test-snapd-policy-app-consumer/meta/snap.yaml"
   100      core_snap_yaml="tests/lib/snaps/test-snapd-policy-app-provider-core/meta/snap.yaml"
   101      classic_snap_yaml="tests/lib/snaps/test-snapd-policy-app-provider-classic/meta/snap.yaml"
   102      for iface in $(go run ./tests/lib/list-interfaces.go) ; do
   103          search="plugs: \\[ $iface \\]"
   104          case "$iface" in
   105              bool-file|gpio|pwm|dsp|netlink-driver|hidraw|i2c|iio|serial-port|spi)
   106                  # skip gadget provided interfaces for now
   107                  continue
   108                  ;;
   109              dbus|content)
   110                  search="interface: $iface"
   111                  ;;
   112              autopilot)
   113                  search='plugs: \[ autopilot-introspection \]'
   114                  ;;
   115          esac
   116          if ! grep -q "$search" "$snap_yaml" ; then
   117              echo "Missing high-level test for interface '$iface'. Please add to:"
   118              echo "* $snap_yaml"
   119              echo "* $core_snap_yaml (if needed)"
   120              echo "* $classic_snap_yaml (if needed)"
   121              exit 1
   122          fi
   123      done
   124  }
   125  
   126  
   127  if [ "$STATIC" = 1 ]; then
   128      ./get-deps.sh
   129  
   130      # Run static tests.
   131      echo Checking docs
   132      ./mdlint.py ./*.md docs/*.md
   133  
   134      # XXX: remove once we can use an action, see workflows/test.yaml for
   135      #      details why we still use this script
   136      if [ -n "${TRAVIS_PULL_REQUEST:-}" ] && [ "${TRAVIS_PULL_REQUEST:-}" != "false" ]; then
   137          echo Checking pull request summary
   138          ./check-pr-title.py "$TRAVIS_PULL_REQUEST"
   139      fi
   140  
   141      if [ -z "${SKIP_GOFMT:-}" ]; then
   142          echo Checking formatting
   143          fmt=""
   144          for dir in $(go list -f '{{.Dir}}' ./... | grep -v '/vendor/' | grep -E 'snapd/[A-Za-z0-9_]+$' ); do
   145              # skip vendor packages
   146              # skip subpackages of packages under snapd, gofmt already inspects them
   147              s="$(${GOFMT:-gofmt} -s -l -d "$dir" || true)"
   148              if [ -n "$s" ]; then
   149                  fmt="$s\\n$fmt"
   150              fi
   151          done
   152          if [ -n "$fmt" ]; then
   153              echo "Formatting wrong in following files:"
   154              # shellcheck disable=SC2001
   155              echo "$fmt" | sed -e 's/\\n/\n/g'
   156              exit 1
   157          fi
   158      fi
   159  
   160      # go vet
   161      echo Running vet
   162      go list ./... | grep -v '/vendor/' | xargs go vet
   163  
   164      echo 'Checking for usages of http.Status*'
   165      got=""
   166      for dir in $(go list -f '{{.Dir}}' ./... | grep -v '/vendor/' ); do
   167          s="$(grep -nP 'http\.Status(?!Text)' "$dir"/*.go || true)"
   168          if [ -n "$s" ]; then
   169              got="$s\\n$got"
   170          fi
   171      done
   172  
   173      if [ -n "$got" ]; then
   174          echo 'Usages of http.Status*, we prefer the numeric values directly:'
   175          echo "$got"
   176          exit 1
   177      fi
   178  
   179      echo "Checking for direct usages of math/rand"
   180      got=""
   181      for dir in $(go list -f '{{.Dir}}' ./... | grep -v '/vendor/' ); do
   182          # shellcheck disable=SC2063
   183          s="$(grep -nP --exclude '*_test.go' --exclude 'randutil/*.go' math/rand "$dir"/*.go || true)"
   184          if [ -n "$s" ]; then
   185              got="$s\\n$got"
   186          fi
   187      done
   188  
   189      if [ -n "$got" ]; then
   190          echo 'Direct usages of math/rand, we prefer randutil:'
   191          echo "$got"
   192          exit 1
   193      fi
   194  
   195      if command -v shellcheck >/dev/null; then
   196          echo Checking shell scripts...
   197          ( git ls-files -z 2>/dev/null ||
   198                  find . \( -name .git -o -name vendor \) -prune -o -print0 ) |
   199              xargs -0 file -N |
   200              awk -F": " '$2~/shell.script/{print $1}' |
   201              xargs shellcheck -x
   202          regexp='GOPATH(?!%%:\*)(?!:)[^= ]*/'
   203          if  grep -qPr                   --exclude HACKING.md --exclude 'Makefile.*' --exclude-dir .git --exclude-dir vendor "$regexp"; then
   204              echo "Using GOPATH as if it were a single entry and not a list:"
   205              grep -PHrn -C1 --color=auto --exclude HACKING.md --exclude 'Makefile.*' --exclude-dir .git --exclude-dir vendor "$regexp"
   206              echo "Use GOHOME, or {GOPATH%%:*}, instead."
   207              exit 1
   208          fi
   209          unset regexp
   210          # also run spread-shellcheck
   211          ./spread-shellcheck spread.yaml tests
   212      fi
   213  
   214      echo "Checking spelling errors"
   215      if ! command -v misspell >/dev/null; then
   216          go get -u github.com/client9/misspell/cmd/misspell
   217      fi
   218      # FIXME: auter is only misspelled in the changelog so we should fix there
   219      # PROCES is used in the seccomp tests (PRIO_PROCES{,S,SS})
   220      # exportfs is used in the nfs-support test
   221      MISSPELL_IGNORE="auther,PROCES,PROCESSS,proces,processs,exportfs"
   222      git ls-files -z -- . ':!:./po' ':!:./vendor' |
   223          xargs -0 misspell -error -i "$MISSPELL_IGNORE"
   224  
   225      if dpkg --compare-versions "$(go version | awk '$3 ~ /^go[0-9]/ {print substr($3, 3)}')" ge 1.12; then
   226          echo "Checking for ineffective assignments"
   227          if ! command -v ineffassign >/dev/null; then
   228              go get -u github.com/gordonklaus/ineffassign
   229          fi
   230          # ineffassign knows about ignoring vendor/ \o/
   231          ineffassign ./...
   232      fi
   233  
   234      echo "Checking for naked returns"
   235      if ! command -v nakedret >/dev/null; then
   236          go get -u github.com/alexkohler/nakedret
   237      fi
   238      got=$(go list ./... | grep -v '/osutil/udev/' | grep -v '/vendor/' | xargs nakedret 2>&1)
   239      if [ -n "$got" ]; then
   240          echo "$got"
   241          if [ -z "${SKIP_NAKEDRET:-}" ]; then
   242              exit 1
   243          else
   244              echo "Ignoring nakedret errors as requested"
   245          fi
   246      fi
   247  
   248      echo "Checking all interfaces have minimal spread test"
   249      missing_interface_spread_test
   250  
   251      echo "Checking for incorrect multiline strings in spread tests"
   252      badmultiline=$(find tests -name 'task.yaml' -print0 -o -name 'spread.yaml' -print0 | \
   253                         xargs -0 grep -R -n -E '(restore*|prepare*|execute|debug):\s*$' || true)
   254      if [ -n "$badmultiline" ]; then
   255          echo "Incorrect multiline strings at the following locations:"
   256          echo "$badmultiline"
   257          exit 1
   258      fi
   259  
   260      echo "Checking for potentially incorrect use of MATCH -v"
   261      badMATCH=$(find tests -name 'task.yaml' -print0 -o -name 'spread.yaml' -print0 | \
   262                         xargs -0 grep -R -n -E 'MATCH +-v' || true)
   263      if [ -n "$badMATCH" ]; then
   264          echo "Potentially incorrect use of MATCH -v at the following locations:"
   265          echo "$badMATCH"
   266          exit 1
   267      fi
   268  
   269      # FIXME: re-add staticcheck with a matching version for the used go-version
   270  
   271      if [ -z "${SKIP_TESTS_FORMAT_CHECK-}" ] || [ "$SKIP_TESTS_FORMAT_CHECK" = 0 ]; then
   272          echo "Checking tests formatting"
   273          ./tests/utils/check-test-format ./tests
   274      fi
   275  fi
   276  
   277  if [ "$UNIT" = 1 ]; then
   278      ./get-deps.sh
   279  
   280      echo "Show go version"
   281      command -v go
   282      go version
   283  
   284      tags=
   285      if [ -n "${GO_BUILD_TAGS-}" ]; then
   286          echo "Using build tags: $GO_BUILD_TAGS"
   287          tags="-tags $GO_BUILD_TAGS"
   288      fi
   289  
   290      echo Building
   291      # shellcheck disable=SC2086
   292      go build -v $tags github.com/snapcore/snapd/...
   293  
   294      # tests
   295      echo Running tests from "$PWD"
   296      if [ "$short" = 1 ]; then
   297              # shellcheck disable=SC2046,SC2086
   298              GOTRACEBACK=1 $goctest $tags -short -timeout 5m $(go list ./... | grep -v '/vendor/' )
   299      else
   300          coverage=""
   301          if [ -z "${SKIP_COVERAGE-}" ]; then
   302              coverage="-coverprofile=.coverage/coverage.out -covermode=$COVERMODE"
   303              # Prepare the coverage output profile.
   304              rm -rf .coverage
   305              mkdir .coverage
   306              echo "mode: $COVERMODE" > .coverage/coverage.out
   307          else
   308              echo "Skipping test coverage"
   309          fi
   310  
   311          if command -v dpkg >/dev/null && dpkg --compare-versions "$(go version | awk '$3 ~ /^go[0-9]/ {print substr($3, 3)}')" ge 1.10; then
   312              # shellcheck disable=SC2046,SC2086
   313              GOTRACEBACK=1 $goctest $tags -timeout 5m $coverage $(go list ./... | grep -v '/vendor/' )
   314          else
   315              for pkg in $(go list ./... | grep -v '/vendor/' ); do
   316                  # shellcheck disable=SC2086
   317                  GOTRACEBACK=1 go test $tags -timeout 5m -i "$pkg"
   318                  if [ -z "${SKIP_COVERAGE-}" ]; then
   319                      # shellcheck disable=SC2086
   320                      GOTRACEBACK=1 $goctest $tags -timeout 5m $coverage "$pkg"
   321                      append_coverage .coverage/profile.out
   322                  fi
   323              done
   324          fi
   325      fi
   326  
   327      # python unit test for mountinfo.query and version-compare
   328      command -v python2 && python2 ./tests/lib/tools/mountinfo.query --run-unit-tests
   329      command -v python3 && python3 ./tests/lib/tools/mountinfo.query --run-unit-tests
   330      command -v python2 && python2 ./tests/lib/tools/version-compare --run-unit-tests
   331      command -v python3 && python3 ./tests/lib/tools/version-compare --run-unit-tests
   332  fi
   333  
   334  UNCLEAN="$(git status -s|grep '^??')" || true
   335  SKIP_UNCLEAN=${SKIP_UNCLEAN=}
   336  if [ -n "$UNCLEAN" ] && [ -z "$SKIP_UNCLEAN" ]; then
   337      cat <<EOF
   338  
   339  There are files left in the git tree after the tests:
   340  
   341  $UNCLEAN
   342  EOF
   343      exit 1
   344  fi
   345  
   346  if [ -n "${SKIP_DIRTY_CHECK-}" ]; then
   347      exit 0
   348  fi
   349  
   350  if git describe --always --dirty | grep -q dirty; then
   351      echo "Build tree is dirty"
   352      git diff
   353      exit 1
   354  fi