Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitaly.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPavlo Strokov <pstrokov@gitlab.com>2022-12-18 20:28:27 +0300
committerPavlo Strokov <pavlo@Pavlos-MacBook-Pro-5.local>2022-12-21 19:31:04 +0300
commite4c3c8db13a365e9d228eea6e33e0b25e31fd94d (patch)
treec910d22e600f555635fffa40480f6e1e5a17b9b9
parent6f1d5675c7c55c6a2984736534a346c799e5913b (diff)
command: Test the 'too many open files' error is returnedps-resource-exhausted-fd
We have statushandler middleware that changes status code of the RPC depending on different conditions. One of such conditions is the syscall.EMFILE error. This test is added to make sure this particular error is returned when there is no more file descriptors available. Otherwise, the statushandler middleware needs to be adjusted to catch the proper error. Part of: https://gitlab.com/gitlab-org/gitaly/-/issues/4688
-rw-r--r--internal/git/command_factory_test.go58
1 files changed, 58 insertions, 0 deletions
diff --git a/internal/git/command_factory_test.go b/internal/git/command_factory_test.go
index 3356fe467..a310164c5 100644
--- a/internal/git/command_factory_test.go
+++ b/internal/git/command_factory_test.go
@@ -12,9 +12,12 @@ import (
"os"
"os/exec"
"path/filepath"
+ "reflect"
"strings"
+ "syscall"
"testing"
+ "github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"gitlab.com/gitlab-org/gitaly/v15/internal/git"
"gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest"
@@ -703,3 +706,58 @@ func TestFsckConfiguration(t *testing.T) {
})
}
}
+
+// TestExecCommandFactory_tooManyOpenFileDescriptors test exists to make sure the system
+// returns an expected syscall.EMFILE error when there is a problem with FD as the
+// middleware in internal/middleware/statushandler/statushandler.go heavily depends on it.
+func TestExecCommandFactory_tooManyOpenFileDescriptors(t *testing.T) {
+ // Do not run this test with t.Parallel(). The test setup affects settings of the
+ // current process and may lead to other tests failures.
+ ctx := testhelper.Context(t)
+
+ // setCur changes value of the Cur field of the Rlimit type.
+ // It is needed because on different OS this field represented by different types.
+ // Currently only by two: uint64, int64. That is why we use reflection to change the value.
+ setCur := func(t *testing.T, rl syscall.Rlimit, val int) syscall.Rlimit {
+ var cur interface{} = rl.Cur
+ switch cur.(type) {
+ case uint64:
+ reflect.ValueOf(&rl.Cur).Elem().SetUint(uint64(val))
+ case int64:
+ reflect.ValueOf(&rl.Cur).Elem().SetInt(int64(val))
+ default:
+ require.FailNowf(t, "code needs to be changed", "please add a new type: %T", rl.Cur)
+ }
+ return rl
+ }
+
+ setOpenFilesLimit := func(t *testing.T, limit int) {
+ // This is a flag for the resource to limit. In that case: open file descriptors.
+ const flag = syscall.RLIMIT_NOFILE
+ var rlim syscall.Rlimit
+ require.NoError(t, syscall.Getrlimit(flag, &rlim))
+ t.Cleanup(func() {
+ require.NoError(t, syscall.Setrlimit(flag, &rlim))
+ })
+ newRLimit := setCur(t, rlim, limit)
+ require.NoError(t, syscall.Setrlimit(flag, &newRLimit))
+ }
+
+ cfg, repo, _ := testcfg.BuildWithRepo(t)
+ factory, finish, err := git.NewExecCommandFactory(cfg)
+ require.NoError(t, err)
+ t.Cleanup(finish)
+
+ setOpenFilesLimit(t, 10)
+
+ // It is enough to run whatever command usually as the limit is really low.
+ cmd, err := factory.New(ctx, repo, git.Command{
+ Name: "show",
+ Args: []string{"HEAD"},
+ })
+ if !assert.Error(t, err) {
+ _ = cmd.Wait() // we don't care about an error here as it shouldn't happen
+ return
+ }
+ require.ErrorIs(t, err, syscall.EMFILE) // too many open files
+}