github.com/silveraid/fabric-ca@v1.1.0-preview.0.20180127000700-71974f53ab08/lib/server_benchmarks_test.go (about) 1 /* 2 Copyright IBM Corp. 2016 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 lib 17 18 import ( 19 "io/ioutil" 20 "net/http" 21 "net/http/httptest" 22 "os" 23 "strconv" 24 "testing" 25 26 "github.com/hyperledger/fabric-ca/api" 27 "github.com/hyperledger/fabric-ca/util" 28 ) 29 30 const ( 31 serverbPort = 7061 32 revokeUserCertEnv = "REVOKE_USER_CERT" 33 clientMspDir = testdataDir + "/msp" 34 ) 35 36 func BenchmarkServerStart(b *testing.B) { 37 b.StopTimer() 38 for i := 0; i < b.N; i++ { 39 srv := getServerForBenchmark(serverbPort, rootDir, "", -1, b) 40 b.StartTimer() 41 err := srv.Start() 42 b.StopTimer() 43 if err != nil { 44 b.Fatalf("Server failed to start: %v", err) 45 } 46 srv.Stop() 47 os.RemoveAll(rootDir) 48 } 49 } 50 51 func BenchmarkGetCACert(b *testing.B) { 52 // Stop the timer and perform all the initialization 53 b.StopTimer() 54 srv := getServerForBenchmark(serverbPort, rootDir, "", -1, b) 55 err := srv.Start() 56 if err != nil { 57 b.Fatalf("Server failed to start: %v", err) 58 } 59 defer cleanup(srv) 60 61 client := getTestClient(serverbPort) 62 infoSE := newCAInfoEndpoint(srv) 63 for i := 0; i < b.N; i++ { 64 req, err := createGetCACertRequest(client) 65 if err != nil { 66 b.Fatalf("Failed to create getCACert request: %s", err) 67 } 68 rw := httptest.NewRecorder() 69 // Start the timer now to measure getCACert handler 70 b.StartTimer() 71 infoSE.ServeHTTP(rw, req) 72 // Stop the timer 73 b.StopTimer() 74 resp := rw.Result() 75 if resp.StatusCode != http.StatusOK { 76 body, _ := ioutil.ReadAll(resp.Body) 77 b.Fatalf("GetCACert request handler returned an error: %s", body) 78 } 79 } 80 } 81 82 func BenchmarkRegister(b *testing.B) { 83 b.StopTimer() 84 srv := getServerForBenchmark(serverbPort, rootDir, "", -1, b) 85 err := srv.Start() 86 if err != nil { 87 b.Fatalf("Server failed to start: %v", err) 88 } 89 defer cleanup(srv) 90 91 client := getTestClient(serverbPort) 92 eresp, err := client.Enroll(&api.EnrollmentRequest{ 93 Name: "admin", 94 Secret: "adminpw", 95 }) 96 if err != nil { 97 b.Fatalf("Failed to enroll admin/adminpw: %s", err) 98 } 99 100 admin := eresp.Identity 101 registerSE := newRegisterEndpoint(srv) 102 for i := 0; i < b.N; i++ { 103 req, err := createRegisterRequest(admin, "registeruser"+strconv.Itoa(i)) 104 if err != nil { 105 b.Fatalf("Failed to create registration request: %s", err) 106 } 107 rw := httptest.NewRecorder() 108 b.StartTimer() 109 registerSE.ServeHTTP(rw, req) 110 b.StopTimer() 111 resp := rw.Result() 112 if resp.StatusCode != http.StatusOK { 113 body, _ := ioutil.ReadAll(resp.Body) 114 b.Fatalf("Register request handler returned an error: %s", body) 115 } 116 } 117 } 118 119 func BenchmarkEnroll(b *testing.B) { 120 b.StopTimer() 121 srv := getServerForBenchmark(serverbPort, rootDir, "", -1, b) 122 err := srv.Start() 123 if err != nil { 124 b.Fatalf("Server failed to start: %v", err) 125 } 126 defer cleanup(srv) 127 128 client := getTestClient(serverbPort) 129 eresp, err := client.Enroll(&api.EnrollmentRequest{ 130 Name: "admin", 131 Secret: "adminpw", 132 }) 133 if err != nil { 134 b.Fatalf("Failed to enroll admin/adminpw: %s", err) 135 } 136 admin := eresp.Identity 137 enrollSE := newEnrollEndpoint(srv) 138 for i := 0; i < b.N; i++ { 139 userName := "enrolluser" + strconv.Itoa(i) 140 regReq := &api.RegistrationRequest{ 141 Name: userName, 142 Type: "user", 143 Affiliation: "hyperledger.fabric.security", 144 } 145 regRes, err := admin.Register(regReq) 146 if err != nil { 147 b.Fatalf("Failed to register user %s: %s", userName, err) 148 } 149 req, err := createEnrollRequest(admin, userName, regRes) 150 if err != nil { 151 b.Fatalf("Failed to create enrollment request: %s", err) 152 } 153 rw := httptest.NewRecorder() 154 b.StartTimer() 155 enrollSE.ServeHTTP(rw, req) 156 b.StopTimer() 157 resp := rw.Result() 158 if resp.StatusCode != http.StatusOK { 159 body, _ := ioutil.ReadAll(resp.Body) 160 b.Fatalf("Enroll request handler returned an error: %s", body) 161 } 162 } 163 } 164 165 func BenchmarkReenrollOneUser(b *testing.B) { 166 b.StopTimer() 167 srv := getServerForBenchmark(serverbPort, rootDir, "", -1, b) 168 err := srv.Start() 169 if err != nil { 170 b.Fatalf("Server failed to start: %v", err) 171 } 172 defer cleanup(srv) 173 174 client := getTestClient(serverbPort) 175 eresp, err := client.Enroll(&api.EnrollmentRequest{ 176 Name: "admin", 177 Secret: "adminpw", 178 }) 179 if err != nil { 180 b.Fatalf("Failed to enroll admin/adminpw: %s", err) 181 } 182 admin := eresp.Identity 183 userName := "reenrolluser0" 184 regReq := &api.RegistrationRequest{ 185 Name: userName, 186 Type: "user", 187 Affiliation: "hyperledger.fabric.security", 188 } 189 user, err := admin.RegisterAndEnroll(regReq) 190 if err != nil { 191 b.Fatalf("Failed to register and enroll the user %s: %s", userName, err) 192 } 193 reenrollSE := newReenrollEndpoint(srv) 194 for i := 0; i < b.N; i++ { 195 req, err := createReenrollRequest(user) 196 if err != nil { 197 b.Fatalf("Failed to create reenroll request: %s", err) 198 } 199 rw := httptest.NewRecorder() 200 b.StartTimer() 201 reenrollSE.ServeHTTP(rw, req) 202 b.StopTimer() 203 resp := rw.Result() 204 if resp.StatusCode != http.StatusOK { 205 body, _ := ioutil.ReadAll(resp.Body) 206 b.Fatalf("Reenroll request handler returned an error: %s", body) 207 } 208 } 209 } 210 211 func BenchmarkReenroll(b *testing.B) { 212 b.StopTimer() 213 srv := getServerForBenchmark(serverbPort, rootDir, "", -1, b) 214 err := srv.Start() 215 if err != nil { 216 b.Fatalf("Server failed to start: %v", err) 217 } 218 defer cleanup(srv) 219 220 client := getTestClient(serverbPort) 221 eresp, err := client.Enroll(&api.EnrollmentRequest{ 222 Name: "admin", 223 Secret: "adminpw", 224 }) 225 if err != nil { 226 b.Fatalf("Failed to enroll admin/adminpw: %s", err) 227 } 228 admin := eresp.Identity 229 reenrollSE := newReenrollEndpoint(srv) 230 for i := 0; i < b.N; i++ { 231 userName := "reenrollusers" + strconv.Itoa(i) 232 regReq := &api.RegistrationRequest{ 233 Name: userName, 234 Type: "user", 235 Affiliation: "hyperledger.fabric.security", 236 } 237 user, err := admin.RegisterAndEnroll(regReq) 238 if err != nil { 239 b.Fatalf("Failed to register and enroll the user %s: %s", userName, err) 240 } 241 req, err := createReenrollRequest(user) 242 if err != nil { 243 b.Fatalf("Failed to create reenroll request: %s", err) 244 } 245 rw := httptest.NewRecorder() 246 b.StartTimer() 247 reenrollSE.ServeHTTP(rw, req) 248 b.StopTimer() 249 resp := rw.Result() 250 if resp.StatusCode != http.StatusOK { 251 body, _ := ioutil.ReadAll(resp.Body) 252 b.Fatalf("Reenroll request handler returned an error: %s", body) 253 } 254 } 255 } 256 257 func BenchmarkRevokeUserCert(b *testing.B) { 258 b.StopTimer() 259 revokeUserCertOrig := os.Getenv(revokeUserCertEnv) 260 os.Setenv(revokeUserCertEnv, "true") 261 defer os.Setenv(revokeUserCertEnv, revokeUserCertOrig) 262 invokeRevokeBenchmark(b) 263 } 264 265 func BenchmarkRevokeIdentity(b *testing.B) { 266 b.StopTimer() 267 revokeUserCertOrig := os.Getenv(revokeUserCertEnv) 268 os.Setenv(revokeUserCertEnv, "") 269 defer os.Setenv(revokeUserCertEnv, revokeUserCertOrig) 270 invokeRevokeBenchmark(b) 271 } 272 273 func BenchmarkGenCRL(b *testing.B) { 274 b.StopTimer() 275 srv := getServerForBenchmark(serverbPort, rootDir, "", -1, b) 276 err := srv.Start() 277 if err != nil { 278 b.Fatalf("Server failed to start: %v", err) 279 } 280 defer cleanup(srv) 281 282 client := getTestClient(serverbPort) 283 eresp, err := client.Enroll(&api.EnrollmentRequest{ 284 Name: "admin", 285 Secret: "adminpw", 286 }) 287 if err != nil { 288 b.Fatalf("Failed to enroll admin/adminpw: %s", err) 289 } 290 admin := eresp.Identity 291 292 for j := 0; j < 50; j++ { 293 userName := "gencrluser" + strconv.Itoa(j) 294 regReq := &api.RegistrationRequest{ 295 Name: userName, 296 Type: "user", 297 Affiliation: "hyperledger.fabric.security", 298 } 299 _, err = admin.RegisterAndEnroll(regReq) 300 if err != nil { 301 b.Fatalf("Failed to register and enroll the user %s: %s", userName, err) 302 } 303 _, err = admin.Revoke(&api.RevocationRequest{ 304 Name: userName, 305 }) 306 if err != nil { 307 b.Fatalf("Failed to revoke the user %s: %s", userName, err) 308 } 309 } 310 311 genCRLSE := newGenCRLEndpoint(srv) 312 313 for i := 0; i < b.N; i++ { 314 req, err := createGenCRLRequest(admin) 315 if err != nil { 316 b.Fatalf("Failed to create the genCRL request %s", err) 317 } 318 rw := httptest.NewRecorder() 319 b.StartTimer() 320 genCRLSE.ServeHTTP(rw, req) 321 b.StopTimer() 322 resp := rw.Result() 323 if resp.StatusCode != http.StatusOK { 324 body, _ := ioutil.ReadAll(resp.Body) 325 b.Fatalf("GenCRL request handler returned an error: %s", body) 326 } 327 } 328 } 329 330 func invokeRevokeBenchmark(b *testing.B) { 331 srv := getServerForBenchmark(serverbPort, rootDir, "", -1, b) 332 err := srv.Start() 333 if err != nil { 334 b.Fatalf("Server failed to start: %v", err) 335 } 336 defer cleanup(srv) 337 338 client := getTestClient(serverbPort) 339 eresp, err := client.Enroll(&api.EnrollmentRequest{ 340 Name: "admin", 341 Secret: "adminpw", 342 }) 343 if err != nil { 344 b.Fatalf("Failed to enroll admin/adminpw: %s", err) 345 } 346 admin := eresp.Identity 347 revokeSE := newRevokeEndpoint(srv) 348 for i := 0; i < b.N; i++ { 349 userName := "revokeuser" + strconv.Itoa(i) 350 regReq := &api.RegistrationRequest{ 351 Name: userName, 352 Type: "user", 353 Affiliation: "hyperledger.fabric.security", 354 } 355 user, err := admin.RegisterAndEnroll(regReq) 356 if err != nil { 357 b.Fatalf("Failed to register and enroll user %s: %s", userName, err) 358 } 359 req, err := createRevokeRequest(admin, user) 360 if err != nil { 361 b.Fatalf("Failed to create revoke request %s", err) 362 } 363 rw := httptest.NewRecorder() 364 b.StartTimer() 365 revokeSE.ServeHTTP(rw, req) 366 b.StopTimer() 367 resp := rw.Result() 368 if resp.StatusCode != http.StatusOK { 369 body, _ := ioutil.ReadAll(resp.Body) 370 b.Fatalf("Revoke request handler returned an error: %s", body) 371 } 372 } 373 } 374 375 func cleanup(srv *Server) { 376 srv.Stop() 377 os.RemoveAll(rootDir) 378 os.RemoveAll(clientMspDir) 379 } 380 381 func createRevokeRequest(admin *Identity, user *Identity) (*http.Request, error) { 382 revokeReq := &api.RevocationRequest{} 383 serial, aki, err := GetCertID(user.GetECert().Cert()) 384 if err != nil { 385 return nil, err 386 } 387 revokeUserCert := os.Getenv(revokeUserCertEnv) 388 if revokeUserCert == "" { 389 revokeReq.Name = user.GetName() 390 } else { 391 revokeReq.AKI = aki 392 revokeReq.Serial = serial 393 } 394 body, err := util.Marshal(revokeReq, "RevocationRequest") 395 if err != nil { 396 return nil, err 397 } 398 req, err := admin.client.newPost("revoke", body) 399 if err != nil { 400 return nil, err 401 } 402 err = admin.addTokenAuthHdr(req, body) 403 if err != nil { 404 return nil, err 405 } 406 return req, nil 407 } 408 409 func createReenrollRequest(user *Identity) (*http.Request, error) { 410 csr := &user.client.Config.CSR 411 csrPEM, _, err := user.client.GenCSR(csr, user.GetName()) 412 if err != nil { 413 return nil, err 414 } 415 reqNet := &api.ReenrollmentRequestNet{ 416 CAName: user.client.Config.CAName, 417 } 418 419 // Get the body of the request 420 if csr != nil { 421 reqNet.SignRequest.Hosts = csr.Hosts 422 } 423 reqNet.SignRequest.Request = string(csrPEM) 424 reqNet.SignRequest.Profile = user.client.Config.Enrollment.Profile 425 reqNet.SignRequest.Label = user.client.Config.Enrollment.Label 426 427 body, err := util.Marshal(reqNet, "SignRequest") 428 if err != nil { 429 return nil, err 430 } 431 req, err := user.client.newPost("reenroll", body) 432 if err != nil { 433 return nil, err 434 } 435 err = user.addTokenAuthHdr(req, body) 436 if err != nil { 437 return nil, err 438 } 439 return req, nil 440 } 441 442 func createEnrollRequest(admin *Identity, userName string, regRes *api.RegistrationResponse) (*http.Request, error) { 443 // Generate the CSR 444 csr := &admin.client.Config.CSR 445 csr.CN = userName 446 csrPEM, _, err := admin.client.GenCSR(csr, userName) 447 if err != nil { 448 return nil, err 449 } 450 451 reqNet := &api.EnrollmentRequestNet{ 452 CAName: "", 453 } 454 455 if csr != nil { 456 reqNet.SignRequest.Hosts = csr.Hosts 457 } 458 reqNet.SignRequest.Request = string(csrPEM) 459 reqNet.SignRequest.Profile = admin.client.Config.Enrollment.Profile 460 reqNet.SignRequest.Label = admin.client.Config.Enrollment.Label 461 462 body, err := util.Marshal(reqNet, "SignRequest") 463 if err != nil { 464 return nil, err 465 } 466 467 // Send the CSR to the fabric-ca server with basic auth header 468 req, err := admin.client.newPost("enroll", body) 469 if err != nil { 470 return nil, err 471 } 472 req.SetBasicAuth(userName, regRes.Secret) 473 return req, nil 474 } 475 476 func createRegisterRequest(admin *Identity, userName string) (*http.Request, error) { 477 regReq := &api.RegistrationRequest{ 478 Name: userName, 479 Type: "user", 480 Affiliation: "hyperledger.fabric.security", 481 } 482 reqBody, err := util.Marshal(regReq, "RegistrationRequest") 483 if err != nil { 484 return nil, err 485 } 486 req, err := admin.client.newPost("register", reqBody) 487 if err != nil { 488 return nil, err 489 } 490 err = admin.addTokenAuthHdr(req, reqBody) 491 if err != nil { 492 return nil, err 493 } 494 return req, nil 495 } 496 497 func createGetCACertRequest(client *Client) (*http.Request, error) { 498 body, err := util.Marshal(&api.GetCAInfoRequest{}, "GetCAInfo") 499 if err != nil { 500 return nil, err 501 } 502 cainforeq, err := client.newPost("cainfo", body) 503 if err != nil { 504 return nil, err 505 } 506 return cainforeq, nil 507 } 508 509 func createGenCRLRequest(user *Identity) (*http.Request, error) { 510 body, err := util.Marshal(&api.GenCRLRequest{CAName: ""}, "GenCRL") 511 if err != nil { 512 return nil, err 513 } 514 req, err := user.client.newPost("gencrl", body) 515 if err != nil { 516 return nil, err 517 } 518 err = user.addTokenAuthHdr(req, body) 519 if err != nil { 520 return nil, err 521 } 522 return req, nil 523 }