public static void TestConversion(IConverter converter, string sourceFileName, FileTypes sourceFormat, FileTypes targetFormat, bool assertSuccess) { string sourceFile = Path.GetFullPath(sourceFileName); // Get a temporary target file TempFolder tempFolder = new TempFolder(); string targetFile = tempFolder.getFilePath("target." + targetFormat); // Do the conversion bool converted = converter.Convert(sourceFile, (int)sourceFormat, targetFile, (int)targetFormat); if (assertSuccess) { // Check that converter returned true Assert.IsTrue(converted); // Check that converter created the target file and it's not empty Assert.AreNotEqual(0, new FileInfo(targetFile).Length); } else { // Check that converter returned false Assert.IsFalse(converted); } // Delete the temp folder created tempFolder.Release(); }
public void Run() { int bytesRead, bytesSent; byte[] buffer = new byte[BufferSize]; TempFolder tempFolder = null; string sourceFilePath = null; FileStream sourceFileStream = null; string targetFilePath = null; FileStream targetFileStream = null; bool everythingOk = false; try { // 1) Read the conversion ID int conversionId = ReceiveInt(); log.Info("received conversion id: " + conversionId); // 1) Read the source file type int sourceFileTypeValue = ReceiveInt(); FileTypes sourceFileType = (FileTypes)sourceFileTypeValue; log.Info("received source file type: " + sourceFileTypeValue + " ("+ sourceFileType +")"); if (!Enum.IsDefined(typeof(FileTypes), sourceFileType)) { throw new ProtocolException(StatusCodes.BadFileType); } // 2) Read the target file type int targetFileTypeValue = ReceiveInt(); FileTypes targetFileType = (FileTypes)targetFileTypeValue; log.Info("received target file type: " + targetFileTypeValue + " (" + targetFileType + ")"); if (!Enum.IsDefined(typeof(FileTypes), targetFileType)) { throw new ProtocolException(StatusCodes.BadFileType); } // 3) Read the source file size int fileSize = ReceiveInt(); log.Info("received source file size: " + fileSize); if (fileSize <= 0) { throw new ProtocolException(StatusCodes.BadFileSize); } // 4) Read the source file and cache it on disk tempFolder = new TempFolder(conversionId); log.Info("created temp folder " + tempFolder.ToString()); sourceFilePath = tempFolder.getFilePath("source." + sourceFileType); sourceFileStream = new FileStream(sourceFilePath, FileMode.Create); int totalBytesRead = 0; log.Info("receiving source file..."); while (totalBytesRead < fileSize) { bytesRead = socket.Receive(buffer, BufferSize, 0); sourceFileStream.Write(buffer, 0, bytesRead); totalBytesRead += bytesRead; } sourceFileStream.Close(); log.Info("source file received"); // 5) Convert the source file bool converted = false; try { targetFilePath = tempFolder.getFilePath("target." + targetFileType); converted = fileConverter.Convert(sourceFilePath, (int)sourceFileType, targetFilePath, (int)targetFileType); } catch (BrokenSourceException e) { throw new ProtocolException(StatusCodes.BrokenSourceFile, e); } catch (ConversionException e) { throw new ProtocolException(StatusCodes.ConversionError, e); } if (!converted) { throw new ProtocolException(StatusCodes.UnsupportedConversion); } // 6) Send back the ok status code SendInt((int)StatusCodes.Ok); log.Info("sent status code: 0 (ok!)"); // 7) Send back the converted file size int filesize = 0; try { filesize = (int)new FileInfo(targetFilePath).Length; } catch (OverflowException e) { throw new ProtocolException(StatusCodes.ConvertedFileTooBig, e); } SendInt(filesize); log.Info("sent target file size: " + filesize); // 8) Send back the converted file buffer = new byte[BufferSize]; targetFileStream = new FileStream(targetFilePath, FileMode.Open); log.Info("sending target file..."); while (true) { bytesRead = targetFileStream.Read(buffer, 0, BufferSize); if (bytesRead == 0) { break; } else { bytesSent = socket.Send(buffer, bytesRead, 0); } } log.Info("target file sent"); targetFileStream.Close(); // If execution arrives here, everything went well! everythingOk = true; } catch (Exception e) { log.Error("exception", e); StatusCodes statusCode = (e is ProtocolException ? ((ProtocolException)e).statusCode : StatusCodes.InternalServerError); string statusCodeDescription = "status code " + (int)statusCode + " (" + statusCode + ")"; try { SendInt((int)statusCode); log.Info("sent " + statusCodeDescription); } catch (Exception ee) { log.Warn("exception while sending " + statusCodeDescription, ee); } } finally { // Close streams if (sourceFileStream != null) sourceFileStream.Close(); if (targetFileStream != null) targetFileStream.Close(); // Delete temp folder if everything ok, or move it to errors repository if (tempFolder != null) { tempFolder.Release(!everythingOk); } EndPoint remoteEndPoint = socket.RemoteEndPoint; socket.Shutdown(SocketShutdown.Both); // Wait that client closes connection //socket.Receive(new byte[1], SocketFlags.Peek); socket.Close(); log.Info("connection closed"); } }
public static void TestHighConcurrencyConversion(IConverter converter, string sourceFileName, FileTypes sourceFormat, FileTypes targetFormat, int concurrentConversions) { // Try to convert always the same file string sourceFile = Path.GetFullPath(sourceFileName); // Count the succeded conversion in this var int successes = 0; // Create the thread pool List<Thread> threads = new List<Thread>(); for (int i = 0; i < concurrentConversions; i++) { threads.Add(new Thread(delegate () { // This code will run many times in the same moment on many threads, // so be very careful to not make two Office instances write the same // file, or they will raise exceptions. The most problems I had // happened exactly because of this. Always make Office instance write // to a clean filepath that points to a still non-existent file. // Don't try anything else, 90% it will raise errors. // The safest way to create a clean lonely filepath is using the // TempFolder class TempFolder tempFolder = new TempFolder(); string targetFile = tempFolder.getFilePath("target." + targetFormat); // Ok, let's do the real conversion try { bool converted = converter.Convert(sourceFile, (int)sourceFormat, targetFile, (int)targetFormat); if (converted) Interlocked.Increment(ref successes); } catch (Exception e) { Console.WriteLine("Conversion failed:\n" + e + "\n"); } finally { // Delete the temp target folder tempFolder.Release(); } })); } // Launch all the threads in the same time foreach (var thread in threads) { thread.Start(); } // Wait for all threads completion foreach (var thread in threads) { thread.Join(); } // Check test final result Assert.AreEqual(concurrentConversions, successes); }
public void Run(object stateInfo) { if (!socket.Connected) throw new InvalidOperationException("Socket is not connected!"); int totalTime = Environment.TickCount; int bytesRead, bytesSent; byte[] buffer = new byte[BufferSize]; TempFolder tempFolder = null; string sourceFilePath = null; FileStream sourceFileStream = null; string targetFilePath = null; FileStream targetFileStream = null; bool healthCheck = false; bool everythingOk = false; try { // Set socket timeouts socket.ReceiveTimeout = SocketTimeout; socket.SendTimeout = SocketTimeout; // 1) Read the conversion ID int conversionId; try { conversionId = ReceiveInt(); } catch (InvalidOperationException) { // If an external service performs a TCP health check on // this on this service, it will shutdown the connection // just after it is accepted by this server. In this catch // I handle just this special case. Don't log anything, // just return successfully. healthCheck = true; everythingOk = true; return; } log.Info("received conversion id: " + conversionId); // 1) Read the source file type int sourceFileTypeValue = ReceiveInt(); FileTypes sourceFileType = (FileTypes)sourceFileTypeValue; log.Info("received source file type: " + sourceFileTypeValue + " ("+ sourceFileType +")"); if (!Enum.IsDefined(typeof(FileTypes), sourceFileType)) { throw new ProtocolException(StatusCodes.BadFileType); } // 2) Read the target file type int targetFileTypeValue = ReceiveInt(); FileTypes targetFileType = (FileTypes)targetFileTypeValue; log.Info("received target file type: " + targetFileTypeValue + " (" + targetFileType + ")"); if (!Enum.IsDefined(typeof(FileTypes), targetFileType)) { throw new ProtocolException(StatusCodes.BadFileType); } // 3) Read the source file size int fileSize = ReceiveInt(); log.Info("received source file size: " + fileSize); if (fileSize <= 0) { throw new ProtocolException(StatusCodes.BadFileSize); } // 4) Read the source file and cache it on disk tempFolder = new TempFolder(conversionId); log.Info("created temp folder " + tempFolder.ToString()); sourceFilePath = tempFolder.getFilePath("source." + sourceFileType); sourceFileStream = new FileStream(sourceFilePath, FileMode.Create); int totalBytesRead = 0; log.Info("receiving source file..."); while (totalBytesRead < fileSize) { bytesRead = socket.Receive(buffer, Math.Min(BufferSize, fileSize - totalBytesRead), 0); sourceFileStream.Write(buffer, 0, bytesRead); totalBytesRead += bytesRead; } sourceFileStream.Close(); log.Info("source file received"); // 5) Convert the source file log.Info("converting file..."); int conversionTime = Environment.TickCount; bool converted = false; try { targetFilePath = tempFolder.getFilePath("target." + targetFileType); converted = fileConverter.Convert(sourceFilePath, (int)sourceFileType, targetFilePath, (int)targetFileType); } catch (BrokenSourceException e) { throw new ProtocolException(StatusCodes.BrokenSourceFile, e); } catch (ConversionException e) { throw new ProtocolException(StatusCodes.InternalServerError, e); } if (!converted) { throw new ProtocolException(StatusCodes.UnsupportedConversion); } conversionTime = Environment.TickCount - conversionTime; log.Info("file converted"); // 6) Send back the ok status code SendInt((int)StatusCodes.Ok); log.Info("sent status code: 0 (ok!)"); // 7) Send back the converted file size int filesize = 0; try { filesize = (int)new FileInfo(targetFilePath).Length; } catch (OverflowException e) { throw new ProtocolException(StatusCodes.ConvertedFileTooBig, e); } SendInt(filesize); log.Info("sent target file size: " + filesize); // 8) Send back the converted file buffer = new byte[BufferSize]; targetFileStream = new FileStream(targetFilePath, FileMode.Open); log.Info("sending target file..."); while ((bytesRead = targetFileStream.Read(buffer, 0, BufferSize)) > 0) { bytesSent = socket.Send(buffer, bytesRead, 0); } log.Info("target file sent"); targetFileStream.Close(); // If execution arrives here, everything went well! everythingOk = true; // Log timings totalTime = Environment.TickCount - totalTime; log.Info("timings: total " + totalTime / 1000 + "s, conversion " + conversionTime / 1000 + "s ("+ (int)(((double)conversionTime / totalTime) * 100) +"%)"); } catch (Exception e) { log.Error("exception", e); StatusCodes statusCode = (e is ProtocolException ? ((ProtocolException)e).statusCode : StatusCodes.InternalServerError); string statusCodeDescription = "status code " + (int)statusCode + " (" + statusCode + ")"; try { SendInt((int)statusCode); log.Info("sent " + statusCodeDescription); } catch (Exception ee) { log.Warn("exception while sending " + statusCodeDescription, ee); } } finally { // Close streams if (sourceFileStream != null) sourceFileStream.Close(); if (targetFileStream != null) targetFileStream.Close(); // Delete temp folder if everything ok, or move it to errors repository if (tempFolder != null) { tempFolder.Release(!everythingOk); } socket.Shutdown(SocketShutdown.Both); socket.Close(); if (!healthCheck) log.Info("connection closed"); Interlocked.Decrement(ref serverConnectionsCounter.value); } }