github.com/yandex/pandora@v0.5.32/core/import/import_test.go (about)

     1  package coreimport
     2  
     3  import (
     4  	"context"
     5  	"os"
     6  	"testing"
     7  	"time"
     8  
     9  	"github.com/spf13/afero"
    10  	"github.com/stretchr/testify/assert"
    11  	"github.com/stretchr/testify/require"
    12  	"github.com/yandex/pandora/core"
    13  	"github.com/yandex/pandora/core/config"
    14  	"github.com/yandex/pandora/core/coretest"
    15  	"github.com/yandex/pandora/core/plugin"
    16  	"github.com/yandex/pandora/lib/testutil"
    17  	"go.uber.org/zap"
    18  )
    19  
    20  func Test_PluginConfig(t *testing.T) {
    21  	defer resetGlobals()
    22  	Import(afero.NewOsFs())
    23  
    24  	t.Run("composite schedule", func(t *testing.T) {
    25  		input := func() map[string]interface{} {
    26  			return map[string]interface{}{
    27  				"schedule": []map[string]interface{}{
    28  					{"type": "once", "times": 1},
    29  					{"type": "const", "ops": 1, "duration": "1s"},
    30  				},
    31  			}
    32  		}
    33  
    34  		t.Run("plugin", func(t *testing.T) {
    35  			var conf struct {
    36  				Schedule core.Schedule
    37  			}
    38  			err := config.Decode(input(), &conf)
    39  			assert.NoError(t, err)
    40  			coretest.ExpectScheduleNextsT(t, conf.Schedule, 0, 0, time.Second)
    41  		})
    42  
    43  		t.Run("plugin factory", func(t *testing.T) {
    44  			var conf struct {
    45  				Schedule func() (core.Schedule, error)
    46  			}
    47  			err := config.Decode(input(), &conf)
    48  			assert.NoError(t, err)
    49  			sched, err := conf.Schedule()
    50  			assert.NoError(t, err)
    51  			coretest.ExpectScheduleNextsT(t, sched, 0, 0, time.Second)
    52  		})
    53  	})
    54  }
    55  
    56  func TestSink(t *testing.T) {
    57  	defer resetGlobals()
    58  	fs := afero.NewMemMapFs()
    59  	const filename = "/xxx"
    60  	Import(fs)
    61  
    62  	tests := []struct {
    63  		name  string
    64  		input map[string]interface{}
    65  	}{
    66  		{"hooked", testConfig(
    67  			"stdout", "stdout",
    68  			"stderr", "stderr",
    69  			"file", filename,
    70  		)},
    71  		{"explicit", testConfig(
    72  			"stdout", testConfig("type", "stdout"),
    73  			"stderr", testConfig("type", "stderr"),
    74  			"file", testConfig(
    75  				"type", "file",
    76  				"path", filename,
    77  			),
    78  		)},
    79  	}
    80  	for _, test := range tests {
    81  		t.Run(test.name, func(t *testing.T) {
    82  			var conf struct {
    83  				Stdout func() core.DataSink
    84  				Stderr func() core.DataSink
    85  				File   core.DataSink
    86  			}
    87  			err := config.Decode(test.input, &conf)
    88  			require.NoError(t, err)
    89  			coretest.AssertSinkEqualStdStream(t, &os.Stdout, conf.Stdout)
    90  			coretest.AssertSinkEqualStdStream(t, &os.Stderr, conf.Stderr)
    91  			coretest.AssertSinkEqualFile(t, fs, filename, conf.File)
    92  		})
    93  	}
    94  }
    95  
    96  func TestProviderJSONLine(t *testing.T) {
    97  	testutil.ReplaceGlobalLogger()
    98  	defer resetGlobals()
    99  	fs := afero.NewMemMapFs()
   100  	const filename = "/xxx"
   101  	Import(fs)
   102  	input := testConfig(
   103  		"aggregator", testConfig(
   104  			"type", "jsonlines",
   105  			"sink", filename,
   106  		),
   107  	)
   108  
   109  	var conf struct {
   110  		Aggregator core.Aggregator
   111  	}
   112  	err := config.Decode(input, &conf)
   113  	require.NoError(t, err)
   114  
   115  	conf.Aggregator.Report([]int{0, 1, 2})
   116  	ctx, cancel := context.WithCancel(context.Background())
   117  	cancel()
   118  	err = conf.Aggregator.Run(ctx, core.AggregatorDeps{Log: zap.L()})
   119  	require.NoError(t, err)
   120  
   121  	testutil.AssertFileEqual(t, fs, filename, "[0,1,2]\n")
   122  }
   123  
   124  // TODO(skipor): test datasources
   125  
   126  func testConfig(keyValuePairs ...interface{}) map[string]interface{} {
   127  	if len(keyValuePairs)%2 != 0 {
   128  		panic("invalid len")
   129  	}
   130  	result := map[string]interface{}{}
   131  	for i := 0; i < len(keyValuePairs); i += 2 {
   132  		key := keyValuePairs[i].(string)
   133  		value := keyValuePairs[i+1]
   134  		result[key] = value
   135  	}
   136  	return result
   137  }
   138  
   139  func resetGlobals() {
   140  	plugin.SetDefaultRegistry(plugin.NewRegistry())
   141  	config.SetHooks(config.DefaultHooks())
   142  	testutil.ReplaceGlobalLogger()
   143  }