Skip to content
Merged
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
10 changes: 7 additions & 3 deletions core/services/health.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,9 +49,6 @@ func (i *StartUpHealthReport) Stop() {

func (i *StartUpHealthReport) Start() {
go func() {
i.mux.HandleFunc("/health", func(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusNoContent)
})
i.lggr.Info("Starting StartUpHealthReport")
if err := i.server.ListenAndServe(); !errors.Is(err, http.ErrServerClosed) {
i.lggr.Errorf("StartUpHealthReport server error: %v", err)
Expand All @@ -63,6 +60,13 @@ func (i *StartUpHealthReport) Start() {
// preventing shutdowns due to health-checks when running long backup tasks or migrations
func NewStartUpHealthReport(port uint16, lggr logger.Logger) *StartUpHealthReport {
mux := http.NewServeMux()
mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
if r.URL.Path == "/health" {
w.WriteHeader(http.StatusNoContent)
return
}
w.WriteHeader(http.StatusServiceUnavailable)
})
return &StartUpHealthReport{
lggr: lggr,
mux: mux,
Expand Down
12 changes: 12 additions & 0 deletions core/services/health_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,18 @@ func TestNewStartUpHealthReport(t *testing.T) {
res, err := http.DefaultClient.Do(req)
require.NoError(t, err)
require.Equal(t, http.StatusNoContent, res.StatusCode)

req, err = http.NewRequestWithContext(t.Context(), "GET", "http://localhost:1234/", nil)
require.NoError(t, err)
res, err = http.DefaultClient.Do(req)
require.NoError(t, err)
require.Equal(t, http.StatusServiceUnavailable, res.StatusCode)

req, err = http.NewRequestWithContext(t.Context(), "GET", "http://localhost:1234/unknown", nil)
require.NoError(t, err)
res, err = http.DefaultClient.Do(req)
require.NoError(t, err)
require.Equal(t, http.StatusServiceUnavailable, res.StatusCode)
}()

ibhr.Stop()
Expand Down
43 changes: 33 additions & 10 deletions main_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,9 +37,9 @@ const (
)

func TestMain(m *testing.M) {
os.Exit(testscript.RunMain(m, map[string]func() int{
"chainlink": core.Main,
}))
testscript.Main(m, map[string]func(){
"chainlink": func() { os.Exit(core.Main()) },
})
}

var (
Expand All @@ -58,21 +58,43 @@ func TestScripts(t *testing.T) {
if testing.Short() {
t.Skip("skipping testscript")
}
t.Parallel()

require.NoError(t, os.Setenv("TMPDIR", "/tmp")) // osx default is too long for go-plugin sockets
tmp := t.TempDir()
require.NoError(t, os.Setenv("GOTMPDIR", tmp))
t.Cleanup(func() {
require.NoError(t, os.Unsetenv("GOTMPDIR"))
})
t.Parallel()

visitor := txtar.NewDirVisitor("testdata/scripts", txtar.Recurse, func(path string) error {
t.Run(strings.TrimPrefix(path, "testdata/scripts/"), func(t *testing.T) {
t.Parallel()
if message, shouldSkip := skipFlakyTests[t.Name()]; shouldSkip {
t.Skipf("Flaky Test: %s", message)

// Check each .txtar file against skipFlakyTests
matches, err := filepath.Glob(filepath.Join(path, "*.txtar"))
require.NoError(t, err)

var filesToRun []string
for _, match := range matches {
scriptName := strings.TrimSuffix(filepath.Base(match), ".txtar")
fullTestName := t.Name() + "/" + scriptName

if message, shouldSkip := skipFlakyTests[fullTestName]; shouldSkip {
t.Logf("Skipping Flaky Test: %s - %s", fullTestName, message)
continue
}
filesToRun = append(filesToRun, match)
}

if len(filesToRun) == 0 {
t.Skip("all scripts in directory skipped")
}

testscript.Run(t, testscript.Params{
Dir: path,
Setup: commonEnv(t),
ContinueOnError: true,
Files: filesToRun,
Setup: commonEnv(t),
ContinueOnError: true,
RequireExplicitExec: true,
// UpdateScripts: true, // uncomment to update golden files
})
})
Expand All @@ -96,6 +118,7 @@ func commonEnv(t testing.TB) func(*testscript.Env) error {
te.Setenv("VERSION", static.Version)
te.Setenv("VERSION_TAG", static.VersionTag)
te.Setenv("COMMIT_SHA", static.Sha)
te.Setenv("TMPDIR", "/tmp") // osx default is too long for go-plugin sockets

b, err := os.ReadFile(filepath.Join(te.WorkDir, testPortName))
if err != nil && !os.IsNotExist(err) {
Expand Down
1 change: 1 addition & 0 deletions tools/txtar/testdata/callback_error/test.txtar
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
txtar
Empty file.
1 change: 1 addition & 0 deletions tools/txtar/testdata/ignore_empty/empty/readme.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
txtar
1 change: 1 addition & 0 deletions tools/txtar/testdata/ignore_empty/scripts/test.txtar
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
txtar
1 change: 1 addition & 0 deletions tools/txtar/testdata/no_recurse_nested/nested/test.txtar
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
txtar
1 change: 1 addition & 0 deletions tools/txtar/testdata/no_recurse_root/nested/test.txtar
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
txtar
1 change: 1 addition & 0 deletions tools/txtar/testdata/no_recurse_root/root.txtar
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
txtar
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
txtar
1 change: 1 addition & 0 deletions tools/txtar/testdata/recurse_includes_root/root.txtar
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
txtar
1 change: 1 addition & 0 deletions tools/txtar/testdata/recurse_nested/a/test.txtar
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
txtar
1 change: 1 addition & 0 deletions tools/txtar/testdata/recurse_nested/b/readme.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
txtar
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
txtar
1 change: 1 addition & 0 deletions tools/txtar/testdata/suffix_matches/weird/foo_txtar
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
txtar
37 changes: 12 additions & 25 deletions tools/txtar/visitor.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ package txtar

import (
"io/fs"
"os"
"path/filepath"
)

Expand All @@ -20,7 +19,8 @@ type DirVisitor struct {
}

func (d *DirVisitor) Walk() error {
return filepath.WalkDir(d.rootDir, func(path string, de fs.DirEntry, err error) error {
root := filepath.Clean(d.rootDir)
return filepath.WalkDir(root, func(path string, de fs.DirEntry, err error) error {
if err != nil {
return err
}
Expand All @@ -29,42 +29,29 @@ func (d *DirVisitor) Walk() error {
return nil
}

isRootDir, err := d.isRootDir(de)
if err != nil {
return err
}

// If we're not recursing, skip all other directories except the root.
if !bool(d.recurse) && !isRootDir {
return nil
if !bool(d.recurse) && filepath.Clean(path) != root {
Comment thread
jmank88 marked this conversation as resolved.
return fs.SkipDir
}

matches, err := fs.Glob(os.DirFS(path), "*txtar")
matches, err := filepath.Glob(filepath.Join(path, "*txtar"))
if err != nil {
return err
}

if len(matches) > 0 {
return d.cb(path)
if err := d.cb(path); err != nil {
return err
}
}

if !bool(d.recurse) {
return fs.SkipDir
}

return nil
})
}

func (d *DirVisitor) isRootDir(de fs.DirEntry) (bool, error) {
fi, err := os.Stat(d.rootDir)
if err != nil {
return false, err
}

fi2, err := de.Info()
if err != nil {
return false, err
}
return os.SameFile(fi, fi2), nil
}

func NewDirVisitor(rootDir string, recurse RecurseOpt, cb func(path string) error) *DirVisitor {
return &DirVisitor{
rootDir: rootDir,
Expand Down
116 changes: 116 additions & 0 deletions tools/txtar/visitor_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
package txtar

import (
"errors"
"path/filepath"
"slices"
"testing"

"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)

func collectTxtarDirs(t *testing.T, root string, recurse RecurseOpt) []string {
t.Helper()

var dirs []string
visitor := NewDirVisitor(root, recurse, func(path string) error {
rel, err := filepath.Rel(root, path)
require.NoError(t, err)
dirs = append(dirs, rel)
return nil
})
require.NoError(t, visitor.Walk())

slices.Sort(dirs)
return dirs
}

func TestDirVisitor_Walk(t *testing.T) {
t.Parallel()

tests := []struct {
name string
testDir string
recurse RecurseOpt
wantDirs []string
}{
{
name: "recurse finds nested txtar directories",
testDir: "recurse_nested",
recurse: Recurse,
wantDirs: []string{"a", "nested/deep"},
},
{
name: "no recurse only visits root directory",
testDir: "no_recurse_root",
recurse: NoRecurse,
wantDirs: []string{"."},
},
{
name: "no recurse skips nested txtar directories",
testDir: "no_recurse_nested",
recurse: NoRecurse,
wantDirs: nil,
},
{
name: "recurse includes root when it contains txtar files",
testDir: "recurse_includes_root",
recurse: Recurse,
wantDirs: []string{".", "child"},
},
{
name: "directories without txtar files are ignored",
testDir: "ignore_empty",
recurse: Recurse,
wantDirs: []string{"scripts"},
},
{
name: "empty root returns no directories",
testDir: "empty_root",
recurse: Recurse,
wantDirs: nil,
},
{
name: "*txtar suffix matches non dotted extensions",
testDir: "suffix_matches",
recurse: Recurse,
wantDirs: []string{"weird"},
},
}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
t.Parallel()

root := filepath.Join("testdata", tt.testDir)
got := collectTxtarDirs(t, root, tt.recurse)
assert.Equal(t, tt.wantDirs, got)
})
}
}

func TestDirVisitor_Walk_callbackError(t *testing.T) {
t.Parallel()

root := filepath.Join("testdata", "callback_error")

wantErr := errors.New("callback failed")
visitor := NewDirVisitor(root, Recurse, func(string) error {
return wantErr
})

assert.ErrorIs(t, visitor.Walk(), wantErr)
}

func TestDirVisitor_Walk_missingRoot(t *testing.T) {
t.Parallel()

root := filepath.Join("testdata", "missing_root_dir_that_does_not_exist")
visitor := NewDirVisitor(root, Recurse, func(string) error {
t.Fatal("callback should not run")
return nil
})

assert.Error(t, visitor.Walk())
}
Loading