mirror of
https://gitlab.eurecom.fr/oai/openairinterface5g.git
synced 2026-07-13 12:40:28 +00:00
Compare commits
622 Commits
bugfix-ldp
...
e2ap_integ
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
878b3c3857 | ||
|
|
e2de6719ee | ||
|
|
e69feb9384 | ||
|
|
65abd4b55b | ||
|
|
0583c5411a | ||
|
|
2e0a39816e | ||
|
|
d060ae2008 | ||
|
|
95ba33d955 | ||
|
|
3e5e7abaab | ||
|
|
76216713db | ||
|
|
f10ca57b77 | ||
|
|
8e8c6a7da3 | ||
|
|
155761417d | ||
|
|
1324d151ea | ||
|
|
b385f1778c | ||
|
|
d4ff3e8fb7 | ||
|
|
28010c223c | ||
|
|
b3fd97bb99 | ||
|
|
89108aa716 | ||
|
|
781f85e35d | ||
|
|
e3a96bbeef | ||
|
|
d370df812a | ||
|
|
98f4d038d4 | ||
|
|
daa1a911ac | ||
|
|
486ae6e7bd | ||
|
|
1679cf38ba | ||
|
|
bdfec26d82 | ||
|
|
19d3014150 | ||
|
|
733c7e5e89 | ||
|
|
5b35523c2c | ||
|
|
ebd70a3915 | ||
|
|
3cf3a42b44 | ||
|
|
6fb10cd5fa | ||
|
|
a6862df7aa | ||
|
|
a0a92f4581 | ||
|
|
f4dc362247 | ||
|
|
778c88d8a9 | ||
|
|
ad598a2d5d | ||
|
|
ca010654bf | ||
|
|
1923bed4a3 | ||
|
|
9142357069 | ||
|
|
a3c13fdc71 | ||
|
|
bf844247bf | ||
|
|
7eb2e99dcd | ||
|
|
26909e7c32 | ||
|
|
0a4e28688b | ||
|
|
22db2d613f | ||
|
|
33c09b7776 | ||
|
|
af8b3b0486 | ||
|
|
5403198996 | ||
|
|
1f6d111f6a | ||
|
|
2bfe9ba229 | ||
|
|
c8a61331ea | ||
|
|
0004626ac7 | ||
|
|
9e4d522937 | ||
|
|
e45a051c80 | ||
|
|
5c6778be0c | ||
|
|
7d23ec27b5 | ||
|
|
f1841639f5 | ||
|
|
a03864ee8c | ||
|
|
f3be849904 | ||
|
|
1d9a4a42e7 | ||
|
|
15c12caa37 | ||
|
|
5c333cca65 | ||
|
|
1f97969675 | ||
|
|
06c0979b90 | ||
|
|
51fe9b84dd | ||
|
|
5268dbf3f8 | ||
|
|
ca6ae2c486 | ||
|
|
8c1aeb4ab9 | ||
|
|
7a52279078 | ||
|
|
c4a9f0ea03 | ||
|
|
a6149386dc | ||
|
|
25b3aaf230 | ||
|
|
06436655ff | ||
|
|
0631c04fba | ||
|
|
8e6554bdf3 | ||
|
|
7fb242d33e | ||
|
|
03862de437 | ||
|
|
ca3a7c612b | ||
|
|
8ca640337a | ||
|
|
a29e59b602 | ||
|
|
e4143ded39 | ||
|
|
b69fb5bd74 | ||
|
|
d1fc95a8a1 | ||
|
|
ed1d009381 | ||
|
|
99d5e50b6a | ||
|
|
1ac428a323 | ||
|
|
50bf571347 | ||
|
|
15adb12b71 | ||
|
|
bd42a4259f | ||
|
|
cf8dff2093 | ||
|
|
670fcc0459 | ||
|
|
81d44c6422 | ||
|
|
889a50072f | ||
|
|
1880ede547 | ||
|
|
40c06fa8d5 | ||
|
|
a6486909ca | ||
|
|
4700dde2ae | ||
|
|
a0318fb413 | ||
|
|
09ea970b34 | ||
|
|
77e61425e0 | ||
|
|
4642a7c0f5 | ||
|
|
6e01a62838 | ||
|
|
e35401efde | ||
|
|
223fd28bb2 | ||
|
|
528025e9a6 | ||
|
|
d4da44f1d3 | ||
|
|
0de51bcd93 | ||
|
|
6529d875d8 | ||
|
|
ffebe2498d | ||
|
|
0f43c2c713 | ||
|
|
c405ad16a8 | ||
|
|
2ac2a7f074 | ||
|
|
a458a251a0 | ||
|
|
47ea8d79a2 | ||
|
|
d664190f9d | ||
|
|
0d66410317 | ||
|
|
12ccca72b6 | ||
|
|
6e93619896 | ||
|
|
779748579c | ||
|
|
f3126586f3 | ||
|
|
48d19391e2 | ||
|
|
7c9b501310 | ||
|
|
b58ad4baf0 | ||
|
|
dcdf057dc8 | ||
|
|
342ea0882d | ||
|
|
60d7fe6347 | ||
|
|
8fd0ad58b2 | ||
|
|
9eac725441 | ||
|
|
8e9f9b5629 | ||
|
|
e5954f2dbf | ||
|
|
96f21a1ccb | ||
|
|
7e29f16d53 | ||
|
|
9074566869 | ||
|
|
b44bb41235 | ||
|
|
a4718d4a16 | ||
|
|
6475cf21a5 | ||
|
|
5b8674cc57 | ||
|
|
9ab2fde392 | ||
|
|
b5acd48e5b | ||
|
|
acf73ac23f | ||
|
|
b3791364fd | ||
|
|
7c0cb06e59 | ||
|
|
9c9ce64809 | ||
|
|
508b67e5e5 | ||
|
|
9e6fe8cf80 | ||
|
|
a4d43c249e | ||
|
|
451449e148 | ||
|
|
508d7d284b | ||
|
|
b2e1631f7d | ||
|
|
29ee6b17fa | ||
|
|
90bfdfcaf3 | ||
|
|
7b40520a2d | ||
|
|
b3ff033e29 | ||
|
|
27566f49dd | ||
|
|
c4c41d3b69 | ||
|
|
0ed9201169 | ||
|
|
da193d1bd1 | ||
|
|
65ce834863 | ||
|
|
de7f072e85 | ||
|
|
ca25160c4c | ||
|
|
3514cb43ba | ||
|
|
40b5e99197 | ||
|
|
ef9104d264 | ||
|
|
7773311e0e | ||
|
|
10a10e9910 | ||
|
|
15055c26b8 | ||
|
|
d77c1c3ebf | ||
|
|
93f42683d1 | ||
|
|
6fdb44953b | ||
|
|
9dc3f4f61f | ||
|
|
f97d002ca6 | ||
|
|
d5bdeb0699 | ||
|
|
0b7da43638 | ||
|
|
e3f0482d09 | ||
|
|
faffc9b136 | ||
|
|
df110d457a | ||
|
|
e88ca34423 | ||
|
|
3a1102d9bf | ||
|
|
fefa0bfea7 | ||
|
|
4dd579e042 | ||
|
|
79d351fbbb | ||
|
|
b3b53506a1 | ||
|
|
96c1cadf2b | ||
|
|
563421b4dc | ||
|
|
6cee30ba79 | ||
|
|
b64185e85e | ||
|
|
8131f63504 | ||
|
|
29ec271586 | ||
|
|
f82bba5535 | ||
|
|
7db8dce51c | ||
|
|
bf03abae6a | ||
|
|
36f374be2a | ||
|
|
cdac404c47 | ||
|
|
27546f60da | ||
|
|
32f9d95bba | ||
|
|
03d3e1a5db | ||
|
|
bc73e73c26 | ||
|
|
9288930a3b | ||
|
|
2560ba84e8 | ||
|
|
8352f71a71 | ||
|
|
1a79b7ca74 | ||
|
|
3efb55ad17 | ||
|
|
ce96cb193b | ||
|
|
2328ee259b | ||
|
|
4352c8314c | ||
|
|
d550fb220e | ||
|
|
082ba963d3 | ||
|
|
474f662337 | ||
|
|
a853a0873e | ||
|
|
36783a3a79 | ||
|
|
459eb193e0 | ||
|
|
6791974004 | ||
|
|
c9db9b4c22 | ||
|
|
258ad6e4c1 | ||
|
|
352eaa2c57 | ||
|
|
ceef0fdb7b | ||
|
|
d0357cc998 | ||
|
|
cc6b473d17 | ||
|
|
c1394b7097 | ||
|
|
4d16f1f883 | ||
|
|
0968576649 | ||
|
|
9dc3b26c1b | ||
|
|
6577a9a379 | ||
|
|
b35451222c | ||
|
|
29c984a1ec | ||
|
|
8e87374b47 | ||
|
|
232700e417 | ||
|
|
52d7d2881a | ||
|
|
7631381a98 | ||
|
|
8263ac09ec | ||
|
|
1436470943 | ||
|
|
3e3dd40cf8 | ||
|
|
52154ddeb9 | ||
|
|
8b0ad24dcd | ||
|
|
a6bd14c2cd | ||
|
|
31e6b5814f | ||
|
|
1b29701368 | ||
|
|
59feb72fca | ||
|
|
4ae28aba10 | ||
|
|
e3520f952e | ||
|
|
7fc9550f7b | ||
|
|
76caa943b5 | ||
|
|
97d989a865 | ||
|
|
e1dc1d9d03 | ||
|
|
6c6ce912b1 | ||
|
|
e76e6f1266 | ||
|
|
6a89d4568e | ||
|
|
39c42bca41 | ||
|
|
7e52caa588 | ||
|
|
40a0072d5b | ||
|
|
0d9268ec10 | ||
|
|
8198272571 | ||
|
|
931cf0a868 | ||
|
|
742800b858 | ||
|
|
7668a8917e | ||
|
|
64c59ef5ec | ||
|
|
665fdd3d8d | ||
|
|
9826c81808 | ||
|
|
c9b043eb09 | ||
|
|
f8d0c3de03 | ||
|
|
ff4c48f952 | ||
|
|
6d13f28bc0 | ||
|
|
4065e7b4b7 | ||
|
|
87f603687a | ||
|
|
2385bc364a | ||
|
|
7975b90d7c | ||
|
|
61f49be3eb | ||
|
|
585eb1d357 | ||
|
|
799d0b3ab5 | ||
|
|
ff1749a557 | ||
|
|
670cc4de09 | ||
|
|
87b7a980e1 | ||
|
|
b925dd3e2b | ||
|
|
14caab46dd | ||
|
|
253aa011f9 | ||
|
|
51c0a5457f | ||
|
|
6d97394f28 | ||
|
|
3f0833b140 | ||
|
|
b4ef9fe69a | ||
|
|
b3061bc48c | ||
|
|
44906a236c | ||
|
|
c1aec06360 | ||
|
|
94faf0b46c | ||
|
|
9a90e85da8 | ||
|
|
c39861d9a3 | ||
|
|
29b6011be4 | ||
|
|
3b7d6377a0 | ||
|
|
6cd72e4e7d | ||
|
|
c67a612192 | ||
|
|
e90ef3bc68 | ||
|
|
8a15fb7c63 | ||
|
|
f30185bc0e | ||
|
|
035b5bb665 | ||
|
|
cd8df70e5c | ||
|
|
6d90aaaae2 | ||
|
|
4e144dba6a | ||
|
|
bd42f37ad4 | ||
|
|
15852ca054 | ||
|
|
1ba3b13aef | ||
|
|
db1928573f | ||
|
|
a96732e347 | ||
|
|
e223f4ee1d | ||
|
|
0b05fce71b | ||
|
|
c4538995db | ||
|
|
a59753121a | ||
|
|
3084ae89dd | ||
|
|
bccf8379c3 | ||
|
|
d379bbae9c | ||
|
|
2547feeff1 | ||
|
|
30b7ab3c12 | ||
|
|
532584deca | ||
|
|
c6883ad2ee | ||
|
|
1e3de79862 | ||
|
|
03f752e1b0 | ||
|
|
5b13d71e24 | ||
|
|
fd5a124c84 | ||
|
|
88cbf8c940 | ||
|
|
dc12dfd7d4 | ||
|
|
cbb257a547 | ||
|
|
f1d5a92cd7 | ||
|
|
27f242ea08 | ||
|
|
5cdea25a3b | ||
|
|
0ab5b35867 | ||
|
|
e06704a8aa | ||
|
|
dcae2e7f68 | ||
|
|
d8c97ec756 | ||
|
|
490e230b75 | ||
|
|
6315dae4ca | ||
|
|
fda5c4aed3 | ||
|
|
122a4e8d5b | ||
|
|
5b3977ce13 | ||
|
|
70765d1ebe | ||
|
|
f35945e912 | ||
|
|
5acdc72b3b | ||
|
|
a0594dd638 | ||
|
|
8a6e64179b | ||
|
|
8a2caa66d5 | ||
|
|
e4ce069d1a | ||
|
|
0740b59684 | ||
|
|
4e0f7419dc | ||
|
|
1a6dbad0d7 | ||
|
|
263436d866 | ||
|
|
f64ed09574 | ||
|
|
a4eeefc13f | ||
|
|
605efb5e86 | ||
|
|
a7e7899edd | ||
|
|
4b6ac06b5e | ||
|
|
ffdffeee9e | ||
|
|
0d9d4f55f7 | ||
|
|
91f8f88781 | ||
|
|
b4675c106f | ||
|
|
f83f5f1a52 | ||
|
|
4d0762e43d | ||
|
|
e017df3d70 | ||
|
|
6b9d98f467 | ||
|
|
61e22e39b3 | ||
|
|
85b4f2c67f | ||
|
|
de359dae9f | ||
|
|
f2992564bb | ||
|
|
ab009fabff | ||
|
|
9a727b744a | ||
|
|
e7b40cb444 | ||
|
|
e1e6413977 | ||
|
|
2825d2bf5d | ||
|
|
08ea58b243 | ||
|
|
5a113cdbb2 | ||
|
|
df209625ab | ||
|
|
41e8191578 | ||
|
|
917bea36d3 | ||
|
|
69fc7b1100 | ||
|
|
503a6b1a8b | ||
|
|
5d78609871 | ||
|
|
0a0cd884dd | ||
|
|
208a15aacc | ||
|
|
59af5bd8aa | ||
|
|
3ea461340b | ||
|
|
415e830c1a | ||
|
|
42a00a8111 | ||
|
|
2cdc433518 | ||
|
|
600f46dddd | ||
|
|
6553239fbc | ||
|
|
646cec27d0 | ||
|
|
738ccce421 | ||
|
|
30f0942dbc | ||
|
|
e87f123870 | ||
|
|
194e61cfbe | ||
|
|
b5b0e59c35 | ||
|
|
1613e12df7 | ||
|
|
11ac735ee3 | ||
|
|
86f31972f1 | ||
|
|
9db78ab4d6 | ||
|
|
39f522c546 | ||
|
|
134cf55931 | ||
|
|
bbca763110 | ||
|
|
133865b7a4 | ||
|
|
9fe2c0bdf8 | ||
|
|
d7ba0230d1 | ||
|
|
89cc4d2d02 | ||
|
|
a3685e6bde | ||
|
|
f4412ac03e | ||
|
|
20242b7522 | ||
|
|
e9ff5ee562 | ||
|
|
2e7011588a | ||
|
|
9a0dd7c1b3 | ||
|
|
fc30280a7d | ||
|
|
c6d880329d | ||
|
|
c94ba6ecd6 | ||
|
|
c093a2cf6d | ||
|
|
d3ef88edf8 | ||
|
|
e6dd524099 | ||
|
|
192a24c434 | ||
|
|
914b47039c | ||
|
|
9dc2282249 | ||
|
|
fcc41355ea | ||
|
|
ffecf830b7 | ||
|
|
ca41bc0731 | ||
|
|
5824a0603b | ||
|
|
13cbe0d0d3 | ||
|
|
972cbd5cb3 | ||
|
|
379bc3e519 | ||
|
|
d7d067165c | ||
|
|
9e5e6bf16d | ||
|
|
5723e7135f | ||
|
|
8f7a4bf353 | ||
|
|
4f097b425a | ||
|
|
b89b0d5074 | ||
|
|
52e160a08a | ||
|
|
79f8d16da6 | ||
|
|
2debc770ec | ||
|
|
07e2e797e9 | ||
|
|
4e3e4cb5da | ||
|
|
c1f63858ac | ||
|
|
f7b4d18146 | ||
|
|
43d8ee586f | ||
|
|
8601b8c990 | ||
|
|
37b808d171 | ||
|
|
70949fd4af | ||
|
|
73ae66f2cc | ||
|
|
4f36249c8c | ||
|
|
99bfac9c77 | ||
|
|
16b0b5f0ec | ||
|
|
c73ac5cf30 | ||
|
|
d45a9a933b | ||
|
|
22ad41e6f7 | ||
|
|
38a908a4ec | ||
|
|
2a49e1fbdb | ||
|
|
43b698f434 | ||
|
|
9f8a468d94 | ||
|
|
d3d76080f7 | ||
|
|
ef1d5079f2 | ||
|
|
2de56bf324 | ||
|
|
31d6a5e9bd | ||
|
|
8d91453b52 | ||
|
|
f493a47a89 | ||
|
|
c8aceea464 | ||
|
|
a51cb67cb0 | ||
|
|
801dc4cc6c | ||
|
|
d656022e1e | ||
|
|
ca2b5f15a7 | ||
|
|
39b7cce490 | ||
|
|
a6145ca92b | ||
|
|
0d4a95b88f | ||
|
|
007dcc63a8 | ||
|
|
616bdf8360 | ||
|
|
4d10437474 | ||
|
|
3ec0f5ee68 | ||
|
|
e859533454 | ||
|
|
472e916af6 | ||
|
|
553f1d1a52 | ||
|
|
986a1a80ff | ||
|
|
20f8515724 | ||
|
|
f4b394a30f | ||
|
|
adb02aa2ee | ||
|
|
3c73b3aadf | ||
|
|
eca08df857 | ||
|
|
a36ed24b1a | ||
|
|
2e215b0951 | ||
|
|
ea1be5276c | ||
|
|
9c6f07dbc8 | ||
|
|
bc21da6ab2 | ||
|
|
389b9cf4ef | ||
|
|
8a388f4b0e | ||
|
|
344f8b75e6 | ||
|
|
817ee1a217 | ||
|
|
00ef792d47 | ||
|
|
19ffb7be48 | ||
|
|
f516d7ab4f | ||
|
|
a03d274676 | ||
|
|
43a2ae0040 | ||
|
|
6905159a38 | ||
|
|
76ed14e76c | ||
|
|
63124fc487 | ||
|
|
f984f49310 | ||
|
|
3f61f27bd3 | ||
|
|
ca3dc63a92 | ||
|
|
48dc0d8bc7 | ||
|
|
90918b20f0 | ||
|
|
e7fec943fd | ||
|
|
f77f930c7d | ||
|
|
e169577917 | ||
|
|
88943f0e2a | ||
|
|
b7de87f568 | ||
|
|
8ee63636a1 | ||
|
|
52de87dbae | ||
|
|
19e5e545eb | ||
|
|
703fa47814 | ||
|
|
b167298cb0 | ||
|
|
c952feff0d | ||
|
|
3beb38d3c1 | ||
|
|
af2ea8f275 | ||
|
|
c8b9cf6c63 | ||
|
|
0afa3f3193 | ||
|
|
950b110e58 | ||
|
|
358772429e | ||
|
|
721b8e9d9f | ||
|
|
43685afe1a | ||
|
|
d8612a6ca7 | ||
|
|
b4b5516ca7 | ||
|
|
571f488ddb | ||
|
|
dd24ddd645 | ||
|
|
698122d6d2 | ||
|
|
13bbd326d1 | ||
|
|
0ebec67daa | ||
|
|
0b24b5f0ce | ||
|
|
d840c9db1e | ||
|
|
15a375e811 | ||
|
|
5a8d94fff2 | ||
|
|
aff3395f30 | ||
|
|
8fc58e2f00 | ||
|
|
5d58645a85 | ||
|
|
d501025037 | ||
|
|
5b2b0432c9 | ||
|
|
1f21757d62 | ||
|
|
206f8ae187 | ||
|
|
60bf3a9869 | ||
|
|
d0bc613d64 | ||
|
|
e38b2433df | ||
|
|
b74ba0fb92 | ||
|
|
368ec8956d | ||
|
|
3d03e522d3 | ||
|
|
9948d97230 | ||
|
|
72460cec61 | ||
|
|
faba9ac244 | ||
|
|
565b8482f9 | ||
|
|
fc7bcceca9 | ||
|
|
08e57ca313 | ||
|
|
3674a6f0f2 | ||
|
|
924d88bbf9 | ||
|
|
90a836a022 | ||
|
|
f9f6283cc3 | ||
|
|
0f62f51f9f | ||
|
|
e881ffca95 | ||
|
|
214aa50595 | ||
|
|
7d3100dbe7 | ||
|
|
18b9135c4f | ||
|
|
75e542c6ad | ||
|
|
da099ca77a | ||
|
|
f36d7e8e96 | ||
|
|
1e812a4b7c | ||
|
|
2c3e4ef47f | ||
|
|
47a4da8d5f | ||
|
|
3598180557 | ||
|
|
a040fbddf2 | ||
|
|
6620471822 | ||
|
|
da70a37551 | ||
|
|
ce1246e0dd | ||
|
|
3b4371e01c | ||
|
|
6886f0d3dd | ||
|
|
451937d88b | ||
|
|
1f458c7107 | ||
|
|
9c165e3992 | ||
|
|
b780c9db80 | ||
|
|
096a32bf16 | ||
|
|
cdf7fb6f70 | ||
|
|
3b9107228a | ||
|
|
57dbc79668 | ||
|
|
074cf91bec | ||
|
|
941acb2e8d | ||
|
|
7361c1689e | ||
|
|
de4a9e1d5a | ||
|
|
ce03b84898 | ||
|
|
affa5e3086 | ||
|
|
89bddc76f0 | ||
|
|
21ef822c45 | ||
|
|
9a789dbb8a | ||
|
|
24237b3e35 | ||
|
|
1434175a84 | ||
|
|
b7762141e8 | ||
|
|
551aee172a | ||
|
|
3ab368f9b0 | ||
|
|
0d8a1327b0 | ||
|
|
719e36159d | ||
|
|
01030bbc4e | ||
|
|
f277a27f57 | ||
|
|
5300c57f3d | ||
|
|
e55e880b71 | ||
|
|
1e6db77be7 | ||
|
|
675ebb1f22 | ||
|
|
ad6c250595 | ||
|
|
00c36d7b40 | ||
|
|
a7db9280b8 | ||
|
|
c6bfb97988 | ||
|
|
f7a34d4274 | ||
|
|
4c6a1c722b | ||
|
|
01ddccb101 | ||
|
|
b95b95e7a7 | ||
|
|
44dabd7377 | ||
|
|
93770edc8a | ||
|
|
4a518335bb | ||
|
|
9de7f5838b | ||
|
|
10e9474e67 | ||
|
|
387ff92ab3 | ||
|
|
69b6d7ed5b | ||
|
|
a74ced54a2 | ||
|
|
cc04996bd5 | ||
|
|
c4963ed16d | ||
|
|
3e3dd82433 | ||
|
|
c54cf49f27 | ||
|
|
ef65ad6cd5 | ||
|
|
4412a2d318 |
@@ -9,9 +9,10 @@ AlignEscapedNewlines: Left
|
||||
AlignOperands: true
|
||||
AlignTrailingComments: false
|
||||
AllowAllParametersOfDeclarationOnNextLine: false
|
||||
AllowAllArgumentsOnNextLine: false
|
||||
AllowShortBlocksOnASingleLine: false
|
||||
AllowShortCaseLabelsOnASingleLine: false
|
||||
AllowShortFunctionsOnASingleLine: None
|
||||
AllowShortFunctionsOnASingleLine: false
|
||||
AllowShortIfStatementsOnASingleLine: false
|
||||
AllowShortLoopsOnASingleLine: false
|
||||
AlwaysBreakAfterDefinitionReturnType: None
|
||||
@@ -44,7 +45,7 @@ BreakBeforeTernaryOperators: true
|
||||
BreakConstructorInitializersBeforeComma: false
|
||||
BreakConstructorInitializers: BeforeColon
|
||||
BreakStringLiterals: true
|
||||
ColumnLimit: 200
|
||||
ColumnLimit: 132
|
||||
CommentPragmas: '^ IWYU pragma:'
|
||||
CompactNamespaces: false
|
||||
ConstructorInitializerAllOnOneLineOrOnePerLine: true
|
||||
|
||||
681
CMakeLists.txt
681
CMakeLists.txt
File diff suppressed because it is too large
Load Diff
@@ -2,20 +2,26 @@
|
||||
|
||||
We want to make contributing to this project as easy and transparent as possible.
|
||||
|
||||
Please refer to the steps described on our website: [How to contribute to OAI](https://www.openairinterface.org/?page_id=112).
|
||||
|
||||
1. Sign and return a Contributor License Agreement to OAI team.
|
||||
2. We recommend that you provide us with a professional or student email address
|
||||
2. Register on [Eurecom GitLab Server](https://gitlab.eurecom.fr/users/sign_in)
|
||||
2. Register on [Eurecom GitLab Server](https://gitlab.eurecom.fr/users/sign_up) if you do not have any.
|
||||
- We recommend that you register with a professional or student email address.
|
||||
- If your email domain (`@domain.com`) is not whitelisted, please contact us (mailto:contact@openairinterface.org).
|
||||
- Eurecom GitLab does NOT accept public email domains.
|
||||
3. Provide the OAI team with the **username** of this account to (mailto:contact@openairinterface.org) ; we will give you the developer rights on this repository.
|
||||
4. The policies are described in these wiki pages: [OAI Policies](https://gitlab.eurecom.fr/oai/openairinterface5g/wikis/oai-policies-home)
|
||||
4. The policies are described in these wiki pages: [OAI Policies](https://gitlab.eurecom.fr/oai/openairinterface5g/wikis/oai-policies-home).
|
||||
- PLEASE DO NOT FORK the OAI repository on your own Eurecom GitLab account. It just eats up space on our servers.
|
||||
- You can fork onto another hosting system. But we will NOT accept a merge request from a forked repository.
|
||||
* This decision was made for the license reasons.
|
||||
* The Continuous Integration will reject your merge request.
|
||||
- All merge requests SHALL have `develop` branch as target branch.
|
||||
- All merge requests SHALL have source branch names that SHALL not contain the `/` character.
|
||||
* We are using a `docker` registry scheme and the image names are based on the source branch name.
|
||||
|
||||
## Coding Styles ##
|
||||
|
||||
There are described [here](https://gitlab.eurecom.fr/oai/openairinterface5g/wikis/guidelines/guidelines-home)
|
||||
There are described [here](https://gitlab.eurecom.fr/oai/openairinterface5g/wikis/guidelines/guidelines-home).
|
||||
|
||||
## License ##
|
||||
|
||||
|
||||
72
README.md
72
README.md
@@ -4,8 +4,12 @@
|
||||
|
||||
<p align="center">
|
||||
<a href="https://gitlab.eurecom.fr/oai/openairinterface5g/-/blob/master/LICENSE"><img src="https://img.shields.io/badge/license-OAI--Public--V1.1-blue" alt="License"></a>
|
||||
<a href="https://releases.ubuntu.com/18.04/"><img src="https://img.shields.io/badge/OS-Ubuntu18-Green" alt="Supported OS"></a>
|
||||
<a href="https://www.redhat.com/en/enterprise-linux-8"><img src="https://img.shields.io/badge/OS-RHEL8-Green" alt="Supported OS"></a>
|
||||
<a href="https://releases.ubuntu.com/18.04/"><img src="https://img.shields.io/badge/OS-Ubuntu18-Green" alt="Supported OS Ubuntu 18"></a>
|
||||
<a href="https://releases.ubuntu.com/20.04/"><img src="https://img.shields.io/badge/OS-Ubuntu20-Green" alt="Supported OS Ubuntu 20"></a>
|
||||
<a href="https://releases.ubuntu.com/22.04/"><img src="https://img.shields.io/badge/OS-Ubuntu22-Green" alt="Supported OS Ubuntu 22"></a>
|
||||
<a href="https://www.redhat.com/en/technologies/linux-platforms/enterprise-linux"><img src="https://img.shields.io/badge/OS-RHEL8-Green" alt="Supported OS RHEL8"></a>
|
||||
<a href="https://www.redhat.com/en/technologies/linux-platforms/enterprise-linux"><img src="https://img.shields.io/badge/OS-RHEL9-Green" alt="Supported OS RELH9"></a>
|
||||
<a href="https://getfedora.org/en/workstation/"><img src="https://img.shields.io/badge/OS-Fedore37-Green" alt="Supported OS Fedora 37"></a>
|
||||
</p>
|
||||
|
||||
<p align="center">
|
||||
@@ -13,10 +17,10 @@
|
||||
</p>
|
||||
|
||||
<p align="center">
|
||||
<a href="https://hub.docker.com/r/rdefosseoai/oai-enb"><img alt="Docker Pulls" src="https://img.shields.io/docker/pulls/rdefosseoai/oai-enb?label=eNB%20docker%20pulls"></a>
|
||||
<a href="https://hub.docker.com/r/rdefosseoai/oai-lte-ue"><img alt="Docker Pulls" src="https://img.shields.io/docker/pulls/rdefosseoai/oai-lte-ue?label=LTE-UE%20docker%20pulls"></a>
|
||||
<a href="https://hub.docker.com/r/rdefosseoai/oai-gnb"><img alt="Docker Pulls" src="https://img.shields.io/docker/pulls/rdefosseoai/oai-gnb?label=gNB%20docker%20pulls"></a>
|
||||
<a href="https://hub.docker.com/r/rdefosseoai/oai-nr-ue"><img alt="Docker Pulls" src="https://img.shields.io/docker/pulls/rdefosseoai/oai-nr-ue?label=NR-UE%20docker%20pulls"></a>
|
||||
<a href="https://hub.docker.com/r/oaisoftwarealliance/oai-gnb"><img alt="Docker Pulls" src="https://img.shields.io/docker/pulls/oaisoftwarealliance/oai-gnb?label=gNB%20docker%20pulls"></a>
|
||||
<a href="https://hub.docker.com/r/oaisoftwarealliance/oai-nr-ue"><img alt="Docker Pulls" src="https://img.shields.io/docker/pulls/oaisoftwarealliance/oai-nr-ue?label=NR-UE%20docker%20pulls"></a>
|
||||
<a href="https://hub.docker.com/r/oaisoftwarealliance/oai-enb"><img alt="Docker Pulls" src="https://img.shields.io/docker/pulls/oaisoftwarealliance/oai-enb?label=eNB%20docker%20pulls"></a>
|
||||
<a href="https://hub.docker.com/r/oaisoftwarealliance/oai-lte-ue"><img alt="Docker Pulls" src="https://img.shields.io/docker/pulls/oaisoftwarealliance/oai-lte-ue?label=LTE-UE%20docker%20pulls"></a>
|
||||
</p>
|
||||
|
||||
# OpenAirInterface License #
|
||||
@@ -32,12 +36,12 @@ Please see [NOTICE](NOTICE.md) file for third party software that is included in
|
||||
|
||||
# Where to Start #
|
||||
|
||||
* [General overview of documentation](./doc/README.md)
|
||||
* [The implemented features](./doc/FEATURE_SET.md)
|
||||
* [How to build](./doc/BUILD.md)
|
||||
* [How to run the modems](./doc/RUNMODEM.md)
|
||||
|
||||
More information and documentation can be found in the [doc folder](./doc).
|
||||
Unfortunately, not all information is available there, and information for
|
||||
Not all information is available in a central place, and information for
|
||||
specific sub-systems might be available in the corresponding sub-directories.
|
||||
To find all READMEs, this command might be handy:
|
||||
|
||||
@@ -51,52 +55,20 @@ The OpenAirInterface (OAI) software is composed of the following parts:
|
||||
|
||||
```
|
||||
openairinterface5g
|
||||
├── charts
|
||||
├── ci-scripts : Meta-scripts used by the OSA CI process. Contains also configuration files used day-to-day by CI.
|
||||
├── CMakeLists.txt : Top-level CMakeLists.txt for building
|
||||
├── cmake_targets : Build utilities to compile (simulation, emulation and real-time platforms), and generated build files.
|
||||
├── common : Some common OAI utilities, other tools can be found at openair2/UTILS.
|
||||
├── doc : Contains an up-to-date feature set list and starting tutorials.
|
||||
├── executables : Top-level executable source files.
|
||||
├── LICENSE : License file.
|
||||
├── common : Some common OAI utilities, some other tools can be found at openair2/UTILS.
|
||||
├── doc : Documentation
|
||||
├── docker : Dockerfiles to build for Ubuntu and RHEL
|
||||
├── executables : Top-level executable source files (gNB, eNB, ...)
|
||||
├── maketags : Script to generate emacs tags.
|
||||
├── nfapi : Contains the NFAPI code. A local Readme file provides more details.
|
||||
├── nfapi : (n)FAPI code for MAC-PHY interface
|
||||
├── openair1 : 3GPP LTE Rel-10/12 PHY layer / 3GPP NR Rel-15 layer. A local Readme file provides more details.
|
||||
│ ├── PHY
|
||||
│ ├── SCHED
|
||||
│ ├── SCHED_NBIOT
|
||||
│ ├── SCHED_NR
|
||||
│ ├── SCHED_NR_UE
|
||||
│ ├── SCHED_UE
|
||||
│ └── SIMULATION : PHY RF simulation.
|
||||
├── openair2 : 3GPP LTE Rel-10 RLC/MAC/PDCP/RRC/X2AP + LTE Rel-14 M2AP implementation. Also 3GPP NR Rel-15 RLC/MAC/PDCP/RRC/X2AP.
|
||||
│ ├── COMMON
|
||||
│ ├── DOCS
|
||||
│ ├── ENB_APP
|
||||
│ ├── F1AP
|
||||
│ ├── GNB_APP
|
||||
│ ├── LAYER2/RLC/ : with the following subdirectories: UM_v9.3.0, TM_v9.3.0, and AM_v9.3.0.
|
||||
│ ├── LAYER2/PDCP/PDCP_v10.1.0
|
||||
│ ├── M2AP
|
||||
│ ├── MCE_APP
|
||||
│ ├── NETWORK_DRIVER
|
||||
│ ├── NR_PHY_INTERFACE
|
||||
│ ├── NR_UE_PHY_INTERFACE
|
||||
│ ├── PHY_INTERFACE
|
||||
│ ├── RRC
|
||||
│ ├── UTIL
|
||||
│ └── X2AP
|
||||
├── openair3 : 3GPP LTE Rel10 for S1AP, NAS GTPV1-U for both ENB and UE.
|
||||
│ ├── COMMON
|
||||
│ ├── DOCS
|
||||
│ ├── GTPV1-U
|
||||
│ ├── M3AP
|
||||
│ ├── MME_APP
|
||||
│ ├── NAS
|
||||
│ ├── S1AP
|
||||
│ ├── SCTP
|
||||
│ ├── SECU
|
||||
│ ├── TEST
|
||||
│ ├── UDP
|
||||
│ └── UTILS
|
||||
├── radio : drivers for various radios such as USRP, AW2S, RFsim, ...
|
||||
└── targets : Top-level wrappers for unitary simulation for PHY channels, system-level emulation (eNB-UE with and without S1), and realtime eNB and UE and RRH GW.
|
||||
├── openshift : OpenShift helm charts for some deployment options of OAI
|
||||
├── radio : Drivers for various radios such as USRP, AW2S, RFsim, ...
|
||||
└── targets : Some configuration files; only historical relevance, and might be deleted in the future
|
||||
```
|
||||
|
||||
@@ -385,6 +385,27 @@ pipeline {
|
||||
}
|
||||
}
|
||||
}
|
||||
stage ("LTE-TDD-2x2-Container") {
|
||||
when { expression {do4Gtest} }
|
||||
steps {
|
||||
script {
|
||||
triggerSlaveJob ('RAN-LTE-TDD-2x2-Container', 'LTE-TDD-2x2-Container')
|
||||
}
|
||||
}
|
||||
post {
|
||||
always {
|
||||
script {
|
||||
finalizeSlaveJob('RAN-LTE-TDD-2x2-Container')
|
||||
}
|
||||
}
|
||||
failure {
|
||||
script {
|
||||
currentBuild.result = 'FAILURE'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//avra is offline, re-enable once it is available
|
||||
//stage ("T1-Offload-Test") {
|
||||
// when { expression {do5Gtest} }
|
||||
|
||||
@@ -155,14 +155,6 @@ pipeline {
|
||||
allParametersPresent = false
|
||||
}
|
||||
|
||||
if (params.ADB_IPAddress == null) {
|
||||
echo "no ADB_IPAddress given"
|
||||
allParametersPresent = false
|
||||
}
|
||||
if (params.ADB_Credentials == null) {
|
||||
echo "no ADB_IPAddress given"
|
||||
allParametersPresent = false
|
||||
}
|
||||
if (params.OC_Credentials == null) {
|
||||
echo "no OC_Credentials given"
|
||||
allParametersPresent = false
|
||||
@@ -207,14 +199,13 @@ pipeline {
|
||||
withCredentials([
|
||||
[$class: 'UsernamePasswordMultiBinding', credentialsId: "${params.eNB_Credentials}", usernameVariable: 'eNB_Username', passwordVariable: 'eNB_Password'],
|
||||
[$class: 'UsernamePasswordMultiBinding', credentialsId: "${params.EPC_Credentials}", usernameVariable: 'EPC_Username', passwordVariable: 'EPC_Password'],
|
||||
[$class: 'UsernamePasswordMultiBinding', credentialsId: "${params.ADB_Credentials}", usernameVariable: 'ADB_Username', passwordVariable: 'ADB_Password'],
|
||||
[$class: 'UsernamePasswordMultiBinding', credentialsId: "${params.OC_Credentials}", usernameVariable: 'OC_Username', passwordVariable: 'OC_Password']
|
||||
]) {
|
||||
sh "python3 main.py --mode=InitiateHtml --ranRepository=${eNB_Repository} --ranBranch=${eNB_Branch} --ranCommitID=${eNB_CommitID} --ranAllowMerge=${eNB_AllowMergeRequestProcess} --ranTargetBranch=${eNB_TargetBranch} --ADBIPAddress=${params.ADB_IPAddress} --ADBUserName=${ADB_Username} --ADBPassword=${ADB_Password} ${mainPythonAllXmlFiles}"
|
||||
sh "python3 main.py --mode=InitiateHtml --ranRepository=${eNB_Repository} --ranBranch=${eNB_Branch} --ranCommitID=${eNB_CommitID} --ranAllowMerge=${eNB_AllowMergeRequestProcess} --ranTargetBranch=${eNB_TargetBranch} ${mainPythonAllXmlFiles}"
|
||||
for (xmlFile in myXmlTestSuite) {
|
||||
if (fileExists(xmlFile)) {
|
||||
try {
|
||||
sh "python3 main.py --mode=TesteNB --eNBIPAddress=${params.eNB_IPAddress} --ranRepository=${eNB_Repository} --ranBranch=${eNB_Branch} --ranCommitID=${eNB_CommitID} --ranAllowMerge=${eNB_AllowMergeRequestProcess} --ranTargetBranch=${eNB_TargetBranch} --eNBUserName=${eNB_Username} --eNBPassword=${eNB_Password} --eNBSourceCodePath=${params.eNB_SourceCodePath} --EPCIPAddress=${params.EPC_IPAddress} --EPCType=${params.EPC_Type} --EPCUserName=${EPC_Username} --EPCPassword=${EPC_Password} --EPCSourceCodePath=${params.EPC_SourceCodePath} --ADBIPAddress=${params.ADB_IPAddress} --ADBUserName=${ADB_Username} --ADBPassword=${ADB_Password} --XMLTestFile=${xmlFile} --OCUserName=${OC_Username} --OCPassword=${OC_Password} --OCProjectName=${OC_ProjectName}"
|
||||
sh "python3 main.py --mode=TesteNB --eNBIPAddress=${params.eNB_IPAddress} --ranRepository=${eNB_Repository} --ranBranch=${eNB_Branch} --ranCommitID=${eNB_CommitID} --ranAllowMerge=${eNB_AllowMergeRequestProcess} --ranTargetBranch=${eNB_TargetBranch} --eNBUserName=${eNB_Username} --eNBPassword=${eNB_Password} --eNBSourceCodePath=${params.eNB_SourceCodePath} --EPCIPAddress=${params.EPC_IPAddress} --EPCType=${params.EPC_Type} --EPCUserName=${EPC_Username} --EPCPassword=${EPC_Password} --EPCSourceCodePath=${params.EPC_SourceCodePath} --XMLTestFile=${xmlFile} --OCUserName=${OC_Username} --OCPassword=${OC_Password} --OCProjectName=${OC_ProjectName}"
|
||||
} catch (Exception e) {
|
||||
currentBuild.result = 'FAILURE'
|
||||
buildStageStatus = false
|
||||
|
||||
@@ -1,48 +0,0 @@
|
||||
#!/bin/groovy
|
||||
/*
|
||||
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The OpenAirInterface Software Alliance licenses this file to You under
|
||||
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.openairinterface.org/?page_id=698
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*-------------------------------------------------------------------------------
|
||||
* For more information about the OpenAirInterface (OAI) Software Alliance:
|
||||
* contact@openairinterface.org
|
||||
*/
|
||||
|
||||
// Template Jenkins Declarative Pipeline script to run Test w/ RF HW
|
||||
|
||||
// Location of the python executor node shall be in the same subnet as the others servers
|
||||
def pythonExecutor = params.pythonExecutor
|
||||
|
||||
|
||||
pipeline {
|
||||
agent {
|
||||
label pythonExecutor
|
||||
}
|
||||
stages {
|
||||
stage ("gDashboard") {
|
||||
steps {
|
||||
script {
|
||||
dir ("ci-scripts/ran_dashboard") {
|
||||
//retrieve MR data from gitlab / mySQL db, build HTML pages and load them to AWS S3 bucket (configured as static web page hosting)
|
||||
//deprecated method : sh returnStdout: true, script: 'python3 ran_dashboard.py'
|
||||
sh returnStdout: true, script: 'python3 Hdashboard.py'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,391 +0,0 @@
|
||||
#!/bin/groovy
|
||||
/*
|
||||
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The OpenAirInterface Software Alliance licenses this file to You under
|
||||
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.openairinterface.org/?page_id=698
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*-------------------------------------------------------------------------------
|
||||
* For more information about the OpenAirInterface (OAI) Software Alliance:
|
||||
* contact@openairinterface.org
|
||||
*/
|
||||
|
||||
// Location of the executor node
|
||||
def nodeExecutor = params.nodeExecutor
|
||||
|
||||
// VM Lockable resources
|
||||
def vmResource = params.vmLockableResource
|
||||
|
||||
// Tags to shorten pipeline duration
|
||||
def doMandatoryTests = false
|
||||
def doFullTestsuite = false
|
||||
|
||||
pipeline {
|
||||
agent {
|
||||
label nodeExecutor
|
||||
}
|
||||
options {
|
||||
disableConcurrentBuilds()
|
||||
timestamps()
|
||||
gitLabConnection('OAI GitLab')
|
||||
ansiColor('xterm')
|
||||
}
|
||||
|
||||
stages {
|
||||
stage ("Verify Parameters") {
|
||||
steps {
|
||||
script {
|
||||
JOB_TIMESTAMP = sh returnStdout: true, script: 'date --utc --rfc-3339=seconds | sed -e "s#+00:00##"'
|
||||
JOB_TIMESTAMP = JOB_TIMESTAMP.trim()
|
||||
|
||||
echo '\u2705 \u001B[32mVerify Parameters\u001B[0m'
|
||||
def allParametersPresent = true
|
||||
if (env.TESTPLATFORM_OWNER) {
|
||||
echo "Platform is ${env.TESTPLATFORM_OWNER}"
|
||||
}
|
||||
|
||||
echo '\u2705 \u001B[32mVerify Labels\u001B[0m'
|
||||
if ("MERGE".equals(env.gitlabActionType)) {
|
||||
LABEL_CHECK = sh returnStdout: true, script: 'ci-scripts/checkGitLabMergeRequestLabels.sh --mr-id ' + env.gitlabMergeRequestIid
|
||||
LABEL_CHECK = LABEL_CHECK.trim()
|
||||
if (LABEL_CHECK == 'NONE') {
|
||||
def message = "OAI " + JOB_NAME + " build (" + BUILD_ID + "): Your merge request has none of the mandatory labels:\n\n"
|
||||
message += " - BUILD-ONLY\n"
|
||||
message += " - 4G-LTE\n"
|
||||
message += " - 5G-NR\n"
|
||||
message += " - CI\n\n"
|
||||
message += "Not performing CI due to lack of labels"
|
||||
addGitLabMRComment comment: message
|
||||
error('Not performing CI due to lack of labels')
|
||||
} else if (LABEL_CHECK == 'FULL' || LABEL_CHECK == 'SHORTEN-4G') {
|
||||
doMandatoryTests = true
|
||||
doFullTestsuite = true
|
||||
} else if (LABEL_CHECK == 'SHORTEN-5G') {
|
||||
doMandatoryTests = true
|
||||
} else {
|
||||
def message = "OAI " + JOB_NAME + " build (" + BUILD_ID + "): We will perform only build stages on your Merge Request"
|
||||
addGitLabMRComment comment: message
|
||||
}
|
||||
} else {
|
||||
doMandatoryTests = true
|
||||
doFullTestsuite = true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
stage ("Verify Guidelines") {
|
||||
steps {
|
||||
echo "Git URL is ${GIT_URL}"
|
||||
echo "GitLab Act is ${env.gitlabActionType}"
|
||||
script {
|
||||
if ("MERGE".equals(env.gitlabActionType)) {
|
||||
// since a bit, in push events, gitlabUserEmail is not populated
|
||||
gitCommitAuthorEmailAddr = env.gitlabUserEmail
|
||||
echo "GitLab Usermail is ${gitCommitAuthorEmailAddr}"
|
||||
// GitLab-Jenkins plugin integration is lacking to perform the merge by itself
|
||||
// Doing it manually --> it may have merge conflicts
|
||||
sh "./ci-scripts/doGitLabMerge.sh --src-branch ${env.gitlabSourceBranch} --src-commit ${env.gitlabMergeRequestLastCommit} --target-branch ${env.gitlabTargetBranch} --target-commit ${GIT_COMMIT}"
|
||||
sh "zip -r -qq localZip.zip ."
|
||||
|
||||
// here was an astyle formatting check, with corresponding messages. The same could be done with clang-format
|
||||
} else {
|
||||
echo "Git Branch is ${GIT_BRANCH}"
|
||||
echo "Git Commit is ${GIT_COMMIT}"
|
||||
// since a bit, in push events, gitlabUserEmail is not populated
|
||||
gitCommitAuthorEmailAddr = sh returnStdout: true, script: 'git log -n1 --pretty=format:%ae ${GIT_COMMIT}'
|
||||
gitCommitAuthorEmailAddr = gitCommitAuthorEmailAddr.trim()
|
||||
echo "GitLab Usermail is ${gitCommitAuthorEmailAddr}"
|
||||
sh "git log -n1 --pretty=format:\"%s\" > .git/CI_COMMIT_MSG"
|
||||
|
||||
sh "zip -r -qq localZip.zip ."
|
||||
}
|
||||
}
|
||||
}
|
||||
post {
|
||||
failure {
|
||||
script {
|
||||
def message = "OAI " + JOB_NAME + " build (" + BUILD_ID + "): Merge Conflicts -- Cannot perform CI"
|
||||
addGitLabMRComment comment: message
|
||||
currentBuild.result = 'FAILURE'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
stage ("Start VM -- gnb-usrp") {
|
||||
steps {
|
||||
lock (vmResource) {
|
||||
timeout (time: 5, unit: 'MINUTES') {
|
||||
sh "./ci-scripts/oai-ci-vm-tool build --workspace $WORKSPACE --variant gnb-usrp --job-name ${JOB_NAME} --build-id ${BUILD_ID} --daemon"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
stage ("Start VM -- nr-ue-usrp") {
|
||||
steps {
|
||||
lock (vmResource) {
|
||||
timeout (time: 5, unit: 'MINUTES') {
|
||||
sh "./ci-scripts/oai-ci-vm-tool build --workspace $WORKSPACE --variant nr-ue-usrp --job-name ${JOB_NAME} --build-id ${BUILD_ID} --daemon"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
stage ("Start VM -- enb-ethernet") {
|
||||
steps {
|
||||
lock (vmResource) {
|
||||
timeout (time: 7, unit: 'MINUTES') {
|
||||
sh "./ci-scripts/oai-ci-vm-tool build --workspace $WORKSPACE --variant enb-ethernet --job-name ${JOB_NAME} --build-id ${BUILD_ID} --daemon"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
stage ("Start VM -- ue-ethernet") {
|
||||
steps {
|
||||
lock (vmResource) {
|
||||
timeout (time: 7, unit: 'MINUTES') {
|
||||
sh "./ci-scripts/oai-ci-vm-tool build --workspace $WORKSPACE --variant ue-ethernet --job-name ${JOB_NAME} --build-id ${BUILD_ID} --daemon"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
stage ("Variant Builds") {
|
||||
parallel {
|
||||
stage ("Build 5G gNB-USRP") {
|
||||
steps {
|
||||
gitlabCommitStatus(name: "Build gNB-USRP") {
|
||||
timeout (time: 45, unit: 'MINUTES') {
|
||||
sh "./ci-scripts/oai-ci-vm-tool wait --workspace $WORKSPACE --variant gnb-usrp --job-name ${JOB_NAME} --build-id ${BUILD_ID} --keep-vm-alive"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
stage ("Build 5G NR-UE-USRP") {
|
||||
steps {
|
||||
gitlabCommitStatus(name: "Build nr-UE-USRP") {
|
||||
timeout (time: 45, unit: 'MINUTES') {
|
||||
sh "./ci-scripts/oai-ci-vm-tool wait --workspace $WORKSPACE --variant nr-ue-usrp --job-name ${JOB_NAME} --build-id ${BUILD_ID} --keep-vm-alive"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
stage ("Build eNB-ethernet") {
|
||||
steps {
|
||||
gitlabCommitStatus(name: "Build eNB-ethernet") {
|
||||
timeout (time: 45, unit: 'MINUTES') {
|
||||
sh "./ci-scripts/oai-ci-vm-tool wait --workspace $WORKSPACE --variant enb-ethernet --job-name ${JOB_NAME} --build-id ${BUILD_ID} --keep-vm-alive"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
stage ("Build UE-ethernet") {
|
||||
steps {
|
||||
// This is typically the last one to finish.
|
||||
lock (vmResource) {
|
||||
gitlabCommitStatus(name: "Build UE-ethernet") {
|
||||
timeout (time: 45, unit: 'MINUTES') {
|
||||
sh "./ci-scripts/oai-ci-vm-tool wait --workspace $WORKSPACE --variant ue-ethernet --job-name ${JOB_NAME} --build-id ${BUILD_ID} --keep-vm-alive"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
post {
|
||||
failure {
|
||||
script {
|
||||
currentBuild.result = 'FAILURE'
|
||||
}
|
||||
}
|
||||
always {
|
||||
script {
|
||||
dir ('archives') {
|
||||
if (fileExists('red_hat')) {
|
||||
sh "zip -r -qq vm_build_logs.zip enb_eth ue_eth gnb_usrp nr_ue_usrp red_hat"
|
||||
} else {
|
||||
sh "zip -r -qq vm_build_logs.zip enb_eth ue_eth gnb_usrp nr_ue_usrp"
|
||||
}
|
||||
}
|
||||
if(fileExists('archives/vm_build_logs.zip')) {
|
||||
archiveArtifacts artifacts: 'archives/vm_build_logs.zip'
|
||||
}
|
||||
if ("MERGE".equals(env.gitlabActionType)) {
|
||||
sh "./ci-scripts/oai-ci-vm-tool report-build --workspace $WORKSPACE --git-url ${GIT_URL} --job-name ${JOB_NAME} --build-id ${BUILD_ID} --trigger merge-request --src-branch ${env.gitlabSourceBranch} --src-commit ${env.gitlabMergeRequestLastCommit} --target-branch ${env.gitlabTargetBranch} --target-commit ${GIT_COMMIT}"
|
||||
// If the merge request has introduced compilation warnings, notifications in GitLab
|
||||
sh "./ci-scripts/checkAddedWarnings.sh --src-branch ${env.gitlabSourceBranch} --target-branch ${env.gitlabTargetBranch}"
|
||||
def res=readFile('./oai_warning_files.txt').trim();
|
||||
if ("0".equals(res)) {
|
||||
echo "No issues w/ warnings/errors in this merge request"
|
||||
} else {
|
||||
def fileList=readFile('./oai_warning_files_list.txt').trim();
|
||||
def message = "OAI " + JOB_NAME + " build (" + BUILD_ID + "): Some modified files in Merge Request MAY have INTRODUCED WARNINGS (" + fileList + ")"
|
||||
addGitLabMRComment comment: message
|
||||
}
|
||||
} else {
|
||||
sh "./ci-scripts/oai-ci-vm-tool report-build --workspace $WORKSPACE --git-url ${GIT_URL} --job-name ${JOB_NAME} --build-id ${BUILD_ID} --trigger push --branch ${GIT_BRANCH} --commit ${GIT_COMMIT}"
|
||||
}
|
||||
if(fileExists('build_results.html')) {
|
||||
sh "sed -i -e 's#Build-ID: ${BUILD_ID}#Build-ID: <a href=\"${BUILD_URL}\">${BUILD_ID}</a>#' -e 's#TEMPLATE_BUILD_TIME#${JOB_TIMESTAMP}#' build_results.html"
|
||||
archiveArtifacts artifacts: 'build_results.html'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
stage ("Variant Tests") {
|
||||
parallel {
|
||||
stage ("VM-based tests") {
|
||||
stages {
|
||||
stage ("Test L1 simulator") {
|
||||
when {
|
||||
expression {doMandatoryTests}
|
||||
}
|
||||
steps {
|
||||
lock (vmResource) {
|
||||
script {
|
||||
timeout (time: 30, unit: 'MINUTES') {
|
||||
try {
|
||||
gitlabCommitStatus(name: "Test L1-sim") {
|
||||
sh "./ci-scripts/oai-ci-vm-tool test --workspace $WORKSPACE --variant l1-sim --job-name ${JOB_NAME} --build-id ${BUILD_ID} --keep-vm-alive"
|
||||
}
|
||||
} catch (Exception e) {
|
||||
currentBuild.result = 'FAILURE'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
stage ("Test RF simulator") {
|
||||
when {
|
||||
expression {doMandatoryTests}
|
||||
}
|
||||
steps {
|
||||
lock (vmResource) {
|
||||
script {
|
||||
timeout (time: 40, unit: 'MINUTES') {
|
||||
try {
|
||||
gitlabCommitStatus(name: "Test RF-sim") {
|
||||
sh "./ci-scripts/oai-ci-vm-tool test --workspace $WORKSPACE --variant rf-sim --job-name ${JOB_NAME} --build-id ${BUILD_ID} --keep-vm-alive"
|
||||
}
|
||||
} catch (Exception e) {
|
||||
currentBuild.result = 'FAILURE'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
stage ("Test 5G RF simulator") {
|
||||
when {
|
||||
expression {doMandatoryTests}
|
||||
}
|
||||
steps {
|
||||
lock (vmResource) {
|
||||
script {
|
||||
timeout (time: 40, unit: 'MINUTES') {
|
||||
try {
|
||||
gitlabCommitStatus(name: "Test 5G RF-sim") {
|
||||
sh "./ci-scripts/oai-ci-vm-tool test --workspace $WORKSPACE --variant rf5g-sim --job-name ${JOB_NAME} --build-id ${BUILD_ID} --keep-vm-alive"
|
||||
}
|
||||
} catch (Exception e) {
|
||||
currentBuild.result = 'FAILURE'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
stage ("Destroy all Virtual Machines") {
|
||||
when {
|
||||
expression {doMandatoryTests}
|
||||
}
|
||||
steps {
|
||||
lock (vmResource) {
|
||||
sh "./ci-scripts/oai-ci-vm-tool destroy --job-name ${JOB_NAME} --build-id ${BUILD_ID}"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
post {
|
||||
always {
|
||||
script {
|
||||
if (doMandatoryTests) {
|
||||
dir ('archives') {
|
||||
sh "if [ -d rf_sim/test ] || [ -d rf5g_sim/test ] || [ -d l2_sim/test ]; then zip -r -qq vm_tests_logs.zip */test ; fi"
|
||||
}
|
||||
if(fileExists('archives/vm_tests_logs.zip')) {
|
||||
archiveArtifacts artifacts: 'archives/vm_tests_logs.zip'
|
||||
if ("MERGE".equals(env.gitlabActionType)) {
|
||||
sh "./ci-scripts/oai-ci-vm-tool report-test --workspace $WORKSPACE --git-url ${GIT_URL} --job-name ${JOB_NAME} --build-id ${BUILD_ID} --trigger merge-request --src-branch ${env.gitlabSourceBranch} --src-commit ${env.gitlabMergeRequestLastCommit} --target-branch ${env.gitlabTargetBranch} --target-commit ${GIT_COMMIT}"
|
||||
} else {
|
||||
sh "./ci-scripts/oai-ci-vm-tool report-test --workspace $WORKSPACE --git-url ${GIT_URL} --job-name ${JOB_NAME} --build-id ${BUILD_ID} --trigger push --branch ${GIT_BRANCH} --commit ${GIT_COMMIT}"
|
||||
}
|
||||
if(fileExists('test_simulator_results.html')) {
|
||||
sh "sed -i -e 's#Build-ID: ${BUILD_ID}#Build-ID: <a href=\"${BUILD_URL}\">${BUILD_ID}</a>#' -e 's#TEMPLATE_BUILD_TIME#${JOB_TIMESTAMP}#' test_simulator_results.html"
|
||||
archiveArtifacts artifacts: 'test_simulator_results.html'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
post {
|
||||
always {
|
||||
script {
|
||||
// Stage destroy may not be run if error in previous stage
|
||||
sh "./ci-scripts/oai-ci-vm-tool destroy --job-name ${JOB_NAME} --build-id ${BUILD_ID}"
|
||||
emailext attachmentsPattern: '*results*.html',
|
||||
body: '''Hi,
|
||||
|
||||
Here are attached HTML report files for $PROJECT_NAME - Build # $BUILD_NUMBER - $BUILD_STATUS!
|
||||
|
||||
Regards,
|
||||
OAI CI Team''',
|
||||
replyTo: 'no-reply@openairinterface.org',
|
||||
subject: '$PROJECT_NAME - Build # $BUILD_NUMBER - $BUILD_STATUS!',
|
||||
to: gitCommitAuthorEmailAddr
|
||||
|
||||
if (fileExists('.git/CI_COMMIT_MSG')) {
|
||||
sh "rm -f .git/CI_COMMIT_MSG"
|
||||
}
|
||||
}
|
||||
}
|
||||
success {
|
||||
script {
|
||||
def message = "OAI " + JOB_NAME + " build (" + BUILD_ID + "): passed (" + BUILD_URL + ")"
|
||||
if ("MERGE".equals(env.gitlabActionType)) {
|
||||
echo "This is a MERGE event"
|
||||
addGitLabMRComment comment: message
|
||||
}
|
||||
}
|
||||
}
|
||||
failure {
|
||||
script {
|
||||
def message = "OAI " + JOB_NAME + " build (" + BUILD_ID + "): failed (" + BUILD_URL + ")"
|
||||
if ("MERGE".equals(env.gitlabActionType)) {
|
||||
echo "This is a MERGE event"
|
||||
addGitLabMRComment comment: message
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -140,12 +140,6 @@ pipeline {
|
||||
allParametersPresent = false
|
||||
}
|
||||
|
||||
if (params.ADB_IPAddress == null) {
|
||||
allParametersPresent = false
|
||||
}
|
||||
if (params.ADB_Credentials == null) {
|
||||
allParametersPresent = false
|
||||
}
|
||||
if (params.OC_Credentials == null) {
|
||||
allParametersPresent = false
|
||||
}
|
||||
@@ -192,15 +186,14 @@ pipeline {
|
||||
withCredentials([
|
||||
[$class: 'UsernamePasswordMultiBinding', credentialsId: "${params.eNB_Credentials}", usernameVariable: 'eNB_Username', passwordVariable: 'eNB_Password'],
|
||||
[$class: 'UsernamePasswordMultiBinding', credentialsId: "${params.EPC_Credentials}", usernameVariable: 'EPC_Username', passwordVariable: 'EPC_Password'],
|
||||
[$class: 'UsernamePasswordMultiBinding', credentialsId: "${params.ADB_Credentials}", usernameVariable: 'ADB_Username', passwordVariable: 'ADB_Password'],
|
||||
[$class: 'UsernamePasswordMultiBinding', credentialsId: "${params.OC_Credentials}", usernameVariable: 'OC_Username', passwordVariable: 'OC_Password']
|
||||
]) {
|
||||
sh "python3 main.py --mode=InitiateHtml --ranRepository=${eNB_Repository} --ranBranch=${eNB_Branch} --ranCommitID=${eNB_CommitID} --ranAllowMerge=${eNB_AllowMergeRequestProcess} --ranTargetBranch=${eNB_TargetBranch} --ADBIPAddress=${params.ADB_IPAddress} --ADBUserName=${ADB_Username} --ADBPassword=${ADB_Password} ${mainPythonAllXmlFiles}"
|
||||
sh "python3 main.py --mode=InitiateHtml --ranRepository=${eNB_Repository} --ranBranch=${eNB_Branch} --ranCommitID=${eNB_CommitID} --ranAllowMerge=${eNB_AllowMergeRequestProcess} --ranTargetBranch=${eNB_TargetBranch} ${mainPythonAllXmlFiles}"
|
||||
String[] myXmlTestSuite = testXMLFile.split("\\r?\\n")
|
||||
for (xmlFile in myXmlTestSuite) {
|
||||
if (fileExists(xmlFile)) {
|
||||
try {
|
||||
sh "python3 main.py --mode=TesteNB --eNBIPAddress=${params.eNB_IPAddress} --ranRepository=${eNB_Repository} --ranBranch=${eNB_Branch} --ranCommitID=${eNB_CommitID} --ranAllowMerge=${eNB_AllowMergeRequestProcess} --ranTargetBranch=${eNB_TargetBranch} --eNBUserName=${eNB_Username} --eNBPassword=${eNB_Password} --eNBSourceCodePath=${params.eNB_SourceCodePath} --EPCIPAddress=${params.EPC_IPAddress} --EPCType=${params.EPC_Type} --EPCUserName=${EPC_Username} --EPCPassword=${EPC_Password} --EPCSourceCodePath=${params.EPC_SourceCodePath} --ADBIPAddress=${params.ADB_IPAddress} --ADBUserName=${ADB_Username} --ADBPassword=${ADB_Password} --XMLTestFile=${xmlFile} --OCUserName=${OC_Username} --OCPassword=${OC_Password} --OCProjectName=${OC_ProjectName}"
|
||||
sh "python3 main.py --mode=TesteNB --eNBIPAddress=${params.eNB_IPAddress} --ranRepository=${eNB_Repository} --ranBranch=${eNB_Branch} --ranCommitID=${eNB_CommitID} --ranAllowMerge=${eNB_AllowMergeRequestProcess} --ranTargetBranch=${eNB_TargetBranch} --eNBUserName=${eNB_Username} --eNBPassword=${eNB_Password} --eNBSourceCodePath=${params.eNB_SourceCodePath} --EPCIPAddress=${params.EPC_IPAddress} --EPCType=${params.EPC_Type} --EPCUserName=${EPC_Username} --EPCPassword=${EPC_Password} --EPCSourceCodePath=${params.EPC_SourceCodePath} --XMLTestFile=${xmlFile} --OCUserName=${OC_Username} --OCPassword=${OC_Password} --OCProjectName=${OC_ProjectName}"
|
||||
} catch (Exception e) {
|
||||
currentBuild.result = 'FAILURE'
|
||||
buildStageStatus = false
|
||||
|
||||
@@ -77,7 +77,7 @@ pipeline {
|
||||
withCredentials([
|
||||
[$class: 'UsernamePasswordMultiBinding', credentialsId: "${params.DH_Credentials}", usernameVariable: 'DH_Username', passwordVariable: 'DH_Password']
|
||||
]) {
|
||||
def listOfImages = ["oai-enb", "oai-gnb", "oai-lte-ue", "oai-nr-ue"]
|
||||
def listOfImages = ["oai-enb", "oai-gnb", "oai-lte-ue", "oai-nr-ue", "oai-nr-cuup"]
|
||||
// Logging in on both registries
|
||||
sh "docker login -u ${DH_Username} -p ${DH_Password} > /dev/null 2>&1"
|
||||
sh "docker login -u oaicicd -p oaicicd porcepix.sboai.cs.eurecom.fr > /dev/null 2>&1"
|
||||
|
||||
@@ -155,13 +155,6 @@ pipeline {
|
||||
allParametersPresent = false
|
||||
}
|
||||
|
||||
if (params.ADB_IPAddress == null) {
|
||||
allParametersPresent = false
|
||||
}
|
||||
if (params.ADB_Credentials == null) {
|
||||
allParametersPresent = false
|
||||
}
|
||||
|
||||
if (allParametersPresent) {
|
||||
echo "All parameters are present"
|
||||
if (eNB_AllowMergeRequestProcess) {
|
||||
@@ -202,14 +195,13 @@ pipeline {
|
||||
[$class: 'UsernamePasswordMultiBinding', credentialsId: "${params.eNB_Credentials}", usernameVariable: 'eNB_Username', passwordVariable: 'eNB_Password'],
|
||||
[$class: 'UsernamePasswordMultiBinding', credentialsId: "${params.UE_Credentials}", usernameVariable: 'UE_Username', passwordVariable: 'UE_Password'],
|
||||
[$class: 'UsernamePasswordMultiBinding', credentialsId: "${params.EPC_Credentials}", usernameVariable: 'EPC_Username', passwordVariable: 'EPC_Password'],
|
||||
[$class: 'UsernamePasswordMultiBinding', credentialsId: "${params.ADB_Credentials}", usernameVariable: 'ADB_Username', passwordVariable: 'ADB_Password']
|
||||
]) {
|
||||
sh "python3 main.py --mode=InitiateHtml --ranRepository=${eNB_Repository} --ranBranch=${eNB_Branch} --ranCommitID=${eNB_CommitID} --ranAllowMerge=${eNB_AllowMergeRequestProcess} --ranTargetBranch=${eNB_TargetBranch} --ADBIPAddress=${params.ADB_IPAddress} --ADBUserName=${ADB_Username} --ADBPassword=${ADB_Password} ${mainPythonAllXmlFiles}"
|
||||
sh "python3 main.py --mode=InitiateHtml --ranRepository=${eNB_Repository} --ranBranch=${eNB_Branch} --ranCommitID=${eNB_CommitID} --ranAllowMerge=${eNB_AllowMergeRequestProcess} --ranTargetBranch=${eNB_TargetBranch} ${mainPythonAllXmlFiles}"
|
||||
String[] myXmlTestSuite = testXMLFile.split("\\r?\\n")
|
||||
for (xmlFile in myXmlTestSuite) {
|
||||
if (fileExists(xmlFile)) {
|
||||
try {
|
||||
sh "python3 main.py --mode=TesteNB --ranRepository=${eNB_Repository} --ranBranch=${eNB_Branch} --ranCommitID=${eNB_CommitID} --ranAllowMerge=${eNB_AllowMergeRequestProcess} --ranTargetBranch=${eNB_TargetBranch} --eNBIPAddress=${params.eNB_IPAddress} --eNBUserName=${eNB_Username} --eNBPassword=${eNB_Password} --eNBSourceCodePath=${params.eNB_SourceCodePath} --UEIPAddress=${params.UE_IPAddress} --UEUserName=${UE_Username} --UEPassword=${UE_Password} --UESourceCodePath=${params.UE_SourceCodePath} --EPCIPAddress=${params.EPC_IPAddress} --EPCType=${params.EPC_Type} --EPCUserName=${EPC_Username} --EPCPassword=${EPC_Password} --EPCSourceCodePath=${params.EPC_SourceCodePath} --ADBIPAddress=${params.ADB_IPAddress} --ADBUserName=${ADB_Username} --ADBPassword=${ADB_Password} --XMLTestFile=${xmlFile}"
|
||||
sh "python3 main.py --mode=TesteNB --ranRepository=${eNB_Repository} --ranBranch=${eNB_Branch} --ranCommitID=${eNB_CommitID} --ranAllowMerge=${eNB_AllowMergeRequestProcess} --ranTargetBranch=${eNB_TargetBranch} --eNBIPAddress=${params.eNB_IPAddress} --eNBUserName=${eNB_Username} --eNBPassword=${eNB_Password} --eNBSourceCodePath=${params.eNB_SourceCodePath} --UEIPAddress=${params.UE_IPAddress} --UEUserName=${UE_Username} --UEPassword=${UE_Password} --UESourceCodePath=${params.UE_SourceCodePath} --EPCIPAddress=${params.EPC_IPAddress} --EPCType=${params.EPC_Type} --EPCUserName=${EPC_Username} --EPCPassword=${EPC_Password} --EPCSourceCodePath=${params.EPC_SourceCodePath} --XMLTestFile=${xmlFile}"
|
||||
} catch (Exception e) {
|
||||
currentBuild.result = 'FAILURE'
|
||||
buildStageStatus = false
|
||||
|
||||
@@ -150,13 +150,6 @@ pipeline {
|
||||
allParametersPresent = false
|
||||
}
|
||||
|
||||
if (params.ADB_IPAddress == null) {
|
||||
allParametersPresent = false
|
||||
}
|
||||
if (params.ADB_Credentials == null) {
|
||||
allParametersPresent = false
|
||||
}
|
||||
|
||||
if (allParametersPresent) {
|
||||
echo "All parameters are present"
|
||||
if (eNB_AllowMergeRequestProcess) {
|
||||
@@ -198,14 +191,13 @@ pipeline {
|
||||
[$class: 'UsernamePasswordMultiBinding', credentialsId: "${params.eNB1_Credentials}", usernameVariable: 'eNB1_Username', passwordVariable: 'eNB1_Password'],
|
||||
[$class: 'UsernamePasswordMultiBinding', credentialsId: "${params.eNB2_Credentials}", usernameVariable: 'eNB2_Username', passwordVariable: 'eNB2_Password'],
|
||||
[$class: 'UsernamePasswordMultiBinding', credentialsId: "${params.EPC_Credentials}", usernameVariable: 'EPC_Username', passwordVariable: 'EPC_Password'],
|
||||
[$class: 'UsernamePasswordMultiBinding', credentialsId: "${params.ADB_Credentials}", usernameVariable: 'ADB_Username', passwordVariable: 'ADB_Password']
|
||||
]) {
|
||||
sh "python3 main.py --mode=InitiateHtml --ranRepository=${eNB_Repository} --ranBranch=${eNB_Branch} --ranCommitID=${eNB_CommitID} --ranAllowMerge=${eNB_AllowMergeRequestProcess} --ranTargetBranch=${eNB_TargetBranch} --ADBIPAddress=${params.ADB_IPAddress} --ADBUserName=${ADB_Username} --ADBPassword=${ADB_Password} ${mainPythonAllXmlFiles}"
|
||||
sh "python3 main.py --mode=InitiateHtml --ranRepository=${eNB_Repository} --ranBranch=${eNB_Branch} --ranCommitID=${eNB_CommitID} --ranAllowMerge=${eNB_AllowMergeRequestProcess} --ranTargetBranch=${eNB_TargetBranch} ${mainPythonAllXmlFiles}"
|
||||
String[] myXmlTestSuite = testXMLFile.split("\\r?\\n")
|
||||
for (xmlFile in myXmlTestSuite) {
|
||||
if (fileExists(xmlFile)) {
|
||||
try {
|
||||
sh "python3 main.py --mode=TesteNB --ranRepository=${eNB_Repository} --ranBranch=${eNB_Branch} --ranCommitID=${eNB_CommitID} --ranAllowMerge=${eNB_AllowMergeRequestProcess} --ranTargetBranch=${eNB_TargetBranch} --eNBIPAddress=${params.eNB_IPAddress} --eNBUserName=${eNB_Username} --eNBPassword=${eNB_Password} --eNBSourceCodePath=${params.eNB_SourceCodePath} --eNB1IPAddress=${params.eNB1_IPAddress} --eNB1UserName=${eNB1_Username} --eNB1Password=${eNB1_Password} --eNB1SourceCodePath=${params.eNB1_SourceCodePath} --eNB2IPAddress=${params.eNB2_IPAddress} --eNB2UserName=${eNB2_Username} --eNB2Password=${eNB2_Password} --eNB2SourceCodePath=${params.eNB2_SourceCodePath} --EPCIPAddress=${params.EPC_IPAddress} --EPCType=${params.EPC_Type} --EPCUserName=${EPC_Username} --EPCPassword=${EPC_Password} --EPCSourceCodePath=${params.EPC_SourceCodePath} --ADBIPAddress=${params.ADB_IPAddress} --ADBUserName=${ADB_Username} --ADBPassword=${ADB_Password} --XMLTestFile=${xmlFile}"
|
||||
sh "python3 main.py --mode=TesteNB --ranRepository=${eNB_Repository} --ranBranch=${eNB_Branch} --ranCommitID=${eNB_CommitID} --ranAllowMerge=${eNB_AllowMergeRequestProcess} --ranTargetBranch=${eNB_TargetBranch} --eNBIPAddress=${params.eNB_IPAddress} --eNBUserName=${eNB_Username} --eNBPassword=${eNB_Password} --eNBSourceCodePath=${params.eNB_SourceCodePath} --eNB1IPAddress=${params.eNB1_IPAddress} --eNB1UserName=${eNB1_Username} --eNB1Password=${eNB1_Password} --eNB1SourceCodePath=${params.eNB1_SourceCodePath} --eNB2IPAddress=${params.eNB2_IPAddress} --eNB2UserName=${eNB2_Username} --eNB2Password=${eNB2_Password} --eNB2SourceCodePath=${params.eNB2_SourceCodePath} --EPCIPAddress=${params.EPC_IPAddress} --EPCType=${params.EPC_Type} --EPCUserName=${EPC_Username} --EPCPassword=${EPC_Password} --EPCSourceCodePath=${params.EPC_SourceCodePath} --XMLTestFile=${xmlFile}"
|
||||
} catch (Exception e) {
|
||||
currentBuild.result = 'FAILURE'
|
||||
buildStageStatus = false
|
||||
@@ -220,20 +212,6 @@ pipeline {
|
||||
}
|
||||
stage ("Terminate") {
|
||||
parallel {
|
||||
stage('Terminate UE') {
|
||||
// Bypassing this stage if there are no abd server defined
|
||||
when {
|
||||
expression { params.ADB_IPAddress != "none" }
|
||||
}
|
||||
steps {
|
||||
echo '\u2705 \u001B[32mTerminate UE\u001B[0m'
|
||||
withCredentials([
|
||||
[$class: 'UsernamePasswordMultiBinding', credentialsId: "${params.ADB_Credentials}", usernameVariable: 'ADB_Username', passwordVariable: 'ADB_Password']
|
||||
]) {
|
||||
sh "python3 ci-scripts/main.py --mode=TerminateUE --ADBIPAddress=${params.ADB_IPAddress} --ADBUserName=${ADB_Username} --ADBPassword=${ADB_Password}"
|
||||
}
|
||||
}
|
||||
}
|
||||
stage('Terminate eNB') {
|
||||
steps {
|
||||
echo '\u2705 \u001B[32mTerminate eNB\u001B[0m'
|
||||
|
||||
@@ -24,7 +24,6 @@
|
||||
|
||||
// Location of the python executor node shall be in the same subnet as the others servers
|
||||
def pythonExecutor = params.pythonExecutor
|
||||
def DataBaseHost = params.DataBaseHost
|
||||
|
||||
// Location of the test XML file to be run
|
||||
def testXMLFile = params.pythonTestXmlFile
|
||||
@@ -169,16 +168,6 @@ pipeline {
|
||||
allParametersPresent = false
|
||||
}
|
||||
|
||||
if (params.ADB_IPAddress == null) {
|
||||
allParametersPresent = false
|
||||
}
|
||||
if (params.ADB_Credentials == null) {
|
||||
allParametersPresent = false
|
||||
}
|
||||
if (params.DataBaseHost == "none") {
|
||||
DataBaseHost = pythonExecutor
|
||||
}
|
||||
|
||||
if (allParametersPresent) {
|
||||
echo "All parameters are present"
|
||||
if (eNB_AllowMergeRequestProcess) {
|
||||
@@ -220,15 +209,14 @@ pipeline {
|
||||
[$class: 'UsernamePasswordMultiBinding', credentialsId: "${params.eNB1_Credentials}", usernameVariable: 'eNB1_Username', passwordVariable: 'eNB1_Password'],
|
||||
[$class: 'UsernamePasswordMultiBinding', credentialsId: "${params.eNB2_Credentials}", usernameVariable: 'eNB2_Username', passwordVariable: 'eNB2_Password'],
|
||||
[$class: 'UsernamePasswordMultiBinding', credentialsId: "${params.EPC_Credentials}", usernameVariable: 'EPC_Username', passwordVariable: 'EPC_Password'],
|
||||
[$class: 'UsernamePasswordMultiBinding', credentialsId: "${params.ADB_Credentials}", usernameVariable: 'ADB_Username', passwordVariable: 'ADB_Password'],
|
||||
[$class: 'UsernamePasswordMultiBinding', credentialsId: "${params.UE_Credentials}", usernameVariable: 'UE_Username', passwordVariable: 'UE_Password']
|
||||
]) {
|
||||
sh "python3 main.py --mode=InitiateHtml --ranRepository=${eNB_Repository} --ranBranch=${eNB_Branch} --ranCommitID=${eNB_CommitID} --ranAllowMerge=${eNB_AllowMergeRequestProcess} --ranTargetBranch=${eNB_TargetBranch} --ADBIPAddress=${params.ADB_IPAddress} --ADBUserName=${ADB_Username} --ADBPassword=${ADB_Password} ${mainPythonAllXmlFiles}"
|
||||
sh "python3 main.py --mode=InitiateHtml --ranRepository=${eNB_Repository} --ranBranch=${eNB_Branch} --ranCommitID=${eNB_CommitID} --ranAllowMerge=${eNB_AllowMergeRequestProcess} --ranTargetBranch=${eNB_TargetBranch} ${mainPythonAllXmlFiles}"
|
||||
String[] myXmlTestSuite = testXMLFile.split("\\r?\\n")
|
||||
for (xmlFile in myXmlTestSuite) {
|
||||
if (fileExists(xmlFile)) {
|
||||
try {
|
||||
sh "python3 main.py --mode=TesteNB --ranRepository=${eNB_Repository} --ranBranch=${eNB_Branch} --ranCommitID=${eNB_CommitID} --ranAllowMerge=${eNB_AllowMergeRequestProcess} --ranTargetBranch=${eNB_TargetBranch} --eNBIPAddress=${params.eNB_IPAddress} --eNBUserName=${eNB_Username} --eNBPassword=${eNB_Password} --eNBSourceCodePath=${params.eNB_SourceCodePath} --eNB1IPAddress=${params.eNB1_IPAddress} --eNB1UserName=${eNB1_Username} --eNB1Password=${eNB1_Password} --eNB1SourceCodePath=${params.eNB1_SourceCodePath} --eNB2IPAddress=${params.eNB2_IPAddress} --eNB2UserName=${eNB2_Username} --eNB2Password=${eNB2_Password} --eNB2SourceCodePath=${params.eNB2_SourceCodePath} --UEIPAddress=${params.UE_IPAddress} --UEUserName=${UE_Username} --UEPassword=${UE_Password} --UESourceCodePath=${params.UE_SourceCodePath} --EPCIPAddress=${params.EPC_IPAddress} --EPCType=${params.EPC_Type} --EPCUserName=${EPC_Username} --EPCPassword=${EPC_Password} --EPCSourceCodePath=${params.EPC_SourceCodePath} --ADBIPAddress=${params.ADB_IPAddress} --ADBUserName=${ADB_Username} --ADBPassword=${ADB_Password} --XMLTestFile=${xmlFile}"
|
||||
sh "python3 main.py --mode=TesteNB --ranRepository=${eNB_Repository} --ranBranch=${eNB_Branch} --ranCommitID=${eNB_CommitID} --ranAllowMerge=${eNB_AllowMergeRequestProcess} --ranTargetBranch=${eNB_TargetBranch} --eNBIPAddress=${params.eNB_IPAddress} --eNBUserName=${eNB_Username} --eNBPassword=${eNB_Password} --eNBSourceCodePath=${params.eNB_SourceCodePath} --eNB1IPAddress=${params.eNB1_IPAddress} --eNB1UserName=${eNB1_Username} --eNB1Password=${eNB1_Password} --eNB1SourceCodePath=${params.eNB1_SourceCodePath} --eNB2IPAddress=${params.eNB2_IPAddress} --eNB2UserName=${eNB2_Username} --eNB2Password=${eNB2_Password} --eNB2SourceCodePath=${params.eNB2_SourceCodePath} --UEIPAddress=${params.UE_IPAddress} --UEUserName=${UE_Username} --UEPassword=${UE_Password} --UESourceCodePath=${params.UE_SourceCodePath} --EPCIPAddress=${params.EPC_IPAddress} --EPCType=${params.EPC_Type} --EPCUserName=${EPC_Username} --EPCPassword=${EPC_Password} --EPCSourceCodePath=${params.EPC_SourceCodePath} --XMLTestFile=${xmlFile}"
|
||||
} catch (Exception e) {
|
||||
currentBuild.result = 'FAILURE'
|
||||
buildStageStatus = false
|
||||
@@ -364,31 +352,6 @@ pipeline {
|
||||
}
|
||||
}
|
||||
}
|
||||
stage ("SQL Collect"){
|
||||
when {
|
||||
expression { params.DataBaseHost != "none" }
|
||||
}
|
||||
agent {label DataBaseHost}
|
||||
steps {
|
||||
script {
|
||||
if (currentBuild.result=='FAILURE') {StatusForDb = 'FAIL'} else {StatusForDb = 'PASS'}
|
||||
sh "python3 /home/oaicicd/mysql/sql_connect.py ${JOB_NAME} ${params.eNB_MR} ${params.eNB_Branch} ${env.BUILD_ID} ${env.BUILD_URL} ${StatusForDb} ''"
|
||||
}
|
||||
}
|
||||
}
|
||||
stage ("Result Update"){
|
||||
when {
|
||||
expression { params.DataBaseHost != "none" }
|
||||
}
|
||||
agent {label DataBaseHost}
|
||||
steps {
|
||||
script {
|
||||
dir ('ci-scripts/ran_dashboard') {
|
||||
sh "python3 Hdashboard.py testevent ${params.eNB_MR} "
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -89,10 +89,6 @@ pipeline {
|
||||
string(name: 'EPC_Type', defaultValue: 'ltebox', description: 'EPC type: OAI or ltebox')
|
||||
credentials(name: 'EPC_Credentials', defaultValue: 'XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX', credentialType: "Username with password", required: true, description: 'Credentials for EPC')
|
||||
string(name: 'EPC_SourceCodePath', defaultValue: '/tmp/CI-enb', description: 'Full path of EPC source code')
|
||||
|
||||
//ADB server parameters
|
||||
string(name: 'ADB_IPAddress', defaultValue: '192.168.XX.XX', description: 'IP Address of ADB server')
|
||||
credentials(name: 'ADB_Credentials', defaultValue: 'XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX', credentialType: "Username with password", required: true, description: 'Credentials for ADB')
|
||||
}
|
||||
*/
|
||||
|
||||
@@ -171,13 +167,6 @@ pipeline {
|
||||
allParametersPresent = false
|
||||
}
|
||||
|
||||
if (params.ADB_IPAddress == null) {
|
||||
allParametersPresent = false
|
||||
}
|
||||
if (params.ADB_Credentials == null) {
|
||||
allParametersPresent = false
|
||||
}
|
||||
|
||||
if (allParametersPresent) {
|
||||
echo "All parameters are present"
|
||||
if (eNB_AllowMergeRequestProcess) {
|
||||
@@ -217,14 +206,13 @@ pipeline {
|
||||
withCredentials([
|
||||
[$class: 'UsernamePasswordMultiBinding', credentialsId: "${params.eNB_Credentials}", usernameVariable: 'eNB_Username', passwordVariable: 'eNB_Password'],
|
||||
[$class: 'UsernamePasswordMultiBinding', credentialsId: "${params.EPC_Credentials}", usernameVariable: 'EPC_Username', passwordVariable: 'EPC_Password'],
|
||||
[$class: 'UsernamePasswordMultiBinding', credentialsId: "${params.ADB_Credentials}", usernameVariable: 'ADB_Username', passwordVariable: 'ADB_Password']
|
||||
]) {
|
||||
sh "python3 main.py --mode=InitiateHtml --ranRepository=${eNB_Repository} --ranBranch=${eNB_Branch} --ranCommitID=${eNB_CommitID} --ranAllowMerge=${eNB_AllowMergeRequestProcess} --ranTargetBranch=${eNB_TargetBranch} --ADBIPAddress=${params.ADB_IPAddress} --ADBUserName=${ADB_Username} --ADBPassword=${ADB_Password} ${mainPythonAllXmlFiles}"
|
||||
sh "python3 main.py --mode=InitiateHtml --ranRepository=${eNB_Repository} --ranBranch=${eNB_Branch} --ranCommitID=${eNB_CommitID} --ranAllowMerge=${eNB_AllowMergeRequestProcess} --ranTargetBranch=${eNB_TargetBranch} ${mainPythonAllXmlFiles}"
|
||||
String[] myXmlTestSuite = testXMLFile.split("\\r?\\n")
|
||||
for (xmlFile in myXmlTestSuite) {
|
||||
if (fileExists(xmlFile)) {
|
||||
try {
|
||||
sh "python3 main.py --mode=TesteNB --eNBIPAddress=${params.eNB_IPAddress} --ranRepository=${eNB_Repository} --ranBranch=${eNB_Branch} --ranCommitID=${eNB_CommitID} --ranAllowMerge=${eNB_AllowMergeRequestProcess} --ranTargetBranch=${eNB_TargetBranch} --eNBUserName=${eNB_Username} --eNBPassword=${eNB_Password} --eNBSourceCodePath=${params.eNB_SourceCodePath} --EPCIPAddress=${params.EPC_IPAddress} --EPCType=${params.EPC_Type} --EPCUserName=${EPC_Username} --EPCPassword=${EPC_Password} --EPCSourceCodePath=${params.EPC_SourceCodePath} --ADBIPAddress=${params.ADB_IPAddress} --ADBUserName=${ADB_Username} --ADBPassword=${ADB_Password} --XMLTestFile=${xmlFile}"
|
||||
sh "python3 main.py --mode=TesteNB --eNBIPAddress=${params.eNB_IPAddress} --ranRepository=${eNB_Repository} --ranBranch=${eNB_Branch} --ranCommitID=${eNB_CommitID} --ranAllowMerge=${eNB_AllowMergeRequestProcess} --ranTargetBranch=${eNB_TargetBranch} --eNBUserName=${eNB_Username} --eNBPassword=${eNB_Password} --eNBSourceCodePath=${params.eNB_SourceCodePath} --EPCIPAddress=${params.EPC_IPAddress} --EPCType=${params.EPC_Type} --EPCUserName=${EPC_Username} --EPCPassword=${EPC_Password} --EPCSourceCodePath=${params.EPC_SourceCodePath} --XMLTestFile=${xmlFile}"
|
||||
} catch (Exception e) {
|
||||
currentBuild.result = 'FAILURE'
|
||||
buildStageStatus = false
|
||||
@@ -239,27 +227,6 @@ pipeline {
|
||||
}
|
||||
stage ("Terminate") {
|
||||
parallel {
|
||||
stage('Terminate UE') {
|
||||
// Bypassing this stage if there are no abd server defined
|
||||
when {
|
||||
expression { params.ADB_IPAddress != "none" }
|
||||
}
|
||||
steps {
|
||||
echo '\u2705 \u001B[32mTerminate UE\u001B[0m'
|
||||
withCredentials([
|
||||
[$class: 'UsernamePasswordMultiBinding', credentialsId: "${params.ADB_Credentials}", usernameVariable: 'ADB_Username', passwordVariable: 'ADB_Password']
|
||||
]) {
|
||||
sh "python3 ci-scripts/main.py --mode=TerminateUE --ADBIPAddress=${params.ADB_IPAddress} --ADBUserName=${ADB_Username} --ADBPassword=${ADB_Password}"
|
||||
}
|
||||
}
|
||||
post {
|
||||
success {
|
||||
script {
|
||||
termStatusArray[termUE] = true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
stage('Terminate eNB') {
|
||||
steps {
|
||||
echo '\u2705 \u001B[32mTerminate eNB\u001B[0m'
|
||||
@@ -517,13 +484,6 @@ pipeline {
|
||||
// Making sure that we really shutdown every thing before leaving
|
||||
failure {
|
||||
script {
|
||||
if ((!termStatusArray[termUE]) && (params.ADB_IPAddress != "none")) {
|
||||
withCredentials([
|
||||
[$class: 'UsernamePasswordMultiBinding', credentialsId: "${params.ADB_Credentials}", usernameVariable: 'ADB_Username', passwordVariable: 'ADB_Password']
|
||||
]) {
|
||||
sh "python3 ci-scripts/main.py --mode=TerminateUE --ADBIPAddress=${params.ADB_IPAddress} --ADBUserName=${ADB_Username} --ADBPassword=${ADB_Password}"
|
||||
}
|
||||
}
|
||||
if (!termStatusArray[termENB]) {
|
||||
withCredentials([
|
||||
[$class: 'UsernamePasswordMultiBinding', credentialsId: "${params.eNB_Credentials}", usernameVariable: 'eNB_Username', passwordVariable: 'eNB_Password']
|
||||
|
||||
@@ -142,13 +142,6 @@ pipeline {
|
||||
allParametersPresent = false
|
||||
}
|
||||
*/
|
||||
if (params.ADB_IPAddress == null) {
|
||||
allParametersPresent = false
|
||||
}
|
||||
if (params.ADB_Credentials == null) {
|
||||
allParametersPresent = false
|
||||
}
|
||||
|
||||
if (allParametersPresent) {
|
||||
echo "All parameters are present"
|
||||
if (eNB_AllowMergeRequestProcess) {
|
||||
@@ -187,14 +180,13 @@ pipeline {
|
||||
}
|
||||
withCredentials([
|
||||
[$class: 'UsernamePasswordMultiBinding', credentialsId: "${params.UE_Credentials}", usernameVariable: 'UE_Username', passwordVariable: 'UE_Password'],
|
||||
[$class: 'UsernamePasswordMultiBinding', credentialsId: "${params.ADB_Credentials}", usernameVariable: 'ADB_Username', passwordVariable: 'ADB_Password']
|
||||
]) {
|
||||
sh "python3 main.py --mode=InitiateHtml --ranRepository=${eNB_Repository} --ranBranch=${eNB_Branch} --ranCommitID=${eNB_CommitID} --ranAllowMerge=${eNB_AllowMergeRequestProcess} --ranTargetBranch=${eNB_TargetBranch} --ADBIPAddress=${params.ADB_IPAddress} --ADBUserName=${ADB_Username} --ADBPassword=${ADB_Password} ${mainPythonAllXmlFiles}"
|
||||
sh "python3 main.py --mode=InitiateHtml --ranRepository=${eNB_Repository} --ranBranch=${eNB_Branch} --ranCommitID=${eNB_CommitID} --ranAllowMerge=${eNB_AllowMergeRequestProcess} --ranTargetBranch=${eNB_TargetBranch} ${mainPythonAllXmlFiles}"
|
||||
String[] myXmlTestSuite = testXMLFile.split("\\r?\\n")
|
||||
for (xmlFile in myXmlTestSuite) {
|
||||
if (fileExists(xmlFile)) {
|
||||
try {
|
||||
sh "python3 main.py --mode=TestUE --UEIPAddress=${params.UE_IPAddress} --ranRepository=${eNB_Repository} --ranBranch=${eNB_Branch} --ranCommitID=${eNB_CommitID} --ranAllowMerge=${eNB_AllowMergeRequestProcess} --ranTargetBranch=${eNB_TargetBranch} --UEUserName=${UE_Username} --UEPassword=${UE_Password} --UESourceCodePath=${params.UE_SourceCodePath} --ADBIPAddress=${params.ADB_IPAddress} --ADBUserName=${ADB_Username} --ADBPassword=${ADB_Password} --XMLTestFile=${xmlFile}"
|
||||
sh "python3 main.py --mode=TestUE --UEIPAddress=${params.UE_IPAddress} --ranRepository=${eNB_Repository} --ranBranch=${eNB_Branch} --ranCommitID=${eNB_CommitID} --ranAllowMerge=${eNB_AllowMergeRequestProcess} --ranTargetBranch=${eNB_TargetBranch} --UEUserName=${UE_Username} --UEPassword=${UE_Password} --UESourceCodePath=${params.UE_SourceCodePath} --XMLTestFile=${xmlFile}"
|
||||
} catch (Exception e) {
|
||||
currentBuild.result = 'FAILURE'
|
||||
buildStageStatus = false
|
||||
|
||||
@@ -227,23 +227,13 @@ def ArgsParse(argvs,CiTestObj,RAN,HTML,EPC,ldpc,CONTAINERS,HELP,SCA,PHYSIM,CLUST
|
||||
matchReg = re.match('^\-\-EPCContainerPrefix=(.+)$', myArgv, re.IGNORECASE)
|
||||
EPC.ContainerPrefix=matchReg.group(1)
|
||||
elif re.match('^\-\-ADBIPAddress=(.+)$', myArgv, re.IGNORECASE):
|
||||
matchReg = re.match('^\-\-ADBIPAddress=(.+)$', myArgv, re.IGNORECASE)
|
||||
CiTestObj.ADBIPAddress = matchReg.group(1)
|
||||
print("ignoring --ADBIPAddress parameter")
|
||||
elif re.match('^\-\-ADBUserName=(.+)$', myArgv, re.IGNORECASE):
|
||||
matchReg = re.match('^\-\-ADBUserName=(.+)$', myArgv, re.IGNORECASE)
|
||||
CiTestObj.ADBUserName = matchReg.group(1)
|
||||
print("ignoring --ADBUserName parameter")
|
||||
elif re.match('^\-\-ADBType=(.+)$', myArgv, re.IGNORECASE):
|
||||
matchReg = re.match('^\-\-ADBType=(.+)$', myArgv, re.IGNORECASE)
|
||||
if re.match('centralized', matchReg.group(1), re.IGNORECASE) or re.match('distributed', matchReg.group(1), re.IGNORECASE):
|
||||
if re.match('distributed', matchReg.group(1), re.IGNORECASE):
|
||||
CiTestObj.ADBCentralized = False
|
||||
else:
|
||||
CiTestObj.ADBCentralized = True
|
||||
else:
|
||||
sys.exit('Invalid ADB Type: ' + matchReg.group(1) + ' -- (should be centralized or distributed)')
|
||||
print("ignoring --ADBType parameter")
|
||||
elif re.match('^\-\-ADBPassword=(.+)$', myArgv, re.IGNORECASE):
|
||||
matchReg = re.match('^\-\-ADBPassword=(.+)$', myArgv, re.IGNORECASE)
|
||||
CiTestObj.ADBPassword = matchReg.group(1)
|
||||
print("ignoring --ADBPassword parameter")
|
||||
elif re.match('^\-\-XMLTestFile=(.+)$', myArgv, re.IGNORECASE):
|
||||
matchReg = re.match('^\-\-XMLTestFile=(.+)$', myArgv, re.IGNORECASE)
|
||||
CiTestObj.testXMLfiles.append(matchReg.group(1))
|
||||
|
||||
@@ -1,7 +0,0 @@
|
||||
#!/bin/bash
|
||||
while true
|
||||
do
|
||||
echo "gNB will be started automatically..."
|
||||
sleep 1
|
||||
sudo .././cmake_targets/ran_build/build/nr-softmodem -E -O ../targets/PROJECTS/GENERIC-LTE-EPC/CONF/testing_gnb.conf
|
||||
done
|
||||
@@ -1,236 +0,0 @@
|
||||
#!/bin/bash
|
||||
#/*
|
||||
# * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
|
||||
# * contributor license agreements. See the NOTICE file distributed with
|
||||
# * this work for additional information regarding copyright ownership.
|
||||
# * The OpenAirInterface Software Alliance licenses this file to You under
|
||||
# * the OAI Public License, Version 1.1 (the "License"); you may not use this file
|
||||
# * except in compliance with the License.
|
||||
# * You may obtain a copy of the License at
|
||||
# *
|
||||
# * http://www.openairinterface.org/?page_id=698
|
||||
# *
|
||||
# * Unless required by applicable law or agreed to in writing, software
|
||||
# * distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# * See the License for the specific language governing permissions and
|
||||
# * limitations under the License.
|
||||
# *-------------------------------------------------------------------------------
|
||||
# * For more information about the OpenAirInterface (OAI) Software Alliance:
|
||||
# * contact@openairinterface.org
|
||||
# */
|
||||
|
||||
function build_usage {
|
||||
echo "OAI CI VM script"
|
||||
echo " Original Author: Raphael Defosseux"
|
||||
echo " Requirements:"
|
||||
echo " -- uvtool uvtool-libvirt apt-cacher"
|
||||
echo " -- $VM_OSREL image already synced"
|
||||
echo " Default:"
|
||||
echo " -- eNB with USRP"
|
||||
echo ""
|
||||
echo "Usage:"
|
||||
echo "------"
|
||||
echo " oai-ci-vm-tool build [OPTIONS]"
|
||||
echo ""
|
||||
command_options_usage
|
||||
|
||||
}
|
||||
|
||||
function build_on_vm {
|
||||
if [ ! -f $JENKINS_WKSP/localZip.zip ]
|
||||
then
|
||||
echo "Missing localZip.zip file!"
|
||||
STATUS=1
|
||||
return
|
||||
fi
|
||||
if [[ ! -f /etc/apt/apt.conf.d/01proxy ]] && [[ "$OPTIONAL_APTCACHER" != "true" ]]
|
||||
then
|
||||
echo "Missing /etc/apt/apt.conf.d/01proxy file!"
|
||||
echo "Is apt-cacher installed and configured?"
|
||||
STATUS=1
|
||||
return
|
||||
fi
|
||||
|
||||
echo "############################################################"
|
||||
echo "OAI CI VM script"
|
||||
echo "############################################################"
|
||||
|
||||
echo "VM_NAME = $VM_NAME"
|
||||
echo "VM_CMD_FILE = $VM_CMDS"
|
||||
echo "JENKINS_WKSP = $JENKINS_WKSP"
|
||||
echo "ARCHIVES_LOC = $ARCHIVES_LOC"
|
||||
echo "BUILD_OPTIONS = $BUILD_OPTIONS"
|
||||
|
||||
if [[ "$VM_NAME" == *"-enb-usrp"* ]] || [[ "$VM_NAME" == *"-cppcheck"* ]] || [[ "$VM_NAME" == *"-phy-sim"* ]] || [[ "$VM_NAME" == *"-basic-sim"* ]] || [[ "$VM_NAME" == *"-flexran-rtc"* ]] || [[ "$VM_NAME" == *"-rf-sim"* ]] || [[ "$VM_NAME" == *"-ethernet"* ]] || [[ "$VM_NAME" == *"rf5g-sim"* ]] || [[ "$VM_NAME" == *"gnb-usrp"* ]] || [[ "$VM_NAME" == *"nr-ue-usrp"* ]]
|
||||
then
|
||||
echo "This VM type is no longer supported in the pipeline framework"
|
||||
return
|
||||
fi
|
||||
|
||||
IS_VM_ALIVE=`uvt-kvm list | grep -c $VM_NAME`
|
||||
|
||||
if [ $IS_VM_ALIVE -eq 0 ]
|
||||
then
|
||||
echo "VM_MEMORY = $VM_MEMORY MBytes"
|
||||
echo "VM_CPU = $VM_CPU"
|
||||
echo "VM_DISK = $VM_DISK GBytes"
|
||||
echo "############################################################"
|
||||
echo "Creating VM ($VM_NAME) on Ubuntu Cloud Image base"
|
||||
echo "############################################################"
|
||||
acquire_vm_create_lock
|
||||
uvt-kvm create $VM_NAME release=$VM_OSREL --memory $VM_MEMORY --cpu $VM_CPU --disk $VM_DISK --unsafe-caching --template ci-scripts/template-host.xml
|
||||
echo "Waiting for VM to be started"
|
||||
uvt-kvm wait $VM_NAME --insecure
|
||||
|
||||
VM_IP_ADDR=`uvt-kvm ip $VM_NAME`
|
||||
echo "$VM_NAME has for IP addr = $VM_IP_ADDR"
|
||||
release_vm_create_lock
|
||||
else
|
||||
echo "Waiting for VM to be started"
|
||||
uvt-kvm wait $VM_NAME --insecure
|
||||
|
||||
VM_IP_ADDR=`uvt-kvm ip $VM_NAME`
|
||||
echo "$VM_NAME has for IP addr = $VM_IP_ADDR"
|
||||
fi
|
||||
|
||||
echo "############################################################"
|
||||
echo "Copying GIT repo into VM ($VM_NAME)"
|
||||
echo "############################################################"
|
||||
if [[ "$VM_NAME" == *"-flexran-rtc"* ]]
|
||||
then
|
||||
scp -o StrictHostKeyChecking=no $JENKINS_WKSP/flexran/flexran.zip ubuntu@$VM_IP_ADDR:/home/ubuntu/localZip.zip
|
||||
else
|
||||
scp -o StrictHostKeyChecking=no $JENKINS_WKSP/localZip.zip ubuntu@$VM_IP_ADDR:/home/ubuntu
|
||||
fi
|
||||
[ -f /etc/apt/apt.conf.d/01proxy ] && scp -o StrictHostKeyChecking=no /etc/apt/apt.conf.d/01proxy ubuntu@$VM_IP_ADDR:/home/ubuntu
|
||||
|
||||
echo "############################################################"
|
||||
echo "Running install and build script on VM ($VM_NAME)"
|
||||
echo "############################################################"
|
||||
echo "[ -f 01proxy ] && sudo cp 01proxy /etc/apt/apt.conf.d/" > $VM_CMDS
|
||||
echo "touch /home/ubuntu/.hushlogin" >> $VM_CMDS
|
||||
echo "git config --global https.postBuffer 123289600" >> $VM_CMDS
|
||||
if [[ "$VM_NAME" == *"-cppcheck"* ]]
|
||||
then
|
||||
if [ $DAEMON -eq 0 ]
|
||||
then
|
||||
echo "echo \"sudo apt-get --yes --quiet install zip cppcheck \"" >> $VM_CMDS
|
||||
echo "sudo apt-get update > zip-install.txt 2>&1" >> $VM_CMDS
|
||||
echo "sudo apt-get --yes install zip cppcheck >> zip-install.txt 2>&1" >> $VM_CMDS
|
||||
else
|
||||
echo "echo \"sudo apt-get --yes --quiet install zip daemon cppcheck \"" >> $VM_CMDS
|
||||
echo "sudo apt-get update > zip-install.txt 2>&1" >> $VM_CMDS
|
||||
echo "sudo apt-get --yes install zip daemon cppcheck >> zip-install.txt 2>&1" >> $VM_CMDS
|
||||
fi
|
||||
fi
|
||||
if [[ "$VM_NAME" == *"-flexran-rtc"* ]]
|
||||
then
|
||||
if [ $DAEMON -eq 0 ]
|
||||
then
|
||||
echo "echo \"sudo apt-get --yes --quiet install zip curl jq \"" >> $VM_CMDS
|
||||
echo "sudo apt-get update > zip-install.txt 2>&1" >> $VM_CMDS
|
||||
echo "sudo apt-get --yes install zip curl jq >> zip-install.txt 2>&1" >> $VM_CMDS
|
||||
else
|
||||
echo "echo \"sudo apt-get --yes --quiet install zip daemon curl jq \"" >> $VM_CMDS
|
||||
echo "sudo apt-get update > zip-install.txt 2>&1" >> $VM_CMDS
|
||||
echo "sudo apt-get --yes install zip daemon curl jq >> zip-install.txt 2>&1" >> $VM_CMDS
|
||||
fi
|
||||
fi
|
||||
if [[ "$VM_NAME" != *"-cppcheck"* ]] && [[ "$VM_NAME" != *"-flexran-rtc"* ]]
|
||||
then
|
||||
if [ $DAEMON -eq 0 ]
|
||||
then
|
||||
echo "echo \"sudo apt-get --yes --quiet install zip subversion libboost-dev \"" >> $VM_CMDS
|
||||
echo "sudo apt-get update > zip-install.txt 2>&1" >> $VM_CMDS
|
||||
if [[ "$VM_NAME" == *"-phy-sim"* ]]
|
||||
then
|
||||
echo "sudo apt-get --yes install zip subversion libboost-dev make gcc >> zip-install.txt 2>&1" >> $VM_CMDS
|
||||
else
|
||||
echo "sudo apt-get --yes install zip subversion libboost-dev >> zip-install.txt 2>&1" >> $VM_CMDS
|
||||
fi
|
||||
else
|
||||
echo "echo \"sudo apt-get --yes --quiet install zip daemon subversion libboost-dev \"" >> $VM_CMDS
|
||||
echo "sudo apt-get update > zip-install.txt 2>&1" >> $VM_CMDS
|
||||
if [[ "$VM_NAME" == *"-phy-sim"* ]]
|
||||
then
|
||||
echo "sudo apt-get --yes install zip daemon subversion libboost-dev make gcc >> zip-install.txt 2>&1" >> $VM_CMDS
|
||||
else
|
||||
echo "sudo apt-get --yes install zip daemon subversion libboost-dev >> zip-install.txt 2>&1" >> $VM_CMDS
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
echo "mkdir tmp" >> $VM_CMDS
|
||||
echo "cd tmp" >> $VM_CMDS
|
||||
echo "echo \"unzip -qq -DD ../localZip.zip\"" >> $VM_CMDS
|
||||
echo "unzip -qq -DD ../localZip.zip" >> $VM_CMDS
|
||||
# Trying to make some room on filesystem before building
|
||||
echo "rm ../localZip.zip" >> $VM_CMDS
|
||||
echo "export CI_ENV=True" >> $VM_CMDS
|
||||
if [[ "$VM_NAME" == *"-cppcheck"* ]]
|
||||
then
|
||||
echo "mkdir cmake_targets/log" >> $VM_CMDS
|
||||
echo "chmod 777 cmake_targets/log" >> $VM_CMDS
|
||||
echo "cp /home/ubuntu/zip-install.txt cmake_targets/log" >> $VM_CMDS
|
||||
echo "echo \"cppcheck $BUILD_OPTIONS . \"" >> $VM_CMDS
|
||||
if [ $DAEMON -eq 0 ]
|
||||
then
|
||||
echo "cppcheck $BUILD_OPTIONS . 2> cmake_targets/log/cppcheck.xml 1> cmake_targets/log/cppcheck_build.txt" >> $VM_CMDS
|
||||
else
|
||||
echo "echo \"cppcheck $BUILD_OPTIONS .\" > ./my-vm-build.sh" >> $VM_CMDS
|
||||
echo "chmod 775 ./my-vm-build.sh " >> $VM_CMDS
|
||||
echo "sudo -E daemon --inherit --unsafe --name=build_daemon --chdir=/home/ubuntu/tmp -O /home/ubuntu/tmp/cmake_targets/log/cppcheck_build.txt -E /home/ubuntu/tmp/cmake_targets/log/cppcheck.xml ./my-vm-build.sh" >> $VM_CMDS
|
||||
fi
|
||||
fi
|
||||
if [[ "$VM_NAME" == *"-flexran-rtc"* ]]
|
||||
then
|
||||
echo "mkdir -p cmake_targets/log" >> $VM_CMDS
|
||||
echo "chmod 777 cmake_targets/log" >> $VM_CMDS
|
||||
echo "cp /home/ubuntu/zip-install.txt cmake_targets/log" >> $VM_CMDS
|
||||
# Patching the pistache build for Xenial (cmake too old for new commits)
|
||||
echo "sed -i -e 's@cd pistache@cd pistache \&\& git checkout -f 9a65f40975fafca5bb5370ba6d0d00f42cbc4356@' ./tools/install_dependencies" >> $VM_CMDS
|
||||
echo "echo \"./tools/install_dependencies \"" >> $VM_CMDS
|
||||
echo "./tools/install_dependencies > cmake_targets/log/install-build.txt 2>&1" >> $VM_CMDS
|
||||
echo "echo \"mkdir build\"" >> $VM_CMDS
|
||||
echo "mkdir build" >> $VM_CMDS
|
||||
echo "echo \"cd build\"" >> $VM_CMDS
|
||||
echo "cd build" >> $VM_CMDS
|
||||
echo "echo \"$BUILD_OPTIONS \"" >> $VM_CMDS
|
||||
echo "$BUILD_OPTIONS > ../cmake_targets/log/rt_controller.txt 2>&1" >> $VM_CMDS
|
||||
fi
|
||||
if [[ "$VM_NAME" != *"-cppcheck"* ]] && [[ "$VM_NAME" != *"-flexran-rtc"* ]]
|
||||
then
|
||||
echo "echo \"source oaienv\"" >> $VM_CMDS
|
||||
echo "source oaienv" >> $VM_CMDS
|
||||
if [[ "$VM_NAME" == *"-phy-sim"* ]]
|
||||
then
|
||||
echo "cd common/utils/T" >> $VM_CMDS
|
||||
echo "make" >> $VM_CMDS
|
||||
echo "cd ../../.." >> $VM_CMDS
|
||||
fi
|
||||
echo "cd cmake_targets/" >> $VM_CMDS
|
||||
echo "mkdir log" >> $VM_CMDS
|
||||
echo "chmod 777 log" >> $VM_CMDS
|
||||
echo "cp /home/ubuntu/zip-install.txt log" >> $VM_CMDS
|
||||
if [ $DAEMON -eq 0 ]
|
||||
then
|
||||
echo "echo \"./build_oai -I $BUILD_OPTIONS \"" >> $VM_CMDS
|
||||
echo "./build_oai -I $BUILD_OPTIONS > log/install-build.txt 2>&1" >> $VM_CMDS
|
||||
else
|
||||
if [[ "$VM_NAME" == *"-enb-ethernet"* ]]
|
||||
then
|
||||
echo "echo \"sleep 170 && ./build_oai -I $BUILD_OPTIONS\" > ./my-vm-build.sh" >> $VM_CMDS
|
||||
elif [[ "$VM_NAME" == *"-ue-ethernet"* ]]
|
||||
then
|
||||
echo "echo \"sleep 60 && ./build_oai -I $BUILD_OPTIONS\" > ./my-vm-build.sh" >> $VM_CMDS
|
||||
else
|
||||
echo "echo \"./build_oai -I $BUILD_OPTIONS\" > ./my-vm-build.sh" >> $VM_CMDS
|
||||
fi
|
||||
echo "chmod 775 ./my-vm-build.sh " >> $VM_CMDS
|
||||
echo "echo \"sudo -E daemon --inherit --unsafe --name=build_daemon --chdir=/home/ubuntu/tmp/cmake_targets -o /home/ubuntu/tmp/cmake_targets/log/install-build.txt ./my-vm-build.sh\"" >> $VM_CMDS
|
||||
echo "sudo -E daemon --inherit --unsafe --name=build_daemon --chdir=/home/ubuntu/tmp/cmake_targets -o /home/ubuntu/tmp/cmake_targets/log/install-build.txt ./my-vm-build.sh" >> $VM_CMDS
|
||||
fi
|
||||
fi
|
||||
ssh -T -o StrictHostKeyChecking=no ubuntu@$VM_IP_ADDR < $VM_CMDS
|
||||
rm -f $VM_CMDS
|
||||
}
|
||||
@@ -39,10 +39,6 @@ def main():
|
||||
'--ranAllowMerge=' + params['ranAllowMerge'] + ' ' + \
|
||||
'--ranTargetBranch=' + params['ranTargetBranch'] + ' ' + \
|
||||
\
|
||||
'--ADBIPAddress=' + params['ADB']['ADBIPAddress'] + ' ' + \
|
||||
'--ADBUserName=' + params['ADB']['ADBUserName'] + ' ' + \
|
||||
'--ADBPassword=' + params['ADB']['ADBPassword'] + ' ' + \
|
||||
\
|
||||
'--UEIPAddress=' + params['UE']['UEIPAddress'] + ' ' + \
|
||||
'--UEUserName=' + params['UE']['UEUserName'] + ' ' + \
|
||||
'--UEPassword=' + params['UE']['UEPassword'] + ' ' + \
|
||||
|
||||
@@ -12,12 +12,6 @@ steps:
|
||||
- TesteNB,xml_files/fr1_nsa_base_next.xml #ue toggle, nodes initialize, ue toggle, ping, nodes terminate
|
||||
- TesteNB,xml_files/fr1_epc_closure.xml
|
||||
|
||||
|
||||
ADB: #on Caracal
|
||||
ADBIPAddress : 172.21.16.132
|
||||
ADBUserName : oaici
|
||||
ADBPassword : KkexF6CErOi1fNuebCPsuIVK
|
||||
|
||||
RAN:
|
||||
- eNBIPAddress : 192.168.18.199 #eNB on Minimassive
|
||||
eNBUserName : oaicicd
|
||||
|
||||
55
ci-scripts/ci_ctl_adb.sh
Executable file
55
ci-scripts/ci_ctl_adb.sh
Executable file
@@ -0,0 +1,55 @@
|
||||
#!/bin/bash
|
||||
|
||||
usage() {
|
||||
echo "usage: $0 <command> <id>"
|
||||
echo "available commands: initialize, attach, detach, terminate, check"
|
||||
}
|
||||
|
||||
if [ $# -ne 2 ]; then
|
||||
usage
|
||||
exit 1
|
||||
fi
|
||||
|
||||
cmd=$1
|
||||
id=$2
|
||||
|
||||
flightmode_off() {
|
||||
set +x
|
||||
adb -s $id shell "/data/local/tmp/on"
|
||||
}
|
||||
|
||||
flightmode_on() {
|
||||
set +x
|
||||
adb -s $id shell "/data/local/tmp/off"
|
||||
}
|
||||
|
||||
initialize() {
|
||||
set +x
|
||||
adb -s $id shell "svc data enable" # make sure data services are enabled
|
||||
flightmode_on
|
||||
}
|
||||
|
||||
terminate() {
|
||||
echo "terminate: does nothing"
|
||||
}
|
||||
|
||||
check() {
|
||||
declare -A service=( ["0"]="IN_SERVICE" ["1"]="OUT_OF_SERVICE" ["2"]="EMERGENCY_ONLY" ["3"]="RADIO_POWERED_OFF")
|
||||
declare -A data=( ["0"]="DISCONNECTED" ["1"]="CONNECTING" ["2"]="CONNECTED" ["3"]="SUSPENDED")
|
||||
serv_idx=$(adb -s $id shell "dumpsys telephony.registry" | sed -n 's/.*mServiceState=\([0-3]\).*/\1/p')
|
||||
data_idx=$(adb -s $id shell "dumpsys telephony.registry" | sed -n 's/.*mDataConnectionState=\([0-3]\).*/\1/p')
|
||||
data_reason=$(adb -s $id shell "dumpsys telephony.registry" | sed -n 's/.*mDataConnectionReason=\([0-9a-zA-Z_]\+\).*/\1/p')
|
||||
#echo "Status Check UE $id"
|
||||
echo "Service State: ${service[$serv_idx]}"
|
||||
echo "Data State: ${data[$data_idx]}"
|
||||
echo "Data Reason: ${data_reason}"
|
||||
}
|
||||
|
||||
case "${cmd}" in
|
||||
initialize) initialize;;
|
||||
attach) flightmode_off;;
|
||||
detach) flightmode_on;;
|
||||
terminate) terminate;;
|
||||
check) check;;
|
||||
*) echo "Invalid command $cmd"; usage; exit 1;;
|
||||
esac
|
||||
@@ -33,7 +33,6 @@ import sys
|
||||
import time
|
||||
import serial
|
||||
|
||||
|
||||
class qtel_ctl:
|
||||
#---------------
|
||||
#private methods
|
||||
@@ -75,12 +74,15 @@ class qtel_ctl:
|
||||
self.__set_modem_state(self.modem,'0')
|
||||
|
||||
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
#argv[1] : usb port
|
||||
#argv[2] : qtel command (see function pointers dict "wup", "detach" etc ...)
|
||||
command = sys.argv[2]
|
||||
Module=qtel_ctl(sys.argv[1])
|
||||
if len(sys.argv) >= 3:
|
||||
command = sys.argv[2]
|
||||
print(command)
|
||||
Module=qtel_ctl(sys.argv[1])
|
||||
#calling the function to be applied
|
||||
Module.cmd_dict[command]()
|
||||
Module.cmd_dict[command]()
|
||||
print(Module.cmd_dict[command])
|
||||
else:
|
||||
print("To many arguments")
|
||||
|
||||
@@ -1,106 +1,128 @@
|
||||
idefix:
|
||||
ID: idefix
|
||||
State : enabled
|
||||
Kind : quectel
|
||||
Process :
|
||||
Name : quectel-CM
|
||||
Cmd : /home/oaicicd/quectel-CM/quectel-CM -4 -s
|
||||
Apn :
|
||||
ltebox : oai.ipv4
|
||||
WakeupScript : ci_ctl_qtel.py /dev/ttyUSB2 wup
|
||||
DetachScript : ci_ctl_qtel.py /dev/ttyUSB2 detach
|
||||
LogStore : /media/usb-drive/ci_qlogs
|
||||
PLMN : 22201
|
||||
UENetwork : wwan0
|
||||
HostIPAddress : 172.21.16.135
|
||||
HostUsername : oaicicd
|
||||
HostPassword : oaicicd
|
||||
HostSourceCodePath : none
|
||||
MTU : 1500
|
||||
Host: idefix
|
||||
InitScript: sudo stdbuf -oL /home/oaicicd/quectel-CM/quectel-CM -4 -s oai.ipv4 &> /tmp/quectel-cm.log &
|
||||
TermScript: sudo -S killall --signal SIGKILL quectel-CM
|
||||
AttachScript: sudo python3 ci_ctl_qtel.py /dev/ttyUSB2 wup
|
||||
DetachScript: sudo python3 ci_ctl_qtel.py /dev/ttyUSB2 detach
|
||||
UENetworkScript: ip a show dev wwan0
|
||||
IF: wwan0
|
||||
MTU: 1500
|
||||
Trace: True
|
||||
LogStore: /media/usb-drive/ci_qlogs
|
||||
nrmodule2_quectel:
|
||||
ID: nrmodule2_quectel
|
||||
State : enabled
|
||||
Kind : quectel
|
||||
Process :
|
||||
Name : quectel-CM
|
||||
Cmd : /home/nrmodule2/quectel-CM/quectel-CM -4 -s
|
||||
Apn :
|
||||
OAICN5G : oai
|
||||
OAI-Rel14-Docker : oai.ipv4
|
||||
WakeupScript : ci_ctl_qtel.py /dev/ttyUSB2 wup
|
||||
DetachScript : ci_ctl_qtel.py /dev/ttyUSB2 detach
|
||||
LogStore : /media/ci_qlogs
|
||||
PLMN : 20897
|
||||
UENetwork : wwan0
|
||||
HostIPAddress : 172.21.16.139
|
||||
HostUsername : nrmodule2
|
||||
HostPassword : linux
|
||||
HostSourceCodePath : none
|
||||
StartCommands :
|
||||
- sudo -S ip link set dev wwan1 mtu 1500
|
||||
MTU : 1500
|
||||
Host: nrmodule2
|
||||
InitScript: sudo stdbuf -oL /home/nrmodule2/quectel-CM/quectel-CM -4 -s oai.ipv4 &> /tmp/quecel-cm.log &
|
||||
TermScript: sudo -S killall --signal SIGKILL quectel-CM
|
||||
AttachScript: sudo python3 ci_ctl_qtel.py /dev/ttyUSB2 wup
|
||||
DetachScript: sudo python3 ci_ctl_qtel.py /dev/ttyUSB2 detach
|
||||
UENetworkScript: ip a show dev wwan0
|
||||
IF: wwan0
|
||||
MTU: 1500
|
||||
LogStore: /media/ci_qlogs
|
||||
|
||||
# CAUTION: 192.168.18.89 address has to be changed when the server is moved
|
||||
#single UE single ping
|
||||
adb_ue_1:
|
||||
Host: nano
|
||||
InitScript: /home/oaicicd/ci_ctl_adb.sh initialize R3CM40LZPHT
|
||||
TermScript: /home/oaicicd/ci_ctl_adb.sh terminate R3CM40LZPHT
|
||||
AttachScript: /home/oaicicd/ci_ctl_adb.sh attach R3CM40LZPHT
|
||||
DetachScript: /home/oaicicd/ci_ctl_adb.sh detach R3CM40LZPHT
|
||||
CheckStatusScript: /home/oaicicd/ci_ctl_adb.sh check R3CM40LZPHT
|
||||
DataEnableScript: adb -s R3CM40LZPHT shell "svc data enable"
|
||||
DataDisableScript: adb -s R3CM40LZPHT shell "svc data disable"
|
||||
UENetworkScript: adb -s R3CM40LZPHT shell "ip address show | grep rmnet_data0"
|
||||
CmdPrefix: adb -s R3CM40LZPHT shell
|
||||
MTU: 1500
|
||||
LogStore: /media/usb-drive/ci_adb_1-logs
|
||||
adb_ue_2:
|
||||
Host: nano
|
||||
InitScript: /home/oaicicd/ci_ctl_adb.sh initialize 5200c00db4413517
|
||||
TermScript: /home/oaicicd/ci_ctl_adb.sh terminate 5200c00db4413517
|
||||
AttachScript: /home/oaicicd/ci_ctl_adb.sh attach 5200c00db4413517
|
||||
DetachScript: /home/oaicicd/ci_ctl_adb.sh detach 5200c00db4413517
|
||||
CheckStatusScript: /home/oaicicd/ci_ctl_adb.sh check 5200c00db4413517
|
||||
DataEnableScript: adb -s 5200c00db4413517 shell "svc data enable"
|
||||
DataDisableScript: adb -s 5200c00db4413517 shell "svc data disable"
|
||||
UENetworkScript: adb -s 5200c00db4413517 shell "ip address show | grep rmnet"
|
||||
CmdPrefix: adb -s 5200c00db4413517 shell
|
||||
MTU: 1500
|
||||
LogStore: /media/usb-drive/ci_adb_2-logs
|
||||
|
||||
amarisoft_ue:
|
||||
Host: amariue
|
||||
InitScript: nohup /root/NV18-06-2022/ue/lteue /root/NV18-06-2022/ue/config/oaicicd-ue-ci-test.cfg &
|
||||
TermScript: /root/NV18-06-2022/lteue-linux-2022-06-18/doc/ws.js 127.0.0.1:9002 '{"message":"quit"}'
|
||||
amarisoft_ue_1:
|
||||
ID: amarisoft_ue_1
|
||||
State : enabled
|
||||
Kind : amarisoft
|
||||
#not required for AS config but needed for py script
|
||||
WakeupScript : none
|
||||
DetachScript : none
|
||||
#end
|
||||
Cmd : /root/NV18-06-2022/ue/lteue
|
||||
Config : /root/NV17-12-21/ue/config/oaicicd-ue-Ping-SATest.cfg
|
||||
Duration : 60
|
||||
Ping : /tmp/test_ue1.log
|
||||
UELog : /tmp/ue1.log
|
||||
HostIPAddress : 172.21.16.144
|
||||
HostUsername : root
|
||||
HostPassword : toor
|
||||
HostSourceCodePath : /tmp
|
||||
|
||||
|
||||
#an other scenario example
|
||||
#notice : this will not work as such, only suggestion for multi ue scenario
|
||||
Host: amariue
|
||||
AttachScript: /root/NV18-06-2022/lteue-linux-2022-06-18/doc/ws.js 127.0.0.1:9002 '{"message":"power_on","ue_id":1}'
|
||||
DetachScript: /root/NV18-06-2022/lteue-linux-2022-06-18/doc/ws.js 127.0.0.1:9002 '{"message":"power_off","ue_id":1}'
|
||||
UENetworkScript: ip netns exec ue1 ip a show dev pdn0
|
||||
CmdPrefix: ip netns exec ue1
|
||||
MTU: 1500
|
||||
amarisoft_ue_2:
|
||||
ID: amarisoft_ue_2
|
||||
State : enabled
|
||||
Kind : amarisoft
|
||||
#not required for AS config but needed for py script
|
||||
WakeupScript : none
|
||||
DetachScript : none
|
||||
#end
|
||||
Cmd : /root/NV18-06-2022/ue/lteue
|
||||
Config : /root/NV17-12-21/ue/config/xxxxxxx.cfg #to be updated for an other scenario
|
||||
Duration : 60
|
||||
Ping :
|
||||
- /tmp/test_ue1.log #to be updated fo an other scenario
|
||||
- /tmp/test_ue2.log #could be a list for a multi ue scenario
|
||||
UELog :
|
||||
- /tmp/ue1.log
|
||||
- /tmp/ue1.log
|
||||
HostIPAddress : 192.168.18.89
|
||||
HostUsername : root
|
||||
HostPassword : toor
|
||||
HostSourceCodePath : /tmp
|
||||
|
||||
|
||||
#do not remove
|
||||
dummy:
|
||||
ID: ''
|
||||
State : ''
|
||||
Kind : ''
|
||||
Process :
|
||||
Name : ''
|
||||
Cmd : ''
|
||||
WakeupScript : ''
|
||||
DetachScript : ''
|
||||
PLMN : 22201
|
||||
UENetwork : wwan0
|
||||
HostIPAddress : 172.21.16.135
|
||||
HostUsername : oaicicd
|
||||
HostPassword : oaicicd
|
||||
HostSourceCodePath : none
|
||||
|
||||
Host: amariue
|
||||
AttachScript: /root/NV18-06-2022/lteue-linux-2022-06-18/doc/ws.js 127.0.0.1:9002 '{"message":"power_on","ue_id":2}'
|
||||
DetachScript: /root/NV18-06-2022/lteue-linux-2022-06-18/doc/ws.js 127.0.0.1:9002 '{"message":"power_off","ue_id":2}'
|
||||
UENetworkScript: ip netns exec ue2 ip a show dev pdn0
|
||||
CmdPrefix: ip netns exec ue2
|
||||
MTU: 1500
|
||||
amarisoft_ue_3:
|
||||
Host: amariue
|
||||
AttachScript: /root/NV18-06-2022/lteue-linux-2022-06-18/doc/ws.js 127.0.0.1:9002 '{"message":"power_on","ue_id":3}'
|
||||
DetachScript: /root/NV18-06-2022/lteue-linux-2022-06-18/doc/ws.js 127.0.0.1:9002 '{"message":"power_off","ue_id":3}'
|
||||
UENetworkScript: ip netns exec ue3 ip a show dev pdn0
|
||||
CmdPrefix: ip netns exec ue3
|
||||
MTU: 1500
|
||||
amarisoft_ue_4:
|
||||
Host: amariue
|
||||
AttachScript: /root/NV18-06-2022/lteue-linux-2022-06-18/doc/ws.js 127.0.0.1:9002 '{"message":"power_on","ue_id":4}'
|
||||
DetachScript: /root/NV18-06-2022/lteue-linux-2022-06-18/doc/ws.js 127.0.0.1:9002 '{"message":"power_off","ue_id":4}'
|
||||
UENetworkScript: ip netns exec ue4 ip a show dev pdn0
|
||||
CmdPrefix: ip netns exec ue4
|
||||
MTU: 1500
|
||||
amarisoft_ue_5:
|
||||
Host: amariue
|
||||
AttachScript: /root/NV18-06-2022/lteue-linux-2022-06-18/doc/ws.js 127.0.0.1:9002 '{"message":"power_on","ue_id":5}'
|
||||
DetachScript: /root/NV18-06-2022/lteue-linux-2022-06-18/doc/ws.js 127.0.0.1:9002 '{"message":"power_off","ue_id":5}'
|
||||
UENetworkScript: ip netns exec ue5 ip a show dev pdn0
|
||||
CmdPrefix: ip netns exec ue5
|
||||
MTU: 1500
|
||||
amarisoft_ue_6:
|
||||
Host: amariue
|
||||
AttachScript: /root/NV18-06-2022/lteue-linux-2022-06-18/doc/ws.js 127.0.0.1:9002 '{"message":"power_on","ue_id":6}'
|
||||
DetachScript: /root/NV18-06-2022/lteue-linux-2022-06-18/doc/ws.js 127.0.0.1:9002 '{"message":"power_off","ue_id":6}'
|
||||
UENetworkScript: ip netns exec ue6 ip a show dev pdn0
|
||||
CmdPrefix: ip netns exec ue6
|
||||
MTU: 1500
|
||||
amarisoft_ue_7:
|
||||
Host: amariue
|
||||
AttachScript: /root/NV18-06-2022/lteue-linux-2022-06-18/doc/ws.js 127.0.0.1:9002 '{"message":"power_on","ue_id":7}'
|
||||
DetachScript: /root/NV18-06-2022/lteue-linux-2022-06-18/doc/ws.js 127.0.0.1:9002 '{"message":"power_off","ue_id":7}'
|
||||
UENetworkScript: ip netns exec ue7 ip a show dev pdn0
|
||||
CmdPrefix: ip netns exec ue7
|
||||
MTU: 1500
|
||||
amarisoft_ue_8:
|
||||
Host: amariue
|
||||
AttachScript: /root/NV18-06-2022/lteue-linux-2022-06-18/doc/ws.js 127.0.0.1:9002 '{"message":"power_on","ue_id":8}'
|
||||
DetachScript: /root/NV18-06-2022/lteue-linux-2022-06-18/doc/ws.js 127.0.0.1:9002 '{"message":"power_off","ue_id":8}'
|
||||
UENetworkScript: ip netns exec ue8 ip a show dev pdn0
|
||||
CmdPrefix: ip netns exec ue8
|
||||
MTU: 1500
|
||||
amarisoft_ue_9:
|
||||
Host: amariue
|
||||
AttachScript: /root/NV18-06-2022/lteue-linux-2022-06-18/doc/ws.js 127.0.0.1:9002 '{"message":"power_on","ue_id":9}'
|
||||
DetachScript: /root/NV18-06-2022/lteue-linux-2022-06-18/doc/ws.js 127.0.0.1:9002 '{"message":"power_off","ue_id":9}'
|
||||
UENetworkScript: ip netns exec ue9 ip a show dev pdn0
|
||||
CmdPrefix: ip netns exec ue9
|
||||
MTU: 1500
|
||||
amarisoft_ue_10:
|
||||
Host: amariue
|
||||
AttachScript: /root/NV18-06-2022/lteue-linux-2022-06-18/doc/ws.js 127.0.0.1:9002 '{"message":"power_on","ue_id":10}'
|
||||
DetachScript: /root/NV18-06-2022/lteue-linux-2022-06-18/doc/ws.js 127.0.0.1:9002 '{"message":"power_off","ue_id":10}'
|
||||
UENetworkScript: ip netns exec ue10 ip a show dev pdn0
|
||||
CmdPrefix: ip netns exec ue10
|
||||
MTU: 1500
|
||||
|
||||
oai_ue_obelix:
|
||||
Host: obelix
|
||||
UENetworkScript: ip a show dev oaitun_ue1
|
||||
IF: oaitun_ue1
|
||||
|
||||
@@ -1,81 +0,0 @@
|
||||
# * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
|
||||
# * contributor license agreements. See the NOTICE file distributed with
|
||||
# * this work for additional information regarding copyright ownership.
|
||||
# * The OpenAirInterface Software Alliance licenses this file to You under
|
||||
# * the OAI Public License, Version 1.1 (the "License"); you may not use this file
|
||||
# * except in compliance with the License.
|
||||
# * You may obtain a copy of the License at
|
||||
# *
|
||||
# * http://www.openairinterface.org/?page_id=698
|
||||
# *
|
||||
# * Unless required by applicable law or agreed to in writing, software
|
||||
# * distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# * See the License for the specific language governing permissions and
|
||||
# * limitations under the License.
|
||||
# *-------------------------------------------------------------------------------
|
||||
# * For more information about the OpenAirInterface (OAI) Software Alliance:
|
||||
# * contact@openairinterface.org
|
||||
# */
|
||||
#---------------------------------------------------------------------
|
||||
#
|
||||
# Required Python Version
|
||||
# Python 3.x
|
||||
#
|
||||
#---------------------------------------------------------------------
|
||||
|
||||
#to use isfile
|
||||
import os
|
||||
import sys
|
||||
import logging
|
||||
#to create a SSH object locally in the methods
|
||||
import sshconnection
|
||||
#time.sleep
|
||||
import time
|
||||
|
||||
|
||||
import re
|
||||
import subprocess
|
||||
|
||||
from datetime import datetime
|
||||
|
||||
|
||||
class AS_UE:
|
||||
|
||||
def __init__(self,Module):
|
||||
#create attributes as in the UE dictionary
|
||||
for k, v in Module.items():
|
||||
setattr(self, k, v)
|
||||
|
||||
|
||||
|
||||
|
||||
#-----------------$
|
||||
#PUBLIC Methods$
|
||||
#-----------------$
|
||||
|
||||
def WaitEndScenario(self):
|
||||
logging.debug('waiting for scenario duration')
|
||||
time.sleep(int(self.Duration))
|
||||
|
||||
def KillASUE(self):
|
||||
mySSH = sshconnection.SSHConnection()
|
||||
mySSH.open(self.HostIPAddress, self.HostUsername, self.HostPassword)
|
||||
mySSH.command('killall --signal SIGKILL lteue-avx2', '\$', 5)
|
||||
mySSH.close()
|
||||
|
||||
def RunScenario(self):
|
||||
mySSH = sshconnection.SSHConnection()
|
||||
mySSH.open(self.HostIPAddress, self.HostUsername, self.HostPassword)
|
||||
|
||||
logging.debug("Deleting old artifacts :")
|
||||
cmd='rm -rf ' + self.Ping + ' ' + self.UELog
|
||||
mySSH.command(cmd, '\$',5)
|
||||
logging.debug("Running scenario :")
|
||||
cmd='echo $USER; nohup '+self.Cmd + ' ' + self.Config + ' &'
|
||||
mySSH.command(cmd, '\$',5)
|
||||
|
||||
mySSH.close()
|
||||
|
||||
|
||||
|
||||
@@ -19,29 +19,27 @@
|
||||
# * contact@openairinterface.org
|
||||
# */
|
||||
#---------------------------------------------------------------------
|
||||
# Python for CI of OAI-eNB + COTS-UE
|
||||
#
|
||||
# Required Python Version
|
||||
# Python 3.x
|
||||
#
|
||||
# Required Python Package
|
||||
# pexpect
|
||||
#---------------------------------------------------------------------
|
||||
|
||||
#-----------------------------------------------------------
|
||||
# Import
|
||||
#-----------------------------------------------------------
|
||||
import logging
|
||||
import sshconnection as SSH
|
||||
import cls_oai_html
|
||||
#import os
|
||||
import re
|
||||
import time
|
||||
#import subprocess
|
||||
import sys
|
||||
|
||||
import cls_oai_html
|
||||
import constants as CONST
|
||||
import helpreadme as HELP
|
||||
import cls_containerize
|
||||
import cls_cmd
|
||||
|
||||
IMAGE_REGISTRY_SERVICE_NAME = "image-registry.openshift-image-registry.svc"
|
||||
NAMESPACE = "oaicicd-ran"
|
||||
|
||||
class Cluster:
|
||||
def __init__(self):
|
||||
@@ -58,86 +56,73 @@ class Cluster:
|
||||
self.ranCommitID = ""
|
||||
self.ranAllowMerge = False
|
||||
self.ranTargetBranch = ""
|
||||
self.cmd = None
|
||||
|
||||
def _recreate_entitlements(self, sshSession):
|
||||
|
||||
def _recreate_entitlements(self):
|
||||
# recreating entitlements, don't care if deletion fails
|
||||
sshSession.command('oc delete secret etc-pki-entitlement', '\$', 5)
|
||||
if re.search(r"not found", sshSession.getBefore()):
|
||||
logging.warning("no secrets etc-pki-entitlement found, recreating")
|
||||
sshSession.command('ls /etc/pki/entitlement/???????????????????.pem | tail -1', '\$', 5, silent=True)
|
||||
regres1 = re.search(r"/etc/pki/entitlement/[0-9]+.pem", sshSession.getBefore())
|
||||
sshSession.command('ls /etc/pki/entitlement/???????????????????-key.pem | tail -1', '\$', 5, silent=True)
|
||||
regres2 = re.search(r"/etc/pki/entitlement/[0-9]+-key.pem", sshSession.getBefore())
|
||||
self.cmd.run('oc delete secret etc-pki-entitlement')
|
||||
ret = self.cmd.run('ls /etc/pki/entitlement/???????????????????.pem | tail -1', silent=True)
|
||||
regres1 = re.search(r"/etc/pki/entitlement/[0-9]+.pem", ret.stdout)
|
||||
ret = self.cmd.run('ls /etc/pki/entitlement/???????????????????-key.pem | tail -1', silent=True)
|
||||
regres2 = re.search(r"/etc/pki/entitlement/[0-9]+-key.pem", ret.stdout)
|
||||
if regres1 is None or regres2 is None:
|
||||
logging.error("could not find entitlements")
|
||||
return False
|
||||
file1 = regres1.group(0)
|
||||
file2 = regres2.group(0)
|
||||
sshSession.command(f'oc create secret generic etc-pki-entitlement --from-file {file1} --from-file {file2}', '\$', 5)
|
||||
regres = re.search(r"secret/etc-pki-entitlement created", sshSession.getBefore())
|
||||
if regres is None:
|
||||
ret = self.cmd.run(f'oc create secret generic etc-pki-entitlement --from-file {file1} --from-file {file2}')
|
||||
regres = re.search(r"secret/etc-pki-entitlement created", ret.stdout)
|
||||
if ret.returncode != 0 or regres is None:
|
||||
logging.error("could not create secret/etc-pki-entitlement")
|
||||
return False
|
||||
return True
|
||||
|
||||
def _recreate_bc(self, sshSession, name, newTag, filename):
|
||||
self._retag_image_statement(sshSession, name, name, newTag, filename)
|
||||
sshSession.command(f'oc delete -f {filename}', '\$', 5)
|
||||
sshSession.command(f'oc create -f {filename}', '\$', 5)
|
||||
before = sshSession.getBefore()
|
||||
if re.search('buildconfig.build.openshift.io/[a-zA-Z\-0-9]+ created', before) is not None:
|
||||
def _recreate_bc(self, name, newTag, filename):
|
||||
self._retag_image_statement(name, name, newTag, filename)
|
||||
self.cmd.run(f'oc delete -f {filename}')
|
||||
ret = self.cmd.run(f'oc create -f {filename}')
|
||||
if re.search('buildconfig.build.openshift.io/[a-zA-Z\-0-9]+ created', ret.stdout) is not None:
|
||||
return True
|
||||
logging.error('error while creating buildconfig: ' + sshSession.getBefore())
|
||||
logging.error('error while creating buildconfig: ' + ret.stdout)
|
||||
return False
|
||||
|
||||
def _recreate_is_tag(self, sshSession, name, newTag, filename):
|
||||
sshSession.command(f'oc describe is {name}', '\$', 5)
|
||||
if sshSession.getBefore().count('NotFound') > 0:
|
||||
sshSession.command(f'oc create -f {filename}', '\$', 5)
|
||||
before = sshSession.getBefore()
|
||||
if re.search(f'imagestream.image.openshift.io/{name} created', before) is None:
|
||||
logging.error('error while creating imagestream: ' + sshSession.getBefore())
|
||||
def _recreate_is_tag(self, name, newTag, filename):
|
||||
ret = self.cmd.run(f'oc describe is {name}')
|
||||
if ret.returncode != 0:
|
||||
ret = self.cmd.run(f'oc create -f {filename}')
|
||||
if ret.returncode != 0:
|
||||
logging.error(f'error while creating imagestream: {ret.stdout}')
|
||||
return False
|
||||
else:
|
||||
logging.debug(f'-> imagestream {name} found')
|
||||
image = f'{name}:{newTag}'
|
||||
sshSession.command(f'oc delete istag {image}', '\$', 5) # we don't care if this fails, e.g., if it is missing
|
||||
sshSession.command(f'oc create istag {image}', '\$', 5)
|
||||
before = sshSession.getBefore()
|
||||
if re.search(f'imagestreamtag.image.openshift.io/{image} created', before) is not None:
|
||||
self.cmd.run(f'oc delete istag {image}', reportNonZero=False) # we don't care if this fails, e.g., if it is missing
|
||||
ret = self.cmd.run(f'oc create istag {image}')
|
||||
if ret.returncode == 0:
|
||||
return True
|
||||
logging.error('error while creating imagestreamtag: ' + sshSession.getBefore())
|
||||
logging.error(f'error while creating imagestreamtag: {ret.stdout}')
|
||||
return False
|
||||
|
||||
def _start_build(self, sshSession, name):
|
||||
def _start_build(self, name):
|
||||
# will return "immediately" but build runs in background
|
||||
# if multiple builds are started at the same time, this can take some time, however
|
||||
ret = sshSession.command(f'oc start-build {name} --from-file={self.eNBSourceCodePath}', '\$', 300)
|
||||
before = sshSession.getBefore()
|
||||
regres = re.search(r'build.build.openshift.io/(?P<jobname>[a-zA-Z0-9\-]+) started', str(before))
|
||||
if ret != 0 or before.count('Uploading finished') != 1 or regres is None:
|
||||
logging.error("error during oc start-build: " + sshSession.getBefore())
|
||||
self._delete_pod(sshSession, name)
|
||||
ret = self.cmd.run(f'oc start-build {name} --from-file={self.eNBSourceCodePath}')
|
||||
regres = re.search(r'build.build.openshift.io/(?P<jobname>[a-zA-Z0-9\-]+) started', ret.stdout)
|
||||
if ret.returncode != 0 or ret.stdout.count('Uploading finished') != 1 or regres is None:
|
||||
logging.error(f"error during oc start-build: {ret.stdout}")
|
||||
return None
|
||||
return regres.group('jobname') + '-build'
|
||||
|
||||
def _delete_pod(self, sshSession, shortName):
|
||||
sshSession.command(f"oc get pods | grep {shortName}", '\$', 5)
|
||||
regres = re.search(rf'{shortName}-[0-9]+-build', sshSession.getBefore())
|
||||
if regres is not None:
|
||||
sshSession.command(f"oc delete pod {regres.group(0)}", '\$', 5)
|
||||
else:
|
||||
logging.warning(f"no pod found with name {shortName}")
|
||||
|
||||
def _wait_build_end(self, sshSession, jobs, timeout_sec, check_interval_sec = 5):
|
||||
def _wait_build_end(self, jobs, timeout_sec, check_interval_sec = 5):
|
||||
logging.debug(f"waiting for jobs {jobs} to finish building")
|
||||
while timeout_sec > 0:
|
||||
# check status
|
||||
for j in jobs:
|
||||
sshSession.command(f'oc get pods | grep {j}', '\$', 30, silent = True)
|
||||
if sshSession.getBefore().count('Completed') > 0: jobs.remove(j)
|
||||
if sshSession.getBefore().count('Error') > 0:
|
||||
logging.error(f'error for job {j}: ' + sshSession.getBefore())
|
||||
ret = self.cmd.run(f'oc get pods | grep {j}', silent = True)
|
||||
if ret.stdout.count('Completed') > 0: jobs.remove(j)
|
||||
if ret.stdout.count('Error') > 0:
|
||||
logging.error(f'error for job {j}: {ret.stdout}')
|
||||
return False
|
||||
if jobs == []:
|
||||
logging.debug('all jobs completed')
|
||||
@@ -147,44 +132,43 @@ class Cluster:
|
||||
logging.error(f"timeout while waiting for end of build of {jobs}")
|
||||
return False
|
||||
|
||||
def _retag_image_statement(self, sshSession, oldImage, newImage, newTag, filename):
|
||||
sshSession.command(f'sed -i -e "s#{oldImage}:latest#{newImage}:{newTag}#" {filename}', '\$', 5)
|
||||
def _retag_image_statement(self, oldImage, newImage, newTag, filename):
|
||||
self.cmd.run(f'sed -i -e "s#{oldImage}:latest#{newImage}:{newTag}#" {filename}')
|
||||
|
||||
def _get_image_size(self, sshSession, image, tag):
|
||||
def _get_image_size(self, image, tag):
|
||||
# get the SHA of the image we built using the image name and its tag
|
||||
sshSession.command(f'oc describe is {image} | grep -A4 {tag}', '\$', 5)
|
||||
result = re.search(f'image-registry.openshift-image-registry.svc:5000/oaicicd-ran/(?P<imageSha>{image}@sha256:[a-f0-9]+)', sshSession.getBefore())
|
||||
ret = self.cmd.run(f'oc describe is {image} | grep -A4 {tag}')
|
||||
result = re.search(f'{IMAGE_REGISTRY_SERVICE_NAME}:5000/{NAMESPACE}/(?P<imageSha>{image}@sha256:[a-f0-9]+)', ret.stdout)
|
||||
if result is None:
|
||||
return -1
|
||||
imageSha = result.group("imageSha")
|
||||
|
||||
# retrieve the size
|
||||
sshSession.command(f'oc get -o json isimage {imageSha} | jq -Mc "{{dockerImageSize: .image.dockerImageMetadata.Size}}"', '\$', 5)
|
||||
result = re.search('{"dockerImageSize":(?P<size>[0-9]+)}', str(sshSession.getBefore()))
|
||||
ret = self.cmd.run(f'oc get -o json isimage {imageSha} | jq -Mc "{{dockerImageSize: .image.dockerImageMetadata.Size}}"')
|
||||
result = re.search('{"dockerImageSize":(?P<size>[0-9]+)}', ret.stdout)
|
||||
if result is None:
|
||||
return -1
|
||||
return int(result.group("size"))
|
||||
|
||||
def _deploy_pod(self, sshSession, filename, timeout = 30):
|
||||
sshSession.command(f'oc create -f {filename}', '\$', 10)
|
||||
result = re.search(f'pod/(?P<pod>[a-zA-Z0-9_\-]+) created', sshSession.getBefore())
|
||||
def _deploy_pod(self, filename, timeout = 30):
|
||||
ret = self.cmd.run(f'oc create -f {filename}')
|
||||
result = re.search(f'pod/(?P<pod>[a-zA-Z0-9_\-]+) created', ret.stdout)
|
||||
if result is None:
|
||||
logging.error(f'could not deploy pod: {sshSession.getBefore()}')
|
||||
logging.error(f'could not deploy pod: {ret.stdout}')
|
||||
return None
|
||||
pod = result.group("pod")
|
||||
logging.debug(f'checking if pod {pod} is in Running state')
|
||||
while timeout > 0:
|
||||
sshSession.command(f'oc get pod {pod} -o json | jq -Mc .status.phase', '\$', 5, silent=True)
|
||||
if re.search('"Running"', sshSession.getBefore()) is not None: return pod
|
||||
ret = self.cmd.run(f'oc get pod {pod} -o json | jq -Mc .status.phase', silent=True)
|
||||
if re.search('"Running"', ret.stdout) is not None: return pod
|
||||
timeout -= 1
|
||||
time.sleep(1)
|
||||
logging.error(f'pod {pod} did not reach Running state')
|
||||
self._undeploy_pod(sshSession, filename)
|
||||
self._undeploy_pod(filename)
|
||||
return None
|
||||
|
||||
def _undeploy_pod(self, sshSession, filename):
|
||||
# to save time we start this in the background and trust that oc stops correctly
|
||||
sshSession.command(f'oc delete -f {filename} &', '\$', 5)
|
||||
def _undeploy_pod(self, filename):
|
||||
self.cmd.run(f'oc delete -f {filename}')
|
||||
|
||||
def BuildClusterImage(self, HTML):
|
||||
if self.ranRepository == '' or self.ranBranch == '' or self.ranCommitID == '':
|
||||
@@ -194,8 +178,7 @@ class Cluster:
|
||||
lIpAddr = self.eNBIPAddress
|
||||
lSourcePath = self.eNBSourceCodePath
|
||||
if lIpAddr == '' or lSourcePath == '':
|
||||
HELP.GenericHelp(CONST.Version)
|
||||
sys.exit('Insufficient Parameter: no SSH Credentials')
|
||||
sys.exit('Insufficient Parameter: eNBSourceCodePath missing')
|
||||
ocUserName = self.OCUserName
|
||||
ocPassword = self.OCPassword
|
||||
ocProjectName = self.OCProjectName
|
||||
@@ -206,29 +189,27 @@ class Cluster:
|
||||
sys.exit(f'ocRegistry {self.OCRegistry} should not start with http:// or https:// and end on a slash /')
|
||||
|
||||
logging.debug(f'Building on cluster triggered from server: {lIpAddr}')
|
||||
mySSH = SSH.SSHConnection()
|
||||
mySSH.open(lIpAddr, "oaicicd", "SHOULD NOT BE NECESSARY")
|
||||
self.cmd = cls_cmd.RemoteCmd(lIpAddr)
|
||||
|
||||
self.testCase_id = HTML.testCase_id
|
||||
|
||||
# Workaround for some servers, we need to erase completely the workspace
|
||||
if self.forcedWorkspaceCleanup:
|
||||
mySSH.command(f'rm -Rf {lSourcePath}', '\$', 15)
|
||||
cls_containerize.CreateWorkspace(mySSH, lSourcePath, self.ranRepository, self.ranCommitID, self.ranTargetBranch, self.ranAllowMerge)
|
||||
self.cmd.run(f'rm -Rf {lSourcePath}')
|
||||
cls_containerize.CreateWorkspace(self.cmd, lSourcePath, self.ranRepository, self.ranCommitID, self.ranTargetBranch, self.ranAllowMerge)
|
||||
|
||||
# we don't necessarily need a forced workspace cleanup, but in
|
||||
# order to reduce the amount of data send to OpenShift, we
|
||||
# to reduce the amount of data send to OpenShift, we
|
||||
# manually delete all generated files in the workspace
|
||||
mySSH.command(f'rm -rf {lSourcePath}/cmake_targets/ran_build', '\$', 30);
|
||||
self.cmd.run(f'rm -rf {lSourcePath}/cmake_targets/ran_build');
|
||||
|
||||
baseTag = 'develop'
|
||||
forceBaseImageBuild = False
|
||||
imageTag = 'develop'
|
||||
if self.ranAllowMerge: # merging MR branch into develop -> temporary image
|
||||
imageTag = 'ci-temp'
|
||||
imageTag = f'{self.ranBranch}-{self.ranCommitID[0:8]}'
|
||||
if self.ranTargetBranch == 'develop':
|
||||
mySSH.command(f'git diff HEAD..origin/develop -- cmake_targets/build_oai cmake_targets/tools/build_helper docker/Dockerfile.base.rhel8.2 | grep --colour=never -i INDEX', '\$', 5)
|
||||
result = re.search('index', mySSH.getBefore())
|
||||
ret = self.cmd.run(f'git diff HEAD..origin/develop -- cmake_targets/build_oai cmake_targets/tools/build_helper docker/Dockerfile.base.rhel8.2 | grep --colour=never -i INDEX')
|
||||
result = re.search('index', ret.stdout)
|
||||
if result is not None:
|
||||
forceBaseImageBuild = True
|
||||
baseTag = 'ci-temp'
|
||||
@@ -236,122 +217,128 @@ class Cluster:
|
||||
forceBaseImageBuild = True
|
||||
|
||||
# logging to OC Cluster and then switch to corresponding project
|
||||
mySSH.command(f'oc login -u {ocUserName} -p {ocPassword} --server {self.OCUrl}', '\$', 31)
|
||||
if mySSH.getBefore().count('Login successful.') == 0:
|
||||
ret = self.cmd.run(f'oc login -u {ocUserName} -p {ocPassword} --server {self.OCUrl}')
|
||||
if ret.returncode != 0:
|
||||
logging.error('\u001B[1m OC Cluster Login Failed\u001B[0m')
|
||||
mySSH.close()
|
||||
HTML.CreateHtmlTestRow('N/A', 'KO', CONST.OC_LOGIN_FAIL)
|
||||
return False
|
||||
|
||||
mySSH.command(f'oc project {ocProjectName}', '\$', 30)
|
||||
if mySSH.getBefore().count(f'Already on project "{ocProjectName}"') == 0 and mySSH.getBefore().count(f'Now using project "{self.OCProjectName}"') == 0:
|
||||
ret = self.cmd.run(f'oc project {ocProjectName}')
|
||||
if ret.returncode != 0:
|
||||
logging.error(f'\u001B[1mUnable to access OC project {ocProjectName}\u001B[0m')
|
||||
mySSH.command('oc logout', '\$', 30)
|
||||
mySSH.close()
|
||||
self.cmd.run('oc logout')
|
||||
HTML.CreateHtmlTestRow('N/A', 'KO', CONST.OC_PROJECT_FAIL)
|
||||
return False
|
||||
|
||||
self._recreate_entitlements(mySSH)
|
||||
# delete old images by Sagar Arora <sagar.arora@openairinterface.org>:
|
||||
# 1. retrieve all images and their timestamp
|
||||
# 2. awk retrieves those whose timestamp is older than 4 weeks
|
||||
# 3. issue delete command on corresponding istags (the images are dangling and will be cleaned by the registry)
|
||||
delete_cmd = "oc get istag -o go-template --template '{{range .items}}{{.metadata.name}} {{.metadata.creationTimestamp}}{{\"\\n\"}}{{end}}' | awk '$2 <= \"'$(date -d '-4weeks' -Ins --utc | sed 's/+0000/Z/')'\" { print $1 }' | xargs --no-run-if-empty oc delete istag"
|
||||
response = self.cmd.run(delete_cmd)
|
||||
logging.debug(f"deleted images:\n{response.stdout}")
|
||||
|
||||
self._recreate_entitlements()
|
||||
|
||||
status = True # flag to abandon compiling if any image fails
|
||||
attemptedImages = []
|
||||
if forceBaseImageBuild:
|
||||
self._recreate_is_tag(mySSH, 'ran-base', baseTag, 'openshift/ran-base-is.yaml')
|
||||
self._recreate_bc(mySSH, 'ran-base', baseTag, 'openshift/ran-base-bc.yaml')
|
||||
ranbase_job = self._start_build(mySSH, 'ran-base')
|
||||
self._recreate_is_tag('ran-base', baseTag, 'openshift/ran-base-is.yaml')
|
||||
self._recreate_bc('ran-base', baseTag, 'openshift/ran-base-bc.yaml')
|
||||
ranbase_job = self._start_build('ran-base')
|
||||
attemptedImages += ['ran-base']
|
||||
status = ranbase_job is not None and self._wait_build_end(mySSH, [ranbase_job], 600)
|
||||
status = ranbase_job is not None and self._wait_build_end([ranbase_job], 600)
|
||||
if not status: logging.error('failure during build of ran-base')
|
||||
mySSH.command(f'oc logs {ranbase_job} &> cmake_targets/log/ran-base.log', '\$', 10)
|
||||
self.cmd.run(f'oc logs {ranbase_job} &> cmake_targets/log/ran-base.log') # cannot use cmd.run because of redirect
|
||||
# recover logs by mounting image
|
||||
self._retag_image_statement(mySSH, 'ran-base', 'ran-base', baseTag, 'openshift/ran-base-log-retrieval.yaml')
|
||||
pod = self._deploy_pod(mySSH, 'openshift/ran-base-log-retrieval.yaml')
|
||||
self._retag_image_statement('ran-base', 'ran-base', baseTag, 'openshift/ran-base-log-retrieval.yaml')
|
||||
pod = self._deploy_pod('openshift/ran-base-log-retrieval.yaml')
|
||||
if pod is not None:
|
||||
mySSH.command(f'mkdir -p cmake_targets/log/ran-base', '\$', 5)
|
||||
mySSH.command(f'oc rsync {pod}:/oai-ran/cmake_targets/log/ cmake_targets/log/ran-base', '\$', 5)
|
||||
self._undeploy_pod(mySSH, 'openshift/ran-base-log-retrieval.yaml')
|
||||
self.cmd.run(f'mkdir -p cmake_targets/log/ran-base')
|
||||
self.cmd.run(f'oc rsync {pod}:/oai-ran/cmake_targets/log/ cmake_targets/log/ran-base')
|
||||
self._undeploy_pod('openshift/ran-base-log-retrieval.yaml')
|
||||
else:
|
||||
status = False
|
||||
|
||||
if status:
|
||||
self._recreate_is_tag(mySSH, 'oai-physim', imageTag, 'openshift/oai-physim-is.yaml')
|
||||
self._recreate_bc(mySSH, 'oai-physim', imageTag, 'openshift/oai-physim-bc.yaml')
|
||||
self._retag_image_statement(mySSH, 'ran-base', 'image-registry.openshift-image-registry.svc:5000/oaicicd-ran/ran-base', baseTag, 'docker/Dockerfile.phySim.rhel8.2')
|
||||
physim_job = self._start_build(mySSH, 'oai-physim')
|
||||
self._recreate_is_tag('oai-physim', imageTag, 'openshift/oai-physim-is.yaml')
|
||||
self._recreate_bc('oai-physim', imageTag, 'openshift/oai-physim-bc.yaml')
|
||||
self._retag_image_statement('ran-base', 'image-registry.openshift-image-registry.svc:5000/oaicicd-ran/ran-base', baseTag, 'docker/Dockerfile.phySim.rhel8.2')
|
||||
physim_job = self._start_build('oai-physim')
|
||||
attemptedImages += ['oai-physim']
|
||||
|
||||
self._recreate_is_tag(mySSH, 'ran-build', imageTag, 'openshift/ran-build-is.yaml')
|
||||
self._recreate_bc(mySSH, 'ran-build', imageTag, 'openshift/ran-build-bc.yaml')
|
||||
self._retag_image_statement(mySSH, 'ran-base', 'image-registry.openshift-image-registry.svc:5000/oaicicd-ran/ran-base', baseTag, 'docker/Dockerfile.build.rhel8.2')
|
||||
ranbuild_job = self._start_build(mySSH, 'ran-build')
|
||||
self._recreate_is_tag('ran-build', imageTag, 'openshift/ran-build-is.yaml')
|
||||
self._recreate_bc('ran-build', imageTag, 'openshift/ran-build-bc.yaml')
|
||||
self._retag_image_statement('ran-base', 'image-registry.openshift-image-registry.svc:5000/oaicicd-ran/ran-base', baseTag, 'docker/Dockerfile.build.rhel8.2')
|
||||
ranbuild_job = self._start_build('ran-build')
|
||||
attemptedImages += ['ran-build']
|
||||
|
||||
wait = ranbuild_job is not None and physim_job is not None and self._wait_build_end(mySSH, [ranbuild_job, physim_job], 1200)
|
||||
wait = ranbuild_job is not None and physim_job is not None and self._wait_build_end([ranbuild_job, physim_job], 1200)
|
||||
if not wait: logging.error('error during build of ranbuild_job or physim_job')
|
||||
status = status and wait
|
||||
mySSH.command(f'oc logs {ranbuild_job} &> cmake_targets/log/ran-build.log', '\$', 10)
|
||||
mySSH.command(f'oc logs {physim_job} &> cmake_targets/log/oai-physim.log', '\$', 10)
|
||||
mySSH.command('oc get pods.metrics.k8s.io >> cmake_targets/log/build-metrics.log', '\$', 10)
|
||||
self.cmd.run(f'oc logs {ranbuild_job} &> cmake_targets/log/ran-build.log')
|
||||
self.cmd.run(f'oc logs {physim_job} &> cmake_targets/log/oai-physim.log')
|
||||
self.cmd.run(f'oc get pods.metrics.k8s.io &>> cmake_targets/log/build-metrics.log', '\$', 10)
|
||||
|
||||
if status:
|
||||
self._recreate_is_tag(mySSH, 'oai-enb', imageTag, 'openshift/oai-enb-is.yaml')
|
||||
self._recreate_bc(mySSH, 'oai-enb', imageTag, 'openshift/oai-enb-bc.yaml')
|
||||
self._retag_image_statement(mySSH, 'ran-base', 'image-registry.openshift-image-registry.svc:5000/oaicicd-ran/ran-base', baseTag, 'docker/Dockerfile.eNB.rhel8.2')
|
||||
self._retag_image_statement(mySSH, 'ran-build', 'image-registry.openshift-image-registry.svc:5000/oaicicd-ran/ran-build', imageTag, 'docker/Dockerfile.eNB.rhel8.2')
|
||||
enb_job = self._start_build(mySSH, 'oai-enb')
|
||||
self._recreate_is_tag('oai-enb', imageTag, 'openshift/oai-enb-is.yaml')
|
||||
self._recreate_bc('oai-enb', imageTag, 'openshift/oai-enb-bc.yaml')
|
||||
self._retag_image_statement('ran-base', 'image-registry.openshift-image-registry.svc:5000/oaicicd-ran/ran-base', baseTag, 'docker/Dockerfile.eNB.rhel8.2')
|
||||
self._retag_image_statement('ran-build', 'image-registry.openshift-image-registry.svc:5000/oaicicd-ran/ran-build', imageTag, 'docker/Dockerfile.eNB.rhel8.2')
|
||||
enb_job = self._start_build('oai-enb')
|
||||
attemptedImages += ['oai-enb']
|
||||
|
||||
self._recreate_is_tag(mySSH, 'oai-gnb', imageTag, 'openshift/oai-gnb-is.yaml')
|
||||
self._recreate_bc(mySSH, 'oai-gnb', imageTag, 'openshift/oai-gnb-bc.yaml')
|
||||
self._retag_image_statement(mySSH, 'ran-base', 'image-registry.openshift-image-registry.svc:5000/oaicicd-ran/ran-base', baseTag, 'docker/Dockerfile.gNB.rhel8.2')
|
||||
self._retag_image_statement(mySSH, 'ran-build', 'image-registry.openshift-image-registry.svc:5000/oaicicd-ran/ran-build', imageTag, 'docker/Dockerfile.gNB.rhel8.2')
|
||||
gnb_job = self._start_build(mySSH, 'oai-gnb')
|
||||
self._recreate_is_tag('oai-gnb', imageTag, 'openshift/oai-gnb-is.yaml')
|
||||
self._recreate_bc('oai-gnb', imageTag, 'openshift/oai-gnb-bc.yaml')
|
||||
self._retag_image_statement('ran-base', 'image-registry.openshift-image-registry.svc:5000/oaicicd-ran/ran-base', baseTag, 'docker/Dockerfile.gNB.rhel8.2')
|
||||
self._retag_image_statement('ran-build', 'image-registry.openshift-image-registry.svc:5000/oaicicd-ran/ran-build', imageTag, 'docker/Dockerfile.gNB.rhel8.2')
|
||||
gnb_job = self._start_build('oai-gnb')
|
||||
attemptedImages += ['oai-gnb']
|
||||
|
||||
self._recreate_is_tag(mySSH, 'oai-gnb-aw2s', imageTag, 'openshift/oai-gnb-aw2s-is.yaml')
|
||||
self._recreate_bc(mySSH, 'oai-gnb-aw2s', imageTag, 'openshift/oai-gnb-aw2s-bc.yaml')
|
||||
self._retag_image_statement(mySSH, 'ran-base', 'image-registry.openshift-image-registry.svc:5000/oaicicd-ran/ran-base', baseTag, 'docker/Dockerfile.gNB.aw2s.rhel8.2')
|
||||
self._retag_image_statement(mySSH, 'ran-build', 'image-registry.openshift-image-registry.svc:5000/oaicicd-ran/ran-build', imageTag, 'docker/Dockerfile.gNB.aw2s.rhel8.2')
|
||||
gnb_aw2s_job = self._start_build(mySSH, 'oai-gnb-aw2s')
|
||||
self._recreate_is_tag('oai-gnb-aw2s', imageTag, 'openshift/oai-gnb-aw2s-is.yaml')
|
||||
self._recreate_bc('oai-gnb-aw2s', imageTag, 'openshift/oai-gnb-aw2s-bc.yaml')
|
||||
self._retag_image_statement('ran-base', 'image-registry.openshift-image-registry.svc:5000/oaicicd-ran/ran-base', baseTag, 'docker/Dockerfile.gNB.aw2s.rhel8.2')
|
||||
self._retag_image_statement('ran-build', 'image-registry.openshift-image-registry.svc:5000/oaicicd-ran/ran-build', imageTag, 'docker/Dockerfile.gNB.aw2s.rhel8.2')
|
||||
gnb_aw2s_job = self._start_build('oai-gnb-aw2s')
|
||||
attemptedImages += ['oai-gnb-aw2s']
|
||||
|
||||
wait = enb_job is not None and gnb_job is not None and gnb_aw2s_job is not None and self._wait_build_end(mySSH, [enb_job, gnb_job, gnb_aw2s_job], 600)
|
||||
wait = enb_job is not None and gnb_job is not None and gnb_aw2s_job is not None and self._wait_build_end([enb_job, gnb_job, gnb_aw2s_job], 600)
|
||||
if not wait: logging.error('error during build of eNB/gNB')
|
||||
status = status and wait
|
||||
# recover logs
|
||||
mySSH.command(f'oc logs {enb_job} &> cmake_targets/log/oai-enb.log', '\$', 10)
|
||||
mySSH.command(f'oc logs {gnb_job} &> cmake_targets/log/oai-gnb.log', '\$', 10)
|
||||
mySSH.command(f'oc logs {gnb_aw2s_job} &> cmake_targets/log/oai-gnb-aw2s.log', '\$', 10)
|
||||
self.cmd.run(f'oc logs {enb_job} &> cmake_targets/log/oai-enb.log')
|
||||
self.cmd.run(f'oc logs {gnb_job} &> cmake_targets/log/oai-gnb.log')
|
||||
self.cmd.run(f'oc logs {gnb_aw2s_job} &> cmake_targets/log/oai-gnb-aw2s.log')
|
||||
|
||||
self._recreate_is_tag(mySSH, 'oai-lte-ue', imageTag, 'openshift/oai-lte-ue-is.yaml')
|
||||
self._recreate_bc(mySSH, 'oai-lte-ue', imageTag, 'openshift/oai-lte-ue-bc.yaml')
|
||||
self._retag_image_statement(mySSH, 'ran-base', 'image-registry.openshift-image-registry.svc:5000/oaicicd-ran/ran-base', baseTag, 'docker/Dockerfile.lteUE.rhel8.2')
|
||||
self._retag_image_statement(mySSH, 'ran-build', 'image-registry.openshift-image-registry.svc:5000/oaicicd-ran/ran-build', imageTag, 'docker/Dockerfile.lteUE.rhel8.2')
|
||||
lteue_job = self._start_build(mySSH, 'oai-lte-ue')
|
||||
self._recreate_is_tag('oai-lte-ue', imageTag, 'openshift/oai-lte-ue-is.yaml')
|
||||
self._recreate_bc('oai-lte-ue', imageTag, 'openshift/oai-lte-ue-bc.yaml')
|
||||
self._retag_image_statement('ran-base', 'image-registry.openshift-image-registry.svc:5000/oaicicd-ran/ran-base', baseTag, 'docker/Dockerfile.lteUE.rhel8.2')
|
||||
self._retag_image_statement('ran-build', 'image-registry.openshift-image-registry.svc:5000/oaicicd-ran/ran-build', imageTag, 'docker/Dockerfile.lteUE.rhel8.2')
|
||||
lteue_job = self._start_build('oai-lte-ue')
|
||||
attemptedImages += ['oai-lte-ue']
|
||||
|
||||
self._recreate_is_tag(mySSH, 'oai-nr-ue', imageTag, 'openshift/oai-nr-ue-is.yaml')
|
||||
self._recreate_bc(mySSH, 'oai-nr-ue', imageTag, 'openshift/oai-nr-ue-bc.yaml')
|
||||
self._retag_image_statement(mySSH, 'ran-base', 'image-registry.openshift-image-registry.svc:5000/oaicicd-ran/ran-base', baseTag, 'docker/Dockerfile.nrUE.rhel8.2')
|
||||
self._retag_image_statement(mySSH, 'ran-build', 'image-registry.openshift-image-registry.svc:5000/oaicicd-ran/ran-build', imageTag, 'docker/Dockerfile.nrUE.rhel8.2')
|
||||
nrue_job = self._start_build(mySSH, 'oai-nr-ue')
|
||||
self._recreate_is_tag('oai-nr-ue', imageTag, 'openshift/oai-nr-ue-is.yaml')
|
||||
self._recreate_bc('oai-nr-ue', imageTag, 'openshift/oai-nr-ue-bc.yaml')
|
||||
self._retag_image_statement('ran-base', 'image-registry.openshift-image-registry.svc:5000/oaicicd-ran/ran-base', baseTag, 'docker/Dockerfile.nrUE.rhel8.2')
|
||||
self._retag_image_statement('ran-build', 'image-registry.openshift-image-registry.svc:5000/oaicicd-ran/ran-build', imageTag, 'docker/Dockerfile.nrUE.rhel8.2')
|
||||
nrue_job = self._start_build('oai-nr-ue')
|
||||
attemptedImages += ['oai-nr-ue']
|
||||
|
||||
wait = lteue_job is not None and nrue_job is not None and self._wait_build_end(mySSH, [lteue_job, nrue_job], 600)
|
||||
wait = lteue_job is not None and nrue_job is not None and self._wait_build_end([lteue_job, nrue_job], 600)
|
||||
if not wait: logging.error('error during build of lteUE/nrUE')
|
||||
status = status and wait
|
||||
# recover logs
|
||||
mySSH.command(f'oc logs {lteue_job} &> cmake_targets/log/oai-lte-ue.log', '\$', 10)
|
||||
mySSH.command(f'oc logs {nrue_job} &> cmake_targets/log/oai-nr-ue.log', '\$', 10)
|
||||
mySSH.command('oc get pods.metrics.k8s.io >> cmake_targets/log/build-metrics.log', '\$', 10)
|
||||
self.cmd.run(f'oc logs {lteue_job} &> cmake_targets/log/oai-lte-ue.log')
|
||||
self.cmd.run(f'oc logs {nrue_job} &> cmake_targets/log/oai-nr-ue.log')
|
||||
self.cmd.run(f'oc get pods.metrics.k8s.io &>> cmake_targets/log/build-metrics.log', '\$', 10)
|
||||
|
||||
# split and analyze logs
|
||||
imageSize = {}
|
||||
for image in attemptedImages:
|
||||
mySSH.command(f'mkdir -p cmake_targets/log/{image}', '\$', 5)
|
||||
mySSH.command(f'python3 ci-scripts/docker_log_split.py --logfilename=cmake_targets/log/{image}.log', '\$', 5)
|
||||
self.cmd.run(f'mkdir -p cmake_targets/log/{image}')
|
||||
self.cmd.run(f'python3 ci-scripts/docker_log_split.py --logfilename=cmake_targets/log/{image}.log')
|
||||
tag = imageTag if image != 'ran-base' else baseTag
|
||||
size = self._get_image_size(mySSH, image, tag)
|
||||
size = self._get_image_size(image, tag)
|
||||
if size <= 0:
|
||||
imageSize[image] = 'unknown -- BUILD FAILED'
|
||||
status = False
|
||||
@@ -361,17 +348,17 @@ class Cluster:
|
||||
logging.info(f'\u001B[1m{image} size is {imageSize[image]}\u001B[0m')
|
||||
|
||||
grep_exp = "\|".join(attemptedImages)
|
||||
mySSH.command(f'oc get images | grep -e \'{grep_exp}\' &> cmake_targets/log/image_registry.log', '\$', 10);
|
||||
mySSH.command('for pod in $(oc get pods | tail -n +2 | awk \'{print $1}\'); do oc get pod $pod -o json >> cmake_targets/log/build_pod_summary.log; done', '\$', 60)
|
||||
self.cmd.run(f'oc get images | grep -e \'{grep_exp}\' &> cmake_targets/log/image_registry.log');
|
||||
self.cmd.run(f'for pod in $(oc get pods | tail -n +2 | awk \'{{print $1}}\'); do oc get pod $pod -o json &>> cmake_targets/log/build_pod_summary.log; done', '\$', 60)
|
||||
|
||||
build_log_name = f'build_log_{self.testCase_id}'
|
||||
cls_containerize.CopyLogsToExecutor(mySSH, lSourcePath, build_log_name, lIpAddr, 'oaicicd', CONST.CI_NO_PASSWORD)
|
||||
cls_containerize.CopyLogsToExecutor(self.cmd, lSourcePath, build_log_name)
|
||||
|
||||
mySSH.command('for pod in $(oc get pods | tail -n +2 | awk \'{print $1}\'); do oc delete pod ${pod}; done', '\$', 60)
|
||||
self.cmd.run('for pod in $(oc get pods | tail -n +2 | awk \'{print $1}\'); do oc delete pod ${pod}; done')
|
||||
|
||||
# logout will return eventually, but we don't care when -> start in background
|
||||
mySSH.command('oc logout &', '\$', 5)
|
||||
mySSH.close()
|
||||
self.cmd.run(f'oc logout')
|
||||
self.cmd.close()
|
||||
|
||||
# Analyze the logs
|
||||
collectInfo = cls_containerize.AnalyzeBuildLogs(build_log_name, attemptedImages, status)
|
||||
|
||||
214
ci-scripts/cls_cmd.py
Normal file
214
ci-scripts/cls_cmd.py
Normal file
@@ -0,0 +1,214 @@
|
||||
#/*
|
||||
# * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
|
||||
# * contributor license agreements. See the NOTICE file distributed with
|
||||
# * this work for additional information regarding copyright ownership.
|
||||
# * The OpenAirInterface Software Alliance licenses this file to You under
|
||||
# * the OAI Public License, Version 1.1 (the "License"); you may not use this file
|
||||
# * except in compliance with the License.
|
||||
# * You may obtain a copy of the License at
|
||||
# *
|
||||
# * http://www.openairinterface.org/?page_id=698
|
||||
# *
|
||||
# * Unless required by applicable law or agreed to in writing, software
|
||||
# * distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# * See the License for the specific language governing permissions and
|
||||
# * limitations under the License.
|
||||
# *-------------------------------------------------------------------------------
|
||||
# * For more information about the OpenAirInterface (OAI) Software Alliance:
|
||||
# * contact@openairinterface.org
|
||||
# */
|
||||
#---------------------------------------------------------------------
|
||||
#
|
||||
# Required Python Version
|
||||
# Python 3.x
|
||||
#
|
||||
#---------------------------------------------------------------------
|
||||
|
||||
import abc
|
||||
import logging
|
||||
import subprocess as sp
|
||||
import os
|
||||
import paramiko
|
||||
import uuid
|
||||
|
||||
# helper that returns either LocalCmd or RemoteCmd based on passed host name
|
||||
def getConnection(host, d=None):
|
||||
if host is None or host.lower() in ["", "none", "localhost"]:
|
||||
return LocalCmd(d=d)
|
||||
else:
|
||||
return RemoteCmd(host, d=d)
|
||||
|
||||
# provides a partial interface for the legacy SSHconnection class (getBefore(), command())
|
||||
class Cmd(metaclass=abc.ABCMeta):
|
||||
def cd(self, d, silent=False):
|
||||
if d == None or d == '':
|
||||
self.cwd = None
|
||||
elif d[0] == '/':
|
||||
self.cwd = d
|
||||
else:
|
||||
if not self.cwd:
|
||||
# no cwd set: get current working directory
|
||||
self.cwd = self.run('pwd').stdout.strip()
|
||||
self.cwd += f"/{d}"
|
||||
if not silent:
|
||||
logging.debug(f'cd {self.cwd}')
|
||||
|
||||
@abc.abstractmethod
|
||||
def run(self, line, timeout=300, silent=False):
|
||||
return
|
||||
|
||||
def command(self, commandline, expectedline=None, timeout=300, silent=False, resync=False):
|
||||
splitted = commandline.split(' ')
|
||||
if splitted[0] == 'cd':
|
||||
self.cd(' '.join(splitted[1:]), silent)
|
||||
else:
|
||||
self.run(commandline, timeout, silent)
|
||||
return 0
|
||||
|
||||
@abc.abstractmethod
|
||||
def close(self):
|
||||
return
|
||||
|
||||
@abc.abstractmethod
|
||||
def getBefore(self):
|
||||
return
|
||||
|
||||
@abc.abstractmethod
|
||||
def copyin(self, scpIp, scpUser, scpPw, src, tgt):
|
||||
return
|
||||
|
||||
@abc.abstractmethod
|
||||
def copyout(self, scpIp, scpUser, scpPw, src, tgt):
|
||||
return
|
||||
|
||||
class LocalCmd(Cmd):
|
||||
def __init__(self, d = None):
|
||||
self.cwd = d
|
||||
if self.cwd is not None:
|
||||
logging.debug(f'Working dir is {self.cwd}')
|
||||
self.cp = sp.CompletedProcess(args='', returncode=0, stdout='')
|
||||
|
||||
def run(self, line, timeout=300, silent=False, reportNonZero=True):
|
||||
if not silent:
|
||||
logging.info(line)
|
||||
try:
|
||||
if line.strip().endswith('&'):
|
||||
# if we wait for stdout, subprocess does not return before the end of the command
|
||||
# however, we don't want to wait for commands with &, so just return fake command
|
||||
ret = sp.run(line, shell=True, cwd=self.cwd, timeout=5)
|
||||
else:
|
||||
ret = sp.run(line, shell=True, cwd=self.cwd, stdout=sp.PIPE, stderr=sp.STDOUT, timeout=timeout)
|
||||
except Exception as e:
|
||||
ret = sp.CompletedProcess(args=line, returncode=255, stdout=f'Exception: {str(e)}'.encode('utf-8'))
|
||||
if ret.stdout is None:
|
||||
ret.stdout = b''
|
||||
ret.stdout = ret.stdout.decode('utf-8').strip()
|
||||
if reportNonZero and ret.returncode != 0:
|
||||
logging.warning(f'command "{ret.args}" returned non-zero returncode {ret.returncode}: output:\n{ret.stdout}')
|
||||
self.cp = ret
|
||||
return ret
|
||||
|
||||
def close(self):
|
||||
pass
|
||||
|
||||
def getBefore(self):
|
||||
return self.cp.stdout
|
||||
|
||||
def copyin(self, scpIp, scpUser, scpPw, src, tgt):
|
||||
self.run(f'cp -r {src} {tgt}')
|
||||
|
||||
def copyout(self, scpIp, scpUser, scpPw, src, tgt):
|
||||
self.run(f'cp -r {src} {tgt}')
|
||||
|
||||
class RemoteCmd(Cmd):
|
||||
def __init__(self, hostname, d=None):
|
||||
logging.getLogger('paramiko').setLevel(logging.ERROR) # prevent spamming through Paramiko
|
||||
self.client = paramiko.SSHClient()
|
||||
self.client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
|
||||
cfg = RemoteCmd._lookup_ssh_config(hostname)
|
||||
self.client.connect(**cfg)
|
||||
self.cwd = d
|
||||
self.cp = sp.CompletedProcess(args='', returncode=0, stdout='')
|
||||
|
||||
def _lookup_ssh_config(hostname):
|
||||
ssh_config = paramiko.SSHConfig()
|
||||
user_config_file = os.path.expanduser("~/.ssh/config")
|
||||
if os.path.exists(user_config_file):
|
||||
with open(user_config_file) as f:
|
||||
ssh_config.parse(f)
|
||||
else:
|
||||
raise FileNotFoundError('class needs SSH config at ~/.ssh/config')
|
||||
ucfg = ssh_config.lookup(hostname)
|
||||
if 'identityfile' not in ucfg or 'user' not in ucfg:
|
||||
raise KeyError(f'no identityfile or user in SSH config for host {hostname}')
|
||||
cfg = {'hostname':hostname, 'username':ucfg['user'], 'key_filename':ucfg['identityfile']}
|
||||
if 'hostname' in ucfg:
|
||||
cfg['hostname'] = ucfg['hostname'] # override user-given hostname with what is in config
|
||||
if 'port' in ucfg:
|
||||
cfg['port'] = int(ucfg['port'])
|
||||
if 'proxycommand' in ucfg:
|
||||
cfg['sock'] = paramiko.ProxyCommand(ucfg['proxycommand'])
|
||||
return cfg
|
||||
|
||||
def run(self, line, timeout=300, silent=False, reportNonZero=True):
|
||||
if not silent:
|
||||
logging.info(line)
|
||||
if self.cwd:
|
||||
line = f"cd {self.cwd} && {line}"
|
||||
try:
|
||||
if line.strip().endswith('&'):
|
||||
# if we wait for stdout, Paramiko does not return before the end of the command
|
||||
# however, we don't want to wait for commands with &, so just return fake command
|
||||
self.client.exec_command(line, timeout = 5)
|
||||
ret = sp.CompletedProcess(args=line, returncode=0, stdout=b'')
|
||||
else:
|
||||
stdin, stdout, stderr = self.client.exec_command(line, timeout=timeout)
|
||||
ret = sp.CompletedProcess(args=line, returncode=stdout.channel.recv_exit_status(), stdout=stdout.read(size=None) + stderr.read(size=None))
|
||||
except Exception as e:
|
||||
ret = sp.CompletedProcess(args=line, returncode=255, stdout=f'Exception: {str(e)}'.encode('utf-8'))
|
||||
ret.stdout = ret.stdout.decode('utf-8').strip()
|
||||
if reportNonZero and ret.returncode != 0:
|
||||
logging.warning(f'command "{line}" returned non-zero returncode {ret.returncode}: output:\n{ret.stdout}')
|
||||
self.cp = ret
|
||||
return ret
|
||||
|
||||
def close(self):
|
||||
self.client.close()
|
||||
|
||||
def getBefore(self):
|
||||
return self.cp.stdout
|
||||
|
||||
def copyout(self, src, tgt, recursive=False):
|
||||
logging.debug(f"copyout: local:{src} -> remote:{tgt}")
|
||||
if recursive:
|
||||
tmpfile = f"{uuid.uuid4()}.tar"
|
||||
abstmpfile = f"/tmp/{tmpfile}"
|
||||
cmd = LocalCmd()
|
||||
cmd.run(f"tar -cf {abstmpfile} {src}")
|
||||
sftp = self.client.open_sftp()
|
||||
sftp.put(abstmpfile, abstmpfile)
|
||||
sftp.close()
|
||||
cmd.run(f"rm {abstmpfile}")
|
||||
self.run(f"mv {abstmpfile} {tgt}; cd {tgt} && tar -xf {tmpfile} && rm {tmpfile}")
|
||||
else:
|
||||
sftp = self.client.open_sftp()
|
||||
sftp.put(src, tgt)
|
||||
sftp.close()
|
||||
|
||||
def copyin(self, src, tgt, recursive=False):
|
||||
logging.debug(f"copyin: remote:{src} -> local:{tgt}")
|
||||
if recursive:
|
||||
tmpfile = f"{uuid.uuid4()}.tar"
|
||||
abstmpfile = f"/tmp/{tmpfile}"
|
||||
self.run(f"tar -cf {abstmpfile} {src}")
|
||||
sftp = self.client.open_sftp()
|
||||
sftp.get(abstmpfile, abstmpfile)
|
||||
sftp.close()
|
||||
self.run(f"rm {abstmpfile}")
|
||||
cmd = LocalCmd()
|
||||
cmd.run(f"mv {abstmpfile} {tgt}; cd {tgt} && tar -xf {tmpfile} && rm {tmpfile}")
|
||||
else:
|
||||
sftp = self.client.open_sftp()
|
||||
sftp.get(src, tgt)
|
||||
sftp.close()
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,138 +0,0 @@
|
||||
# * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
|
||||
# * contributor license agreements. See the NOTICE file distributed with
|
||||
# * this work for additional information regarding copyright ownership.
|
||||
# * The OpenAirInterface Software Alliance licenses this file to You under
|
||||
# * the OAI Public License, Version 1.1 (the "License"); you may not use this file
|
||||
# * except in compliance with the License.
|
||||
# * You may obtain a copy of the License at
|
||||
# *
|
||||
# * http://www.openairinterface.org/?page_id=698
|
||||
# *
|
||||
# * Unless required by applicable law or agreed to in writing, software
|
||||
# * distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# * See the License for the specific language governing permissions and
|
||||
# * limitations under the License.
|
||||
# *-------------------------------------------------------------------------------
|
||||
# * For more information about the OpenAirInterface (OAI) Software Alliance:
|
||||
# * contact@openairinterface.org
|
||||
# */
|
||||
#---------------------------------------------------------------------
|
||||
# Python for CI of OAI-eNB + COTS-UE
|
||||
#
|
||||
# Required Python Version
|
||||
# Python 3.x
|
||||
#
|
||||
# Required Python Package
|
||||
# pexpect
|
||||
#---------------------------------------------------------------------
|
||||
|
||||
#to use isfile
|
||||
import os
|
||||
import sys
|
||||
#to use logging.info()
|
||||
import logging
|
||||
#to create a SSH object locally in the methods
|
||||
import sshconnection
|
||||
#time.sleep
|
||||
import time
|
||||
#to load cots_ue dictionary
|
||||
import yaml
|
||||
|
||||
class CotsUe:
|
||||
def __init__(self,ADBIPAddr,ADBUserName,ADBPassWord):
|
||||
self.cots_id = '' #cots id from yaml oppo, s10 etc...
|
||||
self.ADBIPAddr = ADBIPAddr
|
||||
self.ADBUserName = ADBUserName
|
||||
self.ADBPassWord = ADBPassWord
|
||||
self.cots_run_mode = '' #on of off to toggle airplane mode on/off
|
||||
self.__cots_cde_dict_file = 'cots_ue_ctl.yaml'
|
||||
self.__SetAirplaneRetry = 3
|
||||
|
||||
|
||||
#-----------------$
|
||||
#PUBLIC Methods$
|
||||
#-----------------$
|
||||
|
||||
def Check_Airplane(self):
|
||||
mySSH = sshconnection.SSHConnection()
|
||||
mySSH.open(self.ADBIPAddr, self.ADBUserName, self.ADBPassWord)
|
||||
status=mySSH.cde_check_value('adb shell settings get global airplane_mode_on ', ['0','1'],5)
|
||||
mySSH.close()
|
||||
return status
|
||||
|
||||
#simply check if the device id exists in the dictionary
|
||||
#returns true if it exists, false otherwise
|
||||
def Check_Exists(self,target_id):
|
||||
#load cots commands dictionary
|
||||
if (os.path.isfile(self.__cots_cde_dict_file)):
|
||||
yaml_file=self.__cots_cde_dict_file
|
||||
elif (os.path.isfile('ci-scripts/'+self.__cots_cde_dict_file)):
|
||||
yaml_file='ci-scripts/'+self.__cots_cde_dict_file
|
||||
else:
|
||||
logging.error("COTS UE dictionary yaml file cannot be found")
|
||||
sys.exit("COTS UE dictionary yaml file cannot be found")
|
||||
|
||||
#load cots commands dictionary
|
||||
with open(yaml_file,'r') as file:
|
||||
cots_ue_ctl = yaml.load(file,Loader=yaml.FullLoader)
|
||||
#check if ue id is in the dictionary
|
||||
if target_id in cots_ue_ctl:
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
|
||||
def Set_Airplane(self, target_id, target_state_str):
|
||||
#loading cots commands dictionary
|
||||
|
||||
if (os.path.isfile(self.__cots_cde_dict_file)):
|
||||
yaml_file=self.__cots_cde_dict_file
|
||||
elif (os.path.isfile('ci-scripts/'+self.__cots_cde_dict_file)):
|
||||
yaml_file='ci-scripts/'+self.__cots_cde_dict_file
|
||||
else:
|
||||
logging.error("COTS UE dictionary yaml file cannot be found")
|
||||
sys.exit("COTS UE dictionary yaml file cannot be found")
|
||||
|
||||
#load cots commands dictionary
|
||||
with open(yaml_file,'r') as file:
|
||||
cots_ue_ctl = yaml.load(file,Loader=yaml.FullLoader)
|
||||
#check if ue id is in the dictionary
|
||||
if target_id in cots_ue_ctl:
|
||||
mySSH = sshconnection.SSHConnection()
|
||||
mySSH.open(self.ADBIPAddr, self.ADBUserName, self.ADBPassWord)
|
||||
logging.info(str(self.ADBIPAddr)+' '+str(self.ADBUserName)+' '+str(self.ADBPassWord))
|
||||
mySSH.command('adb start-server','\$',5)
|
||||
mySSH.command('adb devices','\$',5)
|
||||
logging.info("Toggling COTS UE Airplane mode to : "+target_state_str)
|
||||
#get current state
|
||||
current_state = self.Check_Airplane()
|
||||
if target_state_str.lower()=="on":
|
||||
target_state=1
|
||||
else:
|
||||
target_state=0
|
||||
if current_state != target_state:
|
||||
#toggle state
|
||||
retry = 0
|
||||
while (current_state!=target_state) and (retry < self.__SetAirplaneRetry):
|
||||
#loop over the command list from dictionary for the selected ue, to switch to required state
|
||||
for i in range (0,len(cots_ue_ctl[target_id])):
|
||||
mySSH.command(cots_ue_ctl[target_id][i], '\$', 5)
|
||||
time.sleep(1)
|
||||
current_state = self.Check_Airplane()
|
||||
retry+=1
|
||||
#could not toggle despite the retry
|
||||
if current_state != target_state:
|
||||
logging.error("ATTENTION : Could not toggle to : "+target_state_str)
|
||||
logging.error("Current state is : "+ str(current_state))
|
||||
else:
|
||||
logging.info("Airplane mode is already "+ target_state_str)
|
||||
mySSH.command('adb kill-server','\$',5)
|
||||
mySSH.close()
|
||||
#ue id is NOT in the dictionary
|
||||
else:
|
||||
logging.error("COTS UE Id from XML could not be found in UE YAML dictionary " + self.__cots_cde_dict_file)
|
||||
sys.exit("COTS UE Id from XML could not be found in UE YAML dictionary " + self.__cots_cde_dict_file)
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -28,177 +28,197 @@
|
||||
import os
|
||||
import sys
|
||||
import logging
|
||||
#to create a SSH object locally in the methods
|
||||
import sshconnection
|
||||
#time.sleep
|
||||
import time
|
||||
|
||||
|
||||
import re
|
||||
import subprocess
|
||||
|
||||
from datetime import datetime
|
||||
import yaml
|
||||
|
||||
#for log rotation mgt
|
||||
import cls_log_mgt
|
||||
import cls_cmd
|
||||
|
||||
class Module_UE:
|
||||
|
||||
def __init__(self,Module):
|
||||
#create attributes as in the Module dictionary
|
||||
for k, v in Module.items():
|
||||
setattr(self, k, v)
|
||||
self.UEIPAddress = ""
|
||||
#dictionary linking command names and related module scripts
|
||||
self.cmd_dict= {"wup": self.WakeupScript,"detach":self.DetachScript}#dictionary of function scripts
|
||||
self.ue_trace=''
|
||||
def __init__(self, module_name, filename="ci_ueinfra.yaml"):
|
||||
with open(filename, 'r') as f:
|
||||
all_ues = yaml.load(f, Loader=yaml.FullLoader)
|
||||
m = all_ues.get(module_name)
|
||||
if m is None:
|
||||
raise Exception(f'no such module name "{module_name}" in "{filename}"')
|
||||
self.module_name = module_name
|
||||
self.host = m['Host']
|
||||
self.cmd_dict = {
|
||||
"attach": m.get('AttachScript'),
|
||||
"detach": m.get('DetachScript'),
|
||||
"initialize": m.get('InitScript'),
|
||||
"terminate": m.get('TermScript'),
|
||||
"getNetwork": m.get('UENetworkScript'),
|
||||
"check": m.get('CheckStatusScript'),
|
||||
"dataEnable": m.get('DataEnableScript'),
|
||||
"dataDisable": m.get('DataDisableScript'),
|
||||
}
|
||||
self.interface = m.get('IF')
|
||||
self.MTU = m.get('MTU')
|
||||
self.trace = m.get('trace') == True
|
||||
self.logStore = m.get('LogStore')
|
||||
self.cmd_prefix = m.get('CmdPrefix')
|
||||
logging.info(f'initialized UE {self.module_name}@{self.host} from {filename}')
|
||||
|
||||
def __str__(self):
|
||||
return f"{self.module_name}@{self.host} [IP: {self.getIP()}]"
|
||||
|
||||
def __repr__(self):
|
||||
return self.__str__()
|
||||
|
||||
def _command(self, cmd, silent = False):
|
||||
if cmd is None:
|
||||
raise Exception("no command provided")
|
||||
if self.host == "" or self.host == "localhost":
|
||||
c = cls_cmd.LocalCmd()
|
||||
else:
|
||||
c = cls_cmd.RemoteCmd(self.host)
|
||||
response = c.run(cmd, silent=silent)
|
||||
c.close()
|
||||
return response.stdout
|
||||
|
||||
#-----------------$
|
||||
#PUBLIC Methods$
|
||||
#-----------------$
|
||||
|
||||
#this method checks if the specified Process is running on the server hosting the module
|
||||
#if not it will be started
|
||||
def CheckCMProcess(self,CNType):
|
||||
HOST=self.HostUsername+'@'+self.HostIPAddress
|
||||
COMMAND="ps aux | grep --colour=never " + self.Process['Name'] + " | grep -v grep "
|
||||
logging.debug(COMMAND)
|
||||
ssh = subprocess.Popen(["ssh", "%s" % HOST, COMMAND],shell=False,stdout=subprocess.PIPE,stderr=subprocess.PIPE)
|
||||
result = ssh.stdout.readlines()
|
||||
if len(result)!=0:
|
||||
logging.debug(self.Process['Name'] + " process found")
|
||||
return True
|
||||
else:#start process and check again
|
||||
logging.debug(self.Process['Name'] + " process NOT found")
|
||||
#starting the process
|
||||
logging.debug('Starting ' + self.Process['Name'])
|
||||
mySSH = sshconnection.SSHConnection()
|
||||
mySSH.open(self.HostIPAddress, self.HostUsername, self.HostPassword)
|
||||
mySSH.command('echo ' + self.HostPassword + ' | sudo -S rm -f /tmp/quectel-cm.log','\$',5)
|
||||
mySSH.command('echo $USER; echo ' + self.HostPassword + ' | nohup sudo -S stdbuf -o0 ' + self.Process['Cmd'] + ' ' + self.Process['Apn'][CNType] + ' > /tmp/quectel-cm.log 2>&1 &','\$',5)
|
||||
mySSH.close()
|
||||
#checking the process
|
||||
def initialize(self):
|
||||
if self.trace:
|
||||
raise Exception("UE tracing not implemented yet")
|
||||
self._enableTrace()
|
||||
# we first terminate to make sure the UE has been stopped
|
||||
if self.cmd_dict["detach"]:
|
||||
self._command(self.cmd_dict["detach"], silent=True)
|
||||
self._command(self.cmd_dict["terminate"], silent=True)
|
||||
self._command(self.cmd_dict["initialize"])
|
||||
|
||||
def terminate(self):
|
||||
self._command(self.cmd_dict["terminate"])
|
||||
if self.trace:
|
||||
raise Exception("UE tracing not implemented yet")
|
||||
self._disableTrace()
|
||||
return self._logCollect()
|
||||
return None
|
||||
|
||||
def attach(self, attach_tries = 4, attach_timeout = 60):
|
||||
ip = None
|
||||
while attach_tries > 0:
|
||||
self._command(self.cmd_dict["attach"])
|
||||
timeout = attach_timeout
|
||||
logging.debug("Waiting for IP address to be assigned")
|
||||
while timeout > 0 and not ip:
|
||||
time.sleep(5)
|
||||
timeout -= 5
|
||||
ip = self.getIP()
|
||||
if ip:
|
||||
break
|
||||
logging.warning(f"UE did not receive IP address after {attach_timeout} s, detaching")
|
||||
attach_tries -= 1
|
||||
self._command(self.cmd_dict["detach"])
|
||||
time.sleep(5)
|
||||
HOST=self.HostUsername+'@'+self.HostIPAddress
|
||||
COMMAND="ps aux | grep --colour=never " + self.Process['Name'] + " | grep -v grep "
|
||||
logging.debug(COMMAND)
|
||||
ssh = subprocess.Popen(["ssh", "%s" % HOST, COMMAND],shell=False,stdout=subprocess.PIPE,stderr=subprocess.PIPE)
|
||||
result = ssh.stdout.readlines()
|
||||
if len(result)!=0:
|
||||
logging.debug(self.Process['Name'] + " process found")
|
||||
return True
|
||||
else:
|
||||
logging.debug(self.Process['Name'] + " process NOT found")
|
||||
return False
|
||||
|
||||
#Generic command function, using function pointers dictionary
|
||||
def Command(self,cmd):
|
||||
mySSH = sshconnection.SSHConnection()
|
||||
mySSH.open(self.HostIPAddress, self.HostUsername, self.HostPassword)
|
||||
mySSH.command('echo ' + self.HostPassword + ' | sudo -S python3 ' + self.cmd_dict[cmd],'\$',10)
|
||||
time.sleep(5)
|
||||
logging.debug("Module "+ cmd)
|
||||
mySSH.close()
|
||||
|
||||
|
||||
#this method retrieves the Module IP address (not the Host IP address)
|
||||
def GetModuleIPAddress(self):
|
||||
HOST=self.HostUsername+'@'+self.HostIPAddress
|
||||
response= []
|
||||
tentative = 8
|
||||
while (len(response)==0) and (tentative>0):
|
||||
COMMAND="ip a show dev " + self.UENetwork + " | grep --colour=never inet | grep " + self.UENetwork
|
||||
if tentative == 8:
|
||||
logging.debug(COMMAND)
|
||||
ssh = subprocess.Popen(["ssh", "%s" % HOST, COMMAND],shell=False,stdout=subprocess.PIPE,stderr=subprocess.PIPE)
|
||||
response = ssh.stdout.readlines()
|
||||
tentative-=1
|
||||
time.sleep(2)
|
||||
if (tentative==0) and (len(response)==0):
|
||||
logging.debug('\u001B[1;37;41m Module IP Address Not Found! Time expired \u001B[0m')
|
||||
return -1
|
||||
else: #check response
|
||||
result = re.search('inet (?P<moduleipaddress>[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+)', response[0].decode("utf-8") )
|
||||
if result is not None:
|
||||
if result.group('moduleipaddress') is not None:
|
||||
self.UEIPAddress = result.group('moduleipaddress')
|
||||
logging.debug('\u001B[1mUE Module IP Address is ' + self.UEIPAddress + '\u001B[0m')
|
||||
return 0
|
||||
else:
|
||||
logging.debug('\u001B[1;37;41m Module IP Address Not Found! \u001B[0m')
|
||||
return -1
|
||||
else:
|
||||
logging.debug('\u001B[1;37;41m Module IP Address Not Found! \u001B[0m')
|
||||
return -1
|
||||
|
||||
def CheckModuleMTU(self):
|
||||
HOST=self.HostUsername+'@'+self.HostIPAddress
|
||||
response= []
|
||||
tentative = 3
|
||||
while (len(response)==0) and (tentative>0):
|
||||
COMMAND="ip a show dev " + self.UENetwork + " | grep --colour=never mtu"
|
||||
logging.debug(COMMAND)
|
||||
ssh = subprocess.Popen(["ssh", "%s" % HOST, COMMAND],shell=False,stdout=subprocess.PIPE,stderr=subprocess.PIPE)
|
||||
response = ssh.stdout.readlines()
|
||||
tentative-=1
|
||||
time.sleep(10)
|
||||
if (tentative==0) and (len(response)==0):
|
||||
logging.debug('\u001B[1;37;41m Module NIC MTU Not Found! Time expired \u001B[0m')
|
||||
return -1
|
||||
else: #check response
|
||||
result = re.search('mtu (?P<mtu>[0-9]+)', response[0].decode("utf-8") )
|
||||
if result is not None:
|
||||
if (result.group('mtu') is not None) and (str(result.group('mtu'))==str(self.MTU)) :
|
||||
logging.debug('\u001B[1mUE Module NIC MTU is ' + str(self.MTU) + ' as expected\u001B[0m')
|
||||
return 0
|
||||
else:
|
||||
logging.debug('\u001B[1;37;41m Incorrect Module NIC MTU ' + str(result.group('mtu')) + '! Expected : ' + str(self.MTU) + '\u001B[0m')
|
||||
return -1
|
||||
else:
|
||||
logging.debug('\u001B[1;37;41m Module NIC MTU Not Found! \u001B[0m')
|
||||
return -1
|
||||
|
||||
def EnableTrace(self):
|
||||
if self.ue_trace=="yes":
|
||||
mySSH = sshconnection.SSHConnection()
|
||||
mySSH.open(self.HostIPAddress, self.HostUsername, self.HostPassword)
|
||||
#delete old artifacts
|
||||
mySSH.command('echo ' + self.HostPassword + ' | sudo -S rm -rf ci_qlog','\$',5)
|
||||
#start Trace, artifact is created in home dir
|
||||
mySSH.command('echo $USER; nohup sudo -E QLog/QLog -s ci_qlog -f NR5G.cfg > /dev/null 2>&1 &','\$', 5)
|
||||
mySSH.close()
|
||||
|
||||
def DisableTrace(self):
|
||||
mySSH = sshconnection.SSHConnection()
|
||||
mySSH.open(self.HostIPAddress, self.HostUsername, self.HostPassword)
|
||||
mySSH.command('echo ' + self.HostPassword + ' | sudo -S killall --signal=SIGINT *QLog*', '\$',5)
|
||||
mySSH.close()
|
||||
|
||||
|
||||
def DisableCM(self):
|
||||
mySSH = sshconnection.SSHConnection()
|
||||
mySSH.open(self.HostIPAddress, self.HostUsername, self.HostPassword)
|
||||
mySSH.command('echo ' + self.HostPassword + ' | sudo -S killall --signal SIGKILL *'+self.Process['Name']+'*', '\$', 5)
|
||||
mySSH.close()
|
||||
|
||||
|
||||
def LogCollect(self):
|
||||
if self.ue_trace=="yes":
|
||||
mySSH = sshconnection.SSHConnection()
|
||||
mySSH.open(self.HostIPAddress, self.HostUsername, self.HostPassword)
|
||||
#archive qlog to USB stick in /media/usb-drive/ci_qlogs with datetime suffix
|
||||
now=datetime.now()
|
||||
now_string = now.strftime("%Y%m%d-%H%M")
|
||||
source='ci_qlog'
|
||||
destination= self.LogStore + '/ci_qlog_'+now_string+'.zip'
|
||||
#qlog artifact is zipped into the target folder
|
||||
mySSH.command('echo $USER; echo ' + self.HostPassword + ' | nohup sudo -S zip -r '+destination+' '+source+' > /dev/null 2>&1 &','\$', 10)
|
||||
mySSH.close()
|
||||
#post action : log cleaning to make sure enough space is reserved for the next run
|
||||
Log_Mgt=cls_log_mgt.Log_Mgt(self.HostUsername,self.HostIPAddress, self.HostPassword, self.LogStore)
|
||||
Log_Mgt.LogRotation()
|
||||
if ip:
|
||||
logging.debug(f'\u001B[1mUE IP Address is {ip}\u001B[0m')
|
||||
else:
|
||||
destination=""
|
||||
logging.debug('\u001B[1;37;41mUE IP Address Not Found!\u001B[0m')
|
||||
return ip
|
||||
|
||||
def detach(self):
|
||||
self._command(self.cmd_dict["detach"])
|
||||
|
||||
def check(self):
|
||||
cmd = self.cmd_dict["check"]
|
||||
if cmd:
|
||||
return self._command(cmd)
|
||||
else:
|
||||
logging.warning(f"requested status check of UE {self.getName()}, but operation is not supported")
|
||||
return f"UE {self.getName()} does not support status checking"
|
||||
|
||||
def dataEnable(self):
|
||||
cmd = self.cmd_dict["dataEnable"]
|
||||
if cmd:
|
||||
self._command(cmd)
|
||||
return True
|
||||
else:
|
||||
message = f"requested enabling data of UE {self.getName()}, but operation is not supported"
|
||||
logging.error(message)
|
||||
return False
|
||||
|
||||
def dataDisable(self):
|
||||
cmd = self.cmd_dict["dataDisable"]
|
||||
if cmd:
|
||||
self._command(cmd)
|
||||
return True
|
||||
else:
|
||||
message = f"requested disabling data of UE {self.getName()}, but operation is not supported"
|
||||
logging.error(message)
|
||||
return False
|
||||
|
||||
def getIP(self):
|
||||
output = self._command(self.cmd_dict["getNetwork"], silent=True)
|
||||
result = re.search('inet (?P<ip>[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+)', output)
|
||||
if result and result.group('ip'):
|
||||
ip = result.group('ip')
|
||||
return ip
|
||||
return None
|
||||
|
||||
def checkMTU(self):
|
||||
output = self._command(self.cmd_dict["getNetwork"], silent=True)
|
||||
result = re.search('mtu (?P<mtu>[0-9]+)', output)
|
||||
if result and result.group('mtu') and int(result.group('mtu')) == self.MTU:
|
||||
logging.debug('\u001B[1mUE Module NIC MTU is ' + str(self.MTU) + ' as expected\u001B[0m')
|
||||
return True
|
||||
else:
|
||||
logging.debug('\u001B[1;37;41m Incorrect Module NIC MTU or MTU not found! Expected: ' + str(self.MTU) + '\u001B[0m')
|
||||
return False
|
||||
|
||||
def getName(self):
|
||||
return self.module_name
|
||||
|
||||
def getIFName(self):
|
||||
return self.interface
|
||||
|
||||
def getHost(self):
|
||||
return self.host
|
||||
|
||||
def getCmdPrefix(self):
|
||||
return self.cmd_prefix if self.cmd_prefix else ""
|
||||
|
||||
def _enableTrace(self):
|
||||
raise Exception("not implemented")
|
||||
mySSH = sshconnection.SSHConnection()
|
||||
mySSH.open(self.HostIPAddress, self.HostUsername, self.HostPassword)
|
||||
#delete old artifacts
|
||||
mySSH.command('echo ' + ' ' + ' | sudo -S rm -rf ci_qlog','\$',5)
|
||||
#start Trace, artifact is created in home dir
|
||||
mySSH.command('echo $USER; nohup sudo -E QLog/QLog -s ci_qlog -f NR5G.cfg > /dev/null 2>&1 &','\$', 5)
|
||||
mySSH.close()
|
||||
|
||||
def _disableTrace(self):
|
||||
raise Exception("not implemented")
|
||||
mySSH = sshconnection.SSHConnection()
|
||||
mySSH.open(self.HostIPAddress, self.HostUsername, self.HostPassword)
|
||||
mySSH.command('echo ' + ' ' + ' | sudo -S killall --signal=SIGINT *QLog*', '\$',5)
|
||||
mySSH.close()
|
||||
|
||||
|
||||
def _logCollect(self):
|
||||
raise Exception("not implemented")
|
||||
mySSH = sshconnection.SSHConnection()
|
||||
mySSH.open(self.HostIPAddress, self.HostUsername, self.HostPassword)
|
||||
#archive qlog to USB stick in /media/usb-drive/ci_qlogs with datetime suffix
|
||||
now=datetime.now()
|
||||
now_string = now.strftime("%Y%m%d-%H%M")
|
||||
source='ci_qlog'
|
||||
destination= self.LogStore + '/ci_qlog_'+now_string+'.zip'
|
||||
#qlog artifact is zipped into the target folder
|
||||
mySSH.command('echo $USER; echo ' + ' ' + ' | nohup sudo -S zip -r '+destination+' '+source+' > /dev/null 2>&1 &','\$', 10)
|
||||
mySSH.close()
|
||||
#post action : log cleaning to make sure enough space is reserved for the next run
|
||||
Log_Mgt=cls_log_mgt.Log_Mgt(self.HostUsername,self.HostIPAddress, self.HostPassword, self.LogStore)
|
||||
return destination
|
||||
|
||||
|
||||
@@ -84,16 +84,6 @@ class HTMLManagement():
|
||||
self.CpuModel = ['', '']
|
||||
self.CpuMHz = ['', '']
|
||||
|
||||
#-----------------------------------------------------------
|
||||
# Setters and Getters
|
||||
#-----------------------------------------------------------
|
||||
|
||||
def SethtmlUEConnected(self, nbUEs):
|
||||
if nbUEs > 0:
|
||||
self.htmlUEConnected = nbUEs
|
||||
else:
|
||||
self.htmlUEConnected = 1
|
||||
|
||||
|
||||
|
||||
#-----------------------------------------------------------
|
||||
@@ -101,7 +91,7 @@ class HTMLManagement():
|
||||
#-----------------------------------------------------------
|
||||
|
||||
|
||||
def CreateHtmlHeader(self, ADBIPAddress):
|
||||
def CreateHtmlHeader(self):
|
||||
if (not self.htmlHeaderCreated):
|
||||
logging.info('\u001B[1m----------------------------------------\u001B[0m')
|
||||
logging.info('\u001B[1m Creating HTML header \u001B[0m')
|
||||
@@ -116,7 +106,7 @@ class HTMLManagement():
|
||||
self.htmlFile.write(' <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>\n')
|
||||
self.htmlFile.write(' <title>Test Results for TEMPLATE_JOB_NAME job build #TEMPLATE_BUILD_ID</title>\n')
|
||||
self.htmlFile.write('</head>\n')
|
||||
self.htmlFile.write('<body><div class="container">\n')
|
||||
self.htmlFile.write('<body><div class="container-fluid" style="margin-left:1em; margin-right:1em">\n')
|
||||
self.htmlFile.write(' <br>\n')
|
||||
self.htmlFile.write(' <table style="border-collapse: collapse; border: none;">\n')
|
||||
self.htmlFile.write(' <tr style="border-collapse: collapse; border: none;">\n')
|
||||
@@ -183,15 +173,6 @@ class HTMLManagement():
|
||||
self.htmlFile.write(' </tr>\n')
|
||||
self.htmlFile.write(' </table>\n')
|
||||
|
||||
if (ADBIPAddress != 'none') and (ADBIPAddress != 'modules'):
|
||||
self.htmlFile.write(' <h2><span class="glyphicon glyphicon-phone"></span> <span class="glyphicon glyphicon-menu-right"></span> ' + str(self.htmlNb_Smartphones) + ' UE(s) is(are) connected to ADB bench server</h2>\n')
|
||||
self.htmlFile.write(' <h2><span class="glyphicon glyphicon-phone"></span> <span class="glyphicon glyphicon-menu-right"></span> ' + str(self.htmlNb_CATM_Modules) + ' CAT-M UE(s) is(are) connected to bench server</h2>\n')
|
||||
elif (ADBIPAddress == 'modules'):
|
||||
self.htmlUEConnected = 1
|
||||
self.htmlFile.write(' <h2><span class="glyphicon glyphicon-phone"></span> <span class="glyphicon glyphicon-menu-right"></span> 1 commercial module is connected to CI bench</h2>\n')
|
||||
else:
|
||||
self.htmlUEConnected = 1
|
||||
self.htmlFile.write(' <h2><span class="glyphicon glyphicon-phone"></span> <span class="glyphicon glyphicon-menu-right"></span> 1 OAI UE(s) is(are) connected to CI bench</h2>\n')
|
||||
self.htmlFile.write(' <br>\n')
|
||||
self.htmlFile.write(' <ul class="nav nav-pills">\n')
|
||||
count = 0
|
||||
@@ -225,16 +206,13 @@ class HTMLManagement():
|
||||
self.htmlFile.write(' <div id="build-tab" class="tab-pane fade">\n')
|
||||
self.htmlFile.write(' <table class="table" border = "1">\n')
|
||||
self.htmlFile.write(' <tr bgcolor = "#33CCFF" >\n')
|
||||
self.htmlFile.write(' <th>Relative Time (s)</th>\n')
|
||||
self.htmlFile.write(' <th>Test Id</th>\n')
|
||||
self.htmlFile.write(' <th style="width:5%">Relative Time (s)</th>\n')
|
||||
self.htmlFile.write(' <th style="width:5%">Test Id</th>\n')
|
||||
self.htmlFile.write(' <th>Test Desc</th>\n')
|
||||
self.htmlFile.write(' <th>Test Options</th>\n')
|
||||
self.htmlFile.write(' <th>Test Status</th>\n')
|
||||
self.htmlFile.write(' <th style="width:5%">Test Status</th>\n')
|
||||
|
||||
i = 0
|
||||
while (i < self.htmlUEConnected):
|
||||
self.htmlFile.write(' <th>UE' + str(i) + ' Status</th>\n')
|
||||
i += 1
|
||||
self.htmlFile.write(' <th>Info</th>\n')
|
||||
self.htmlFile.write(' </tr>\n')
|
||||
self.htmlFile.close()
|
||||
self.htmlHeaderCreated = True
|
||||
@@ -247,14 +225,14 @@ class HTMLManagement():
|
||||
testOkEvenIfUnstable = True
|
||||
self.htmlFile = open('test_results.html', 'a')
|
||||
self.htmlFile.write(' <tr>\n')
|
||||
self.htmlFile.write(' <th bgcolor = "#33CCFF" colspan=3>Final Tab Status</th>\n')
|
||||
self.htmlFile.write(' <th bgcolor = "#33CCFF" colspan="3">Final Tab Status</th>\n')
|
||||
if passStatus:
|
||||
self.htmlFile.write(' <th bgcolor = "green" colspan=' + str(2 + self.htmlUEConnected) + '><font color="white">PASS <span class="glyphicon glyphicon-ok"></span> </font></th>\n')
|
||||
self.htmlFile.write(' <th bgcolor = "green" colspan="3"><font color="white">PASS <span class="glyphicon glyphicon-ok"></span> </font></th>\n')
|
||||
else:
|
||||
if testOkEvenIfUnstable:
|
||||
self.htmlFile.write(' <th bgcolor = "orange" colspan=' + str(2 + self.htmlUEConnected) + '><font color="white">KNOWN UNSTABLE SCENARIO <span class="glyphicon glyphicon-exclamation-sign"></span> </font></th>\n')
|
||||
self.htmlFile.write(' <th bgcolor = "orange" colspan="3"><font color="white">KNOWN UNSTABLE SCENARIO <span class="glyphicon glyphicon-exclamation-sign"></span> </font></th>\n')
|
||||
else:
|
||||
self.htmlFile.write(' <th bgcolor = "red" colspan=' + str(2 + self.htmlUEConnected) + '><font color="white">FAIL <span class="glyphicon glyphicon-remove"></span> </font></th>\n')
|
||||
self.htmlFile.write(' <th bgcolor = "red" colspan="3"><font color="white">FAIL <span class="glyphicon glyphicon-remove"></span> </font></th>\n')
|
||||
self.htmlFile.write(' </tr>\n')
|
||||
self.htmlFile.write(' </table>\n')
|
||||
self.htmlFile.write(' </div>\n')
|
||||
@@ -287,45 +265,12 @@ class HTMLManagement():
|
||||
self.htmlFile.write(' <p></p>\n')
|
||||
self.htmlFile.write(' <table class="table table-condensed">\n')
|
||||
|
||||
machines = [ 'eNB', 'UE' ]
|
||||
for machine in machines:
|
||||
if machine == 'eNB':
|
||||
idx = 0
|
||||
else:
|
||||
idx = 1
|
||||
if self.OsVersion[idx] == '':
|
||||
continue
|
||||
|
||||
self.htmlFile.write(' <tr>\n')
|
||||
self.htmlFile.write(' <th colspan=8>' + str(machine) + ' Server Characteristics</th>\n')
|
||||
self.htmlFile.write(' </tr>\n')
|
||||
self.htmlFile.write(' <tr>\n')
|
||||
self.htmlFile.write(' <td>OS Version</td>\n')
|
||||
self.htmlFile.write(' <td><span class="label label-default">' + self.OsVersion[idx] + '</span></td>\n')
|
||||
self.htmlFile.write(' <td>Kernel Version</td>\n')
|
||||
self.htmlFile.write(' <td><span class="label label-default">' + self.KernelVersion[idx] + '</span></td>\n')
|
||||
self.htmlFile.write(' <td>UHD Version</td>\n')
|
||||
self.htmlFile.write(' <td><span class="label label-default">' + self.UhdVersion[idx] + '</span></td>\n')
|
||||
self.htmlFile.write(' <td>USRP Board</td>\n')
|
||||
self.htmlFile.write(' <td><span class="label label-default">' + self.UsrpBoard[idx] + '</span></td>\n')
|
||||
self.htmlFile.write(' </tr>\n')
|
||||
self.htmlFile.write(' <tr>\n')
|
||||
self.htmlFile.write(' <td>Nb CPUs</td>\n')
|
||||
self.htmlFile.write(' <td><span class="label label-default">' + self.CpuNb[idx] + '</span></td>\n')
|
||||
self.htmlFile.write(' <td>CPU Model Name</td>\n')
|
||||
self.htmlFile.write(' <td><span class="label label-default">' + self.CpuModel[idx] + '</span></td>\n')
|
||||
self.htmlFile.write(' <td>CPU Frequency</td>\n')
|
||||
self.htmlFile.write(' <td><span class="label label-default">' + self.CpuMHz[idx] + '</span></td>\n')
|
||||
self.htmlFile.write(' <td></td>\n')
|
||||
self.htmlFile.write(' <td></td>\n')
|
||||
self.htmlFile.write(' </tr>\n')
|
||||
|
||||
self.htmlFile.write(' <tr>\n')
|
||||
self.htmlFile.write(' <th colspan=5 bgcolor = "#33CCFF">Final Status</th>\n')
|
||||
self.htmlFile.write(' <th colspan="5" bgcolor = "#33CCFF">Final Status</th>\n')
|
||||
if passStatus:
|
||||
self.htmlFile.write(' <th colspan=3 bgcolor="green"><font color="white">PASS <span class="glyphicon glyphicon-ok"></span></font></th>\n')
|
||||
self.htmlFile.write(' <th colspan="3" bgcolor="green"><font color="white">PASS <span class="glyphicon glyphicon-ok"></span></font></th>\n')
|
||||
else:
|
||||
self.htmlFile.write(' <th colspan=3 bgcolor="red"><font color="white">FAIL <span class="glyphicon glyphicon-remove"></span> </font></th>\n')
|
||||
self.htmlFile.write(' <th colspan="3" bgcolor="red"><font color="white">FAIL <span class="glyphicon glyphicon-remove"></span> </font></th>\n')
|
||||
self.htmlFile.write(' </tr>\n')
|
||||
self.htmlFile.write(' </table>\n')
|
||||
self.htmlFile.write(' <p></p>\n')
|
||||
@@ -338,7 +283,7 @@ class HTMLManagement():
|
||||
if ((not self.htmlFooterCreated) and (self.htmlHeaderCreated)):
|
||||
self.htmlFile = open('test_results.html', 'a')
|
||||
self.htmlFile.write(' <tr bgcolor = "#F0F0F0" >\n')
|
||||
self.htmlFile.write(' <td colspan=' + str(5+self.htmlUEConnected) + '><b> ---- Try Run #' + str(cntnumfails) + ' ---- </b></td>\n')
|
||||
self.htmlFile.write(' <td colspan="6"><b> ---- Try Run #' + str(cntnumfails) + ' ---- </b></td>\n')
|
||||
self.htmlFile.write(' </tr>\n')
|
||||
self.htmlFile.close()
|
||||
|
||||
@@ -404,7 +349,7 @@ class HTMLManagement():
|
||||
result = re.search('showed|Reestablishment|Could not copy eNB logfile', self.htmleNBFailureMsg)
|
||||
if result is not None:
|
||||
cellBgColor = 'orange'
|
||||
self.htmlFile.write(' <td bgcolor = "' + cellBgColor + '" colspan=' + str(self.htmlUEConnected) + '><pre style="background-color:' + cellBgColor + '">' + self.htmleNBFailureMsg + '</pre></td>\n')
|
||||
self.htmlFile.write(' <td bgcolor = "' + cellBgColor + '" colspan="1"><pre style="background-color:' + cellBgColor + '">' + self.htmleNBFailureMsg + '</pre></td>\n')
|
||||
self.htmleNBFailureMsg = ''
|
||||
elif (len(str(self.htmlUEFailureMsg)) > 2):
|
||||
cellBgColor = 'white'
|
||||
@@ -415,13 +360,10 @@ class HTMLManagement():
|
||||
result = re.search('showed|Could not copy UE logfile|oaitun_ue1 interface is either NOT mounted or NOT configured', self.htmlUEFailureMsg)
|
||||
if result is not None:
|
||||
cellBgColor = 'orange'
|
||||
self.htmlFile.write(' <td bgcolor = "' + cellBgColor + '" colspan=' + str(self.htmlUEConnected) + '><pre style="background-color:' + cellBgColor + '">' + self.htmlUEFailureMsg + '</pre></td>\n')
|
||||
self.htmlFile.write(' <td bgcolor = "' + cellBgColor + '" colspan="1"><pre style="background-color:' + cellBgColor + '">' + self.htmlUEFailureMsg + '</pre></td>\n')
|
||||
self.htmlUEFailureMsg = ''
|
||||
else:
|
||||
i = 0
|
||||
while (i < self.htmlUEConnected):
|
||||
self.htmlFile.write(' <td>-</td>\n')
|
||||
i += 1
|
||||
self.htmlFile.write(' <td>-</td>\n')
|
||||
self.htmlFile.write(' </tr>\n')
|
||||
self.htmlFile.close()
|
||||
|
||||
@@ -432,7 +374,7 @@ class HTMLManagement():
|
||||
self.htmlFile = open('test_results.html', 'a')
|
||||
if bool(collectInfo) == False:
|
||||
self.htmlFile.write(' <tr bgcolor = "red" >\n')
|
||||
self.htmlFile.write(' <td colspan=' + str(5+self.htmlUEConnected) + '><b> ----IMAGES BUILDING FAILED - Unable to recover the image logs ---- </b></td>\n')
|
||||
self.htmlFile.write(' <td colspan="6"><b> ----IMAGES BUILDING FAILED - Unable to recover the image logs ---- </b></td>\n')
|
||||
self.htmlFile.write(' </tr>\n')
|
||||
else:
|
||||
for image in collectInfo:
|
||||
@@ -444,13 +386,13 @@ class HTMLManagement():
|
||||
self.htmlFile.write(' <tr bgcolor = "red" >\n')
|
||||
else:
|
||||
self.htmlFile.write(' <tr bgcolor = "#F0F0F0" >\n')
|
||||
self.htmlFile.write(' <td colspan=' + str(5+self.htmlUEConnected) + '><b> ---- ' + image + ' IMAGE STATUS ----> Size ' + allImagesSize[image] + ' </b></td>\n')
|
||||
self.htmlFile.write(' <td colspan="6"><b> ---- ' + image + ' IMAGE STATUS ----> Size ' + allImagesSize[image] + ' </b></td>\n')
|
||||
self.htmlFile.write(' </tr>\n')
|
||||
self.htmlFile.write(' <tr bgcolor = "#33CCFF" >\n')
|
||||
self.htmlFile.write(' <th colspan="2">Element</th>\n')
|
||||
self.htmlFile.write(' <th>Nb Errors</th>\n')
|
||||
self.htmlFile.write(' <th>Nb Warnings</th>\n')
|
||||
self.htmlFile.write(' <th colspan=' + str(1+self.htmlUEConnected) + '>Status</th>\n')
|
||||
self.htmlFile.write(' <th colspan="2">Status</th>\n')
|
||||
self.htmlFile.write(' </tr>\n')
|
||||
|
||||
for fil in files:
|
||||
@@ -469,11 +411,11 @@ class HTMLManagement():
|
||||
else:
|
||||
self.htmlFile.write(' <td bgcolor = "orange" >' + str(parameters['warnings']) + '</td>\n')
|
||||
if (parameters['errors'] == 0) and (parameters['warnings'] == 0):
|
||||
self.htmlFile.write(' <th colspan=' + str(1+self.htmlUEConnected) + ' bgcolor = "green" ><font color="white">OK </font></th>\n')
|
||||
self.htmlFile.write(' <th colspan="2" bgcolor = "green" ><font color="white">OK </font></th>\n')
|
||||
elif (parameters['errors'] == 0):
|
||||
self.htmlFile.write(' <th colspan=' + str(1+self.htmlUEConnected) + ' bgcolor = "orange" ><font color="white">OK </font></th>\n')
|
||||
self.htmlFile.write(' <th colspan="2" bgcolor = "orange" ><font color="white">OK </font></th>\n')
|
||||
else:
|
||||
self.htmlFile.write(' <th colspan=' + str(1+self.htmlUEConnected) + ' bgcolor = "red" > NOT OK </th>\n')
|
||||
self.htmlFile.write(' <th colspan="2" bgcolor = "red" > NOT OK </th>\n')
|
||||
self.htmlFile.write(' </tr>\n')
|
||||
self.htmlFile.close()
|
||||
|
||||
@@ -485,12 +427,12 @@ class HTMLManagement():
|
||||
|
||||
# TabHeader
|
||||
self.htmlFile.write(' <tr bgcolor = "#F0F0F0" >\n')
|
||||
self.htmlFile.write(' <td colspan=' + str(5+self.htmlUEConnected) + '><b> ---- ' + DataLog['Title'] + ' ---- </b></td>\n')
|
||||
self.htmlFile.write(' <td colspan="6"><b> ---- ' + DataLog['Title'] + ' ---- </b></td>\n')
|
||||
self.htmlFile.write(' </tr>\n')
|
||||
self.htmlFile.write(' <tr bgcolor = "#33CCFF" >\n')
|
||||
self.htmlFile.write(' <th colspan="3">'+ DataLog['ColNames'][0] +'</th>\n')
|
||||
self.htmlFile.write(' <th colspan="2">' + DataLog['ColNames'][1] + '</th>\n')
|
||||
self.htmlFile.write(' <th colspan=' + str(1+self.htmlUEConnected) + '>'+ DataLog['ColNames'][2] +'</th>\n')
|
||||
self.htmlFile.write(' <th colspan="2">'+ DataLog['ColNames'][2] +'</th>\n')
|
||||
self.htmlFile.write(' </tr>\n')
|
||||
|
||||
for k in DataLog['Data']:
|
||||
@@ -506,7 +448,7 @@ class HTMLManagement():
|
||||
self.htmlFile.close()
|
||||
|
||||
|
||||
def CreateHtmlTestRowQueue(self, options, status, ue_status, ue_queue):
|
||||
def CreateHtmlTestRowQueue(self, options, status, infoList):
|
||||
if ((not self.htmlFooterCreated) and (self.htmlHeaderCreated)):
|
||||
self.htmlFile = open('test_results.html', 'a')
|
||||
currentTime = int(round(time.time() * 1000)) - self.startTime
|
||||
@@ -517,25 +459,20 @@ class HTMLManagement():
|
||||
self.htmlFile.write(' <td>' + self.desc + '</td>\n')
|
||||
self.htmlFile.write(' <td>' + str(options) + '</td>\n')
|
||||
if (str(status) == 'OK'):
|
||||
self.htmlFile.write(' <td bgcolor = "lightgreen" >' + str(status) + '</td>\n')
|
||||
self.htmlFile.write(f' <td bgcolor = "lightgreen" >{status}</td>\n')
|
||||
elif (str(status) == 'KO'):
|
||||
self.htmlFile.write(' <td bgcolor = "lightcoral" >' + str(status) + '</td>\n')
|
||||
self.htmlFile.write(f' <td bgcolor = "lightcoral" >{status}</td>\n')
|
||||
else:
|
||||
addOrangeBK = True
|
||||
self.htmlFile.write(' <td bgcolor = "orange" >' + str(status) + '</td>\n')
|
||||
i = 0
|
||||
while (i < self.htmlUEConnected):
|
||||
if (i < ue_status):
|
||||
if (not ue_queue.empty()):
|
||||
if (addOrangeBK):
|
||||
self.htmlFile.write(' <td bgcolor = "orange" >' + str(ue_queue.get()).replace('white', 'orange') + '</td>\n')
|
||||
else:
|
||||
self.htmlFile.write(' <td>' + str(ue_queue.get()) + '</td>\n')
|
||||
else:
|
||||
self.htmlFile.write(' <td>-</td>\n')
|
||||
else:
|
||||
self.htmlFile.write(' <td>-</td>\n')
|
||||
i += 1
|
||||
self.htmlFile.write(f' <td bgcolor = "orange" >{status}</td>\n')
|
||||
if (addOrangeBK):
|
||||
self.htmlFile.write(' <td bgcolor = "orange" >')
|
||||
else:
|
||||
self.htmlFile.write(' <td>')
|
||||
for i in infoList:
|
||||
self.htmlFile.write(f' <pre>{i}</pre>')
|
||||
|
||||
self.htmlFile.write(' </td>')
|
||||
self.htmlFile.write(' </tr>\n')
|
||||
self.htmlFile.close()
|
||||
|
||||
@@ -546,80 +483,80 @@ class HTMLManagement():
|
||||
vId = 0
|
||||
for version in CCR.versions:
|
||||
self.htmlFile.write(' <tr bgcolor = "#F0F0F0" >\n')
|
||||
self.htmlFile.write(' <td colspan=' + str(5+self.htmlUEConnected) + '><b> Results for cppcheck v ' + version + ' </b></td>\n')
|
||||
self.htmlFile.write(' <td colspan="6"><b> Results for cppcheck v ' + version + ' </b></td>\n')
|
||||
self.htmlFile.write(' </tr>\n')
|
||||
self.htmlFile.write(' <tr>\n')
|
||||
self.htmlFile.write(' <td></td>\n')
|
||||
self.htmlFile.write(' <td colspan=2 bgcolor = "lightcyan" ><b> NB ERRORS</b></td>\n')
|
||||
self.htmlFile.write(' <td colspan="2" bgcolor = "lightcyan" ><b> NB ERRORS</b></td>\n')
|
||||
if CCR.nbErrors[vId] == 0:
|
||||
myColor = 'lightgreen'
|
||||
elif CCR.nbErrors[vId] < 20:
|
||||
myColor = 'orange'
|
||||
else:
|
||||
myColor = 'lightcoral'
|
||||
self.htmlFile.write(' <td colspan=' + str(2+self.htmlUEConnected) + ' bgcolor = "' + myColor + '"><b>' + str(CCR.nbErrors[vId]) + '</b></td>\n')
|
||||
self.htmlFile.write(' <td colspan="3" bgcolor = "' + myColor + '"><b>' + str(CCR.nbErrors[vId]) + '</b></td>\n')
|
||||
self.htmlFile.write(' </tr>\n')
|
||||
self.htmlFile.write(' <tr>\n')
|
||||
self.htmlFile.write(' <td></td>\n')
|
||||
self.htmlFile.write(' <td colspan=2 bgcolor = "lightcyan" ><b> NB WARNINGS</b></td>\n')
|
||||
self.htmlFile.write(' <td colspan="2" bgcolor = "lightcyan" ><b> NB WARNINGS</b></td>\n')
|
||||
if CCR.nbWarnings[vId] == 0:
|
||||
myColor = 'lightgreen'
|
||||
elif CCR.nbWarnings[vId] < 20:
|
||||
myColor = 'orange'
|
||||
else:
|
||||
myColor = 'lightcoral'
|
||||
self.htmlFile.write(' <td colspan=' + str(2+self.htmlUEConnected) + ' bgcolor = "' + myColor + '"><b>' + str(CCR.nbWarnings[vId]) + '</b></td>\n')
|
||||
self.htmlFile.write(' <td colspan="3" bgcolor = "' + myColor + '"><b>' + str(CCR.nbWarnings[vId]) + '</b></td>\n')
|
||||
self.htmlFile.write(' </tr>\n')
|
||||
self.htmlFile.write(' <tr bgcolor = "#F0F0F0" >\n')
|
||||
self.htmlFile.write(' <td colspan=' + str(5+self.htmlUEConnected) + '> ----------------- </td>\n')
|
||||
self.htmlFile.write(' <td colspan="6"> ----------------- </td>\n')
|
||||
self.htmlFile.write(' </tr>\n')
|
||||
self.htmlFile.write(' <tr>\n')
|
||||
self.htmlFile.write(' <td></td>\n')
|
||||
self.htmlFile.write(' <td colspan=2 bgcolor = "lightcyan" ><b> Memory leak</b></td>\n')
|
||||
self.htmlFile.write(' <td colspan=' + str(2+self.htmlUEConnected) + '>' + str(CCR.nbMemLeaks[vId]) + '</td>\n')
|
||||
self.htmlFile.write(' <td colspan="2" bgcolor = "lightcyan" ><b> Memory leak</b></td>\n')
|
||||
self.htmlFile.write(' <td colspan="3">' + str(CCR.nbMemLeaks[vId]) + '</td>\n')
|
||||
self.htmlFile.write(' </tr>\n')
|
||||
self.htmlFile.write(' <tr>\n')
|
||||
self.htmlFile.write(' <td></td>\n')
|
||||
self.htmlFile.write(' <td colspan=2 bgcolor = "lightcyan" ><b> Possible null pointer deference</b></td>\n')
|
||||
self.htmlFile.write(' <td colspan=' + str(2+self.htmlUEConnected) + '>' + str(CCR.nbNullPtrs[vId]) + '</td>\n')
|
||||
self.htmlFile.write(' <td colspan="2" bgcolor = "lightcyan" ><b> Possible null pointer deference</b></td>\n')
|
||||
self.htmlFile.write(' <td colspan="3">' + str(CCR.nbNullPtrs[vId]) + '</td>\n')
|
||||
self.htmlFile.write(' </tr>\n')
|
||||
self.htmlFile.write(' <tr>\n')
|
||||
self.htmlFile.write(' <td></td>\n')
|
||||
self.htmlFile.write(' <td colspan=2 bgcolor = "lightcyan" ><b> Uninitialized variable</b></td>\n')
|
||||
self.htmlFile.write(' <td colspan=' + str(2+self.htmlUEConnected) + '>' + str(CCR.nbUninitVars[vId]) + '</td>\n')
|
||||
self.htmlFile.write(' <td colspan="2" bgcolor = "lightcyan" ><b> Uninitialized variable</b></td>\n')
|
||||
self.htmlFile.write(' <td colspan="3">' + str(CCR.nbUninitVars[vId]) + '</td>\n')
|
||||
self.htmlFile.write(' </tr>\n')
|
||||
self.htmlFile.write(' <tr>\n')
|
||||
self.htmlFile.write(' <td></td>\n')
|
||||
self.htmlFile.write(' <td colspan=2 bgcolor = "lightcyan" ><b> Undefined behaviour shifting</b></td>\n')
|
||||
self.htmlFile.write(' <td colspan=' + str(2+self.htmlUEConnected) + '>' + str(CCR.nbTooManyBitsShift[vId]) + '</td>\n')
|
||||
self.htmlFile.write(' <td colspan="2" bgcolor = "lightcyan" ><b> Undefined behaviour shifting</b></td>\n')
|
||||
self.htmlFile.write(' <td colspan="3">' + str(CCR.nbTooManyBitsShift[vId]) + '</td>\n')
|
||||
self.htmlFile.write(' </tr>\n')
|
||||
self.htmlFile.write(' <tr>\n')
|
||||
self.htmlFile.write(' <td></td>\n')
|
||||
self.htmlFile.write(' <td colspan=2 bgcolor = "lightcyan" ><b> Signed integer overflow</b></td>\n')
|
||||
self.htmlFile.write(' <td colspan=' + str(2+self.htmlUEConnected) + '>' + str(CCR.nbIntegerOverflow[vId]) + '</td>\n')
|
||||
self.htmlFile.write(' <td colspan="2" bgcolor = "lightcyan" ><b> Signed integer overflow</b></td>\n')
|
||||
self.htmlFile.write(' <td colspan="3">' + str(CCR.nbIntegerOverflow[vId]) + '</td>\n')
|
||||
self.htmlFile.write(' </tr>\n')
|
||||
self.htmlFile.write(' <tr bgcolor = "#F0F0F0" >\n')
|
||||
self.htmlFile.write(' <td colspan=' + str(5+self.htmlUEConnected) + '> </td>\n')
|
||||
self.htmlFile.write(' <td colspan="6"> </td>\n')
|
||||
self.htmlFile.write(' </tr>\n')
|
||||
self.htmlFile.write(' <tr>\n')
|
||||
self.htmlFile.write(' <td></td>\n')
|
||||
self.htmlFile.write(' <td colspan=2 bgcolor = "lightcyan" ><b> Printf formatting issues</b></td>\n')
|
||||
self.htmlFile.write(' <td colspan=' + str(2+self.htmlUEConnected) + '>' + str(CCR.nbInvalidPrintf[vId]) + '</td>\n')
|
||||
self.htmlFile.write(' <td colspan="2" bgcolor = "lightcyan" ><b> Printf formatting issues</b></td>\n')
|
||||
self.htmlFile.write(' <td colspan="3">' + str(CCR.nbInvalidPrintf[vId]) + '</td>\n')
|
||||
self.htmlFile.write(' </tr>\n')
|
||||
self.htmlFile.write(' <tr>\n')
|
||||
self.htmlFile.write(' <td></td>\n')
|
||||
self.htmlFile.write(' <td colspan=2 bgcolor = "lightcyan" ><b> Modulo result is predetermined</b></td>\n')
|
||||
self.htmlFile.write(' <td colspan=' + str(2+self.htmlUEConnected) + '>' + str(CCR.nbModuloAlways[vId]) + '</td>\n')
|
||||
self.htmlFile.write(' <td colspan="2" bgcolor = "lightcyan" ><b> Modulo result is predetermined</b></td>\n')
|
||||
self.htmlFile.write(' <td colspan="3">' + str(CCR.nbModuloAlways[vId]) + '</td>\n')
|
||||
self.htmlFile.write(' </tr>\n')
|
||||
self.htmlFile.write(' <tr>\n')
|
||||
self.htmlFile.write(' <td></td>\n')
|
||||
self.htmlFile.write(' <td colspan=2 bgcolor = "lightcyan" ><b> Opposite Condition -> dead code</b></td>\n')
|
||||
self.htmlFile.write(' <td colspan=' + str(2+self.htmlUEConnected) + '>' + str(CCR.nbOppoInnerCondition[vId]) + '</td>\n')
|
||||
self.htmlFile.write(' <td colspan="2" bgcolor = "lightcyan" ><b> Opposite Condition -> dead code</b></td>\n')
|
||||
self.htmlFile.write(' <td colspan="3">' + str(CCR.nbOppoInnerCondition[vId]) + '</td>\n')
|
||||
self.htmlFile.write(' </tr>\n')
|
||||
self.htmlFile.write(' <tr>\n')
|
||||
self.htmlFile.write(' <td></td>\n')
|
||||
self.htmlFile.write(' <td colspan=2 bgcolor = "lightcyan" ><b> Wrong Scanf Nb Args</b></td>\n')
|
||||
self.htmlFile.write(' <td colspan=' + str(2+self.htmlUEConnected) + '>' + str(CCR.nbWrongScanfArg[vId]) + '</td>\n')
|
||||
self.htmlFile.write(' <td colspan="2" bgcolor = "lightcyan" ><b> Wrong Scanf Nb Args</b></td>\n')
|
||||
self.htmlFile.write(' <td colspan="3">' + str(CCR.nbWrongScanfArg[vId]) + '</td>\n')
|
||||
self.htmlFile.write(' </tr>\n')
|
||||
vId += 1
|
||||
|
||||
@@ -629,12 +566,12 @@ class HTMLManagement():
|
||||
self.htmlFile = open('test_results.html', 'a')
|
||||
if bool(testResult) == False and bool(testSummary) == False:
|
||||
self.htmlFile.write(' <tr bgcolor = "red" >\n')
|
||||
self.htmlFile.write(' <td colspan=' + str(5+self.htmlUEConnected) + '><b> ----PHYSIM TESTING FAILED - Unable to recover the test logs ---- </b></td>\n')
|
||||
self.htmlFile.write(' <td colspan="6"><b> ----PHYSIM TESTING FAILED - Unable to recover the test logs ---- </b></td>\n')
|
||||
self.htmlFile.write(' </tr>\n')
|
||||
else:
|
||||
# Tab header
|
||||
self.htmlFile.write(' <tr bgcolor = "#F0F0F0" >\n')
|
||||
self.htmlFile.write(' <td colspan=' + str(5+self.htmlUEConnected) + '><b> ---- PHYSIM TEST SUMMARY---- </b></td>\n')
|
||||
self.htmlFile.write(' <td colspan="6"><b> ---- PHYSIM TEST SUMMARY---- </b></td>\n')
|
||||
self.htmlFile.write(' </tr>\n')
|
||||
self.htmlFile.write(' <tr bgcolor = "#33CCFF" >\n')
|
||||
self.htmlFile.write(' <th colspan="2">LogFile Name</th>\n')
|
||||
@@ -652,27 +589,27 @@ class HTMLManagement():
|
||||
self.htmlFile.write(' <td gcolor = "lightcyan" >' + str(testSummary['Nbpass']) + ' </td>\n')
|
||||
self.htmlFile.write(' </tr>\n')
|
||||
self.htmlFile.write(' <tr bgcolor = "#F0F0F0" >\n')
|
||||
self.htmlFile.write(' <td colspan=' + str(5+self.htmlUEConnected) + '><b> ---- PHYSIM TEST DETAIL INFO---- </b></td>\n')
|
||||
self.htmlFile.write(' <td colspan="6"><b> ---- PHYSIM TEST DETAIL INFO---- </b></td>\n')
|
||||
self.htmlFile.write(' </tr>\n')
|
||||
self.htmlFile.write(' <tr bgcolor = "#33CCFF" >\n')
|
||||
self.htmlFile.write(' <th colspan="2">Test Name</th>\n')
|
||||
self.htmlFile.write(' <th colspan="2">Test Description</th>\n')
|
||||
self.htmlFile.write(' <th colspan=' + str(1+self.htmlUEConnected) + '>Result</th>\n')
|
||||
self.htmlFile.write(' <th colspan="2">Result</th>\n')
|
||||
self.htmlFile.write(' </tr>\n')
|
||||
y = ''
|
||||
for key, value in testResult.items():
|
||||
x = key.split(".")
|
||||
if x[0] != y:
|
||||
self.htmlFile.write(' <tr bgcolor = "lightgreen" >\n')
|
||||
self.htmlFile.write(' <td style="text-align: center;" colspan=' + str(5+self.htmlUEConnected) + '><b>"' + x[0] + '" series </b></td>\n')
|
||||
self.htmlFile.write(' <td style="text-align: center;" colspan="6"><b>"' + x[0] + '" series </b></td>\n')
|
||||
self.htmlFile.write(' </tr>\n')
|
||||
y = x[0]
|
||||
self.htmlFile.write(' <tr>\n')
|
||||
self.htmlFile.write(' <td colspan="2" bgcolor = "lightcyan" >' + key + ' </td>\n')
|
||||
self.htmlFile.write(' <td colspan="2" bgcolor = "lightcyan" >' + value[0] + '</td>\n')
|
||||
if 'PASS' in value:
|
||||
self.htmlFile.write(' <td colspan=' + str(1+self.htmlUEConnected) + ' bgcolor = "green" >' + value[1] + '</td>\n')
|
||||
self.htmlFile.write(' <td colspan="2" bgcolor = "green" >' + value[1] + '</td>\n')
|
||||
else:
|
||||
self.htmlFile.write(' <td colspan=' + str(1+self.htmlUEConnected) + ' bgcolor = "red" >' + value[1] + '</td>\n')
|
||||
self.htmlFile.write(' <td colspan="2" bgcolor = "red" >' + value[1] + '</td>\n')
|
||||
|
||||
self.htmlFile.close()
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -81,15 +81,39 @@ class PhySim:
|
||||
#once parsed move the local logfile to its folder for tidiness
|
||||
os.system('mv '+self.__runLogFile+' '+ self.__runLogPath+'/.')
|
||||
|
||||
#updating the HTML with results
|
||||
html_cell = '<pre style="background-color:white">' + info + '</pre>'
|
||||
html_queue=SimpleQueue()
|
||||
html_queue.put(html_cell)
|
||||
HTML.CreateHtmlTestRowQueue(self.runargs, 'OK', 1, html_queue)
|
||||
HTML.CreateHtmlTestRowQueue(self.runargs, 'OK', [info])
|
||||
return HTML
|
||||
|
||||
def __CheckResults_LDPCt1Test(self,HTML,CONST,testcase_id):
|
||||
thrs_NOK = 500
|
||||
thrs_KO = 1000
|
||||
mySSH = sshconnection.SSHConnection()
|
||||
mySSH.open(self.eNBIpAddr, self.eNBUserName, self.eNBPassWord)
|
||||
#retrieve run log file and store it locally$
|
||||
mySSH.copyin(self.eNBIpAddr, self.eNBUserName, self.eNBPassWord, self.__workSpacePath+self.__runLogFile, '.')
|
||||
mySSH.close()
|
||||
#parse results looking for Decoding values
|
||||
runResultsT1=[]
|
||||
with open(self.__runLogFile) as g:
|
||||
for line in g:
|
||||
if 'decoding time' in line:
|
||||
runResultsT1.append(line)
|
||||
info = runResultsT1[0][15:-13]
|
||||
result = int(''.join(filter(str.isdigit, info)))/100
|
||||
#once parsed move the local logfile to its folder for tidiness
|
||||
os.system('mv '+self.__runLogFile+' '+ self.__runLogPath+'/.')
|
||||
if result < thrs_NOK:
|
||||
HTML.CreateHtmlTestRowQueue(self.runargs, 'OK', [info])
|
||||
elif result > thrs_KO:
|
||||
error_msg = f'Decoding time exceeds a limit of {thrs_KO} us'
|
||||
logging.error(error_msg)
|
||||
HTML.CreateHtmlTestRowQueue(self.runargs, 'KO', [info + '\n' + error_msg])
|
||||
self.exitStatus = 1
|
||||
else:
|
||||
HTML.CreateHtmlTestRowQueue(self.runargs, 'NOK', [info])
|
||||
return HTML
|
||||
|
||||
def __CheckResults_NRulsimTest(self, HTML, CONST, testcase_id):
|
||||
html_queue = SimpleQueue()
|
||||
#retrieve run log file and store it locally
|
||||
mySSH = sshconnection.SSHConnection()
|
||||
filename = self.__workSpacePath + self.__runLogFile
|
||||
@@ -97,8 +121,7 @@ class PhySim:
|
||||
if ret != 0:
|
||||
error_msg = f'could not recover test result file {filename}'
|
||||
logging.error(error_msg)
|
||||
html_queue.put(f'<pre style="background-color:white">{error_msg}</pre>')
|
||||
HTML.CreateHtmlTestRowQueue("could not recover results", 'KO', 1, html_queue)
|
||||
HTML.CreateHtmlTestRowQueue("could not recover results", 'KO', [error_msg])
|
||||
self.exitStatus = 1
|
||||
return HTML
|
||||
|
||||
@@ -111,13 +134,11 @@ class PhySim:
|
||||
|
||||
#updating the HTML with results
|
||||
if PUSCH_OK:
|
||||
html_queue.put('<pre style="background-color:white">succeeded</pre>')
|
||||
HTML.CreateHtmlTestRowQueue(self.runargs, 'OK', 1, html_queue)
|
||||
HTML.CreateHtmlTestRowQueue(self.runargs, 'OK', 1, ["succeeded"])
|
||||
else:
|
||||
error_msg = 'error: no "PUSCH test OK"'
|
||||
logging.error(error_msg)
|
||||
html_queue.put(f'<pre style="background-color:white">{error_msg}</pre>')
|
||||
HTML.CreateHtmlTestRowQueue(self.runargs, 'KO', 1, html_queue)
|
||||
HTML.CreateHtmlTestRowQueue(self.runargs, 'KO', 1, [error_msg])
|
||||
self.exitStatus = 1
|
||||
return HTML
|
||||
|
||||
@@ -216,6 +237,24 @@ class PhySim:
|
||||
lHTML=self.__CheckResults_LDPCTest(htmlObj,constObj,testcase_id)
|
||||
return lHTML
|
||||
|
||||
def Run_LDPCt1Test(self,htmlObj,constObj,testcase_id):
|
||||
self.__workSpacePath = self.eNBSourceCodePath+'/cmake_targets/'
|
||||
#create run logs folder locally
|
||||
os.system('mkdir -p ./'+self.__runLogPath)
|
||||
#log file is tc_<testcase_id>.log remotely
|
||||
self.__runLogFile='physim_'+str(testcase_id)+'.log'
|
||||
#open a session for test run
|
||||
mySSH = sshconnection.SSHConnection()
|
||||
mySSH.open(self.eNBIpAddr, self.eNBUserName, self.eNBPassWord)
|
||||
mySSH.command('cd '+self.__workSpacePath,'\$',5)
|
||||
#run and redirect the results to a log file
|
||||
mySSH.command(f'sudo {self.__workSpacePath}ran_build/build/nr_ulsim {self.runargs} > {self.__runLogFile} 2>&1', '\$', 30)
|
||||
mySSH.close()
|
||||
#return updated HTML to main
|
||||
lHTML = cls_oai_html.HTMLManagement()
|
||||
lHTML=self.__CheckResults_LDPCt1Test(htmlObj,constObj,testcase_id)
|
||||
return lHTML
|
||||
|
||||
def Run_NRulsimTest(self, htmlObj, constObj, testcase_id):
|
||||
self.__workSpacePath=self.eNBSourceCodePath+'/cmake_targets/'
|
||||
os.system(f'mkdir -p ./{self.__runLogPath}')
|
||||
|
||||
@@ -32,13 +32,14 @@
|
||||
# Import
|
||||
#-----------------------------------------------------------
|
||||
import logging
|
||||
import sshconnection as SSH
|
||||
import cls_oai_html
|
||||
import os
|
||||
import re
|
||||
import time
|
||||
import subprocess
|
||||
import sys
|
||||
|
||||
import sshconnection as SSH
|
||||
import cls_oai_html
|
||||
import constants as CONST
|
||||
import helpreadme as HELP
|
||||
|
||||
@@ -105,7 +106,7 @@ class PhySim:
|
||||
if self.ranCommitID != '':
|
||||
mySSH.command('git checkout -f ' + self.ranCommitID, '\$', 30)
|
||||
if self.ranAllowMerge:
|
||||
imageTag = "ci-temp"
|
||||
imageTag = f'{self.ranBranch}-{self.ranCommitID[0:8]}'
|
||||
if self.ranTargetBranch == '':
|
||||
if (self.ranBranch != 'develop') and (self.ranBranch != 'origin/develop'):
|
||||
mySSH.command('git merge --ff origin/develop -m "Temporary merge for CI"', '\$', 30)
|
||||
|
||||
@@ -357,63 +357,43 @@ class StaticCodeAnalysis():
|
||||
if nbFilesNotFormatted == 0:
|
||||
HTML.CreateHtmlTestRow('File(s) Format', 'OK', CONST.ALL_PROCESSES_OK)
|
||||
else:
|
||||
html_queue = SimpleQueue()
|
||||
html_cell = '<pre style="background-color:white">\n'
|
||||
html_cell += 'Number of files not following OAI Rules: ' + str(nbFilesNotFormatted) + '\n'
|
||||
html_cell = f'Number of files not following OAI Rules: {nbFilesNotFormatted}\n'
|
||||
for nFile in listFilesNotFormatted:
|
||||
html_cell += str(nFile).strip() + '\n'
|
||||
html_cell += '</pre>'
|
||||
html_queue.put(html_cell)
|
||||
HTML.CreateHtmlTestRowQueue('File(s) Format', 'KO', 1, html_queue)
|
||||
HTML.CreateHtmlTestRowQueue('File(s) Format', 'KO', [html_cell])
|
||||
del(html_cell)
|
||||
del(html_queue)
|
||||
|
||||
logging.debug('header files not respecting the circular dependency protection: ' + str(len(circularHeaderDependencyFiles)))
|
||||
if len(circularHeaderDependencyFiles) == 0:
|
||||
HTML.CreateHtmlTestRow('Header Circular Dependency', 'OK', CONST.ALL_PROCESSES_OK)
|
||||
else:
|
||||
html_queue = SimpleQueue()
|
||||
html_cell = '<pre style="background-color:white">\n'
|
||||
html_cell += 'Number of files not respecting: ' + str(len(circularHeaderDependencyFiles)) + '\n'
|
||||
html_cell = f'Number of files not respecting: {len(circularHeaderDependencyFiles)}\n'
|
||||
for nFile in circularHeaderDependencyFiles:
|
||||
html_cell += str(nFile).strip() + '\n'
|
||||
html_cell += '</pre>'
|
||||
html_queue.put(html_cell)
|
||||
HTML.CreateHtmlTestRowQueue('Header Circular Dependency', 'KO', 1, html_queue)
|
||||
HTML.CreateHtmlTestRowQueue('Header Circular Dependency', 'KO', [html_cell])
|
||||
del(html_cell)
|
||||
del(html_queue)
|
||||
finalStatus = -1
|
||||
|
||||
logging.debug('files with a GNU GPL license: ' + str(len(gnuGplLicenceFiles)))
|
||||
if len(gnuGplLicenceFiles) == 0:
|
||||
HTML.CreateHtmlTestRow('Files w/ GNU GPL License', 'OK', CONST.ALL_PROCESSES_OK)
|
||||
else:
|
||||
html_queue = SimpleQueue()
|
||||
html_cell = '<pre style="background-color:white">\n'
|
||||
html_cell += 'Number of files not respecting: ' + str(len(gnuGplLicenceFiles)) + '\n'
|
||||
html_cell = f'Number of files not respecting: {len(gnuGplLicenceFiles)}\n'
|
||||
for nFile in gnuGplLicenceFiles:
|
||||
html_cell += str(nFile).strip() + '\n'
|
||||
html_cell += '</pre>'
|
||||
html_queue.put(html_cell)
|
||||
HTML.CreateHtmlTestRowQueue('Files w/ GNU GPL License', 'KO', 1, html_queue)
|
||||
HTML.CreateHtmlTestRowQueue('Files w/ GNU GPL License', 'KO', html_queue)
|
||||
del(html_cell)
|
||||
del(html_queue)
|
||||
finalStatus = -1
|
||||
|
||||
logging.debug('files with a suspect license: ' + str(len(suspectLicenceFiles)))
|
||||
if len(suspectLicenceFiles) == 0:
|
||||
HTML.CreateHtmlTestRow('Files with suspect license', 'OK', CONST.ALL_PROCESSES_OK)
|
||||
else:
|
||||
html_queue = SimpleQueue()
|
||||
html_cell = '<pre style="background-color:white">\n'
|
||||
html_cell += 'Number of files not respecting: ' + str(len(suspectLicenceFiles)) + '\n'
|
||||
html_cell = f'Number of files not respecting: {len(suspectLicenceFiles)}\n'
|
||||
for nFile in suspectLicenceFiles:
|
||||
html_cell += str(nFile).strip() + '\n'
|
||||
html_cell += '</pre>'
|
||||
html_queue.put(html_cell)
|
||||
HTML.CreateHtmlTestRowQueue('Files with suspect license', 'KO', 1, html_queue)
|
||||
HTML.CreateHtmlTestRowQueue('Files with suspect license', 'KO', [html_cell])
|
||||
del(html_cell)
|
||||
del(html_queue)
|
||||
finalStatus = -1
|
||||
|
||||
else:
|
||||
|
||||
@@ -172,7 +172,7 @@ eNBs =
|
||||
|
||||
|
||||
////////// MME parameters:
|
||||
mme_ip_address = ( { ipv4 = "CI_MME_IP_ADDR";
|
||||
mme_ip_address = ( { ipv4 = "192.168.61.195";
|
||||
ipv6 = "192:168:30::17";
|
||||
active = "yes";
|
||||
preference = "ipv4";
|
||||
@@ -191,11 +191,11 @@ eNBs =
|
||||
NETWORK_INTERFACES :
|
||||
{
|
||||
ENB_INTERFACE_NAME_FOR_S1_MME = "eno1";
|
||||
ENB_IPV4_ADDRESS_FOR_S1_MME = "CI_ENB_IP_ADDR";
|
||||
ENB_IPV4_ADDRESS_FOR_S1_MME = "172.21.16.128";
|
||||
ENB_INTERFACE_NAME_FOR_S1U = "eno1";
|
||||
ENB_IPV4_ADDRESS_FOR_S1U = "CI_ENB_IP_ADDR";
|
||||
ENB_IPV4_ADDRESS_FOR_S1U = "172.21.16.128";
|
||||
ENB_PORT_FOR_S1U = 2152; # Spec 2152
|
||||
ENB_IPV4_ADDRESS_FOR_X2C = "CI_ENB_IP_ADDR";
|
||||
ENB_IPV4_ADDRESS_FOR_X2C = "172.21.16.128";
|
||||
ENB_PORT_FOR_X2C = 36422; # Spec 36422
|
||||
};
|
||||
}
|
||||
@@ -237,7 +237,7 @@ RUs = (
|
||||
max_pdschReferenceSignalPower = -27;
|
||||
max_rxgain = 75;
|
||||
eNB_instances = [0];
|
||||
sdr_addrs = "mgmt_addr=172.21.19.13,addr=192.168.20.2,second_addr=192.168.10.2";
|
||||
sdr_addrs = "mgmt_addr=172.21.19.13,addr=192.168.10.2";
|
||||
|
||||
}
|
||||
);
|
||||
|
||||
@@ -172,7 +172,7 @@ eNBs =
|
||||
|
||||
|
||||
////////// MME parameters:
|
||||
mme_ip_address = ( { ipv4 = "CI_MME_IP_ADDR";
|
||||
mme_ip_address = ( { ipv4 = "192.168.61.195";
|
||||
ipv6 = "192:168:30::17";
|
||||
active = "yes";
|
||||
preference = "ipv4";
|
||||
@@ -191,11 +191,11 @@ eNBs =
|
||||
NETWORK_INTERFACES :
|
||||
{
|
||||
ENB_INTERFACE_NAME_FOR_S1_MME = "eno1";
|
||||
ENB_IPV4_ADDRESS_FOR_S1_MME = "CI_ENB_IP_ADDR";
|
||||
ENB_IPV4_ADDRESS_FOR_S1_MME = "172.21.16.128";
|
||||
ENB_INTERFACE_NAME_FOR_S1U = "eno1";
|
||||
ENB_IPV4_ADDRESS_FOR_S1U = "CI_ENB_IP_ADDR";
|
||||
ENB_IPV4_ADDRESS_FOR_S1U = "172.21.16.128";
|
||||
ENB_PORT_FOR_S1U = 2152; # Spec 2152
|
||||
ENB_IPV4_ADDRESS_FOR_X2C = "CI_ENB_IP_ADDR";
|
||||
ENB_IPV4_ADDRESS_FOR_X2C = "172.21.16.128";
|
||||
ENB_PORT_FOR_X2C = 36422; # Spec 36422
|
||||
};
|
||||
}
|
||||
@@ -237,7 +237,7 @@ RUs = (
|
||||
max_pdschReferenceSignalPower = -27;
|
||||
max_rxgain = 75;
|
||||
eNB_instances = [0];
|
||||
sdr_addrs = "mgmt_addr=172.21.19.13,addr=192.168.20.2,second_addr=192.168.10.2";
|
||||
sdr_addrs = "mgmt_addr=172.21.19.13,addr=192.168.10.2";
|
||||
|
||||
}
|
||||
);
|
||||
|
||||
@@ -237,7 +237,7 @@ RUs = (
|
||||
max_pdschReferenceSignalPower = -27;
|
||||
max_rxgain = 75;
|
||||
eNB_instances = [0];
|
||||
sdr_addrs = "mgmt_addr=172.21.19.13,addr=192.168.20.2,second_addr=192.168.10.2";
|
||||
sdr_addrs = "mgmt_addr=172.21.19.13,addr=192.168.10.2";
|
||||
|
||||
}
|
||||
);
|
||||
|
||||
@@ -261,3 +261,9 @@ log_config :
|
||||
rrc_log_level ="info";
|
||||
};
|
||||
|
||||
e2_agent = {
|
||||
enable = 1;
|
||||
address = "127.0.0.1";
|
||||
port = 36421;
|
||||
sm_dir = "/path/where/the/SMs/are/located/"
|
||||
}
|
||||
|
||||
@@ -23,12 +23,6 @@ gNBs =
|
||||
|
||||
min_rxtxtime = 6;
|
||||
|
||||
pdcch_ConfigSIB1 = (
|
||||
{
|
||||
controlResourceSetZero = 12;
|
||||
searchSpaceZero = 0;
|
||||
}
|
||||
);
|
||||
servingCellConfigCommon = (
|
||||
{
|
||||
#spCellConfigCommon
|
||||
|
||||
@@ -21,12 +21,6 @@ gNBs =
|
||||
pusch_AntennaPorts = 2;
|
||||
do_CSIRS = 1;
|
||||
min_rxtxtime = 6;
|
||||
pdcch_ConfigSIB1 = (
|
||||
{
|
||||
controlResourceSetZero = 12;
|
||||
searchSpaceZero = 0;
|
||||
}
|
||||
);
|
||||
|
||||
servingCellConfigCommon = (
|
||||
{
|
||||
|
||||
@@ -19,13 +19,6 @@ gNBs =
|
||||
|
||||
min_rxtxtime = 6;
|
||||
|
||||
pdcch_ConfigSIB1 = (
|
||||
{
|
||||
controlResourceSetZero = 12;
|
||||
searchSpaceZero = 0;
|
||||
}
|
||||
);
|
||||
|
||||
servingCellConfigCommon = (
|
||||
{
|
||||
#spCellConfigCommon
|
||||
|
||||
@@ -32,13 +32,6 @@ gNBs =
|
||||
remote_s_portd = 2152;
|
||||
min_rxtxtime = 6;
|
||||
|
||||
pdcch_ConfigSIB1 = (
|
||||
{
|
||||
controlResourceSetZero = 12;
|
||||
searchSpaceZero = 0;
|
||||
}
|
||||
);
|
||||
|
||||
servingCellConfigCommon = (
|
||||
{
|
||||
#spCellConfigCommon
|
||||
@@ -176,7 +169,7 @@ gNBs =
|
||||
|
||||
|
||||
////////// AMF parameters:
|
||||
amf_ip_address = ( { ipv4 = "192.168.5.233";
|
||||
amf_ip_address = ( { ipv4 = "192.168.70.132";
|
||||
ipv6 = "192:168:30::17";
|
||||
active = "yes";
|
||||
preference = "ipv4";
|
||||
@@ -185,11 +178,10 @@ gNBs =
|
||||
|
||||
NETWORK_INTERFACES :
|
||||
{
|
||||
|
||||
GNB_INTERFACE_NAME_FOR_NG_AMF = "eth0";
|
||||
GNB_IPV4_ADDRESS_FOR_NG_AMF = "CI_GNB_IP_ADDR";
|
||||
GNB_INTERFACE_NAME_FOR_NGU = "eth0";
|
||||
GNB_IPV4_ADDRESS_FOR_NGU = "CI_GNB_IP_ADDR";
|
||||
GNB_INTERFACE_NAME_FOR_NG_AMF = "demo-oai";
|
||||
GNB_IPV4_ADDRESS_FOR_NG_AMF = "192.168.70.129/24";
|
||||
GNB_INTERFACE_NAME_FOR_NGU = "demo-oai";
|
||||
GNB_IPV4_ADDRESS_FOR_NGU = "192.168.70.129/24";
|
||||
GNB_PORT_FOR_S1U = 2152; # Spec 2152
|
||||
};
|
||||
}
|
||||
@@ -220,7 +212,7 @@ security = {
|
||||
rlc_log_level ="debug";
|
||||
pdcp_log_level ="info";
|
||||
rrc_log_level ="info";
|
||||
f1ap_log_level ="debug";
|
||||
f1ap_log_level ="info";
|
||||
ngap_log_level ="debug";
|
||||
};
|
||||
|
||||
|
||||
@@ -24,13 +24,6 @@ gNBs =
|
||||
min_rxtxtime = 6;
|
||||
force_256qam_off = 1;
|
||||
|
||||
pdcch_ConfigSIB1 = (
|
||||
{
|
||||
controlResourceSetZero = 12;
|
||||
searchSpaceZero = 0;
|
||||
}
|
||||
);
|
||||
|
||||
servingCellConfigCommon = (
|
||||
{
|
||||
#spCellConfigCommon
|
||||
@@ -184,6 +177,7 @@ MACRLCs = (
|
||||
remote_n_portd = 2152;
|
||||
pusch_TargetSNRx10 = 200;
|
||||
pucch_TargetSNRx10 = 200;
|
||||
ulsch_max_frame_inactivity = 1;
|
||||
}
|
||||
);
|
||||
|
||||
@@ -239,7 +233,7 @@ serveraddr = "server";
|
||||
rlc_log_level ="info";
|
||||
pdcp_log_level ="info";
|
||||
rrc_log_level ="info";
|
||||
f1ap_log_level ="debug";
|
||||
f1ap_log_level ="info";
|
||||
ngap_log_level ="debug";
|
||||
};
|
||||
|
||||
|
||||
@@ -26,13 +26,6 @@ gNBs =
|
||||
pdsch_AntennaPorts_XP = 2;
|
||||
pusch_AntennaPorts = 2;
|
||||
|
||||
pdcch_ConfigSIB1 = (
|
||||
{
|
||||
controlResourceSetZero = 11;
|
||||
searchSpaceZero = 0;
|
||||
}
|
||||
);
|
||||
|
||||
servingCellConfigCommon = (
|
||||
{
|
||||
#spCellConfigCommon
|
||||
@@ -281,5 +274,5 @@ security = {
|
||||
rlc_log_level ="info";
|
||||
pdcp_log_level ="info";
|
||||
rrc_log_level ="info";
|
||||
f1ap_log_level ="debug";
|
||||
f1ap_log_level ="info";
|
||||
};
|
||||
|
||||
@@ -27,13 +27,6 @@ gNBs =
|
||||
pdsch_AntennaPorts_XP = 2;
|
||||
pusch_AntennaPorts = 2;
|
||||
|
||||
pdcch_ConfigSIB1 = (
|
||||
{
|
||||
controlResourceSetZero = 10;
|
||||
searchSpaceZero = 0;
|
||||
}
|
||||
);
|
||||
|
||||
servingCellConfigCommon = (
|
||||
{
|
||||
#spCellConfigCommon
|
||||
@@ -277,5 +270,5 @@ security = {
|
||||
rlc_log_level ="info";
|
||||
pdcp_log_level ="info";
|
||||
rrc_log_level ="info";
|
||||
f1ap_log_level ="debug";
|
||||
f1ap_log_level ="info";
|
||||
};
|
||||
|
||||
228
ci-scripts/conf_files/gnb-cucp.sa.f1.conf
Normal file
228
ci-scripts/conf_files/gnb-cucp.sa.f1.conf
Normal file
@@ -0,0 +1,228 @@
|
||||
Active_gNBs = ( "gNB-OAI");
|
||||
# Asn1_verbosity, choice in: none, info, annoying
|
||||
Asn1_verbosity = "none";
|
||||
Num_Threads_PUSCH = 8;
|
||||
sa = 1;
|
||||
|
||||
gNBs =
|
||||
(
|
||||
{
|
||||
////////// Identification parameters:
|
||||
gNB_CU_ID = 0xe00;
|
||||
|
||||
# cell_type = "CELL_MACRO_GNB";
|
||||
|
||||
gNB_name = "gNB-OAI";
|
||||
|
||||
// Tracking area code, 0x0000 and 0xfffe are reserved values
|
||||
tracking_area_code = 1;
|
||||
plmn_list = ({ mcc = 208; mnc = 99; mnc_length = 2; snssaiList = ({ sst = 1, sd = 0xffffff }) });
|
||||
|
||||
|
||||
nr_cellid = 12345678L;
|
||||
force_256qam_off = 1;
|
||||
|
||||
tr_s_preference = "f1";
|
||||
|
||||
local_s_if_name = "lo";
|
||||
local_s_address = "192.168.72.140";
|
||||
remote_s_address = "192.168.72.143";
|
||||
local_s_portc = 501;
|
||||
local_s_portd = 2152;
|
||||
remote_s_portc = 500;
|
||||
remote_s_portd = 2152;
|
||||
ssb_SubcarrierOffset = 0;
|
||||
min_rxtxtime = 6;
|
||||
|
||||
servingCellConfigCommon = (
|
||||
{
|
||||
#spCellConfigCommon
|
||||
|
||||
physCellId = 0;
|
||||
|
||||
# downlinkConfigCommon
|
||||
#frequencyInfoDL
|
||||
# this is 3600 MHz + 43 PRBs@30kHz SCS (same as initial BWP)
|
||||
absoluteFrequencySSB = 641280;
|
||||
dl_frequencyBand = 78;
|
||||
# this is 3600 MHz
|
||||
dl_absoluteFrequencyPointA = 640008;
|
||||
#scs-SpecificCarrierList
|
||||
dl_offstToCarrier = 0;
|
||||
# subcarrierSpacing
|
||||
# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
|
||||
dl_subcarrierSpacing = 1;
|
||||
dl_carrierBandwidth = 106;
|
||||
#initialDownlinkBWP
|
||||
#genericParameters
|
||||
# this is RBstart=27,L=48 (275*(L-1))+RBstart
|
||||
initialDLBWPlocationAndBandwidth = 28875; # 6366 12925 12956 28875 12952
|
||||
# subcarrierSpacing
|
||||
# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
|
||||
initialDLBWPsubcarrierSpacing = 1;
|
||||
#pdcch-ConfigCommon
|
||||
initialDLBWPcontrolResourceSetZero = 11;
|
||||
initialDLBWPsearchSpaceZero = 0;
|
||||
|
||||
#uplinkConfigCommon
|
||||
#frequencyInfoUL
|
||||
ul_frequencyBand = 78;
|
||||
#scs-SpecificCarrierList
|
||||
ul_offstToCarrier = 0;
|
||||
# subcarrierSpacing
|
||||
# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
|
||||
ul_subcarrierSpacing = 1;
|
||||
ul_carrierBandwidth = 106;
|
||||
pMax = 20;
|
||||
#initialUplinkBWP
|
||||
#genericParameters
|
||||
initialULBWPlocationAndBandwidth = 28875;
|
||||
# subcarrierSpacing
|
||||
# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
|
||||
initialULBWPsubcarrierSpacing = 1;
|
||||
#rach-ConfigCommon
|
||||
#rach-ConfigGeneric
|
||||
prach_ConfigurationIndex = 98;
|
||||
#prach_msg1_FDM
|
||||
#0 = one, 1=two, 2=four, 3=eight
|
||||
prach_msg1_FDM = 0;
|
||||
prach_msg1_FrequencyStart = 0;
|
||||
zeroCorrelationZoneConfig = 13;
|
||||
preambleReceivedTargetPower = -96;
|
||||
#preamblTransMax (0...10) = (3,4,5,6,7,8,10,20,50,100,200)
|
||||
preambleTransMax = 6;
|
||||
#powerRampingStep
|
||||
# 0=dB0,1=dB2,2=dB4,3=dB6
|
||||
powerRampingStep = 1;
|
||||
#ra_ReponseWindow
|
||||
#1,2,4,8,10,20,40,80
|
||||
ra_ResponseWindow = 4;
|
||||
#ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR
|
||||
#1=oneeighth,2=onefourth,3=half,4=one,5=two,6=four,7=eight,8=sixteen
|
||||
ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR = 4;
|
||||
#oneHalf (0..15) 4,8,12,16,...60,64
|
||||
ssb_perRACH_OccasionAndCB_PreamblesPerSSB = 14;
|
||||
#ra_ContentionResolutionTimer
|
||||
#(0..7) 8,16,24,32,40,48,56,64
|
||||
ra_ContentionResolutionTimer = 7;
|
||||
rsrp_ThresholdSSB = 19;
|
||||
#prach-RootSequenceIndex_PR
|
||||
#1 = 839, 2 = 139
|
||||
prach_RootSequenceIndex_PR = 2;
|
||||
prach_RootSequenceIndex = 1;
|
||||
# SCS for msg1, can only be 15 for 30 kHz < 6 GHz, takes precendence over the one derived from prach-ConfigIndex
|
||||
#
|
||||
msg1_SubcarrierSpacing = 1,
|
||||
# restrictedSetConfig
|
||||
# 0=unrestricted, 1=restricted type A, 2=restricted type B
|
||||
restrictedSetConfig = 0,
|
||||
|
||||
msg3_DeltaPreamble = 1;
|
||||
p0_NominalWithGrant =-90;
|
||||
|
||||
# pucch-ConfigCommon setup :
|
||||
# pucchGroupHopping
|
||||
# 0 = neither, 1= group hopping, 2=sequence hopping
|
||||
pucchGroupHopping = 0;
|
||||
hoppingId = 40;
|
||||
p0_nominal = -90;
|
||||
# ssb_PositionsInBurs_BitmapPR
|
||||
# 1=short, 2=medium, 3=long
|
||||
ssb_PositionsInBurst_PR = 2;
|
||||
ssb_PositionsInBurst_Bitmap = 1;
|
||||
|
||||
# ssb_periodicityServingCell
|
||||
# 0 = ms5, 1=ms10, 2=ms20, 3=ms40, 4=ms80, 5=ms160, 6=spare2, 7=spare1
|
||||
ssb_periodicityServingCell = 2;
|
||||
|
||||
# dmrs_TypeA_position
|
||||
# 0 = pos2, 1 = pos3
|
||||
dmrs_TypeA_Position = 0;
|
||||
|
||||
# subcarrierSpacing
|
||||
# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
|
||||
subcarrierSpacing = 1;
|
||||
|
||||
|
||||
#tdd-UL-DL-ConfigurationCommon
|
||||
# subcarrierSpacing
|
||||
# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
|
||||
referenceSubcarrierSpacing = 1;
|
||||
# pattern1
|
||||
# dl_UL_TransmissionPeriodicity
|
||||
# 0=ms0p5, 1=ms0p625, 2=ms1, 3=ms1p25, 4=ms2, 5=ms2p5, 6=ms5, 7=ms10
|
||||
dl_UL_TransmissionPeriodicity = 6;
|
||||
nrofDownlinkSlots = 7;
|
||||
nrofDownlinkSymbols = 6;
|
||||
nrofUplinkSlots = 2;
|
||||
nrofUplinkSymbols = 4;
|
||||
|
||||
ssPBCH_BlockPower = -25;
|
||||
}
|
||||
|
||||
);
|
||||
# ------- SCTP definitions
|
||||
SCTP :
|
||||
{
|
||||
# Number of streams to use in input/output
|
||||
SCTP_INSTREAMS = 2;
|
||||
SCTP_OUTSTREAMS = 2;
|
||||
};
|
||||
|
||||
|
||||
////////// AMF parameters:
|
||||
amf_ip_address = ( { ipv4 = "192.168.71.132";
|
||||
ipv6 = "192:168:30::17";
|
||||
active = "yes";
|
||||
preference = "ipv4";
|
||||
}
|
||||
);
|
||||
|
||||
E1_INTERFACE =
|
||||
(
|
||||
{
|
||||
type = "cp";
|
||||
ipv4_cucp = "192.168.72.140";
|
||||
port_cucp = 38462;
|
||||
ipv4_cuup = "192.168.72.141";
|
||||
port_cuup = 38462;
|
||||
}
|
||||
)
|
||||
|
||||
NETWORK_INTERFACES :
|
||||
{
|
||||
GNB_INTERFACE_NAME_FOR_NG_AMF = "demo-oai";
|
||||
GNB_IPV4_ADDRESS_FOR_NG_AMF = "192.168.71.140/24";
|
||||
};
|
||||
}
|
||||
);
|
||||
|
||||
security = {
|
||||
# preferred ciphering algorithms
|
||||
# the first one of the list that an UE supports in chosen
|
||||
# valid values: nea0, nea1, nea2, nea3
|
||||
ciphering_algorithms = ( "nea0" );
|
||||
|
||||
# preferred integrity algorithms
|
||||
# the first one of the list that an UE supports in chosen
|
||||
# valid values: nia0, nia1, nia2, nia3
|
||||
integrity_algorithms = ( "nia2", "nia0" );
|
||||
|
||||
# setting 'drb_ciphering' to "no" disables ciphering for DRBs, no matter
|
||||
# what 'ciphering_algorithms' configures; same thing for 'drb_integrity'
|
||||
drb_ciphering = "yes";
|
||||
drb_integrity = "no";
|
||||
};
|
||||
log_config :
|
||||
{
|
||||
global_log_level ="info";
|
||||
hw_log_level ="info";
|
||||
phy_log_level ="info";
|
||||
mac_log_level ="info";
|
||||
rlc_log_level ="debug";
|
||||
pdcp_log_level ="info";
|
||||
rrc_log_level ="info";
|
||||
f1ap_log_level ="info";
|
||||
ngap_log_level ="debug";
|
||||
};
|
||||
|
||||
87
ci-scripts/conf_files/gnb-cuup.sa.f1.conf
Normal file
87
ci-scripts/conf_files/gnb-cuup.sa.f1.conf
Normal file
@@ -0,0 +1,87 @@
|
||||
Active_gNBs = ( "gNB-OAI");
|
||||
# Asn1_verbosity, choice in: none, info, annoying
|
||||
Asn1_verbosity = "none";
|
||||
sa = 1;
|
||||
|
||||
gNBs =
|
||||
(
|
||||
{
|
||||
////////// Identification parameters:
|
||||
gNB_CU_ID = 0xe00;
|
||||
|
||||
# cell_type = "CELL_MACRO_GNB";
|
||||
|
||||
gNB_name = "gNB-OAI";
|
||||
|
||||
// Tracking area code, 0x0000 and 0xfffe are reserved values
|
||||
tracking_area_code = 1;
|
||||
plmn_list = ({ mcc = 208; mnc = 99; mnc_length = 2; snssaiList = ({ sst = 1, sd = 0xffffff }) });
|
||||
|
||||
|
||||
tr_s_preference = "f1";
|
||||
|
||||
local_s_if_name = "lo";
|
||||
local_s_address = "192.168.72.141";
|
||||
remote_s_address = "192.168.72.142";
|
||||
local_s_portc = 501;
|
||||
local_s_portd = 2152;
|
||||
remote_s_portc = 500;
|
||||
remote_s_portd = 2152;
|
||||
|
||||
# ------- SCTP definitions
|
||||
SCTP :
|
||||
{
|
||||
# Number of streams to use in input/output
|
||||
SCTP_INSTREAMS = 2;
|
||||
SCTP_OUTSTREAMS = 2;
|
||||
};
|
||||
|
||||
E1_INTERFACE =
|
||||
(
|
||||
{
|
||||
type = "up";
|
||||
ipv4_cucp = "192.168.72.140";
|
||||
ipv4_cuup = "192.168.72.141";
|
||||
}
|
||||
)
|
||||
|
||||
NETWORK_INTERFACES :
|
||||
{
|
||||
GNB_INTERFACE_NAME_FOR_NG_AMF = "demo-oai";
|
||||
GNB_IPV4_ADDRESS_FOR_NG_AMF = "192.168.71.141/24";
|
||||
GNB_INTERFACE_NAME_FOR_NGU = "demo-oai";
|
||||
GNB_IPV4_ADDRESS_FOR_NGU = "192.168.71.141/24";
|
||||
GNB_PORT_FOR_S1U = 2152; # Spec 2152
|
||||
};
|
||||
}
|
||||
);
|
||||
|
||||
security = {
|
||||
# preferred ciphering algorithms
|
||||
# the first one of the list that an UE supports in chosen
|
||||
# valid values: nea0, nea1, nea2, nea3
|
||||
ciphering_algorithms = ( "nea0" );
|
||||
|
||||
# preferred integrity algorithms
|
||||
# the first one of the list that an UE supports in chosen
|
||||
# valid values: nia0, nia1, nia2, nia3
|
||||
integrity_algorithms = ( "nia2", "nia0" );
|
||||
|
||||
# setting 'drb_ciphering' to "no" disables ciphering for DRBs, no matter
|
||||
# what 'ciphering_algorithms' configures; same thing for 'drb_integrity'
|
||||
drb_ciphering = "yes";
|
||||
drb_integrity = "no";
|
||||
};
|
||||
log_config :
|
||||
{
|
||||
global_log_level ="info";
|
||||
hw_log_level ="info";
|
||||
phy_log_level ="info";
|
||||
mac_log_level ="info";
|
||||
rlc_log_level ="debug";
|
||||
pdcp_log_level ="info";
|
||||
rrc_log_level ="info";
|
||||
f1ap_log_level ="info";
|
||||
ngap_log_level ="debug";
|
||||
};
|
||||
|
||||
238
ci-scripts/conf_files/gnb-du.band78.106prb.rfsim.conf
Normal file
238
ci-scripts/conf_files/gnb-du.band78.106prb.rfsim.conf
Normal file
@@ -0,0 +1,238 @@
|
||||
Active_gNBs = ( "du-rfsim");
|
||||
# Asn1_verbosity, choice in: none, info, annoying
|
||||
Asn1_verbosity = "none";
|
||||
|
||||
gNBs =
|
||||
(
|
||||
{
|
||||
////////// Identification parameters:
|
||||
gNB_ID = 0xe00;
|
||||
|
||||
# cell_type = "CELL_MACRO_GNB";
|
||||
|
||||
gNB_name = "du-rfsim";
|
||||
|
||||
// Tracking area code, 0x0000 and 0xfffe are reserved values
|
||||
tracking_area_code = 1;
|
||||
plmn_list = ({ mcc = 208; mnc = 99; mnc_length = 2; snssaiList = ({ sst = 1, sd = 0xffffff }) });
|
||||
|
||||
|
||||
nr_cellid = 12345678L;
|
||||
|
||||
////////// Physical parameters:
|
||||
|
||||
min_rxtxtime = 6;
|
||||
force_256qam_off = 1;
|
||||
|
||||
servingCellConfigCommon = (
|
||||
{
|
||||
#spCellConfigCommon
|
||||
|
||||
physCellId = 0;
|
||||
|
||||
# downlinkConfigCommon
|
||||
#frequencyInfoDL
|
||||
# this is 3600 MHz + 43 PRBs@30kHz SCS (same as initial BWP)
|
||||
absoluteFrequencySSB = 641280;
|
||||
dl_frequencyBand = 78;
|
||||
# this is 3600 MHz
|
||||
dl_absoluteFrequencyPointA = 640008;
|
||||
#scs-SpecificCarrierList
|
||||
dl_offstToCarrier = 0;
|
||||
# subcarrierSpacing
|
||||
# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
|
||||
dl_subcarrierSpacing = 1;
|
||||
dl_carrierBandwidth = 106;
|
||||
#initialDownlinkBWP
|
||||
#genericParameters
|
||||
# this is RBstart=27,L=48 (275*(L-1))+RBstart
|
||||
initialDLBWPlocationAndBandwidth = 28875; # 6366 12925 12956 28875 12952
|
||||
# subcarrierSpacing
|
||||
# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
|
||||
initialDLBWPsubcarrierSpacing = 1;
|
||||
#pdcch-ConfigCommon
|
||||
initialDLBWPcontrolResourceSetZero = 12;
|
||||
initialDLBWPsearchSpaceZero = 0;
|
||||
|
||||
#uplinkConfigCommon
|
||||
#frequencyInfoUL
|
||||
ul_frequencyBand = 78;
|
||||
#scs-SpecificCarrierList
|
||||
ul_offstToCarrier = 0;
|
||||
# subcarrierSpacing
|
||||
# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
|
||||
ul_subcarrierSpacing = 1;
|
||||
ul_carrierBandwidth = 106;
|
||||
pMax = 20;
|
||||
#initialUplinkBWP
|
||||
#genericParameters
|
||||
initialULBWPlocationAndBandwidth = 28875;
|
||||
# subcarrierSpacing
|
||||
# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
|
||||
initialULBWPsubcarrierSpacing = 1;
|
||||
#rach-ConfigCommon
|
||||
#rach-ConfigGeneric
|
||||
prach_ConfigurationIndex = 98;
|
||||
#prach_msg1_FDM
|
||||
#0 = one, 1=two, 2=four, 3=eight
|
||||
prach_msg1_FDM = 0;
|
||||
prach_msg1_FrequencyStart = 0;
|
||||
zeroCorrelationZoneConfig = 13;
|
||||
preambleReceivedTargetPower = -96;
|
||||
#preamblTransMax (0...10) = (3,4,5,6,7,8,10,20,50,100,200)
|
||||
preambleTransMax = 6;
|
||||
#powerRampingStep
|
||||
# 0=dB0,1=dB2,2=dB4,3=dB6
|
||||
powerRampingStep = 1;
|
||||
#ra_ReponseWindow
|
||||
#1,2,4,8,10,20,40,80
|
||||
ra_ResponseWindow = 4;
|
||||
#ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR
|
||||
#1=oneeighth,2=onefourth,3=half,4=one,5=two,6=four,7=eight,8=sixteen
|
||||
ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR = 4;
|
||||
#oneHalf (0..15) 4,8,12,16,...60,64
|
||||
ssb_perRACH_OccasionAndCB_PreamblesPerSSB = 14;
|
||||
#ra_ContentionResolutionTimer
|
||||
#(0..7) 8,16,24,32,40,48,56,64
|
||||
ra_ContentionResolutionTimer = 7;
|
||||
rsrp_ThresholdSSB = 19;
|
||||
#prach-RootSequenceIndex_PR
|
||||
#1 = 839, 2 = 139
|
||||
prach_RootSequenceIndex_PR = 2;
|
||||
prach_RootSequenceIndex = 1;
|
||||
# SCS for msg1, can only be 15 for 30 kHz < 6 GHz, takes precendence over the one derived from prach-ConfigIndex
|
||||
#
|
||||
msg1_SubcarrierSpacing = 1,
|
||||
# restrictedSetConfig
|
||||
# 0=unrestricted, 1=restricted type A, 2=restricted type B
|
||||
restrictedSetConfig = 0,
|
||||
|
||||
msg3_DeltaPreamble = 1;
|
||||
p0_NominalWithGrant =-90;
|
||||
|
||||
# pucch-ConfigCommon setup :
|
||||
# pucchGroupHopping
|
||||
# 0 = neither, 1= group hopping, 2=sequence hopping
|
||||
pucchGroupHopping = 0;
|
||||
hoppingId = 40;
|
||||
p0_nominal = -90;
|
||||
# ssb_PositionsInBurs_BitmapPR
|
||||
# 1=short, 2=medium, 3=long
|
||||
ssb_PositionsInBurst_PR = 2;
|
||||
ssb_PositionsInBurst_Bitmap = 1;
|
||||
|
||||
# ssb_periodicityServingCell
|
||||
# 0 = ms5, 1=ms10, 2=ms20, 3=ms40, 4=ms80, 5=ms160, 6=spare2, 7=spare1
|
||||
ssb_periodicityServingCell = 2;
|
||||
|
||||
# dmrs_TypeA_position
|
||||
# 0 = pos2, 1 = pos3
|
||||
dmrs_TypeA_Position = 0;
|
||||
|
||||
# subcarrierSpacing
|
||||
# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
|
||||
subcarrierSpacing = 1;
|
||||
|
||||
|
||||
#tdd-UL-DL-ConfigurationCommon
|
||||
# subcarrierSpacing
|
||||
# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
|
||||
referenceSubcarrierSpacing = 1;
|
||||
# pattern1
|
||||
# dl_UL_TransmissionPeriodicity
|
||||
# 0=ms0p5, 1=ms0p625, 2=ms1, 3=ms1p25, 4=ms2, 5=ms2p5, 6=ms5, 7=ms10
|
||||
dl_UL_TransmissionPeriodicity = 6;
|
||||
nrofDownlinkSlots = 7;
|
||||
nrofDownlinkSymbols = 6;
|
||||
nrofUplinkSlots = 2;
|
||||
nrofUplinkSymbols = 4;
|
||||
|
||||
ssPBCH_BlockPower = -25;
|
||||
}
|
||||
|
||||
);
|
||||
|
||||
|
||||
# ------- SCTP definitions
|
||||
SCTP :
|
||||
{
|
||||
# Number of streams to use in input/output
|
||||
SCTP_INSTREAMS = 2;
|
||||
SCTP_OUTSTREAMS = 2;
|
||||
};
|
||||
}
|
||||
);
|
||||
|
||||
MACRLCs = (
|
||||
{
|
||||
num_cc = 1;
|
||||
tr_s_preference = "local_L1";
|
||||
tr_n_preference = "f1";
|
||||
local_n_if_name = "eth0";
|
||||
local_n_address = "192.168.72.142";
|
||||
remote_n_address = "192.168.72.140";
|
||||
local_n_portc = 500;
|
||||
local_n_portd = 2152;
|
||||
remote_n_portc = 501;
|
||||
remote_n_portd = 2152;
|
||||
pusch_TargetSNRx10 = 200;
|
||||
pucch_TargetSNRx10 = 200;
|
||||
}
|
||||
);
|
||||
|
||||
L1s = (
|
||||
{
|
||||
num_cc = 1;
|
||||
tr_n_preference = "local_mac";
|
||||
prach_dtx_threshold = 200;
|
||||
pucch0_dtx_threshold = 150;
|
||||
ofdm_offset_divisor = 8; #set this to UINT_MAX for offset 0
|
||||
}
|
||||
);
|
||||
|
||||
RUs = (
|
||||
{
|
||||
local_rf = "yes"
|
||||
nb_tx = 1
|
||||
nb_rx = 1
|
||||
att_tx = 0
|
||||
att_rx = 0;
|
||||
bands = [78];
|
||||
max_pdschReferenceSignalPower = -27;
|
||||
max_rxgain = 114;
|
||||
eNB_instances = [0];
|
||||
#beamforming 1x4 matrix:
|
||||
bf_weights = [0x00007fff, 0x0000, 0x0000, 0x0000];
|
||||
clock_src = "internal";
|
||||
}
|
||||
);
|
||||
|
||||
THREAD_STRUCT = (
|
||||
{
|
||||
#three config for level of parallelism "PARALLEL_SINGLE_THREAD", "PARALLEL_RU_L1_SPLIT", or "PARALLEL_RU_L1_TRX_SPLIT"
|
||||
parallel_config = "PARALLEL_SINGLE_THREAD";
|
||||
#two option for worker "WORKER_DISABLE" or "WORKER_ENABLE"
|
||||
worker_config = "WORKER_ENABLE";
|
||||
}
|
||||
);
|
||||
|
||||
rfsimulator: {
|
||||
serveraddr = "server";
|
||||
serverport = "4043";
|
||||
options = (); #("saviq"); or/and "chanmod"
|
||||
modelname = "AWGN";
|
||||
IQfile = "/tmp/rfsimulator.iqs"
|
||||
}
|
||||
|
||||
log_config :
|
||||
{
|
||||
global_log_level = "info";
|
||||
hw_log_level = "info";
|
||||
nr_phy_log_level = "info";
|
||||
nr_mac_log_level = "info";
|
||||
rlc_log_level = "info";
|
||||
pdcp_log_level = "info";
|
||||
rrc_log_level = "info";
|
||||
f1ap_log_level = "info";
|
||||
ngap_log_level = "debug";
|
||||
};
|
||||
@@ -29,13 +29,6 @@ gNBs =
|
||||
do_SRS = 0;
|
||||
do_CSIRS = 1;
|
||||
|
||||
pdcch_ConfigSIB1 = (
|
||||
{
|
||||
controlResourceSetZero = 11;
|
||||
searchSpaceZero = 0;
|
||||
}
|
||||
);
|
||||
|
||||
servingCellConfigCommon = (
|
||||
{
|
||||
#spCellConfigCommon
|
||||
@@ -285,5 +278,5 @@ security = {
|
||||
rlc_log_level ="info";
|
||||
pdcp_log_level ="info";
|
||||
rrc_log_level ="info";
|
||||
f1ap_log_level ="debug";
|
||||
f1ap_log_level ="info";
|
||||
};
|
||||
|
||||
@@ -27,13 +27,6 @@ gNBs =
|
||||
pusch_AntennaPorts = 2;
|
||||
do_SRS = 0;
|
||||
|
||||
pdcch_ConfigSIB1 = (
|
||||
{
|
||||
controlResourceSetZero = 11;
|
||||
searchSpaceZero = 0;
|
||||
}
|
||||
);
|
||||
|
||||
servingCellConfigCommon = (
|
||||
{
|
||||
#spCellConfigCommon
|
||||
@@ -283,5 +276,5 @@ security = {
|
||||
rlc_log_level ="info";
|
||||
pdcp_log_level ="info";
|
||||
rrc_log_level ="info";
|
||||
f1ap_log_level ="debug";
|
||||
f1ap_log_level ="info";
|
||||
};
|
||||
|
||||
@@ -27,13 +27,6 @@ gNBs =
|
||||
ul_prbblacklist = "51,52,53,54"
|
||||
do_SRS = 0;
|
||||
|
||||
pdcch_ConfigSIB1 = (
|
||||
{
|
||||
controlResourceSetZero = 11;
|
||||
searchSpaceZero = 0;
|
||||
}
|
||||
);
|
||||
|
||||
servingCellConfigCommon = (
|
||||
{
|
||||
#spCellConfigCommon
|
||||
@@ -284,5 +277,5 @@ security = {
|
||||
rlc_log_level ="info";
|
||||
pdcp_log_level ="info";
|
||||
rrc_log_level ="info";
|
||||
f1ap_log_level ="debug";
|
||||
f1ap_log_level ="info";
|
||||
};
|
||||
|
||||
@@ -29,13 +29,6 @@ gNBs =
|
||||
min_rxtxtime = 6;
|
||||
do_SRS = 1;
|
||||
|
||||
pdcch_ConfigSIB1 = (
|
||||
{
|
||||
controlResourceSetZero = 11;
|
||||
searchSpaceZero = 0;
|
||||
}
|
||||
);
|
||||
|
||||
servingCellConfigCommon = (
|
||||
{
|
||||
#spCellConfigCommon
|
||||
@@ -287,5 +280,5 @@ security = {
|
||||
rlc_log_level ="info";
|
||||
pdcp_log_level ="info";
|
||||
rrc_log_level ="info";
|
||||
f1ap_log_level ="debug";
|
||||
f1ap_log_level ="info";
|
||||
};
|
||||
|
||||
@@ -30,13 +30,6 @@ gNBs =
|
||||
ul_prbblacklist = "79,80,81,82"
|
||||
do_SRS = 0;
|
||||
|
||||
pdcch_ConfigSIB1 = (
|
||||
{
|
||||
controlResourceSetZero = 11;
|
||||
searchSpaceZero = 0;
|
||||
}
|
||||
);
|
||||
|
||||
servingCellConfigCommon = (
|
||||
{
|
||||
#spCellConfigCommon
|
||||
@@ -286,5 +279,5 @@ security = {
|
||||
rlc_log_level ="info";
|
||||
pdcp_log_level ="info";
|
||||
rrc_log_level ="info";
|
||||
f1ap_log_level ="debug";
|
||||
f1ap_log_level ="info";
|
||||
};
|
||||
|
||||
@@ -46,9 +46,6 @@ gNBs =
|
||||
# subcarrierSpacing
|
||||
# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
|
||||
initialDLBWPsubcarrierSpacing = 1;
|
||||
#pdcch-ConfigCommon
|
||||
initialDLBWPcontrolResourceSetZero = 0;
|
||||
initialDLBWPsearchSpaceZero = 0;
|
||||
|
||||
#uplinkConfigCommon
|
||||
#frequencyInfoUL
|
||||
|
||||
@@ -20,13 +20,6 @@ gNBs =
|
||||
min_rxtxtime = 6;
|
||||
enable_sdap = 1;
|
||||
|
||||
pdcch_ConfigSIB1 = (
|
||||
{
|
||||
controlResourceSetZero = 12;
|
||||
searchSpaceZero = 0;
|
||||
}
|
||||
);
|
||||
|
||||
servingCellConfigCommon = (
|
||||
{
|
||||
#spCellConfigCommon
|
||||
|
||||
284
ci-scripts/conf_files/gnb.sa.band66.u0.25prb.rfsim.conf
Normal file
284
ci-scripts/conf_files/gnb.sa.band66.u0.25prb.rfsim.conf
Normal file
@@ -0,0 +1,284 @@
|
||||
Active_gNBs = ( "5G-GOA-gNB");
|
||||
# Asn1_verbosity, choice in: none, info, annoying
|
||||
Asn1_verbosity = "none";
|
||||
|
||||
gNBs =
|
||||
(
|
||||
{
|
||||
////////// Identification parameters:
|
||||
gNB_ID = 0xe00;
|
||||
gNB_name = "5G-GOA-gNB";
|
||||
|
||||
// Tracking area code, 0x0000 and 0xfffe are reserved values
|
||||
tracking_area_code = 1;
|
||||
plmn_list = ({ mcc = 208; mnc = 99; mnc_length = 2; snssaiList = ({ sst = 1 }) });
|
||||
|
||||
nr_cellid = 12345678L;
|
||||
|
||||
////////// Physical parameters:
|
||||
|
||||
sib1_tda = 5;
|
||||
min_rxtxtime = 6;
|
||||
|
||||
pdcch_ConfigSIB1 = (
|
||||
{
|
||||
controlResourceSetZero = 2;
|
||||
searchSpaceZero = 0;
|
||||
}
|
||||
);
|
||||
|
||||
servingCellConfigCommon = (
|
||||
{
|
||||
#spCellConfigCommon
|
||||
|
||||
physCellId = 0;
|
||||
|
||||
# downlinkConfigCommon
|
||||
#frequencyInfoDL
|
||||
# this is 2150 MHz + 14 PRBs@15kHz SCS (same as initial BWP), points to Subcarrier 0 of RB#10 of SSB block
|
||||
absoluteFrequencySSB = 430504;
|
||||
dl_frequencyBand = 66;
|
||||
# this is 2150 MHz
|
||||
dl_absoluteFrequencyPointA = 430000;
|
||||
#scs-SpecificCarrierList
|
||||
dl_offstToCarrier = 0;
|
||||
# subcarrierSpacing
|
||||
# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
|
||||
dl_subcarrierSpacing = 0;
|
||||
dl_carrierBandwidth = 25;
|
||||
#initialDownlinkBWP
|
||||
#genericParameters
|
||||
# this is RBstart=0,L=25 (275*(L-1))+RBstart
|
||||
initialDLBWPlocationAndBandwidth = 6600;
|
||||
# subcarrierSpacing
|
||||
# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
|
||||
initialDLBWPsubcarrierSpacing = 0;
|
||||
#pdcch-ConfigCommon
|
||||
initialDLBWPcontrolResourceSetZero = 2;
|
||||
initialDLBWPsearchSpaceZero = 0;
|
||||
|
||||
#uplinkConfigCommon
|
||||
#frequencyInfoUL
|
||||
ul_frequencyBand = 66;
|
||||
# this is 1750 MHz
|
||||
ul_absoluteFrequencyPointA = 350000;
|
||||
#scs-SpecificCarrierList
|
||||
ul_offstToCarrier = 0;
|
||||
# subcarrierSpacing
|
||||
# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
|
||||
ul_subcarrierSpacing = 0;
|
||||
ul_carrierBandwidth = 25;
|
||||
pMax = 20;
|
||||
#initialUplinkBWP
|
||||
#genericParameters
|
||||
initialULBWPlocationAndBandwidth = 6600;
|
||||
# subcarrierSpacing
|
||||
# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
|
||||
initialULBWPsubcarrierSpacing = 0;
|
||||
#rach-ConfigCommon
|
||||
#rach-ConfigGeneric
|
||||
prach_ConfigurationIndex = 98;
|
||||
#prach_msg1_FDM
|
||||
#0 = one, 1=two, 2=four, 3=eight
|
||||
prach_msg1_FDM = 0;
|
||||
prach_msg1_FrequencyStart = 0;
|
||||
zeroCorrelationZoneConfig = 13;
|
||||
preambleReceivedTargetPower = -118;
|
||||
#preamblTransMax (0...10) = (3,4,5,6,7,8,10,20,50,100,200)
|
||||
preambleTransMax = 6;
|
||||
#powerRampingStep
|
||||
# 0=dB0,1=dB2,2=dB4,3=dB6
|
||||
powerRampingStep = 1;
|
||||
#ra_ReponseWindow
|
||||
#1,2,4,8,10,20,40,80
|
||||
ra_ResponseWindow = 4;
|
||||
#ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR
|
||||
#1=oneeighth,2=onefourth,3=half,4=one,5=two,6=four,7=eight,8=sixteen
|
||||
ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR = 4;
|
||||
#oneHalf (0..15) 4,8,12,16,...60,64
|
||||
ssb_perRACH_OccasionAndCB_PreamblesPerSSB = 15;
|
||||
#ra_ContentionResolutionTimer
|
||||
#(0..7) 8,16,24,32,40,48,56,64
|
||||
ra_ContentionResolutionTimer = 7;
|
||||
rsrp_ThresholdSSB = 19;
|
||||
#prach-RootSequenceIndex_PR
|
||||
#1 = 839, 2 = 139
|
||||
prach_RootSequenceIndex_PR = 2;
|
||||
prach_RootSequenceIndex = 1;
|
||||
# SCS for msg1, can only be 15 for 30 kHz < 6 GHz, takes precendence over the one derived from prach-ConfigIndex
|
||||
#
|
||||
msg1_SubcarrierSpacing = 0;
|
||||
# restrictedSetConfig
|
||||
# 0=unrestricted, 1=restricted type A, 2=restricted type B
|
||||
restrictedSetConfig = 0;
|
||||
|
||||
msg3_DeltaPreamble = 1;
|
||||
p0_NominalWithGrant =-90;
|
||||
|
||||
# pucch-ConfigCommon setup :
|
||||
# pucchGroupHopping
|
||||
# 0 = neither, 1= group hopping, 2=sequence hopping
|
||||
pucchGroupHopping = 0;
|
||||
hoppingId = 40;
|
||||
p0_nominal = -90;
|
||||
# ssb_PositionsInBurs_BitmapPR
|
||||
# 1=short, 2=medium, 3=long
|
||||
ssb_PositionsInBurst_PR = 2;
|
||||
ssb_PositionsInBurst_Bitmap = 1;
|
||||
|
||||
# ssb_periodicityServingCell
|
||||
# 0 = ms5, 1=ms10, 2=ms20, 3=ms40, 4=ms80, 5=ms160, 6=spare2, 7=spare1
|
||||
ssb_periodicityServingCell = 2;
|
||||
|
||||
# dmrs_TypeA_position
|
||||
# 0 = pos2, 1 = pos3
|
||||
dmrs_TypeA_Position = 0;
|
||||
|
||||
# subcarrierSpacing
|
||||
# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
|
||||
subcarrierSpacing = 0;
|
||||
|
||||
|
||||
#tdd-UL-DL-ConfigurationCommon
|
||||
# subcarrierSpacing
|
||||
# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
|
||||
referenceSubcarrierSpacing = 0;
|
||||
# pattern1
|
||||
# dl_UL_TransmissionPeriodicity
|
||||
# 0=ms0p5, 1=ms0p625, 2=ms1, 3=ms1p25, 4=ms2, 5=ms2p5, 6=ms5, 7=ms10
|
||||
dl_UL_TransmissionPeriodicity = 6;
|
||||
nrofDownlinkSlots = 7;
|
||||
nrofDownlinkSymbols = 6;
|
||||
nrofUplinkSlots = 2;
|
||||
nrofUplinkSymbols = 4;
|
||||
|
||||
ssPBCH_BlockPower = -25;
|
||||
}
|
||||
|
||||
);
|
||||
|
||||
|
||||
# ------- SCTP definitions
|
||||
SCTP :
|
||||
{
|
||||
# Number of streams to use in input/output
|
||||
SCTP_INSTREAMS = 2;
|
||||
SCTP_OUTSTREAMS = 2;
|
||||
};
|
||||
|
||||
|
||||
////////// AMF parameters:
|
||||
amf_ip_address = ( { ipv4 = "192.168.71.132";
|
||||
ipv6 = "192:168:30::17";
|
||||
active = "yes";
|
||||
preference = "ipv4";
|
||||
}
|
||||
);
|
||||
|
||||
NETWORK_INTERFACES :
|
||||
{
|
||||
GNB_INTERFACE_NAME_FOR_NG_AMF = "eno1";
|
||||
GNB_IPV4_ADDRESS_FOR_NG_AMF = "192.168.71.140/26";
|
||||
GNB_INTERFACE_NAME_FOR_NGU = "eno1";
|
||||
GNB_IPV4_ADDRESS_FOR_NGU = "192.168.71.140/26";
|
||||
GNB_PORT_FOR_S1U = 2152; # Spec 2152
|
||||
};
|
||||
|
||||
}
|
||||
);
|
||||
|
||||
MACRLCs = (
|
||||
{
|
||||
num_cc = 1;
|
||||
tr_s_preference = "local_L1";
|
||||
tr_n_preference = "local_RRC";
|
||||
pusch_TargetSNRx10 = 150;
|
||||
pucch_TargetSNRx10 = 200;
|
||||
ulsch_max_frame_inactivity = 0;
|
||||
}
|
||||
);
|
||||
|
||||
L1s = (
|
||||
{
|
||||
num_cc = 1;
|
||||
tr_n_preference = "local_mac";
|
||||
prach_dtx_threshold = 120;
|
||||
pucch0_dtx_threshold = 150;
|
||||
ofdm_offset_divisor = 8; #set this to UINT_MAX for offset 0
|
||||
}
|
||||
);
|
||||
|
||||
RUs = (
|
||||
{
|
||||
local_rf = "yes";
|
||||
nb_tx = 1;
|
||||
nb_rx = 1;
|
||||
att_tx = 0;
|
||||
att_rx = 0;
|
||||
bands = [7];
|
||||
max_pdschReferenceSignalPower = -27;
|
||||
max_rxgain = 114;
|
||||
sf_extension = 0;
|
||||
eNB_instances = [0];
|
||||
##beamforming 1x2 matrix: 1 layer x 2 antennas
|
||||
bf_weights = [0x00007fff, 0x0000];
|
||||
##beamforming 1x4 matrix: 1 layer x 4 antennas
|
||||
#bf_weights = [0x00007fff, 0x0000,0x0000, 0x0000];
|
||||
## beamforming 2x2 matrix:
|
||||
# bf_weights = [0x00007fff, 0x00000000, 0x00000000, 0x00007fff];
|
||||
## beamforming 4x4 matrix:
|
||||
#bf_weights = [0x00007fff, 0x0000, 0x0000, 0x0000, 0x00000000, 0x00007fff, 0x0000, 0x0000, 0x0000, 0x0000, 0x00007fff, 0x0000, 0x0000, 0x0000, 0x0000, 0x00007fff];
|
||||
sdr_addrs = "type=x300";
|
||||
clock_src = "internal";
|
||||
# if_freq = 3700000000L;
|
||||
# if_offset = 1000000;
|
||||
}
|
||||
);
|
||||
|
||||
THREAD_STRUCT = (
|
||||
{
|
||||
#three config for level of parallelism "PARALLEL_SINGLE_THREAD", "PARALLEL_RU_L1_SPLIT", or "PARALLEL_RU_L1_TRX_SPLIT"
|
||||
parallel_config = "PARALLEL_RU_L1_TRX_SPLIT";
|
||||
#two option for worker "WORKER_DISABLE" or "WORKER_ENABLE"
|
||||
worker_config = "WORKER_DISABLE";
|
||||
}
|
||||
);
|
||||
|
||||
rfsimulator :
|
||||
{
|
||||
serveraddr = "server";
|
||||
serverport = "4043";
|
||||
options = (); #("saviq"); or/and "chanmod"
|
||||
modelname = "AWGN";
|
||||
IQfile = "/tmp/rfsimulator.iqs";
|
||||
};
|
||||
|
||||
security = {
|
||||
# preferred ciphering algorithms
|
||||
# the first one of the list that an UE supports in chosen
|
||||
# valid values: nea0, nea1, nea2, nea3
|
||||
ciphering_algorithms = ( "nea0" );
|
||||
|
||||
# preferred integrity algorithms
|
||||
# the first one of the list that an UE supports in chosen
|
||||
# valid values: nia0, nia1, nia2, nia3
|
||||
integrity_algorithms = ( "nia2", "nia0" );
|
||||
|
||||
# setting 'drb_ciphering' to "no" disables ciphering for DRBs, no matter
|
||||
# what 'ciphering_algorithms' configures; same thing for 'drb_integrity'
|
||||
drb_ciphering = "yes";
|
||||
drb_integrity = "no";
|
||||
};
|
||||
|
||||
log_config :
|
||||
{
|
||||
global_log_level ="info";
|
||||
hw_log_level ="info";
|
||||
phy_log_level ="info";
|
||||
mac_log_level ="info";
|
||||
rlc_log_level ="info";
|
||||
pdcp_log_level ="info";
|
||||
rrc_log_level ="info";
|
||||
ngap_log_level ="debug";
|
||||
f1ap_log_level ="info";
|
||||
};
|
||||
276
ci-scripts/conf_files/gnb.sa.band78.106prb.rfsim.2x2.conf
Normal file
276
ci-scripts/conf_files/gnb.sa.band78.106prb.rfsim.2x2.conf
Normal file
@@ -0,0 +1,276 @@
|
||||
Active_gNBs = ( "gNB-OAI");
|
||||
# Asn1_verbosity, choice in: none, info, annoying
|
||||
Asn1_verbosity = "none";
|
||||
|
||||
gNBs =
|
||||
(
|
||||
{
|
||||
////////// Identification parameters:
|
||||
gNB_ID = 0xe00;
|
||||
gNB_name = "gNB-OAI";
|
||||
|
||||
// Tracking area code, 0x0000 and 0xfffe are reserved values
|
||||
tracking_area_code = 1;
|
||||
plmn_list = ({ mcc = 208; mnc = 99; mnc_length = 2; snssaiList = ({ sst = 1 }) });
|
||||
|
||||
nr_cellid = 12345678L;
|
||||
|
||||
////////// Physical parameters:
|
||||
|
||||
pdsch_AntennaPorts_XP = 2;
|
||||
pusch_AntennaPorts = 2;
|
||||
do_CSIRS = 1;
|
||||
do_SRS = 1;
|
||||
min_rxtxtime = 5;
|
||||
|
||||
pdcch_ConfigSIB1 = (
|
||||
{
|
||||
controlResourceSetZero = 12;
|
||||
searchSpaceZero = 0;
|
||||
}
|
||||
);
|
||||
|
||||
servingCellConfigCommon = (
|
||||
{
|
||||
#spCellConfigCommon
|
||||
|
||||
physCellId = 0;
|
||||
|
||||
# downlinkConfigCommon
|
||||
#frequencyInfoDL
|
||||
# this is 3300.60 MHz + 53*12*30e-3 MHz = 3319.68
|
||||
absoluteFrequencySSB = 621312; # 641280
|
||||
dl_frequencyBand = 78;
|
||||
# this is 3300.60 MHz
|
||||
dl_absoluteFrequencyPointA = 620040; # 640008
|
||||
#scs-SpecificCarrierList
|
||||
dl_offstToCarrier = 0;
|
||||
# subcarrierSpacing
|
||||
# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
|
||||
dl_subcarrierSpacing = 1;
|
||||
dl_carrierBandwidth = 106;
|
||||
#initialDownlinkBWP
|
||||
#genericParameters
|
||||
# this is RBstart=27,L=48 (275*(L-1))+RBstart
|
||||
initialDLBWPlocationAndBandwidth = 28875; # 6366 12925 12956 28875 12952
|
||||
# subcarrierSpacing
|
||||
# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
|
||||
initialDLBWPsubcarrierSpacing = 1;
|
||||
#pdcch-ConfigCommon
|
||||
initialDLBWPcontrolResourceSetZero = 12;
|
||||
initialDLBWPsearchSpaceZero = 0;
|
||||
|
||||
#uplinkConfigCommon
|
||||
#frequencyInfoUL
|
||||
ul_frequencyBand = 78;
|
||||
#scs-SpecificCarrierList
|
||||
ul_offstToCarrier = 0;
|
||||
# subcarrierSpacing
|
||||
# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
|
||||
ul_subcarrierSpacing = 1;
|
||||
ul_carrierBandwidth = 106;
|
||||
pMax = 20;
|
||||
#initialUplinkBWP
|
||||
#genericParameters
|
||||
initialULBWPlocationAndBandwidth = 28875;
|
||||
# subcarrierSpacing
|
||||
# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
|
||||
initialULBWPsubcarrierSpacing = 1;
|
||||
#rach-ConfigCommon
|
||||
#rach-ConfigGeneric
|
||||
prach_ConfigurationIndex = 98;
|
||||
#prach_msg1_FDM
|
||||
#0 = one, 1=two, 2=four, 3=eight
|
||||
prach_msg1_FDM = 0;
|
||||
prach_msg1_FrequencyStart = 0;
|
||||
zeroCorrelationZoneConfig = 12;
|
||||
preambleReceivedTargetPower = -96;
|
||||
#preamblTransMax (0...10) = (3,4,5,6,7,8,10,20,50,100,200)
|
||||
preambleTransMax = 6;
|
||||
#powerRampingStep
|
||||
# 0=dB0,1=dB2,2=dB4,3=dB6
|
||||
powerRampingStep = 1;
|
||||
#ra_ReponseWindow
|
||||
#1,2,4,8,10,20,40,80
|
||||
ra_ResponseWindow = 4;
|
||||
#ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR
|
||||
#1=oneeighth,2=onefourth,3=half,4=one,5=two,6=four,7=eight,8=sixteen
|
||||
ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR = 3;
|
||||
#oneHalf (0..15) 4,8,12,16,...60,64
|
||||
ssb_perRACH_OccasionAndCB_PreamblesPerSSB = 15;
|
||||
#ra_ContentionResolutionTimer
|
||||
#(0..7) 8,16,24,32,40,48,56,64
|
||||
ra_ContentionResolutionTimer = 7;
|
||||
rsrp_ThresholdSSB = 19;
|
||||
#prach-RootSequenceIndex_PR
|
||||
#1 = 839, 2 = 139
|
||||
prach_RootSequenceIndex_PR = 2;
|
||||
prach_RootSequenceIndex = 1;
|
||||
# SCS for msg1, can only be 15 for 30 kHz < 6 GHz, takes precendence over the one derived from prach-ConfigIndex
|
||||
#
|
||||
msg1_SubcarrierSpacing = 1,
|
||||
# restrictedSetConfig
|
||||
# 0=unrestricted, 1=restricted type A, 2=restricted type B
|
||||
restrictedSetConfig = 0,
|
||||
|
||||
msg3_DeltaPreamble = 1;
|
||||
p0_NominalWithGrant =-90;
|
||||
|
||||
# pucch-ConfigCommon setup :
|
||||
# pucchGroupHopping
|
||||
# 0 = neither, 1= group hopping, 2=sequence hopping
|
||||
pucchGroupHopping = 0;
|
||||
hoppingId = 40;
|
||||
p0_nominal = -70;
|
||||
# ssb_PositionsInBurs_BitmapPR
|
||||
# 1=short, 2=medium, 3=long
|
||||
ssb_PositionsInBurst_PR = 2;
|
||||
ssb_PositionsInBurst_Bitmap = 1;
|
||||
|
||||
# ssb_periodicityServingCell
|
||||
# 0 = ms5, 1=ms10, 2=ms20, 3=ms40, 4=ms80, 5=ms160, 6=spare2, 7=spare1
|
||||
ssb_periodicityServingCell = 2;
|
||||
|
||||
# dmrs_TypeA_position
|
||||
# 0 = pos2, 1 = pos3
|
||||
dmrs_TypeA_Position = 0;
|
||||
|
||||
# subcarrierSpacing
|
||||
# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
|
||||
subcarrierSpacing = 1;
|
||||
|
||||
|
||||
#tdd-UL-DL-ConfigurationCommon
|
||||
# subcarrierSpacing
|
||||
# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
|
||||
referenceSubcarrierSpacing = 1;
|
||||
# pattern1
|
||||
# dl_UL_TransmissionPeriodicity
|
||||
# 0=ms0p5, 1=ms0p625, 2=ms1, 3=ms1p25, 4=ms2, 5=ms2p5, 6=ms5, 7=ms10
|
||||
dl_UL_TransmissionPeriodicity = 6;
|
||||
nrofDownlinkSlots = 7;
|
||||
nrofDownlinkSymbols = 6;
|
||||
nrofUplinkSlots = 2;
|
||||
nrofUplinkSymbols = 4;
|
||||
|
||||
ssPBCH_BlockPower = -25;
|
||||
}
|
||||
|
||||
);
|
||||
|
||||
# ------- SCTP definitions
|
||||
SCTP :
|
||||
{
|
||||
# Number of streams to use in input/output
|
||||
SCTP_INSTREAMS = 2;
|
||||
SCTP_OUTSTREAMS = 2;
|
||||
};
|
||||
|
||||
|
||||
////////// AMF parameters:
|
||||
amf_ip_address = ( { ipv4 = "192.168.71.132";
|
||||
ipv6 = "192:168:30::17";
|
||||
active = "yes";
|
||||
preference = "ipv4";
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
NETWORK_INTERFACES :
|
||||
{
|
||||
GNB_INTERFACE_NAME_FOR_NG_AMF = "demo-oai";
|
||||
GNB_IPV4_ADDRESS_FOR_NG_AMF = "192.168.71.140/24";
|
||||
GNB_INTERFACE_NAME_FOR_NGU = "demo-oai";
|
||||
GNB_IPV4_ADDRESS_FOR_NGU = "192.168.71.140/24";
|
||||
GNB_PORT_FOR_S1U = 2152; # Spec 2152
|
||||
};
|
||||
|
||||
}
|
||||
);
|
||||
|
||||
MACRLCs = (
|
||||
{
|
||||
num_cc = 1;
|
||||
tr_s_preference = "local_L1";
|
||||
tr_n_preference = "local_RRC";
|
||||
#pusch_TargetSNRx10 = 150;
|
||||
#pucch_TargetSNRx10 = 200;
|
||||
ulsch_max_frame_inactivity = 0;
|
||||
dl_max_mcs = 16; # there are retransmissions if more
|
||||
}
|
||||
);
|
||||
|
||||
L1s = (
|
||||
{
|
||||
num_cc = 1;
|
||||
tr_n_preference = "local_mac";
|
||||
prach_dtx_threshold = 120;
|
||||
#pucch0_dtx_threshold = 120;
|
||||
}
|
||||
);
|
||||
|
||||
RUs = (
|
||||
{
|
||||
local_rf = "yes"
|
||||
nb_tx = 2
|
||||
nb_rx = 2
|
||||
att_tx = 0
|
||||
att_rx = 0;
|
||||
bands = [78];
|
||||
max_pdschReferenceSignalPower = -27;
|
||||
max_rxgain = 75;
|
||||
eNB_instances = [0];
|
||||
##beamforming 1x2 matrix: 1 layer x 2 antennas
|
||||
bf_weights = [0x00007fff, 0x0000];
|
||||
#clock_src = "internal";
|
||||
sdr_addrs = "mgmt_addr=192.168.10.2,addr=192.168.10.2,clock_source=internal,time_source=internal"
|
||||
}
|
||||
);
|
||||
|
||||
THREAD_STRUCT = (
|
||||
{
|
||||
#three config for level of parallelism "PARALLEL_SINGLE_THREAD", "PARALLEL_RU_L1_SPLIT", or "PARALLEL_RU_L1_TRX_SPLIT"
|
||||
parallel_config = "PARALLEL_SINGLE_THREAD";
|
||||
#two option for worker "WORKER_DISABLE" or "WORKER_ENABLE"
|
||||
worker_config = "WORKER_ENABLE";
|
||||
}
|
||||
);
|
||||
|
||||
rfsimulator :
|
||||
{
|
||||
serveraddr = "server";
|
||||
serverport = "4043";
|
||||
options = (); #("saviq"); or/and "chanmod"
|
||||
modelname = "AWGN";
|
||||
IQfile = "/tmp/rfsimulator.iqs";
|
||||
};
|
||||
|
||||
security = {
|
||||
# preferred ciphering algorithms
|
||||
# the first one of the list that an UE supports in chosen
|
||||
# valid values: nea0, nea1, nea2, nea3
|
||||
ciphering_algorithms = ( "nea0" );
|
||||
|
||||
# preferred integrity algorithms
|
||||
# the first one of the list that an UE supports in chosen
|
||||
# valid values: nia0, nia1, nia2, nia3
|
||||
integrity_algorithms = ( "nia2", "nia0" );
|
||||
|
||||
# setting 'drb_ciphering' to "no" disables ciphering for DRBs, no matter
|
||||
# what 'ciphering_algorithms' configures; same thing for 'drb_integrity'
|
||||
drb_ciphering = "yes";
|
||||
drb_integrity = "no";
|
||||
};
|
||||
|
||||
log_config :
|
||||
{
|
||||
global_log_level ="info";
|
||||
hw_log_level ="info";
|
||||
phy_log_level ="info";
|
||||
mac_log_level ="info";
|
||||
rlc_log_level ="info";
|
||||
pdcp_log_level ="info";
|
||||
rrc_log_level ="info";
|
||||
ngap_log_level ="debug";
|
||||
f1ap_log_level ="info";
|
||||
};
|
||||
@@ -20,13 +20,6 @@ gNBs =
|
||||
sib1_tda = 15;
|
||||
min_rxtxtime = 6;
|
||||
|
||||
pdcch_ConfigSIB1 = (
|
||||
{
|
||||
controlResourceSetZero = 2;
|
||||
searchSpaceZero = 0;
|
||||
}
|
||||
);
|
||||
|
||||
servingCellConfigCommon = (
|
||||
{
|
||||
#spCellConfigCommon
|
||||
|
||||
@@ -20,13 +20,6 @@ gNBs =
|
||||
do_CSIRS = 0;
|
||||
do_SRS = 0;
|
||||
|
||||
pdcch_ConfigSIB1 = (
|
||||
{
|
||||
controlResourceSetZero = 12;
|
||||
searchSpaceZero = 0;
|
||||
}
|
||||
);
|
||||
|
||||
servingCellConfigCommon = (
|
||||
{
|
||||
#spCellConfigCommon
|
||||
@@ -269,6 +262,6 @@ log_config :
|
||||
pdcp_log_level ="info";
|
||||
rrc_log_level ="info";
|
||||
ngap_log_level ="debug";
|
||||
f1ap_log_level ="debug";
|
||||
f1ap_log_level ="info";
|
||||
};
|
||||
|
||||
|
||||
@@ -1,107 +0,0 @@
|
||||
#!/bin/bash
|
||||
#/*
|
||||
# * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
|
||||
# * contributor license agreements. See the NOTICE file distributed with
|
||||
# * this work for additional information regarding copyright ownership.
|
||||
# * The OpenAirInterface Software Alliance licenses this file to You under
|
||||
# * the OAI Public License, Version 1.1 (the "License"); you may not use this file
|
||||
# * except in compliance with the License.
|
||||
# * You may obtain a copy of the License at
|
||||
# *
|
||||
# * http://www.openairinterface.org/?page_id=698
|
||||
# *
|
||||
# * Unless required by applicable law or agreed to in writing, software
|
||||
# * distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# * See the License for the specific language governing permissions and
|
||||
# * limitations under the License.
|
||||
# *-------------------------------------------------------------------------------
|
||||
# * For more information about the OpenAirInterface (OAI) Software Alliance:
|
||||
# * contact@openairinterface.org
|
||||
# */
|
||||
|
||||
function create_usage {
|
||||
echo "OAI CI VM script"
|
||||
echo " Original Author: Raphael Defosseux"
|
||||
echo " Requirements:"
|
||||
echo " -- uvtool uvtool-libvirt apt-cacher"
|
||||
echo " -- $VM_OSREL image already synced"
|
||||
echo " Default:"
|
||||
echo " -- eNB with USRP"
|
||||
echo ""
|
||||
echo "Usage:"
|
||||
echo "------"
|
||||
echo " oai-ci-vm-tool create [OPTIONS]"
|
||||
echo ""
|
||||
echo "Mandatory Options:"
|
||||
echo "--------"
|
||||
echo " --job-name #### OR -jn ####"
|
||||
echo " Specify the name of the Jenkins job."
|
||||
echo ""
|
||||
echo " --build-id #### OR -id ####"
|
||||
echo " Specify the build ID of the Jenkins job."
|
||||
echo ""
|
||||
variant_usage
|
||||
echo " Specify the variant to build."
|
||||
echo ""
|
||||
echo " --help OR -h"
|
||||
echo " Print this help message."
|
||||
echo ""
|
||||
}
|
||||
|
||||
function acquire_vm_create_lock {
|
||||
local FlockFile="/tmp/vmclone.lck"
|
||||
local unlocked="0"
|
||||
touch ${FlockFile} 2>/dev/null
|
||||
if [[ $? -ne 0 ]]
|
||||
then
|
||||
echo "Cannot access lock file ${FlockFile}"
|
||||
exit 2
|
||||
fi
|
||||
while [ $unlocked -eq 0 ]
|
||||
do
|
||||
exec 5>${FlockFile}
|
||||
flock -nx 5
|
||||
if [[ $? -ne 0 ]]
|
||||
then
|
||||
echo "Another instance of VM creation is running"
|
||||
sleep 10
|
||||
else
|
||||
unlocked="1"
|
||||
fi
|
||||
done
|
||||
chmod 666 ${FlockFile} 2>/dev/null
|
||||
}
|
||||
|
||||
function release_vm_create_lock {
|
||||
local FlockFile="/tmp/vmclone.lck"
|
||||
rm -Rf ${FlockFile}
|
||||
}
|
||||
|
||||
function create_vm {
|
||||
echo "############################################################"
|
||||
echo "OAI CI VM script"
|
||||
echo "############################################################"
|
||||
echo "VM_NAME = $VM_NAME"
|
||||
echo "VM_MEMORY = $VM_MEMORY MBytes"
|
||||
echo "VM_CPU = $VM_CPU"
|
||||
echo "VM_DISK = $VM_DISK GBytes"
|
||||
|
||||
if [[ "$VM_NAME" == *"-enb-usrp"* ]] || [[ "$VM_NAME" == *"-cppcheck"* ]] || [[ "$VM_NAME" == *"-phy-sim"* ]] || [[ "$VM_NAME" == *"-rf-sim"* ]] || [[ "$VM_NAME" == *"-ethernet"* ]] || [[ "$VM_NAME" == *"rf5g-sim"* ]]
|
||||
then
|
||||
echo "This VM type is no longer supported in the pipeline framework"
|
||||
return
|
||||
fi
|
||||
|
||||
echo "############################################################"
|
||||
echo "Creating VM ($VM_NAME) on Ubuntu Cloud Image base"
|
||||
echo "############################################################"
|
||||
acquire_vm_create_lock
|
||||
uvt-kvm create $VM_NAME release=$VM_OSREL --memory $VM_MEMORY --cpu $VM_CPU --disk $VM_DISK --unsafe-caching --template ci-scripts/template-host.xml
|
||||
echo "Waiting for VM to be started"
|
||||
uvt-kvm wait $VM_NAME --insecure
|
||||
|
||||
VM_IP_ADDR=`uvt-kvm ip $VM_NAME`
|
||||
echo "$VM_NAME has for IP addr = $VM_IP_ADDR"
|
||||
release_vm_create_lock
|
||||
}
|
||||
@@ -8,14 +8,14 @@ ColNames :
|
||||
- Average vs Reference Deviation (Reference Value; Acceptability Threshold)
|
||||
Ref :
|
||||
feprx : 46.0
|
||||
feptx_prec : 11.0
|
||||
feptx_prec : 15.0
|
||||
feptx_ofdm : 35.0
|
||||
feptx_total : 57.0
|
||||
L1 Tx processing : 210.0
|
||||
DLSCH encoding : 137.0
|
||||
L1 Rx processing : 345.0
|
||||
PUSCH inner-receiver : 184.0
|
||||
PUSCH decoding : 276.0
|
||||
PUSCH inner-receiver : 210.0
|
||||
PUSCH decoding : 210.0
|
||||
Schedule Response : 48.0
|
||||
DL & UL scheduling timing : 13.0
|
||||
UL Indication : 60.0
|
||||
|
||||
@@ -14,10 +14,10 @@ Ref :
|
||||
L1 Tx processing : 400.0
|
||||
DLSCH encoding : 177.0
|
||||
L1 Rx processing : 345.0
|
||||
PUSCH inner-receiver : 184.0
|
||||
PUSCH decoding : 276.0
|
||||
PUSCH inner-receiver : 210.0
|
||||
PUSCH decoding : 210.0
|
||||
Schedule Response : 111.0
|
||||
DL & UL scheduling timing : 37.0
|
||||
DL & UL scheduling timing : 20.0
|
||||
UL Indication : 127.0
|
||||
Threshold :
|
||||
feprx : 1.25
|
||||
|
||||
@@ -14,11 +14,11 @@ Ref :
|
||||
L1 Tx processing : 170.0
|
||||
DLSCH encoding : 118.0
|
||||
L1 Rx processing : 305.0
|
||||
PUSCH inner-receiver : 117.0
|
||||
PUSCH decoding : 303.0
|
||||
Schedule Response : 25.0
|
||||
PUSCH inner-receiver : 150.0
|
||||
PUSCH decoding : 210.0
|
||||
Schedule Response : 20.0
|
||||
DL & UL scheduling timing : 10.0
|
||||
UL Indication : 34.0
|
||||
UL Indication : 30.0
|
||||
Threshold :
|
||||
feprx : 1.25
|
||||
feptx_prec : 1.25
|
||||
|
||||
@@ -1,51 +0,0 @@
|
||||
#!/bin/bash
|
||||
#/*
|
||||
# * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
|
||||
# * contributor license agreements. See the NOTICE file distributed with
|
||||
# * this work for additional information regarding copyright ownership.
|
||||
# * The OpenAirInterface Software Alliance licenses this file to You under
|
||||
# * the OAI Public License, Version 1.1 (the "License"); you may not use this file
|
||||
# * except in compliance with the License.
|
||||
# * You may obtain a copy of the License at
|
||||
# *
|
||||
# * http://www.openairinterface.org/?page_id=698
|
||||
# *
|
||||
# * Unless required by applicable law or agreed to in writing, software
|
||||
# * distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# * See the License for the specific language governing permissions and
|
||||
# * limitations under the License.
|
||||
# *-------------------------------------------------------------------------------
|
||||
# * For more information about the OpenAirInterface (OAI) Software Alliance:
|
||||
# * contact@openairinterface.org
|
||||
# */
|
||||
|
||||
function destroy_usage {
|
||||
echo "OAI CI VM script"
|
||||
echo " Original Author: Raphael Defosseux"
|
||||
echo " Requirements:"
|
||||
echo " -- uvtool uvtool-libvirt apt-cacher"
|
||||
echo ""
|
||||
echo "Usage:"
|
||||
echo "------"
|
||||
echo " oai-ci-vm-tool destroy [OPTIONS]"
|
||||
echo ""
|
||||
command_options_usage
|
||||
}
|
||||
|
||||
function destroy_vm {
|
||||
echo "############################################################"
|
||||
echo "OAI CI VM script"
|
||||
echo "############################################################"
|
||||
echo "VM_TEMPLATE = $VM_TEMPLATE"
|
||||
|
||||
LIST_CI_VM=`uvt-kvm list | grep $VM_TEMPLATE`
|
||||
|
||||
for CI_VM in $LIST_CI_VM
|
||||
do
|
||||
VM_IP_ADDR=`uvt-kvm ip $CI_VM`
|
||||
echo "VM to destroy: $CI_VM -- IP $VM_IP_ADDR"
|
||||
uvt-kvm destroy $CI_VM
|
||||
ssh-keygen -R $VM_IP_ADDR
|
||||
done
|
||||
}
|
||||
@@ -1,31 +0,0 @@
|
||||
<table style="border-collapse: collapse; border: none;">
|
||||
<tr style="border-collapse: collapse; border: none;">
|
||||
<td style="border-collapse: collapse; border: none;">
|
||||
<a href="http://www.openairinterface.org/">
|
||||
<img src="../../doc/images/oai_final_logo.png" alt="" border=3 height=50 width=150>
|
||||
</img>
|
||||
</a>
|
||||
</td>
|
||||
<td style="border-collapse: collapse; border: none; vertical-align: center;">
|
||||
<b><font size = "5">OAI CI Dev documentation</font></b>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
VM-based RF-Less Environment:
|
||||
|
||||
* [How to setup your test env](./vm_based_simulator_env.md)
|
||||
* [How to deal with OAI source files](./vm_based_simulator_sources.md)
|
||||
* [The main script](./vm_based_simulator_main_scripts.md)
|
||||
* [How to create one or several VM instances](./vm_based_simulator_create.md)
|
||||
* [How to build an OAI variant](./vm_based_simulator_build.md)
|
||||
* [How the build is checked](./vm_based_simulator_check_build.md)
|
||||
* [How to test an OAI variant](./vm_based_simulator_test.md)
|
||||
* [How to destroy all VM instances](./vm_based_simulator_destroy.md)
|
||||
|
||||
Currently missing documentation:
|
||||
* How to generate a build report
|
||||
* How to generate a test report
|
||||
|
||||
---
|
||||
|
||||
@@ -1,261 +0,0 @@
|
||||
<table style="border-collapse: collapse; border: none;">
|
||||
<tr style="border-collapse: collapse; border: none;">
|
||||
<td style="border-collapse: collapse; border: none;">
|
||||
<a href="http://www.openairinterface.org/">
|
||||
<img src="../../doc/images/oai_final_logo.png" alt="" border=3 height=50 width=150>
|
||||
</img>
|
||||
</a>
|
||||
</td>
|
||||
<td style="border-collapse: collapse; border: none; vertical-align: center;">
|
||||
<b><font size = "5">OAI CI Virtual-Machine-based Test Environment: build an OAI variant</font></b>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
**Table of Contents**
|
||||
|
||||
[[_TOC_]]
|
||||
|
||||
# 1. Introduction #
|
||||
|
||||
```bash
|
||||
$ cd /tmp/CI-raphael
|
||||
$ ls *.zip
|
||||
localZip.zip
|
||||
$ ./ci-scripts/oai-ci-vm-tool build --help
|
||||
OAI CI VM script
|
||||
Original Author: Raphael Defosseux
|
||||
Requirements:
|
||||
-- uvtool uvtool-libvirt apt-cacher
|
||||
-- xenial image already synced
|
||||
Default:
|
||||
-- eNB with USRP
|
||||
|
||||
Usage:
|
||||
------
|
||||
oai-ci-vm-tool build [OPTIONS]
|
||||
|
||||
Mandatory Options:
|
||||
--------
|
||||
--job-name #### OR -jn ####
|
||||
Specify the name of the Jenkins job.
|
||||
|
||||
--build-id #### OR -id ####
|
||||
Specify the build ID of the Jenkins job.
|
||||
|
||||
--workspace #### OR -ws ####
|
||||
Specify the workspace.
|
||||
|
||||
Options:
|
||||
--------
|
||||
# OpenAirInterface Build Variants
|
||||
--variant enb-usrp OR -v1 ( build and test )
|
||||
--variant phy-sim OR -v3 ( build and test )
|
||||
--variant cppcheck OR -v4 ( build and test )
|
||||
--variant gnb-usrp OR -v5 ( build and test )
|
||||
--variant nr-ue-usrp OR -v6 ( build and test )
|
||||
--variant enb-ethernet OR -v7 ( build and test )
|
||||
--variant ue-ethernet OR -v8 ( build and test )
|
||||
# non-OSA Build Variants
|
||||
--variant flexran-rtc OR -v10 ( build and test non-OSA )
|
||||
# OpenAirInterface Test Variants
|
||||
--variant l1-sim OR -v20 ( test )
|
||||
--variant rf-sim OR -v21 ( test )
|
||||
--variant l2-sim OR -v22 ( test )
|
||||
Specify the variant to build.
|
||||
|
||||
--keep-vm-alive OR -k
|
||||
Keep the VM alive after the build.
|
||||
|
||||
--daemon OR -D
|
||||
Run as daemon
|
||||
|
||||
--help OR -h
|
||||
Print this help message.
|
||||
```
|
||||
|
||||
# 2. Detailed Description #
|
||||
|
||||
Source file concerned: `ci-scripts/buildOnVM.sh`
|
||||
|
||||
## 2.1. build_on_vm function ##
|
||||
|
||||
* First check if the ZIP file is available and if the apt-cacher proxy configuration file is present. If not, it will stop.
|
||||
* Check if the VM instance is alive. If not, create it.
|
||||
* Once the VM is alive, retrieve the IP address with VM_IP_ADDR=`uvt-kvm ip $VM_NAME`
|
||||
* We copy the ZIP file to the VM : `scp localZip.zip ubuntu@$VM_IP_ADDR:/home/ubuntu`
|
||||
* apt-cacher proxy file: `scp etc/apt/apt.conf.d/01proxy ubuntu@$VM_IP_ADDR:/home/ubuntu`
|
||||
|
||||
Then we open a SSH session on the VM : `ssh ubuntu@$VM_IP_ADDR`
|
||||
|
||||
* We copy the apt-cacher proxy file to its destination space: `sudo cp 01proxy /etc/apt/apt.conf.d/`
|
||||
* We create an hush login file to eliminate the ssh opening session messages.
|
||||
* We unzip the ZIP file into `/home/ubuntu/tmp/` folder
|
||||
* and we work from there.
|
||||
|
||||
# 3. Typical Usage #
|
||||
|
||||
## 3.1. Build in the foreground, check the results and destroy the VM at the end ##
|
||||
|
||||
```bash
|
||||
$ cd /tmp/CI-raphael
|
||||
$ ls *.zip
|
||||
localZip.zip
|
||||
$ ./ci-scripts/oai-ci-vm-tool build --workspace /tmp/CI-raphael --job-name RAN-CI-develop --build-id 47 --variant enb-usrp
|
||||
############################################################
|
||||
OAI CI VM script
|
||||
############################################################
|
||||
VM_NAME = RAN-CI-develop-b47-enb-usrp
|
||||
VM_CMD_FILE = RAN-CI-develop-b47-enb-usrp_cmds.txt
|
||||
JENKINS_WKSP = /var/jenkins/workspace/RAN-CI-develop
|
||||
ARCHIVES_LOC = /var/jenkins/workspace/RAN-CI-develop/archives/enb_usrp
|
||||
BUILD_OPTIONS = --eNB -w USRP --mu
|
||||
VM_MEMORY = 2048 MBytes
|
||||
VM_CPU = 4
|
||||
############################################################
|
||||
Creating VM (RAN-CI-develop-b47-enb-usrp) on Ubuntu Cloud Image base
|
||||
############################################################
|
||||
Waiting for VM to be started
|
||||
Warning: Permanently added '192.168.122.2' (ECDSA) to the list of known hosts.
|
||||
RAN-CI-develop-b47-enb-usrp has for IP addr = 192.168.122.2
|
||||
############################################################
|
||||
Copying GIT repo into VM (RAN-CI-develop-b47-enb-usrp)
|
||||
############################################################
|
||||
Warning: Permanently added '192.168.122.2' (ECDSA) to the list of known hosts.
|
||||
############################################################
|
||||
Running install and build script on VM (RAN-CI-develop-b47-enb-usrp)
|
||||
############################################################
|
||||
Welcome to Ubuntu 16.04.6 LTS (GNU/Linux 4.4.0-145-generic x86_64)
|
||||
|
||||
* Documentation: https://help.ubuntu.com
|
||||
* Management: https://landscape.canonical.com
|
||||
* Support: https://ubuntu.com/advantage
|
||||
|
||||
Get cloud support with Ubuntu Advantage Cloud Guest:
|
||||
http://www.ubuntu.com/business/services/cloud
|
||||
|
||||
0 packages can be updated.
|
||||
0 updates are security updates.
|
||||
|
||||
New release '18.04.2 LTS' available.
|
||||
Run 'do-release-upgrade' to upgrade to it.
|
||||
|
||||
|
||||
sudo apt-get --yes --quiet install zip subversion libboost-dev
|
||||
unzip -qq -DD ../localZip.zip
|
||||
cd /home/ubuntu/tmp
|
||||
source oaienv
|
||||
cd cmake_targets
|
||||
./build_oai -I --eNB -w USRP --mu
|
||||
|
||||
# Here wait for a few minutes 8 to 12 minutes #
|
||||
|
||||
############################################################
|
||||
Creating a tmp folder to store results and artifacts
|
||||
############################################################
|
||||
############################################################
|
||||
Destroying VM
|
||||
############################################################
|
||||
# Host 192.168.122.2 found: line 19
|
||||
/home/eurecom/.ssh/known_hosts updated.
|
||||
Original contents retained as /home/eurecom/.ssh/known_hosts.old
|
||||
############################################################
|
||||
Checking build status
|
||||
############################################################
|
||||
STATUS seems OK
|
||||
```
|
||||
|
||||
If you are adding the `-k` or `--keep-vm-alive` option, the VM instance will not be destroyed and you explore what happenned.
|
||||
|
||||
## 3.2. Build in the background ##
|
||||
|
||||
This is how it is done in the CI master job pipeline.
|
||||
|
||||
```bash
|
||||
$ cd /tmp/CI-raphael
|
||||
$ ls *.zip
|
||||
localZip.zip
|
||||
$ ./ci-scripts/oai-ci-vm-tool build --workspace /tmp/CI-raphael --job-name RAN-CI-develop --build-id 47 --variant phy-sim --daemon
|
||||
12:44:24 ############################################################
|
||||
12:44:24 OAI CI VM script
|
||||
12:44:24 ############################################################
|
||||
12:44:24 VM_NAME = RAN-CI-develop-b47-phy-sim
|
||||
12:44:24 VM_CMD_FILE = RAN-CI-develop-b47-phy-sim_cmds.txt
|
||||
12:44:24 JENKINS_WKSP = /var/jenkins/workspace/RAN-CI-develop
|
||||
12:44:24 ARCHIVES_LOC = /var/jenkins/workspace/RAN-CI-develop/archives/phy_sim
|
||||
12:44:24 BUILD_OPTIONS = --phy_simulators
|
||||
12:44:24 VM_MEMORY = 2048 MBytes
|
||||
12:44:24 VM_CPU = 4
|
||||
12:44:24 ############################################################
|
||||
12:44:24 Creating VM (RAN-CI-develop-b47-phy-sim) on Ubuntu Cloud Image base
|
||||
12:44:24 ############################################################
|
||||
12:44:27 Waiting for VM to be started
|
||||
12:46:34 Warning: Permanently added '192.168.122.220' (ECDSA) to the list of known hosts.
|
||||
12:46:34 RAN-CI-develop-b47-phy-sim has for IP addr = 192.168.122.220
|
||||
12:46:34 ############################################################
|
||||
12:46:34 Copying GIT repo into VM (RAN-CI-develop-b47-phy-sim)
|
||||
12:46:34 ############################################################
|
||||
12:46:34 Warning: Permanently added '192.168.122.220' (ECDSA) to the list of known hosts.
|
||||
12:46:34 ############################################################
|
||||
12:46:34 Running install and build script on VM (RAN-CI-develop-b47-phy-sim)
|
||||
12:46:34 ############################################################
|
||||
12:46:34 Welcome to Ubuntu 16.04.6 LTS (GNU/Linux 4.4.0-145-generic x86_64)
|
||||
12:46:34
|
||||
12:46:34 * Documentation: https://help.ubuntu.com
|
||||
12:46:34 * Management: https://landscape.canonical.com
|
||||
12:46:34 * Support: https://ubuntu.com/advantage
|
||||
12:46:34
|
||||
12:46:34 Get cloud support with Ubuntu Advantage Cloud Guest:
|
||||
12:46:34 http://www.ubuntu.com/business/services/cloud
|
||||
12:46:34
|
||||
12:46:34 0 packages can be updated.
|
||||
12:46:34 0 updates are security updates.
|
||||
12:46:34
|
||||
12:46:34 New release '18.04.2 LTS' available.
|
||||
12:46:34 Run 'do-release-upgrade' to upgrade to it.
|
||||
12:46:34
|
||||
12:46:34
|
||||
12:46:34 sudo apt-get --yes --quiet install zip daemon subversion libboost-dev
|
||||
12:46:46 unzip -qq -DD ../localZip.zip
|
||||
12:46:48 source oaienv
|
||||
12:46:48 sudo -E daemon --inherit --unsafe --name=build_daemon --chdir=/home/ubuntu/tmp/cmake_targets -o /home/ubuntu/tmp/cmake_targets/log/install-build.txt ./my-vm-build.sh
|
||||
12:46:48 STATUS seems OK
|
||||
```
|
||||
|
||||
So here is 2.5 minutes, a VM was created, source files copied and the build process is started in the background.
|
||||
|
||||
```bash
|
||||
$ cd /tmp/raphael
|
||||
$ ./ci-scripts/oai-ci-vm-tool wait --workspace /var/jenkins/workspace/RAN-CI-develop --variant phy-sim --job-name RAN-CI-develop --build-id 47 --keep-vm-alive
|
||||
12:49:14 ############################################################
|
||||
12:49:14 OAI CI VM script
|
||||
12:49:14 ############################################################
|
||||
12:49:14 VM_NAME = RAN-CI-develop-b47-phy-sim
|
||||
12:49:14 VM_CMD_FILE = RAN-CI-develop-b47-phy-sim_cmds.txt
|
||||
12:49:14 JENKINS_WKSP = /var/jenkins/workspace/RAN-CI-develop
|
||||
12:49:14 ARCHIVES_LOC = /var/jenkins/workspace/RAN-CI-develop/archives/phy_sim
|
||||
12:49:14 BUILD_OPTIONS = --phy_simulators
|
||||
12:49:15 Waiting for VM to be started
|
||||
12:49:15 Warning: Permanently added '192.168.122.220' (ECDSA) to the list of known hosts.
|
||||
12:49:16 RAN-CI-develop-b47-phy-sim has for IP addr = 192.168.122.220
|
||||
12:49:16 ############################################################
|
||||
12:49:16 Waiting build process to end on VM (RAN-CI-develop-b47-phy-sim)
|
||||
12:49:16 ############################################################
|
||||
12:49:16 ps -aux | grep build
|
||||
12:54:23 ############################################################
|
||||
12:54:23 Creating a tmp folder to store results and artifacts
|
||||
12:54:23 ############################################################
|
||||
12:54:23 ############################################################
|
||||
12:54:23 Checking build status
|
||||
12:54:23 ############################################################
|
||||
12:54:23 STATUS seems OK
|
||||
```
|
||||
|
||||
Here the `--keep-vm-alive` option is used to keep the VM alive and performs some testing.
|
||||
|
||||
---
|
||||
|
||||
Next step: [how the build is checked](./vm_based_simulator_check_build.md)
|
||||
|
||||
You can also go back to the [CI dev main page](./ci_dev_home.md)
|
||||
|
||||
@@ -1,44 +0,0 @@
|
||||
<table style="border-collapse: collapse; border: none;">
|
||||
<tr style="border-collapse: collapse; border: none;">
|
||||
<td style="border-collapse: collapse; border: none;">
|
||||
<a href="http://www.openairinterface.org/">
|
||||
<img src="../../doc/images/oai_final_logo.png" alt="" border=3 height=50 width=150>
|
||||
</img>
|
||||
</a>
|
||||
</td>
|
||||
<td style="border-collapse: collapse; border: none; vertical-align: center;">
|
||||
<b><font size = "5">OAI CI Virtual-Machine-based Test Environment: checking the build result</font></b>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
**Table of Contents**
|
||||
|
||||
[[_TOC_]]
|
||||
|
||||
# 1. Introduction #
|
||||
|
||||
Function is called:
|
||||
|
||||
- when building in foreground
|
||||
- when waiting for the background build process is finished
|
||||
|
||||
# 2. Detailed Description #
|
||||
|
||||
Source file concerned: `ci-scripts/waitBuildOnVM.sh`
|
||||
|
||||
## 2.1. check_on_vm_build function ##
|
||||
|
||||
* Retrieve the build log files from the VM instance `ubuntu@$VM_IP_ADDR:/home/ubuntu/tmp/cmake_targets/log/*.txt`
|
||||
* and copy them locally in the workspace at $ARCHIVES_LOC
|
||||
* List all log files that match the pattern. Each should have
|
||||
* the `Built target` pattern (the library/executable SHALL link)
|
||||
* Evaluate the remaining space on VM disk
|
||||
* The number of patterned log files SHALL match $NB_PATTERN_FILES defined in `ci-scripts/oai-ci-vm-tool` script for the variant
|
||||
|
||||
---
|
||||
|
||||
Next step: [how to test a function](./vm_based_simulator_test.md)
|
||||
|
||||
You can also go back to the [CI dev main page](./ci_dev_home.md)
|
||||
|
||||
@@ -1,110 +0,0 @@
|
||||
<table style="border-collapse: collapse; border: none;">
|
||||
<tr style="border-collapse: collapse; border: none;">
|
||||
<td style="border-collapse: collapse; border: none;">
|
||||
<a href="http://www.openairinterface.org/">
|
||||
<img src="../../doc/images/oai_final_logo.png" alt="" border=3 height=50 width=150>
|
||||
</img>
|
||||
</a>
|
||||
</td>
|
||||
<td style="border-collapse: collapse; border: none; vertical-align: center;">
|
||||
<b><font size = "5">OAI CI Virtual-Machine-based Test Environment: create a VM instance</font></b>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
**Table of Contents**
|
||||
|
||||
[[_TOC_]]
|
||||
|
||||
# 1. Introduction #
|
||||
|
||||
```bash
|
||||
$ cd /tmp/CI-raphael
|
||||
$ ./ci-scripts/oai-ci-vm-tool create --help
|
||||
OAI CI VM script
|
||||
Original Author: Raphael Defosseux
|
||||
Requirements:
|
||||
-- uvtool uvtool-libvirt apt-cacher
|
||||
-- xenial image already synced
|
||||
Default:
|
||||
-- eNB with USRP
|
||||
|
||||
Usage:
|
||||
------
|
||||
oai-ci-vm-tool create [OPTIONS]
|
||||
|
||||
Mandatory Options:
|
||||
--------
|
||||
--job-name #### OR -jn ####
|
||||
Specify the name of the Jenkins job.
|
||||
|
||||
--build-id #### OR -id ####
|
||||
Specify the build ID of the Jenkins job.
|
||||
|
||||
# OpenAirInterface Build Variants
|
||||
--variant enb-usrp OR -v1 ( build and test )
|
||||
--variant phy-sim OR -v3 ( build and test )
|
||||
--variant cppcheck OR -v4 ( build and test )
|
||||
--variant gnb-usrp OR -v5 ( build and test )
|
||||
--variant nr-ue-usrp OR -v6 ( build and test )
|
||||
--variant enb-ethernet OR -v7 ( build and test )
|
||||
--variant ue-ethernet OR -v8 ( build and test )
|
||||
# non-OSA Build Variants
|
||||
--variant flexran-rtc OR -v10 ( build and test non-OSA )
|
||||
# OpenAirInterface Test Variants
|
||||
--variant l1-sim OR -v20 ( test )
|
||||
--variant rf-sim OR -v21 ( test )
|
||||
--variant l2-sim OR -v22 ( test )
|
||||
Specify the variant to build.
|
||||
|
||||
--help OR -h
|
||||
Print this help message.
|
||||
```
|
||||
|
||||
# 2. Detailed Description #
|
||||
|
||||
Source file concerned: `ci-scripts/createVM.sh`
|
||||
|
||||
## 2.1. create_vm function ##
|
||||
|
||||
This is the function that is being called from the main oai-vm-tool script.
|
||||
|
||||
The main purpose is to start a VM instance:
|
||||
|
||||
```bash
|
||||
uvt-kvm create $VM_NAME release=xenial --memory $VM_MEMORY --cpu $VM_CPU --disk $VM_DISK --unsafe-caching --template ci-scripts/template-host.xml
|
||||
```
|
||||
|
||||
Variables are set in the main script based on the options.
|
||||
|
||||
`--unsafe-caching` option is used because our VM instances are throw-away's.
|
||||
|
||||
`--template ci-scripts/template-host.xml` is used to duplicate the CPU properties to the VM instance. **VERY IMPORTANT to build OAI**
|
||||
|
||||
## 2.2. Lock / Unlock functions ##
|
||||
|
||||
There are `acquire_vm_create_lock` and `release_vm_create_lock` functions.
|
||||
|
||||
Creating Virtual Machines instances in parallel **creates a lot of stress** on the host server HW. If you launch creations in parallel (Jenkins pipeline could do it) or you are several people working on the same host server, this mechanism atomizes the creation process and wait until the previous VM creation is finished.
|
||||
|
||||
# 3. Typical Usage #
|
||||
|
||||
```bash
|
||||
$ cd /tmp/CI-raphael
|
||||
$ ./ci-scripts/oai-ci-vm-tool create --job-name raphael --build-id 1 --variant phy-sim
|
||||
# or a more **unique approach**
|
||||
$ ./ci-scripts/oai-ci-vm-tool create -jn toto -id 1 -v2
|
||||
```
|
||||
|
||||
The Jenkins pipeline uses the master job name as `job-name` option and the job-build ID.
|
||||
|
||||
Try to be unique if you are several developers working on the same host server.
|
||||
|
||||
Finally, typically I never use the `create` command. I use directly the build command that checks if VM is created and if not, will create it. See next step.
|
||||
|
||||
---
|
||||
|
||||
Next step: [how to build an OAI variant](./vm_based_simulator_build.md)
|
||||
|
||||
You can also go back to the [CI dev main page](./ci_dev_home.md)
|
||||
|
||||
@@ -1,69 +0,0 @@
|
||||
<table style="border-collapse: collapse; border: none;">
|
||||
<tr style="border-collapse: collapse; border: none;">
|
||||
<td style="border-collapse: collapse; border: none;">
|
||||
<a href="http://www.openairinterface.org/">
|
||||
<img src="../../doc/images/oai_final_logo.png" alt="" border=3 height=50 width=150>
|
||||
</img>
|
||||
</a>
|
||||
</td>
|
||||
<td style="border-collapse: collapse; border: none; vertical-align: center;">
|
||||
<b><font size = "5">OAI CI Virtual-Machine-based Test Environment: Properly Destroy all VM instances</font></b>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
**Table of Contents**
|
||||
|
||||
[[_TOC_]]
|
||||
|
||||
# 1. Introduction #
|
||||
|
||||
```bash
|
||||
$ cd /tmp/CI-raphael
|
||||
$ ./ci-scripts/oai-ci-vm-tool destroy --help
|
||||
OAI CI VM script
|
||||
Original Author: Raphael Defosseux
|
||||
Requirements:
|
||||
-- uvtool uvtool-libvirt apt-cacher
|
||||
|
||||
Usage:
|
||||
------
|
||||
oai-ci-vm-tool destroy [OPTIONS]
|
||||
|
||||
Mandatory Options:
|
||||
--------
|
||||
--job-name #### OR -jn ####
|
||||
Specify the name of the Jenkins job.
|
||||
|
||||
--build-id #### OR -id ####
|
||||
Specify the build ID of the Jenkins job.
|
||||
|
||||
Options:
|
||||
--------
|
||||
--help OR -h
|
||||
Print this help message.
|
||||
```
|
||||
|
||||
# 2. Detailed Description #
|
||||
|
||||
Source file concerned: `ci-scripts/destroyAllRunningVM.sh`
|
||||
|
||||
## 2.1. destroy_vm function ##
|
||||
|
||||
This is the function that is being called from the main oai-vm-tool script.
|
||||
|
||||
The main purpose is to destroy all VM instances whose name matches a pattern.
|
||||
|
||||
It also cleans up the `.ssh/known_hosts` file.
|
||||
|
||||
# 3. Typical Usage #
|
||||
|
||||
```bash
|
||||
$ cd /tmp/CI-raphael
|
||||
$ ./ci-scripts/oai-ci-vm-tool destroy --job-name raphael --build-id 1
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
You can go back to the [CI dev main page](./ci_dev_home.md)
|
||||
|
||||
@@ -1,119 +0,0 @@
|
||||
<table style="border-collapse: collapse; border: none;">
|
||||
<tr style="border-collapse: collapse; border: none;">
|
||||
<td style="border-collapse: collapse; border: none;">
|
||||
<a href="http://www.openairinterface.org/">
|
||||
<img src="../../doc/images/oai_final_logo.png" alt="" border=3 height=50 width=150>
|
||||
</img>
|
||||
</a>
|
||||
</td>
|
||||
<td style="border-collapse: collapse; border: none; vertical-align: center;">
|
||||
<b><font size = "5">OAI CI Virtual-Machine-based Simulator Test Environment</font></b>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
**Table of Contents**
|
||||
|
||||
[[_TOC_]]
|
||||
|
||||
# 1. Introduction #
|
||||
|
||||
This document explains how the master pipeline works and how any developer could contribute to add testing.
|
||||
|
||||
It is an extension to the wiki [page](https://gitlab.eurecom.fr/oai/openairinterface5g/wikis/ci/enb-master-job).
|
||||
|
||||
The purpose of this master pipeline is to:
|
||||
|
||||
* Validate that a Merge Request is mergeable
|
||||
* Validate that a Merge Request is following coding guidelines
|
||||
* Validate that a Merge Request is not breaking any typical build variant
|
||||
* Validate that a Merge Request is not breaking any legacy simulator-based test
|
||||
|
||||
We will mainly focused on the 2 last items.
|
||||
|
||||
Last point, this documentation is valid for all CI-supported branches:
|
||||
|
||||
* `master`
|
||||
* `develop`
|
||||
|
||||
But the feature set may not be aligned. **The principles still apply.**
|
||||
|
||||
# 2. Prerequisites #
|
||||
|
||||
Some details are available on this wiki [section](https://gitlab.eurecom.fr/oai/openairinterface5g/wikis/ci/enb-ci-architecture#22-pipeline-executor).
|
||||
|
||||
Currently we have a host server (`bellatrix`) with the current parameters:
|
||||
|
||||
* 40 x Intel(R) Xeon(R) CPU E5-2640 v4 @ 2.40GHz
|
||||
* 64 Gbytes RAM
|
||||
* Ubuntu 16.04.3 LTS (xenial)
|
||||
|
||||
For you to replicate this environment, you need a strong server:
|
||||
|
||||
* At least 16 cores
|
||||
* Ubuntu 16 (xenial) or higher (such as bionic, not tested)
|
||||
|
||||
Also we are using a Virtual Machine (VM for the rest of document) based strategy for the moment.
|
||||
|
||||
So you need to install 2 tools:
|
||||
|
||||
* uvt-kvm
|
||||
* apt-cacher
|
||||
|
||||
We are planning to also add:
|
||||
|
||||
* A Red Hat Linux Entreprise 7.6 host environment
|
||||
* A Container-based strategy (such as Docket and Kubernetes)
|
||||
|
||||
## 2.1. uvtool installation ##
|
||||
|
||||
```bash
|
||||
$ sudo apt-get install uvtool
|
||||
# if you don't have already, create an ssh key
|
||||
$ ssh-keygen -b 2048
|
||||
# retrieve an image
|
||||
$ sudo uvt-simplestreams-libvirt sync arch=amd64 release=xenial
|
||||
# we might soon switch to an Ubuntu 18.04 version
|
||||
$ sudo uvt-simplestreams-libvirt sync arch=amd64 release=bionic
|
||||
$ uvt-simplestreams-libvirt query
|
||||
release=bionic arch=amd64 label=release (20190402)
|
||||
release=xenial arch=amd64 label=release (20190406)
|
||||
```
|
||||
|
||||
On our server, I don't update (sync) that often (every 2-4 months).
|
||||
|
||||
For more details:
|
||||
|
||||
* uvtool syntax is [here](http://manpages.ubuntu.com/manpages/trusty/man1/uvt-kvm.1.html)
|
||||
* more readable tutorial is [here](https://help.ubuntu.com/lts/serverguide/cloud-images-and-uvtool.html)
|
||||
|
||||
## 2.2. apt-cacher-server installation ##
|
||||
|
||||
I recommend to follow to the letter this [tutorial](https://help.ubuntu.com/community/Apt-Cacher-Server).
|
||||
|
||||
The reason: we are creating/using/destroying a lot of VM instances and we are always installing the same packages.
|
||||
This service allows to cache on the host and, doing so, **decreases the pressure on your internet bandwith usage**.
|
||||
It also optimizes time at build stage.
|
||||
|
||||
```bash
|
||||
$ sudo apt-get install apt-cacher apache2
|
||||
$ sudo vi /etc/default/apt-cache
|
||||
$ sudo service apache2 restart
|
||||
|
||||
# Server configuration
|
||||
$ sudo vi /etc/apt-cacher/apt-cacher.conf
|
||||
--> allowed_hosts = *
|
||||
--> fix the installer_files_regexp
|
||||
$ sudo vi /etc/apt/apt.conf.d/01proxy
|
||||
--> add `Acquire::http::Proxy "http://<IP address or hostname of the apt-cacher server>:3142";`
|
||||
$ sudo service apt-cacher restart
|
||||
```
|
||||
|
||||
This last file (/etc/apt/apt.conf.d/01proxy) is very important since it is tested in any CI script.
|
||||
|
||||
---
|
||||
|
||||
We can now switch to the next step: [how to deal with oai sources](./vm_based_simulator_sources.md)
|
||||
|
||||
You can also go back to the [CI dev main page](./ci_dev_home.md)
|
||||
|
||||
@@ -1,188 +0,0 @@
|
||||
<table style="border-collapse: collapse; border: none;">
|
||||
<tr style="border-collapse: collapse; border: none;">
|
||||
<td style="border-collapse: collapse; border: none;">
|
||||
<a href="http://www.openairinterface.org/">
|
||||
<img src="../../doc/images/oai_final_logo.png" alt="" border=3 height=50 width=150>
|
||||
</img>
|
||||
</a>
|
||||
</td>
|
||||
<td style="border-collapse: collapse; border: none; vertical-align: center;">
|
||||
<b><font size = "5">OAI CI Virtual-Machine-based Test Environment: the Main Script</font></b>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
**Table of Contents**
|
||||
|
||||
[[_TOC_]]
|
||||
|
||||
# 1. Introduction #
|
||||
|
||||
The file name is `./ci-scripts/oai-ci-vm-tool` from the workspace root.
|
||||
|
||||
```bash
|
||||
$ cd /tmp/CI-raphael
|
||||
$ ./ci-scripts/oai-ci-vm-tool --help
|
||||
OAI CI VM script
|
||||
Original Author: Raphael Defosseux
|
||||
Requirements:
|
||||
-- uvtool uvtool-libvirt apt-cacher
|
||||
-- xenial image already synced
|
||||
|
||||
Usage:
|
||||
------
|
||||
oai-ci-vm-tool (-h|--help) {create,destroy,build,wait,test,report-build,report-test} ...
|
||||
|
||||
```
|
||||
|
||||
This is a **BASH** script.
|
||||
|
||||
|
||||
# 2. Sub BASH scripts #
|
||||
|
||||
The main script is including a bunch of sub BASH scripts.
|
||||
|
||||
* ci-scripts/createVM.sh
|
||||
* ci-scripts/buildOnVM.sh
|
||||
* ci-scripts/waitBuildOnVM.sh
|
||||
* ci-scripts/destroyAllRunningVM.sh
|
||||
* ci-scripts/runTestOnVM.sh
|
||||
* ci-scripts/reportBuildLocally.sh
|
||||
* ci-scripts/reportTestLocally.sh
|
||||
|
||||
**NOTE: ci-scripts/runTestOnVM.sh is getting big and will certainly be split to facilitate maintenance. Start functions will be also factorized.**
|
||||
|
||||
# 3. Main script features #
|
||||
|
||||
The main purpose of the main script is decipher the options and launch the requested function.
|
||||
|
||||
It is also **testing if uvtool and apt-cacher are installed.**
|
||||
|
||||
It finally provides parameters to the requested functions. Parameter definition is centralized there.
|
||||
|
||||
For example:
|
||||
|
||||
for VM instance creation:
|
||||
|
||||
* the instance name: VM_NAME
|
||||
* the RAM and number of CPUs: VM_MEMORY, VM_CPU
|
||||
|
||||
for OAI variant build:
|
||||
|
||||
* build options: BUILD_OPTIONS
|
||||
* build log file to parse: LOG_PATTERN
|
||||
* the number of log files to parse: NB_PATTERN_FILES
|
||||
|
||||
You can get the list of variant specific variables specifying the variant argument when asking for help:
|
||||
|
||||
``` bash
|
||||
./ci-scripts/oai-ci-vm-tool help variant
|
||||
--variant flexran-rtc OR -v10 ( build and test non-OSA )
|
||||
VM_NAME=ci-flexran-rtc ARCHIVES_LOC=flexran
|
||||
VM_MEMORY=2048 VM_CPU=4
|
||||
NB_PATTERN_FILES=1 BUILD_OPTIONS="cmake . && make -j2"
|
||||
LOG_PATTERN=.txt
|
||||
|
||||
--variant enb-usrp OR -v1 ( build and test )
|
||||
VM_NAME=ci-enb-usrp ARCHIVES_LOC=enb_usrp
|
||||
VM_MEMORY=2048 VM_CPU=4
|
||||
NB_PATTERN_FILES=9 BUILD_OPTIONS="--eNB -w USRP --mu"
|
||||
LOG_PATTERN=.txt
|
||||
|
||||
--variant l1-sim OR -v20 ( test )
|
||||
VM_NAME=ci-l1-sim ARCHIVES_LOC=l1_sim
|
||||
VM_MEMORY=2048 VM_CPU=4
|
||||
NB_PATTERN_FILES=9 BUILD_OPTIONS=""
|
||||
LOG_PATTERN=.txt
|
||||
|
||||
--variant rf-sim OR -v21 ( test )
|
||||
VM_NAME=ci-rf-sim ARCHIVES_LOC=rf_sim
|
||||
VM_MEMORY=2048 VM_CPU=4
|
||||
NB_PATTERN_FILES=9 BUILD_OPTIONS=""
|
||||
LOG_PATTERN=.txt
|
||||
|
||||
--variant l2-sim OR -v22 ( test )
|
||||
VM_NAME=ci-l2-sim ARCHIVES_LOC=l2_sim
|
||||
VM_MEMORY=2048 VM_CPU=4
|
||||
NB_PATTERN_FILES=9 BUILD_OPTIONS=""
|
||||
LOG_PATTERN=.txt
|
||||
|
||||
--variant phy-sim OR -v3 ( build and test )
|
||||
VM_NAME=ci-phy-sim ARCHIVES_LOC=phy_sim
|
||||
VM_MEMORY=2048 VM_CPU=4
|
||||
NB_PATTERN_FILES=3 BUILD_OPTIONS="--phy_simulators"
|
||||
LOG_PATTERN=.txt
|
||||
|
||||
--variant cppcheck OR -v4 ( build and test )
|
||||
VM_NAME=ci-cppcheck ARCHIVES_LOC=cppcheck
|
||||
VM_MEMORY=4096 VM_CPU=4
|
||||
NB_PATTERN_FILES=1 BUILD_OPTIONS="--enable=warning --force --xml --xml-version=2 --suppressions-list=ci-scripts/cppcheck_suppressions.list -I common/utils -j4"
|
||||
LOG_PATTERN=cppcheck.xml
|
||||
|
||||
--variant enb-ethernet OR -v7 ( build and test )
|
||||
VM_NAME=ci-enb-ethernet ARCHIVES_LOC=enb_eth
|
||||
VM_MEMORY=4096 VM_CPU=4
|
||||
NB_PATTERN_FILES=8 BUILD_OPTIONS="--eNB"
|
||||
LOG_PATTERN=.txt
|
||||
|
||||
--variant ue-ethernet OR -v8 ( build and test )
|
||||
VM_NAME=ci-ue-ethernet ARCHIVES_LOC=ue_eth
|
||||
VM_MEMORY=4096 VM_CPU=4
|
||||
NB_PATTERN_FILES=12 BUILD_OPTIONS="--UE"
|
||||
LOG_PATTERN=.txt
|
||||
|
||||
```
|
||||
|
||||
To define a new variant you just need to define a function which name conforms to `function variant__v<n>__<variant_name>` where n and variant_name will respectively define the short and long options for your variant. The function only needs to define the variant dependent variables. For many variables, default values are set in the `check_set_variant` function. When a variant doesn't define the BUILD_OPTIONS variable it cannot be used for the `build` `wait` and `create` commands.
|
||||
|
||||
The main scripts also allows the definition of non variant-dependant variable via the `--setvar_<variable name> <variable value>` options.
|
||||
You can get the list of these variables by using `help setvar`:
|
||||
|
||||
```BASH
|
||||
./ci-scripts/oai-ci-vm-tool help setvar
|
||||
--setvar_<varname> <value> where varname is one of:
|
||||
VM_OSREL : OS release to use in virtual machines
|
||||
RUN_EXPERIMENTAL : Enforce execution of variants with EXPERIMENTAL variable set to "true"
|
||||
```
|
||||
|
||||
To add a new non-variant dependant variable you need:
|
||||
* Add an item to the `AUTHORIZED_VAR` array
|
||||
* In the `setvar_usage`function, add your help string in the HELP_VAR["<your variable name>"] variable.
|
||||
* Write the bash code for your variable.
|
||||
|
||||
Example of non variant dependent usage:
|
||||
|
||||
``` bash
|
||||
./ci-scripts/oai-ci-vm-tool test -v21 -ws /usr/local/oai/enhance_CI_extEPC/openairinterface5g -id 1 -jn testci
|
||||
Currently testci-b1-rf-sim Testing is not implemented / enabled
|
||||
Comment out these lines in ./ci-scripts/oai-ci-vm-tool if you want to run it
|
||||
or use option --setvar_RUN_EXPERIMENTAL=true to test it
|
||||
|
||||
|
||||
./ci-scripts/oai-ci-vm-tool test -v21 -ws /usr/local/oai/enhance_CI_extEPC/openairinterface5g -id 1 -jn testci --setvar_RUN_EXPERIMENTAL true
|
||||
Setting RUN_EXPERIMENTAL to true...
|
||||
############################################################
|
||||
OAI CI VM script
|
||||
############################################################
|
||||
ENB_VM_NAME = testci-b1-enb-ethernet
|
||||
ENB_VM_CMD_FILE = testci-b1-enb-ethernet_cmds.txt
|
||||
UE_VM_NAME = testci-b1-ue-ethernet
|
||||
UE_VM_CMD_FILE = testci-b1-ue-ethernet_cmds.txt
|
||||
JENKINS_WKSP = /usr/local/oai/enhance_CI_extEPC/openairinterface5g
|
||||
ARCHIVES_LOC = /usr/local/oai/enhance_CI_extEPC/openairinterface5g/archives/rf_sim/test
|
||||
############################################################
|
||||
Waiting for ENB VM to be started
|
||||
...........................
|
||||
```
|
||||
|
||||
In the same way, you can set the variable `VM_OSREL` to run the test in virtual machines of the specified OS release:
|
||||
|
||||
``` bash
|
||||
./ci-scripts/oai-ci-vm-tool test -v21 -ws /usr/local/oai/enhance_CI_extEPC/openairinterface5g -id 1 -jn testci --setvar_VM_OSREL bionic
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
Next step: [how to create one or several VM instances](./vm_based_simulator_create.md)
|
||||
|
||||
You can also go back to the [CI dev main page](./ci_dev_home.md)
|
||||
@@ -1,83 +0,0 @@
|
||||
<table style="border-collapse: collapse; border: none;">
|
||||
<tr style="border-collapse: collapse; border: none;">
|
||||
<td style="border-collapse: collapse; border: none;">
|
||||
<a href="http://www.openairinterface.org/">
|
||||
<img src="../../doc/images/oai_final_logo.png" alt="" border=3 height=50 width=150>
|
||||
</img>
|
||||
</a>
|
||||
</td>
|
||||
<td style="border-collapse: collapse; border: none; vertical-align: center;">
|
||||
<b><font size = "5">OAI CI Virtual-Machine-based Simulator OAI source management</font></b>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
**Table of Contents**
|
||||
|
||||
[[_TOC_]]
|
||||
|
||||
# 1. Introduction #
|
||||
|
||||
The idea of this section is to optimize/uniform source management for several VM instances.
|
||||
|
||||
If we were cloning the same repository in each VM we are creating, we would put so much pressure on the central GitLab repository.
|
||||
|
||||
The solution:
|
||||
|
||||
* clone/fetch on a given clean workspace and tar/zip only the source files without any artifacts.
|
||||
* we then copy the tar/zip file to each VM instance
|
||||
* and within each VM instance, unzip
|
||||
|
||||
# 2. Centralized Workspace #
|
||||
|
||||
You can create a brand new workspace by cloning:
|
||||
|
||||
```bash
|
||||
$ mkdir /tmp/CI-raphael
|
||||
$ cd /tmp/CI-raphael
|
||||
$ git clone https://gitlab.eurecom.fr/oai/openairinterface5g.git .
|
||||
$ git checkout develop
|
||||
```
|
||||
|
||||
You can also use your current cloned workspace and any `develop`-based branch.
|
||||
|
||||
```bash
|
||||
$ cd /home/raphael/openairinterface5g
|
||||
$ git fetch
|
||||
$ git checkout develop-improved-documentation
|
||||
# CAUTION: the following command will remove any file that has not already been added to GIT
|
||||
$ sudo git clean -x -d -ff
|
||||
$ git status
|
||||
On branch develop-improved-documentation
|
||||
Your branch is up-to-date with 'origin/develop-improved-documentation'.
|
||||
nothing to commit, working directory clean
|
||||
```
|
||||
|
||||
You can also have modified files.
|
||||
|
||||
**The main point is to have NO ARTIFACTS from a previous build in your workspace.**
|
||||
|
||||
Last point, the workspace folder name is not necesseraly `openairinterface5g`. But all the following commands will be run for the root of the workspace.
|
||||
|
||||
For clarity, I will always use `/tmp/CI-raphael` as $WORKSPACE.
|
||||
|
||||
# 3. Create the ZIP file #
|
||||
|
||||
```bash
|
||||
# go to root of workspace
|
||||
$ cd /tmp/CI-raphael
|
||||
$ zip -r -qq localZip.zip .
|
||||
```
|
||||
|
||||
The **Jenkins Pipeline** performs automatically these operations.
|
||||
|
||||
In addition, in case of a merge request, it tries to merge with the target branch and might create a dummy local commit.
|
||||
|
||||
See [section](https://gitlab.eurecom.fr/oai/openairinterface5g/wikis/ci/enb-master-job#32-verify-guidelines-stage)
|
||||
|
||||
---
|
||||
|
||||
Next step: [the main scripts](./vm_based_simulator_main_scripts.md)
|
||||
|
||||
You can also go back to the [CI dev main page](./ci_dev_home.md)
|
||||
|
||||
@@ -1,197 +0,0 @@
|
||||
<table style="border-collapse: collapse; border: none;">
|
||||
<tr style="border-collapse: collapse; border: none;">
|
||||
<td style="border-collapse: collapse; border: none;">
|
||||
<a href="http://www.openairinterface.org/">
|
||||
<img src="../../doc/images/oai_final_logo.png" alt="" border=3 height=50 width=150>
|
||||
</img>
|
||||
</a>
|
||||
</td>
|
||||
<td style="border-collapse: collapse; border: none; vertical-align: center;">
|
||||
<b><font size = "5">OAI CI Virtual-Machine-based Test Environment: Testing an OAI variant</font></b>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
**Table of Contents**
|
||||
|
||||
[[_TOC_]]
|
||||
|
||||
# 1. Introduction #
|
||||
|
||||
Currently 1 build variant can be directly tested:
|
||||
|
||||
* Physical Simulators
|
||||
|
||||
In addition, 2 build variants are used:
|
||||
|
||||
* OAI eNB with ETHERNET transport
|
||||
* OAI UE with ETHERNET transport
|
||||
|
||||
for the following scenarios:
|
||||
|
||||
* L1 simulator w/ a channel simulator (NOT IMPLEMENTED)
|
||||
* RF simulator : (IMPLEMENTED but not working as of 2019.w15)
|
||||
* L2 nFAPI simulator
|
||||
|
||||
Tests are run sequentially in the Jenkins pipeline because:
|
||||
|
||||
* We want to mutualize the VM creation for an EPC
|
||||
* We have seen performance issues when running in parallel.
|
||||
|
||||
|
||||
```bash
|
||||
./ci-scripts/oai-ci-vm-tool test --help
|
||||
OAI CI VM script
|
||||
Original Author: Raphael Defosseux
|
||||
Requirements:
|
||||
-- uvtool uvtool-libvirt apt-cacher
|
||||
-- xenial image already synced
|
||||
Default:
|
||||
-- eNB with USRP
|
||||
|
||||
Usage:
|
||||
------
|
||||
oai-ci-vm-tool test [OPTIONS]
|
||||
|
||||
Options:
|
||||
--------
|
||||
--job-name #### OR -jn ####
|
||||
Specify the name of the Jenkins job.
|
||||
|
||||
--build-id #### OR -id ####
|
||||
Specify the build ID of the Jenkins job.
|
||||
|
||||
--workspace #### OR -ws ####
|
||||
Specify the workspace.
|
||||
|
||||
# OpenAirInterface Build Variants
|
||||
--variant enb-usrp OR -v1 ( build and test )
|
||||
--variant phy-sim OR -v3 ( build and test )
|
||||
--variant cppcheck OR -v4 ( build and test )
|
||||
--variant gnb-usrp OR -v5 ( build and test )
|
||||
--variant nr-ue-usrp OR -v6 ( build and test )
|
||||
--variant enb-ethernet OR -v7 ( build and test )
|
||||
--variant ue-ethernet OR -v8 ( build and test )
|
||||
# non-OSA Build Variants
|
||||
--variant flexran-rtc OR -v10 ( build and test non-OSA )
|
||||
# OpenAirInterface Test Variants
|
||||
--variant l1-sim OR -v20 ( test )
|
||||
--variant rf-sim OR -v21 ( test )
|
||||
--variant l2-sim OR -v22 ( test )
|
||||
Specify the variant to build.
|
||||
|
||||
--keep-vm-alive OR -k
|
||||
Keep the VM alive after the build.
|
||||
|
||||
--help OR -h
|
||||
Print this help message.
|
||||
```
|
||||
|
||||
# 2. Detailed Description #
|
||||
|
||||
Source file concerned: `ci-scripts/run_test_on_vm.sh`
|
||||
|
||||
**TBD when file is re-structured.**
|
||||
|
||||
# 3. Typical Usage #
|
||||
|
||||
## 3.1. Testing the physical simulators ##
|
||||
|
||||
```bash
|
||||
$ ./ci-scripts/oai-ci-vm-tool test --workspace /var/jenkins/workspace/RAN-CI-develop --variant phy-sim --job-name RAN-CI-develop --build-id 47
|
||||
12:54:29 ############################################################
|
||||
12:54:29 OAI CI VM script
|
||||
12:54:29 ############################################################
|
||||
12:54:29 VM_NAME = RAN-CI-develop-b47-phy-sim
|
||||
12:54:29 VM_CMD_FILE = RAN-CI-develop-b47-phy-sim_cmds.txt
|
||||
12:54:29 JENKINS_WKSP = /var/jenkins/workspace/RAN-CI-develop
|
||||
12:54:29 ARCHIVES_LOC = /var/jenkins/workspace/RAN-CI-develop/archives/phy_sim/test
|
||||
12:54:29 ############################################################
|
||||
12:54:29 Waiting for VM to be started
|
||||
12:54:29 ############################################################
|
||||
12:54:29 Warning: Permanently added '192.168.122.220' (ECDSA) to the list of known hosts.
|
||||
12:54:30 RAN-CI-develop-b47-phy-sim has for IP addr = 192.168.122.220
|
||||
...
|
||||
13:04:48 Test Results are written to /home/ubuntu/tmp/cmake_targets/autotests/log/results_autotests.xml
|
||||
13:05:00 ############################################################
|
||||
13:05:00 Creating a tmp folder to store results and artifacts
|
||||
13:05:00 ############################################################
|
||||
13:05:00 /var/jenkins/workspace/RAN-CI-develop/archives/phy_sim/test /var/jenkins/workspace/RAN-CI-develop
|
||||
13:05:04 /var/jenkins/workspace/RAN-CI-develop
|
||||
13:05:04 ############################################################
|
||||
13:05:04 Destroying VM
|
||||
13:05:04 ############################################################
|
||||
13:05:06 # Host 192.168.122.220 found: line 21
|
||||
13:05:06 /home/eurecom/.ssh/known_hosts updated.
|
||||
13:05:06 Original contents retained as /home/eurecom/.ssh/known_hosts.old
|
||||
13:05:06 ############################################################
|
||||
13:05:06 Checking run status
|
||||
13:05:06 ############################################################
|
||||
13:05:06 NB_FOUND_FILES = 1
|
||||
13:05:06 NB_RUNS = 20
|
||||
13:05:06 NB_FAILURES = 0
|
||||
13:05:06 STATUS seems OK
|
||||
```
|
||||
|
||||
Note that the VM instance is destroyed. You do that when you are sure your test is passing.
|
||||
|
||||
## 3.2. Test the RF simulator ##
|
||||
|
||||
```bash
|
||||
./ci-scripts/oai-ci-vm-tool test --workspace /var/jenkins/workspace/RAN-CI-develop --variant rf-sim --job-name RAN-CI-develop --build-id 48 --keep-vm-alive
|
||||
15:24:45 Currently RF-Simulator Testing is not implemented / enabled
|
||||
15:24:45 Comment out these lines in ./ci-scripts/oai-ci-vm-tool if you want to run it
|
||||
15:24:45 STATUS seems OK
|
||||
```
|
||||
|
||||
## 3.3. Testing the L2-nFAPI simulator
|
||||
|
||||
```bash
|
||||
./ci-scripts/oai-ci-vm-tool test --workspace /var/jenkins/workspace/RAN-CI-develop --variant l2-sim --job-name RAN-CI-develop --build-id 48
|
||||
15:24:47 ############################################################
|
||||
15:24:47 OAI CI VM script
|
||||
15:24:47 ############################################################
|
||||
15:24:47 ENB_VM_NAME = RAN-CI-develop-b48-enb-ethernet
|
||||
15:24:47 ENB_VM_CMD_FILE = RAN-CI-develop-b48-enb-ethernet_cmds.txt
|
||||
15:24:47 UE_VM_NAME = RAN-CI-develop-b48-ue-ethernet
|
||||
15:24:47 UE_VM_CMD_FILE = RAN-CI-develop-b48-ue-ethernet_cmds.txt
|
||||
15:24:47 JENKINS_WKSP = /var/jenkins/workspace/RAN-CI-develop
|
||||
15:24:47 ARCHIVES_LOC = /var/jenkins/workspace/RAN-CI-develop/archives/l2_sim/test
|
||||
15:24:47 ############################################################
|
||||
15:24:47 Waiting for ENB VM to be started
|
||||
15:24:47 ############################################################
|
||||
15:24:47 Warning: Permanently added '192.168.122.110' (ECDSA) to the list of known hosts.
|
||||
15:24:48 RAN-CI-develop-b48-enb-ethernet has for IP addr = 192.168.122.110
|
||||
15:24:48 ############################################################
|
||||
15:24:48 Waiting for UE VM to be started
|
||||
15:24:48 ############################################################
|
||||
15:24:49 Warning: Permanently added '192.168.122.90' (ECDSA) to the list of known hosts.
|
||||
15:24:50 RAN-CI-develop-b48-ue-ethernet has for IP addr = 192.168.122.90
|
||||
15:24:50 ############################################################
|
||||
15:24:50 Test EPC on VM (RAN-CI-develop-b48-epc) will be using ltebox
|
||||
15:24:50 ############################################################
|
||||
15:24:50 EPC_VM_CMD_FILE = RAN-CI-develop-b48-epc_cmds.txt
|
||||
15:24:50 Waiting for VM to be started
|
||||
15:24:50 Warning: Permanently added '192.168.122.156' (ECDSA) to the list of known hosts.
|
||||
15:24:51 RAN-CI-develop-b48-epc has for IP addr = 192.168.122.156
|
||||
...
|
||||
15:42:44 ############################################################
|
||||
15:42:44 Destroying VMs
|
||||
15:42:44 ############################################################
|
||||
15:42:46 # Host 192.168.122.110 found: line 18
|
||||
15:42:46 /home/eurecom/.ssh/known_hosts updated.
|
||||
15:42:46 Original contents retained as /home/eurecom/.ssh/known_hosts.old
|
||||
15:42:47 # Host 192.168.122.90 found: line 18
|
||||
15:42:47 /home/eurecom/.ssh/known_hosts updated.
|
||||
15:42:47 Original contents retained as /home/eurecom/.ssh/known_hosts.old
|
||||
15:42:47 ############################################################
|
||||
15:42:47 Checking run status
|
||||
15:42:47 ############################################################
|
||||
15:42:47 STATUS failed?
|
||||
```
|
||||
---
|
||||
|
||||
Final step: [how to properly destroy all VM instances](./vm_based_simulator_destroy.md)
|
||||
|
||||
You can also go back to the [CI dev main page](./ci_dev_home.md)
|
||||
|
||||
@@ -43,7 +43,7 @@ from multiprocessing import Process, Lock, SimpleQueue
|
||||
#-----------------------------------------------------------
|
||||
# OAI Testing modules
|
||||
#-----------------------------------------------------------
|
||||
import sshconnection as SSH
|
||||
import sshconnection as SSH
|
||||
import helpreadme as HELP
|
||||
import constants as CONST
|
||||
|
||||
@@ -66,8 +66,8 @@ class EPCManagement():
|
||||
self.mmeConfFile = 'mme.conf'
|
||||
self.yamlPath = ''
|
||||
self.isMagmaUsed = False
|
||||
self.cfgDeploy = '--type start-mini --fqdn yes --scenario 1 --capture /tmp/oai-cn5g-v1.3.pcap' #from xml, 'mini' is default normal for docker-network.py
|
||||
self.cfgUnDeploy = '--type stop-mini --fqdn yes --scenario 1' #from xml, 'mini' is default normal for docker-network.py
|
||||
self.cfgDeploy = '--type start-mini --scenario 1 --capture /tmp/oai-cn5g-v1.5.pcap' #from xml, 'mini' is default normal for docker-network.py
|
||||
self.cfgUnDeploy = '--type stop-mini --scenario 1' #from xml, 'mini' is default normal for docker-network.py
|
||||
|
||||
|
||||
#-----------------------------------------------------------
|
||||
@@ -237,7 +237,7 @@ class EPCManagement():
|
||||
sys.exit('Insufficient EPC Parameters')
|
||||
mySSH = SSH.SSHConnection()
|
||||
mySSH.open(self.IPAddress, self.UserName, self.Password)
|
||||
html_cell = '<pre style="background-color:white">\n'
|
||||
html_cell = ''
|
||||
if re.match('ltebox', self.Type, re.IGNORECASE):
|
||||
logging.debug('Using the SABOX simulated HSS')
|
||||
mySSH.command('if [ -d ' + self.SourceCodePath + '/scripts ]; then echo ' + self.Password + ' | sudo -S rm -Rf ' + self.SourceCodePath + '/scripts ; fi', '\$', 5)
|
||||
@@ -253,18 +253,18 @@ class EPCManagement():
|
||||
logging.debug('Starting OAI CN5G')
|
||||
mySSH.command('if [ -d ' + self.SourceCodePath + '/scripts ]; then echo ' + self.Password + ' | sudo -S rm -Rf ' + self.SourceCodePath + '/scripts ; fi', '\$', 5)
|
||||
mySSH.command('mkdir -p ' + self.SourceCodePath + '/scripts', '\$', 5)
|
||||
mySSH.command('cd /opt/oai-cn5g-fed-v1.4/docker-compose', '\$', 5)
|
||||
mySSH.command('cd /opt/oai-cn5g-fed-v1.5/docker-compose', '\$', 5)
|
||||
mySSH.command('python3 ./core-network.py '+self.cfgDeploy, '\$', 60)
|
||||
if re.search('start-mini-as-ue', self.cfgDeploy):
|
||||
dFile = 'docker-compose-mini-nrf-asue.yaml'
|
||||
else:
|
||||
dFile = 'docker-compose-mini-nrf.yaml'
|
||||
mySSH.command('docker-compose -p 5gcn -f ' + dFile + ' ps -a', '\$', 60)
|
||||
mySSH.command('docker-compose -f ' + dFile + ' ps -a', '\$', 60)
|
||||
if mySSH.getBefore().count('Up (healthy)') != 6:
|
||||
logging.error('Not all container healthy')
|
||||
else:
|
||||
logging.debug('OK --> all containers are healthy')
|
||||
mySSH.command('docker-compose -p 5gcn -f ' + dFile + ' config | grep --colour=never image', '\$', 10)
|
||||
mySSH.command('docker-compose -f ' + dFile + ' config | grep --colour=never image', '\$', 10)
|
||||
listOfImages = mySSH.getBefore()
|
||||
for imageLine in listOfImages.split('\\r\\n'):
|
||||
res1 = re.search('image: (?P<name>[a-zA-Z0-9\-/]+):(?P<tag>[a-zA-Z0-9\-]+)', str(imageLine))
|
||||
@@ -288,11 +288,8 @@ class EPCManagement():
|
||||
html_cell += '\n'
|
||||
else:
|
||||
logging.error('This option should not occur!')
|
||||
html_cell += '</pre>'
|
||||
mySSH.close()
|
||||
html_queue = SimpleQueue()
|
||||
html_queue.put(html_cell)
|
||||
HTML.CreateHtmlTestRowQueue(self.Type, 'OK', 1, html_queue)
|
||||
HTML.CreateHtmlTestRowQueue(self.Type, 'OK', [html_cell])
|
||||
|
||||
def SetAmfIPAddress(self):
|
||||
# Not an error if we don't need an 5GCN
|
||||
@@ -537,11 +534,11 @@ class EPCManagement():
|
||||
mySSH.command('docker logs ' + c + ' > ' + self.SourceCodePath + '/logs/' + c + '.log', '\$', 5)
|
||||
|
||||
logging.debug('Terminating OAI CN5G')
|
||||
mySSH.command('cd /opt/oai-cn5g-fed-v1.4/docker-compose', '\$', 5)
|
||||
mySSH.command('cd /opt/oai-cn5g-fed-v1.5/docker-compose', '\$', 5)
|
||||
mySSH.command('python3 ./core-network.py '+self.cfgUnDeploy, '\$', 60)
|
||||
mySSH.command('docker volume prune --force || true', '\$', 60)
|
||||
time.sleep(2)
|
||||
mySSH.command('tshark -r /tmp/oai-cn5g-v1.3.pcap | egrep --colour=never "Tracking area update" ','\$', 30)
|
||||
mySSH.command('tshark -r /tmp/oai-cn5g-v1.5.pcap | egrep --colour=never "Tracking area update" ','\$', 30)
|
||||
result = re.search('Tracking area update request', mySSH.getBefore())
|
||||
if result is not None:
|
||||
message = 'UE requested ' + str(mySSH.getBefore().count('Tracking area update request')) + 'Tracking area update request(s)'
|
||||
@@ -551,10 +548,7 @@ class EPCManagement():
|
||||
else:
|
||||
logging.error('This should not happen!')
|
||||
mySSH.close()
|
||||
html_queue = SimpleQueue()
|
||||
html_cell = '<pre style="background-color:white">' + message + '</pre>'
|
||||
html_queue.put(html_cell)
|
||||
HTML.CreateHtmlTestRowQueue(self.Type, 'OK', 1, html_queue)
|
||||
HTML.CreateHtmlTestRowQueue(self.Type, 'OK', [message])
|
||||
|
||||
def DeployEpc(self, HTML):
|
||||
logging.debug('Trying to deploy')
|
||||
@@ -644,7 +638,7 @@ class EPCManagement():
|
||||
expectedHealthyContainers += 1
|
||||
|
||||
mySSH.command('docker-compose config | grep --colour=never image', '\$', 10)
|
||||
html_cell = '<pre style="background-color:white">\n'
|
||||
html_cell = ''
|
||||
listOfImages = mySSH.getBefore()
|
||||
for imageLine in listOfImages.split('\\r\\n'):
|
||||
res1 = re.search('image: (?P<name>[a-zA-Z0-9\-]+):(?P<tag>[a-zA-Z0-9\-]+)', str(imageLine))
|
||||
@@ -666,7 +660,6 @@ class EPCManagement():
|
||||
if res4 is not None:
|
||||
html_cell += '(' + res4.group('date') + ')'
|
||||
html_cell += '\n'
|
||||
html_cell += '</pre>'
|
||||
# Checking if all are healthy
|
||||
cnt = 0
|
||||
while (cnt < 3):
|
||||
@@ -682,8 +675,6 @@ class EPCManagement():
|
||||
logging.debug(' -- ' + str(healthyNb) + ' healthy container(s)')
|
||||
logging.debug(' -- ' + str(unhealthyNb) + ' unhealthy container(s)')
|
||||
logging.debug(' -- ' + str(startingNb) + ' still starting container(s)')
|
||||
html_queue = SimpleQueue()
|
||||
html_queue.put(html_cell)
|
||||
if healthyNb == expectedHealthyContainers:
|
||||
mySSH.command('docker exec -d prod-oai-hss /bin/bash -c "nohup tshark -i any -f \'port 9042 or port 3868\' -w /tmp/hss_check_run.pcap 2>&1 > /dev/null"', '\$', 5)
|
||||
if self.isMagmaUsed:
|
||||
@@ -695,11 +686,11 @@ class EPCManagement():
|
||||
mySSH.command('docker exec -d prod-oai-spgwu-tiny /bin/bash -c "nohup tshark -i any -f \'port 8805\' -w /tmp/spgwu_check_run.pcap 2>&1 > /dev/null"', '\$', 10)
|
||||
mySSH.close()
|
||||
logging.debug('Deployment OK')
|
||||
HTML.CreateHtmlTestRowQueue(self.Type, 'OK', 1, html_queue)
|
||||
HTML.CreateHtmlTestRowQueue(self.Type, 'OK', [html_cell])
|
||||
else:
|
||||
mySSH.close()
|
||||
logging.debug('Deployment went wrong')
|
||||
HTML.CreateHtmlTestRowQueue(self.Type, 'KO', 1, html_queue)
|
||||
HTML.CreateHtmlTestRowQueue(self.Type, 'KO', [html_cell])
|
||||
|
||||
def UndeployEpc(self, HTML):
|
||||
logging.debug('Trying to undeploy')
|
||||
@@ -767,15 +758,12 @@ class EPCManagement():
|
||||
mySSH.command('docker inspect --format=\'{{.Name}}\' prod-oai-public-net prod-oai-private-net', '\$', 10)
|
||||
noMoreNetworkNb = mySSH.getBefore().count('No such object')
|
||||
mySSH.close()
|
||||
html_queue = SimpleQueue()
|
||||
html_cell = '<pre style="background-color:white">' + message + '</pre>'
|
||||
html_queue.put(html_cell)
|
||||
if noMoreContainerNb == nbContainers and noMoreNetworkNb == 2:
|
||||
logging.debug('Undeployment OK')
|
||||
HTML.CreateHtmlTestRowQueue(self.Type, 'OK', 1, html_queue)
|
||||
HTML.CreateHtmlTestRowQueue(self.Type, 'OK', [message])
|
||||
else:
|
||||
logging.debug('Undeployment went wrong')
|
||||
HTML.CreateHtmlTestRowQueue(self.Type, 'KO', 1, html_queue)
|
||||
HTML.CreateHtmlTestRowQueue(self.Type, 'KO', [message])
|
||||
|
||||
def LogCollectHSS(self):
|
||||
mySSH = SSH.SSHConnection()
|
||||
@@ -828,7 +816,7 @@ class EPCManagement():
|
||||
mySSH.command('zip mme.log.zip mme_check_run.*', '\$', 60)
|
||||
elif re.match('OAICN5G', self.Type, re.IGNORECASE):
|
||||
mySSH.command('cd ' + self.SourceCodePath + '/logs','\$', 5)
|
||||
mySSH.command('cp -f /tmp/oai-cn5g-v1.3.pcap .','\$', 30)
|
||||
mySSH.command('cp -f /tmp/oai-cn5g-v1.5.pcap .','\$', 30)
|
||||
mySSH.command('zip mme.log.zip oai-amf.log oai-nrf.log oai-cn5g*.pcap','\$', 30)
|
||||
mySSH.command('mv mme.log.zip ' + self.SourceCodePath + '/scripts','\$', 30)
|
||||
elif re.match('OAI', self.Type, re.IGNORECASE) or re.match('OAI-Rel14-CUPS', self.Type, re.IGNORECASE):
|
||||
|
||||
@@ -41,7 +41,7 @@ def GenericHelp(vers):
|
||||
print(' --mode=[Mode]')
|
||||
print(' TesteNB')
|
||||
print(' InitiateHtml, FinalizeHtml')
|
||||
print(' TerminateeNB, TerminateUE, TerminateHSS, TerminateMME, TerminateSPGW')
|
||||
print(' TerminateeNB, TerminateHSS, TerminateMME, TerminateSPGW')
|
||||
print(' LogCollectBuild, LogCollecteNB, LogCollectHSS, LogCollectMME, LogCollectSPGW, LogCollectPing, LogCollectIperf')
|
||||
|
||||
def GitSrvHelp(repository,branch,commit,mergeallow,targetbranch):
|
||||
@@ -70,11 +70,6 @@ def EPCSrvHelp(ipaddr, username, password, sourcepath, epctype):
|
||||
print(' --EPCSourceCodePath=[EPC\'s Source Code Path] -- ' + sourcepath)
|
||||
print(' --EPCType=[EPC\'s Type: OAI or ltebox or OAI-Rel14-CUPS] -- ' + epctype)
|
||||
|
||||
def ADBSrvHelp(ipaddr, username, password):
|
||||
print(' --ADBIPAddress=[ADB\'s IP Address] -- ' + ipaddr)
|
||||
print(' --ADBUserName=[ADB\'s Login User Name] -- ' + username)
|
||||
print(' --ADBPassword=[ADB\'s Login Password] -- ' + password)
|
||||
|
||||
def XmlHelp(filename):
|
||||
print(' --XMLTestFile=[XML Test File to be run] -- ' + filename)
|
||||
print(' Note: multiple xml files can be specified (--XMLFile=File1 ... --XMLTestFile=FileN) when HTML headers are created ("InitiateHtml" mode)')
|
||||
|
||||
@@ -40,10 +40,8 @@ import constants as CONST
|
||||
|
||||
import cls_oaicitest #main class for OAI CI test framework
|
||||
import cls_physim #class PhySim for physical simulators build and test
|
||||
import cls_cots_ue #class CotsUe for Airplane mode control
|
||||
import cls_containerize #class Containerize for all container-based operations on RAN/UE objects
|
||||
import cls_static_code_analysis #class for static code analysis
|
||||
import cls_ci_ueinfra #class defining the multi Ue infrastrucure
|
||||
import cls_physim1 #class PhySim for physical simulators deploy and run
|
||||
import cls_cluster # class for building/deploying on cluster
|
||||
|
||||
@@ -70,6 +68,7 @@ import subprocess
|
||||
from multiprocessing import Process, Lock, SimpleQueue
|
||||
logging.basicConfig(
|
||||
level=logging.DEBUG,
|
||||
stream=sys.stdout,
|
||||
format="[%(asctime)s] %(levelname)8s: %(message)s"
|
||||
)
|
||||
|
||||
@@ -180,12 +179,10 @@ def GetParametersFromXML(action):
|
||||
|
||||
#local variable air_interface
|
||||
air_interface = test.findtext('air_interface')
|
||||
if (air_interface is None) or (air_interface.lower() not in ['nr','lte','ocp']):
|
||||
if (air_interface is None) or (air_interface.lower() not in ['nr','lte']):
|
||||
RAN.air_interface[RAN.eNB_instance] = 'lte-softmodem'
|
||||
elif (air_interface.lower() in ['nr','lte']):
|
||||
else:
|
||||
RAN.air_interface[RAN.eNB_instance] = air_interface.lower() +'-softmodem'
|
||||
else :
|
||||
RAN.air_interface[RAN.eNB_instance] = 'ocp-enb'
|
||||
|
||||
cmd_prefix = test.findtext('cmd_prefix')
|
||||
if cmd_prefix is not None: RAN.cmd_prefix = cmd_prefix
|
||||
@@ -212,54 +209,13 @@ def GetParametersFromXML(action):
|
||||
|
||||
#local variable air_interface
|
||||
air_interface = test.findtext('air_interface')
|
||||
if (air_interface is None) or (air_interface.lower() not in ['nr','lte','ocp']):
|
||||
if (air_interface is None) or (air_interface.lower() not in ['nr','lte']):
|
||||
RAN.air_interface[RAN.eNB_instance] = 'lte-softmodem'
|
||||
elif (air_interface.lower() in ['nr','lte']):
|
||||
else:
|
||||
RAN.air_interface[RAN.eNB_instance] = air_interface.lower() +'-softmodem'
|
||||
else :
|
||||
RAN.air_interface[RAN.eNB_instance] = 'ocp-enb'
|
||||
|
||||
elif action == 'Initialize_UE':
|
||||
ue_id = test.findtext('id')
|
||||
CiTestObj.ue_trace=test.findtext('UE_Trace')#temporary variable, to be passed to Module_UE in Initialize_UE call
|
||||
if (ue_id is None):
|
||||
CiTestObj.ue_id = ""
|
||||
else:
|
||||
CiTestObj.ue_id = ue_id
|
||||
|
||||
elif action == 'Detach_UE':
|
||||
ue_id = test.findtext('id')
|
||||
if (ue_id is None):
|
||||
CiTestObj.ue_id = ""
|
||||
else:
|
||||
CiTestObj.ue_id = ue_id
|
||||
|
||||
elif action == 'Attach_UE':
|
||||
ue_id = test.findtext('id')
|
||||
if (ue_id is None):
|
||||
CiTestObj.ue_id = ""
|
||||
else:
|
||||
CiTestObj.ue_id = ue_id
|
||||
nbMaxUEtoAttach = test.findtext('nbMaxUEtoAttach')
|
||||
if (nbMaxUEtoAttach is None):
|
||||
CiTestObj.nbMaxUEtoAttach = -1
|
||||
else:
|
||||
CiTestObj.nbMaxUEtoAttach = int(nbMaxUEtoAttach)
|
||||
|
||||
elif action == 'Terminate_UE':
|
||||
ue_id = test.findtext('id')
|
||||
if (ue_id is None):
|
||||
CiTestObj.ue_id = ""
|
||||
else:
|
||||
CiTestObj.ue_id = ue_id
|
||||
|
||||
|
||||
elif action == 'CheckStatusUE':
|
||||
expectedNBUE = test.findtext('expectedNbOfConnectedUEs')
|
||||
if (expectedNBUE is None):
|
||||
CiTestObj.expectedNbOfConnectedUEs = -1
|
||||
else:
|
||||
CiTestObj.expectedNbOfConnectedUEs = int(expectedNBUE)
|
||||
elif action == 'Initialize_UE' or action == 'Attach_UE' or action == 'Detach_UE' or action == 'Terminate_UE' or action == 'CheckStatusUE' or action == 'DataEnable_UE' or action == 'DataDisable_UE':
|
||||
CiTestObj.ue_ids = test.findtext('id').split(' ')
|
||||
|
||||
elif action == 'Build_OAI_UE':
|
||||
CiTestObj.Build_OAI_UE_args = test.findtext('Build_OAI_UE_args')
|
||||
@@ -279,14 +235,15 @@ def GetParametersFromXML(action):
|
||||
|
||||
#local variable air_interface
|
||||
air_interface = test.findtext('air_interface')
|
||||
if (air_interface is None) or (air_interface.lower() not in ['nr','lte','ocp']):
|
||||
if (air_interface is None) or (air_interface.lower() not in ['nr','lte']):
|
||||
CiTestObj.air_interface = 'lte-uesoftmodem'
|
||||
elif (air_interface.lower() in ['nr','lte']):
|
||||
CiTestObj.air_interface = air_interface.lower() +'-uesoftmodem'
|
||||
else :
|
||||
#CiTestObj.air_interface = 'ocp-enb'
|
||||
logging.error('OCP UE -- NOT SUPPORTED')
|
||||
|
||||
CiTestObj.cmd_prefix = test.findtext('cmd_prefix') or ""
|
||||
|
||||
elif action == 'Terminate_OAI_UE':
|
||||
UE_instance=test.findtext('UE_instance')
|
||||
if (UE_instance is None):
|
||||
@@ -296,58 +253,31 @@ def GetParametersFromXML(action):
|
||||
|
||||
#local variable air_interface
|
||||
air_interface = test.findtext('air_interface')
|
||||
if (air_interface is None) or (air_interface.lower() not in ['nr','lte','ocp']):
|
||||
if (air_interface is None) or (air_interface.lower() not in ['nr','lte']):
|
||||
CiTestObj.air_interface = 'lte-uesoftmodem'
|
||||
elif (air_interface.lower() in ['nr','lte']):
|
||||
else:
|
||||
CiTestObj.air_interface = air_interface.lower() +'-uesoftmodem'
|
||||
else :
|
||||
#CiTestObj.air_interface = 'ocp-enb'
|
||||
logging.error('OCP UE -- NOT SUPPORTED')
|
||||
|
||||
elif (action == 'Ping') or (action == 'Ping_CatM_module'):
|
||||
elif action == 'Ping':
|
||||
CiTestObj.ping_args = test.findtext('ping_args')
|
||||
CiTestObj.ping_packetloss_threshold = test.findtext('ping_packetloss_threshold')
|
||||
ue_id = test.findtext('id')
|
||||
if (ue_id is None):
|
||||
CiTestObj.ue_id = ""
|
||||
else:
|
||||
CiTestObj.ue_id = ue_id
|
||||
ping_rttavg_threshold = test.findtext('ping_rttavg_threshold')
|
||||
if (ping_rttavg_threshold is None):
|
||||
CiTestObj.ping_rttavg_threshold = ""
|
||||
else:
|
||||
CiTestObj.ping_rttavg_threshold = ping_rttavg_threshold
|
||||
CiTestObj.ue_ids = test.findtext('id').split(' ')
|
||||
ping_rttavg_threshold = test.findtext('ping_rttavg_threshold') or ''
|
||||
|
||||
elif action == 'Iperf':
|
||||
CiTestObj.iperf_args = test.findtext('iperf_args')
|
||||
ue_id = test.findtext('id')
|
||||
if (ue_id is None):
|
||||
CiTestObj.ue_id = ""
|
||||
else:
|
||||
CiTestObj.ue_id = ue_id
|
||||
CiTestObj.iperf_direction = test.findtext('direction')#used for modules only
|
||||
CiTestObj.ue_ids = test.findtext('id').split(' ')
|
||||
CiTestObj.iperf_direction = test.findtext('direction')
|
||||
CiTestObj.iperf_packetloss_threshold = test.findtext('iperf_packetloss_threshold')
|
||||
iperf_bitrate_threshold = test.findtext('iperf_bitrate_threshold')
|
||||
if (iperf_bitrate_threshold is None):
|
||||
CiTestObj.iperf_bitrate_threshold = "90" #if no threshold is specified, default will be 90%
|
||||
else:
|
||||
CiTestObj.iperf_bitrate_threshold = iperf_bitrate_threshold
|
||||
|
||||
|
||||
CiTestObj.iperf_profile = test.findtext('iperf_profile')
|
||||
if (CiTestObj.iperf_profile is None):
|
||||
CiTestObj.iperf_bitrate_threshold = test.findtext('iperf_bitrate_threshold') or '90'
|
||||
CiTestObj.iperf_profile = test.findtext('iperf_profile') or 'balanced'
|
||||
if CiTestObj.iperf_profile != 'balanced' and CiTestObj.iperf_profile != 'unbalanced' and CiTestObj.iperf_profile != 'single-ue':
|
||||
logging.error(f'test-case has wrong profile {CiTestObj.iperf_profile}, forcing balanced')
|
||||
CiTestObj.iperf_profile = 'balanced'
|
||||
else:
|
||||
if CiTestObj.iperf_profile != 'balanced' and CiTestObj.iperf_profile != 'unbalanced' and CiTestObj.iperf_profile != 'single-ue':
|
||||
logging.error('test-case has wrong profile ' + CiTestObj.iperf_profile)
|
||||
CiTestObj.iperf_profile = 'balanced'
|
||||
CiTestObj.iperf_options = test.findtext('iperf_options')
|
||||
if (CiTestObj.iperf_options is None):
|
||||
CiTestObj.iperf_options = test.findtext('iperf_options') or 'check'
|
||||
if CiTestObj.iperf_options != 'check' and CiTestObj.iperf_options != 'sink':
|
||||
logging.error('test-case has wrong option ' + CiTestObj.iperf_options)
|
||||
CiTestObj.iperf_options = 'check'
|
||||
else:
|
||||
if CiTestObj.iperf_options != 'check' and CiTestObj.iperf_options != 'sink':
|
||||
logging.error('test-case has wrong option ' + CiTestObj.iperf_options)
|
||||
CiTestObj.iperf_options = 'check'
|
||||
|
||||
elif action == 'IdleSleep':
|
||||
string_field = test.findtext('idle_sleep_time_in_sec')
|
||||
@@ -469,7 +399,7 @@ def GetParametersFromXML(action):
|
||||
if (string_field is not None):
|
||||
CONTAINERS.cliOptions = string_field
|
||||
|
||||
elif action == 'Run_LDPCTest' or action == 'Run_NRulsimTest':
|
||||
elif action == 'Run_LDPCTest' or action == 'Run_NRulsimTest' or action == 'Run_LDPCt1Test':
|
||||
ldpc.runargs = test.findtext('physim_run_args')
|
||||
|
||||
elif action == 'LicenceAndFormattingCheck':
|
||||
@@ -496,6 +426,10 @@ def GetParametersFromXML(action):
|
||||
string_field = test.findtext('test_svr_id')
|
||||
if (string_field is not None):
|
||||
CONTAINERS.testSvrId = string_field
|
||||
elif action == 'Custom_Command':
|
||||
RAN.node = test.findtext('node')
|
||||
RAN.command = test.findtext('command')
|
||||
RAN.command_fail = test.findtext('command_fail') in ['True', 'true', 'Yes', 'yes']
|
||||
|
||||
else:
|
||||
logging.warning(f"unknown action {action} from option-parsing point-of-view")
|
||||
@@ -538,22 +472,6 @@ with open(yaml_file,'r') as f:
|
||||
#from YAML scalar values to Python dictionary format$
|
||||
xml_class_list = yaml.load(f,Loader=yaml.FullLoader)
|
||||
|
||||
|
||||
|
||||
#loading UE infrastructure from yaml
|
||||
ue_infra_file='ci_ueinfra.yaml'
|
||||
if (os.path.isfile(ue_infra_file)):
|
||||
yaml_file=ue_infra_file
|
||||
elif (os.path.isfile('ci-scripts/'+ue_infra_file)):
|
||||
yaml_file='ci-scripts/'+ue_infra_file
|
||||
else:
|
||||
logging.error("UE infrastructure yaml file cannot be found")
|
||||
sys.exit("UE infrastructure file cannot be found")
|
||||
InfraUE=cls_ci_ueinfra.InfraUE() #initialize UE infrastructure class
|
||||
InfraUE.Get_UE_Infra(yaml_file) #read the UE infra, filename is hardcoded and unique for the moment but should be passed as parameter from the test suite
|
||||
|
||||
|
||||
|
||||
mode = ''
|
||||
|
||||
CiTestObj = cls_oaicitest.OaiCiTest()
|
||||
@@ -586,15 +504,6 @@ py_param_file_present, py_params, mode = args_parse.ArgsParse(sys.argv,CiTestObj
|
||||
if py_param_file_present == True:
|
||||
AssignParams(py_params)
|
||||
|
||||
|
||||
#-----------------------------------------------------------
|
||||
# COTS UE instanciation
|
||||
#-----------------------------------------------------------
|
||||
#COTS_UE instanciation and ADB server init
|
||||
#ue id and ue mode are retrieved from xml
|
||||
COTS_UE=cls_cots_ue.CotsUe(CiTestObj.ADBIPAddress, CiTestObj.ADBUserName,CiTestObj.ADBPassword)
|
||||
|
||||
|
||||
#-----------------------------------------------------------
|
||||
# mode amd XML class (action) analysis
|
||||
#-----------------------------------------------------------
|
||||
@@ -610,18 +519,12 @@ if re.match('^TerminateeNB$', mode, re.IGNORECASE):
|
||||
RAN.eNB_serverId[0]='0'
|
||||
RAN.eNBSourceCodePath='/tmp/'
|
||||
RAN.TerminateeNB(HTML, EPC)
|
||||
elif re.match('^TerminateUE$', mode, re.IGNORECASE):
|
||||
if (CiTestObj.ADBIPAddress == '' or CiTestObj.ADBUserName == '' or CiTestObj.ADBPassword == ''):
|
||||
HELP.GenericHelp(CONST.Version)
|
||||
sys.exit('Insufficient Parameter')
|
||||
signal.signal(signal.SIGUSR1, receive_signal)
|
||||
CiTestObj.TerminateUE(HTML,COTS_UE,InfraUE,CiTestObj.ue_trace)
|
||||
elif re.match('^TerminateOAIUE$', mode, re.IGNORECASE):
|
||||
if CiTestObj.UEIPAddress == '' or CiTestObj.UEUserName == '' or CiTestObj.UEPassword == '':
|
||||
HELP.GenericHelp(CONST.Version)
|
||||
sys.exit('Insufficient Parameter')
|
||||
signal.signal(signal.SIGUSR1, receive_signal)
|
||||
CiTestObj.TerminateOAIUE(HTML,RAN,COTS_UE,EPC,InfraUE,CONTAINERS)
|
||||
CiTestObj.TerminateOAIUE(HTML,RAN,EPC,CONTAINERS)
|
||||
elif re.match('^TerminateHSS$', mode, re.IGNORECASE):
|
||||
if EPC.IPAddress == '' or EPC.UserName == '' or EPC.Password == '' or EPC.Type == '' or EPC.SourceCodePath == '':
|
||||
HELP.GenericHelp(CONST.Version)
|
||||
@@ -685,9 +588,6 @@ elif re.match('^LogCollectOAIUE$', mode, re.IGNORECASE):
|
||||
sys.exit('Insufficient Parameter')
|
||||
CiTestObj.LogCollectOAIUE()
|
||||
elif re.match('^InitiateHtml$', mode, re.IGNORECASE):
|
||||
if (CiTestObj.ADBIPAddress == '' or CiTestObj.ADBUserName == '' or CiTestObj.ADBPassword == ''):
|
||||
HELP.GenericHelp(CONST.Version)
|
||||
sys.exit('Insufficient Parameter')
|
||||
count = 0
|
||||
foundCount = 0
|
||||
while (count < HTML.nbTestXMLfiles):
|
||||
@@ -707,28 +607,19 @@ elif re.match('^InitiateHtml$', mode, re.IGNORECASE):
|
||||
if foundCount != HTML.nbTestXMLfiles:
|
||||
HTML.nbTestXMLfiles=foundCount
|
||||
|
||||
if (CiTestObj.ADBIPAddress != 'none') and (CiTestObj.ADBIPAddress != 'modules'):
|
||||
terminate_ue_flag = False
|
||||
CiTestObj.GetAllUEDevices(terminate_ue_flag)
|
||||
CiTestObj.GetAllCatMDevices(terminate_ue_flag)
|
||||
HTML.SethtmlUEConnected(len(CiTestObj.UEDevices) + len(CiTestObj.CatMDevices))
|
||||
HTML.htmlNb_Smartphones=len(CiTestObj.UEDevices)
|
||||
HTML.htmlNb_CATM_Modules=len(CiTestObj.CatMDevices)
|
||||
HTML.CreateHtmlHeader(CiTestObj.ADBIPAddress)
|
||||
HTML.CreateHtmlHeader()
|
||||
elif re.match('^FinalizeHtml$', mode, re.IGNORECASE):
|
||||
logging.info('\u001B[1m----------------------------------------\u001B[0m')
|
||||
logging.info('\u001B[1m Creating HTML footer \u001B[0m')
|
||||
logging.info('\u001B[1m----------------------------------------\u001B[0m')
|
||||
|
||||
CiTestObj.RetrieveSystemVersion('eNB',HTML,RAN)
|
||||
CiTestObj.RetrieveSystemVersion('UE',HTML,RAN)
|
||||
HTML.CreateHtmlFooter(CiTestObj.finalStatus)
|
||||
elif re.match('^TesteNB$', mode, re.IGNORECASE) or re.match('^TestUE$', mode, re.IGNORECASE):
|
||||
logging.info('\u001B[1m----------------------------------------\u001B[0m')
|
||||
logging.info('\u001B[1m Starting Scenario: ' + CiTestObj.testXMLfiles[0] + '\u001B[0m')
|
||||
logging.info('\u001B[1m----------------------------------------\u001B[0m')
|
||||
if re.match('^TesteNB$', mode, re.IGNORECASE):
|
||||
if RAN.eNBIPAddress == '' or RAN.ranRepository == '' or RAN.ranBranch == '' or RAN.eNBUserName == '' or RAN.eNBPassword == '' or RAN.eNBSourceCodePath == '' or EPC.IPAddress == '' or EPC.UserName == '' or EPC.Password == '' or EPC.Type == '' or EPC.SourceCodePath == '' or CiTestObj.ADBIPAddress == '' or CiTestObj.ADBUserName == '' or CiTestObj.ADBPassword == '':
|
||||
if RAN.eNBIPAddress == '' or RAN.ranRepository == '' or RAN.ranBranch == '' or RAN.eNBUserName == '' or RAN.eNBPassword == '' or RAN.eNBSourceCodePath == '' or EPC.IPAddress == '' or EPC.UserName == '' or EPC.Password == '' or EPC.Type == '' or EPC.SourceCodePath == '':
|
||||
HELP.GenericHelp(CONST.Version)
|
||||
if EPC.IPAddress == '' or EPC.UserName == '' or EPC.Password == '' or EPC.SourceCodePath == '' or EPC.Type == '':
|
||||
HELP.EPCSrvHelp(EPC.IPAddress, EPC.UserName, EPC.Password, EPC.SourceCodePath, EPC.Type)
|
||||
@@ -810,20 +701,13 @@ elif re.match('^TesteNB$', mode, re.IGNORECASE) or re.match('^TestUE$', mode, re
|
||||
|
||||
signal.signal(signal.SIGUSR1, receive_signal)
|
||||
|
||||
if (CiTestObj.ADBIPAddress != 'none') and (CiTestObj.ADBIPAddress != 'modules'):
|
||||
terminate_ue_flag = False
|
||||
CiTestObj.GetAllUEDevices(terminate_ue_flag)
|
||||
CiTestObj.GetAllCatMDevices(terminate_ue_flag)
|
||||
elif (CiTestObj.ADBIPAddress == 'modules'):
|
||||
CiTestObj.UEDevices.append('COTS-Module')
|
||||
else:
|
||||
CiTestObj.UEDevices.append('OAI-UE')
|
||||
HTML.SethtmlUEConnected(len(CiTestObj.UEDevices) + len(CiTestObj.CatMDevices))
|
||||
HTML.CreateHtmlTabHeader()
|
||||
|
||||
# On CI bench w/ containers, we need to validate if IP routes are set
|
||||
if EPC.IPAddress == '172.21.16.136':
|
||||
CONTAINERS.CheckAndAddRoute('porcepix', EPC.IPAddress, EPC.UserName, EPC.Password)
|
||||
if EPC.IPAddress == '172.21.16.137':
|
||||
CONTAINERS.CheckAndAddRoute('nepes', EPC.IPAddress, EPC.UserName, EPC.Password)
|
||||
if CONTAINERS.eNBIPAddress == '172.21.16.127':
|
||||
CONTAINERS.CheckAndAddRoute('asterix', CONTAINERS.eNBIPAddress, CONTAINERS.eNBUserName, CONTAINERS.eNBPassword)
|
||||
if CONTAINERS.eNB1IPAddress == '172.21.16.127':
|
||||
@@ -832,6 +716,8 @@ elif re.match('^TesteNB$', mode, re.IGNORECASE) or re.match('^TestUE$', mode, re
|
||||
CONTAINERS.CheckAndAddRoute('obelix', CONTAINERS.eNBIPAddress, CONTAINERS.eNBUserName, CONTAINERS.eNBPassword)
|
||||
if CONTAINERS.eNB1IPAddress == '172.21.16.128':
|
||||
CONTAINERS.CheckAndAddRoute('obelix', CONTAINERS.eNB1IPAddress, CONTAINERS.eNB1UserName, CONTAINERS.eNB1Password)
|
||||
if CONTAINERS.eNBIPAddress == '172.21.16.109' or CONTAINERS.eNBIPAddress == 'ofqot':
|
||||
CONTAINERS.CheckAndAddRoute('ofqot', CONTAINERS.eNBIPAddress, CONTAINERS.eNBUserName, CONTAINERS.eNBPassword)
|
||||
if CONTAINERS.eNBIPAddress == '172.21.16.137':
|
||||
CONTAINERS.CheckAndAddRoute('nepes', CONTAINERS.eNBIPAddress, CONTAINERS.eNBUserName, CONTAINERS.eNBPassword)
|
||||
if CONTAINERS.eNB1IPAddress == '172.21.16.137':
|
||||
@@ -864,64 +750,45 @@ elif re.match('^TesteNB$', mode, re.IGNORECASE) or re.match('^TestUE$', mode, re
|
||||
continue
|
||||
CiTestObj.ShowTestID()
|
||||
GetParametersFromXML(action)
|
||||
if action == 'Initialize_UE' or action == 'Attach_UE' or action == 'Detach_UE' or action == 'Ping' or action == 'Iperf' or action == 'Reboot_UE' or action == 'DataDisable_UE' or action == 'DataEnable_UE' or action == 'CheckStatusUE':
|
||||
if (CiTestObj.ADBIPAddress != 'none') and (CiTestObj.ADBIPAddress != 'modules'):
|
||||
#in these cases, having no devices is critical, GetAllUEDevices function has to manage it as a critical error, reason why terminate_ue_flag is set to True
|
||||
terminate_ue_flag = True
|
||||
# Now we stop properly the test-suite --> clean reporting
|
||||
status = CiTestObj.GetAllUEDevices(terminate_ue_flag)
|
||||
if not status:
|
||||
RAN.prematureExit = True
|
||||
break
|
||||
if action == 'Build_eNB':
|
||||
RAN.BuildeNB(HTML)
|
||||
elif action == 'WaitEndBuild_eNB':
|
||||
RAN.WaitBuildeNBisFinished(HTML)
|
||||
elif action == 'Custom_Command':
|
||||
logging.info(f"Executing custom command")
|
||||
RAN.CustomCommand(HTML)
|
||||
if RAN.prematureExit:
|
||||
CiTestObj.AutoTerminateeNB(HTML,RAN,EPC,CONTAINERS)
|
||||
elif action == 'Initialize_eNB':
|
||||
check_eNB = False
|
||||
check_OAI_UE = False
|
||||
RAN.pStatus=CiTestObj.CheckProcessExist(check_eNB, check_OAI_UE,RAN,EPC)
|
||||
RAN.InitializeeNB(HTML, EPC)
|
||||
if RAN.prematureExit:
|
||||
CiTestObj.AutoTerminateeNB(HTML,RAN,EPC,CONTAINERS)
|
||||
elif action == 'Terminate_eNB':
|
||||
RAN.TerminateeNB(HTML, EPC)
|
||||
elif action == 'Initialize_UE':
|
||||
CiTestObj.InitializeUE(HTML,RAN, EPC, COTS_UE, InfraUE, CiTestObj.ue_trace, CONTAINERS)
|
||||
CiTestObj.InitializeUE(HTML)
|
||||
elif action == 'Terminate_UE':
|
||||
CiTestObj.TerminateUE(HTML,COTS_UE, InfraUE, CiTestObj.ue_trace)
|
||||
CiTestObj.TerminateUE(HTML)
|
||||
elif action == 'Attach_UE':
|
||||
CiTestObj.AttachUE(HTML,RAN,EPC,COTS_UE,InfraUE,CONTAINERS)
|
||||
CiTestObj.AttachUE(HTML, RAN, EPC, CONTAINERS)
|
||||
elif action == 'Detach_UE':
|
||||
CiTestObj.DetachUE(HTML,RAN,EPC,COTS_UE,InfraUE,CONTAINERS)
|
||||
CiTestObj.DetachUE(HTML)
|
||||
elif action == 'DataDisable_UE':
|
||||
CiTestObj.DataDisableUE(HTML)
|
||||
elif action == 'DataEnable_UE':
|
||||
CiTestObj.DataEnableUE(HTML)
|
||||
elif action == 'CheckStatusUE':
|
||||
CiTestObj.CheckStatusUE(HTML,RAN,EPC,COTS_UE,InfraUE,CONTAINERS)
|
||||
CiTestObj.CheckStatusUE(HTML)
|
||||
elif action == 'Build_OAI_UE':
|
||||
CiTestObj.BuildOAIUE(HTML)
|
||||
elif action == 'Initialize_OAI_UE':
|
||||
CiTestObj.InitializeOAIUE(HTML,RAN,EPC,COTS_UE,InfraUE,CONTAINERS)
|
||||
CiTestObj.InitializeOAIUE(HTML,RAN,EPC,CONTAINERS)
|
||||
elif action == 'Terminate_OAI_UE':
|
||||
CiTestObj.TerminateOAIUE(HTML,RAN,COTS_UE,EPC,InfraUE,CONTAINERS)
|
||||
elif action == 'Initialize_CatM_module':
|
||||
CiTestObj.InitializeCatM(HTML)
|
||||
elif action == 'Terminate_CatM_module':
|
||||
CiTestObj.TerminateCatM(HTML)
|
||||
elif action == 'Attach_CatM_module':
|
||||
CiTestObj.AttachCatM(HTML,RAN,COTS_UE,EPC,InfraUE,CONTAINERS)
|
||||
elif action == 'Detach_CatM_module':
|
||||
CiTestObj.TerminateCatM(HTML)
|
||||
elif action == 'Ping_CatM_module':
|
||||
CiTestObj.PingCatM(HTML,RAN,EPC,COTS_UE,EPC,InfraUE,CONTAINERS)
|
||||
CiTestObj.TerminateOAIUE(HTML,RAN,EPC,CONTAINERS)
|
||||
elif action == 'Ping':
|
||||
CiTestObj.Ping(HTML,RAN,EPC,COTS_UE, InfraUE, CONTAINERS)
|
||||
CiTestObj.Ping(HTML,RAN,EPC,CONTAINERS)
|
||||
elif action == 'Iperf':
|
||||
CiTestObj.Iperf(HTML,RAN,EPC,COTS_UE, InfraUE, CONTAINERS)
|
||||
elif action == 'Reboot_UE':
|
||||
CiTestObj.RebootUE(HTML,RAN,EPC)
|
||||
CiTestObj.Iperf(HTML,RAN,EPC,CONTAINERS)
|
||||
elif action == 'Initialize_HSS':
|
||||
EPC.InitializeHSS(HTML)
|
||||
elif action == 'Terminate_HSS':
|
||||
@@ -954,6 +821,10 @@ elif re.match('^TesteNB$', mode, re.IGNORECASE) or re.match('^TestUE$', mode, re
|
||||
HTML=ldpc.Run_LDPCTest(HTML,CONST,id)
|
||||
if ldpc.exitStatus==1:
|
||||
RAN.prematureExit = True
|
||||
elif action == 'Run_LDPCt1Test':
|
||||
HTML=ldpc.Run_LDPCt1Test(HTML,CONST,id)
|
||||
if ldpc.exitStatus==1:
|
||||
RAN.prematureExit = True
|
||||
elif action == 'Run_NRulsimTest':
|
||||
HTML=ldpc.Run_NRulsimTest(HTML,CONST,id)
|
||||
if ldpc.exitStatus==1:
|
||||
|
||||
@@ -1,889 +0,0 @@
|
||||
#!/bin/bash
|
||||
#/*
|
||||
# * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
|
||||
# * contributor license agreements. See the NOTICE file distributed with
|
||||
# * this work for additional information regarding copyright ownership.
|
||||
# * The OpenAirInterface Software Alliance licenses this file to You under
|
||||
# * the OAI Public License, Version 1.1 (the "License"); you may not use this file
|
||||
# * except in compliance with the License.
|
||||
# * You may obtain a copy of the License at
|
||||
# *
|
||||
# * http://www.openairinterface.org/?page_id=698
|
||||
# *
|
||||
# * Unless required by applicable law or agreed to in writing, software
|
||||
# * distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# * See the License for the specific language governing permissions and
|
||||
# * limitations under the License.
|
||||
# *-------------------------------------------------------------------------------
|
||||
# * For more information about the OpenAirInterface (OAI) Software Alliance:
|
||||
# * contact@openairinterface.org
|
||||
# */
|
||||
|
||||
|
||||
function top_usage {
|
||||
echo "OAI CI VM script"
|
||||
echo " Original Author: Raphael Defosseux"
|
||||
echo " Requirements:"
|
||||
echo " -- uvtool uvtool-libvirt apt-cacher"
|
||||
echo " -- $VM_OSREL image already synced"
|
||||
echo ""
|
||||
echo "Usage:"
|
||||
echo "------"
|
||||
echo " oai-ci-vm-tool (-h|--help) { `for i in "${COMMANDS_NAME[@]}"; do echo -n $i,;done` ..." }
|
||||
echo ""
|
||||
}
|
||||
|
||||
function variant_usage {
|
||||
|
||||
for (( i=0 ; i<${#VARIANTS_LONG[@]} ; i++ ))
|
||||
do
|
||||
unset BUILD_OPTIONS
|
||||
unset VARIANT_INFO
|
||||
check_set_variant "${VARIANTS_SHORT[$i]}"
|
||||
printf " --variant %-15s OR -%-3s" "${VARIANTS_LONG[$i]}" "${VARIANTS_SHORT[$i]}"
|
||||
if [ "$BUILD_OPTIONS" = "" ]
|
||||
then
|
||||
echo -n " ( test "
|
||||
else
|
||||
echo -n " ( build and test "
|
||||
fi
|
||||
echo "$VARIANT_INFO )"
|
||||
if [ "$1" = "full" ]
|
||||
then
|
||||
printf " VM_NAME=%-15s ARCHIVES_LOC=%-15s\n" "$VM_NAME" "$ARCHIVES_LOC"
|
||||
printf " VM_MEMORY=%-15s VM_CPU=%-15s VM_DISK=%-15s\n" "$VM_MEMORY" "$VM_CPU" "$VM_DISK"
|
||||
printf " NB_PATTERN_FILES=%-15s BUILD_OPTIONS=%-15s\n" "$NB_PATTERN_FILES" "\"$BUILD_OPTIONS\""
|
||||
printf " LOG_PATTERN=%-15s EXPERIMENTAL=%-15s\n\n\n" "$LOG_PATTERN" "$EXPERIMENTAL"
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
function command_options_usage {
|
||||
|
||||
local -A HELP_MSG
|
||||
HELP_MSG["jn"]=" Specify the name of the Jenkins job."
|
||||
HELP_MSG["id"]=" Specify the build ID of the Jenkins job."
|
||||
HELP_MSG["ws"]=" Specify the workspace"
|
||||
HELP_MSG["var"]=" Specify the variant to build."
|
||||
HELP_MSG["k"]=" Keep the VM alive after the build."
|
||||
HELP_MSG["D"]=" Run as daemon"
|
||||
HELP_MSG["gu"]=" Specify the URL of the GIT Repository."
|
||||
HELP_MSG["pu"]=" trigger a push action from the Jenkins job to the specified url, \"--trigger pu\" can also be used"
|
||||
HELP_MSG["mr"]=" trigger a merge request action from the Jenkins job, \"--trigger mr\" can also be used"
|
||||
HELP_MSG["sb"]=" Specify the source branch of the merge request."
|
||||
HELP_MSG["sc"]=" Specify the source commit ID (SHA-1) of the merge request."
|
||||
HELP_MSG["tb"]=" Specify the target branch of the merge request (usually develop)."
|
||||
HELP_MSG["tc"]=" Specify the target commit ID (SHA-1) of the merge request."
|
||||
HELP_MSG["br"]=" Specify the branch of the push event."
|
||||
HELP_MSG["co"]=" Specify the commit ID (SHA-1) of the push event."
|
||||
HELP_MSG["epc"]=" (two arguments) Specify the ip addresses of an external EPC, on respectively the core network and the UEs network"
|
||||
HELP_MSG["sim"]=" Specify the path to the sim file, used to emulate the oai UE sim card "
|
||||
for (( m=0 ; m<2 ; m++ ))
|
||||
do
|
||||
if [[ $m -eq 0 || ( $m > 0 && ${MANDATORY_OPTMASK[$m]} > 0 ) ]]
|
||||
then
|
||||
echo "Mandatory Options ($((m+1))):"
|
||||
echo "---------------------"
|
||||
for (( i=0 ; i<${#SHORT_OPTIONS[@]} ; i++ ))
|
||||
do
|
||||
if [ $(( MANDATORY_OPTMASK[$m] & $(( 2**$i )) )) -ne 0 ]
|
||||
then
|
||||
if [ "${LONG_OPTIONS[$i]}" != "" ]
|
||||
then
|
||||
local ARGPATTERN
|
||||
if [[ !("${HELP_MSG[${SHORT_OPTIONS[$i]}]}" =~ "Specify") ]]
|
||||
then
|
||||
ARGPATTERN=""
|
||||
elif [[ "${HELP_MSG[${SHORT_OPTIONS[$i]}]}" =~ "(two arguments)" ]]
|
||||
then
|
||||
ARGPATTERN="#### ####"
|
||||
else
|
||||
ARGPATTERN="####"
|
||||
fi
|
||||
printf " %s %s OR " "--${LONG_OPTIONS[$i]}" "$ARGPATTERN"
|
||||
fi
|
||||
printf "%s %s \n" "-${SHORT_OPTIONS[$i]}" "$ARGPATTERN"
|
||||
printf " %s\n\n" "${HELP_MSG[${SHORT_OPTIONS[$i]}]}"
|
||||
fi
|
||||
done
|
||||
fi
|
||||
done
|
||||
echo "Options:"
|
||||
echo "--------"
|
||||
|
||||
for (( i=0 ; i<${#SHORT_OPTIONS[@]} ; i++ ))
|
||||
do
|
||||
if [ $(( ALLOWED_OPTMASK & $(( 2**$i )) )) -ne 0 ]
|
||||
then
|
||||
if [ "${LONG_OPTIONS[$i]}" != "" ]
|
||||
then
|
||||
printf " %s #### OR " "--${LONG_OPTIONS[$i]}"
|
||||
fi
|
||||
printf "%s #### \n" "-${SHORT_OPTIONS[$i]}"
|
||||
printf " %s\n\n" "${HELP_MSG[${SHORT_OPTIONS[$i]}]}"
|
||||
fi
|
||||
done
|
||||
|
||||
for (( i=0 ; i<${#SHORT_OPTIONS[@]} ; i++ ))
|
||||
do
|
||||
if [ $(( ALLOWED_OPTMASK & $(( 2**$i )) )) -ne 0 ]
|
||||
then
|
||||
if [ "$(type -t ${LONG_OPTIONS[$i]}_usage)" = 'function' ]
|
||||
then
|
||||
${LONG_OPTIONS[$i]}_usage
|
||||
fi
|
||||
fi
|
||||
done
|
||||
echo " --help OR -h"
|
||||
echo " Print this help message."
|
||||
echo ""
|
||||
}
|
||||
|
||||
# function to set specific behavior depending on the TESTPLATFORM_OWNER variable
|
||||
# which may be set by a jenkins server for exemple
|
||||
function platform_set {
|
||||
if [ "$TESTPLATFORM_OWNER" != "" ]
|
||||
then
|
||||
echo "Running on $TESTPLATFORM_OWNER platform"
|
||||
if [ -x "/usr/local/bin/oai_${TESTPLATFORM_OWNER}_setenv.sh" ]
|
||||
then
|
||||
. /usr/local/bin/oai_${TESTPLATFORM_OWNER}_setenv.sh
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
function setvar_usage {
|
||||
declare -A HELP_VAR
|
||||
HELP_VAR["VM_OSREL"]="OS release to use in virtual machines"
|
||||
HELP_VAR["RUN_EXPERIMENTAL"]="Enforce execution of variants with EXPERIMENTAL variable set to \"true\""
|
||||
HELP_VAR["OPTIONAL_APTCACHER"]="build and Run tests will fail if apt-cacher not installed and this variable not set to \"true\""
|
||||
HELP_VAR["TESTPLATFORM_OWNER"]="Allow pipeline customization via execution of an externel scripts residing on the jenkins server"
|
||||
echo "--setvar_<varname> <value> where varname is one of:"
|
||||
for i in ${AUTHORIZED_VAR[@]}; do printf "%20s : %s\n" "$i" "${HELP_VAR[$i]}" ;done
|
||||
}
|
||||
|
||||
# functions variant__v<n>__<variant name> are used to define build or test variants
|
||||
# The only thing to do to define a new variant is to add a function which name
|
||||
# match this template. Note that "_" character in function <varriant name> part
|
||||
# will be replaced by "-" character in build_variant_arrays function, this is
|
||||
# for compatibility reasons
|
||||
|
||||
function variant__v1__enb_usrp {
|
||||
NB_PATTERN_FILES=7
|
||||
BUILD_OPTIONS="--eNB -w USRP --mu"
|
||||
VM_MEMORY=3072
|
||||
}
|
||||
|
||||
function variant__v2__basic_sim {
|
||||
NB_PATTERN_FILES=11
|
||||
BUILD_OPTIONS="--eNB --UE --noavx512"
|
||||
VM_MEMORY=8192
|
||||
RUN_OPTIONS="complex"
|
||||
}
|
||||
|
||||
function variant__v3__phy_sim {
|
||||
NB_PATTERN_FILES=11
|
||||
BUILD_OPTIONS="--phy_simulators"
|
||||
VM_MEMORY=8192
|
||||
VM_DISK=20
|
||||
RUN_OPTIONS="./run_exec_autotests.bash -g \"01510* 015111 015112\" -q -np -b"
|
||||
}
|
||||
|
||||
function variant__v4__cppcheck {
|
||||
VM_MEMORY=4096
|
||||
LOG_PATTERN=cppcheck.xml
|
||||
NB_PATTERN_FILES=1
|
||||
BUILD_OPTIONS="--enable=warning --force --xml --xml-version=2 -i openair1/PHY/CODING/nrLDPC_decoder/nrLDPC_decoder.c --suppressions-list=ci-scripts/cppcheck_suppressions.list -I common/utils -I openair3/NAS/COMMON/UTIL -j4"
|
||||
}
|
||||
|
||||
function variant__v5__gnb_usrp {
|
||||
VM_MEMORY=10240
|
||||
VM_CPU=8
|
||||
NB_PATTERN_FILES=6
|
||||
BUILD_OPTIONS="--gNB -w USRP --noavx512"
|
||||
}
|
||||
|
||||
function variant__v6__nr_ue_usrp {
|
||||
VM_MEMORY=4096
|
||||
VM_CPU=4
|
||||
NB_PATTERN_FILES=6
|
||||
BUILD_OPTIONS="--nrUE -w USRP --noavx512"
|
||||
}
|
||||
|
||||
function variant__v7__enb_ethernet {
|
||||
VM_MEMORY=4096
|
||||
ARCHIVES_LOC=enb_eth
|
||||
NB_PATTERN_FILES=6
|
||||
BUILD_OPTIONS="--eNB -w USRP --noavx512"
|
||||
}
|
||||
|
||||
function variant__v8__ue_ethernet {
|
||||
VM_MEMORY=4096
|
||||
ARCHIVES_LOC=ue_eth
|
||||
NB_PATTERN_FILES=10
|
||||
BUILD_OPTIONS="--UE -w USRP --noavx512"
|
||||
}
|
||||
|
||||
function variant__v10__flexran_rtc {
|
||||
ARCHIVES_LOC=flexran
|
||||
NB_PATTERN_FILES=1
|
||||
BUILD_OPTIONS="cmake .. && make -j2"
|
||||
VARIANT_INFO="non-OSA"
|
||||
}
|
||||
|
||||
function variant__v20__l1_sim {
|
||||
ARCHIVES_LOC=l1_sim
|
||||
RUN_OPTIONS="complex"
|
||||
EXPERIMENTAL="true"
|
||||
}
|
||||
|
||||
function variant__v21__rf_sim {
|
||||
ARCHIVES_LOC=rf_sim
|
||||
RUN_OPTIONS="complex"
|
||||
}
|
||||
|
||||
function variant__v22__l2_sim {
|
||||
RUN_OPTIONS="complex"
|
||||
}
|
||||
|
||||
function variant__v23__rf5g_sim {
|
||||
ARCHIVES_LOC=rf5g_sim
|
||||
RUN_OPTIONS="complex"
|
||||
}
|
||||
|
||||
# Following function lists all variant__v<n>__<variant name> functions
|
||||
# and set the VARIANTS_SHORT and VARIANTS_LONG arrays from
|
||||
# the function names
|
||||
function build_variant_arrays {
|
||||
VARIANTS=`declare -F`
|
||||
VARIANTS=${VARIANTS//"declare -f "}
|
||||
for i in $VARIANTS
|
||||
do
|
||||
if [ `expr match "$i" 'variant__v'` -eq 10 ]
|
||||
then
|
||||
IDX1=`expr match "$i" 'variant__v[0-9]\+__'`
|
||||
VARIANTS_SHORT+=(${i:9:$((IDX1-11))})
|
||||
LONGNAME=${i:$IDX1}
|
||||
VARIANTS_LONG+=(${LONGNAME//"_"/"-"})
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
# check that the passed argument is a valid variant, set
|
||||
# default values for variant related variables and then execute
|
||||
# the corresponding variant__v<n>__<variant name> function
|
||||
function check_set_variant {
|
||||
for (( i=0 ; i<${#VARIANTS_SHORT[@]} ; i++ ))
|
||||
do
|
||||
if [ "$1" = "${VARIANTS_SHORT[$i]}" ] || [ "$1" = "${VARIANTS_LONG[$i]}" ]
|
||||
then
|
||||
VM_NAME=ci-${VARIANTS_LONG[$i]}
|
||||
LOG_PATTERN=.txt
|
||||
ARCHIVES_LOC=${VARIANTS_LONG[$i]//"-"/"_"}
|
||||
VM_MEMORY=2048
|
||||
VM_CPU=4
|
||||
VM_DISK=10
|
||||
EXPERIMENTAL=""
|
||||
NBARGS=$[$NBARGS+$VARIANT_OPTID]
|
||||
variant__${VARIANTS_SHORT[$i]}__${VARIANTS_LONG[$i]//"-"/"_"}
|
||||
return 0
|
||||
fi
|
||||
done
|
||||
echo "$1" is not a valid variant
|
||||
variant_usage
|
||||
exit 1
|
||||
|
||||
}
|
||||
|
||||
function check_command_options {
|
||||
GIVEN_OPTIONS=$1
|
||||
declare -a MANDATORY_OPTIONS=("${!2}")
|
||||
if [ ${MANDATORY_OPTIONS[1]} -eq 0 ]
|
||||
then
|
||||
MANDATORY_OPTIONS[1]=${MANDATORY_OPTIONS[0]}
|
||||
fi
|
||||
OPTIONAL_OPTIONS=$3
|
||||
if [ $(($GIVEN_OPTIONS & ${MANDATORY_OPTIONS[0]} )) -ne ${MANDATORY_OPTIONS[0]} ] && [ $(($GIVEN_OPTIONS & ${MANDATORY_OPTIONS[1]} )) -ne ${MANDATORY_OPTIONS[1]} ]
|
||||
then
|
||||
echo "Syntax Error: missing option(s) for $4 command"
|
||||
${4//-/_}_usage
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ $(( $(($GIVEN_OPTIONS ^ ${MANDATORY_OPTIONS[0]})) | $OPTIONAL_OPTIONS )) -ne $(( $OPTIONAL_OPTIONS )) ] && [ $(( $(($GIVEN_OPTIONS ^ ${MANDATORY_OPTIONS[1]})) | $OPTIONAL_OPTIONS )) -ne $(( $OPTIONAL_OPTIONS )) ]
|
||||
then
|
||||
echo "Syntax Error: unknown option(s) for $4 command"
|
||||
${4//-/_}_usage
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
function check_ipv4addr {
|
||||
local ipaddr=$1
|
||||
local stat=1
|
||||
|
||||
if [[ $ipaddr =~ ^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3} ]]
|
||||
then
|
||||
OIFS=$IFS
|
||||
IFS='.'
|
||||
ipaddr=($ipaddr)
|
||||
IFS=$OIFS
|
||||
[[ ${ipaddr[0]} -le 255 && ${ipaddr[1]} -le 255 \
|
||||
&& ${ipaddr[2]} -le 255 && ${ipaddr[3]} -le 255 ]]
|
||||
stat=$?
|
||||
fi
|
||||
if [ $stat -ne 0 ]
|
||||
then
|
||||
echo $ipaddr " is not a valid ip V4 address"
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
function check_setvar {
|
||||
for i in ${AUTHORIZED_VAR[@]}
|
||||
do
|
||||
if [ "$1" = "$i" ]
|
||||
then
|
||||
echo "Setting $1 to $2..."
|
||||
export "$1"="$2"
|
||||
return 0
|
||||
fi
|
||||
done
|
||||
echo " $1 is not a variable you can set"
|
||||
setvar_usage
|
||||
exit 1
|
||||
}
|
||||
|
||||
platform_set
|
||||
MY_DIR=$(dirname $(readlink -f $0))
|
||||
. $MY_DIR/createVM.sh
|
||||
. $MY_DIR/buildOnVM.sh
|
||||
. $MY_DIR/waitBuildOnVM.sh
|
||||
. $MY_DIR/destroyAllRunningVM.sh
|
||||
. $MY_DIR/runTestOnVM.sh
|
||||
. $MY_DIR/reportBuildLocally.sh
|
||||
. $MY_DIR/reportTestLocally.sh
|
||||
|
||||
|
||||
if [ $# -lt 1 ]
|
||||
then
|
||||
echo "Syntax Error: too few arguments"
|
||||
echo ""
|
||||
top_usage
|
||||
exit 1
|
||||
fi
|
||||
|
||||
VM_TEMPLATE=ci-
|
||||
|
||||
|
||||
# look for ASN1 release in cmake directives
|
||||
# It will be the release used when building
|
||||
ASN1VEROPT=( `grep "set (RRC_ASN1_VERSION" CMakeLists.txt` )
|
||||
ASN1VER=${ASN1VEROPT[2]//\"}
|
||||
ASN1VER=${ASN1VER//)}
|
||||
unset ASN1VEROPT
|
||||
|
||||
# variable to identify and store the command (build, create ...)
|
||||
# command index in the COMMAND and COMMANDS_NAME arrays
|
||||
HELP_CMD=0
|
||||
CREATE_CMD=1
|
||||
BUILD_CMD=2
|
||||
WAIT_CMD=3
|
||||
DESTROY_CMD=4
|
||||
TEST_CMD=5
|
||||
REPORT_BUILD_CMD=6
|
||||
REPORT_TEST_CMD=7
|
||||
|
||||
COMMANDS_NAME=(help create build wait destroy test report-build report-test)
|
||||
|
||||
#COMMAND will be used to save the command entered as argument
|
||||
declare -A COMMAND
|
||||
for i in "${COMMANDS_NAME[@]}"
|
||||
do
|
||||
COMMAND[$i]=0
|
||||
done
|
||||
|
||||
# build the variant arrays
|
||||
declare -a VARIANTS_SHORT
|
||||
declare -a VARIANTS_LONG
|
||||
build_variant_arrays
|
||||
|
||||
#variables to process options, for each option we define a variable to store
|
||||
# its value and a bit mask, used to check allowed options depending on
|
||||
# the command
|
||||
|
||||
# The two following arrays must be consistent: a given index must point to the long and short options
|
||||
# of a given command
|
||||
SHORT_OPTIONS=( "jn" "id" "ws" "k" "D" "gu" "pu" "mr" "var" "notused" "sb" "sc" "tb" "tc" "br" "co" "epc" "sim")
|
||||
LONG_OPTIONS=( "job-name" "build-id" "workspace" "keep-vm-alive" "daemon" "git-url" "push" "merge-request"
|
||||
"variant" "notused" "src-branch" "src-commit" "target-branch" "target-commit" "branch" "commit"
|
||||
"external-epc" "sim-file")
|
||||
|
||||
JOB_NAME=XX
|
||||
JOB_NAME_OPTINDEX=0
|
||||
JOB_NAME_OPTID=1
|
||||
|
||||
BUILD_ID=XX
|
||||
BUILD_ID_OPTINDEX=1
|
||||
BUILD_ID_OPTID=2
|
||||
|
||||
JENKINS_WKSP_OPTINDEX=2
|
||||
JENKINS_WKSP_OPTID=4
|
||||
|
||||
KEEP_VM_ALIVE_OPTINDEX=3
|
||||
KEEP_VM_ALIVE_OPTID=8
|
||||
KEEP_VM_ALIVE=0
|
||||
|
||||
DAEMON_OPTINDEX=4
|
||||
DAEMON_OPTID=$((2**4))
|
||||
DAEMON=0
|
||||
|
||||
GITURL_OPTINDEX=5
|
||||
GITURL_OPTID=$((2**5))
|
||||
|
||||
PU_OPTINDEX=6
|
||||
PU_OPTID=$((2**6))
|
||||
PU_TRIG=0
|
||||
|
||||
MR_OPTINDEX=7
|
||||
MR_OPTID=$((2**7))
|
||||
MR_TRIG=0
|
||||
|
||||
VARIANT_OPTINDEX=8
|
||||
VARIANT_OPTID=$((2**8))
|
||||
|
||||
SB_OPTINDEX=10
|
||||
SB_OPTID=$((2**10))
|
||||
|
||||
SC_OPTINDEX=11
|
||||
SC_OPTID=$((2**11))
|
||||
|
||||
TB_OPTINDEX=12
|
||||
TB_OPTID=$((2**12))
|
||||
|
||||
TC_OPTINDEX=13
|
||||
TC_OPTID=$((2**13))
|
||||
|
||||
BR_OPTINDEX=14
|
||||
BR_OPTID=$((2**14))
|
||||
|
||||
CO_OPTINDEX=15
|
||||
CO_OPTID=$((2**15))
|
||||
|
||||
EPC_IPADDR_OPTINDEX=16
|
||||
EPC_IPADDR_OPTID=$((2**16))
|
||||
EPC_IPADDR=""
|
||||
|
||||
SIM_OPTINDEX=17
|
||||
SIM_OPTID=$((2**17))
|
||||
SIMFILE=""
|
||||
|
||||
RUN_OPTIONS="none"
|
||||
|
||||
|
||||
# list of variables that can be set via the --setvar option
|
||||
AUTHORIZED_VAR=("VM_OSREL RUN_EXPERIMENTAL OPTIONAL_APTCACHER TESTPLATFORM_OWNER")
|
||||
|
||||
|
||||
#variables to set which OS VM should use
|
||||
#if [ -f "/etc/os-release" ]
|
||||
#then
|
||||
# source /etc/os-release
|
||||
# VM_OS="$NAME"
|
||||
# VM_OSREL="$VERSION_CODENAME"
|
||||
# VM_ARCHI=`uname -m`
|
||||
#else
|
||||
VM_OS="ubuntu"
|
||||
VM_OSREL="xenial"
|
||||
VM_ARCHI="x86_64"
|
||||
#fi
|
||||
|
||||
|
||||
# variant option, ie the test variant which will be run triggers the
|
||||
# variables listed below, used to configure the VM and to define what this
|
||||
# VM will do. The variant can be specified by the --variant option or by a
|
||||
# -V<xx> option.
|
||||
VM_NAME=""
|
||||
VM_MEMORY=0
|
||||
VM_DISK=0
|
||||
VM_CPU=0
|
||||
ARCHIVES_LOC=""
|
||||
LOG_PATTERN=""
|
||||
NB_PATTERN_FILES=0
|
||||
BUILD_OPTIONS=""
|
||||
RUN_OPTIONS=""
|
||||
|
||||
|
||||
|
||||
# NARGS is used to check that only valid options are used for the given command
|
||||
# It is a bit mask, each bit set to 1 specifies the corresponding option
|
||||
# has been entered on the command line. MANDATORY_OPTMASK and ALLOWED_OPTMASK define
|
||||
# respectively the mandatory and optional parameters of the entered command
|
||||
NBARGS=0
|
||||
MANDATORY_OPTMASK=(0 0) # some command have two sets of mandatory options
|
||||
ALLOWED_OPTMASK=0
|
||||
|
||||
while [[ $# -gt 0 ]]
|
||||
do
|
||||
key="$1"
|
||||
|
||||
if [ "$(type -t $funcname)" != 'function' ]; then
|
||||
funcname=do_it_normal
|
||||
fi
|
||||
case $key in
|
||||
--debug)
|
||||
set -v
|
||||
set -x
|
||||
shift
|
||||
;;
|
||||
-h|--help|help)
|
||||
COMMAND["help"]=1
|
||||
# following word might specify the topic for the help request
|
||||
# but help can also be used without argument, so don't shift
|
||||
if [ "$2" != "" ] && [ "$(type -t ${2//-/_}_usage)" = 'function' ]
|
||||
then
|
||||
HELPCMD="${2//-/_}_usage full"
|
||||
fi
|
||||
shift
|
||||
;;
|
||||
create)
|
||||
COMMAND[$key]=1
|
||||
# For create, mandatory options: jn, id. Optional: variant
|
||||
MANDATORY_OPTMASK[0]=$(($JOB_NAME_OPTID + $BUILD_ID_OPTID ))
|
||||
ALLOWED_OPTMASK=$(($VARIANT_OPTID))
|
||||
# It is implied to keep the VM when creating it
|
||||
KEEP_VM_ALIVE=1
|
||||
shift
|
||||
;;
|
||||
build)
|
||||
COMMAND[$key]=1
|
||||
# For build, mandatory options: jn, id, ws. Optional: variant, k, D
|
||||
MANDATORY_OPTMASK[0]=$(($JOB_NAME_OPTID + $BUILD_ID_OPTID + $JENKINS_WKSP_OPTID))
|
||||
ALLOWED_OPTMASK=$(($KEEP_VM_ALIVE_OPTID + $DAEMON_OPTID + $VARIANT_OPTID))
|
||||
shift
|
||||
;;
|
||||
wait)
|
||||
# For test, mandatory options: jn, id, ws. Optional: variant, k
|
||||
COMMAND[$key]=1
|
||||
MANDATORY_OPTMASK[0]=$(($JOB_NAME_OPTID + $BUILD_ID_OPTID + $JENKINS_WKSP_OPTID))
|
||||
ALLOWED_OPTMASK=$(($KEEP_VM_ALIVE_OPTID + $VARIANT_OPTID))
|
||||
shift
|
||||
;;
|
||||
test)
|
||||
COMMAND[$key]=1
|
||||
# For test, mandatory options: jn, id, ws. Optional: variant, k, epc
|
||||
MANDATORY_OPTMASK[0]=$(($JOB_NAME_OPTID + $BUILD_ID_OPTID + $JENKINS_WKSP_OPTID))
|
||||
ALLOWED_OPTMASK=$(($KEEP_VM_ALIVE_OPTID + $VARIANT_OPTID + $EPC_IPADDR_OPTID + $SIM_OPTID))
|
||||
shift
|
||||
;;
|
||||
destroy)
|
||||
COMMAND[$key]=1
|
||||
# For destroy, mandatory options: jn, id.
|
||||
MANDATORY_OPTMASK[0]=$(($JOB_NAME_OPTID + $BUILD_ID_OPTID))
|
||||
shift
|
||||
;;
|
||||
report-build)
|
||||
COMMAND[$key]=1
|
||||
# For report-build, mandatory options: jn, id, ws, gu, pu, br,co.
|
||||
# or: jn, id, ws, gu, mr, sb, sc, tb, tc.
|
||||
MANDATORY_OPTMASK[0]=$(($JOB_NAME_OPTID + $BUILD_ID_OPTID + $JENKINS_WKSP_OPTID + $GITURL_OPTID + $PU_OPTID + $BR_OPTID + $CO_OPTID))
|
||||
MANDATORY_OPTMASK[1]=$(($JOB_NAME_OPTID + $BUILD_ID_OPTID + $JENKINS_WKSP_OPTID + $GITURL_OPTID + $MR_OPTID + $SB_OPTID + $SC_OPTID))
|
||||
MANDATORY_OPTMASK[1]=$(( ${MANDATORY_OPTMASK[1]} + $TB_OPTID + $TC_OPTID))
|
||||
shift
|
||||
;;
|
||||
report-test)
|
||||
COMMAND[$key]=1
|
||||
# For report-test, mandatory options: jn, id, ws, gu, pu, br,co.
|
||||
# or: jn, id, ws, gu, mr, sb, sc, tb, tc.
|
||||
MANDATORY_OPTMASK[0]=$(($JOB_NAME_OPTID + $BUILD_ID_OPTID + $JENKINS_WKSP_OPTID))
|
||||
MANDATORY_OPTMASK[0]=$((${MANDATORY_OPTMASK[0]} + $GITURL_OPTID + $PU_OPTID + $BR_OPTID + $CO_OPTID))
|
||||
MANDATORY_OPTMASK[1]=$(($JOB_NAME_OPTID + $BUILD_ID_OPTID + $JENKINS_WKSP_OPTID))
|
||||
MANDATORY_OPTMASK[1]=$((${MANDATORY_OPTMASK[1]} + GITURL_OPTID + $MR_OPTID + $SB_OPTID + $SC_OPTID))
|
||||
MANDATORY_OPTMASK[1]=$((${MANDATORY_OPTMASK[1]} + $TB_OPTID + $TC_OPTID))
|
||||
shift
|
||||
;;
|
||||
-jn|--job-name)
|
||||
JOB_NAME="$2"
|
||||
NBARGS=$[$NBARGS+$JOB_NAME_OPTID]
|
||||
shift
|
||||
shift
|
||||
;;
|
||||
-id|--build-id)
|
||||
BUILD_ID="$2"
|
||||
NBARGS=$[$NBARGS+$BUILD_ID_OPTID]
|
||||
shift
|
||||
shift
|
||||
;;
|
||||
-ws|--workspace)
|
||||
JENKINS_WKSP="$2"
|
||||
NBARGS=$[$NBARGS+$JENKINS_WKSP_OPTID]
|
||||
shift
|
||||
shift
|
||||
;;
|
||||
-k|--keep-vm-alive)
|
||||
KEEP_VM_ALIVE=1
|
||||
NBARGS=$[$NBARGS+$KEEP_VM_ALIVE_OPTID]
|
||||
shift
|
||||
;;
|
||||
-D|--daemon)
|
||||
DAEMON=1
|
||||
NBARGS=$[$NBARGS+$DAEMON_OPTID]
|
||||
shift
|
||||
;;
|
||||
-gu|--git-url)
|
||||
GIT_URL="$2"
|
||||
NBARGS=$[$NBARGS+$GITURL_OPTID]
|
||||
shift
|
||||
shift
|
||||
;;
|
||||
--trigger)
|
||||
TRIG="$2"
|
||||
case $TRIG in
|
||||
merge-request)
|
||||
MR_TRIG=1
|
||||
NBARGS=$[$NBARGS+$MR_OPTID]
|
||||
;;
|
||||
push)
|
||||
PU_TRIG=1
|
||||
NBARGS=$[$NBARGS+$PU_OPTID]
|
||||
;;
|
||||
*)
|
||||
echo ""
|
||||
echo "Syntax Error: Invalid Trigger option -> $TRIG"
|
||||
echo ""
|
||||
trigger_usage
|
||||
exit
|
||||
;;
|
||||
esac
|
||||
shift
|
||||
shift
|
||||
;;
|
||||
-mr|--merge-request)
|
||||
MR_TRIG=1
|
||||
NBARGS=$[$NBARGS+$MR_OPTID]
|
||||
shift
|
||||
;;
|
||||
-pu|--push)
|
||||
PU_TRIG=1
|
||||
NBARGS=$[$NBARGS+$PU_OPTID]
|
||||
shift
|
||||
;;
|
||||
-sb|--src-branch)
|
||||
SOURCE_BRANCH="$2"
|
||||
NBARGS=$[$NBARGS+$SB_OPTID]
|
||||
shift
|
||||
shift
|
||||
;;
|
||||
-sc|--src-commit)
|
||||
SOURCE_COMMIT_ID="$2"
|
||||
NBARGS=$[$NBARGS+$SC_OPTID]
|
||||
shift
|
||||
shift
|
||||
;;
|
||||
-tb|--target-branch)
|
||||
TARGET_BRANCH="$2"
|
||||
NBARGS=$[$NBARGS+$TB_OPTID]
|
||||
shift
|
||||
shift
|
||||
;;
|
||||
-tc|--target-commit)
|
||||
TARGET_COMMIT_ID="$2"
|
||||
NBARGS=$[$NBARGS+$TC_OPTID]
|
||||
shift
|
||||
shift
|
||||
;;
|
||||
-br|--branch)
|
||||
SOURCE_BRANCH="$2"
|
||||
NBARGS=$[$NBARGS+$BR_OPTID]
|
||||
shift
|
||||
shift
|
||||
;;
|
||||
-co|--commit)
|
||||
SOURCE_COMMIT_ID="$2"
|
||||
NBARGS=$[$NBARGS+$CO_OPTID]
|
||||
shift
|
||||
shift
|
||||
;;
|
||||
-epc|--external-epc)
|
||||
check_ipv4addr "$2"
|
||||
check_ipv4addr "$3"
|
||||
EPC_IPADDR="$2"
|
||||
EPC_TUN_IPADDR="$3"
|
||||
NBARGS=$[$NBARGS+$EPC_IPADDR_OPTID]
|
||||
shift
|
||||
shift
|
||||
shift
|
||||
;;
|
||||
-sim|--sim-file)
|
||||
SIMFILE="$2"
|
||||
NBARGS=$[$NBARGS+$SIM_OPTID]
|
||||
shift
|
||||
shift
|
||||
;;
|
||||
--setvar_*)
|
||||
check_setvar "${key:9}" "$2"
|
||||
shift
|
||||
shift
|
||||
;;
|
||||
-v[0-9] | -v[0-9][0-9])
|
||||
check_set_variant ${key//"-"}
|
||||
shift
|
||||
;;
|
||||
-var|--variant)
|
||||
variant="$2"
|
||||
check_set_variant ${2}
|
||||
shift
|
||||
shift
|
||||
;;
|
||||
*)
|
||||
echo "Syntax Error: unknown option: $key"
|
||||
echo ""
|
||||
top_usage
|
||||
exit 1
|
||||
esac
|
||||
done
|
||||
|
||||
i=0
|
||||
for (( COUNT=1 ; COUNT<${#COMMAND[@]} ; COUNT++ ))
|
||||
do
|
||||
if [ ${COMMAND[${COMMANDS_NAME[$COUNT]}]} -eq 1 ]
|
||||
then
|
||||
COMMAND_KEY[$i]=${COMMANDS_NAME[$COUNT]}
|
||||
(( i++ ))
|
||||
fi
|
||||
done
|
||||
|
||||
if [ ${COMMAND["help"]} -eq 1 ]
|
||||
then
|
||||
if [ ${#COMMAND_KEY[@]} -ne 1 ] && [ "$HELPCMD" == "" ]
|
||||
then
|
||||
top_usage
|
||||
elif [ "$HELPCMD" != "" ]
|
||||
then
|
||||
$HELPCMD
|
||||
else
|
||||
${COMMAND_KEY[0]//-/_}_usage
|
||||
fi
|
||||
exit 0
|
||||
else
|
||||
if [ ${#COMMAND_KEY[@]} -gt 1 ]
|
||||
then
|
||||
echo "Syntax Error, too many commands: ${COMMAND_KEY[@]}"
|
||||
top_usage
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ -z "${COMMAND_KEY[0]}" ]
|
||||
then
|
||||
echo "Syntax Error: no command, specify one of: ${COMMANDS_NAME[@]}"
|
||||
top_usage
|
||||
exit 1
|
||||
fi
|
||||
|
||||
check_command_options $NBARGS MANDATORY_OPTMASK[@] $ALLOWED_OPTMASK ${COMMAND_KEY[0]}
|
||||
fi
|
||||
|
||||
if [ ${COMMAND[${COMMANDS_NAME[$REPORT_BUILD_CMD]}]} -ne 1 ] && [ ${COMMAND[${COMMANDS_NAME[$REPORT_TEST_CMD]}]} -ne 1 ]
|
||||
then
|
||||
# Checking uvt-kvm is installed
|
||||
UVT_KVM_PATH=`which uvt-kvm | grep -c uvt-kvm`
|
||||
if [ $UVT_KVM_PATH -eq 0 ]
|
||||
then
|
||||
echo "Error: uvt-kvm is not installed"
|
||||
top_usage
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ "$JOB_NAME" == "XX" ] || [ "$BUILD_ID" == "XX" ]
|
||||
then
|
||||
VM_TEMPLATE=ci-
|
||||
else
|
||||
VM_TEMPLATE=${JOB_NAME}-b${BUILD_ID}-
|
||||
fi
|
||||
# set default variant
|
||||
if [ "$VM_NAME" = "" ]
|
||||
then
|
||||
check_set_variant "v1"
|
||||
fi
|
||||
VM_NAME=`echo $VM_NAME | sed -e "s#ci-#$VM_TEMPLATE#"`
|
||||
VM_CMDS=${VM_NAME}_cmds.txt
|
||||
ARCHIVES_LOC=${JENKINS_WKSP}/archives/${ARCHIVES_LOC}
|
||||
|
||||
STATUS=0
|
||||
if [ ${COMMAND[${COMMANDS_NAME[$CREATE_CMD]}]} -eq 1 ]
|
||||
then
|
||||
if [[ "$BUILD_OPTIONS" = "" ]]
|
||||
then
|
||||
echo "$VM_NAME is not a build variant"
|
||||
exit 0
|
||||
else
|
||||
create_vm
|
||||
fi
|
||||
fi
|
||||
if [ ${COMMAND[${COMMANDS_NAME[$BUILD_CMD]}]} -eq 1 ]
|
||||
then
|
||||
if [[ "$BUILD_OPTIONS" = "" ]]
|
||||
then
|
||||
echo " $VM_NAME is not a build variant"
|
||||
exit 0
|
||||
else
|
||||
build_on_vm
|
||||
fi
|
||||
if [ $DAEMON -eq 0 ] && [ $STATUS -eq 0 ]
|
||||
then
|
||||
check_on_vm_build
|
||||
fi
|
||||
fi
|
||||
if [ ${COMMAND[${COMMANDS_NAME[$WAIT_CMD]}]} -eq 1 ]
|
||||
then
|
||||
if [[ "$BUILD_OPTIONS" = "" ]]
|
||||
then
|
||||
echo "$VM_NAME is not a build variant"
|
||||
exit 0
|
||||
else
|
||||
wait_on_vm_build
|
||||
fi
|
||||
if [ $STATUS -eq 0 ]
|
||||
then
|
||||
check_on_vm_build
|
||||
fi
|
||||
fi
|
||||
if [ ${COMMAND[${COMMANDS_NAME[$TEST_CMD]}]} -eq 1 ]
|
||||
then
|
||||
# variant with EXPERIMENTAL variable set to true won't run and will be
|
||||
# considered OK, except if --setvar_RUN_EXPERIMENTAL option has been set to true
|
||||
if [ "$EXPERIMENTAL" = "true" ] && [ "$RUN_EXPERIMENTAL" != "true" ]
|
||||
then
|
||||
echo "Currently $VM_NAME Testing is not implemented / enabled"
|
||||
echo "remove EXPERIMENTAL variable definition from this variant"
|
||||
echo " or use option --setvar_RUN_EXPERIMENTAL=true to enforce testing it"
|
||||
echo "STATUS seems OK"
|
||||
exit $STATUS
|
||||
fi
|
||||
|
||||
ARCHIVES_LOC=${ARCHIVES_LOC}/test
|
||||
run_test_on_vm
|
||||
fi
|
||||
if [ ${COMMAND[${COMMANDS_NAME[$DESTROY_CMD]}]} -eq 1 ]
|
||||
then
|
||||
destroy_vm
|
||||
fi
|
||||
if [ ${COMMAND[${COMMANDS_NAME[$REPORT_BUILD_CMD]}]} -eq 1 ]
|
||||
then
|
||||
report_build
|
||||
fi
|
||||
if [ ${COMMAND[${COMMANDS_NAME[$REPORT_TEST_CMD]}]} -eq 1 ]
|
||||
then
|
||||
report_test
|
||||
fi
|
||||
|
||||
# Did command pass or fail?
|
||||
if [ $STATUS -eq 0 ]
|
||||
then
|
||||
echo "STATUS seems OK"
|
||||
else
|
||||
echo "STATUS failed?"
|
||||
fi
|
||||
exit $STATUS
|
||||
@@ -38,11 +38,6 @@ EPCSourceCodePath : s
|
||||
EPCType : t
|
||||
EPCContainerPrefix : u
|
||||
|
||||
ADBIPAddress : v
|
||||
ADBUserName : w
|
||||
ADBType : x
|
||||
ADBPassword : y
|
||||
|
||||
XMLTestFile : z
|
||||
|
||||
UEIPAddress : qqq
|
||||
|
||||
@@ -69,13 +69,6 @@ EPC:
|
||||
EPCType : t
|
||||
EPCContainerPrefix : u
|
||||
|
||||
ADB:
|
||||
ADBIPAddress : v
|
||||
ADBUserName : w
|
||||
ADBType : x
|
||||
ADBPassword : y
|
||||
|
||||
|
||||
UE:
|
||||
UE_inst_0:
|
||||
name : UE_1
|
||||
|
||||
@@ -38,6 +38,7 @@ import os
|
||||
import time
|
||||
from multiprocessing import Process, Lock, SimpleQueue
|
||||
import yaml
|
||||
import cls_cmd
|
||||
|
||||
|
||||
#-----------------------------------------------------------
|
||||
@@ -96,6 +97,9 @@ class RANManagement():
|
||||
#checkers from xml
|
||||
self.ran_checkers={}
|
||||
self.cmd_prefix = '' # prefix before {lte,nr}-softmodem
|
||||
self.node = ''
|
||||
self.command = ''
|
||||
self.command_fail = False
|
||||
|
||||
|
||||
#-----------------------------------------------------------
|
||||
@@ -128,20 +132,16 @@ class RANManagement():
|
||||
mySSH = SSH.SSHConnection()
|
||||
mySSH.open(lIpAddr, lUserName, lPassWord)
|
||||
|
||||
# Check if we build an 5G-NR gNB or an LTE eNB or an OCP eNB
|
||||
result = re.search('--eNBocp', self.Build_eNB_args)
|
||||
# Check if we build an 5G-NR gNB or an LTE eNB
|
||||
result = re.search('--RU', self.Build_eNB_args)
|
||||
if result is not None:
|
||||
self.air_interface[self.eNB_instance] = 'ocp-enb'
|
||||
self.air_interface[self.eNB_instance] = 'oairu'
|
||||
else:
|
||||
result = re.search('--RU', self.Build_eNB_args)
|
||||
result = re.search('--gNB', self.Build_eNB_args)
|
||||
if result is not None:
|
||||
self.air_interface[self.eNB_instance] = 'oairu'
|
||||
self.air_interface[self.eNB_instance] = 'nr-softmodem'
|
||||
else:
|
||||
result = re.search('--gNB', self.Build_eNB_args)
|
||||
if result is not None:
|
||||
self.air_interface[self.eNB_instance] = 'nr-softmodem'
|
||||
else:
|
||||
self.air_interface[self.eNB_instance] = 'lte-softmodem'
|
||||
self.air_interface[self.eNB_instance] = 'lte-softmodem'
|
||||
|
||||
# Worakround for some servers, we need to erase completely the workspace
|
||||
if self.Build_eNB_forced_workspace_cleanup:
|
||||
@@ -220,7 +220,7 @@ class RANManagement():
|
||||
HTML.CreateHtmlTestRow(self.Build_eNB_args, 'OK', CONST.ALL_PROCESSES_OK)
|
||||
self.backgroundBuildTestId[int(self.eNB_instance)] = self.testCase_id
|
||||
return
|
||||
mySSH.command('stdbuf -o0 ./build_oai ' + self.Build_eNB_args + ' 2>&1 | stdbuf -o0 tee compile_oai_enb.log', 'Bypassing the Tests|build have failed', 1500)
|
||||
mySSH.command('stdbuf -o0 ./build_oai ' + self.Build_eNB_args + ' 2>&1 | stdbuf -o0 tee compile_oai_enb.log', 'BUILD SHOULD BE SUCCESSFUL|build have failed', 900)
|
||||
mySSH.close()
|
||||
self.checkBuildeNB(lIpAddr, lUserName, lPassWord, lSourcePath, self.testCase_id, HTML)
|
||||
|
||||
@@ -259,6 +259,26 @@ class RANManagement():
|
||||
mySSH.close()
|
||||
self.checkBuildeNB(lIpAddr, lUserName, lPassWord, lSourcePath, self.backgroundBuildTestId[int(self.eNB_instance)], HTML)
|
||||
|
||||
def CustomCommand(self, HTML):
|
||||
cmd = cls_cmd.getConnection(self.node)
|
||||
ret = cmd.run(self.command)
|
||||
cmd.close()
|
||||
logging.debug(f'CustomCommand: {self.command} returnCode: {ret.returncode}')
|
||||
status = 'OK'
|
||||
message = []
|
||||
if ret.returncode != 0 and not self.command_fail:
|
||||
message = [ret.stdout]
|
||||
logging.warning(f'CustomCommand output: {message}')
|
||||
status = 'Warning'
|
||||
if self.command_fail: # important command since it would make the pipeline fail, so show output in HTML
|
||||
message = [ret.stdout]
|
||||
if ret.returncode != 0 and self.command_fail:
|
||||
message = [ret.stdout]
|
||||
logging.error(f'CustomCommand failed: output: {message}')
|
||||
status = 'KO'
|
||||
self.prematureExit = True
|
||||
HTML.CreateHtmlTestRowQueue(self.command, status, message)
|
||||
|
||||
def checkBuildeNB(self, lIpAddr, lUserName, lPassWord, lSourcePath, testcaseId, HTML):
|
||||
HTML.testCase_id=testcaseId
|
||||
|
||||
@@ -268,7 +288,7 @@ class RANManagement():
|
||||
mySSH.command('ls ran_build/build', '\$', 3)
|
||||
mySSH.command('ls ran_build/build', '\$', 3)
|
||||
|
||||
#check if we have the build corresponding to the air interface keywords (nr-softmode, lte-softmodem, ocp-enb)
|
||||
#check if we have the build corresponding to the air interface keywords (nr-softmode, lte-softmodem)
|
||||
logging.info('CHECK Build with IP='+lIpAddr+' SourcePath='+lSourcePath)
|
||||
result = re.search(self.air_interface[self.eNB_instance], mySSH.getBefore())
|
||||
if result is None:
|
||||
@@ -347,25 +367,9 @@ class RANManagement():
|
||||
cwd = os.getcwd()
|
||||
mySSH.copyout(lIpAddr,lUserName,lPassWord, cwd + "/active_net_interfaces.awk", "/tmp")
|
||||
|
||||
#reboot USRP if requested in xml
|
||||
if self.USRPIPAddress!='':
|
||||
logging.debug('USRP '+ self.USRPIPAddress +': reboot request')
|
||||
mySSH.open(lIpAddr, lUserName, lPassWord)
|
||||
cmd2usrp='ssh root@'+self.USRPIPAddress+' reboot'
|
||||
mySSH.command2(cmd2usrp,1)
|
||||
mySSH.close()
|
||||
logging.debug('Waiting for USRP to be ready')
|
||||
time.sleep(120)
|
||||
|
||||
|
||||
if (self.pStatus < 0):
|
||||
HTML.CreateHtmlTestRow(self.air_interface[self.eNB_instance] + ' ' + self.Initialize_eNB_args, 'KO', self.pStatus)
|
||||
HTML.CreateHtmlTabFooter(False)
|
||||
sys.exit(1)
|
||||
|
||||
#Get pcap on enb and/or gnb if enabled in the xml
|
||||
if self.eNB_Trace=='yes':
|
||||
if ((self.air_interface[self.eNB_instance] == 'lte-softmodem') or (self.air_interface[self.eNB_instance] == 'ocp-enb')):
|
||||
if self.air_interface[self.eNB_instance] == 'lte-softmodem':
|
||||
pcapfile_prefix="enb_"
|
||||
else:
|
||||
pcapfile_prefix="gnb_"
|
||||
@@ -419,16 +423,6 @@ class RANManagement():
|
||||
result = re.search('^rru|^rcc|^du.band', str(config_file))
|
||||
if result is not None:
|
||||
rruCheck = True
|
||||
# do not reset board twice in IF4.5 case
|
||||
result = re.search('^rru|^enb|^du.band', str(config_file))
|
||||
if result is not None:
|
||||
mySSH.command('echo ' + lPassWord + ' | sudo -S uhd_find_devices', '\$', 180)
|
||||
result = re.search('type: b200', mySSH.getBefore())
|
||||
if result is not None:
|
||||
logging.debug('Found a B2xx device --> resetting it')
|
||||
mySSH.command('echo ' + lPassWord + ' | sudo -S b2xx_fx3_utils --reset-device', '\$', 10)
|
||||
# Reloading FGPA bin firmware
|
||||
mySSH.command('echo ' + lPassWord + ' | sudo -S uhd_find_devices', '\$', 180)
|
||||
# Make a copy and adapt to EPC / eNB IP addresses
|
||||
mySSH.command('cp ' + full_config_file + ' ' + ci_full_config_file, '\$', 5)
|
||||
localMmeIpAddr = EPC.MmeIPAddress
|
||||
@@ -460,7 +454,7 @@ class RANManagement():
|
||||
|
||||
#hack UHD_RFNOC_DIR variable for gNB / N310 on RHEL8 server:
|
||||
#if the USRP address is in the xml then we are using an eth USRP (N3xx)
|
||||
if (self.air_interface[self.eNB_instance] == 'lte-softmodem') or (self.air_interface[self.eNB_instance] == 'ocp-enb'):
|
||||
if self.air_interface[self.eNB_instance] == 'lte-softmodem':
|
||||
gNB = False
|
||||
else:
|
||||
gNB = True
|
||||
@@ -476,7 +470,7 @@ class RANManagement():
|
||||
monitor_file='../ci-scripts/stats_monitor.py'
|
||||
conf_file='../ci-scripts/stats_monitor_conf.yaml'
|
||||
if self.eNB_Stats=='yes':
|
||||
if (self.air_interface[self.eNB_instance] == 'lte-softmodem') or (self.air_interface[self.eNB_instance] == 'ocp-enb'):
|
||||
if self.air_interface[self.eNB_instance] == 'lte-softmodem':
|
||||
mySSH.command('echo $USER; nohup python3 ' + monitor_file + ' ' + conf_file + ' ' + self.testCase_id + ' enb 2>&1 > enb_stats_monitor_execution.log &', '\$', 5)
|
||||
else:
|
||||
mySSH.command('echo $USER; nohup python3 ' + monitor_file + ' ' + conf_file + ' ' + self.testCase_id + ' gnb 2>&1 > gnb_stats_monitor_execution.log &', '\$', 5)
|
||||
@@ -499,7 +493,7 @@ class RANManagement():
|
||||
mySSH.command('killall --signal SIGKILL record', '\$', 5)
|
||||
mySSH.close()
|
||||
doLoop = False
|
||||
logging.error('\u001B[1;37;41m eNB/gNB/ocp-eNB logging system did not show got sync! \u001B[0m')
|
||||
logging.error('\u001B[1;37;41m eNB/gNB logging system did not show got sync! \u001B[0m')
|
||||
HTML.CreateHtmlTestRow(self.air_interface[self.eNB_instance] + ' -O ' + config_file + extra_options, 'KO', CONST.ALL_PROCESSES_OK)
|
||||
# In case of T tracer recording, we need to kill tshark on EPC side
|
||||
localEpcIpAddr = EPC.IPAddress
|
||||
@@ -556,7 +550,7 @@ class RANManagement():
|
||||
|
||||
|
||||
HTML.CreateHtmlTestRow(f'{self.cmd_prefix} {self.air_interface[self.eNB_instance]} -O {config_file} {extra_options}', 'OK', CONST.ALL_PROCESSES_OK)
|
||||
logging.debug('\u001B[1m Initialize eNB/gNB/ocp-eNB Completed\u001B[0m')
|
||||
logging.debug('\u001B[1m Initialize eNB/gNB Completed\u001B[0m')
|
||||
|
||||
def CheckeNBProcess(self, status_queue):
|
||||
try:
|
||||
@@ -617,19 +611,19 @@ class RANManagement():
|
||||
mySSH = SSH.SSHConnection()
|
||||
mySSH.open(lIpAddr, lUserName, lPassWord)
|
||||
mySSH.command('cd ' + lSourcePath + '/cmake_targets', '\$', 5)
|
||||
if (self.air_interface[self.eNB_instance] == 'lte-softmodem') or (self.air_interface[self.eNB_instance] == 'ocp-enb'):
|
||||
if self.air_interface[self.eNB_instance] == 'lte-softmodem':
|
||||
nodeB_prefix = 'e'
|
||||
else:
|
||||
nodeB_prefix = 'g'
|
||||
mySSH.command('stdbuf -o0 ps -aux | grep --color=never -e softmodem -e ocp-enb | grep -v grep', '\$', 5)
|
||||
result = re.search('(-softmodem|ocp)', mySSH.getBefore())
|
||||
mySSH.command('stdbuf -o0 ps -aux | grep --color=never -e softmodem | grep -v grep', '\$', 5)
|
||||
result = re.search('-softmodem', mySSH.getBefore())
|
||||
if result is not None:
|
||||
mySSH.command('echo ' + lPassWord + ' | sudo -S killall --signal SIGINT -r .*-softmodem ocp-enb || true', '\$', 5)
|
||||
mySSH.command('echo ' + lPassWord + ' | sudo -S killall --signal SIGINT -r .*-softmodem || true', '\$', 5)
|
||||
time.sleep(10)
|
||||
mySSH.command('stdbuf -o0 ps -aux | grep --color=never -e softmodem -e ocp-enb | grep -v grep', '\$', 5)
|
||||
result = re.search('(-softmodem|ocp)', mySSH.getBefore())
|
||||
mySSH.command('stdbuf -o0 ps -aux | grep --color=never -e softmodem | grep -v grep', '\$', 5)
|
||||
result = re.search('-softmodem', mySSH.getBefore())
|
||||
if result is not None:
|
||||
mySSH.command('echo ' + lPassWord + ' | sudo -S killall --signal SIGKILL -r .*-softmodem ocp-enb || true', '\$', 5)
|
||||
mySSH.command('echo ' + lPassWord + ' | sudo -S killall --signal SIGKILL -r .*-softmodem || true', '\$', 5)
|
||||
time.sleep(5)
|
||||
mySSH.command('rm -f my-lte-softmodem-run' + str(self.eNB_instance) + '.sh', '\$', 5)
|
||||
#stopping tshark (valid if eNB and enabled in xml, will not harm otherwise)
|
||||
@@ -1091,7 +1085,7 @@ class RANManagement():
|
||||
|
||||
#post processing depending on the node type
|
||||
if not nodeB_prefix_found:
|
||||
if (self.air_interface[self.eNB_instance] == 'lte-softmodem') or (self.air_interface[self.eNB_instance] == 'ocp-enb'):
|
||||
if self.air_interface[self.eNB_instance] == 'lte-softmodem':
|
||||
nodeB_prefix = 'e'
|
||||
else:
|
||||
nodeB_prefix = 'g'
|
||||
|
||||
@@ -32,488 +32,34 @@
|
||||
|
||||
|
||||
#Author Remi
|
||||
import boto3
|
||||
import shlex
|
||||
import subprocess
|
||||
import json #json structures
|
||||
import datetime #now() and date formating
|
||||
from datetime import datetime
|
||||
import re
|
||||
import gitlab
|
||||
import yaml
|
||||
import os
|
||||
import time
|
||||
import sys
|
||||
|
||||
from sqlconnect import SQLConnect
|
||||
|
||||
#-----------------------------------------------------------
|
||||
# Class Declaration
|
||||
#-----------------------------------------------------------
|
||||
|
||||
class Dashboard:
|
||||
def __init__(self):
|
||||
|
||||
|
||||
#init with data sources : git, yaml config file, test results databases
|
||||
#init with data sources : git, test results databases
|
||||
print("Collecting Data")
|
||||
cmd="""curl --silent "https://gitlab.eurecom.fr/api/v4/projects/oai%2Fopenairinterface5g/merge_requests?state=opened&per_page=100" """
|
||||
self.git = self.__getGitData(cmd) #git data from Gitlab
|
||||
self.tests = self.__loadCfg('ran_dashboard_cfg.yaml') #tests table setup from yaml
|
||||
self.db = self.__loadFromDB() #test results from database
|
||||
self.mr_list=[] #mr list in string format
|
||||
for x in range(len(self.git)):
|
||||
self.mr_list.append(str(self.git[x]['iid']))
|
||||
|
||||
def __loadCfg(self,yaml_file):
|
||||
with open(yaml_file,'r') as f:
|
||||
tests = yaml.load(f)
|
||||
return tests
|
||||
|
||||
def __getGitData(self,cmd):
|
||||
#cmd="""curl --silent "https://gitlab.eurecom.fr/api/v4/projects/oai%2Fopenairinterface5g/merge_requests?state=opened&per_page=100" """
|
||||
process = subprocess.Popen(shlex.split(cmd), stdout=subprocess.PIPE)
|
||||
output = process.stdout.readline()
|
||||
tmp=output.decode("utf-8")
|
||||
d = json.loads(tmp)
|
||||
return d
|
||||
|
||||
def __loadFromDB(self):
|
||||
mr_list=[]
|
||||
for x in range(len(self.git)):
|
||||
mr_list.append(str(self.git[x]['iid']))
|
||||
mydb=SQLConnect()
|
||||
for MR in mr_list:
|
||||
mydb.get(MR)
|
||||
mydb.close_connection()
|
||||
return mydb.data
|
||||
|
||||
def singleMR_initHTML(self, date):
|
||||
self.f_html.write('<!DOCTYPE html>\n')
|
||||
self.f_html.write('<head>\n')
|
||||
self.f_html.write('<link rel="stylesheet" href="../test_styles.css">\n')
|
||||
self.f_html.write('<title>Test Dashboard</title>\n')
|
||||
self.f_html.write('</head>\n')
|
||||
self.f_html.write('<br>\n')
|
||||
self.f_html.write('<br>\n')
|
||||
self.f_html.write('<table>\n')
|
||||
self.f_html.write('<tr>\n')
|
||||
self.f_html.write('<td class="Main">OAI RAN TEST Status Dashboard</td>\n')
|
||||
self.f_html.write('</td>\n')
|
||||
self.f_html.write('<tr>\n')
|
||||
self.f_html.write('<tr></tr>\n')
|
||||
self.f_html.write('<tr>\n')
|
||||
self.f_html.write('<td class="Date">Update : '+date+'</td>\n')
|
||||
self.f_html.write('</td>\n')
|
||||
self.f_html.write('</tr>\n')
|
||||
self.f_html.write('</table>\n')
|
||||
self.f_html.write('<br>\n')
|
||||
self.f_html.write('<br>\n')
|
||||
|
||||
|
||||
def Test_initHTML(self, date):
|
||||
self.f_html.write('<!DOCTYPE html>\n')
|
||||
self.f_html.write('<head>\n')
|
||||
self.f_html.write('<link rel="stylesheet" href="test_styles.css">\n')
|
||||
self.f_html.write('<title>Test Dashboard</title>\n')
|
||||
self.f_html.write('</head>\n')
|
||||
self.f_html.write('<br>\n')
|
||||
self.f_html.write('<br>\n')
|
||||
self.f_html.write('<table>\n')
|
||||
self.f_html.write('<tr>\n')
|
||||
self.f_html.write('<td class="Main">OAI RAN TEST Status Dashboard</td>\n')
|
||||
self.f_html.write('</td>\n')
|
||||
self.f_html.write('<tr>\n')
|
||||
self.f_html.write('<td class="DashLink"> <a href="https://oairandashboard.s3.eu-west-1.amazonaws.com/index.html">Merge Requests Dashboard</a></td>\n')
|
||||
self.f_html.write('</td>\n')
|
||||
self.f_html.write('<tr></tr>\n')
|
||||
self.f_html.write('<tr>\n')
|
||||
self.f_html.write('<td class="Date">Update : '+date+'</td>\n')
|
||||
self.f_html.write('</td>\n')
|
||||
self.f_html.write('</tr>\n')
|
||||
self.f_html.write('</table>\n')
|
||||
self.f_html.write('<br>\n')
|
||||
self.f_html.write('<br>\n')
|
||||
|
||||
def Test_terminateHTML(self):
|
||||
self.f_html.write('</body>\n')
|
||||
self.f_html.write('</html>\n')
|
||||
self.f_html.close()
|
||||
|
||||
|
||||
def MR_initHTML(self,date):
|
||||
self.f_html.write('<!DOCTYPE html>\n')
|
||||
self.f_html.write('<head>\n')
|
||||
self.f_html.write('<link rel="stylesheet" href="mr_styles.css">\n')
|
||||
self.f_html.write('<title>MR Dashboard</title>\n')
|
||||
self.f_html.write('</head>\n')
|
||||
self.f_html.write('<br>\n')
|
||||
self.f_html.write('<br>\n')
|
||||
self.f_html.write('<table>\n')
|
||||
self.f_html.write('<tr>\n')
|
||||
self.f_html.write('<td class="Main">OAI RAN MR Status Dashboard</td>\n')
|
||||
self.f_html.write('</td>\n')
|
||||
self.f_html.write('<tr>\n')
|
||||
self.f_html.write('<td class="DashLink"> <a href="https://oaitestdashboard.s3.eu-west-1.amazonaws.com/index.html">Tests Dashboard</a></td>\n')
|
||||
self.f_html.write('</td>\n')
|
||||
self.f_html.write('<tr></tr>\n')
|
||||
self.f_html.write('<tr>\n')
|
||||
self.f_html.write('<td class="Date">Update : '+date+'</td>\n')
|
||||
self.f_html.write('</td>\n')
|
||||
self.f_html.write('</tr>\n')
|
||||
self.f_html.write('</table>\n')
|
||||
self.f_html.write('<br>\n')
|
||||
self.f_html.write('<br>\n')
|
||||
self.f_html.write('<table class="MR_Table">\n')
|
||||
self.f_html.write('<tr>\n')
|
||||
self.f_html.write('<th class="MR">MR</th>\n')
|
||||
self.f_html.write('<th class="CREATED_AT">Created_At</th>\n')
|
||||
self.f_html.write('<th class="AUTHOR">Author</th>\n')
|
||||
self.f_html.write('<th class="TITLE">Title</th>\n')
|
||||
self.f_html.write('<th class="ASSIGNEE">Assignee</th>\n')
|
||||
self.f_html.write('<th class="REVIEWER">Reviewer</th>\n')
|
||||
self.f_html.write('<th class="CAN_START">CAN START</th>\n')
|
||||
self.f_html.write('<th class="IN_PROGRESS">IN PROGRESS</th>\n')
|
||||
self.f_html.write('<th class="COMPLETED">COMPLETED</th>\n')
|
||||
self.f_html.write('<th class="REVIEW_FORM">Review Form</th>\n')
|
||||
self.f_html.write('<th class="OK_MERGE">OK Merge</th>\n')
|
||||
self.f_html.write('<th class="MERGE_CONFLICTS">Merge Conflicts</th>\n')
|
||||
self.f_html.write('</tr>\n')
|
||||
|
||||
def MR_terminateHTML(self):
|
||||
self.f_html.write('</table> \n')
|
||||
self.f_html.write('</body>\n')
|
||||
self.f_html.write('</html>\n')
|
||||
self.f_html.close()
|
||||
|
||||
|
||||
def MR_rowHTML(self,row):
|
||||
self.f_html.write('<tr>\n')
|
||||
self.f_html.write('<td><a href=\"'+row[0]+'\">'+row[1]+'</a></td>\n')
|
||||
self.f_html.write('<td>'+row[2]+'</td>\n')
|
||||
self.f_html.write('<td>'+row[3]+'</td>\n')
|
||||
self.f_html.write('<td class="title_cell">'+row[4]+'</td>\n')
|
||||
self.f_html.write('<td>'+row[5]+'</td>\n')
|
||||
self.f_html.write('<td>'+row[6]+'</td>\n')
|
||||
if row[7]=='X':
|
||||
self.f_html.write('<td style="background-color: orange;">'+row[7]+'</td>\n')
|
||||
else:
|
||||
self.f_html.write('<td></td>\n')
|
||||
if row[8]=='X':
|
||||
self.f_html.write('<td style="background-color: yellow;">'+row[8]+'</td>\n')
|
||||
else:
|
||||
self.f_html.write('<td></td>\n')
|
||||
if row[9]=='X':
|
||||
self.f_html.write('<td style="background-color: rgb(144, 221, 231);">'+row[9]+'</td>\n')
|
||||
else:
|
||||
self.f_html.write('<td></td>\n')
|
||||
if row[10]=='X':
|
||||
self.f_html.write('<td style="background-color: rgb(58, 236, 58);">'+row[10]+'</td>\n')
|
||||
else:
|
||||
self.f_html.write('<td></td>\n')
|
||||
if row[11]=='X':
|
||||
self.f_html.write('<td style="background-color: rgb(58, 236, 58);">'+row[11]+'</td>\n')
|
||||
else:
|
||||
self.f_html.write('<td></td>\n')
|
||||
if row[12]=='YES':
|
||||
self.f_html.write('<td style="background-color: red;">'+row[12]+'</td>\n')
|
||||
else:
|
||||
self.f_html.write('<td></td>\n')
|
||||
self.f_html.write('</tr>\n')
|
||||
|
||||
|
||||
def Build(self, type, mr, htmlfilename):
|
||||
if type=='MR':
|
||||
self.Build_MR_Table(htmlfilename)
|
||||
elif type=='Tests':
|
||||
self.Build_Test_Table(htmlfilename)
|
||||
elif type=='singleMR':
|
||||
self.Build_singleMR_Table(mr,htmlfilename)
|
||||
else :
|
||||
print("Undefined Dashboard Type, options : MR or Tests")
|
||||
|
||||
|
||||
def Build_Test_Table(self,htmlfilename):
|
||||
print("Building Tests Dashboard...")
|
||||
|
||||
self.f_html=open(htmlfilename,'w')
|
||||
|
||||
###update date/time, format dd/mm/YY H:M:S
|
||||
now = datetime.now()
|
||||
dt_string = now.strftime("%d/%m/%Y %H:%M")
|
||||
#HTML table header
|
||||
self.Test_initHTML(dt_string)
|
||||
|
||||
|
||||
#1 table per MR if test results exist
|
||||
for x in range(len(self.git)):
|
||||
mr=str(self.git[x]['iid'])
|
||||
if 'PASS' not in self.db[mr]:
|
||||
self.f_html.write('<h3><a href="https://gitlab.eurecom.fr/oai/openairinterface5g/-/merge_requests/'+mr+'">'+mr+'</a>'+' '+self.git[x]['title'] + '</h3>\n')
|
||||
self.f_html.write('<table class="Test_Table">\n')
|
||||
self.f_html.write('<tr>\n')
|
||||
self.f_html.write('<th class="Test_Name">Test Name</th>\n')
|
||||
self.f_html.write('<th class="Test_Descr">Bench</th> \n')
|
||||
self.f_html.write('<th class="Test_Descr">Test</th> \n')
|
||||
self.f_html.write('<th class="Pass"># Pass</th>\n')
|
||||
self.f_html.write('<th class="Fail"># Fail</th>\n')
|
||||
self.f_html.write('<th class="Last_Pass">Last Pass</th>\n')
|
||||
self.f_html.write('<th class="Last_Fail">Last Fail</th>\n')
|
||||
self.f_html.write('</tr>\n')
|
||||
|
||||
#parsing the tests
|
||||
for t in self.tests:
|
||||
|
||||
row=[]
|
||||
short_name= t
|
||||
hyperlink= self.tests[t]['link']
|
||||
job=self.tests[t]['job']
|
||||
|
||||
|
||||
if job in self.db[mr]:
|
||||
if 'PASS' in self.db[mr][job]:
|
||||
row.append(self.db[mr][job]['PASS'])
|
||||
else:
|
||||
row.append('')
|
||||
if 'FAIL' in self.db[mr][job]:
|
||||
row.append(self.db[mr][job]['FAIL'])
|
||||
else:
|
||||
row.append('')
|
||||
#2 columns for last_pass and last_fail links
|
||||
if 'last_pass' in self.db[mr][job]:
|
||||
lastpasshyperlink= self.db[mr][job]['last_pass'][1]
|
||||
lastpasstext= self.db[mr][job]['last_pass'][0]
|
||||
else:
|
||||
lastpasshyperlink=''
|
||||
lastpasstext=''
|
||||
|
||||
if 'last_fail' in self.db[mr][job]:
|
||||
lastfailhyperlink= self.db[mr][job]['last_fail'][1]
|
||||
lastfailtext= self.db[mr][job]['last_fail'][0]
|
||||
else:
|
||||
lastfailhyperlink=''
|
||||
lastfailtext=''
|
||||
|
||||
|
||||
|
||||
self.f_html.write('<tr>\n')
|
||||
self.f_html.write('<td><a href='+hyperlink+'>'+short_name+'</a></td>\n')
|
||||
self.f_html.write('<td>'+self.tests[t]['bench']+'</td>\n')
|
||||
self.f_html.write('<td>'+self.tests[t]['test']+'</td>\n')
|
||||
if row[0]!='':
|
||||
self.f_html.write('<td style="background-color: rgb(58, 236, 58);">'+str(row[0])+'</td>\n')
|
||||
else:
|
||||
self.f_html.write('<td></td>\n')
|
||||
if row[1]!='':
|
||||
self.f_html.write('<td style="background-color: red;">'+str(row[1])+'</td>\n')
|
||||
else:
|
||||
self.f_html.write('<td></td>\n')
|
||||
self.f_html.write('<td><a href='+lastpasshyperlink+'>'+lastpasstext+'</a></td>\n')
|
||||
self.f_html.write('<td><a href='+lastfailhyperlink+'>'+lastfailtext+'</a></td>\n')
|
||||
self.f_html.write('</tr>\n')
|
||||
|
||||
self.f_html.write('</table>\n')
|
||||
|
||||
#terminate HTML table and close file
|
||||
self.Test_terminateHTML()
|
||||
|
||||
|
||||
def Build_singleMR_Table(self,singlemr,htmlfilename):
|
||||
print("Building single MR Tests Results...")
|
||||
|
||||
self.f_html=open(htmlfilename,'w')
|
||||
|
||||
###update date/time, format dd/mm/YY H:M:S
|
||||
now = datetime.now()
|
||||
dt_string = now.strftime("%d/%m/%Y %H:%M")
|
||||
#HTML table header
|
||||
self.singleMR_initHTML(dt_string)
|
||||
|
||||
|
||||
#1 table per MR if test results exist => 1 table for matching mr
|
||||
for x in range(len(self.git)):
|
||||
mr=str(self.git[x]['iid'])
|
||||
if mr==singlemr:
|
||||
#if 'PASS' not in self.db[mr]:
|
||||
self.f_html.write('<h3><a href="https://gitlab.eurecom.fr/oai/openairinterface5g/-/merge_requests/'+mr+'">'+mr+'</a>'+' '+self.git[x]['title'] + '</h3>\n')
|
||||
self.f_html.write('<table class="Test_Table">\n')
|
||||
self.f_html.write('<tr>\n')
|
||||
self.f_html.write('<th class="Test_Name">Test Name</th>\n')
|
||||
self.f_html.write('<th class="Test_Descr">Bench</th> \n')
|
||||
self.f_html.write('<th class="Test_Descr">Test</th> \n')
|
||||
self.f_html.write('<th class="Pass"># Pass</th>\n')
|
||||
self.f_html.write('<th class="Fail"># Fail</th>\n')
|
||||
self.f_html.write('<th class="Last_Pass">Last Pass</th>\n')
|
||||
self.f_html.write('<th class="Last_Fail">Last Fail</th>\n')
|
||||
self.f_html.write('</tr>\n')
|
||||
|
||||
#parsing the tests
|
||||
for t in self.tests:
|
||||
|
||||
row=[]
|
||||
short_name= t
|
||||
hyperlink= self.tests[t]['link']
|
||||
job=self.tests[t]['job']
|
||||
|
||||
|
||||
if job in self.db[mr]:
|
||||
if 'PASS' in self.db[mr][job]:
|
||||
row.append(self.db[mr][job]['PASS'])
|
||||
else:
|
||||
row.append('')
|
||||
if 'FAIL' in self.db[mr][job]:
|
||||
row.append(self.db[mr][job]['FAIL'])
|
||||
else:
|
||||
row.append('')
|
||||
#2 columns for last_pass and last_fail links
|
||||
if 'last_pass' in self.db[mr][job]:
|
||||
lastpasshyperlink= self.db[mr][job]['last_pass'][1]
|
||||
lastpasstext= self.db[mr][job]['last_pass'][0]
|
||||
else:
|
||||
lastpasshyperlink=''
|
||||
lastpasstext=''
|
||||
|
||||
if 'last_fail' in self.db[mr][job]:
|
||||
lastfailhyperlink= self.db[mr][job]['last_fail'][1]
|
||||
lastfailtext= self.db[mr][job]['last_fail'][0]
|
||||
else:
|
||||
lastfailhyperlink=''
|
||||
lastfailtext=''
|
||||
|
||||
|
||||
|
||||
self.f_html.write('<tr>\n')
|
||||
self.f_html.write('<td><a href='+hyperlink+'>'+short_name+'</a></td>\n')
|
||||
self.f_html.write('<td>'+self.tests[t]['bench']+'</td>\n')
|
||||
self.f_html.write('<td>'+self.tests[t]['test']+'</td>\n')
|
||||
if row[0]!='':
|
||||
self.f_html.write('<td style="background-color: rgb(58, 236, 58);">'+str(row[0])+'</td>\n')
|
||||
else:
|
||||
self.f_html.write('<td></td>\n')
|
||||
if row[1]!='':
|
||||
self.f_html.write('<td style="background-color: red;">'+str(row[1])+'</td>\n')
|
||||
else:
|
||||
self.f_html.write('<td></td>\n')
|
||||
self.f_html.write('<td><a href='+lastpasshyperlink+'>'+lastpasstext+'</a></td>\n')
|
||||
self.f_html.write('<td><a href='+lastfailhyperlink+'>'+lastfailtext+'</a></td>\n')
|
||||
self.f_html.write('</tr>\n')
|
||||
|
||||
self.f_html.write('</table>\n')
|
||||
|
||||
#terminate HTML table and close file
|
||||
self.Test_terminateHTML()
|
||||
|
||||
|
||||
|
||||
def Build_MR_Table(self,htmlfilename):
|
||||
|
||||
print("Building Merge Requests Dashboard...")
|
||||
|
||||
self.f_html=open(htmlfilename,'w')
|
||||
|
||||
###update date/time, format dd/mm/YY H:M:S
|
||||
now = datetime.now()
|
||||
dt_string = now.strftime("%d/%m/%Y %H:%M")
|
||||
|
||||
#HTML table header
|
||||
self.MR_initHTML(dt_string)
|
||||
|
||||
|
||||
###MR data lines
|
||||
for x in range(len(self.git)):
|
||||
|
||||
|
||||
hyperlink= 'https://gitlab.eurecom.fr/oai/openairinterface5g/-/merge_requests/'+ str(self.git[x]['iid'])
|
||||
text= str(self.git[x]['iid'])
|
||||
|
||||
|
||||
date_time_str = self.git[x]['created_at']
|
||||
date_time_obj = datetime.strptime(date_time_str, '%Y-%m-%dT%H:%M:%S.%fZ')
|
||||
|
||||
milestone1=milestone2=milestone3=milestone4=""
|
||||
if self.git[x]['milestone']!=None:
|
||||
if self.git[x]['milestone']['title']=="REVIEW_CAN_START":
|
||||
milestone1="X"
|
||||
elif self.git[x]['milestone']['title']=="REVIEW_IN_PROGRESS":
|
||||
milestone2="X"
|
||||
elif self.git[x]['milestone']['title']=="REVIEW_COMPLETED_AND_APPROVED":
|
||||
milestone3="X"
|
||||
elif self.git[x]['milestone']['title']=="OK_TO_BE_MERGED":
|
||||
milestone4="X"
|
||||
else:
|
||||
pass
|
||||
else:
|
||||
pass
|
||||
|
||||
#check if empty or not
|
||||
if self.git[x]['assignee']!=None:
|
||||
assignee = str(self.git[x]['assignee']['name'])
|
||||
else:
|
||||
assignee = ""
|
||||
|
||||
#check if empty or not
|
||||
if len(self.git[x]['reviewers'])!=0:
|
||||
reviewer = str(self.git[x]['reviewers'][0]['name'])
|
||||
else:
|
||||
reviewer = ""
|
||||
|
||||
if self.git[x]['has_conflicts']==True:
|
||||
conflicts = "YES"
|
||||
else:
|
||||
conflicts = ""
|
||||
|
||||
|
||||
#add a column flagging that the review form is present
|
||||
#we use gitlab API to parse the MR notes
|
||||
gl = gitlab.Gitlab.from_config('OAI')
|
||||
project_id = 223
|
||||
project = gl.projects.get(project_id)
|
||||
#get the opened MR in the project
|
||||
mrs = project.mergerequests.list(state='opened',per_page=100)
|
||||
review_form=''
|
||||
for m in range (0,len(mrs)):
|
||||
if mrs[m].iid==self.git[x]['iid']:#check the iid is the one we are on
|
||||
mr_notes = mrs[m].notes.list(all=True)
|
||||
n=0
|
||||
found=False
|
||||
while found==False and n<len(mr_notes):
|
||||
res=re.search('Code Review by',mr_notes[n].body)#this is the marker we are looking for in all notes
|
||||
if res!=None:
|
||||
review_form = "X"
|
||||
found=True
|
||||
n+=1
|
||||
|
||||
#build final row to be inserted
|
||||
row =[hyperlink, text, str(date_time_obj.date()),str(self.git[x]['author']['name']), str(self.git[x]['title']),\
|
||||
assignee, reviewer,\
|
||||
milestone1,milestone2,milestone3,review_form,milestone4,conflicts]
|
||||
|
||||
self.MR_rowHTML(row)
|
||||
|
||||
#terminate HTML table and close file
|
||||
self.MR_terminateHTML()
|
||||
|
||||
|
||||
def CopyToS3(self,htmlfilename,bucket,key):
|
||||
print("Uploading to S3 bucket")
|
||||
#Creating Session With Boto3.
|
||||
s3 = boto3.client('s3')
|
||||
|
||||
#Creating S3 Resource From the Session.
|
||||
result = s3.upload_file(htmlfilename, bucket,key, ExtraArgs={'ACL':'public-read','ContentType': 'text/html'})
|
||||
|
||||
#unused
|
||||
def CopyCSS(self,path):
|
||||
s3 = boto3.resource('s3')
|
||||
copy_source = {'Bucket': 'oaitestdashboard','Key':'test_styles.css'}
|
||||
s3.meta.client.copy(copy_source, 'oaitestdashboard', path+'/'+ 'test_styles.css')
|
||||
|
||||
|
||||
def PostGitNote(self,mr,commit,args):
|
||||
#current date and time to be posted with test results
|
||||
#now = datetime.now()
|
||||
#dt_string = now.strftime("%d/%m/%Y %H:%M")
|
||||
|
||||
if len(args)%4 != 0:
|
||||
print("Wrong Number of Arguments")
|
||||
return
|
||||
@@ -528,7 +74,7 @@ class Dashboard:
|
||||
editable_mr = project.mergerequests.get(int(mr))
|
||||
mr_notes = editable_mr.notes.list(all=True)
|
||||
|
||||
body = '[Consolidated Test Results](https://oaitestdashboard.s3.eu-west-1.amazonaws.com/MR'+mr+'/index.html)\\\n'
|
||||
body = '[Consolidated Test Results]\\\n'
|
||||
body += 'Tested CommitID: ' + commit
|
||||
|
||||
for i in range(0,n_tests):
|
||||
@@ -544,54 +90,16 @@ class Dashboard:
|
||||
})
|
||||
editable_mr.save()
|
||||
|
||||
def AWSCleanup(self,mode):
|
||||
#first build MR list from aws S3 bucket
|
||||
if mode != 'report' and mode !='delete':
|
||||
print("incorrect mode for awsclean")
|
||||
return
|
||||
aws_mr_list=[]
|
||||
s3 = boto3.resource('s3')
|
||||
my_bucket = s3.Bucket('oaitestdashboard')
|
||||
for my_bucket_object in my_bucket.objects.all():
|
||||
#MR objects are like MR1407/index.html
|
||||
res=re.search(r'^MR([0-9]+)',my_bucket_object.key)
|
||||
if res!=None:
|
||||
aws_mr_list.append(res.group(1))#store MR number as a string
|
||||
#open MR list from GIt already exists as an attribute of this class self.mr_list
|
||||
#parse aws MR list and delete those MR that are no longer open
|
||||
for aws_mr in aws_mr_list:
|
||||
if aws_mr not in self.mr_list:
|
||||
if mode=="report":
|
||||
print(aws_mr+' can be deleted from AWS S3')
|
||||
else :
|
||||
awspath="MR"+aws_mr+"/"
|
||||
print('deleting ' + aws_mr)
|
||||
my_bucket.objects.filter(Prefix=awspath).delete()
|
||||
|
||||
|
||||
|
||||
|
||||
def main():
|
||||
|
||||
#call from slave Jenkinsfile : sh "python3 Hdashboard.py testevent ${params.eNB_MR} "
|
||||
#call from master Jenkinsfile : sh "python3 Hdashboard.py gitpost ${GitPostArgs}"
|
||||
|
||||
|
||||
if len(sys.argv)>1:
|
||||
if len(sys.argv) > 1:
|
||||
|
||||
#individual MR test results + test dashboard, event based (end of slave jenkins pipeline)
|
||||
if sys.argv[1]=="testevent" :
|
||||
mr=sys.argv[2]
|
||||
htmlDash=Dashboard()
|
||||
if mr in htmlDash.mr_list:
|
||||
#single MR test results
|
||||
htmlDash.Build('singleMR',mr,'/tmp/MR'+mr+'_index.html')
|
||||
htmlDash.CopyToS3('/tmp/MR'+mr+'_index.html','oaitestdashboard','MR'+mr+'/index.html')
|
||||
#all MR test results
|
||||
htmlDash.Build('Tests','0000','/tmp/Tests_index.html')
|
||||
htmlDash.CopyToS3('/tmp/Tests_index.html','oaitestdashboard','index.html')
|
||||
if sys.argv[1] != "gitpost":
|
||||
print("error: only gitpost subcommand is supported")
|
||||
exit(1)
|
||||
|
||||
#git post with MR test results, event based (end of master jenkins pipeline)
|
||||
elif sys.argv[1]=="gitpost":
|
||||
mr=sys.argv[2]
|
||||
commit=sys.argv[3]
|
||||
@@ -603,25 +111,15 @@ def main():
|
||||
htmlDash.PostGitNote(mr,commit, args)
|
||||
else:
|
||||
print("Not a Merge Request => this build is for testing/debug purpose, no report to git")
|
||||
elif sys.argv[1]=="awsclean":
|
||||
mode=sys.argv[2]#report or delete
|
||||
htmlDash=Dashboard()
|
||||
htmlDash.AWSCleanup(mode)
|
||||
else:
|
||||
print("Wrong argument at position 1")
|
||||
exit(1)
|
||||
|
||||
|
||||
#test and MR status dashboards, cron based
|
||||
else:
|
||||
htmlDash=Dashboard()
|
||||
#all MR status dashboard
|
||||
htmlDash.Build('MR','0000','/tmp/MR_index.html')
|
||||
htmlDash.CopyToS3('/tmp/MR_index.html','oairandashboard','index.html')
|
||||
#all MR test results
|
||||
htmlDash.Build('Tests','0000','/tmp/Tests_index.html')
|
||||
htmlDash.CopyToS3('/tmp/Tests_index.html','oaitestdashboard','index.html')
|
||||
|
||||
|
||||
print("error: only gitpost subcommand is supported")
|
||||
exit(1)
|
||||
|
||||
if __name__ == "__main__":
|
||||
# execute only if run as a script
|
||||
|
||||
@@ -1,136 +0,0 @@
|
||||
body {
|
||||
font-family: 'lato', sans-serif;
|
||||
}
|
||||
|
||||
|
||||
.Main {
|
||||
text-align:left;
|
||||
font-size: 30px;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.DashLink {
|
||||
text-align:left;
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
.DashLink:hover {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.Date {
|
||||
text-align:left;
|
||||
font-size: 16px;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
|
||||
a { text-decoration: none; }
|
||||
a:visited { text-decoration: none; color:blue}
|
||||
a:hover { text-decoration: none; font-weight: bold; color:blue}
|
||||
|
||||
|
||||
.MR_Table {
|
||||
border-collapse: collapse;
|
||||
}
|
||||
|
||||
.MR_Table tr {
|
||||
font-size: 12px;
|
||||
text-align:center;
|
||||
}
|
||||
|
||||
|
||||
.MR_Table tr:hover {
|
||||
background-color:lightgray;
|
||||
}
|
||||
|
||||
.MR_Table td {
|
||||
border: 1px solid black;
|
||||
padding : 5px;
|
||||
}
|
||||
.MR_Table td:hover {
|
||||
font-weight : bold;
|
||||
}
|
||||
|
||||
.MR_Table th {
|
||||
font-size: 14px;
|
||||
text-align:center;
|
||||
padding : 5px;
|
||||
}
|
||||
|
||||
|
||||
.title_cell {
|
||||
text-align:left;
|
||||
}
|
||||
|
||||
|
||||
.MR {
|
||||
table-layout: fixed;
|
||||
width: 50px;
|
||||
background-color: rgb(143, 154, 216);
|
||||
}
|
||||
|
||||
.CREATED_AT {
|
||||
table-layout: fixed;
|
||||
width: 100px;
|
||||
background-color: rgb(143, 154, 216);
|
||||
}
|
||||
|
||||
.AUTHOR {
|
||||
table-layout: fixed;
|
||||
width: 150px;
|
||||
background-color: rgb(143, 154, 216);
|
||||
}
|
||||
|
||||
.TITLE {
|
||||
table-layout: fixed;
|
||||
width: 500px;
|
||||
background-color: rgb(143, 154, 216);
|
||||
}
|
||||
|
||||
.ASSIGNEE {
|
||||
table-layout: fixed;
|
||||
width: 150px;
|
||||
background-color: rgb(143, 154, 216);
|
||||
}
|
||||
|
||||
.REVIEWER {
|
||||
table-layout: fixed;
|
||||
width: 150px;
|
||||
background-color: rgb(143, 154, 216);
|
||||
}
|
||||
|
||||
.CAN_START {
|
||||
background-color: orange;
|
||||
table-layout: fixed;
|
||||
width: 150px;
|
||||
}
|
||||
.IN_PROGRESS {
|
||||
background-color: yellow;
|
||||
table-layout: fixed;
|
||||
width: 150px;
|
||||
}
|
||||
.COMPLETED {
|
||||
background-color: rgb(144, 221, 231);
|
||||
table-layout: fixed;
|
||||
width: 150px;
|
||||
}
|
||||
|
||||
.REVIEW_FORM {
|
||||
table-layout: fixed;
|
||||
width: 100px;
|
||||
background-color: rgb(143, 154, 216);
|
||||
}
|
||||
|
||||
.OK_MERGE {
|
||||
background-color: rgb(58, 236, 58);
|
||||
table-layout: fixed;
|
||||
width: 150px;
|
||||
}
|
||||
|
||||
.MERGE_CONFLICTS {
|
||||
table-layout: fixed;
|
||||
width: 100px;
|
||||
background-color: rgb(143, 154, 216);
|
||||
}
|
||||
|
||||
@@ -1,405 +0,0 @@
|
||||
#/*
|
||||
# * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
|
||||
# * contributor license agreements. See the NOTICE file distributed with
|
||||
# * this work for additional information regarding copyright ownership.
|
||||
# * The OpenAirInterface Software Alliance licenses this file to You under
|
||||
# * the OAI Public License, Version 1.1 (the "License"); you may not use this file
|
||||
# * except in compliance with the License.
|
||||
# * You may obtain a copy of the License at
|
||||
# *
|
||||
# * http://www.openairinterface.org/?page_id=698
|
||||
# *
|
||||
# * Unless required by applicable law or agreed to in writing, software
|
||||
# * distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# * See the License for the specific language governing permissions and
|
||||
# * limitations under the License.
|
||||
# *-------------------------------------------------------------------------------
|
||||
# * For more information about the OpenAirInterface (OAI) Software Alliance:
|
||||
# * contact@openairinterface.org
|
||||
# */
|
||||
#---------------------------------------------------------------------
|
||||
# Merge Requests Dashboard for RAN on googleSheet
|
||||
#
|
||||
# Required Python Version
|
||||
# Python 3.x
|
||||
#
|
||||
#---------------------------------------------------------------------
|
||||
|
||||
#-----------------------------------------------------------
|
||||
# Import
|
||||
#-----------------------------------------------------------
|
||||
|
||||
#author Remi
|
||||
|
||||
#import google spreadsheet API
|
||||
import gspread
|
||||
from oauth2client.service_account import ServiceAccountCredentials
|
||||
|
||||
|
||||
import subprocess
|
||||
import shlex #lexical analysis
|
||||
import json #json structures
|
||||
import datetime #now() and date formating
|
||||
from datetime import datetime
|
||||
import re
|
||||
import gitlab
|
||||
import yaml
|
||||
import os
|
||||
import pickle
|
||||
import time
|
||||
|
||||
|
||||
from sqlconnect import SQLConnect
|
||||
|
||||
#-----------------------------------------------------------
|
||||
# Class Declaration
|
||||
#-----------------------------------------------------------
|
||||
|
||||
class gDashboard:
|
||||
def __init__(self, creds_file, spreadsheet, worksheet): #"creds.json", 'OAI RAN Dashboard', 'MR Status'
|
||||
self.scope = ["https://spreadsheets.google.com/feeds",'https://www.googleapis.com/auth/spreadsheets',"https://www.googleapis.com/auth/drive.file","https://www.googleapis.com/auth/drive"]
|
||||
self.creds = ServiceAccountCredentials.from_json_keyfile_name(creds_file, self.scope)
|
||||
self.client = gspread.authorize(self.creds)
|
||||
#spreadsheet
|
||||
self.ss = self.client.open(spreadsheet)
|
||||
#worksheet
|
||||
self.sheet = self.ss.worksheet(worksheet)
|
||||
self.ss.del_worksheet(self.sheet) #start by deleting the old sheet
|
||||
self.sheet = self.ss.add_worksheet(title=worksheet, rows="100", cols="30") #create a new one
|
||||
|
||||
#init with data sources : git, yaml config file, test results databases
|
||||
cmd="""curl --silent "https://gitlab.eurecom.fr/api/v4/projects/oai%2Fopenairinterface5g/merge_requests?state=opened&per_page=100" """
|
||||
self.git = self.__getGitData(cmd) #git data from Gitlab
|
||||
self.tests = self.__loadCfg('ran_dashboard_cfg.yaml') #tests table setup from yaml
|
||||
self.db = self.__loadFromDB() #test results from database
|
||||
|
||||
|
||||
def __loadCfg(self,yaml_file):
|
||||
with open(yaml_file,'r') as f:
|
||||
tests = yaml.load(f)
|
||||
return tests
|
||||
|
||||
def __getGitData(self,cmd):
|
||||
#cmd="""curl --silent "https://gitlab.eurecom.fr/api/v4/projects/oai%2Fopenairinterface5g/merge_requests?state=opened&per_page=100" """
|
||||
process = subprocess.Popen(shlex.split(cmd), stdout=subprocess.PIPE)
|
||||
output = process.stdout.readline()
|
||||
tmp=output.decode("utf-8")
|
||||
d = json.loads(tmp)
|
||||
return d
|
||||
|
||||
def __loadFromDB(self):
|
||||
mr_list=[]
|
||||
for x in range(len(self.git)):
|
||||
mr_list.append(str(self.git[x]['iid']))
|
||||
mydb=SQLConnect()
|
||||
for MR in mr_list:
|
||||
mydb.get(MR)
|
||||
mydb.close_connection()
|
||||
return mydb.data
|
||||
|
||||
|
||||
|
||||
def gBuild(self, destinationSheetName):
|
||||
|
||||
###line 1 : update date/time, format dd/mm/YY H:M:S
|
||||
now = datetime.now()
|
||||
dt_string = "Update : " + now.strftime("%d/%m/%Y %H:%M")
|
||||
row =[dt_string]
|
||||
self.sheet.insert_row(row, index=1, value_input_option='RAW')
|
||||
|
||||
###line 2 is for the test short names (links to jenkins pipeline), updated at the end
|
||||
|
||||
###line 3 is for the column names
|
||||
i=3
|
||||
row =["MR","Created_at","Author","Title","Assignee", "Reviewer", "CAN START","IN PROGRESS","COMPLETED","Review Form","OK MERGE","Merge conflicts",""]
|
||||
|
||||
#tests
|
||||
for t in range(0,len(self.tests)):
|
||||
row.append("# PASS")
|
||||
row.append("# FAIL")
|
||||
row.append("Last Pass")
|
||||
row.append("Last Fail")
|
||||
|
||||
self.sheet.insert_row(row, index=i, value_input_option='RAW')
|
||||
|
||||
###line 4 onward, MR data lines
|
||||
for x in range(len(self.git)):
|
||||
i=i+1
|
||||
date_time_str = self.git[x]['created_at']
|
||||
date_time_obj = datetime.strptime(date_time_str, '%Y-%m-%dT%H:%M:%S.%fZ')
|
||||
|
||||
milestone1=milestone2=milestone3=milestone4=""
|
||||
if self.git[x]['milestone']!=None:
|
||||
if self.git[x]['milestone']['title']=="REVIEW_CAN_START":
|
||||
milestone1="X"
|
||||
elif self.git[x]['milestone']['title']=="REVIEW_IN_PROGRESS":
|
||||
milestone2="X"
|
||||
elif self.git[x]['milestone']['title']=="REVIEW_COMPLETED_AND_APPROVED":
|
||||
milestone3="X"
|
||||
elif self.git[x]['milestone']['title']=="OK_TO_BE_MERGED":
|
||||
milestone4="X"
|
||||
else:
|
||||
pass
|
||||
else:
|
||||
pass
|
||||
|
||||
#check if empty or not
|
||||
if self.git[x]['assignee']!=None:
|
||||
assignee = str(self.git[x]['assignee']['name'])
|
||||
else:
|
||||
assignee = ""
|
||||
|
||||
#check if empty or not
|
||||
if len(self.git[x]['reviewers'])!=0:
|
||||
reviewer = str(self.git[x]['reviewers'][0]['name'])
|
||||
else:
|
||||
reviewer = ""
|
||||
|
||||
if self.git[x]['has_conflicts']==True:
|
||||
conflicts = "YES"
|
||||
else:
|
||||
conflicts = ""
|
||||
|
||||
|
||||
#add a column flagging that the review form is present
|
||||
#we use gitlab API to parse the MR notes
|
||||
gl = gitlab.Gitlab.from_config('OAI')
|
||||
project_id = 223
|
||||
project = gl.projects.get(project_id)
|
||||
#get the opened MR in the project
|
||||
mrs = project.mergerequests.list(state='opened',per_page=100)
|
||||
review_form=''
|
||||
for m in range (0,len(mrs)):
|
||||
if mrs[m].iid==self.git[x]['iid']:#check the iid is the one we are on
|
||||
mr_notes = mrs[m].notes.list(all=True)
|
||||
n=0
|
||||
found=False
|
||||
while found==False and n<len(mr_notes):
|
||||
res=re.search('Code Review by',mr_notes[n].body)#this is the marker we are looking for in all notes
|
||||
if res!=None:
|
||||
review_form = "X"
|
||||
found=True
|
||||
n+=1
|
||||
|
||||
#build final row to be inserted, the first column is left empty for now, will be filled afterward with hyperlinks to gitlab MR
|
||||
row =["", str(date_time_obj.date()),str(self.git[x]['author']['name']), str(self.git[x]['title']),\
|
||||
assignee, reviewer,\
|
||||
milestone1,milestone2,milestone3,review_form,milestone4,conflicts,""]
|
||||
#and append the test results coming from self.db
|
||||
mr=str(self.git[x]['iid'])
|
||||
for t in self.tests:
|
||||
if mr in self.db:
|
||||
job=self.tests[t]['job']
|
||||
if job in self.db[mr]:
|
||||
if 'PASS' in self.db[mr][job]:
|
||||
row.append(self.db[mr][job]['PASS'])
|
||||
else:
|
||||
row.append('')
|
||||
if 'FAIL' in self.db[mr][job]:
|
||||
row.append(self.db[mr][job]['FAIL'])
|
||||
else:
|
||||
row.append('')
|
||||
#leave 2 columns for last_pass and last_fail links
|
||||
row.append('')
|
||||
row.append('')
|
||||
else:
|
||||
#4 columns are empty
|
||||
row.append('')
|
||||
row.append('')
|
||||
row.append('')
|
||||
row.append('')
|
||||
|
||||
#insert the final row to worksheet
|
||||
self.sheet.insert_row(row, index=i, value_input_option='RAW')
|
||||
time.sleep(10)
|
||||
|
||||
|
||||
#add MR hyperlinks in a list of requests to be sent as one update batch; this to save API calls (quotas)
|
||||
i=3
|
||||
requests=[]
|
||||
for x in range(len(self.git)):
|
||||
rowIndex=i
|
||||
colIndex=0
|
||||
hyperlink= '\"'+"https://gitlab.eurecom.fr/oai/openairinterface5g/-/merge_requests/"+ str(self.git[x]['iid']) +'\"'
|
||||
text= '\"'+str(self.git[x]['iid'])+'"'
|
||||
requests.append(self.addHyperlink(hyperlink, text, destinationSheetName, rowIndex, colIndex))
|
||||
|
||||
mr=str(self.git[x]['iid'])
|
||||
colIndex=15
|
||||
for t in self.tests:
|
||||
job=self.tests[t]['job']
|
||||
if job in self.db[mr]:
|
||||
if 'last_pass' in self.db[mr][job]:
|
||||
hyperlink= '\"'+ self.db[mr][job]['last_pass'][1] +'\"'
|
||||
text= '\"'+self.db[mr][job]['last_pass'][0]+'"'
|
||||
requests.append(self.addHyperlink(hyperlink, text, destinationSheetName, rowIndex, colIndex))
|
||||
if 'last_fail' in self.db[mr][job]:
|
||||
hyperlink= '\"'+ self.db[mr][job]['last_fail'][1] +'\"'
|
||||
text= '\"'+self.db[mr][job]['last_fail'][0]+'"'
|
||||
requests.append(self.addHyperlink(hyperlink, text, destinationSheetName, rowIndex, colIndex+1))
|
||||
colIndex+=4 #move to next test
|
||||
i=i+1 #increment row index for next MR
|
||||
|
||||
body = {"requests": requests}
|
||||
self.ss.batch_update(body)
|
||||
|
||||
###line 2 is for the test names
|
||||
#add MR hyperlinks in a list of requests to be sent as one update batch; this to save API calls (quotas)
|
||||
requests=[]
|
||||
rowIndex=1
|
||||
colIndex=13
|
||||
for t in self.tests :
|
||||
hyperlink= '\"'+self.tests[t]['link']+'\"'
|
||||
short_name= '\"'+ t +'\"'
|
||||
requests.append(self.addHyperlink(hyperlink, short_name, destinationSheetName, rowIndex, colIndex))
|
||||
colIndex+=4
|
||||
|
||||
body = {"requests": requests}
|
||||
self.ss.batch_update(body)
|
||||
|
||||
|
||||
def addHyperlink(self, hyperlink, text, destinationSheetName, rowIndex, colIndex):
|
||||
sheetId = self.ss.worksheet(destinationSheetName)._properties['sheetId']
|
||||
request =\
|
||||
{
|
||||
"updateCells": {
|
||||
"rows": [
|
||||
{
|
||||
"values": [
|
||||
{
|
||||
"userEnteredValue": {
|
||||
"formulaValue":"=HYPERLINK({},{})".format(hyperlink, text)
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"fields": "userEnteredValue",
|
||||
"start": {
|
||||
"sheetId": sheetId,
|
||||
"rowIndex": rowIndex,
|
||||
"columnIndex": colIndex
|
||||
}
|
||||
}
|
||||
}
|
||||
return request
|
||||
|
||||
|
||||
|
||||
def gFormat(self,sourceSheetName,destinationSheetName): # "Formating" , "MR Status"
|
||||
#the requests are appended in a list of requests to be sent as one update batch; this to save API calls (quotas)
|
||||
#copy formating template
|
||||
sourceSheetId = self.ss.worksheet(sourceSheetName)._properties['sheetId']
|
||||
destinationSheetId = self.ss.worksheet(destinationSheetName)._properties['sheetId']
|
||||
requests=[]
|
||||
requests.append(
|
||||
{
|
||||
"copyPaste": {
|
||||
"source": {
|
||||
"sheetId": sourceSheetId,
|
||||
"startRowIndex": 1,
|
||||
"endRowIndex": 40,
|
||||
"startColumnIndex": 0,
|
||||
"endColumnIndex": 30
|
||||
},
|
||||
"destination": {
|
||||
"sheetId": destinationSheetId,
|
||||
"startRowIndex": 1,
|
||||
"endRowIndex": 40,
|
||||
"startColumnIndex": 0,
|
||||
"endColumnIndex": 30
|
||||
},
|
||||
"pasteType": "PASTE_FORMAT"
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
#resize columns fit to data, except col 0
|
||||
sheetId = self.ss.worksheet(destinationSheetName)._properties['sheetId']
|
||||
requests.append(
|
||||
{
|
||||
'autoResizeDimensions': {
|
||||
'dimensions': {
|
||||
'sheetId': sheetId,
|
||||
'dimension': 'COLUMNS',
|
||||
'startIndex': 1,
|
||||
'endIndex': 12
|
||||
}
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
#resize col 0
|
||||
sheetId = self.ss.worksheet(destinationSheetName)._properties['sheetId']
|
||||
requests.append(
|
||||
{
|
||||
"updateDimensionProperties": {
|
||||
"range": {
|
||||
"sheetId": sheetId,
|
||||
"dimension": "COLUMNS",
|
||||
"startIndex": 0,
|
||||
"endIndex": 1
|
||||
},
|
||||
"properties": {
|
||||
"pixelSize": 100
|
||||
},
|
||||
"fields": "pixelSize"
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
#resize milestones to be cleaner
|
||||
sheetId = self.ss.worksheet(destinationSheetName)._properties['sheetId']
|
||||
requests.append(
|
||||
{
|
||||
"updateDimensionProperties": {
|
||||
"range": {
|
||||
"sheetId": sheetId,
|
||||
"dimension": "COLUMNS",
|
||||
"startIndex": 6,
|
||||
"endIndex": 11
|
||||
},
|
||||
"properties": {
|
||||
"pixelSize": 120
|
||||
},
|
||||
"fields": "pixelSize"
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
#group MR related columns
|
||||
# sheetId = self.ss.worksheet(destinationSheetName)._properties['sheetId']
|
||||
# requests.append(
|
||||
# {
|
||||
# "addDimensionGroup": {
|
||||
# "range": {
|
||||
# "dimension": "COLUMNS",
|
||||
# "sheetId": sheetId,
|
||||
# "startIndex": 3,
|
||||
# "endIndex": 12
|
||||
# },
|
||||
# }
|
||||
# }
|
||||
# )
|
||||
#
|
||||
body = {"requests": requests}
|
||||
self.ss.batch_update(body)
|
||||
|
||||
|
||||
|
||||
|
||||
def main():
|
||||
my_gDashboard=gDashboard("/opt/dashboard/g_creds.json", 'OAI RAN Dashboard', 'MR Status')
|
||||
my_gDashboard.gBuild("MR Status")
|
||||
my_gDashboard.gFormat("Formating" , "MR Status")
|
||||
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
# execute only if run as a script
|
||||
main()
|
||||
@@ -1,26 +0,0 @@
|
||||
LTE-2x2 : #short name used in the dashboard
|
||||
job : 'RAN-LTE-2x2-Module-OAIEPC' #job name from Jenkins, used in the database
|
||||
link : 'https://jenkins-oai.eurecom.fr/view/RAN/job/RAN-LTE-2x2-Module-OAIEPC'
|
||||
bench : 'Obelix-N310-OAIEPC-Quectel(nrmodule2)'
|
||||
test : 'TM1 + TM2, TDD, 40MHz, MCS9, 26Mb DL, 7Mb UL'
|
||||
NSA-B200 :
|
||||
job : 'RAN-NSA-B200-Module-LTEBOX'
|
||||
link : 'https://jenkins-oai.eurecom.fr/view/RAN/job/RAN-NSA-B200-Module-LTEBOX'
|
||||
bench : 'Nepes-B200-Obelix-B200-LTEBOX-Quectel(idefix)'
|
||||
test : '20MHz, 60Mb DL, 3Mb UL'
|
||||
NSA-2x2 :
|
||||
job : 'RAN-NSA-2x2-Module-OAIEPC'
|
||||
link : 'https://jenkins-oai.eurecom.fr/view/RAN/job/RAN-NSA-2x2-Module-OAIEPC'
|
||||
bench : 'Asterix-N310-Obelix-N310-OAIEPC-Quectel(nrmodule2)'
|
||||
test : 'TDD, 40MHz, 60Mb DL, 3Mb UL'
|
||||
SA-N310 :
|
||||
job : 'RAN-SA-Module-CN5G'
|
||||
link : 'https://jenkins-oai.eurecom.fr/view/RAN/job/RAN-SA-Module-CN5G'
|
||||
bench : 'Asterix-N310-OAICN5G-Quectel(nrmodule2)'
|
||||
test : 'TDD, 40MHz, 60Mb DL, 3Mb UL'
|
||||
SA-OAIUE-N310-X300 :
|
||||
job : 'RAN-SA-OAIUE-N310-X300-CN5G'
|
||||
link : 'https://jenkins-oai.eurecom.fr/view/RAN/job/RAN-SA-OAIUE-N310-X300-CN5G/'
|
||||
bench : 'Asterix-N310-OAICN5G-OAIUE-N310'
|
||||
test : 'TDD, 40MHz, Ping, (to be implemented : iperf)'
|
||||
|
||||
@@ -1,3 +0,0 @@
|
||||
The code ran_dashboard.py was initially developped to bring MR status and test resuts to a google sheet, using google sheets API.
|
||||
This method is now deprecated, and replaced by Hdashboard.py that builds the results as HTML page and loads it to AWS S3.
|
||||
ran_dashboard_cfg.yaml is still used by Hdashboard.py as tests config file.
|
||||
@@ -1,107 +0,0 @@
|
||||
#/*
|
||||
# * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
|
||||
# * contributor license agreements. See the NOTICE file distributed with
|
||||
# * this work for additional information regarding copyright ownership.
|
||||
# * The OpenAirInterface Software Alliance licenses this file to You under
|
||||
# * the OAI Public License, Version 1.1 (the "License"); you may not use this file
|
||||
# * except in compliance with the License.
|
||||
# * You may obtain a copy of the License at
|
||||
# *
|
||||
# * http://www.openairinterface.org/?page_id=698
|
||||
# *
|
||||
# * Unless required by applicable law or agreed to in writing, software
|
||||
# * distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# * See the License for the specific language governing permissions and
|
||||
# * limitations under the License.
|
||||
# *-------------------------------------------------------------------------------
|
||||
# * For more information about the OpenAirInterface (OAI) Software Alliance:
|
||||
# * contact@openairinterface.org
|
||||
# */
|
||||
#---------------------------------------------------------------------
|
||||
# Merge Requests Dashboard for RAN on googleSheet
|
||||
#
|
||||
# Required Python Version
|
||||
# Python 3.x
|
||||
#
|
||||
#---------------------------------------------------------------------
|
||||
|
||||
#author Remi
|
||||
|
||||
|
||||
import pymysql
|
||||
import sys
|
||||
from datetime import datetime
|
||||
import pickle
|
||||
|
||||
#This is the script/package used by the dashboard to retrieve the MR test results from the database
|
||||
|
||||
class SQLConnect:
|
||||
def __init__(self):
|
||||
self.connection = pymysql.connect(
|
||||
host='172.22.0.2',
|
||||
user='root',
|
||||
password = 'ucZBc2XRYdvEm59F',
|
||||
db='oaicicd_tests',
|
||||
port=3306
|
||||
)
|
||||
self.data={}
|
||||
|
||||
|
||||
#retrieve data from mysql database and organize it in a dictionary (per MR passed as argument)
|
||||
def get(self,MR):
|
||||
self.data[MR]={}
|
||||
cur=self.connection.cursor()
|
||||
|
||||
#get counters per test
|
||||
sql = "select TEST,STATUS, count(*) AS COUNT from test_results where MR=(%s) group by TEST, STATUS;"
|
||||
cur.execute(sql,MR)
|
||||
response=cur.fetchall()
|
||||
if len(response)==0:#no test results yet
|
||||
self.data[MR]['PASS']=''
|
||||
self.data[MR]['FAIL']=''
|
||||
else:
|
||||
for i in range(0,len(response)):
|
||||
test=response[i][0]
|
||||
status=response[i][1]
|
||||
count=response[i][2]
|
||||
if test in self.data[MR]:
|
||||
self.data[MR][test][status]=count
|
||||
else:
|
||||
self.data[MR][test]={}
|
||||
self.data[MR][test][status]=count
|
||||
|
||||
#get last failing build and link
|
||||
sql = "select TEST,BUILD, BUILD_LINK from test_results where MR=(%s) and STATUS='FAIL' order by DATE DESC;"
|
||||
cur.execute(sql,MR)
|
||||
response=cur.fetchall()
|
||||
if len(response)!=0:
|
||||
for i in range(0,len(response)):
|
||||
test=response[i][0]
|
||||
build=response[i][1]
|
||||
link=response[i][2]
|
||||
if 'last_fail' not in self.data[MR][test]:
|
||||
self.data[MR][test]['last_fail']=[]
|
||||
self.data[MR][test]['last_fail'].append(build)
|
||||
self.data[MR][test]['last_fail'].append(link)
|
||||
|
||||
#get last passing build and link
|
||||
sql = "select TEST,BUILD, BUILD_LINK from test_results where MR=(%s) and STATUS='PASS' order by DATE DESC;"
|
||||
cur.execute(sql,MR)
|
||||
response=cur.fetchall()
|
||||
if len(response)!=0:
|
||||
for i in range(0,len(response)):
|
||||
test=response[i][0]
|
||||
build=response[i][1]
|
||||
link=response[i][2]
|
||||
if 'last_pass' not in self.data[MR][test]:
|
||||
self.data[MR][test]['last_pass']=[]
|
||||
self.data[MR][test]['last_pass'].append(build)
|
||||
self.data[MR][test]['last_pass'].append(link)
|
||||
|
||||
|
||||
#close database connection
|
||||
def close_connection(self):
|
||||
self.connection.close()
|
||||
|
||||
|
||||
@@ -1,103 +0,0 @@
|
||||
body {
|
||||
font-family: 'lato', sans-serif;
|
||||
}
|
||||
|
||||
.Main {
|
||||
text-align: left;
|
||||
font-size: 30px;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
|
||||
.DashLink {
|
||||
text-align:left;
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
.DashLink:hover {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
|
||||
.Date {
|
||||
text-align: left;
|
||||
font-size: 16px;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
h3 {
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
a { text-decoration: none; }
|
||||
a:visited { text-decoration: none; color:blue}
|
||||
a:hover { text-decoration: none; font-weight: bold; color:blue}
|
||||
|
||||
|
||||
.Test_Table {
|
||||
border-collapse: collapse;
|
||||
}
|
||||
|
||||
.Test_Table tr {
|
||||
font-size: 12px;
|
||||
text-align:center;
|
||||
}
|
||||
|
||||
|
||||
.Test_Table tr:hover {
|
||||
background-color:lightgray;
|
||||
}
|
||||
|
||||
.Test_Table td {
|
||||
border: 1px solid black;
|
||||
padding : 5px;
|
||||
}
|
||||
.Test_Table td:hover {
|
||||
font-weight : bold;
|
||||
}
|
||||
|
||||
.Test_Table th {
|
||||
font-size: 14px;
|
||||
text-align:center;
|
||||
padding : 5px;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
.Test_Name {
|
||||
table-layout: fixed;
|
||||
width: 100px;
|
||||
background-color: rgb(143, 154, 216);
|
||||
}
|
||||
|
||||
.Test_Descr {
|
||||
table-layout: fixed;
|
||||
width: 400px;
|
||||
background-color: rgb(143, 154, 216);
|
||||
}
|
||||
|
||||
.Pass {
|
||||
table-layout: fixed;
|
||||
width: 100px;
|
||||
background-color: rgb(143, 154, 216);
|
||||
}
|
||||
|
||||
.Fail {
|
||||
table-layout: fixed;
|
||||
width: 100px;
|
||||
background-color: rgb(143, 154, 216);
|
||||
}
|
||||
|
||||
.Last_Pass {
|
||||
table-layout: fixed;
|
||||
width: 100px;
|
||||
background-color: rgb(143, 154, 216);
|
||||
}
|
||||
|
||||
.Last_Fail {
|
||||
table-layout: fixed;
|
||||
width: 100px;
|
||||
background-color: rgb(143, 154, 216);
|
||||
}
|
||||
|
||||
@@ -1,613 +0,0 @@
|
||||
#!/bin/bash
|
||||
#/*
|
||||
# * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
|
||||
# * contributor license agreements. See the NOTICE file distributed with
|
||||
# * this work for additional information regarding copyright ownership.
|
||||
# * The OpenAirInterface Software Alliance licenses this file to You under
|
||||
# * the OAI Public License, Version 1.1 (the "License"); you may not use this file
|
||||
# * except in compliance with the License.
|
||||
# * You may obtain a copy of the License at
|
||||
# *
|
||||
# * http://www.openairinterface.org/?page_id=698
|
||||
# *
|
||||
# * Unless required by applicable law or agreed to in writing, software
|
||||
# * distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# * See the License for the specific language governing permissions and
|
||||
# * limitations under the License.
|
||||
# *-------------------------------------------------------------------------------
|
||||
# * For more information about the OpenAirInterface (OAI) Software Alliance:
|
||||
# * contact@openairinterface.org
|
||||
# */
|
||||
|
||||
function report_build_usage {
|
||||
echo "OAI CI VM script"
|
||||
echo " Original Author: Raphael Defosseux"
|
||||
echo ""
|
||||
echo "Usage:"
|
||||
echo "------"
|
||||
echo " oai-ci-vm-tool report-build [OPTIONS]"
|
||||
echo ""
|
||||
command_options_usage
|
||||
|
||||
}
|
||||
|
||||
function trigger_usage {
|
||||
echo "OAI CI VM script"
|
||||
echo " Original Author: Raphael Defosseux"
|
||||
echo ""
|
||||
echo " --trigger merge-request OR -mr"
|
||||
echo " --trigger push OR -pu"
|
||||
echo " Specify trigger action of the Jenkins job. Either a merge-request event or a push event."
|
||||
echo ""
|
||||
}
|
||||
|
||||
function details_table {
|
||||
echo " <h4>$1</h4>" >> $3
|
||||
|
||||
echo " <table border = \"1\">" >> $3
|
||||
echo " <tr bgcolor = \"#33CCFF\" >" >> $3
|
||||
echo " <th>File</th>" >> $3
|
||||
echo " <th>Line Number</th>" >> $3
|
||||
echo " <th>Status</th>" >> $3
|
||||
echo " <th>Message</th>" >> $3
|
||||
echo " </tr>" >> $3
|
||||
|
||||
LIST_MESSAGES=`egrep "error:|warning:" $2 | egrep -v "jobserver unavailable|Clock skew detected.|disabling jobserver mode"`
|
||||
COMPLETE_MESSAGE="start"
|
||||
for MESSAGE in $LIST_MESSAGES
|
||||
do
|
||||
if [[ $MESSAGE == *"/home/ubuntu/tmp"* ]] || [[ $MESSAGE == *"/tmp/CI-eNB"* ]]
|
||||
then
|
||||
FILENAME=`echo $MESSAGE | sed -e "s#^/home/ubuntu/tmp/##" -e "s#^.*/tmp/CI-eNB/##" | awk -F ":" '{print $1}'`
|
||||
LINENB=`echo $MESSAGE | awk -F ":" '{print $2}'`
|
||||
if [ "$COMPLETE_MESSAGE" != "start" ]
|
||||
then
|
||||
COMPLETE_MESSAGE=`echo $COMPLETE_MESSAGE | sed -e "s#‘#'#g" -e "s#’#'#g"`
|
||||
echo " <td>$COMPLETE_MESSAGE</td>" >> $3
|
||||
echo " </tr>" >> $3
|
||||
fi
|
||||
echo " <tr>" >> $3
|
||||
echo " <td>$FILENAME</td>" >> $3
|
||||
echo " <td>$LINENB</td>" >> $3
|
||||
else
|
||||
if [[ $MESSAGE == *"warning:"* ]] || [[ $MESSAGE == *"error:"* ]]
|
||||
then
|
||||
MSGTYPE=`echo $MESSAGE | sed -e "s#:##g"`
|
||||
echo " <td>$MSGTYPE</td>" >> $3
|
||||
COMPLETE_MESSAGE=""
|
||||
else
|
||||
COMPLETE_MESSAGE=$COMPLETE_MESSAGE" "$MESSAGE
|
||||
fi
|
||||
fi
|
||||
done
|
||||
|
||||
if [ "$COMPLETE_MESSAGE" != "start" ]
|
||||
then
|
||||
COMPLETE_MESSAGE=`echo $COMPLETE_MESSAGE | sed -e "s#‘#'#g" -e "s#’#'#g"`
|
||||
echo " <td>$COMPLETE_MESSAGE</td>" >> $3
|
||||
echo " </tr>" >> $3
|
||||
fi
|
||||
echo " </table>" >> $3
|
||||
}
|
||||
|
||||
function summary_table_header {
|
||||
echo " <h3>$1</h3>" >> ./build_results.html
|
||||
if [ -f $2/build_final_status.log ]
|
||||
then
|
||||
if [ `grep -c COMMAND $2/build_final_status.log` -eq 1 ]
|
||||
then
|
||||
COMMAND=`grep COMMAND $2/build_final_status.log | sed -e "s#COMMAND: ##"`
|
||||
else
|
||||
COMMAND="Unknown"
|
||||
fi
|
||||
if [ `grep -c BUILD_OK $2/build_final_status.log` -eq 1 ]
|
||||
then
|
||||
echo " <div class=\"alert alert-success\">" >> ./build_results.html
|
||||
echo " <span class=\"glyphicon glyphicon-expand\"></span> $COMMAND <span class=\"glyphicon glyphicon-arrow-right\"></span> " >> ./build_results.html
|
||||
echo " <strong>BUILD was SUCCESSFUL <span class=\"glyphicon glyphicon-ok-circle\"></span></strong>" >> ./build_results.html
|
||||
echo " </div>" >> ./build_results.html
|
||||
else
|
||||
echo " <div class=\"alert alert-danger\">" >> ./build_results.html
|
||||
echo " <span class=\"glyphicon glyphicon-expand\"></span> $COMMAND <span class=\"glyphicon glyphicon-arrow-right\"></span> " >> ./build_results.html
|
||||
echo " <strong>BUILD was a FAILURE! <span class=\"glyphicon glyphicon-ban-circle\"></span></strong>" >> ./build_results.html
|
||||
echo " </div>" >> ./build_results.html
|
||||
fi
|
||||
else
|
||||
echo " <div class=\"alert alert-danger\">" >> ./build_results.html
|
||||
echo " <strong>COULD NOT DETERMINE BUILD FINAL STATUS! <span class=\"glyphicon glyphicon-ban-circle\"></span></strong>" >> ./build_results.html
|
||||
echo " </div>" >> ./build_results.html
|
||||
fi
|
||||
echo " <table border = \"1\">" >> ./build_results.html
|
||||
echo " <tr bgcolor = \"#33CCFF\" >" >> ./build_results.html
|
||||
echo " <th>Element</th>" >> ./build_results.html
|
||||
echo " <th>Status</th>" >> ./build_results.html
|
||||
echo " <th>Nb Errors</th>" >> ./build_results.html
|
||||
echo " <th>Nb Warnings</th>" >> ./build_results.html
|
||||
echo " </tr>" >> ./build_results.html
|
||||
}
|
||||
|
||||
function summary_table_row {
|
||||
echo " <tr>" >> ./build_results.html
|
||||
echo " <td bgcolor = \"lightcyan\" >$1</th>" >> ./build_results.html
|
||||
if [ -f $2 ]
|
||||
then
|
||||
BUILD_STATUS=`egrep -c "$3" $2`
|
||||
if [ $BUILD_STATUS -eq 1 ]
|
||||
then
|
||||
echo " <td bgcolor = \"green\" >OK</th>" >> ./build_results.html
|
||||
else
|
||||
echo " <td bgcolor = \"red\" >KO</th>" >> ./build_results.html
|
||||
fi
|
||||
NB_ERRORS=`egrep -c "error:" $2`
|
||||
if [ $NB_ERRORS -eq 0 ]
|
||||
then
|
||||
echo " <td bgcolor = \"green\" >$NB_ERRORS</th>" >> ./build_results.html
|
||||
else
|
||||
echo " <td bgcolor = \"red\" >$NB_ERRORS</th>" >> ./build_results.html
|
||||
fi
|
||||
NB_WARNINGS=`egrep "warning:" $2 | egrep -v "jobserver unavailable|Clock skew detected.|disabling jobserver mode" | egrep -c "warning:"`
|
||||
if [ $NB_WARNINGS -eq 0 ]
|
||||
then
|
||||
echo " <td bgcolor = \"green\" >$NB_WARNINGS</th>" >> ./build_results.html
|
||||
else
|
||||
if [ $NB_WARNINGS -gt 20 ]
|
||||
then
|
||||
echo " <td bgcolor = \"red\" >$NB_WARNINGS</th>" >> ./build_results.html
|
||||
else
|
||||
echo " <td bgcolor = \"orange\" >$NB_WARNINGS</th>" >> ./build_results.html
|
||||
fi
|
||||
fi
|
||||
if [ $NB_ERRORS -ne 0 ] || [ $NB_WARNINGS -ne 0 ]
|
||||
then
|
||||
details_table "$1" $2 $4
|
||||
fi
|
||||
else
|
||||
echo " <td bgcolor = \"lightgray\" >Unknown</th>" >> ./build_results.html
|
||||
echo " <td bgcolor = \"lightgray\" >--</th>" >> ./build_results.html
|
||||
echo " <td bgcolor = \"lightgray\" >--</th>" >> ./build_results.html
|
||||
fi
|
||||
echo " </tr>" >> ./build_results.html
|
||||
}
|
||||
|
||||
function summary_table_footer {
|
||||
echo " </table>" >> ./build_results.html
|
||||
}
|
||||
|
||||
function sca_summary_table_header {
|
||||
echo " <h3>$2</h3>" >> ./build_results.html
|
||||
NB_ERRORS=`egrep -c "severity=\"error\"" $1`
|
||||
NB_WARNINGS=`egrep -c "severity=\"warning\"" $1`
|
||||
ADDED_ERRORS="0"
|
||||
ADDED_WARNINGS="0"
|
||||
FINAL_LOG=`echo $1 | sed -e "s#cppcheck\.xml#build_final_status.log#"`
|
||||
if [ `grep -c COMMAND $FINAL_LOG` -eq 1 ]
|
||||
then
|
||||
COMMAND=`grep COMMAND $FINAL_LOG | sed -e "s#COMMAND: ##"`
|
||||
else
|
||||
COMMAND="Unknown"
|
||||
fi
|
||||
if [ $MR_TRIG -eq 1 ]
|
||||
then
|
||||
if [ -d ../../cppcheck_archives ]
|
||||
then
|
||||
if [ -d ../../cppcheck_archives/$JOB_NAME ]
|
||||
then
|
||||
ADDED_ERRORS=`diff $1 ../../cppcheck_archives/$JOB_NAME/cppcheck.xml | egrep --color=never "^<" | egrep -c "severity=\"error"`
|
||||
ADDED_WARNINGS=`diff $1 ../../cppcheck_archives/$JOB_NAME/cppcheck.xml | egrep --color=never "^<" | egrep -c "severity=\"warning"`
|
||||
fi
|
||||
fi
|
||||
local TOTAL_NUMBER=$[$ADDED_ERRORS+$ADDED_WARNINGS]
|
||||
if [ -f $JENKINS_WKSP/oai_cppcheck_added_errors.txt ]; then rm -f $JENKINS_WKSP/oai_cppcheck_added_errors.txt; fi
|
||||
echo "$TOTAL_NUMBER" > $JENKINS_WKSP/oai_cppcheck_added_errors.txt
|
||||
fi
|
||||
if [ $NB_ERRORS -eq 0 ] && [ $NB_WARNINGS -eq 0 ]
|
||||
then
|
||||
echo " <div class=\"alert alert-success\">" >> ./build_results.html
|
||||
echo " <span class=\"glyphicon glyphicon-expand\"></span> $COMMAND <br><br>" >> ./build_results.html
|
||||
echo " <strong>CPPCHECK found NO error and NO warning <span class=\"glyphicon glyphicon-ok-circle\"></span></strong>" >> ./build_results.html
|
||||
echo " </div>" >> ./build_results.html
|
||||
else
|
||||
if [ $NB_ERRORS -eq 0 ]
|
||||
then
|
||||
echo " <div class=\"alert alert-warning\">" >> ./build_results.html
|
||||
echo " <span class=\"glyphicon glyphicon-expand\"></span> $COMMAND <br><br>" >> ./build_results.html
|
||||
if [ $PU_TRIG -eq 1 ]
|
||||
then
|
||||
echo " <strong>CPPCHECK found NO error and $NB_WARNINGS warnings <span class=\"glyphicon glyphicon-warning-sign\"></span></strong>" >> ./build_results.html
|
||||
fi
|
||||
if [ $MR_TRIG -eq 1 ]
|
||||
then
|
||||
if [ $ADDED_WARNINGS -eq 0 ]
|
||||
then
|
||||
echo " <strong>CPPCHECK found NO error and $NB_WARNINGS warnings <span class=\"glyphicon glyphicon-warning-sign\"></span></strong>" >> ./build_results.html
|
||||
else
|
||||
echo " <strong>CPPCHECK found NO error and $NB_WARNINGS warnings <span class=\"glyphicon glyphicon-warning-sign\"></span></strong>" >> ./build_results.html
|
||||
fi
|
||||
fi
|
||||
echo " </div>" >> ./build_results.html
|
||||
else
|
||||
echo " <div class=\"alert alert-danger\">" >> ./build_results.html
|
||||
echo " <span class=\"glyphicon glyphicon-expand\"></span> $COMMAND <br><br>" >> ./build_results.html
|
||||
if [ $PU_TRIG -eq 1 ]
|
||||
then
|
||||
echo " <strong>CPPCHECK found $NB_ERRORS errors and $NB_WARNINGS warnings <span class=\"glyphicon glyphicon-ban-circle\"></span></strong>" >> ./build_results.html
|
||||
fi
|
||||
if [ $MR_TRIG -eq 1 ]
|
||||
then
|
||||
if [ $ADDED_ERRORS -eq 0 ] && [ $ADDED_WARNINGS -eq 0 ]
|
||||
then
|
||||
echo " <strong>CPPCHECK found $NB_ERRORS errors and $NB_WARNINGS warnings <span class=\"glyphicon glyphicon-ban-circle\"></span></strong>" >> ./build_results.html
|
||||
else
|
||||
echo " <strong>CPPCHECK found $NB_ERRORS errors and $NB_WARNINGS warnings <span class=\"glyphicon glyphicon-ban-circle\"></span>" >> ./build_results.html
|
||||
echo " <br>" >> ./build_results.html
|
||||
echo " <br>" >> ./build_results.html
|
||||
echo " <span class=\"glyphicon glyphicon-alert\"></span> This Merge Request may have introduced up to $ADDED_ERRORS errors and $ADDED_WARNINGS warnings. <span class=\"glyphicon glyphicon-alert\"></span></strong>" >> ./build_results.html
|
||||
fi
|
||||
fi
|
||||
echo " </div>" >> ./build_results.html
|
||||
fi
|
||||
fi
|
||||
if [ $PU_TRIG -eq 1 ]
|
||||
then
|
||||
if [ -d ../../cppcheck_archives ]
|
||||
then
|
||||
if [ -d ../../cppcheck_archives/$JOB_NAME ]
|
||||
then
|
||||
cp $1 ../../cppcheck_archives/$JOB_NAME
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
echo " <button data-toggle=\"collapse\" data-target=\"#oai-cppcheck-details\">More details on CPPCHECK results</button>" >> ./build_results.html
|
||||
echo " <div id=\"oai-cppcheck-details\" class=\"collapse\">" >> ./build_results.html
|
||||
echo " <br>" >> ./build_results.html
|
||||
echo " <table border = \"1\">" >> ./build_results.html
|
||||
echo " <tr bgcolor = \"#33CCFF\" >" >> ./build_results.html
|
||||
echo " <th>Error / Warning Type</th>" >> ./build_results.html
|
||||
echo " <th>Nb Errors</th>" >> ./build_results.html
|
||||
echo " <th>Nb Warnings</th>" >> ./build_results.html
|
||||
echo " </tr>" >> ./build_results.html
|
||||
echo "0" > ccp_error_cnt.txt
|
||||
}
|
||||
|
||||
function sca_summary_table_row {
|
||||
echo " <tr>" >> ./build_results.html
|
||||
echo " <td bgcolor = \"lightcyan\" >$2</td>" >> ./build_results.html
|
||||
if [ -f $1 ]
|
||||
then
|
||||
NB_ERRORS=`egrep "severity=\"error\"" $1 | egrep -c "id=\"$3\""`
|
||||
echo " <td>$NB_ERRORS</td>" >> ./build_results.html
|
||||
echo " <td>N/A</td>" >> ./build_results.html
|
||||
if [ -f ccp_error_cnt.txt ]
|
||||
then
|
||||
TOTAL_ERRORS=`cat ccp_error_cnt.txt`
|
||||
TOTAL_ERRORS=$((TOTAL_ERRORS + NB_ERRORS))
|
||||
echo $TOTAL_ERRORS > ccp_error_cnt.txt
|
||||
fi
|
||||
else
|
||||
echo " <td>Unknown</td>" >> ./build_results.html
|
||||
echo " <td>Unknown</td>" >> ./build_results.html
|
||||
fi
|
||||
echo " </tr>" >> ./build_results.html
|
||||
}
|
||||
|
||||
function sca_summary_table_footer {
|
||||
if [ -f $1 ]
|
||||
then
|
||||
NB_ERRORS=`egrep -c "severity=\"error\"" $1`
|
||||
NB_WARNINGS=`egrep -c "severity=\"warning\"" $1`
|
||||
if [ -f ccp_error_cnt.txt ]
|
||||
then
|
||||
echo " <tr>" >> ./build_results.html
|
||||
echo " <td bgcolor = \"lightcyan\" >Others</td>" >> ./build_results.html
|
||||
TOTAL_ERRORS=`cat ccp_error_cnt.txt`
|
||||
TOTAL_ERRORS=$((NB_ERRORS - TOTAL_ERRORS))
|
||||
echo " <td>$TOTAL_ERRORS</td>" >> ./build_results.html
|
||||
echo " <td>$NB_WARNINGS</td>" >> ./build_results.html
|
||||
echo " </tr>" >> ./build_results.html
|
||||
rm -f ccp_error_cnt.txt
|
||||
fi
|
||||
echo " <tr bgcolor = \"#33CCFF\" >" >> ./build_results.html
|
||||
echo " <th>Total</th>" >> ./build_results.html
|
||||
echo " <th>$NB_ERRORS</th>" >> ./build_results.html
|
||||
echo " <th>$NB_WARNINGS</th>" >> ./build_results.html
|
||||
else
|
||||
echo " <tr bgcolor = \"#33CCFF\" >" >> ./build_results.html
|
||||
echo " <th>Total</th>" >> ./build_results.html
|
||||
echo " <th>Unknown</th>" >> ./build_results.html
|
||||
echo " <th>Unknown</th>" >> ./build_results.html
|
||||
if [ -f ccp_error_cnt.txt ]
|
||||
then
|
||||
rm -f ccp_error_cnt.txt
|
||||
fi
|
||||
fi
|
||||
echo " </tr>" >> ./build_results.html
|
||||
echo " </table>" >> ./build_results.html
|
||||
echo " <p>Full details in zipped artifact (cppcheck/cppcheck.xml) </p>" >> ./build_results.html
|
||||
echo " <p style=\"margin-left: 30px\">Graphical Interface tool : <strong><code>cppcheck-gui -l cppcheck/cppcheck.xml</code></strong></p>" >> ./build_results.html
|
||||
|
||||
if [ $MR_TRIG -eq 1 ]
|
||||
then
|
||||
if [ $ADDED_ERRORS -ne 0 ] || [ $ADDED_WARNINGS -ne 0 ]
|
||||
then
|
||||
echo " <table border = \"1\">" >> ./build_results.html
|
||||
echo " <tr bgcolor = \"#33CCFF\" >" >> ./build_results.html
|
||||
echo " <th>Potential File(s) impacted by added errors/warnings</th>" >> ./build_results.html
|
||||
echo " <th>Line Number</th>" >> ./build_results.html
|
||||
echo " <th>Severity</th>" >> ./build_results.html
|
||||
echo " <th>Message</th>" >> ./build_results.html
|
||||
echo " </tr>" >> ./build_results.html
|
||||
SEVERITY="none"
|
||||
POTENTIAL_FILES=`diff $1 ../../cppcheck_archives/$JOB_NAME/cppcheck.xml | egrep --color=never "^<" | egrep "location file|severity" | sed -e "s# #@#g"`
|
||||
for POT_FILE in $POTENTIAL_FILES
|
||||
do
|
||||
if [ `echo $POT_FILE | grep -c location` -eq 1 ]
|
||||
then
|
||||
FILENAME=`echo $POT_FILE | sed -e "s#^.*file=\"##" -e "s#\"@line.*/>##"`
|
||||
LINE=`echo $POT_FILE | sed -e "s#^.*line=\"##" -e "s#\"/>##"`
|
||||
if [[ $SEVERITY != *"none" ]]
|
||||
then
|
||||
echo " <tr>" >> ./build_results.html
|
||||
echo " <td>$FILENAME</td>" >> ./build_results.html
|
||||
echo " <td>$LINE</td>" >> ./build_results.html
|
||||
echo " <td>$SEVERITY</td>" >> ./build_results.html
|
||||
echo " <td>$MESSAGE</td>" >> ./build_results.html
|
||||
echo " </tr>" >> ./build_results.html
|
||||
fi
|
||||
else
|
||||
SEVERITY=`echo $POT_FILE | sed -e "s#^.*severity=\"##" -e "s#\"@msg=.*##"`
|
||||
MESSAGE=`echo $POT_FILE | sed -e "s#^.*msg=\"##" -e "s#\"@verbose=.*##" -e "s#@# #g"`
|
||||
fi
|
||||
done
|
||||
echo " </table>" >> ./build_results.html
|
||||
fi
|
||||
fi
|
||||
echo " </div>" >> ./build_results.html
|
||||
}
|
||||
|
||||
function report_build {
|
||||
echo "############################################################"
|
||||
echo "OAI CI VM script"
|
||||
echo "############################################################"
|
||||
|
||||
echo "JENKINS_WKSP = $JENKINS_WKSP"
|
||||
echo "GIT_URL = $GIT_URL"
|
||||
|
||||
cd ${JENKINS_WKSP}
|
||||
echo "<!DOCTYPE html>" > ./build_results.html
|
||||
echo "<html class=\"no-js\" lang=\"en-US\">" >> ./build_results.html
|
||||
echo "<head>" >> ./build_results.html
|
||||
echo " <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">" >> ./build_results.html
|
||||
echo " <link rel=\"stylesheet\" href=\"https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css\">" >> ./build_results.html
|
||||
echo " <script src=\"https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js\"></script>" >> ./build_results.html
|
||||
echo " <script src=\"https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js\"></script>" >> ./build_results.html
|
||||
echo " <title>Build Results for $JOB_NAME job build #$BUILD_ID</title>" >> ./build_results.html
|
||||
echo " <base href = \"http://www.openairinterface.org/\" />" >> ./build_results.html
|
||||
echo "</head>" >> ./build_results.html
|
||||
echo "<body><div class=\"container\">" >> ./build_results.html
|
||||
echo " <br>" >> ./build_results.html
|
||||
echo " <table style=\"border-collapse: collapse; border: none;\">" >> ./build_results.html
|
||||
echo " <tr style=\"border-collapse: collapse; border: none;\">" >> ./build_results.html
|
||||
echo " <td style=\"border-collapse: collapse; border: none;\">" >> ./build_results.html
|
||||
echo " <a href=\"http://www.openairinterface.org/\">" >> ./build_results.html
|
||||
echo " <img src=\"/wp-content/uploads/2016/03/cropped-oai_final_logo2.png\" alt=\"\" border=\"none\" height=50 width=150>" >> ./build_results.html
|
||||
echo " </img>" >> ./build_results.html
|
||||
echo " </a>" >> ./build_results.html
|
||||
echo " </td>" >> ./build_results.html
|
||||
echo " <td style=\"border-collapse: collapse; border: none; vertical-align: center;\">" >> ./build_results.html
|
||||
echo " <b><font size = \"6\">Job Summary -- Job: $JOB_NAME -- Build-ID: $BUILD_ID</font></b>" >> ./build_results.html
|
||||
echo " </td>" >> ./build_results.html
|
||||
echo " </tr>" >> ./build_results.html
|
||||
echo " </table>" >> ./build_results.html
|
||||
echo " <br>" >> ./build_results.html
|
||||
echo " <table border = \"1\">" >> ./build_results.html
|
||||
echo " <tr>" >> ./build_results.html
|
||||
echo " <td bgcolor = \"lightcyan\" > <span class=\"glyphicon glyphicon-time\"></span> Build Start Time (UTC)</td>" >> ./build_results.html
|
||||
echo " <td>TEMPLATE_BUILD_TIME</td>" >> ./build_results.html
|
||||
echo " </tr>" >> ./build_results.html
|
||||
echo " <tr>" >> ./build_results.html
|
||||
echo " <td bgcolor = \"lightcyan\" > <span class=\"glyphicon glyphicon-cloud-upload\"></span> GIT Repository</td>" >> ./build_results.html
|
||||
echo " <td><a href=\"$GIT_URL\">$GIT_URL</a></td>" >> ./build_results.html
|
||||
echo " </tr>" >> ./build_results.html
|
||||
echo " <tr>" >> ./build_results.html
|
||||
echo " <td bgcolor = \"lightcyan\" > <span class=\"glyphicon glyphicon-wrench\"></span> Job Trigger</td>" >> ./build_results.html
|
||||
if [ $PU_TRIG -eq 1 ]; then echo " <td>Push Event</td>" >> ./build_results.html; fi
|
||||
if [ $MR_TRIG -eq 1 ]; then echo " <td>Merge-Request</td>" >> ./build_results.html; fi
|
||||
echo " </tr>" >> ./build_results.html
|
||||
if [ $PU_TRIG -eq 1 ]
|
||||
then
|
||||
echo " <tr>" >> ./build_results.html
|
||||
echo " <td bgcolor = \"lightcyan\" > <span class=\"glyphicon glyphicon-tree-deciduous\"></span> Branch</td>" >> ./build_results.html
|
||||
echo " <td>$SOURCE_BRANCH</td>" >> ./build_results.html
|
||||
echo " </tr>" >> ./build_results.html
|
||||
echo " <tr>" >> ./build_results.html
|
||||
echo " <td bgcolor = \"lightcyan\" > <span class=\"glyphicon glyphicon-tag\"></span> Commit ID</td>" >> ./build_results.html
|
||||
echo " <td>$SOURCE_COMMIT_ID</td>" >> ./build_results.html
|
||||
echo " </tr>" >> ./build_results.html
|
||||
if [ -e .git/CI_COMMIT_MSG ]
|
||||
then
|
||||
echo " <tr>" >> ./build_results.html
|
||||
echo " <td bgcolor = \"lightcyan\" > <span class=\"glyphicon glyphicon-comment\"></span> Commit Message</td>" >> ./build_results.html
|
||||
MSG=`cat .git/CI_COMMIT_MSG`
|
||||
echo " <td>$MSG</td>" >> ./build_results.html
|
||||
echo " </tr>" >> ./build_results.html
|
||||
fi
|
||||
fi
|
||||
if [ $MR_TRIG -eq 1 ]
|
||||
then
|
||||
echo " <tr>" >> ./build_results.html
|
||||
echo " <td bgcolor = \"lightcyan\" > <span class=\"glyphicon glyphicon-log-out\"></span> Source Branch</td>" >> ./build_results.html
|
||||
echo " <td>$SOURCE_BRANCH</td>" >> ./build_results.html
|
||||
echo " </tr>" >> ./build_results.html
|
||||
echo " <tr>" >> ./build_results.html
|
||||
echo " <td bgcolor = \"lightcyan\" > <span class=\"glyphicon glyphicon-tag\"></span> Source Commit ID</td>" >> ./build_results.html
|
||||
echo " <td>$SOURCE_COMMIT_ID</td>" >> ./build_results.html
|
||||
echo " </tr>" >> ./build_results.html
|
||||
if [ -e .git/CI_COMMIT_MSG ]
|
||||
then
|
||||
echo " <tr>" >> ./build_results.html
|
||||
echo " <td bgcolor = \"lightcyan\" > <span class=\"glyphicon glyphicon-comment\"></span> Source Commit Message</td>" >> ./build_results.html
|
||||
MSG=`cat .git/CI_COMMIT_MSG`
|
||||
echo " <td>$MSG</td>" >> ./build_results.html
|
||||
echo " </tr>" >> ./build_results.html
|
||||
fi
|
||||
echo " <tr>" >> ./build_results.html
|
||||
echo " <td bgcolor = \"lightcyan\" > <span class=\"glyphicon glyphicon-log-in\"></span> Target Branch</td>" >> ./build_results.html
|
||||
echo " <td>$TARGET_BRANCH</td>" >> ./build_results.html
|
||||
echo " </tr>" >> ./build_results.html
|
||||
echo " <tr>" >> ./build_results.html
|
||||
echo " <td bgcolor = \"lightcyan\" > <span class=\"glyphicon glyphicon-tag\"></span> Target Commit ID</td>" >> ./build_results.html
|
||||
echo " <td>$TARGET_COMMIT_ID</td>" >> ./build_results.html
|
||||
echo " </tr>" >> ./build_results.html
|
||||
fi
|
||||
echo " </table>" >> ./build_results.html
|
||||
echo " <h2>Build Summary</h2>" >> ./build_results.html
|
||||
|
||||
echo " <h3>OAI Coding / Formatting Guidelines Check</h3>" >> ./build_results.html
|
||||
if [ -f ./header-files-w-incorrect-define.txt ]
|
||||
then
|
||||
NB_FILES_IN_ERROR=`wc -l ./header-files-w-incorrect-define.txt | sed -e "s@ .*@@"`
|
||||
if [ $NB_FILES_IN_ERROR -eq 0 ]
|
||||
then
|
||||
echo " <div class=\"alert alert-success\">" >> ./build_results.html
|
||||
if [ $MR_TRIG -eq 1 ]; then echo " <strong>No Issue for CIRCULAR DEPENDENCY PROTECTION in modified files</strong>" >> ./build_results.html; fi
|
||||
if [ $PU_TRIG -eq 1 ]; then echo " <strong>No Issue for CIRCULAR DEPENDENCY PROTECTION in the whole repository</strong>" >> ./build_results.html; fi
|
||||
echo " </div>" >> ./build_results.html
|
||||
else
|
||||
echo " <div class=\"alert alert-warning\">" >> ./build_results.html
|
||||
if [ $MR_TRIG -eq 1 ]; then echo " <strong>${NB_FILES_IN_ERROR} modified files MAY NOT HAVE CIRCULAR DEPENDENCY PROTECTION</strong>" >> ./build_results.html; fi
|
||||
if [ $PU_TRIG -eq 1 ]; then echo " <strong>${NB_FILES_IN_ERROR} files in repository MAY NOT HAVE CIRCULAR DEPENDENCY PROTECTION in the whole repository</strong>" >> ./build_results.html; fi
|
||||
echo " </div>" >> ./build_results.html
|
||||
echo " <button data-toggle=\"collapse\" data-target=\"#oai-circular-details\">More details on circular dependency protection check</button>" >> ./build_results.html
|
||||
echo " <div id=\"oai-circular-details\" class=\"collapse\">" >> ./build_results.html
|
||||
echo " <table border = 1>" >> ./build_results.html
|
||||
echo " <tr>" >> ./build_results.html
|
||||
echo " <th bgcolor = \"lightcyan\" >Potential Issue</th>" >> ./build_results.html
|
||||
echo " <th bgcolor = \"lightcyan\" >Impacted File</th>" >> ./build_results.html
|
||||
echo " <th bgcolor = \"lightcyan\" >Incorrect Macro</th>" >> ./build_results.html
|
||||
echo " </tr>" >> ./build_results.html
|
||||
awk '{if($0 ~/error in/){print " <tr><td>error in declaration</td><td>"$4"</td><td>"$5"</td></tr>"};if($0 ~/files with same/){print " <tr><td>files with same #define</td><td>"$5"</td><td>"$6"</td></tr>"}}' ./header-files-w-incorrect-define.txt >> ./build_results.html
|
||||
echo " </table>" >> ./build_results.html
|
||||
echo " </div>" >> ./build_results.html
|
||||
echo " <br>" >> ./build_results.html
|
||||
fi
|
||||
fi
|
||||
if [ -f ./files-w-gnu-gpl-license-banner.txt ]
|
||||
then
|
||||
NB_FILES_IN_ERROR=`wc -l ./files-w-gnu-gpl-license-banner.txt | sed -e "s@ .*@@"`
|
||||
if [ $NB_FILES_IN_ERROR -ne 0 ]
|
||||
then
|
||||
echo " <div class=\"alert alert-danger\">" >> ./build_results.html
|
||||
if [ $MR_TRIG -eq 1 ]; then echo " <strong>${NB_FILES_IN_ERROR} modified files HAVE a GNU GPL license banner</strong>" >> ./build_results.html; fi
|
||||
if [ $PU_TRIG -eq 1 ]; then echo " <strong>${NB_FILES_IN_ERROR} files in repository HAVE a GNU GPL license banner</strong>" >> ./build_results.html; fi
|
||||
echo " </div>" >> ./build_results.html
|
||||
echo " <button data-toggle=\"collapse\" data-target=\"#oai-license-gpl\">More details on GNU GPL license banner issue</button>" >> ./build_results.html
|
||||
echo " <div id=\"oai-license-gpl\" class=\"collapse\">" >> ./build_results.html
|
||||
echo " <table border = 1>" >> ./build_results.html
|
||||
echo " <tr>" >> ./build_results.html
|
||||
echo " <th bgcolor = \"lightcyan\" >Filename</th>" >> ./build_results.html
|
||||
echo " </tr>" >> ./build_results.html
|
||||
awk '{print " <tr><td>"$1"</td></tr>"}' ./files-w-gnu-gpl-license-banner.txt >> ./build_results.html
|
||||
echo " </table>" >> ./build_results.html
|
||||
echo " </div>" >> ./build_results.html
|
||||
echo " <br>" >> ./build_results.html
|
||||
fi
|
||||
fi
|
||||
if [ -f ./files-w-suspect-banner.txt ]
|
||||
then
|
||||
NB_FILES_IN_ERROR=`wc -l ./files-w-suspect-banner.txt | sed -e "s@ .*@@"`
|
||||
if [ $NB_FILES_IN_ERROR -ne 0 ]
|
||||
then
|
||||
echo " <div class=\"alert alert-warning\">" >> ./build_results.html
|
||||
if [ $MR_TRIG -eq 1 ]; then echo " <strong>${NB_FILES_IN_ERROR} modified files HAVE a suspect license banner</strong>" >> ./build_results.html; fi
|
||||
if [ $PU_TRIG -eq 1 ]; then echo " <strong>${NB_FILES_IN_ERROR} files in repository HAVE a suspect license banner</strong>" >> ./build_results.html; fi
|
||||
echo " </div>" >> ./build_results.html
|
||||
echo " <button data-toggle=\"collapse\" data-target=\"#oai-license-suspect\">More details on suspect banner files</button>" >> ./build_results.html
|
||||
echo " <div id=\"oai-license-suspect\" class=\"collapse\">" >> ./build_results.html
|
||||
echo " <table border = 1>" >> ./build_results.html
|
||||
echo " <tr>" >> ./build_results.html
|
||||
echo " <th bgcolor = \"lightcyan\" >Filename</th>" >> ./build_results.html
|
||||
echo " </tr>" >> ./build_results.html
|
||||
awk '{print " <tr><td>"$1"</td></tr>"}' ././files-w-suspect-banner.txt >> ./build_results.html
|
||||
echo " </table>" >> ./build_results.html
|
||||
echo " </div>" >> ./build_results.html
|
||||
echo " <br>" >> ./build_results.html
|
||||
fi
|
||||
fi
|
||||
|
||||
echo " <h2>Ubuntu 16.04 LTS -- Summary</h2>" >> ./build_results.html
|
||||
|
||||
if [ -f archives/gnb_usrp/nr-softmodem.txt ]
|
||||
then
|
||||
summary_table_header "OAI Build: 5G NR gNB -- USRP option" ./archives/gnb_usrp
|
||||
summary_table_row "5G NR SoftModem" ./archives/gnb_usrp/nr-softmodem.txt "Built target nr-softmodem" ./gnb_usrp_row1.html
|
||||
summary_table_row "Coding" ./archives/gnb_usrp/coding.txt "Built target coding" ./gnb_usrp_row2.html
|
||||
summary_table_row "OAI USRP device if" ./archives/gnb_usrp/oai_usrpdevif.txt "Built target oai_usrpdevif" ./gnb_usrp_row3.html
|
||||
summary_table_row "OAI ETHERNET transport" ./archives/gnb_usrp/oai_eth_transpro.txt "Built target oai_eth_transpro" ./gnb_usrp_row4.html
|
||||
summary_table_row "Parameters Lib Config" ./archives/gnb_usrp/params_libconfig.txt "Built target params_libconfig" ./gnb_usrp_row6.html
|
||||
summary_table_footer
|
||||
fi
|
||||
|
||||
if [ -f archives/nr_ue_usrp/nr-uesoftmodem.txt ]
|
||||
then
|
||||
summary_table_header "OAI Build: 5G NR UE -- USRP option" ./archives/nr_ue_usrp
|
||||
summary_table_row "5G NR UE SoftModem" ./archives/nr_ue_usrp/nr-uesoftmodem.txt "Built target nr-uesoftmodem" ./nr_ue_usrp_row1.html
|
||||
summary_table_row "Coding" ./archives/nr_ue_usrp/coding.txt "Built target coding" ./nr_ue_usrp_row2.html
|
||||
summary_table_row "OAI USRP device if" ./archives/nr_ue_usrp/oai_usrpdevif.txt "Built target oai_usrpdevif" ./nr_ue_usrp_row3.html
|
||||
summary_table_row "OAI ETHERNET transport" ./archives/nr_ue_usrp/oai_eth_transpro.txt "Built target oai_eth_transpro" ./nr_ue_usrp_row4.html
|
||||
summary_table_row "Parameters Lib Config" ./archives/nr_ue_usrp/params_libconfig.txt "Built target params_libconfig" ./nr_ue_usrp_row6.html
|
||||
summary_table_footer
|
||||
fi
|
||||
|
||||
if [ -e ./archives/red_hat ]
|
||||
then
|
||||
echo " <h2>Red Hat Enterprise Linux Server release 7.6) -- Summary</h2>" >> ./build_results.html
|
||||
|
||||
summary_table_header "OAI Build: 4G LTE eNB -- USRP option (RHEL)" ./archives/red_hat
|
||||
summary_table_row "LTE SoftModem" ./archives/red_hat/lte-softmodem.txt "Built target lte-softmodem" ./enb_usrp_rh_row1.html
|
||||
summary_table_row "Coding" ./archives/red_hat/coding.txt "Built target coding" ./enb_usrp_rh_row2.html
|
||||
summary_table_row "OAI USRP device if" ./archives/red_hat/oai_usrpdevif.txt "Built target oai_usrpdevif" ./enb_usrp_rh_row3.html
|
||||
summary_table_row "Parameters Lib Config" ./archives/red_hat/params_libconfig.txt "Built target params_libconfig" ./enb_usrp_rh_row4.html
|
||||
summary_table_footer
|
||||
fi
|
||||
|
||||
echo " <h3>Details</h3>" >> ./build_results.html
|
||||
echo " <button data-toggle=\"collapse\" data-target=\"#oai-compilation-details\">Details for Compilation Errors and Warnings </button>" >> ./build_results.html
|
||||
echo " <div id=\"oai-compilation-details\" class=\"collapse\">" >> ./build_results.html
|
||||
|
||||
if [ -f ./enb_eth_row1.html ] || [ -f ./enb_eth_row2.html ] || [ -f ./enb_eth_row3.html ] || [ -f ./enb_eth_row4.html ] || [ -f ./enb_eth_row5.html ] || [ -f ./enb_eth_row6.html ] || [ -f ./enb_eth_row7.html ]
|
||||
then
|
||||
for DETAILS_TABLE in `ls ./enb_eth_row*.html`
|
||||
do
|
||||
cat $DETAILS_TABLE >> ./build_results.html
|
||||
done
|
||||
fi
|
||||
if [ -f ./ue_eth_row1.html ] || [ -f ./ue_eth_row2.html ] || [ -f ./ue_eth_row3.html ] || [ -f ./ue_eth_row4.html ] || [ -f ./ue_eth_row5.html ] || [ -f ./ue_eth_row6.html ] || [ -f ./ue_eth_row7.html ] || [ -f ./ue_eth_row8.html ] || [ -f ./ue_eth_row9.html ] || [ -f ./ue_eth_row9a.html ] || [ -f ./ue_eth_row9b.html ]
|
||||
then
|
||||
for DETAILS_TABLE in `ls ./ue_eth_row*.html`
|
||||
do
|
||||
cat $DETAILS_TABLE >> ./build_results.html
|
||||
done
|
||||
fi
|
||||
if [ -f ./gnb_usrp_row1.html ] || [ -f ./gnb_usrp_row2.html ] || [ -f ./gnb_usrp_row3.html ] || [ -f ./gnb_usrp_row4.html ]
|
||||
then
|
||||
for DETAILS_TABLE in `ls ./gnb_usrp_row*.html`
|
||||
do
|
||||
cat $DETAILS_TABLE >> ./build_results.html
|
||||
done
|
||||
fi
|
||||
if [ -f ./nr_ue_usrp_row1.html ] || [ -f ./nr_ue_usrp_row2.html ] || [ -f ./nr_ue_usrp_row3.html ] || [ -f ./nr_ue_usrp_row4.html ]
|
||||
then
|
||||
for DETAILS_TABLE in `ls ./nr_ue_usrp_row*.html`
|
||||
do
|
||||
cat $DETAILS_TABLE >> ./build_results.html
|
||||
done
|
||||
fi
|
||||
rm -f ./*_row*.html
|
||||
|
||||
echo " </div>" >> ./build_results.html
|
||||
echo " <p></p>" >> ./build_results.html
|
||||
echo " <div class=\"well well-lg\">End of Build Report -- Copyright <span class=\"glyphicon glyphicon-copyright-mark\"></span> 2018 <a href=\"http://www.openairinterface.org/\">OpenAirInterface</a>. All Rights Reserved.</div>" >> ./build_results.html
|
||||
echo "</div></body>" >> ./build_results.html
|
||||
echo "</html>" >> ./build_results.html
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,65 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
|
||||
<xsl:output method="html" version="4" encoding="UTF-8" indent="no" omit-xml-declaration="yes"/>
|
||||
<!-- main body -->
|
||||
<xsl:template match="/">
|
||||
<html>
|
||||
<body>
|
||||
<h3>TEMPLATE Results Summary</h3>
|
||||
<table border="1">
|
||||
<tr bgcolor="lightcyan">
|
||||
<!--Header only so select first row to get headers-->
|
||||
<th>Hostname</th>
|
||||
<th>Nb Tests</th>
|
||||
<th>Failures</th>
|
||||
<th>Timestamp</th>
|
||||
</tr>
|
||||
<!--Get all the other rows-->
|
||||
<xsl:for-each select="testsuites/testsuite">
|
||||
<tr>
|
||||
<td>
|
||||
<xsl:value-of select="@hostname"/>
|
||||
</td>
|
||||
<td>
|
||||
<xsl:value-of select="@tests"/>
|
||||
</td>
|
||||
<td>
|
||||
<xsl:value-of select="@failures"/>
|
||||
</td>
|
||||
<td>
|
||||
<xsl:value-of select="@timestamp"/>
|
||||
</td>
|
||||
</tr>
|
||||
</xsl:for-each>
|
||||
</table>
|
||||
<h4>Details</h4>
|
||||
<table border="1">
|
||||
<tr bgcolor="lightcyan">
|
||||
<!--Header only so select first row to get headers-->
|
||||
<th>Test Name</th>
|
||||
<th>Result</th>
|
||||
<th>Time</th>
|
||||
<th>Description</th>
|
||||
</tr>
|
||||
<!--Get all the other rows-->
|
||||
<xsl:for-each select="testsuites/testsuite/testcase">
|
||||
<tr>
|
||||
<td>
|
||||
<xsl:value-of select="@name"/>
|
||||
</td>
|
||||
<td>
|
||||
<xsl:value-of select="@RESULT"/>
|
||||
</td>
|
||||
<td>
|
||||
<xsl:value-of select="@time"/>
|
||||
</td>
|
||||
<td>
|
||||
<xsl:value-of select="@description"/>
|
||||
</td>
|
||||
</tr>
|
||||
</xsl:for-each>
|
||||
</table>
|
||||
</body>
|
||||
</html>
|
||||
</xsl:template>
|
||||
</xsl:stylesheet>
|
||||
@@ -1,205 +0,0 @@
|
||||
#!/bin/bash
|
||||
#/*
|
||||
# * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
|
||||
# * contributor license agreements. See the NOTICE file distributed with
|
||||
# * this work for additional information regarding copyright ownership.
|
||||
# * The OpenAirInterface Software Alliance licenses this file to You under
|
||||
# * the OAI Public License, Version 1.1 (the "License"); you may not use this file
|
||||
# * except in compliance with the License.
|
||||
# * You may obtain a copy of the License at
|
||||
# *
|
||||
# * http://www.openairinterface.org/?page_id=698
|
||||
# *
|
||||
# * Unless required by applicable law or agreed to in writing, software
|
||||
# * distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# * See the License for the specific language governing permissions and
|
||||
# * limitations under the License.
|
||||
# *-------------------------------------------------------------------------------
|
||||
# * For more information about the OpenAirInterface (OAI) Software Alliance:
|
||||
# * contact@openairinterface.org
|
||||
# */
|
||||
|
||||
function wait_usage {
|
||||
echo "OAI CI VM script"
|
||||
echo " Original Author: Raphael Defosseux"
|
||||
echo " Requirements:"
|
||||
echo " -- uvtool uvtool-libvirt apt-cacher"
|
||||
echo " -- $VM_OSREL image already synced"
|
||||
echo " Default:"
|
||||
echo " -- eNB with USRP"
|
||||
echo ""
|
||||
echo "Usage:"
|
||||
echo "------"
|
||||
echo " oai-ci-vm-tool wait [OPTIONS]"
|
||||
echo ""
|
||||
command_options_usage
|
||||
}
|
||||
|
||||
function wait_on_vm_build {
|
||||
echo "############################################################"
|
||||
echo "OAI CI VM script"
|
||||
echo "############################################################"
|
||||
|
||||
echo "VM_NAME = $VM_NAME"
|
||||
echo "VM_CMD_FILE = $VM_CMDS"
|
||||
echo "JENKINS_WKSP = $JENKINS_WKSP"
|
||||
echo "ARCHIVES_LOC = $ARCHIVES_LOC"
|
||||
echo "BUILD_OPTIONS = $BUILD_OPTIONS"
|
||||
|
||||
if [[ "$VM_NAME" == *"-enb-usrp"* ]] || [[ "$VM_NAME" == *"-cppcheck"* ]] || [[ "$VM_NAME" == *"-phy-sim"* ]] || [[ "$VM_NAME" == *"-basic-sim"* ]] || [[ "$VM_NAME" == *"-flexran-rtc"* ]] || [[ "$VM_NAME" == *"-rf-sim"* ]] || [[ "$VM_NAME" == *"-ethernet"* ]] || [[ "$VM_NAME" == *"rf5g-sim"* ]] || [[ "$VM_NAME" == *"gnb-usrp"* ]] || [[ "$VM_NAME" == *"nr-ue-usrp"* ]]
|
||||
then
|
||||
echo "This VM type is no longer supported in the pipeline framework"
|
||||
return
|
||||
fi
|
||||
|
||||
IS_VM_ALIVE=`uvt-kvm list | grep -c $VM_NAME`
|
||||
|
||||
if [ $IS_VM_ALIVE -eq 0 ]
|
||||
then
|
||||
echo "############################################################"
|
||||
echo "You should have created the VM before doing anything"
|
||||
echo "############################################################"
|
||||
STATUS=1
|
||||
return
|
||||
fi
|
||||
|
||||
echo "Waiting for VM to be started"
|
||||
uvt-kvm wait $VM_NAME --insecure
|
||||
|
||||
VM_IP_ADDR=`uvt-kvm ip $VM_NAME`
|
||||
echo "$VM_NAME has for IP addr = $VM_IP_ADDR"
|
||||
|
||||
echo "############################################################"
|
||||
echo "Waiting build process to end on VM ($VM_NAME)"
|
||||
echo "############################################################"
|
||||
# Since the last VM was cppcheck and is removed
|
||||
# we are going too fast in wait and the build_oai is not yet started
|
||||
sleep 120
|
||||
|
||||
if [[ "$VM_NAME" == *"-cppcheck"* ]]
|
||||
then
|
||||
echo "echo \"ps -aux | grep cppcheck \"" >> $VM_CMDS
|
||||
echo "while [ \$(ps -aux | grep --color=never cppcheck | grep -v grep | wc -l) -gt 0 ]; do sleep 3; done" >> $VM_CMDS
|
||||
else
|
||||
echo "echo \"ps -aux | grep build \"" >> $VM_CMDS
|
||||
echo "while [ \$(ps -aux | grep --color=never build_oai | grep -v grep | wc -l) -gt 0 ]; do sleep 3; done" >> $VM_CMDS
|
||||
fi
|
||||
echo "echo \"df -h\"" >> $VM_CMDS
|
||||
echo "df -h" >> $VM_CMDS
|
||||
|
||||
ssh -T -o StrictHostKeyChecking=no ubuntu@$VM_IP_ADDR < $VM_CMDS
|
||||
rm -f $VM_CMDS
|
||||
}
|
||||
|
||||
function check_on_vm_build {
|
||||
if [[ "$VM_NAME" == *"-enb-usrp"* ]] || [[ "$VM_NAME" == *"-cppcheck"* ]] || [[ "$VM_NAME" == *"-phy-sim"* ]] || [[ "$VM_NAME" == *"-basic-sim"* ]] || [[ "$VM_NAME" == *"-flexran-rtc"* ]] || [[ "$VM_NAME" == *"-rf-sim"* ]] || [[ "$VM_NAME" == *"-ethernet"* ]] || [[ "$VM_NAME" == *"rf5g-sim"* ]] || [[ "$VM_NAME" == *"gnb-usrp"* ]] || [[ "$VM_NAME" == *"nr-ue-usrp"* ]]
|
||||
then
|
||||
echo "This VM type is no longer supported in the pipeline framework"
|
||||
return
|
||||
fi
|
||||
|
||||
echo "############################################################"
|
||||
echo "Creating a tmp folder to store results and artifacts"
|
||||
echo "############################################################"
|
||||
if [ ! -d $JENKINS_WKSP/archives ]
|
||||
then
|
||||
mkdir $JENKINS_WKSP/archives
|
||||
fi
|
||||
|
||||
if [ ! -d $ARCHIVES_LOC ]
|
||||
then
|
||||
mkdir $ARCHIVES_LOC
|
||||
fi
|
||||
|
||||
scp -o StrictHostKeyChecking=no ubuntu@$VM_IP_ADDR:/home/ubuntu/tmp/cmake_targets/log/*.txt $ARCHIVES_LOC
|
||||
if [[ "$VM_NAME" == *"-cppcheck"* ]]
|
||||
then
|
||||
scp -o StrictHostKeyChecking=no ubuntu@$VM_IP_ADDR:/home/ubuntu/tmp/cmake_targets/log/*.xml $ARCHIVES_LOC
|
||||
fi
|
||||
|
||||
if [ $KEEP_VM_ALIVE -eq 0 ]
|
||||
then
|
||||
if [[ "$VM_NAME" == *"-enb-ethernet"* ]] || [[ "$VM_NAME" == *"-ue-ethernet"* ]]
|
||||
then
|
||||
echo "Hack to not destroy in current pipeline"
|
||||
else
|
||||
echo "############################################################"
|
||||
echo "Destroying VM"
|
||||
echo "############################################################"
|
||||
uvt-kvm destroy $VM_NAME
|
||||
ssh-keygen -R $VM_IP_ADDR
|
||||
fi
|
||||
fi
|
||||
rm -f $VM_CMDS
|
||||
|
||||
echo "############################################################"
|
||||
echo "Checking build status"
|
||||
echo "############################################################"
|
||||
|
||||
if [[ "$VM_NAME" == *"-cppcheck"* ]]
|
||||
then
|
||||
LOG_FILES=`ls $ARCHIVES_LOC/*.txt $ARCHIVES_LOC/*.xml`
|
||||
else
|
||||
LOG_FILES=`ls $ARCHIVES_LOC/*.txt`
|
||||
fi
|
||||
echo "LOG_FILES=$LOG_FILES"
|
||||
echo "expecting NB_PATTERN_FILES=$NB_PATTERN_FILES"
|
||||
STATUS=0
|
||||
NB_FOUND_FILES=0
|
||||
|
||||
for FULLFILE in $LOG_FILES
|
||||
do
|
||||
if [[ $FULLFILE == *"$LOG_PATTERN"* ]]
|
||||
then
|
||||
filename=$(basename -- "$FULLFILE")
|
||||
if [ "$LOG_PATTERN" == ".txt" ]
|
||||
then
|
||||
PASS_PATTERN=`echo $filename | sed -e "s#$LOG_PATTERN##"`
|
||||
fi
|
||||
if [ "$LOG_PATTERN" == "cppcheck.xml" ]
|
||||
then
|
||||
PASS_PATTERN="results version"
|
||||
LOCAL_STAT=`egrep -c "$PASS_PATTERN" $FULLFILE`
|
||||
else
|
||||
LOCAL_STAT=`egrep -c "Built target $PASS_PATTERN" $FULLFILE`
|
||||
fi
|
||||
if [ $LOCAL_STAT -eq 0 ]; then
|
||||
echo "WARNING: file $filename does not contain pass pattern"
|
||||
else
|
||||
NB_FOUND_FILES=$((NB_FOUND_FILES + 1))
|
||||
fi
|
||||
fi
|
||||
done
|
||||
|
||||
if [ $NB_PATTERN_FILES -ne $NB_FOUND_FILES ]
|
||||
then
|
||||
echo "Expecting $NB_PATTERN_FILES log files and found $NB_FOUND_FILES"
|
||||
STATUS=-1
|
||||
fi
|
||||
|
||||
# If we were building the FlexRan Controller, flag-touch for basic-simulator to continue
|
||||
#if [[ "$VM_NAME" == *"-flexran-rtc"* ]]
|
||||
#then
|
||||
# if [[ $STATUS -eq 0 ]]
|
||||
# then
|
||||
# touch $JENKINS_WKSP/flexran/flexran_build_complete.txt
|
||||
# fi
|
||||
#fi
|
||||
|
||||
if [[ "$VM_NAME" == *"-cppcheck"* ]]
|
||||
then
|
||||
echo "COMMAND: cppcheck $BUILD_OPTIONS . 2> cppcheck.xml" > $ARCHIVES_LOC/build_final_status.log
|
||||
elif [[ "$VM_NAME" == *"-flexran-rtc"* ]]
|
||||
then
|
||||
echo "COMMAND: $BUILD_OPTIONS" > $ARCHIVES_LOC/build_final_status.log
|
||||
else
|
||||
echo "COMMAND: build_oai -I $BUILD_OPTIONS" > $ARCHIVES_LOC/build_final_status.log
|
||||
fi
|
||||
if [[ $STATUS -eq 0 ]]
|
||||
then
|
||||
echo "BUILD_OK" >> $ARCHIVES_LOC/build_final_status.log
|
||||
else
|
||||
echo "BUILD_KO" >> $ARCHIVES_LOC/build_final_status.log
|
||||
fi
|
||||
}
|
||||
@@ -2,6 +2,7 @@
|
||||
- Build_Cluster_Image
|
||||
- Build_PhySim
|
||||
- Run_LDPCTest
|
||||
- Run_LDPCt1Test
|
||||
- Run_NRulsimTest
|
||||
- Build_eNB
|
||||
- WaitEndBuild_eNB
|
||||
@@ -19,7 +20,6 @@
|
||||
- CheckStatusUE
|
||||
- Ping
|
||||
- Iperf
|
||||
- Reboot_UE
|
||||
- Deploy_EPC
|
||||
- Undeploy_EPC
|
||||
- Initialize_HSS
|
||||
@@ -30,11 +30,6 @@
|
||||
- Terminate_SPGW
|
||||
- Initialize_5GCN
|
||||
- Terminate_5GCN
|
||||
- Initialize_CatM_module
|
||||
- Terminate_CatM_module
|
||||
- Attach_CatM_module
|
||||
- Detach_CatM_module
|
||||
- Ping_CatM_module
|
||||
- IdleSleep
|
||||
- Perform_X2_Handover
|
||||
- Build_Image
|
||||
@@ -51,3 +46,4 @@
|
||||
- Push_Local_Registry
|
||||
- Pull_Local_Registry
|
||||
- Clean_Test_Server_Images
|
||||
- Custom_Command
|
||||
|
||||
@@ -1,54 +0,0 @@
|
||||
<!--
|
||||
|
||||
Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
|
||||
contributor license agreements. See the NOTICE file distributed with
|
||||
this work for additional information regarding copyright ownership.
|
||||
The OpenAirInterface Software Alliance licenses this file to You under
|
||||
the OAI Public License, Version 1.1 (the "License"); you may not use this file
|
||||
except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.openairinterface.org/?page_id=698
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
|
||||
For more information about the OpenAirInterface (OAI) Software Alliance:
|
||||
contact@openairinterface.org
|
||||
|
||||
-->
|
||||
<testCaseList>
|
||||
<htmlTabRef>build-tab</htmlTabRef>
|
||||
<htmlTabName>Build</htmlTabName>
|
||||
<htmlTabIcon>wrench</htmlTabIcon>
|
||||
<TestCaseRequestedList>
|
||||
000001 000002
|
||||
</TestCaseRequestedList>
|
||||
<TestCaseExclusionList></TestCaseExclusionList>
|
||||
|
||||
<testCase id="000001">
|
||||
<class>Build_eNB</class>
|
||||
<desc>Build eNB</desc>
|
||||
<Build_eNB_args>--eNB -t benetel4g -w None</Build_eNB_args>
|
||||
<forced_workspace_cleanup>True</forced_workspace_cleanup>
|
||||
<eNB_instance>0</eNB_instance>
|
||||
<eNB_serverId>0</eNB_serverId>
|
||||
</testCase>
|
||||
|
||||
|
||||
<testCase id="000002">
|
||||
<class>Build_eNB</class>
|
||||
<desc>Build gNB</desc>
|
||||
<Build_eNB_args>--gNB -t benetel5g -w None</Build_eNB_args>
|
||||
<forced_workspace_cleanup>True</forced_workspace_cleanup>
|
||||
<eNB_instance>1</eNB_instance>
|
||||
<eNB_serverId>1</eNB_serverId>
|
||||
</testCase>
|
||||
|
||||
|
||||
|
||||
|
||||
</testCaseList>
|
||||
@@ -1,147 +0,0 @@
|
||||
<!--
|
||||
|
||||
Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
|
||||
contributor license agreements. See the NOTICE file distributed with
|
||||
this work for additional information regarding copyright ownership.
|
||||
The OpenAirInterface Software Alliance licenses this file to You under
|
||||
the OAI Public License, Version 1.1 (the "License"); you may not use this file
|
||||
except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.openairinterface.org/?page_id=698
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
|
||||
For more information about the OpenAirInterface (OAI) Software Alliance:
|
||||
contact@openairinterface.org
|
||||
|
||||
-->
|
||||
<testCaseList>
|
||||
<htmlTabRef>TEST-NSA-FR1-TM1</htmlTabRef>
|
||||
<htmlTabName>NSA Ping DL UL with QUECTEL</htmlTabName>
|
||||
<htmlTabIcon>tasks</htmlTabIcon>
|
||||
<repeatCount>1</repeatCount>
|
||||
<TestCaseRequestedList>
|
||||
030000
|
||||
040000
|
||||
000002
|
||||
010000
|
||||
050000
|
||||
050001
|
||||
000001
|
||||
070000
|
||||
000001
|
||||
070001
|
||||
000001
|
||||
010002
|
||||
000001
|
||||
080001
|
||||
080000
|
||||
</TestCaseRequestedList>
|
||||
<TestCaseExclusionList></TestCaseExclusionList>
|
||||
|
||||
<testCase id="010000">
|
||||
<class>Initialize_UE</class>
|
||||
<desc>Initialize Quectel</desc>
|
||||
<id>idefix</id>
|
||||
</testCase>
|
||||
|
||||
|
||||
<testCase id="010002">
|
||||
<class>Detach_UE</class>
|
||||
<desc>Detach UE</desc>
|
||||
<id>idefix</id>
|
||||
</testCase>
|
||||
|
||||
|
||||
<testCase id="030000">
|
||||
<class>Initialize_eNB</class>
|
||||
<desc>Initialize eNB</desc>
|
||||
<Initialize_eNB_args>-O ci-scripts/conf_files/benetel-4g.conf --log_config.global_log_options level,nocolor,time,line_num,function</Initialize_eNB_args>
|
||||
<eNB_instance>0</eNB_instance>
|
||||
<eNB_serverId>0</eNB_serverId>
|
||||
<air_interface>lte</air_interface>
|
||||
</testCase>
|
||||
|
||||
|
||||
<testCase id="040000">
|
||||
<class>Initialize_eNB</class>
|
||||
<desc>Initialize gNB</desc>
|
||||
<Initialize_eNB_args>-O ci-scripts/conf_files/benetel-5g.conf -q --log_config.global_log_options level,nocolor,time,line_num,function</Initialize_eNB_args>
|
||||
<eNB_instance>1</eNB_instance>
|
||||
<eNB_serverId>1</eNB_serverId>
|
||||
<air_interface>nr</air_interface>
|
||||
</testCase>
|
||||
|
||||
<testCase id="000001">
|
||||
<class>IdleSleep</class>
|
||||
<desc>Sleep</desc>
|
||||
<idle_sleep_time_in_sec>5</idle_sleep_time_in_sec>
|
||||
</testCase>
|
||||
|
||||
<testCase id="000002">
|
||||
<class>IdleSleep</class>
|
||||
<desc>Sleep</desc>
|
||||
<idle_sleep_time_in_sec>20</idle_sleep_time_in_sec>
|
||||
</testCase>
|
||||
|
||||
|
||||
<testCase id="050000">
|
||||
<class>Ping</class>
|
||||
<desc>Ping: 20pings in 20sec</desc>
|
||||
<id>idefix</id>
|
||||
<ping_args>-c 20</ping_args>
|
||||
<ping_packetloss_threshold>50</ping_packetloss_threshold>
|
||||
</testCase>
|
||||
|
||||
<testCase id="050001">
|
||||
<class>Ping</class>
|
||||
<desc>Ping: 100pings in 20sec</desc>
|
||||
<id>idefix</id>
|
||||
<ping_args>-c 100 -i 0.2</ping_args>
|
||||
<ping_packetloss_threshold>50</ping_packetloss_threshold>
|
||||
</testCase>
|
||||
|
||||
<testCase id="070000">
|
||||
<class>Iperf</class>
|
||||
<desc>iperf (DL/20Mbps/UDP)(60 sec)(single-ue profile)</desc>
|
||||
<iperf_args>-u -b 20M -t 60 -i 1</iperf_args>
|
||||
<direction>DL</direction>
|
||||
<id>idefix</id>
|
||||
<iperf_packetloss_threshold>50</iperf_packetloss_threshold>
|
||||
<iperf_profile>single-ue</iperf_profile>
|
||||
</testCase>
|
||||
|
||||
<testCase id="070001">
|
||||
<class>Iperf</class>
|
||||
<desc>iperf (UL/3Mbps/UDP)(60 sec)(single-ue profile)</desc>
|
||||
<iperf_args>-u -b 3M -t 60 -i 1</iperf_args>
|
||||
<direction>UL</direction>
|
||||
<id>idefix</id>
|
||||
<iperf_packetloss_threshold>50</iperf_packetloss_threshold>
|
||||
<iperf_profile>single-ue</iperf_profile>
|
||||
</testCase>
|
||||
|
||||
|
||||
<testCase id="080000">
|
||||
<class>Terminate_eNB</class>
|
||||
<desc>Terminate eNB</desc>
|
||||
<eNB_instance>0</eNB_instance>
|
||||
<eNB_serverId>0</eNB_serverId>
|
||||
<air_interface>lte</air_interface>
|
||||
</testCase>
|
||||
|
||||
<testCase id="080001">
|
||||
<class>Terminate_eNB</class>
|
||||
<desc>Terminate gNB</desc>
|
||||
<eNB_instance>1</eNB_instance>
|
||||
<eNB_serverId>1</eNB_serverId>
|
||||
<air_interface>nr</air_interface>
|
||||
</testCase>
|
||||
|
||||
</testCaseList>
|
||||
|
||||
@@ -1,149 +0,0 @@
|
||||
<!--
|
||||
|
||||
Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
|
||||
contributor license agreements. See the NOTICE file distributed with
|
||||
this work for additional information regarding copyright ownership.
|
||||
The OpenAirInterface Software Alliance licenses this file to You under
|
||||
the OAI Public License, Version 1.1 (the "License"); you may not use this file
|
||||
except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.openairinterface.org/?page_id=698
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
|
||||
For more information about the OpenAirInterface (OAI) Software Alliance:
|
||||
contact@openairinterface.org
|
||||
|
||||
-->
|
||||
<testCaseList>
|
||||
<htmlTabRef>TEST-NSA-FR1-TM1</htmlTabRef>
|
||||
<htmlTabName>NSA Ping DL UL with QUECTEL</htmlTabName>
|
||||
<htmlTabIcon>tasks</htmlTabIcon>
|
||||
<repeatCount>1</repeatCount>
|
||||
<TestCaseRequestedList>
|
||||
030000
|
||||
040000
|
||||
000002
|
||||
010000
|
||||
000001
|
||||
050000
|
||||
050001
|
||||
000001
|
||||
070000
|
||||
000001
|
||||
070001
|
||||
000001
|
||||
010002
|
||||
000001
|
||||
080001
|
||||
080000
|
||||
|
||||
</TestCaseRequestedList>
|
||||
<TestCaseExclusionList></TestCaseExclusionList>
|
||||
|
||||
<testCase id="010000">
|
||||
<class>Initialize_UE</class>
|
||||
<desc>Initialize Quectel</desc>
|
||||
<id>idefix</id>
|
||||
</testCase>
|
||||
|
||||
|
||||
<testCase id="010002">
|
||||
<class>Detach_UE</class>
|
||||
<desc>Detach UE</desc>
|
||||
<id>idefix</id>
|
||||
</testCase>
|
||||
|
||||
|
||||
<testCase id="030000">
|
||||
<class>Initialize_eNB</class>
|
||||
<desc>Initialize eNB</desc>
|
||||
<Initialize_eNB_args>-O ci-scripts/conf_files/benetel-4g.conf --log_config.global_log_options level,nocolor,time,line_num,function</Initialize_eNB_args>
|
||||
<eNB_instance>0</eNB_instance>
|
||||
<eNB_serverId>0</eNB_serverId>
|
||||
<air_interface>lte</air_interface>
|
||||
</testCase>
|
||||
|
||||
|
||||
<testCase id="040000">
|
||||
<class>Initialize_eNB</class>
|
||||
<desc>Initialize gNB</desc>
|
||||
<Initialize_eNB_args>-O ci-scripts/conf_files/benetel-5g.conf -q --log_config.global_log_options level,nocolor,time,line_num,function</Initialize_eNB_args>
|
||||
<eNB_instance>1</eNB_instance>
|
||||
<eNB_serverId>1</eNB_serverId>
|
||||
<air_interface>nr</air_interface>
|
||||
</testCase>
|
||||
|
||||
<testCase id="000001">
|
||||
<class>IdleSleep</class>
|
||||
<desc>Sleep</desc>
|
||||
<idle_sleep_time_in_sec>10</idle_sleep_time_in_sec>
|
||||
</testCase>
|
||||
|
||||
<testCase id="000002">
|
||||
<class>IdleSleep</class>
|
||||
<desc>Sleep</desc>
|
||||
<idle_sleep_time_in_sec>30</idle_sleep_time_in_sec>
|
||||
</testCase>
|
||||
|
||||
|
||||
<testCase id="050000">
|
||||
<class>Ping</class>
|
||||
<desc>Ping: 20pings in 20sec</desc>
|
||||
<id>idefix</id>
|
||||
<ping_args>-c 20</ping_args>
|
||||
<ping_packetloss_threshold>50</ping_packetloss_threshold>
|
||||
</testCase>
|
||||
|
||||
<testCase id="050001">
|
||||
<class>Ping</class>
|
||||
<desc>Ping: 100pings in 20sec</desc>
|
||||
<id>idefix</id>
|
||||
<ping_args>-c 100 -i 0.2</ping_args>
|
||||
<ping_packetloss_threshold>50</ping_packetloss_threshold>
|
||||
</testCase>
|
||||
|
||||
<testCase id="070000">
|
||||
<class>Iperf</class>
|
||||
<desc>iperf (DL/20Mbps/UDP)(20 min)(single-ue profile)</desc>
|
||||
<iperf_args>-u -b 20M -t 1200 -i 1</iperf_args>
|
||||
<direction>DL</direction>
|
||||
<id>idefix</id>
|
||||
<iperf_packetloss_threshold>50</iperf_packetloss_threshold>
|
||||
<iperf_profile>single-ue</iperf_profile>
|
||||
</testCase>
|
||||
|
||||
<testCase id="070001">
|
||||
<class>Iperf</class>
|
||||
<desc>iperf (UL/3Mbps/UDP)(20 min)(single-ue profile)</desc>
|
||||
<iperf_args>-u -b 2M -t 1200 -i 1</iperf_args>
|
||||
<direction>UL</direction>
|
||||
<id>idefix</id>
|
||||
<iperf_packetloss_threshold>50</iperf_packetloss_threshold>
|
||||
<iperf_profile>single-ue</iperf_profile>
|
||||
</testCase>
|
||||
|
||||
|
||||
<testCase id="080000">
|
||||
<class>Terminate_eNB</class>
|
||||
<desc>Terminate eNB</desc>
|
||||
<eNB_instance>0</eNB_instance>
|
||||
<eNB_serverId>0</eNB_serverId>
|
||||
<air_interface>lte</air_interface>
|
||||
</testCase>
|
||||
|
||||
<testCase id="080001">
|
||||
<class>Terminate_eNB</class>
|
||||
<desc>Terminate gNB</desc>
|
||||
<eNB_instance>1</eNB_instance>
|
||||
<eNB_serverId>1</eNB_serverId>
|
||||
<air_interface>nr</air_interface>
|
||||
</testCase>
|
||||
|
||||
</testCaseList>
|
||||
|
||||
@@ -36,7 +36,7 @@
|
||||
<eNB_instance>1</eNB_instance>
|
||||
<eNB_serverId>1</eNB_serverId>
|
||||
<forced_workspace_cleanup>True</forced_workspace_cleanup>
|
||||
<proxy_commit>a6169d8</proxy_commit>
|
||||
<proxy_commit>a2fa216</proxy_commit>
|
||||
</testCase>
|
||||
|
||||
</testCaseList>
|
||||
|
||||
131
ci-scripts/xml_files/container_5g_e1_rfsim.xml
Normal file
131
ci-scripts/xml_files/container_5g_e1_rfsim.xml
Normal file
@@ -0,0 +1,131 @@
|
||||
<!--
|
||||
|
||||
Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
|
||||
contributor license agreements. See the NOTICE file distributed with
|
||||
this work for additional information regarding copyright ownership.
|
||||
The OpenAirInterface Software Alliance licenses this file to You under
|
||||
the OAI Public License, Version 1.1 (the "License"); you may not use this file
|
||||
except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.openairinterface.org/?page_id=698
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
|
||||
For more information about the OpenAirInterface (OAI) Software Alliance:
|
||||
contact@openairinterface.org
|
||||
|
||||
-->
|
||||
<testCaseList>
|
||||
<htmlTabRef>rfsim-5gnr-e1</htmlTabRef>
|
||||
<htmlTabName>CUCP-CUUP-DU E1+F1 split</htmlTabName>
|
||||
<htmlTabIcon>wrench</htmlTabIcon>
|
||||
<TestCaseRequestedList>
|
||||
111111
|
||||
100021
|
||||
000020
|
||||
000021
|
||||
000022
|
||||
000023
|
||||
000024
|
||||
020021
|
||||
020022
|
||||
030021
|
||||
100021
|
||||
</TestCaseRequestedList>
|
||||
<TestCaseExclusionList></TestCaseExclusionList>
|
||||
|
||||
<testCase id="111111">
|
||||
<class>Pull_Local_Registry</class>
|
||||
<desc>Pull Images from Local Registry</desc>
|
||||
<test_svr_id>0</test_svr_id>
|
||||
<images_to_pull>oai-gnb oai-nr-cuup oai-nr-ue</images_to_pull>
|
||||
</testCase>
|
||||
|
||||
<testCase id="000020">
|
||||
<class>DeployGenObject</class>
|
||||
<desc>Deploy MySql Database</desc>
|
||||
<yaml_path>yaml_files/5g_rfsimulator_e1</yaml_path>
|
||||
<services>mysql</services>
|
||||
<nb_healthy>1</nb_healthy>
|
||||
</testCase>
|
||||
|
||||
<testCase id="000021">
|
||||
<class>DeployGenObject</class>
|
||||
<desc>Deploy OAI 5G CoreNetwork</desc>
|
||||
<yaml_path>yaml_files/5g_rfsimulator_e1</yaml_path>
|
||||
<services>oai-nrf oai-amf oai-smf oai-spgwu oai-ext-dn</services>
|
||||
<nb_healthy>6</nb_healthy>
|
||||
</testCase>
|
||||
|
||||
<testCase id="000022">
|
||||
<class>DeployGenObject</class>
|
||||
<desc>Deploy OAI 5G CU-CP RF sim SA</desc>
|
||||
<yaml_path>yaml_files/5g_rfsimulator_e1</yaml_path>
|
||||
<services>oai-cucp</services>
|
||||
<nb_healthy>7</nb_healthy>
|
||||
</testCase>
|
||||
|
||||
<testCase id="000023">
|
||||
<class>DeployGenObject</class>
|
||||
<desc>Deploy OAI 5G CU-UP and DU RF sim SA</desc>
|
||||
<yaml_path>yaml_files/5g_rfsimulator_e1</yaml_path>
|
||||
<services>oai-cuup oai-du</services>
|
||||
<nb_healthy>9</nb_healthy>
|
||||
</testCase>
|
||||
|
||||
<testCase id="000024">
|
||||
<class>DeployGenObject</class>
|
||||
<desc>Deploy OAI 5G NR-UE RF sim SA</desc>
|
||||
<yaml_path>yaml_files/5g_rfsimulator_e1</yaml_path>
|
||||
<services>oai-nr-ue</services>
|
||||
<nb_healthy>10</nb_healthy>
|
||||
</testCase>
|
||||
|
||||
<testCase id="020021">
|
||||
<class>PingFromContainer</class>
|
||||
<desc>Ping ext-dn from NR-UE</desc>
|
||||
<container_name>rfsim5g-oai-nr-ue</container_name>
|
||||
<options>-I oaitun_ue1 -c 20 192.168.73.135</options>
|
||||
<loss_threshold>5</loss_threshold>
|
||||
</testCase>
|
||||
|
||||
<testCase id="020022">
|
||||
<class>PingFromContainer</class>
|
||||
<desc>Ping NR-UE from ext-dn</desc>
|
||||
<container_name>rfsim5g-oai-ext-dn</container_name>
|
||||
<options>-c 20 12.1.1.2</options>
|
||||
<loss_threshold>5</loss_threshold>
|
||||
</testCase>
|
||||
|
||||
<testCase id="030021">
|
||||
<class>IperfFromContainer</class>
|
||||
<desc>Iperf UDP Downlink</desc>
|
||||
<server_container_name>rfsim5g-oai-nr-ue</server_container_name>
|
||||
<client_container_name>rfsim5g-oai-ext-dn</client_container_name>
|
||||
<server_options>-B 12.1.1.2 -u -i 1 -s</server_options>
|
||||
<client_options>-c 12.1.1.2 -u -i 1 -t 30 -b 3M</client_options>
|
||||
</testCase>
|
||||
|
||||
<testCase id="030022">
|
||||
<class>IperfFromContainer</class>
|
||||
<desc>Iperf UDP Uplink</desc>
|
||||
<server_container_name>rfsim5g-oai-ext-dn</server_container_name>
|
||||
<client_container_name>rfsim5g-oai-nr-ue</client_container_name>
|
||||
<server_options>-u -i 1 -s</server_options>
|
||||
<client_options>-B 12.1.1.2 -c 192.168.73.135 -u -i 1 -t 30 -b 1M</client_options>
|
||||
</testCase>
|
||||
|
||||
<testCase id="100021">
|
||||
<class>UndeployGenObject</class>
|
||||
<desc>Undeploy all OAI 5G stack</desc>
|
||||
<yaml_path>yaml_files/5g_rfsimulator_e1</yaml_path>
|
||||
<d_retx_th>1,0,0,0</d_retx_th>
|
||||
<u_retx_th>1,0,0,0</u_retx_th>
|
||||
</testCase>
|
||||
|
||||
</testCaseList>
|
||||
@@ -21,33 +21,25 @@
|
||||
|
||||
-->
|
||||
<testCaseList>
|
||||
<htmlTabRef>epc-closure</htmlTabRef>
|
||||
<htmlTabName>EPC-Closure</htmlTabName>
|
||||
<htmlTabIcon>log-out</htmlTabIcon>
|
||||
<TestCaseRequestedList>
|
||||
040202
|
||||
050201 060201 070201
|
||||
</TestCaseRequestedList>
|
||||
<TestCaseExclusionList></TestCaseExclusionList>
|
||||
<htmlTabRef>rfsim-5gnr-down-e1</htmlTabRef>
|
||||
<htmlTabName>CleanUp CUCP-CUUP-DU E1+F1 split</htmlTabName>
|
||||
<htmlTabIcon>trash</htmlTabIcon>
|
||||
<TestCaseRequestedList>
|
||||
100022
|
||||
222222
|
||||
</TestCaseRequestedList>
|
||||
<TestCaseExclusionList></TestCaseExclusionList>
|
||||
|
||||
<testCase id="040202">
|
||||
<class>Terminate_CatM_module</class>
|
||||
<desc>Terminate CAT-M Module</desc>
|
||||
</testCase>
|
||||
<testCase id="100022">
|
||||
<class>UndeployGenObject</class>
|
||||
<desc>Undeploy all OAI 5G stack</desc>
|
||||
<yaml_path>yaml_files/5g_rfsimulator_e1</yaml_path>
|
||||
</testCase>
|
||||
|
||||
<testCase id="050201">
|
||||
<class>Terminate_HSS</class>
|
||||
<desc>Terminate HSS</desc>
|
||||
</testCase>
|
||||
|
||||
<testCase id="060201">
|
||||
<class>Terminate_MME</class>
|
||||
<desc>Terminate MME</desc>
|
||||
</testCase>
|
||||
|
||||
<testCase id="070201">
|
||||
<class>Terminate_SPGW</class>
|
||||
<desc>Terminate SPGW</desc>
|
||||
</testCase>
|
||||
<testCase id="222222">
|
||||
<class>Clean_Test_Server_Images</class>
|
||||
<desc>Clean Test Images on Test Server</desc>
|
||||
<test_svr_id>0</test_svr_id>
|
||||
</testCase>
|
||||
|
||||
</testCaseList>
|
||||
124
ci-scripts/xml_files/container_5g_rfsim_2x2.xml
Normal file
124
ci-scripts/xml_files/container_5g_rfsim_2x2.xml
Normal file
@@ -0,0 +1,124 @@
|
||||
<!--
|
||||
|
||||
Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
|
||||
contributor license agreements. See the NOTICE file distributed with
|
||||
this work for additional information regarding copyright ownership.
|
||||
The OpenAirInterface Software Alliance licenses this file to You under
|
||||
the OAI Public License, Version 1.1 (the "License"); you may not use this file
|
||||
except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.openairinterface.org/?page_id=698
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
|
||||
For more information about the OpenAirInterface (OAI) Software Alliance:
|
||||
contact@openairinterface.org
|
||||
|
||||
-->
|
||||
<testCaseList>
|
||||
<htmlTabRef>rfsim-5gnr-tdd-2x2</htmlTabRef>
|
||||
<htmlTabName>Monolithic SA TDD 2x2 gNB</htmlTabName>
|
||||
<htmlTabIcon>wrench</htmlTabIcon>
|
||||
<repeatCount>1</repeatCount>
|
||||
<TestCaseRequestedList>
|
||||
111111
|
||||
100001
|
||||
000000
|
||||
000001
|
||||
000002
|
||||
000003
|
||||
020001
|
||||
020002
|
||||
030001
|
||||
030002
|
||||
100001
|
||||
</TestCaseRequestedList>
|
||||
<TestCaseExclusionList></TestCaseExclusionList>
|
||||
|
||||
<testCase id="111111">
|
||||
<class>Pull_Local_Registry</class>
|
||||
<desc>Pull Images from Local Registry</desc>
|
||||
<test_svr_id>0</test_svr_id>
|
||||
<images_to_pull>oai-gnb oai-nr-ue</images_to_pull>
|
||||
</testCase>
|
||||
|
||||
<testCase id="000000">
|
||||
<class>DeployGenObject</class>
|
||||
<desc>Deploy MySql Database</desc>
|
||||
<yaml_path>yaml_files/5g_rfsimulator_2x2</yaml_path>
|
||||
<services>mysql</services>
|
||||
<nb_healthy>1</nb_healthy>
|
||||
</testCase>
|
||||
|
||||
<testCase id="000001">
|
||||
<class>DeployGenObject</class>
|
||||
<desc>Deploy OAI 5G CoreNetwork</desc>
|
||||
<yaml_path>yaml_files/5g_rfsimulator_2x2</yaml_path>
|
||||
<services>oai-nrf oai-amf oai-smf oai-spgwu oai-ext-dn</services>
|
||||
<nb_healthy>6</nb_healthy>
|
||||
</testCase>
|
||||
|
||||
<testCase id="000002">
|
||||
<class>DeployGenObject</class>
|
||||
<desc>Deploy OAI 5G gNB RF sim SA</desc>
|
||||
<yaml_path>yaml_files/5g_rfsimulator_2x2</yaml_path>
|
||||
<services>oai-gnb</services>
|
||||
<nb_healthy>7</nb_healthy>
|
||||
</testCase>
|
||||
|
||||
<testCase id="000003">
|
||||
<class>DeployGenObject</class>
|
||||
<desc>Deploy OAI 5G NR-UE RF sim SA</desc>
|
||||
<yaml_path>yaml_files/5g_rfsimulator_2x2</yaml_path>
|
||||
<services>oai-nr-ue</services>
|
||||
<nb_healthy>8</nb_healthy>
|
||||
</testCase>
|
||||
|
||||
<testCase id="020001">
|
||||
<class>PingFromContainer</class>
|
||||
<desc>Ping ext-dn from NR-UE</desc>
|
||||
<container_name>rfsim5g-oai-nr-ue</container_name>
|
||||
<options>-I oaitun_ue1 -c 20 192.168.72.135</options>
|
||||
<loss_threshold>5</loss_threshold>
|
||||
</testCase>
|
||||
|
||||
<testCase id="020002">
|
||||
<class>PingFromContainer</class>
|
||||
<desc>Ping NR-UE from ext-dn</desc>
|
||||
<container_name>rfsim5g-oai-ext-dn</container_name>
|
||||
<options>-c 20 12.1.1.2</options>
|
||||
<loss_threshold>5</loss_threshold>
|
||||
</testCase>
|
||||
|
||||
<testCase id="030001">
|
||||
<class>IperfFromContainer</class>
|
||||
<desc>Iperf UDP Downlink</desc>
|
||||
<server_container_name>rfsim5g-oai-nr-ue</server_container_name>
|
||||
<client_container_name>rfsim5g-oai-ext-dn</client_container_name>
|
||||
<server_options>-B 12.1.1.2 -u -i 1 -s</server_options>
|
||||
<client_options>-c 12.1.1.2 -u -i 1 -t 10 -b 3M</client_options>
|
||||
</testCase>
|
||||
|
||||
<testCase id="030002">
|
||||
<class>IperfFromContainer</class>
|
||||
<desc>Iperf UDP Uplink</desc>
|
||||
<server_container_name>rfsim5g-oai-ext-dn</server_container_name>
|
||||
<client_container_name>rfsim5g-oai-nr-ue</client_container_name>
|
||||
<server_options>-u -i 1 -s</server_options>
|
||||
<client_options>-B 12.1.1.2 -c 192.168.72.135 -u -i 1 -t 10 -b 1M</client_options>
|
||||
</testCase>
|
||||
|
||||
<testCase id="100001">
|
||||
<class>UndeployGenObject</class>
|
||||
<desc>Undeploy all OAI 5G stack</desc>
|
||||
<yaml_path>yaml_files/5g_rfsimulator_2x2</yaml_path>
|
||||
<d_retx_th>1,0,0,0</d_retx_th>
|
||||
<u_retx_th>1,0,0,0</u_retx_th>
|
||||
</testCase>
|
||||
|
||||
</testCaseList>
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user