github.com/henvic/wedeploycli@v1.7.6-0.20200319005353-3630f582f284/logs/logs_test.go (about)

     1  package logs
     2  
     3  import (
     4  	"bytes"
     5  	"context"
     6  	"flag"
     7  	"fmt"
     8  	"net/http"
     9  	"os"
    10  	"sync"
    11  	"testing"
    12  	"time"
    13  
    14  	"github.com/henvic/wedeploy-sdk-go/jsonlib"
    15  	"github.com/henvic/wedeploycli/color"
    16  	"github.com/henvic/wedeploycli/config"
    17  	"github.com/henvic/wedeploycli/defaults"
    18  	"github.com/henvic/wedeploycli/servertest"
    19  	"github.com/henvic/wedeploycli/stringlib"
    20  	"github.com/henvic/wedeploycli/tdata"
    21  )
    22  
    23  var update bool
    24  
    25  func init() {
    26  	flag.BoolVar(&update, "update", false, "update golden files")
    27  	setAnywhereOnEarthTimezone()
    28  }
    29  
    30  func setAnywhereOnEarthTimezone() {
    31  	timezone := "Etc/GMT-12"
    32  	l, err := time.LoadLocation(timezone)
    33  
    34  	if err != nil {
    35  		panic(err)
    36  	}
    37  
    38  	time.Local = l
    39  
    40  	if err := os.Setenv("TZ", timezone); err != nil {
    41  		panic(err)
    42  	}
    43  }
    44  
    45  var wectx config.Context
    46  
    47  func TestMain(m *testing.M) {
    48  	time.Local = time.UTC
    49  
    50  	var err error
    51  	wectx, err = config.Setup("mocks/.lcp")
    52  
    53  	if err != nil {
    54  		panic(err)
    55  	}
    56  
    57  	if err := wectx.SetEndpoint(defaults.CloudRemote); err != nil {
    58  		panic(err)
    59  	}
    60  
    61  	ec := m.Run()
    62  	os.Exit(ec)
    63  }
    64  
    65  var (
    66  	bufOutStream bytes.Buffer
    67  )
    68  
    69  func TestGetList(t *testing.T) {
    70  	servertest.Setup()
    71  
    72  	servertest.Mux.HandleFunc("/projects/foo/logs",
    73  		func(w http.ResponseWriter, r *http.Request) {
    74  			if r.URL.Query().Get("serviceId") != "nodejs5143" {
    75  				t.Errorf("Wrong value for serviceId")
    76  			}
    77  
    78  			if r.URL.Query().Get("level") != "INFO" {
    79  				t.Errorf("Wrong value for level")
    80  			}
    81  
    82  			w.Header().Set("Content-Type", "application/json; charset=UTF-8")
    83  			_, _ = fmt.Fprint(w, tdata.FromFile("mocks/logs_response.json"))
    84  		})
    85  
    86  	var filter = &Filter{
    87  		Project:  "foo",
    88  		Services: []string{"nodejs5143"},
    89  		Instance: "foo_nodejs5143_sqimupf5tfsf9iylzpg3e4zj",
    90  		Level:    "INFO",
    91  	}
    92  
    93  	var list, err = New(wectx).GetList(context.Background(), filter)
    94  
    95  	if err != nil {
    96  		t.Errorf("Unexpected error %v on GetList", err)
    97  	}
    98  
    99  	jsonlib.AssertJSONMarshal(t, tdata.FromFile("mocks/logs_response_ref.json"), list)
   100  
   101  	servertest.Teardown()
   102  }
   103  
   104  func TestList(t *testing.T) {
   105  	outStreamMutex.Lock()
   106  	var defaultOutStream = outStream
   107  	outStream = &bufOutStream
   108  	bufOutStream.Reset()
   109  	outStreamMutex.Unlock()
   110  
   111  	var defaultNoColor = color.NoColor
   112  	color.NoColor = true
   113  
   114  	servertest.Setup()
   115  
   116  	servertest.Mux.HandleFunc("/projects/foo/logs",
   117  		tdata.ServerJSONFileHandler("mocks/logs_response.json"))
   118  
   119  	var filter = &Filter{
   120  		Level:    "INFO",
   121  		Project:  "foo",
   122  		Services: []string{"nodejs5143"},
   123  		Instance: "foo_nodejs5143_sqimupf5tfsf9iylzpg3e4zj",
   124  	}
   125  
   126  	var err = New(wectx).List(context.Background(), filter)
   127  
   128  	if err != nil {
   129  		t.Errorf("Unexpected error %v", err)
   130  	}
   131  
   132  	outStreamMutex.Lock()
   133  	var got = bufOutStream.String()
   134  	outStreamMutex.Unlock()
   135  
   136  	if update {
   137  		tdata.ToFile("mocks/logs_response_print", got)
   138  	}
   139  
   140  	var want = tdata.FromFile("mocks/logs_response_print")
   141  
   142  	stringlib.AssertSimilar(t, want, got)
   143  
   144  	color.NoColor = defaultNoColor
   145  	outStreamMutex.Lock()
   146  	outStream = defaultOutStream
   147  	outStreamMutex.Unlock()
   148  
   149  	servertest.Teardown()
   150  }
   151  
   152  func TestListProject(t *testing.T) {
   153  	outStreamMutex.Lock()
   154  	var defaultOutStream = outStream
   155  	outStream = &bufOutStream
   156  	bufOutStream.Reset()
   157  	outStreamMutex.Unlock()
   158  
   159  	var defaultNoColor = color.NoColor
   160  	color.NoColor = true
   161  
   162  	servertest.Setup()
   163  
   164  	servertest.Mux.HandleFunc("/projects/foo/logs",
   165  		tdata.ServerJSONFileHandler("mocks/logs_response_project.json"))
   166  
   167  	var filter = &Filter{
   168  		Level:   "INFO",
   169  		Project: "foo",
   170  	}
   171  
   172  	var err = New(wectx).List(context.Background(), filter)
   173  
   174  	if err != nil {
   175  		t.Errorf("Unexpected error %v", err)
   176  	}
   177  
   178  	outStreamMutex.Lock()
   179  	var got = bufOutStream.String()
   180  	outStreamMutex.Unlock()
   181  
   182  	if update {
   183  		tdata.ToFile("mocks/logs_response_project_print", got)
   184  	}
   185  
   186  	var want = tdata.FromFile("mocks/logs_response_project_print")
   187  
   188  	stringlib.AssertSimilar(t, want, got)
   189  
   190  	color.NoColor = defaultNoColor
   191  	outStreamMutex.Lock()
   192  	outStream = defaultOutStream
   193  	outStreamMutex.Unlock()
   194  
   195  	servertest.Teardown()
   196  }
   197  
   198  func TestWatch(t *testing.T) {
   199  	outStreamMutex.Lock()
   200  	var defaultOutStream = outStream
   201  	outStream = &bufOutStream
   202  	bufOutStream.Reset()
   203  	outStreamMutex.Unlock()
   204  
   205  	var defaultNoColor = color.NoColor
   206  	color.NoColor = true
   207  
   208  	servertest.Setup()
   209  
   210  	var missing = true
   211  
   212  	servertest.Mux.HandleFunc("/projects/foo/logs",
   213  		func(w http.ResponseWriter, r *http.Request) {
   214  			if r.URL.Query().Get("serviceId") != "bar" {
   215  				t.Errorf("Wrong value for serviceId")
   216  			}
   217  
   218  			w.Header().Set("Content-Type", "application/json; charset=UTF-8")
   219  			switch missing {
   220  			case true:
   221  				_, _ = fmt.Fprintln(w, tdata.FromFile("mocks/logs_watch_response_syscall.json"))
   222  				missing = false
   223  			default:
   224  				_, _ = fmt.Fprintln(w, "[]")
   225  			}
   226  		})
   227  
   228  	var w = &Watcher{
   229  		Filter: &Filter{
   230  			Project:  "foo",
   231  			Services: []string{"bar"},
   232  			Level:    "INFO",
   233  		},
   234  		PoolingInterval: time.Millisecond,
   235  	}
   236  
   237  	var wg sync.WaitGroup
   238  
   239  	wg.Add(1)
   240  
   241  	var ctx, cancel = context.WithCancel(context.Background())
   242  	defer cancel()
   243  
   244  	go func() {
   245  		time.Sleep(20 * time.Millisecond)
   246  		cancel()
   247  		time.Sleep(20 * time.Millisecond)
   248  		wg.Done()
   249  	}()
   250  
   251  	w.Watch(ctx, wectx)
   252  
   253  	wg.Wait()
   254  
   255  	outStreamMutex.Lock()
   256  	var got = bufOutStream.String()
   257  	outStreamMutex.Unlock()
   258  
   259  	if update {
   260  		tdata.ToFile("mocks/logs_watch_syscall", got)
   261  	}
   262  
   263  	var want = tdata.FromFile("mocks/logs_watch_syscall")
   264  
   265  	stringlib.AssertSimilar(t, want, got)
   266  
   267  	// some time before cleaning up services on other goroutines...
   268  	time.Sleep(10 * time.Millisecond)
   269  	color.NoColor = defaultNoColor
   270  	outStreamMutex.Lock()
   271  	outStream = defaultOutStream
   272  	outStreamMutex.Unlock()
   273  	servertest.Teardown()
   274  }
   275  
   276  func TestWatcherStart(t *testing.T) {
   277  	outStreamMutex.Lock()
   278  	var defaultOutStream = outStream
   279  	outStream = &bufOutStream
   280  	bufOutStream.Reset()
   281  	outStreamMutex.Unlock()
   282  
   283  	var defaultNoColor = color.NoColor
   284  	color.NoColor = true
   285  
   286  	servertest.Setup()
   287  
   288  	var file = 0
   289  	var fileM sync.Mutex
   290  
   291  	servertest.Mux.HandleFunc("/projects/foo/logs",
   292  		func(w http.ResponseWriter, r *http.Request) {
   293  			if r.URL.Query().Get("serviceId") != "bar" {
   294  				t.Errorf("Wrong value for serviceId")
   295  			}
   296  
   297  			fileM.Lock()
   298  			defer fileM.Unlock()
   299  
   300  			w.Header().Set("Content-Type", "application/json; charset=UTF-8")
   301  
   302  			if file < 4 {
   303  				file++
   304  				log := fmt.Sprintf("%s%d%s", "mocks/logs_watch_response_", file, ".json")
   305  				_, _ = fmt.Fprintln(w, tdata.FromFile(log))
   306  			} else {
   307  				_, _ = fmt.Fprintln(w, "[]")
   308  			}
   309  		})
   310  
   311  	var w = &Watcher{
   312  		Filter: &Filter{
   313  			Project:  "foo",
   314  			Services: []string{"bar"},
   315  			Instance: "foo_nodejs5143_sqimupf5tfsf9iylzpg3e4zj",
   316  			Level:    "INFO",
   317  		},
   318  		PoolingInterval: 2 * time.Millisecond,
   319  	}
   320  
   321  	var wg sync.WaitGroup
   322  
   323  	wg.Add(1)
   324  
   325  	var ctx, cancel = context.WithCancel(context.Background())
   326  	defer cancel()
   327  
   328  	go func() {
   329  		// this sleep has to be slightly greater than pooling * requests
   330  		time.Sleep(60 * time.Millisecond)
   331  		cancel()
   332  		wg.Done()
   333  	}()
   334  
   335  	w.Watch(ctx, wectx)
   336  
   337  	wg.Wait()
   338  
   339  	outStreamMutex.Lock()
   340  	var got = bufOutStream.String()
   341  	outStreamMutex.Unlock()
   342  
   343  	if update {
   344  		tdata.ToFile("mocks/logs_watch", got)
   345  	}
   346  
   347  	var want = tdata.FromFile("mocks/logs_watch")
   348  
   349  	stringlib.AssertSimilar(t, want, got)
   350  
   351  	// some time before cleaning up services on other goroutines...
   352  	time.Sleep(10 * time.Millisecond)
   353  
   354  	color.NoColor = defaultNoColor
   355  
   356  	outStreamMutex.Lock()
   357  	outStream = defaultOutStream
   358  	outStreamMutex.Unlock()
   359  	servertest.Teardown()
   360  }
   361  
   362  func TestGetUnixTimestamp(t *testing.T) {
   363  	var want int64 = 1470422556
   364  	var got, err = GetUnixTimestamp("1470422556")
   365  
   366  	if err != nil {
   367  		t.Errorf("Wanted error to be nil, got %v instead", err)
   368  	}
   369  
   370  	if want != got {
   371  		t.Errorf("Expected numeric Unix timestamp return same numeric value")
   372  	}
   373  }
   374  
   375  func TestGetUnixTimestampSame(t *testing.T) {
   376  	var current = time.Now().Unix()
   377  	var got, err = GetUnixTimestamp("60m60s")
   378  	var diff int64 = 3660
   379  
   380  	if err != nil {
   381  		t.Errorf("Wanted error to be nil, got %v instead", err)
   382  	}
   383  
   384  	// give some room for error, since it runs time.Now() again
   385  	var delay = got - current + diff
   386  
   387  	if delay < 0 || delay > 2 {
   388  		t.Errorf("Wanted GetUnixTimestamp %v returned value not between expected boundaries", delay)
   389  	}
   390  }
   391  
   392  func TestGetUnixTimestampSameMin(t *testing.T) {
   393  	var current = time.Now().Unix()
   394  	var got, err = GetUnixTimestamp("1h30min30s")
   395  	var diff int64 = 5430
   396  
   397  	if err != nil {
   398  		t.Errorf("Wanted error to be nil, got %v instead", err)
   399  	}
   400  
   401  	// give some room for error, since it runs time.Now() again
   402  	var delay = got - current + diff
   403  
   404  	if delay < 0 || delay > 2 {
   405  		t.Errorf("Wanted GetUnixTimestamp %v returned value not between expected boundaries", delay)
   406  	}
   407  }
   408  
   409  func TestGetUnixTimestampParseError(t *testing.T) {
   410  	var _, err = GetUnixTimestamp("dog")
   411  
   412  	if err == nil {
   413  		t.Errorf("Wanted parsing error, got %v instead", err)
   414  	}
   415  }