@@ -72,19 +72,26 @@ def _get_tar_testdata(compression_type=""):
72
72
return temp_f .getvalue ()
73
73
74
74
75
+ def _get_whl_testdata (name = "fake_package" , version = "1.0" ):
76
+ temp_f = io .BytesIO ()
77
+ with zipfile .ZipFile (file = temp_f , mode = "w" ) as zfp :
78
+ zfp .writestr (f"{ name } -{ version } .dist-info/METADATA" , "Fake metadata" )
79
+ return temp_f .getvalue ()
80
+
81
+
82
+ def _storage_hash (data ):
83
+ return hashlib .blake2b (data , digest_size = 256 // 8 ).hexdigest ()
84
+
85
+
75
86
_TAR_GZ_PKG_TESTDATA = _get_tar_testdata ("gz" )
76
87
_TAR_GZ_PKG_MD5 = hashlib .md5 (_TAR_GZ_PKG_TESTDATA ).hexdigest ()
77
88
_TAR_GZ_PKG_SHA256 = hashlib .sha256 (_TAR_GZ_PKG_TESTDATA ).hexdigest ()
78
- _TAR_GZ_PKG_STORAGE_HASH = hashlib .blake2b (
79
- _TAR_GZ_PKG_TESTDATA , digest_size = 256 // 8
80
- ).hexdigest ()
89
+ _TAR_GZ_PKG_STORAGE_HASH = _storage_hash (_TAR_GZ_PKG_TESTDATA )
81
90
82
91
_TAR_BZ2_PKG_TESTDATA = _get_tar_testdata ("bz2" )
83
92
_TAR_BZ2_PKG_MD5 = hashlib .md5 (_TAR_BZ2_PKG_TESTDATA ).hexdigest ()
84
93
_TAR_BZ2_PKG_SHA256 = hashlib .sha256 (_TAR_BZ2_PKG_TESTDATA ).hexdigest ()
85
- _TAR_BZ2_PKG_STORAGE_HASH = hashlib .blake2b (
86
- _TAR_BZ2_PKG_TESTDATA , digest_size = 256 // 8
87
- ).hexdigest ()
94
+ _TAR_BZ2_PKG_STORAGE_HASH = _storage_hash (_TAR_BZ2_PKG_TESTDATA )
88
95
89
96
90
97
class TestExcWithMessage :
@@ -2771,6 +2778,8 @@ def test_upload_succeeds_with_wheel(
2771
2778
RoleFactory .create (user = user , project = project )
2772
2779
2773
2780
filename = f"{ project .name } -{ release .version } -cp34-none-{ plat } .whl"
2781
+ filebody = _get_whl_testdata (name = project .name , version = release .version )
2782
+ filestoragehash = _storage_hash (filebody )
2774
2783
2775
2784
pyramid_config .testing_securitypolicy (identity = user )
2776
2785
db_request .user = user
@@ -2782,19 +2791,22 @@ def test_upload_succeeds_with_wheel(
2782
2791
"version" : release .version ,
2783
2792
"filetype" : "bdist_wheel" ,
2784
2793
"pyversion" : "cp34" ,
2785
- "md5_digest" : _TAR_GZ_PKG_MD5 ,
2794
+ "md5_digest" : hashlib . md5 ( filebody ). hexdigest () ,
2786
2795
"content" : pretend .stub (
2787
2796
filename = filename ,
2788
- file = io .BytesIO (_TAR_GZ_PKG_TESTDATA ),
2789
- type = "application/tar " ,
2797
+ file = io .BytesIO (filebody ),
2798
+ type = "application/zip " ,
2790
2799
),
2791
2800
}
2792
2801
)
2793
2802
2794
2803
@pretend .call_recorder
2795
2804
def storage_service_store (path , file_path , * , meta ):
2796
2805
with open (file_path , "rb" ) as fp :
2797
- assert fp .read () == _TAR_GZ_PKG_TESTDATA
2806
+ if file_path .endswith (".metadata" ):
2807
+ assert fp .read () == b"Fake metadata"
2808
+ else :
2809
+ assert fp .read () == filebody
2798
2810
2799
2811
storage_service = pretend .stub (store = storage_service_store )
2800
2812
@@ -2818,9 +2830,9 @@ def storage_service_store(path, file_path, *, meta):
2818
2830
pretend .call (
2819
2831
"/" .join (
2820
2832
[
2821
- _TAR_GZ_PKG_STORAGE_HASH [:2 ],
2822
- _TAR_GZ_PKG_STORAGE_HASH [2 :4 ],
2823
- _TAR_GZ_PKG_STORAGE_HASH [4 :],
2833
+ filestoragehash [:2 ],
2834
+ filestoragehash [2 :4 ],
2835
+ filestoragehash [4 :],
2824
2836
filename ,
2825
2837
]
2826
2838
),
@@ -2831,7 +2843,24 @@ def storage_service_store(path, file_path, *, meta):
2831
2843
"package-type" : "bdist_wheel" ,
2832
2844
"python-version" : "cp34" ,
2833
2845
},
2834
- )
2846
+ ),
2847
+ pretend .call (
2848
+ "/" .join (
2849
+ [
2850
+ filestoragehash [:2 ],
2851
+ filestoragehash [2 :4 ],
2852
+ filestoragehash [4 :],
2853
+ filename + ".metadata" ,
2854
+ ]
2855
+ ),
2856
+ mock .ANY ,
2857
+ meta = {
2858
+ "project" : project .normalized_name ,
2859
+ "version" : release .version ,
2860
+ "package-type" : "bdist_wheel" ,
2861
+ "python-version" : "cp34" ,
2862
+ },
2863
+ ),
2835
2864
]
2836
2865
2837
2866
# Ensure that a File object has been created.
@@ -2884,6 +2913,8 @@ def test_upload_succeeds_with_wheel_after_sdist(
2884
2913
RoleFactory .create (user = user , project = project )
2885
2914
2886
2915
filename = f"{ project .name } -{ release .version } -cp34-none-any.whl"
2916
+ filebody = _get_whl_testdata (name = project .name , version = release .version )
2917
+ filestoragehash = _storage_hash (filebody )
2887
2918
2888
2919
pyramid_config .testing_securitypolicy (identity = user )
2889
2920
db_request .user = user
@@ -2895,19 +2926,22 @@ def test_upload_succeeds_with_wheel_after_sdist(
2895
2926
"version" : release .version ,
2896
2927
"filetype" : "bdist_wheel" ,
2897
2928
"pyversion" : "cp34" ,
2898
- "md5_digest" : "335c476dc930b959dda9ec82bd65ef19" ,
2929
+ "md5_digest" : hashlib . md5 ( filebody ). hexdigest () ,
2899
2930
"content" : pretend .stub (
2900
2931
filename = filename ,
2901
- file = io .BytesIO (b"A fake file." ),
2902
- type = "application/tar " ,
2932
+ file = io .BytesIO (filebody ),
2933
+ type = "application/zip " ,
2903
2934
),
2904
2935
}
2905
2936
)
2906
2937
2907
2938
@pretend .call_recorder
2908
2939
def storage_service_store (path , file_path , * , meta ):
2909
2940
with open (file_path , "rb" ) as fp :
2910
- assert fp .read () == b"A fake file."
2941
+ if file_path .endswith (".metadata" ):
2942
+ assert fp .read () == b"Fake metadata"
2943
+ else :
2944
+ assert fp .read () == filebody
2911
2945
2912
2946
storage_service = pretend .stub (store = storage_service_store )
2913
2947
db_request .find_service = pretend .call_recorder (
@@ -2930,9 +2964,9 @@ def storage_service_store(path, file_path, *, meta):
2930
2964
pretend .call (
2931
2965
"/" .join (
2932
2966
[
2933
- "4e" ,
2934
- "6e" ,
2935
- "fa4c0ee2bbad071b4f5b5ea68f1aea89fa716e7754eb13e2314d45a5916e" ,
2967
+ filestoragehash [: 2 ] ,
2968
+ filestoragehash [ 2 : 4 ] ,
2969
+ filestoragehash [ 4 :] ,
2936
2970
filename ,
2937
2971
]
2938
2972
),
@@ -2943,7 +2977,24 @@ def storage_service_store(path, file_path, *, meta):
2943
2977
"package-type" : "bdist_wheel" ,
2944
2978
"python-version" : "cp34" ,
2945
2979
},
2946
- )
2980
+ ),
2981
+ pretend .call (
2982
+ "/" .join (
2983
+ [
2984
+ filestoragehash [:2 ],
2985
+ filestoragehash [2 :4 ],
2986
+ filestoragehash [4 :],
2987
+ filename + ".metadata" ,
2988
+ ]
2989
+ ),
2990
+ mock .ANY ,
2991
+ meta = {
2992
+ "project" : project .normalized_name ,
2993
+ "version" : release .version ,
2994
+ "package-type" : "bdist_wheel" ,
2995
+ "python-version" : "cp34" ,
2996
+ },
2997
+ ),
2947
2998
]
2948
2999
2949
3000
# Ensure that a File object has been created.
@@ -3025,6 +3076,55 @@ def test_upload_fails_with_unsupported_wheel_plat(
3025
3076
"400 Binary wheel .* has an unsupported platform tag .*" , resp .status
3026
3077
)
3027
3078
3079
+ def test_upload_fails_with_missing_metadata_wheel (
3080
+ self , monkeypatch , pyramid_config , db_request
3081
+ ):
3082
+ user = UserFactory .create ()
3083
+ pyramid_config .testing_securitypolicy (identity = user )
3084
+ db_request .user = user
3085
+ EmailFactory .create (user = user )
3086
+ project = ProjectFactory .create ()
3087
+ release = ReleaseFactory .create (project = project , version = "1.0" )
3088
+ RoleFactory .create (user = user , project = project )
3089
+
3090
+ temp_f = io .BytesIO ()
3091
+ with zipfile .ZipFile (file = temp_f , mode = "w" ) as zfp :
3092
+ zfp .writestr (
3093
+ f"{ project .name .lower ()} -{ release .version } .dist-info/METADATA" ,
3094
+ "Fake metadata" ,
3095
+ )
3096
+
3097
+ filename = f"{ project .name } -{ release .version } -cp34-none-any.whl"
3098
+ filebody = temp_f .getvalue ()
3099
+
3100
+ db_request .POST = MultiDict (
3101
+ {
3102
+ "metadata_version" : "1.2" ,
3103
+ "name" : project .name ,
3104
+ "version" : release .version ,
3105
+ "filetype" : "bdist_wheel" ,
3106
+ "pyversion" : "cp34" ,
3107
+ "md5_digest" : hashlib .md5 (filebody ).hexdigest (),
3108
+ "content" : pretend .stub (
3109
+ filename = filename ,
3110
+ file = io .BytesIO (filebody ),
3111
+ type = "application/zip" ,
3112
+ ),
3113
+ }
3114
+ )
3115
+
3116
+ monkeypatch .setattr (legacy , "_is_valid_dist_file" , lambda * a , ** kw : True )
3117
+
3118
+ with pytest .raises (HTTPBadRequest ) as excinfo :
3119
+ legacy .file_upload (db_request )
3120
+
3121
+ resp = excinfo .value
3122
+
3123
+ assert resp .status_code == 400
3124
+ assert re .match (
3125
+ "400 Wheel .* does not contain the required METADATA file: .*" , resp .status
3126
+ )
3127
+
3028
3128
def test_upload_updates_existing_project_name (
3029
3129
self , pyramid_config , db_request , metrics
3030
3130
):
0 commit comments