git.gammaspectra.live/P2Pool/consensus/v3@v3.8.0/monero/client/levin/levin_test.go (about)

     1  package levin_test
     2  
     3  import (
     4  	"fmt"
     5  	"reflect"
     6  	"strings"
     7  	"testing"
     8  
     9  	"git.gammaspectra.live/P2Pool/consensus/v3/monero/client/levin"
    10  )
    11  
    12  func assertNoError(t *testing.T, err error, msgAndArgs ...any) {
    13  	if err != nil {
    14  		message := ""
    15  		if len(msgAndArgs) > 0 {
    16  			message = fmt.Sprint(msgAndArgs...) + ": "
    17  		}
    18  		t.Errorf("%sunexpected err: %s", message, err)
    19  	}
    20  }
    21  
    22  func assertError(t *testing.T, err error, msgAndArgs ...any) {
    23  	if err == nil {
    24  		message := ""
    25  		if len(msgAndArgs) > 0 {
    26  			message = fmt.Sprint(msgAndArgs...) + ": "
    27  		}
    28  		t.Errorf("%sexpected err", message)
    29  	}
    30  }
    31  
    32  func assertContains(t *testing.T, actual, expected string, msgAndArgs ...any) {
    33  	if !strings.Contains(actual, expected) {
    34  		message := ""
    35  		if len(msgAndArgs) > 0 {
    36  			message = fmt.Sprint(msgAndArgs...) + ": "
    37  		}
    38  		t.Errorf("%sactual: %v expected: %v", message, actual, expected)
    39  	}
    40  }
    41  
    42  func assertEqual(t *testing.T, actual, expected any, msgAndArgs ...any) {
    43  	if !reflect.DeepEqual(actual, expected) {
    44  		message := ""
    45  		if len(msgAndArgs) > 0 {
    46  			message = fmt.Sprint(msgAndArgs...) + ": "
    47  		}
    48  		t.Errorf("%sactual: %v expected: %v", message, actual, expected)
    49  	}
    50  }
    51  
    52  func it(t *testing.T, msg string, f func(t *testing.T)) {
    53  	t.Run(msg, func(t *testing.T) {
    54  		f(t)
    55  	})
    56  }
    57  
    58  func TestLevin(t *testing.T) {
    59  	t.Parallel()
    60  	t.Run("NewHeaderFromBytes", func(t *testing.T) {
    61  		it(t, "fails w/ wrong size", func(t *testing.T) {
    62  			bytes := []byte{
    63  				0xff,
    64  			}
    65  
    66  			_, err := levin.NewHeaderFromBytesBytes(bytes)
    67  			assertError(t, err)
    68  		})
    69  
    70  		it(t, "fails w/ wrong signature", func(t *testing.T) {
    71  			bytes := []byte{
    72  				0xff, 0xff, 0xff, 0xff, // signature
    73  				0xff, 0xff, 0xff, 0xff,
    74  				0x00, 0x00, 0x00, 0x00, // length
    75  				0x00, 0x00, 0x00, 0x00, //
    76  				0x00,                   // expects response
    77  				0x00, 0x00, 0x00, 0x00, // command
    78  				0x00, 0x00, 0x00, 0x00, // return code
    79  				0x00, 0x00, 0x00, 0x00, // flags
    80  				0x00, 0x00, 0x00, 0x00, // version
    81  			}
    82  
    83  			_, err := levin.NewHeaderFromBytesBytes(bytes)
    84  			assertError(t, err)
    85  			assertContains(t, err.Error(), "signature mismatch")
    86  		})
    87  
    88  		it(t, "fails w/ invalid command", func(t *testing.T) {
    89  			bytes := []byte{
    90  				0x01, 0x21, 0x01, 0x01, // signature
    91  				0x01, 0x01, 0x01, 0x01,
    92  				0x01, 0x00, 0x00, 0x00, // length
    93  				0x00, 0x00, 0x00, 0x00, //
    94  				0x01,                   // expects response
    95  				0xff, 0xff, 0xff, 0xff, // command
    96  				0x00, 0x00, 0x00, 0x00, // return code
    97  				0x00, 0x00, 0x00, 0x00, // flags
    98  				0x00, 0x00, 0x00, 0x00, // version
    99  			}
   100  
   101  			_, err := levin.NewHeaderFromBytesBytes(bytes)
   102  			assertError(t, err)
   103  			assertContains(t, err.Error(), "invalid command")
   104  		})
   105  
   106  		it(t, "fails w/ invalid return code", func(t *testing.T) {
   107  			bytes := []byte{
   108  				0x01, 0x21, 0x01, 0x01, // signature
   109  				0x01, 0x01, 0x01, 0x01,
   110  				0x01, 0x00, 0x00, 0x00, // length
   111  				0x00, 0x00, 0x00, 0x00, //
   112  				0x01,                   // expects response
   113  				0xe9, 0x03, 0x00, 0x00, // command
   114  				0xaa, 0xaa, 0xaa, 0xaa, // return code
   115  				0x00, 0x00, 0x00, 0x00, // flags
   116  				0x00, 0x00, 0x00, 0x00, // version
   117  			}
   118  
   119  			_, err := levin.NewHeaderFromBytesBytes(bytes)
   120  			assertError(t, err)
   121  			assertContains(t, err.Error(), "invalid return code")
   122  		})
   123  
   124  		it(t, "fails w/ invalid version", func(t *testing.T) {
   125  			bytes := []byte{
   126  				0x01, 0x21, 0x01, 0x01, // signature
   127  				0x01, 0x01, 0x01, 0x01,
   128  				0x01, 0x00, 0x00, 0x00, // length
   129  				0x00, 0x00, 0x00, 0x00, //
   130  				0x01,                   // expects response
   131  				0xe9, 0x03, 0x00, 0x00, // command
   132  				0x00, 0x00, 0x00, 0x00, // return code
   133  				0x02, 0x00, 0x00, 0x00, // flags
   134  				0x00, 0x00, 0x00, 0x00, // version
   135  			}
   136  
   137  			_, err := levin.NewHeaderFromBytesBytes(bytes)
   138  			assertError(t, err)
   139  			assertContains(t, err.Error(), "invalid version")
   140  		})
   141  
   142  		it(t, "assembles properly from pong", func(t *testing.T) {
   143  			bytes := []byte{
   144  				0x01, 0x21, 0x01, 0x01, // signature
   145  				0x01, 0x01, 0x01, 0x01,
   146  				0x01, 0x00, 0x00, 0x00, // length
   147  				0x00, 0x00, 0x00, 0x00, //
   148  				0x01,                   // expects response
   149  				0xeb, 0x03, 0x00, 0x00, // command
   150  				0x00, 0x00, 0x00, 0x00, // return code
   151  				0x02, 0x00, 0x00, 0x00, // flags
   152  				0x01, 0x00, 0x00, 0x00, // version
   153  			}
   154  
   155  			header, err := levin.NewHeaderFromBytesBytes(bytes)
   156  			assertNoError(t, err)
   157  			assertEqual(t, header.Command, levin.CommandPing)
   158  			assertEqual(t, header.ReturnCode, levin.LevinOk)
   159  			assertEqual(t, header.Flags, levin.LevinPacketReponse)
   160  			assertEqual(t, header.Version, levin.LevinProtocolVersion)
   161  		})
   162  	})
   163  
   164  	t.Run("NewRequestHeader", func(t *testing.T) {
   165  		it(t, "assembles properly w/ ping", func(t *testing.T) {
   166  			bytes := levin.NewRequestHeader(levin.CommandPing, 1).Bytes()
   167  
   168  			assertEqual(t, bytes, []byte{
   169  				0x01, 0x21, 0x01, 0x01, // signature
   170  				0x01, 0x01, 0x01, 0x01,
   171  				0x01, 0x00, 0x00, 0x00, // length		-- 0 for a ping msg
   172  				0x00, 0x00, 0x00, 0x00,
   173  				0x01,                   // expects response	-- `true` bool
   174  				0xeb, 0x03, 0x00, 0x00, // command		-- 1003 for ping
   175  				0x00, 0x00, 0x00, 0x00, // return code		-- 0 for requests
   176  				0x01, 0x00, 0x00, 0x00, // flags		-- Q(1st lsb) set for req
   177  				0x01, 0x00, 0x00, 0x00, // version
   178  			})
   179  		})
   180  
   181  		it(t, "assembles properly w/ handshake", func(t *testing.T) {
   182  			bytes := levin.NewRequestHeader(levin.CommandHandshake, 4).Bytes()
   183  
   184  			assertEqual(t, bytes, []byte{
   185  				0x01, 0x21, 0x01, 0x01, // signature
   186  				0x01, 0x01, 0x01, 0x01,
   187  				0x04, 0x00, 0x00, 0x00, // length		-- 0 for a ping msg
   188  				0x00, 0x00, 0x00, 0x00,
   189  				0x01, // expects response	-- `true` bool
   190  				0xe9, 0x03, 0x00, 0x00,
   191  				0x00, 0x00, 0x00, 0x00, // return code		-- 0 for requests
   192  				0x01, 0x00, 0x00, 0x00, // flags		-- Q(1st lsb) set for req
   193  				0x01, 0x00, 0x00, 0x00, // version
   194  			})
   195  		})
   196  	})
   197  }