[Notes] [Git][BuildGrid/buildgrid][finn/bot-refactor] New unittests to reflect bot refactor



Title: GitLab

finnball pushed to branch finn/bot-refactor at BuildGrid / buildgrid

Commits:

2 changed files:

Changes:

  • tests/integration/bot_session.py
    1
    +# Copyright (C) 2018 Bloomberg LP
    
    2
    +#
    
    3
    +# Licensed under the Apache License, Version 2.0 (the "License");
    
    4
    +# you may not use this file except in compliance with the License.
    
    5
    +# You may obtain a copy of the License at
    
    6
    +#
    
    7
    +#  <http://www.apache.org/licenses/LICENSE-2.0>
    
    8
    +#
    
    9
    +# Unless required by applicable law or agreed to in writing, software
    
    10
    +# distributed under the License is distributed on an "AS IS" BASIS,
    
    11
    +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    
    12
    +# See the License for the specific language governing permissions and
    
    13
    +# limitations under the License.
    
    14
    +
    
    15
    +import grpc
    
    16
    +import pytest
    
    17
    +import uuid
    
    18
    +
    
    19
    +from unittest import mock
    
    20
    +
    
    21
    +from buildgrid.bot import bot_session, bot_interface
    
    22
    +
    
    23
    +@pytest.mark.parametrize("docker_value", ["True", "False"])
    
    24
    +@pytest.mark.parametrize("os_value", ["nexus7", "nexus8"])
    
    25
    +def test_create_device(docker_value, os_value):
    
    26
    +    properties = {'docker' : docker_value, 'os' : os_value}
    
    27
    +    device = bot_session.Device(properties)
    
    28
    +
    
    29
    +    assert uuid.UUID(device.name, version=4)
    
    30
    +    assert properties == device.properties
    
    31
    +
    
    32
    +def test_create_device_key_fail():
    
    33
    +    properties = {'voight' : 'kampff'}
    
    34
    +
    
    35
    +    with pytest.raises(KeyError):
    
    36
    +        device = bot_session.Device(properties)
    
    37
    +
    
    38
    +def test_create_device_value_fail():
    
    39
    +    properties = {'docker' :  True}
    
    40
    +
    
    41
    +    with pytest.raises(ValueError):
    
    42
    +        device = bot_session.Device(properties)
    
    43
    +
    
    44
    +def test_create_worker():
    
    45
    +    properties = {'pool' : 'swim'}
    
    46
    +    configs = {'DockerImage' : 'Windows'}
    
    47
    +    worker = bot_session.Worker(properties, configs)
    
    48
    +
    
    49
    +    assert properties == worker.properties
    
    50
    +    assert configs == worker.configs
    
    51
    +
    
    52
    +    device = bot_session.Device()
    
    53
    +    worker.add_device(device)
    
    54
    +
    
    55
    +    assert worker._devices[0] == device
    
    56
    +
    
    57
    +def test_create_worker_key_fail():
    
    58
    +    properties = {'voight' : 'kampff'}
    
    59
    +    configs = {'voight' : 'kampff'}
    
    60
    +
    
    61
    +    with pytest.raises(KeyError):
    
    62
    +        bot_session.Worker(properties)
    
    63
    +    with pytest.raises(KeyError):
    
    64
    +        bot_session.Worker(configs)

  • tests/integration/bots_service.py
    ... ... @@ -36,6 +36,12 @@ from buildgrid.server.worker import bots_interface, bots_service
    36 36
     def context():
    
    37 37
         yield mock.MagicMock(spec = _Context)
    
    38 38
     
    
    39
    +@pytest.fixture
    
    40
    +def action_job():
    
    41
    +    action_digest = remote_execution_pb2.Digest()
    
    42
    +    j = job.Job(action_digest, None)
    
    43
    +    yield j
    
    44
    +
    
    39 45
     @pytest.fixture
    
    40 46
     def bot_session():
    
    41 47
         bot = bots_pb2.BotSession()
    
    ... ... @@ -101,7 +107,6 @@ def test_update_bot_session_zombie(bot_session, context, instance):
    101 107
     
    
    102 108
         response = instance.UpdateBotSession(request, context)
    
    103 109
     
    
    104
    -    assert isinstance(response, bots_pb2.BotSession)
    
    105 110
         context.set_code.assert_called_once_with(grpc.StatusCode.INVALID_ARGUMENT)
    
    106 111
     
    
    107 112
     def test_update_bot_session_bot_id_fail(bot_session, context, instance):
    
    ... ... @@ -113,35 +118,33 @@ def test_update_bot_session_bot_id_fail(bot_session, context, instance):
    113 118
     
    
    114 119
         context.set_code.assert_called_once_with(grpc.StatusCode.INVALID_ARGUMENT)
    
    115 120
     
    
    116
    -@pytest.mark.parametrize("number_of_leases", [1, 3, 500])
    
    117
    -def test_update_leases(number_of_leases, bot_session, context, instance):
    
    118
    -    leases = [bots_pb2.Lease() for x in range(number_of_leases)]
    
    119
    -    bot_session.leases.extend(leases)
    
    121
    +@pytest.mark.parametrize("number_of_jobs", [0, 1, 3, 500])
    
    122
    +def test_number_of_leases(number_of_jobs, bot_session, context, instance):
    
    120 123
         request = bots_pb2.CreateBotSessionRequest(parent='',
    
    121 124
                                                    bot_session=bot_session)
    
    125
    +    # Inject work
    
    126
    +    for n in range(0, number_of_jobs):
    
    127
    +        action_digest = remote_execution_pb2.Digest()
    
    128
    +        instance._instance._scheduler.append_job(job.Job(action_digest))
    
    122 129
         # Simulated the severed binding between client and server
    
    123 130
         bot = copy.deepcopy(instance.CreateBotSession(request, context))
    
    124 131
     
    
    132
    +    # Creation of bot session should not create leases
    
    133
    +    assert len(bot.leases) == 0
    
    134
    +
    
    125 135
         request = bots_pb2.UpdateBotSessionRequest(name=bot.name,
    
    126 136
                                                    bot_session=bot)
    
    127 137
     
    
    128 138
         response = instance.UpdateBotSession(request, context)
    
    129 139
     
    
    130
    -    assert isinstance(response, bots_pb2.BotSession)
    
    131
    -    assert len(response.leases) == len(bot.leases)
    
    132
    -    assert bot == response
    
    140
    +    assert len(response.leases) == number_of_jobs
    
    133 141
     
    
    134 142
     def test_update_leases_with_work(bot_session, context, instance):
    
    135
    -    leases = [bots_pb2.Lease() for x in range(2)]
    
    136
    -    bot_session.leases.extend(leases)
    
    137
    -
    
    138
    -    # Inject some work to be done
    
    139
    -    action = remote_execution_pb2.Action()
    
    140
    -    action.command_digest.hash = 'rick'
    
    141
    -    instance._instance._scheduler.append_job(job.Job(action))
    
    142
    -
    
    143 143
         request = bots_pb2.CreateBotSessionRequest(parent='',
    
    144 144
                                                    bot_session=bot_session)
    
    145
    +    # Inject work
    
    146
    +    action_digest = remote_execution_pb2.Digest(hash = 'gaff')
    
    147
    +    instance._instance._scheduler.append_job(job.Job(action_digest))
    
    145 148
         # Simulated the severed binding between client and server
    
    146 149
         bot = copy.deepcopy(instance.CreateBotSession(request, context))
    
    147 150
     
    
    ... ... @@ -149,26 +152,50 @@ def test_update_leases_with_work(bot_session, context, instance):
    149 152
                                                    bot_session=bot)
    
    150 153
     
    
    151 154
         response = instance.UpdateBotSession(request, context)
    
    152
    -    response_action = remote_execution_pb2.Action()
    
    153
    -    _unpack_any(response.leases[0].payload, response_action)
    
    154 155
     
    
    156
    +    response_action = remote_execution_pb2.Digest()
    
    157
    +    response.leases[0].payload.Unpack(response_action)
    
    155 158
         assert isinstance(response, bots_pb2.BotSession)
    
    156 159
         assert response.leases[0].state == LeaseState.PENDING.value
    
    157
    -    assert response.leases[1].state == LeaseState.LEASE_STATE_UNSPECIFIED.value
    
    158 160
         assert uuid.UUID(response.leases[0].id, version=4)
    
    159
    -    assert response_action == action
    
    161
    +    assert response_action == action_digest
    
    160 162
     
    
    161 163
     def test_update_leases_work_complete(bot_session, context, instance):
    
    162
    -    leases = [bots_pb2.Lease() for x in range(2)]
    
    163
    -    bot_session.leases.extend(leases)
    
    164
    +    request = bots_pb2.CreateBotSessionRequest(parent='',
    
    165
    +                                               bot_session=bot_session)
    
    166
    +    # Inject work
    
    167
    +    action_digest = remote_execution_pb2.Digest(hash = 'gaff')
    
    168
    +    instance._instance._scheduler.append_job(job.Job(action_digest))
    
    169
    +    # Simulated the severed binding between client and server
    
    170
    +    bot = copy.deepcopy(instance.CreateBotSession(request, context))
    
    171
    +
    
    172
    +    request = bots_pb2.UpdateBotSessionRequest(name=bot.name,
    
    173
    +                                               bot_session=bot)
    
    174
    +
    
    175
    +    response = copy.deepcopy(instance.UpdateBotSession(request, context))
    
    176
    +
    
    177
    +    response.leases[0].state = LeaseState.ACTIVE.value
    
    178
    +
    
    179
    +    request = bots_pb2.UpdateBotSessionRequest(name=response.name,
    
    180
    +                                               bot_session=response)
    
    181
    +
    
    182
    +    response = copy.deepcopy(instance.UpdateBotSession(request, context))
    
    183
    +
    
    184
    +    response.leases[0].state = LeaseState.COMPLETED.value
    
    185
    +
    
    186
    +    request = bots_pb2.UpdateBotSessionRequest(name=response.name,
    
    187
    +                                               bot_session=response)
    
    164 188
     
    
    165
    -    # Inject some work to be done
    
    166
    -    action = remote_execution_pb2.Action()
    
    167
    -    action.command_digest.hash = 'rick'
    
    168
    -    instance._instance._scheduler.append_job(job.Job(action))
    
    189
    +    response = copy.deepcopy(instance.UpdateBotSession(request, context))
    
    190
    +
    
    191
    +    assert len(response.leases) == 0
    
    169 192
     
    
    193
    +def test_work_rejected_by_bot(bot_session, context, instance):
    
    170 194
         request = bots_pb2.CreateBotSessionRequest(parent='',
    
    171 195
                                                    bot_session=bot_session)
    
    196
    +    # Inject work
    
    197
    +    action_digest = remote_execution_pb2.Digest(hash = 'gaff')
    
    198
    +    instance._instance._scheduler.append_job(job.Job(action_digest))
    
    172 199
         # Simulated the severed binding between client and server
    
    173 200
         bot = copy.deepcopy(instance.CreateBotSession(request, context))
    
    174 201
     
    
    ... ... @@ -177,26 +204,125 @@ def test_update_leases_work_complete(bot_session, context, instance):
    177 204
     
    
    178 205
         response = copy.deepcopy(instance.UpdateBotSession(request, context))
    
    179 206
     
    
    180
    -    operation_name = response.leases[0].id
    
    207
    +    response.leases[0].state = LeaseState.COMPLETED.value
    
    208
    +
    
    209
    +    request = bots_pb2.UpdateBotSessionRequest(name=response.name,
    
    210
    +                                               bot_session=response)
    
    211
    +
    
    212
    +    response = instance.UpdateBotSession(request, context)
    
    213
    +
    
    214
    +    context.set_code.assert_called_once_with(grpc.StatusCode.UNIMPLEMENTED)
    
    215
    +
    
    216
    +def test_work_rejected_by_bot(bot_session, context, instance):
    
    217
    +    request = bots_pb2.CreateBotSessionRequest(parent='',
    
    218
    +                                               bot_session=bot_session)
    
    219
    +    # Inject work
    
    220
    +    action_digest = remote_execution_pb2.Digest(hash = 'gaff')
    
    221
    +    instance._instance._scheduler.append_job(job.Job(action_digest))
    
    222
    +    # Simulated the severed binding between client and server
    
    223
    +    bot = copy.deepcopy(instance.CreateBotSession(request, context))
    
    224
    +
    
    225
    +    request = bots_pb2.UpdateBotSessionRequest(name=bot.name,
    
    226
    +                                               bot_session=bot)
    
    227
    +
    
    228
    +    response = copy.deepcopy(instance.UpdateBotSession(request, context))
    
    181 229
     
    
    182
    -    assert response.leases[0].state == LeaseState.PENDING.value
    
    183 230
         response.leases[0].state = LeaseState.COMPLETED.value
    
    184 231
     
    
    185 232
         request = bots_pb2.UpdateBotSessionRequest(name=response.name,
    
    186 233
                                                    bot_session=response)
    
    234
    +
    
    235
    +    response = instance.UpdateBotSession(request, context)
    
    236
    +
    
    237
    +    context.set_code.assert_called_once_with(grpc.StatusCode.UNIMPLEMENTED)
    
    238
    +
    
    239
    +@pytest.mark.parametrize("state", [ LeaseState.LEASE_STATE_UNSPECIFIED, LeaseState.PENDING])
    
    240
    +def test_work_out_of_sync_from_pending(state, bot_session, context, instance):
    
    241
    +    request = bots_pb2.CreateBotSessionRequest(parent='',
    
    242
    +                                               bot_session=bot_session)
    
    243
    +    # Inject work
    
    244
    +    action_digest = remote_execution_pb2.Digest(hash = 'gaff')
    
    245
    +    instance._instance._scheduler.append_job(job.Job(action_digest))
    
    246
    +    # Simulated the severed binding between client and server
    
    247
    +    bot = copy.deepcopy(instance.CreateBotSession(request, context))
    
    248
    +
    
    249
    +    request = bots_pb2.UpdateBotSessionRequest(name=bot.name,
    
    250
    +                                               bot_session=bot)
    
    251
    +
    
    252
    +    response = copy.deepcopy(instance.UpdateBotSession(request, context))
    
    253
    +
    
    254
    +    response.leases[0].state = state.value
    
    255
    +
    
    256
    +    request = bots_pb2.UpdateBotSessionRequest(name=response.name,
    
    257
    +                                               bot_session=response)
    
    258
    +
    
    259
    +    response = instance.UpdateBotSession(request, context)
    
    260
    +
    
    261
    +    context.set_code.assert_called_once_with(grpc.StatusCode.DATA_LOSS)
    
    262
    +
    
    263
    +@pytest.mark.parametrize("state", [ LeaseState.LEASE_STATE_UNSPECIFIED, LeaseState.PENDING])
    
    264
    +def test_work_out_of_sync_from_active(state, bot_session, context, instance):
    
    265
    +    request = bots_pb2.CreateBotSessionRequest(parent='',
    
    266
    +                                               bot_session=bot_session)
    
    267
    +    # Inject work
    
    268
    +    action_digest = remote_execution_pb2.Digest(hash = 'gaff')
    
    269
    +    instance._instance._scheduler.append_job(job.Job(action_digest))
    
    187 270
         # Simulated the severed binding between client and server
    
    271
    +    bot = copy.deepcopy(instance.CreateBotSession(request, context))
    
    272
    +
    
    273
    +    request = bots_pb2.UpdateBotSessionRequest(name=bot.name,
    
    274
    +                                               bot_session=bot)
    
    275
    +
    
    188 276
         response = copy.deepcopy(instance.UpdateBotSession(request, context))
    
    189
    -    assert isinstance(response, bots_pb2.BotSession)
    
    190
    -    assert instance._instance._scheduler.jobs[operation_name]._execute_stage == ExecuteStage.COMPLETED
    
    277
    +
    
    278
    +    response.leases[0].state = LeaseState.ACTIVE.value
    
    279
    +
    
    280
    +    request = copy.deepcopy(bots_pb2.UpdateBotSessionRequest(name=response.name,
    
    281
    +                                                             bot_session=response))
    
    282
    +
    
    283
    +    response = instance.UpdateBotSession(request, context)
    
    284
    +
    
    285
    +    response.leases[0].state = state.value
    
    286
    +
    
    287
    +    request = bots_pb2.UpdateBotSessionRequest(name=response.name,
    
    288
    +                                               bot_session=response)
    
    289
    +
    
    290
    +    response = instance.UpdateBotSession(request, context)
    
    291
    +
    
    292
    +    context.set_code.assert_called_once_with(grpc.StatusCode.DATA_LOSS)
    
    293
    +
    
    294
    +def test_work_active_to_active(bot_session, context, instance):
    
    295
    +    request = bots_pb2.CreateBotSessionRequest(parent='',
    
    296
    +                                               bot_session=bot_session)
    
    297
    +    # Inject work
    
    298
    +    action_digest = remote_execution_pb2.Digest(hash = 'gaff')
    
    299
    +    instance._instance._scheduler.append_job(job.Job(action_digest))
    
    300
    +    # Simulated the severed binding between client and server
    
    301
    +    bot = copy.deepcopy(instance.CreateBotSession(request, context))
    
    302
    +
    
    303
    +    request = bots_pb2.UpdateBotSessionRequest(name=bot.name,
    
    304
    +                                               bot_session=bot)
    
    305
    +
    
    306
    +    response = copy.deepcopy(instance.UpdateBotSession(request, context))
    
    307
    +
    
    308
    +    response.leases[0].state = LeaseState.ACTIVE.value
    
    309
    +
    
    310
    +    request = copy.deepcopy(bots_pb2.UpdateBotSessionRequest(name=response.name,
    
    311
    +                                                             bot_session=response))
    
    312
    +
    
    313
    +    response = instance.UpdateBotSession(request, context)
    
    314
    +
    
    315
    +    response.leases[0].state = LeaseState.ACTIVE.value
    
    316
    +
    
    317
    +    request = bots_pb2.UpdateBotSessionRequest(name=response.name,
    
    318
    +                                               bot_session=response)
    
    319
    +
    
    320
    +    response = instance.UpdateBotSession(request, context)
    
    321
    +
    
    322
    +    assert response.leases[0].state == LeaseState.ACTIVE.value
    
    191 323
     
    
    192 324
     def test_post_bot_event_temp(context, instance):
    
    193 325
         request = bots_pb2.PostBotEventTempRequest()
    
    194 326
         instance.PostBotEventTemp(request, context)
    
    195 327
     
    
    196 328
         context.set_code.assert_called_once_with(grpc.StatusCode.UNIMPLEMENTED)
    197
    -
    
    198
    -def _unpack_any(unpack_from, to):
    
    199
    -    any = any_pb2.Any()
    
    200
    -    any.CopyFrom(unpack_from)
    
    201
    -    any.Unpack(to)
    
    202
    -    return to



  • [Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]