github.com/m3db/m3@v1.5.0/src/x/config/hostid/hostid_test.go (about)

     1  // Copyright (c) 2017 Uber Technologies, Inc.
     2  //
     3  // Permission is hereby granted, free of charge, to any person obtaining a copy
     4  // of this software and associated documentation files (the "Software"), to deal
     5  // in the Software without restriction, including without limitation the rights
     6  // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
     7  // copies of the Software, and to permit persons to whom the Software is
     8  // furnished to do so, subject to the following conditions:
     9  //
    10  // The above copyright notice and this permission notice shall be included in
    11  // all copies or substantial portions of the Software.
    12  //
    13  // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
    14  // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
    15  // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
    16  // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
    17  // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
    18  // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
    19  // THE SOFTWARE.
    20  
    21  package hostid
    22  
    23  import (
    24  	"fmt"
    25  	"io/ioutil"
    26  	"os"
    27  	"strconv"
    28  	"strings"
    29  	"testing"
    30  	"time"
    31  
    32  	"github.com/stretchr/testify/assert"
    33  	"github.com/stretchr/testify/require"
    34  )
    35  
    36  func TestHostnameResolver(t *testing.T) {
    37  	cfg := Configuration{
    38  		Resolver: "hostname",
    39  	}
    40  
    41  	value, err := cfg.Resolve()
    42  	require.NoError(t, err)
    43  
    44  	expected, err := os.Hostname()
    45  	require.NoError(t, err)
    46  
    47  	assert.Equal(t, expected, value)
    48  }
    49  
    50  func TestHostnameResolverWithFormat(t *testing.T) {
    51  	cfg := Configuration{
    52  		Resolver: "hostname",
    53  		Hostname: &HostnameConfig{
    54  			Format: `{"name":"{{.Hostname}}"}`,
    55  		},
    56  	}
    57  
    58  	value, err := cfg.Resolve()
    59  	require.NoError(t, err)
    60  
    61  	expected, err := os.Hostname()
    62  	require.NoError(t, err)
    63  
    64  	expected = fmt.Sprintf("{\"name\":\"%s\"}", expected)
    65  	assert.Equal(t, expected, value)
    66  }
    67  
    68  func TestConfigResolver(t *testing.T) {
    69  	expected := "foo"
    70  
    71  	cfg := Configuration{
    72  		Resolver: "config",
    73  		Value:    &expected,
    74  	}
    75  
    76  	value, err := cfg.Resolve()
    77  	require.NoError(t, err)
    78  
    79  	assert.Equal(t, expected, value)
    80  }
    81  
    82  func TestConfigResolverErrorWhenMissing(t *testing.T) {
    83  	cfg := Configuration{
    84  		Resolver: "config",
    85  	}
    86  
    87  	_, err := cfg.Resolve()
    88  	require.Error(t, err)
    89  }
    90  
    91  func TestEnvironmentVariableResolver(t *testing.T) {
    92  	varName := "HOST_ENV_NAME_" + strconv.Itoa(int(time.Now().UnixNano()))
    93  	expected := "foo"
    94  
    95  	require.NoError(t, os.Setenv(varName, expected))
    96  
    97  	cfg := Configuration{
    98  		Resolver:   "environment",
    99  		EnvVarName: &varName,
   100  	}
   101  
   102  	value, err := cfg.Resolve()
   103  	require.NoError(t, err)
   104  
   105  	assert.Equal(t, expected, value)
   106  }
   107  
   108  func TestEnvironmentResolverErrorWhenNameMissing(t *testing.T) {
   109  	cfg := Configuration{
   110  		Resolver: "environment",
   111  	}
   112  
   113  	_, err := cfg.Resolve()
   114  	require.Error(t, err)
   115  }
   116  
   117  func TestEnvironmentResolverErrorWhenValueMissing(t *testing.T) {
   118  	varName := "HOST_ENV_NAME_" + strconv.Itoa(int(time.Now().UnixNano()))
   119  
   120  	cfg := Configuration{
   121  		Resolver:   "environment",
   122  		EnvVarName: &varName,
   123  	}
   124  
   125  	_, err := cfg.Resolve()
   126  	require.Error(t, err)
   127  }
   128  
   129  func TestFileResolver(t *testing.T) {
   130  	cfg := Configuration{
   131  		Resolver: "file",
   132  		File: &FileConfig{
   133  			Path: "foobarbaz",
   134  		},
   135  	}
   136  
   137  	_, err := cfg.Resolve()
   138  	assert.Error(t, err)
   139  	assert.True(t, strings.Contains(err.Error(), "no such file"), "expected error to be due to file not found")
   140  }
   141  
   142  func TestUnknownResolverError(t *testing.T) {
   143  	cfg := Configuration{
   144  		Resolver: "some-unknown-type",
   145  	}
   146  
   147  	_, err := cfg.Resolve()
   148  	require.Error(t, err)
   149  }
   150  
   151  func TestFileConfig(t *testing.T) {
   152  	c := &file{
   153  		path: "foobarpath",
   154  	}
   155  
   156  	_, err := c.ID()
   157  	assert.Error(t, err)
   158  
   159  	f, err := ioutil.TempFile("", "hostid-test")
   160  	require.NoError(t, err)
   161  
   162  	defer os.Remove(f.Name())
   163  
   164  	_, err = f.WriteString("testidentity")
   165  	require.NoError(t, err)
   166  
   167  	c = &file{
   168  		path: f.Name(),
   169  	}
   170  
   171  	v, err := c.ID()
   172  	assert.NoError(t, err)
   173  	assert.Equal(t, "testidentity", v)
   174  }
   175  
   176  func TestFileConfig_Timeout(t *testing.T) {
   177  	f, err := ioutil.TempFile("", "hostid-test")
   178  	require.NoError(t, err)
   179  
   180  	defer os.Remove(f.Name())
   181  
   182  	timeout := time.Minute
   183  	c := &file{
   184  		path:     f.Name(),
   185  		interval: 10 * time.Millisecond,
   186  		timeout:  &timeout,
   187  	}
   188  
   189  	valC := make(chan string)
   190  
   191  	go func() {
   192  		v, err := c.ID()
   193  		if err == nil {
   194  			valC <- v
   195  			close(valC)
   196  		}
   197  	}()
   198  
   199  	time.Sleep(time.Second)
   200  	_, err = f.WriteString("testidentity")
   201  	require.NoError(t, err)
   202  
   203  	select {
   204  	case v := <-valC:
   205  		assert.Equal(t, "testidentity", v)
   206  	case <-time.After(5 * time.Second):
   207  		t.Fatal("expected to see value within 5s")
   208  	}
   209  }
   210  
   211  func TestFileConfig_TimeoutErr(t *testing.T) {
   212  	f, err := ioutil.TempFile("", "hostid-test")
   213  	require.NoError(t, err)
   214  
   215  	defer os.Remove(f.Name())
   216  
   217  	timeout := time.Second
   218  	c := &file{
   219  		path:     f.Name(),
   220  		interval: 10 * time.Millisecond,
   221  		timeout:  &timeout,
   222  	}
   223  
   224  	_, err = c.ID()
   225  	assert.Error(t, err)
   226  	assert.True(t, strings.Contains(err.Error(), "within 1s"))
   227  }