go.dedis.ch/onet/v3@v3.2.11-0.20210930124529-e36530bca7ef/processor_test.go (about)

     1  package onet
     2  
     3  import (
     4  	"bytes"
     5  	"encoding/base64"
     6  	"encoding/json"
     7  	"fmt"
     8  	"io"
     9  	"io/ioutil"
    10  	"net/http"
    11  	"reflect"
    12  	"strconv"
    13  	"sync"
    14  	"testing"
    15  
    16  	"github.com/stretchr/testify/require"
    17  	"go.dedis.ch/kyber/v3"
    18  	"go.dedis.ch/kyber/v3/group/edwards25519"
    19  	"go.dedis.ch/kyber/v3/pairing/bn256"
    20  	"go.dedis.ch/kyber/v3/sign/bls"
    21  	"go.dedis.ch/kyber/v3/util/key"
    22  	"go.dedis.ch/kyber/v3/util/random"
    23  	"go.dedis.ch/onet/v3/log"
    24  	"go.dedis.ch/onet/v3/network"
    25  	"go.dedis.ch/protobuf"
    26  	"golang.org/x/xerrors"
    27  )
    28  
    29  const testServiceName = "testService"
    30  
    31  func init() {
    32  	RegisterNewService(testServiceName, newTestService)
    33  	ServiceFactory.ServiceID(testServiceName)
    34  	network.RegisterMessages(&testMsg{}, &testPanicMsg{})
    35  }
    36  
    37  func TestProcessor_AddMessage(t *testing.T) {
    38  	h1 := NewLocalServer(tSuite, 2000)
    39  	defer h1.Close()
    40  	p := NewServiceProcessor(&Context{server: h1})
    41  	require.Nil(t, p.RegisterHandler(procMsg))
    42  	if len(p.handlers) != 1 {
    43  		require.Fail(t, "Should have registered one function")
    44  	}
    45  	mt := network.MessageType(&testMsg{})
    46  	if mt.Equal(network.ErrorType) {
    47  		require.Fail(t, "Didn't register message-type correctly")
    48  	}
    49  	var wrongFunctions = []interface{}{
    50  		procMsgWrong1,
    51  		procMsgWrong2,
    52  		procMsgWrong3,
    53  		procMsgWrong4,
    54  		procMsgWrong5,
    55  		procMsgWrong6,
    56  	}
    57  	for _, f := range wrongFunctions {
    58  		fsig := reflect.TypeOf(f).String()
    59  		log.Lvl2("Checking function", fsig)
    60  		require.Error(t, p.RegisterHandler(f),
    61  			"Could register wrong function: "+fsig)
    62  	}
    63  }
    64  
    65  func TestProcessor_RegisterMessages(t *testing.T) {
    66  	h1 := NewLocalServer(tSuite, 2000)
    67  	defer h1.Close()
    68  	p := NewServiceProcessor(&Context{server: h1})
    69  	require.Nil(t, p.RegisterHandlers(procMsg, procMsg2, procMsg3, procMsg4))
    70  	require.Error(t, p.RegisterHandlers(procMsg3, procMsgWrong1))
    71  }
    72  
    73  func TestProcessor_RegisterStreamingMessage(t *testing.T) {
    74  	h1 := NewLocalServer(tSuite, 2000)
    75  	defer h1.Close()
    76  	p := NewServiceProcessor(&Context{server: h1})
    77  
    78  	// correct registration
    79  	f1 := func(m *testMsg) (chan network.Message, chan bool, error) {
    80  		return make(chan network.Message), make(chan bool), nil
    81  	}
    82  	f2 := func(m *testMsg) (chan *testMsg, chan bool, error) {
    83  		return make(chan *testMsg), make(chan bool), nil
    84  	}
    85  	require.Nil(t, p.RegisterStreamingHandlers(f1, f2))
    86  
    87  	// wrong registrations
    88  	require.Error(t, p.RegisterStreamingHandler(
    89  		func(m int) (chan network.Message, chan bool, error) {
    90  			return nil, nil, nil
    91  		}), "input must be a pointer to struct")
    92  	require.Error(t, p.RegisterStreamingHandler(
    93  		func(m testMsg) (chan network.Message, chan bool, error) {
    94  			return nil, nil, nil
    95  		}), "input must be a pointer to struct")
    96  	require.Error(t, p.RegisterStreamingHandler(
    97  		func(m *testMsg) (chan int, chan bool, error) {
    98  			return nil, nil, nil
    99  		}), "first return must be a pointer or interface")
   100  	require.Error(t, p.RegisterStreamingHandler(
   101  		func(m *testMsg) (chan testMsg, chan bool, error) {
   102  			return nil, nil, nil
   103  		}), "first return must be a pointer or interface")
   104  	require.Error(t, p.RegisterStreamingHandler(
   105  		func(m *testMsg) (chan testMsg, error) {
   106  			return nil, nil
   107  		}), "must have three return values")
   108  	require.Error(t, p.RegisterStreamingHandler(
   109  		func(m *testMsg) (chan testMsg, chan int, error) {
   110  			return nil, nil, nil
   111  		}), "second return must be a boolean channel")
   112  	require.Error(t, p.RegisterStreamingHandler(
   113  		func(m *testMsg) (chan testMsg, []int, error) {
   114  			return nil, nil, nil
   115  		}), "second return must be a boolean channel")
   116  	require.Error(t, p.RegisterStreamingHandler(
   117  		func(m *testMsg) (chan testMsg, chan int, []byte) {
   118  			return nil, nil, nil
   119  		}), "must return an error")
   120  }
   121  
   122  func TestServiceProcessor_ProcessClientRequest(t *testing.T) {
   123  	h1 := NewLocalServer(tSuite, 2000)
   124  	defer h1.Close()
   125  	p := NewServiceProcessor(&Context{server: h1})
   126  	require.Nil(t, p.RegisterHandlers(procMsg, procMsg2))
   127  
   128  	buf, err := protobuf.Encode(&testMsg{11})
   129  	require.Nil(t, err)
   130  	rep, repChan, err := p.ProcessClientRequest(nil, "testMsg", buf)
   131  	require.Nil(t, repChan)
   132  	require.NoError(t, err)
   133  	val := &testMsg{}
   134  	require.Nil(t, protobuf.Decode(rep, val))
   135  	if val.I != 11 {
   136  		require.Fail(t, "Value got lost - should be 11")
   137  	}
   138  
   139  	buf, err = protobuf.Encode(&testMsg{42})
   140  	require.Nil(t, err)
   141  	_, _, err = p.ProcessClientRequest(nil, "testMsg", buf)
   142  	require.NotNil(t, err)
   143  
   144  	buf, err = protobuf.Encode(&testMsg2{42})
   145  	require.Nil(t, err)
   146  	_, _, err = p.ProcessClientRequest(nil, "testMsg2", buf)
   147  	require.NotNil(t, err)
   148  
   149  	// Test non-existing endpoint
   150  	buf, err = protobuf.Encode(&testMsg2{42})
   151  	require.Nil(t, err)
   152  	lvl := log.DebugVisible()
   153  	log.SetDebugVisible(0)
   154  	log.OutputToBuf()
   155  	_, _, err = p.ProcessClientRequest(nil, "testMsgNotAvailable", buf)
   156  	log.OutputToOs()
   157  	log.SetDebugVisible(lvl)
   158  	require.NotNil(t, err)
   159  	require.NotEqual(t, "", log.GetStdErr())
   160  }
   161  
   162  func TestServiceProcessor_ProcessClientRequest_Streaming_Simple(t *testing.T) {
   163  	h1 := NewLocalServer(tSuite, 2000)
   164  	defer h1.Close()
   165  
   166  	p := NewServiceProcessor(&Context{server: h1})
   167  	h := func(m *testMsg) (chan network.Message, chan bool, error) {
   168  		outChan := make(chan network.Message)
   169  		closeChan := make(chan bool)
   170  		go func() {
   171  			for i := 0; i < int(m.I); i++ {
   172  				outChan <- m
   173  			}
   174  			<-closeChan
   175  			close(outChan)
   176  		}()
   177  		return outChan, closeChan, nil
   178  	}
   179  	require.Nil(t, p.RegisterStreamingHandler(h))
   180  
   181  	n := 5
   182  	buf, err := protobuf.Encode(&testMsg{int64(n)})
   183  	require.NoError(t, err)
   184  	rep, _, err := p.ProcessClientRequest(nil, "testMsg", buf)
   185  	// Using ProcessClientRequest with a streaming request should yield an error
   186  	require.Nil(t, rep)
   187  	require.Error(t, err)
   188  
   189  	inputChan := make(chan []byte, 1)
   190  	inputChan <- buf
   191  	outChan, err := p.ProcessClientStreamRequest(nil, "testMsg", inputChan)
   192  
   193  	require.NoError(t, err)
   194  
   195  	for i := 0; i < n; i++ {
   196  		buf := <-outChan
   197  		val := &testMsg{}
   198  		require.Nil(t, protobuf.Decode(buf, val))
   199  		require.Equal(t, val.I, int64(n))
   200  	}
   201  	close(inputChan)
   202  }
   203  
   204  func TestServiceProcessor_ProcessClientRequest_Streaming_Multiple(t *testing.T) {
   205  	h1 := NewLocalServer(tSuite, 2000)
   206  
   207  	// order matters: last-in first-out
   208  	defer log.AfterTest(t) // check for leaking go routines
   209  	defer h1.Close()
   210  
   211  	p := NewServiceProcessor(&Context{server: h1})
   212  	h := func(m *testMsg) (chan network.Message, chan bool, error) {
   213  		outChan := make(chan network.Message)
   214  		closeChan := make(chan bool)
   215  		go func() {
   216  			for i := 0; i < int(m.I); i++ {
   217  				outChan <- m
   218  			}
   219  			<-closeChan
   220  			close(outChan)
   221  		}()
   222  		return outChan, closeChan, nil
   223  	}
   224  	require.Nil(t, p.RegisterStreamingHandler(h))
   225  
   226  	n := 5
   227  	buf, err := protobuf.Encode(&testMsg{int64(n)})
   228  	require.NoError(t, err)
   229  
   230  	// Send 3 requests
   231  	inputChan := make(chan []byte, 3)
   232  	outChan, err := p.ProcessClientStreamRequest(nil, "testMsg", inputChan)
   233  	require.NoError(t, err)
   234  
   235  	inputChan <- buf
   236  	inputChan <- buf
   237  	inputChan <- buf
   238  
   239  	for k := 0; k < 3; k++ {
   240  		for i := 0; i < n; i++ {
   241  			buf := <-outChan
   242  			val := &testMsg{}
   243  			require.Nil(t, protobuf.Decode(buf, val))
   244  			require.Equal(t, val.I, int64(n))
   245  		}
   246  	}
   247  
   248  	close(inputChan)
   249  }
   250  
   251  func TestServiceProcessor_ProcessClientStreamRequest(t *testing.T) {
   252  	h1 := NewLocalServer(tSuite, 2000)
   253  	defer h1.Close()
   254  
   255  	p := NewServiceProcessor(&Context{server: h1})
   256  	// The function need to use the same outChan and closeChan if a request is
   257  	// coming from the same client that expects the same outChan to be used.
   258  	serviceStruct := struct {
   259  		once      sync.Once
   260  		outChan   chan network.Message
   261  		closeChan chan bool
   262  	}{
   263  		outChan:   make(chan network.Message, 10),
   264  		closeChan: make(chan bool),
   265  	}
   266  
   267  	h := func(m *testMsg) (chan network.Message, chan bool, error) {
   268  		go func() {
   269  			for i := 0; i < int(m.I); i++ {
   270  				serviceStruct.outChan <- m
   271  			}
   272  			<-serviceStruct.closeChan
   273  			serviceStruct.once.Do(func() {
   274  				close(serviceStruct.outChan)
   275  			})
   276  		}()
   277  		return serviceStruct.outChan, serviceStruct.closeChan, nil
   278  	}
   279  	require.Nil(t, p.RegisterStreamingHandler(h))
   280  
   281  	// Sending a first message from the client to the service.
   282  	n := 5
   283  	clientInputs := make(chan []byte, 10)
   284  	buf, err := protobuf.Encode(&testMsg{int64(n)})
   285  	require.NoError(t, err)
   286  	clientInputs <- buf
   287  	outVals, err := p.ProcessClientStreamRequest(nil, "testMsg", clientInputs)
   288  	require.NoError(t, err)
   289  
   290  	for i := 0; i < n; i++ {
   291  		buf := <-outVals
   292  		val := &testMsg{}
   293  		require.Nil(t, protobuf.Decode(buf, val))
   294  		require.Equal(t, val.I, int64(n))
   295  	}
   296  
   297  	// Sending an additional message from the client to the service using the
   298  	// same channel.
   299  	n = 2
   300  	buf, err = protobuf.Encode(&testMsg{int64(n)})
   301  	require.NoError(t, err)
   302  	clientInputs <- buf
   303  
   304  	for i := 0; i < n; i++ {
   305  		buf := <-outVals
   306  		val := &testMsg{}
   307  		require.Nil(t, protobuf.Decode(buf, val))
   308  		require.Equal(t, val.I, int64(n))
   309  	}
   310  
   311  	close(clientInputs)
   312  }
   313  
   314  // If the caller closes early the client input chans then the
   315  // ProcessClientStreamRequest should not try to decode an empty buffer
   316  func TestServiceProcessor_ProcessClientStreamRequest_close_early(t *testing.T) {
   317  	h1 := NewLocalServer(tSuite, 2000)
   318  	defer h1.Close()
   319  
   320  	p := NewServiceProcessor(&Context{server: h1})
   321  	// The function need to use the same outChan and closeChan if a request is
   322  	// coming from the same client that expects the same outChan to be used.
   323  	serviceStruct := struct {
   324  		once      sync.Once
   325  		outChan   chan network.Message
   326  		closeChan chan bool
   327  	}{
   328  		outChan:   make(chan network.Message, 10),
   329  		closeChan: make(chan bool),
   330  	}
   331  
   332  	h := func(m *testMsg) (chan network.Message, chan bool, error) {
   333  		go func() {
   334  			for i := 0; i < int(m.I); i++ {
   335  				serviceStruct.outChan <- m
   336  			}
   337  			<-serviceStruct.closeChan
   338  			serviceStruct.once.Do(func() {
   339  				close(serviceStruct.outChan)
   340  			})
   341  		}()
   342  		return serviceStruct.outChan, serviceStruct.closeChan, nil
   343  	}
   344  	require.Nil(t, p.RegisterStreamingHandler(h))
   345  
   346  	// Sending a first message from the client to the service.
   347  	clientInputs := make(chan []byte, 10)
   348  	// early close by the caller
   349  	close(clientInputs)
   350  	_, err := p.ProcessClientStreamRequest(nil, "testMsg", clientInputs)
   351  	require.NoError(t, err)
   352  }
   353  
   354  func TestProcessor_ProcessClientRequest(t *testing.T) {
   355  	local := NewTCPTest(tSuite)
   356  
   357  	// generate 1 host
   358  	h := local.GenServers(1)[0]
   359  	defer local.CloseAll()
   360  
   361  	client := local.NewClient(testServiceName)
   362  	msg := &testMsg{}
   363  	err := client.SendProtobuf(h.ServerIdentity, &testMsg{12}, msg)
   364  	require.Nil(t, err)
   365  	if msg == nil {
   366  		require.Fail(t, "Msg should not be nil")
   367  	}
   368  	if msg.I != 12 {
   369  		require.Fail(t, "Didn't send 12")
   370  	}
   371  }
   372  
   373  // Test that the panic will be recovered and announced without crashing the server.
   374  func TestProcessor_PanicClientRequest(t *testing.T) {
   375  	local := NewTCPTest(tSuite)
   376  
   377  	h := local.GenServers(1)[0]
   378  	defer local.CloseAll()
   379  
   380  	client := local.NewClient(testServiceName)
   381  	err := client.SendProtobuf(h.ServerIdentity, &testPanicMsg{}, struct{}{})
   382  	require.Error(t, err)
   383  	require.Contains(t, err.Error(), "deadbeef")
   384  }
   385  
   386  type testMsg struct {
   387  	I int64
   388  }
   389  
   390  type testMsg2 testMsg
   391  type testMsg3 testMsg
   392  type testMsg4 testMsg
   393  type testMsg5 testMsg
   394  type testPanicMsg struct{}
   395  
   396  func procMsg(msg *testMsg) (network.Message, error) {
   397  	// Return an error for testing
   398  	if msg.I == 42 {
   399  		return nil, xerrors.New("42 is NOT the answer")
   400  	}
   401  	return msg, nil
   402  }
   403  
   404  func procMsg2(msg *testMsg2) (network.Message, error) {
   405  	// Return an error for testing
   406  	if msg.I == 42 {
   407  		return nil, xerrors.New("42 is NOT the answer")
   408  	}
   409  	return nil, nil
   410  }
   411  
   412  func procMsg3(msg *testMsg3) (network.Message, error) {
   413  	return nil, nil
   414  }
   415  
   416  func procMsg4(msg *testMsg4) (*testMsg4, error) {
   417  	return msg, nil
   418  }
   419  
   420  func procMsgWrong1() (network.Message, error) {
   421  	return nil, nil
   422  }
   423  
   424  func procMsgWrong2(msg testMsg2) (network.Message, error) {
   425  	return msg, nil
   426  }
   427  
   428  func procMsgWrong3(msg *testMsg3) error {
   429  	return nil
   430  }
   431  
   432  func procMsgWrong4(msg *testMsg) (*network.Message, error) {
   433  	return nil, nil
   434  }
   435  
   436  func procMsgWrong5(msg *testMsg) (int, error) {
   437  	return 10, nil
   438  }
   439  
   440  func procMsgWrong6(msg *testMsg) (testMsg, error) {
   441  	return *msg, nil
   442  }
   443  
   444  type testService struct {
   445  	*ServiceProcessor
   446  	Msg interface{}
   447  }
   448  
   449  func newTestService(c *Context) (Service, error) {
   450  	ts := &testService{
   451  		ServiceProcessor: NewServiceProcessor(c),
   452  	}
   453  	if err := ts.RegisterHandlers(ts.ProcessMsg, ts.ProcessMsgPanic); err != nil {
   454  		panic(err.Error())
   455  	}
   456  
   457  	if err := ts.RegisterRESTHandler(procRestMsgGET1, testServiceName, "GET", 3, 3); err != nil {
   458  		panic(err.Error())
   459  	}
   460  	if err := ts.RegisterRESTHandler(procRestMsgGET2, testServiceName, "GET", 3, 3); err != nil {
   461  		panic(err.Error())
   462  	}
   463  	if err := ts.RegisterRESTHandler(procRestMsgGET3, testServiceName, "GET", 3, 3); err != nil {
   464  		panic(err.Error())
   465  	}
   466  	if err := ts.RegisterRESTHandler(procRestMsgPOSTString, testServiceName, "POST", 3, 3); err != nil {
   467  		panic(err.Error())
   468  	}
   469  	if err := ts.RegisterRESTHandler(procRestMsgPOSTPoint, testServiceName, "POST", 3, 3); err != nil {
   470  		panic(err.Error())
   471  	}
   472  	return ts, nil
   473  }
   474  
   475  func (ts *testService) NewProtocol(tn *TreeNodeInstance, conf *GenericConfig) (ProtocolInstance, error) {
   476  	return nil, nil
   477  }
   478  
   479  func (ts *testService) ProcessMsg(msg *testMsg) (network.Message, error) {
   480  	ts.Msg = msg
   481  	return msg, nil
   482  }
   483  
   484  func (ts *testService) ProcessMsgPanic(msg *testPanicMsg) (network.Message, error) {
   485  	panic("deadbeef")
   486  }
   487  
   488  func TestProcessor_REST_Registration(t *testing.T) {
   489  	h1 := NewLocalServer(tSuite, 2000)
   490  	defer h1.Close()
   491  	p := NewServiceProcessor(&Context{server: h1})
   492  	require.NoError(t, p.RegisterRESTHandler(procRestMsgGET1, "dummyService", "GET", 3, 3))
   493  	require.NoError(t, p.RegisterRESTHandler(procRestMsgGET2, "dummyService", "GET", 3, 3))
   494  	require.NoError(t, p.RegisterRESTHandler(procRestMsgGET3, "dummyService", "GET", 3, 3))
   495  
   496  	require.NoError(t, p.RegisterRESTHandler(procRestMsgPOSTString, "dummyService", "POST", 3, 3))
   497  	require.NoError(t, p.RegisterRESTHandler(procRestMsgPOSTPoint, "dummyService", "POST", 3, 3))
   498  	require.NoError(t, p.RegisterRESTHandler(procMsg, "dummyService", "POST", 3, 3))
   499  	require.NoError(t, p.RegisterRESTHandler(procMsg2, "dummyService", "POST", 3, 3))
   500  	require.NoError(t, p.RegisterRESTHandler(procMsg3, "dummyService", "POST", 3, 3))
   501  	require.NoError(t, p.RegisterRESTHandler(procMsg4, "dummyService", "POST", 3, 3))
   502  
   503  	require.Error(t, p.RegisterRESTHandler(procRestMsgGET3, "dummyService", "GET", 3, 2))
   504  	require.Error(t, p.RegisterRESTHandler(procRestMsgGET3, "dummyService", "GET", 1, 2))
   505  	require.Error(t, p.RegisterRESTHandler(procRestMsgGETWrong1, "dummyService", "GET", 3, 3))
   506  	require.Error(t, p.RegisterRESTHandler(procRestMsgGETWrong2, "dummyService", "GET", 3, 3))
   507  	require.Error(t, p.RegisterRESTHandler(procRestMsgGETWrong3, "dummyService", "GET", 3, 3))
   508  	require.Error(t, p.RegisterRESTHandler(procRestMsgGET1, "dummyService", "XXX", 3, 3))
   509  
   510  	require.Error(t, p.RegisterRESTHandler(procMsgWrong1, "dummyService", "POST", 3, 3))
   511  	require.Error(t, p.RegisterRESTHandler(procMsgWrong2, "dummyService", "POST", 3, 3))
   512  	require.Error(t, p.RegisterRESTHandler(procMsgWrong3, "dummyService", "POST", 3, 3))
   513  	require.Error(t, p.RegisterRESTHandler(procMsgWrong4, "dummyService", "POST", 3, 3))
   514  	require.Error(t, p.RegisterRESTHandler(procMsgWrong5, "dummyService", "POST", 3, 3))
   515  	require.Error(t, p.RegisterRESTHandler(procMsgWrong6, "dummyService", "POST", 3, 3))
   516  }
   517  
   518  type bnPoint struct {
   519  	P kyber.Point
   520  }
   521  
   522  type bnPointWrapper struct {
   523  	P []byte
   524  }
   525  
   526  func (p bnPoint) MarshalJSON() ([]byte, error) {
   527  	buf, err := p.P.MarshalBinary()
   528  	if err != nil {
   529  		return nil, err
   530  	}
   531  	return []byte(fmt.Sprintf(`{"P": "%s"}`, base64.StdEncoding.EncodeToString(buf))), nil
   532  }
   533  
   534  func (p *bnPoint) UnmarshalJSON(b []byte) error {
   535  	wrapper := bnPointWrapper{}
   536  	if err := json.Unmarshal(b, &wrapper); err != nil {
   537  		return err
   538  	}
   539  	suite := bn256.NewSuite()
   540  	g2 := suite.G2().Point()
   541  	if err := g2.UnmarshalBinary(wrapper.P); err != nil {
   542  		return err
   543  	}
   544  	p.P = g2
   545  	return nil
   546  }
   547  
   548  type edPoint struct {
   549  	P kyber.Point
   550  }
   551  
   552  type edPointWrapper struct {
   553  	P []byte
   554  }
   555  
   556  func (p edPoint) MarshalJSON() ([]byte, error) {
   557  	buf, err := p.P.MarshalBinary()
   558  	if err != nil {
   559  		return nil, err
   560  	}
   561  	return []byte(fmt.Sprintf(`{"P": "%s"}`, base64.StdEncoding.EncodeToString(buf))), nil
   562  }
   563  
   564  func (p *edPoint) UnmarshalJSON(b []byte) error {
   565  	wrapper := edPointWrapper{}
   566  	if err := json.Unmarshal(b, &wrapper); err != nil {
   567  		return err
   568  	}
   569  	suite := edwards25519.NewBlakeSHA256Ed25519()
   570  	point := suite.Point()
   571  	if err := point.UnmarshalBinary(wrapper.P); err != nil {
   572  		return err
   573  	}
   574  	p.P = point
   575  	return nil
   576  }
   577  
   578  type twoPoints struct {
   579  	PointEd edPoint
   580  	PointBn bnPoint
   581  }
   582  
   583  func TestMarshalJSON_bn(t *testing.T) {
   584  	suite := bn256.NewSuite()
   585  	_, pk := bls.NewKeyPair(suite, random.New())
   586  	p := bnPoint{pk}
   587  	buf, err := json.Marshal(&p)
   588  	require.NoError(t, err)
   589  
   590  	p2 := bnPoint{}
   591  	err = json.Unmarshal(buf, &p2)
   592  	require.NoError(t, err)
   593  
   594  	require.True(t, p2.P.Equal(pk))
   595  }
   596  
   597  func TestMarshalJSON_ed(t *testing.T) {
   598  	suite := edwards25519.NewBlakeSHA256Ed25519()
   599  	pk := key.NewKeyPair(suite).Public
   600  
   601  	p := edPoint{pk}
   602  	buf, err := json.Marshal(&p)
   603  	require.NoError(t, err)
   604  
   605  	p2 := edPoint{}
   606  	err = json.Unmarshal(buf, &p2)
   607  	require.NoError(t, err)
   608  
   609  	require.True(t, p2.P.Equal(pk))
   610  }
   611  
   612  func TestMarshalJSON_twoPoints(t *testing.T) {
   613  	pkEd := key.NewKeyPair(edwards25519.NewBlakeSHA256Ed25519()).Public
   614  	_, pkBn := bls.NewKeyPair(bn256.NewSuite(), random.New())
   615  
   616  	pTwo := twoPoints{edPoint{pkEd}, bnPoint{pkBn}}
   617  	buf, err := json.Marshal(&pTwo)
   618  	require.NoError(t, err)
   619  
   620  	pTwo2 := twoPoints{}
   621  	err = json.Unmarshal(buf, &pTwo2)
   622  	require.NoError(t, err)
   623  
   624  	require.True(t, pTwo2.PointEd.P.Equal(pkEd))
   625  	require.True(t, pTwo2.PointBn.P.Equal(pkBn))
   626  }
   627  
   628  func TestProcessor_REST_Handler(t *testing.T) {
   629  	log.AddUserUninterestingGoroutine("created by net/http.(*Transport).dialConn")
   630  
   631  	local := NewTCPTest(tSuite)
   632  
   633  	// generate 1 host
   634  	h := local.GenServers(1)[0]
   635  	defer local.CloseAll()
   636  
   637  	c := http.Client{}
   638  	port, err := strconv.Atoi(h.ServerIdentity.Address.Port())
   639  	require.NoError(t, err)
   640  	addr := "http://" + h.ServerIdentity.Address.Host() + ":" + strconv.Itoa(port+1)
   641  
   642  	// get with empty "body"
   643  	resp, err := c.Get(addr + "/v3/testService/restMsgGET1")
   644  	require.NoError(t, err)
   645  	require.Equal(t, resp.StatusCode, http.StatusOK)
   646  	msg := testMsg{}
   647  	require.NoError(t, json.NewDecoder(resp.Body).Decode(&msg))
   648  	require.Equal(t, int64(42), msg.I)
   649  
   650  	// get by an integer
   651  	resp, err = c.Get(addr + "/v3/testService/restMsgGET2/99")
   652  	require.NoError(t, err)
   653  	require.Equal(t, resp.StatusCode, http.StatusOK)
   654  	msg = testMsg{}
   655  	require.NoError(t, json.NewDecoder(resp.Body).Decode(&msg))
   656  	require.Equal(t, int64(99), msg.I)
   657  
   658  	// get by byte slice, e.g., skipchain ID
   659  	resp, err = c.Get(addr + "/v3/testService/restMsgGET3/deadbeef")
   660  	require.NoError(t, err)
   661  	require.Equal(t, resp.StatusCode, http.StatusOK)
   662  	msg = testMsg{}
   663  	require.NoError(t, json.NewDecoder(resp.Body).Decode(&msg))
   664  	require.Equal(t, int64(0xde), msg.I)
   665  
   666  	// wrong url
   667  	// NOTE: the error code is 400 because the websocket upgrade failed
   668  	// usually it should be http.StatusNotFound
   669  	resp, err = c.Get(addr + "/v3/testService/doesnotexist")
   670  	require.NoError(t, err)
   671  	require.Equal(t, resp.StatusCode, http.StatusBadRequest)
   672  
   673  	// wrong url (extra slash)
   674  	resp, err = c.Get(addr + "/v3/testService/restMsgGET3/deadbeef/")
   675  	require.NoError(t, err)
   676  	require.Equal(t, resp.StatusCode, http.StatusNotFound)
   677  	checkJSONMsg(t, resp.Body, "invalid path")
   678  
   679  	// wrong encoding of integer
   680  	resp, err = c.Get(addr + "/v3/testService/restMsgGET2/one")
   681  	require.NoError(t, err)
   682  	require.Equal(t, resp.StatusCode, http.StatusNotFound)
   683  	checkJSONMsg(t, resp.Body, "invalid path")
   684  
   685  	// wrong encoding of byte slice (must be hex)
   686  	resp, err = c.Get(addr + "/v3/testService/restMsgGET3/zzzz")
   687  	require.NoError(t, err)
   688  	require.Equal(t, resp.StatusCode, http.StatusNotFound)
   689  	checkJSONMsg(t, resp.Body, "invalid path")
   690  
   691  	// good post request
   692  	resp, err = c.Post(addr+"/v3/testService/restMsgPOSTString", "application/json", bytes.NewReader([]byte(`{"S": "42"}`)))
   693  	require.NoError(t, err)
   694  	require.Equal(t, resp.StatusCode, http.StatusOK)
   695  	require.NoError(t, json.NewDecoder(resp.Body).Decode(&testMsg{}))
   696  
   697  	// wrong content type
   698  	resp, err = c.Post(addr+"/v3/testService/restMsgPOSTString", "application/text", bytes.NewReader([]byte(`{"S": "42"}`)))
   699  	require.NoError(t, err)
   700  	require.Equal(t, resp.StatusCode, http.StatusBadRequest)
   701  	checkJSONMsg(t, resp.Body, "content type needs to be application/json")
   702  
   703  	// wrong value in body
   704  	resp, err = c.Post(addr+"/v3/testService/restMsgPOSTString", "application/json", bytes.NewReader([]byte(`{"S": "43"}`)))
   705  	require.NoError(t, err)
   706  	require.Equal(t, resp.StatusCode, http.StatusBadRequest)
   707  	checkJSONMsg(t, resp.Body, "processing error")
   708  
   709  	// wrong field name
   710  	resp, err = c.Post(addr+"/v3/testService/restMsgPOSTString", "application/json", bytes.NewReader([]byte(`{"T": "42"}`)))
   711  	require.NoError(t, err)
   712  	require.Equal(t, resp.StatusCode, http.StatusBadRequest)
   713  	checkJSONMsg(t, resp.Body, "processing error")
   714  
   715  	// wrong method
   716  	resp, err = c.Get(addr + "/v3/testService/restMsgPOSTString")
   717  	require.NoError(t, err)
   718  	require.Equal(t, resp.StatusCode, http.StatusMethodNotAllowed)
   719  	checkJSONMsg(t, resp.Body, "unsupported method")
   720  
   721  	// test sending points
   722  	_, pk := bls.NewKeyPair(bn256.NewSuite(), random.New())
   723  	buf, err := json.Marshal(&restMsgPOSTPoint{bnPoint{pk}})
   724  	require.NoError(t, err)
   725  	resp, err = c.Post(addr+"/v3/testService/restMsgPOSTPoint", "application/json", bytes.NewReader(buf))
   726  	require.NoError(t, err)
   727  	require.Equal(t, resp.StatusCode, http.StatusOK)
   728  	respPoint := restMsgPOSTPoint{}
   729  	require.NoError(t, json.NewDecoder(resp.Body).Decode(&respPoint))
   730  	require.True(t, respPoint.bnPoint.P.Equal(pk))
   731  }
   732  
   733  func checkJSONMsg(t *testing.T, r io.Reader, contains string) {
   734  	s, err := ioutil.ReadAll(r)
   735  	require.NoError(t, err)
   736  	type msg struct {
   737  		Message string `json:"message"`
   738  	}
   739  	var m msg
   740  	require.NoError(t, json.Unmarshal(s, &m))
   741  	require.NotEmpty(t, m.Message)
   742  	require.Contains(t, m.Message, contains)
   743  }
   744  
   745  func procRestMsgGET1(s *restMsgGET1) (*testMsg, error) {
   746  	return &testMsg{42}, nil
   747  }
   748  
   749  func procRestMsgGET2(s *restMsgGET2) (*testMsg, error) {
   750  	return &testMsg{int64(s.X)}, nil
   751  }
   752  
   753  func procRestMsgGET3(s *restMsgGET3) (*testMsg, error) {
   754  	return &testMsg{int64(s.Xs[0])}, nil
   755  }
   756  
   757  func procRestMsgGETWrong1(s *restMsgGETWrong1) (*testMsg, error) {
   758  	return &testMsg{}, nil
   759  }
   760  
   761  func procRestMsgGETWrong2(s *restMsgGETWrong2) (*testMsg, error) {
   762  	return &testMsg{}, nil
   763  }
   764  
   765  func procRestMsgGETWrong3(s *restMsgGETWrong3) (*testMsg, error) {
   766  	return &testMsg{}, nil
   767  }
   768  
   769  func procRestMsgPOSTString(s *restMsgPOSTString) (*testMsg, error) {
   770  	if s.S != "42" {
   771  		return nil, xerrors.New("not the right answer")
   772  	}
   773  	return &testMsg{}, nil
   774  }
   775  
   776  func procRestMsgPOSTPoint(s *restMsgPOSTPoint) (*restMsgPOSTPoint, error) {
   777  	return &restMsgPOSTPoint{s.bnPoint}, nil
   778  }
   779  
   780  type restMsgGET1 struct {
   781  }
   782  
   783  type restMsgGET2 struct {
   784  	X int
   785  }
   786  
   787  type restMsgGET3 struct {
   788  	Xs []byte
   789  }
   790  
   791  type restMsgGETWrong1 struct {
   792  	X float64
   793  }
   794  
   795  type restMsgGETWrong2 struct {
   796  	X float64
   797  	Y float64
   798  }
   799  
   800  type restMsgGETWrong3 struct {
   801  	Xs []int
   802  }
   803  
   804  type restMsgPOSTString struct {
   805  	S string
   806  }
   807  
   808  type restMsgPOSTPoint struct {
   809  	bnPoint
   810  }