Remove most instances of blog.Get() (#1870)

In this PR, logger is passed to the following callers:
  NewWebFrontEndImpl
  NewCertificateAuthorityImpl
  NewValidationAuthorityImpl
  NewAmqpRPCServer
  newUpdater
  NewRegistrationAuthorityServer

This reduces the usage of a global singleton logger and allows tests to consistently use a mock logger.

Fixes #1642

* remove blog.Get() in wfe
* remove blog.Get() from va
* remove Blog.Get() from ca
* remove blog.Get() from oscp updater, ampq rpc server, registration authority server
* removed some pointless logging code
* remove one added newline
* fix format issue
* fix setup function to return *blog.Mock instead of being passed in
* remove useless blog.NewMock() call
This commit is contained in:
Ben Irving 2016-06-02 14:26:39 -07:00 committed by Roland Bracewell Shoemaker
parent b9f2fa6790
commit a713823cd5
17 changed files with 97 additions and 72 deletions

View File

@ -183,10 +183,10 @@ func NewCertificateAuthorityImpl(
stats statsd.Statter,
issuers []Issuer,
keyPolicy goodkey.KeyPolicy,
logger blog.Logger,
) (*CertificateAuthorityImpl, error) {
var ca *CertificateAuthorityImpl
var err error
logger := blog.Get()
if config.SerialPrefix <= 0 || config.SerialPrefix >= 256 {
err = errors.New("Must have a positive non-zero serial prefix less than 256 for CA.")

View File

@ -134,6 +134,7 @@ type testCtx struct {
keyPolicy goodkey.KeyPolicy
fc clock.FakeClock
stats *mocks.Statter
logger blog.Logger
}
type mockSA struct {
@ -245,6 +246,8 @@ func setup(t *testing.T) *testCtx {
AllowECDSANISTP384: true,
}
logger := blog.NewMock()
return &testCtx{
caConfig,
pa,
@ -252,6 +255,7 @@ func setup(t *testing.T) *testCtx {
keyPolicy,
fc,
stats,
logger,
}
}
@ -264,7 +268,8 @@ func TestFailNoSerial(t *testing.T) {
testCtx.fc,
testCtx.stats,
testCtx.issuers,
testCtx.keyPolicy)
testCtx.keyPolicy,
testCtx.logger)
test.AssertError(t, err, "CA should have failed with no SerialPrefix")
}
@ -275,7 +280,8 @@ func TestIssueCertificate(t *testing.T) {
testCtx.fc,
testCtx.stats,
testCtx.issuers,
testCtx.keyPolicy)
testCtx.keyPolicy,
testCtx.logger)
test.AssertNotError(t, err, "Failed to create CA")
ca.Publisher = &mocks.Publisher{}
ca.PA = testCtx.pa
@ -335,7 +341,8 @@ func TestIssueCertificateMultipleIssuers(t *testing.T) {
testCtx.fc,
testCtx.stats,
newIssuers,
testCtx.keyPolicy)
testCtx.keyPolicy,
testCtx.logger)
test.AssertNotError(t, err, "Failed to remake CA")
ca.Publisher = &mocks.Publisher{}
ca.PA = testCtx.pa
@ -359,7 +366,8 @@ func TestOCSP(t *testing.T) {
testCtx.fc,
testCtx.stats,
testCtx.issuers,
testCtx.keyPolicy)
testCtx.keyPolicy,
testCtx.logger)
test.AssertNotError(t, err, "Failed to create CA")
ca.Publisher = &mocks.Publisher{}
ca.PA = testCtx.pa
@ -407,7 +415,8 @@ func TestOCSP(t *testing.T) {
testCtx.fc,
testCtx.stats,
newIssuers,
testCtx.keyPolicy)
testCtx.keyPolicy,
testCtx.logger)
test.AssertNotError(t, err, "Failed to remake CA")
ca.Publisher = &mocks.Publisher{}
ca.PA = testCtx.pa
@ -453,7 +462,8 @@ func TestNoHostnames(t *testing.T) {
testCtx.fc,
testCtx.stats,
testCtx.issuers,
testCtx.keyPolicy)
testCtx.keyPolicy,
testCtx.logger)
test.AssertNotError(t, err, "Failed to create CA")
ca.Publisher = &mocks.Publisher{}
ca.PA = testCtx.pa
@ -473,7 +483,8 @@ func TestRejectTooManyNames(t *testing.T) {
testCtx.fc,
testCtx.stats,
testCtx.issuers,
testCtx.keyPolicy)
testCtx.keyPolicy,
testCtx.logger)
test.AssertNotError(t, err, "Failed to create CA")
ca.Publisher = &mocks.Publisher{}
ca.PA = testCtx.pa
@ -494,7 +505,8 @@ func TestRejectValidityTooLong(t *testing.T) {
testCtx.fc,
testCtx.stats,
testCtx.issuers,
testCtx.keyPolicy)
testCtx.keyPolicy,
testCtx.logger)
test.AssertNotError(t, err, "Failed to create CA")
ca.Publisher = &mocks.Publisher{}
ca.PA = testCtx.pa
@ -520,7 +532,8 @@ func TestShortKey(t *testing.T) {
testCtx.fc,
testCtx.stats,
testCtx.issuers,
testCtx.keyPolicy)
testCtx.keyPolicy,
testCtx.logger)
ca.Publisher = &mocks.Publisher{}
ca.PA = testCtx.pa
ca.SA = &mockSA{}
@ -540,7 +553,8 @@ func TestAllowNoCN(t *testing.T) {
testCtx.fc,
testCtx.stats,
testCtx.issuers,
testCtx.keyPolicy)
testCtx.keyPolicy,
testCtx.logger)
test.AssertNotError(t, err, "Couldn't create new CA")
ca.Publisher = &mocks.Publisher{}
ca.PA = testCtx.pa
@ -580,7 +594,8 @@ func TestLongCommonName(t *testing.T) {
testCtx.fc,
testCtx.stats,
testCtx.issuers,
testCtx.keyPolicy)
testCtx.keyPolicy,
testCtx.logger)
ca.Publisher = &mocks.Publisher{}
ca.PA = testCtx.pa
ca.SA = &mockSA{}
@ -600,7 +615,8 @@ func TestWrongSignature(t *testing.T) {
testCtx.fc,
testCtx.stats,
testCtx.issuers,
testCtx.keyPolicy)
testCtx.keyPolicy,
testCtx.logger)
ca.Publisher = &mocks.Publisher{}
ca.PA = testCtx.pa
ca.SA = &mockSA{}
@ -622,7 +638,8 @@ func TestProfileSelection(t *testing.T) {
testCtx.fc,
testCtx.stats,
testCtx.issuers,
testCtx.keyPolicy)
testCtx.keyPolicy,
testCtx.logger)
ca.Publisher = &mocks.Publisher{}
ca.PA = testCtx.pa
ca.SA = &mockSA{}
@ -671,7 +688,8 @@ func TestExtensions(t *testing.T) {
testCtx.fc,
testCtx.stats,
testCtx.issuers,
testCtx.keyPolicy)
testCtx.keyPolicy,
testCtx.logger)
ca.Publisher = &mocks.Publisher{}
ca.PA = testCtx.pa
ca.SA = &mockSA{}

View File

@ -126,7 +126,8 @@ func main() {
clock.Default(),
stats,
issuers,
c.KeyPolicy())
c.KeyPolicy(),
logger)
cmd.FailOnError(err, "Failed to create CA impl")
cai.PA = pa
@ -145,7 +146,7 @@ func main() {
cmd.FailOnError(err, "Failed to create Publisher client")
}
cas, err := rpc.NewAmqpRPCServer(amqpConf, c.CA.MaxConcurrentRPCServerRequests, stats)
cas, err := rpc.NewAmqpRPCServer(amqpConf, c.CA.MaxConcurrentRPCServerRequests, stats, logger)
cmd.FailOnError(err, "Unable to create CA RPC server")
err = rpc.NewCertificateAuthorityServer(cas, cai)
cmd.FailOnError(err, "Failed to create Certificate Authority RPC server")

View File

@ -58,7 +58,7 @@ func main() {
}()
}
pubs, err := rpc.NewAmqpRPCServer(amqpConf, c.Publisher.MaxConcurrentRPCServerRequests, stats)
pubs, err := rpc.NewAmqpRPCServer(amqpConf, c.Publisher.MaxConcurrentRPCServerRequests, stats, logger)
cmd.FailOnError(err, "Unable to create Publisher RPC server")
err = rpc.NewPublisherServer(pubs, pubi)
cmd.FailOnError(err, "Unable to setup Publisher RPC server")

View File

@ -80,9 +80,9 @@ func main() {
rai.CA = cac
rai.SA = sac
ras, err := rpc.NewAmqpRPCServer(amqpConf, c.RA.MaxConcurrentRPCServerRequests, stats)
ras, err := rpc.NewAmqpRPCServer(amqpConf, c.RA.MaxConcurrentRPCServerRequests, stats, logger)
cmd.FailOnError(err, "Unable to create RA RPC server")
err = rpc.NewRegistrationAuthorityServer(ras, rai)
err = rpc.NewRegistrationAuthorityServer(ras, rai, logger)
cmd.FailOnError(err, "Unable to setup RA RPC server")
err = ras.Start(amqpConf)

View File

@ -28,7 +28,7 @@ func main() {
go cmd.ProfileCmd("SA", stats)
amqpConf := saConf.AMQP
sas, err := rpc.NewAmqpRPCServer(amqpConf, c.SA.MaxConcurrentRPCServerRequests, stats)
sas, err := rpc.NewAmqpRPCServer(amqpConf, c.SA.MaxConcurrentRPCServerRequests, stats, logger)
cmd.FailOnError(err, "Unable to create SA RPC server")
err = rpc.NewStorageAuthorityServer(sas, sai)
cmd.FailOnError(err, "Unable to setup SA RPC server")

View File

@ -85,7 +85,8 @@ func main() {
c.VA.UserAgent,
c.VA.IssuerDomain,
stats,
clk)
clk,
logger)
amqpConf := c.VA.AMQP
@ -98,7 +99,7 @@ func main() {
cmd.FailOnError(err, "VA gRPC service failed")
}
vas, err := rpc.NewAmqpRPCServer(amqpConf, c.VA.MaxConcurrentRPCServerRequests, stats)
vas, err := rpc.NewAmqpRPCServer(amqpConf, c.VA.MaxConcurrentRPCServerRequests, stats, logger)
cmd.FailOnError(err, "Unable to create VA RPC server")
err = rpc.NewValidationAuthorityServer(vas, vai)
cmd.FailOnError(err, "Unable to setup VA RPC server")

View File

@ -47,7 +47,7 @@ func main() {
app.Action = func(c cmd.Config, stats metrics.Statter, logger blog.Logger) {
go cmd.DebugServer(c.WFE.DebugAddr)
wfe, err := wfe.NewWebFrontEndImpl(stats, clock.Default(), c.KeyPolicy())
wfe, err := wfe.NewWebFrontEndImpl(stats, clock.Default(), c.KeyPolicy(), logger)
cmd.FailOnError(err, "Unable to create WFE")
rac, sac := setupWFE(c, logger, stats)
wfe.RA = rac

View File

@ -63,6 +63,7 @@ func newUpdater(
config cmd.OCSPUpdaterConfig,
numLogs int,
issuerPath string,
log blog.Logger,
) (*OCSPUpdater, error) {
if config.NewCertificateBatchSize == 0 ||
config.OldOCSPBatchSize == 0 ||
@ -75,8 +76,6 @@ func newUpdater(
return nil, fmt.Errorf("Loop window sizes must be non-zero")
}
log := blog.Get()
updater := OCSPUpdater{
stats: stats,
clk: clk,
@ -585,6 +584,7 @@ func main() {
conf,
len(c.Common.CT.Logs),
c.Common.IssuerCert,
auditlogger,
)
cmd.FailOnError(err, "Failed to create updater")

View File

@ -89,6 +89,7 @@ func setup(t *testing.T) (*OCSPUpdater, core.StorageAuthority, *gorp.DbMap, cloc
},
0,
"",
blog.NewMock(),
)
return updater, sa, dbMap, fc, cleanUp

View File

@ -130,8 +130,12 @@ const wildcardRoutingKey = "#"
// NewAmqpRPCServer creates a new RPC server for the given queue and will begin
// consuming requests from the queue. To start the server you must call Start().
func NewAmqpRPCServer(amqpConf *cmd.AMQPConfig, maxConcurrentRPCServerRequests int64, stats statsd.Statter) (*AmqpRPCServer, error) {
log := blog.Get()
func NewAmqpRPCServer(
amqpConf *cmd.AMQPConfig,
maxConcurrentRPCServerRequests int64,
stats statsd.Statter,
log blog.Logger,
) (*AmqpRPCServer, error) {
reconnectBase := amqpConf.ReconnectTimeouts.Base.Duration
if reconnectBase == 0 {

View File

@ -215,9 +215,7 @@ func errorCondition(method string, err error, obj interface{}) {
}
// NewRegistrationAuthorityServer constructs an RPC server
func NewRegistrationAuthorityServer(rpc Server, impl core.RegistrationAuthority) error {
log := blog.Get()
func NewRegistrationAuthorityServer(rpc Server, impl core.RegistrationAuthority, log blog.Logger) error {
rpc.Handle(MethodNewRegistration, func(ctx context.Context, req []byte) (response []byte, err error) {
var rr registrationRequest
if err = json.Unmarshal(req, &rr); err != nil {

View File

@ -10,6 +10,7 @@ import (
safebrowsing "github.com/letsencrypt/go-safe-browsing-api"
"github.com/letsencrypt/boulder/cmd"
blog "github.com/letsencrypt/boulder/log"
vaPB "github.com/letsencrypt/boulder/va/proto"
)
@ -38,7 +39,8 @@ func TestIsSafeDomain(t *testing.T) {
"user agent 1.0",
"letsencrypt.org",
stats,
clock.NewFake())
clock.NewFake(),
blog.NewMock())
domain := "good.com"
resp, err := va.IsSafeDomain(ctx, &vaPB.IsSafeDomainRequest{Domain: &domain})
@ -88,7 +90,8 @@ func TestAllowNilInIsSafeDomain(t *testing.T) {
"user agent 1.0",
"letsencrypt.org",
stats,
clock.NewFake())
clock.NewFake(),
blog.NewMock())
// Be cool with a nil SafeBrowsing. This will happen in prod when we have
// flag mismatch between the VA and RA.

View File

@ -72,8 +72,8 @@ func NewValidationAuthorityImpl(
issuerDomain string,
stats statsd.Statter,
clk clock.Clock,
logger blog.Logger,
) *ValidationAuthorityImpl {
logger := blog.Get()
return &ValidationAuthorityImpl{
log: logger,
dnsResolver: resolver,

View File

@ -64,8 +64,6 @@ var accountKey = &jose.JsonWebKey{Key: TheKey.Public()}
var ident = core.AcmeIdentifier{Type: core.IdentifierDNS, Value: "localhost"}
var log = blog.UseMock()
var ctx = context.Background()
// All paths that get assigned to tokens MUST be valid tokens
@ -220,7 +218,7 @@ func TestHTTP(t *testing.T) {
if badPort == 65536 {
badPort = goodPort - 1
}
va, _ := setup()
va, _, log := setup()
va.httpPort = badPort
_, prob := va.validateHTTP01(ctx, ident, chall)
@ -309,10 +307,9 @@ func TestHTTPRedirectLookup(t *testing.T) {
defer hs.Close()
port, err := getPort(hs)
test.AssertNotError(t, err, "failed to get test server port")
va, _ := setup()
va, _, log := setup()
va.httpPort = port
log.Clear()
setChallengeToken(&chall, pathMoved)
_, prob := va.validateHTTP01(ctx, ident, chall)
if prob != nil {
@ -365,10 +362,9 @@ func TestHTTPRedirectLoop(t *testing.T) {
defer hs.Close()
port, err := getPort(hs)
test.AssertNotError(t, err, "failed to get test server port")
va, _ := setup()
va, _, _ := setup()
va.httpPort = port
log.Clear()
_, prob := va.validateHTTP01(ctx, ident, chall)
if prob == nil {
t.Fatalf("Challenge should have failed for %s", chall.Token)
@ -383,7 +379,7 @@ func TestHTTPRedirectUserAgent(t *testing.T) {
defer hs.Close()
port, err := getPort(hs)
test.AssertNotError(t, err, "failed to get test server port")
va, _ := setup()
va, _, _ := setup()
va.userAgent = rejectUserAgent
va.httpPort = port
@ -423,10 +419,9 @@ func TestTLSSNI(t *testing.T) {
port, err := getPort(hs)
test.AssertNotError(t, err, "failed to get test server port")
va, _ := setup()
va, _, log := setup()
va.tlsPort = port
log.Clear()
_, prob := va.validateTLSSNI01(ctx, ident, chall)
if prob != nil {
t.Fatalf("Unexpected failre in validateTLSSNI01: %s", prob)
@ -493,7 +488,7 @@ func TestTLSError(t *testing.T) {
port, err := getPort(hs)
test.AssertNotError(t, err, "failed to get test server port")
va, _ := setup()
va, _, _ := setup()
va.tlsPort = port
_, prob := va.validateTLSSNI01(ctx, ident, chall)
@ -510,7 +505,7 @@ func TestValidateHTTP(t *testing.T) {
hs := httpSrv(t, chall.Token)
port, err := getPort(hs)
test.AssertNotError(t, err, "failed to get test server port")
va, _ := setup()
va, _, _ := setup()
va.httpPort = port
defer hs.Close()
@ -554,7 +549,7 @@ func TestValidateTLSSNI01(t *testing.T) {
port, err := getPort(hs)
test.AssertNotError(t, err, "failed to get test server port")
va, _ := setup()
va, _, _ := setup()
va.tlsPort = port
_, prob := va.validateChallenge(ctx, ident, chall)
@ -563,7 +558,7 @@ func TestValidateTLSSNI01(t *testing.T) {
}
func TestValidateTLSSNINotSane(t *testing.T) {
va, _ := setup()
va, _, _ := setup()
chall := createChallenge(core.ChallengeTypeTLSSNI01)
@ -575,7 +570,7 @@ func TestValidateTLSSNINotSane(t *testing.T) {
}
func TestCAATimeout(t *testing.T) {
va, _ := setup()
va, _, _ := setup()
err := va.checkCAA(ctx, core.AcmeIdentifier{Type: core.IdentifierDNS, Value: "caa-timeout.com"})
if err.Type != probs.ConnectionProblem {
t.Errorf("Expected timeout error type %s, got %s", probs.ConnectionProblem, err.Type)
@ -617,7 +612,7 @@ func TestCAAChecking(t *testing.T) {
{"unsatisfiable.com", true, false},
}
va, _ := setup()
va, _, _ := setup()
for _, caaTest := range tests {
present, valid, err := va.checkCAARecords(ctx, core.AcmeIdentifier{Type: "dns", Value: caaTest.Domain})
if err != nil {
@ -653,7 +648,7 @@ func TestCAAChecking(t *testing.T) {
}
func TestPerformValidationInvalid(t *testing.T) {
va, stats := setup()
va, stats, _ := setup()
chalDNS := createChallenge(core.ChallengeTypeDNS01)
_, prob := va.PerformValidation(context.Background(), "foo.com", chalDNS, core.Authorization{})
test.Assert(t, prob != nil, "validation succeeded")
@ -661,7 +656,7 @@ func TestPerformValidationInvalid(t *testing.T) {
}
func TestPerformValidationValid(t *testing.T) {
va, stats := setup()
va, stats, _ := setup()
// create a challenge with well known token
chalDNS := core.DNSChallenge01(accountKey)
chalDNS.Token = expectedToken
@ -672,7 +667,7 @@ func TestPerformValidationValid(t *testing.T) {
}
func TestDNSValidationFailure(t *testing.T) {
va, _ := setup()
va, _, _ := setup()
chalDNS := createChallenge(core.ChallengeTypeDNS01)
@ -690,7 +685,7 @@ func TestDNSValidationInvalid(t *testing.T) {
chalDNS := core.DNSChallenge01(accountKey)
chalDNS.ProvidedKeyAuthorization, _ = chalDNS.ExpectedKeyAuthorization()
va, _ := setup()
va, _, _ := setup()
_, prob := va.validateChallenge(ctx, notDNS, chalDNS)
@ -698,7 +693,7 @@ func TestDNSValidationInvalid(t *testing.T) {
}
func TestDNSValidationNotSane(t *testing.T) {
va, _ := setup()
va, _, _ := setup()
chal0 := core.DNSChallenge01(accountKey)
chal0.Token = ""
@ -729,7 +724,7 @@ func TestDNSValidationNotSane(t *testing.T) {
}
func TestDNSValidationServFail(t *testing.T) {
va, _ := setup()
va, _, _ := setup()
chalDNS := createChallenge(core.ChallengeTypeDNS01)
@ -743,7 +738,7 @@ func TestDNSValidationServFail(t *testing.T) {
}
func TestDNSValidationNoServer(t *testing.T) {
va, _ := setup()
va, _, _ := setup()
va.dnsResolver = bdns.NewTestDNSResolverImpl(
time.Second*5,
nil,
@ -759,7 +754,7 @@ func TestDNSValidationNoServer(t *testing.T) {
}
func TestDNSValidationOK(t *testing.T) {
va, _ := setup()
va, _, _ := setup()
// create a challenge with well known token
chalDNS := core.DNSChallenge01(accountKey)
@ -778,7 +773,7 @@ func TestDNSValidationOK(t *testing.T) {
}
func TestDNSValidationNoAuthorityOK(t *testing.T) {
va, _ := setup()
va, _, _ := setup()
// create a challenge with well known token
chalDNS := core.DNSChallenge01(accountKey)
@ -800,7 +795,7 @@ func TestDNSValidationNoAuthorityOK(t *testing.T) {
// the existence of some Internet resources. Because of that,
// it asserts nothing; it is intended for coverage.
func TestDNSValidationLive(t *testing.T) {
va, _ := setup()
va, _, _ := setup()
goodChalDNS := core.DNSChallenge01(accountKey)
// The matching value LPsIwTo7o8BoG0-vjCyGQGBWSVIPxI-i_X336eUOQZo
@ -841,7 +836,7 @@ func TestCAAFailure(t *testing.T) {
port, err := getPort(hs)
test.AssertNotError(t, err, "failed to get test server port")
va, _ := setup()
va, _, _ := setup()
va.tlsPort = port
ident.Value = "reserved.com"
@ -857,7 +852,7 @@ func TestLimitedReader(t *testing.T) {
hs := httpSrv(t, "01234567890123456789012345678901234567890123456789012345678901234567890123456789")
port, err := getPort(hs)
test.AssertNotError(t, err, "failed to get test server port")
va, _ := setup()
va, _, _ := setup()
va.httpPort = port
defer hs.Close()
@ -869,8 +864,9 @@ func TestLimitedReader(t *testing.T) {
"Expected failure due to truncation")
}
func setup() (*ValidationAuthorityImpl, *mocks.Statter) {
func setup() (*ValidationAuthorityImpl, *mocks.Statter, *blog.Mock) {
stats := mocks.NewStatter()
logger := blog.NewMock()
va := NewValidationAuthorityImpl(
&cmd.PortConfig{},
nil,
@ -880,19 +876,20 @@ func setup() (*ValidationAuthorityImpl, *mocks.Statter) {
"user agent 1.0",
"letsencrypt.org",
stats,
clock.Default())
return va, stats
clock.Default(),
logger)
return va, stats, logger
}
func TestGetCAASetFallback(t *testing.T) {
testSrv := httptest.NewServer(http.HandlerFunc(mocks.GPDNSHandler))
defer testSrv.Close()
caaDR, err := cdr.New(metrics.NewNoopScope(), time.Second, 1, nil, log)
caaDR, err := cdr.New(metrics.NewNoopScope(), time.Second, 1, nil, blog.NewMock())
test.AssertNotError(t, err, "Failed to create CAADistributedResolver")
caaDR.URI = testSrv.URL
caaDR.Clients["1.1.1.1"] = new(http.Client)
va, _ := setup()
va, _, _ := setup()
va.caaDR = caaDR
set, err := va.getCAASet(ctx, "bad-local-resolver.com")

View File

@ -86,9 +86,12 @@ type WebFrontEndImpl struct {
}
// NewWebFrontEndImpl constructs a web service for Boulder
func NewWebFrontEndImpl(stats statsd.Statter, clk clock.Clock, keyPolicy goodkey.KeyPolicy) (WebFrontEndImpl, error) {
logger := blog.Get()
func NewWebFrontEndImpl(
stats statsd.Statter,
clk clock.Clock,
keyPolicy goodkey.KeyPolicy,
logger blog.Logger,
) (WebFrontEndImpl, error) {
nonceService, err := nonce.NewNonceService()
if err != nil {
return WebFrontEndImpl{}, err

View File

@ -215,11 +215,10 @@ func setupWFE(t *testing.T) (WebFrontEndImpl, clock.FakeClock) {
fc := clock.NewFake()
stats, _ := statsd.NewNoopClient()
wfe, err := NewWebFrontEndImpl(stats, fc, testKeyPolicy)
wfe, err := NewWebFrontEndImpl(stats, fc, testKeyPolicy, blog.NewMock())
test.AssertNotError(t, err, "Unable to create WFE")
wfe.SubscriberAgreementURL = agreementURL
wfe.log = blog.NewMock()
wfe.RA = &MockRegistrationAuthority{}
wfe.SA = mocks.NewStorageAuthority(fc)