Skip to content

Commit

Permalink
Refactor TestMissingObjects
Browse files Browse the repository at this point in the history
  • Loading branch information
spraints committed Nov 8, 2024
1 parent 20bb13d commit a10726f
Showing 1 changed file with 92 additions and 45 deletions.
137 changes: 92 additions & 45 deletions internal/integration/missingobjects_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,37 +13,97 @@ import (
"testing"
"time"

"github.com/github/spokes-receive-pack/internal/objectformat"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)

func TestMissingObjects(t *testing.T) {
var info struct {
x := setUpMissingObjectsTestRepo(t)
testRepo := x.TestRepo
info := x.Info

ctx, cancel := context.WithTimeout(context.Background(), time.Second)
defer cancel()

srp := startSpokesReceivePack(ctx, t, testRepo)

refs, _, err := readAdv(srp.Out)
require.NoError(t, err)
assert.Equal(t, refs, map[string]string{
info.Ref: info.OldOID,
info.DelRef: info.OldOID,
})

// Send the pack that's missing a commit.
pack, err := os.Open("testdata/missing-objects/bad.pack")
require.NoError(t, err)
defer pack.Close()

writePushData(
t, srp,
[]refUpdate{
// Try to update the ref that's already there to commit C (but we won't
// push its parent and the remote doesn't have the parent either).
{info.OldOID, info.NewOID, info.Ref},
// Try to create another ref with a commit that the remote already has.
{objectformat.NullOIDSHA1, info.OldOID, "refs/heads/new-branch"},
// Try to delete another ref.
{info.OldOID, objectformat.NullOIDSHA1, info.DelRef},
},
pack,
)

refStatus, unpackRes, _, err := readResult(t, srp.Out)
require.NoError(t, err)
assert.Equal(t, map[string]string{
info.Ref: "ng missing necessary objects",
info.DelRef: "ok",
refToCreate: "ok",

Check failure on line 62 in internal/integration/missingobjects_test.go

View workflow job for this annotation

GitHub Actions / test

undefined: refToCreate
}, refStatus)
assert.Equal(t, "unpack ok\n", unpackRes)
}

type missingObjectsTestInfo struct {
TestRepo string
Info struct {
OldOID string `json:"push_from"`
NewOID string `json:"push_to"`
Ref string `json:"ref"`
DelRef string `json:"extra_ref"`
}
}

func setUpMissingObjectsTestRepo(t *testing.T) missingObjectsTestInfo {
const (
remote = "testdata/missing-objects/remote.git"
badPack = "testdata/missing-objects/bad.pack"
infoFile = "testdata/missing-objects/info.json"
refToCreate = "refs/heads/new-branch"
remote = "testdata/missing-objects/remote.git"
badPack = "testdata/missing-objects/bad.pack"
infoFile = "testdata/missing-objects/info.json"
)

var res missingObjectsTestInfo

infoJSON, err := os.ReadFile(infoFile)
require.NoError(t, err)
require.NoError(t, json.Unmarshal(infoJSON, &info))
require.NoError(t, json.Unmarshal(infoJSON, &res.Info))

origin, err := filepath.Abs(remote)
require.NoError(t, err)

testRepo := t.TempDir()
requireRun(t, "git", "clone", "--mirror", origin, testRepo)
res.TestRepo = t.TempDir()
requireRun(t, "git", "clone", "--mirror", origin, res.TestRepo)

ctx, cancel := context.WithTimeout(context.Background(), time.Second)
defer cancel()
return res
}

type spokesReceivePackProcess struct {
Cmd *exec.Cmd
In io.WriteCloser
Out io.Reader
Err chan error
}

func startSpokesReceivePack(ctx context.Context, t *testing.T, testRepo string) spokesReceivePackProcess {
srp := exec.CommandContext(ctx, "spokes-receive-pack", ".")
srp.Dir = testRepo
srp.Env = append(os.Environ(),
Expand All @@ -59,47 +119,34 @@ func TestMissingObjects(t *testing.T) {

bufSRPOut := bufio.NewReader(srpOut)

refs, _, err := readAdv(bufSRPOut)
require.NoError(t, err)
assert.Equal(t, refs, map[string]string{
info.Ref: info.OldOID,
info.DelRef: info.OldOID,
})

// Try to update the ref that's already there to commit C (but we won't
// push its parent and the remote doesn't have the parent either).
require.NoError(t, writePktlinef(srpIn,
"%s %s %s\x00report-status report-status-v2 side-band-64k object-format=sha1\n",
info.OldOID, info.NewOID, info.Ref))
return spokesReceivePackProcess{
Cmd: srp,
In: srpIn,
Out: bufSRPOut,
Err: srpErr,
}
}

// Try to create another ref with a commit that the remote already has.
require.NoError(t, writePktlinef(srpIn,
"%040d %s %s",
0, info.OldOID, refToCreate))
type refUpdate struct {
OldOID, NewOID, Ref string
}

// Try to delete another ref.
require.NoError(t, writePktlinef(srpIn,
"%s %040d %s",
info.OldOID, 0, info.DelRef))
func writePushData(t *testing.T, srp spokesReceivePackProcess, updates []refUpdate, pack io.Reader) {
caps := "\x00report-status report-status-v2 side-band-64k object-format=sha1\n"
for _, up := range updates {
require.NoError(t, writePktlinef(srp.In,
"%s %s %s%s",
up.OldOID, up.NewOID, up.Ref,
caps))
caps = ""
}

_, err = srpIn.Write([]byte("0000"))
_, err := srp.In.Write([]byte("0000"))
require.NoError(t, err)

// Send the pack that's missing a commit.
pack, err := os.Open("testdata/missing-objects/bad.pack")
require.NoError(t, err)
if _, err := io.Copy(srpIn, pack); err != nil {
if _, err := io.Copy(srp.In, pack); err != nil {
t.Logf("error writing pack to spokes-receive-pack input: %v", err)
}

require.NoError(t, srpIn.Close())

refStatus, unpackRes, _, err := readResult(t, bufSRPOut)
require.NoError(t, err)
assert.Equal(t, map[string]string{
info.Ref: "ng missing necessary objects",
info.DelRef: "ok",
refToCreate: "ok",
}, refStatus)
assert.Equal(t, "unpack ok\n", unpackRes)
require.NoError(t, srp.In.Close())
}

0 comments on commit a10726f

Please sign in to comment.