github.com/canhui/fabric_ca2_2@v2.0.0-alpha+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/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 "get-tcerts":
   122  		err = c.getTCerts(test.Req, enrRes.Identity)
   123  		if err != nil {
   124  			log.Printf("Failed to get TCert batch for identity %s: %v", *eid.ID, err)
   125  		}
   126  	case "revoke":
   127  		err = c.revoke(test.Req, enrRes.Identity, "")
   128  		if err != nil {
   129  			log.Printf("Failed to revoke identity %s: %v", *eid.ID, err)
   130  		}
   131  	case "get-cacert":
   132  		err = c.getCACert()
   133  		if err != nil {
   134  			log.Printf("Failed to get CA certificate: %v", err)
   135  		}
   136  	default:
   137  		var r *lib.EnrollmentResponse
   138  		r, err = c.registerAndEnroll(eid, getAffiliation())
   139  		if err != nil {
   140  			log.Printf("Failed to enroll identity %s: %v", *eid.ID, err)
   141  		} else {
   142  			*enrRes = *r
   143  		}
   144  	}
   145  	return
   146  }
   147  
   148  // Registers the specified identity
   149  func (c *testClient) register(eid *enrollmentID, afl string) (resp *api.RegistrationResponse, err error) {
   150  	regReq := api.RegistrationRequest{
   151  		Name:           *eid.ID,
   152  		Type:           string(*eid.it),
   153  		Affiliation:    afl,
   154  		MaxEnrollments: 2,
   155  	}
   156  	resp, err = c.Identity.Register(&regReq)
   157  	if err != nil {
   158  		return
   159  	}
   160  	log.Printf("Successfully registered identity %s: %+v", *eid.ID, resp)
   161  	return
   162  }
   163  
   164  // Enrolls the specified identity
   165  func (c *testClient) enrollOnly(req TestRequest) (enrRes *lib.EnrollmentResponse, err error) {
   166  	csr := c.FabClient.Config.CSR
   167  	enrollReq := req.getEnrollmentReq()
   168  	if enrollReq.CSR == nil {
   169  		csr.CN = enrollReq.Name
   170  		enrollReq.CSR = &csr
   171  	}
   172  	enrRes, err = c.FabClient.Enroll(enrollReq)
   173  	if enrRes != nil {
   174  		log.Printf("Successfully enrolled identity: %s", enrollReq.Name)
   175  	}
   176  	return
   177  }
   178  
   179  // Enrolls the specified identity
   180  func (c *testClient) enroll(eid *enrollmentID, pass string) (enrRes *lib.EnrollmentResponse, err error) {
   181  	csr := c.FabClient.Config.CSR
   182  	csr.CN = *eid.ID
   183  	enrollReq := api.EnrollmentRequest{
   184  		Name:   *eid.ID,
   185  		Secret: pass,
   186  		CSR:    &csr,
   187  	}
   188  	enrRes, err = c.FabClient.Enroll(&enrollReq)
   189  	if enrRes != nil {
   190  		log.Printf("Successfully enrolled identity: %s", *eid.ID)
   191  	}
   192  	return
   193  }
   194  
   195  func (c *testClient) registerAndEnroll(eid *enrollmentID, afl string) (enrRes *lib.EnrollmentResponse, err error) {
   196  	var regRes *api.RegistrationResponse
   197  	regRes, err = c.register(eid, afl)
   198  	if regRes != nil {
   199  		enrRes, err = c.enroll(eid, regRes.Secret)
   200  		if err == nil {
   201  			log.Printf("Successfully registered and enrolled identity: %s", *eid.ID)
   202  		}
   203  	}
   204  	return
   205  }
   206  
   207  // Returns TCert batch for the specified identity
   208  func (c *testClient) getTCerts(req TestRequest, id *lib.Identity) error {
   209  	var tcertReq *api.GetTCertBatchRequest
   210  	if req != nil {
   211  		tcertReq = req.getTCertsReq()
   212  	} else {
   213  		tcertReq = &api.GetTCertBatchRequest{
   214  			Count:                1,
   215  			DisableKeyDerivation: true,
   216  			EncryptAttrs:         true,
   217  		}
   218  	}
   219  	if tcertReq.PreKey == "" {
   220  		tcertReq.PreKey = id.GetName()
   221  	}
   222  	_, err := id.GetTCertBatch(tcertReq)
   223  	if err == nil {
   224  		log.Printf("Successfully retrieved TCert batch %d for the idenity: %s",
   225  			tcertReq.Count, id.GetName())
   226  	}
   227  	return err
   228  }
   229  
   230  // Re-enrolls the specified identity
   231  func (c *testClient) reenroll(id *lib.Identity) error {
   232  	csr := c.FabClient.Config.CSR
   233  	enrRes, err := id.Reenroll(&api.ReenrollmentRequest{
   234  		CSR: &csr,
   235  	})
   236  	if enrRes != nil {
   237  		log.Printf("Successfully re-enrolled identity: %s", id.GetName())
   238  	}
   239  	return err
   240  }
   241  
   242  // Revokes the specified identity
   243  func (c *testClient) revoke(req TestRequest, id *lib.Identity, reason string) (err error) {
   244  	if c.Identity == nil {
   245  		c.Identity, err = c.FabClient.LoadMyIdentity()
   246  		if err != nil {
   247  			return
   248  		}
   249  	}
   250  
   251  	revokeReq := &api.RevocationRequest{}
   252  	if reason != "" {
   253  		revokeReq.Reason = reason
   254  	}
   255  	var serial, aki, msg string
   256  	serial, aki, err = lib.GetCertID(id.GetECert().Cert())
   257  	if req["Name"] != "" {
   258  		revokeReq.Name = id.GetName()
   259  		msg = fmt.Sprintf("Successfully revoked Identity: %s", id.GetName())
   260  	} else {
   261  		if err != nil {
   262  			return
   263  		}
   264  		msg = fmt.Sprintf("Successfully revoked ECert %s of Identity: %s", aki, id.GetName())
   265  		revokeReq.AKI = aki
   266  		revokeReq.Serial = serial
   267  	}
   268  	result, err := c.Identity.Revoke(revokeReq)
   269  	log.Printf("Sucessfully revoked certificates: %+v", result.RevokedCerts)
   270  	if err == nil {
   271  		log.Printf(msg)
   272  	}
   273  	return
   274  }
   275  
   276  // Gets CA root of the fabric-ca-server
   277  func (c *testClient) getCACert() error {
   278  	req := api.GetCAInfoRequest{
   279  		CAName: "",
   280  	}
   281  	_, err := c.FabClient.GetCAInfo(&req)
   282  	if err != nil {
   283  		return err
   284  	}
   285  	log.Println("Successfully retrieved CA certificate")
   286  	return err
   287  }
   288  
   289  func getTestClient(id int, configHome *string, cfg *lib.ClientConfig, i *lib.Identity) *testClient {
   290  	return &testClient{
   291  		id: id,
   292  		FabClient: &lib.Client{
   293  			HomeDir: *configHome,
   294  			Config:  cfg,
   295  		},
   296  		Identity: i,
   297  	}
   298  }