Tighten opaque plugin content boundaries
This commit is contained in:
@@ -1,9 +1,12 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/base64"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"sync"
|
||||
"testing"
|
||||
@@ -11,6 +14,7 @@ import (
|
||||
|
||||
"browser.local/platform/domain"
|
||||
"browser.local/platform/repo"
|
||||
"browser.local/platform/validator"
|
||||
)
|
||||
|
||||
type captureDistributionBuilder struct {
|
||||
@@ -25,6 +29,11 @@ type progressDistributionBuilder struct {
|
||||
payload []byte
|
||||
}
|
||||
|
||||
type fileDistributionBuilder struct {
|
||||
inputs chan domain.DistributionBuildInput
|
||||
outputPath string
|
||||
}
|
||||
|
||||
func (builder captureDistributionBuilder) Readiness() (bool, string) {
|
||||
return true, ""
|
||||
}
|
||||
@@ -58,6 +67,28 @@ func (builder progressDistributionBuilder) BuildWithProgress(_ domain.Distributi
|
||||
return domain.CopyBytes(builder.payload), nil
|
||||
}
|
||||
|
||||
func (builder fileDistributionBuilder) Readiness() (bool, string) {
|
||||
return true, ""
|
||||
}
|
||||
|
||||
func (builder fileDistributionBuilder) Build(domain.DistributionBuildInput) ([]byte, error) {
|
||||
return nil, errors.New("byte build path should not be used for file output builders")
|
||||
}
|
||||
|
||||
func (builder fileDistributionBuilder) BuildFile(input domain.DistributionBuildInput, progress func(DistributionBuildProgress)) (DistributionBuildOutput, error) {
|
||||
if progress != nil {
|
||||
progress(DistributionBuildProgress{Percent: 88, Message: "package_finalize: output file ready"})
|
||||
}
|
||||
if builder.inputs != nil {
|
||||
builder.inputs <- input
|
||||
}
|
||||
sizeBytes, checksum, err := fileSizeAndChecksum(builder.outputPath)
|
||||
if err != nil {
|
||||
return DistributionBuildOutput{}, err
|
||||
}
|
||||
return DistributionBuildOutput{Path: builder.outputPath, SizeBytes: sizeBytes, Checksum: checksum}, nil
|
||||
}
|
||||
|
||||
func TestCoreServiceKeepsPlatformBuildKeyOffMachineJobChannel(t *testing.T) {
|
||||
svc, session, instance := newDistributionTestFixture(t)
|
||||
plugin, err := svc.store.GamePlugins().Get(instance.PluginID)
|
||||
@@ -393,6 +424,47 @@ func TestCoreServiceProjectsPlatformBuilderProgressBeforeCompletion(t *testing.T
|
||||
completeDistributionBuild(t, svc, distribution, nil)
|
||||
}
|
||||
|
||||
func TestCoreServiceStoresPlatformBuildFileOutput(t *testing.T) {
|
||||
svc, session, instance := newDistributionTestFixture(t)
|
||||
outputPath := filepath.Join(t.TempDir(), "run")
|
||||
payload := bytes.Repeat([]byte("platform-build-file-output"), 8192)
|
||||
if err := os.WriteFile(outputPath, payload, 0o600); err != nil {
|
||||
t.Fatalf("write builder file output: %v", err)
|
||||
}
|
||||
inputs := make(chan domain.DistributionBuildInput, 1)
|
||||
svc.ConfigureDistributionBuilder(fileDistributionBuilder{inputs: inputs, outputPath: outputPath})
|
||||
|
||||
distribution, err := svc.GenerateRunDistributionForSession(session, domain.RunDistributionGenerateRequest{
|
||||
ServerInstanceID: instance.ID,
|
||||
TargetOS: "linux",
|
||||
TargetArch: "amd64",
|
||||
IdempotencyKey: "platform-builder-file-output",
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("generate platform distribution: %v", err)
|
||||
}
|
||||
select {
|
||||
case <-inputs:
|
||||
case <-time.After(time.Second):
|
||||
t.Fatal("platform file builder did not receive internal build input")
|
||||
}
|
||||
distribution = completeDistributionBuild(t, svc, distribution, nil)
|
||||
artifact, err := svc.GetArtifact(distribution.ArtifactID)
|
||||
if err != nil {
|
||||
t.Fatalf("get distribution artifact: %v", err)
|
||||
}
|
||||
if artifact.SizeBytes != int64(len(payload)) || artifact.Checksum != validator.BytesChecksum(payload) {
|
||||
t.Fatalf("artifact metadata did not come from file output: %+v", artifact)
|
||||
}
|
||||
stored, err := svc.artifactStore.GetPayload(distribution.ArtifactID)
|
||||
if err != nil {
|
||||
t.Fatalf("get stored distribution payload: %v", err)
|
||||
}
|
||||
if !bytes.Equal(stored, payload) {
|
||||
t.Fatalf("stored distribution payload changed during file-backed recording")
|
||||
}
|
||||
}
|
||||
|
||||
func TestCoreServiceDiscardsBuildCompletedAfterKeyReset(t *testing.T) {
|
||||
svc, session, instance := newDistributionTestFixture(t)
|
||||
inputs := make(chan domain.DistributionBuildInput, 1)
|
||||
|
||||
Reference in New Issue
Block a user