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));
                }
        }
Beispiel #3
0
 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));
         }
 }
Beispiel #4
0
 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);
         }
 }
Beispiel #5
0
        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;
            }
        }
Beispiel #6
0
        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);
                }
        }
Beispiel #7
0
        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);
                }
        }
Beispiel #8
0
 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));
                }
        }
Beispiel #10
0
        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);
                }
        }
Beispiel #11
0
 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);
         }
 }
Beispiel #12
0
        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");
                }
        }
Beispiel #14
0
        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());
                }
        }