github.com/datastax/go-cassandra-native-protocol@v0.0.0-20220706104457-5e8aad05cf90/client/client_local_test.go (about) 1 // Copyright 2020 DataStax 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package client_test 16 17 import ( 18 "context" 19 "fmt" 20 "github.com/datastax/go-cassandra-native-protocol/client" 21 "github.com/datastax/go-cassandra-native-protocol/frame" 22 "github.com/datastax/go-cassandra-native-protocol/message" 23 "github.com/datastax/go-cassandra-native-protocol/primitive" 24 "github.com/stretchr/testify/assert" 25 "github.com/stretchr/testify/require" 26 "sync" 27 "testing" 28 "time" 29 ) 30 31 func TestLocalServer(t *testing.T) { 32 33 for _, version := range primitive.SupportedProtocolVersions() { 34 t.Run(version.String(), func(t *testing.T) { 35 36 for genName, generator := range streamIdGenerators { 37 t.Run(fmt.Sprintf("generator %v", genName), func(t *testing.T) { 38 39 for _, compression := range compressions { 40 41 if version.SupportsCompression(compression) { 42 t.Run(fmt.Sprintf("%v", compression), func(t *testing.T) { 43 44 server := client.NewCqlServer( 45 "127.0.0.1:9043", 46 &client.AuthCredentials{ 47 Username: "cassandra", 48 Password: "cassandra", 49 }, 50 ) 51 52 clt := client.NewCqlClient( 53 "127.0.0.1:9043", 54 &client.AuthCredentials{ 55 Username: "cassandra", 56 Password: "cassandra", 57 }, 58 ) 59 clt.Compression = compression 60 61 ctx, cancelFn := context.WithCancel(context.Background()) 62 defer cancelFn() 63 64 err := server.Start(ctx) 65 require.NoError(t, err) 66 67 clientConn, serverConn, err := server.BindAndInit(clt, ctx, version, client.ManagedStreamId) 68 require.NoError(t, err) 69 70 playServer(serverConn, version, compression, ctx) 71 playClient(t, clientConn, version, compression, generator) 72 73 cancelFn() 74 75 assert.Eventually(t, clientConn.IsClosed, time.Second*10, time.Millisecond*10) 76 assert.Eventually(t, serverConn.IsClosed, time.Second*10, time.Millisecond*10) 77 assert.Eventually(t, server.IsClosed, time.Second*10, time.Millisecond*10) 78 79 }) 80 } 81 } 82 }) 83 } 84 }) 85 } 86 } 87 88 func playServer( 89 serverConn *client.CqlServerConnection, 90 version primitive.ProtocolVersion, 91 compression primitive.Compression, 92 ctx context.Context, 93 ) { 94 go func() { 95 for { 96 select { 97 case <-ctx.Done(): 98 return 99 default: 100 incoming, err := serverConn.Receive() 101 if err != nil { 102 return 103 } 104 outgoing := frame.NewFrame( 105 version, 106 incoming.Header.StreamId, 107 &message.RowsResult{ 108 Metadata: &message.RowsMetadata{ColumnCount: 1}, 109 Data: message.RowSet{ 110 message.Row{ 111 message.Column{0, 0, 0, 4, 1, 2, 3, 4}, 112 }, 113 message.Row{ 114 message.Column{0, 0, 0, 4, 5, 6, 7, 8}, 115 }, 116 }, 117 }, 118 ) 119 outgoing.SetCompress(compression != primitive.CompressionNone) 120 err = serverConn.Send(outgoing) 121 if err != nil { 122 return 123 } 124 } 125 } 126 }() 127 } 128 129 func playClient( 130 t *testing.T, 131 clientConn *client.CqlClientConnection, 132 version primitive.ProtocolVersion, 133 compression primitive.Compression, 134 generateStreamId func(int, primitive.ProtocolVersion) int16, 135 ) { 136 wg := &sync.WaitGroup{} 137 for i := 1; i <= 10; i++ { 138 wg.Add(1) 139 go func(i int) { 140 defer wg.Done() 141 for j := 1; j <= 10; j++ { 142 outgoing := frame.NewFrame( 143 version, 144 generateStreamId(i, version), 145 &message.Query{ 146 Query: "SELECT * FROM system.local", 147 Options: &message.QueryOptions{}, 148 }, 149 ) 150 outgoing.SetCompress(compression != primitive.CompressionNone) 151 incoming, err := clientConn.SendAndReceive(outgoing) 152 require.NoError(t, err) 153 require.NotNil(t, incoming) 154 } 155 156 }(i) 157 } 158 wg.Wait() 159 }