1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
|
// Copyright Epic Games, Inc. All Rights Reserved.
#if ZEN_WITH_TESTS && ZEN_WITH_NOMAD
# include "zenserver-test.h"
# include <zencore/filesystem.h>
# include <zencore/logging.h>
# include <zencore/testing.h>
# include <zencore/timer.h>
# include <zenhttp/httpclient.h>
# include <zennomad/nomadclient.h>
# include <zennomad/nomadprocess.h>
# include <zenutil/zenserverprocess.h>
# include <fmt/format.h>
namespace zen::tests::nomad_tests {
using namespace std::literals;
TEST_CASE("nomad.client.lifecycle" * doctest::skip())
{
zen::nomad::NomadProcess NomadProc;
NomadProc.SpawnNomadAgent();
zen::nomad::NomadTestClient Client("http://localhost:4646/");
// Submit a simple batch job that sleeps briefly
# if ZEN_PLATFORM_WINDOWS
auto Job = Client.SubmitJob("zen-test-job", "cmd.exe", {"/C", "timeout /t 10 /nobreak"});
# else
auto Job = Client.SubmitJob("zen-test-job", "/bin/sleep", {"10"});
# endif
REQUIRE(!Job.Id.empty());
CHECK_EQ(Job.Status, "pending");
// Poll until the job is running (or dead)
{
Stopwatch Timer;
bool FoundRunning = false;
while (Timer.GetElapsedTimeMs() < 15000)
{
auto Status = Client.GetJobStatus("zen-test-job");
if (Status.Status == "running")
{
FoundRunning = true;
break;
}
if (Status.Status == "dead")
{
break;
}
Sleep(500);
}
CHECK(FoundRunning);
}
// Verify allocations exist
auto Allocs = Client.GetAllocations("zen-test-job");
CHECK(!Allocs.empty());
// Stop the job
Client.StopJob("zen-test-job");
// Verify it reaches dead state
{
Stopwatch Timer;
bool FoundDead = false;
while (Timer.GetElapsedTimeMs() < 10000)
{
auto Status = Client.GetJobStatus("zen-test-job");
if (Status.Status == "dead")
{
FoundDead = true;
break;
}
Sleep(500);
}
CHECK(FoundDead);
}
NomadProc.StopNomadAgent();
}
TEST_CASE("nomad.provisioner.integration" * doctest::skip())
{
zen::nomad::NomadProcess NomadProc;
NomadProc.SpawnNomadAgent();
// Spawn zenserver in compute mode with Nomad provisioning enabled
ZenServerInstance Instance(TestEnv, ZenServerInstance::ServerMode::kComputeServer);
Instance.SetDataDir(TestEnv.CreateNewTestDir());
std::filesystem::path ZenServerPath = TestEnv.ProgramBaseDir() / "zenserver" ZEN_EXE_SUFFIX_LITERAL;
std::string NomadArgs = fmt::format(
"--nomad-enabled=true"
" --nomad-server=http://localhost:4646"
" --nomad-driver=raw_exec"
" --nomad-binary-path={}"
" --nomad-max-cores=32"
" --nomad-cores-per-job=32",
ZenServerPath.string());
const uint16_t Port = Instance.SpawnServerAndWaitUntilReady(NomadArgs);
REQUIRE(Port != 0);
// Give the provisioner time to submit jobs.
// The management thread has a 5s wait between cycles, and the HTTP client has
// a 10s connect timeout, so we need to allow enough time for at least one full cycle.
Sleep(15000);
// Verify jobs were submitted to Nomad
zen::nomad::NomadTestClient NomadClient("http://localhost:4646/");
auto Jobs = NomadClient.ListJobs("zenserver-worker");
ZEN_INFO("nomad.provisioner.integration: found {} jobs with prefix 'zenserver-worker'", Jobs.size());
CHECK_MESSAGE(!Jobs.empty(), Instance.GetLogOutput());
Instance.Shutdown();
NomadProc.StopNomadAgent();
}
} // namespace zen::tests::nomad_tests
#endif
|