Skip to content

Commit d079678

Browse files
committed
add bin/create_brancher and bin/destroy_brancher
1 parent 67873e6 commit d079678

6 files changed

Lines changed: 155 additions & 2 deletions

File tree

bin/create_brancher

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
command

bin/destroy_brancher

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
command

hypernode_api_python/client.py

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -840,7 +840,6 @@ def get_active_branchers(self, app_name):
840840
"GET", HYPERNODE_API_BRANCHER_APP_ENDPOINT.format(app_name)
841841
)
842842

843-
# TODO: add entrypoint for this method in bin/ and commands.py
844843
def create_brancher(self, app_name, data):
845844
"""
846845
Create a new branch (server replica) of your Hypernode.
@@ -854,7 +853,6 @@ def create_brancher(self, app_name, data):
854853
"POST", HYPERNODE_API_BRANCHER_APP_ENDPOINT.format(app_name), data=data
855854
)
856855

857-
# TODO: add entrypoint for this method in bin/ and commands.py
858856
def destroy_brancher(self, brancher_name):
859857
"""
860858
Destroy an existing brancher node of your Hypernode.

hypernode_api_python/commands.py

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -641,3 +641,63 @@ def get_active_branchers(args=None):
641641
client = get_client()
642642
app_name = get_app_name()
643643
print_response(client.get_active_branchers(app_name))
644+
645+
646+
def create_brancher(args=None):
647+
parser = ArgumentParser(
648+
description="""
649+
Create a Brancher Hypernode from the specified app.
650+
Outputs the app_info of the brancher to be created..
651+
652+
Example:
653+
$ ./bin/create_brancher
654+
{
655+
"name": "yourappname-ephoj82yb",
656+
"parent": "yourappname",
657+
"type": "brancher",
658+
"product": "FALCON_M_202203",
659+
"domainname": "yourappname-ephoj82yb.hypernode.io",
660+
...
661+
}
662+
""",
663+
formatter_class=RawTextHelpFormatter,
664+
)
665+
parser.parse_args(args=args)
666+
client = get_client()
667+
app_name = get_app_name()
668+
data = {}
669+
print_response(client.create_brancher(app_name, data=data))
670+
671+
672+
def destroy_brancher(args=None):
673+
parser = ArgumentParser(
674+
description="""
675+
Destroy a Brancher Hypernode.
676+
677+
Examples:
678+
$ ./bin/destroy_brancher yourbrancherappname-eph12345
679+
A job has been posted to cancel the 'yourbrancherappname-eph12345' brancher app.
680+
""",
681+
formatter_class=RawTextHelpFormatter,
682+
)
683+
parser.add_argument(
684+
"brancher_app_name",
685+
help="The name of the brancher to destroy. See ./bin/get_active_branchers",
686+
)
687+
args = parser.parse_args(args=args)
688+
client = get_client()
689+
try:
690+
client.destroy_brancher(args.brancher_app_name)
691+
print(
692+
"A job has been posted to cancel the '{}' brancher app.".format(
693+
args.brancher_app_name
694+
)
695+
)
696+
exit(EX_OK)
697+
except Exception as e:
698+
print(
699+
"Brancher app '{}' failed to be cancelled: {}".format(
700+
args.brancher_app_name, e
701+
)
702+
)
703+
exit(EX_UNAVAILABLE)
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
from hypernode_api_python.commands import create_brancher
2+
from tests.testcase import TestCase
3+
4+
5+
class TestCreateBrancher(TestCase):
6+
def setUp(self):
7+
self.print_response = self.set_up_patch(
8+
"hypernode_api_python.commands.print_response"
9+
)
10+
self.get_client = self.set_up_patch("hypernode_api_python.commands.get_client")
11+
self.client = self.get_client.return_value
12+
self.get_app_name = self.set_up_patch(
13+
"hypernode_api_python.commands.get_app_name"
14+
)
15+
self.get_app_name.return_value = "myappname"
16+
17+
def test_create_brancher_gets_client(self):
18+
create_brancher([])
19+
20+
self.get_client.assert_called_once_with()
21+
22+
def test_create_brancher_gets_app_name(self):
23+
create_brancher([])
24+
25+
self.get_app_name.assert_called_once_with()
26+
27+
def test_create_brancher_creates_brancher(self):
28+
create_brancher([])
29+
30+
expected_data = {}
31+
self.client.create_brancher.assert_called_once_with(
32+
"myappname", data=expected_data
33+
)
34+
35+
def test_create_brancher_prints_response(self):
36+
create_brancher([])
37+
38+
self.print_response.assert_called_once_with(
39+
self.client.create_brancher.return_value
40+
)
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
from os import EX_UNAVAILABLE, EX_OK
2+
3+
from hypernode_api_python.commands import destroy_brancher
4+
from tests.testcase import TestCase
5+
6+
7+
class TestDestroyBrancher(TestCase):
8+
def setUp(self):
9+
self.exit = self.set_up_patch("hypernode_api_python.commands.exit")
10+
self.print = self.set_up_patch("hypernode_api_python.commands.print")
11+
self.print_response = self.set_up_patch(
12+
"hypernode_api_python.commands.print_response"
13+
)
14+
self.get_client = self.set_up_patch("hypernode_api_python.commands.get_client")
15+
self.client = self.get_client.return_value
16+
17+
def test_destroy_brancher_gets_client(self):
18+
destroy_brancher(["myappname-eph1234"])
19+
20+
self.get_client.assert_called_once_with()
21+
22+
def test_destroy_brancher_destroys_brancher(self):
23+
destroy_brancher(["myappname-eph1234"])
24+
25+
self.client.destroy_brancher.assert_called_once_with("myappname-eph1234")
26+
27+
def test_destroy_brancher_prints_app_name_is_valid(self):
28+
destroy_brancher(["myappname-eph1234"])
29+
30+
self.print.assert_called_once_with(
31+
"A job has been posted to cancel the 'myappname-eph1234' brancher app."
32+
)
33+
34+
def test_destroy_brancher_prints_app_name_is_invalid(self):
35+
self.client.destroy_brancher.side_effect = MemoryError("Killed")
36+
37+
destroy_brancher(["myappname-eph1234"])
38+
39+
self.print.assert_called_once_with(
40+
"Brancher app 'myappname-eph1234' failed to be cancelled: Killed"
41+
)
42+
43+
def test_destroy_brancher_exits_zero_when_cancel_job_posted(self):
44+
destroy_brancher(["myappname-eph1234"])
45+
46+
self.exit.assert_called_once_with(EX_OK)
47+
48+
def test_destroy_brancher_exits_nonzero_when_unexpected_exception_occurs(self):
49+
self.client.destroy_brancher.side_effect = RuntimeError
50+
51+
destroy_brancher(["myappname-eph1234"])
52+
53+
self.exit.assert_called_once_with(EX_UNAVAILABLE)

0 commit comments

Comments
 (0)