1
2
3 package integration
4
5 import (
6 "bytes"
7 "context"
8 "fmt"
9 "os"
10 "os/exec"
11 "syscall"
12 "testing"
13 "time"
14
15 akamaipb "github.com/letsencrypt/boulder/akamai/proto"
16 "github.com/letsencrypt/boulder/cmd"
17 bcreds "github.com/letsencrypt/boulder/grpc/creds"
18 "github.com/letsencrypt/boulder/metrics"
19 "github.com/letsencrypt/boulder/test"
20 "google.golang.org/grpc"
21 "google.golang.org/grpc/balancer/roundrobin"
22 "google.golang.org/grpc/connectivity"
23 )
24
25 func setup() (*exec.Cmd, *bytes.Buffer, akamaipb.AkamaiPurgerClient, error) {
26 purgerCmd := exec.Command("./bin/boulder", "akamai-purger", "--config", "test/integration/testdata/akamai-purger-queue-drain-config.json")
27 var outputBuffer bytes.Buffer
28 purgerCmd.Stdout = &outputBuffer
29 purgerCmd.Stderr = &outputBuffer
30 purgerCmd.Start()
31
32
33
34 sigterm := func() {
35 purgerCmd.Process.Signal(syscall.SIGTERM)
36 purgerCmd.Wait()
37 }
38
39 tlsConfig, err := (&cmd.TLSConfig{
40 CACertFile: "test/grpc-creds/minica.pem",
41 CertFile: "test/grpc-creds/ra.boulder/cert.pem",
42 KeyFile: "test/grpc-creds/ra.boulder/key.pem",
43 }).Load(metrics.NoopRegisterer)
44 if err != nil {
45 sigterm()
46 return nil, nil, nil, err
47 }
48 creds := bcreds.NewClientCredentials(tlsConfig.RootCAs, tlsConfig.Certificates, "akamai-purger.boulder")
49 conn, err := grpc.Dial(
50 "dns:///akamai-purger.service.consul:9199",
51 grpc.WithDefaultServiceConfig(fmt.Sprintf(`{"loadBalancingConfig": [{"%s":{}}]}`, roundrobin.Name)),
52 grpc.WithTransportCredentials(creds),
53 )
54 if err != nil {
55 sigterm()
56 return nil, nil, nil, err
57 }
58 for i := 0; ; i++ {
59 if conn.GetState() == connectivity.Ready {
60 break
61 }
62 if i > 40 {
63 sigterm()
64 return nil, nil, nil, fmt.Errorf("timed out waiting for akamai-purger to come up: %s", outputBuffer.String())
65 }
66 time.Sleep(50 * time.Millisecond)
67 }
68 purgerClient := akamaipb.NewAkamaiPurgerClient(conn)
69 return purgerCmd, &outputBuffer, purgerClient, nil
70 }
71
72 func TestAkamaiPurgerDrainQueueFails(t *testing.T) {
73 purgerCmd, outputBuffer, purgerClient, err := setup()
74 if err != nil {
75 t.Fatal(err)
76 }
77
78
79
80
81 for i := 0; i < 10; i++ {
82 _, err = purgerClient.Purge(context.Background(), &akamaipb.PurgeRequest{
83 Urls: []string{fmt.Sprintf("http://example%d.com/", i)},
84 })
85 if err != nil {
86
87
88 t.Error(err)
89 }
90 }
91
92 purgerCmd.Process.Signal(syscall.SIGTERM)
93 err = purgerCmd.Wait()
94 if err == nil {
95 t.Error("expected error shutting down akamai-purger that could not reach backend")
96 }
97
98
99
100 test.AssertContains(t, outputBuffer.String(), "failed to purge OCSP responses for")
101 test.AssertContains(t, outputBuffer.String(), "certificates before exit: all attempts to submit purge request failed")
102 }
103
104 func TestAkamaiPurgerDrainQueueSucceeds(t *testing.T) {
105 purgerCmd, outputBuffer, purgerClient, err := setup()
106 if err != nil {
107 t.Fatal(err)
108 }
109 for i := 0; i < 10; i++ {
110 _, err := purgerClient.Purge(context.Background(), &akamaipb.PurgeRequest{
111 Urls: []string{"http://example.com/"},
112 })
113 if err != nil {
114 t.Error(err)
115 }
116 }
117 time.Sleep(200 * time.Millisecond)
118 purgerCmd.Process.Signal(syscall.SIGTERM)
119
120 akamaiTestSrvCmd := exec.Command("./bin/akamai-test-srv", "--listen", "localhost:6889",
121 "--secret", "its-a-secret")
122 akamaiTestSrvCmd.Stdout = os.Stdout
123 akamaiTestSrvCmd.Stderr = os.Stderr
124 akamaiTestSrvCmd.Start()
125
126 err = purgerCmd.Wait()
127 if err != nil {
128 t.Errorf("unexpected error shutting down akamai-purger: %s. Output was:\n%s", err, outputBuffer.String())
129 }
130 test.AssertContains(t, outputBuffer.String(), "Shutting down; finished purging OCSP responses")
131 akamaiTestSrvCmd.Process.Signal(syscall.SIGTERM)
132 _ = akamaiTestSrvCmd.Wait()
133 }
134
View as plain text