test(e2e): подключаться по ссылке из production-генератора share URI
Внутри e2e-hysteria.sh жила вторая реализация hysteria2:// URI на bash. Go-юнит-тесты проверяли production-генератор, e2e проверял свою функцию - и дрейф любой из двух реализаций оставлял обе группы тестов зелёными. Фраза "реальный клиент подключается именно по ссылке, которую выдаёт HY2XS" была неточной. Билдер ссылки вынесен в экспортируемую service.BuildHysteria2ShareURI, production-путь Hysteria2Url стал её тонкой обёрткой. Новая тестовая утилита apps/tools/share-uri печатает ссылку тем же кодом; в production-бинарь админки она не входит. Единственное расхождение с пользовательской ссылкой - insecure=1: e2e работает на самоподписанном сертификате. Расхождение ограничено с трёх сторон: - e2e отдельно печатает и проверяет production-вариант ссылки (insecure=0, корректные obfs и sni); - TestBuildHysteria2ShareURI_InsecureDiffersOnlyInThatParam доказывает, что кроме этого параметра ссылки совпадают; - TestBuildHysteria2Url_ProductionPathNeverDisablesVerification фиксирует, что production-путь никогда не передаёт insecure=1. Для запуска e2e теперь нужен Go (GO_BIN).
This commit is contained in:
@@ -165,6 +165,72 @@ func TestBuildHysteria2Url_PlusInCredentialsSurvivesRoundTrip(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
// Инвариант production-пути: проверка сертификата не отключается никогда.
|
||||
// Флаг Insecure существует только для e2e с самоподписанным сертификатом.
|
||||
func TestBuildHysteria2Url_ProductionPathNeverDisablesVerification(t *testing.T) {
|
||||
cases := []bo.ObfsShareConfig{
|
||||
{},
|
||||
{Type: "gecko", Password: "p"},
|
||||
{Type: "salamander", Password: "p"},
|
||||
}
|
||||
|
||||
for _, obfs := range cases {
|
||||
raw := buildHysteria2Url("pass", "vpn.example.com", 443, obfs, "vpn.example.com", "remark")
|
||||
if got := mustParse(t, raw).Query().Get("insecure"); got != "0" {
|
||||
t.Fatalf("production share URI must carry insecure=0, got %q (raw=%s)", got, raw)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// e2e использует production-генератор, поэтому единственное расхождение с
|
||||
// пользовательской ссылкой обязано быть ровно одним параметром.
|
||||
func TestBuildHysteria2ShareURI_InsecureDiffersOnlyInThatParam(t *testing.T) {
|
||||
opts := shareOptionsFixture()
|
||||
|
||||
production := BuildHysteria2ShareURI(opts)
|
||||
opts.Insecure = true
|
||||
relaxed := BuildHysteria2ShareURI(opts)
|
||||
|
||||
productionURL := mustParse(t, production)
|
||||
testURL := mustParse(t, relaxed)
|
||||
|
||||
if productionURL.Host != testURL.Host || productionURL.Path != testURL.Path {
|
||||
t.Fatalf("host/path must not depend on the insecure flag: %s vs %s", production, relaxed)
|
||||
}
|
||||
if productionURL.User.String() != testURL.User.String() {
|
||||
t.Fatalf("userinfo must not depend on the insecure flag")
|
||||
}
|
||||
if productionURL.Fragment != testURL.Fragment {
|
||||
t.Fatalf("remark must not depend on the insecure flag")
|
||||
}
|
||||
|
||||
productionQuery := productionURL.Query()
|
||||
testQuery := testURL.Query()
|
||||
|
||||
if productionQuery.Get("insecure") != "0" || testQuery.Get("insecure") != "1" {
|
||||
t.Fatalf("unexpected insecure values: %q / %q",
|
||||
productionQuery.Get("insecure"), testQuery.Get("insecure"))
|
||||
}
|
||||
|
||||
productionQuery.Del("insecure")
|
||||
testQuery.Del("insecure")
|
||||
if productionQuery.Encode() != testQuery.Encode() {
|
||||
t.Fatalf("only the insecure param may differ:\n %s\n %s",
|
||||
productionQuery.Encode(), testQuery.Encode())
|
||||
}
|
||||
}
|
||||
|
||||
func shareOptionsFixture() ShareURIOptions {
|
||||
return ShareURIOptions{
|
||||
Secret: "peer-secret",
|
||||
Host: "vpn.example.com",
|
||||
Port: 443,
|
||||
Obfs: bo.ObfsShareConfig{Type: "gecko", Password: "gecko-secret"},
|
||||
SNI: "vpn.example.com",
|
||||
Remark: "HY2XS",
|
||||
}
|
||||
}
|
||||
|
||||
func TestResolveShareSni(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
|
||||
Reference in New Issue
Block a user