Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update go1.21 and CI #315

Merged
merged 2 commits into from
Apr 9, 2024
Merged
Changes from 1 commit
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
Next Next commit
Update to go 1.21
Use `atomic.Bool` stdlib instead of including our own.

Include `tools\mkwinsyscall` updates from go-winio/283 to switch to
`syscallN`.
Note: removed `// TODO` about `print`/`ln`, since the latter adds spaces
between args when printing, which is undesired.

Also update CI to run steps on windows-2022 instead of windows-2019,
similar to our hcsshim CI.

Signed-off-by: Hamza El-Saawy <[email protected]>
helsaawy committed Apr 1, 2024
commit b034afcbed4c181f33f088e99fa7904bccace2cc
25 changes: 19 additions & 6 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -6,11 +6,12 @@ on:
env:
GO_VERSION: "oldstable"
GOTESTSUM_VERSION: "latest"
GOLANGCILINT_VERSION: "latest"

jobs:
lint:
name: Lint
runs-on: windows-2019
runs-on: windows-2022
steps:
- name: Checkout
uses: actions/checkout@v4
@@ -24,9 +25,9 @@ jobs:
cache: false

- name: Run golangci-lint
uses: golangci/golangci-lint-action@v3
uses: golangci/golangci-lint-action@v4
with:
version: v1.53
version: ${{ env.GOLANGCILINT_VERSION }}
args: >-
--verbose
--timeout=5m
@@ -37,7 +38,7 @@ jobs:

go-generate:
name: Go Generate
runs-on: windows-2019
runs-on: windows-2022
steps:
- name: Checkout
uses: actions/checkout@v4
@@ -103,7 +104,19 @@ jobs:
run: go install gotest.tools/gotestsum@${{ env.GOTESTSUM_VERSION }}

- name: Test repo
run: gotestsum --format standard-verbose --debug -- -gcflags=all=-d=checkptr -race -v ./...
shell: pwsh
run: |
# `go test -race` requires mingw on windows, and there is some weirdness on windows 2019
# which causes tests to fail with `"exit status 0xc0000139"`.
# Even trying to update mingw with choco still fails.
#
# see: https://go.dev/doc/articles/race_detector#Requirements

if ( '${{ matrix.os }}' -ne 'windows-2019' ) {
$race = '-race'
}

gotestsum --format standard-verbose --debug -- -gcflags=all=-d=checkptr $race -v ./...

# !NOTE:
# Fuzzing cannot be run across multiple packages, (ie, `go -fuzz "^Fuzz" ./...` fails).
@@ -115,7 +128,7 @@ jobs:
name: Build Repo
needs:
- test
runs-on: "windows-2019"
runs-on: "windows-2022"
steps:
- name: Checkout
uses: actions/checkout@v4
9 changes: 3 additions & 6 deletions .golangci.yml
Original file line number Diff line number Diff line change
@@ -1,7 +1,3 @@
run:
skip-dirs:
- pkg/etw/sample

linters:
enable:
# style
@@ -24,6 +20,9 @@ linters:
- unparam # unused function params

issues:
exclude-dirs:
- pkg/etw/sample

exclude-rules:
# err is very often shadowed in nested scopes
- linters:
@@ -70,9 +69,7 @@ linters-settings:
# struct order is often for Win32 compat
# also, ignore pointer bytes/GC issues for now until performance becomes an issue
- fieldalignment
check-shadowing: true
nolintlint:
allow-leading-space: false
require-explanation: true
require-specific: true
revive:
42 changes: 12 additions & 30 deletions file.go
Original file line number Diff line number Diff line change
@@ -21,23 +21,6 @@ import (
//sys setFileCompletionNotificationModes(h windows.Handle, flags uint8) (err error) = SetFileCompletionNotificationModes
//sys wsaGetOverlappedResult(h windows.Handle, o *windows.Overlapped, bytes *uint32, wait bool, flags *uint32) (err error) = ws2_32.WSAGetOverlappedResult

//todo (go1.19): switch to [atomic.Bool]

type atomicBool int32

func (b *atomicBool) isSet() bool { return atomic.LoadInt32((*int32)(b)) != 0 }
func (b *atomicBool) setFalse() { atomic.StoreInt32((*int32)(b), 0) }
func (b *atomicBool) setTrue() { atomic.StoreInt32((*int32)(b), 1) }

//revive:disable-next-line:predeclared Keep "new" to maintain consistency with "atomic" pkg
func (b *atomicBool) swap(new bool) bool {
var newInt int32
if new {
newInt = 1
}
return atomic.SwapInt32((*int32)(b), newInt) == 1
}

var (
ErrFileClosed = errors.New("file has already been closed")
ErrTimeout = &timeoutError{}
@@ -81,7 +64,7 @@ type win32File struct {
handle windows.Handle
wg sync.WaitGroup
wgLock sync.RWMutex
closing atomicBool
closing atomic.Bool
socket bool
readDeadline deadlineHandler
writeDeadline deadlineHandler
@@ -92,7 +75,7 @@ type deadlineHandler struct {
channel timeoutChan
channelLock sync.RWMutex
timer *time.Timer
timedout atomicBool
timedout atomic.Bool
}

// makeWin32File makes a new win32File from an existing file handle.
@@ -131,7 +114,7 @@ func NewOpenFile(h windows.Handle) (io.ReadWriteCloser, error) {
func (f *win32File) closeHandle() {
f.wgLock.Lock()
// Atomically set that we are closing, releasing the resources only once.
if !f.closing.swap(true) {
if !f.closing.Swap(true) {
f.wgLock.Unlock()
// cancel all IO and wait for it to complete
_ = cancelIoEx(f.handle, nil)
@@ -152,14 +135,14 @@ func (f *win32File) Close() error {

// IsClosed checks if the file has been closed.
func (f *win32File) IsClosed() bool {
return f.closing.isSet()
return f.closing.Load()
}

// prepareIO prepares for a new IO operation.
// The caller must call f.wg.Done() when the IO is finished, prior to Close() returning.
func (f *win32File) prepareIO() (*ioOperation, error) {
f.wgLock.RLock()
if f.closing.isSet() {
if f.closing.Load() {
f.wgLock.RUnlock()
return nil, ErrFileClosed
}
@@ -193,7 +176,7 @@ func (f *win32File) asyncIO(c *ioOperation, d *deadlineHandler, bytes uint32, er
return int(bytes), err
}

if f.closing.isSet() {
if f.closing.Load() {
_ = cancelIoEx(f.handle, &c.o)
}

@@ -209,7 +192,7 @@ func (f *win32File) asyncIO(c *ioOperation, d *deadlineHandler, bytes uint32, er
case r = <-c.ch:
err = r.err
if err == windows.ERROR_OPERATION_ABORTED { //nolint:errorlint // err is Errno
if f.closing.isSet() {
if f.closing.Load() {
err = ErrFileClosed
}
} else if err != nil && f.socket {
@@ -242,7 +225,7 @@ func (f *win32File) Read(b []byte) (int, error) {
}
defer f.wg.Done()

if f.readDeadline.timedout.isSet() {
if f.readDeadline.timedout.Load() {
return 0, ErrTimeout
}

@@ -256,9 +239,8 @@ func (f *win32File) Read(b []byte) (int, error) {
return 0, io.EOF
} else if err == windows.ERROR_BROKEN_PIPE { //nolint:errorlint // err is Errno
return 0, io.EOF
} else {
return n, err
}
return n, err
}

// Write writes to a file handle.
@@ -269,7 +251,7 @@ func (f *win32File) Write(b []byte) (int, error) {
}
defer f.wg.Done()

if f.writeDeadline.timedout.isSet() {
if f.writeDeadline.timedout.Load() {
return 0, ErrTimeout
}

@@ -306,7 +288,7 @@ func (d *deadlineHandler) set(deadline time.Time) error {
}
d.timer = nil
}
d.timedout.setFalse()
d.timedout.Store(false)

select {
case <-d.channel:
@@ -321,7 +303,7 @@ func (d *deadlineHandler) set(deadline time.Time) error {
}

timeoutIO := func() {
d.timedout.setTrue()
d.timedout.Store(true)
close(d.channel)
}

2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
module github.com/Microsoft/go-winio

go 1.17
go 1.21

require (
github.com/sirupsen/logrus v1.9.3
38 changes: 0 additions & 38 deletions go.sum
Original file line number Diff line number Diff line change
@@ -8,53 +8,15 @@ github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVs
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/crypto v0.11.0/go.mod h1:xgJhtzW8F9jGdVFWZESrid1U1bjeNy4zgy5cRr/CIio=
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
golang.org/x/mod v0.12.0 h1:rmsUpXtvNzj340zd98LZ4KntptpfRHwpFOHG188oHXc=
golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
golang.org/x/net v0.12.0/go.mod h1:zEVYFnQC7m/vmpQFELhcD1EWkZlX69l4oqgmer6hfKA=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.3.0 h1:ftCYgMx6zT/asHUrPw8BLLscYtGznsLAnjq5RH9P66E=
golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.10.0 h1:SqMFp9UcQJZa+pmYuAKjd9xq1f0j5rLcDIk0mj4qAsA=
golang.org/x/sys v0.10.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo=
golang.org/x/term v0.10.0/go.mod h1:lpqdcUyK/oCiQxvxVrppt5ggO2KCZ5QblwqPnfZ6d5o=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
golang.org/x/text v0.11.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
golang.org/x/tools v0.11.0 h1:EMCa6U9S2LtZXLAMoWiR/R8dAQFRqbAitmbJ2UKhoi8=
golang.org/x/tools v0.11.0/go.mod h1:anzJrxPjNtfgiYQYirP2CPGzGLxrH2u2QBhn6Bf3qY8=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
36 changes: 29 additions & 7 deletions hvsock_test.go
Original file line number Diff line number Diff line change
@@ -57,7 +57,11 @@ func clientServer(u testUtil) (cl, sv *HvsockConn, _ *HvsockAddr) {
if err != nil {
return fmt.Errorf("listener accept: %w", err)
}
sv = conn.(*HvsockConn)
var ok bool
sv, ok = conn.(*HvsockConn)
if !ok {
return fmt.Errorf("expected connection type %T; got %T", new(HvsockConn), conn)
}
if err := l.Close(); err != nil {
return err
}
@@ -109,7 +113,10 @@ func TestHvSockListenerAddresses(t *testing.T) {
u := newUtil(t)
l, addr := serverListen(u)

la := (l.Addr()).(*HvsockAddr)
la, ok := (l.Addr()).(*HvsockAddr)
if !ok {
t.Fatalf("expected type %T; got %T", new(HvsockAddr), l.Addr())
}
u.Assert(*la == *addr, fmt.Sprintf("give: %v; want: %v", la, addr))

ra := rawHvsockAddr{}
@@ -123,10 +130,22 @@ func TestHvSockAddresses(t *testing.T) {
u := newUtil(t)
cl, sv, addr := clientServer(u)

sra := (sv.RemoteAddr()).(*HvsockAddr)
sla := (sv.LocalAddr()).(*HvsockAddr)
cra := (cl.RemoteAddr()).(*HvsockAddr)
cla := (cl.LocalAddr()).(*HvsockAddr)
sra, ok := (sv.RemoteAddr()).(*HvsockAddr)
if !ok {
t.Fatalf("expected type %T; got %T", new(HvsockAddr), sv.RemoteAddr())
}
Copy link
Member

Choose a reason for hiding this comment

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

You can make this a lot cleaner by defining a function:

func MustBeType[T any](t *testing.T, v any) T {
	v2, ok := v.(T)
	if !ok {
		t.Fatalf("expected type %T; got %T", *new(T), v)
	}
	return v2
}

and using it like:

sra := MustBeType[*HvsockAddr](t, sv.RemoteAddr())

sla, ok := (sv.LocalAddr()).(*HvsockAddr)
if !ok {
t.Fatalf("expected type %T; got %T", new(HvsockAddr), sv.LocalAddr())
}
cra, ok := (cl.RemoteAddr()).(*HvsockAddr)
if !ok {
t.Fatalf("expected type %T; got %T", new(HvsockAddr), cl.RemoteAddr())
}
cla, ok := (cl.LocalAddr()).(*HvsockAddr)
if !ok {
t.Fatalf("expected type %T; got %T", new(HvsockAddr), cl.LocalAddr())
}

t.Run("Info", func(t *testing.T) {
tests := []struct {
@@ -322,7 +341,10 @@ func TestHvSockCloseReadWriteListener(t *testing.T) {
}
defer c.Close()

hv := c.(*HvsockConn)
hv, ok := c.(*HvsockConn)
if !ok {
t.Fatalf("expected type %T; got %T", new(HvsockConn), c)
}
//
// test CloseWrite()
//
7 changes: 2 additions & 5 deletions internal/computestorage/zsyscall_windows.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 1 addition & 4 deletions internal/fs/zsyscall_windows.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading