diff --git a/cmd/soroban-rpc/internal/test/archive_test.go b/cmd/soroban-rpc/internal/test/archive_test.go new file mode 100644 index 00000000..2840881e --- /dev/null +++ b/cmd/soroban-rpc/internal/test/archive_test.go @@ -0,0 +1,25 @@ +package test + +import ( + "net/http" + "sync" + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestArchiveUserAgent(t *testing.T) { + userAgents := sync.Map{} + cfg := &Test{ + historyArchiveProxyCallback: func(r *http.Request) { + userAgents.Store(r.Header["User-Agent"][0], "") + }, + } + NewTest(t, cfg) + + _, ok := userAgents.Load("testing") + assert.True(t, ok, "rpc service should set user agent for history archives") + + _, ok = userAgents.Load("testing/captivecore") + assert.True(t, ok, "rpc captive core should set user agent for history archives") +} diff --git a/cmd/soroban-rpc/internal/test/cli_test.go b/cmd/soroban-rpc/internal/test/cli_test.go index db138c86..d1a5b901 100644 --- a/cmd/soroban-rpc/internal/test/cli_test.go +++ b/cmd/soroban-rpc/internal/test/cli_test.go @@ -296,7 +296,7 @@ func getCLIDefaultAccount(t *testing.T) string { } func NewCLITest(t *testing.T) *Test { - test := NewTest(t) + test := NewTest(t, nil) fundAccount(t, test, getCLIDefaultAccount(t), "1000000") return test } diff --git a/cmd/soroban-rpc/internal/test/cors_test.go b/cmd/soroban-rpc/internal/test/cors_test.go index 2e0cdb3e..ede91fd8 100644 --- a/cmd/soroban-rpc/internal/test/cors_test.go +++ b/cmd/soroban-rpc/internal/test/cors_test.go @@ -13,7 +13,7 @@ import ( // Specifically, when we include an Origin header in the request, a soroban-rpc should response // with a corresponding Access-Control-Allow-Origin. func TestCORS(t *testing.T) { - test := NewTest(t) + test := NewTest(t, nil) request, err := http.NewRequest("POST", test.sorobanRPCURL(), bytes.NewBufferString("{\"jsonrpc\": \"2.0\", \"id\": 1, \"method\": \"getHealth\"}")) require.NoError(t, err) diff --git a/cmd/soroban-rpc/internal/test/get_ledger_entries_test.go b/cmd/soroban-rpc/internal/test/get_ledger_entries_test.go index 46b0b25d..889b4e04 100644 --- a/cmd/soroban-rpc/internal/test/get_ledger_entries_test.go +++ b/cmd/soroban-rpc/internal/test/get_ledger_entries_test.go @@ -18,7 +18,7 @@ import ( ) func TestGetLedgerEntriesNotFound(t *testing.T) { - test := NewTest(t) + test := NewTest(t, nil) ch := jhttp.NewChannel(test.sorobanRPCURL(), nil) client := jrpc2.NewClient(ch, nil) @@ -56,7 +56,7 @@ func TestGetLedgerEntriesNotFound(t *testing.T) { } func TestGetLedgerEntriesInvalidParams(t *testing.T) { - test := NewTest(t) + test := NewTest(t, nil) ch := jhttp.NewChannel(test.sorobanRPCURL(), nil) client := jrpc2.NewClient(ch, nil) @@ -74,7 +74,7 @@ func TestGetLedgerEntriesInvalidParams(t *testing.T) { } func TestGetLedgerEntriesSucceeds(t *testing.T) { - test := NewTest(t) + test := NewTest(t, nil) ch := jhttp.NewChannel(test.sorobanRPCURL(), nil) client := jrpc2.NewClient(ch, nil) diff --git a/cmd/soroban-rpc/internal/test/get_ledger_entry_test.go b/cmd/soroban-rpc/internal/test/get_ledger_entry_test.go index dd4879d5..b453f4d8 100644 --- a/cmd/soroban-rpc/internal/test/get_ledger_entry_test.go +++ b/cmd/soroban-rpc/internal/test/get_ledger_entry_test.go @@ -18,7 +18,7 @@ import ( ) func TestGetLedgerEntryNotFound(t *testing.T) { - test := NewTest(t) + test := NewTest(t, nil) ch := jhttp.NewChannel(test.sorobanRPCURL(), nil) client := jrpc2.NewClient(ch, nil) @@ -51,7 +51,7 @@ func TestGetLedgerEntryNotFound(t *testing.T) { } func TestGetLedgerEntryInvalidParams(t *testing.T) { - test := NewTest(t) + test := NewTest(t, nil) ch := jhttp.NewChannel(test.sorobanRPCURL(), nil) client := jrpc2.NewClient(ch, nil) @@ -67,7 +67,7 @@ func TestGetLedgerEntryInvalidParams(t *testing.T) { } func TestGetLedgerEntrySucceeds(t *testing.T) { - test := NewTest(t) + test := NewTest(t, nil) ch := jhttp.NewChannel(test.sorobanRPCURL(), nil) client := jrpc2.NewClient(ch, nil) diff --git a/cmd/soroban-rpc/internal/test/get_network_test.go b/cmd/soroban-rpc/internal/test/get_network_test.go index 39805d86..9c8ef266 100644 --- a/cmd/soroban-rpc/internal/test/get_network_test.go +++ b/cmd/soroban-rpc/internal/test/get_network_test.go @@ -12,7 +12,7 @@ import ( ) func TestGetNetworkSucceeds(t *testing.T) { - test := NewTest(t) + test := NewTest(t, nil) ch := jhttp.NewChannel(test.sorobanRPCURL(), nil) client := jrpc2.NewClient(ch, nil) diff --git a/cmd/soroban-rpc/internal/test/health_test.go b/cmd/soroban-rpc/internal/test/health_test.go index 4afbf7f8..517b374d 100644 --- a/cmd/soroban-rpc/internal/test/health_test.go +++ b/cmd/soroban-rpc/internal/test/health_test.go @@ -11,7 +11,7 @@ import ( ) func TestHealth(t *testing.T) { - test := NewTest(t) + test := NewTest(t, nil) ch := jhttp.NewChannel(test.sorobanRPCURL(), nil) client := jrpc2.NewClient(ch, nil) diff --git a/cmd/soroban-rpc/internal/test/integration.go b/cmd/soroban-rpc/internal/test/integration.go index ea918d13..b1e98f85 100644 --- a/cmd/soroban-rpc/internal/test/integration.go +++ b/cmd/soroban-rpc/internal/test/integration.go @@ -3,6 +3,10 @@ package test import ( "context" "fmt" + "net/http" + "net/http/httptest" + "net/http/httputil" + "net/url" "os" "os/exec" "os/signal" @@ -47,6 +51,9 @@ type Test struct { daemon *daemon.Daemon + historyArchiveProxy *httptest.Server + historyArchiveProxyCallback func(*http.Request) + coreClient *stellarcore.Client masterAccount txnbuild.Account @@ -54,7 +61,7 @@ type Test struct { shutdownCalls []func() } -func NewTest(t *testing.T) *Test { +func NewTest(t *testing.T, i *Test) *Test { if os.Getenv("SOROBAN_RPC_INTEGRATION_TESTS_ENABLED") == "" { t.Skip("skipping integration test: SOROBAN_RPC_INTEGRATION_TESTS_ENABLED not set") } @@ -63,14 +70,30 @@ func NewTest(t *testing.T) *Test { t.Fatal("missing SOROBAN_RPC_INTEGRATION_TESTS_CAPTIVE_CORE_BIN") } - i := &Test{ - t: t, - composePath: findDockerComposePath(), + if i == nil { + i = &Test{} } + + i.t = t + i.composePath = findDockerComposePath() i.masterAccount = &txnbuild.SimpleAccount{ AccountID: i.MasterKey().Address(), Sequence: 0, } + + origin, err := url.Parse("http://localhost:1570") + if err != nil { + panic(err) + } + proxy := httputil.NewSingleHostReverseProxy(origin) + + i.historyArchiveProxy = httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + if i.historyArchiveProxyCallback != nil { + i.historyArchiveProxyCallback(r) + } + proxy.ServeHTTP(w, r) + })) + i.runComposeCommand("up", "--detach", "--quiet-pull", "--no-color") i.prepareShutdownHandlers() i.coreClient = &stellarcore.Client{URL: "http://localhost:" + strconv.Itoa(stellarCorePort)} @@ -138,7 +161,7 @@ func (i *Test) launchDaemon(coreBinaryPath string) { config.CaptiveCoreHTTPPort = 0 config.FriendbotURL = friendbotURL config.NetworkPassphrase = StandaloneNetworkPassphrase - config.HistoryArchiveURLs = []string{"http://localhost:1570"} + config.HistoryArchiveURLs = []string{i.historyArchiveProxy.URL} config.LogLevel = logrus.DebugLevel config.SQLiteDBPath = path.Join(i.t.TempDir(), "soroban_rpc.sqlite") config.IngestionTimeout = 10 * time.Minute @@ -146,6 +169,7 @@ func (i *Test) launchDaemon(coreBinaryPath string) { config.CheckpointFrequency = checkpointFrequency config.MaxHealthyLedgerLatency = time.Second * 10 config.PreflightEnableDebug = true + config.HistoryArchiveUserAgent = "testing" i.daemon = daemon.MustNew(&config) go i.daemon.Run() @@ -203,6 +227,9 @@ func (i *Test) prepareShutdownHandlers() { if i.daemon != nil { i.daemon.Close() } + if i.historyArchiveProxy != nil { + i.historyArchiveProxy.Close() + } i.runComposeCommand("down", "-v") }, ) diff --git a/cmd/soroban-rpc/internal/test/metrics_test.go b/cmd/soroban-rpc/internal/test/metrics_test.go index 5608a2f9..b807cb77 100644 --- a/cmd/soroban-rpc/internal/test/metrics_test.go +++ b/cmd/soroban-rpc/internal/test/metrics_test.go @@ -14,7 +14,7 @@ import ( ) func TestMetrics(t *testing.T) { - test := NewTest(t) + test := NewTest(t, nil) metrics := getMetrics(test) buildMetric := fmt.Sprintf( "soroban_rpc_build_info{branch=\"%s\",build_timestamp=\"%s\",commit=\"%s\",goversion=\"%s\",version=\"%s\"} 1", diff --git a/cmd/soroban-rpc/internal/test/simulate_transaction_test.go b/cmd/soroban-rpc/internal/test/simulate_transaction_test.go index 02e46451..12387530 100644 --- a/cmd/soroban-rpc/internal/test/simulate_transaction_test.go +++ b/cmd/soroban-rpc/internal/test/simulate_transaction_test.go @@ -189,7 +189,7 @@ func preflightTransactionParams(t *testing.T, client *jrpc2.Client, params txnbu } func TestSimulateTransactionSucceeds(t *testing.T) { - test := NewTest(t) + test := NewTest(t, nil) ch := jhttp.NewChannel(test.sorobanRPCURL(), nil) client := jrpc2.NewClient(ch, nil) @@ -307,7 +307,7 @@ func TestSimulateTransactionSucceeds(t *testing.T) { } func TestSimulateTransactionWithAuth(t *testing.T) { - test := NewTest(t) + test := NewTest(t, nil) ch := jhttp.NewChannel(test.sorobanRPCURL(), nil) client := jrpc2.NewClient(ch, nil) @@ -365,7 +365,7 @@ func TestSimulateTransactionWithAuth(t *testing.T) { } func TestSimulateInvokeContractTransactionSucceeds(t *testing.T) { - test := NewTest(t) + test := NewTest(t, nil) ch := jhttp.NewChannel(test.sorobanRPCURL(), nil) client := jrpc2.NewClient(ch, nil) @@ -550,7 +550,7 @@ func TestSimulateInvokeContractTransactionSucceeds(t *testing.T) { } func TestSimulateTransactionError(t *testing.T) { - test := NewTest(t) + test := NewTest(t, nil) ch := jhttp.NewChannel(test.sorobanRPCURL(), nil) client := jrpc2.NewClient(ch, nil) @@ -590,7 +590,7 @@ func TestSimulateTransactionError(t *testing.T) { } func TestSimulateTransactionMultipleOperations(t *testing.T) { - test := NewTest(t) + test := NewTest(t, nil) ch := jhttp.NewChannel(test.sorobanRPCURL(), nil) client := jrpc2.NewClient(ch, nil) @@ -625,7 +625,7 @@ func TestSimulateTransactionMultipleOperations(t *testing.T) { } func TestSimulateTransactionWithoutInvokeHostFunction(t *testing.T) { - test := NewTest(t) + test := NewTest(t, nil) ch := jhttp.NewChannel(test.sorobanRPCURL(), nil) client := jrpc2.NewClient(ch, nil) @@ -656,7 +656,7 @@ func TestSimulateTransactionWithoutInvokeHostFunction(t *testing.T) { } func TestSimulateTransactionUnmarshalError(t *testing.T) { - test := NewTest(t) + test := NewTest(t, nil) ch := jhttp.NewChannel(test.sorobanRPCURL(), nil) client := jrpc2.NewClient(ch, nil) @@ -673,7 +673,7 @@ func TestSimulateTransactionUnmarshalError(t *testing.T) { } func TestSimulateTransactionExtendAndRestoreFootprint(t *testing.T) { - test := NewTest(t) + test := NewTest(t, nil) ch := jhttp.NewChannel(test.sorobanRPCURL(), nil) client := jrpc2.NewClient(ch, nil) @@ -906,7 +906,7 @@ func waitUntilLedgerEntryTTL(t *testing.T, client *jrpc2.Client, ledgerKey xdr.L } func TestSimulateInvokePrng_u64_in_range(t *testing.T) { - test := NewTest(t) + test := NewTest(t, nil) ch := jhttp.NewChannel(test.sorobanRPCURL(), nil) client := jrpc2.NewClient(ch, nil) @@ -1017,7 +1017,7 @@ func TestSimulateInvokePrng_u64_in_range(t *testing.T) { } func TestSimulateSystemEvent(t *testing.T) { - test := NewTest(t) + test := NewTest(t, nil) ch := jhttp.NewChannel(test.sorobanRPCURL(), nil) client := jrpc2.NewClient(ch, nil) diff --git a/cmd/soroban-rpc/internal/test/transaction_test.go b/cmd/soroban-rpc/internal/test/transaction_test.go index 1cd0d198..9027bc58 100644 --- a/cmd/soroban-rpc/internal/test/transaction_test.go +++ b/cmd/soroban-rpc/internal/test/transaction_test.go @@ -21,7 +21,7 @@ import ( ) func TestSendTransactionSucceedsWithoutResults(t *testing.T) { - test := NewTest(t) + test := NewTest(t, nil) ch := jhttp.NewChannel(test.sorobanRPCURL(), nil) client := jrpc2.NewClient(ch, nil) @@ -46,7 +46,7 @@ func TestSendTransactionSucceedsWithoutResults(t *testing.T) { } func TestSendTransactionSucceedsWithResults(t *testing.T) { - test := NewTest(t) + test := NewTest(t, nil) ch := jhttp.NewChannel(test.sorobanRPCURL(), nil) client := jrpc2.NewClient(ch, nil) @@ -110,7 +110,7 @@ func TestSendTransactionSucceedsWithResults(t *testing.T) { } func TestSendTransactionBadSequence(t *testing.T) { - test := NewTest(t) + test := NewTest(t, nil) ch := jhttp.NewChannel(test.sorobanRPCURL(), nil) client := jrpc2.NewClient(ch, nil) @@ -152,7 +152,7 @@ func TestSendTransactionBadSequence(t *testing.T) { } func TestSendTransactionFailedInsufficientResourceFee(t *testing.T) { - test := NewTest(t) + test := NewTest(t, nil) ch := jhttp.NewChannel(test.sorobanRPCURL(), nil) client := jrpc2.NewClient(ch, nil) @@ -204,7 +204,7 @@ func TestSendTransactionFailedInsufficientResourceFee(t *testing.T) { } func TestSendTransactionFailedInLedger(t *testing.T) { - test := NewTest(t) + test := NewTest(t, nil) ch := jhttp.NewChannel(test.sorobanRPCURL(), nil) client := jrpc2.NewClient(ch, nil) @@ -266,7 +266,7 @@ func TestSendTransactionFailedInLedger(t *testing.T) { } func TestSendTransactionFailedInvalidXDR(t *testing.T) { - test := NewTest(t) + test := NewTest(t, nil) ch := jhttp.NewChannel(test.sorobanRPCURL(), nil) client := jrpc2.NewClient(ch, nil)