Merge pull request #119888 from dgrisonnet/panic-storage-metric
Fix segfault during storage size metric collection
This commit is contained in:
		@@ -85,7 +85,7 @@ var (
 | 
				
			|||||||
		[]string{"endpoint"},
 | 
							[]string{"endpoint"},
 | 
				
			||||||
	)
 | 
						)
 | 
				
			||||||
	storageSizeDescription   = compbasemetrics.NewDesc("apiserver_storage_size_bytes", "Size of the storage database file physically allocated in bytes.", []string{"cluster"}, nil, compbasemetrics.ALPHA, "")
 | 
						storageSizeDescription   = compbasemetrics.NewDesc("apiserver_storage_size_bytes", "Size of the storage database file physically allocated in bytes.", []string{"cluster"}, nil, compbasemetrics.ALPHA, "")
 | 
				
			||||||
	storageMonitor           = &monitorCollector{}
 | 
						storageMonitor           = &monitorCollector{monitorGetter: func() ([]Monitor, error) { return nil, nil }}
 | 
				
			||||||
	etcdEventsReceivedCounts = compbasemetrics.NewCounterVec(
 | 
						etcdEventsReceivedCounts = compbasemetrics.NewCounterVec(
 | 
				
			||||||
		&compbasemetrics.CounterOpts{
 | 
							&compbasemetrics.CounterOpts{
 | 
				
			||||||
			Subsystem:      "apiserver",
 | 
								Subsystem:      "apiserver",
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -17,6 +17,7 @@ limitations under the License.
 | 
				
			|||||||
package metrics
 | 
					package metrics
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import (
 | 
					import (
 | 
				
			||||||
 | 
						"context"
 | 
				
			||||||
	"errors"
 | 
						"errors"
 | 
				
			||||||
	"strings"
 | 
						"strings"
 | 
				
			||||||
	"testing"
 | 
						"testing"
 | 
				
			||||||
@@ -179,3 +180,60 @@ etcd_request_errors_total{operation="foo",type="bar"} 1
 | 
				
			|||||||
		})
 | 
							})
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func TestStorageSizeCollector(t *testing.T) {
 | 
				
			||||||
 | 
						registry := metrics.NewKubeRegistry()
 | 
				
			||||||
 | 
						registry.CustomMustRegister(storageMonitor)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						testCases := []struct {
 | 
				
			||||||
 | 
							desc           string
 | 
				
			||||||
 | 
							getterOverride func() ([]Monitor, error)
 | 
				
			||||||
 | 
							err            error
 | 
				
			||||||
 | 
							want           string
 | 
				
			||||||
 | 
						}{
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								desc: "fake etcd getter",
 | 
				
			||||||
 | 
								getterOverride: func() ([]Monitor, error) {
 | 
				
			||||||
 | 
									return []Monitor{fakeEtcdMonitor{storageSize: 1e9}}, nil
 | 
				
			||||||
 | 
								},
 | 
				
			||||||
 | 
								err: nil,
 | 
				
			||||||
 | 
								want: `# HELP apiserver_storage_size_bytes [ALPHA] Size of the storage database file physically allocated in bytes.
 | 
				
			||||||
 | 
								# TYPE apiserver_storage_size_bytes gauge
 | 
				
			||||||
 | 
								apiserver_storage_size_bytes{cluster="etcd-0"} 1e+09
 | 
				
			||||||
 | 
								`,
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								desc:           "getters not configured",
 | 
				
			||||||
 | 
								getterOverride: nil,
 | 
				
			||||||
 | 
								err:            nil,
 | 
				
			||||||
 | 
								want:           ``,
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for _, test := range testCases {
 | 
				
			||||||
 | 
							t.Run(test.desc, func(t *testing.T) {
 | 
				
			||||||
 | 
								defer registry.Reset()
 | 
				
			||||||
 | 
								if test.getterOverride != nil {
 | 
				
			||||||
 | 
									oldGetter := storageMonitor.monitorGetter
 | 
				
			||||||
 | 
									defer SetStorageMonitorGetter(oldGetter)
 | 
				
			||||||
 | 
									SetStorageMonitorGetter(test.getterOverride)
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								if err := testutil.GatherAndCompare(registry, strings.NewReader(test.want), "apiserver_storage_size_bytes"); err != nil {
 | 
				
			||||||
 | 
									t.Fatal(err)
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							})
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type fakeEtcdMonitor struct {
 | 
				
			||||||
 | 
						storageSize int64
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (m fakeEtcdMonitor) Monitor(_ context.Context) (StorageMetrics, error) {
 | 
				
			||||||
 | 
						return StorageMetrics{Size: m.storageSize}, nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (m fakeEtcdMonitor) Close() error {
 | 
				
			||||||
 | 
						return nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user