github.com/google/fleetspeak@v0.1.15-0.20240426164851-4f31f62c1aea/fleetspeak/src/server/grpcservice/client/testing/tester.go (about) 1 // Copyright 2017 Google Inc. 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 // https://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 main tests a fleetspeak server talking through a grpcserver to a python loopback process. 16 package main 17 18 import ( 19 "context" 20 "flag" 21 "net" 22 "path" 23 "time" 24 25 log "github.com/golang/glog" 26 anypb "google.golang.org/protobuf/types/known/anypb" 27 28 "google.golang.org/grpc" 29 30 "github.com/google/fleetspeak/fleetspeak/src/common" 31 "github.com/google/fleetspeak/fleetspeak/src/comtesting" 32 "github.com/google/fleetspeak/fleetspeak/src/server" 33 "github.com/google/fleetspeak/fleetspeak/src/server/admin" 34 "github.com/google/fleetspeak/fleetspeak/src/server/comms" 35 "github.com/google/fleetspeak/fleetspeak/src/server/db" 36 "github.com/google/fleetspeak/fleetspeak/src/server/grpcservice" 37 "github.com/google/fleetspeak/fleetspeak/src/server/sertesting" 38 "github.com/google/fleetspeak/fleetspeak/src/server/service" 39 "github.com/google/fleetspeak/fleetspeak/src/server/sqlite" 40 "github.com/google/fleetspeak/fleetspeak/src/server/testserver" 41 42 fspb "github.com/google/fleetspeak/fleetspeak/src/common/proto/fleetspeak" 43 gpb "github.com/google/fleetspeak/fleetspeak/src/server/grpcservice/proto/fleetspeak_grpcservice" 44 sgrpc "github.com/google/fleetspeak/fleetspeak/src/server/proto/fleetspeak_server" 45 spb "github.com/google/fleetspeak/fleetspeak/src/server/proto/fleetspeak_server" 46 ) 47 48 var ( 49 adminAddr = flag.String("admin_addr", "", "Bind address for the admin rpc server.") 50 messageAddr = flag.String("message_addr", "", "The address to send messages to over grpc.") 51 ) 52 53 func main() { 54 flag.Parse() 55 tempDir, tmpDirCleanup := comtesting.GetTempDir("grpcservice") 56 defer tmpDirCleanup() 57 p := path.Join(tempDir, "client_test.sqlite") 58 ds, err := sqlite.MakeDatastore(p) 59 60 sertesting.SetServerRetryTime(func(_ uint32) time.Time { 61 return db.Now().Add(time.Second) 62 }) 63 64 if err != nil { 65 log.Exitf("Unable to create datastore[%s]: %v", p, err) 66 } 67 ts := testserver.Server{ 68 DS: ds, 69 } 70 gc, err := anypb.New(&gpb.Config{ 71 Target: *messageAddr, 72 Insecure: true, 73 }) 74 if err != nil { 75 log.Exitf("Unable to marshal grpcservice config: %v", err) 76 } 77 s, err := server.MakeServer( 78 &spb.ServerConfig{ 79 Services: []*spb.ServiceConfig{{ 80 Name: "TestService", 81 Factory: "GRPC", 82 Config: gc, 83 }}, 84 }, 85 server.Components{ 86 Datastore: ds, 87 ServiceFactories: map[string]service.Factory{"GRPC": grpcservice.Factory}, 88 Communicators: []comms.Communicator{&testserver.FakeCommunicator{Dest: &ts}}, 89 }, 90 ) 91 ts.S = s 92 if err != nil { 93 log.Exitf("Unable to create server: %v", err) 94 } 95 serveAdminInterface(s, ds) 96 97 k, err := ts.AddClient() 98 if err != nil { 99 log.Exitf("Unable to add client: %v", err) 100 } 101 id, err := common.MakeClientID(k) 102 if err != nil { 103 log.Exitf("Unable to make ClientID: %v", err) 104 } 105 106 m := &fspb.Message{ 107 SourceMessageId: []byte("2"), 108 Source: &fspb.Address{ 109 ClientId: id.Bytes(), 110 ServiceName: "TestService", 111 }, 112 Destination: &fspb.Address{ 113 ServiceName: "TestService", 114 }, 115 MessageType: "TestMessage", 116 } 117 mid := common.MakeMessageID(m.Source, m.SourceMessageId) 118 m.MessageId = mid.Bytes() 119 ctx, fin := context.WithTimeout(context.Background(), 30*time.Second) 120 defer fin() 121 // Because of grpc retry logic and the possibility of getting an error when 122 // the message was successfully sent, the message might pass through the 123 // loopback during the first SimulateContact call. 124 msgs, err := ts.SimulateContactFromClient(ctx, k, []*fspb.Message{m}) 125 if err != nil { 126 log.Exitf("Error putting message into system: %v", err) 127 } 128 var resp *fspb.Message 129 for len(msgs) == 0 { 130 msgs, err = ts.SimulateContactFromClient(ctx, k, nil) 131 if err != nil { 132 log.Exitf("Error while waiting for loopback: %v", err) 133 } 134 if len(msgs) > 0 { 135 break 136 } 137 time.Sleep(100 * time.Millisecond) 138 } 139 if len(msgs) > 1 { 140 log.Exitf("Expected 1 message back, got %d", len(msgs)) 141 } 142 resp = msgs[0] 143 144 log.Infof("Received through loopback: %+v", resp) 145 if resp.MessageType != "TestMessage" { 146 log.Exitf("Looped message had unexpected MessageType, got [%v] want [%v]", resp.MessageType, "TestMessage") 147 } 148 } 149 150 func serveAdminInterface(fs *server.Server, ds db.Store) *grpc.Server { 151 gs := grpc.NewServer() 152 as := admin.NewServer(ds, nil) 153 sgrpc.RegisterAdminServer(gs, as) 154 addr, err := net.ResolveTCPAddr("tcp", *adminAddr) 155 if err != nil { 156 log.Exitf("Unable to resolve admin listener address [%v]: %v", *adminAddr, err) 157 } 158 l, err := net.ListenTCP("tcp", addr) 159 if err != nil { 160 log.Exitf("Unable to listen on [%v]: %v", addr, err) 161 } 162 go func() { 163 err := gs.Serve(l) 164 log.Errorf("Admin server finished with error: %v", err) 165 }() 166 log.Infof("Admin interface started, listening for clients on: %v", l.Addr()) 167 return gs 168 }