Hash passwords with 1 MiB in tests so make test fits in 4 GiB (closes #261)
Check / check (pull_request) Skipped

On a build machine with 4 GiB, docker build . failed: the auth test
binary was killed for lack of memory. upaasd hashes passwords with
argon2id at 64 MiB per hash; the auth and handlers tests run many such
hashes at once, and the race detector multiplies what each one takes,
so make test peaked at 2.7 GiB.

The memory per hash is now the auth service's ArgonMemory field. New
sets it to the same 64 MiB, which upaasd keeps; the test helpers lower
it to 1 MiB. A new test checks that New sets 64 MiB and hashes and
verifies a password with it. GOMAXPROCS=4 make test now peaks at about
1.4 GiB.

Model: opus-5-5
This commit is contained in:
2026-10-03 00:37:04 +00:00
parent d3b9c6fca9
commit 55795ddfc4
4 changed files with 42 additions and 6 deletions
+3
View File
@@ -109,6 +109,9 @@ func createAppServices(
})
require.NoError(t, authErr)
// 1 MiB per password hash instead of 64 MiB; see auth.Service.ArgonMemory.
authSvc.ArgonMemory = 1024
appSvc, appErr := app.New(fx.Lifecycle(nil), app.ServiceParams{
Logger: logInstance,
Database: dbInstance,
+14 -6
View File
@@ -59,6 +59,13 @@ type ServiceParams struct {
// Service provides authentication functionality.
type Service struct {
// ArgonMemory is the memory each argon2id hash takes, in KiB. New sets
// argonMemory, 64 MiB, and upaasd never changes it. Tests lower it, since
// many 64 MiB hashes at once under the race detector need more memory
// than a 4 GiB build machine has. A hash verifies only with the value it
// was made with.
ArgonMemory uint32
log *slog.Logger
db *database.Database
store *sessions.CookieStore
@@ -77,10 +84,11 @@ func New(_ fx.Lifecycle, params ServiceParams) (*Service, error) {
}
return &Service{
log: params.Logger.Get(),
db: params.Database,
store: store,
params: &params,
ArgonMemory: argonMemory,
log: params.Logger.Get(),
db: params.Database,
store: store,
params: &params,
}, nil
}
@@ -97,7 +105,7 @@ func (svc *Service) HashPassword(password string) (string, error) {
[]byte(password),
salt,
argonTime,
argonMemory,
svc.ArgonMemory,
argonThreads,
argonKeyLen,
)
@@ -132,7 +140,7 @@ func (svc *Service) VerifyPassword(hashedPassword, password string) bool {
[]byte(password),
salt,
argonTime,
argonMemory,
svc.ArgonMemory,
argonThreads,
argonKeyLen,
)
+19
View File
@@ -65,6 +65,10 @@ func setupTestService(t *testing.T) (*auth.Service, func()) {
})
require.NoError(t, err)
// 1 MiB per hash instead of 64 MiB; see Service.ArgonMemory. The tests
// that use setupAuthService keep 64 MiB.
svc.ArgonMemory = 1024
// t.TempDir() automatically cleans up after test
cleanup := func() {}
@@ -237,6 +241,21 @@ func TestVerifyPassword(testingT *testing.T) {
})
}
// TestHashPasswordWithUpaasdMemory hashes and verifies a password with the
// memory New sets, which upaasd uses. setupTestService lowers it.
func TestHashPasswordWithUpaasdMemory(t *testing.T) {
t.Parallel()
svc := setupAuthService(t, false)
require.Equal(t, uint32(64*1024), svc.ArgonMemory)
hash, err := svc.HashPassword("correctpassword")
require.NoError(t, err)
assert.True(t, svc.VerifyPassword(hash, "correctpassword"))
assert.False(t, svc.VerifyPassword(hash, "wrongpassword"))
}
func TestIsSetupRequired(testingT *testing.T) {
testingT.Parallel()