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(&regReq)
   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  }