sq source4/torture/rpc/echo.c
[metze/samba/wip.git] / source4 / torture / rpc / echo.c
index f2a40912e66df030aa90df4aecf23ad070dfed22..1517fa1f845c7b29489c70b6cd6f2eacf90c543a 100644 (file)
@@ -8,7 +8,7 @@
    
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
-   the Free Software Foundation; either version 2 of the License, or
+   the Free Software Foundation; either version 3 of the License, or
    (at your option) any later version.
    
    This program is distributed in the hope that it will be useful,
    GNU General Public License for more details.
    
    You should have received a copy of the GNU General Public License
-   along with this program; if not, write to the Free Software
-   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
 
 #include "includes.h"
-#include "torture/torture.h"
-#include "torture/rpc/rpc.h"
+#include "torture/rpc/torture_rpc.h"
 #include "lib/events/events.h"
 #include "librpc/gen_ndr/ndr_echo_c.h"
 
        n = i = value; \
        r.in.in_data = n; \
        r.out.out_data = &n; \
-       status = dcerpc_echo_AddOne(p, tctx, &r); \
-       torture_assert_ntstatus_ok(tctx, status, talloc_asprintf(tctx, "AddOne(%d) failed", i)); \
+       torture_assert_ntstatus_ok(tctx, dcerpc_echo_AddOne_r(b, tctx, &r), \
+               talloc_asprintf(tctx, "AddOne(%d) failed", i)); \
        torture_assert (tctx, n == i+1, talloc_asprintf(tctx, "%d + 1 != %u (should be %u)\n", i, n, i+1)); \
        torture_comment (tctx, "%d + 1 = %u\n", i, n); \
 } while(0)
 
 static bool test_addone(struct torture_context *tctx, 
-                                               struct dcerpc_pipe *p)
+                       struct dcerpc_pipe *p)
 {
        uint32_t i;
-       NTSTATUS status;
        uint32_t n;
        struct echo_AddOne r;
+       struct dcerpc_binding_handle *b = p->binding_handle;
 
        for (i=0;i<10;i++) {
                TEST_ADDONE(tctx, i);
@@ -64,13 +62,13 @@ static bool test_addone(struct torture_context *tctx,
   test the EchoData interface
 */
 static bool test_echodata(struct torture_context *tctx,
-                                                 struct dcerpc_pipe *p)
+                         struct dcerpc_pipe *p)
 {
        int i;
-       NTSTATUS status;
        uint8_t *data_in, *data_out;
        int len;
        struct echo_EchoData r;
+       struct dcerpc_binding_handle *b = p->binding_handle;
 
        if (torture_setting_bool(tctx, "quick", false) &&
            (p->conn->flags & DCERPC_DEBUG_VALIDATE_BOTH)) {
@@ -79,8 +77,8 @@ static bool test_echodata(struct torture_context *tctx,
                len = 1 + (random() % 5000);
        }
 
-       data_in = talloc_size(tctx, len);
-       data_out = talloc_size(tctx, len);
+       data_in = talloc_array(tctx, uint8_t, len);
+       data_out = talloc_array(tctx, uint8_t, len);
        for (i=0;i<len;i++) {
                data_in[i] = i;
        }
@@ -88,9 +86,8 @@ static bool test_echodata(struct torture_context *tctx,
        r.in.len = len;
        r.in.in_data = data_in;
 
-       status = dcerpc_echo_EchoData(p, tctx, &r);
-       torture_assert_ntstatus_ok(tctx, status, talloc_asprintf(tctx, 
-                                                                                       "EchoData(%d) failed\n", len));
+       torture_assert_ntstatus_ok(tctx, dcerpc_echo_EchoData_r(b, tctx, &r),
+               talloc_asprintf(tctx, "EchoData(%d) failed\n", len));
 
        data_out = r.out.out_data;
 
@@ -112,12 +109,12 @@ static bool test_echodata(struct torture_context *tctx,
   test the SourceData interface
 */
 static bool test_sourcedata(struct torture_context *tctx,
-                                                 struct dcerpc_pipe *p)
+                           struct dcerpc_pipe *p)
 {
        int i;
-       NTSTATUS status;
        int len;
        struct echo_SourceData r;
+       struct dcerpc_binding_handle *b = p->binding_handle;
 
        if (torture_setting_bool(tctx, "quick", false) &&
            (p->conn->flags & DCERPC_DEBUG_VALIDATE_BOTH)) {
@@ -128,9 +125,8 @@ static bool test_sourcedata(struct torture_context *tctx,
 
        r.in.len = len;
 
-       status = dcerpc_echo_SourceData(p, tctx, &r);
-       torture_assert_ntstatus_ok(tctx, status, talloc_asprintf(tctx, 
-                                                                               "SourceData(%d) failed", len));
+       torture_assert_ntstatus_ok(tctx, dcerpc_echo_SourceData_r(b, tctx, &r),
+               talloc_asprintf(tctx, "SourceData(%d) failed", len));
 
        for (i=0;i<len;i++) {
                uint8_t *v = (uint8_t *)r.out.data;
@@ -145,13 +141,13 @@ static bool test_sourcedata(struct torture_context *tctx,
   test the SinkData interface
 */
 static bool test_sinkdata(struct torture_context *tctx, 
-                                                 struct dcerpc_pipe *p)
+                         struct dcerpc_pipe *p)
 {
        int i;
-       NTSTATUS status;
        uint8_t *data_in;
        int len;
        struct echo_SinkData r;
+       struct dcerpc_binding_handle *b = p->binding_handle;
 
        if (torture_setting_bool(tctx, "quick", false) &&
            (p->conn->flags & DCERPC_DEBUG_VALIDATE_BOTH)) {
@@ -160,7 +156,7 @@ static bool test_sinkdata(struct torture_context *tctx,
                len = 200000 + (random() % 5000);
        }
 
-       data_in = talloc_size(tctx, len);
+       data_in = talloc_array(tctx, uint8_t, len);
        for (i=0;i<len;i++) {
                data_in[i] = i+1;
        }
@@ -168,10 +164,8 @@ static bool test_sinkdata(struct torture_context *tctx,
        r.in.len = len;
        r.in.data = data_in;
 
-       status = dcerpc_echo_SinkData(p, tctx, &r);
-       torture_assert_ntstatus_ok(tctx, status, talloc_asprintf(tctx, 
-                                                                               "SinkData(%d) failed", 
-                                                          len));
+       torture_assert_ntstatus_ok(tctx, dcerpc_echo_SinkData_r(b, tctx, &r),
+               talloc_asprintf(tctx, "SinkData(%d) failed", len));
 
        torture_comment(tctx, "sunk %d bytes\n", len);
        return true;
@@ -182,17 +176,17 @@ static bool test_sinkdata(struct torture_context *tctx,
   test the testcall interface
 */
 static bool test_testcall(struct torture_context *tctx,
-                                                 struct dcerpc_pipe *p)
+                         struct dcerpc_pipe *p)
 {
-       NTSTATUS status;
        struct echo_TestCall r;
        const char *s = NULL;
+       struct dcerpc_binding_handle *b = p->binding_handle;
 
        r.in.s1 = "input string";
        r.out.s2 = &s;
 
-       status = dcerpc_echo_TestCall(p, tctx, &r);
-       torture_assert_ntstatus_ok(tctx, status, "TestCall failed");
+       torture_assert_ntstatus_ok(tctx, dcerpc_echo_TestCall_r(b, tctx, &r),
+               "TestCall failed");
 
        torture_assert_str_equal(tctx, s, "input string", "Didn't receive back same string");
 
@@ -203,91 +197,117 @@ static bool test_testcall(struct torture_context *tctx,
   test the testcall interface
 */
 static bool test_testcall2(struct torture_context *tctx,
-                                                 struct dcerpc_pipe *p)
+                          struct dcerpc_pipe *p)
 {
-       NTSTATUS status;
        struct echo_TestCall2 r;
        int i;
+       struct dcerpc_binding_handle *b = p->binding_handle;
 
        for (i=1;i<=7;i++) {
                r.in.level = i;
                r.out.info = talloc(tctx, union echo_Info);
 
                torture_comment(tctx, "Testing TestCall2 level %d\n", i);
-               status = dcerpc_echo_TestCall2(p, tctx, &r);
-               torture_assert_ntstatus_ok(tctx, status, "TestCall2 failed");
+               torture_assert_ntstatus_ok(tctx, dcerpc_echo_TestCall2_r(b, tctx, &r),
+                       "TestCall2 failed");
+               torture_assert_ntstatus_ok(tctx, r.out.result, "TestCall2 failed");
        }
        return true;
 }
 
+static void test_sleep_done(struct tevent_req *subreq)
+{
+       bool *done1 = (bool *)tevent_req_callback_data_void(subreq);
+       *done1 = true;
+}
+
 /*
   test the TestSleep interface
 */
 static bool test_sleep(struct torture_context *tctx,
-                                                 struct dcerpc_pipe *p)
+                      struct dcerpc_pipe *p)
 {
        int i;
-       NTSTATUS status;
 #define ASYNC_COUNT 3
-       struct rpc_request *req[ASYNC_COUNT];
+       struct tevent_req *req[ASYNC_COUNT];
        struct echo_TestSleep r[ASYNC_COUNT];
-       BOOL done[ASYNC_COUNT];
+       bool done1[ASYNC_COUNT];
+       bool done2[ASYNC_COUNT];
        struct timeval snd[ASYNC_COUNT];
        struct timeval rcv[ASYNC_COUNT];
        struct timeval diff[ASYNC_COUNT];
-       struct event_context *ctx;
        int total_done = 0;
+       struct dcerpc_binding_handle *b = p->binding_handle;
+       enum dcerpc_transport_t transport;
+       uint32_t assoc_group_id;
+       struct dcerpc_pipe *p2 = NULL;
+       NTSTATUS status;
 
        if (torture_setting_bool(tctx, "quick", false)) {
                torture_skip(tctx, "TestSleep disabled - use \"torture:quick=no\" to enable\n");
        }
-       torture_comment(tctx, "Testing TestSleep - use \"torture:quick=no\" to disable\n");
+       torture_comment(tctx, "Testing TestSleep - use \"torture:quick=yes\" to disable\n");
+
+       transport       = dcerpc_binding_get_transport(p->binding);
+       assoc_group_id  = dcerpc_binding_get_assoc_group_id(p->binding);
+
+       torture_comment(tctx, "connect echo connection 2 with "
+                       "DCERPC_CONCURRENT_MULTIPLEX\n");
+       status = torture_rpc_connection_transport(tctx, &p2,
+                                                 &ndr_table_rpcecho,
+                                                 transport,
+                                                 assoc_group_id,
+                                                 DCERPC_CONCURRENT_MULTIPLEX);
+       torture_assert_ntstatus_ok(tctx, status, "opening echo connection 2");
+       b = p2->binding_handle;
 
        for (i=0;i<ASYNC_COUNT;i++) {
-               done[i]         = False;
+               done1[i]        = false;
+               done2[i]        = false;
                snd[i]          = timeval_current();
                rcv[i]          = timeval_zero();
                r[i].in.seconds = ASYNC_COUNT-i;
-               req[i] = dcerpc_echo_TestSleep_send(p, tctx, &r[i]);
+               req[i] = dcerpc_echo_TestSleep_r_send(tctx, tctx->ev, b, &r[i]);
                torture_assert(tctx, req[i], "Failed to send async sleep request\n");
+               tevent_req_set_callback(req[i], test_sleep_done, &done1[i]);
        }
 
-       ctx = dcerpc_event_context(p);
        while (total_done < ASYNC_COUNT) {
-               torture_assert(tctx, event_loop_once(ctx) == 0, 
+               torture_assert(tctx, tevent_loop_once(tctx->ev) == 0,
                                           "Event context loop failed");
                for (i=0;i<ASYNC_COUNT;i++) {
-                       if (done[i] == False && req[i]->state == RPC_REQUEST_DONE) {
+                       if (done2[i] == false && done1[i] == true) {
                                int rounded_tdiff;
                                total_done++;
-                               done[i] = True;
+                               done2[i] = true;
                                rcv[i]  = timeval_current();
                                diff[i] = timeval_until(&snd[i], &rcv[i]);
                                rounded_tdiff = (int)(0.5 + diff[i].tv_sec + (1.0e-6*diff[i].tv_usec));
-                               status  = dcerpc_ndr_request_recv(req[i]);
-                               printf("rounded_tdiff=%d\n", rounded_tdiff);
-                               torture_assert_ntstatus_ok(tctx, status, 
-                                                       talloc_asprintf(tctx, "TestSleep(%d) failed", i));
+                               torture_comment(tctx, "rounded_tdiff=%d\n", rounded_tdiff);
+                               torture_assert_ntstatus_ok(tctx,
+                                       dcerpc_echo_TestSleep_r_recv(req[i], tctx),
+                                       talloc_asprintf(tctx, "TestSleep(%d) failed", i));
                                torture_assert(tctx, r[i].out.result == r[i].in.seconds,
                                        talloc_asprintf(tctx, "Failed - Asked to sleep for %u seconds (server replied with %u seconds and the reply takes only %u seconds)", 
-                                               r[i].out.result, r[i].in.seconds, (uint_t)diff[i].tv_sec));
+                                               r[i].out.result, r[i].in.seconds, (unsigned int)diff[i].tv_sec));
                                torture_assert(tctx, r[i].out.result <= rounded_tdiff, 
                                        talloc_asprintf(tctx, "Failed - Slept for %u seconds (but reply takes only %u.%06u seconds)", 
-                                               r[i].out.result, (uint_t)diff[i].tv_sec, (uint_t)diff[i].tv_usec));
+                                               r[i].out.result, (unsigned int)diff[i].tv_sec, (unsigned int)diff[i].tv_usec));
                                if (r[i].out.result+1 == rounded_tdiff) {
                                        torture_comment(tctx, "Slept for %u seconds (but reply takes %u.%06u seconds - busy server?)\n", 
-                                                       r[i].out.result, (uint_t)diff[i].tv_sec, (uint_t)diff[i].tv_usec);
+                                                       r[i].out.result, (unsigned int)diff[i].tv_sec, (unsigned int)diff[i].tv_usec);
                                } else if (r[i].out.result == rounded_tdiff) {
                                        torture_comment(tctx, "Slept for %u seconds (reply takes %u.%06u seconds - ok)\n", 
-                                                       r[i].out.result, (uint_t)diff[i].tv_sec, (uint_t)diff[i].tv_usec);
+                                                       r[i].out.result, (unsigned int)diff[i].tv_sec, (unsigned int)diff[i].tv_usec);
                                } else {
-                                               torture_comment(tctx, "(Failed) - Not async - Slept for %u seconds (but reply takes %u.%06u seconds)", 
-                                                       r[i].out.result, (uint_t)diff[i].tv_sec, (uint_t)diff[i].tv_usec);
-                                       /* TODO: let the test fail here, when we support async rpc on ncacn_np */
+                                       torture_fail(tctx, talloc_asprintf(tctx,
+                                                    "(Failed) - Not async - Slept for %u seconds (but reply takes %u.%06u seconds)\n",
+                                                    r[i].out.result, (unsigned int)diff[i].tv_sec, (unsigned int)diff[i].tv_usec));
                                }
                        }
                }
        }
+       torture_comment(tctx, "\n");
        return true;
 }
 
@@ -297,11 +317,11 @@ static bool test_sleep(struct torture_context *tctx,
 static bool test_enum(struct torture_context *tctx,
                                                  struct dcerpc_pipe *p)
 {
-       NTSTATUS status;
        struct echo_TestEnum r;
        enum echo_Enum1 v = ECHO_ENUM1;
        struct echo_Enum2 e2;
        union echo_Enum3 e3;
+       struct dcerpc_binding_handle *b = p->binding_handle;
 
        r.in.foo1 = &v;
        r.in.foo2 = &e2;
@@ -314,8 +334,8 @@ static bool test_enum(struct torture_context *tctx,
        e2.e2 = ECHO_ENUM1_32;
        e3.e1 = ECHO_ENUM2;
 
-       status = dcerpc_echo_TestEnum(p, tctx, &r);
-       torture_assert_ntstatus_ok(tctx, status, "TestEnum failed");
+       torture_assert_ntstatus_ok(tctx, dcerpc_echo_TestEnum_r(b, tctx, &r),
+               "TestEnum failed");
        return true;
 }
 
@@ -325,8 +345,8 @@ static bool test_enum(struct torture_context *tctx,
 static bool test_surrounding(struct torture_context *tctx,
                                                  struct dcerpc_pipe *p)
 {
-       NTSTATUS status;
        struct echo_TestSurrounding r;
+       struct dcerpc_binding_handle *b = p->binding_handle;
 
        ZERO_STRUCT(r);
        r.in.data = talloc(tctx, struct echo_Surrounding);
@@ -336,8 +356,8 @@ static bool test_surrounding(struct torture_context *tctx,
 
        r.out.data = talloc(tctx, struct echo_Surrounding);
 
-       status = dcerpc_echo_TestSurrounding(p, tctx, &r);
-       torture_assert_ntstatus_ok(tctx, status, "TestSurrounding failed");
+       torture_assert_ntstatus_ok(tctx, dcerpc_echo_TestSurrounding_r(b, tctx, &r),
+               "TestSurrounding failed");
        
        torture_assert(tctx, r.out.data->x == 2 * r.in.data->x,
                "TestSurrounding did not make the array twice as large");
@@ -349,29 +369,135 @@ static bool test_surrounding(struct torture_context *tctx,
   test multiple levels of pointers
 */
 static bool test_doublepointer(struct torture_context *tctx,
-                                                          struct dcerpc_pipe *p)
+                              struct dcerpc_pipe *p)
 {
-       NTSTATUS status;
        struct echo_TestDoublePointer r;
        uint16_t value = 12;
        uint16_t *pvalue = &value;
        uint16_t **ppvalue = &pvalue;
+       struct dcerpc_binding_handle *b = p->binding_handle;
 
        ZERO_STRUCT(r);
        r.in.data = &ppvalue;
 
-       status = dcerpc_echo_TestDoublePointer(p, tctx, &r);
-       torture_assert_ntstatus_ok(tctx, status, "TestDoublePointer failed");
+       torture_assert_ntstatus_ok(tctx, dcerpc_echo_TestDoublePointer_r(b, tctx, &r),
+               "TestDoublePointer failed");
 
        torture_assert_int_equal(tctx, value, r.out.result, 
                                        "TestDoublePointer did not return original value");
        return true;
 }
 
+static bool test_bytepipein(struct torture_context *tctx,
+                           struct dcerpc_pipe *p)
+{
+       struct dcerpc_binding_handle *b = p->binding_handle;
+       struct echo_TestBytePipeIn r;
+       struct echo_BytePipe_chunk chunk;
+       struct echo_BytePipe *in_pipe;
+       struct tevent_req *subreq1;
+       struct tevent_req *subreq2;
+       size_t i;
+       uint8_t bytes[0x8000];
+       NTSTATUS status;
+
+       in_pipe = dcerpc_echo_BytePipe_create(tctx);
+
+       ZERO_STRUCT(r);
+       r.in.num_chunks = 1;
+       r.in.chunk_size = sizeof(bytes);
+       r.in.in_pipe = in_pipe;
+
+       ZERO_STRUCT(chunk);
 
+       subreq1 = dcerpc_echo_TestBytePipeIn_r_send(tctx, tctx->ev, b, &r);
+       for (i=0; i <= r.in.num_chunks; i++) {
+               struct timeval tv = timeval_current_ofs(0, 100);
+
+               memset(bytes, i, sizeof(bytes));
+               chunk.count = r.in.chunk_size;
+               chunk.array = bytes;
+
+               if (i == r.in.num_chunks) {
+                       chunk.count = 0;
+               }
+
+               subreq2 = tevent_wakeup_send(tctx, tctx->ev, tv);
+               tevent_req_poll(subreq2, tctx->ev);
+               tevent_wakeup_recv(subreq2);
+               TALLOC_FREE(subreq2);
+
+               torture_comment(tctx, "chunk[%u] count[%u]\n", (unsigned)i, (unsigned)chunk.count);
+               subreq2 = dcerpc_echo_BytePipe_chunk_push_send(tctx, tctx->ev, in_pipe, &chunk);
+               tevent_req_poll(subreq2, tctx->ev);
+               status = dcerpc_echo_BytePipe_chunk_push_recv(subreq2);
+               TALLOC_FREE(subreq2);
+               torture_assert_ntstatus_ok(tctx, status, __location__);
+       }
+
+       tevent_req_poll(subreq1, tctx->ev);
+       status = dcerpc_echo_TestBytePipeIn_r_recv(subreq1, tctx);
+       TALLOC_FREE(subreq1);
+       torture_assert_ntstatus_ok(tctx, status, __location__);
+
+       return true;
+}
+
+static bool test_bytepipeout(struct torture_context *tctx,
+                            struct dcerpc_pipe *p)
+{
+       struct dcerpc_binding_handle *b = p->binding_handle;
+       struct echo_TestBytePipeOut r;
+       struct echo_BytePipe_chunk *chunk;
+       struct echo_BytePipe *out_pipe;
+       struct tevent_req *subreq1;
+       struct tevent_req *subreq2;
+       size_t i;
+       NTSTATUS status;
+
+       out_pipe = dcerpc_echo_BytePipe_create(tctx);
+
+       ZERO_STRUCT(r);
+       r.in.num_chunks = 100;
+       r.in.chunk_size = 0x80000;
+       r.out.out_pipe = out_pipe;
+
+       ZERO_STRUCT(chunk);
+
+       dcerpc_binding_handle_set_timeout(b, UINT32_MAX);
+       subreq1 = dcerpc_echo_TestBytePipeOut_r_send(tctx, tctx->ev, b, &r);
+       for (i=0; ; i++) {
+               //struct timeval tv = timeval_current_ofs(0, 100);
+
+               //subreq2 = tevent_wakeup_send(tctx, tctx->ev, tv);
+               //tevent_req_poll(subreq2, tctx->ev);
+               //tevent_wakeup_recv(subreq2);
+               //TALLOC_FREE(subreq2);
+
+               subreq2 = dcerpc_echo_BytePipe_chunk_pull_send(tctx, tctx->ev, out_pipe);
+               tevent_req_poll(subreq2, tctx->ev);
+               status = dcerpc_echo_BytePipe_chunk_pull_recv(subreq2, tctx, &chunk);
+               TALLOC_FREE(subreq2);
+               torture_assert_ntstatus_ok(tctx, status, __location__);
+               torture_comment(tctx, "chunk[%u] count[%u]\n", (unsigned)i, (unsigned)chunk->count);
+               if (chunk->count == 0) {
+                       TALLOC_FREE(chunk);
+                       break;
+               }
+               TALLOC_FREE(chunk);
+       }
+
+       tevent_req_poll(subreq1, tctx->ev);
+       status = dcerpc_echo_TestBytePipeOut_r_recv(subreq1, tctx);
+       TALLOC_FREE(subreq1);
+       torture_assert_ntstatus_ok(tctx, status, __location__);
+
+       return true;
+}
 /*
   test request timeouts
 */
+#if 0 /* this test needs fixing to work over ncacn_np */
 static bool test_timeout(struct torture_context *tctx,
                                                 struct dcerpc_pipe *p)
 {
@@ -388,10 +514,14 @@ static bool test_timeout(struct torture_context *tctx,
        r.in.seconds = 2;
        p->request_timeout = 1;
 
-       torture_assert(tctx, req = dcerpc_echo_TestSleep_send(p, tctx, &r), 
-               "Failed to send async sleep request");
+       req = dcerpc_echo_TestSleep_send(p, tctx, &r);
+       if (!req) {
+               torture_comment(tctx, "Failed to send async sleep request\n");
+               goto failed;
+       }
+       req->ignore_timeout = true;
 
-       status  = dcerpc_ndr_request_recv(req);
+       status  = dcerpc_echo_TestSleep_recv(req);
        torture_assert_ntstatus_equal(tctx, status, NT_STATUS_IO_TIMEOUT, 
                                                                  "request should have timed out");
 
@@ -408,7 +538,8 @@ static bool test_timeout(struct torture_context *tctx,
                torture_comment(tctx, "Failed to send async sleep request\n");
                goto failed;
        }
-       status  = dcerpc_ndr_request_recv(req);
+       req->ignore_timeout = true;
+       status  = dcerpc_echo_TestSleep_recv(req);
        torture_assert_ntstatus_equal(tctx, status, NT_STATUS_IO_TIMEOUT, 
                "request should have timed out");
 
@@ -420,28 +551,31 @@ failed:
        p->request_timeout = timeout_saved;
        return false;
 }
+#endif
 
-
-struct torture_suite *torture_rpc_echo(void)
+struct torture_suite *torture_rpc_echo(TALLOC_CTX *mem_ctx)
 {
-       struct torture_suite *suite = torture_suite_create(
-               talloc_autofree_context(), "ECHO");
-       struct torture_tcase *tcase;
+       struct torture_suite *suite = torture_suite_create(mem_ctx, "echo");
+       struct torture_rpc_tcase *tcase;
 
        tcase = torture_suite_add_rpc_iface_tcase(suite, "echo", 
-                                                 &dcerpc_table_rpcecho);
-
-       torture_rpc_tcase_add_test(tcase, "addone", test_addone);
-       torture_rpc_tcase_add_test(tcase, "sinkdata", test_sinkdata);
-       torture_rpc_tcase_add_test(tcase, "echodata", test_echodata);
-       torture_rpc_tcase_add_test(tcase, "sourcedata", test_sourcedata);
-       torture_rpc_tcase_add_test(tcase, "testcall", test_testcall);
-       torture_rpc_tcase_add_test(tcase, "testcall2", test_testcall2);
-       torture_rpc_tcase_add_test(tcase, "enum", test_enum);
-       torture_rpc_tcase_add_test(tcase, "surrounding", test_surrounding);
-       torture_rpc_tcase_add_test(tcase, "doublepointer", test_doublepointer);
-       torture_rpc_tcase_add_test(tcase, "sleep", test_sleep);
+                                                 &ndr_table_rpcecho);
+
+       if (0) torture_rpc_tcase_add_test(tcase, "addone", test_addone);
+       if (0) torture_rpc_tcase_add_test(tcase, "sinkdata", test_sinkdata);
+       if (0) torture_rpc_tcase_add_test(tcase, "echodata", test_echodata);
+       if (0) torture_rpc_tcase_add_test(tcase, "sourcedata", test_sourcedata);
+       if (0) torture_rpc_tcase_add_test(tcase, "testcall", test_testcall);
+       if (0) torture_rpc_tcase_add_test(tcase, "testcall2", test_testcall2);
+       if (0) torture_rpc_tcase_add_test(tcase, "enum", test_enum);
+       if (0) torture_rpc_tcase_add_test(tcase, "surrounding", test_surrounding);
+       if (0) torture_rpc_tcase_add_test(tcase, "doublepointer", test_doublepointer);
+       if (0) torture_rpc_tcase_add_test(tcase, "sleep", test_sleep);
+       torture_rpc_tcase_add_test(tcase, "bytepipein", test_bytepipein);
+       torture_rpc_tcase_add_test(tcase, "bytepipeout", test_bytepipeout);
+#if 0 /* this test needs fixing to work over ncacn_np */
        torture_rpc_tcase_add_test(tcase, "timeout", test_timeout);
+#endif
 
        return suite;
 }