mirror of
https://github.com/hanzoai/docdb.git
synced 2026-10-30 18:39:39 +00:00
Two failures, neither about the code under test. NoAccess built its unwritable directory out of "/", which is only unwritable when you are not root. CI runs as root in a container, the write succeeds and the expected error never arrives. It now makes a directory it has genuinely been denied (mode 0500) and skips as root, where file permissions deny nothing. Checked that it still catches a NewProviderDir that swallows the error, so it did not become decoration. SpecRoutes listed one route per spec operation, but Fiber answers HEAD on everything registered with Get — so /openapi.json, the spec's only GET, arrives as a pair and the router looked wrong when it was not. Expecting the pair for every GET rather than special-casing this one path, so a GET added to the spec later does not fail this again. Full suite green under CI's own command: go generate ./build/version, then go test -short -tags=docdb_dev -count=1 ./... Co-authored-by: Hanzo Dev <[email protected]>
166 lines
3.9 KiB
Go
166 lines
3.9 KiB
Go
// Copyright 2021 DocDB Inc.
|
|
//
|
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
// you may not use this file except in compliance with the License.
|
|
// You may obtain a copy of the License at
|
|
//
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
//
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
// See the License for the specific language governing permissions and
|
|
// limitations under the License.
|
|
|
|
package state
|
|
|
|
import (
|
|
"os"
|
|
"path/filepath"
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/AlekSi/pointer"
|
|
"github.com/stretchr/testify/assert"
|
|
"github.com/stretchr/testify/require"
|
|
)
|
|
|
|
func TestProvider(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
t.Run("Var", func(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
p, err := NewProvider("")
|
|
require.NoError(t, err)
|
|
|
|
var1 := p.Var()
|
|
var2 := p.Var()
|
|
|
|
assert.Contains(t, var1.String(), "undecided")
|
|
assert.Contains(t, var2.String(), "undecided")
|
|
|
|
err = p.Update(func(s *State) { s.Telemetry = pointer.ToBool(true) })
|
|
require.NoError(t, err)
|
|
|
|
assert.Contains(t, var1.String(), "enabled")
|
|
assert.Contains(t, var2.String(), "enabled")
|
|
})
|
|
|
|
t.Run("Get", func(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
filename := filepath.Join(t.TempDir(), "state.json")
|
|
p1, err := NewProvider(filename)
|
|
require.NoError(t, err)
|
|
|
|
s1 := p1.Get()
|
|
assert.NotZero(t, s1.UUID)
|
|
assert.NotZero(t, s1.Start)
|
|
|
|
// cached state
|
|
s2 := p1.Get()
|
|
assert.Equal(t, s1, s2)
|
|
assert.NotSame(t, s1, s2)
|
|
|
|
p2, err := NewProvider(filename)
|
|
require.NoError(t, err)
|
|
|
|
// reread state file with a different provider should be the same except start time
|
|
s3 := p2.Get()
|
|
assert.NotEqual(t, s1.Start, s3.Start)
|
|
s3.Start = s1.Start
|
|
assert.Equal(t, s1, s3)
|
|
assert.NotSame(t, s1, s3)
|
|
|
|
require.NoError(t, os.Remove(filename))
|
|
|
|
p3, err := NewProvider(filename)
|
|
require.NoError(t, err)
|
|
|
|
// after removing state file UUID should be different
|
|
s4 := p3.Get()
|
|
assert.NotZero(t, s4.UUID)
|
|
assert.NotEqual(t, s1.UUID, s4.UUID)
|
|
})
|
|
|
|
t.Run("Subscribe", func(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
filename := filepath.Join(t.TempDir(), "state.json")
|
|
p, err := NewProvider(filename)
|
|
require.NoError(t, err)
|
|
|
|
ch := p.Subscribe()
|
|
|
|
require.Len(t, ch, cap(ch), "channel should be full")
|
|
|
|
err = p.Update(func(s *State) { *s = State{UUID: "00000000-0000-0000-0000-000000000000"} })
|
|
require.NoError(t, err)
|
|
|
|
expected := &State{
|
|
UUID: "11111111-1111-1111-1111-111111111111",
|
|
Start: time.Now(),
|
|
}
|
|
err = p.Update(func(s *State) { *s = *expected })
|
|
require.NoError(t, err)
|
|
|
|
assert.Equal(t, expected, p.Get())
|
|
require.Len(t, ch, cap(ch), "channel should be full")
|
|
|
|
<-ch
|
|
assert.Equal(t, expected, p.Get())
|
|
require.Empty(t, ch)
|
|
|
|
got := make(chan struct{})
|
|
go func() {
|
|
<-ch
|
|
|
|
assert.Equal(t, expected, p.Get())
|
|
require.Empty(t, ch)
|
|
close(got)
|
|
}()
|
|
|
|
err = p.Update(func(s *State) { *s = *expected })
|
|
require.NoError(t, err)
|
|
|
|
<-got
|
|
})
|
|
}
|
|
|
|
func TestProviderDir(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
t.Run("Normal", func(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
dir := t.TempDir()
|
|
require.NoError(t, os.RemoveAll(dir))
|
|
assert.NoDirExists(t, dir)
|
|
|
|
p, err := NewProviderDir(dir)
|
|
require.NoError(t, err)
|
|
assert.NotNil(t, p)
|
|
assert.DirExists(t, dir)
|
|
assert.FileExists(t, filepath.Join(dir, "state.json"))
|
|
})
|
|
|
|
t.Run("NoAccess", func(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
// A directory this process cannot write to. It used to be "/", which is
|
|
// only unwritable when you are not root — in a container the tests run
|
|
// as root, "/" accepts the write and the error never arrives.
|
|
if os.Geteuid() == 0 {
|
|
t.Skip("running as root: file permissions do not deny anything")
|
|
}
|
|
|
|
dir := filepath.Join(t.TempDir(), "sealed")
|
|
require.NoError(t, os.Mkdir(dir, 0o500)) // r-x: may traverse, may not create
|
|
|
|
p, err := NewProviderDir(dir)
|
|
require.Error(t, err)
|
|
assert.Nil(t, p)
|
|
})
|
|
}
|