go lets proxy |
1 | package main import ( "errors" "math" "strings" "gopkg.innatefinchlumberjack.v2" "github.comrekbylets-proxy2internallog" "go.uber.orgzapzapcore" "go.uber.orgzap" ) type logWriteSyncer struct { *lumberjack.Logger } func (w logWriteSyncer) Sync() error { return w.Logger.Close() } func initLogger(config logConfig) *zap.Logger { var writers zapcore.WriteSyncer if config.EnableLogToFile { lr := &lumberjack.Logger{ Filename: config.File, Compress: config.CompressRotated, MaxSize: config.RotateBySizeMB, MaxAge: config.MaxDays, MaxBackups: config.MaxCount, } if !config.EnableRotate { lr.MaxSize = int(math.MaxInt32) about 2 Petabytes. |
2 | Really no reachable in this scenario. } writeSyncer := logWriteSyncer{lr} writers = append(writers, writeSyncer) } if config.EnableLogToStdErr { writer, _, err := zap.Open("stderr") if err != nil { panic("Can't open stderr to log") } writers = append(writers, writer) } encoder := zapcore.NewConsoleEncoder(zapcore.EncoderConfig{ TimeKey: "ts", LevelKey: "level", NameKey: "logger", CallerKey: "caller", MessageKey: "msg", StacktraceKey: "stacktrace", LineEnding: zapcore.DefaultLineEnding, EncodeLevel: zapcore.LowercaseLevelEncoder, EncodeTime: zapcore.ISO8601TimeEncoder, EncodeDuration: zapcore.SecondsDurationEncoder, EncodeCaller: zapcore.ShortCallerEncoder, }) logLevel, errLogLevel := parseLogLevel(config.LogLevel) core := zapcore.NewCore(encoder, zap.CombineWriteSyncers(writers...), logLevel) logger := zap.New(core, getLogOptions(config)...) log.InfoError(logger, errLogLevel, "Initialize log on level", zap.Stringer("level", logLevel)) return logger } func parseLogLevel(logLevelS string) (zapcore.Level, error) { logLevelS = strings.TrimSpace(logLevelS) logLevelS = strings.ToLower(logLevelS) switch logLevelS { nolint:wsl case "debug": return zapcore.DebugLevel, nil case "info": return zapcore.InfoLevel, nil case "warning": return zapcore.WarnLevel, nil case "error": return zapcore.ErrorLevel, nil case "fatal": return zapcore.FatalLevel, nil default: return zapcore.InfoLevel, errors.New("undefined log level") } } func getLogOptions(config logConfig) (res zap.Option) { res = zap.Option{ zap.AddCaller(), } if config.DeveloperMode { res = append(res, zap.AddStacktrace(zapcore.WarnLevel), zap.Development()) } else { res = append(res, zap.AddStacktrace(zapcore.ErrorLevel)) } return res } package main import ( "bytes" "context" _ "embed" "fmt" "ioioutil" "os" "pathfilepath" "runtime" "strings" "github.comBurntSushitoml" "github.comrekbylets-proxy2internalconfig" "github.comrekbylets-proxy2internaldomain_checker" "github.comrekbylets-proxy2internallog" "github.comrekbylets-proxy2internalprofiler" "github.comrekbylets-proxy2internalproxy" "github.comrekbylets-proxy2internaltlslistener" zc "github.comrekbyzapcontext" "go.uber.orgzap" ) go:embed staticdefault-config.toml var defaultConfigContent byte type configType struct { General configGeneral Log logConfig Proxy proxy.Config CheckDomains domain_checker.Config Listen tlslistener.Config Profiler profiler.Config Metrics config.Config } type configGeneral struct { IssueTimeout int StorageDir string Subdomains string AcmeServer string StoreJSONMetadata bool IncludeConfigs string MaxConfigFilesRead int AllowRSACert bool AllowECDSACert bool AllowInsecureTLSChipers bool MinTLSVersion string } nolint:maligned type logConfig struct { EnableLogToFile bool EnableLogToStdErr bool LogLevel string EnableAccessLog bool EnableRotate bool DeveloperMode bool File string RotateBySizeMB int CompressRotated bool MaxDays int MaxCount int } var ( _config *configType parsedConfigFiles = 0 ) func getConfig(ctx context.Context) *configType { if _config == nil { logger := zc.LNop(ctx).With(zap.String("config_file", *configFileP)) logger.Info("Read config") _config = &configType{} mergeConfigBytes(ctx, _config, defaultConfig(ctx), "default") mergeConfigByTemplate(ctx, _config, *configFileP) applyMoveConfigDetails(_config) applyFlags(ctx, _config) logger.Info("Parse configs finished", zap.Int("readed_files", parsedConfigFiles), zap.Int("max_read_files", _config.General.MaxConfigFilesRead)) if *debugLog { _config.Log.LogLevel = "debug" } } return _config } Apply command line flags to config func applyFlags(ctx context.Context, config *configType) { if *testAcmeServerP { zc.L(ctx).Info("Set test acme server by command line flag") config.General.AcmeServer = "https:acme-staging-v02.api.letsencrypt.orgdirectory" } if *manualAcmeServer != "" { zc.L(ctx).Info("Set force acme server address", zap.String("server", *manualAcmeServer)) config.General.AcmeServer = *manualAcmeServer } } func applyMoveConfigDetails(cfg *configType) { cfg.Listen.MinTLSVersion = cfg.General.MinTLSVersion } func defaultConfig(ctx context.Context) byte { configBytes := bytes.Replace(defaultConfigContent, byte("\r "), byte(" "), -1) log.DebugCtx(ctx, "Got builtin default config") return configBytes } func mergeConfigByTemplate(ctx context.Context, c *configType, filepathTemplate string) { logger := zc.LNop(ctx).With(zap.String("config_file", filepathTemplate)) if !hasMeta(filepathTemplate) { mergeConfigByFilepath(ctx, c, filepathTemplate) return } filenames, err := filepath.Glob(filepathTemplate) log.DebugFatal(logger, err, "Expand config file template", zap.String("filepathTemplate", filepathTemplate), zap.Strings("files", filenames)) for _, filename := range filenames { mergeConfigByFilepath(ctx, c, filename) } } func mergeConfigByFilepath(ctx context.Context, c *configType, filename string) { logger := zc.LNop(ctx).With(zap.String("config_file", filename)) if parsedConfigFiles > c.General.MaxConfigFilesRead { logger.Fatal("Exceed max config files read count", zap.Int("MaxConfigFilesRead", c.General.MaxConfigFilesRead)) } parsedConfigFiles++ var err error if !filepath.IsAbs(filename) { var filepathNew string filepathNew, err = filepath.Abs(filename) log.DebugFatal(logger, err, "Convert filepath to absolute", zap.String("old", filename), zap.String("new", filepathNew)) filename = filepathNew } content, err := ioutil.ReadFile(filename) log.DebugFatal(logger, err, "Read filename") dir, err := os.Getwd() log.DebugFatal(logger, err, "Current workdir", zap.String("dir", dir)) fileDir := filepath.Dir(filename) if dir != fileDir { err = os.Chdir(fileDir) log.DebugFatal(logger, err, "Chdir to config filename directory") defer func() { err = os.Chdir(dir) log.DebugFatal(logger, err, "Restore workdir to", zap.String("dir", dir)) }() } mergeConfigBytes(ctx, c, content, filename) } hasMeta reports whether path contains any of the magic characters recognized by Match. |
3 | copy from filepath module func hasMeta(path string) bool { magicChars := '*?' if runtime.GOOS != "windows" { magicChars = '*?\' } return strings.ContainsAny(path, magicChars) } func mergeConfigBytes(ctx context.Context, c *configType, content byte, file string) { for prevent loop by existed included c.General.IncludeConfigs = nil meta, err := toml.Decode(string(content), c) if err == nil && len(meta.Undecoded()) > 0 { err = fmt.Errorf("unknown fields: %v", meta.Undecoded()) } log.InfoFatal(zc.L(ctx), err, "Parse config file", zap.String("config_file", file)) if len(c.General.IncludeConfigs) > 0 { includeConfigs := c.General.IncludeConfigs need save because it will reset while merging for _, file := range includeConfigs { mergeConfigByTemplate(ctx, c, file) } } } package main import ( "ioioutil" "pathfilepath" "strings" "testing" "github.comrekbylets-proxy2internalth" "github.commaxatomego-testdeep" "go.uber.orgzapzapcore" ) func TestParseLogLever(t *testing.T) { td := testdeep.NewT(t) res, err := parseLogLevel("debug") td.CmpNoError(err) td.CmpDeeply(res, zapcore.DebugLevel) res, err = parseLogLevel("info") td.CmpNoError(err) td.CmpDeeply(res, zapcore.InfoLevel) res, err = parseLogLevel("warning") td.CmpNoError(err) td.CmpDeeply(res, zapcore.WarnLevel) res, err = parseLogLevel("error") td.CmpNoError(err) td.CmpDeeply(res, zapcore.ErrorLevel) res, err = parseLogLevel("fatal") td.CmpNoError(err) td.CmpDeeply(res, zapcore.FatalLevel) res, err = parseLogLevel("") td.CmpError(err) td.CmpDeeply(res, zapcore.InfoLevel) } func TestInitLogger(t *testing.T) { e, _, flush := th.NewEnv(t) defer flush() tmpDir := th.TmpDir(e) LogToFile, logLevel logFile := filepath.Join(tmpDir, "log.txt") config := logConfig{ EnableLogToFile: true, File: logFile, LogLevel: "warning", } logger := initLogger(config) testError := "errorTest" testInfo := "infoTest" logger.Error(testError) logger.Info(testInfo) logger.Sync() fileBytes, err := ioutil.ReadFile(logFile) e.CmpNoError(err) e.True(strings.Contains(string(fileBytes), testError)) e.False(strings.Contains(string(fileBytes), testInfo)) DevelMode config = logConfig{DeveloperMode: false, LogLevel: "info", EnableLogToStdErr: true} logger = initLogger(config) logger.DPanic(testError) config = logConfig{DeveloperMode: true, LogLevel: "info"} logger = initLogger(config) e.CmpPanic(func() { logger.DPanic(testError) }, testError) } package main import "flag" var ( configFileP = flag.String("config", "config.toml", "Path to config file. |
4 | Internally expand glob syntax.") debugLog = flag.Bool("debug", false, "Enable debug logging") defaultConfigP = flag.Bool("print-default-config", false, "Write default config to stdout and exit.") versionP = flag.Bool("version", false, "print version and exit") testAcmeServerP = flag.Bool("test-acme-server", false, "Use test acme server, instead address from config") manualAcmeServer = flag.String("acme-server", "", "Override acme server") ) package main import ( "ioioutil" "os" "pathfilepath" "strings" "testing" "github.comrekbylets-proxy2internalth" "github.commaxatomego-testdeep" ) func TestConfigEmbed(t *testing.T) { td := testdeep.NewT(t) sourceConfig, err := ioutil.ReadFile("staticdefault-config.toml") td.CmpNoError(err) force remove file - for prevent box read from disk err = os.Rename("staticdefault-config.toml", "staticdefault-config.toml.tmp") td.CmpNoError(err) defer os.Rename("staticdefault-config.toml.tmp", "staticdefault-config.toml") toUnixString := func(source byte) string { s := string(source) s = strings.Replace(s, "\r ", " ", -1) return s } td.CmpDeeply(toUnixString(defaultConfigContent), toUnixString(sourceConfig)) } func TestReadConfig(t *testing.T) { e, ctx, cancel := th.NewEnv(t) defer cancel() td := testdeep.NewT(t) tmpDir := th.TmpDir(e) _ = ioutil.WriteFile(filepath.Join(tmpDir, "config.toml"), byte(' General IssueTimeout = 1 StorageDir = "storage1" IncludeConfigs = "configs*.toml" '), 0600) _ = os.MkdirAll(filepath.Join(tmpDir, "configs"), 0700) _ = ioutil.WriteFile(filepath.Join(tmpDir, "configsconfig2.toml"), byte(' General StorageDir = "storage2" '), 0600) var config configType mergeConfigBytes(ctx, &config, defaultConfig(ctx), "") mergeConfigByFilepath(ctx, &config, filepath.Join(tmpDir, "config.toml")) td.CmpDeeply(config.General.IssueTimeout, 1) td.CmpDeeply(config.General.StorageDir, "storage2") } func TestGetConfig(t *testing.T) { e, ctx, cancel := th.NewEnv(t) defer cancel() e.NotNil(getConfig(ctx)) } package main import ( "context" "cryptotls" "flag" "fmt" "net" "nethttp" "os" "runtime" "strings" "time" "golang.orgxxerrors" "github.comrekbylets-proxy2internalconfig" "github.comrekbylets-proxy2internalsecrethandler" "github.comprometheusclient_golangprometheus" "github.comrekbylets-proxy2internalmetrics" "go.uber.orgzapzapcore" "github.comrekbylets-proxy2internalcert_manager" "github.comrekbylets-proxy2internalprofiler" _ "github.comkardianosminwinsvc" "github.comrekbylets-proxy2internalacme_client_manager" "github.comrekbylets-proxy2internalcache" "github.comrekbylets-proxy2internallog" "github.comrekbylets-proxy2internalproxy" "github.comrekbylets-proxy2internaltlslistener" zc "github.comrekbyzapcontext" "go.uber.orgzap" ) var VERSION = "custom" need be var because it redefine by --ldflags "-X main.VERSION" during autobuild const defaultDirMode = 0700 func main() { flag.Parse() z, _ := zap.NewProduction() globalContext := zc.WithLogger(context.Background(), z) if *defaultConfigP { fmt.Println(string(defaultConfig(globalContext))) os.Exit(0) } if *versionP { fmt.Println(version()) fmt.Println("Website: https:github.comrekbylets-proxy2") fmt.Println("Developer: timofey@koolin.ru") return } startProgram(getConfig(globalContext)) } func version() string { return fmt.Sprintf("Version: '%v', Os: '%v', Arch: '%v'", VERSION, runtime.GOOS, runtime.GOARCH) } func startMetrics(ctx context.Context, r prometheus.Gatherer, config config.Config, getCertificate func(*tls.ClientHelloInfo) (*tls.Certificate, error)) error { if !config.Enable { return nil } loggerLocal := zc.L(ctx).Named("startMetrics") listener := &tlslistener.ListenersHandler{GetCertificate: getCertificate} err := config.GetListenConfig().Apply(ctx, listener) log.DebugFatal(loggerLocal, err, "Apply listen config") if err != nil { return xerrors.Errorf("apply config settings to metrics listener: %w", err) } err = listener.Start(zc.WithLogger(ctx, zc.L(ctx).Named("metrics_listener")), nil) log.DebugFatal(loggerLocal, err, "start metrics listener") if err != nil { return xerrors.Errorf("start metrics listener: %w", err) } m := metrics.New(zc.L(ctx).Named("metrics"), r) secretMetric := secrethandler.New(zc.L(ctx).Named("metrics_secret"), config.GetSecretHandlerConfig(), m) go func() { defer log.HandlePanic(loggerLocal) err := http.Serve(listener, secretMetric) var effectiveError = err if effectiveError == http.ErrServerClosed { effectiveError = nil } log.DebugDPanic(loggerLocal, effectiveError, "Handle metric stopped") }() return nil } nolint:funlen func startProgram(config *configType) { logger := initLogger(config.Log) ctx := zc.WithLogger(context.Background(), logger) logger.Info("StartAutoRenew program version", zap.String("version", version())) var registry *prometheus.Registry if config.Metrics.Enable { registry = prometheus.NewRegistry() } startProfiler(ctx, config.Profiler) err := os.MkdirAll(config.General.StorageDir, defaultDirMode) log.InfoFatal(logger, err, "Create storage dir", zap.String("dir", config.General.StorageDir)) storage := &cache.DiskCache{Dir: config.General.StorageDir} clientManager := acme_client_manager.New(ctx, storage) clientManager.DirectoryURL = config.General.AcmeServer logger.Info("Acme directory", zap.String("url", config.General.AcmeServer)) _, _, err = clientManager.GetClient(ctx) log.InfoFatal(logger, err, "Get acme client") certManager := cert_manager.New(clientManager, storage, registry) certManager.CertificateIssueTimeout = time.Duration(config.General.IssueTimeout) * time.Second certManager.SaveJSONMeta = config.General.StoreJSONMetadata certManager.AllowECDSACert = config.General.AllowECDSACert certManager.AllowRSACert = config.General.AllowRSACert certManager.AllowInsecureTLSChipers = config.General.AllowInsecureTLSChipers for _, subdomain := range config.General.Subdomains { subdomain = strings.TrimSpace(subdomain) subdomain = strings.TrimSuffix(subdomain, ".") + "." must ends with dot certManager.AutoSubdomains = append(certManager.AutoSubdomains, subdomain) } certManager.DomainChecker, err = config.CheckDomains.CreateDomainChecker(ctx) log.DebugFatal(logger, err, "Config domain checkers.") err = startMetrics(ctx, registry, config.Metrics, certManager.GetCertificate) log.InfoFatalCtx(ctx, err, "start metrics") tlsListener := &tlslistener.ListenersHandler{ GetCertificate: certManager.GetCertificate, } err = config.Listen.Apply(ctx, tlsListener) log.DebugFatal(logger, err, "Config listeners") err = tlsListener.Start(ctx, registry) log.DebugFatal(logger, err, "StartAutoRenew tls listener") config.Proxy.EnableAccessLog = config.Log.EnableAccessLog p := proxy.NewHTTPProxy(ctx, tlsListener) p.GetContext = func(req *http.Request) (i context.Context, e error) { localAddr := req.Context().Value(http.LocalAddrContextKey).(net.Addr) return tlsListener.GetConnectionContext(req.RemoteAddr, localAddr.String()) } err = config.Proxy.Apply(ctx, p) log.InfoFatal(logger, err, "Apply proxy config") go func() { defer log.HandlePanic(logger) <-ctx.Done() err := p.Close() log.DebugError(logger, err, "Stop proxy") }() err = p.Start() var effectiveError = err if effectiveError == http.ErrServerClosed { effectiveError = nil } log.DebugErrorCtx(ctx, effectiveError, "Handle request stopped") } func startProfiler(ctx context.Context, config profiler.Config) { logger := zc.L(ctx) if !config.Enable { logger.Info("Profiler disabled") return } go func() { defer log.HandlePanic(logger) httpServer := http.Server{ Addr: config.BindAddress, Handler: profiler.New(logger.Named("profiler"), config), } logger.Info("Start profiler", zap.String("bind_address", httpServer.Addr)) err := httpServer.ListenAndServe() var logLevel zapcore.Level if err == http.ErrServerClosed { logLevel = zapcore.InfoLevel } else { logLevel = zapcore.ErrorLevel } log.LevelParam(logger, logLevel, "Profiler stopped") }() } package metrics import ( "nethttp" "reflect" "github.comprometheusclient_golangprometheus" "github.comprometheusclient_golangprometheuspromhttp" "go.uber.orgzap" ) type Metrics struct { logger *zap.Logger metricsHandler http.Handler } type ProcessStartFunc func() type ProcessFinishFunc func(error) type loggerError interface { Error(args ...interface{}) } type errorLoggger struct { logger loggerError } func (el errorLoggger) Println(args ...interface{}) { el.logger.Error(args...) } check access and allow if ok func (m *Metrics) ServeHTTP(w http.ResponseWriter, r *http.Request) { m.metricsHandler.ServeHTTP(w, r) } func New(logger *zap.Logger, gatherer prometheus.Gatherer) *Metrics { metrics := Metrics{ logger: logger, metricsHandler: promhttp.HandlerFor(gatherer, promhttp.HandlerOpts{ ErrorLog: errorLoggger{logger: logger.Sugar()}, }), } return &metrics } func ToefCounters(r prometheus.Registerer, name, description string) (start ProcessStartFunc, finish ProcessFinishFunc) { if r == nil reflect.ValueOf(r).IsNil() { return func() {}, func(error) {} } total := prometheus.NewCounter(prometheus.CounterOpts{Name: name, Help: "Total count of " + description}) ok := prometheus.NewCounter(prometheus.CounterOpts{Name: name + "_ok", Help: "Ok count of " + description}) err := prometheus.NewCounter(prometheus.CounterOpts{Name: name + "_err", Help: "Err count of " + description}) inflight := prometheus.NewGauge(prometheus.GaugeOpts{Name: name + "_inflight", Help: "Err count of " + description}) r.MustRegister(total, ok, err, inflight) start = func() { total.Inc() inflight.Inc() } finish = func(error error) { if error == nil { ok.Inc() } else { err.Inc() } inflight.Dec() } return start, finish } package metrics import ( "errors" "nethttp" "nethttphttptest" "testing" "go.uber.orgzap" io_prometheus_client "github.comprometheusclient_modelgo" "github.commaxatomego-testdeep" "github.comprometheusclient_golangprometheus" ) func TestNew(t *testing.T) { td := testdeep.NewT(t) logger := zap.NewNop() gatherer := NewGathererMock(t) defer gatherer.MinimockFinish() gatherer.GatherMock.Set(func() (metrics *io_prometheus_client.MetricFamily, err error) { return nil, nil }) metrics := New(logger, gatherer) td.CmpDeeply(metrics.logger, logger) td.NotNil(metrics.metricsHandler) req, _ := http.NewRequest(http.MethodGet, "", nil) metrics.ServeHTTP(httptest.NewRecorder(), req) } func TestToefCounters(t *testing.T) { td := testdeep.NewT(t) getDesc := func(c prometheus.Collector) string { iDescChan := make(chan *prometheus.Desc, 1) c.Describe(iDescChan) res := (<-iDescChan).String() return res } getCount := func(c prometheus.Collector) int { iMetricChan := make(chan prometheus.Metric, 1) c.Collect(iMetricChan) metric := <-iMetricChan metProto := io_prometheus_client.Metric{} err := metric.Write(&metProto) td.CmpNoError(err) if metProto.Counter != nil { return int(*metProto.Counter.Value) } return int(*metProto.Gauge.Value) } var cntTotal, cntOk, cntErr, cntInFly prometheus.Collector r := NewRegistererMock(t) defer r.MinimockFinish() r.MustRegisterMock.Set(func(args ...prometheus.Collector) { cntTotal, cntOk, cntErr, cntInFly = args0, args1, args2, args3 td.Len(args, 4) for i, arg := range args { td.Contains(getDesc(arg), "asd", i) } td.Contains(getDesc(cntTotal), "test") td.Contains(getDesc(cntOk), "test_ok") td.Contains(getDesc(cntErr), "test_err") td.Contains(getDesc(cntInFly), "test_inflight") }) start, finish := ToefCounters(r, "test", "asd") td.Cmp(getCount(cntTotal), 0) td.Cmp(getCount(cntOk), 0) td.Cmp(getCount(cntErr), 0) td.Cmp(getCount(cntInFly), 0) start() td.Cmp(getCount(cntTotal), 1) td.Cmp(getCount(cntOk), 0) td.Cmp(getCount(cntErr), 0) td.Cmp(getCount(cntInFly), 1) finish(nil) td.Cmp(getCount(cntTotal), 1) td.Cmp(getCount(cntOk), 1) td.Cmp(getCount(cntErr), 0) td.Cmp(getCount(cntInFly), 0) start() td.Cmp(getCount(cntTotal), 2) td.Cmp(getCount(cntOk), 1) td.Cmp(getCount(cntErr), 0) td.Cmp(getCount(cntInFly), 1) finish(errors.New("test")) td.Cmp(getCount(cntTotal), 2) td.Cmp(getCount(cntOk), 1) td.Cmp(getCount(cntErr), 1) td.Cmp(getCount(cntInFly), 0) start, finish = ToefCounters(nil, "qwe", "ddd") start() td.Cmp(getCount(cntTotal), 2) td.Cmp(getCount(cntOk), 1) td.Cmp(getCount(cntErr), 1) td.Cmp(getCount(cntInFly), 0) finish(nil) td.Cmp(getCount(cntTotal), 2) td.Cmp(getCount(cntOk), 1) td.Cmp(getCount(cntErr), 1) td.Cmp(getCount(cntInFly), 0) finish(errors.New("test")) td.Cmp(getCount(cntTotal), 2) td.Cmp(getCount(cntOk), 1) td.Cmp(getCount(cntErr), 1) td.Cmp(getCount(cntInFly), 0) } func TestErrorLoggger_Println(t *testing.T) { loggerMock := NewLoggerErrorMock(t) defer loggerMock.MinimockFinish() loggerMock.ErrorMock.Expect("a", "s", 3).Return() logger := errorLoggger{loggerMock} logger.Println("a", "s", 3) } package metrics Code generated by http:github.comgojunominimock (3.0.6). |
5 | DO NOT EDIT. go:generate minimock -i github.comrekbylets-proxy2internalmetrics.loggerError -o .logger_error_mock_test.go import ( "sync" mm_atomic "syncatomic" mm_time "time" "github.comgojunominimockv3" ) LoggerErrorMock implements loggerError type LoggerErrorMock struct { t minimock.Tester funcError func(args ...interface{}) inspectFuncError func(args ...interface{}) afterErrorCounter uint64 beforeErrorCounter uint64 ErrorMock mLoggerErrorMockError } NewLoggerErrorMock returns a mock for loggerError func NewLoggerErrorMock(t minimock.Tester) *LoggerErrorMock { m := &LoggerErrorMock{t: t} if controller, ok := t.(minimock.MockController); ok { controller.RegisterMocker(m) } m.ErrorMock = mLoggerErrorMockError{mock: m} m.ErrorMock.callArgs = *LoggerErrorMockErrorParams{} return m } type mLoggerErrorMockError struct { mock *LoggerErrorMock defaultExpectation *LoggerErrorMockErrorExpectation expectations *LoggerErrorMockErrorExpectation callArgs *LoggerErrorMockErrorParams mutex sync.RWMutex } LoggerErrorMockErrorExpectation specifies expectation struct of the loggerError.Error type LoggerErrorMockErrorExpectation struct { mock *LoggerErrorMock params *LoggerErrorMockErrorParams Counter uint64 } LoggerErrorMockErrorParams contains parameters of the loggerError.Error type LoggerErrorMockErrorParams struct { args interface{} } Expect sets up expected params for loggerError.Error func (mmError *mLoggerErrorMockError) Expect(args ...interface{}) *mLoggerErrorMockError { if mmError.mock.funcError != nil { mmError.mock.t.Fatalf("LoggerErrorMock.Error mock is already set by Set") } if mmError.defaultExpectation == nil { mmError.defaultExpectation = &LoggerErrorMockErrorExpectation{} } mmError.defaultExpectation.params = &LoggerErrorMockErrorParams{args} for _, e := range mmError.expectations { if minimock.Equal(e.params, mmError.defaultExpectation.params) { mmError.mock.t.Fatalf("Expectation set by When has same params: %#v", *mmError.defaultExpectation.params) } } return mmError } Inspect accepts an inspector function that has same arguments as the loggerError.Error func (mmError *mLoggerErrorMockError) Inspect(f func(args ...interface{})) *mLoggerErrorMockError { if mmError.mock.inspectFuncError != nil { mmError.mock.t.Fatalf("Inspect function is already set for LoggerErrorMock.Error") } mmError.mock.inspectFuncError = f return mmError } Return sets up results that will be returned by loggerError.Error func (mmError *mLoggerErrorMockError) Return() *LoggerErrorMock { if mmError.mock.funcError != nil { mmError.mock.t.Fatalf("LoggerErrorMock.Error mock is already set by Set") } if mmError.defaultExpectation == nil { mmError.defaultExpectation = &LoggerErrorMockErrorExpectation{mock: mmError.mock} } return mmError.mock } Set uses given function f to mock the loggerError.Error method func (mmError *mLoggerErrorMockError) Set(f func(args ...interface{})) *LoggerErrorMock { if mmError.defaultExpectation != nil { mmError.mock.t.Fatalf("Default expectation is already set for the loggerError.Error method") } if len(mmError.expectations) > 0 { mmError.mock.t.Fatalf("Some expectations are already set for the loggerError.Error method") } mmError.mock.funcError = f return mmError.mock } Error implements loggerError func (mmError *LoggerErrorMock) Error(args ...interface{}) { mm_atomic.AddUint64(&mmError.beforeErrorCounter, 1) defer mm_atomic.AddUint64(&mmError.afterErrorCounter, 1) if mmError.inspectFuncError != nil { mmError.inspectFuncError(args...) } mm_params := &LoggerErrorMockErrorParams{args} Record call args mmError.ErrorMock.mutex.Lock() mmError.ErrorMock.callArgs = append(mmError.ErrorMock.callArgs, mm_params) mmError.ErrorMock.mutex.Unlock() for _, e := range mmError.ErrorMock.expectations { if minimock.Equal(e.params, mm_params) { mm_atomic.AddUint64(&e.Counter, 1) return } } if mmError.ErrorMock.defaultExpectation != nil { mm_atomic.AddUint64(&mmError.ErrorMock.defaultExpectation.Counter, 1) mm_want := mmError.ErrorMock.defaultExpectation.params mm_got := LoggerErrorMockErrorParams{args} if mm_want != nil && !minimock.Equal(*mm_want, mm_got) { mmError.t.Errorf("LoggerErrorMock.Error got unexpected parameters, want: %#v, got: %#v%s ", *mm_want, mm_got, minimock.Diff(*mm_want, mm_got)) } return } if mmError.funcError != nil { mmError.funcError(args...) return } mmError.t.Fatalf("Unexpected call to LoggerErrorMock.Error. |
6 | %v", args) } ErrorAfterCounter returns a count of finished LoggerErrorMock.Error invocations func (mmError *LoggerErrorMock) ErrorAfterCounter() uint64 { return mm_atomic.LoadUint64(&mmError.afterErrorCounter) } ErrorBeforeCounter returns a count of LoggerErrorMock.Error invocations func (mmError *LoggerErrorMock) ErrorBeforeCounter() uint64 { return mm_atomic.LoadUint64(&mmError.beforeErrorCounter) } Calls returns a list of arguments used in each call to LoggerErrorMock.Error. |
7 | The list is in the same order as the calls were made (i.e. recent calls have a higher index) func (mmError *mLoggerErrorMockError) Calls() *LoggerErrorMockErrorParams { mmError.mutex.RLock() argCopy := make(*LoggerErrorMockErrorParams, len(mmError.callArgs)) copy(argCopy, mmError.callArgs) mmError.mutex.RUnlock() return argCopy } MinimockErrorDone returns true if the count of the Error invocations corresponds the number of defined expectations func (m *LoggerErrorMock) MinimockErrorDone() bool { for _, e := range m.ErrorMock.expectations { if mm_atomic.LoadUint64(&e.Counter) < 1 { return false } } if default expectation was set then invocations count should be greater than zero if m.ErrorMock.defaultExpectation != nil && mm_atomic.LoadUint64(&m.afterErrorCounter) < 1 { return false } if func was set then invocations count should be greater than zero if m.funcError != nil && mm_atomic.LoadUint64(&m.afterErrorCounter) < 1 { return false } return true } MinimockErrorInspect logs each unmet expectation func (m *LoggerErrorMock) MinimockErrorInspect() { for _, e := range m.ErrorMock.expectations { if mm_atomic.LoadUint64(&e.Counter) < 1 { m.t.Errorf("Expected call to LoggerErrorMock.Error with params: %#v", *e.params) } } if default expectation was set then invocations count should be greater than zero if m.ErrorMock.defaultExpectation != nil && mm_atomic.LoadUint64(&m.afterErrorCounter) < 1 { if m.ErrorMock.defaultExpectation.params == nil { m.t.Error("Expected call to LoggerErrorMock.Error") } else { m.t.Errorf("Expected call to LoggerErrorMock.Error with params: %#v", *m.ErrorMock.defaultExpectation.params) } } if func was set then invocations count should be greater than zero if m.funcError != nil && mm_atomic.LoadUint64(&m.afterErrorCounter) < 1 { m.t.Error("Expected call to LoggerErrorMock.Error") } } MinimockFinish checks that all mocked methods have been called the expected number of times func (m *LoggerErrorMock) MinimockFinish() { if !m.minimockDone() { m.MinimockErrorInspect() m.t.FailNow() } } MinimockWait waits for all mocked methods to be called the expected number of times func (m *LoggerErrorMock) MinimockWait(timeout mm_time.Duration) { timeoutCh := mm_time.After(timeout) for { if m.minimockDone() { return } select { case <-timeoutCh: m.MinimockFinish() return case <-mm_time.After(10 * mm_time.Millisecond): } } } func (m *LoggerErrorMock) minimockDone() bool { done := true return done && m.MinimockErrorDone() } package metrics Code generated by http:github.comgojunominimock (3.0.6). |
8 | DO NOT EDIT. go:generate minimock -i github.comprometheusclient_golangprometheus.Gatherer -o .gatherer_mock_test.go import ( mm_atomic "syncatomic" mm_time "time" "github.comgojunominimockv3" dto "github.comprometheusclient_modelgo" ) GathererMock implements prometheus.Gatherer type GathererMock struct { t minimock.Tester funcGather func() (mpa1 *dto.MetricFamily, err error) inspectFuncGather func() afterGatherCounter uint64 beforeGatherCounter uint64 GatherMock mGathererMockGather } NewGathererMock returns a mock for prometheus.Gatherer func NewGathererMock(t minimock.Tester) *GathererMock { m := &GathererMock{t: t} if controller, ok := t.(minimock.MockController); ok { controller.RegisterMocker(m) } m.GatherMock = mGathererMockGather{mock: m} return m } type mGathererMockGather struct { mock *GathererMock defaultExpectation *GathererMockGatherExpectation expectations *GathererMockGatherExpectation } GathererMockGatherExpectation specifies expectation struct of the Gatherer.Gather type GathererMockGatherExpectation struct { mock *GathererMock results *GathererMockGatherResults Counter uint64 } GathererMockGatherResults contains results of the Gatherer.Gather type GathererMockGatherResults struct { mpa1 *dto.MetricFamily err error } Expect sets up expected params for Gatherer.Gather func (mmGather *mGathererMockGather) Expect() *mGathererMockGather { if mmGather.mock.funcGather != nil { mmGather.mock.t.Fatalf("GathererMock.Gather mock is already set by Set") } if mmGather.defaultExpectation == nil { mmGather.defaultExpectation = &GathererMockGatherExpectation{} } return mmGather } Inspect accepts an inspector function that has same arguments as the Gatherer.Gather func (mmGather *mGathererMockGather) Inspect(f func()) *mGathererMockGather { if mmGather.mock.inspectFuncGather != nil { mmGather.mock.t.Fatalf("Inspect function is already set for GathererMock.Gather") } mmGather.mock.inspectFuncGather = f return mmGather } Return sets up results that will be returned by Gatherer.Gather func (mmGather *mGathererMockGather) Return(mpa1 *dto.MetricFamily, err error) *GathererMock { if mmGather.mock.funcGather != nil { mmGather.mock.t.Fatalf("GathererMock.Gather mock is already set by Set") } if mmGather.defaultExpectation == nil { mmGather.defaultExpectation = &GathererMockGatherExpectation{mock: mmGather.mock} } mmGather.defaultExpectation.results = &GathererMockGatherResults{mpa1, err} return mmGather.mock } Set uses given function f to mock the Gatherer.Gather method func (mmGather *mGathererMockGather) Set(f func() (mpa1 *dto.MetricFamily, err error)) *GathererMock { if mmGather.defaultExpectation != nil { mmGather.mock.t.Fatalf("Default expectation is already set for the Gatherer.Gather method") } if len(mmGather.expectations) > 0 { mmGather.mock.t.Fatalf("Some expectations are already set for the Gatherer.Gather method") } mmGather.mock.funcGather = f return mmGather.mock } Gather implements prometheus.Gatherer func (mmGather *GathererMock) Gather() (mpa1 *dto.MetricFamily, err error) { mm_atomic.AddUint64(&mmGather.beforeGatherCounter, 1) defer mm_atomic.AddUint64(&mmGather.afterGatherCounter, 1) if mmGather.inspectFuncGather != nil { mmGather.inspectFuncGather() } if mmGather.GatherMock.defaultExpectation != nil { mm_atomic.AddUint64(&mmGather.GatherMock.defaultExpectation.Counter, 1) mm_results := mmGather.GatherMock.defaultExpectation.results if mm_results == nil { mmGather.t.Fatal("No results are set for the GathererMock.Gather") } return (*mm_results).mpa1, (*mm_results).err } if mmGather.funcGather != nil { return mmGather.funcGather() } mmGather.t.Fatalf("Unexpected call to GathererMock.Gather.") return } GatherAfterCounter returns a count of finished GathererMock.Gather invocations func (mmGather *GathererMock) GatherAfterCounter() uint64 { return mm_atomic.LoadUint64(&mmGather.afterGatherCounter) } GatherBeforeCounter returns a count of GathererMock.Gather invocations func (mmGather *GathererMock) GatherBeforeCounter() uint64 { return mm_atomic.LoadUint64(&mmGather.beforeGatherCounter) } MinimockGatherDone returns true if the count of the Gather invocations corresponds the number of defined expectations func (m *GathererMock) MinimockGatherDone() bool { for _, e := range m.GatherMock.expectations { if mm_atomic.LoadUint64(&e.Counter) < 1 { return false } } if default expectation was set then invocations count should be greater than zero if m.GatherMock.defaultExpectation != nil && mm_atomic.LoadUint64(&m.afterGatherCounter) < 1 { return false } if func was set then invocations count should be greater than zero if m.funcGather != nil && mm_atomic.LoadUint64(&m.afterGatherCounter) < 1 { return false } return true } MinimockGatherInspect logs each unmet expectation func (m *GathererMock) MinimockGatherInspect() { for _, e := range m.GatherMock.expectations { if mm_atomic.LoadUint64(&e.Counter) < 1 { m.t.Error("Expected call to GathererMock.Gather") } } if default expectation was set then invocations count should be greater than zero if m.GatherMock.defaultExpectation != nil && mm_atomic.LoadUint64(&m.afterGatherCounter) < 1 { m.t.Error("Expected call to GathererMock.Gather") } if func was set then invocations count should be greater than zero if m.funcGather != nil && mm_atomic.LoadUint64(&m.afterGatherCounter) < 1 { m.t.Error("Expected call to GathererMock.Gather") } } MinimockFinish checks that all mocked methods have been called the expected number of times func (m *GathererMock) MinimockFinish() { if !m.minimockDone() { m.MinimockGatherInspect() m.t.FailNow() } } MinimockWait waits for all mocked methods to be called the expected number of times func (m *GathererMock) MinimockWait(timeout mm_time.Duration) { timeoutCh := mm_time.After(timeout) for { if m.minimockDone() { return } select { case <-timeoutCh: m.MinimockFinish() return case <-mm_time.After(10 * mm_time.Millisecond): } } } func (m *GathererMock) minimockDone() bool { done := true return done && m.MinimockGatherDone() } package metrics Code generated by http:github.comgojunominimock (3.0.6). |
9 | DO NOT EDIT. go:generate minimock -i github.comprometheusclient_golangprometheus.Registerer -o .registerer_mock_test.go import ( "sync" mm_atomic "syncatomic" mm_time "time" "github.comgojunominimockv3" mm_prometheus "github.comprometheusclient_golangprometheus" ) RegistererMock implements prometheus.Registerer type RegistererMock struct { t minimock.Tester funcMustRegister func(p1 ...mm_prometheus.Collector) inspectFuncMustRegister func(p1 ...mm_prometheus.Collector) afterMustRegisterCounter uint64 beforeMustRegisterCounter uint64 MustRegisterMock mRegistererMockMustRegister funcRegister func(c1 mm_prometheus.Collector) (err error) inspectFuncRegister func(c1 mm_prometheus.Collector) afterRegisterCounter uint64 beforeRegisterCounter uint64 RegisterMock mRegistererMockRegister funcUnregister func(c1 mm_prometheus.Collector) (b1 bool) inspectFuncUnregister func(c1 mm_prometheus.Collector) afterUnregisterCounter uint64 beforeUnregisterCounter uint64 UnregisterMock mRegistererMockUnregister } NewRegistererMock returns a mock for prometheus.Registerer func NewRegistererMock(t minimock.Tester) *RegistererMock { m := &RegistererMock{t: t} if controller, ok := t.(minimock.MockController); ok { controller.RegisterMocker(m) } m.MustRegisterMock = mRegistererMockMustRegister{mock: m} m.MustRegisterMock.callArgs = *RegistererMockMustRegisterParams{} m.RegisterMock = mRegistererMockRegister{mock: m} m.RegisterMock.callArgs = *RegistererMockRegisterParams{} m.UnregisterMock = mRegistererMockUnregister{mock: m} m.UnregisterMock.callArgs = *RegistererMockUnregisterParams{} return m } type mRegistererMockMustRegister struct { mock *RegistererMock defaultExpectation *RegistererMockMustRegisterExpectation expectations *RegistererMockMustRegisterExpectation callArgs *RegistererMockMustRegisterParams mutex sync.RWMutex } RegistererMockMustRegisterExpectation specifies expectation struct of the Registerer.MustRegister type RegistererMockMustRegisterExpectation struct { mock *RegistererMock params *RegistererMockMustRegisterParams Counter uint64 } RegistererMockMustRegisterParams contains parameters of the Registerer.MustRegister type RegistererMockMustRegisterParams struct { p1 mm_prometheus.Collector } Expect sets up expected params for Registerer.MustRegister func (mmMustRegister *mRegistererMockMustRegister) Expect(p1 ...mm_prometheus.Collector) *mRegistererMockMustRegister { if mmMustRegister.mock.funcMustRegister != nil { mmMustRegister.mock.t.Fatalf("RegistererMock.MustRegister mock is already set by Set") } if mmMustRegister.defaultExpectation == nil { mmMustRegister.defaultExpectation = &RegistererMockMustRegisterExpectation{} } mmMustRegister.defaultExpectation.params = &RegistererMockMustRegisterParams{p1} for _, e := range mmMustRegister.expectations { if minimock.Equal(e.params, mmMustRegister.defaultExpectation.params) { mmMustRegister.mock.t.Fatalf("Expectation set by When has same params: %#v", *mmMustRegister.defaultExpectation.params) } } return mmMustRegister } Inspect accepts an inspector function that has same arguments as the Registerer.MustRegister func (mmMustRegister *mRegistererMockMustRegister) Inspect(f func(p1 ...mm_prometheus.Collector)) *mRegistererMockMustRegister { if mmMustRegister.mock.inspectFuncMustRegister != nil { mmMustRegister.mock.t.Fatalf("Inspect function is already set for RegistererMock.MustRegister") } mmMustRegister.mock.inspectFuncMustRegister = f return mmMustRegister } Return sets up results that will be returned by Registerer.MustRegister func (mmMustRegister *mRegistererMockMustRegister) Return() *RegistererMock { if mmMustRegister.mock.funcMustRegister != nil { mmMustRegister.mock.t.Fatalf("RegistererMock.MustRegister mock is already set by Set") } if mmMustRegister.defaultExpectation == nil { mmMustRegister.defaultExpectation = &RegistererMockMustRegisterExpectation{mock: mmMustRegister.mock} } return mmMustRegister.mock } Set uses given function f to mock the Registerer.MustRegister method func (mmMustRegister *mRegistererMockMustRegister) Set(f func(p1 ...mm_prometheus.Collector)) *RegistererMock { if mmMustRegister.defaultExpectation != nil { mmMustRegister.mock.t.Fatalf("Default expectation is already set for the Registerer.MustRegister method") } if len(mmMustRegister.expectations) > 0 { mmMustRegister.mock.t.Fatalf("Some expectations are already set for the Registerer.MustRegister method") } mmMustRegister.mock.funcMustRegister = f return mmMustRegister.mock } MustRegister implements prometheus.Registerer func (mmMustRegister *RegistererMock) MustRegister(p1 ...mm_prometheus.Collector) { mm_atomic.AddUint64(&mmMustRegister.beforeMustRegisterCounter, 1) defer mm_atomic.AddUint64(&mmMustRegister.afterMustRegisterCounter, 1) if mmMustRegister.inspectFuncMustRegister != nil { mmMustRegister.inspectFuncMustRegister(p1...) } mm_params := &RegistererMockMustRegisterParams{p1} Record call args mmMustRegister.MustRegisterMock.mutex.Lock() mmMustRegister.MustRegisterMock.callArgs = append(mmMustRegister.MustRegisterMock.callArgs, mm_params) mmMustRegister.MustRegisterMock.mutex.Unlock() for _, e := range mmMustRegister.MustRegisterMock.expectations { if minimock.Equal(e.params, mm_params) { mm_atomic.AddUint64(&e.Counter, 1) return } } if mmMustRegister.MustRegisterMock.defaultExpectation != nil { mm_atomic.AddUint64(&mmMustRegister.MustRegisterMock.defaultExpectation.Counter, 1) mm_want := mmMustRegister.MustRegisterMock.defaultExpectation.params mm_got := RegistererMockMustRegisterParams{p1} if mm_want != nil && !minimock.Equal(*mm_want, mm_got) { mmMustRegister.t.Errorf("RegistererMock.MustRegister got unexpected parameters, want: %#v, got: %#v%s ", *mm_want, mm_got, minimock.Diff(*mm_want, mm_got)) } return } if mmMustRegister.funcMustRegister != nil { mmMustRegister.funcMustRegister(p1...) return } mmMustRegister.t.Fatalf("Unexpected call to RegistererMock.MustRegister. |
10 | %v", p1) } MustRegisterAfterCounter returns a count of finished RegistererMock.MustRegister invocations func (mmMustRegister *RegistererMock) MustRegisterAfterCounter() uint64 { return mm_atomic.LoadUint64(&mmMustRegister.afterMustRegisterCounter) } MustRegisterBeforeCounter returns a count of RegistererMock.MustRegister invocations func (mmMustRegister *RegistererMock) MustRegisterBeforeCounter() uint64 { return mm_atomic.LoadUint64(&mmMustRegister.beforeMustRegisterCounter) } Calls returns a list of arguments used in each call to RegistererMock.MustRegister. |
… |
Комментарии