Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .github/workflows/go.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,6 @@ jobs:
- name: Unit Tests (Windows)
if: runner.os == 'Windows'
run: ./bin/test-unit.ps1
- name: Unit Tests (Linux)
if: runner.os == 'Linux'
- name: Unit Tests (Linux/macOS)
if: runner.os != 'Windows'
run: ./bin/test-unit
15 changes: 7 additions & 8 deletions bin/build
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
#!/bin/bash
#!/usr/bin/env bash
set -eu -o pipefail

set -e
ROOT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )/.." && pwd )"

bin=$(dirname $0)
(
cd "${ROOT_DIR}"

if [[ "$GOOS" == 'linux' ]] && [[ "$GOARCH" == 'amd64' ]]; then
export GOTOOLDIR=$(go env GOROOT)/pkg/linux_amd64
fi

CGO_ENABLED=0 go build -o $bin/../out/verify-multidigest github.com/cloudfoundry/bosh-utils/main
CGO_ENABLED=0 go build -o out/verify-multidigest github.com/cloudfoundry/bosh-utils/main
)
8 changes: 4 additions & 4 deletions bin/build-linux-amd64
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
#!/bin/bash
#!/usr/bin/env bash
set -eu -o pipefail

set -e
ROOT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )/.." && pwd )"

export GOARCH=amd64
export GOOS=linux
export GOTOOLDIR=$(go env GOROOT)/pkg/linux_amd64

$(dirname $0)/build
"${ROOT_DIR}/bin/build"
23 changes: 23 additions & 0 deletions bin/lint
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
#!/usr/bin/env bash
set -eu -o pipefail

ROOT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )/.." && pwd )"

go_bin_path="$(go env GOBIN)"
export PATH=${go_bin_path}:${PATH}
(
cd "${ROOT_DIR}"
if ! command -v golangci-lint &> /dev/null; then
echo "Installing golangci-lint@latest..."
go install github.com/golangci/golangci-lint/v2/cmd/golangci-lint@latest

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this worth pinning to a version to avoid changes to linting causing unexpected failures

fi

golangci-lint version
Comment thread
aramprice marked this conversation as resolved.

linted_os_list=(linux windows)

for os in "${linted_os_list[@]}"; do
echo "lint-ing with GOOS=${os}..."
GOOS="${os}" golangci-lint run ./...
done
)
10 changes: 0 additions & 10 deletions bin/test

This file was deleted.

11 changes: 7 additions & 4 deletions bin/test-unit
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
#!/bin/bash
#!/usr/bin/env bash
set -eu -o pipefail

set -e
bin=$(dirname $0)
ROOT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )/.." && pwd )"

echo -e "\n Testing packages..."
go run github.com/onsi/ginkgo/v2/ginkgo run -p -r --race --trace --keep-going "${@}"
(
cd "${ROOT_DIR}"
go run github.com/onsi/ginkgo/v2/ginkgo run -p -r --race --trace --keep-going ${1+"${@}"}
)
9 changes: 9 additions & 0 deletions ci/pipeline.yml
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,16 @@ jobs:
GOOS_LIST: linux,windows
GOPROXY: ((repository_mirrors.goproxy))
GOSUMDB: ((repository_mirrors.gosumdb))
BUMP_TEST_DEPS: linux,windows
- in_parallel:
- task: lint
input_mapping:
bosh-utils: bumped-bosh-utils
file: bosh-utils/ci/tasks/lint.yml
image: bosh-utils-registry-image
Comment thread
aramprice marked this conversation as resolved.
params:
GOPROXY: ((repository_mirrors.goproxy))
GOSUMDB: ((repository_mirrors.gosumdb))
- task: test-unit
input_mapping:
bosh-utils: bumped-bosh-utils
Expand Down
6 changes: 6 additions & 0 deletions ci/tasks/lint.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
#!/usr/bin/env bash

set -ex

cd bosh-utils
bin/lint
8 changes: 8 additions & 0 deletions ci/tasks/lint.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
---
platform: linux

inputs:
- name: bosh-utils

run:
path: bosh-utils/ci/tasks/lint.sh
2 changes: 2 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -37,3 +37,5 @@ require (
google.golang.org/protobuf v1.36.7 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)

tool github.com/maxbrunsfeld/counterfeiter/v6
98 changes: 46 additions & 52 deletions logger/async_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import (
. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"

. "github.com/cloudfoundry/bosh-utils/logger"
"github.com/cloudfoundry/bosh-utils/logger"
)

type intervalWriter struct {
Expand Down Expand Up @@ -52,33 +52,27 @@ func (w *blockingWriter) String() string {
}

var _ = Describe("Logger", func() {
var (
outBuf = new(bytes.Buffer)
)
BeforeEach(func() {
outBuf.Reset()
})

Describe("Async Logger", func() {
It("logs the formatted message to Logger.err at the debug level", func() {
logger := NewAsyncWriterLogger(LevelDebug, outBuf)
logger.Debug("TAG", "some %s info to log", "awesome")
logger.Flush()
out := new(bytes.Buffer)
asyncWriterLogger := logger.NewAsyncWriterLogger(logger.LevelDebug, out)
asyncWriterLogger.Debug("TAG", "some %s info to log", "awesome")
asyncWriterLogger.Flush()

expectedContent := expectedLogFormat("TAG", "DEBUG - some awesome info to log")
Expect(outBuf).To(MatchRegexp(expectedContent))
Expect(out).To(MatchRegexp(expectedContent))
})

It("does not block when its writer is blocked", func() {
out := new(blockingWriter)
logger := NewAsyncWriterLogger(LevelDebug, out)
asyncWriterLogger := logger.NewAsyncWriterLogger(logger.LevelDebug, out)

out.Lock()
ch := make(chan struct{}, 1)
go func() {
for i := 0; i < 10; i++ {
logger.Info("TAG", "Make sure we are not just buffering bytes: %s", strings.Repeat("A", 4096))
logger.Error("TAG", "Make sure we are not just buffering bytes: %s", strings.Repeat("A", 4096))
for range 10 {
asyncWriterLogger.Info("TAG", "Make sure we are not just buffering bytes: %s", strings.Repeat("A", 4096))
asyncWriterLogger.Error("TAG", "Make sure we are not just buffering bytes: %s", strings.Repeat("A", 4096))
}
ch <- struct{}{}
}()
Expand All @@ -90,46 +84,46 @@ var _ = Describe("Logger", func() {
const s0 = "ABCDEFGHIJ"
const s1 = "abcdefghij"

outBuf := new(blockingWriter)
logger := NewAsyncWriterLogger(LevelDebug, outBuf)
out := new(blockingWriter)
asyncWriterLogger := logger.NewAsyncWriterLogger(logger.LevelDebug, out)

outBuf.Lock()
logger.Debug("TAG", s0)
logger.Debug("TAG", s1)
outBuf.Unlock()
out.Lock()
asyncWriterLogger.Debug("TAG", s0)
asyncWriterLogger.Debug("TAG", s1)
out.Unlock()

Expect(logger.Flush()).To(Succeed())
Expect(asyncWriterLogger.Flush()).To(Succeed())

lines := strings.Split(strings.TrimSpace(outBuf.buf.String()), "\n")
lines := strings.Split(strings.TrimSpace(out.buf.String()), "\n")
Expect(lines).To(HaveLen(2))
Expect(lines[0]).To(HaveSuffix(s0))
Expect(lines[1]).To(HaveSuffix(s1))
})

It("continuously flushes queued log messages", func() {
outBuf := new(blockingWriter)
logger := NewAsyncWriterLogger(LevelDebug, outBuf)
out := new(blockingWriter)
asyncWriterLogger := logger.NewAsyncWriterLogger(logger.LevelDebug, out)

outBuf.Lock()
for i := 0; i < 10; i++ {
logger.Debug("TAG", "Queued log message")
out.Lock()
for range 10 {
asyncWriterLogger.Debug("TAG", "Queued log message")
}
Expect(outBuf.buf.Len()).To(Equal(0))
outBuf.Unlock()
Eventually(outBuf.Len).ShouldNot(Equal(0))
Expect(out.buf.Len()).To(Equal(0))
out.Unlock()
Eventually(out.Len).ShouldNot(Equal(0))
})

It("flushes with a timeout", func() {
outBuf := new(blockingWriter)
logger := NewAsyncWriterLogger(LevelDebug, outBuf)
logger.Debug("TAG", "something")
out := new(blockingWriter)
asyncWriterLogger := logger.NewAsyncWriterLogger(logger.LevelDebug, out)
asyncWriterLogger.Debug("TAG", "something")

outBuf.Lock()
Expect(logger.FlushTimeout(time.Millisecond * 10)).ToNot(Succeed())
out.Lock()
Expect(asyncWriterLogger.FlushTimeout(time.Millisecond * 10)).ToNot(Succeed())

outBuf.Unlock()
Expect(logger.FlushTimeout(time.Millisecond * 10)).To(Succeed())
Expect(strings.TrimSpace(outBuf.buf.String())).To(HaveSuffix("something"))
out.Unlock()
Expect(asyncWriterLogger.FlushTimeout(time.Millisecond * 10)).To(Succeed())
Expect(strings.TrimSpace(out.buf.String())).To(HaveSuffix("something"))
})

It("flush doesn't block writes", func() {
Expand All @@ -140,21 +134,21 @@ var _ = Describe("Logger", func() {
)

out := &intervalWriter{dur: WriteInterval}
logger := NewAsyncWriterLogger(LevelDebug, out)
asyncWriterLogger := logger.NewAsyncWriterLogger(logger.LevelDebug, out)

// add some messages to the queue
out.Lock()
for i := 0; i < MessageCount; i++ {
logger.Debug("NEW", "message")
for range MessageCount {
asyncWriterLogger.Debug("NEW", "message")
}
out.Unlock()

go logger.Flush()
go asyncWriterLogger.Flush()

ch := make(chan struct{}, 1)
go func() {
for i := 0; i < MessageCount; i++ {
logger.Debug("NEW", "message")
for range MessageCount {
asyncWriterLogger.Debug("NEW", "message")
}
ch <- struct{}{}
}()
Expand All @@ -169,12 +163,12 @@ var _ = Describe("Logger", func() {
)

out := &intervalWriter{dur: WriteInterval}
logger := NewAsyncWriterLogger(LevelDebug, out)
asyncWriterLogger := logger.NewAsyncWriterLogger(logger.LevelDebug, out)

// add some messages to the queue
out.Lock()
for i := 0; i < MessageCount; i++ {
logger.Debug("QUEUED", "queued")
for range MessageCount {
asyncWriterLogger.Debug("QUEUED", "queued")
}
out.Unlock()

Expand All @@ -183,13 +177,13 @@ var _ = Describe("Logger", func() {
defer tick.Stop()
go func() {
for range tick.C {
logger.Debug("NEW", "new")
asyncWriterLogger.Debug("NEW", "new")
}
}()

ch := make(chan struct{}, 1)
go func() {
logger.Flush()
asyncWriterLogger.Flush()
ch <- struct{}{}
}()

Expand All @@ -200,7 +194,7 @@ var _ = Describe("Logger", func() {
It("prints the correct prefix during concurrent writes", func() {
ch := make(chan struct{}, 1)
go func() {
testConcurrentPrefix(NewAsyncWriterLogger)
testConcurrentPrefix(logger.NewAsyncWriterLogger)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

New logger with no arguments. Doesn't follow the pattern in the file. Is it intentional?

ch <- struct{}{}
}()
Eventually(ch, time.Second*5).Should(Receive())
Expand Down
3 changes: 2 additions & 1 deletion main/verify_multidigest_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"os"
"os/exec"
"path/filepath"
"time"

. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
Expand Down Expand Up @@ -31,7 +32,7 @@ var _ = Describe("VerifyMultidigest", func() {
It("has a version flag", func() {
session, err := runVerifyMultidigest("--version")
Expect(err).ToNot(HaveOccurred())
Eventually(session).Should(gexec.Exit(0))
Eventually(session).WithTimeout(3 * time.Second).Should(gexec.Exit(0))
Eventually(session.Out).Should(gbytes.Say("version \\[DEV BUILD\\]"))
})
})
Expand Down
29 changes: 29 additions & 0 deletions system/exec_cmd_runner_fixtures/priority/priority_unix.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
//go:build !windows

package main

import (
"fmt"
"os"
"runtime"
"syscall"
"time"
)

func main() {
time.Sleep(100 * time.Millisecond)

pid := os.Getpid()
niceValue, err := syscall.Getpriority(syscall.PRIO_PROCESS, pid)
Comment thread
aramprice marked this conversation as resolved.
if err != nil {
fmt.Printf("error getting priority: %s\n", err)
os.Exit(1)
}

// Linux: convert knice => unice see https://linux.die.net/man/2/getpriority
if runtime.GOOS == "linux" {
fmt.Printf("%d\n", (niceValue-20)*-1)
} else {
fmt.Printf("%d\n", niceValue)
}
}
Loading