Repository: hashicorp/nomad
File: nomad/encrypter_test.go (Go)

Code before:
	// Create a valid and correctly formatted key and wrap it.
	key, err := structs.NewUnwrappedRootKey(structs.EncryptionAlgorithmAES256GCM)
	must.NoError(t, err)

	wrappedKey, err := encrypter.wrapRootKey(key, true)
	must.NoError(t, err)

	timeoutCtx, timeoutCancel := context.WithTimeout(context.Background(), 2*time.Second)
	t.Cleanup(timeoutCancel)

	// Add the wrapped key to the encrypter and assert that the key is added to
	// the keyring and no decryption tasks are queued.
	must.NoError(t, encrypter.AddWrappedKey(timeoutCtx, wrappedKey))
	must.NoError(t, encrypter.IsReady(timeoutCtx))
	must.MapEmpty(t, encrypter.decryptTasks)
	must.MapLen(t, 1, encrypter.keyring)
	must.MapContainsKey(t, encrypter.keyring, key.Meta.KeyID)

	timeoutCtx, timeoutCancel = context.WithTimeout(context.Background(), 2*time.Second)
	t.Cleanup(timeoutCancel)

	// Add the same key again and assert that the key is not added to the
	// keyring and no decryption tasks are queued.
	must.NoError(t, encrypter.AddWrappedKey(timeoutCtx, wrappedKey))
	must.NoError(t, encrypter.IsReady(timeoutCtx))
	must.MapEmpty(t, encrypter.decryptTasks)
	must.MapLen(t, 1, encrypter.keyring)
	must.MapContainsKey(t, encrypter.keyring, key.Meta.KeyID)
}

func TestEncrypter_AddWrappedKey_sameKeyConcurrent(t *testing.T) {
	ci.Parallel(t)

	srv := &Server{
		logger: testlog.HCLogger(t),
		config: &Config{},
	}

	encrypter, err := NewEncrypter(srv, t.TempDir())
	must.NoError(t, err)

	// Create a valid and correctly formatted key and wrap it.
	key, err := structs.NewUnwrappedRootKey(structs.EncryptionAlgorithmAES256GCM)
	must.NoError(t, err)

	wrappedKey, err := encrypter.wrapRootKey(key, true)
	must.NoError(t, err)

	timeoutCtx, timeoutCancel := context.WithTimeout(context.Background(), 5*time.Second)
	t.Cleanup(timeoutCancel)


Review comment (suggestion):
It might be a good idea to swap these two lines. It's a bit of a racy test anyways (no way to avoid that I think) but if we assert there's no decrypt task _before_ we wait for `IsReady`, it makes the intent a little more clear.

Code after:
	// Create a valid and correctly formatted key and wrap it.
	key, err := structs.NewUnwrappedRootKey(structs.EncryptionAlgorithmAES256GCM)
	must.NoError(t, err)

	wrappedKey, err := encrypter.wrapRootKey(key, true)
	must.NoError(t, err)

	timeoutCtx, timeoutCancel := context.WithTimeout(context.Background(), 2*time.Second)
	t.Cleanup(timeoutCancel)

	// Add the wrapped key to the encrypter and assert that the key is added to
	// the keyring and no decryption tasks are queued.
	must.NoError(t, encrypter.AddWrappedKey(timeoutCtx, wrappedKey))
	must.MapEmpty(t, encrypter.decryptTasks)
	must.NoError(t, encrypter.IsReady(timeoutCtx))
	must.MapLen(t, 1, encrypter.keyring)
	must.MapContainsKey(t, encrypter.keyring, key.Meta.KeyID)

	timeoutCtx, timeoutCancel = context.WithTimeout(context.Background(), 2*time.Second)
	t.Cleanup(timeoutCancel)

	// Add the same key again and assert that the key is not added to the
	// keyring and no decryption tasks are queued.
	must.NoError(t, encrypter.AddWrappedKey(timeoutCtx, wrappedKey))
	must.MapEmpty(t, encrypter.decryptTasks)
	must.NoError(t, encrypter.IsReady(timeoutCtx))
	must.MapLen(t, 1, encrypter.keyring)
	must.MapContainsKey(t, encrypter.keyring, key.Meta.KeyID)
}

func TestEncrypter_AddWrappedKey_sameKeyConcurrent(t *testing.T) {
	ci.Parallel(t)

	srv := &Server{
		logger: testlog.HCLogger(t),
		config: &Config{},
	}

	encrypter, err := NewEncrypter(srv, t.TempDir())
	must.NoError(t, err)

	// Create a valid and correctly formatted key and wrap it.
	key, err := structs.NewUnwrappedRootKey(structs.EncryptionAlgorithmAES256GCM)
	must.NoError(t, err)

	wrappedKey, err := encrypter.wrapRootKey(key, true)
	must.NoError(t, err)

	timeoutCtx, timeoutCancel := context.WithTimeout(context.Background(), 5*time.Second)
	t.Cleanup(timeoutCancel)