this repo has no description
2
fork

Configure Feed

Select the types of activity you want to include in your feed.

at master 193 lines 5.4 kB view raw
1defmodule TrinityTest do 2 use ExUnit.Case 3 4 alias Trinity.{Sim, SimProcess, SimPersistentTerm, SimFile, SimLogger, Scheduler} 5 import Trinity.Scheduler, only: [receive_yield: 1] 6 require SimLogger 7 8 defmodule Counter do 9 use GenServer 10 alias Trinity.{SimServer, SimFile} 11 12 def start_link(id, initial_count) do 13 SimServer.start_link(__MODULE__, %{id: id, initial_count: initial_count}) 14 end 15 16 def add(server, amount) do 17 SimServer.call(server, {:add, amount}) 18 end 19 20 def init(%{id: id, initial_count: initial_count}) do 21 assert SimFile.exists?("/counters/#{id}/") == false 22 :ok = SimFile.mkdir_p("/counters/#{id}/") 23 assert SimFile.exists?("/counters/#{id}") == true 24 assert SimFile.exists?("/counters/#{id}/") == true 25 26 {:ok, fd} = SimFile.open("/counters/#{id}/#{id}.count", [:read, :write]) 27 assert SimFile.ls("/counters/#{id}/") == {:ok, ["#{id}.count"]} 28 29 SimLogger.debug "Init (id=#{id}, fd=#{fd}, initial_count=#{initial_count})" 30 31 state = %{ 32 fd: fd, 33 size: nil, 34 } 35 state = write_value(state, initial_count) 36 SimLogger.debug "Initial state (id=#{id}): #{inspect(state)}" 37 38 :ok = SimPersistentTerm.put("counter-#{id}", initial_count) 39 term = SimPersistentTerm.get("counter-#{id}", nil) 40 SimLogger.debug "Persistent term: #{term}" 41 42 # Note: this intentionally tests a log message with no variables 43 SimLogger.debug "Init complete" 44 {:ok, state} 45 end 46 47 def handle_call({:add, amount}, _from, state) do 48 value = read_value(state) 49 value = value + amount 50 state = write_value(state, value) 51 {:reply, value, state} 52 end 53 54 defp read_value(%{fd: fd, size: size}) do 55 {:ok, data} = SimFile.pread(fd, 3, size) 56 "The current value of the counter is: " <> value_str = data 57 String.to_integer(value_str) 58 end 59 60 defp write_value(%{fd: fd} = state, value) do 61 data = "The current value of the counter is: " <> Integer.to_string(value) 62 SimFile.pwrite(fd, 3, data) 63 %{state | size: byte_size(data)} 64 end 65 end 66 67 defmodule CounterSupervisor do 68 use GenServer 69 alias Trinity.SimServer 70 71 def start_link(children, opts), do: SimServer.start_link(__MODULE__, children, opts) 72 def get_children(server), do: SimServer.call(server, :get_children) 73 74 def init(children) do 75 pids = Enum.map(children, fn {m, f, a} -> 76 {:ok, pid} = apply(m, f, a) 77 pid 78 end) 79 {:ok, pids} 80 end 81 82 def handle_call(:get_children, _from, pids) do 83 {:reply, pids, pids} 84 end 85 end 86 87 test "scheduler" do 88 message = Sim.run_simulation(fn -> 89 nodes = [:n1, :n2, :n3] 90 91 names = Enum.map(nodes, fn node -> 92 name = String.to_atom(Atom.to_string(node) <> "_proc") 93 94 children = Enum.map(1..10, fn i -> 95 {TrinityTest.Counter, :start_link, [i, i]} 96 end) 97 98 node_mfa = { 99 TrinityTest.CounterSupervisor, 100 :start_link, 101 [children, [name: name]], 102 } 103 Sim.create_node(node, node_mfa) 104 Sim.start_node(node) 105 {name, node} 106 end) 107 108 # Wait for nodes to start/register 109 SimProcess.sleep(100) 110 111 pids = 112 names 113 |> Enum.map(fn name -> 114 CounterSupervisor.get_children(name) 115 |> Enum.with_index(1) 116 end) 117 |> Enum.concat() 118 119 Enum.each(pids, fn {pid, id} -> 120 result = Counter.add(pid, 10) 121 assert result == (id + 10) 122 end) 123 124 SimProcess.send_after self(), :finish, 1000 125 receive_yield do 126 :finish -> :noop 127 end 128 129 Scheduler.yield(1000) 130 #dbg Scheduler.dump(), limit: :infinity 131 :success 132 133 hash = SimLogger.get_hash() 134 tail = SimLogger.log_tail(10) 135 """ 136 Simulation complete. 137 138 Hash: #{hash} 139 140 Log tail: 141 #{Enum.join(tail, "\n")} 142 """ 143 end, seed: 101) 144 145 require Logger 146 Logger.info(message) 147 end 148 149 describe "fs" do 150 @describetag :fs 151 @describetag :disable 152 @describetag :tmp_dir 153 154 test "read/write", %{tmp_dir: tmp_dir} do 155 path = Path.join(tmp_dir, "foobar.txt") 156 {:ok, fd} = SimFile.open(path, [:read, :write, :raw]) 157 158 text = "foo bar baz\n" 159 :ok = SimFile.pwrite(fd, 100, text) 160 {:ok, result} = SimFile.pread(fd, 100, byte_size(text)) 161 assert result == text 162 163 :ok = SimFile.pwrite(fd, 101, "ool") 164 {:ok, result} = SimFile.pread(fd, 100, byte_size(text)) 165 assert result == "foolbar baz\n" 166 end 167 168 test "paths", %{tmp_dir: tmp_dir} do 169 subdir = Path.join([tmp_dir, "foo", "bar"]) 170 path = Path.join(subdir, "foobar.txt") 171 172 assert {:ok, []} = SimFile.ls(tmp_dir) 173 assert {:error, :enoent} = SimFile.ls(subdir) 174 refute SimFile.exists?(subdir) 175 refute SimFile.exists?(path) 176 177 assert {:error, :enoent} = SimFile.open(path, [:read, :write, :raw]) 178 assert :ok = SimFile.mkdir_p(subdir) 179 180 assert {:ok, ["foo"]} = SimFile.ls(tmp_dir) 181 assert {:ok, []} = SimFile.ls(subdir) 182 assert SimFile.exists?(subdir) 183 refute SimFile.exists?(path) 184 185 assert {:ok, _fd} = SimFile.open(path, [:read, :write, :raw]) 186 187 assert {:ok, ["foo"]} = SimFile.ls(tmp_dir) 188 assert {:ok, ["foobar.txt"]} = SimFile.ls(subdir) 189 assert SimFile.exists?(subdir) 190 assert SimFile.exists?(path) 191 end 192 end 193end