|
1 | 1 | # Testing |
2 | 2 |
|
3 | | -cert-exporter testing is fairly simple. The [./test.sh](../test/files/test.sh) in the test directory will generate some certs and kubeconfigs, run the application against the files and curl the prometheus metrics to confirm they are accurate. It takes one parameter which is the number of days to expire the test certs in. |
| 3 | +cert-exporter uses both Go's built-in testing framework for unit tests and bash scripts for end-to-end integration testing. |
| 4 | + |
| 5 | +## Running Tests |
| 6 | + |
| 7 | +### Unit Tests |
| 8 | + |
| 9 | +Run all unit tests with: |
| 10 | + |
| 11 | +```bash |
| 12 | +make test |
| 13 | +``` |
| 14 | + |
| 15 | +Or directly with Go: |
| 16 | + |
| 17 | +```bash |
| 18 | +go test -v -race ./... |
| 19 | +``` |
| 20 | + |
| 21 | +Unit tests cover: |
| 22 | +- Certificate parsing (PEM and PKCS12 formats) |
| 23 | +- Certificate exporter functionality |
| 24 | +- Kubeconfig parsing and certificate extraction |
| 25 | +- File-based certificate checking |
| 26 | +- Metric generation and labels |
| 27 | +- Error handling |
| 28 | + |
| 29 | +### Integration Tests (Go) |
| 30 | + |
| 31 | +Integration tests require a Kubernetes cluster with KUBECONFIG set: |
| 32 | + |
| 33 | +```bash |
| 34 | +make test-integration |
| 35 | +``` |
| 36 | + |
| 37 | +Or directly with Go: |
| 38 | + |
| 39 | +```bash |
| 40 | +go test -v -tags=integration ./integration_test.go |
| 41 | +``` |
| 42 | + |
| 43 | +Integration tests cover: |
| 44 | +- End-to-end certificate monitoring |
| 45 | +- Kubernetes secret checking |
| 46 | +- ConfigMap certificate extraction |
| 47 | +- Real Prometheus metric collection |
| 48 | + |
| 49 | +### Integration Tests (Bash) |
| 50 | + |
| 51 | +#### File-based Certificate Testing |
| 52 | + |
| 53 | +The [test/files/test.sh](../test/files/test.sh) script generates test certificates and kubeconfigs, runs the application against the files, and curls the prometheus metrics to confirm they are accurate. It takes one parameter which is the number of days to expire the test certs in. |
4 | 54 |
|
5 | 55 | Example: |
6 | 56 |
|
| 57 | +```bash |
| 58 | +cd test/files |
| 59 | +./test.sh 100 |
| 60 | +``` |
| 61 | + |
| 62 | +Output: |
7 | 63 | ``` |
8 | | -# ./test.sh |
9 | 64 | ** Testing Certs and kubeconfig in the same dir |
10 | 65 | cert_exporter_error_total 0 |
11 | 66 | TEST SUCCESS: cert_exporter_cert_expires_in_seconds{filename="certs/client.crt",issuer="root",nodename="master0"} |
12 | 67 | TEST SUCCESS: cert_exporter_cert_expires_in_seconds{filename="certs/root.crt",issuer="root",nodename="master0"} |
13 | 68 | TEST SUCCESS: cert_exporter_cert_expires_in_seconds{filename="certs/server.crt",issuer="root",nodename="master0"} |
14 | 69 | TEST SUCCESS: cert_exporter_kubeconfig_expires_in_seconds{filename="certs/kubeconfig",name="cluster1",nodename="master0",type="cluster"} |
15 | | -TEST SUCCESS: cert_exporter_kubeconfig_expires_in_seconds{filename="certs/kubeconfig",name="cluster2",nodename="master0",type="cluster"} |
16 | | -TEST SUCCESS: cert_exporter_kubeconfig_expires_in_seconds{filename="certs/kubeconfig",name="user1",nodename="master0",type="user"} |
17 | | -TEST SUCCESS: cert_exporter_kubeconfig_expires_in_seconds{filename="certs/kubeconfig",name="user2",nodename="master0",type="user"} |
18 | | -** Testing Certs and kubeconfig in sibling dirs |
19 | | -cert_exporter_error_total 0 |
20 | | -TEST SUCCESS: cert_exporter_cert_expires_in_seconds{filename="certsSibling/client.crt",issuer="root",nodename="master0"} |
21 | | -TEST SUCCESS: cert_exporter_cert_expires_in_seconds{filename="certsSibling/root.crt",issuer="root",nodename="master0"} |
22 | | -TEST SUCCESS: cert_exporter_cert_expires_in_seconds{filename="certsSibling/server.crt",issuer="root",nodename="master0"} |
23 | | -TEST SUCCESS: cert_exporter_kubeconfig_expires_in_seconds{filename="kubeConfigSibling/kubeconfig",name="cluster1",nodename="master0",type="cluster"} |
24 | | -TEST SUCCESS: cert_exporter_kubeconfig_expires_in_seconds{filename="kubeConfigSibling/kubeconfig",name="cluster2",nodename="master0",type="cluster"} |
25 | | -TEST SUCCESS: cert_exporter_kubeconfig_expires_in_seconds{filename="kubeConfigSibling/kubeconfig",name="user1",nodename="master0",type="user"} |
26 | | -TEST SUCCESS: cert_exporter_kubeconfig_expires_in_seconds{filename="kubeConfigSibling/kubeconfig",name="user2",nodename="master0",type="user"} |
27 | | -** Testing Error metric increments |
28 | | -E0707 09:25:59.470115 56712 periodicCertChecker.go:47] Error on certs/client.crt: Failed to parse as a pem |
29 | | -cert_exporter_error_total 1 |
30 | | -# ./testCleanup.sh |
| 70 | +... |
31 | 71 | ``` |
32 | 72 |
|
33 | | -It's not great, but it gets the job done. There could definitely be some work put into this. |
34 | | - |
35 | | -### Dependencies |
36 | | - |
| 73 | +Dependencies: |
37 | 74 | - bash |
38 | 75 | - openssl |
39 | 76 | - curl |
40 | 77 |
|
41 | | -### cert-manager testing |
| 78 | +#### cert-manager Testing |
| 79 | + |
| 80 | +The [test/cert-manager/test.sh](../test/cert-manager/test.sh) script does basic testing of cert-manager created certificates in a Kubernetes cluster. |
| 81 | + |
| 82 | +Requirements: |
| 83 | +- kind (Kubernetes in Docker) |
| 84 | +- kubectl |
| 85 | +- A built cert-exporter binary |
| 86 | + |
| 87 | +Example: |
| 88 | + |
| 89 | +```bash |
| 90 | +cd test/cert-manager |
| 91 | +./test.sh |
| 92 | +``` |
| 93 | + |
| 94 | +This will: |
| 95 | +1. Create a kind cluster |
| 96 | +2. Install cert-manager |
| 97 | +3. Create test certificates, secrets, configmaps, and webhooks |
| 98 | +4. Run cert-exporter against these resources |
| 99 | +5. Validate the exported metrics |
| 100 | +6. Clean up the cluster |
| 101 | + |
| 102 | +### All Tests |
| 103 | + |
| 104 | +Run both unit and integration tests: |
| 105 | + |
| 106 | +```bash |
| 107 | +make test-all |
| 108 | +``` |
| 109 | + |
| 110 | +## Test Coverage |
| 111 | + |
| 112 | +Generate a coverage report: |
| 113 | + |
| 114 | +```bash |
| 115 | +go test -coverprofile=coverage.txt -covermode=atomic ./... |
| 116 | +go tool cover -html=coverage.txt |
| 117 | +``` |
| 118 | + |
| 119 | +## Test Organization |
| 120 | + |
| 121 | +- **Unit tests**: Located alongside source files (e.g., `certExporter_test.go`) |
| 122 | +- **Integration tests**: Located in `integration_test.go` at the root |
| 123 | +- **Test utilities**: Located in `internal/testutil/` |
| 124 | + - `certs.go` - Certificate generation helpers |
| 125 | + - `kubeconfig.go` - Kubeconfig file builders |
| 126 | + |
| 127 | +## Writing Tests |
| 128 | + |
| 129 | +When adding new functionality: |
| 130 | + |
| 131 | +1. Add unit tests for individual components |
| 132 | +2. Add integration tests for end-to-end flows |
| 133 | +3. Ensure tests use the test utilities in `internal/testutil/` |
| 134 | +4. Use `t.TempDir()` for temporary files |
| 135 | +5. Initialize metrics with `metrics.Init(true)` to avoid conflicts |
| 136 | + |
| 137 | +### Example Unit Test |
| 138 | + |
| 139 | +```go |
| 140 | +func TestCertExporter_ExportMetrics(t *testing.T) { |
| 141 | + metrics.Init(true) |
| 142 | + |
| 143 | + tmpDir := testutil.CreateTempCertDir(t) |
| 144 | + certFile := filepath.Join(tmpDir, "test.crt") |
| 145 | + |
| 146 | + cert := testutil.GenerateCertificate(t, testutil.CertConfig{ |
| 147 | + CommonName: "test-cert", |
| 148 | + Organization: "test-org", |
| 149 | + Country: "US", |
| 150 | + Province: "CA", |
| 151 | + Days: 30, |
| 152 | + }) |
| 153 | + |
| 154 | + testutil.WriteCertToFile(t, cert.CertPEM, certFile) |
| 155 | + |
| 156 | + exporter := &CertExporter{} |
| 157 | + err := exporter.ExportMetrics(certFile, "test-node") |
| 158 | + |
| 159 | + if err != nil { |
| 160 | + t.Fatalf("ExportMetrics() failed: %v", err) |
| 161 | + } |
| 162 | + |
| 163 | + // Verify metrics... |
| 164 | +} |
| 165 | +``` |
| 166 | + |
| 167 | +## Continuous Integration |
| 168 | + |
| 169 | +Tests run automatically in GitHub Actions on: |
| 170 | +- Pull requests |
| 171 | +- Pushes to master |
| 172 | +- Tag releases |
42 | 173 |
|
43 | | -`./test/cert-manager-v1/test.sh` do really basic testing of cert-manager created certs. |
| 174 | +The CI pipeline runs both unit and integration tests to ensure quality. |
0 commit comments