Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

services/horizon: Add some manual-close improvements to integration tests #3171

Merged
merged 2 commits into from
Oct 29, 2020
Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
84 changes: 54 additions & 30 deletions services/horizon/internal/test/integration/integration.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import (
"os"
"os/signal"
"strconv"
"sync"
"syscall"
"testing"
"time"
Expand Down Expand Up @@ -412,7 +413,7 @@ func createTestContainer(i *Test, image string) error {
t.Log(" trying to find local image (might be out-dated)")

args := filters.NewArgs()
args.Add("reference", "stellar/quickstart:testing")
args.Add("reference", image)
list, innerErr := i.cli.ImageList(ctx, types.ImageListOptions{Filters: args})
if innerErr != nil || len(list) == 0 {
t.Fatal(errors.Wrap(err, "failed to find local image"))
Expand Down Expand Up @@ -655,43 +656,59 @@ func (i *Test) CreateSignedTransaction(
}

// CloseCoreLedgersUntilSequence will close ledgers until sequence.
// Note: because manualclose command doesn't block until ledger is actually
// closed, after running this method the last sequence can be higher than seq.
func (i *Test) CloseCoreLedgersUntilSequence(seq int) error {
currentLedger, err := i.GetCurrentCoreLedgerSequence()
if err != nil {
return err
}
for ; currentLedger < seq; currentLedger++ {
if err = i.CloseCoreLedger(); err != nil {
return err
}
}
return nil
}

// CloseCoreLedger will synchronously close one ledger.
// Note: because manualclose command doesn't block until ledger is actually
// closed, this method may end up closing multiple ledgers
func (i *Test) CloseCoreLedger() error {
i.t.Log("Closing one ledger manually...")
currentLedgerNum, err := i.GetCurrentCoreLedgerSequence()
if err != nil {
return err
}
targetLedgerNum := currentLedgerNum + 1
// manualclose command in core doesn't currently block until ledger is actually
// closed. So, we loop until we are certain it happened.
for {
ctx, cancel := context.WithTimeout(context.Background(), time.Second)
defer cancel()
info, err := i.cclient.Info(ctx)
err = i.cclient.ManualClose(ctx)
cancel()
if err != nil {
return err
}

if info.Info.Ledger.Num >= seq {
return nil
}

i.t.Logf(
"Currently at ledger: %d, want: %d.",
info.Info.Ledger.Num,
seq,
)

err = i.CloseCoreLedger()
currentLedgerNum, err = i.GetCurrentCoreLedgerSequence()
if err != nil {
return err
}
// manualclose command in core doesn't block until ledger is actually
// closed. Let's give it time to close the ledger.
time.Sleep(200 * time.Millisecond)
if currentLedgerNum >= targetLedgerNum {
return nil
}
// pace ourselves
time.Sleep(50 * time.Millisecond)
}
return nil
}

// CloseCoreLedgers will close one ledger.
func (i *Test) CloseCoreLedger() error {
func (i *Test) GetCurrentCoreLedgerSequence() (int, error) {
ctx, cancel := context.WithTimeout(context.Background(), time.Second)
defer cancel()
i.t.Log("Closing one ledger manually...")
return i.cclient.ManualClose(ctx)
info, err := i.cclient.Info(ctx)
if err != nil {
return 0, err
}
return info.Info.Ledger.Num, nil
}

func (i *Test) SubmitTransaction(tx *txnbuild.Transaction) (proto.Transaction, error) {
Expand All @@ -703,19 +720,26 @@ func (i *Test) SubmitTransaction(tx *txnbuild.Transaction) (proto.Transaction, e
}

func (i *Test) SubmitTransactionXDR(txb64 string) (proto.Transaction, error) {
// Core runs in manual-close mode, so we need to close ledgers explicitly
// We need to close the ledger in parallel because Horizon's submission endpoint
// blocks until the transaction is in a closed ledger
// Core runs in manual-close mode to run tests faster, so we need to explicitly
// close the ledgers after a submission is sent.
// We need to close the ledger in parallel to the submission,
// because Horizon's submission endpoint blocks until the transaction
// is in a closed ledger
var wg sync.WaitGroup
wg.Add(1)
go func() {
defer wg.Done()
// Wait for Horizon to submit the transaction to Core.
// This sleep is ugly, but a better approach would probably require
// instrumenting Horizon to tell us when the transaction was sent to core.
// instrumenting Horizon to tell us when the submission is done.
time.Sleep(time.Millisecond * 100)
if err := i.CloseCoreLedger(); err != nil {
log.Fatalf("failed to CloseCoreLedger(): %s", err)
}
}()

return i.Client().SubmitTransactionXDR(txb64)
tx, err := i.Client().SubmitTransactionXDR(txb64)
wg.Wait()
2opremio marked this conversation as resolved.
Show resolved Hide resolved
return tx, err
}

// A convenience function to provide verbose information about a failing
Expand Down