Ctrl K
ComunidadGuías…

tests/admin_delete_tunnels_test.go

Rama master · réplica de lectura del repositorio original.

Archivo original ↗Preguntar a KiBot
package main

import (
	"context"
	"net/http"
	"testing"
	"time"

	"github.com/shellhub-io/shellhub/pkg/models"
	"github.com/shellhub-io/shellhub/tests/environment"
	"github.com/stretchr/testify/assert"
	"github.com/stretchr/testify/require"
)

// TestAdminDeletesCloseTunnels deletes, as an instance administrator, a namespace whose device is
// online, either directly or with the user who owns it, and reads the server's count of tunnels
// closed because their device was removed. The enterprise admin API deletes in the process that
// holds the tunnel, which counts the eviction before the delete answers. The community admin CLI
// runs apart from that process, so its deletion reaches the tunnel on the device's next heartbeat.
func TestAdminDeletesCloseTunnels(t *testing.T) {
	t.Parallel()

	const evictedTunnels = "shellhub_ssh_dialer_connections_evicted_total"

	cases := []struct {
		description string
		edition     environment.Edition
		delete      func(t *testing.T, compose *environment.DockerCompose, admin *models.UserAuthResponse)
		onHeartbeat bool
	}{
		{
			description: "deleting the namespace through the admin API",
			edition:     environment.EditionEnterprise,
			delete: func(t *testing.T, compose *environment.DockerCompose, admin *models.UserAuthResponse) {
				t.Helper()

				resp, err := asBearer(t, compose, admin.Token).Delete("/admin/api/namespaces/" + ShellHubNamespace)
				require.NoError(t, err)
				require.Equal(t, http.StatusOK, resp.StatusCode(), resp.String())
			},
		},
		{
			description: "deleting its owner through the admin API",
			edition:     environment.EditionEnterprise,
			delete: func(t *testing.T, compose *environment.DockerCompose, admin *models.UserAuthResponse) {
				t.Helper()

				owner := compose.AuthUser(t, ShellHubUsername, ShellHubPassword)

				resp, err := asBearer(t, compose, admin.Token).Delete("/admin/api/users/" + owner.ID)
				require.NoError(t, err)
				require.Equal(t, http.StatusOK, resp.StatusCode(), resp.String())
			},
		},
		{
			description: "deleting its owner through the admin CLI",
			edition:     environment.EditionCommunity,
			delete: func(t *testing.T, compose *environment.DockerCompose, _ *models.UserAuthResponse) {
				t.Helper()

				compose.DeleteUser(t, ShellHubUsername)
			},
			onHeartbeat: true,
		},
	}

	for _, tc := range cases {
		t.Run(tc.description, func(t *testing.T) {
			compose, admin := newAdministeredTunnelEnvironment(t, t.Context(), tc.edition)

			startAcceptedAgent(t, t.Context(), compose)

			evicted, err := compose.ServerMetric(t, evictedTunnels)
			require.NoError(t, err)
			require.Zero(t, evicted)

			tc.delete(t, compose, admin)

			if tc.onHeartbeat {
				require.EventuallyWithT(t, func(tt *assert.CollectT) {
					evicted, err := compose.ServerMetric(t, evictedTunnels)
					if !assert.NoError(tt, err) {
						return
					}

					assert.InDelta(tt, 1, evicted, 0)
				}, tunnelBeatTimeout, time.Second)
			} else {
				evicted, err := compose.ServerMetric(t, evictedTunnels)
				require.NoError(t, err)
				assert.InDelta(t, 1, evicted, 0)
			}
		})
	}
}

func newAdministeredTunnelEnvironment(t *testing.T, ctx context.Context, edition environment.Edition) (*environment.DockerCompose, *models.UserAuthResponse) {
	t.Helper()

	compose := environment.New(t, run).
		WithEdition(edition).
		WithEnv("SHELLHUB_TUNNEL_PING_INTERVAL", fastTunnelPingInterval.String()).
		Up(ctx)
	t.Cleanup(compose.Down)

	const adminUsername = "root"
	compose.NewUser(t, adminUsername, "root@ossystems.com.br", ShellHubPassword)
	admin := compose.AuthUser(t, adminUsername, ShellHubPassword)
	require.True(t, admin.Admin, "the first user is the instance's administrator")

	compose.NewUser(t, ShellHubUsername, ShellHubEmail, ShellHubPassword)
	ownNamespace(t, ctx, compose, legacyNamespace)

	return compose, admin
}