1
1
using System ;
2
+ using System . Diagnostics ;
2
3
using System . IO ;
3
4
using System . Net ;
5
+ using System . Net . Cache ;
6
+ using System . Runtime . CompilerServices ;
7
+ using System . Runtime . Serialization ;
8
+ using System . Threading ;
4
9
using System . Threading . Tasks ;
5
10
using dotnetCampus . FileDownloader ;
6
11
using Microsoft . Extensions . Logging ;
@@ -34,6 +39,83 @@ public void CreateWebRequest()
34
39
35
40
mock . Verify ( downloader => downloader . CreateWebRequest ( It . IsAny < string > ( ) ) , Times . AtLeastOnce ) ;
36
41
} ) ;
42
+
43
+ "测试进入慢网环境下载,能成功下载文件" . Test ( ( ) =>
44
+ {
45
+ var url = $ "https://blog.lindexi.com";
46
+ var file = new FileInfo ( Path . GetTempFileName ( ) ) ;
47
+ var slowlySegmentFileDownloader = new SlowSegmentFileDownloader ( url , file ) ;
48
+ var task = slowlySegmentFileDownloader . DownloadFileAsync ( ) ;
49
+
50
+ Task . WaitAny ( task , Task . Delay ( TimeSpan . FromSeconds ( 20 ) ) ) ;
51
+
52
+ if ( task . IsCompleted )
53
+ {
54
+ file . Refresh ( ) ;
55
+ Assert . AreEqual ( 100 , file . Length ) ;
56
+ }
57
+ else
58
+ {
59
+ // 测试设备太渣
60
+ }
61
+ } ) ;
62
+ }
63
+
64
+ class SlowStream : Stream
65
+ {
66
+ public override void Flush ( )
67
+ {
68
+ }
69
+
70
+ public override Task < int > ReadAsync ( byte [ ] buffer , int offset , int count , CancellationToken cancellationToken )
71
+ {
72
+ return Task . FromResult ( Read ( buffer , offset , count ) ) ;
73
+ }
74
+
75
+ public override int Read ( byte [ ] buffer , int offset , int count )
76
+ {
77
+ Thread . Sleep ( 100 ) ;
78
+ buffer [ 0 ] = 0xFF ;
79
+ return 1 ;
80
+ }
81
+
82
+ public override long Seek ( long offset , SeekOrigin origin )
83
+ {
84
+ return offset ;
85
+ }
86
+
87
+ public override void SetLength ( long value )
88
+ {
89
+ throw new NotImplementedException ( ) ;
90
+ }
91
+
92
+ public override void Write ( byte [ ] buffer , int offset , int count )
93
+ {
94
+ throw new NotImplementedException ( ) ;
95
+ }
96
+
97
+ public override bool CanRead => true ;
98
+ public override bool CanSeek => false ;
99
+ public override bool CanWrite => false ;
100
+ public override long Length => 100 ;
101
+ public override long Position { get ; set ; }
102
+ }
103
+
104
+ class SlowSegmentFileDownloader : SegmentFileDownloader
105
+ {
106
+ public SlowSegmentFileDownloader ( string url , FileInfo file , ILogger < SegmentFileDownloader > ? logger = null , IProgress < DownloadProgress > ? progress = null , ISharedArrayPool ? sharedArrayPool = null , int bufferLength = UInt16 . MaxValue , TimeSpan ? stepTimeOut = null ) : base ( url , file , logger , progress , sharedArrayPool , bufferLength , stepTimeOut )
107
+ {
108
+ }
109
+
110
+ protected override WebRequest CreateWebRequest ( string url )
111
+ {
112
+ var fakeWebResponse = new FakeWebResponse ( )
113
+ {
114
+ Stream = new SlowStream ( )
115
+ } ;
116
+
117
+ return new FakeHttpWebRequest ( fakeWebResponse ) ;
118
+ }
37
119
}
38
120
39
121
class FakeSegmentFileDownloader : SegmentFileDownloader
@@ -49,21 +131,64 @@ public FakeSegmentFileDownloader(IMockSegmentFileDownloader mockSegmentFileDownl
49
131
50
132
public IMockSegmentFileDownloader MockSegmentFileDownloader { get ; }
51
133
52
- protected override HttpWebRequest CreateWebRequest ( string url )
134
+ protected override WebRequest CreateWebRequest ( string url )
53
135
{
54
136
return MockSegmentFileDownloader . CreateWebRequest ( url ) ;
55
137
}
56
138
57
- protected override HttpWebRequest OnWebRequestSet ( HttpWebRequest webRequest )
139
+ protected override WebRequest OnWebRequestSet ( WebRequest webRequest )
58
140
{
59
141
return MockSegmentFileDownloader . OnWebRequestSet ( webRequest ) ;
60
142
}
61
143
}
62
144
63
145
public interface IMockSegmentFileDownloader
64
146
{
65
- HttpWebRequest CreateWebRequest ( string url ) ;
66
- HttpWebRequest OnWebRequestSet ( HttpWebRequest webRequest ) ;
147
+ WebRequest CreateWebRequest ( string url ) ;
148
+ WebRequest OnWebRequestSet ( WebRequest webRequest ) ;
149
+ }
150
+ }
151
+
152
+ class FakeHttpWebRequest : WebRequest
153
+ {
154
+ public FakeHttpWebRequest ( FakeWebResponse fakeWebResponse )
155
+ {
156
+ FakeWebResponse = fakeWebResponse ;
157
+ }
158
+
159
+ public override Task < WebResponse > GetResponseAsync ( )
160
+ {
161
+ return Task . FromResult ( GetResponse ( ) ) ;
162
+ }
163
+
164
+ public override string Method { get ; set ; }
165
+ public override RequestCachePolicy CachePolicy { get ; set ; }
166
+ public override string ConnectionGroupName { get ; set ; }
167
+ public override long ContentLength { get ; set ; }
168
+ public override string ContentType { get ; set ; }
169
+ public override ICredentials Credentials { get ; set ; }
170
+ public override WebHeaderCollection Headers { get ; set ; }
171
+ public override bool PreAuthenticate { get ; set ; }
172
+ public override Uri RequestUri { get ; }
173
+ public override int Timeout { get ; set ; }
174
+ public override bool UseDefaultCredentials { get ; set ; }
175
+
176
+ private FakeWebResponse FakeWebResponse { get ; }
177
+
178
+ public override WebResponse GetResponse ( )
179
+ {
180
+ return FakeWebResponse ;
181
+ }
182
+ }
183
+
184
+ class FakeWebResponse : WebResponse
185
+ {
186
+ public Stream Stream { set ; get ; }
187
+ public override long ContentLength => Stream . Length ;
188
+
189
+ public override Stream GetResponseStream ( )
190
+ {
191
+ return Stream ;
67
192
}
68
193
}
69
194
}
0 commit comments