falco
falco copied to clipboard
[BUG] The [not set] value is being output as a string in v1.3.0
Describe the problem When concatenating the not_set value with a string, it outputs the value '[not set]'. This value shouldn't be outputted originally.
Expected behavior
// @scope: recv
// @suite: print not_set as empty
sub test_recv {
declare local var.NOTSET STRING;
declare local var.message STRING;
set var.message = var.NOTSET;
assert.equal(var.message, "");
set var.message = "output:" var.NOTSET;
assert.equal(var.message, "output:");
}
This should pass, but in falco v1.3.0, it results in the following error.
Assertion Error: Assertion error: expect=output:, actual=output:[not set]
Actual Value: output:[not set]
10| set var.message = "output:" var.NOTSET;
11| assert.equal(var.message, "output:");
12| }
Additional context I have prepared various test cases related to 'empty'. https://github.com/bungoume/falco-vcl-empty-test/blob/main/tests/empty.test.vcl
Blocking this problem by VCL behavior https://fiddle.fastly.dev/fiddle/e9852716
https://developer.fastly.com/reference/vcl/types/string/
Various functions and operators treat unset strings differently; some render them as the empty string, and some as "(null)". This handling is a property of the function (or operator), rather than a property of the STRING type. A not set value is converted to an empty string when assigned to a STRING variable
This is quite difficult...
Here is the test and understanding based on my own fiddle test results. https://fiddle.fastly.dev/fiddle/116ac5ce
sub test_recv {
declare local var.NOTSET STRING;
declare local var.message STRING;
set req.http.MESSAGE = var.NOTSET; # Looks like same process as `unset req.http.MESSAGE;`
assert.is_notset(req.http.MESSAGE);
set var.message = var.NOTSET; # auto convert empty string
assert.equal(var.message, "");
set req.http.MESSAGE = "var:" var.NOTSET; # render as `(null)`
assert.equal(req.http.MESSAGE, "var:(null)");
set var.message = "var:" var.NOTSET; # render as ``(empty string)
assert.equal(var.message, "var:");
}
Understood, we will try to follow VCL's behavior.