github.com/ldc1995/fabric-ca@v2.0.0-alpha.0.20200422214819-8d49c278c386+incompatible/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  }