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

[test] test in actuated runners #219

Closed
wants to merge 12 commits into from
91 changes: 82 additions & 9 deletions .github/workflows/validate.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ on:
jobs:

commit:
runs-on: ubuntu-20.04
runs-on: ubuntu-22.04
# Only check commits on pull requests.
if: github.event_name == 'pull_request'
steps:
Expand All @@ -28,16 +28,15 @@ jobs:
error: 'Subject too long (max 72)'

lint:
runs-on: ubuntu-20.04
runs-on: ubuntu-22.04
steps:
- uses: actions/checkout@v4
- uses: actions/setup-go@v5
with:
go-version: 1.22.x
cache: false # golangci-lint-action does its own caching
- uses: golangci/golangci-lint-action@v6
with:
version: v1.56
version: v1.61

codespell:
runs-on: ubuntu-22.04
Expand All @@ -50,7 +49,7 @@ jobs:
run: codespell

cross:
runs-on: ubuntu-20.04
runs-on: ubuntu-22.04
steps:
- uses: actions/checkout@v4
- name: cross
Expand All @@ -63,20 +62,19 @@ jobs:
- uses: actions/setup-go@v5
with:
go-version: 1.22.x
cache: false # golangci-lint-action does its own caching
- uses: golangci/golangci-lint-action@v6
with:
version: v1.56
version: v1.61
- name: test-stubs
run: make test

test:
strategy:
fail-fast: false
matrix:
go-version: [1.21.x, 1.22.x]
go-version: [1.21.x, 1.22.x, 1.23.x]
race: ["-race", ""]
runs-on: ubuntu-20.04
runs-on: ubuntu-22.04
steps:
- uses: actions/checkout@v4

Expand All @@ -90,3 +88,78 @@ jobs:

- name: test
run: make TESTFLAGS="${{ matrix.race }}" test

- name: test 32-bit
if: ${{ matrix.race }} == "" # -race is not supported on linux/386
run: make GOARCH=386 test

test-actuated:
runs-on: actuated-arm64-6cpu-8gb
steps:
# https://gist.github.com/alexellis/1f33e581c75e11e161fe613c46180771#file-metering-gha-md
# vmmeter start
- name: Prepare arkade
uses: alexellis/arkade-get@master
with:
crane: latest
print-summary: false

- name: Install vmmeter
run: |
crane export --platform linux/arm64 ghcr.io/openfaasltd/vmmeter:latest | sudo tar -xvf - -C /usr/local/bin

- name: Run vmmeter
uses: self-actuated/vmmeter-action@master
# vmmeter end

- uses: actions/checkout@v4

- name: enable selinux
run: |
sudo apt update
sudo apt install -y policycoreutils selinux-basics selinux-policy-default selinux-utils
sudo selinux-activate
#------------
sestatus
#------------

- name: host info
run: |
set -x
# Sync `set -x` outputs with command ouputs
exec 2>&1
# Version
uname -a
cat /etc/os-release
# SELinux
sestatus

- name: install Go
uses: actions/setup-go@v5
with:
go-version: 1.23.x

- name: build
run: make build

- name: test
run: make test

- name: test -race
run: make TESTFLAGS="-race" test

- name: test 32-bit
run: make GOARCH=arm test

all-done:
needs:
- commit
- lint
- codespell
- cross
- test-stubs
- test
- test-actuated
runs-on: ubuntu-22.04
steps:
- run: echo "All jobs completed"
2 changes: 0 additions & 2 deletions .golangci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ linters:
enable:
- dupword # Detects duplicate words.
- errorlint # Detects code that may cause problems with Go 1.13 error wrapping.
- exportloopref # Detects pointers to enclosing loop variables.
- gocritic # Metalinter; detects bugs, performance, and styling issues.
- gofumpt # Detects whether code was gofumpt-ed.
- gosec # Detects security problems.
Expand All @@ -22,7 +21,6 @@ linters:
- unconvert # Detects unnecessary type conversions.
linters-settings:
govet:
check-shadowing: true
enable-all: true
settings:
shadow:
Expand Down
37 changes: 12 additions & 25 deletions go-selinux/selinux_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ type selinuxState struct {

type level struct {
cats *big.Int
sens uint
sens int
}

type mlsRange struct {
Expand Down Expand Up @@ -138,7 +138,7 @@ func verifySELinuxfsMount(mnt string) bool {
return false
}

if uint32(buf.Type) != uint32(unix.SELINUX_MAGIC) {
if uint32(buf.Type) != uint32(unix.SELINUX_MAGIC) { //nolint:gosec
return false
}
if (buf.Flags & unix.ST_RDONLY) != 0 {
Expand Down Expand Up @@ -501,31 +501,32 @@ func catsToBitset(cats string) (*big.Int, error) {
return nil, err
}
for i := catstart; i <= catend; i++ {
bitset.SetBit(bitset, int(i), 1)
bitset.SetBit(bitset, i, 1)
}
} else {
cat, err := parseLevelItem(ranges[0], category)
if err != nil {
return nil, err
}
bitset.SetBit(bitset, int(cat), 1)
bitset.SetBit(bitset, cat, 1)
}
}

return bitset, nil
}

// parseLevelItem parses and verifies that a sensitivity or category are valid
func parseLevelItem(s string, sep levelItem) (uint, error) {
func parseLevelItem(s string, sep levelItem) (int, error) {
if len(s) < minSensLen || levelItem(s[0]) != sep {
return 0, ErrLevelSyntax
}
val, err := strconv.ParseUint(s[1:], 10, 32)
const bitSize = 31 // Make sure the result fits into signed int32.
val, err := strconv.ParseUint(s[1:], 10, bitSize)
if err != nil {
return 0, err
}

return uint(val), nil
return int(val), nil //nolint:gosec
}

// parseLevel fills a level from a string that contains
Expand Down Expand Up @@ -582,7 +583,8 @@ func bitsetToStr(c *big.Int) string {
var str string

length := 0
for i := int(c.TrailingZeroBits()); i < c.BitLen(); i++ {
i0 := int(c.TrailingZeroBits()) //nolint:gosec
for i := i0; i < c.BitLen(); i++ {
if c.Bit(i) == 0 {
continue
}
Expand Down Expand Up @@ -622,7 +624,7 @@ func (l *level) equal(l2 *level) bool {

// String returns an mlsRange as a string.
func (m mlsRange) String() string {
low := "s" + strconv.Itoa(int(m.low.sens))
low := "s" + strconv.Itoa(m.low.sens)
if m.low.cats != nil && m.low.cats.BitLen() > 0 {
low += ":" + bitsetToStr(m.low.cats)
}
Expand All @@ -631,29 +633,14 @@ func (m mlsRange) String() string {
return low
}

high := "s" + strconv.Itoa(int(m.high.sens))
high := "s" + strconv.Itoa(m.high.sens)
if m.high.cats != nil && m.high.cats.BitLen() > 0 {
high += ":" + bitsetToStr(m.high.cats)
}

return low + "-" + high
}

// TODO: remove min and max once Go < 1.21 is not supported.
func max(a, b uint) uint {
if a > b {
return a
}
return b
}

func min(a, b uint) uint {
if a < b {
return a
}
return b
}

// calculateGlbLub computes the glb (greatest lower bound) and lub (least upper bound)
// of a source and target range.
// The glblub is calculated as the greater of the low sensitivities and
Expand Down
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
module github.com/opencontainers/selinux

go 1.19
go 1.21

require golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8
27 changes: 15 additions & 12 deletions pkg/pwalk/pwalk_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,21 +12,22 @@ import (
)

func TestWalk(t *testing.T) {
var count uint32
var ac atomic.Uint32
concurrency := runtime.NumCPU() * 2

dir, total := prepareTestSet(t, 3, 2, 1)

err := WalkN(dir,
func(_ string, _ os.FileInfo, _ error) error {
atomic.AddUint32(&count, 1)
ac.Add(1)
return nil
},
concurrency)
if err != nil {
t.Errorf("Walk failed: %v", err)
}
if count != uint32(total) {
count := ac.Load()
if count != total {
t.Errorf("File count mismatch: found %d, expected %d", count, total)
}

Expand All @@ -41,7 +42,7 @@ func TestWalkTopLevelErrNotExistNotIgnored(t *testing.T) {

// https://github.com/opencontainers/selinux/issues/199
func TestWalkRaceWithRemoval(t *testing.T) {
var count uint32
var ac atomic.Uint32
concurrency := runtime.NumCPU() * 2
// This test is still on a best-effort basis, meaning it can still pass
// when there is a bug in the code, but the larger the test set is, the
Expand All @@ -55,41 +56,43 @@ func TestWalkRaceWithRemoval(t *testing.T) {
go os.RemoveAll(dir)
err := WalkN(dir,
func(_ string, _ os.FileInfo, _ error) error {
atomic.AddUint32(&count, 1)
ac.Add(1)
return nil
},
concurrency)
count := int(ac.Load())
t.Logf("found %d of %d files", count, total)
if err != nil {
t.Fatalf("expected nil, got %v", err)
}
}

func TestWalkDirManyErrors(t *testing.T) {
var count uint32
var ac atomic.Uint32

dir, total := prepareTestSet(t, 3, 3, 2)

max := uint32(total / 2)
maxFiles := total / 2
e42 := errors.New("42")
err := Walk(dir,
func(_ string, _ os.FileInfo, _ error) error {
if atomic.AddUint32(&count, 1) > max {
if ac.Add(1) > maxFiles {
return e42
}
return nil
})
count := ac.Load()
t.Logf("found %d of %d files", count, total)

if err == nil {
t.Errorf("Walk succeeded, but error is expected")
if count != uint32(total) {
if count != total {
t.Errorf("File count mismatch: found %d, expected %d", count, total)
}
}
}

func makeManyDirs(prefix string, levels, dirs, files int) (count int, err error) {
func makeManyDirs(prefix string, levels, dirs, files int) (count uint32, err error) {
for d := 0; d < dirs; d++ {
var dir string
dir, err = os.MkdirTemp(prefix, "d-")
Expand All @@ -109,7 +112,7 @@ func makeManyDirs(prefix string, levels, dirs, files int) (count int, err error)
if levels == 0 {
continue
}
var c int
var c uint32
if c, err = makeManyDirs(dir, levels-1, dirs, files); err != nil {
return
}
Expand All @@ -124,7 +127,7 @@ func makeManyDirs(prefix string, levels, dirs, files int) (count int, err error)
//
// Total dirs: dirs^levels + dirs^(levels-1) + ... + dirs^1
// Total files: total_dirs * files
func prepareTestSet(tb testing.TB, levels, dirs, files int) (dir string, total int) {
func prepareTestSet(tb testing.TB, levels, dirs, files int) (dir string, total uint32) {
tb.Helper()
var err error

Expand Down
Loading
Loading