github.com/avenga/couper@v1.12.2/definitions/job_test.go (about)

     1  package definitions_test
     2  
     3  import (
     4  	"context"
     5  	"net/http"
     6  	"reflect"
     7  	"strings"
     8  	"testing"
     9  	"time"
    10  
    11  	"github.com/avenga/couper/config"
    12  	"github.com/avenga/couper/definitions"
    13  	"github.com/avenga/couper/eval"
    14  	"github.com/avenga/couper/internal/test"
    15  )
    16  
    17  func TestJob_Run(t *testing.T) {
    18  	type fields struct {
    19  		conf    *config.Job
    20  		handler http.Handler
    21  	}
    22  
    23  	logger, hook := test.NewLogger()
    24  
    25  	const subTestKey = "subTest"
    26  	getST := func(r *http.Request) *testing.T {
    27  		return eval.ContextFromRequest(r).Value(subTestKey).(*testing.T)
    28  	}
    29  
    30  	tests := []struct {
    31  		name    string
    32  		fields  fields
    33  		expErr  string
    34  		expLogs int
    35  		waitFor time.Duration
    36  	}{
    37  		{"job with interval", fields{
    38  			conf: &config.Job{Name: "testCase1", IntervalDuration: time.Millisecond * 200},
    39  			handler: http.HandlerFunc(func(rw http.ResponseWriter, r *http.Request) {
    40  				if !strings.HasPrefix(r.Header.Get("User-Agent"), "Couper") {
    41  					getST(r).Error("expected trigger req with Couper UA")
    42  				}
    43  			}),
    44  		}, "", 2, time.Millisecond * 300}, // two due to initial req
    45  		{"job with small interval", fields{
    46  			conf: &config.Job{Name: "testCase2", IntervalDuration: time.Millisecond * 100},
    47  			handler: http.HandlerFunc(func(rw http.ResponseWriter, r *http.Request) {
    48  				if !strings.HasPrefix(r.Header.Get("User-Agent"), "Couper") {
    49  					getST(r).Error("expected trigger req with Couper UA")
    50  				}
    51  			}),
    52  		}, "", 5, time.Millisecond * 480}, // five due to initial req
    53  		{"job with greater interval", fields{
    54  			conf:    &config.Job{Name: "testCase3", IntervalDuration: time.Second},
    55  			handler: http.HandlerFunc(func(rw http.ResponseWriter, r *http.Request) {}),
    56  		}, "", 2, time.Millisecond * 1100}, // two due to initial req
    57  		{"job with greater origin delay than interval", fields{
    58  			conf: &config.Job{Name: "testCase4", IntervalDuration: time.Millisecond * 1500},
    59  			handler: http.HandlerFunc(func(rw http.ResponseWriter, r *http.Request) {
    60  				time.Sleep(time.Second)
    61  			}),
    62  		}, "", 2, time.Second * 3}, // initial req + one (hit at 2.5s)
    63  	}
    64  	for _, tt := range tests {
    65  		t.Run(tt.name, func(st *testing.T) {
    66  			j := definitions.NewJob(tt.fields.conf, tt.fields.handler, config.NewDefaultSettings())
    67  
    68  			ctx, cancel := context.WithCancel(context.Background())
    69  			defer cancel()
    70  			ctx = context.WithValue(ctx, subTestKey, st)
    71  			ctx = eval.NewDefaultContext().WithContext(ctx)
    72  
    73  			hook.Reset()
    74  
    75  			go j.Run(ctx, logger.WithContext(ctx))
    76  
    77  			// 50ms are the initial ticker delay
    78  			time.Sleep(tt.waitFor + (time.Millisecond * 50))
    79  
    80  			logEntries := hook.AllEntries()
    81  			var cnt int
    82  			for _, entry := range logEntries {
    83  				msg, _ := entry.String()
    84  				if strings.Contains(msg, "context canceled") {
    85  					continue
    86  				}
    87  				cnt++
    88  
    89  				if !reflect.DeepEqual(entry.Data["name"], tt.fields.conf.Name) {
    90  					st.Error("expected the job name in log fields")
    91  				}
    92  
    93  				if uid, _ := entry.Data["uid"].(string); uid == "" {
    94  					st.Error("expected an uid log field")
    95  				}
    96  
    97  				defer func() {
    98  					if st.Failed() {
    99  						st.Log(msg)
   100  					}
   101  				}()
   102  			}
   103  
   104  			if cnt != tt.expLogs {
   105  				st.Errorf("expected %d log entries, got: %d", tt.expLogs, len(logEntries))
   106  			}
   107  		})
   108  	}
   109  }