THRIFT-2852 Better Open/IsOpen/Close behavior for StreamTransport.
Client: Go
Patch: Chi Vinh Le <cvl@chinet.info>

This closes #285
diff --git a/lib/go/thrift/iostream_transport.go b/lib/go/thrift/iostream_transport.go
index 314eaa6..82563e9 100644
--- a/lib/go/thrift/iostream_transport.go
+++ b/lib/go/thrift/iostream_transport.go
@@ -29,6 +29,7 @@
 	io.Reader
 	io.Writer
 	isReadWriter bool
+	closed       bool
 }
 
 type StreamTransportFactory struct {
@@ -95,12 +96,16 @@
 // (The streams must already be open at construction time, so this should
 // always return true.)
 func (p *StreamTransport) IsOpen() bool {
-	return true
+	return !p.closed
 }
 
 // (The streams must already be open. This method does nothing.)
 func (p *StreamTransport) Open() error {
-	return nil
+	if !p.closed {
+		return NewTTransportException(ALREADY_OPEN, "StreamTransport already open.")
+	} else {
+		return NewTTransportException(NOT_OPEN, "cannot reopen StreamTransport.")
+	}
 }
 
 // func (p *StreamTransport) Peek() bool {
@@ -109,6 +114,10 @@
 
 // Closes both the input and output streams.
 func (p *StreamTransport) Close() error {
+	if p.closed {
+		return NewTTransportException(NOT_OPEN, "StreamTransport already closed.")
+	}
+	p.closed = true
 	closedReader := false
 	if p.Reader != nil {
 		c, ok := p.Reader.(io.Closer)
diff --git a/lib/go/thrift/iostream_transport_test.go b/lib/go/thrift/iostream_transport_test.go
index 15ea2d4..15a6116 100644
--- a/lib/go/thrift/iostream_transport_test.go
+++ b/lib/go/thrift/iostream_transport_test.go
@@ -28,3 +28,25 @@
 	trans := NewStreamTransportRW(bytes.NewBuffer(make([]byte, 0, 1024)))
 	TransportTest(t, trans, trans)
 }
+
+func TestStreamTransportOpenClose(t *testing.T) {
+	trans := NewStreamTransportRW(bytes.NewBuffer(make([]byte, 0, 1024)))
+	if !trans.IsOpen() {
+		t.Fatal("StreamTransport should be already open")
+	}
+	if trans.Open() == nil {
+		t.Fatal("StreamTransport should return error when open twice")
+	}
+	if trans.Close() != nil {
+		t.Fatal("StreamTransport should not return error when closing open transport")
+	}
+	if trans.IsOpen() {
+		t.Fatal("StreamTransport should not be open after close")
+	}
+	if trans.Close() == nil {
+		t.Fatal("StreamTransport should return error when closing a non open transport")
+	}
+	if trans.Open() == nil {
+		t.Fatal("StreamTransport should not be able to reopen")
+	}
+}