OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-dev/] [or1k-gcc/] [libgo/] [go/] [net/] [rpc/] [jsonrpc/] [all_test.go] - Rev 848

Go to most recent revision | Compare with Previous | Blame | View Log

// Copyright 2010 The Go Authors.  All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package jsonrpc

import (
        "encoding/json"
        "errors"
        "fmt"
        "io"
        "net"
        "net/rpc"
        "testing"
)

type Args struct {
        A, B int
}

type Reply struct {
        C int
}

type Arith int

func (t *Arith) Add(args *Args, reply *Reply) error {
        reply.C = args.A + args.B
        return nil
}

func (t *Arith) Mul(args *Args, reply *Reply) error {
        reply.C = args.A * args.B
        return nil
}

func (t *Arith) Div(args *Args, reply *Reply) error {
        if args.B == 0 {
                return errors.New("divide by zero")
        }
        reply.C = args.A / args.B
        return nil
}

func (t *Arith) Error(args *Args, reply *Reply) error {
        panic("ERROR")
}

func init() {
        rpc.Register(new(Arith))
}

func TestServer(t *testing.T) {
        type addResp struct {
                Id     interface{} `json:"id"`
                Result Reply       `json:"result"`
                Error  interface{} `json:"error"`
        }

        cli, srv := net.Pipe()
        defer cli.Close()
        go ServeConn(srv)
        dec := json.NewDecoder(cli)

        // Send hand-coded requests to server, parse responses.
        for i := 0; i < 10; i++ {
                fmt.Fprintf(cli, `{"method": "Arith.Add", "id": "\u%04d", "params": [{"A": %d, "B": %d}]}`, i, i, i+1)
                var resp addResp
                err := dec.Decode(&resp)
                if err != nil {
                        t.Fatalf("Decode: %s", err)
                }
                if resp.Error != nil {
                        t.Fatalf("resp.Error: %s", resp.Error)
                }
                if resp.Id.(string) != string(i) {
                        t.Fatalf("resp: bad id %q want %q", resp.Id.(string), string(i))
                }
                if resp.Result.C != 2*i+1 {
                        t.Fatalf("resp: bad result: %d+%d=%d", i, i+1, resp.Result.C)
                }
        }

        fmt.Fprintf(cli, "{}\n")
        var resp addResp
        if err := dec.Decode(&resp); err != nil {
                t.Fatalf("Decode after empty: %s", err)
        }
        if resp.Error == nil {
                t.Fatalf("Expected error, got nil")
        }
}

func TestClient(t *testing.T) {
        // Assume server is okay (TestServer is above).
        // Test client against server.
        cli, srv := net.Pipe()
        go ServeConn(srv)

        client := NewClient(cli)
        defer client.Close()

        // Synchronous calls
        args := &Args{7, 8}
        reply := new(Reply)
        err := client.Call("Arith.Add", args, reply)
        if err != nil {
                t.Errorf("Add: expected no error but got string %q", err.Error())
        }
        if reply.C != args.A+args.B {
                t.Errorf("Add: expected %d got %d", reply.C, args.A+args.B)
        }

        args = &Args{7, 8}
        reply = new(Reply)
        err = client.Call("Arith.Mul", args, reply)
        if err != nil {
                t.Errorf("Mul: expected no error but got string %q", err.Error())
        }
        if reply.C != args.A*args.B {
                t.Errorf("Mul: expected %d got %d", reply.C, args.A*args.B)
        }

        // Out of order.
        args = &Args{7, 8}
        mulReply := new(Reply)
        mulCall := client.Go("Arith.Mul", args, mulReply, nil)
        addReply := new(Reply)
        addCall := client.Go("Arith.Add", args, addReply, nil)

        addCall = <-addCall.Done
        if addCall.Error != nil {
                t.Errorf("Add: expected no error but got string %q", addCall.Error.Error())
        }
        if addReply.C != args.A+args.B {
                t.Errorf("Add: expected %d got %d", addReply.C, args.A+args.B)
        }

        mulCall = <-mulCall.Done
        if mulCall.Error != nil {
                t.Errorf("Mul: expected no error but got string %q", mulCall.Error.Error())
        }
        if mulReply.C != args.A*args.B {
                t.Errorf("Mul: expected %d got %d", mulReply.C, args.A*args.B)
        }

        // Error test
        args = &Args{7, 0}
        reply = new(Reply)
        err = client.Call("Arith.Div", args, reply)
        // expect an error: zero divide
        if err == nil {
                t.Error("Div: expected error")
        } else if err.Error() != "divide by zero" {
                t.Error("Div: expected divide by zero error; got", err)
        }
}

func TestMalformedInput(t *testing.T) {
        cli, srv := net.Pipe()
        go cli.Write([]byte(`{id:1}`)) // invalid json
        ServeConn(srv)                 // must return, not loop
}

func TestUnexpectedError(t *testing.T) {
        cli, srv := myPipe()
        go cli.PipeWriter.CloseWithError(errors.New("unexpected error!")) // reader will get this error
        ServeConn(srv)                                                    // must return, not loop
}

// Copied from package net.
func myPipe() (*pipe, *pipe) {
        r1, w1 := io.Pipe()
        r2, w2 := io.Pipe()

        return &pipe{r1, w2}, &pipe{r2, w1}
}

type pipe struct {
        *io.PipeReader
        *io.PipeWriter
}

type pipeAddr int

func (pipeAddr) Network() string {
        return "pipe"
}

func (pipeAddr) String() string {
        return "pipe"
}

func (p *pipe) Close() error {
        err := p.PipeReader.Close()
        err1 := p.PipeWriter.Close()
        if err == nil {
                err = err1
        }
        return err
}

func (p *pipe) LocalAddr() net.Addr {
        return pipeAddr(0)
}

func (p *pipe) RemoteAddr() net.Addr {
        return pipeAddr(0)
}

func (p *pipe) SetTimeout(nsec int64) error {
        return errors.New("net.Pipe does not support timeouts")
}

func (p *pipe) SetReadTimeout(nsec int64) error {
        return errors.New("net.Pipe does not support timeouts")
}

func (p *pipe) SetWriteTimeout(nsec int64) error {
        return errors.New("net.Pipe does not support timeouts")
}

Go to most recent revision | Compare with Previous | Blame | View Log

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.