def test_delete(self):
     rh = MockRequestHandler(responses=[templates.Delete.response()])
     with BambooHome().config(aid=1234).temp() as home:
         agent = make_bamboo_agent(home=home, request_handler=rh)
         agent.delete()
     self.assert_requests(rh.requests, templates.Delete.request(agent_id=1234))
     self.assertTrue(agent.state["deleted"])
class TestNewAgentRegistration(BambooAgentIntegrationTest):
    Uuid = "00000000-1111-2222-3333-444444444444"
    Home = BambooHome().temp_uuid(Uuid)
    ExpectChange = True
    ExpectedRequests = [
        templates.Pending.request(),
        templates.Authentication.request(uuid=Uuid),
        templates.Agents.request(),
    ]
    Responses = [
        templates.Pending.response(uuid=Uuid),
        templates.Authentication.response().action(lambda: BambooHome().config(
            aid=1234).create(TestNewAgentRegistration.Home.path)),
        templates.Agents.response([dict(id=1234, enabled=True)]),
    ]
    ExpectedResult = dict(id=1234, enabled=True, authenticated=True)
class TestAssignments(BambooAgentIntegrationTest):
    Arguments = dict(assignments=[
        dict(type="plan", key="PL"),
        dict(type="project", key="PR")
    ])
    Home = BambooHome().config(aid=1234)
    ExpectChange = True
    ExpectedRequests = [
        templates.Pending.request(),
        templates.Agents.request(),
        templates.SearchAssignment.request(etype="PLAN"),
        templates.SearchAssignment.request(etype="PROJECT"),
        templates.Assignments.request(agent_id=1234),
        templates.AddAssignment.request(agent_id=1234, etype="PROJECT", eid=1),
        templates.RemoveAssignment.request(agent_id=1234,
                                           etype="PROJECT",
                                           eid=2),
    ]
    Responses = [
        ActionResponse([]),
        templates.Agents.response([dict(id=1234)]),
        templates.SearchAssignment.response([dict(key="PL", id=0)]),
        templates.SearchAssignment.response([dict(key="PR", id=1)]),
        templates.Assignments.response([
            dict(executableType="PROJECT", executableId=2),
            dict(executableType="PLAN", executableId=0),
        ]),
        templates.AddAssignment.response(),
        templates.RemoveAssignment.response(),
    ]
    ExpectedResult = dict(assignments={"0": "PLAN", "1": "PROJECT"})
 def test_name(self):
     rh = MockRequestHandler(
         responses=[templates.Agents.response([dict(id=1234, name="agent-name")])]
     )
     with BambooHome().config(aid=1234).temp() as home:
         agent = make_bamboo_agent(home=home, request_handler=rh)
         self.assertEqual(agent.name(), "agent-name")
     self.assert_requests(rh.requests, templates.Agents.request())
 def test_enable(self):
     rh = MockRequestHandler(responses=[templates.Enable.response()])
     with BambooHome().config(aid=1234).temp() as home:
         agent = make_bamboo_agent(home=home, request_handler=rh)
         agent.state.set("info", dict(enabled=False))
         agent.enable()
     self.assert_requests(rh.requests, templates.Enable.request(agent_id=1234))
     self.assertTrue(agent.state["info"]["enabled"])
 def test_authenticate(self):
     rh = MockRequestHandler(responses=[templates.Authentication.response()])
     with BambooHome().temp_uuid(uuid="0000").temp() as home:
         agent = make_bamboo_agent(home=home, request_handler=rh)
         agent.state.set("authenticated", False)
         agent.authenticate()
     self.assert_requests(rh.requests, templates.Authentication.request(uuid="0000"))
     self.assertTrue(agent.state["authenticated"])
 def test_set_name(self):
     rh = MockRequestHandler(responses=[templates.SetName.response()])
     with BambooHome().config(aid=1234).temp() as home:
         agent = make_bamboo_agent(home=home, request_handler=rh)
         agent.set_name("new-name")
     self.assert_requests(
         rh.requests, templates.SetName.request(agent_id=1234, name="new-name")
     )
     self.assertEqual(agent.state["info"]["name"], "new-name")
 def test_busy(self):
     with BambooHome().config(aid=1234).temp() as home:
         agent = make_bamboo_agent(
             home=home,
             request_handler=MockRequestHandler(
                 responses=[templates.Agents.response([dict(id=1234, busy=True)])]
             ),
         )
         self.assertTrue(agent.busy())
 def test_not_available(self):
     with BambooHome().config(aid=1234).temp() as home:
         agent = make_bamboo_agent(
             home=home,
             request_handler=MockRequestHandler(
                 responses=[templates.Agents.response(list())]
             ),
         )
         self.assertFalse(agent.available())
 def test_not_authenticated_pending(self):
     with BambooHome().temp_uuid(uuid="0000").temp() as home:
         agent = make_bamboo_agent(
             home=home,
             request_handler=MockRequestHandler(
                 responses=[Response([dict(uuid="0000")])]
             ),
         )
         self.assertFalse(agent.authenticated())
 def test_add_assignment(self):
     rh = MockRequestHandler(responses=[templates.AddAssignment.response()])
     with BambooHome().config(aid=1234).temp() as home:
         agent = make_bamboo_agent(home=home, request_handler=rh)
         agent.add_assignment(etype="PROJECT", eid=2)
     self.assert_requests(
         rh.requests,
         templates.AddAssignment.request(agent_id=1234, eid=2, etype="PROJECT"),
     )
     self.assertEqual(agent.state["assignments"], {2: "PROJECT"})
 def test_authenticated(self):
     with BambooHome().config(uuid="0000", aid=1234).temp() as home:
         agent = make_bamboo_agent(
             home=home,
             request_handler=MockRequestHandler(
                 responses=[Response([]), templates.Agents.response([dict(id=1234)])]
             ),
         )
         self.assertTrue(agent.authenticated())
         self.assertTrue(agent.state["authenticated"])
 def test_info(self):
     with BambooHome().config(aid=1234).temp() as home:
         agent = make_bamboo_agent(
             home=home,
             request_handler=MockRequestHandler(
                 responses=[templates.Agents.response([dict(id=1234, key="value")])]
             ),
         )
         self.assertEqual(agent.info(), dict(id=1234, key="value"))
         self.assertEqual(agent.state["info"], dict(id=1234, key="value"))
class TestNewAgentWithCheckMode(BambooAgentIntegrationTest):
    Uuid = "00000000-1111-2222-3333-444444444444"
    Home = BambooHome().temp_uuid(Uuid)
    CheckMode = True
    ExpectChange = True
    ExpectedRequests = [
        templates.Pending.request(),
    ]
    Responses = [
        templates.Pending.response(uuid=Uuid),
    ]
    ExpectedResult = dict(authenticated=True)
 def test_info_caching(self):
     request_handler = MockRequestHandler(
         responses=[
             templates.Agents.response(
                 [dict(id=1234, enabled=True, name="agent-name")]
             )
         ]
     )
     with BambooHome().config(aid=1234).temp() as home:
         agent = make_bamboo_agent(home=home, request_handler=request_handler,)
         agent.info()
         agent.info()
     self.assert_requests(request_handler.requests, templates.Agents.request())
 def test_assignments(self):
     rh = MockRequestHandler(
         responses=[
             templates.Assignments.response(
                 [dict(executableType="PROJECT", executableId=123456)]
             )
         ]
     )
     with BambooHome().config(aid=1234).temp() as home:
         agent = make_bamboo_agent(home=home, request_handler=rh)
         self.assertEqual(agent.assignments(), {123456: "PROJECT"})
         self.assertEqual(agent.state["assignments"], {123456: "PROJECT"})
     self.assert_requests(rh.requests, templates.Assignments.request(agent_id=1234))
class TestAgentDelete(BambooAgentIntegrationTest):
    Arguments = dict(deleted=True)
    Home = BambooHome().config(aid=1234)
    ExpectChange = True
    ExpectedRequests = [
        templates.Pending.request(),
        templates.Agents.request(),
        templates.Delete.request(agent_id=1234),
    ]
    Responses = [
        ActionResponse([]),
        templates.Agents.response([dict(id=1234, enabled=True)]),
        templates.Delete.response(),
    ]
    ExpectedResult = dict(id=1234, deleted=True)
class TestSetAgentName(BambooAgentIntegrationTest):
    Arguments = dict(name="new-name")
    Home = BambooHome().config(aid=1234)
    ExpectChange = True
    ExpectedRequests = [
        templates.Pending.request(),
        templates.Agents.request(),
        templates.SetName.request(agent_id=1234, name="new-name"),
    ]
    Responses = [
        ActionResponse([]),
        templates.Agents.response([dict(id=1234, name="old-name")]),
        templates.SetName.response(),
    ]
    ExpectedResult = dict(id=1234, name="new-name")
class TestBlockWhileBusy(BambooAgentIntegrationTest):
    Home = BambooHome().config(aid=1234)
    Arguments = dict(block_while_busy=True,
                     timings=dict(interval_busy_polling=0))
    ExpectChange = True
    ExpectedRequests = [
        templates.Pending.request(),
        templates.Agents.request(),
        templates.Agents.request(),
    ]
    Responses = [
        ActionResponse([]),
        templates.Agents.response([dict(id=1234, busy=True)]),
        templates.Agents.response([dict(id=1234, busy=False)]),
    ]
    ExpectedResult = dict(id=1234, busy=False)
class TestDiff(BambooAgentIntegrationTest):
    Home = BambooHome().config(aid=1234)
    ExpectedRequests = [
        templates.Pending.request(),
        templates.Agents.request(),
    ]
    Responses = [
        ActionResponse([]),
        templates.Agents.response([
            dict(id=1234,
                 name="agent-name",
                 enabled=True,
                 busy=False,
                 active=True)
        ]),
    ]
    ExpectedResult = dict(diff=dict(
        before=textwrap.dedent("""
                {
                    "assignments": {},
                    "authenticated": true,
                    "deleted": false,
                    "info": {
                        "active": true,
                        "busy": false,
                        "enabled": true,
                        "id": 1234,
                        "name": "agent-name"
                    }
                }
                """).strip(),
        after=textwrap.dedent("""
                {
                    "assignments": {},
                    "authenticated": true,
                    "deleted": false,
                    "info": {
                        "active": true,
                        "busy": false,
                        "enabled": true,
                        "id": 1234,
                        "name": "agent-name"
                    }
                }
                """).strip(),
    ))
class TestReturnValues(BambooAgentIntegrationTest):
    Home = BambooHome().config(aid=1234)
    ExpectedRequests = [
        templates.Pending.request(),
        templates.Agents.request(),
    ]
    Responses = [
        ActionResponse([]),
        templates.Agents.response([
            dict(id=1234,
                 name="agent-name",
                 enabled=True,
                 busy=False,
                 active=True)
        ]),
    ]
    ExpectedResult = dict(id=1234,
                          name="agent-name",
                          enabled=True,
                          busy=False,
                          active=True)
class TestUnchanged(BambooAgentIntegrationTest):
    Arguments = dict(enabled=True,
                     name="agent-name",
                     assignments=[dict(type="plan", key="PL")])
    Home = BambooHome().config(aid=1234)
    ExpectChange = False
    ExpectedRequests = [
        templates.Pending.request(),
        templates.Agents.request(),
        templates.SearchAssignment.request(etype="PLAN"),
        templates.Assignments.request(agent_id=1234),
    ]
    Responses = [
        ActionResponse([]),
        templates.Agents.response(
            [dict(id=1234, enabled=True, name="agent-name")]),
        templates.SearchAssignment.response([dict(key="PL", id=1)]),
        templates.Assignments.response(
            [dict(executableType="PLAN", executableId=1)]),
    ]
    ExpectedResult = dict(id=1234, name="agent-name", enabled=True)
class BambooAgentIntegrationTest(RequestTestCase):
    Home = BambooHome()
    Arguments = dict(credentials=dict(user="", password=""))
    Responses: List[Response] = list()
    ExpectedRequests: List[Request] = list()
    ExpectedResult = dict()
    ExpectChange = False
    ExpectFailure = False
    CheckMode = False

    _HttpServer = HttpServerMock()

    def __init_subclass__(cls, **kwargs):
        super().__init_subclass__(**kwargs)
        setattr(cls, f"test_{cls.__name__}", cls._test)

    def _test(self):
        result, requests = self._execute_module_in_process()
        del result["invocation"]

        self.assert_requests(requests, *self.ExpectedRequests)
        if self.ExpectFailure:
            self.assertTrue(result["failed"])
        else:
            self.assertEqual(result.pop("changed"), self.ExpectChange)
        for key, expected in self.ExpectedResult.items():
            self.assertEqual(result[key], expected, key)

    def _execute_module_in_process(self):
        with TemporaryDirectory() as tempdir:
            self._HttpServer.reset(self.Responses)
            arguments_file_path = Path(tempdir, "arguments.json")
            with open(arguments_file_path, mode="w+") as arguments_file:
                arguments = {
                    **BambooAgentIntegrationTest.Arguments,
                    **self.Arguments,
                }
                arguments.setdefault("timings",
                                     {}).setdefault("http_timeout", 1)
                json.dump(
                    dict(ANSIBLE_MODULE_ARGS=dict(
                        host=self._HttpServer.url,
                        home=str(self.Home.create(tempdir)),
                        _ansible_check_mode=self.CheckMode,
                        **arguments,
                    ), ),
                    arguments_file,
                )

            process = subprocess.run(
                [
                    sys.executable,
                    "plugins/modules/configuration.py",
                    str(arguments_file_path),
                ],
                stdout=subprocess.PIPE,
                stderr=subprocess.PIPE,
            )

        if process.returncode and not self.ExpectFailure:
            error_msg = "\n".join([
                f"RETURN_CODE: {process.returncode}",
                "STDOUT:",
                textwrap.indent(process.stdout.decode("utf-8"), prefix="  "),
                "STDERR:",
                textwrap.indent(process.stderr.decode("utf-8"), prefix="  "),
            ])
            raise RuntimeError(error_msg)
        return json.loads(process.stdout), self._HttpServer.requests
 def test_id_config(self):
     with BambooHome().config(uuid="0000", aid=1234).temp() as home:
         agent = make_bamboo_agent(home=home)
         self.assertEqual(agent.id(), 1234)
class TestHttpTimeout(BambooAgentIntegrationTest):
    Uuid = "00000000-1111-2222-3333-444444444444"
    Arguments = dict(timings=dict(http_timeout=0))
    Home = BambooHome().temp_uuid(Uuid)
    ExpectFailure = True
class TestErrorHandling(BambooAgentIntegrationTest):
    Uuid = "00000000-1111-2222-3333-444444444444"
    Home = BambooHome().temp_uuid(Uuid)
    ExpectFailure = True
    ExpectedRequests = [templates.Pending.request()]
    Responses = [ActionResponse(status_code=400)]
 def test_authenticated_no_uuid(self):
     with BambooHome().temp() as home:
         agent = make_bamboo_agent(home=home,)
         self.assertFalse(agent.authenticated())
 def test_available_no_id(self):
     with BambooHome().temp() as home:
         agent = make_bamboo_agent(home=home)
         self.assertFalse(agent.available())
 def test_authenticate_no_uuid(self):
     with BambooHome().temp() as home:
         agent = make_bamboo_agent(home=home)
         self.assertRaises(MissingUuid, agent.authenticate)
 def test_set_name_with_redirect(self):
     rh = MockRequestHandler(responses=[templates.SetName.response(status_code=302)])
     with BambooHome().config(aid=1234).temp() as home:
         agent = make_bamboo_agent(home=home, request_handler=rh)
         agent.set_name("name")