[Notes] [Git][BuildStream/buildstream][dp0/casserver-tests] 2 commits: Refactor casserver for better coverage



Title: GitLab

Daniel Playle pushed to branch dp0/casserver-tests at BuildStream / buildstream

Commits:

5 changed files:

Changes:

  • buildstream/_artifactcache/casserver.py
    ... ... @@ -42,6 +42,11 @@ from .cascache import CASCache
    42 42
     class ArtifactTooLargeException(Exception):
    
    43 43
         pass
    
    44 44
     
    
    45
    +class RequiresServerKeyPairException(Exception):
    
    46
    +    pass
    
    47
    +
    
    48
    +class RequiresServerKeyForClientAuthException(Exception):
    
    49
    +    pass
    
    45 50
     
    
    46 51
     # create_server():
    
    47 52
     #
    
    ... ... @@ -72,27 +77,37 @@ def create_server(repo, *, enable_push):
    72 77
     
    
    73 78
         return server
    
    74 79
     
    
    75
    -
    
    76
    -@click.command(short_help="CAS Artifact Server")
    
    77
    -@click.option('--port', '-p', type=click.INT, required=True, help="Port number")
    
    78
    -@click.option('--server-key', help="Private server key for TLS (PEM-encoded)")
    
    79
    -@click.option('--server-cert', help="Public server certificate for TLS (PEM-encoded)")
    
    80
    -@click.option('--client-certs', help="Public client certificates for TLS (PEM-encoded)")
    
    81
    -@click.option('--enable-push', default=False, is_flag=True,
    
    82
    -              help="Allow clients to upload blobs and update artifact cache")
    
    83
    -@click.argument('repo')
    
    84
    -def server_main(repo, port, server_key, server_cert, client_certs, enable_push):
    
    85
    -    server = create_server(repo, enable_push=enable_push)
    
    86
    -
    
    80
    +# setup_server():
    
    81
    +#
    
    82
    +# Creates a port on the given server. This port either be secured or unsecured.
    
    83
    +# This is dependent on the optional credential arguments.
    
    84
    +#
    
    85
    +# Either none or both of server_key and server_cert must be specified. If
    
    86
    +# client_certs is specified, then both server_key and server_cert must be
    
    87
    +# specified.
    
    88
    +#
    
    89
    +# If the caller of this function does not care what port is used, this decision
    
    90
    +# can be made by the gRPC runtime by specifying port 0. The port that is
    
    91
    +# actually used is returned.
    
    92
    +#
    
    93
    +# Args:
    
    94
    +#     server (grpc.server): The server to open a port on
    
    95
    +#     address (str): The address to bind the port on
    
    96
    +#     port (int): The port number to bind on. 0 if the gRPC runtime should pick
    
    97
    +#     server_key (str): The filename of the server private key file
    
    98
    +#     server_cert (str): The filename of the server public cert file
    
    99
    +#     client_certs (str): The filename of the client public certs file
    
    100
    +#
    
    101
    +# Returns:
    
    102
    +#     int: The actual port that was opened for this server
    
    103
    +def setup_server(server, address, port, server_key=None, server_cert=None, client_certs=None):
    
    87 104
         use_tls = bool(server_key)
    
    88 105
     
    
    89 106
         if bool(server_cert) != use_tls:
    
    90
    -        click.echo("ERROR: --server-key and --server-cert are both required for TLS", err=True)
    
    91
    -        sys.exit(-1)
    
    107
    +        raise RequiresServerKeyPairException()
    
    92 108
     
    
    93 109
         if client_certs and not use_tls:
    
    94
    -        click.echo("ERROR: --client-certs can only be used with --server-key", err=True)
    
    95
    -        sys.exit(-1)
    
    110
    +        raise RequiresServerKeyForClientAuthException()
    
    96 111
     
    
    97 112
         if use_tls:
    
    98 113
             # Read public/private key pair
    
    ... ... @@ -110,9 +125,30 @@ def server_main(repo, port, server_key, server_cert, client_certs, enable_push):
    110 125
             credentials = grpc.ssl_server_credentials([(server_key_bytes, server_cert_bytes)],
    
    111 126
                                                       root_certificates=client_certs_bytes,
    
    112 127
                                                       require_client_auth=bool(client_certs))
    
    113
    -        server.add_secure_port('[::]:{}'.format(port), credentials)
    
    128
    +        return server.add_secure_port('{}:{}'.format(address, port), credentials)
    
    114 129
         else:
    
    115
    -        server.add_insecure_port('[::]:{}'.format(port))
    
    130
    +        return server.add_insecure_port('{}:{}'.format(address, port))
    
    131
    +
    
    132
    +
    
    133
    +@click.command(short_help="CAS Artifact Server")
    
    134
    +@click.option('--port', '-p', type=click.INT, required=True, help="Port number")
    
    135
    +@click.option('--server-key', help="Private server key for TLS (PEM-encoded)")
    
    136
    +@click.option('--server-cert', help="Public server certificate for TLS (PEM-encoded)")
    
    137
    +@click.option('--client-certs', help="Public client certificates for TLS (PEM-encoded)")
    
    138
    +@click.option('--enable-push', default=False, is_flag=True,
    
    139
    +              help="Allow clients to upload blobs and update artifact cache")
    
    140
    +@click.argument('repo')
    
    141
    +def server_main(repo, port, server_key, server_cert, client_certs, enable_push):
    
    142
    +    server = create_server(repo, enable_push=enable_push)
    
    143
    +
    
    144
    +    try:
    
    145
    +        setup_server(server, '[::]', port, server_key, server_cert, client_certs)
    
    146
    +    except RequiresServerKeyPairException:
    
    147
    +        click.echo("ERROR: --server-key and --server-cert are both required for TLS", err=True)
    
    148
    +        sys.exit(-1)
    
    149
    +    except RequiresServerKeyForClientAuthException:
    
    150
    +        click.echo("ERROR: --client-certs can only be used with --server-key", err=True)
    
    151
    +        sys.exit(-1)
    
    116 152
     
    
    117 153
         # Run artifact server
    
    118 154
         server.start()
    

  • tests/frontend/creds/server_cert.pem
    1
    +-----BEGIN CERTIFICATE-----
    
    2
    +MIIFADCCAuigAwIBAgIJAMrnbCKz2am/MA0GCSqGSIb3DQEBCwUAMBQxEjAQBgNV
    
    3
    +BAMMCWxvY2FsaG9zdDAgFw0xODA4MzExNTEzMThaGA8zMDE4MDEwMTE1MTMxOFow
    
    4
    +FDESMBAGA1UEAwwJbG9jYWxob3N0MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIIC
    
    5
    +CgKCAgEAtOF+EmfIIQVz4eox6lZLcQcsf089r65XB5su8SzDXvC2kYIn8Crqs67Q
    
    6
    +x4s10YfYAOWS0Bj0Jx5GS7NQB+vUQtHWNTAO+19edAsrH204OD3QTrU0rt1rpJGb
    
    7
    +P36tIgZk+zgWj9MquHibacg2u/sz+4OlfxsDg2FDt1zhgamY9AQ2BRlxDza9/lcU
    
    8
    +/yBD2hSw3LyLQLJAL0TbTARqUkCHWZRcy1KPQ47SV4aWC2WhUwimDK44UZs1Ub50
    
    9
    +GcaB7s/ZRm6mREGV5mBzW63GLthOGlTps5YzE45GsLrmRiQ9aJgr8I6BZoNggLl9
    
    10
    +WomvGvd4PBzsXxyu3d+ZVdoudxeQbMKlyr7i5yVDO5S26xohUbpQg8wAl4YZ7tG7
    
    11
    +K2ihEphSgeCh3owWPkptXSxX+dXnA7W2/uJ4HwHjRLf7/MRL3GccJsviL7qtg9fO
    
    12
    +PF5av/psRkfR5tq/qtFrWAor4E1/nLKJbtEzHP8XoSJglSIXL2g1Q6ofNmbHvghg
    
    13
    +hR0pT6oEf6hc5R+qXVT7TTSxdVQkyLnrR+nUWMzaMUrD990kdhY+eJu15sJXsHyJ
    
    14
    +OThkuqiGbiTlTUEyhbTsFCK1UVi9P8cLGndyeB9LtQynWVqBFXPkT/qVyjOINUHZ
    
    15
    +2wu2U0OhjMpZ3dtQC58ME/Q0xDbJoyr+HwsMFV97TXT/WoLiN48CAwEAAaNTMFEw
    
    16
    +HQYDVR0OBBYEFFWfm5e2tS2Ask/QRNP8Y10yM3S4MB8GA1UdIwQYMBaAFFWfm5e2
    
    17
    +tS2Ask/QRNP8Y10yM3S4MA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQELBQAD
    
    18
    +ggIBACGpGGhliKiwAu1TjxMoQfI9rpO7uVyEYeBIYJ/eK3beJqCs3FmirgYdmGtK
    
    19
    +2KHcPnMG27c1m9EEsJf9sVOjkd43OB7fdWw38i0TaPxSgmPh0v6b+jhR4tqxwIRi
    
    20
    +jSQUxNklurKroyMWL9QFFLufwd43g3XTm449EOzrLB2jxUd10u+OXwzraQRRgTeM
    
    21
    +9U9PMoTfp6dICKKcV7XJdDR2hUH7SRrk96ucgYhztLx4x9R+mTZzgeCw5euY7a/t
    
    22
    +02uijT4tIrtCryOTukHrtfWdy5+ng4mcsdlWvZgJiRy+vwdWFx8k5t/MJ6f1xqxs
    
    23
    +RHl/99LAh/d9scdkVXPEB57vQRuHeybPH2i4cM/0VyFDfCrCG9AeXeVeB/pbanzB
    
    24
    +ex6MHttnhopTWtFHuMDquCeLP5P5cnKNLB676bZvKhgNoYZAXIrFGJtJNLMFBXD6
    
    25
    +v9kXrCIpDdUFHd3GLi8U9GTiwSmfz6HQVCvQZ+feVBpZLxaFrLpbRszKIE1lYFVS
    
    26
    +eJd3StxS/BGm3jzbWGgG9kq7kuF3cuJmtfKoAzOYYNz3/eipfQl6giOitJx5MWW5
    
    27
    +mevCq9mCNBIKvRNdxR0kJ4rJ5eTlDJ6xfFs2aKGXHFKS1+21RM/S58El+XosWXov
    
    28
    +4jZCTLS7wmk2/MrABGmbCgK4YfrQnt6eY2nElJXEBPX0jeHu
    
    29
    +-----END CERTIFICATE-----

  • tests/frontend/creds/server_key.pem
    1
    +-----BEGIN PRIVATE KEY-----
    
    2
    +MIIJQgIBADANBgkqhkiG9w0BAQEFAASCCSwwggkoAgEAAoICAQC04X4SZ8ghBXPh
    
    3
    +6jHqVktxByx/Tz2vrlcHmy7xLMNe8LaRgifwKuqzrtDHizXRh9gA5ZLQGPQnHkZL
    
    4
    +s1AH69RC0dY1MA77X150CysfbTg4PdBOtTSu3WukkZs/fq0iBmT7OBaP0yq4eJtp
    
    5
    +yDa7+zP7g6V/GwODYUO3XOGBqZj0BDYFGXEPNr3+VxT/IEPaFLDcvItAskAvRNtM
    
    6
    +BGpSQIdZlFzLUo9DjtJXhpYLZaFTCKYMrjhRmzVRvnQZxoHuz9lGbqZEQZXmYHNb
    
    7
    +rcYu2E4aVOmzljMTjkawuuZGJD1omCvwjoFmg2CAuX1aia8a93g8HOxfHK7d35lV
    
    8
    +2i53F5BswqXKvuLnJUM7lLbrGiFRulCDzACXhhnu0bsraKESmFKB4KHejBY+Sm1d
    
    9
    +LFf51ecDtbb+4ngfAeNEt/v8xEvcZxwmy+Ivuq2D1848Xlq/+mxGR9Hm2r+q0WtY
    
    10
    +CivgTX+csolu0TMc/xehImCVIhcvaDVDqh82Zse+CGCFHSlPqgR/qFzlH6pdVPtN
    
    11
    +NLF1VCTIuetH6dRYzNoxSsP33SR2Fj54m7XmwlewfIk5OGS6qIZuJOVNQTKFtOwU
    
    12
    +IrVRWL0/xwsad3J4H0u1DKdZWoEVc+RP+pXKM4g1QdnbC7ZTQ6GMylnd21ALnwwT
    
    13
    +9DTENsmjKv4fCwwVX3tNdP9aguI3jwIDAQABAoICAQClXfJwyUkCR4XmaMIxx6s5
    
    14
    +LqHT0pJG51DRt2J3Q8FqLw/6f9AblmD03UIq7G7LnTIxv7E1Z1rv2JHT65+jXku0
    
    15
    +uzrnbYSE9G/aD8vg822OnZSwIKKFrBEZZ7VTm3CVxtrTgje+TgSkmj8butuviL3B
    
    16
    +mF3ZkszndCkAnn3cmT0o+iCZEOV4T0fsG5kqlkjyPDBl3kpBX7WmgYEsQm0hvbUA
    
    17
    +hM9BY71uukg7lOPgj42p6CJHPZBnq0pX7ZMfbYik2ImABvEjPgLZmBxfGMQzV7Yw
    
    18
    +BKmUciFII68lK/oS7lbmJRkm2GIdYsb7aJneCDp6oPzfmGHRotuMJTx+bPZGEtkJ
    
    19
    +zGTc3zbJYiMyrpI35CdAtRgpWIrJEvWEAodRyeR+XkeKRfHDCo79QPBatF+xEm0h
    
    20
    +qZu01q5I0J5+k7i07cz2RaStzgsgDgYUBtQmlC9+HR7Pg12CrKfv0sbXR67BW15n
    
    21
    +6W54XZH0MV40JdxbRN4FeZY1XmER4npLFjQncwT2ESuB4W461RRC5uEdP1H3G2UF
    
    22
    +Dx8A6kvkazHoNXFrXkMA2vpr4kgkztlPYl80L4elLbpH6wCfyitf21MVXz5Td0IN
    
    23
    +mLgDVj2bHymgQ0KSf7o+r0Ps2cvMOQTCHvepXY3WxTyT5Fog5OzHLgw/I0RkXv9r
    
    24
    +jTkktEThD2hd7Qtl86LcoQKCAQEA3Ib71it2jrByZkoiSwRDM1P6VYofCa93pQid
    
    25
    +yWji0Q5fAcW8f3T7rohqyfdkDZ+TpBX/AiJP33zY4To3LJjBNFtSPxSZA3EeQjkW
    
    26
    +LKchmHkz5ufg+zZig+HIs/wNT5YY74Ru27wRApDf6rbHYYZq30SlkJTx+kfD/jTF
    
    27
    +nlzuhcSgK9piP19N2No8C03/BwVUgMuXrBEOGBMqTaBSzcLZLXp24R3X7FDi7S5f
    
    28
    +lntO4Um+e106bnYqPQMJhzVZV6ZHuMGt1VD3XlUXI4vPwcRsPi4s5egDVhH6wSRF
    
    29
    +6vMzdE7UnwG6MAflKXShqCUHVkWScFngiGk4rOmUwtLAp8Ds6wKCAQEA0fnr3DUs
    
    30
    +OMt4y/ZRqQ5wy/XceAAYI40CkLbo8uthYWpHscZWmf6gfOb3DAIeg9+CbfaqCYKb
    
    31
    +EGO5cBRm7yTlJYv0T06hfrmt36cJewLtIinYLQFyB8GgyVApMUeO/xNJhIsRX73U
    
    32
    +GmP4CzVgtYCbaqgfrZpDUJt4Ayq/7RULRPRErP7PXAhxAeoNR76qC7d0rxmR4gAA
    
    33
    +yxIb2/Wdx+X3XH047bHZ/wjyZD3JAjwwDtCUxfNsuZCdItIeto46U3obnAeBdQZX
    
    34
    +FWefTud0dnv2eE1nxxFSJmIZd8NoS03Y40moFUWOeORBWQ2A04Gl7Uzv8lHb+hwY
    
    35
    +2u5dJxo3P1Qm7QKCAQBvAkv3LX3KqiuMLjlBBe5GAjn7oUGqgHd7zfCPmIrErbVJ
    
    36
    +kR4oEt02qFkJPc1RxkhtytzJWDhYyeHqzoFDo8lt76JhOp8jymdu8omlBKS2uhxU
    
    37
    +Wdk429GPjbKYV4Lj0yzONR4Q4oS1g/QTlNqczysxJL8rHq8IS+PvLOVlqGYxVB9E
    
    38
    +s/PM7s6jIIglMKf2Asrc4p+A8DzmBY+/77p+9VyZthHtlDZDMRxqRHO9rmiwo4yN
    
    39
    +UQq+3CC7AbJkK4jDxGJKMMSuoslC5RZ2wERex9+tFVVojfhP9VECtJ21faMjIyOI
    
    40
    +vzfYQcErsxhFKg6dcPwcLkIGqODsudA2mhx81XLtAoIBABKRGdT/8qgW/dhzMGdV
    
    41
    +eo3ecJ8/yuKh3l8zfUe1nofBoRNMKW42gLRqq9+o9E/O3LaigAiVPublGomZlDyD
    
    42
    +M6vtQy4cEtWkz4YePA1fhd5metIH9bBP48rJRssvu6o8Z1zL+z5PB8lJm65KCwIh
    
    43
    +nByDP0HXiSpAhQ0qo4vwN23id4wgf+9wY6W6r2/voROmJjAxf5/PRkKumD4L6ua5
    
    44
    +I/VOsVD7T/5oKR7KA9MpxUoaEX2rd6q06eAhWkvkKa4l9vkGBOF3LQ4ceo68kqTD
    
    45
    +c1jR52JH2s7AD+ZyJe+6s3ntkmpHG0D/VfPs6L5LEYP5MKJpsJzeDSiWuS/y9n2o
    
    46
    +EEUCggEAWfQ4qXWzzniM/N8a27+hxPAzQxGr2EoYIxGVuMAEbSvgUNIP6snOtvZc
    
    47
    +NTGEFutcNRi5YmIu9upb+PfSOC6i1k7l0t0v0kkzVejx6lKjlWvP22zfiqKrH8JB
    
    48
    +4Pm3MDeqz+8XQZFKxRQY/v3Vyn2YtUiolzP96ZhkJv4IFNWEziMrWfo1a12qHtSN
    
    49
    +bsOu9BsMBtbhoE1bf0YUaKAcBYzGw3yqGH0Uz0jqRJaVKK5bhq6ou/tz4ftud/T9
    
    50
    +TBlQa62+br8Q/W3HgfAqqijh+SwgnhgU80cBjJfdAaDquNqIdK+sZuXStvfVY/WN
    
    51
    +e+XVdfiURwWj6Q7/y/Rujtp7K6z2dA==
    
    52
    +-----END PRIVATE KEY-----

  • tests/frontend/push.py
    ... ... @@ -35,6 +35,22 @@ DATA_DIR = os.path.join(
    35 35
         "project",
    
    36 36
     )
    
    37 37
     
    
    38
    +# Credential directory
    
    39
    +CRED_DIR = os.path.join(
    
    40
    +    os.path.dirname(os.path.realpath(__file__)),
    
    41
    +    "creds",
    
    42
    +)
    
    43
    +
    
    44
    +# Parameters for credentials
    
    45
    +CREDENTIAL_FILENAMES = {
    
    46
    +    'unsecured': {},
    
    47
    +
    
    48
    +    'server_secured': {
    
    49
    +        'server_key': 'server_key.pem',
    
    50
    +        'server_cert': 'server_cert.pem',
    
    51
    +    },
    
    52
    +}
    
    53
    +
    
    38 54
     
    
    39 55
     # Assert that a given artifact is in the share
    
    40 56
     #
    
    ... ... @@ -60,14 +76,41 @@ def assert_not_shared(cli, share, project, element_name):
    60 76
                                  .format(share.repo, element_name))
    
    61 77
     
    
    62 78
     
    
    79
    +# Taking a dictionary of filenames, this returns a dictionary of qualified
    
    80
    +# fielnames
    
    81
    +def join_credentials_path(credential_filenames, credential_files):
    
    82
    +    return {
    
    83
    +        key: os.path.join(credential_files, filename)
    
    84
    +        for key, filename in credential_filenames.items()
    
    85
    +    }
    
    86
    +
    
    87
    +
    
    88
    +# Adds the server certificate to the configuration if it exists and returns
    
    89
    +# this for ease of use
    
    90
    +def add_client_config_creds(configuration, credentials):
    
    91
    +    if 'server_cert' in credentials:
    
    92
    +        artifacts = configuration['artifacts']
    
    93
    +        if isinstance(artifacts, (list,)):
    
    94
    +            for subconfig in artifacts:
    
    95
    +                subconfig['server-cert'] = credentials['server_cert']
    
    96
    +        else:
    
    97
    +            artifacts['server-cert'] = credentials['server_cert']
    
    98
    +    return configuration
    
    99
    +
    
    100
    +
    
    63 101
     # Tests that:
    
    64 102
     #
    
    65 103
     #  * `bst push` fails if there are no remotes configured for pushing
    
    66 104
     #  * `bst push` successfully pushes to any remote that is configured for pushing
    
    67 105
     #
    
    68
    -@pytest.mark.datafiles(DATA_DIR)
    
    69
    -def test_push(cli, tmpdir, datafiles):
    
    70
    -    project = str(datafiles)
    
    106
    +@pytest.mark.parametrize(
    
    107
    +    'credential_filenames', CREDENTIAL_FILENAMES.values(), ids=list(CREDENTIAL_FILENAMES))
    
    108
    +@pytest.mark.datafiles(DATA_DIR, CRED_DIR, keep_top_dir=True)
    
    109
    +def test_push(cli, tmpdir, datafiles, credential_filenames):
    
    110
    +    project = os.path.join(datafiles, 'project')
    
    111
    +    credfiles = os.path.join(datafiles, 'creds')
    
    112
    +
    
    113
    +    credentials = join_credentials_path(credential_filenames, credfiles)
    
    71 114
     
    
    72 115
         # First build the project without the artifact cache configured
    
    73 116
         result = cli.run(project=project, args=['build', 'target.bst'])
    
    ... ... @@ -77,9 +120,11 @@ def test_push(cli, tmpdir, datafiles):
    77 120
         assert cli.get_element_state(project, 'target.bst') == 'cached'
    
    78 121
     
    
    79 122
         # Set up two artifact shares.
    
    80
    -    with create_artifact_share(os.path.join(str(tmpdir), 'artifactshare1')) as share1:
    
    123
    +    with create_artifact_share(os.path.join(str(tmpdir), 'artifactshare1'),
    
    124
    +                               credentials=credentials) as share1:
    
    81 125
     
    
    82
    -        with create_artifact_share(os.path.join(str(tmpdir), 'artifactshare2')) as share2:
    
    126
    +        with create_artifact_share(os.path.join(str(tmpdir), 'artifactshare2'),
    
    127
    +                                   credentials=credentials) as share2:
    
    83 128
     
    
    84 129
                 # Try pushing with no remotes configured. This should fail.
    
    85 130
                 result = cli.run(project=project, args=['push', 'target.bst'])
    
    ... ... @@ -87,19 +132,19 @@ def test_push(cli, tmpdir, datafiles):
    87 132
     
    
    88 133
                 # Configure bst to pull but not push from a cache and run `bst push`.
    
    89 134
                 # This should also fail.
    
    90
    -            cli.configure({
    
    135
    +            cli.configure(add_client_config_creds({
    
    91 136
                     'artifacts': {'url': share1.repo, 'push': False},
    
    92
    -            })
    
    137
    +            }, credentials))
    
    93 138
                 result = cli.run(project=project, args=['push', 'target.bst'])
    
    94 139
                 result.assert_main_error(ErrorDomain.STREAM, None)
    
    95 140
     
    
    96 141
                 # Configure bst to push to one of the caches and run `bst push`. This works.
    
    97
    -            cli.configure({
    
    142
    +            cli.configure(add_client_config_creds({
    
    98 143
                     'artifacts': [
    
    99 144
                         {'url': share1.repo, 'push': False},
    
    100 145
                         {'url': share2.repo, 'push': True},
    
    101 146
                     ]
    
    102
    -            })
    
    147
    +            }, credentials))
    
    103 148
                 result = cli.run(project=project, args=['push', 'target.bst'])
    
    104 149
     
    
    105 150
                 assert_not_shared(cli, share1, project, 'target.bst')
    
    ... ... @@ -108,12 +153,12 @@ def test_push(cli, tmpdir, datafiles):
    108 153
             # Now try pushing to both
    
    109 154
     
    
    110 155
             with create_artifact_share(os.path.join(str(tmpdir), 'artifactshare2')) as share2:
    
    111
    -            cli.configure({
    
    156
    +            cli.configure(add_client_config_creds({
    
    112 157
                     'artifacts': [
    
    113 158
                         {'url': share1.repo, 'push': True},
    
    114 159
                         {'url': share2.repo, 'push': True},
    
    115 160
                     ]
    
    116
    -            })
    
    161
    +            }, credentials))
    
    117 162
                 result = cli.run(project=project, args=['push', 'target.bst'])
    
    118 163
     
    
    119 164
                 assert_shared(cli, share1, project, 'target.bst')
    
    ... ... @@ -122,11 +167,16 @@ def test_push(cli, tmpdir, datafiles):
    122 167
     
    
    123 168
     # Tests that `bst push --deps all` pushes all dependencies of the given element.
    
    124 169
     #
    
    125
    -@pytest.mark.datafiles(DATA_DIR)
    
    126
    -def test_push_all(cli, tmpdir, datafiles):
    
    127
    -    project = os.path.join(datafiles.dirname, datafiles.basename)
    
    170
    +@pytest.mark.parametrize(
    
    171
    +    'credential_filenames', CREDENTIAL_FILENAMES.values(), ids=list(CREDENTIAL_FILENAMES))
    
    172
    +@pytest.mark.datafiles(DATA_DIR, CRED_DIR, keep_top_dir=True)
    
    173
    +def test_push_all(cli, tmpdir, datafiles, credential_filenames):
    
    174
    +    project = os.path.join(datafiles, 'project')
    
    175
    +    credfiles = os.path.join(datafiles, 'creds')
    
    128 176
     
    
    129
    -    with create_artifact_share(os.path.join(str(tmpdir), 'artifactshare')) as share:
    
    177
    +    credentials = join_credentials_path(credential_filenames, credfiles)
    
    178
    +
    
    179
    +    with create_artifact_share(os.path.join(str(tmpdir), 'artifactshare'), credentials=credentials) as share:
    
    130 180
     
    
    131 181
             # First build it without the artifact cache configured
    
    132 182
             result = cli.run(project=project, args=['build', 'target.bst'])
    
    ... ... @@ -136,7 +186,7 @@ def test_push_all(cli, tmpdir, datafiles):
    136 186
             assert cli.get_element_state(project, 'target.bst') == 'cached'
    
    137 187
     
    
    138 188
             # Configure artifact share
    
    139
    -        cli.configure({
    
    189
    +        cli.configure(add_client_config_creds({
    
    140 190
                 #
    
    141 191
                 # FIXME: This test hangs "sometimes" if we allow
    
    142 192
                 #        concurrent push.
    
    ... ... @@ -152,7 +202,7 @@ def test_push_all(cli, tmpdir, datafiles):
    152 202
                     'url': share.repo,
    
    153 203
                     'push': True,
    
    154 204
                 }
    
    155
    -        })
    
    205
    +        }, credentials))
    
    156 206
     
    
    157 207
             # Now try bst push all the deps
    
    158 208
             result = cli.run(project=project, args=[
    

  • tests/testutils/artifactshare.py
    ... ... @@ -12,7 +12,7 @@ import pytest_cov
    12 12
     
    
    13 13
     from buildstream import _yaml
    
    14 14
     from buildstream._artifactcache.cascache import CASCache
    
    15
    -from buildstream._artifactcache.casserver import create_server
    
    15
    +from buildstream._artifactcache.casserver import create_server, setup_server
    
    16 16
     from buildstream._context import Context
    
    17 17
     from buildstream._exceptions import ArtifactError
    
    18 18
     
    
    ... ... @@ -29,7 +29,7 @@ from buildstream._exceptions import ArtifactError
    29 29
     #
    
    30 30
     class ArtifactShare():
    
    31 31
     
    
    32
    -    def __init__(self, directory, *, total_space=None, free_space=None):
    
    32
    +    def __init__(self, directory, *, total_space=None, free_space=None, credentials={}):
    
    33 33
     
    
    34 34
             # The working directory for the artifact share (in case it
    
    35 35
             # needs to do something outside of it's backend's storage folder).
    
    ... ... @@ -55,19 +55,24 @@ class ArtifactShare():
    55 55
     
    
    56 56
             q = Queue()
    
    57 57
     
    
    58
    -        self.process = Process(target=self.run, args=(q,))
    
    58
    +        self.process = Process(target=self.run, args=(q, credentials))
    
    59 59
             self.process.start()
    
    60 60
     
    
    61 61
             # Retrieve port from server subprocess
    
    62 62
             port = q.get()
    
    63 63
     
    
    64
    -        self.repo = 'http://localhost:{}'.format(port)
    
    64
    +        if credentials:
    
    65
    +            protocol = 'https'
    
    66
    +        else:
    
    67
    +            protocol = 'http'
    
    68
    +
    
    69
    +        self.repo = '{}://localhost:{}'.format(protocol, port)
    
    65 70
     
    
    66 71
         # run():
    
    67 72
         #
    
    68 73
         # Run the artifact server.
    
    69 74
         #
    
    70
    -    def run(self, q):
    
    75
    +    def run(self, q, credentials):
    
    71 76
             pytest_cov.embed.cleanup_on_sigterm()
    
    72 77
     
    
    73 78
             # Optionally mock statvfs
    
    ... ... @@ -77,7 +82,7 @@ class ArtifactShare():
    77 82
                 os.statvfs = self._mock_statvfs
    
    78 83
     
    
    79 84
             server = create_server(self.repodir, enable_push=True)
    
    80
    -        port = server.add_insecure_port('localhost:0')
    
    85
    +        port = setup_server(server, 'localhost', 0, **credentials)
    
    81 86
     
    
    82 87
             server.start()
    
    83 88
     
    
    ... ... @@ -149,8 +154,8 @@ class ArtifactShare():
    149 154
     # Create an ArtifactShare for use in a test case
    
    150 155
     #
    
    151 156
     @contextmanager
    
    152
    -def create_artifact_share(directory, *, total_space=None, free_space=None):
    
    153
    -    share = ArtifactShare(directory, total_space=total_space, free_space=free_space)
    
    157
    +def create_artifact_share(directory, *, total_space=None, free_space=None, credentials={}):
    
    158
    +    share = ArtifactShare(directory, total_space=total_space, free_space=free_space, credentials=credentials)
    
    154 159
         try:
    
    155 160
             yield share
    
    156 161
         finally:
    



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