| 
									
										
										
										
											2013-11-05 08:25:17 +08:00
										 |  |  | package sftp | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-11-05 11:36:38 +08:00
										 |  |  | import ( | 
					
						
							|  |  |  | 	"bytes" | 
					
						
							| 
									
										
										
										
											2014-09-26 04:40:48 +08:00
										 |  |  | 	"encoding" | 
					
						
							|  |  |  | 	"os" | 
					
						
							| 
									
										
										
										
											2013-11-05 11:36:38 +08:00
										 |  |  | 	"testing" | 
					
						
							|  |  |  | ) | 
					
						
							| 
									
										
										
										
											2013-11-05 08:25:17 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | var marshalUint32Tests = []struct { | 
					
						
							|  |  |  | 	v    uint32 | 
					
						
							|  |  |  | 	want []byte | 
					
						
							|  |  |  | }{ | 
					
						
							|  |  |  | 	{1, []byte{0, 0, 0, 1}}, | 
					
						
							|  |  |  | 	{256, []byte{0, 0, 1, 0}}, | 
					
						
							|  |  |  | 	{^uint32(0), []byte{255, 255, 255, 255}}, | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func TestMarshalUint32(t *testing.T) { | 
					
						
							|  |  |  | 	for _, tt := range marshalUint32Tests { | 
					
						
							|  |  |  | 		got := marshalUint32(nil, tt.v) | 
					
						
							|  |  |  | 		if !bytes.Equal(tt.want, got) { | 
					
						
							|  |  |  | 			t.Errorf("marshalUint32(%d): want %v, got %v", tt.v, tt.want, got) | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | var marshalUint64Tests = []struct { | 
					
						
							|  |  |  | 	v    uint64 | 
					
						
							|  |  |  | 	want []byte | 
					
						
							|  |  |  | }{ | 
					
						
							|  |  |  | 	{1, []byte{0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1}}, | 
					
						
							|  |  |  | 	{256, []byte{0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x0}}, | 
					
						
							|  |  |  | 	{^uint64(0), []byte{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}}, | 
					
						
							| 
									
										
										
										
											2014-05-25 12:27:01 +08:00
										 |  |  | 	{1 << 32, []byte{0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0}}, | 
					
						
							| 
									
										
										
										
											2013-11-05 08:25:17 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func TestMarshalUint64(t *testing.T) { | 
					
						
							|  |  |  | 	for _, tt := range marshalUint64Tests { | 
					
						
							|  |  |  | 		got := marshalUint64(nil, tt.v) | 
					
						
							|  |  |  | 		if !bytes.Equal(tt.want, got) { | 
					
						
							|  |  |  | 			t.Errorf("marshalUint64(%d): want %#v, got %#v", tt.v, tt.want, got) | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | var marshalStringTests = []struct { | 
					
						
							|  |  |  | 	v    string | 
					
						
							|  |  |  | 	want []byte | 
					
						
							|  |  |  | }{ | 
					
						
							|  |  |  | 	{"", []byte{0, 0, 0, 0}}, | 
					
						
							|  |  |  | 	{"/foo", []byte{0x0, 0x0, 0x0, 0x4, 0x2f, 0x66, 0x6f, 0x6f}}, | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func TestMarshalString(t *testing.T) { | 
					
						
							|  |  |  | 	for _, tt := range marshalStringTests { | 
					
						
							|  |  |  | 		got := marshalString(nil, tt.v) | 
					
						
							|  |  |  | 		if !bytes.Equal(tt.want, got) { | 
					
						
							|  |  |  | 			t.Errorf("marshalString(%q): want %#v, got %#v", tt.v, tt.want, got) | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2013-11-05 08:36:47 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | var marshalTests = []struct { | 
					
						
							|  |  |  | 	v    interface{} | 
					
						
							|  |  |  | 	want []byte | 
					
						
							|  |  |  | }{ | 
					
						
							| 
									
										
										
										
											2013-11-05 11:36:38 +08:00
										 |  |  | 	{uint8(1), []byte{1}}, | 
					
						
							|  |  |  | 	{byte(1), []byte{1}}, | 
					
						
							| 
									
										
										
										
											2013-11-05 08:36:47 +08:00
										 |  |  | 	{uint32(1), []byte{0, 0, 0, 1}}, | 
					
						
							|  |  |  | 	{uint64(1), []byte{0, 0, 0, 0, 0, 0, 0, 1}}, | 
					
						
							|  |  |  | 	{"foo", []byte{0x0, 0x0, 0x0, 0x3, 0x66, 0x6f, 0x6f}}, | 
					
						
							| 
									
										
										
										
											2013-11-05 11:36:38 +08:00
										 |  |  | 	{[]uint32{1, 2, 3, 4}, []byte{0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x2, 0x0, 0x0, 0x0, 0x3, 0x0, 0x0, 0x0, 0x4}}, | 
					
						
							| 
									
										
										
										
											2013-11-05 08:36:47 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func TestMarshal(t *testing.T) { | 
					
						
							|  |  |  | 	for _, tt := range marshalTests { | 
					
						
							|  |  |  | 		got := marshal(nil, tt.v) | 
					
						
							|  |  |  | 		if !bytes.Equal(tt.want, got) { | 
					
						
							|  |  |  | 			t.Errorf("marshal(%v): want %#v, got %#v", tt.v, tt.want, got) | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2013-11-05 09:23:48 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | var unmarshalUint32Tests = []struct { | 
					
						
							|  |  |  | 	b    []byte | 
					
						
							|  |  |  | 	want uint32 | 
					
						
							|  |  |  | 	rest []byte | 
					
						
							|  |  |  | }{ | 
					
						
							|  |  |  | 	{[]byte{0, 0, 0, 0}, 0, nil}, | 
					
						
							|  |  |  | 	{[]byte{0, 0, 1, 0}, 256, nil}, | 
					
						
							|  |  |  | 	{[]byte{255, 0, 0, 255}, 4278190335, nil}, | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func TestUnmarshalUint32(t *testing.T) { | 
					
						
							|  |  |  | 	for _, tt := range unmarshalUint32Tests { | 
					
						
							|  |  |  | 		got, rest := unmarshalUint32(tt.b) | 
					
						
							|  |  |  | 		if got != tt.want || !bytes.Equal(rest, tt.rest) { | 
					
						
							|  |  |  | 			t.Errorf("unmarshalUint32(%v): want %v, %#v, got %v, %#v", tt.b, tt.want, tt.rest, got, rest) | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | var unmarshalUint64Tests = []struct { | 
					
						
							|  |  |  | 	b    []byte | 
					
						
							|  |  |  | 	want uint64 | 
					
						
							|  |  |  | 	rest []byte | 
					
						
							|  |  |  | }{ | 
					
						
							|  |  |  | 	{[]byte{0, 0, 0, 0, 0, 0, 0, 0}, 0, nil}, | 
					
						
							|  |  |  | 	{[]byte{0, 0, 0, 0, 0, 0, 1, 0}, 256, nil}, | 
					
						
							|  |  |  | 	{[]byte{255, 0, 0, 0, 0, 0, 0, 255}, 18374686479671623935, nil}, | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func TestUnmarshalUint64(t *testing.T) { | 
					
						
							|  |  |  | 	for _, tt := range unmarshalUint64Tests { | 
					
						
							|  |  |  | 		got, rest := unmarshalUint64(tt.b) | 
					
						
							|  |  |  | 		if got != tt.want || !bytes.Equal(rest, tt.rest) { | 
					
						
							|  |  |  | 			t.Errorf("unmarshalUint64(%v): want %v, %#v, got %v, %#v", tt.b, tt.want, tt.rest, got, rest) | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2013-11-05 09:31:20 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | var unmarshalStringTests = []struct { | 
					
						
							|  |  |  | 	b    []byte | 
					
						
							|  |  |  | 	want string | 
					
						
							|  |  |  | 	rest []byte | 
					
						
							|  |  |  | }{ | 
					
						
							|  |  |  | 	{marshalString(nil, ""), "", nil}, | 
					
						
							|  |  |  | 	{marshalString(nil, "blah"), "blah", nil}, | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func TestUnmarshalString(t *testing.T) { | 
					
						
							|  |  |  | 	for _, tt := range unmarshalStringTests { | 
					
						
							|  |  |  | 		got, rest := unmarshalString(tt.b) | 
					
						
							|  |  |  | 		if got != tt.want || !bytes.Equal(rest, tt.rest) { | 
					
						
							|  |  |  | 			t.Errorf("unmarshalUint64(%v): want %q, %#v, got %q, %#v", tt.b, tt.want, tt.rest, got, rest) | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2013-11-05 11:36:38 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | var sendPacketTests = []struct { | 
					
						
							| 
									
										
										
										
											2014-09-26 04:40:48 +08:00
										 |  |  | 	p    encoding.BinaryMarshaler | 
					
						
							| 
									
										
										
										
											2013-11-05 11:36:38 +08:00
										 |  |  | 	want []byte | 
					
						
							|  |  |  | }{ | 
					
						
							| 
									
										
										
										
											2014-09-26 04:40:48 +08:00
										 |  |  | 	{sshFxInitPacket{ | 
					
						
							| 
									
										
										
										
											2013-11-05 11:36:38 +08:00
										 |  |  | 		Version: 3, | 
					
						
							| 
									
										
										
										
											2015-07-25 16:19:29 +08:00
										 |  |  | 		Extensions: []ExtensionPair{ | 
					
						
							| 
									
										
										
										
											2013-11-05 11:36:38 +08:00
										 |  |  | 			{"posix-rename@openssh.com", "1"}, | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 	}, []byte{0x0, 0x0, 0x0, 0x26, 0x1, 0x0, 0x0, 0x0, 0x3, 0x0, 0x0, 0x0, 0x18, 0x70, 0x6f, 0x73, 0x69, 0x78, 0x2d, 0x72, 0x65, 0x6e, 0x61, 0x6d, 0x65, 0x40, 0x6f, 0x70, 0x65, 0x6e, 0x73, 0x73, 0x68, 0x2e, 0x63, 0x6f, 0x6d, 0x0, 0x0, 0x0, 0x1, 0x31}}, | 
					
						
							| 
									
										
										
										
											2014-09-26 04:40:48 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	{sshFxpOpenPacket{ | 
					
						
							|  |  |  | 		Id:     1, | 
					
						
							|  |  |  | 		Path:   "/foo", | 
					
						
							|  |  |  | 		Pflags: flags(os.O_RDONLY), | 
					
						
							| 
									
										
										
										
											2014-10-10 02:40:02 +08:00
										 |  |  | 	}, []byte{0x0, 0x0, 0x0, 0x15, 0x3, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x4, 0x2f, 0x66, 0x6f, 0x6f, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0}}, | 
					
						
							| 
									
										
										
										
											2014-09-26 04:40:48 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	{sshFxpWritePacket{ | 
					
						
							|  |  |  | 		Id:     124, | 
					
						
							|  |  |  | 		Handle: "foo", | 
					
						
							|  |  |  | 		Offset: 13, | 
					
						
							|  |  |  | 		Length: uint32(len([]byte("bar"))), | 
					
						
							|  |  |  | 		Data:   []byte("bar"), | 
					
						
							|  |  |  | 	}, []byte{0x0, 0x0, 0x0, 0x1b, 0x6, 0x0, 0x0, 0x0, 0x7c, 0x0, 0x0, 0x0, 0x3, 0x66, 0x6f, 0x6f, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xd, 0x0, 0x0, 0x0, 0x3, 0x62, 0x61, 0x72}}, | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	{sshFxpSetstatPacket{ | 
					
						
							|  |  |  | 		Id:    31, | 
					
						
							|  |  |  | 		Path:  "/bar", | 
					
						
							|  |  |  | 		Flags: flags(os.O_WRONLY), | 
					
						
							|  |  |  | 		Attrs: struct { | 
					
						
							|  |  |  | 			Uid uint32 | 
					
						
							|  |  |  | 			Gid uint32 | 
					
						
							|  |  |  | 		}{1000, 100}, | 
					
						
							|  |  |  | 	}, []byte{0x0, 0x0, 0x0, 0x19, 0x9, 0x0, 0x0, 0x0, 0x1f, 0x0, 0x0, 0x0, 0x4, 0x2f, 0x62, 0x61, 0x72, 0x0, 0x0, 0x0, 0x2, 0x0, 0x0, 0x3, 0xe8, 0x0, 0x0, 0x0, 0x64}}, | 
					
						
							| 
									
										
										
										
											2013-11-05 11:36:38 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func TestSendPacket(t *testing.T) { | 
					
						
							|  |  |  | 	for _, tt := range sendPacketTests { | 
					
						
							|  |  |  | 		var w bytes.Buffer | 
					
						
							|  |  |  | 		sendPacket(&w, tt.p) | 
					
						
							|  |  |  | 		if got := w.Bytes(); !bytes.Equal(tt.want, got) { | 
					
						
							|  |  |  | 			t.Errorf("sendPacket(%v): want %#v, got %#v", tt.p, tt.want, got) | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-09-26 04:40:48 +08:00
										 |  |  | func sp(p encoding.BinaryMarshaler) []byte { | 
					
						
							| 
									
										
										
										
											2013-11-05 11:36:38 +08:00
										 |  |  | 	var w bytes.Buffer | 
					
						
							|  |  |  | 	sendPacket(&w, p) | 
					
						
							|  |  |  | 	return w.Bytes() | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | var recvPacketTests = []struct { | 
					
						
							|  |  |  | 	b    []byte | 
					
						
							|  |  |  | 	want uint8 | 
					
						
							|  |  |  | 	rest []byte | 
					
						
							|  |  |  | }{ | 
					
						
							| 
									
										
										
										
											2014-09-26 04:40:48 +08:00
										 |  |  | 	{sp(sshFxInitPacket{ | 
					
						
							| 
									
										
										
										
											2013-11-05 11:36:38 +08:00
										 |  |  | 		Version: 3, | 
					
						
							| 
									
										
										
										
											2015-07-25 16:19:29 +08:00
										 |  |  | 		Extensions: []ExtensionPair{ | 
					
						
							| 
									
										
										
										
											2013-11-05 11:36:38 +08:00
										 |  |  | 			{"posix-rename@openssh.com", "1"}, | 
					
						
							|  |  |  | 		}, | 
					
						
							| 
									
										
										
										
											2013-11-06 16:10:28 +08:00
										 |  |  | 	}), ssh_FXP_INIT, []byte{0x0, 0x0, 0x0, 0x3, 0x0, 0x0, 0x0, 0x18, 0x70, 0x6f, 0x73, 0x69, 0x78, 0x2d, 0x72, 0x65, 0x6e, 0x61, 0x6d, 0x65, 0x40, 0x6f, 0x70, 0x65, 0x6e, 0x73, 0x73, 0x68, 0x2e, 0x63, 0x6f, 0x6d, 0x0, 0x0, 0x0, 0x1, 0x31}}, | 
					
						
							| 
									
										
										
										
											2013-11-05 11:36:38 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func TestRecvPacket(t *testing.T) { | 
					
						
							|  |  |  | 	for _, tt := range recvPacketTests { | 
					
						
							|  |  |  | 		r := bytes.NewReader(tt.b) | 
					
						
							|  |  |  | 		got, rest, _ := recvPacket(r) | 
					
						
							|  |  |  | 		if got != tt.want || !bytes.Equal(rest, tt.rest) { | 
					
						
							|  |  |  | 			t.Errorf("recvPacket(%#v): want %v, %#v, got %v, %#v", tt.b, tt.want, tt.rest, got, rest) | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2014-09-26 04:40:48 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | func BenchmarkMarshalInit(b *testing.B) { | 
					
						
							|  |  |  | 	for i := 0; i < b.N; i++ { | 
					
						
							|  |  |  | 		sp(sshFxInitPacket{ | 
					
						
							|  |  |  | 			Version: 3, | 
					
						
							| 
									
										
										
										
											2015-07-25 16:19:29 +08:00
										 |  |  | 			Extensions: []ExtensionPair{ | 
					
						
							| 
									
										
										
										
											2014-09-26 04:40:48 +08:00
										 |  |  | 				{"posix-rename@openssh.com", "1"}, | 
					
						
							|  |  |  | 			}, | 
					
						
							|  |  |  | 		}) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func BenchmarkMarshalOpen(b *testing.B) { | 
					
						
							|  |  |  | 	for i := 0; i < b.N; i++ { | 
					
						
							|  |  |  | 		sp(sshFxpOpenPacket{ | 
					
						
							|  |  |  | 			Id:     1, | 
					
						
							|  |  |  | 			Path:   "/home/test/some/random/path", | 
					
						
							|  |  |  | 			Pflags: flags(os.O_RDONLY), | 
					
						
							|  |  |  | 		}) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func BenchmarkMarshalWriteWorstCase(b *testing.B) { | 
					
						
							|  |  |  | 	data := make([]byte, 32*1024) | 
					
						
							|  |  |  | 	for i := 0; i < b.N; i++ { | 
					
						
							|  |  |  | 		sp(sshFxpWritePacket{ | 
					
						
							|  |  |  | 			Id:     1, | 
					
						
							|  |  |  | 			Handle: "someopaquehandle", | 
					
						
							|  |  |  | 			Offset: 0, | 
					
						
							|  |  |  | 			Length: uint32(len(data)), | 
					
						
							|  |  |  | 			Data:   data, | 
					
						
							|  |  |  | 		}) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func BenchmarkMarshalWrite1k(b *testing.B) { | 
					
						
							|  |  |  | 	data := make([]byte, 1024) | 
					
						
							|  |  |  | 	for i := 0; i < b.N; i++ { | 
					
						
							|  |  |  | 		sp(sshFxpWritePacket{ | 
					
						
							|  |  |  | 			Id:     1, | 
					
						
							|  |  |  | 			Handle: "someopaquehandle", | 
					
						
							|  |  |  | 			Offset: 0, | 
					
						
							|  |  |  | 			Length: uint32(len(data)), | 
					
						
							|  |  |  | 			Data:   data, | 
					
						
							|  |  |  | 		}) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } |