Skip to content

Commit

Permalink
Update tests after rebase
Browse files Browse the repository at this point in the history
  • Loading branch information
jhiemstrawisc committed Mar 12, 2024
1 parent cb53b8d commit 4282531
Show file tree
Hide file tree
Showing 9 changed files with 506 additions and 402 deletions.
731 changes: 397 additions & 334 deletions client/fed_test.go

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion client/resources/both-auth.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@
Origin:
# Things that configure the origin itself
StorageType: "posix"
EnableDirectReads: true
# The actual namespaces we export
EnableDirectReads: true
Exports:
- StoragePrefix: /<SHOULD BE OVERRIDDEN>
FederationPrefix: /first/namespace
Expand Down
106 changes: 65 additions & 41 deletions fed_test_utils/fed.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,46 +23,43 @@ package fed_test_utils
import (
"context"
"encoding/json"
"fmt"
"io"
"net/http"
"os"
"path/filepath"
"strings"
"testing"
"time"

"github.com/spf13/viper"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"golang.org/x/sync/errgroup"

"github.com/pelicanplatform/pelican/common"
"github.com/pelicanplatform/pelican/config"
"github.com/pelicanplatform/pelican/launchers"
"github.com/pelicanplatform/pelican/param"
"github.com/pelicanplatform/pelican/server_utils"
"github.com/pelicanplatform/pelican/test_utils"
"github.com/pelicanplatform/pelican/token"
"github.com/pelicanplatform/pelican/token_scopes"
"github.com/spf13/viper"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"golang.org/x/sync/errgroup"
)

type (
FedTest struct {
OriginDir string
Token string
Ctx context.Context
Egrp *errgroup.Group
Exports *[]common.OriginExports
Token string
Ctx context.Context
Egrp *errgroup.Group
}
)

func NewFedTest(t *testing.T) (ft *FedTest) {
func NewFedTest(t *testing.T, originConfig string) (ft *FedTest) {
ft = &FedTest{}

ctx, cancel, egrp := test_utils.TestContext(context.Background(), t)
t.Cleanup(func() {
cancel()
if err := egrp.Wait(); err != nil && err != context.Canceled && err != http.ErrServerClosed {
require.NoError(t, err)
}
})

ft.Ctx = ctx
ft.Egrp = egrp

Expand All @@ -72,7 +69,6 @@ func NewFedTest(t *testing.T) (ft *FedTest) {
modules.Set(config.RegistryType)
// TODO: the cache startup routines not sequenced correctly for the downloads
// to immediately work through the cache. For now, unit tests will just use the origin.
viper.Set("Origin.EnableFallbackRead", true)
modules.Set(config.LocalCacheType)

tmpPathPattern := "PelicanOrigin-FedTest*"
Expand All @@ -82,35 +78,53 @@ func NewFedTest(t *testing.T) (ft *FedTest) {
permissions := os.FileMode(0755)
err = os.Chmod(tmpPath, permissions)
require.NoError(t, err)
t.Cleanup(func() {
err := os.RemoveAll(tmpPath)
require.NoError(t, err)
})

viper.Set("ConfigDir", tmpPath)

config.InitConfig()

originDir, err := os.MkdirTemp("", "Origin")
assert.NoError(t, err)
t.Cleanup(func() {
err := os.RemoveAll(originDir)
// Read in any config we may have set
if originConfig != "" {
viper.SetConfigType("yaml")
err = viper.MergeConfig(strings.NewReader(originConfig))
require.NoError(t, err, "error reading config")
}
// Now call GetOriginExports and check the struct
exports, err := common.GetOriginExports()
require.NoError(t, err, "error getting origin exports")
ft.Exports = exports

// Override the test directory from the config file with our temp directory
for i := 0; i < len(*ft.Exports); i++ {
originDir, err := os.MkdirTemp("", fmt.Sprintf("Export%d", i))
assert.NoError(t, err)
t.Cleanup(func() {
err := os.RemoveAll(originDir)
require.NoError(t, err)
})

// Set the storage prefix to the temporary origin directory
((*ft.Exports)[i]).StoragePrefix = originDir
// Our exports object becomes global -- we must reset in between each fed test
t.Cleanup(func() {
common.ResetOriginExports()
})

// Change the permissions of the temporary origin directory
permissions = os.FileMode(0755)
err = os.Chmod(originDir, permissions)
require.NoError(t, err)
})

// Change the permissions of the temporary origin directory
permissions = os.FileMode(0755)
err = os.Chmod(originDir, permissions)
require.NoError(t, err)
// Change ownership on the temporary origin directory so files can be uploaded
uinfo, err := config.GetDaemonUserInfo()
require.NoError(t, err)
require.NoError(t, os.Chown(originDir, uinfo.Uid, uinfo.Gid))

// Change ownership on the temporary origin directory so files can be uploaded
uinfo, err := config.GetDaemonUserInfo()
require.NoError(t, err)
require.NoError(t, os.Chown(originDir, uinfo.Uid, uinfo.Gid))
// Start off with a Hello World file we can use for testing in each of our exports
err = os.WriteFile(filepath.Join(originDir, "hello_world.txt"), []byte("Hello, World!"), os.FileMode(0644))
require.NoError(t, err)
}

viper.Set("Origin.ExportVolume", originDir+":/test")
viper.Set("Origin.Mode", "posix")
viper.Set("Origin.EnableFallbackRead", true)
// Disable functionality we're not using (and is difficult to make work on Mac)
viper.Set("Origin.EnableCmsd", false)
viper.Set("Origin.EnableMacaroons", false)
Expand Down Expand Up @@ -150,9 +164,6 @@ func NewFedTest(t *testing.T) (ft *FedTest) {
require.NoError(t, err)
assert.NotEmpty(t, expectedResponse.Msg)

err = os.WriteFile(filepath.Join(originDir, "hello_world.txt"), []byte("Hello, World!"), os.FileMode(0644))
require.NoError(t, err)

issuer, err := config.GetServerIssuerURL()
require.NoError(t, err)
tokConf := token.NewWLCGToken()
Expand All @@ -165,8 +176,21 @@ func NewFedTest(t *testing.T) (ft *FedTest) {
token, err := tokConf.CreateToken()
require.NoError(t, err)

ft.OriginDir = originDir
ft.Token = token

// Explicitly run tmpPath cleanup AFTER cancel and egrp are done -- otherwise we end up
// with a race condition where removing tmpPath might happen while the server is still
// using it, resulting in "error: unlinkat <tmpPath>: directory not empty"
t.Cleanup(func() {
cancel()
if err := egrp.Wait(); err != nil && err != context.Canceled && err != http.ErrServerClosed {
require.NoError(t, err)
}
err := os.RemoveAll(tmpPath)
require.NoError(t, err)
// Throw in a viper.Reset for good measure. Keeps our env squeaky clean!
viper.Reset()
})

return
}
1 change: 0 additions & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ require (
github.com/hashicorp/go-version v1.6.0
github.com/jellydator/ttlcache/v3 v3.1.0
github.com/jsipprell/keyctl v1.0.4-0.20211208153515-36ca02672b6c
github.com/lestrrat-go/httprc v1.0.4
github.com/lestrrat-go/jwx/v2 v2.0.20
github.com/minio/minio-go/v7 v7.0.65
github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f
Expand Down
6 changes: 3 additions & 3 deletions local_cache/cache_authz.go
Original file line number Diff line number Diff line change
Expand Up @@ -223,14 +223,14 @@ func (ac *authConfig) getAcls(token string) (newAcls acls, err error) {

newAcls = make(acls, 0)
for _, conf := range *namespaces {
if conf.Caps.PublicRead {
if conf.Caps.PublicReads {
newAcls = append(newAcls, token_scopes.ResourceScope{Authorization: token_scopes.Storage_Read, Resource: conf.Path})
} else if conf.Issuer != nil {
for _, resource := range resources {
if (resource.Authorization == token_scopes.Storage_Create || resource.Authorization == token_scopes.Storage_Modify) && !conf.Caps.Write {
if (resource.Authorization == token_scopes.Storage_Create || resource.Authorization == token_scopes.Storage_Modify) && !conf.Caps.Writes {
continue
}
if resource.Authorization == token_scopes.Storage_Read && !conf.Caps.Read {
if resource.Authorization == token_scopes.Storage_Read && !conf.Caps.Reads {
continue
}
for _, issuerConfig := range conf.Issuer {
Expand Down
43 changes: 22 additions & 21 deletions local_cache/cache_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ package local_cache_test

import (
"context"
_ "embed"
"errors"
"fmt"
"io"
Expand All @@ -47,14 +48,21 @@ import (
"github.com/stretchr/testify/require"
)

var (
//go:embed resources/public-origin-cfg.yml
pubOriginCfg string

//go:embed resources/auth-origin-cfg.yml
authOriginCfg string
)

// Setup a federation, invoke "get" through the local cache module
//
// The download is done twice -- once to verify functionality and once
// as a cache hit.
func TestFedPublicGet(t *testing.T) {
viper.Reset()
viper.Set("Origin.EnablePublicReads", true)
ft := fed_test_utils.NewFedTest(t)
ft := fed_test_utils.NewFedTest(t, pubOriginCfg)

lc, err := local_cache.NewLocalCache(ft.Ctx, ft.Egrp)
require.NoError(t, err)
Expand All @@ -79,8 +87,7 @@ func TestFedPublicGet(t *testing.T) {
// Test the local cache library on an authenticated GET.
func TestFedAuthGet(t *testing.T) {
viper.Reset()
viper.Set("Origin.EnablePublicReads", false)
ft := fed_test_utils.NewFedTest(t)
ft := fed_test_utils.NewFedTest(t, authOriginCfg)

lc, err := local_cache.NewLocalCache(ft.Ctx, ft.Egrp)
require.NoError(t, err)
Expand Down Expand Up @@ -112,8 +119,7 @@ func TestFedAuthGet(t *testing.T) {
// Test a raw HTTP request (no Pelican client) works with the local cache
func TestHttpReq(t *testing.T) {
viper.Reset()
viper.Set("Origin.EnablePublicReads", false)
ft := fed_test_utils.NewFedTest(t)
ft := fed_test_utils.NewFedTest(t, authOriginCfg)

transport := config.GetTransport().Clone()
transport.DialContext = func(_ context.Context, _, _ string) (net.Conn, error) {
Expand All @@ -138,8 +144,7 @@ func TestClient(t *testing.T) {
tmpDir := t.TempDir()

viper.Reset()
viper.Set("Origin.EnablePublicReads", false)
ft := fed_test_utils.NewFedTest(t)
ft := fed_test_utils.NewFedTest(t, authOriginCfg)

cacheUrl := &url.URL{
Scheme: "unix",
Expand Down Expand Up @@ -195,8 +200,7 @@ func TestClient(t *testing.T) {
// Test that HEAD requests to the local cache return the correct result
func TestStat(t *testing.T) {
viper.Reset()
viper.Set("Origin.EnablePublicReads", true)
ft := fed_test_utils.NewFedTest(t)
ft := fed_test_utils.NewFedTest(t, pubOriginCfg)

lc, err := local_cache.NewLocalCache(ft.Ctx, ft.Egrp)
require.NoError(t, err)
Expand Down Expand Up @@ -251,16 +255,15 @@ func TestLargeFile(t *testing.T) {
tmpDir := t.TempDir()

viper.Reset()
viper.Set("Origin.EnablePublicReads", true)
viper.Set("Client.MaximumDownloadSpeed", 40*1024*1024)
ft := fed_test_utils.NewFedTest(t)
ft := fed_test_utils.NewFedTest(t, pubOriginCfg)

cacheUrl := &url.URL{
Scheme: "unix",
Path: param.LocalCache_Socket.GetString(),
}

fp, err := os.OpenFile(filepath.Join(ft.OriginDir, "hello_world.txt"), os.O_CREATE|os.O_TRUNC|os.O_WRONLY, 0644)
fp, err := os.OpenFile(filepath.Join((*ft.Exports)[0].StoragePrefix, "hello_world.txt"), os.O_CREATE|os.O_TRUNC|os.O_WRONLY, 0644)
require.NoError(t, err)
size := writeBigBuffer(t, fp, 100)

Expand All @@ -282,9 +285,8 @@ func TestPurge(t *testing.T) {
tmpDir := t.TempDir()

viper.Reset()
viper.Set("Origin.EnablePublicReads", true)
viper.Set("LocalCache.Size", "5MB")
ft := fed_test_utils.NewFedTest(t)
ft := fed_test_utils.NewFedTest(t, pubOriginCfg)

cacheUrl := &url.URL{
Scheme: "unix",
Expand All @@ -293,8 +295,8 @@ func TestPurge(t *testing.T) {

size := 0
for idx := 0; idx < 5; idx++ {
log.Debugln("Will write origin file", filepath.Join(ft.OriginDir, fmt.Sprintf("hello_world.txt.%d", idx)))
fp, err := os.OpenFile(filepath.Join(ft.OriginDir, fmt.Sprintf("hello_world.txt.%d", idx)), os.O_CREATE|os.O_TRUNC|os.O_WRONLY, 0644)
log.Debugln("Will write origin file", filepath.Join((*ft.Exports)[0].StoragePrefix, fmt.Sprintf("hello_world.txt.%d", idx)))
fp, err := os.OpenFile(filepath.Join((*ft.Exports)[0].StoragePrefix, fmt.Sprintf("hello_world.txt.%d", idx)), os.O_CREATE|os.O_TRUNC|os.O_WRONLY, 0644)
require.NoError(t, err)
size = writeBigBuffer(t, fp, 1)
}
Expand Down Expand Up @@ -330,11 +332,10 @@ func TestForcePurge(t *testing.T) {
tmpDir := t.TempDir()

viper.Reset()
viper.Set("Origin.EnablePublicReads", true)
viper.Set("LocalCache.Size", "5MB")
// Decrease the low water mark so invoking purge will result in 3 files in the cache.
viper.Set("LocalCache.LowWaterMarkPercentage", "80")
ft := fed_test_utils.NewFedTest(t)
ft := fed_test_utils.NewFedTest(t, pubOriginCfg)

issuer, err := config.GetServerIssuerURL()
require.NoError(t, err)
Expand All @@ -360,8 +361,8 @@ func TestForcePurge(t *testing.T) {
// Populate the cache with our test files
size := 0
for idx := 0; idx < 4; idx++ {
log.Debugln("Will write origin file", filepath.Join(ft.OriginDir, fmt.Sprintf("hello_world.txt.%d", idx)))
fp, err := os.OpenFile(filepath.Join(ft.OriginDir, fmt.Sprintf("hello_world.txt.%d", idx)), os.O_CREATE|os.O_TRUNC|os.O_WRONLY, 0644)
log.Debugln("Will write origin file", filepath.Join((*ft.Exports)[0].StoragePrefix, fmt.Sprintf("hello_world.txt.%d", idx)))
fp, err := os.OpenFile(filepath.Join((*ft.Exports)[0].StoragePrefix, fmt.Sprintf("hello_world.txt.%d", idx)), os.O_CREATE|os.O_TRUNC|os.O_WRONLY, 0644)
require.NoError(t, err)
size = writeBigBuffer(t, fp, 1)
}
Expand Down
9 changes: 9 additions & 0 deletions local_cache/resources/auth-origin-cfg.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
Origin:
# Things that configure the origin itself
StorageType: "posix"
# The actual namespaces we export
Exports:
- StoragePrefix: /<SHOULD BE OVERRIDDEN>
FederationPrefix: /test
# Don't set Reads -- it should be toggled true by setting PublicReads
Capabilities: ["Reads", "Writes", "DirectReads"]
9 changes: 9 additions & 0 deletions local_cache/resources/public-origin-cfg.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
Origin:
# Things that configure the origin itself
StorageType: "posix"
# The actual namespaces we export
Exports:
- StoragePrefix: /<SHOULD BE OVERRIDDEN>
FederationPrefix: /test
# Don't set Reads -- it should be toggled true by setting PublicReads
Capabilities: ["PublicReads", "Writes", "DirectReads"]
1 change: 0 additions & 1 deletion param/parameters.go

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

0 comments on commit 4282531

Please sign in to comment.