public void TestUploadInBadServer_NeedsResume( [Values(true, false)] bool knownSize, [Values(new[] { 0 }, new[] { 100 }, new[] { 410 }, new[] { 0, 410 })] int[] dodgyBytes, [Values(100, 400, 1000)] int chunkSize, [Values(4096, 51, 100)] int bufferSize) { var expectedCallCount = 1 + (uploadLength + chunkSize - 1) / chunkSize + dodgyBytes.Length * 2; using (var server = new MultiChunkBadServer(_server, dodgyBytes, HttpStatusCode.NotFound)) using (var service = new MockClientService(server.HttpPrefix)) { var content = knownSize ? new MemoryStream(uploadTestBytes) : new UnknownSizeMemoryStream(uploadTestBytes); var uploader = new TestResumableUpload(service, "MultiChunk", "POST", content, "text/plain", chunkSize); uploader.BufferSize = bufferSize; var progress = uploader.Upload(); int sanity = 0; while (progress.Status == UploadStatus.Failed && sanity++ < 10) { progress = uploader.Resume(); } Assert.That(progress.Status, Is.EqualTo(UploadStatus.Completed)); Assert.That(server.Requests.Count, Is.EqualTo(expectedCallCount)); Assert.That(server.Bytes, Is.EqualTo(uploadTestBytes)); } }
public async Task TestInitiatedResumableUpload( [Values("", "text/plain")] string contentType) { using (var server = new SingleChunkServer(_server)) using (var service = new MockClientService(server.HttpPrefix)) { var content = new MemoryStream(uploadTestBytes); var tmpUploader = new TestResumableUpload( service, "SingleChunk", "POST", content, contentType, uploadLength); var uploadUri = await tmpUploader.InitiateSessionAsync(); var uploader = ResumableUpload.CreateFromUploadUri(uploadUri, content); var progress = uploader.Upload(); Assert.That(server.Requests.Count, Is.EqualTo(2)); var r0 = server.Requests[0]; Assert.That(r0.Headers["X-Upload-Content-Type"], Is.EqualTo(contentType)); Assert.That(r0.Headers["X-Upload-Content-Length"], Is.EqualTo(uploadTestBytes.Length.ToString())); var r1 = server.Requests[1]; Assert.That(server.RemovePrefix(r1.Url.AbsolutePath), Is.EqualTo(uploadPath)); Assert.That(r1.Headers["Content-Range"], Is.EqualTo($"bytes 0-{uploadLength - 1}/{uploadLength}")); Assert.That(progress.Status, Is.EqualTo(UploadStatus.Completed)); Assert.That(progress.BytesSent, Is.EqualTo(uploadTestBytes.Length)); } }
public void TestUploadWithUploaderRestart_UnknownSize() { // Unknown stream size not supported, exception always thrown using (var server = new MultiChunkServer(_server)) using (var service = new MockClientService(server.HttpPrefix)) { var content = new UnknownSizeMemoryStream(uploadTestBytes); var uploader = new TestResumableUpload(service, "whatever", "PUT", content, "", 100); var url = new Uri("http://what.ever/"); Assert.ThrowsAsync <NotImplementedException>(async() => await uploader.ResumeAsync(url)); } }
public void TestUploadStreamDisposedBetweenConstructionAndUpload() { using (var server = new SingleChunkServer(_server)) using (var service = new MockClientService(server.HttpPrefix)) { var content = new MemoryStream(new byte[10]); var uploader = new TestResumableUpload(service, "SingleChunk", "POST", content, "text/plain", 100); content.Dispose(); var progress = uploader.Upload(); Assert.IsType <ObjectDisposedException>(progress.Exception); } }
public void TestChunkSize() { using (var service = new MockClientService(new BaseClientService.Initializer())) { var stream = new MemoryStream(Encoding.UTF8.GetBytes(UploadTestData)); var upload = new TestResumableUpload(service, "whatever", "POST", stream, "text/plain", 100); // Negative chunk size. Assert.Throws <ArgumentOutOfRangeException>(() => upload.ChunkSize = -1); // Less than the minimum. Assert.Throws <ArgumentOutOfRangeException>(() => upload.ChunkSize = TestResumableUpload.MinimumChunkSize - 1); // Valid chunk size. upload.ChunkSize = TestResumableUpload.MinimumChunkSize; upload.ChunkSize = TestResumableUpload.MinimumChunkSize * 2; } }
public void TestUploadInMultipleChunks( [CombinatorialValues(true, false)] bool knownSize, [CombinatorialValues(100, 400, 1000)] int chunkSize) { var expectedCallCount = 1 + (uploadLength + chunkSize - 1) / chunkSize; using (var server = new MultiChunkServer(_server)) using (var service = new MockClientService(server.HttpPrefix)) { var content = knownSize ? new MemoryStream(uploadTestBytes) : new UnknownSizeMemoryStream(uploadTestBytes); var uploader = new TestResumableUpload(service, "MultiChunk", "POST", content, "text/plain", chunkSize); var progress = uploader.Upload(); Assert.Equal(expectedCallCount, server.Requests.Count); Assert.Equal(uploadTestBytes, server.Bytes); Assert.Equal(UploadStatus.Completed, progress.Status); } }
public void TestUploadInBadServer_ServerUnavailable( [CombinatorialValues(true, false)] bool knownSize, [CombinatorialValues(new[] { 0 }, new[] { 100 }, new[] { 410 }, new[] { 0, 100 })] int[] dodgyBytes, [CombinatorialValues(100, 400, 1000)] int chunkSize) { var expectedCallCount = 1 + (uploadLength + chunkSize - 1) / chunkSize; expectedCallCount += dodgyBytes.Length * 2; using (var server = new MultiChunkBadServer(_server, dodgyBytes, HttpStatusCode.ServiceUnavailable)) using (var service = new MockClientService(server.HttpPrefix)) { var content = knownSize ? new MemoryStream(uploadTestBytes) : new UnknownSizeMemoryStream(uploadTestBytes); var uploader = new TestResumableUpload(service, "MultiChunk", "POST", content, "text/plain", chunkSize); var progress = uploader.Upload(); Assert.Equal(expectedCallCount, server.Requests.Count); Assert.Equal(uploadTestBytes, server.Bytes); Assert.Equal(UploadStatus.Completed, progress.Status); } }
public void TestUploadEmptyFile( [CombinatorialValues(true, false)] bool knownSize) { using (var server = new SingleChunkServer(_server)) using (var service = new MockClientService(server.HttpPrefix)) { var content = knownSize ? new MemoryStream(new byte[0]) : new UnknownSizeMemoryStream(new byte[0]); var uploader = new TestResumableUpload(service, "SingleChunk", "POST", content, "text/plain", 100); var progress = uploader.Upload(); Assert.Equal(2, server.Requests.Count); var r0 = server.Requests[0]; Assert.Equal(knownSize ? "0" : null, r0.Headers["X-Upload-Content-Length"]); var r1 = server.Requests[1]; Assert.Equal(uploadPath, server.RemovePrefix(r1.Url.AbsolutePath)); Assert.Equal("bytes *" + "/0", r1.Headers["Content-Range"]); Assert.Equal(UploadStatus.Completed, progress.Status); Assert.Equal(0, progress.BytesSent); } }
public void TestUploadInPartialServer( [Values(true, false)] bool knownSize, [Values(80, 150)] int partialSize, [Values(100, 200)] int chunkSize) { var actualChunkSize = Math.Min(partialSize, chunkSize); var expectedCallCount = (uploadLength + actualChunkSize - 1) / actualChunkSize + 1; using (var server = new MultiChunkPartialServer(_server, partialSize)) using (var service = new MockClientService(server.HttpPrefix)) { var content = knownSize ? new MemoryStream(uploadTestBytes) : new UnknownSizeMemoryStream(uploadTestBytes); var uploader = new TestResumableUpload(service, "MultiChunk", "POST", content, "text/plain", chunkSize); var progress = uploader.Upload(); Assert.That(server.Requests.Count, Is.EqualTo(expectedCallCount)); Assert.That(server.Bytes, Is.EqualTo(uploadTestBytes)); Assert.That(progress.Status, Is.EqualTo(UploadStatus.Completed)); } }
public void TestUploadInBadServer_NotFound_PlainTextError( [CombinatorialValues(true, false)] bool knownSize, [CombinatorialValues(new[] { 0 }, new[] { 100 }, new[] { 410 })] int[] dodgyBytes) { string plainTextError = "Not Found"; using (var server = new MultiChunkBadServer(_server, dodgyBytes, HttpStatusCode.NotFound, plainTextError)) using (var service = new MockClientService(server.HttpPrefix)) { var content = knownSize ? new MemoryStream(uploadTestBytes) : new UnknownSizeMemoryStream(uploadTestBytes); var uploader = new TestResumableUpload(service, "MultiChunk", "POST", content, "text/plain", 100); IUploadProgress lastProgress = null; uploader.ProgressChanged += p => lastProgress = p; uploader.Upload(); Assert.NotNull(lastProgress); Assert.Equal(UploadStatus.Failed, lastProgress.Status); var exception = (GoogleApiException)lastProgress.Exception; Assert.Equal(plainTextError, exception.Message); Assert.Null(exception.Error); } }
public void TestUploadInSingleChunk( [CombinatorialValues(true, false)] bool knownSize, [CombinatorialValues("", "text/plain")] string contentType, [CombinatorialValues(0, 10)] int chunkSizeDelta) { using (var server = new SingleChunkServer(_server)) using (var service = new MockClientService(server.HttpPrefix)) { var content = knownSize ? new MemoryStream(uploadTestBytes) : new UnknownSizeMemoryStream(uploadTestBytes); var uploader = new TestResumableUpload( service, "SingleChunk", "POST", content, contentType, uploadLength + chunkSizeDelta); var progress = uploader.Upload(); Assert.Equal(2, server.Requests.Count); var r0 = server.Requests[0]; Assert.Equal(contentType, r0.Headers["X-Upload-Content-Type"]); Assert.Equal(knownSize ? uploadTestBytes.Length.ToString() : null, r0.Headers["X-Upload-Content-Length"]); var r1 = server.Requests[1]; Assert.Equal(uploadPath, server.RemovePrefix(r1.Url.AbsolutePath)); Assert.Equal($"bytes 0-{uploadLength - 1}/{uploadLength}", r1.Headers["Content-Range"]); Assert.Equal(UploadStatus.Completed, progress.Status); Assert.Equal(uploadTestBytes.Length, progress.BytesSent); } }
public void TestUploadProgress( [CombinatorialValues(true, false)] bool knownSize) { int chunkSize = 200; using (var server = new MultiChunkServer(_server)) using (var service = new MockClientService(server.HttpPrefix)) { var content = knownSize ? new MemoryStream(uploadTestBytes) : new UnknownSizeMemoryStream(uploadTestBytes); var uploader = new TestResumableUpload(service, "MultiChunk", "POST", content, "text/plain", chunkSize); var progress = new List <IUploadProgress>(); uploader.ProgressChanged += p => progress.Add(p); uploader.Upload(); Assert.Equal(4, progress.Count); Assert.Equal(UploadStatus.Starting, progress[0].Status); Assert.Equal(0, progress[0].BytesSent); Assert.Equal(UploadStatus.Uploading, progress[1].Status); Assert.Equal(chunkSize, progress[1].BytesSent); Assert.Equal(UploadStatus.Uploading, progress[2].Status); Assert.Equal(chunkSize * 2, progress[2].BytesSent); Assert.Equal(UploadStatus.Completed, progress[3].Status); Assert.Equal(uploadLength, progress[3].BytesSent); } }
public void TestUploadInBadServer_NotFound_JsonError( [Values(true, false)] bool knownSize, [Values(new[] { 0 }, new[] { 100 }, new[] { 410 })] int[] dodgyBytes) { string jsonError = @"{ ""error"": { ""errors"": [ { ""domain"": ""global"", ""reason"": ""required"", ""message"": ""Login Required"", ""locationType"": ""header"", ""location"": ""Authorization"" } ], ""code"": 401, ""message"": ""Login Required"" }}"; using (var server = new MultiChunkBadServer(_server, dodgyBytes, HttpStatusCode.NotFound, jsonError)) using (var service = new MockClientService(server.HttpPrefix)) { var content = knownSize ? new MemoryStream(uploadTestBytes) : new UnknownSizeMemoryStream(uploadTestBytes); var uploader = new TestResumableUpload(service, "MultiChunk", "POST", content, "text/plain", 100); IUploadProgress lastProgress = null; uploader.ProgressChanged += p => lastProgress = p; uploader.Upload(); Assert.That(lastProgress, Is.Not.Null); Assert.That(lastProgress.Status, Is.EqualTo(UploadStatus.Failed)); var exception = (GoogleApiException)lastProgress.Exception; Assert.That(exception.Message, Contains.Substring( "Message[Login Required] Location[Authorization - header] Reason[required] Domain[global]"), "Error message is invalid"); Assert.That(exception.Error.Message, Is.EqualTo("Login Required"), "Parsed error incorrect"); } }
public void TestUploadInMultipleChunks_Interception( [CombinatorialValues(true, false)] bool knownSize, [CombinatorialValues(100, 400, 1000)] int chunkSize) { // One fewer interception call than server calls, as there's no initialization call. var expectedInterceptionCount = (uploadLength + chunkSize - 1) / chunkSize; using (var server = new MultiChunkServer(_server)) using (var service = new MockClientService(server.HttpPrefix)) { var content = knownSize ? new MemoryStream(uploadTestBytes) : new UnknownSizeMemoryStream(uploadTestBytes); var uploader = new TestResumableUpload(service, "MultiChunk", "POST", content, "text/plain", chunkSize); int interceptionCount = 0; MemoryStream interceptedBytes = new MemoryStream(); uploader.UploadStreamInterceptor = (buffer, offset, count) => { interceptedBytes.Write(buffer, offset, count); interceptionCount++; }; var progress = uploader.Upload(); Assert.Equal(expectedInterceptionCount, interceptionCount); Assert.Equal(uploadTestBytes, interceptedBytes.ToArray()); } }