14 changed files with 132 additions and 23 deletions
@ -0,0 +1,28 @@ |
|||
package mock |
|||
|
|||
import ( |
|||
"testing" |
|||
|
|||
"tera-clone/services/tera-api/internal/domain" |
|||
) |
|||
|
|||
func TestPortListenerConflictsAreScopedToOperationInterface(t *testing.T) { |
|||
ssh := domain.PortOperation{Mode: "reverse_ssh", Port: 10001} |
|||
telnet := domain.PortOperation{Mode: "reverse_telnet", Port: 10001} |
|||
for _, test := range []struct { |
|||
name string |
|||
configs map[string]portConfig |
|||
conflict bool |
|||
}{ |
|||
{"same channel different interfaces", map[string]portConfig{"CH01": {Operation1: ssh, Operation2: telnet}}, false}, |
|||
{"different channels same eth0", map[string]portConfig{"CH01": {Operation1: ssh}, "CH02": {Operation1: telnet}}, true}, |
|||
{"different channels same eth1", map[string]portConfig{"CH01": {Operation2: ssh}, "CH02": {Operation2: telnet}}, true}, |
|||
{"different channels different interfaces", map[string]portConfig{"CH01": {Operation1: ssh}, "CH02": {Operation2: telnet}}, false}, |
|||
} { |
|||
t.Run(test.name, func(t *testing.T) { |
|||
if err := validatePortOperationConflicts(test.configs); (err != nil) != test.conflict { |
|||
t.Fatalf("conflict=%v, error=%v", test.conflict, err) |
|||
} |
|||
}) |
|||
} |
|||
} |
|||
@ -0,0 +1,40 @@ |
|||
package api |
|||
|
|||
import ( |
|||
"net/http" |
|||
"path/filepath" |
|||
"testing" |
|||
|
|||
"tera-clone/services/tera-api/internal/adapters/mock" |
|||
"tera-clone/services/tera-api/internal/domain" |
|||
) |
|||
|
|||
func TestOperationTwoTelnetCanBeStagedAppliedSavedAndReloadedBesideSSH(t *testing.T) { |
|||
path := filepath.Join(t.TempDir(), "config.json") |
|||
store, err := mock.NewStoreWithConfigFile(fixedClock, path) |
|||
if err != nil { |
|||
t.Fatal(err) |
|||
} |
|||
handler := NewRouter(store) |
|||
// Use the same separate PATCH + apply requests sent by the two UI tabs.
|
|||
getJSONAs(t, handler, http.MethodPatch, "/api/v1/ports/CH01", `{"operation_1":{"mode":"reverse_ssh","port":10001,"max_clients":2,"authentication":"local","newline":"cr"}}`, "mock-admin") |
|||
getJSONAs(t, handler, http.MethodPost, "/api/v1/config/apply", "", "mock-admin") |
|||
getJSONAs(t, handler, http.MethodPatch, "/api/v1/ports/CH01", `{"operation_2":{"mode":"reverse_telnet","port":10001,"max_clients":4,"authentication":"local","newline":"cr"}}`, "mock-admin") |
|||
getJSONAs(t, handler, http.MethodPost, "/api/v1/config/apply", "", "mock-admin") |
|||
assertDualOperation(t, getPort(t, handler, "CH01")) |
|||
getJSONAs(t, handler, http.MethodPost, "/api/v1/config/save", "", "mock-admin") |
|||
reloaded, err := mock.NewStoreWithConfigFile(fixedClock, path) |
|||
if err != nil { |
|||
t.Fatal(err) |
|||
} |
|||
assertDualOperation(t, getPort(t, NewRouter(reloaded), "CH01")) |
|||
} |
|||
|
|||
func assertDualOperation(t *testing.T, port domain.Port) { |
|||
t.Helper() |
|||
if port.Operation1.Mode != "reverse_ssh" || port.Operation2.Mode != "reverse_telnet" || |
|||
port.Operation1.Port != 10001 || port.Operation2.Port != 10001 || |
|||
port.Operation1.MaxClients != 2 || port.Operation2.MaxClients != 2 { |
|||
t.Fatalf("CH01 operations not preserved: op1=%+v op2=%+v", port.Operation1, port.Operation2) |
|||
} |
|||
} |
|||
Binary file not shown.
Binary file not shown.
Loading…
Reference in new issue