• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

mizosoft / methanol / #577

19 Aug 2025 04:34PM UTC coverage: 87.897%. First build
#577

Pull #132

github

mizosoft
Setup covered & test-contributing projects properly
Pull Request #132: Properly setup coveralls

2325 of 2818 branches covered (82.51%)

Branch coverage included in aggregate %.

18 of 135 new or added lines in 3 files covered. (13.33%)

7639 of 8518 relevant lines covered (89.68%)

0.9 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

0.0
/methanol/src/main/java/com/github/mizosoft/methanol/RateControlledServer.java
1
/*
2
 * Copyright © 2025 Moataz Hussein
3
 *
4
 * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
5
 *
6
 * The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
7
 *
8
 * THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
9
 */
10

11
package com.github.mizosoft.methanol;
12

13
import com.sun.net.httpserver.HttpExchange;
14
import com.sun.net.httpserver.HttpHandler;
15
import com.sun.net.httpserver.HttpServer;
16
import java.io.IOException;
17
import java.io.OutputStream;
18
import java.net.InetSocketAddress;
19
import java.time.Instant;
20
import java.util.concurrent.Executors;
21

NEW
22
public class RateControlledServer {
×
23
  private static final int PORT = 8080;
24
  private static final int CHUNK_SIZE = 10 * 1024; // 1KB chunks
25
  private static final long RATE_LIMIT_MS = 1; // Send chunk every 1 (10KB/s)
26

27
  public static void main(String[] args) throws IOException {
NEW
28
    HttpServer server = HttpServer.create(new InetSocketAddress(PORT), 0);
×
NEW
29
    server.createContext("/upload", new UploadHandler());
×
NEW
30
    server.createContext("/download", new DownloadHandler());
×
NEW
31
    server.setExecutor(Executors.newCachedThreadPool());
×
32

NEW
33
    System.out.println("Rate-controlled server started on port " + PORT);
×
NEW
34
    System.out.println("Upload endpoint: http://localhost:" + PORT + "/upload");
×
NEW
35
    System.out.println("Download endpoint: http://localhost:" + PORT + "/download");
×
NEW
36
    server.start();
×
NEW
37
  }
×
38

39
  // Handler for testing HTTP client uploads (server receives at controlled rate)
NEW
40
  static class UploadHandler implements HttpHandler {
×
41
    @Override
42
    public void handle(HttpExchange exchange) throws IOException {
NEW
43
      if (!"POST".equals(exchange.getRequestMethod())) {
×
NEW
44
        exchange.sendResponseHeaders(405, 0);
×
NEW
45
        exchange.close();
×
NEW
46
        return;
×
47
      }
48

NEW
49
      System.out.println("\n=== Upload Handler Started ===");
×
NEW
50
      System.out.println("Timestamp: " + Instant.now());
×
51

52
      // Read request body at controlled rate
NEW
53
      byte[] buffer = new byte[CHUNK_SIZE];
×
NEW
54
      int totalBytesRead = 0;
×
NEW
55
      int chunkCount = 0;
×
NEW
56
      long startTime = System.currentTimeMillis();
×
57

NEW
58
      try (var inputStream = exchange.getRequestBody()) {
×
59
        int bytesRead;
NEW
60
        while ((bytesRead = inputStream.read(buffer)) != -1) {
×
NEW
61
          chunkCount++;
×
NEW
62
          totalBytesRead += bytesRead;
×
63

NEW
64
          long currentTime = System.currentTimeMillis();
×
NEW
65
          System.out.printf(
×
66
              "Chunk %d: Read %d bytes (Total: %d bytes, Time: %dms)%n",
NEW
67
              chunkCount, bytesRead, totalBytesRead, currentTime - startTime);
×
68

69
          // Simulate controlled processing rate
70
          try {
NEW
71
            Thread.sleep(RATE_LIMIT_MS);
×
NEW
72
          } catch (InterruptedException e) {
×
NEW
73
            Thread.currentThread().interrupt();
×
NEW
74
            break;
×
NEW
75
          }
×
NEW
76
        }
×
77
      }
78

NEW
79
      long endTime = System.currentTimeMillis();
×
NEW
80
      double durationSeconds = (endTime - startTime) / 1000.0;
×
NEW
81
      double avgRate = totalBytesRead / durationSeconds / 1024; // KB/s
×
82

NEW
83
      System.out.printf(
×
84
          "Upload complete: %d bytes in %.2fs (%.2f KB/s)%n",
NEW
85
          totalBytesRead, durationSeconds, avgRate);
×
86

87
      // Send response
NEW
88
      String response =
×
NEW
89
          String.format(
×
90
              "Received %d bytes in %d chunks over %.2fs (%.2f KB/s)",
NEW
91
              totalBytesRead, chunkCount, durationSeconds, avgRate);
×
NEW
92
      exchange.sendResponseHeaders(200, response.length());
×
NEW
93
      try (OutputStream os = exchange.getResponseBody()) {
×
NEW
94
        os.write(response.getBytes());
×
95
      }
NEW
96
    }
×
97
  }
98

99
  // Handler for testing HTTP client downloads (server sends at controlled rate)
NEW
100
  static class DownloadHandler implements HttpHandler {
×
101
    @Override
102
    public void handle(HttpExchange exchange) throws IOException {
NEW
103
      if (!"GET".equals(exchange.getRequestMethod())) {
×
NEW
104
        exchange.sendResponseHeaders(405, 0);
×
NEW
105
        exchange.close();
×
NEW
106
        return;
×
107
      }
108

NEW
109
      System.out.println("\n=== Download Handler Started ===");
×
NEW
110
      System.out.println("Timestamp: " + Instant.now());
×
111

112
      // Parse size parameter (default 10KB)
NEW
113
      String query = exchange.getRequestURI().getQuery();
×
NEW
114
      int totalSize = 10 * 1024; // 10KB default
×
NEW
115
      if (query != null && query.startsWith("size=")) {
×
116
        try {
NEW
117
          totalSize = Integer.parseInt(query.substring(5)) * 1024; // Convert KB to bytes
×
NEW
118
        } catch (NumberFormatException e) {
×
119
          // Use default
NEW
120
        }
×
121
      }
122

NEW
123
      exchange.sendResponseHeaders(200, totalSize);
×
124

NEW
125
      try (OutputStream os = exchange.getResponseBody()) {
×
NEW
126
        byte[] chunk = new byte[CHUNK_SIZE];
×
127
        // Fill with some data pattern
NEW
128
        for (int i = 0; i < chunk.length; i++) {
×
NEW
129
          chunk[i] = (byte) (i % 256);
×
130
        }
131

NEW
132
        int bytesSent = 0;
×
NEW
133
        int chunkCount = 0;
×
NEW
134
        long startTime = System.currentTimeMillis();
×
135

NEW
136
        while (bytesSent < totalSize) {
×
NEW
137
          int bytesToSend = Math.min(CHUNK_SIZE, totalSize - bytesSent);
×
NEW
138
          os.write(chunk, 0, bytesToSend);
×
NEW
139
          os.flush();
×
140

NEW
141
          bytesSent += bytesToSend;
×
NEW
142
          chunkCount++;
×
143

NEW
144
          long currentTime = System.currentTimeMillis();
×
NEW
145
          System.out.printf(
×
146
              "Chunk %d: Sent %d bytes (Total: %d/%d bytes, Time: %dms)%n",
NEW
147
              chunkCount, bytesToSend, bytesSent, totalSize, currentTime - startTime);
×
148

149
          // Rate limiting - don't send last chunk delay
NEW
150
          if (bytesSent < totalSize) {
×
151
            try {
NEW
152
              Thread.sleep(RATE_LIMIT_MS);
×
NEW
153
            } catch (InterruptedException e) {
×
NEW
154
              Thread.currentThread().interrupt();
×
NEW
155
              break;
×
NEW
156
            }
×
157
          }
NEW
158
        }
×
159

NEW
160
        long endTime = System.currentTimeMillis();
×
NEW
161
        double durationSeconds = (endTime - startTime) / 1000.0;
×
NEW
162
        double avgRate = bytesSent / durationSeconds / 1024; // KB/s
×
163

NEW
164
        System.out.printf(
×
165
            "Download complete: %d bytes in %.2fs (%.2f KB/s)%n",
NEW
166
            bytesSent, durationSeconds, avgRate);
×
167
      }
NEW
168
    }
×
169
  }
170
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc