github.com/hugh712/snapd@v0.0.0-20200910133618-1a99902bd583/run-checks (about)

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