github.com/Jeffail/benthos/v3@v3.65.0/lib/api/dynamic_crud_test.go (about)

     1  package api
     2  
     3  import (
     4  	"bytes"
     5  	"errors"
     6  	"net/http"
     7  	"net/http/httptest"
     8  	"reflect"
     9  	"strings"
    10  	"testing"
    11  
    12  	"github.com/gorilla/mux"
    13  )
    14  
    15  //------------------------------------------------------------------------------
    16  
    17  func TestDynamicConfMgr(t *testing.T) {
    18  	hasher := newDynamicConfMgr()
    19  	hasher.Remove("foo")
    20  
    21  	if hasher.Matches("foo", []byte("test")) {
    22  		t.Error("matched hash on non-existing id")
    23  	}
    24  
    25  	if !hasher.Set("foo", []byte("test")) {
    26  		t.Error("Collision on new id")
    27  	}
    28  
    29  	if !hasher.Matches("foo", []byte("test")) {
    30  		t.Error("Non-matched on same content")
    31  	}
    32  
    33  	if hasher.Matches("foo", []byte("test 2")) {
    34  		t.Error("Matched on different content")
    35  	}
    36  
    37  	if hasher.Set("foo", []byte("test")) {
    38  		t.Error("Non-collision on existing id")
    39  	}
    40  
    41  	if !hasher.Set("foo", []byte("test 2")) {
    42  		t.Error("Collision on new content")
    43  	}
    44  
    45  	if !hasher.Matches("foo", []byte("test 2")) {
    46  		t.Error("Non-matched on same content")
    47  	}
    48  
    49  	if hasher.Matches("foo", []byte("test")) {
    50  		t.Error("Matched on different content")
    51  	}
    52  
    53  	if hasher.Set("foo", []byte("test 2")) {
    54  		t.Error("Non-collision on existing content")
    55  	}
    56  }
    57  
    58  //------------------------------------------------------------------------------
    59  
    60  func router(dAPI *Dynamic) *mux.Router {
    61  	router := mux.NewRouter()
    62  	router.HandleFunc("/inputs", dAPI.HandleList)
    63  	router.HandleFunc("/input/{id}", dAPI.HandleCRUD)
    64  	return router
    65  }
    66  
    67  func TestDynamicCRUDBadReqs(t *testing.T) {
    68  	dAPI := NewDynamic()
    69  	r := router(dAPI)
    70  
    71  	request, _ := http.NewRequest("DERP", "/input/foo", http.NoBody)
    72  	response := httptest.NewRecorder()
    73  	r.ServeHTTP(response, request)
    74  	if exp, act := http.StatusBadGateway, response.Code; exp != act {
    75  		t.Errorf("Unexpected response code: %v != %v", act, exp)
    76  	}
    77  }
    78  
    79  func TestDynamicDelete(t *testing.T) {
    80  	dAPI := NewDynamic()
    81  	r := router(dAPI)
    82  
    83  	expRemoved := []string{}
    84  	removed := []string{}
    85  	failRemove := true
    86  
    87  	dAPI.OnDelete(func(id string) error {
    88  		if failRemove {
    89  			return errors.New("foo err")
    90  		}
    91  		removed = append(removed, id)
    92  		return nil
    93  	})
    94  	dAPI.OnUpdate(func(id string, content []byte) error {
    95  		t.Error("Unexpected update called")
    96  		return nil
    97  	})
    98  
    99  	request, _ := http.NewRequest("DELETE", "/input/foo", http.NoBody)
   100  	response := httptest.NewRecorder()
   101  	r.ServeHTTP(response, request)
   102  	if exp, act := http.StatusBadGateway, response.Code; exp != act {
   103  		t.Errorf("Unexpected response code: %v != %v", act, exp)
   104  	}
   105  	if exp, act := expRemoved, removed; !reflect.DeepEqual(exp, act) {
   106  		t.Errorf("Wrong collection of removed configs: %v != %v", act, exp)
   107  	}
   108  
   109  	failRemove = false
   110  	expRemoved = append(expRemoved, "foo")
   111  	request, _ = http.NewRequest("DELETE", "/input/foo", http.NoBody)
   112  	response = httptest.NewRecorder()
   113  	r.ServeHTTP(response, request)
   114  	if exp, act := http.StatusOK, response.Code; exp != act {
   115  		t.Errorf("Unexpected response code: %v != %v", act, exp)
   116  	}
   117  	if exp, act := expRemoved, removed; !reflect.DeepEqual(exp, act) {
   118  		t.Errorf("Wrong collection of removed configs: %v != %v", act, exp)
   119  	}
   120  }
   121  
   122  func TestDynamicBasicCRUD(t *testing.T) {
   123  	dAPI := NewDynamic()
   124  	r := router(dAPI)
   125  
   126  	deleteExp := ""
   127  	var deleteErr error
   128  	dAPI.OnDelete(func(id string) error {
   129  		if exp, act := deleteExp, id; exp != act {
   130  			t.Errorf("Wrong content on delete: %v != %v", act, exp)
   131  		}
   132  		return deleteErr
   133  	})
   134  
   135  	updateExp := []byte("hello world")
   136  	var updateErr error
   137  	dAPI.OnUpdate(func(id string, content []byte) error {
   138  		if exp, act := updateExp, content; !reflect.DeepEqual(exp, act) {
   139  			t.Errorf("Wrong content on update: %s != %s", act, exp)
   140  		}
   141  		return updateErr
   142  	})
   143  
   144  	request, _ := http.NewRequest("GET", "/input/foo", http.NoBody)
   145  	response := httptest.NewRecorder()
   146  	r.ServeHTTP(response, request)
   147  	if exp, act := http.StatusNotFound, response.Code; exp != act {
   148  		t.Errorf("Unexpected response code: %v != %v", act, exp)
   149  	}
   150  
   151  	request, _ = http.NewRequest("POST", "/input/foo", bytes.NewReader([]byte("hello world")))
   152  	response = httptest.NewRecorder()
   153  	r.ServeHTTP(response, request)
   154  	if exp, act := http.StatusOK, response.Code; exp != act {
   155  		t.Errorf("Unexpected response code: %v != %v", act, exp)
   156  	}
   157  
   158  	dAPI.Started("foo", []byte("foo bar"))
   159  
   160  	request, _ = http.NewRequest("GET", "/input/foo", http.NoBody)
   161  	response = httptest.NewRecorder()
   162  	r.ServeHTTP(response, request)
   163  	if exp, act := http.StatusOK, response.Code; exp != act {
   164  		t.Errorf("Unexpected response code: %v != %v", act, exp)
   165  	}
   166  	if exp, act := []byte("foo bar"), response.Body.Bytes(); !reflect.DeepEqual(exp, act) {
   167  		t.Errorf("Wrong content on GET: %s != %s", act, exp)
   168  	}
   169  
   170  	updateErr = errors.New("this shouldnt happen")
   171  	request, _ = http.NewRequest("POST", "/input/foo", bytes.NewReader([]byte("hello world")))
   172  	response = httptest.NewRecorder()
   173  	r.ServeHTTP(response, request)
   174  	if exp, act := http.StatusOK, response.Code; exp != act {
   175  		t.Errorf("Unexpected response code: %v != %v", act, exp)
   176  	}
   177  
   178  	request, _ = http.NewRequest("GET", "/input/foo", http.NoBody)
   179  	response = httptest.NewRecorder()
   180  	r.ServeHTTP(response, request)
   181  	if exp, act := http.StatusOK, response.Code; exp != act {
   182  		t.Errorf("Unexpected response code: %v != %v", act, exp)
   183  	}
   184  	if exp, act := []byte("foo bar"), response.Body.Bytes(); !reflect.DeepEqual(exp, act) {
   185  		t.Errorf("Wrong content on GET: %s != %s", act, exp)
   186  	}
   187  }
   188  
   189  func TestDynamicListing(t *testing.T) {
   190  	dAPI := NewDynamic()
   191  	r := router(dAPI)
   192  
   193  	dAPI.OnDelete(func(id string) error {
   194  		return nil
   195  	})
   196  
   197  	dAPI.OnUpdate(func(id string, content []byte) error {
   198  		return nil
   199  	})
   200  
   201  	dAPI.Started("bar", []byte(`{"test":"sanitised"}`))
   202  
   203  	request, _ := http.NewRequest("POST", "/input/foo", bytes.NewReader([]byte(`{"test":"from crud raw"}`)))
   204  	response := httptest.NewRecorder()
   205  	r.ServeHTTP(response, request)
   206  	if exp, act := http.StatusOK, response.Code; exp != act {
   207  		t.Errorf("Unexpected response code: %v != %v", act, exp)
   208  	}
   209  
   210  	dAPI.Started("foo", []byte(`{"test":"second sanitised"}`))
   211  
   212  	request, _ = http.NewRequest("GET", "/inputs", http.NoBody)
   213  	response = httptest.NewRecorder()
   214  	r.ServeHTTP(response, request)
   215  	if exp, act := http.StatusOK, response.Code; exp != act {
   216  		t.Errorf("Unexpected response code: %v != %v", act, exp)
   217  	}
   218  
   219  	expSections := []string{
   220  		`{"bar":{"uptime":"`,
   221  		`","config":{"test":"sanitised"}},"foo":{"uptime":"`,
   222  		`","config":{"test":"second sanitised"}}}`,
   223  	}
   224  	res := response.Body.String()
   225  	for _, exp := range expSections {
   226  		if !strings.Contains(res, exp) {
   227  			t.Errorf("Response does not contain substr: %v > %v", res, exp)
   228  		}
   229  	}
   230  
   231  	dAPI.Stopped("foo")
   232  
   233  	request, _ = http.NewRequest("DELETE", "/input/bar", http.NoBody)
   234  	response = httptest.NewRecorder()
   235  	r.ServeHTTP(response, request)
   236  	if exp, act := http.StatusOK, response.Code; exp != act {
   237  		t.Errorf("Unexpected response code: %v != %v", act, exp)
   238  	}
   239  
   240  	dAPI.Stopped("bar")
   241  
   242  	request, _ = http.NewRequest("GET", "/inputs", http.NoBody)
   243  	response = httptest.NewRecorder()
   244  	r.ServeHTTP(response, request)
   245  	if exp, act := http.StatusOK, response.Code; exp != act {
   246  		t.Errorf("Unexpected response code: %v != %v", act, exp)
   247  	}
   248  	if exp, act := []byte(`{"foo":{"uptime":"stopped","config":{"test":"second sanitised"}}}`), response.Body.Bytes(); !reflect.DeepEqual(exp, act) {
   249  		t.Errorf("Wrong content on GET list: %s != %s", act, exp)
   250  	}
   251  }
   252  
   253  //------------------------------------------------------------------------------