diff --git a/go/worker/common/host/sandboxed_test.go b/go/worker/common/host/sandboxed_test.go index 80ff4a99608..1168bc661ec 100644 --- a/go/worker/common/host/sandboxed_test.go +++ b/go/worker/common/host/sandboxed_test.go @@ -10,8 +10,10 @@ import ( "github.com/stretchr/testify/require" + "github.com/oasislabs/ekiden/go/common/cbor" "github.com/oasislabs/ekiden/go/common/logging" "github.com/oasislabs/ekiden/go/common/node" + "github.com/oasislabs/ekiden/go/common/runtime" "github.com/oasislabs/ekiden/go/ias" "github.com/oasislabs/ekiden/go/worker/common/host/protocol" ) @@ -123,6 +125,10 @@ func testSandboxedHost(t *testing.T, host Host) { t.Run("InterruptWorker", func(t *testing.T) { testInterruptWorker(t, host) }) + + t.Run("CheckTxRequest", func(t *testing.T) { + testCheckTxRequest(t, host) + }) } func testWaitForCapabilityTEE(t *testing.T, host Host) { @@ -156,6 +162,60 @@ func testSimpleRequest(t *testing.T, host Host) { } } +func testCheckTxRequest(t *testing.T, host Host) { + ctx, cancel := context.WithTimeout(context.Background(), recvTimeout) + defer cancel() + + type KeyValue struct { + Key string `codec:"key"` + Value string `codec:"value"` + } + + type TxnCall struct { + Method string `codec:"method"` + Args KeyValue `codec:"args"` + } + + type TxnOutput struct { + Success interface{} + Error *string + } + + txnCallValid := TxnCall{Method: "insert", Args: KeyValue{Key: "foo", Value: "bar"}} + txnCallInvalid := TxnCall{Method: "missing_method", Args: KeyValue{Key: "foo", Value: "bar"}} + batch := runtime.Batch([][]byte{cbor.Marshal(&txnCallValid), cbor.Marshal(&txnCallInvalid)}) + + rspCh, err := host.MakeRequest(ctx, &protocol.Body{ + WorkerCheckTxBatchRequest: &protocol.WorkerCheckTxBatchRequest{ + Calls: batch, + }, + }) + require.NoError(t, err, "MakeRequest") + + select { + case rsp := <-rspCh: + require.NotNil(t, rsp, "worker channel should not be closed while waiting for response") + require.NotNil(t, rsp.WorkerCheckTxBatchResponse.Checks, "worker should respond to check tx call") + require.Len(t, rsp.WorkerCheckTxBatchResponse.Checks, 2, "worker should return a check tx call result for each txn") + + txnOutputValidRaw := rsp.WorkerCheckTxBatchResponse.Checks[0] + var txnOutputValid TxnOutput + cbor.MustUnmarshal(txnOutputValidRaw, &txnOutputValid) + require.NotNil(t, txnOutputValid.Success, "valid tx call should return success") + require.Nil(t, txnOutputValid.Error, "valid tx call should not return error") + + txnOutputInvalidRaw := rsp.WorkerCheckTxBatchResponse.Checks[1] + var txnOutputInvalid TxnOutput + cbor.MustUnmarshal(txnOutputInvalidRaw, &txnOutputInvalid) + require.Nil(t, txnOutputInvalid.Success, "invalid tx call should not return success") + require.NotNil(t, txnOutputInvalid.Error, "invalid tx call should return error") + require.Regexp(t, "^method not found", *txnOutputInvalid.Error, "invalid tx call should indicate that method was not found") + + case <-ctx.Done(): + require.Fail(t, "timed out while waiting for response from worker") + } +} + func testInterruptWorker(t *testing.T, host Host) { ctx, cancel := context.WithTimeout(context.Background(), recvTimeout) defer cancel()