...

Source file src/github.com/urfave/cli/v2/altsrc/yaml_file_loader_test.go

Documentation: github.com/urfave/cli/v2/altsrc

     1  package altsrc_test
     2  
     3  import (
     4  	"errors"
     5  	"fmt"
     6  	"io/ioutil"
     7  	"log"
     8  	"os"
     9  	"testing"
    10  	"time"
    11  
    12  	"github.com/urfave/cli/v2"
    13  	"github.com/urfave/cli/v2/altsrc"
    14  )
    15  
    16  func ExampleApp_Run_yamlFileLoaderDuration() {
    17  	execServe := func(c *cli.Context) error {
    18  		keepaliveInterval := c.Duration("keepalive-interval")
    19  		fmt.Printf("keepalive %s\n", keepaliveInterval)
    20  		return nil
    21  	}
    22  
    23  	fileExists := func(filename string) bool {
    24  		stat, _ := os.Stat(filename)
    25  		return stat != nil
    26  	}
    27  
    28  	// initConfigFileInputSource is like InitInputSourceWithContext and NewYamlSourceFromFlagFunc, but checks
    29  	// if the config flag is exists and only loads it if it does. If the flag is set and the file exists, it fails.
    30  	initConfigFileInputSource := func(configFlag string, flags []cli.Flag) cli.BeforeFunc {
    31  		return func(context *cli.Context) error {
    32  			configFile := context.String(configFlag)
    33  			if context.IsSet(configFlag) && !fileExists(configFile) {
    34  				return fmt.Errorf("config file %s does not exist", configFile)
    35  			} else if !context.IsSet(configFlag) && !fileExists(configFile) {
    36  				return nil
    37  			}
    38  			inputSource, err := altsrc.NewYamlSourceFromFile(configFile)
    39  			if err != nil {
    40  				return err
    41  			}
    42  			return altsrc.ApplyInputSourceValues(context, inputSource, flags)
    43  		}
    44  	}
    45  
    46  	flagsServe := []cli.Flag{
    47  		&cli.StringFlag{
    48  			Name:        "config",
    49  			Aliases:     []string{"c"},
    50  			EnvVars:     []string{"CONFIG_FILE"},
    51  			Value:       "../testdata/empty.yml",
    52  			DefaultText: "../testdata/empty.yml",
    53  			Usage:       "config file",
    54  		},
    55  		altsrc.NewDurationFlag(
    56  			&cli.DurationFlag{
    57  				Name:    "keepalive-interval",
    58  				Aliases: []string{"k"},
    59  				EnvVars: []string{"KEEPALIVE_INTERVAL"},
    60  				Value:   45 * time.Second,
    61  				Usage:   "interval of keepalive messages",
    62  			},
    63  		),
    64  	}
    65  
    66  	cmdServe := &cli.Command{
    67  		Name:      "serve",
    68  		Usage:     "Run the server",
    69  		UsageText: "serve [OPTIONS..]",
    70  		Action:    execServe,
    71  		Flags:     flagsServe,
    72  		Before:    initConfigFileInputSource("config", flagsServe),
    73  	}
    74  
    75  	c := &cli.App{
    76  		Name:                   "cmd",
    77  		HideVersion:            true,
    78  		UseShortOptionHandling: true,
    79  		Commands: []*cli.Command{
    80  			cmdServe,
    81  		},
    82  	}
    83  
    84  	if err := c.Run([]string{"cmd", "serve", "--config", "../testdata/empty.yml"}); err != nil {
    85  		log.Fatal(err)
    86  	}
    87  
    88  	// Output:
    89  	// keepalive 45s
    90  }
    91  
    92  func TestYamlFileInt64Slice(t *testing.T) {
    93  	_ = ioutil.WriteFile("current.yaml", []byte(`top: 
    94    test: [100, 9223372036854775808]`), 0666)
    95  	defer os.Remove("current.yaml")
    96  
    97  	testFlag := []cli.Flag{
    98  		&altsrc.StringFlag{StringFlag: &cli.StringFlag{Name: "conf"}},
    99  		&altsrc.Int64SliceFlag{Int64SliceFlag: &cli.Int64SliceFlag{Name: "top.test"}},
   100  	}
   101  	app := &cli.App{}
   102  	app.Before = altsrc.InitInputSourceWithContext(testFlag, altsrc.NewYamlSourceFromFlagFunc("conf"))
   103  	app.Action = func(c *cli.Context) error { return nil }
   104  	app.Flags = append(app.Flags, testFlag...)
   105  
   106  	test := []string{"testApp", "--conf", "current.yaml"}
   107  	if err := app.Run(test); err == nil {
   108  		t.Error("should return the mismatch error")
   109  	}
   110  }
   111  
   112  func TestYamlFileStringSlice(t *testing.T) {
   113  	_ = ioutil.WriteFile("current.yaml", []byte(`top:
   114    test: ["s1", "s2"]`), 0666)
   115  	defer os.Remove("current.yaml")
   116  
   117  	testFlag := []cli.Flag{
   118  		&altsrc.StringFlag{StringFlag: &cli.StringFlag{Name: "conf"}},
   119  		&altsrc.StringSliceFlag{StringSliceFlag: &cli.StringSliceFlag{Name: "top.test", EnvVars: []string{"THE_TEST"}}},
   120  	}
   121  	app := &cli.App{}
   122  	app.Before = altsrc.InitInputSourceWithContext(testFlag, altsrc.NewYamlSourceFromFlagFunc("conf"))
   123  	app.Action = func(c *cli.Context) error {
   124  		if c.IsSet("top.test") {
   125  			return nil
   126  		} else {
   127  			return errors.New("top.test is not set")
   128  		}
   129  	}
   130  	app.Flags = append(app.Flags, testFlag...)
   131  
   132  	test := []string{"testApp", "--conf", "current.yaml"}
   133  	if err := app.Run(test); err != nil {
   134  		t.Error(err)
   135  	}
   136  }
   137  
   138  func TestYamlFileUint64(t *testing.T) {
   139  	tests := []struct {
   140  		name  string
   141  		entry string
   142  		err   bool
   143  	}{
   144  		{
   145  			"top.test",
   146  			`top: 
   147    test: 100`,
   148  			false,
   149  		},
   150  		{
   151  			"test",
   152  			"test: ",
   153  			false,
   154  		},
   155  		{
   156  			"test",
   157  			"test: 100", //int
   158  			false,
   159  		},
   160  		{
   161  			"test",
   162  			"test: -100", //int
   163  			true,
   164  		},
   165  		{
   166  			"test",
   167  			"test: 9223372036854775807", //int
   168  			false,
   169  		},
   170  		{
   171  			"test",
   172  			"test: 9223372036854775808", //uintt64
   173  			false,
   174  		},
   175  		{
   176  			"test",
   177  			"test: 19223372036854775808", //float64
   178  			true,
   179  		},
   180  	}
   181  
   182  	for i, test := range tests {
   183  		_ = ioutil.WriteFile("current.yaml", []byte(test.entry), 0666)
   184  		defer os.Remove("current.yaml")
   185  
   186  		testFlag := []cli.Flag{
   187  			&altsrc.StringFlag{StringFlag: &cli.StringFlag{Name: "conf"}},
   188  			&altsrc.Uint64Flag{Uint64Flag: &cli.Uint64Flag{Name: test.name}},
   189  		}
   190  		app := &cli.App{}
   191  		app.Flags = append(app.Flags, testFlag...)
   192  		app.Before = altsrc.InitInputSourceWithContext(testFlag, altsrc.NewYamlSourceFromFlagFunc("conf"))
   193  
   194  		appCmd := []string{"testApp", "--conf", "current.yaml"}
   195  		err := app.Run(appCmd)
   196  		if result := err != nil; result != test.err {
   197  			t.Error(i, "testcast: expect error but", err)
   198  		}
   199  	}
   200  }
   201  
   202  func TestYamlFileUint(t *testing.T) {
   203  	tests := []struct {
   204  		name  string
   205  		entry string
   206  		err   bool
   207  	}{
   208  		{
   209  			"top.test",
   210  			`top: 
   211    test: 100`,
   212  			false,
   213  		},
   214  		{
   215  			"test",
   216  			"test: ",
   217  			false,
   218  		},
   219  		{
   220  			"test",
   221  			"test: 100", //int
   222  			false,
   223  		},
   224  		{
   225  			"test",
   226  			"test: -100", //int
   227  			true,
   228  		},
   229  		{
   230  			"test",
   231  			"test: 9223372036854775807", //int
   232  			false,
   233  		},
   234  		{
   235  			"test",
   236  			"test: 9223372036854775808", //uintt64
   237  			false,
   238  		},
   239  		{
   240  			"test",
   241  			"test: 19223372036854775808", //float64
   242  			true,
   243  		},
   244  	}
   245  
   246  	for i, test := range tests {
   247  		_ = ioutil.WriteFile("current.yaml", []byte(test.entry), 0666)
   248  		defer os.Remove("current.yaml")
   249  
   250  		testFlag := []cli.Flag{
   251  			&altsrc.StringFlag{StringFlag: &cli.StringFlag{Name: "conf"}},
   252  			&altsrc.UintFlag{UintFlag: &cli.UintFlag{Name: test.name}},
   253  		}
   254  		app := &cli.App{}
   255  		app.Flags = append(app.Flags, testFlag...)
   256  		app.Before = altsrc.InitInputSourceWithContext(testFlag, altsrc.NewYamlSourceFromFlagFunc("conf"))
   257  
   258  		appCmd := []string{"testApp", "--conf", "current.yaml"}
   259  		err := app.Run(appCmd)
   260  		if result := err != nil; result != test.err {
   261  			t.Error(i, "testcast: expect error but", err)
   262  		}
   263  	}
   264  }
   265  
   266  func TestYamlFileInt64(t *testing.T) {
   267  	tests := []struct {
   268  		name  string
   269  		entry string
   270  		err   bool
   271  	}{
   272  		{
   273  			"top.test",
   274  			`top: 
   275    test: 100`,
   276  			false,
   277  		},
   278  		{
   279  			"test",
   280  			"test: ",
   281  			false,
   282  		},
   283  		{
   284  			"test",
   285  			"test: 100", //int
   286  			false,
   287  		},
   288  		{
   289  			"test",
   290  			"test: -100", //int
   291  			false,
   292  		},
   293  		{
   294  			"test",
   295  			"test: 9223372036854775807", //int
   296  			false,
   297  		},
   298  		{
   299  			"test",
   300  			"test: 9223372036854775808", //uintt64
   301  			true,
   302  		},
   303  		{
   304  			"test",
   305  			"test: 19223372036854775808", //float64
   306  			true,
   307  		},
   308  	}
   309  
   310  	for i, test := range tests {
   311  		_ = ioutil.WriteFile("current.yaml", []byte(test.entry), 0666)
   312  		defer os.Remove("current.yaml")
   313  
   314  		testFlag := []cli.Flag{
   315  			&altsrc.StringFlag{StringFlag: &cli.StringFlag{Name: "conf"}},
   316  			&altsrc.Int64Flag{Int64Flag: &cli.Int64Flag{Name: test.name}},
   317  		}
   318  		app := &cli.App{}
   319  		app.Flags = append(app.Flags, testFlag...)
   320  		app.Before = altsrc.InitInputSourceWithContext(testFlag, altsrc.NewYamlSourceFromFlagFunc("conf"))
   321  
   322  		appCmd := []string{"testApp", "--conf", "current.yaml"}
   323  		err := app.Run(appCmd)
   324  		if result := err != nil; result != test.err {
   325  			t.Error(i, "testcast: expect error but", err)
   326  		}
   327  	}
   328  }
   329  

View as plain text