github.com/hyperledger/fabric-ca@v2.0.0-alpha.0.20201120210307-7b4f34729db1+incompatible/test/fabric-ca-load-tester/testClient.go (about) 1 /* 2 Copyright IBM Corp. 2017 All Rights Reserved. 3 4 Licensed under the Apache License, Version 2.0 (the "License"); 5 you may not use this file except in compliance with the License. 6 You may obtain a copy of the License at 7 8 http://www.apache.org/licenses/LICENSE-2.0 9 10 Unless required by applicable law or agreed to in writing, software 11 distributed under the License is distributed on an "AS IS" BASIS, 12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 See the License for the specific language governing permissions and 14 limitations under the License. 15 */ 16 package main 17 18 import ( 19 "bytes" 20 "fmt" 21 "log" 22 23 "github.com/hyperledger/fabric-ca/internal/pkg/api" 24 "github.com/hyperledger/fabric-ca/lib" 25 ) 26 27 // testClient represents an application using the fabric-ca client 28 type testClient struct { 29 id int 30 FabClient *lib.Client 31 Identity *lib.Identity 32 numTests int 33 res testClientRes 34 } 35 36 // testClientRes represents a response returned by the TestClient 37 // after it completes running all the tests 38 type testClientRes struct { 39 clientID int 40 numTests int 41 numErrors int 42 errs []string 43 } 44 45 func (c *testClient) runTests(fin chan testClientRes) { 46 c.res = testClientRes{ 47 clientID: c.id, 48 numErrors: 0, 49 errs: make([]string, 0, 1), 50 } 51 iter := 0 52 for { 53 it := getIdentityType(iter) 54 iter++ 55 eid, err := genEnrollmentID(it) 56 if err != nil { 57 log.Printf("Failed to get enrollment ID: %v", err) 58 continue 59 } 60 c.runTestSuite(eid) 61 if c.numTests >= testCfg.NumReqsPerUser { 62 c.res.numTests = c.numTests 63 fin <- c.res 64 break 65 } 66 } 67 } 68 69 // Stringify TestClientRes 70 func (cr testClientRes) String() string { 71 var buffer bytes.Buffer 72 buffer.WriteString(fmt.Sprintf("Client %d finished with %d errors, after running %d tests", 73 cr.clientID, cr.numErrors, cr.numTests)) 74 if cr.errs != nil && len(cr.errs) > 0 { 75 buffer.WriteString("\n errors:\n") 76 for _, errStr := range cr.errs { 77 buffer.WriteString(" " + errStr + "\n") 78 } 79 } 80 return buffer.String() 81 } 82 83 func (c *testClient) runTestSuite(eid *enrollmentID) { 84 var enrRes lib.EnrollmentResponse 85 suite: 86 for _, test := range testCfg.TestSeq { 87 i := 0 88 for { 89 err := c.runTest(test, eid, &enrRes) 90 if err != nil { 91 c.res.numErrors++ 92 c.res.errs = append(c.res.errs, err.Error()) 93 break suite 94 } 95 c.numTests++ 96 if test.Repeat <= 0 || i == test.Repeat { 97 break 98 } 99 i++ 100 } 101 } 102 } 103 104 func (c *testClient) runTest(test Test, eid *enrollmentID, enrRes *lib.EnrollmentResponse) (err error) { 105 switch test.Name { 106 case "enroll": 107 _, err = c.enrollOnly(test.Req) 108 if err != nil { 109 log.Printf("Failed to enroll identity %s: %v", *eid.ID, err) 110 } 111 case "register": 112 _, err = c.register(eid, getAffiliation()) 113 if err != nil { 114 log.Printf("Failed to register identity %s: %v", *eid.ID, err) 115 } 116 case "re-enroll": 117 err = c.reenroll(enrRes.Identity) 118 if err != nil { 119 log.Printf("Failed to reenroll identity %s: %v", *eid.ID, err) 120 } 121 case "revoke": 122 err = c.revoke(test.Req, enrRes.Identity, "") 123 if err != nil { 124 log.Printf("Failed to revoke identity %s: %v", *eid.ID, err) 125 } 126 case "get-cacert": 127 err = c.getCACert() 128 if err != nil { 129 log.Printf("Failed to get CA certificate: %v", err) 130 } 131 default: 132 var r *lib.EnrollmentResponse 133 r, err = c.registerAndEnroll(eid, getAffiliation()) 134 if err != nil { 135 log.Printf("Failed to enroll identity %s: %v", *eid.ID, err) 136 } else { 137 *enrRes = *r 138 } 139 } 140 return 141 } 142 143 // Registers the specified identity 144 func (c *testClient) register(eid *enrollmentID, afl string) (resp *api.RegistrationResponse, err error) { 145 regReq := api.RegistrationRequest{ 146 Name: *eid.ID, 147 Type: string(*eid.it), 148 Affiliation: afl, 149 MaxEnrollments: 2, 150 } 151 resp, err = c.Identity.Register(®Req) 152 if err != nil { 153 return 154 } 155 log.Printf("Successfully registered identity %s: %+v", *eid.ID, resp) 156 return 157 } 158 159 // Enrolls the specified identity 160 func (c *testClient) enrollOnly(req TestRequest) (enrRes *lib.EnrollmentResponse, err error) { 161 csr := c.FabClient.Config.CSR 162 enrollReq := req.getEnrollmentReq() 163 if enrollReq.CSR == nil { 164 csr.CN = enrollReq.Name 165 enrollReq.CSR = &csr 166 } 167 enrRes, err = c.FabClient.Enroll(enrollReq) 168 if enrRes != nil { 169 log.Printf("Successfully enrolled identity: %s", enrollReq.Name) 170 } 171 return 172 } 173 174 // Enrolls the specified identity 175 func (c *testClient) enroll(eid *enrollmentID, pass string) (enrRes *lib.EnrollmentResponse, err error) { 176 csr := c.FabClient.Config.CSR 177 csr.CN = *eid.ID 178 enrollReq := api.EnrollmentRequest{ 179 Name: *eid.ID, 180 Secret: pass, 181 CSR: &csr, 182 } 183 enrRes, err = c.FabClient.Enroll(&enrollReq) 184 if enrRes != nil { 185 log.Printf("Successfully enrolled identity: %s", *eid.ID) 186 } 187 return 188 } 189 190 func (c *testClient) registerAndEnroll(eid *enrollmentID, afl string) (enrRes *lib.EnrollmentResponse, err error) { 191 var regRes *api.RegistrationResponse 192 regRes, err = c.register(eid, afl) 193 if regRes != nil { 194 enrRes, err = c.enroll(eid, regRes.Secret) 195 if err == nil { 196 log.Printf("Successfully registered and enrolled identity: %s", *eid.ID) 197 } 198 } 199 return 200 } 201 202 // Re-enrolls the specified identity 203 func (c *testClient) reenroll(id *lib.Identity) error { 204 csr := c.FabClient.Config.CSR 205 enrRes, err := id.Reenroll(&api.ReenrollmentRequest{ 206 CSR: &csr, 207 }) 208 if enrRes != nil { 209 log.Printf("Successfully re-enrolled identity: %s", id.GetName()) 210 } 211 return err 212 } 213 214 // Revokes the specified identity 215 func (c *testClient) revoke(req TestRequest, id *lib.Identity, reason string) (err error) { 216 if c.Identity == nil { 217 c.Identity, err = c.FabClient.LoadMyIdentity() 218 if err != nil { 219 return 220 } 221 } 222 223 revokeReq := &api.RevocationRequest{} 224 if reason != "" { 225 revokeReq.Reason = reason 226 } 227 var serial, aki, msg string 228 serial, aki, err = lib.GetCertID(id.GetECert().Cert()) 229 if req["Name"] != "" { 230 revokeReq.Name = id.GetName() 231 msg = fmt.Sprintf("Successfully revoked Identity: %s", id.GetName()) 232 } else { 233 if err != nil { 234 return 235 } 236 msg = fmt.Sprintf("Successfully revoked ECert %s of Identity: %s", aki, id.GetName()) 237 revokeReq.AKI = aki 238 revokeReq.Serial = serial 239 } 240 result, err := c.Identity.Revoke(revokeReq) 241 log.Printf("Sucessfully revoked certificates: %+v", result.RevokedCerts) 242 if err == nil { 243 log.Printf(msg) 244 } 245 return 246 } 247 248 // Gets CA root of the fabric-ca-server 249 func (c *testClient) getCACert() error { 250 req := api.GetCAInfoRequest{ 251 CAName: "", 252 } 253 _, err := c.FabClient.GetCAInfo(&req) 254 if err != nil { 255 return err 256 } 257 log.Println("Successfully retrieved CA certificate") 258 return err 259 } 260 261 func getTestClient(id int, configHome *string, cfg *lib.ClientConfig, i *lib.Identity) *testClient { 262 return &testClient{ 263 id: id, 264 FabClient: &lib.Client{ 265 HomeDir: *configHome, 266 Config: cfg, 267 }, 268 Identity: i, 269 } 270 }