As previously discussed, some of us think that a mock TO server can be 
beneficial for testing clients. For specific reasoning, refer to that 
discussion: 
https://mail-archives.apache.org/mod_mbox/trafficcontrol-dev/201902.mbox/%3CCA%2B5ZNX9pE5F-ecC0atpq6bTkBDnr7zCsADQcW3enXdpVRbpCdQ%40mail.gmail.com%3E

Now some code for that mock server has been written. The Pull Request for it is 
here: https://github.com/apache/trafficcontrol/pull/3478 but a short 
description of what it does (and doesn't) do is:

The Traffic Ops mock server **SHALL**

* Serve all of the API routes supported by the Traffic Ops API
* Serve static responses that never change in structure or content* Identify 
itself through the ``Server`` HTTP header as ``Traffic Ops/{{version}} (Mock)``
* Support all methods supported by the Traffic Ops (the behavior of the server 
when the client uses erroneous request methods, request paths or request 
parameters is not defined)
* Faithfully reproduce syntactically valid - and self-consistent - responses of 
the real Traffic Ops

The Traffic Ops mock server **SHALL NOT**

* Require proper authentication, despite that a real server would (because 
testing one route shouldn't have extraneous dependencies)
* Modify any of its pre-determined responses during runtime. This means that a 
client may attempt to e.g. create a server object by submitting a ``POST`` 
request to ``/api/{{version}}/servers`` - which should receive a response 
indicating the operation was successful (assuming it was syntactically valid 
and consistent with the static data set) - the new server object will not 
appear in the response of a subsequent ``GET`` request to the same endpoint


Now, with all that in mind, there's been discussion on the PR as to whether 
it's more appropriate to serve static JSON files or use globally scoped Go 
structure constants. There are advantages and disadvantages to both approaches.

Personally, I favor the Go structures. Global structs aid in consistency; for 
example, a server's id is declared once and can be used in responses to the 
``/api/{{version}}/servers`` endpoint, deliveryservice assignment endpoints 
etc. If we use JSON files, any change or update will require the developer to 
check through all remaining JSON files for further instances. They also allow 
us to use (some of) the same functions as the real Traffic Ops when serving API 
responses, which gives us correct ``alerts`` objects for free. Since it's 
supposed to fully mock the API, it should also be able to handle 
POST/PUT/DELETE requests as well as just GET. In order to be self-consistent, 
this means we'd need to have prepared responses for those as well - but this 
isn't possible since e.g. the user can POST a server with any arbitrary (valid) 
hostname. So when we echo the created object back to the client, we'd need to 
be able to parse, validate and respond with this unknown input data. Which 
means writing specific Go handlers for almost every endpoint anyway, so at most 
static JSON will handle 1/4 of all cases, which is going to leave us with a 
mixture of using pure JSON and using Go structs.
Some downsides of the Go structs: the code is really ugly, and the GET requests 
have a lot of associated data that could be handled much more simply by just 
serving from the filesystem. It would also probably grow to use significantly 
more memory that a JSON approach.

The biggest advantage of a JSON file structure is that it's very simple, and 
it's been argued that the cost of updating things when they change is next to 
negligible, since the canonical mock server shouldn't need to change actual 
data - just add new fields. Which is true, my only concern is that the current 
set of implemented routes is very small and as it grows things will need to 
change until parity with the real TO API is reached. Doing all of that at once 
is - in my opinion - certainly far beyond the scope of a single PR.


So for anyone who cares: which do you think we should use? (Also I'm sure 
Rawlin Peters can better articulate his position on using JSON than I have, so 
please feel free to do that my dude)


Reply via email to